From 9d0d46dee35c257fdee5145eba0fda275a0795dc Mon Sep 17 00:00:00 2001 From: t00thpick1 Date: Sat, 8 Feb 2014 04:07:11 -0500 Subject: [Bleeding] Improve alias system. Adds a large expansion of the aliases system. Aliases can now take arguments, reorder their arguments, and only pass certain arguments to certain commands. New syntax added to the aliases are $1 for optional arguments, $$1 for required arguments, $1- for optionally using all the arguments from the specified position onward, and $$1- to do the same thing but require at least the specified position exist. These exist for numbers 1 through 9. You are able to pass arguments to one command of a multiple command argument and not others. You can also use the argument as a prefix and/or suffix. A raw $ can be represented in the arguments by using \$. Examples: aliases: # Usage: /testobjective score_deaths 1 5 testobjective: - "testfor @p[$$1=$$3,$$1_min=$$2]" # Usage: /ban Amaranthus Because reasons ban: - ban $$1 $2- - say Banned $$1 # Usage: /icanhasbukkit icanhasbukkit: - version # Usage: /icanhasplugin HomeBukkit icanhasplugin: - version $$1 One change from the previous aliases system is that commands are no longer passed all arguments implicitly. You must explicitly pass the arguments you want to pass to the command. --- .../org/bukkit/command/FormattedCommandAlias.java | 119 +++++++++++++++++++++ .../java/org/bukkit/command/SimpleCommandMap.java | 17 +-- 2 files changed, 128 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/bukkit/command/FormattedCommandAlias.java (limited to 'src/main/java') diff --git a/src/main/java/org/bukkit/command/FormattedCommandAlias.java b/src/main/java/org/bukkit/command/FormattedCommandAlias.java new file mode 100644 index 00000000..250f6ecf --- /dev/null +++ b/src/main/java/org/bukkit/command/FormattedCommandAlias.java @@ -0,0 +1,119 @@ +package org.bukkit.command; + +import java.util.ArrayList; +import java.util.logging.Level; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.server.RemoteServerCommandEvent; +import org.bukkit.event.server.ServerCommandEvent; + +public class FormattedCommandAlias extends Command { + private final String[] formatStrings; + + public FormattedCommandAlias(String alias, String[] formatStrings) { + super(alias); + this.formatStrings = formatStrings; + } + + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + boolean result = false; + ArrayList commands = new ArrayList(); + for (String formatString : formatStrings) { + try { + if (sender instanceof Player) { + PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent((Player) sender, "/" + formatString); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return false; + } else { + formatString = event.getMessage().substring(1); + } + } else if (sender instanceof RemoteConsoleCommandSender) { + RemoteServerCommandEvent event = new RemoteServerCommandEvent(sender, formatString); + Bukkit.getPluginManager().callEvent(event); + formatString = event.getCommand(); + } else if (sender instanceof ConsoleCommandSender) { + ServerCommandEvent event = new ServerCommandEvent(sender, formatString); + Bukkit.getPluginManager().callEvent(event); + formatString = event.getCommand(); + } + + commands.add(buildCommand(formatString, args)); + } catch (Throwable throwable) { + if (throwable instanceof IllegalArgumentException) { + sender.sendMessage(throwable.getMessage()); + } else { + sender.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command"); + } + Bukkit.getLogger().log(Level.WARNING, "Failed to parse command alias " + commandLabel + ": " + formatString, throwable); + return false; + } + } + + for (String command : commands) { + result |= Bukkit.dispatchCommand(sender, command); + } + + return result; + } + + private String buildCommand(String formatString, String[] args) { + int index = formatString.indexOf("$"); + while (index != -1) { + int start = index; + + boolean required = false; + if (formatString.charAt(index + 1) == '$') { + required = true; + // Move index past the second $ + index++; + } + + // Move index past the $ + index++; + int position = Character.getNumericValue(formatString.charAt(index)) - 1; + // Move index past the position + index++; + + boolean rest = false; + if (index < formatString.length() && formatString.charAt(index) == '-') { + rest = true; + // Move index past the - + index++; + } + + int end = index; + + if (required && position >= args.length) { + throw new IllegalArgumentException("Missing required argument " + (position + 1)); + } + + String replacement = null; + if (rest && position < args.length) { + StringBuilder builder = new StringBuilder(); + for (int i = position; i < args.length; i++) { + if (i != position) { + builder.append(' '); + } + builder.append(args[i]); + } + replacement = builder.toString(); + } else if (position < args.length) { + replacement = args[position]; + } + + if (replacement != null && replacement.length() > 0) { + formatString = formatString.substring(0, start) + replacement + formatString.substring(end); + // Move index past the replaced data so we don't process it again + index = start + replacement.length(); + } + + index = formatString.indexOf("$", index); + } + + return formatString; + } +} diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java index 13b13bdc..a0dd292f 100644 --- a/src/main/java/org/bukkit/command/SimpleCommandMap.java +++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java @@ -3,6 +3,7 @@ package org.bukkit.command; import static org.bukkit.util.Java15Compat.Arrays_copyOfRange; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -256,27 +257,27 @@ public class SimpleCommandMap implements CommandMap { Map values = server.getCommandAliases(); for (String alias : values.keySet()) { - String[] targetNames = values.get(alias); - List targets = new ArrayList(); + String[] commandStrings = values.get(alias); + List targets = new ArrayList(); StringBuilder bad = new StringBuilder(); - for (String name : targetNames) { - Command command = getCommand(name); + for (String commandString : commandStrings) { + String[] commandArgs = commandString.split(" "); + Command command = getCommand(commandArgs[0]); if (command == null) { if (bad.length() > 0) { bad.append(", "); } - bad.append(name); + bad.append(commandString); } else { - targets.add(command); + targets.add(commandString); } } // We register these as commands so they have absolute priority. - if (targets.size() > 0) { - knownCommands.put(alias.toLowerCase(), new MultipleCommandAlias(alias.toLowerCase(), targets.toArray(new Command[0]))); + knownCommands.put(alias.toLowerCase(), new FormattedCommandAlias(alias.toLowerCase(), targets.toArray(new String[targets.size()]))); } else { knownCommands.remove(alias.toLowerCase()); } -- cgit v1.2.3