#305 Modularize logic / separate from data classes (wip – doesn't compile)

- Remove permission logic on command side; make PermissionsManager handle checks for all CommandSender objects (not only Player), cf. #314
- Remove unnecessary redundancies in passed arguments ("command references" that can be inferred from the FoundResult)
- Extend FoundCommandResult to represent all possible error cases
This commit is contained in:
ljacqu 2015-12-12 00:43:55 +01:00
parent ec9009d776
commit 2f153fb85c
8 changed files with 178 additions and 245 deletions

View File

@ -214,11 +214,9 @@ public class AuthMe extends JavaPlugin {
plugin = this; plugin = this;
setupConstants(); setupConstants();
// Set up the permissions manager // Set up the permissions manager and command handler
setupPermissionsManager(); permsMan = initializePermissionsManager();
commandHandler = new CommandHandler(CommandInitializer.getBaseCommands(), permsMan);
// Set up and initialize the command handler
setupCommandHandler();
// Set up the module manager // Set up the module manager
setupModuleManager(); setupModuleManager();
@ -433,8 +431,8 @@ public class AuthMe extends JavaPlugin {
/** /**
* Set up the command handler. * Set up the command handler.
*/ */
private void setupCommandHandler() { private void setupCommandHandler(PermissionsManager permissionsManager) {
this.commandHandler = new CommandHandler(CommandInitializer.getBaseCommands()); this.commandHandler = new CommandHandler(CommandInitializer.getBaseCommands(), permissionsManager);
} }
/** /**
@ -606,9 +604,10 @@ public class AuthMe extends JavaPlugin {
/** /**
* Set up the permissions manager. * Set up the permissions manager.
*/ */
public void setupPermissionsManager() { private PermissionsManager initializePermissionsManager() {
this.permsMan = new PermissionsManager(Bukkit.getServer(), this, getLogger()); PermissionsManager manager = new PermissionsManager(Bukkit.getServer(), this, getLogger());
this.permsMan.setup(); manager.setup();
return manager;
} }
/** /**

View File

@ -14,6 +14,7 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import static com.google.common.base.Objects.firstNonNull; import static com.google.common.base.Objects.firstNonNull;
import static java.util.Arrays.asList;
/** /**
* Command description - defines which labels ("names") will lead to a command and points to the * Command description - defines which labels ("names") will lead to a command and points to the
@ -31,15 +32,15 @@ public class CommandDescription {
*/ */
private List<String> labels; private List<String> labels;
/** /**
* Command description. * Short description of the command.
*/ */
private String description; private String description;
/** /**
* Detailed description of the command. * Detailed description of what the command does.
*/ */
private String detailedDescription; private String detailedDescription;
/** /**
* The executable command instance. * The executable command instance described by this object.
*/ */
private ExecutableCommand executableCommand; private ExecutableCommand executableCommand;
/** /**
@ -55,7 +56,7 @@ public class CommandDescription {
*/ */
private List<CommandArgumentDescription> arguments; private List<CommandArgumentDescription> arguments;
/** /**
* Defines the command permissions. * Command permissions required to execute this command.
*/ */
private CommandPermissions permissions; private CommandPermissions permissions;
@ -106,9 +107,10 @@ public class CommandDescription {
} }
/** /**
* Get all relative command labels. * Get all relative labels of this command. For example, if this object describes "/authme register" and
* "/authme r", then "r" and "register" are the relative labels, whereas "authme" is the label of the parent.
* *
* @return All relative labels labels. * @return All relative labels.
*/ */
public List<String> getLabels() { public List<String> getLabels() {
return this.labels; return this.labels;
@ -117,9 +119,9 @@ public class CommandDescription {
/** /**
* Check whether this command description has a specific command. * Check whether this command description has a specific command.
* *
* @param commandLabel Command to check for. * @param commandLabel The label to check for.
* *
* @return True if this command label equals to the param command. * @return {@code true} if this command contains the given label, {@code false} otherwise.
*/ */
public boolean hasLabel(String commandLabel) { public boolean hasLabel(String commandLabel) {
for (String label : labels) { for (String label : labels) {
@ -131,25 +133,25 @@ public class CommandDescription {
} }
/** /**
* Get the executable command. * Return the {@link ExecutableCommand} instance defined by the command description.
* *
* @return The executable command. * @return The executable command object.
*/ */
public ExecutableCommand getExecutableCommand() { public ExecutableCommand getExecutableCommand() {
return this.executableCommand; return executableCommand;
} }
/** /**
* Get the parent command if this command description has a parent. * Return the parent.
* *
* @return Parent command, or null * @return The parent command, or null for base commands.
*/ */
public CommandDescription getParent() { public CommandDescription getParent() {
return this.parent; return parent;
} }
/** /**
* Get all command children. * Return all command children.
* *
* @return Command children. * @return Command children.
*/ */
@ -159,7 +161,7 @@ public class CommandDescription {
/** /**
* Get all command arguments. * Return all arguments the command takes.
* *
* @return Command arguments. * @return Command arguments.
*/ */
@ -168,16 +170,7 @@ public class CommandDescription {
} }
/** /**
* Check whether this command has any arguments. * Return a short description of the command.
*
* @return True if this command has any arguments.
*/
public boolean hasArguments() {
return !getArguments().isEmpty();
}
/**
* Get the command description.
* *
* @return Command description. * @return Command description.
*/ */
@ -186,9 +179,9 @@ public class CommandDescription {
} }
/** /**
* Get the command detailed description. * Return a detailed description of the command.
* *
* @return Command detailed description. * @return Detailed description.
*/ */
public String getDetailedDescription() { public String getDetailedDescription() {
return detailedDescription; return detailedDescription;
@ -196,14 +189,19 @@ public class CommandDescription {
/** /**
* Get the command permissions. Return null if the command doesn't require any permission. * Return the permissions required to execute the command.
* *
* @return The command permissions. * @return The command permissions, or null if none are required to execute the command.
*/ */
public CommandPermissions getCommandPermissions() { public CommandPermissions getCommandPermissions() {
return this.permissions; return this.permissions;
} }
/**
* Return a builder instance to create a new command description.
*
* @return The builder
*/
public static CommandBuilder builder() { public static CommandBuilder builder() {
return new CommandBuilder(); return new CommandBuilder();
} }
@ -221,12 +219,11 @@ public class CommandDescription {
private CommandPermissions permissions; private CommandPermissions permissions;
/** /**
* Build a CommandDescription from the builder or throw an exception if mandatory * Build a CommandDescription from the builder or throw an exception if a mandatory
* fields have not been set. * field has not been set.
* *
* @return The generated CommandDescription object * @return The generated CommandDescription object
*/ */
// TODO ljacqu 20151206 Move validation to the create instance method
public CommandDescription build() { public CommandDescription build() {
return createInstance( return createInstance(
getOrThrow(labels, "labels"), getOrThrow(labels, "labels"),
@ -245,7 +242,7 @@ public class CommandDescription {
} }
public CommandBuilder labels(String... labels) { public CommandBuilder labels(String... labels) {
return labels(asMutableList(labels)); return labels(asList(labels));
} }
public CommandBuilder description(String description) { public CommandBuilder description(String description) {
@ -274,7 +271,7 @@ public class CommandDescription {
* *
* @param label The label of the argument (single word name of the argument) * @param label The label of the argument (single word name of the argument)
* @param description The description of the argument * @param description The description of the argument
* @param isOptional True if the argument is option, false if it is mandatory * @param isOptional True if the argument is optional, false if it is mandatory
* *
* @return The builder * @return The builder
*/ */
@ -291,7 +288,7 @@ public class CommandDescription {
@SafeVarargs @SafeVarargs
private static <T> List<T> asMutableList(T... items) { private static <T> List<T> asMutableList(T... items) {
return new ArrayList<>(Arrays.asList(items)); return new ArrayList<>(asList(items));
} }
private static <T> T getOrThrow(T element, String elementName) { private static <T> T getOrThrow(T element, String elementName) {

View File

@ -6,6 +6,7 @@ import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.util.CollectionUtils; import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.ArrayList; import java.util.ArrayList;
@ -56,16 +57,16 @@ public class CommandHandler {
FoundCommandResult result = mapPartsToCommand(parts); FoundCommandResult result = mapPartsToCommand(parts);
switch (result.getResultStatus()) { switch (result.getResultStatus()) {
case SUCCESS: case SUCCESS:
// Check perms + process executeCommandIfAllowed(sender, result.getCommandDescription(), result.getArguments());
break; break;
case MISSING_BASE_COMMAND: case MISSING_BASE_COMMAND:
sender.sendMessage(ChatColor.DARK_RED + "Failed to parse " + AuthMe.getPluginName() + " command!"); sender.sendMessage(ChatColor.DARK_RED + "Failed to parse " + AuthMe.getPluginName() + " command!");
return false; return false;
case INCORRECT_ARGUMENTS: case INCORRECT_ARGUMENTS:
// sendImproperArgumentsMessage(sender, result); sendImproperArgumentsMessage(sender, result);
break; break;
case UNKNOWN_LABEL: case UNKNOWN_LABEL:
// sendUnknownCommandMessage(sender); sendUnknownCommandMessage(sender, result);
break; break;
default: default:
throw new RuntimeException("Unknown result '" + result.getResultStatus() + "'"); throw new RuntimeException("Unknown result '" + result.getResultStatus() + "'");
@ -74,6 +75,14 @@ public class CommandHandler {
return true; return true;
} }
private void executeCommandIfAllowed(CommandSender sender, CommandDescription command, List<String> arguments) {
if (permissionsManager.hasPermission(sender, command)) {
command.getExecutableCommand().executeCommand(sender, arguments);
} else {
sendPermissionDeniedError(sender);
}
}
/** /**
* Skip all entries of the given array that are simply whitespace. * Skip all entries of the given array that are simply whitespace.
* *
@ -81,7 +90,7 @@ public class CommandHandler {
* @return List of the items that are not empty * @return List of the items that are not empty
*/ */
private static List<String> skipEmptyArguments(String[] args) { private static List<String> skipEmptyArguments(String[] args) {
List<String> cleanArguments = new ArrayList<>(args.length); List<String> cleanArguments = new ArrayList<>();
for (String argument : args) { for (String argument : args) {
if (!StringUtils.isEmpty(argument)) { if (!StringUtils.isEmpty(argument)) {
cleanArguments.add(argument); cleanArguments.add(argument);
@ -90,16 +99,14 @@ public class CommandHandler {
return cleanArguments; return cleanArguments;
} }
/** /**
* Show an "unknown command" to the user and suggests an existing command if its similarity is within * Show an "unknown command" to the user and suggests an existing command if its similarity is within
* the defined threshold. * the defined threshold.
* *
* @param sender The command sender * @param sender The command sender
* @param result The command that was found during the mapping process * @param result The command that was found during the mapping process
* @param baseCommand The base command
*/ */
private static void sendUnknownCommandMessage(CommandSender sender, FoundCommandResult result, String baseCommand) { private static void sendUnknownCommandMessage(CommandSender sender, FoundCommandResult result) {
sender.sendMessage(ChatColor.DARK_RED + "Unknown command!"); sender.sendMessage(ChatColor.DARK_RED + "Unknown command!");
// Show a command suggestion if available and the difference isn't too big // Show a command suggestion if available and the difference isn't too big
@ -109,27 +116,29 @@ public class CommandHandler {
// TODO: Define a proper string representation of command description // TODO: Define a proper string representation of command description
} }
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help" sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + result.getLabels().get(0)
+ ChatColor.YELLOW + " to view help."); + " help" + ChatColor.YELLOW + " to view help.");
} }
private static void sendImproperArgumentsMessage(CommandSender sender, FoundCommandResult result, private void sendImproperArgumentsMessage(CommandSender sender, FoundCommandResult result) {
CommandParts commandReference, String baseCommand) { CommandDescription command = result.getCommandDescription();
// Get the command and the suggested command reference if (!permissionsManager.hasPermission(sender, command)) {
// FIXME List<String> suggestedCommandReference = sendPermissionDeniedError(sender);
// result.getCommandDescription().getCommandReference(commandReference).getList(); return;
// List<String> helpCommandReference = CollectionUtils.getRange(suggestedCommandReference, 1); }
// Show the invalid arguments warning
sender.sendMessage(ChatColor.DARK_RED + "Incorrect command arguments!");
// Show the command argument help // Show the command argument help
// HelpProvider.showHelp(sender, commandReference, new CommandParts(suggestedCommandReference), sender.sendMessage(ChatColor.DARK_RED + "Incorrect command arguments!");
// true, false, true, false, false, false); // TODO: Define showHelp(CommandSender, CommandDescription, List<String>, boolean, boolean, ...)
List<String> labels = result.getLabels();
HelpProvider.showHelp(sender, command, labels, true, false, true, false, false, false);
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + labels.get(0)
+ " help " + CommandUtils.labelsToString(labels.subList(1, labels.size())));
}
// Show the command to use for detailed help // TODO ljacqu 20151212: Remove me once I am a MessageKey
// sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + baseCommand private void sendPermissionDeniedError(CommandSender sender) {
// + " help " + CommandUtils.labelsToString(helpCommandReference)); sender.sendMessage(ChatColor.DARK_RED + "You don't have permission to use this command!");
} }
public FoundCommandResult mapPartsToCommand(final List<String> parts) { public FoundCommandResult mapPartsToCommand(final List<String> parts) {
@ -144,64 +153,50 @@ public class CommandHandler {
// Prefer labels: /register help goes to "Help command", not "Register command" with argument 'help' // Prefer labels: /register help goes to "Help command", not "Register command" with argument 'help'
List<String> remaining = parts.subList(1, parts.size()); List<String> remaining = parts.subList(1, parts.size());
CommandDescription childCommand = returnSuitableChild(base, remaining); CommandDescription childCommand = getSuitableChild(base, remaining);
if (childCommand != null) { if (childCommand != null) {
return new FoundCommandResult(childCommand, parts.subList(2, parts.size()), parts.subList(0, 2)); return new FoundCommandResult(childCommand, parts.subList(2, parts.size()), parts.subList(0, 2));
} else if (isSuitableArgumentCount(base, remaining.size())) { } else if (isSuitableArgumentCount(base, remaining.size())) {
return new FoundCommandResult(base, parts.subList(1, parts.size()), parts.subList(0, 1)); return new FoundCommandResult(base, parts.subList(1, parts.size()), parts.subList(0, 1));
} }
// TODO: return getCommandWithSmallestDifference() return getCommandWithSmallestDifference(base, parts);
return null;
} }
// TODO: Return FoundCommandDescription immediately private FoundCommandResult getCommandWithSmallestDifference(CommandDescription base, List<String> parts) {
private CommandDescription getCommandWithSmallestDifference(CommandDescription base, List<String> parts) {
final String label = parts.get(0); final String label = parts.get(0);
final int argumentCount = parts.size() - 1; final int argumentCount = parts.size() - 1;
double minDifference = Double.POSITIVE_INFINITY; double minDifference = Double.POSITIVE_INFINITY;
CommandDescription closestCommand = null; CommandDescription closestCommand = null;
for (CommandDescription child : base.getChildren()) { for (CommandDescription child : base.getChildren()) {
double argumentDifference = getArgumentCountDifference(child, argumentCount);
double labelDifference = getLabelDifference(child, label); double labelDifference = getLabelDifference(child, label);
double argumentDifference = getArgumentCountDifference(child, argumentCount);
// Weigh argument difference less // Weigh argument difference less
double difference = labelDifference + argumentCount / 2; double difference = labelDifference + argumentDifference / 2;
if (difference < minDifference) { if (difference < minDifference) {
minDifference = difference; minDifference = difference;
closestCommand = child; closestCommand = child;
} }
} }
return closestCommand; // TODO: Return the full list of labels and arguments
// TODO: Also compare the base command and suggest it if it's the most similar
return new FoundCommandResult(
closestCommand, null, null, minDifference, FoundCommandResult.ResultStatus.UNKNOWN_LABEL);
} }
private static boolean isSuitableArgumentCount(CommandDescription command, int argumentCount) { private CommandDescription getBaseCommand(String label) {
int minArgs = CommandUtils.getMinNumberOfArguments(command); String baseLabel = label.toLowerCase();
int maxArgs = CommandUtils.getMaxNumberOfArguments(command); for (CommandDescription command : baseCommands) {
if (command.hasLabel(baseLabel)) {
return argumentCount >= minArgs && argumentCount <= maxArgs; return command;
}
private static double getLabelDifference(CommandDescription command, String givenLabel) {
double minDifference = Double.POSITIVE_INFINITY;
for (String commandLabel : command.getLabels()) {
double difference = StringUtils.getDifference(commandLabel, givenLabel);
if (difference < minDifference) {
minDifference = difference;
} }
} }
return minDifference; return null;
}
private static int getArgumentCountDifference(CommandDescription commandDescription, int givenArgumentsCount) {
return Math.min(
Math.abs(givenArgumentsCount - CommandUtils.getMinNumberOfArguments(commandDescription)),
Math.abs(givenArgumentsCount - CommandUtils.getMaxNumberOfArguments(commandDescription)));
} }
// Is the given command a suitable match for the given parts? parts is for example [changepassword, newpw, newpw] // Is the given command a suitable match for the given parts? parts is for example [changepassword, newpw, newpw]
public CommandDescription returnSuitableChild(CommandDescription baseCommand, List<String> parts) { private CommandDescription getSuitableChild(CommandDescription baseCommand, List<String> parts) {
if (CollectionUtils.isEmpty(parts)) { if (CollectionUtils.isEmpty(parts)) {
return null; return null;
} }
@ -217,14 +212,28 @@ public class CommandHandler {
return null; return null;
} }
private CommandDescription getBaseCommand(String label) { private static boolean isSuitableArgumentCount(CommandDescription command, int argumentCount) {
String baseLabel = label.toLowerCase(); int minArgs = CommandUtils.getMinNumberOfArguments(command);
for (CommandDescription command : baseCommands) { int maxArgs = CommandUtils.getMaxNumberOfArguments(command);
if (command.hasLabel(baseLabel)) {
return command; return argumentCount >= minArgs && argumentCount <= maxArgs;
}
private static int getArgumentCountDifference(CommandDescription commandDescription, int givenArgumentsCount) {
return Math.min(
Math.abs(givenArgumentsCount - CommandUtils.getMinNumberOfArguments(commandDescription)),
Math.abs(givenArgumentsCount - CommandUtils.getMaxNumberOfArguments(commandDescription)));
}
private static double getLabelDifference(CommandDescription command, String givenLabel) {
double minDifference = Double.POSITIVE_INFINITY;
for (String commandLabel : command.getLabels()) {
double difference = StringUtils.getDifference(commandLabel, givenLabel);
if (difference < minDifference) {
minDifference = difference;
} }
} }
return null; return minDifference;
} }
} }

View File

@ -1,8 +1,5 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import java.util.List;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
public final class CommandUtils { public final class CommandUtils {
@ -32,26 +29,4 @@ public final class CommandUtils {
return StringUtils.join(" ", labels); return StringUtils.join(" ", labels);
} }
public static double getDifference(List<String> labels1, List<String> labels2, boolean fullCompare) {
// Make sure the other reference is correct
if (labels1 == null || labels2 == null) {
return -1;
}
// Get the range to use
int range = Math.min(labels1.size(), labels2.size());
// Get and the difference
if (fullCompare) {
return StringUtils.getDifference(CommandUtils.labelsToString(labels1), CommandUtils.labelsToString(labels2));
}
return StringUtils.getDifference(
labelsToString(CollectionUtils.getRange(labels1, range - 1, 1)),
labelsToString(CollectionUtils.getRange(labels2, range - 1, 1)));
}
} }

View File

@ -1,6 +1,6 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import org.bukkit.command.CommandSender; import java.util.List;
/** /**
*/ */
@ -9,47 +9,39 @@ public class FoundCommandResult {
/** /**
* The command description instance. * The command description instance.
*/ */
private CommandDescription commandDescription; private final CommandDescription commandDescription;
/**
* The command reference.
*/
private final CommandParts commandReference;
/** /**
* The command arguments. * The command arguments.
*/ */
private final CommandParts commandArguments; private final List<String> arguments;
/** /**
* The original search query reference. * The labels used to invoke the command. This may be different for the same {@link ExecutableCommand} instance
* if multiple labels have been defined, e.g. "/authme register" and "/authme reg".
*/ */
private final CommandParts queryReference; private final List<String> labels;
private final double difference;
private final ResultStatus resultStatus;
/** /**
* Constructor. * Constructor.
* *
* @param commandDescription The command description. * @param commandDescription The command description.
* @param commandReference The command reference. * @param arguments The command arguments.
* @param commandArguments The command arguments. * @param labels The original query reference.
* @param queryReference The original query reference.
*/ */
public FoundCommandResult(CommandDescription commandDescription, CommandParts commandReference, CommandParts commandArguments, CommandParts queryReference) { public FoundCommandResult(CommandDescription commandDescription, List<String> arguments, List<String> labels,
double difference, ResultStatus resultStatus) {
this.commandDescription = commandDescription; this.commandDescription = commandDescription;
this.commandReference = commandReference; this.arguments = arguments;
this.commandArguments = commandArguments; this.labels = labels;
this.queryReference = queryReference; this.difference = difference;
this.resultStatus = resultStatus;
} }
/** public FoundCommandResult(CommandDescription commandDescription, List<String> arguments, List<String> labels) {
* Check whether the command was suitable. this(commandDescription, arguments, labels, 0.0, ResultStatus.SUCCESS);
*
* @return True if the command was suitable, false otherwise.
*/
public boolean hasProperArguments() {
// Make sure the command description is set
if (this.commandDescription == null)
return false;
// Get and return the result
return getCommandDescription().getSuitableArgumentsDifference(this.queryReference) == 0;
} }
/** /**
@ -61,66 +53,14 @@ public class FoundCommandResult {
return this.commandDescription; return this.commandDescription;
} }
/**
* Check whether the command is executable.
*
* @return True if the command is executable, false otherwise.
*/
public boolean isExecutable() {
return commandDescription != null;
}
/**
* Execute the command.
*
* @param sender The command sender that executed the command.
*
* @return True on success, false on failure.
*/
public boolean executeCommand(CommandSender sender) {
// Make sure the command description is valid
if (this.commandDescription == null)
return false;
// Execute the command
return this.commandDescription.execute(sender, this.commandReference, this.commandArguments);
}
/**
* Check whether a command sender has permission to execute the command.
*
* @param sender The command sender.
*
* @return True if the command sender has permission, false otherwise.
*/
public boolean hasPermission(CommandSender sender) {
if (commandDescription == null) {
return false;
} else if (commandDescription.getCommandPermissions() == null) {
return true;
}
// TODO: Move permissions check to the permission package; command package should not define permission-checking
// API
return commandDescription.getCommandPermissions().hasPermission(sender);
}
/**
* Get the command reference.
*
* @return The command reference.
*/
public CommandParts getCommandReference() {
return this.commandReference;
}
/** /**
* Get the command arguments. * Get the command arguments.
* *
* @return The command arguments. * @return The command arguments.
*/ */
public CommandParts getCommandArguments() { public List<String> getArguments() {
return this.commandArguments; return this.arguments;
} }
/** /**
@ -128,22 +68,26 @@ public class FoundCommandResult {
* *
* @return Original query reference. * @return Original query reference.
*/ */
public CommandParts getQueryReference() { public List<String> getLabels() {
return this.queryReference; return this.labels;
} }
/**
* Get the difference value between the original query and the result reference.
*
* @return The difference value.
*/
public double getDifference() { public double getDifference() {
// Get the difference through the command found return difference;
if (this.commandDescription != null) { }
return this.commandDescription.getCommandDifference(this.queryReference);
}
// Get the difference from the query reference public ResultStatus getResultStatus() {
return CommandUtils.getDifference(queryReference.getList(), commandReference.getList(), true); return resultStatus;
}
public enum ResultStatus {
SUCCESS,
INCORRECT_ARGUMENTS,
UNKNOWN_LABEL,
MISSING_BASE_COMMAND
} }
} }

View File

@ -301,19 +301,24 @@ public class PermissionsManager implements PermissionsService {
/** /**
* Check if the player has permission for the given permissions node. If no permissions system is used, * Check if the command sender has permission for the given permissions node. If no permissions system is used or
* the player has to be OP in order to have the permission. * if the sender is not a player (e.g. console user), the player has to be OP in order to have the permission.
* *
* @param player The player. * @param sender The command sender.
* @param permissionNode The permissions node to verify. * @param permissionNode The permissions node to verify.
* *
* @return True if the player has the permission, false otherwise. * @return True if the sender has the permission, false otherwise.
*/ */
public boolean hasPermission(Player player, PermissionNode permissionNode) { public boolean hasPermission(CommandSender sender, PermissionNode permissionNode) {
return hasPermission(player, permissionNode, player.isOp()); return hasPermission(sender, permissionNode, sender.isOp());
} }
public boolean hasPermission(Player player, PermissionNode permissionNode, boolean def) { public boolean hasPermission(CommandSender sender, PermissionNode permissionNode, boolean def) {
if (!(sender instanceof Player)) {
return def;
}
Player player = (Player) sender;
return hasPermission(player, permissionNode.getNode(), def) return hasPermission(player, permissionNode.getNode(), def)
|| hasPermission(player, permissionNode.getWildcardNode().getNode(), def); || hasPermission(player, permissionNode.getWildcardNode().getNode(), def);
} }
@ -327,15 +332,17 @@ public class PermissionsManager implements PermissionsService {
return true; return true;
} }
public boolean hasPermission(Player player, CommandDescription command) { public boolean hasPermission(CommandSender sender, CommandDescription command) {
if (command.getCommandPermissions() == null if (command.getCommandPermissions() == null
|| CollectionUtils.isEmpty(command.getCommandPermissions().getPermissionNodes())) { || CollectionUtils.isEmpty(command.getCommandPermissions().getPermissionNodes())) {
return true; return true;
} }
DefaultPermission defaultPermission = command.getCommandPermissions().getDefaultPermission(); DefaultPermission defaultPermission = command.getCommandPermissions().getDefaultPermission();
boolean def = evaluateDefaultPermission(defaultPermission, player); boolean def = evaluateDefaultPermission(defaultPermission, sender);
return hasPermission(player, command.getCommandPermissions().getPermissionNodes(), def); return (sender instanceof Player)
? hasPermission((Player) sender, command.getCommandPermissions().getPermissionNodes(), def)
: def;
} }
public static boolean evaluateDefaultPermission(DefaultPermission defaultPermission, CommandSender sender) { public static boolean evaluateDefaultPermission(DefaultPermission defaultPermission, CommandSender sender) {

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.permission; package fr.xephi.authme.permission;
import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandDescription;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** /**
@ -11,23 +12,23 @@ public interface PermissionsService {
/** /**
* Check if the player has the given permission. * Check if the player has the given permission.
* *
* @param player The player * @param sender The command sender
* @param permission The permission node to check * @param permission The permission node to check
* @param def Default returned if no permissions system is used * @param def Default returned if no permissions system is used
* *
* @return True if the player has permission * @return True if the player has permission
*/ */
boolean hasPermission(Player player, PermissionNode permission, boolean def); boolean hasPermission(CommandSender sender, PermissionNode permission, boolean def);
/** /**
* Check if the player has the permissions for the given command. * Check if the player has the permissions for the given command.
* *
* @param player The player * @param sender The command sender
* @param command The command whose permissions should be checked * @param command The command whose permissions should be checked
* *
* @return True if the player may execute the command * @return True if the player may execute the command
*/ */
boolean hasPermission(Player player, CommandDescription command); boolean hasPermission(CommandSender sender, CommandDescription command);
/** /**
* Return the permission system the service is working with. * Return the permission system the service is working with.

View File

@ -4,22 +4,23 @@ import org.junit.Test;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
/** /**
* Test for {@link CommandParts}. * Test for {@link CommandUtils}.
*/ */
public class CommandPartsTest { public class CommandUtilsTest {
@Test @Test
public void shouldPrintPartsForStringRepresentation() { public void shouldPrintPartsForStringRepresentation() {
// given // given
CommandParts parts = new CommandParts(Arrays.asList("some", "parts", "for", "test")); Iterable<String> parts = Arrays.asList("some", "parts", "for", "test");
// when // when
String str = parts.toString(); String str = CommandUtils.labelsToString(parts);
// then // then
assertThat(str, equalTo("some parts for test")); assertThat(str, equalTo("some parts for test"));
@ -28,10 +29,10 @@ public class CommandPartsTest {
@Test @Test
public void shouldPrintEmptyStringForNoArguments() { public void shouldPrintEmptyStringForNoArguments() {
// given // given
CommandParts parts = new CommandParts(Collections.EMPTY_LIST); List<String> parts = Collections.EMPTY_LIST;
// when // when
String str = parts.toString(); String str = CommandUtils.labelsToString(parts);
// then // then
assertThat(str, equalTo("")); assertThat(str, equalTo(""));