Add ability to show a per-command usage + apply "correct indentation".

This commit is contained in:
asofold 2014-07-29 11:55:53 +02:00
parent 1aa62de1dd
commit 9b6c717fc0

View File

@ -24,173 +24,182 @@ import org.bukkit.entity.Player;
*/ */
public abstract class AbstractCommand<A> implements TabExecutor{ public abstract class AbstractCommand<A> implements TabExecutor{
public static final List<String> noTabChoices = Collections.unmodifiableList(new LinkedList<String>()); public static final List<String> noTabChoices = Collections.unmodifiableList(new LinkedList<String>());
/** /**
* Convenience method: join with a space in between. * Convenience method: join with a space in between.
* @param args * @param args
* @param startIndex * @param startIndex
* @return * @return
*/ */
public static String join(String[] args, int startIndex){ public static String join(String[] args, int startIndex){
return join(args, startIndex, " "); return join(args, startIndex, " ");
} }
/** /**
* Convenience method. * Convenience method.
* @param args * @param args
* @param startIndex * @param startIndex
* @return * @return
*/ */
public static String join(String[] args, int startIndex, String sep){ public static String join(String[] args, int startIndex, String sep){
final StringBuilder b = new StringBuilder(100); final StringBuilder b = new StringBuilder(100);
if (startIndex < args.length) b.append(args[startIndex]); if (startIndex < args.length) b.append(args[startIndex]);
for (int i = startIndex + 1; i < args.length; i++){ for (int i = startIndex + 1; i < args.length; i++){
b.append(sep); b.append(sep);
b.append(args[i]); b.append(args[i]);
} }
return b.toString(); return b.toString();
} }
/** /**
* *
* @param sender * @param sender
* @return True if sender is a Player, otherwise false is returned and a message sent. * @return True if sender is a Player, otherwise false is returned and a message sent.
*/ */
public static boolean demandPlayer(CommandSender sender) { public static boolean demandPlayer(CommandSender sender) {
if (sender instanceof Player) { if (sender instanceof Player) {
return true; return true;
} else { } else {
sender.sendMessage("[NoCheatPlus] A player is required to run this command."); sender.sendMessage("[NoCheatPlus] A player is required to run this command.");
return false; return false;
} }
} }
/** /**
* *
* @param sender * @param sender
* @return True if sender is a Player, otherwise false is returned and a message sent. * @return True if sender is a Player, otherwise false is returned and a message sent.
*/ */
public static boolean demandConsoleCommandSender(CommandSender sender) { public static boolean demandConsoleCommandSender(CommandSender sender) {
if (sender instanceof ConsoleCommandSender) { if (sender instanceof ConsoleCommandSender) {
return true; return true;
} else { } else {
sender.sendMessage("[NoCheatPlus] This command can only be run from the console."); sender.sendMessage("[NoCheatPlus] This command can only be run from the console.");
return false; return false;
} }
} }
//////////////// ////////////////
// Not static. // Not static.
//////////////// ////////////////
protected final A access; protected final A access;
public final String label; public final String label;
/** Permission necessary to use this command. May be null. */ /** Permission necessary to use this command. May be null. */
public final String permission; public final String permission;
/** Sub commands for delegation. */ /** Sub commands for delegation. */
protected final Map<String, AbstractCommand<?>> subCommands = new LinkedHashMap<String, AbstractCommand<?>>(); protected final Map<String, AbstractCommand<?>> subCommands = new LinkedHashMap<String, AbstractCommand<?>>();
/** The index in args to check for sub-commands. -1 stands for default, either parent + 1 or 0 */ /** The index in args to check for sub-commands. -1 stands for default, either parent + 1 or 0 */
protected int subCommandIndex = -1; protected int subCommandIndex = -1;
/** Aliases for the command label. */ /** Aliases for the command label. */
protected final String[] aliases; protected final String[] aliases;
/** /** This is only shown if a parent command receives false for onCommand and if it is not null. */
* protected String usage = null;
* @param access
* @param label Lower-case.
* @param permission
*/
public AbstractCommand(A access, String label, String permission){
this(access, label, permission, null);
}
/** /**
* *
* @param access * @param access
* @param label Lower-case. * @param label Lower-case.
* @param permission May be null (no permission necessary). * @param permission
* @param aliases May be null (no aliases). If given, the aliases only take effect for tab completion and selection of sub commands. Lower-case. */
*/ public AbstractCommand(A access, String label, String permission){
public AbstractCommand(A access, String label, String permission, String[] aliases){ this(access, label, permission, null);
this.access = access; }
this.label = label;
this.permission = permission;
this.aliases = aliases;
}
public void addSubCommands(AbstractCommand<?>... commands){ /**
for (AbstractCommand<?> subCommand : commands ){ *
subCommands.put(subCommand.label, subCommand); * @param access
if (subCommand.subCommandIndex == -1){ * @param label Lower-case.
subCommand.subCommandIndex = Math.max(0, this.subCommandIndex) + 1; * @param permission May be null (no permission necessary).
} * @param aliases May be null (no aliases). If given, the aliases only take effect for tab completion and selection of sub commands. Lower-case.
if (subCommand.aliases != null){ */
for (final String alias : subCommand.aliases){ public AbstractCommand(A access, String label, String permission, String[] aliases){
if (!subCommands.containsKey(alias)){ this.access = access;
subCommands.put(alias, subCommand); this.label = label;
} this.permission = permission;
} this.aliases = aliases;
} }
}
}
@Override public void addSubCommands(AbstractCommand<?>... commands){
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) for (AbstractCommand<?> subCommand : commands ){
{ subCommands.put(subCommand.label, subCommand);
final Set<String> choices = new LinkedHashSet<String>(subCommands.size()); if (subCommand.subCommandIndex == -1){
int len = args.length; subCommand.subCommandIndex = Math.max(0, this.subCommandIndex) + 1;
// Attempt to delegate. }
int subCommandIndex = Math.max(0, this.subCommandIndex); if (subCommand.aliases != null){
if (len == subCommandIndex || len == subCommandIndex + 1){ for (final String alias : subCommand.aliases){
String arg = len == subCommandIndex ? "" : args[subCommandIndex].trim().toLowerCase(); if (!subCommands.containsKey(alias)){
for (AbstractCommand<?> cmd : subCommands.values()){ subCommands.put(alias, subCommand);
if (cmd.label.startsWith(arg) && cmd.testPermission(sender, command, alias, args)){ }
// Only completes the label (!). }
choices.add(cmd.label); }
} }
} }
}
else if (len > subCommandIndex + 1){
String arg = args[subCommandIndex].trim().toLowerCase();
AbstractCommand<?> subCommand = subCommands.get(arg);
if (subCommand != null && subCommand.testPermission(sender, command, alias, args)){
return subCommand.onTabComplete(sender, command, alias, args);
}
}
// No tab completion by default.
if (choices.isEmpty()) return noTabChoices;
else return new LinkedList<String>(choices);
}
@Override @Override
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args)
{ {
int len = args.length; final Set<String> choices = new LinkedHashSet<String>(subCommands.size());
int subCommandIndex = Math.max(0, this.subCommandIndex); int len = args.length;
if (len > subCommandIndex){ // Attempt to delegate.
String arg = args[subCommandIndex].trim().toLowerCase(); int subCommandIndex = Math.max(0, this.subCommandIndex);
AbstractCommand<?> subCommand = subCommands.get(arg); if (len == subCommandIndex || len == subCommandIndex + 1){
if (subCommand != null){ String arg = len == subCommandIndex ? "" : args[subCommandIndex].trim().toLowerCase();
if (!subCommand.testPermission(sender, command, alias, args)){ for (AbstractCommand<?> cmd : subCommands.values()){
sender.sendMessage(ChatColor.DARK_RED + "You don't have permission."); if (cmd.label.startsWith(arg) && cmd.testPermission(sender, command, alias, args)){
return true; // Only completes the label (!).
} choices.add(cmd.label);
return subCommand.onCommand(sender, command, alias, args); }
} }
} }
// Usage. else if (len > subCommandIndex + 1){
return false; String arg = args[subCommandIndex].trim().toLowerCase();
} AbstractCommand<?> subCommand = subCommands.get(arg);
if (subCommand != null && subCommand.testPermission(sender, command, alias, args)){
return subCommand.onTabComplete(sender, command, alias, args);
}
}
// No tab completion by default.
if (choices.isEmpty()) return noTabChoices;
else return new LinkedList<String>(choices);
}
/** @Override
* Test if the CommandSender has the permission necessary to run THIS command (not meant for checking sub-command permissions recursively). public boolean onCommand(CommandSender sender, Command command, String alias, String[] args)
* <br>Override for more complex specialized permissions. {
* @param sender int len = args.length;
* @return int subCommandIndex = Math.max(0, this.subCommandIndex);
*/ if (len > subCommandIndex){
public boolean testPermission(CommandSender sender, Command command, String alias, String args[]){ String arg = args[subCommandIndex].trim().toLowerCase();
return permission == null || sender.hasPermission(permission); AbstractCommand<?> subCommand = subCommands.get(arg);
} if (subCommand != null){
if (!subCommand.testPermission(sender, command, alias, args)){
sender.sendMessage(ChatColor.DARK_RED + "You don't have permission.");
return true;
}
final boolean res = subCommand.onCommand(sender, command, alias, args);
if (!res && subCommand.usage != null) {
sender.sendMessage(subCommand.usage);
return true;
} else {
return res;
}
}
}
// Usage.
return false;
}
/**
* Test if the CommandSender has the permission necessary to run THIS command (not meant for checking sub-command permissions recursively).
* <br>Override for more complex specialized permissions.
* @param sender
* @return
*/
public boolean testPermission(CommandSender sender, Command command, String alias, String args[]){
return permission == null || sender.hasPermission(permission);
}
} }