geforkt von Mirrors/FastAsyncWorldEdit
Added multiword args and some improvements to value flags.
Dieser Commit ist enthalten in:
Ursprung
c38a6b0677
Commit
2f390e9938
@ -63,15 +63,9 @@ public @interface Command {
|
||||
* Flags allow special processing for flags such as -h in the command,
|
||||
* allowing users to easily turn on a flag. This is a string with
|
||||
* 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
|
||||
*/
|
||||
String flags() default "";
|
||||
|
||||
/**
|
||||
* Value flags are special flags, that take a value after the flag.
|
||||
* The semantics are the same as with the flags parameter.
|
||||
* They aren't automatically documented and thus need to be added
|
||||
* to the "usage" parameter separately.
|
||||
*/
|
||||
String valueFlags() default "";
|
||||
|
||||
}
|
||||
|
@ -18,11 +18,11 @@
|
||||
|
||||
package com.sk89q.minecraft.util.commands;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import static com.sk89q.util.ArrayUtil.removePortionOfArray;
|
||||
|
||||
public class CommandContext {
|
||||
protected static final String QUOTE_CHARS = "\'\"";
|
||||
@ -30,16 +30,30 @@ public class CommandContext {
|
||||
protected final Set<Character> booleanFlags = new HashSet<Character>();
|
||||
protected final Map<Character, String> valueFlags = new HashMap<Character, String>();
|
||||
|
||||
public CommandContext(String args) {
|
||||
this(args.split(" "));
|
||||
public CommandContext(String args) throws CommandException {
|
||||
this(args.split(" "), null);
|
||||
}
|
||||
|
||||
public CommandContext(String[] args) {
|
||||
public CommandContext(String[] args) throws CommandException {
|
||||
this(args, null);
|
||||
}
|
||||
|
||||
public CommandContext(String args, Set<Character> valueFlags) throws CommandException {
|
||||
this(args.split(" "), valueFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args An array with arguments empty strings will be ignored by most things
|
||||
* @param valueFlags A set containing all value flags. Pass null to disable value flag parsing.
|
||||
* @throws CommandException This is thrown if a value flag was passed without a value.
|
||||
*/
|
||||
public CommandContext(String[] args, Set<Character> valueFlags) throws CommandException {
|
||||
// Go through empty args and multiword args first
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
char quotedChar;
|
||||
for (int i = 1; i < args.length; ++i) {
|
||||
if (args[i].length() == 0) {
|
||||
if (args[i].length() < 1) {
|
||||
args = removePortionOfArray(args, i, i, null);
|
||||
} else if (QUOTE_CHARS.indexOf(String.valueOf(args[i].charAt(0))) != -1) {
|
||||
} else if (QUOTE_CHARS.indexOf(args[i].charAt(0)) != -1) {
|
||||
StringBuilder build = new StringBuilder();
|
||||
quotedChar = args[i].charAt(0);
|
||||
int endIndex = i;
|
||||
@ -55,76 +69,35 @@ public class CommandContext {
|
||||
}
|
||||
}
|
||||
args = removePortionOfArray(args, i, endIndex, build.toString());
|
||||
} else if (args[i].charAt(0) == '-' && args[i].matches("^-[a-zA-Z]+$")) {
|
||||
}
|
||||
}
|
||||
// Then flags
|
||||
for (int i = 1; i < args.length; ++i) {
|
||||
if (args[i].charAt(0) == '-' && args[i].matches("^-[a-zA-Z]+$")) {
|
||||
for (int k = 1; k < args[i].length(); ++k) {
|
||||
if (valueFlags != null && valueFlags.contains(args[i].charAt(k))) {
|
||||
int index = i + 1;
|
||||
if (args.length - 1 < index) {
|
||||
throw new CommandException("Value flag '" + args[i].charAt(k) + "' specified without value");
|
||||
}
|
||||
if (this.valueFlags.containsKey(args[i].charAt(k))) {
|
||||
throw new CommandException("Value flag '" + args[i].charAt(k) + "' already given");
|
||||
}
|
||||
this.valueFlags.put(args[i].charAt(k), args[index]);
|
||||
args = removePortionOfArray(args, index, index, null);
|
||||
} else {
|
||||
booleanFlags.add(args[i].charAt(k));
|
||||
}
|
||||
}
|
||||
args = removePortionOfArray(args, i, i, null);
|
||||
} else if (args[i].matches("^--$")) {
|
||||
args = removePortionOfArray(args, i, i, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public CommandContext(String args, Set<Character> isValueFlag) throws CommandException {
|
||||
this(args.split(" "), isValueFlag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args An array with arguments empty strings will be ignored by most things
|
||||
* @param isValueFlag A set containing all value flags. Pass null to disable flag parsing altogether.
|
||||
* @throws CommandException This is thrown if a value flag was passed without a value.
|
||||
*/
|
||||
public CommandContext(String[] args, Set<Character> isValueFlag) throws CommandException {
|
||||
if (isValueFlag == null) {
|
||||
this.args = args;
|
||||
return;
|
||||
}
|
||||
|
||||
int nextArg = 1;
|
||||
|
||||
while (nextArg < args.length) {
|
||||
// Fetch argument
|
||||
String arg = args[nextArg++];
|
||||
|
||||
// Empty argument? (multiple consecutive spaces)
|
||||
if (arg.isEmpty())
|
||||
continue;
|
||||
|
||||
// No more flags?
|
||||
if (arg.charAt(0) != '-' || arg.length() == 1 || !arg.matches("^-[a-zA-Z]+$")) {
|
||||
--nextArg;
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle flag parsing terminator --
|
||||
if (arg.equals("--"))
|
||||
break;
|
||||
|
||||
// Go through the flags
|
||||
for (int i = 1; i < arg.length(); ++i) {
|
||||
char flagName = arg.charAt(i);
|
||||
|
||||
if (isValueFlag.contains(flagName)) {
|
||||
// Skip empty arguments...
|
||||
while (nextArg < args.length && args[nextArg].isEmpty())
|
||||
++nextArg;
|
||||
|
||||
if (nextArg >= args.length)
|
||||
throw new CommandException("No value specified for the '-"+flagName+"' flag.");
|
||||
|
||||
// If it is a value flag, read another argument and add it
|
||||
valueFlags.put(flagName, args[nextArg++]);
|
||||
}
|
||||
else {
|
||||
booleanFlags.add(flagName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.args = Arrays.copyOfRange(args, nextArg-1, args.length);
|
||||
this.args[0] = args[0];
|
||||
}
|
||||
|
||||
public String getCommand() {
|
||||
return args[0];
|
||||
}
|
||||
@ -233,13 +206,4 @@ 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;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sk89q.util.StringUtil;
|
||||
import static com.sk89q.util.ArrayUtil.removePortionOfArray;
|
||||
|
||||
/**
|
||||
* <p>Manager for handling commands. This allows you to easily process commands,
|
||||
@ -228,8 +229,17 @@ public abstract class CommandsManager<T> {
|
||||
for (int i = 0; i <= level; ++i) {
|
||||
command.append(args[i] + " ");
|
||||
}
|
||||
|
||||
command.append(cmd.flags().length() > 0 ? "[-" + cmd.flags() + "] " : "");
|
||||
if (cmd.flags().length() > 0) {
|
||||
char[] flags = cmd.flags().toCharArray();
|
||||
for (int i = 0; i < flags.length; ++i) {
|
||||
if (flags.length > i + 1) {
|
||||
if (flags[i + 1] == ':') {
|
||||
flags = removePortionOfArray(flags, i, i + 1, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flags.length > 0) command.append("[-" + String.valueOf(flags) + "] ");
|
||||
}
|
||||
command.append(cmd.usage());
|
||||
|
||||
return command.toString();
|
||||
@ -378,14 +388,19 @@ public abstract class CommandsManager<T> {
|
||||
String[] newArgs = new String[args.length - level];
|
||||
System.arraycopy(args, level, newArgs, 0, args.length - level);
|
||||
|
||||
final String valueFlags = cmd.valueFlags();
|
||||
final Set<Character> isValueFlag = new HashSet<Character>();
|
||||
final Set<Character> valueFlags = new HashSet<Character>();
|
||||
|
||||
for (int i = 0; i < valueFlags.length(); ++i) {
|
||||
isValueFlag.add(valueFlags.charAt(i));
|
||||
char[] flags = cmd.flags().toCharArray();
|
||||
for (int i = 0; i < flags.length; ++i) {
|
||||
if (flags.length > i + 1) {
|
||||
if (flags[i + 1] == ':') {
|
||||
valueFlags.add(flags[i]);
|
||||
flags = removePortionOfArray(flags, i + 1, i + 1, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CommandContext context = new CommandContext(newArgs, isValueFlag);
|
||||
CommandContext context = new CommandContext(newArgs, valueFlags);
|
||||
|
||||
if (context.argsLength() < cmd.min())
|
||||
throw new CommandUsageException("Too few arguments.", getUsage(args, level, cmd));
|
||||
@ -393,8 +408,9 @@ public abstract class CommandsManager<T> {
|
||||
if (cmd.max() != -1 && context.argsLength() > cmd.max())
|
||||
throw new CommandUsageException("Too many arguments.", getUsage(args, level, cmd));
|
||||
|
||||
String flagStr = String.valueOf(flags);
|
||||
for (char flag : context.getFlags()) {
|
||||
if (cmd.flags().indexOf(String.valueOf(flag)) == -1)
|
||||
if (flagStr.indexOf(flag) == -1)
|
||||
throw new CommandUsageException("Unknown flag: " + flag, getUsage(args, level, cmd));
|
||||
}
|
||||
|
||||
|
22
src/main/java/com/sk89q/util/ArrayUtil.java
Normale Datei
22
src/main/java/com/sk89q/util/ArrayUtil.java
Normale Datei
@ -0,0 +1,22 @@
|
||||
package com.sk89q.util;
|
||||
|
||||
public class ArrayUtil {
|
||||
|
||||
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 + 1, newArray, from + (replace == null ? 0 : 1),
|
||||
array.length - to - 1);
|
||||
return newArray;
|
||||
}
|
||||
|
||||
public static char[] removePortionOfArray(char[] array, int from, int to, Character replace) {
|
||||
char[] newArray = new char[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 + 1, newArray, from + (replace == null ? 0 : 1),
|
||||
array.length - to - 1);
|
||||
return newArray;
|
||||
}
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren