mirror of
https://github.com/aikar/commands.git
synced 2026-05-31 06:11:55 +00:00
Add support for CommandPermission annotation as parameter for permiss… (#197)
…ions by Optional annotation In the past we could not handle a permission in relation to the presence of an optional argument, it forced us to manage it in the body of the command, and could be repetitive and boring, note that it also works with the annotation Default
This commit is contained in:
committed by
Daniel Ennis
parent
d7477cb732
commit
d2754b99c9
@@ -27,9 +27,10 @@ import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressWarnings({"WeakerAccess"})
|
||||
public class CommandExecutionContext <CEC extends CommandExecutionContext, I extends CommandIssuer> {
|
||||
public class CommandExecutionContext<CEC extends CommandExecutionContext, I extends CommandIssuer> {
|
||||
private final RegisteredCommand cmd;
|
||||
private final CommandParameter param;
|
||||
protected final I issuer;
|
||||
@@ -69,7 +70,7 @@ public class CommandExecutionContext <CEC extends CommandExecutionContext, I ext
|
||||
}
|
||||
|
||||
public boolean isLastArg() {
|
||||
return cmd.parameters.length -1 == index;
|
||||
return cmd.parameters.length - 1 == index;
|
||||
}
|
||||
|
||||
public int getNumParams() {
|
||||
@@ -108,6 +109,10 @@ public class CommandExecutionContext <CEC extends CommandExecutionContext, I ext
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<String> getPermissions() {
|
||||
return param.getPermissions();
|
||||
}
|
||||
|
||||
public boolean isOptional() {
|
||||
return param.isOptional();
|
||||
}
|
||||
@@ -170,6 +175,7 @@ public class CommandExecutionContext <CEC extends CommandExecutionContext, I ext
|
||||
|
||||
/**
|
||||
* This method will not support annotation processors!! use getAnnotationValue or hasAnnotation
|
||||
*
|
||||
* @deprecated Use {@link #getAnnotationValue(Class)}
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -226,6 +232,7 @@ public class CommandExecutionContext <CEC extends CommandExecutionContext, I ext
|
||||
public String joinArgs() {
|
||||
return ACFUtil.join(args, " ");
|
||||
}
|
||||
|
||||
public String joinArgs(String sep) {
|
||||
return ACFUtil.join(args, sep);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
package co.aikar.commands;
|
||||
|
||||
import co.aikar.commands.annotation.CommandPermission;
|
||||
import co.aikar.commands.annotation.Conditions;
|
||||
import co.aikar.commands.annotation.Default;
|
||||
import co.aikar.commands.annotation.Description;
|
||||
@@ -37,10 +38,13 @@ import co.aikar.commands.contexts.IssuerOnlyContextResolver;
|
||||
import co.aikar.commands.contexts.OptionalContextResolver;
|
||||
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CommandParameter <CEC extends CommandExecutionContext<CEC, ? extends CommandIssuer>> {
|
||||
public class CommandParameter<CEC extends CommandExecutionContext<CEC, ? extends CommandIssuer>> {
|
||||
private final Parameter parameter;
|
||||
private final Class<?> type;
|
||||
private final String name;
|
||||
@@ -49,6 +53,8 @@ public class CommandParameter <CEC extends CommandExecutionContext<CEC, ? extend
|
||||
|
||||
private ContextResolver<?, CEC> resolver;
|
||||
private boolean optional;
|
||||
private Set<String> permissions = new HashSet<>();
|
||||
private String permission;
|
||||
private String description;
|
||||
private String defaultValue;
|
||||
private String syntax;
|
||||
@@ -82,6 +88,7 @@ public class CommandParameter <CEC extends CommandExecutionContext<CEC, ? extend
|
||||
}
|
||||
|
||||
this.optional = annotations.hasAnnotation(param, Optional.class) || this.defaultValue != null || (isLast && type == String[].class);
|
||||
this.permission = annotations.getAnnotationValue(param, CommandPermission.class, Annotations.REPLACEMENTS | Annotations.NO_EMPTY);
|
||||
this.optionalResolver = isOptionalResolver(resolver);
|
||||
this.requiresInput = !this.optional && !this.optionalResolver;
|
||||
//noinspection unchecked
|
||||
@@ -109,6 +116,7 @@ public class CommandParameter <CEC extends CommandExecutionContext<CEC, ? extend
|
||||
parseFlags(flags);
|
||||
}
|
||||
inheritContextFlags(command.scope);
|
||||
this.computePermissions();
|
||||
}
|
||||
|
||||
private void inheritContextFlags(BaseCommand scope) {
|
||||
@@ -134,10 +142,17 @@ public class CommandParameter <CEC extends CommandExecutionContext<CEC, ? extend
|
||||
}
|
||||
}
|
||||
|
||||
private void computePermissions() {
|
||||
this.permissions.clear();
|
||||
if (this.permission != null && !this.permission.isEmpty()) {
|
||||
this.permissions.addAll(Arrays.asList(ACFPatterns.COMMA.split(this.permission)));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOptionalResolver(ContextResolver<?, CEC> resolver) {
|
||||
return resolver instanceof IssuerAwareContextResolver
|
||||
|| resolver instanceof IssuerOnlyContextResolver
|
||||
|| resolver instanceof OptionalContextResolver;
|
||||
|| resolver instanceof IssuerOnlyContextResolver
|
||||
|| resolver instanceof OptionalContextResolver;
|
||||
}
|
||||
|
||||
|
||||
@@ -256,4 +271,8 @@ public class CommandParameter <CEC extends CommandExecutionContext<CEC, ? extend
|
||||
public void setConditions(String conditions) {
|
||||
this.conditions = conditions;
|
||||
}
|
||||
|
||||
public Set<String> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,11 +226,13 @@ public class RegisteredCommand<CEC extends CommandExecutionContext<CEC, ? extend
|
||||
if (requiresInput && remainingRequired > 0) {
|
||||
remainingRequired--;
|
||||
}
|
||||
|
||||
if (args.isEmpty() && !(isLast && type == String[].class)) {
|
||||
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.");
|
||||
}
|
||||
@@ -244,6 +246,7 @@ public class RegisteredCommand<CEC extends CommandExecutionContext<CEC, ? extend
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (parameter.getValues() != null) {
|
||||
String arg = !args.isEmpty() ? args.get(0) : "";
|
||||
|
||||
@@ -258,13 +261,27 @@ public class RegisteredCommand<CEC extends CommandExecutionContext<CEC, ? extend
|
||||
possible.add(s.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
if (!possible.contains(arg.toLowerCase())) {
|
||||
throw new InvalidCommandArgument(MessageKeys.PLEASE_SPECIFY_ONE_OF,
|
||||
"{valid}", ACFUtil.join(possible, ", "));
|
||||
}
|
||||
}
|
||||
Object paramValue = resolver.getContext(context);
|
||||
|
||||
Set<String> parameterPermissions = parameter.getPermissions();
|
||||
if (!parameter.isOptionalResolver() && parameterPermissions != null && !parameterPermissions.isEmpty()) {
|
||||
if (allowOptional && parameter.isOptional()) {
|
||||
for (String perm : parameterPermissions) {
|
||||
if (!perm.isEmpty() && !sender.hasPermission(perm)) {
|
||||
sender.sendMessage(MessageType.ERROR, MessageKeys.PERMISSION_DENIED);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Using CommandPermission annotation on parameter that is not optional is useless and you should not do it.");
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
this.manager.conditions.validateConditions(context, paramValue);
|
||||
passedArgs.put(parameterName, paramValue);
|
||||
|
||||
@@ -30,11 +30,11 @@ import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Sets the permission required to perform this command.
|
||||
*
|
||||
* <p>
|
||||
* Permission format will vary based on implementation platform
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
|
||||
public @interface CommandPermission {
|
||||
String value();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user