Almost done with modular work

This commit is contained in:
Aikar
2017-06-03 00:11:43 -04:00
parent 0bf2621a91
commit 7bf24e9c13
27 changed files with 429 additions and 208 deletions
@@ -26,10 +26,10 @@ package co.aikar.commands;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Default;
import co.aikar.commands.annotation.PreCommand;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.UnknownHandler;
import co.aikar.commands.apachecommonslang.ApacheCommonsLangUtil;
import co.aikar.timings.lib.MCTiming;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -59,6 +59,7 @@ public abstract class BaseCommand {
public static final String UNKNOWN = "__unknown";
public static final String DEFAULT = "__default";
final SetMultimap<String, RegisteredCommand> subCommands = HashMultimap.create();
Method preCommandHandler;
@SuppressWarnings("WeakerAccess")
private String execLabel;
@@ -73,6 +74,11 @@ public abstract class BaseCommand {
String usageMessage;
String permission;
public BaseCommand() {}
public BaseCommand(String cmd) {
this.commandName = cmd;
}
/**
* Gets the root command name that the user actually typed
* @return Name
@@ -98,7 +104,7 @@ public abstract class BaseCommand {
}
void onRegister(CommandManager manager) {
onRegister(manager, null);
onRegister(manager, this.commandName);
}
void onRegister(CommandManager manager, String cmd) {
this.manager = manager;
@@ -141,18 +147,21 @@ public abstract class BaseCommand {
ACFUtil.sneaky(new IllegalStateException("Multiple @Default commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName()));
}
}
if (sub != null) {
sublist = sub;
} else if (commandAliases != null) {
sublist = commandAliases.value();
}
if (sublist != null) {
registerSubcommand(method, sublist);
}
//CommandIssuer.class, String.class, String[].class
UnknownHandler unknown = method.getAnnotation(UnknownHandler.class);
//CommandIssuer.class, String.class, String[].class
PreCommand preCommand = method.getAnnotation(PreCommand.class);
if (unknown != null) {
if (!foundUnknown) {
registerSubcommand(method, UNKNOWN);
@@ -160,6 +169,14 @@ public abstract class BaseCommand {
} else {
ACFUtil.sneaky(new IllegalStateException("Multiple @UnknownHandler commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName()));
}
} else if (preCommand != null) {
if (this.preCommandHandler == null) {
this.preCommandHandler = method;
} else {
ACFUtil.sneaky(new IllegalStateException("Multiple @PreCommand commands, duplicate on " + method.getDeclaringClass().getName() + "#" + method.getName()));
}
} else if (sublist != null) {
registerSubcommand(method, sublist);
}
}
@@ -246,7 +263,7 @@ public abstract class BaseCommand {
final String[] aliasNames = cmdAlias != null ? ACFPatterns.PIPE.split(manager.getCommandReplacements().replace(cmdAlias.value().toLowerCase())) : null;
String cmdName = aliasNames != null ? aliasNames[0] : this.commandName + " ";
RegisteredCommand cmd = new RegisteredCommand(this, cmdName, method, prefSubCommand);
RegisteredCommand cmd = manager.createRegisteredCommand(this, cmdName, method, prefSubCommand);
for (String subcmd : cmdList) {
subCommands.put(subcmd, cmd);
@@ -305,7 +322,7 @@ public abstract class BaseCommand {
origArgs = args;
if (args.length == 0) {
if (preCommand(sender, commandLabel, args)) {
if (checkPrecommand(sender, args)) {
return true;
}
executeSubcommand(DEFAULT, sender);
@@ -316,7 +333,7 @@ public abstract class BaseCommand {
if (cmd != null) {
execSubcommand = cmd.getCheckSub();
final String[] execargs = Arrays.copyOfRange(args, cmd.argIndex, args.length);
if (preCommand(sender, commandLabel, execargs)) {
if (checkPrecommand(sender, execargs)) {
return true;
}
executeCommand(sender, execargs, cmd.cmd);
@@ -371,15 +388,13 @@ public abstract class BaseCommand {
private static void executeCommand(CommandIssuer sender, String[] args, RegisteredCommand cmd) {
if (cmd.hasPermission(sender)) {
List<String> sargs = Lists.newArrayList(args);
try (MCTiming timing = cmd.getTiming().startTiming()) {
cmd.invoke(sender, sargs);
}
cmd.invoke(sender, sargs);
} else {
sender.sendMessage("&cI'm sorry, but you do not have permission to perform this command.");
}
}
public boolean canExecute(CommandIssuer sender, RegisteredCommand cmd) {
public boolean canExecute(CommandIssuer sender, RegisteredCommand<?> cmd) {
return true;
}
@@ -416,12 +431,9 @@ public abstract class BaseCommand {
}
private List<String> completeCommand(CommandIssuer sender, RegisteredCommand cmd, String[] args, String commandLabel) {
if (args.length > cmd.requiredResolvers + cmd.optionalResolvers) {
if (args.length > cmd.requiredResolvers + cmd.optionalResolvers || args.length == 0 || cmd.complete == null) {
return ImmutableList.of();
}
if (args.length == 0 || cmd.complete == null) {
return args.length < 2 ? null : ImmutableList.of();
}
String[] completions = ACFPatterns.SPACE.split(cmd.complete);
@@ -436,9 +448,6 @@ public abstract class BaseCommand {
.collect(Collectors.toList());
}
public void help(CommandIssuer sender, String[] args) {
sender.sendMessage("&cUnknown Command, please type &f/help");
}
private boolean executeSubcommand(String subcommand, CommandIssuer sender, String... args) {
final Set<RegisteredCommand> defs = subCommands.get(subcommand);
@@ -455,24 +464,44 @@ public abstract class BaseCommand {
return false;
}
public boolean preCommand(CommandIssuer sender, String commandLabel, String[] args) {
private boolean checkPrecommand(CommandIssuer sender, String[] args) {
if (this.preCommandHandler != null) {
try {
if (this.preCommandHandler.getParameterCount() == 1) {
return (boolean) preCommandHandler.invoke(this, new Object[]{ sender.getIssuer() });
} else {
return (boolean) preCommandHandler.invoke(this, sender.getIssuer(), args);
}
} catch (IllegalAccessException | InvocationTargetException e) {
ACFLog.exception(e);
}
}
return false;
}
public void help(Object sender, String[] args) {
help(manager.getCommandIssuer(sender), args);
}
public void help(CommandIssuer sender, String[] args) {
sender.sendMessage("&cUnknown Command, please type &f/help");
}
public void doHelp(Object sender, String... args) {
doHelp(manager.getCommandIssuer(sender), args);
}
public void doHelp(CommandIssuer sender, String... args) {
help(sender, args);
}
public void showSyntax(CommandIssuer sender, RegisteredCommand cmd) {
public void showSyntax(CommandIssuer sender, RegisteredCommand<?> cmd) {
sender.sendMessage("&cUsage: /" + cmd.command + " " + cmd.syntaxText);
}
public boolean testPermission(Object sender) {
return testPermission(manager.getCommandIssuer(sender));
}
public boolean testPermission(CommandIssuer sender) {
if (permission != null && !permission.isEmpty() && !sender.hasPermission(permission)) {
// TODO: Msg
return false;
}
return true;
return permission == null || permission.isEmpty() || sender.hasPermission(permission);
}
public String getName() {
@@ -0,0 +1,127 @@
/*
* 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 com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.Map;
public class CommandCompletionContext {
private final RegisteredCommand command;
private final CommandIssuer issuer;
private final String input;
private final String config;
private final Map<String, String> configs = Maps.newHashMap();
private final List<String> args;
CommandCompletionContext(RegisteredCommand command, CommandIssuer issuer, String input, String config, String[] args) {
this.command = command;
this.issuer = issuer;
this.input = input;
if (config != null) {
String[] configs = ACFPatterns.COMMA.split(config);
for (String conf : configs) {
String[] confsplit = ACFPatterns.EQUALS.split(conf, 2);
this.configs.put(confsplit[0].toLowerCase(), confsplit.length > 1 ? confsplit[1] : null);
}
this.config = configs[0];
} else {
this.config = null;
}
this.args = Lists.newArrayList(args);
}
public Map<String, String> getConfigs() {
return configs;
}
public String getConfig(String key) {
return getConfig(key, null);
}
public String getConfig(String key, String def) {
return this.configs.getOrDefault(key.toLowerCase(), def);
}
public boolean hasConfig(String key) {
return this.configs.containsKey(key.toLowerCase());
}
public <T> T getContextValue(Class<? extends T> clazz) throws InvalidCommandArgument {
return getContextValue(clazz, null);
}
public <T> T getContextValue(Class<? extends T> clazz, Integer paramIdx) throws InvalidCommandArgument {
String name = null;
if (paramIdx != null) {
if (paramIdx >= command.parameters.length) {
throw new IllegalArgumentException("Param index is higher than number of parameters");
}
Parameter 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;
for (int i = 0; i < parameters.length; i++) {
Parameter param = parameters[i];
if (clazz.isAssignableFrom(param.getType())) {
paramIdx = i;
name = param.getName();
break;
}
}
if (paramIdx == null) {
throw new IllegalStateException("Can not find any parameter that can satisfy " + clazz.getName());
}
}
//noinspection unchecked
Map<String, Object> resolved = command.resolveContexts(issuer, args, args.size());
if (resolved == null || paramIdx > resolved.size()) {
ACFLog.error("resolved: " + resolved + " paramIdx: " + paramIdx + " - size: " + (resolved != null ? resolved.size() : null ));
ACFUtil.sneaky(new CommandCompletionTextLookupException());
}
//noinspection unchecked
return (T) resolved.get(name);
}
public CommandIssuer getIssuer() {
return issuer;
}
public String getInput() {
return input;
}
public String getConfig() {
return config;
}
}
@@ -0,0 +1,27 @@
/*
* 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;
class CommandCompletionTextLookupException extends Throwable {
}
@@ -23,13 +23,10 @@
package co.aikar.commands;
import co.aikar.commands.annotation.Split;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Parameter;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -39,7 +36,7 @@ import java.util.stream.IntStream;
@SuppressWarnings({"WeakerAccess", "UnusedReturnValue"})
public class CommandCompletions {
public class CommandCompletions <I, C extends CommandCompletionContext> {
private final CommandManager manager;
private Map<String, CommandCompletionHandler> completionMap = new HashMap<>();
@@ -64,7 +61,7 @@ public class CommandCompletions {
registerCompletion("timeunits", (sender, config, input, c) -> ImmutableList.of("minutes", "hours", "days", "weeks", "months", "years"));
}
public CommandCompletionHandler registerCompletion(String id, CommandCompletionHandler handler) {
public CommandCompletionHandler registerCompletion(String id, CommandCompletionHandler<I, C> handler) {
return this.completionMap.put("@" + id.toLowerCase(), handler);
}
@@ -121,105 +118,8 @@ public class CommandCompletions {
return allCompletions;
}
public interface CommandCompletionHandler {
Collection<String> getCompletions(CommandIssuer sender, String config, String input, CommandCompletionContext context) throws InvalidCommandArgument;
public interface CommandCompletionHandler <I, C extends CommandCompletionContext> {
Collection<String> getCompletions(I sender, String config, String input, C context) throws InvalidCommandArgument;
}
public class CommandCompletionContext {
private final RegisteredCommand command;
private final CommandIssuer sender;
private final String input;
private final String config;
private final Map<String, String> configs = Maps.newHashMap();
private final List<String> args;
CommandCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args) {
this.command = command;
this.sender = sender;
this.input = input;
if (config != null) {
String[] configs = ACFPatterns.COMMA.split(config);
for (String conf : configs) {
String[] confsplit = ACFPatterns.EQUALS.split(conf, 2);
this.configs.put(confsplit[0].toLowerCase(), confsplit.length > 1 ? confsplit[1] : null);
}
this.config = configs[0];
} else {
this.config = null;
}
this.args = Lists.newArrayList(args);
}
public Map<String, String> getConfigs() {
return configs;
}
public String getConfig(String key) {
return getConfig(key, null);
}
public String getConfig(String key, String def) {
return this.configs.getOrDefault(key.toLowerCase(), def);
}
public boolean hasConfig(String key) {
return this.configs.containsKey(key.toLowerCase());
}
public <T> T getContextValue(Class<? extends T> clazz) throws InvalidCommandArgument {
return getContextValue(clazz, null);
}
public <T> T getContextValue(Class<? extends T> clazz, Integer paramIdx) throws InvalidCommandArgument {
String name = null;
if (paramIdx != null) {
if (paramIdx >= command.parameters.length) {
throw new IllegalArgumentException("Param index is higher than number of parameters");
}
Parameter 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;
for (int i = 0; i < parameters.length; i++) {
Parameter param = parameters[i];
if (clazz.isAssignableFrom(param.getType())) {
paramIdx = i;
name = param.getName();
break;
}
}
if (paramIdx == null) {
throw new IllegalStateException("Can not find any parameter that can satisfy " + clazz.getName());
}
}
Map<String, Object> resolved = command.resolveContexts(sender, args, args.size());
if (resolved == null || paramIdx > resolved.size()) {
ACFLog.error("resolved: " + resolved + " paramIdx: " + paramIdx + " - size: " + (resolved != null ? resolved.size() : null ));
ACFUtil.sneaky(new CommandCompletionTextLookupException());
}
//noinspection unchecked
return (T) resolved.get(name);
}
public CommandIssuer getSender() {
return sender;
}
public String getInput() {
return input;
}
public String getConfig() {
return config;
}
}
private class CommandCompletionTextLookupException extends Throwable {
}
}
@@ -34,7 +34,7 @@ import java.util.List;
import java.util.Map;
@SuppressWarnings("WeakerAccess")
public class CommandContexts <R extends CommandExecutionContext> {
public class CommandContexts <R extends CommandExecutionContext<?>> {
protected final Map<Class<?>, ContextResolver<?, R>> contextMap = Maps.newHashMap();
private final CommandManager manager;
@@ -140,10 +140,10 @@ public class CommandContexts <R extends CommandExecutionContext> {
});
}
<T> void registerSenderAwareContext(Class<T> context, SenderAwareContextResolver<T, R> supplier) {
public <T> void registerSenderAwareContext(Class<T> context, SenderAwareContextResolver<T, R> supplier) {
contextMap.put(context, supplier);
}
<T> void registerContext(Class<T> context, ContextResolver<T, R> supplier) {
public <T> void registerContext(Class<T> context, ContextResolver<T, R> supplier) {
contextMap.put(context, supplier);
}
@@ -23,15 +23,14 @@
package co.aikar.commands;
import co.aikar.timings.lib.TimingManager;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SuppressWarnings("WeakerAccess")
public abstract class CommandManager {
abstract class CommandManager {
protected Map<String, RootCommand> rootCommands = new HashMap<>();
protected CommandReplacements replacements = new CommandReplacements(this);
@@ -40,13 +39,13 @@ public abstract class CommandManager {
* Gets the command contexts manager
* @return Command Contexts
*/
public abstract CommandContexts getCommandContexts();
public abstract CommandContexts<?> getCommandContexts();
/**
* Gets the command completions manager
* @return Command Completions
*/
public abstract CommandCompletions getCommandCompletions();
public abstract CommandCompletions<?, ?> getCommandCompletions();
/**
* Lets you add custom string replacements that can be applied to annotation values,
@@ -69,13 +68,18 @@ public abstract class CommandManager {
*/
public abstract void registerCommand(BaseCommand command);
public abstract boolean hasRegisteredCommands();
public abstract TimingManager getTimings();
public abstract boolean isCommandIssuer(Class<?> type);
public abstract CommandIssuer getCommandIssuer(Object issuer);
public abstract RootCommand createRootCommand(String cmd);
public synchronized RootCommand obtainRootCommand(String cmd) {
return rootCommands.computeIfAbsent(cmd.toLowerCase(), this::createRootCommand);
}
public abstract CommandExecutionContext<? extends CommandExecutionContext> createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs);
public abstract <R extends CommandExecutionContext> R createCommandContext(RegisteredCommand command, Parameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs);
public RegisteredCommand createRegisteredCommand(BaseCommand command, String cmdName, Method method, String prefSubCommand) {
return new RegisteredCommand(command, cmdName, method, prefSubCommand);
}
}
@@ -32,7 +32,6 @@ import co.aikar.commands.annotation.Syntax;
import co.aikar.commands.annotation.Values;
import co.aikar.commands.contexts.ContextResolver;
import co.aikar.commands.contexts.SenderAwareContextResolver;
import co.aikar.timings.lib.MCTiming;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -47,20 +46,19 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class RegisteredCommand {
public class RegisteredCommand <R extends CommandExecutionContext<? extends CommandExecutionContext>> {
final BaseCommand scope;
public final String command;
private final Method method;
final String prefSubCommand;
final Parameter[] parameters;
final ContextResolver<?, ?>[] resolvers;
final ContextResolver<?, R>[] resolvers;
final String syntaxText;
private final String permission;
final String complete;
final int requiredResolvers;
final int optionalResolvers;
private MCTiming timing;
RegisteredCommand(BaseCommand scope, String command, Method method, String prefSubCommand) {
this.scope = scope;
@@ -75,6 +73,7 @@ public class RegisteredCommand {
CommandCompletion completionAnno = method.getAnnotation(CommandCompletion.class);
this.complete = completionAnno != null ? scope.manager.getCommandReplacements().replace(completionAnno.value()) : null;
this.parameters = method.getParameters();
//noinspection unchecked
this.resolvers = new ContextResolver[this.parameters.length];
final Syntax syntaxStr = method.getAnnotation(Syntax.class);
final CommandManager manager = scope.manager;
@@ -88,17 +87,19 @@ public class RegisteredCommand {
final Parameter parameter = parameters[i];
final Class<?> type = parameter.getType();
final ContextResolver<?, ?> resolver = commandContexts.getResolver(type);
//noinspection unchecked
final ContextResolver<?, R> resolver = commandContexts.getResolver(type);
if (resolver != null) {
resolvers[i] = resolver;
if (!CommandIssuer.class.isAssignableFrom(parameter.getType())) {
if (!scope.manager.isCommandIssuer(type)) {
String name = parameter.getName();
if (isOptionalResolver(resolver, parameter)) {
optionalResolvers++;
syntaxB.append('[').append(parameter.getName()).append("] ");
syntaxB.append('[').append(name).append("] ");
} else {
requiredResolvers++;
syntaxB.append('<').append(parameter.getName()).append("> ");
syntaxB.append('<').append(name).append("> ");
}
}
} else {
@@ -116,7 +117,7 @@ public class RegisteredCommand {
this.optionalResolvers = optionalResolvers;
}
static boolean isOptionalResolver(ContextResolver<?, ?> resolver, Parameter parameter) {
private boolean isOptionalResolver(ContextResolver<?, R> resolver, Parameter parameter) {
return resolver instanceof SenderAwareContextResolver
|| parameter.getAnnotation(Optional.class) != null
|| parameter.getAnnotation(Default.class) != null;
@@ -126,6 +127,7 @@ public class RegisteredCommand {
if (!scope.canExecute(sender, this)) {
return;
}
preCommand();
try {
Map<String, Object> passedArgs = resolveContexts(sender, args);
if (passedArgs == null) return;
@@ -134,7 +136,10 @@ public class RegisteredCommand {
} catch (Exception e) {
handleException(sender, args, e);
}
postCommand();
}
public void preCommand() {}
public void postCommand() {}
void handleException(CommandIssuer sender, List<String> args, Exception e) {
if (e instanceof InvocationTargetException && e.getCause() instanceof InvalidCommandArgument) {
@@ -169,8 +174,9 @@ public class RegisteredCommand {
final Parameter parameter = parameters[i];
final String parameterName = parameter.getName();
final Class<?> type = parameter.getType();
final ContextResolver<?, ?> resolver = resolvers[i];
CommandExecutionContext context = this.scope.manager.createCommandContext(this, parameter, sender, args, i, passedArgs);
//noinspection unchecked
final ContextResolver<?, R> resolver = resolvers[i];
R context = this.scope.manager.createCommandContext(this, parameter, sender, args, i, passedArgs);
if (!isOptionalResolver(resolver, parameter)) {
remainingRequired--;
}
@@ -212,13 +218,6 @@ public class RegisteredCommand {
return passedArgs;
}
MCTiming getTiming() {
if (this.timing == null) {
this.timing = scope.manager.getTimings().of("Command: " + command);
}
return this.timing;
}
boolean hasPermission(CommandIssuer check) {
return permission == null || !check.isPlayer() || check.hasPermission(permission);
}
@@ -0,0 +1,31 @@
/*
* 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.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface PreCommand {}
@@ -27,6 +27,6 @@ import co.aikar.commands.CommandExecutionContext;
import co.aikar.commands.InvalidCommandArgument;
@FunctionalInterface
public interface ContextResolver <C, T extends CommandExecutionContext> {
C getContext(CommandExecutionContext<T> c) throws InvalidCommandArgument;
public interface ContextResolver <T, C extends CommandExecutionContext<?>> {
T getContext(C c) throws InvalidCommandArgument;
}
@@ -25,4 +25,4 @@ package co.aikar.commands.contexts;
import co.aikar.commands.CommandExecutionContext;
public interface SenderAwareContextResolver<C, T extends CommandExecutionContext> extends ContextResolver <C, T> {}
public interface SenderAwareContextResolver<T, C extends CommandExecutionContext<?>> extends ContextResolver <T, C> {}