diff --git a/src/main/java/com/sk89q/minecraft/util/commands/AliasCommand.java b/src/main/java/com/sk89q/minecraft/util/commands/AliasCommand.java new file mode 100644 index 000000000..134d1c952 --- /dev/null +++ b/src/main/java/com/sk89q/minecraft/util/commands/AliasCommand.java @@ -0,0 +1,40 @@ +// $Id$ +/* + * Copyright (C) 2010 sk89q + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + +package com.sk89q.minecraft.util.commands; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Any command with this annotation will run the raw command as shown in the + * thing, as long as it is registered in the current {@link CommandsManager}. + * Mostly to move commands around without breaking things. + * + * @author zml2008 + */ + +@Retention(RetentionPolicy.RUNTIME) +public @interface AliasCommand { + + /** + * + * @return Raw {@link CommandsManager}-formatted command arg array to run + */ + String[] aliasTo(); +} diff --git a/src/main/java/com/sk89q/minecraft/util/commands/CommandContext.java b/src/main/java/com/sk89q/minecraft/util/commands/CommandContext.java index 6bad1f8b4..94fce79b5 100644 --- a/src/main/java/com/sk89q/minecraft/util/commands/CommandContext.java +++ b/src/main/java/com/sk89q/minecraft/util/commands/CommandContext.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.Set; public class CommandContext { + protected static final String QUOTE_CHARS = "\'\""; protected final String[] args; protected final Set booleanFlags = new HashSet(); protected final Map valueFlags = new HashMap(); @@ -34,25 +35,34 @@ public class CommandContext { } public CommandContext(String[] args) { - int i = 1; - for (; i < args.length; ++i) { + char quotedChar; + for (int i = 1; i < args.length; ++i) { if (args[i].length() == 0) { - // Ignore this + args = removePortionOfArray(args, i, i, null); + } else if (QUOTE_CHARS.indexOf(String.valueOf(args[i].charAt(0))) != -1) { + StringBuilder build = new StringBuilder(); + quotedChar = args[i].charAt(0); + int endIndex = i; + for (; endIndex < args.length; endIndex++) { + if (args[endIndex].charAt(args[endIndex].length() - 1) == quotedChar) { + if (endIndex != i) build.append(" "); + build.append(args[endIndex].substring(endIndex == i ? 1 : 0, args[endIndex].length() - 1)); + break; + } else if (endIndex == i) { + build.append(args[endIndex].substring(1)); + } else { + build.append(" ").append(args[endIndex]); + } + } + args = removePortionOfArray(args, i, endIndex, build.toString()); } else if (args[i].charAt(0) == '-' && args[i].matches("^-[a-zA-Z]+$")) { for (int k = 1; k < args[i].length(); ++k) { booleanFlags.add(args[i].charAt(k)); } - } else { - break; + args = removePortionOfArray(args, i, i, null); } } - - String[] newArgs = new String[args.length - i + 1]; - - System.arraycopy(args, i, newArgs, 1, args.length - i); - newArgs[0] = args[0]; - - this.args = newArgs; + this.args = args; } public CommandContext(String args, Set isValueFlag) throws CommandException { @@ -223,4 +233,13 @@ public class CommandContext { public int argsLength() { return args.length - 1; } + + public static String[] removePortionOfArray(String[] array, int from, int to, String replace) { + String[] newArray = new String[from + array.length - to - (replace == null ? 1 : 0)]; + System.arraycopy(array, 0, newArray, 0, from); + if (replace != null) newArray[from] = replace; + System.arraycopy(array, to + (replace == null ? 0 : 1), newArray, from + (replace == null ? 0 : 1), + array.length - to - 1); + return newArray; + } } 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 0c6f3241f..79b7b6b51 100644 --- a/src/main/java/com/sk89q/minecraft/util/commands/CommandsManager.java +++ b/src/main/java/com/sk89q/minecraft/util/commands/CommandsManager.java @@ -369,7 +369,10 @@ public abstract class CommandsManager { } else { executeMethod(method, args, player, methodArgs, level + 1); } - } else { + } else if (method.isAnnotationPresent(AliasCommand.class)) { + AliasCommand aCmd = method.getAnnotation(AliasCommand.class); + executeMethod(parent, aCmd.aliasTo(), player, methodArgs, level); + } else { Command cmd = method.getAnnotation(Command.class); String[] newArgs = new String[args.length - level];