Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-09-07 00:22:51 +02:00
Make flags command executor-specific.
Dieser Commit ist enthalten in:
Ursprung
f4bb5272e1
Commit
874408ad10
@ -19,37 +19,35 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.command.argument;
|
package com.sk89q.worldedit.command.argument;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.sk89q.minecraft.util.commands.CommandException;
|
import com.sk89q.minecraft.util.commands.CommandException;
|
||||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
import com.sk89q.worldedit.util.command.argument.CommandArgs;
|
import com.sk89q.worldedit.util.command.argument.CommandArgs;
|
||||||
import com.sk89q.worldedit.util.command.composition.CommandExecutor;
|
import com.sk89q.worldedit.util.command.composition.CommandExecutor;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BooleanFlag implements CommandExecutor<Boolean> {
|
public class BooleanFlag implements CommandExecutor<Boolean> {
|
||||||
|
|
||||||
private final char flag;
|
|
||||||
private final String description;
|
private final String description;
|
||||||
|
|
||||||
public BooleanFlag(char flag, String description) {
|
public BooleanFlag(String description) {
|
||||||
this.flag = flag;
|
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean call(CommandArgs args, CommandLocals locals) throws CommandException {
|
public Boolean call(CommandArgs args, CommandLocals locals) throws CommandException {
|
||||||
return args.containsFlag(flag);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) {
|
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) {
|
||||||
return Lists.newArrayList("-" + flag);
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUsage() {
|
public String getUsage() {
|
||||||
return "[-" + flag + "]";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -30,19 +30,22 @@ import com.sk89q.worldedit.extension.platform.Actor;
|
|||||||
import com.sk89q.worldedit.function.factory.Deform;
|
import com.sk89q.worldedit.function.factory.Deform;
|
||||||
import com.sk89q.worldedit.function.factory.Deform.Mode;
|
import com.sk89q.worldedit.function.factory.Deform.Mode;
|
||||||
import com.sk89q.worldedit.util.command.argument.CommandArgs;
|
import com.sk89q.worldedit.util.command.argument.CommandArgs;
|
||||||
|
import com.sk89q.worldedit.util.command.composition.FlagParser.Flag;
|
||||||
|
import com.sk89q.worldedit.util.command.composition.FlagParser.FlagData;
|
||||||
import com.sk89q.worldedit.util.command.composition.SimpleCommand;
|
import com.sk89q.worldedit.util.command.composition.SimpleCommand;
|
||||||
|
|
||||||
public class DeformArg extends SimpleCommand<Deform> {
|
public class DeformArg extends SimpleCommand<Deform> {
|
||||||
|
|
||||||
private final BooleanFlag rawCoordsFlag = addParameter(new BooleanFlag('r', "Raw coords mode"));
|
private final Flag<Boolean> rawCoordsFlag = addFlag('r', new BooleanFlag("Raw coords mode"));
|
||||||
private final BooleanFlag offsetFlag = addParameter(new BooleanFlag('o', "Offset mode"));
|
private final Flag<Boolean> offsetFlag = addFlag('o', new BooleanFlag("Offset mode"));
|
||||||
private final StringArg expressionParser = addParameter(new StringArg("expression", "Expression to apply"));
|
private final StringArg expressionParser = addParameter(new StringArg("expression", "Expression to apply"));
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Deform call(CommandArgs args, CommandLocals locals) throws CommandException {
|
public Deform call(CommandArgs args, CommandLocals locals) throws CommandException {
|
||||||
|
FlagData flagData = getFlagParser().call(args, locals);
|
||||||
String expression = expressionParser.call(args, locals);
|
String expression = expressionParser.call(args, locals);
|
||||||
boolean rawCoords = rawCoordsFlag.call(args, locals);
|
boolean rawCoords = rawCoordsFlag.get(flagData, false);
|
||||||
boolean offset = offsetFlag.call(args, locals);
|
boolean offset = offsetFlag.get(flagData, false);
|
||||||
|
|
||||||
Deform deform = new Deform(expression);
|
Deform deform = new Deform(expression);
|
||||||
|
|
||||||
|
@ -20,26 +20,23 @@
|
|||||||
package com.sk89q.worldedit.util.command.argument;
|
package com.sk89q.worldedit.util.command.argument;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||||
import com.sk89q.minecraft.util.commands.CommandException;
|
import com.sk89q.minecraft.util.commands.CommandException;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class CommandArgs {
|
public class CommandArgs {
|
||||||
|
|
||||||
private final List<String> arguments;
|
private final List<String> arguments;
|
||||||
private final Map<Character, String> flags;
|
|
||||||
private int position = 0;
|
private int position = 0;
|
||||||
private Set<Character> consumedFlags = Sets.newHashSet();
|
|
||||||
|
|
||||||
public CommandArgs(List<String> arguments, Map<Character, String> flags) {
|
public CommandArgs(List<String> arguments) {
|
||||||
this.arguments = arguments;
|
this.arguments = arguments;
|
||||||
this.flags = Maps.newHashMap(flags);
|
}
|
||||||
|
|
||||||
|
public CommandArgs(CommandArgs args) {
|
||||||
|
this(Lists.newArrayList(args.arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
@ -54,6 +51,14 @@ public class CommandArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String uncheckedNext() {
|
||||||
|
if (hasNext()) {
|
||||||
|
return arguments.get(position);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String peek() throws MissingArgumentException {
|
public String peek() throws MissingArgumentException {
|
||||||
try {
|
try {
|
||||||
return arguments.get(position);
|
return arguments.get(position);
|
||||||
@ -62,6 +67,14 @@ public class CommandArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String uncheckedPeek() {
|
||||||
|
if (hasNext()) {
|
||||||
|
return arguments.get(position);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String remaining() throws MissingArgumentException {
|
public String remaining() throws MissingArgumentException {
|
||||||
if (hasNext()) {
|
if (hasNext()) {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
@ -108,206 +121,20 @@ public class CommandArgs {
|
|||||||
position = arguments.size();
|
position = arguments.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandArgs split() {
|
|
||||||
return new CommandArgs(getUnusedArguments(), getUnusedFlags());
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> getUnusedArguments() {
|
|
||||||
List<String> args = Lists.newArrayList();
|
|
||||||
while (position < arguments.size()) {
|
|
||||||
args.add(arguments.get(position++));
|
|
||||||
}
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<Character, String> getUnusedFlags() {
|
|
||||||
Map<Character, String> flags = Maps.newHashMap();
|
|
||||||
for (Entry<Character, String> entry : this.flags.entrySet()) {
|
|
||||||
if (!consumedFlags.contains(entry.getKey())) {
|
|
||||||
flags.put(entry.getKey(), entry.getValue());
|
|
||||||
consumedFlags.add(entry.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void requireAllConsumed() throws UnusedArgumentsException {
|
public void requireAllConsumed() throws UnusedArgumentsException {
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
boolean hasUnconsumed = false;
|
|
||||||
|
|
||||||
if (flags.size() > consumedFlags.size()) {
|
|
||||||
hasUnconsumed = true;
|
|
||||||
for (Entry<Character, String> entry : flags.entrySet()) {
|
|
||||||
if (!consumedFlags.contains(entry.getKey())) {
|
|
||||||
builder.append("-").append(entry.getKey()).append(" ");
|
|
||||||
if (entry.getValue() != null) {
|
|
||||||
builder.append(entry.getValue()).append(" ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasNext()) {
|
if (hasNext()) {
|
||||||
hasUnconsumed = true;
|
StringBuilder builder = new StringBuilder();
|
||||||
try {
|
try {
|
||||||
builder.append(peekRemaining());
|
builder.append(peekRemaining());
|
||||||
} catch (MissingArgumentException e) {
|
} catch (MissingArgumentException e) {
|
||||||
throw new RuntimeException("This should not have happened", e);
|
throw new RuntimeException("This should not have happened", e);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (hasUnconsumed) {
|
|
||||||
throw new UnusedArgumentsException("There were unused arguments: " + builder);
|
throw new UnusedArgumentsException("There were unused arguments: " + builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int nextInt() throws ArgumentParseException, MissingArgumentException {
|
|
||||||
String next = next();
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(next);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
throw new ArgumentParseException("Expected a number, got '" + next + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public short nextShort() throws ArgumentParseException, MissingArgumentException {
|
|
||||||
String next = next();
|
|
||||||
try {
|
|
||||||
return Short.parseShort(next);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
throw new ArgumentParseException("Expected a number, got '" + next + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte nextByte() throws ArgumentParseException, MissingArgumentException {
|
|
||||||
String next = next();
|
|
||||||
try {
|
|
||||||
return Byte.parseByte(next);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
throw new ArgumentParseException("Expected a number, got '" + next + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public double nextDouble() throws ArgumentParseException, MissingArgumentException {
|
|
||||||
String next = next();
|
|
||||||
try {
|
|
||||||
return Double.parseDouble(next);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
throw new ArgumentParseException("Expected a number, got '" + next + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float nextFloat() throws ArgumentParseException, MissingArgumentException {
|
|
||||||
String next = next();
|
|
||||||
try {
|
|
||||||
return Float.parseFloat(next);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
throw new ArgumentParseException("Expected a number, got '" + next + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean nextBoolean() throws ArgumentParseException, MissingArgumentException {
|
|
||||||
String next = next();
|
|
||||||
if (next.equalsIgnoreCase("yes") || next.equalsIgnoreCase("true") || next.equalsIgnoreCase("y") || next.equalsIgnoreCase("1")) {
|
|
||||||
return true;
|
|
||||||
} else if (next.equalsIgnoreCase("no") || next.equalsIgnoreCase("false") || next.equalsIgnoreCase("n") || next.equalsIgnoreCase("0")) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
throw new ArgumentParseException("Expected a boolean (yes/no), got '" + next + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsFlag(char c) {
|
|
||||||
boolean contains = flags.containsKey(c);
|
|
||||||
if (contains) {
|
|
||||||
consumedFlags.add(c);
|
|
||||||
}
|
|
||||||
return contains;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFlag(char c, String fallback) {
|
|
||||||
boolean contains = flags.containsKey(c);
|
|
||||||
if (contains) {
|
|
||||||
consumedFlags.add(c);
|
|
||||||
String value = flags.get(c);
|
|
||||||
if (value == null) {
|
|
||||||
return fallback;
|
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIntFlag(char c, int fallback) throws ArgumentParseException {
|
|
||||||
String next = getFlag(c, String.valueOf(fallback));
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(next);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
throw new ArgumentParseException("Expected a number for flag '-" + c + "', got '" + next + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getShortFlag(char c, short fallback) throws ArgumentParseException {
|
|
||||||
String next = getFlag(c, String.valueOf(fallback));
|
|
||||||
try {
|
|
||||||
return Short.parseShort(next);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
throw new ArgumentParseException("Expected a number for flag '-" + c + "', got '" + next + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte getByteFlag(char c, byte fallback) throws ArgumentParseException {
|
|
||||||
String next = getFlag(c, String.valueOf(fallback));
|
|
||||||
try {
|
|
||||||
return Byte.parseByte(next);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
throw new ArgumentParseException("Expected a number for flag '-" + c + "', got '" + next + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDoubleFlag(char c, double fallback) throws ArgumentParseException {
|
|
||||||
String next = getFlag(c, String.valueOf(fallback));
|
|
||||||
try {
|
|
||||||
return Double.parseDouble(next);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
throw new ArgumentParseException("Expected a number for flag '-" + c + "', got '" + next + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getFloatFlag(char c, float fallback) throws ArgumentParseException {
|
|
||||||
String next = getFlag(c, String.valueOf(fallback));
|
|
||||||
try {
|
|
||||||
return Float.parseFloat(next);
|
|
||||||
} catch (NumberFormatException ignored) {
|
|
||||||
throw new ArgumentParseException("Expected a number for flag '-" + c + "', got '" + next + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getBooleanFlag(char c, boolean fallback) throws ArgumentParseException {
|
|
||||||
String next = getFlag(c, String.valueOf(fallback));
|
|
||||||
if (next.equalsIgnoreCase("yes") || next.equalsIgnoreCase("true") || next.equalsIgnoreCase("y") || next.equalsIgnoreCase("1")) {
|
|
||||||
return true;
|
|
||||||
} else if (next.equalsIgnoreCase("no") || next.equalsIgnoreCase("false") || next.equalsIgnoreCase("n") || next.equalsIgnoreCase("0")) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
throw new ArgumentParseException("Expected a boolean (yes/no), got '" + next + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Parser {
|
public static class Parser {
|
||||||
private boolean parseFlags = true;
|
|
||||||
private boolean usingHangingArguments = false;
|
private boolean usingHangingArguments = false;
|
||||||
private Set<Character> valueFlags = Sets.newHashSet();
|
|
||||||
|
|
||||||
public boolean isParseFlags() {
|
|
||||||
return parseFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Parser setParseFlags(boolean parseFlags) {
|
|
||||||
this.parseFlags = parseFlags;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUsingHangingArguments() {
|
public boolean isUsingHangingArguments() {
|
||||||
return usingHangingArguments;
|
return usingHangingArguments;
|
||||||
@ -318,17 +145,8 @@ public class CommandArgs {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Character> getValueFlags() {
|
|
||||||
return valueFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Parser setValueFlags(Set<Character> valueFlags) {
|
|
||||||
this.valueFlags = valueFlags;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommandArgs parse(String arguments) throws CommandException {
|
public CommandArgs parse(String arguments) throws CommandException {
|
||||||
CommandContext context = new CommandContext(CommandContext.split("_ " + arguments), valueFlags, false, null, parseFlags);
|
CommandContext context = new CommandContext(CommandContext.split("_ " + arguments), Collections.<Character>emptySet(), false, null, false);
|
||||||
List<String> args = Lists.newArrayList();
|
List<String> args = Lists.newArrayList();
|
||||||
for (int i = 0; i < context.argsLength(); i++) {
|
for (int i = 0; i < context.argsLength(); i++) {
|
||||||
args.add(context.getString(i));
|
args.add(context.getString(i));
|
||||||
@ -338,11 +156,7 @@ public class CommandArgs {
|
|||||||
args.add("");
|
args.add("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Map<Character, String> flags = Maps.newHashMap(context.getValueFlags());
|
return new CommandArgs(args);
|
||||||
for (Character c : context.getFlags()) {
|
|
||||||
flags.put(c, null);
|
|
||||||
}
|
|
||||||
return new CommandArgs(args, flags);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.util.command.composition;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandException;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
|
import com.sk89q.worldedit.util.command.argument.CommandArgs;
|
||||||
|
import com.sk89q.worldedit.util.command.composition.FlagParser.FlagData;
|
||||||
|
import com.sk89q.worldedit.util.command.argument.MissingArgumentException;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
public class FlagParser implements CommandExecutor<FlagData> {
|
||||||
|
|
||||||
|
private final Map<Character, CommandExecutor<?>> flags = Maps.newHashMap();
|
||||||
|
|
||||||
|
public <T> Flag<T> registerFlag(char flag, CommandExecutor<T> executor) {
|
||||||
|
Flag<T> ret = new Flag<T>(flag);
|
||||||
|
flags.put(flag, executor);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FlagData call(CommandArgs args, CommandLocals locals) throws CommandException {
|
||||||
|
Map<Character, Object> values = Maps.newHashMap();
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
String next = args.peek();
|
||||||
|
if (next.equals("--")) {
|
||||||
|
args.next();
|
||||||
|
break;
|
||||||
|
} else if (next.length() > 0 && next.charAt(0) == '-') {
|
||||||
|
args.next();
|
||||||
|
|
||||||
|
if (next.length() == 1) {
|
||||||
|
throw new CommandException("- must be followed by a flag (like -a), otherwise use -- before the - (i.e. /cmd -- - is a dash).");
|
||||||
|
} else {
|
||||||
|
for (int i = 1; i < next.length(); i++) {
|
||||||
|
char flag = next.charAt(i);
|
||||||
|
CommandExecutor<?> executor = flags.get(flag);
|
||||||
|
if (executor != null) {
|
||||||
|
values.put(flag, executor.call(args, locals));
|
||||||
|
} else {
|
||||||
|
throw new CommandException("Unknown flag: -" + flag + " (try one of -" + Joiner.on("").join(flags.keySet()) + " or put -- to skip flag parsing, i.e. /cmd -- -this begins with a dash).");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (MissingArgumentException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return new FlagData(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getSuggestions(CommandArgs args, CommandLocals locals) throws MissingArgumentException {
|
||||||
|
List<String> suggestions = Collections.emptyList();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
String next = args.peek();
|
||||||
|
if (next.equals("--")) {
|
||||||
|
args.next();
|
||||||
|
break;
|
||||||
|
} else if (next.length() > 0 && next.charAt(0) == '-') {
|
||||||
|
args.next();
|
||||||
|
|
||||||
|
if (!args.hasNext()) { // Completing -| or -???|
|
||||||
|
List<String> flagSuggestions = Lists.newArrayList();
|
||||||
|
for (Character flag : flags.keySet()) {
|
||||||
|
if (next.indexOf(flag) < 1) { // Don't add any flags that the user has entered
|
||||||
|
flagSuggestions.add(next + flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flagSuggestions;
|
||||||
|
} else { // Completing -??? ???|
|
||||||
|
for (int i = 1; i < next.length(); i++) {
|
||||||
|
char flag = next.charAt(i);
|
||||||
|
CommandExecutor<?> executor = flags.get(flag);
|
||||||
|
if (executor != null) {
|
||||||
|
suggestions = executor.getSuggestions(args, locals);
|
||||||
|
} else {
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return suggestions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
List<String> options = Lists.newArrayList();
|
||||||
|
for (Entry<Character, CommandExecutor<?>> entry : flags.entrySet()) {
|
||||||
|
String usage = entry.getValue().getUsage();
|
||||||
|
options.add("[-" + entry.getKey() + (!usage.isEmpty() ? " " + usage : "") + "]");
|
||||||
|
}
|
||||||
|
return Joiner.on(" ").join(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Read flags";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean testPermission(CommandLocals locals) {
|
||||||
|
for (CommandExecutor<?> executor : flags.values()) {
|
||||||
|
if (!executor.testPermission(locals)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FlagData {
|
||||||
|
private final Map<Character, Object> data;
|
||||||
|
|
||||||
|
private FlagData(Map<Character, Object> data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return data.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(char key) {
|
||||||
|
return data.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(char key) {
|
||||||
|
return data.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Flag<T> {
|
||||||
|
private final char flag;
|
||||||
|
|
||||||
|
private Flag(char flag) {
|
||||||
|
this.flag = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Nullable
|
||||||
|
public T get(FlagData data) {
|
||||||
|
return (T) data.get(flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public T get(FlagData data, T fallback) {
|
||||||
|
T value = get(data);
|
||||||
|
if (value == null) {
|
||||||
|
return fallback;
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -42,17 +42,20 @@ public class LegacyCommandAdapter implements CommandCallable {
|
|||||||
@Override
|
@Override
|
||||||
public final Object call(String arguments, CommandLocals locals, String[] parentCommands) throws CommandException {
|
public final Object call(String arguments, CommandLocals locals, String[] parentCommands) throws CommandException {
|
||||||
CommandArgs args = new CommandArgs.Parser().parse(arguments);
|
CommandArgs args = new CommandArgs.Parser().parse(arguments);
|
||||||
if (args.containsFlag('?')) {
|
|
||||||
throw new CommandException(executor.getUsage());
|
if (args.hasNext()) {
|
||||||
} else {
|
if (args.uncheckedPeek().equals("-?")) {
|
||||||
Object ret = executor.call(args, locals);
|
throw new CommandException(executor.getUsage());
|
||||||
try {
|
|
||||||
args.requireAllConsumed();
|
|
||||||
} catch (UnusedArgumentsException e) {
|
|
||||||
throw new CommandException(e.getMessage());
|
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object ret = executor.call(args, locals);
|
||||||
|
try {
|
||||||
|
args.requireAllConsumed();
|
||||||
|
} catch (UnusedArgumentsException e) {
|
||||||
|
throw new CommandException(e.getMessage());
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -22,28 +22,44 @@ package com.sk89q.worldedit.util.command.composition;
|
|||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
import com.sk89q.worldedit.util.command.composition.CommandExecutor;
|
import com.sk89q.worldedit.util.command.composition.FlagParser.Flag;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class ParameterCommand<T> implements CommandExecutor<T> {
|
public abstract class ParameterCommand<T> implements CommandExecutor<T> {
|
||||||
|
|
||||||
private final List<CommandExecutor<?>> parameters = Lists.newArrayList();
|
private final List<CommandExecutor<?>> parameters = Lists.newArrayList();
|
||||||
|
private final FlagParser flagParser = new FlagParser();
|
||||||
|
|
||||||
|
public ParameterCommand() {
|
||||||
|
addParameter(flagParser);
|
||||||
|
}
|
||||||
|
|
||||||
protected List<CommandExecutor<?>> getParameters() {
|
protected List<CommandExecutor<?>> getParameters() {
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends CommandExecutor<?>> T addParameter(T executor) {
|
public <E extends CommandExecutor<?>> E addParameter(E executor) {
|
||||||
parameters.add(executor);
|
parameters.add(executor);
|
||||||
return executor;
|
return executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <E> Flag<E> addFlag(char flag, CommandExecutor<E> executor) {
|
||||||
|
return flagParser.registerFlag(flag, executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected FlagParser getFlagParser() {
|
||||||
|
return flagParser;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final String getUsage() {
|
public final String getUsage() {
|
||||||
List<String> parts = Lists.newArrayList();
|
List<String> parts = Lists.newArrayList();
|
||||||
for (CommandExecutor<?> executor : parameters) {
|
for (CommandExecutor<?> executor : parameters) {
|
||||||
parts.add(executor.getUsage());
|
String usage = executor.getUsage();
|
||||||
|
if (!usage.isEmpty()) {
|
||||||
|
parts.add(executor.getUsage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Joiner.on(" ").join(parts);
|
return Joiner.on(" ").join(parts);
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren