diff options
author | t00thpick1 <t00thpick1dirko@gmail.com> | 2014-02-08 04:07:11 -0500 |
---|---|---|
committer | Travis Watkins <amaranth@ubuntu.com> | 2014-02-08 03:11:46 -0600 |
commit | 9d0d46dee35c257fdee5145eba0fda275a0795dc (patch) | |
tree | 9b00a48d9b3a882c75a17541577c9bf699091fb8 /src/main/java | |
parent | 9080288a36daa6bbb6c3ca885f2d56f0538e8076 (diff) | |
download | bukkit-9d0d46dee35c257fdee5145eba0fda275a0795dc.tar bukkit-9d0d46dee35c257fdee5145eba0fda275a0795dc.tar.gz bukkit-9d0d46dee35c257fdee5145eba0fda275a0795dc.tar.lz bukkit-9d0d46dee35c257fdee5145eba0fda275a0795dc.tar.xz bukkit-9d0d46dee35c257fdee5145eba0fda275a0795dc.zip |
[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.
Diffstat (limited to 'src/main/java')
-rw-r--r-- | src/main/java/org/bukkit/command/FormattedCommandAlias.java | 119 | ||||
-rw-r--r-- | src/main/java/org/bukkit/command/SimpleCommandMap.java | 17 |
2 files changed, 128 insertions, 8 deletions
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<String> commands = new ArrayList<String>(); + 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<String, String[]> values = server.getCommandAliases(); for (String alias : values.keySet()) { - String[] targetNames = values.get(alias); - List<Command> targets = new ArrayList<Command>(); + String[] commandStrings = values.get(alias); + List<String> targets = new ArrayList<String>(); 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()); } |