diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java index 8bf7f874b..bf08bf45a 100644 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java @@ -126,6 +126,7 @@ public class BukkitServerInterface extends ServerInterface { public void registerCommands(Dispatcher dispatcher) { List toRegister = new ArrayList(); BukkitCommandInspector inspector = new BukkitCommandInspector(plugin, dispatcher); + for (CommandMapping command : dispatcher.getCommands()) { Description description = command.getDescription(); List permissions = description.getPermissions(); diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java b/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java index 77c98a618..41f1e471f 100644 --- a/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java +++ b/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java @@ -258,7 +258,9 @@ public final class CommandManager { @Subscribe public void handleCommandSuggestion(CommandSuggestionEvent event) { try { - event.setSuggestions(dispatcher.getSuggestions(event.getArguments())); + CommandLocals locals = new CommandLocals(); + locals.put(Actor.class, event.getActor()); + event.setSuggestions(dispatcher.getSuggestions(event.getArguments(), locals)); } catch (CommandException e) { event.getActor().printError(e.getMessage()); } diff --git a/src/main/java/com/sk89q/worldedit/util/command/CommandCallable.java b/src/main/java/com/sk89q/worldedit/util/command/CommandCallable.java index 1120dffc8..d8254f4bf 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/CommandCallable.java +++ b/src/main/java/com/sk89q/worldedit/util/command/CommandCallable.java @@ -56,10 +56,11 @@ public interface CommandCallable { * Get a list of suggestions based on input. * * @param arguments the arguments entered up to this point + * @param locals the locals * @return a list of suggestions * @throws CommandException thrown if there was a parsing error */ - List getSuggestions(String arguments) throws CommandException; + List getSuggestions(String arguments, CommandLocals locals) throws CommandException; /** * Get an object describing this command. diff --git a/src/main/java/com/sk89q/worldedit/util/command/Dispatcher.java b/src/main/java/com/sk89q/worldedit/util/command/Dispatcher.java index 3ca0419da..568db508e 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/Dispatcher.java +++ b/src/main/java/com/sk89q/worldedit/util/command/Dispatcher.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.util.command; import javax.annotation.Nullable; import java.util.Collection; +import java.util.Set; /** * Executes a command based on user input. @@ -36,13 +37,14 @@ public interface Dispatcher extends CommandCallable { void registerCommand(CommandCallable callable, String... alias); /** - * Get a list of command registrations. + * Get a list of commands. Each command, regardless of how many aliases + * it may have, will only appear once in the returned set. * *

The returned collection cannot be modified.

* * @return a list of registrations */ - Collection getCommands(); + Set getCommands(); /** * Get a list of primary aliases. diff --git a/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java b/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java index 79a7c672b..2dc778f49 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java +++ b/src/main/java/com/sk89q/worldedit/util/command/SimpleDispatcher.java @@ -20,10 +20,7 @@ package com.sk89q.worldedit.util.command; import com.google.common.base.Joiner; -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.WrappedCommandException; +import com.sk89q.minecraft.util.commands.*; import javax.annotation.Nullable; import java.util.*; @@ -56,8 +53,8 @@ public class SimpleDispatcher implements Dispatcher { } @Override - public Collection getCommands() { - return Collections.unmodifiableCollection(commands.values()); + public Set getCommands() { + return Collections.unmodifiableSet(new HashSet(commands.values())); } @Override @@ -91,6 +88,11 @@ public class SimpleDispatcher implements Dispatcher { @Override public boolean call(@Nullable String alias, String arguments, CommandLocals locals) throws CommandException { + // We have permission for this command if we have permissions for subcommands + if (!testPermission(locals)) { + throw new CommandPermissionsException(); + } + String[] split = CommandContext.split(arguments); Set aliases = getPrimaryAliases(); @@ -116,37 +118,37 @@ public class SimpleDispatcher implements Dispatcher { } - throw new InvalidUsageException(getSubcommandList(), getDescription()); + throw new InvalidUsageException(getSubcommandList(locals), getDescription()); } @Override - public List getSuggestions(String arguments) throws CommandException { + public List getSuggestions(String arguments, CommandLocals locals) throws CommandException { String[] split = CommandContext.split(arguments); - if (split.length == 0) { - return new ArrayList(getAliases()); - } else if (split.length == 1) { - String prefix = split[0]; - if (!prefix.isEmpty()) { - List suggestions = new ArrayList(); + if (split.length <= 1) { + String prefix = split.length > 0 ? split[0] : ""; - for (String alias : getAliases()) { - if (alias.startsWith(prefix)) { - suggestions.add(alias); + List suggestions = new ArrayList(); + + for (CommandMapping mapping : getCommands()) { + if (mapping.getCallable().testPermission(locals)) { + for (String alias : mapping.getAllAliases()) { + if (prefix.isEmpty() || alias.startsWith(arguments)) { + suggestions.add(mapping.getPrimaryAlias()); + break; + } } } - - return suggestions; - } else { - return new ArrayList(getAliases()); } + + return suggestions; } else { String subCommand = split[0]; CommandMapping mapping = get(subCommand); String passedArguments = Joiner.on(" ").join(Arrays.copyOfRange(split, 1, split.length)); if (mapping != null) { - return mapping.getCallable().getSuggestions(passedArguments); + return mapping.getCallable().getSuggestions(passedArguments, locals); } else { return Collections.emptyList(); } @@ -174,16 +176,17 @@ public class SimpleDispatcher implements Dispatcher { * * @return a string */ - private String getSubcommandList() { + private String getSubcommandList(CommandLocals locals) { Set aliases = getPrimaryAliases(); StringBuilder builder = new StringBuilder("Subcommands: "); - for (String alias : getPrimaryAliases()) { - builder.append("\n- ").append(alias); - } - if (aliases.size() == 1) { - builder.append(" (there is only one)"); + for (CommandMapping mapping : getCommands()) { + if (mapping.getCallable().testPermission(locals)) { + for (String alias : mapping.getAllAliases()) { + builder.append("\n- ").append(alias); + } + } } return builder.toString(); diff --git a/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java b/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java index bada21862..46b8e12ff 100644 --- a/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java +++ b/src/main/java/com/sk89q/worldedit/util/command/parametric/ParametricCallable.java @@ -252,7 +252,7 @@ class ParametricCallable implements CommandCallable { } @Override - public List getSuggestions(String stringArguments) throws CommandException { + public List getSuggestions(String stringArguments, CommandLocals locals) throws CommandException { String[] split = CommandContext.split(stringArguments); CommandContext context = new CommandContext(split, getValueFlags());