mirror of
https://github.com/aikar/commands.git
synced 2026-05-31 06:11:55 +00:00
Refactor how parameter annotations are parsed to prep for processors
this also will improve performance, as we will only do flag parsing and replacements once on register instead of every execution for some things.
This commit is contained in:
@@ -31,7 +31,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BukkitCommandExecutionContext extends CommandExecutionContext<BukkitCommandExecutionContext, BukkitCommandIssuer> {
|
||||
BukkitCommandExecutionContext(RegisteredCommand cmd, Parameter param, BukkitCommandIssuer sender, List<String> args,
|
||||
BukkitCommandExecutionContext(RegisteredCommand cmd, CommandParameter param, BukkitCommandIssuer sender, List<String> args,
|
||||
int index, Map<String, Object> passedArgs) {
|
||||
super(cmd, param, sender, args, index, passedArgs);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -317,7 +316,7 @@ public class BukkitCommandManager extends CommandManager<
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitCommandExecutionContext createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
public BukkitCommandExecutionContext createCommandContext(RegisteredCommand command, CommandParameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
return new BukkitCommandExecutionContext(command, parameter, (BukkitCommandIssuer) sender, args, i, passedArgs);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.Map;
|
||||
|
||||
public class BungeeCommandExecutionContext extends CommandExecutionContext<BungeeCommandExecutionContext, BungeeCommandIssuer> {
|
||||
|
||||
BungeeCommandExecutionContext(RegisteredCommand cmd, Parameter param, BungeeCommandIssuer sender, List<String> args, int index, Map<String, Object> passedArgs) {
|
||||
BungeeCommandExecutionContext(RegisteredCommand cmd, CommandParameter param, BungeeCommandIssuer sender, List<String> args, int index, Map<String, Object> passedArgs) {
|
||||
super(cmd, param, sender, args, index, passedArgs);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -178,7 +177,7 @@ public class BungeeCommandManager extends CommandManager<
|
||||
}
|
||||
|
||||
@Override
|
||||
public BungeeCommandExecutionContext createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
public BungeeCommandExecutionContext createCommandContext(RegisteredCommand command, CommandParameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
return new BungeeCommandExecutionContext(command, parameter, (BungeeCommandIssuer) sender, args, i, passedArgs);
|
||||
}
|
||||
|
||||
|
||||
@@ -82,19 +82,19 @@ public class CommandCompletionContext <I extends CommandIssuer> {
|
||||
if (paramIdx >= command.parameters.length) {
|
||||
throw new IllegalArgumentException("Param index is higher than number of parameters");
|
||||
}
|
||||
Parameter param = command.parameters[paramIdx];
|
||||
CommandParameter param = command.parameters[paramIdx];
|
||||
Class<?> paramType = param.getType();
|
||||
if (!clazz.isAssignableFrom(paramType)) {
|
||||
throw new IllegalArgumentException(param.getName() +":" + paramType.getName() + " can not satisfy " + clazz.getName());
|
||||
}
|
||||
name = param.getName();
|
||||
} else {
|
||||
Parameter[] parameters = command.parameters;
|
||||
CommandParameter[] parameters = command.parameters;
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
Parameter param = parameters[i];
|
||||
if (clazz.isAssignableFrom(param.getType())) {
|
||||
final CommandParameter parameter = parameters[i];
|
||||
if (clazz.isAssignableFrom(parameter.getType())) {
|
||||
paramIdx = i;
|
||||
name = param.getName();
|
||||
name = parameter.getName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,13 +23,7 @@
|
||||
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.Default;
|
||||
import co.aikar.commands.annotation.Flags;
|
||||
import co.aikar.commands.annotation.Optional;
|
||||
import co.aikar.commands.contexts.ContextResolver;
|
||||
import co.aikar.commands.contexts.IssuerAwareContextResolver;
|
||||
import co.aikar.commands.contexts.IssuerOnlyContextResolver;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Parameter;
|
||||
@@ -39,7 +33,7 @@ import java.util.Map;
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class CommandExecutionContext <CEC extends CommandExecutionContext, I extends CommandIssuer> {
|
||||
private final RegisteredCommand cmd;
|
||||
private final Parameter param;
|
||||
private final CommandParameter param;
|
||||
protected final I issuer;
|
||||
private final List<String> args;
|
||||
private final int index;
|
||||
@@ -47,8 +41,8 @@ public class CommandExecutionContext <CEC extends CommandExecutionContext, I ext
|
||||
private final Map<String, String> flags;
|
||||
private final CommandManager manager;
|
||||
|
||||
CommandExecutionContext(RegisteredCommand cmd, Parameter param, I sender, List<String> args,
|
||||
int index, Map<String, Object> passedArgs) {
|
||||
CommandExecutionContext(RegisteredCommand cmd, CommandParameter param, I sender, List<String> args,
|
||||
int index, Map<String, Object> passedArgs) {
|
||||
this.cmd = cmd;
|
||||
this.manager = cmd.scope.manager;
|
||||
this.param = param;
|
||||
@@ -56,35 +50,8 @@ public class CommandExecutionContext <CEC extends CommandExecutionContext, I ext
|
||||
this.args = args;
|
||||
this.index = index;
|
||||
this.passedArgs = passedArgs;
|
||||
this.flags = Maps.newHashMap();
|
||||
Flags flags = param.getAnnotation(Flags.class);
|
||||
if (flags != null) {
|
||||
parseFlags(flags.value());
|
||||
}
|
||||
inheritContextFlags(cmd.scope);
|
||||
}
|
||||
this.flags = param.getFlags();
|
||||
|
||||
private void inheritContextFlags(BaseCommand scope) {
|
||||
if (!scope.contextFlags.isEmpty()) {
|
||||
Class<?> pCls = param.getType();
|
||||
do {
|
||||
parseFlags(scope.contextFlags.get(pCls));
|
||||
} while ((pCls = pCls.getSuperclass()) != null);
|
||||
}
|
||||
if (scope.parentCommand != null) {
|
||||
inheritContextFlags(scope.parentCommand);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseFlags(String flags) {
|
||||
if (flags != null) {
|
||||
for (String s : ACFPatterns.COMMA.split(manager.getCommandReplacements().replace(flags))) {
|
||||
String[] v = ACFPatterns.EQUALS.split(s, 2);
|
||||
if (!this.flags.containsKey(v[0])) {
|
||||
this.flags.put(v[0], v.length > 1 ? v[1] : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String popFirstArg() {
|
||||
@@ -112,19 +79,7 @@ public class CommandExecutionContext <CEC extends CommandExecutionContext, I ext
|
||||
}
|
||||
|
||||
public boolean canOverridePlayerContext() {
|
||||
int numRequired = getNumParams();
|
||||
for (int i = 0; i < cmd.resolvers.length; i++) {
|
||||
Parameter parameter = cmd.parameters[i];
|
||||
//noinspection unchecked
|
||||
ContextResolver<?, ?> resolver = cmd.resolvers[i];
|
||||
if (parameter.getAnnotation(Optional.class) != null || parameter.getAnnotation(Default.class) != null) {
|
||||
numRequired--;
|
||||
} else if (resolver instanceof IssuerAwareContextResolver || resolver instanceof IssuerOnlyContextResolver) {
|
||||
numRequired--;
|
||||
}
|
||||
}
|
||||
|
||||
return numRequired >= args.size();
|
||||
return cmd.requiredResolvers >= args.size();
|
||||
}
|
||||
|
||||
public Object getResolvedArg(String arg) {
|
||||
@@ -156,7 +111,7 @@ public class CommandExecutionContext <CEC extends CommandExecutionContext, I ext
|
||||
}
|
||||
|
||||
public boolean isOptional() {
|
||||
return param.getAnnotation(Optional.class) != null;
|
||||
return param.isOptional();
|
||||
}
|
||||
public boolean hasFlag(String flag) {
|
||||
return flags.containsKey(flag);
|
||||
@@ -171,11 +126,11 @@ public class CommandExecutionContext <CEC extends CommandExecutionContext, I ext
|
||||
}
|
||||
|
||||
public <T extends Annotation> T getAnnotation(Class<T> cls) {
|
||||
return param.getAnnotation(cls);
|
||||
return param.getParameter().getAnnotation(cls);
|
||||
}
|
||||
|
||||
public <T extends Annotation> boolean hasAnnotation(Class<T> cls) {
|
||||
return param.getAnnotation(cls) != null;
|
||||
return param.getParameter().isAnnotationPresent(cls);
|
||||
}
|
||||
|
||||
public RegisteredCommand getCmd() {
|
||||
@@ -183,7 +138,7 @@ public class CommandExecutionContext <CEC extends CommandExecutionContext, I ext
|
||||
}
|
||||
|
||||
public Parameter getParam() {
|
||||
return this.param;
|
||||
return this.param.getParameter();
|
||||
}
|
||||
|
||||
public I getIssuer() {
|
||||
|
||||
@@ -35,7 +35,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
@@ -222,7 +221,7 @@ public abstract class CommandManager <
|
||||
return new ConditionContext(issuer, config);
|
||||
}
|
||||
|
||||
public abstract CommandExecutionContext createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs);
|
||||
public abstract CommandExecutionContext createCommandContext(RegisteredCommand command, CommandParameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs);
|
||||
|
||||
public abstract CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args);
|
||||
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* 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
|
||||
* "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.Default;
|
||||
import co.aikar.commands.annotation.Description;
|
||||
import co.aikar.commands.annotation.Flags;
|
||||
import co.aikar.commands.annotation.Optional;
|
||||
import co.aikar.commands.annotation.Values;
|
||||
import co.aikar.commands.contexts.ContextResolver;
|
||||
import co.aikar.commands.contexts.IssuerAwareContextResolver;
|
||||
import co.aikar.commands.contexts.IssuerOnlyContextResolver;
|
||||
import co.aikar.commands.contexts.OptionalContextResolver;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Map;
|
||||
|
||||
public class CommandParameter <CEC extends CommandExecutionContext<CEC, ? extends CommandIssuer>> {
|
||||
private final Parameter parameter;
|
||||
private final Class<?> type;
|
||||
private final String name;
|
||||
private final CommandManager manager;
|
||||
private final int paramIndex;
|
||||
private ContextResolver<?, CEC> resolver;
|
||||
private boolean optional;
|
||||
private String description;
|
||||
private String defaultValue;
|
||||
private boolean requiresInput;
|
||||
private boolean commandIssuer;
|
||||
private String[] values;
|
||||
private Map<String, String> flags;
|
||||
private boolean canConsumeInput;
|
||||
private boolean optionalResolver;
|
||||
|
||||
public CommandParameter(RegisteredCommand<CEC> command, Parameter param, int paramIndex) {
|
||||
this.parameter = param;
|
||||
this.type = param.getType();
|
||||
this.name = param.getName(); // do we care for an annotation to supply name?
|
||||
//noinspection unchecked
|
||||
this.manager = command.manager;
|
||||
this.paramIndex = paramIndex;
|
||||
CommandReplacements replacements = manager.getCommandReplacements();
|
||||
|
||||
Default defaultAnno = param.getAnnotation(Default.class);
|
||||
Description descAnno = param.getAnnotation(Description.class);
|
||||
|
||||
//noinspection unchecked
|
||||
this.resolver = manager.getCommandContexts().getResolver(type);
|
||||
if (this.resolver == null) {
|
||||
ACFUtil.sneaky(new InvalidCommandContextException(
|
||||
"Parameter " + type.getSimpleName() + " of " + command + " has no applicable context resolver"
|
||||
));
|
||||
}
|
||||
|
||||
this.description = descAnno != null ? descAnno.value() : null;
|
||||
String defaultValue = defaultAnno != null ? replacements.replace(defaultAnno.value()) : null;
|
||||
this.defaultValue = defaultValue != null && (type == String.class || !defaultValue.isEmpty()) ? defaultValue : null;
|
||||
|
||||
|
||||
this.optional = param.isAnnotationPresent(Optional.class) || this.defaultValue != null;
|
||||
this.optionalResolver = isOptionalResolver(resolver);
|
||||
this.requiresInput = !this.optional && !this.optionalResolver;
|
||||
//noinspection unchecked
|
||||
this.commandIssuer = manager.isCommandIssuer(type);
|
||||
this.canConsumeInput = !(resolver instanceof IssuerOnlyContextResolver);
|
||||
|
||||
final Values values = param.getAnnotation(Values.class);
|
||||
if (values != null) {
|
||||
this.values = ACFPatterns.PIPE.split(manager.getCommandReplacements().replace(values.value()));
|
||||
} else {
|
||||
this.values = null;
|
||||
}
|
||||
this.flags = Maps.newHashMap();
|
||||
Flags flags = param.getAnnotation(Flags.class);
|
||||
if (flags != null) {
|
||||
parseFlags(flags.value());
|
||||
}
|
||||
inheritContextFlags(command.scope);
|
||||
}
|
||||
|
||||
private void inheritContextFlags(BaseCommand scope) {
|
||||
if (!scope.contextFlags.isEmpty()) {
|
||||
Class<?> pCls = this.type;
|
||||
do {
|
||||
parseFlags(scope.contextFlags.get(pCls));
|
||||
} while ((pCls = pCls.getSuperclass()) != null);
|
||||
}
|
||||
if (scope.parentCommand != null) {
|
||||
inheritContextFlags(scope.parentCommand);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseFlags(String flags) {
|
||||
if (flags != null) {
|
||||
for (String s : ACFPatterns.COMMA.split(manager.getCommandReplacements().replace(flags))) {
|
||||
String[] v = ACFPatterns.EQUALS.split(s, 2);
|
||||
if (!this.flags.containsKey(v[0])) {
|
||||
this.flags.put(v[0], v.length > 1 ? v[1] : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOptionalResolver(ContextResolver<?, CEC> resolver) {
|
||||
return resolver instanceof IssuerAwareContextResolver
|
||||
|| resolver instanceof IssuerOnlyContextResolver
|
||||
|| resolver instanceof OptionalContextResolver;
|
||||
}
|
||||
|
||||
|
||||
public Parameter getParameter() {
|
||||
return parameter;
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public CommandManager getManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
public int getParamIndex() {
|
||||
return paramIndex;
|
||||
}
|
||||
|
||||
public ContextResolver<?, CEC> getResolver() {
|
||||
return resolver;
|
||||
}
|
||||
|
||||
public void setResolver(ContextResolver<?, CEC> resolver) {
|
||||
this.resolver = resolver;
|
||||
}
|
||||
|
||||
public boolean isOptional() {
|
||||
return optional;
|
||||
}
|
||||
|
||||
public void setOptional(boolean optional) {
|
||||
this.optional = optional;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public void setDefaultValue(String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public boolean isCommandIssuer() {
|
||||
return commandIssuer;
|
||||
}
|
||||
|
||||
public void setCommandIssuer(boolean commandIssuer) {
|
||||
this.commandIssuer = commandIssuer;
|
||||
}
|
||||
|
||||
public String[] getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public void setValues(String[] values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public Map<String, String> getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public void setFlags(Map<String, String> flags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
public boolean canConsumeInput() {
|
||||
return canConsumeInput;
|
||||
}
|
||||
|
||||
public void setCanConsumeInput(boolean canConsumeInput) {
|
||||
this.canConsumeInput = canConsumeInput;
|
||||
}
|
||||
|
||||
public void setOptionalResolver(boolean optionalResolver) {
|
||||
this.optionalResolver = optionalResolver;
|
||||
}
|
||||
|
||||
public boolean isOptionalResolver() {
|
||||
return optionalResolver;
|
||||
}
|
||||
|
||||
public boolean requiresInput() {
|
||||
return requiresInput;
|
||||
}
|
||||
|
||||
public void setRequiresInput(boolean requiresInput) {
|
||||
this.requiresInput = requiresInput;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,15 +26,9 @@ package co.aikar.commands;
|
||||
import co.aikar.commands.annotation.CommandAlias;
|
||||
import co.aikar.commands.annotation.CommandCompletion;
|
||||
import co.aikar.commands.annotation.CommandPermission;
|
||||
import co.aikar.commands.annotation.Default;
|
||||
import co.aikar.commands.annotation.Description;
|
||||
import co.aikar.commands.annotation.Optional;
|
||||
import co.aikar.commands.annotation.Syntax;
|
||||
import co.aikar.commands.annotation.Values;
|
||||
import co.aikar.commands.contexts.ContextResolver;
|
||||
import co.aikar.commands.contexts.IssuerAwareContextResolver;
|
||||
import co.aikar.commands.contexts.IssuerOnlyContextResolver;
|
||||
import co.aikar.commands.contexts.OptionalContextResolver;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
@@ -57,8 +51,7 @@ public class RegisteredCommand <CEC extends CommandExecutionContext<CEC, ? exten
|
||||
final String command;
|
||||
final Method method;
|
||||
final String prefSubCommand;
|
||||
final Parameter[] parameters;
|
||||
final ContextResolver<?, CEC>[] resolvers;
|
||||
final CommandParameter<CEC>[] parameters;
|
||||
final String syntaxText;
|
||||
final String helpText;
|
||||
|
||||
@@ -67,7 +60,7 @@ public class RegisteredCommand <CEC extends CommandExecutionContext<CEC, ? exten
|
||||
final int requiredResolvers;
|
||||
final int optionalResolvers;
|
||||
final List<String> registeredSubcommands = new ArrayList<>();
|
||||
private final CommandManager manager;
|
||||
final CommandManager manager;
|
||||
|
||||
RegisteredCommand(BaseCommand scope, String command, Method method, String prefSubCommand) {
|
||||
this.scope = scope;
|
||||
@@ -82,46 +75,35 @@ public class RegisteredCommand <CEC extends CommandExecutionContext<CEC, ? exten
|
||||
this.permission = permissionAnno != null ? scope.manager.getCommandReplacements().replace(permissionAnno.value()) : null;
|
||||
CommandCompletion completionAnno = method.getAnnotation(CommandCompletion.class);
|
||||
this.complete = completionAnno != null ? scope.manager.getCommandReplacements().replace(completionAnno.value()) : null;
|
||||
this.parameters = method.getParameters();
|
||||
Parameter[] parameters = method.getParameters();
|
||||
//noinspection unchecked
|
||||
this.parameters = new CommandParameter[parameters.length];
|
||||
|
||||
Description descriptionAnno = method.getAnnotation(Description.class);
|
||||
this.helpText = descriptionAnno != null ? descriptionAnno.value() : "";
|
||||
//noinspection unchecked
|
||||
this.resolvers = new ContextResolver[this.parameters.length];
|
||||
final Syntax syntaxStr = method.getAnnotation(Syntax.class);
|
||||
//noinspection unchecked
|
||||
final CommandContexts commandContexts = this.manager.getCommandContexts();
|
||||
|
||||
|
||||
int requiredResolvers = 0;
|
||||
int optionalResolvers = 0;
|
||||
StringBuilder syntaxB = new StringBuilder(64);
|
||||
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
final Parameter parameter = parameters[i];
|
||||
final Class<?> type = parameter.getType();
|
||||
CommandParameter<CEC> parameter = this.parameters[i] = new CommandParameter<>(this, parameters[i], i);
|
||||
|
||||
//noinspection unchecked
|
||||
final ContextResolver<?, CEC> resolver = commandContexts.getResolver(type);
|
||||
if (resolver != null) {
|
||||
resolvers[i] = resolver;
|
||||
|
||||
if (!scope.manager.isCommandIssuer(type)) {
|
||||
String name = parameter.getName();
|
||||
if (isOptionalResolver(resolver, parameter)) {
|
||||
optionalResolvers++;
|
||||
if (!(resolver instanceof IssuerOnlyContextResolver)) {
|
||||
syntaxB.append('[').append(name).append("] ");
|
||||
}
|
||||
} else {
|
||||
requiredResolvers++;
|
||||
syntaxB.append('<').append(name).append("> ");
|
||||
if (!parameter.isCommandIssuer()) {
|
||||
String name = parameter.getName();
|
||||
if (!parameter.requiresInput()) {
|
||||
optionalResolvers++;
|
||||
if (parameter.canConsumeInput()) {
|
||||
syntaxB.append('[').append(name).append("] ");
|
||||
}
|
||||
} else {
|
||||
requiredResolvers++;
|
||||
syntaxB.append('<').append(name).append("> ");
|
||||
}
|
||||
} else {
|
||||
ACFUtil.sneaky(new InvalidCommandContextException(
|
||||
"Parameter " + type.getSimpleName() + " of " + this.command + " has no applicable context resolver"
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
String syntaxText = syntaxB.toString();
|
||||
this.syntaxText = this.manager.getCommandReplacements().replace(syntaxStr != null ?
|
||||
@@ -130,16 +112,6 @@ public class RegisteredCommand <CEC extends CommandExecutionContext<CEC, ? exten
|
||||
this.optionalResolvers = optionalResolvers;
|
||||
}
|
||||
|
||||
private boolean isOptionalResolver(ContextResolver<?, CEC> resolver, Parameter parameter) {
|
||||
return isOptionalResolver(resolver)
|
||||
|| parameter.getAnnotation(Optional.class) != null
|
||||
|| parameter.getAnnotation(Default.class) != null;
|
||||
}
|
||||
|
||||
private boolean isOptionalResolver(ContextResolver<?, CEC> resolver) {
|
||||
return resolver instanceof IssuerAwareContextResolver || resolver instanceof IssuerOnlyContextResolver
|
||||
|| resolver instanceof OptionalContextResolver;
|
||||
}
|
||||
|
||||
void invoke(CommandIssuer sender, List<String> args, CommandOperationContext context) {
|
||||
if (!scope.canExecute(sender, this)) {
|
||||
@@ -208,24 +180,22 @@ public class RegisteredCommand <CEC extends CommandExecutionContext<CEC, ? exten
|
||||
for (int i = 0; i < parameters.length && i < argLimit; i++) {
|
||||
boolean isLast = i == parameters.length - 1;
|
||||
boolean allowOptional = remainingRequired == 0;
|
||||
final Parameter parameter = parameters[i];
|
||||
final CommandParameter<CEC> parameter = parameters[i];
|
||||
final String parameterName = parameter.getName();
|
||||
final Class<?> type = parameter.getType();
|
||||
//noinspection unchecked
|
||||
final ContextResolver<?, CEC> resolver = resolvers[i];
|
||||
final ContextResolver<?, CEC> resolver = parameter.getResolver();
|
||||
//noinspection unchecked
|
||||
CEC context = (CEC) this.manager.createCommandContext(this, parameter, sender, args, i, passedArgs);
|
||||
boolean isOptionalResolver = isOptionalResolver(resolver, parameter);
|
||||
if (!isOptionalResolver) {
|
||||
boolean requiresInput = parameter.requiresInput();
|
||||
if (requiresInput && remainingRequired > 0) {
|
||||
remainingRequired--;
|
||||
}
|
||||
if (args.isEmpty() && !(isLast && type == String[].class)) {
|
||||
Default def = parameter.getAnnotation(Default.class);
|
||||
Optional opt = parameter.getAnnotation(Optional.class);
|
||||
if (allowOptional && def != null) {
|
||||
args.add(scope.manager.getCommandReplacements().replace(def.value()));
|
||||
} else if (allowOptional && opt != null) {
|
||||
Object value = isOptionalResolver(resolver) ? resolver.getContext(context) : null;
|
||||
if (allowOptional && parameter.getDefaultValue() != null) {
|
||||
args.add(parameter.getDefaultValue());
|
||||
} else if (allowOptional && parameter.isOptional()) {
|
||||
Object value = parameter.isOptionalResolver() ? resolver.getContext(context) : null;
|
||||
if (value == null && parameter.getClass().isPrimitive()) {
|
||||
throw new IllegalStateException("Parameter " + parameter.getName() + " is primitive and does not support Optional.");
|
||||
}
|
||||
@@ -234,20 +204,19 @@ public class RegisteredCommand <CEC extends CommandExecutionContext<CEC, ? exten
|
||||
passedArgs.put(parameterName, value);
|
||||
//noinspection UnnecessaryContinue
|
||||
continue;
|
||||
} else if (!isOptionalResolver) {
|
||||
} else if (requiresInput) {
|
||||
scope.showSyntax(sender, this);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
final Values values = parameter.getAnnotation(Values.class);
|
||||
if (values != null) {
|
||||
if (parameter.getValues() != null) {
|
||||
String arg = !args.isEmpty() ? args.get(0) : "";
|
||||
|
||||
final String[] split = ACFPatterns.PIPE.split(scope.manager.getCommandReplacements().replace(values.value()));
|
||||
Set<String> possible = Sets.newHashSet();
|
||||
for (String s : split) {
|
||||
CommandCompletions commandCompletions = this.manager.getCommandCompletions();
|
||||
for (String s : parameter.getValues()) {
|
||||
//noinspection unchecked
|
||||
List<String> check = this.manager.getCommandCompletions().getCompletionValues(this, sender, s, origArgs, opContext.isAsync());
|
||||
List<String> check = commandCompletions.getCompletionValues(this, sender, s, origArgs, opContext.isAsync());
|
||||
if (!check.isEmpty()) {
|
||||
possible.addAll(check.stream().map(String::toLowerCase).collect(Collectors.toList()));
|
||||
} else {
|
||||
|
||||
@@ -5,7 +5,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JDACommandExecutionContext extends CommandExecutionContext<JDACommandExecutionContext,JDACommandEvent> {
|
||||
JDACommandExecutionContext(RegisteredCommand cmd, Parameter param, JDACommandEvent sender, List<String> args, int index, Map<String, Object> passedArgs) {
|
||||
JDACommandExecutionContext(RegisteredCommand cmd, CommandParameter param, JDACommandEvent sender, List<String> args, int index, Map<String, Object> passedArgs) {
|
||||
super(cmd, param, sender, args, index, passedArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import net.dv8tion.jda.core.entities.Message;
|
||||
import net.dv8tion.jda.core.events.message.MessageReceivedEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -195,7 +194,7 @@ public class JDACommandManager extends CommandManager<
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandExecutionContext createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
public CommandExecutionContext createCommandContext(RegisteredCommand command, CommandParameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
return new JDACommandExecutionContext(command, parameter, (JDACommandEvent) sender, args, i, passedArgs);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.Map;
|
||||
|
||||
public class SpongeCommandExecutionContext extends CommandExecutionContext<SpongeCommandExecutionContext, SpongeCommandIssuer> {
|
||||
|
||||
SpongeCommandExecutionContext(RegisteredCommand cmd, Parameter param, SpongeCommandIssuer sender, List<String> args,
|
||||
SpongeCommandExecutionContext(RegisteredCommand cmd, CommandParameter param, SpongeCommandIssuer sender, List<String> args,
|
||||
int index, Map<String, Object> passedArgs) {
|
||||
super(cmd, param, sender, args, index, passedArgs);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import org.spongepowered.api.text.format.TextColor;
|
||||
import org.spongepowered.api.text.format.TextColors;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -146,7 +145,7 @@ public class SpongeCommandManager extends CommandManager<
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpongeCommandExecutionContext createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
public SpongeCommandExecutionContext createCommandContext(RegisteredCommand command, CommandParameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
|
||||
return new SpongeCommandExecutionContext(command, parameter, (SpongeCommandIssuer) sender, args, i, passedArgs);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user