diff --git a/bukkit/src/main/java/co/aikar/commands/BukkitCommandCompletionContext.java b/bukkit/src/main/java/co/aikar/commands/BukkitCommandCompletionContext.java index 2908e503..fdd9cb43 100644 --- a/bukkit/src/main/java/co/aikar/commands/BukkitCommandCompletionContext.java +++ b/bukkit/src/main/java/co/aikar/commands/BukkitCommandCompletionContext.java @@ -26,8 +26,8 @@ package co.aikar.commands; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -public class BukkitCommandCompletionContext extends CommandCompletionContext { - BukkitCommandCompletionContext(RegisteredCommand command, CommandIssuer issuer, String input, String config, String[] args) { +public class BukkitCommandCompletionContext extends CommandCompletionContext { + BukkitCommandCompletionContext(RegisteredCommand command, BukkitCommandIssuer issuer, String input, String config, String[] args) { super(command, issuer, input, config, args); } @@ -40,7 +40,6 @@ public class BukkitCommandCompletionContext extends CommandCompletionContext { * @return */ public Player getPlayer() { - CommandSender issuer = this.issuer.getIssuer(); - return issuer instanceof Player ? (Player) issuer : null; + return this.issuer.getPlayer(); } } diff --git a/bukkit/src/main/java/co/aikar/commands/BukkitCommandExecutionContext.java b/bukkit/src/main/java/co/aikar/commands/BukkitCommandExecutionContext.java index abef626a..e3cd18fd 100644 --- a/bukkit/src/main/java/co/aikar/commands/BukkitCommandExecutionContext.java +++ b/bukkit/src/main/java/co/aikar/commands/BukkitCommandExecutionContext.java @@ -45,7 +45,6 @@ public class BukkitCommandExecutionContext extends CommandExecutionContext T getIssuer() { + public CommandSender getIssuer() { //noinspection unchecked - return (T) sender; + return sender; + } + + public Player getPlayer() { + return isPlayer() ? (Player) sender : null; } @Override diff --git a/bukkit/src/main/java/co/aikar/commands/BukkitCommandManager.java b/bukkit/src/main/java/co/aikar/commands/BukkitCommandManager.java index f3055428..d2e65a7f 100644 --- a/bukkit/src/main/java/co/aikar/commands/BukkitCommandManager.java +++ b/bukkit/src/main/java/co/aikar/commands/BukkitCommandManager.java @@ -23,7 +23,6 @@ package co.aikar.commands; -import co.aikar.commands.annotation.Conditions; import co.aikar.commands.apachecommonslang.ApacheCommonsExceptionUtil; import co.aikar.timings.lib.MCTiming; import co.aikar.timings.lib.TimingManager; @@ -59,9 +58,7 @@ public class BukkitCommandManager extends CommandManager< ChatColor, BukkitMessageFormatter, BukkitCommandExecutionContext, - BukkitCommandCompletionContext, - BukkitConditionContext, - BukkitParameterConditionContext + BukkitConditionContext > { @SuppressWarnings("WeakerAccess") @@ -304,7 +301,7 @@ public class BukkitCommandManager extends CommandManager< @Override public BukkitCommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args) { - return new BukkitCommandCompletionContext(command, sender, input, config, args); + return new BukkitCommandCompletionContext(command, (BukkitCommandIssuer) sender, input, config, args); } @Override @@ -313,14 +310,10 @@ public class BukkitCommandManager extends CommandManager< } @Override - public BukkitConditionContext createConditionContext(CommandOperationContext context, Conditions conditions) { - return new BukkitConditionContext(context.getRegisteredCommand(), (BukkitCommandIssuer) context.getCommandIssuer(), conditions); + public BukkitConditionContext createConditionContext(CommandIssuer issuer, String config) { + return new BukkitConditionContext((BukkitCommandIssuer) issuer, config); } - @Override - public

BukkitParameterConditionContext createConditionContext(CommandOperationContext context, BukkitCommandExecutionContext execContext, Conditions conditions) { - return new BukkitParameterConditionContext

(context.getRegisteredCommand(), (BukkitCommandIssuer) context.getCommandIssuer(), execContext, conditions); - } @Override public void log(LogLevel level, String message, Throwable throwable) { diff --git a/bukkit/src/main/java/co/aikar/commands/BukkitConditionContext.java b/bukkit/src/main/java/co/aikar/commands/BukkitConditionContext.java index e26095b6..377d20c3 100644 --- a/bukkit/src/main/java/co/aikar/commands/BukkitConditionContext.java +++ b/bukkit/src/main/java/co/aikar/commands/BukkitConditionContext.java @@ -23,10 +23,19 @@ package co.aikar.commands; -import co.aikar.commands.annotation.Conditions; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; public class BukkitConditionContext extends ConditionContext { - BukkitConditionContext(RegisteredCommand cmd, BukkitCommandIssuer issuer, Conditions condAnno) { - super(cmd, issuer, condAnno); + BukkitConditionContext(BukkitCommandIssuer issuer, String config) { + super(issuer, config); + } + + public CommandSender getSender() { + return getIssuer().getIssuer(); + } + + public Player getPlayer() { + return getIssuer().getPlayer(); } } diff --git a/bungee/src/main/java/co/aikar/commands/BungeeCommandCompletionContext.java b/bungee/src/main/java/co/aikar/commands/BungeeCommandCompletionContext.java index 02f8661c..d3db7ea3 100644 --- a/bungee/src/main/java/co/aikar/commands/BungeeCommandCompletionContext.java +++ b/bungee/src/main/java/co/aikar/commands/BungeeCommandCompletionContext.java @@ -24,14 +24,19 @@ package co.aikar.commands; import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; -public class BungeeCommandCompletionContext extends CommandCompletionContext { +public class BungeeCommandCompletionContext extends CommandCompletionContext { - BungeeCommandCompletionContext(RegisteredCommand command, CommandIssuer issuer, String input, String config, String[] args) { + BungeeCommandCompletionContext(RegisteredCommand command, BungeeCommandIssuer issuer, String input, String config, String[] args) { super(command, issuer, input, config, args); } public CommandSender getSender() { return this.getIssuer().getIssuer(); } + + public ProxiedPlayer getPlayer() { + return this.issuer.getPlayer(); + } } diff --git a/bungee/src/main/java/co/aikar/commands/BungeeCommandExecutionContext.java b/bungee/src/main/java/co/aikar/commands/BungeeCommandExecutionContext.java index 01853b79..2eec2765 100644 --- a/bungee/src/main/java/co/aikar/commands/BungeeCommandExecutionContext.java +++ b/bungee/src/main/java/co/aikar/commands/BungeeCommandExecutionContext.java @@ -24,6 +24,7 @@ package co.aikar.commands; import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; import java.lang.reflect.Parameter; import java.util.List; @@ -38,4 +39,8 @@ public class BungeeCommandExecutionContext extends CommandExecutionContext T getIssuer() { - //noinspection unchecked - return (T) sender; + public CommandSender getIssuer() { + return sender; + } + + public ProxiedPlayer getPlayer() { + return isPlayer() ? (ProxiedPlayer) sender : null; } @Override diff --git a/bungee/src/main/java/co/aikar/commands/BungeeCommandManager.java b/bungee/src/main/java/co/aikar/commands/BungeeCommandManager.java index 45ea391b..88476928 100644 --- a/bungee/src/main/java/co/aikar/commands/BungeeCommandManager.java +++ b/bungee/src/main/java/co/aikar/commands/BungeeCommandManager.java @@ -23,7 +23,6 @@ package co.aikar.commands; -import co.aikar.commands.annotation.Conditions; import co.aikar.commands.apachecommonslang.ApacheCommonsExceptionUtil; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.CommandSender; @@ -43,9 +42,7 @@ public class BungeeCommandManager extends CommandManager< ChatColor, BungeeMessageFormatter, BungeeCommandExecutionContext, - BungeeCommandCompletionContext, - BungeeConditionContext, - BungeeParameterConditionContext + BungeeConditionContext > { protected final Plugin plugin; @@ -160,26 +157,19 @@ public class BungeeCommandManager extends CommandManager< @Override public CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args) { - return new BungeeCommandCompletionContext(command, sender, input, config, args); + return new BungeeCommandCompletionContext(command, (BungeeCommandIssuer) sender, input, config, args); } - - @Override - public BungeeConditionContext createConditionContext(CommandOperationContext context, Conditions conditions) { - return new BungeeConditionContext(context.getRegisteredCommand(), (BungeeCommandIssuer) context.getCommandIssuer(), conditions); - } - - @Override - public

BungeeParameterConditionContext createConditionContext(CommandOperationContext context, BungeeCommandExecutionContext execContext, Conditions conditions) { - return new BungeeParameterConditionContext

(context.getRegisteredCommand(), (BungeeCommandIssuer) context.getCommandIssuer(), execContext, conditions); - } - - @Override public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand) { return new RegisteredCommand(command, cmdName, method, prefSubCommand); } + @Override + public BungeeConditionContext createConditionContext(CommandIssuer issuer, String config) { + return new BungeeConditionContext((BungeeCommandIssuer) issuer, config); + } + @Override public void log(LogLevel level, String message, Throwable throwable) { Logger logger = this.plugin.getLogger(); diff --git a/bungee/src/main/java/co/aikar/commands/BungeeConditionContext.java b/bungee/src/main/java/co/aikar/commands/BungeeConditionContext.java index d9abeacc..a0e5fd50 100644 --- a/bungee/src/main/java/co/aikar/commands/BungeeConditionContext.java +++ b/bungee/src/main/java/co/aikar/commands/BungeeConditionContext.java @@ -1,9 +1,19 @@ package co.aikar.commands; -import co.aikar.commands.annotation.Conditions; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; public class BungeeConditionContext extends ConditionContext { - BungeeConditionContext(RegisteredCommand cmd, BungeeCommandIssuer issuer, Conditions condAnno) { - super(cmd, issuer, condAnno); + BungeeConditionContext(BungeeCommandIssuer issuer, String config) { + super(issuer, config); + } + + + public CommandSender getSender() { + return getIssuer().getIssuer(); + } + + public ProxiedPlayer getPlayer() { + return getIssuer().getPlayer(); } } diff --git a/bungee/src/main/java/co/aikar/commands/BungeeParameterConditionContext.java b/bungee/src/main/java/co/aikar/commands/BungeeParameterConditionContext.java deleted file mode 100644 index b605e5f2..00000000 --- a/bungee/src/main/java/co/aikar/commands/BungeeParameterConditionContext.java +++ /dev/null @@ -1,9 +0,0 @@ -package co.aikar.commands; - -import co.aikar.commands.annotation.Conditions; - -public class BungeeParameterConditionContext

extends ParameterConditionContext { - BungeeParameterConditionContext(RegisteredCommand cmd, BungeeCommandIssuer issuer, BungeeCommandExecutionContext execContext, Conditions conditions) { - super(cmd, issuer, execContext, conditions); - } -} diff --git a/core/src/main/java/co/aikar/commands/BaseCommand.java b/core/src/main/java/co/aikar/commands/BaseCommand.java index ec323bd1..027b5a8c 100644 --- a/core/src/main/java/co/aikar/commands/BaseCommand.java +++ b/core/src/main/java/co/aikar/commands/BaseCommand.java @@ -71,7 +71,7 @@ public abstract class BaseCommand { private String execSubcommand; @SuppressWarnings("WeakerAccess") private String[] origArgs; - CommandManager manager = null; + CommandManager manager = null; BaseCommand parentCommand; Map registeredCommands = new HashMap<>(); String description; @@ -443,7 +443,7 @@ public abstract class BaseCommand { return; } List sargs = Lists.newArrayList(args); - cmd.invoke(issuer, sargs); + cmd.invoke(issuer, sargs, commandOperationContext); } else { issuer.sendMessage(MessageType.ERROR, MessageKeys.PERMISSION_DENIED); } diff --git a/core/src/main/java/co/aikar/commands/CommandCompletionContext.java b/core/src/main/java/co/aikar/commands/CommandCompletionContext.java index 1b366d01..2ec3a49c 100644 --- a/core/src/main/java/co/aikar/commands/CommandCompletionContext.java +++ b/core/src/main/java/co/aikar/commands/CommandCompletionContext.java @@ -30,15 +30,15 @@ import java.lang.reflect.Parameter; import java.util.List; import java.util.Map; -public class CommandCompletionContext { +public class CommandCompletionContext { private final RegisteredCommand command; - protected final CommandIssuer issuer; + protected final I issuer; private final String input; private final String config; private final Map configs = Maps.newHashMap(); private final List args; - CommandCompletionContext(RegisteredCommand command, CommandIssuer issuer, String input, String config, String[] args) { + CommandCompletionContext(RegisteredCommand command, I issuer, String input, String config, String[] args) { this.command = command; this.issuer = issuer; this.input = input; diff --git a/core/src/main/java/co/aikar/commands/CommandConditions.java b/core/src/main/java/co/aikar/commands/CommandConditions.java index 1c5018a5..50325291 100644 --- a/core/src/main/java/co/aikar/commands/CommandConditions.java +++ b/core/src/main/java/co/aikar/commands/CommandConditions.java @@ -27,88 +27,92 @@ import co.aikar.commands.annotation.Conditions; import com.google.common.collect.HashBasedTable; import com.google.common.collect.Maps; import com.google.common.collect.Table; +import org.jetbrains.annotations.NotNull; import java.util.Map; @SuppressWarnings("BooleanMethodIsAlwaysInverted") // No IDEA, you are wrong public class CommandConditions < I extends CommandIssuer, - M extends CommandManager, - CC extends ConditionContext, CEC extends CommandExecutionContext, - PCC extends ParameterConditionContext + CC extends ConditionContext > { - M manager; - Map> conditions = Maps.newHashMap(); - Table, String, ParameterCondition> paramConditions = HashBasedTable.create(); - CommandConditions(M manager) { + private CommandManager manager; + private Map> conditions = Maps.newHashMap(); + private Table, String, ParameterCondition> paramConditions = HashBasedTable.create(); + + CommandConditions(CommandManager manager) { this.manager = manager; } - Condition addCondition(String id, Condition handler) { + public Condition addCondition(@NotNull String id, @NotNull Condition handler) { return this.conditions.put(id.toLowerCase(), handler); } -

ParameterCondition addCondition(Class

clazz, String id, ParameterCondition handler) { + public

ParameterCondition addCondition(Class

clazz, @NotNull String id, + @NotNull ParameterCondition handler) { return this.paramConditions.put(clazz, id.toLowerCase(), handler); } - boolean validateConditions(CommandOperationContext context, CEC cec) { + void validateConditions(CEC cec, Object value) throws InvalidCommandArgument { Conditions conditions = cec.getParam().getAnnotation(Conditions.class); - return conditions == null || validateConditions(conditions, context, cec); + validateConditions(conditions, cec, value); } - boolean validateConditions(CommandOperationContext context) { + void validateConditions(CommandOperationContext context) throws InvalidCommandArgument { RegisteredCommand cmd = context.getRegisteredCommand(); Conditions conditions = cmd.method.getAnnotation(Conditions.class); - if (conditions != null) { - if (!validateConditions(conditions, context)) { - return false; - } - } - return validateConditions(cmd.scope, context); + validateConditions(conditions, context); + validateConditions(cmd.scope, context); } - private boolean validateConditions(BaseCommand scope, CommandOperationContext operationContext) { + private void validateConditions(BaseCommand scope, CommandOperationContext operationContext) throws InvalidCommandArgument { Conditions conditions = scope.getClass().getAnnotation(Conditions.class); - //noinspection SimplifiableIfStatement - if (!validateConditions(conditions, operationContext)) { - return false; + validateConditions(conditions, operationContext); + + if (scope.parentCommand != null) { + validateConditions(scope.parentCommand, operationContext); } - return scope.parentCommand == null || validateConditions(scope.parentCommand, operationContext); } - private boolean validateConditions(Conditions condAnno, CommandOperationContext context) { + private void validateConditions(Conditions condAnno, CommandOperationContext context) throws InvalidCommandArgument { if (condAnno == null) { - return true; + return; } - //noinspection unchecked - CC conditionContext = (CC) this.manager.createConditionContext(context, condAnno); - String conditions = this.manager.getCommandReplacements().replace(condAnno.value()); - for (String cond : ACFPatterns.PIPE.split(conditions)) { - String[] split = ACFPatterns.EQUALS.split(cond, 2); - Condition condition = this.conditions.get(split[0].toLowerCase()); + String conditions = this.manager.getCommandReplacements().replace(condAnno.value()); + CommandIssuer issuer = context.getCommandIssuer(); + for (String cond : ACFPatterns.PIPE.split(conditions)) { + String[] split = ACFPatterns.COLON.split(cond, 2); + String id = split[0].toLowerCase(); + Condition condition = this.conditions.get(id); + if (condition == null) { + RegisteredCommand cmd = context.getRegisteredCommand(); + this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName()); + continue; + } + + String config = split.length == 2 ? split[1] : null; + //noinspection unchecked + CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); + //noinspection unchecked if (!condition.validateCondition(conditionContext)) { - return false; + return; } } - - return true; } - private boolean validateConditions(Conditions condAnno, CommandOperationContext context, CEC execContext) { + private void validateConditions(Conditions condAnno, CEC execContext, Object value) throws InvalidCommandArgument { if (condAnno == null) { - return true; + return; } - //noinspection unchecked - ParameterConditionContext conditionContext = this.manager.createConditionContext(context, execContext, condAnno); String conditions = this.manager.getCommandReplacements().replace(condAnno.value()); + I issuer = execContext.getIssuer(); for (String cond : ACFPatterns.PIPE.split(conditions)) { - String[] split = ACFPatterns.EQUALS.split(cond, 2); + String[] split = ACFPatterns.COLON.split(cond, 2); ParameterCondition condition; - Class cls = execContext.getParam().getClass(); + Class cls = execContext.getParam().getType(); String id = split[0].toLowerCase(); do { condition = this.paramConditions.get(cls, id); @@ -119,19 +123,28 @@ public class CommandConditions < } } while (cls != null); + + if (condition == null) { + RegisteredCommand cmd = execContext.getCmd(); + this.manager.log(LogLevel.ERROR, "Could not find command condition " + id + " for " + cmd.method.getName() + "::" +execContext.getParam().getName()); + continue; + } + String config = split.length == 2 ? split[1] : null; //noinspection unchecked - if (condition != null && !condition.validateCondition(conditionContext)) { - return false; + CC conditionContext = (CC) this.manager.createConditionContext(issuer, config); + + //noinspection unchecked + if (!condition.validateCondition(conditionContext, execContext, value)) { + return; } } - - return true; } - interface Condition { - boolean validateCondition(CC context); + public interface Condition { + boolean validateCondition(ConditionContext context) throws InvalidCommandArgument; } - interface ParameterCondition { - boolean validateCondition(PCC context); + + public interface ParameterCondition { + boolean validateCondition(ConditionContext context, CEC execContext, P value) throws InvalidCommandArgument; } } diff --git a/core/src/main/java/co/aikar/commands/CommandManager.java b/core/src/main/java/co/aikar/commands/CommandManager.java index d91bfb4b..9547c208 100644 --- a/core/src/main/java/co/aikar/commands/CommandManager.java +++ b/core/src/main/java/co/aikar/commands/CommandManager.java @@ -47,9 +47,7 @@ public abstract class CommandManager < FT, MF extends MessageFormatter, CEC extends CommandExecutionContext, - CCC extends CommandCompletionContext, - CC extends ConditionContext, - PCC extends ParameterConditionContext + CC extends ConditionContext > { /** @@ -65,6 +63,7 @@ public abstract class CommandManager < }); protected Map rootCommands = new HashMap<>(); protected final CommandReplacements replacements = new CommandReplacements(this); + protected final CommandConditions conditions = new CommandConditions<>(this); protected ExceptionHandler defaultExceptionHandler = null; protected boolean usePerIssuerLocale = false; @@ -118,6 +117,10 @@ public abstract class CommandManager < this.defaultFormatter = defaultFormatter; } + public CommandConditions getCommandConditions() { + return conditions; + } + /** * Gets the command contexts manager * @return Command Contexts @@ -205,14 +208,10 @@ public abstract class CommandManager < usePerIssuerLocale = setting; return old; } - public ConditionContext createConditionContext(CommandOperationContext context, Conditions conditions) { - //noinspection unchecked - return new ConditionContext<>(context.getRegisteredCommand(), context.getCommandIssuer(), conditions); - } - public

ParameterConditionContext createConditionContext(CommandOperationContext context, CEC execContext, Conditions conditions) { + public ConditionContext createConditionContext(CommandIssuer issuer, String config) { //noinspection unchecked - return new ParameterConditionContext(context.getRegisteredCommand(), (I) context.getCommandIssuer(), execContext, conditions); + return new ConditionContext(issuer, config); } public abstract CommandExecutionContext createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List args, int i, Map passedArgs); @@ -391,4 +390,8 @@ public abstract class CommandManager < throw new IllegalStateException("Using an unstable API that has not been enabled ( " + api + "). See https://acfunstable.emc.gs"); } } + + boolean hasUnstableAPI(String api) { + return unstableAPIs.contains(api); + } } diff --git a/core/src/main/java/co/aikar/commands/ConditionContext.java b/core/src/main/java/co/aikar/commands/ConditionContext.java index bc6ab02c..0c2bda31 100644 --- a/core/src/main/java/co/aikar/commands/ConditionContext.java +++ b/core/src/main/java/co/aikar/commands/ConditionContext.java @@ -23,42 +23,45 @@ package co.aikar.commands; -import co.aikar.commands.annotation.Conditions; import com.google.common.collect.Maps; import java.util.Map; public class ConditionContext { - private final RegisteredCommand cmd; private final I issuer; - private final Conditions condAnno; - private final Map flags; + private final String config; + private final Map configs; - ConditionContext(RegisteredCommand cmd, I issuer, Conditions condAnno) { - this.cmd = cmd; + ConditionContext(I issuer, String config) { this.issuer = issuer; - this.condAnno = condAnno; - this.flags = Maps.newHashMap(); - for (String s : ACFPatterns.COMMA.split(cmd.scope.manager.getCommandReplacements().replace(condAnno.value()))) { - String[] v = ACFPatterns.EQUALS.split(s, 2); - this.flags.put(v[0], v.length > 1 ? v[1] : null); + this.config = config; + this.configs = Maps.newHashMap(); + if (config != null) { + for (String s : ACFPatterns.COMMA.split(config)) { + String[] v = ACFPatterns.EQUALS.split(s, 2); + this.configs.put(v[0], v.length > 1 ? v[1] : null); + } } } + public I getIssuer() { return issuer; } - public boolean hasFlag(String flag) { - return flags.containsKey(flag); + public String getConfig() { + return this.config; + } + public boolean hasConfig(String flag) { + return configs.containsKey(flag); } - public String getFlagValue(String flag, String def) { - return flags.getOrDefault(flag, def); + public String getConfigValue(String flag, String def) { + return configs.getOrDefault(flag, def); } - public Integer getFlagValue(String flag, Integer def) { - return ACFUtil.parseInt(this.flags.get(flag), def); + public Integer getConfigValue(String flag, Integer def) { + return ACFUtil.parseInt(this.configs.get(flag), def); } } diff --git a/bukkit/src/main/java/co/aikar/commands/BukkitParameterConditionContext.java b/core/src/main/java/co/aikar/commands/ConditionFailedException.java similarity index 64% rename from bukkit/src/main/java/co/aikar/commands/BukkitParameterConditionContext.java rename to core/src/main/java/co/aikar/commands/ConditionFailedException.java index 070ae7bd..290e1729 100644 --- a/bukkit/src/main/java/co/aikar/commands/BukkitParameterConditionContext.java +++ b/core/src/main/java/co/aikar/commands/ConditionFailedException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License + * Copyright (c) 2016-2018 Daniel Ennis (Aikar) - MIT License * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -23,10 +23,23 @@ package co.aikar.commands; -import co.aikar.commands.annotation.Conditions; +import co.aikar.locales.MessageKey; +import co.aikar.locales.MessageKeyProvider; -public class BukkitParameterConditionContext

extends ParameterConditionContext { - BukkitParameterConditionContext(RegisteredCommand cmd, BukkitCommandIssuer issuer, BukkitCommandExecutionContext execContext, Conditions conditions) { - super(cmd, issuer, execContext, conditions); +public class ConditionFailedException extends InvalidCommandArgument { + public ConditionFailedException() { + super(false); + } + + public ConditionFailedException(MessageKeyProvider key, String... replacements) { + super(key, false, replacements); + } + + public ConditionFailedException(MessageKey key, String... replacements) { + super(key, false, replacements); + } + + public ConditionFailedException(String message) { + super(message, false); } } diff --git a/core/src/main/java/co/aikar/commands/InvalidCommandArgument.java b/core/src/main/java/co/aikar/commands/InvalidCommandArgument.java index e6cf2060..46f521ee 100644 --- a/core/src/main/java/co/aikar/commands/InvalidCommandArgument.java +++ b/core/src/main/java/co/aikar/commands/InvalidCommandArgument.java @@ -53,19 +53,10 @@ public class InvalidCommandArgument extends Exception { this.replacements = replacements; } - /** - * Please move to a MessageKey - * @deprecated - */ - @Deprecated public InvalidCommandArgument(String message) { this(message, true); } - /** - * Please move to a MessageKey - * @deprecated - */ - @Deprecated + public InvalidCommandArgument(String message, boolean showSyntax) { super(message, null, false, false); this.showSyntax = showSyntax; diff --git a/core/src/main/java/co/aikar/commands/Locales.java b/core/src/main/java/co/aikar/commands/Locales.java index e7e64687..d0651e33 100644 --- a/core/src/main/java/co/aikar/commands/Locales.java +++ b/core/src/main/java/co/aikar/commands/Locales.java @@ -34,6 +34,7 @@ import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; @SuppressWarnings("WeakerAccess") @@ -72,7 +73,7 @@ public class Locales { public static final Locale WELSH = new Locale("cy"); - private final CommandManager manager; + private final CommandManager manager; private final LocaleManager localeManager; private final SetMultimap loadedBundles = HashMultimap.create(); @@ -97,7 +98,9 @@ public class Locales { * Looks for all previously loaded bundles, and if any new Supported Languages have been added, load them. */ public void loadMissingBundles() { - for (Locale locale : manager.getSupportedLanguages()) { + //noinspection unchecked + Set supportedLanguages = manager.getSupportedLanguages(); + for (Locale locale : supportedLanguages) { for (String bundleName : Sets.newHashSet(loadedBundles.keys())) { addMessageBundle(bundleName, locale); } @@ -106,7 +109,9 @@ public class Locales { public void addMessageBundles(String... bundleNames) { for (String bundleName : bundleNames) { - for (Locale locale : manager.getSupportedLanguages()) { + //noinspection unchecked + Set supportedLanguages = manager.getSupportedLanguages(); + for (Locale locale : supportedLanguages) { addMessageBundle(bundleName, locale); } } diff --git a/core/src/main/java/co/aikar/commands/ParameterConditionContext.java b/core/src/main/java/co/aikar/commands/ParameterConditionContext.java deleted file mode 100644 index 7b754e29..00000000 --- a/core/src/main/java/co/aikar/commands/ParameterConditionContext.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -package co.aikar.commands; - -import co.aikar.commands.annotation.Conditions; - -import java.lang.annotation.Annotation; -import java.util.List; -import java.util.Map; - -public class ParameterConditionContext extends ConditionContext { - - private final CEC execContext; - - ParameterConditionContext(RegisteredCommand cmd, I issuer, CEC execContext, Conditions conditions) { - super(cmd, issuer, conditions); - - this.execContext = execContext; - } - - public boolean isLastArg() { - return execContext.isLastArg(); - } - - public int getNumParams() { - return execContext.getNumParams(); - } - - public boolean canOverridePlayerContext() { - return execContext.canOverridePlayerContext(); - } - - public Object getResolvedArg(String arg) { - return execContext.getResolvedArg(arg); - } - - public Object getResolvedArg(Class[] classes) { - return execContext.getResolvedArg(classes); - } - - public Object getResolvedArg(String key, Class[] classes) { - return execContext.getResolvedArg(key, classes); - } - - public boolean isOptional() { - return execContext.isOptional(); - } - - public Annotation getAnnotation(Class cls) { - return execContext.getAnnotation(cls); - } - - public boolean hasAnnotation(Class cls) { - return execContext.hasAnnotation(cls); - } - - public List getArgs() { - return execContext.getArgs(); - } - - public int getIndex() { - return execContext.getIndex(); - } - - public Map getPassedArgs() { - return execContext.getPassedArgs(); - } - - public String joinArgs() { - return execContext.joinArgs(); - } - - public String joinArgs(String sep) { - return execContext.joinArgs(sep); - } -} diff --git a/core/src/main/java/co/aikar/commands/RegisteredCommand.java b/core/src/main/java/co/aikar/commands/RegisteredCommand.java index cb8d5baf..a8ac0cf9 100644 --- a/core/src/main/java/co/aikar/commands/RegisteredCommand.java +++ b/core/src/main/java/co/aikar/commands/RegisteredCommand.java @@ -52,7 +52,7 @@ import java.util.Set; import java.util.stream.Collectors; @SuppressWarnings("WeakerAccess") -public class RegisteredCommand > { +public class RegisteredCommand > { final BaseCommand scope; final String command; final Method method; @@ -67,7 +67,7 @@ public class RegisteredCommand registeredSubcommands = new ArrayList<>(); - private final CommandManager manager; + private final CommandManager manager; RegisteredCommand(BaseCommand scope, String command, Method method, String prefSubCommand) { this.scope = scope; @@ -89,6 +89,7 @@ public class RegisteredCommand args) { + void invoke(CommandIssuer sender, List args, CommandOperationContext context) { if (!scope.canExecute(sender, this)) { return; } preCommand(); try { + this.manager.conditions.validateConditions(context); Map passedArgs = resolveContexts(sender, args); if (passedArgs == null) return; @@ -220,6 +222,8 @@ public class RegisteredCommand possible = Sets.newHashSet(); for (String s : split) { + //noinspection unchecked List check = this.manager.getCommandCompletions().getCompletionValues(this, sender, s, origArgs, opContext.isAsync()); if (!check.isEmpty()) { possible.addAll(check.stream().map(String::toLowerCase).collect(Collectors.toList())); @@ -248,7 +253,10 @@ public class RegisteredCommand { + if (value == null) { + return true; + } + if (c.hasConfig("min") && c.getConfigValue("min", 0) > value.getValue()) { + throw new ConditionFailedException("Min value must be " + c.getConfigValue("min", 0)); + } + if (c.hasConfig("max") && c.getConfigValue("max", 3) < value.getValue()) { + throw new ConditionFailedException("Max value must be " + c.getConfigValue("max", 3)); + } + return true; + }); + + // 6: Register your commands - This first command demonstrates adding an exception handler to that command commandManager.registerCommand(new SomeCommand().setExceptionHandler((command, registeredCommand, sender, args, t) -> { sender.sendMessage(MessageType.ERROR, MessageKeys.ERROR_GENERIC_LOGGED); return true; // mark as handeled, default message will not be send to sender })); - // 5: Register an additional command. This one happens to share the same CommandAlias as the previous command + // 7: Register an additional command. This one happens to share the same CommandAlias as the previous command // This means it simply registers additional sub commands under the same command, but organized into separate // Classes (Maybe different permission sets) commandManager.registerCommand(new SomeCommand_ExtraSubs()); - // 6: Register default exception handler for any command that doesn't supply its own + // 8: Register default exception handler for any command that doesn't supply its own commandManager.setDefaultExceptionHandler((command, registeredCommand, sender, args, t) -> { getLogger().warning("Error occured while executing command " + command.getName()); return false; // mark as unhandeled, sender will see default message diff --git a/sponge/src/main/java/co/aikar/commands/SpongeCommandCompletionContext.java b/sponge/src/main/java/co/aikar/commands/SpongeCommandCompletionContext.java index 5b75b474..b8e825f2 100644 --- a/sponge/src/main/java/co/aikar/commands/SpongeCommandCompletionContext.java +++ b/sponge/src/main/java/co/aikar/commands/SpongeCommandCompletionContext.java @@ -24,15 +24,20 @@ package co.aikar.commands; import org.spongepowered.api.command.CommandSource; +import org.spongepowered.api.entity.living.player.Player; @SuppressWarnings("WeakerAccess") -public class SpongeCommandCompletionContext extends CommandCompletionContext { +public class SpongeCommandCompletionContext extends CommandCompletionContext { - SpongeCommandCompletionContext(final RegisteredCommand command, final CommandIssuer issuer, final String input, final String config, final String[] args) { + SpongeCommandCompletionContext(final RegisteredCommand command, final SpongeCommandIssuer issuer, final String input, final String config, final String[] args) { super(command, issuer, input, config, args); } public CommandSource getSource() { return this.issuer.getIssuer(); } + + public Player getPlayer() { + return this.issuer.getPlayer(); + } } diff --git a/sponge/src/main/java/co/aikar/commands/SpongeCommandExecutionContext.java b/sponge/src/main/java/co/aikar/commands/SpongeCommandExecutionContext.java index 700e6996..9226df83 100644 --- a/sponge/src/main/java/co/aikar/commands/SpongeCommandExecutionContext.java +++ b/sponge/src/main/java/co/aikar/commands/SpongeCommandExecutionContext.java @@ -24,6 +24,7 @@ package co.aikar.commands; import org.spongepowered.api.command.CommandSource; +import org.spongepowered.api.entity.living.player.Player; import java.lang.reflect.Parameter; import java.util.List; @@ -39,4 +40,8 @@ public class SpongeCommandExecutionContext extends CommandExecutionContext T getIssuer() { - //noinspection unchecked - return (T) this.source; + public CommandSource getIssuer() { + return this.source; + } + + public Player getPlayer() { + return isPlayer() ? (Player) source : null; } @Override diff --git a/sponge/src/main/java/co/aikar/commands/SpongeCommandManager.java b/sponge/src/main/java/co/aikar/commands/SpongeCommandManager.java index 4376e809..ce51a36d 100644 --- a/sponge/src/main/java/co/aikar/commands/SpongeCommandManager.java +++ b/sponge/src/main/java/co/aikar/commands/SpongeCommandManager.java @@ -23,7 +23,6 @@ package co.aikar.commands; -import co.aikar.commands.annotation.Conditions; import co.aikar.commands.apachecommonslang.ApacheCommonsExceptionUtil; import co.aikar.timings.Timing; import co.aikar.timings.Timings; @@ -47,9 +46,7 @@ public class SpongeCommandManager extends CommandManager< TextColor, SpongeMessageFormatter, SpongeCommandExecutionContext, - SpongeCommandCompletionContext, - SpongeConditionContext, - SpongeParameterConditionContext + SpongeConditionContext > { protected final PluginContainer plugin; @@ -150,7 +147,7 @@ public class SpongeCommandManager extends CommandManager< @Override public CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args) { - return new SpongeCommandCompletionContext(command, sender, input, config, args); + return new SpongeCommandCompletionContext(command, (SpongeCommandIssuer) sender, input, config, args); } @Override @@ -192,15 +189,9 @@ public class SpongeCommandManager extends CommandManager< ); } - @Override - public SpongeConditionContext createConditionContext(CommandOperationContext context, Conditions conditions) { - return new SpongeConditionContext(context.getRegisteredCommand(), (SpongeCommandIssuer) context.getCommandIssuer(), conditions); - } - - @Override - public

SpongeParameterConditionContext createConditionContext(CommandOperationContext context, SpongeCommandExecutionContext execContext, Conditions conditions) { - return new SpongeParameterConditionContext

(context.getRegisteredCommand(), (SpongeCommandIssuer) context.getCommandIssuer(), execContext, conditions); + public SpongeConditionContext createConditionContext(CommandIssuer issuer, String config) { + return new SpongeConditionContext((SpongeCommandIssuer) issuer, config); } } diff --git a/sponge/src/main/java/co/aikar/commands/SpongeConditionContext.java b/sponge/src/main/java/co/aikar/commands/SpongeConditionContext.java index c06658bf..2257c663 100644 --- a/sponge/src/main/java/co/aikar/commands/SpongeConditionContext.java +++ b/sponge/src/main/java/co/aikar/commands/SpongeConditionContext.java @@ -1,9 +1,19 @@ package co.aikar.commands; -import co.aikar.commands.annotation.Conditions; +import org.spongepowered.api.command.CommandSource; +import org.spongepowered.api.entity.living.player.Player; public class SpongeConditionContext extends ConditionContext { - SpongeConditionContext(RegisteredCommand cmd, SpongeCommandIssuer issuer, Conditions condAnno) { - super(cmd, issuer, condAnno); + SpongeConditionContext(SpongeCommandIssuer issuer, String config) { + super(issuer, config); + } + + + public CommandSource getSource() { + return getIssuer().getIssuer(); + } + + public Player getPlayer() { + return getIssuer().getPlayer(); } } diff --git a/sponge/src/main/java/co/aikar/commands/SpongeParameterConditionContext.java b/sponge/src/main/java/co/aikar/commands/SpongeParameterConditionContext.java deleted file mode 100644 index 2dcac52e..00000000 --- a/sponge/src/main/java/co/aikar/commands/SpongeParameterConditionContext.java +++ /dev/null @@ -1,9 +0,0 @@ -package co.aikar.commands; - -import co.aikar.commands.annotation.Conditions; - -public class SpongeParameterConditionContext

extends ParameterConditionContext { - SpongeParameterConditionContext(RegisteredCommand cmd, SpongeCommandIssuer issuer, SpongeCommandExecutionContext execContext, Conditions conditions) { - super(cmd, issuer, execContext, conditions); - } -}