Add way to set @Flags context for entire command - Closes #29

Couldn't do it through annotations due to limitations on annotations,
but this achieves same goal.
This commit is contained in:
Aikar
2018-01-14 19:48:25 -05:00
parent c7211e0a2b
commit 1739bfc39c
3 changed files with 42 additions and 6 deletions
@@ -37,6 +37,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
@@ -64,6 +65,7 @@ public abstract class BaseCommand {
public static final String CATCHALL = "__catchall";
public static final String DEFAULT = "__default";
final SetMultimap<String, RegisteredCommand> subCommands = HashMultimap.create();
final Map<Class<?>, String> contextFlags = Maps.newHashMap();
private Method preCommandHandler;
@SuppressWarnings("WeakerAccess")
@@ -644,6 +646,14 @@ public abstract class BaseCommand {
return this.getSubcommand(DEFAULT);
}
public String setContextFlags(Class<?> cls, String flags) {
return this.contextFlags.put(cls, flags);
}
public String getContextFlags(Class<?> cls) {
return this.contextFlags.get(cls);
}
private static class CommandSearch { RegisteredCommand cmd; int argIndex; String checkSub;
CommandSearch(RegisteredCommand cmd, int argIndex, String checkSub) {
@@ -29,7 +29,6 @@ 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.ImmutableMap;
import com.google.common.collect.Maps;
import java.lang.annotation.Annotation;
@@ -46,24 +45,45 @@ public class CommandExecutionContext <CEC extends CommandExecutionContext, I ext
private final int index;
private final Map<String, Object> passedArgs;
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) {
this.cmd = cmd;
this.manager = cmd.scope.manager;
this.param = param;
this.issuer = sender;
this.args = args;
this.index = index;
this.passedArgs = passedArgs;
this.flags = Maps.newHashMap();
Flags flags = param.getAnnotation(Flags.class);
if (flags != null) {
this.flags = Maps.newHashMap();
for (String s : ACFPatterns.COMMA.split(cmd.scope.manager.getCommandReplacements().replace(flags.value()))) {
parseFlags(flags.value());
}
inheritContextFlagsFlags(cmd.scope);
}
private void inheritContextFlagsFlags(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) {
inheritContextFlagsFlags(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);
this.flags.put(v[0], v.length > 1 ? v[1] : null);
if (!this.flags.containsKey(v[0])) {
this.flags.put(v[0], v.length > 1 ? v[1] : null);
}
}
} else {
this.flags = ImmutableMap.of();
}
}
@@ -40,6 +40,12 @@ import org.bukkit.entity.Player;
@CommandAlias("acf|somecommand|sc|somcom")
public class SomeCommand extends BaseCommand {
{
// This is the same thing as adding @Flags("foo=bar") to ALL parameters in this command that
// has a SomeObject parameter
setContextFlags(SomeObject.class, "foo=bar");
}
// %testcmd was defined in ACFExample plugin and defined as "test4|foobar|barbaz"
// This means, /test4, /foobar and /barbaz all are aliased here.
// functionally equivalent to @CommandAlias("test4|foobar|barbaz") but could be dynamic (Read from config)