geforkt von Mirrors/FastAsyncWorldEdit
Implemented -? and changed handling of InvalidUsageException.
Fixes WORLDEDIT-2947.
Dieser Commit ist enthalten in:
Ursprung
c29ca03e35
Commit
11d37bce2b
@ -145,7 +145,7 @@ public class CommandContext {
|
|||||||
suggestionContext = SuggestionContext.hangingValue();
|
suggestionContext = SuggestionContext.hangingValue();
|
||||||
|
|
||||||
// Not a flag?
|
// Not a flag?
|
||||||
if (arg.charAt(0) != '-' || arg.length() == 1 || !arg.matches("^-[a-zA-Z]+$")) {
|
if (arg.charAt(0) != '-' || arg.length() == 1 || !arg.matches("^-[a-zA-Z\\?]+$")) {
|
||||||
if (!isHanging) {
|
if (!isHanging) {
|
||||||
suggestionContext = SuggestionContext.lastValue();
|
suggestionContext = SuggestionContext.lastValue();
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ public class CommandException extends Exception {
|
|||||||
}
|
}
|
||||||
builder.append(spacedSuffix);
|
builder.append(spacedSuffix);
|
||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString().trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -643,8 +643,7 @@ public class UtilityCommands {
|
|||||||
|
|
||||||
actor.printRaw(ColorCodeBuilder.asColorCodes(box));
|
actor.printRaw(ColorCodeBuilder.asColorCodes(box));
|
||||||
} else {
|
} else {
|
||||||
String title = String.format("Help: %s", Joiner.on(" ").join(visited));
|
CommandUsageBox box = new CommandUsageBox(callable, Joiner.on(" ").join(visited));
|
||||||
CommandUsageBox box = new CommandUsageBox(callable.getDescription(), title);
|
|
||||||
actor.printRaw(ColorCodeBuilder.asColorCodes(box));
|
actor.printRaw(ColorCodeBuilder.asColorCodes(box));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,8 @@ import com.sk89q.worldedit.util.command.fluent.CommandGraph;
|
|||||||
import com.sk89q.worldedit.util.command.parametric.LegacyCommandsHandler;
|
import com.sk89q.worldedit.util.command.parametric.LegacyCommandsHandler;
|
||||||
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
|
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
|
||||||
import com.sk89q.worldedit.util.eventbus.Subscribe;
|
import com.sk89q.worldedit.util.eventbus.Subscribe;
|
||||||
|
import com.sk89q.worldedit.util.formatting.ColorCodeBuilder;
|
||||||
|
import com.sk89q.worldedit.util.formatting.components.CommandUsageBox;
|
||||||
import com.sk89q.worldedit.util.logging.DynamicStreamHandler;
|
import com.sk89q.worldedit.util.logging.DynamicStreamHandler;
|
||||||
import com.sk89q.worldedit.util.logging.LogFormat;
|
import com.sk89q.worldedit.util.logging.LogFormat;
|
||||||
|
|
||||||
@ -220,7 +222,17 @@ public final class CommandManager {
|
|||||||
} catch (CommandPermissionsException e) {
|
} catch (CommandPermissionsException e) {
|
||||||
actor.printError("You don't have permission to do this.");
|
actor.printError("You don't have permission to do this.");
|
||||||
} catch (InvalidUsageException e) {
|
} catch (InvalidUsageException e) {
|
||||||
actor.printError(e.getMessage() + "\nUsage: " + e.getUsage("/"));
|
if (e.isFullUsageSuggested()) {
|
||||||
|
actor.printRaw(ColorCodeBuilder.asColorCodes(new CommandUsageBox(e.getCommand(), e.toStackString("/", ""), locals)));
|
||||||
|
String message = e.getMessage();
|
||||||
|
if (message != null) {
|
||||||
|
actor.printError(message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String message = e.getMessage();
|
||||||
|
actor.printError(message != null ? message : "The command was not used properly (no more help available).");
|
||||||
|
actor.printError(e.getUsage("/"));
|
||||||
|
}
|
||||||
} catch (WrappedCommandException e) {
|
} catch (WrappedCommandException e) {
|
||||||
Throwable t = e.getCause();
|
Throwable t = e.getCause();
|
||||||
actor.printError("Please report this error: [See console]");
|
actor.printError("Please report this error: [See console]");
|
||||||
|
@ -21,29 +21,46 @@ package com.sk89q.worldedit.util.command;
|
|||||||
|
|
||||||
import com.sk89q.minecraft.util.commands.CommandException;
|
import com.sk89q.minecraft.util.commands.CommandException;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown when a command is not used properly.
|
* Thrown when a command is not used properly.
|
||||||
*/
|
*/
|
||||||
public class InvalidUsageException extends CommandException {
|
public class InvalidUsageException extends CommandException {
|
||||||
|
|
||||||
private static final long serialVersionUID = -3222004168669490390L;
|
private static final long serialVersionUID = -3222004168669490390L;
|
||||||
private final Description description;
|
private final CommandCallable command;
|
||||||
|
private final boolean fullUsageSuggested;
|
||||||
|
|
||||||
public InvalidUsageException(Description description) {
|
public InvalidUsageException(CommandCallable command) {
|
||||||
this.description = description;
|
this(null, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InvalidUsageException(String message, Description description) {
|
public InvalidUsageException(String message, CommandCallable command) {
|
||||||
|
this(message, command, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidUsageException(String message, CommandCallable command, boolean fullUsageSuggested) {
|
||||||
super(message);
|
super(message);
|
||||||
this.description = description;
|
checkNotNull(command);
|
||||||
|
this.command = command;
|
||||||
|
this.fullUsageSuggested = fullUsageSuggested;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Description getDescription() {
|
public CommandCallable getCommand() {
|
||||||
return description;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsage(String prefix) {
|
public String getUsage(String prefix) {
|
||||||
return toStackString(prefix, getDescription().getUsage());
|
return toStackString(prefix, command.getDescription().getUsage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the full usage of the command should be shown.
|
||||||
|
*
|
||||||
|
* @return show full usage
|
||||||
|
*/
|
||||||
|
public boolean isFullUsageSuggested() {
|
||||||
|
return fullUsageSuggested;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,20 @@
|
|||||||
package com.sk89q.worldedit.util.command;
|
package com.sk89q.worldedit.util.command;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.sk89q.minecraft.util.commands.*;
|
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||||
import com.sk89q.worldedit.util.formatting.ColorCodeBuilder;
|
import com.sk89q.minecraft.util.commands.CommandException;
|
||||||
import com.sk89q.worldedit.util.formatting.components.CommandListBox;
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
import com.sk89q.worldedit.util.formatting.StyledFragment;
|
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
|
||||||
|
import com.sk89q.minecraft.util.commands.WrappedCommandException;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple implementation of {@link Dispatcher}.
|
* A simple implementation of {@link Dispatcher}.
|
||||||
@ -109,7 +117,7 @@ public class SimpleDispatcher implements Dispatcher {
|
|||||||
Set<String> aliases = getPrimaryAliases();
|
Set<String> aliases = getPrimaryAliases();
|
||||||
|
|
||||||
if (aliases.isEmpty()) {
|
if (aliases.isEmpty()) {
|
||||||
throw new InvalidUsageException("This command has no sub-commands.", getDescription());
|
throw new InvalidUsageException("This command has no sub-commands.", this);
|
||||||
} else if (split.length > 0) {
|
} else if (split.length > 0) {
|
||||||
String subCommand = split[0];
|
String subCommand = split[0];
|
||||||
String subArguments = Joiner.on(" ").join(Arrays.copyOfRange(split, 1, split.length));
|
String subArguments = Joiner.on(" ").join(Arrays.copyOfRange(split, 1, split.length));
|
||||||
@ -132,7 +140,7 @@ public class SimpleDispatcher implements Dispatcher {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new InvalidUsageException(ColorCodeBuilder.asColorCodes(getSubcommandList(locals, parentCommands)), getDescription());
|
throw new InvalidUsageException("Please choose a sub-command.", this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -185,16 +193,4 @@ public class SimpleDispatcher implements Dispatcher {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private StyledFragment getSubcommandList(CommandLocals locals, String[] parentCommands) {
|
|
||||||
CommandListBox box = new CommandListBox("Subcommands");
|
|
||||||
String prefix = parentCommands.length > 0 ? "/" + Joiner.on(" ").join(parentCommands) + " " : "";
|
|
||||||
for (CommandMapping mapping : getCommands()) {
|
|
||||||
if (mapping.getCallable().testPermission(locals)) {
|
|
||||||
box.appendCommand(prefix + mapping.getPrimaryAlias(), mapping.getDescription().getShortDescription());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return box;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,15 +19,32 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.util.command.parametric;
|
package com.sk89q.worldedit.util.command.parametric;
|
||||||
|
|
||||||
import com.sk89q.minecraft.util.commands.*;
|
import com.google.common.base.Joiner;
|
||||||
import com.sk89q.worldedit.util.command.*;
|
import com.sk89q.minecraft.util.commands.Command;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandException;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
|
||||||
|
import com.sk89q.minecraft.util.commands.WrappedCommandException;
|
||||||
|
import com.sk89q.worldedit.util.command.CommandCallable;
|
||||||
|
import com.sk89q.worldedit.util.command.InvalidUsageException;
|
||||||
|
import com.sk89q.worldedit.util.command.MissingParameterException;
|
||||||
|
import com.sk89q.worldedit.util.command.Parameter;
|
||||||
|
import com.sk89q.worldedit.util.command.SimpleDescription;
|
||||||
|
import com.sk89q.worldedit.util.command.UnconsumedParameterException;
|
||||||
import com.sk89q.worldedit.util.command.binding.Switch;
|
import com.sk89q.worldedit.util.command.binding.Switch;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The implementation of a {@link CommandCallable} for the {@link ParametricBuilder}.
|
* The implementation of a {@link CommandCallable} for the {@link ParametricBuilder}.
|
||||||
@ -169,6 +186,12 @@ class ParametricCallable implements CommandCallable {
|
|||||||
String[] split = CommandContext.split(calledCommand + " " + stringArguments);
|
String[] split = CommandContext.split(calledCommand + " " + stringArguments);
|
||||||
CommandContext context = new CommandContext(split, getValueFlags(), false, locals);
|
CommandContext context = new CommandContext(split, getValueFlags(), false, locals);
|
||||||
|
|
||||||
|
// Provide help if -? is specified
|
||||||
|
if (context.hasFlag('?')) {
|
||||||
|
String title = Joiner.on(" ").join(parentCommands);
|
||||||
|
throw new InvalidUsageException(null, this, true);
|
||||||
|
}
|
||||||
|
|
||||||
Object[] args = new Object[parameters.length];
|
Object[] args = new Object[parameters.length];
|
||||||
ContextArgumentStack arguments = new ContextArgumentStack(context);
|
ContextArgumentStack arguments = new ContextArgumentStack(context);
|
||||||
ParameterData parameter = null;
|
ParameterData parameter = null;
|
||||||
@ -221,14 +244,14 @@ class ParametricCallable implements CommandCallable {
|
|||||||
handler.postInvoke(handler, method, parameters, args, context);
|
handler.postInvoke(handler, method, parameters, args, context);
|
||||||
}
|
}
|
||||||
} catch (MissingParameterException e) {
|
} catch (MissingParameterException e) {
|
||||||
throw new InvalidUsageException("Too few parameters!", getDescription());
|
throw new InvalidUsageException("Too few parameters!", this);
|
||||||
} catch (UnconsumedParameterException e) {
|
} catch (UnconsumedParameterException e) {
|
||||||
throw new InvalidUsageException("Too many parameters! Unused parameters: " + e.getUnconsumed(), getDescription());
|
throw new InvalidUsageException("Too many parameters! Unused parameters: " + e.getUnconsumed(), this);
|
||||||
} catch (ParameterException e) {
|
} catch (ParameterException e) {
|
||||||
assert parameter != null;
|
assert parameter != null;
|
||||||
String name = parameter.getName();
|
String name = parameter.getName();
|
||||||
|
|
||||||
throw new InvalidUsageException("For parameter '" + name + "': " + e.getMessage(), getDescription());
|
throw new InvalidUsageException("For parameter '" + name + "': " + e.getMessage(), this);
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
for (ExceptionConverter converter : builder.getExceptionConverters()) {
|
for (ExceptionConverter converter : builder.getExceptionConverters()) {
|
||||||
converter.convert(e.getCause());
|
converter.convert(e.getCause());
|
||||||
|
@ -19,56 +19,84 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.util.formatting.components;
|
package com.sk89q.worldedit.util.formatting.components;
|
||||||
|
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
|
import com.sk89q.worldedit.util.command.CommandCallable;
|
||||||
|
import com.sk89q.worldedit.util.command.CommandMapping;
|
||||||
import com.sk89q.worldedit.util.command.Description;
|
import com.sk89q.worldedit.util.command.Description;
|
||||||
|
import com.sk89q.worldedit.util.command.Dispatcher;
|
||||||
import com.sk89q.worldedit.util.formatting.Style;
|
import com.sk89q.worldedit.util.formatting.Style;
|
||||||
|
import com.sk89q.worldedit.util.formatting.StyledFragment;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A box to describe usage of a command.
|
* A box to describe usage of a command.
|
||||||
*/
|
*/
|
||||||
public class CommandUsageBox extends MessageBox {
|
public class CommandUsageBox extends StyledFragment {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new box.
|
* Create a new usage box.
|
||||||
*
|
*
|
||||||
* @param description the command to describe
|
* @param command the command to describe
|
||||||
* @param title the title
|
* @param commandString the command that was used, such as "/we" or "/brush sphere"
|
||||||
*/
|
*/
|
||||||
public CommandUsageBox(Description description, String title) {
|
public CommandUsageBox(CommandCallable command, String commandString) {
|
||||||
super(title);
|
this(command, commandString, null);
|
||||||
checkNotNull(description);
|
|
||||||
attachCommandUsage(description);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new box.
|
* Create a new usage box.
|
||||||
*
|
*
|
||||||
* @param description the command to describe
|
* @param command the command to describe
|
||||||
|
* @param commandString the command that was used, such as "/we" or "/brush sphere"
|
||||||
|
* @param locals list of locals to use
|
||||||
*/
|
*/
|
||||||
public CommandUsageBox(Description description) {
|
public CommandUsageBox(CommandCallable command, String commandString, @Nullable CommandLocals locals) {
|
||||||
super("Usage Help");
|
checkNotNull(command);
|
||||||
checkNotNull(description);
|
checkNotNull(commandString);
|
||||||
attachCommandUsage(description);
|
if (command instanceof Dispatcher) {
|
||||||
}
|
attachDispatcherUsage((Dispatcher) command, commandString, locals);
|
||||||
|
|
||||||
private void attachCommandUsage(Description description) {
|
|
||||||
if (description.getUsage() != null) {
|
|
||||||
getContents().append(new Label().append("Usage: "));
|
|
||||||
getContents().append(description.getUsage());
|
|
||||||
} else {
|
} else {
|
||||||
getContents().append(new Subtle().append("Usage information is not available."));
|
attachCommandUsage(command.getDescription(), commandString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void attachDispatcherUsage(Dispatcher dispatcher, String commandString, @Nullable CommandLocals locals) {
|
||||||
|
CommandListBox box = new CommandListBox("Subcommands");
|
||||||
|
String prefix = !commandString.isEmpty() ? commandString + " " : "";
|
||||||
|
for (CommandMapping mapping : dispatcher.getCommands()) {
|
||||||
|
if (locals == null || mapping.getCallable().testPermission(locals)) {
|
||||||
|
box.appendCommand(prefix + mapping.getPrimaryAlias(), mapping.getDescription().getShortDescription());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getContents().newLine();
|
append(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void attachCommandUsage(Description description, String commandString) {
|
||||||
|
MessageBox box = new MessageBox("Help for " + commandString);
|
||||||
|
StyledFragment contents = box.getContents();
|
||||||
|
|
||||||
|
if (description.getUsage() != null) {
|
||||||
|
contents.append(new Label().append("Usage: "));
|
||||||
|
contents.append(description.getUsage());
|
||||||
|
} else {
|
||||||
|
contents.append(new Subtle().append("Usage information is not available."));
|
||||||
|
}
|
||||||
|
|
||||||
|
contents.newLine();
|
||||||
|
|
||||||
if (description.getHelp() != null) {
|
if (description.getHelp() != null) {
|
||||||
getContents().createFragment(Style.YELLOW_DARK).append(description.getHelp());
|
contents.createFragment(Style.YELLOW_DARK).append(description.getHelp());
|
||||||
} else if (description.getShortDescription() != null) {
|
} else if (description.getShortDescription() != null) {
|
||||||
getContents().createFragment(Style.YELLOW_DARK).append(description.getShortDescription());
|
contents.append(description.getShortDescription());
|
||||||
} else {
|
} else {
|
||||||
getContents().append(new Subtle().append("No further help is available."));
|
contents.append(new Subtle().append("No further help is available."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
append(box);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren