From 5e8f50699d6ec3313d47b36740934ca7c1f2d64c Mon Sep 17 00:00:00 2001 From: zml2008 Date: Wed, 28 Mar 2012 11:04:34 -0700 Subject: [PATCH] Added allFlags setting to Command to prevent it from restricting allowed flags --- .../minecraft/util/commands/Command.java | 23 ++++++- .../util/commands/CommandsManager.java | 60 +++++++++++-------- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/sk89q/minecraft/util/commands/Command.java b/src/main/java/com/sk89q/minecraft/util/commands/Command.java index c16aa32b7..32780e6f5 100644 --- a/src/main/java/com/sk89q/minecraft/util/commands/Command.java +++ b/src/main/java/com/sk89q/minecraft/util/commands/Command.java @@ -34,28 +34,36 @@ public @interface Command { * A list of aliases for the command. The first alias is the most * important -- it is the main name of the command. (The method name * is never used for anything). + * + * @return Aliases for a command */ String[] aliases(); /** * Usage instruction. Example text for usage could be - * [-h] [name] [message]. + * [-h harps] [name] [message]. + * + * @return Usage instructions for a command */ String usage() default ""; /** - * A short description for the command. + * @return A short description for the command. */ String desc(); /** * The minimum number of arguments. This should be 0 or above. + * + * @return the minimum number of arguments */ int min() default 0; /** * The maximum number of arguments. Use -1 for an unlimited number * of arguments. + * + * @return the maximum number of arguments */ int max() default -1; @@ -65,11 +73,20 @@ public @interface Command { * each character being a flag. Use A-Z and a-z as possible flags. * Appending a flag with a : makes the flag character before a value flag, * meaning that if it is given it must have a value + * + * @return Flags matching a-zA-Z */ String flags() default ""; /** - * A long description for the command. + * @return A long description for the command. */ String help() default ""; + + /** + * + * + * @return Whether any flag can be provided to the command, even if it is not in {@link #flags()} + */ + boolean anyFlags() default false; } diff --git a/src/main/java/com/sk89q/minecraft/util/commands/CommandsManager.java b/src/main/java/com/sk89q/minecraft/util/commands/CommandsManager.java index daa1224e5..fcf7000b2 100644 --- a/src/main/java/com/sk89q/minecraft/util/commands/CommandsManager.java +++ b/src/main/java/com/sk89q/minecraft/util/commands/CommandsManager.java @@ -36,7 +36,7 @@ import com.sk89q.util.StringUtil; /** *

Manager for handling commands. This allows you to easily process commands, * including nested commands, by correctly annotating methods of a class.

- * + * *

To use this, it is merely a matter of registering classes containing * the commands (as methods with the proper annotations) with the * manager. When you want to process a command, use one of the @@ -47,16 +47,16 @@ import com.sk89q.util.StringUtil; *

Methods of a class to be registered can be static, but if an injector * is registered with the class, the instances of the command classes * will be created automatically and methods will be called non-statically.

- * + * *

To mark a method as a command, use {@link Command}. For nested commands, * see {@link NestedCommand}. To handle permissions, use * {@link CommandPermissions}.

- * + * *

This uses Java reflection extensively, but to reduce the overhead of * reflection, command lookups are completely cached on registration. This * allows for fast command handling. Method invocation still has to be done * with reflection, but this is quite fast in that of itself.

- * + * * @author sk89q * @param command sender class */ @@ -104,7 +104,7 @@ public abstract class CommandsManager { * class will be registered to be called statically. Otherwise, new * instances will be created of the command classes and methods will * not be called statically. - * + * * @param cls */ public void register(Class cls) { @@ -140,8 +140,7 @@ public abstract class CommandsManager { if (getInjector() == null) { return registerMethods(cls, parent, null); } else { - Object obj = null; - obj = getInjector().getInstance(cls); + Object obj = getInjector().getInstance(cls); return registerMethods(cls, parent, obj); } } catch (InvocationTargetException e) { @@ -156,9 +155,11 @@ public abstract class CommandsManager { /** * Register the methods of a class. - * + * * @param cls * @param parent + * @param obj + * @return */ private List registerMethods(Class cls, Method parent, Object obj) { Map map; @@ -213,11 +214,11 @@ public abstract class CommandsManager { String help = cmd.help(); if (help.length() == 0) { help = desc; - } + } final CharSequence arguments = getArguments(cmd); for (String alias : cmd.aliases()) { - final String helpMessage = "/"+alias+" "+arguments+"\n\n"+help; + final String helpMessage = "/" + alias + " " + arguments + "\n\n" + help; final String key = alias.replaceAll("/", ""); String previous = helpMessages.put(key, helpMessage); @@ -242,13 +243,18 @@ public abstract class CommandsManager { } } } + + if (cls.getSuperclass() != null) { + registerMethods(cls.getSuperclass(), parent, obj); + } + return registered; } /** * Checks to see whether there is a command named such at the root level. * This will check aliases as well. - * + * * @param command * @return */ @@ -258,7 +264,7 @@ public abstract class CommandsManager { /** * Get a list of command descriptions. This is only for root commands. - * + * * @return */ public Map getCommands() { @@ -271,7 +277,7 @@ public abstract class CommandsManager { /** * Get a map from command name to help message. This is only for root commands. - * + * * @return */ public Map getHelpMessages() { @@ -280,7 +286,7 @@ public abstract class CommandsManager { /** * Get the usage string for a command. - * + * * @param args * @param level * @param cmd @@ -328,7 +334,7 @@ public abstract class CommandsManager { /** * Get the usage string for a nested command. - * + * * @param args * @param level * @param method @@ -384,12 +390,12 @@ public abstract class CommandsManager { /** * Attempt to execute a command. This version takes a separate command * name (for the root command) and then a list of following arguments. - * + * * @param cmd command to run * @param args arguments * @param player command source * @param methodArgs method arguments - * @throws CommandException + * @throws CommandException */ public void execute(String cmd, String[] args, T player, Object... methodArgs) throws CommandException { @@ -405,11 +411,11 @@ public abstract class CommandsManager { /** * Attempt to execute a command. - * + * * @param args * @param player * @param methodArgs - * @throws CommandException + * @throws CommandException */ public void execute(String[] args, T player, Object... methodArgs) throws CommandException { @@ -421,13 +427,13 @@ public abstract class CommandsManager { /** * Attempt to execute a command. - * + * * @param parent * @param args * @param player * @param methodArgs * @param level - * @throws CommandException + * @throws CommandException */ public void executeMethod(Method parent, String[] args, T player, Object[] methodArgs, int level) throws CommandException { @@ -488,9 +494,11 @@ public abstract class CommandsManager { throw new CommandUsageException("Too many arguments.", getUsage(args, level, cmd)); } - for (char flag : context.getFlags()) { - if (!newFlags.contains(flag)) { - throw new CommandUsageException("Unknown flag: " + flag, getUsage(args, level, cmd)); + if (!cmd.anyFlags()) { + for (char flag : context.getFlags()) { + if (!newFlags.contains(flag)) { + throw new CommandUsageException("Unknown flag: " + flag, getUsage(args, level, cmd)); + } } } @@ -527,7 +535,7 @@ public abstract class CommandsManager { /** * Returns whether a player has access to a command. - * + * * @param method * @param player * @return @@ -549,7 +557,7 @@ public abstract class CommandsManager { /** * Returns whether a player permission.. - * + * * @param player * @param perm * @return