Check permissions in command suggestions and Dispatcher.

This commit is contained in:
sk89q 2014-06-28 16:57:11 -07:00
parent 205fee3c36
commit 10c45fcb22
6 changed files with 42 additions and 33 deletions

View File

@ -126,6 +126,7 @@ public class BukkitServerInterface extends ServerInterface {
public void registerCommands(Dispatcher dispatcher) {
List<CommandInfo> toRegister = new ArrayList<CommandInfo>();
BukkitCommandInspector inspector = new BukkitCommandInspector(plugin, dispatcher);
for (CommandMapping command : dispatcher.getCommands()) {
Description description = command.getDescription();
List<String> permissions = description.getPermissions();

View File

@ -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());
}

View File

@ -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<String> getSuggestions(String arguments) throws CommandException;
List<String> getSuggestions(String arguments, CommandLocals locals) throws CommandException;
/**
* Get an object describing this command.

View File

@ -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.
*
* <p>The returned collection cannot be modified.</p>
*
* @return a list of registrations
*/
Collection<CommandMapping> getCommands();
Set<CommandMapping> getCommands();
/**
* Get a list of primary aliases.

View File

@ -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<CommandMapping> getCommands() {
return Collections.unmodifiableCollection(commands.values());
public Set<CommandMapping> getCommands() {
return Collections.unmodifiableSet(new HashSet<CommandMapping>(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<String> 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<String> getSuggestions(String arguments) throws CommandException {
public List<String> getSuggestions(String arguments, CommandLocals locals) throws CommandException {
String[] split = CommandContext.split(arguments);
if (split.length == 0) {
return new ArrayList<String>(getAliases());
} else if (split.length == 1) {
String prefix = split[0];
if (!prefix.isEmpty()) {
List<String> suggestions = new ArrayList<String>();
if (split.length <= 1) {
String prefix = split.length > 0 ? split[0] : "";
for (String alias : getAliases()) {
if (alias.startsWith(prefix)) {
suggestions.add(alias);
List<String> suggestions = new ArrayList<String>();
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<String>(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<String> 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();

View File

@ -252,7 +252,7 @@ class ParametricCallable implements CommandCallable {
}
@Override
public List<String> getSuggestions(String stringArguments) throws CommandException {
public List<String> getSuggestions(String stringArguments, CommandLocals locals) throws CommandException {
String[] split = CommandContext.split(stringArguments);
CommandContext context = new CommandContext(split, getValueFlags());