Merge pull request #83 from AuthMe-Team/commands-refactor

#305 - Commands refactor
This commit is contained in:
ljacqu 2015-12-19 20:29:27 +01:00
commit 4f6c7d579c
64 changed files with 1539 additions and 2306 deletions

View File

@ -226,11 +226,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();
@ -442,13 +440,6 @@ public class AuthMe extends JavaPlugin {
new API(this); new API(this);
} }
/**
* Set up the command handler.
*/
private void setupCommandHandler() {
this.commandHandler = new CommandHandler(CommandInitializer.getBaseCommands());
}
/** /**
* Load the plugin's settings. * Load the plugin's settings.
* *
@ -617,9 +608,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

@ -6,9 +6,9 @@ package fr.xephi.authme.command;
public class CommandArgumentDescription { public class CommandArgumentDescription {
/** /**
* Argument label (one-word description of the argument). * Argument name (one-word description of the argument).
*/ */
private final String label; private final String name;
/** /**
* Argument description. * Argument description.
*/ */
@ -21,23 +21,23 @@ public class CommandArgumentDescription {
/** /**
* Constructor. * Constructor.
* *
* @param label The argument label. * @param name The argument name.
* @param description The argument description. * @param description The argument description.
* @param isOptional True if the argument is optional, false otherwise. * @param isOptional True if the argument is optional, false otherwise.
*/ */
public CommandArgumentDescription(String label, String description, boolean isOptional) { public CommandArgumentDescription(String name, String description, boolean isOptional) {
this.label = label; this.name = name;
this.description = description; this.description = description;
this.isOptional = isOptional; this.isOptional = isOptional;
} }
/** /**
* Get the argument label. * Get the argument name.
* *
* @return Argument label. * @return Argument name.
*/ */
public String getLabel() { public String getName() {
return this.label; return this.name;
} }
/** /**

View File

@ -4,15 +4,13 @@ import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionNode;
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.command.CommandSender;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
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
* {@link ExecutableCommand} implementation that executes the logic of the command. * {@link ExecutableCommand} implementation that executes the logic of the command.
@ -29,15 +27,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;
/** /**
@ -53,7 +51,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;
@ -67,7 +65,7 @@ public class CommandDescription {
} }
/** /**
* Create an instance for internal use. * Create an instance.
* *
* @param labels List of command labels. * @param labels List of command labels.
* @param description Command description. * @param description Command description.
@ -99,58 +97,29 @@ public class CommandDescription {
return instance; return instance;
} }
/** private void addChild(CommandDescription command) {
* Get the label most similar to the reference. The first label will be returned if no reference was supplied. children.add(command);
*
* @param reference The command reference.
*
* @return The most similar label, or the first label. An empty label will be returned if no label was set.
*/
public String getLabel(CommandParts reference) {
// Ensure there's any item in the command list
if (this.labels.size() == 0)
return "";
// Return the first label if we can't use the reference
if (reference == null)
return this.labels.get(0);
// Get the correct label from the reference
String preferred = reference.get(getParentCount());
// Check whether the preferred label is in the label list
double currentDifference = -1;
String currentLabel = this.labels.get(0);
for (String entry : this.labels) {
double entryDifference = StringUtils.getDifference(entry, preferred);
if (entryDifference < currentDifference || currentDifference < 0) {
currentDifference = entryDifference;
currentLabel = entry;
}
}
// Return the most similar label
return currentLabel;
} }
/** /**
* 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 labels;
} }
/** /**
* 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 : this.labels) { for (String label : labels) {
if (label.equalsIgnoreCase(commandLabel)) { if (label.equalsIgnoreCase(commandLabel)) {
return true; return true;
} }
@ -159,263 +128,55 @@ public class CommandDescription {
} }
/** /**
* Check whether this command label is applicable with a command reference. This doesn't check if the parent * Return the {@link ExecutableCommand} instance defined by the command description.
* are suitable too.
* *
* @param commandReference The command reference. * @return The executable command object.
*
* @return True if the command reference is suitable to this command label, false otherwise.
*/
public boolean isSuitableLabel(CommandParts commandReference) {
// Get the parent count
//getParent() = getParent().getParentCount() + 1
String element = commandReference.get(getParentCount());
// Check whether this command description has this command label
for (String label : labels) {
if (label.equalsIgnoreCase(element)) {
return true;
}
}
return false;
}
/**
* Get the command reference.
*
* @param reference The reference to use as template, which is used to choose the most similar reference.
*
* @return Command reference.
*/
public CommandParts getCommandReference(CommandParts reference) {
// Build the reference
List<String> referenceList = new ArrayList<>();
// Check whether this command has a parent, if so, add the absolute parent command
if (getParent() != null) {
referenceList.addAll(getParent().getCommandReference(reference).getList());
}
// Get the current label
referenceList.add(getLabel(reference));
// Return the reference
return new CommandParts(referenceList);
}
/**
* Get the difference between this command and another command reference.
*
* @param other The other command reference.
*
* @return The command difference. Zero if there's no difference. A negative number on error.
*/
public double getCommandDifference(CommandParts other) {
return getCommandDifference(other, false);
}
/**
* Get the difference between this command and another command reference.
*
* @param other The other command reference.
* @param fullCompare True to fully compare both command references.
*
* @return The command difference. Zero if there's no difference. A negative number on error.
*/
public double getCommandDifference(CommandParts other, boolean fullCompare) {
// Make sure the reference is valid
if (other == null)
return -1;
// Get the command reference
CommandParts reference = getCommandReference(other);
// Compare the two references, return the result
return CommandUtils.getDifference(reference.getList(),
CollectionUtils.getRange(other.getList(), 0, reference.getList().size()), fullCompare);
}
/**
* Get the executable command.
*
* @return The executable command.
*/ */
public ExecutableCommand getExecutableCommand() { public ExecutableCommand getExecutableCommand() {
return this.executableCommand; return executableCommand;
} }
/** /**
* Set the executable command. * Return the parent.
* *
* @param executableCommand The executable command. * @return The parent command, or null for base commands.
*/
public void setExecutableCommand(ExecutableCommand executableCommand) {
this.executableCommand = executableCommand;
}
/**
* Execute the command, if possible.
*
* @param sender The command sender that triggered the execution of this command.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True on success, false on failure.
*/
public boolean execute(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) {
// Execute the command, return the result
return getExecutableCommand().executeCommand(sender, commandReference, commandArguments);
}
/**
* Get the parent command if this command description has a parent.
*
* @return Parent command, or null
*/ */
public CommandDescription getParent() { public CommandDescription getParent() {
return this.parent; return parent;
} }
/** /**
* Get the number of parent this description has. * Return the number of labels necessary to get to this command. This corresponds to the number of parents + 1.
* *
* @return The number of parents. * @return The number of labels, e.g. for "/authme abc def" the label count is 3
*/ */
public int getParentCount() { public int getLabelCount() {
// Check whether the this description has a parent if (parent == null) {
if (!hasParent()) return 1;
return 0; }
return parent.getLabelCount() + 1;
// Get the parent count of the parent, return the result
return getParent().getParentCount() + 1;
} }
/** /**
* Set the parent command. * Return all command children.
*
* @param parent Parent command.
*
* @return True on success, false on failure.
*/
public boolean setParent(CommandDescription parent) {
// Make sure the parent is different
if (this.parent == parent)
return true;
// Set the parent
this.parent = parent;
// Make sure the parent isn't null
if (parent == null)
return true;
// Add this description as a child to the parent
return parent.addChild(this);
}
/**
* Check whether the plugin description has a parent command.
*
* @return True if the description has a parent command, false otherwise.
*/
public boolean hasParent() {
return this.parent != null;
}
/**
* Get all command children.
* *
* @return Command children. * @return Command children.
*/ */
public List<CommandDescription> getChildren() { public List<CommandDescription> getChildren() {
return this.children; return children;
} }
/** /**
* Add a child to the command description. * Return all arguments the command takes.
*
* @param commandDescription The child to add.
*
* @return True on success, false on failure.
*/
public boolean addChild(CommandDescription commandDescription) {
// Make sure the description is valid
if (commandDescription == null)
return false;
// Make sure the child doesn't exist already
if (isChild(commandDescription))
return true;
// The command description to add as a child
if (!this.children.add(commandDescription))
return false;
// Set this description as parent on the child
return commandDescription.setParent(this);
}
/**
* Check whether this command has any child labels.
*
* @return True if this command has any child labels.
*/
public boolean hasChildren() {
return (this.children.size() != 0);
}
/**
* Check if this command description has a specific child.
*
* @param commandDescription The command description to check for.
*
* @return True if this command description has the specific child, false otherwise.
*/
public boolean isChild(CommandDescription commandDescription) {
// Make sure the description is valid
if (commandDescription == null)
return false;
// Check whether this child exists, return the result
return this.children.contains(commandDescription);
}
/**
* Add an argument.
*
* @param argument The argument to add.
*
* @return True if succeed, false if failed.
*/
public boolean addArgument(CommandArgumentDescription argument) {
// Make sure the argument is valid
if (argument == null)
return false;
// Add the argument, return the result
return this.arguments.add(argument);
}
/**
* Get all command arguments.
* *
* @return Command arguments. * @return Command arguments.
*/ */
public List<CommandArgumentDescription> getArguments() { public List<CommandArgumentDescription> getArguments() {
return this.arguments; return arguments;
} }
/** /**
* 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.
*/ */
@ -424,119 +185,28 @@ 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;
} }
/** /**
* Find the best suitable command for a query reference. * Return the permissions required to execute the command.
* *
* @param queryReference The query reference to find a command for. * @return The command permissions, or null if none are required to execute the command.
*
* @return The command found, or null.
*/
public FoundCommandResult findCommand(final CommandParts queryReference) {
// Make sure the command reference is valid
if (queryReference.getCount() <= 0)
return null;
// Check whether this description is for the last element in the command reference, if so return the current command
if (queryReference.getCount() <= getParentCount() + 1) {
return new FoundCommandResult(
this,
getCommandReference(queryReference),
new CommandParts(new ArrayList<String>()),
queryReference);
}
// Get the new command reference and arguments
CommandParts newReference = new CommandParts(CollectionUtils.getRange(queryReference.getList(), 0, getParentCount() + 1));
CommandParts newArguments = new CommandParts(CollectionUtils.getRange(queryReference.getList(), getParentCount() + 1));
// Handle the child's, if this command has any
if (getChildren().size() > 0) {
// Get a new instance of the child's list, and sort them by their difference in comparison to the query reference
List<CommandDescription> commandChildren = new ArrayList<>(getChildren());
Collections.sort(commandChildren, new Comparator<CommandDescription>() {
@Override
public int compare(CommandDescription o1, CommandDescription o2) {
return Double.compare(
o1.getCommandDifference(queryReference),
o2.getCommandDifference(queryReference));
}
});
// Get the difference of the first child in the list
double firstChildDifference = commandChildren.get(0).getCommandDifference(queryReference, true);
// Check if the reference perfectly suits the arguments of the current command if it doesn't perfectly suits a child command
if (firstChildDifference > 0.0)
if (getSuitableArgumentsDifference(queryReference) == 0)
return new FoundCommandResult(this, newReference, newArguments, queryReference);
// Loop through each child
for (CommandDescription child : commandChildren) {
// Get the best suitable command
FoundCommandResult result = child.findCommand(queryReference);
if (result != null)
return result;
}
}
// Check if the remaining command reference elements fit the arguments for this command
if (getSuitableArgumentsDifference(queryReference) >= 0)
return new FoundCommandResult(this, newReference, newArguments, queryReference);
// No command found, return null
return null;
}
/**
* Check if the remaining command reference elements are suitable with arguments of the current command description,
* and get the difference in argument count.
*
* @param commandReference The command reference.
*
* @return The difference in argument count between the reference and the actual command.
*/
public int getSuitableArgumentsDifference(CommandParts commandReference) {
// Make sure the command reference is valid
if (commandReference.getCount() <= 0) {
return -1;
}
// Get the remaining command reference element count
int remainingElementCount = commandReference.getCount() - getParentCount() - 1;
// Check if there are too few arguments
int minArguments = CommandUtils.getMinNumberOfArguments(this);
if (minArguments > remainingElementCount) {
return Math.abs(minArguments - remainingElementCount);
}
// Check if there are too many arguments
int maxArguments = CommandUtils.getMaxNumberOfArguments(this);
if (maxArguments >= 0 && maxArguments < remainingElementCount) {
return Math.abs(remainingElementCount - maxArguments);
}
// The argument count is the same
return 0;
}
/**
* Get the command permissions. Return null if the command doesn't require any permission.
*
* @return The command permissions.
*/ */
public CommandPermissions getCommandPermissions() { public CommandPermissions getCommandPermissions() {
return this.permissions; return 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();
} }
@ -554,21 +224,20 @@ 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
*/ */
public CommandDescription build() { public CommandDescription build() {
return createInstance( checkArgument(!CollectionUtils.isEmpty(labels), "Labels may not be empty");
getOrThrow(labels, "labels"), checkArgument(!StringUtils.isEmpty(description), "Description may not be empty");
firstNonNull(description, ""), checkArgument(!StringUtils.isEmpty(detailedDescription), "Detailed description may not be empty");
firstNonNull(detailedDescription, ""), checkArgument(executableCommand != null, "Executable command must be set");
getOrThrow(executableCommand, "executableCommand"), // parents and permissions may be null; arguments may be empty
firstNonNull(parent, null),
arguments, return createInstance(labels, description, detailedDescription, executableCommand,
firstNonNull(permissions, null) parent, arguments, permissions);
);
} }
public CommandBuilder labels(List<String> labels) { public CommandBuilder labels(List<String> labels) {
@ -577,7 +246,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) {
@ -606,7 +275,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
*/ */
@ -617,37 +286,9 @@ public class CommandDescription {
public CommandBuilder permissions(DefaultPermission defaultPermission, public CommandBuilder permissions(DefaultPermission defaultPermission,
PermissionNode... permissionNodes) { PermissionNode... permissionNodes) {
this.permissions = new CommandPermissions(asMutableList(permissionNodes), defaultPermission); this.permissions = new CommandPermissions(asList(permissionNodes), defaultPermission);
return this; return this;
} }
@SafeVarargs
private static <T> List<T> asMutableList(T... items) {
return new ArrayList<>(Arrays.asList(items));
}
private static <T> T firstNonNull(T first, T second) {
return first != null ? first : second;
}
private static <T> T getOrThrow(T element, String elementName) {
if (!isEmpty(element)) {
return element;
}
throw new RuntimeException("The element '" + elementName + "' may not be empty in CommandDescription");
}
private static <T> boolean isEmpty(T element) {
if (element == null) {
return true;
} else if (element instanceof Collection<?>) {
return ((Collection<?>) element).isEmpty();
} else if (element instanceof String) {
return StringUtils.isEmpty((String) element);
}
return false;
}
} }
} }

View File

@ -1,7 +1,9 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.executable.HelpCommand;
import fr.xephi.authme.command.help.HelpProvider; import fr.xephi.authme.command.help.HelpProvider;
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;
@ -11,86 +13,91 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import static fr.xephi.authme.command.FoundResultStatus.INCORRECT_ARGUMENTS;
import static fr.xephi.authme.command.FoundResultStatus.MISSING_BASE_COMMAND;
import static fr.xephi.authme.command.FoundResultStatus.UNKNOWN_LABEL;
/** /**
* The AuthMe command handler, responsible for mapping incoming commands to the correct {@link CommandDescription} * The AuthMe command handler, responsible for mapping incoming commands to the correct {@link CommandDescription}
* or to display help messages for unknown invocations. * or to display help messages for unknown invocations.
*/ */
public class CommandHandler { public class CommandHandler {
/**
* The threshold for assuming an existing command. If the difference is below this value, we assume
* that the user meant the similar command and we will run it.
*/
private static final double ASSUME_COMMAND_THRESHOLD = 0.12;
/** /**
* The threshold for suggesting a similar command. If the difference is below this value, we will * The threshold for suggesting a similar command. If the difference is below this value, we will
* ask the player whether he meant the similar command. * ask the player whether he meant the similar command.
*/ */
private static final double SUGGEST_COMMAND_THRESHOLD = 0.75; private static final double SUGGEST_COMMAND_THRESHOLD = 0.75;
private final Set<CommandDescription> commands; /**
* The class of the help command, to which the base label should also be passed in the arguments.
*/
private static final Class<? extends ExecutableCommand> HELP_COMMAND_CLASS = HelpCommand.class;
private final Set<CommandDescription> baseCommands;
private final PermissionsManager permissionsManager;
/** /**
* Create a command handler. * Create a command handler.
* *
* @param commands The collection of available AuthMe commands * @param baseCommands The collection of available AuthMe base commands
*/ */
public CommandHandler(Set<CommandDescription> commands) { public CommandHandler(Set<CommandDescription> baseCommands, PermissionsManager permissionsManager) {
this.commands = commands; this.baseCommands = baseCommands;
this.permissionsManager = permissionsManager;
} }
/** /**
* Map a command that was invoked to the proper {@link CommandDescription} or return a useful error * Map a command that was invoked to the proper {@link CommandDescription} or return a useful error
* message upon failure. * message upon failure.
* *
* @param sender The command sender (Bukkit). * @param sender The command sender.
* @param bukkitCommandLabel The command label (Bukkit). * @param bukkitCommandLabel The command label (Bukkit).
* @param bukkitArgs The command arguments (Bukkit). * @param bukkitArgs The command arguments (Bukkit).
* *
* @return True if the command was executed, false otherwise. * @return True if the command was executed, false otherwise.
*/ */
public boolean processCommand(CommandSender sender, String bukkitCommandLabel, String[] bukkitArgs) { public boolean processCommand(CommandSender sender, String bukkitCommandLabel, String[] bukkitArgs) {
List<String> commandArgs = skipEmptyArguments(bukkitArgs); // Add the Bukkit command label to the front so we get a list like [authme, register, bobby, mysecret]
// Add the Bukkit command label to the front so we get a list like [authme, register, pass, passConfirm] List<String> parts = skipEmptyArguments(bukkitArgs);
commandArgs.add(0, bukkitCommandLabel); parts.add(0, bukkitCommandLabel);
FoundCommandResult result = mapPartsToCommand(parts);
// TODO: remove commandParts switch (result.getResultStatus()) {
CommandParts commandReference = new CommandParts(commandArgs); case SUCCESS:
executeCommandIfAllowed(sender, result.getCommandDescription(), result.getArguments());
// Get a suitable command for this reference, and make sure it isn't null break;
FoundCommandResult result = findCommand(commandReference); case MISSING_BASE_COMMAND:
if (result == null) { sender.sendMessage(ChatColor.DARK_RED + "Failed to parse " + AuthMe.getPluginName() + " command!");
// TODO ljacqu 20151204: Log more information to the console (bukkitCommandLabel) return false;
sender.sendMessage(ChatColor.DARK_RED + "Failed to parse " + AuthMe.getPluginName() + " command!"); case INCORRECT_ARGUMENTS:
return false; sendImproperArgumentsMessage(sender, result);
break;
case UNKNOWN_LABEL:
sendUnknownCommandMessage(sender, result);
break;
default:
throw new IllegalStateException("Unknown result '" + result.getResultStatus() + "'");
} }
String baseCommand = commandArgs.get(0);
// Make sure the difference between the command reference and the actual command isn't too big
final double commandDifference = result.getDifference();
if (commandDifference <= ASSUME_COMMAND_THRESHOLD) {
// Show a message when the command handler is assuming a command
if (commandDifference > 0) {
sendCommandAssumptionMessage(sender, result, commandReference);
}
if (!result.hasPermission(sender)) {
sender.sendMessage(ChatColor.DARK_RED + "You don't have permission to use this command!");
} else if (!result.hasProperArguments()) {
sendImproperArgumentsMessage(sender, result, commandReference, baseCommand);
} else {
return result.executeCommand(sender);
}
} else {
sendUnknownCommandMessage(sender, commandDifference, result, baseCommand);
}
return true; return true;
} }
/**
* Check a command's permissions and execute it with the given arguments if the check succeeds.
*
* @param sender The command sender
* @param command The command to process
* @param arguments The arguments to pass to the command
*/
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.
* *
@ -98,7 +105,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);
@ -107,131 +114,181 @@ public class CommandHandler {
return cleanArguments; return cleanArguments;
} }
private static CommandDescription mapToBase(String commandLabel) {
for (CommandDescription command : CommandInitializer.getBaseCommands()) {
if (command.getLabels().contains(commandLabel)) {
return command;
}
}
return null;
}
/**
* Find the best suitable command for the specified reference.
*
* @param queryReference The query reference to find a command for.
*
* @return The command found, or null.
*/
public FoundCommandResult findCommand(CommandParts queryReference) {
// Make sure the command reference is valid
if (queryReference.getCount() <= 0)
return null;
for (CommandDescription commandDescription : commands) {
// Check whether there's a command description available for the
// current command
if (!commandDescription.isSuitableLabel(queryReference))
continue;
// Find the command reference, return the result
return commandDescription.findCommand(queryReference);
}
// No applicable command description found, return false
return null;
}
/**
* Find the best suitable command for the specified reference.
*
* @param commandParts The query reference to find a command for.
*
* @return The command found, or null.
*/
private CommandDescription findCommand(List<String> commandParts) {
// Make sure the command reference is valid
if (commandParts.isEmpty()) {
return null;
}
// TODO ljacqu 20151129: Since we only use .contains() on the CommandDescription#labels after init, change
// the type to set for faster lookup
Iterable<CommandDescription> commandsToScan = CommandInitializer.getBaseCommands();
CommandDescription result = null;
for (String label : commandParts) {
result = findLabel(label, commandsToScan);
if (result == null) {
return null;
}
commandsToScan = result.getChildren();
}
return result;
}
private static CommandDescription findLabel(String label, Iterable<CommandDescription> commands) {
if (commands == null) {
return null;
}
for (CommandDescription command : commands) {
if (command.getLabels().contains(label)) { // TODO ljacqu should be case-insensitive
return command;
}
}
return null;
}
/** /**
* 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 commandDifference The difference between the invoked command and the existing one
* @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 (TODO: This is probably already in FoundCommandResult)
*/ */
private static void sendUnknownCommandMessage(CommandSender sender, double commandDifference, private static void sendUnknownCommandMessage(CommandSender sender, FoundCommandResult result) {
FoundCommandResult result, String baseCommand) {
CommandParts commandReference = result.getCommandReference();
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
if (commandDifference < SUGGEST_COMMAND_THRESHOLD && result.getCommandDescription() != null) { if (result.getDifference() <= SUGGEST_COMMAND_THRESHOLD && result.getCommandDescription() != null) {
sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/" sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD
+ result.getCommandDescription().getCommandReference(commandReference) + ChatColor.YELLOW + "?"); + CommandUtils.constructCommandPath(result.getCommandDescription()) + ChatColor.YELLOW + "?");
} }
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)) {
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); List<String> lines = HelpProvider.printHelp(result, HelpProvider.SHOW_ARGUMENTS);
for (String line : lines) {
sender.sendMessage(line);
}
// Show the command to use for detailed help List<String> labels = result.getLabels();
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + baseCommand String childLabel = labels.size() >= 2 ? labels.get(1) : "";
+ " help " + CommandUtils.labelsToString(helpCommandReference)); sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE
+ "/" + labels.get(0) + " help " + childLabel);
} }
private static void sendCommandAssumptionMessage(CommandSender sender, FoundCommandResult result, // TODO ljacqu 20151212: Remove me once I am a MessageKey
CommandParts commandReference) { private void sendPermissionDeniedError(CommandSender sender) {
List<String> assumedCommandParts = sender.sendMessage(ChatColor.DARK_RED + "You don't have permission to use this command!");
result.getCommandDescription().getCommandReference(commandReference).getList();
sender.sendMessage(ChatColor.DARK_RED + "Unknown command, assuming " + ChatColor.GOLD + "/"
+ CommandUtils.labelsToString(assumedCommandParts) + ChatColor.DARK_RED + "!");
} }
/**
* Map incoming command parts to a command. This processes all parts and distinguishes the labels from arguments.
*
* @param parts The parts to map to commands and arguments
* @return The generated {@link FoundCommandResult}
*/
public FoundCommandResult mapPartsToCommand(final List<String> parts) {
if (CollectionUtils.isEmpty(parts)) {
return new FoundCommandResult(null, parts, null, 0.0, MISSING_BASE_COMMAND);
}
CommandDescription base = getBaseCommand(parts.get(0));
if (base == null) {
return new FoundCommandResult(null, parts, null, 0.0, MISSING_BASE_COMMAND);
}
// Prefer labels: /register help goes to "Help command", not "Register command" with argument 'help'
List<String> remainingParts = parts.subList(1, parts.size());
CommandDescription childCommand = getSuitableChild(base, remainingParts);
if (childCommand != null) {
FoundCommandResult result = new FoundCommandResult(
childCommand, parts.subList(0, 2), parts.subList(2, parts.size()));
return transformResultForHelp(result);
} else if (hasSuitableArgumentCount(base, remainingParts.size())) {
return new FoundCommandResult(base, parts.subList(0, 1), parts.subList(1, parts.size()));
}
return getCommandWithSmallestDifference(base, parts);
}
private FoundCommandResult getCommandWithSmallestDifference(CommandDescription base, List<String> parts) {
// Return the base command with incorrect arg count error if we only have one part
if (parts.size() <= 1) {
return new FoundCommandResult(base, parts, new ArrayList<String>(), 0.0, INCORRECT_ARGUMENTS);
}
final String childLabel = parts.get(1);
double minDifference = Double.POSITIVE_INFINITY;
CommandDescription closestCommand = null;
for (CommandDescription child : base.getChildren()) {
double difference = getLabelDifference(child, childLabel);
if (difference < minDifference) {
minDifference = difference;
closestCommand = child;
}
}
// base command may have no children, in which case we return the base command with incorrect arguments error
if (closestCommand == null) {
return new FoundCommandResult(
base, parts.subList(0, 1), parts.subList(1, parts.size()), 0.0, INCORRECT_ARGUMENTS);
}
FoundResultStatus status = (minDifference == 0.0) ? INCORRECT_ARGUMENTS : UNKNOWN_LABEL;
final int partsSize = parts.size();
List<String> labels = parts.subList(0, Math.min(closestCommand.getLabelCount(), partsSize));
List<String> arguments = (labels.size() == partsSize)
? new ArrayList<String>()
: parts.subList(labels.size(), partsSize);
return new FoundCommandResult(closestCommand, labels, arguments, minDifference, status);
}
private CommandDescription getBaseCommand(String label) {
String baseLabel = label.toLowerCase();
for (CommandDescription command : baseCommands) {
if (command.hasLabel(baseLabel)) {
return command;
}
}
return null;
}
/**
* Return a child from a base command if the label and the argument count match.
*
* @param baseCommand The base command whose children should be checked
* @param parts The command parts received from the invocation; the first item is the potential label and any
* other items are command arguments. The first initial part that led to the base command should not
* be present.
*
* @return A command if there was a complete match (including proper argument count), null otherwise
*/
private CommandDescription getSuitableChild(CommandDescription baseCommand, List<String> parts) {
if (CollectionUtils.isEmpty(parts)) {
return null;
}
final String label = parts.get(0).toLowerCase();
final int argumentCount = parts.size() - 1;
for (CommandDescription child : baseCommand.getChildren()) {
if (child.hasLabel(label) && hasSuitableArgumentCount(child, argumentCount)) {
return child;
}
}
return null;
}
private static FoundCommandResult transformResultForHelp(FoundCommandResult result) {
if (result.getCommandDescription() != null
&& HELP_COMMAND_CLASS.isAssignableFrom(result.getCommandDescription().getExecutableCommand().getClass())) {
// For "/authme help register" we have labels = [authme, help] and arguments = [register]
// But for the help command we want labels = [authme, help] and arguments = [authme, register],
// so we can use the arguments as the labels to the command to show help for
List<String> arguments = new ArrayList<>(result.getArguments());
arguments.add(0, result.getLabels().get(0));
return new FoundCommandResult(result.getCommandDescription(), result.getLabels(),
arguments, result.getDifference(), result.getResultStatus());
}
return result;
}
private static boolean hasSuitableArgumentCount(CommandDescription command, int argumentCount) {
int minArgs = CommandUtils.getMinNumberOfArguments(command);
int maxArgs = CommandUtils.getMaxNumberOfArguments(command);
return argumentCount >= minArgs && argumentCount <= maxArgs;
}
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;
}
} }

View File

@ -1,5 +1,6 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import com.google.common.collect.ImmutableSet;
import fr.xephi.authme.command.executable.HelpCommand; import fr.xephi.authme.command.executable.HelpCommand;
import fr.xephi.authme.command.executable.authme.AccountsCommand; import fr.xephi.authme.command.executable.authme.AccountsCommand;
import fr.xephi.authme.command.executable.authme.AuthMeCommand; import fr.xephi.authme.command.executable.authme.AuthMeCommand;
@ -33,9 +34,10 @@ import fr.xephi.authme.command.executable.register.RegisterCommand;
import fr.xephi.authme.command.executable.unregister.UnregisterCommand; import fr.xephi.authme.command.executable.unregister.UnregisterCommand;
import fr.xephi.authme.permission.AdminPermission; import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.util.Wrapper;
import java.util.*; import java.util.Arrays;
import java.util.List;
import java.util.Set;
import static fr.xephi.authme.permission.DefaultPermission.ALLOWED; import static fr.xephi.authme.permission.DefaultPermission.ALLOWED;
import static fr.xephi.authme.permission.DefaultPermission.OP_ONLY; import static fr.xephi.authme.permission.DefaultPermission.OP_ONLY;
@ -53,7 +55,6 @@ public final class CommandInitializer {
public static Set<CommandDescription> getBaseCommands() { public static Set<CommandDescription> getBaseCommands() {
if (baseCommands == null) { if (baseCommands == null) {
Wrapper.getInstance().getLogger().info("Initializing AuthMe commands");
initializeCommands(); initializeCommands();
} }
return baseCommands; return baseCommands;
@ -156,179 +157,179 @@ public final class CommandInitializer {
.labels("getemail", "getmail", "email", "mail") .labels("getemail", "getmail", "email", "mail")
.description("Display player's email") .description("Display player's email")
.detailedDescription("Display the email address of the specified player if set.") .detailedDescription("Display the email address of the specified player if set.")
.permissions(OP_ONLY, AdminPermission.GET_EMAIL)
.withArgument("player", "Player name", true) .withArgument("player", "Player name", true)
.permissions(OP_ONLY, AdminPermission.GET_EMAIL)
.executableCommand(new GetEmailCommand()) .executableCommand(new GetEmailCommand())
.build(); .build();
// Register the setemail command // Register the setemail command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new SetEmailCommand())
.parent(AUTHME_BASE) .parent(AUTHME_BASE)
.labels("chgemail", "chgmail", "setemail", "setmail") .labels("chgemail", "chgmail", "setemail", "setmail")
.description("Change player's email") .description("Change player's email")
.detailedDescription("Change the email address of the specified player.") .detailedDescription("Change the email address of the specified player.")
.permissions(OP_ONLY, AdminPermission.CHANGE_EMAIL)
.withArgument("player", "Player name", false) .withArgument("player", "Player name", false)
.withArgument("email", "Player email", false) .withArgument("email", "Player email", false)
.permissions(OP_ONLY, AdminPermission.CHANGE_EMAIL)
.executableCommand(new SetEmailCommand())
.build(); .build();
// Register the getip command // Register the getip command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new GetIpCommand()) .parent(AUTHME_BASE)
.parent(AUTHME_BASE) .labels("getip", "ip")
.labels("getip", "ip") .description("Get player's IP")
.description("Get player's IP") .detailedDescription("Get the IP address of the specified online player.")
.detailedDescription("Get the IP address of the specified online player.") .withArgument("player", "Player Name", false)
.permissions(OP_ONLY, AdminPermission.GET_IP) .permissions(OP_ONLY, AdminPermission.GET_IP)
.withArgument("player", "Player Name", false) .executableCommand(new GetIpCommand())
.build(); .build();
// Register the spawn command // Register the spawn command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new SpawnCommand()) .parent(AUTHME_BASE)
.parent(AUTHME_BASE) .labels("spawn", "home")
.labels("spawn", "home") .description("Teleport to spawn")
.description("Teleport to spawn") .detailedDescription("Teleport to the spawn.")
.detailedDescription("Teleport to the spawn.") .withArgument("player", "Player Name", false)
.permissions(OP_ONLY, AdminPermission.SPAWN) .permissions(OP_ONLY, AdminPermission.SPAWN)
.withArgument("player", "Player Name", false) .executableCommand(new SpawnCommand())
.build(); .build();
// Register the setspawn command // Register the setspawn command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new SetSpawnCommand()) .parent(AUTHME_BASE)
.parent(AUTHME_BASE) .labels("setspawn", "chgspawn")
.labels("setspawn", "chgspawn") .description("Change the spawn")
.description("Change the spawn") .detailedDescription("Change the player's spawn to your current position.")
.detailedDescription("Change the player's spawn to your current position.") .permissions(OP_ONLY, AdminPermission.SET_SPAWN)
.permissions(OP_ONLY, AdminPermission.SET_SPAWN) .executableCommand(new SetSpawnCommand())
.build(); .build();
// Register the firstspawn command // Register the firstspawn command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new FirstSpawnCommand()) .parent(AUTHME_BASE)
.parent(AUTHME_BASE) .labels("firstspawn", "firsthome")
.labels("firstspawn", "firsthome") .description("Teleport to first spawn")
.description("Teleport to first spawn") .detailedDescription("Teleport to the first spawn.")
.detailedDescription("Teleport to the first spawn.") .permissions(OP_ONLY, AdminPermission.FIRST_SPAWN)
.permissions(OP_ONLY, AdminPermission.FIRST_SPAWN) .executableCommand(new FirstSpawnCommand())
.build(); .build();
// Register the setfirstspawn command // Register the setfirstspawn command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new SetFirstSpawnCommand()) .parent(AUTHME_BASE)
.parent(AUTHME_BASE) .labels("setfirstspawn", "chgfirstspawn")
.labels("setfirstspawn", "chgfirstspawn") .description("Change the first spawn")
.description("Change the first spawn") .detailedDescription("Change the first player's spawn to your current position.")
.detailedDescription("Change the first player's spawn to your current position.") .permissions(OP_ONLY, AdminPermission.SET_FIRST_SPAWN)
.permissions(OP_ONLY, AdminPermission.SET_FIRST_SPAWN) .executableCommand(new SetFirstSpawnCommand())
.build(); .build();
// Register the purge command // Register the purge command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new PurgeCommand()) .parent(AUTHME_BASE)
.parent(AUTHME_BASE) .labels("purge", "delete")
.labels("purge", "delete") .description("Purge old data")
.description("Purge old data") .detailedDescription("Purge old AuthMeReloaded data longer than the specified amount of days ago.")
.detailedDescription("Purge old AuthMeReloaded data longer than the specified amount of days ago.") .withArgument("days", "Number of days", false)
.permissions(OP_ONLY, AdminPermission.PURGE) .permissions(OP_ONLY, AdminPermission.PURGE)
.withArgument("days", "Number of days", false) .executableCommand(new PurgeCommand())
.build(); .build();
// Register the purgelastposition command // Register the purgelastposition command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new PurgeLastPositionCommand()) .parent(AUTHME_BASE)
.parent(AUTHME_BASE) .labels("resetpos", "purgelastposition", "purgelastpos", "resetposition",
.labels("resetpos", "purgelastposition", "purgelastpos", "resetposition", "resetlastposition", "resetlastpos")
"resetlastposition", "resetlastpos") .description("Purge player's last position")
.description("Purge player's last position") .detailedDescription("Purge the last know position of the specified player.")
.detailedDescription("Purge the last know position of the specified player.") .withArgument("player", "Player name", false)
.permissions(OP_ONLY, AdminPermission.PURGE_LAST_POSITION) .permissions(OP_ONLY, AdminPermission.PURGE_LAST_POSITION)
.withArgument("player", "Player name", false) .executableCommand(new PurgeLastPositionCommand())
.build(); .build();
// Register the purgebannedplayers command // Register the purgebannedplayers command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new PurgeBannedPlayersCommand()) .parent(AUTHME_BASE)
.parent(AUTHME_BASE) .labels("purgebannedplayers", "purgebannedplayer", "deletebannedplayers", "deletebannedplayer")
.labels("purgebannedplayers", "purgebannedplayer", "deletebannedplayers", "deletebannedplayer") .description("Purge banned players data")
.description("Purge banned players data") .detailedDescription("Purge all AuthMeReloaded data for banned players.")
.detailedDescription("Purge all AuthMeReloaded data for banned players.") .permissions(OP_ONLY, AdminPermission.PURGE_BANNED_PLAYERS)
.permissions(OP_ONLY, AdminPermission.PURGE_BANNED_PLAYERS) .executableCommand(new PurgeBannedPlayersCommand())
.build(); .build();
// Register the switchantibot command // Register the switchantibot command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new SwitchAntiBotCommand()) .parent(AUTHME_BASE)
.parent(AUTHME_BASE) .labels("switchantibot", "toggleantibot", "antibot")
.labels("switchantibot", "toggleantibot", "antibot") .description("Switch AntiBot mode")
.description("Switch AntiBot mode") .detailedDescription("Switch or toggle the AntiBot mode to the specified state.")
.detailedDescription("Switch or toggle the AntiBot mode to the specified state.") .withArgument("mode", "ON / OFF", true)
.permissions(OP_ONLY, AdminPermission.SWITCH_ANTIBOT) .permissions(OP_ONLY, AdminPermission.SWITCH_ANTIBOT)
.withArgument("mode", "ON / OFF", true) .executableCommand(new SwitchAntiBotCommand())
.build(); .build();
// Register the reload command // Register the reload command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new ReloadCommand()) .parent(AUTHME_BASE)
.parent(AUTHME_BASE) .labels("reload", "rld")
.labels("reload", "rld") .description("Reload plugin")
.description("Reload plugin") .detailedDescription("Reload the AuthMeReloaded plugin.")
.detailedDescription("Reload the AuthMeReloaded plugin.") .permissions(OP_ONLY, AdminPermission.RELOAD)
.permissions(OP_ONLY, AdminPermission.RELOAD) .executableCommand(new ReloadCommand())
.build(); .build();
// Register the version command // Register the version command
CommandDescription.builder() CommandDescription.builder()
.parent(AUTHME_BASE) .parent(AUTHME_BASE)
.labels("version", "ver", "v", "about", "info") .labels("version", "ver", "v", "about", "info")
.description("Version info") .description("Version info")
.detailedDescription("Show detailed information about the installed AuthMeReloaded version, and shows the " .detailedDescription("Show detailed information about the installed AuthMeReloaded version, the "
+ "developers, contributors, license and other information.") + "developers, contributors, and license.")
.executableCommand(new VersionCommand()) .executableCommand(new VersionCommand())
.build(); .build();
// Register the base login command // Register the base login command
final CommandDescription LOGIN_BASE = CommandDescription.builder() final CommandDescription LOGIN_BASE = CommandDescription.builder()
.executableCommand(new LoginCommand()) .parent(null)
.labels("login", "l") .labels("login", "l")
.description("Login command") .description("Login command")
.detailedDescription("Command to log in using AuthMeReloaded.") .detailedDescription("Command to log in using AuthMeReloaded.")
.parent(null)
.permissions(ALLOWED, PlayerPermission.LOGIN)
.withArgument("password", "Login password", false) .withArgument("password", "Login password", false)
.permissions(ALLOWED, PlayerPermission.LOGIN)
.executableCommand(new LoginCommand())
.build(); .build();
// Register the help command // Register the help command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(helpCommandExecutable) .parent(LOGIN_BASE)
.parent(LOGIN_BASE) .labels(helpCommandLabels)
.labels(helpCommandLabels) .description("View Help")
.description("View Help") .detailedDescription("View detailed help pages about AuthMeReloaded login commands.")
.detailedDescription("View detailed help pages about AuthMeReloaded login commands.") .withArgument("query", "The command or query to view help for.", true)
.withArgument("query", "The command or query to view help for.", true) .executableCommand(helpCommandExecutable)
.build(); .build();
// Register the base logout command // Register the base logout command
CommandDescription LOGOUT_BASE = CommandDescription.builder() CommandDescription LOGOUT_BASE = CommandDescription.builder()
.executableCommand(new LogoutCommand()) .parent(null)
.parent(null) .labels("logout")
.labels("logout") .description("Logout command")
.description("Logout command") .detailedDescription("Command to logout using AuthMeReloaded.")
.detailedDescription("Command to logout using AuthMeReloaded.") .permissions(ALLOWED, PlayerPermission.LOGOUT)
.permissions(ALLOWED, PlayerPermission.LOGOUT) .executableCommand(new LogoutCommand())
.build(); .build();
// Register the help command // Register the help command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(helpCommandExecutable) .parent(LOGOUT_BASE)
.parent(LOGOUT_BASE) .labels(helpCommandLabels)
.labels(helpCommandLabels) .description("View help")
.description("View help") .detailedDescription("View detailed help pages about AuthMeReloaded logout commands.")
.detailedDescription("View detailed help pages about AuthMeReloaded logout commands.") .withArgument("query", "The command or query to view help for.", true)
.withArgument("query", "The command or query to view help for.", true) .executableCommand(helpCommandExecutable)
.build(); .build();
// Register the base register command // Register the base register command
final CommandDescription REGISTER_BASE = CommandDescription.builder() final CommandDescription REGISTER_BASE = CommandDescription.builder()
@ -344,158 +345,157 @@ public final class CommandInitializer {
// Register the help command // Register the help command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(helpCommandExecutable) .parent(REGISTER_BASE)
.parent(REGISTER_BASE) .labels(helpCommandLabels)
.labels(helpCommandLabels) .description("View help")
.description("View help") .detailedDescription("View detailed help pages about AuthMeReloaded register commands.")
.detailedDescription("View detailed help pages about AuthMeReloaded register commands.") .withArgument("query", "The command or query to view help for.", true)
.withArgument("query", "The command or query to view help for.", true) .executableCommand(helpCommandExecutable)
.build(); .build();
// Register the base unregister command // Register the base unregister command
CommandDescription UNREGISTER_BASE = CommandDescription.builder() CommandDescription UNREGISTER_BASE = CommandDescription.builder()
.executableCommand(new UnregisterCommand()) .parent(null)
.parent(null) .labels("unreg", "unregister")
.labels("unreg", "unregister") .description("Unregistration Command")
.description("Unregistration Command") .detailedDescription("Command to unregister using AuthMeReloaded.")
.detailedDescription("Command to unregister using AuthMeReloaded.") .withArgument("password", "Password", false)
.permissions(ALLOWED, PlayerPermission.UNREGISTER) .permissions(ALLOWED, PlayerPermission.UNREGISTER)
.withArgument("password", "Password", false) .executableCommand(new UnregisterCommand())
.build(); .build();
// Register the help command // Register the help command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(helpCommandExecutable) .parent(UNREGISTER_BASE)
.parent(UNREGISTER_BASE) .labels(helpCommandLabels)
.labels(helpCommandLabels) .description("View help")
.description("View help") .detailedDescription("View detailed help pages about AuthMeReloaded unregister commands.")
.detailedDescription("View detailed help pages about AuthMeReloaded unregister commands.") .withArgument("query", "The command or query to view help for.", true)
.withArgument("query", "The command or query to view help for.", true) .executableCommand(helpCommandExecutable)
.build(); .build();
// Register the base changepassword command // Register the base changepassword command
final CommandDescription CHANGE_PASSWORD_BASE = CommandDescription.builder() final CommandDescription CHANGE_PASSWORD_BASE = CommandDescription.builder()
.executableCommand(new ChangePasswordCommand()) .parent(null)
.parent(null) .labels("changepassword", "changepass", "cp")
.labels("changepassword", "changepass", "cp") .description("Change password Command")
.description("Change password Command") .detailedDescription("Command to change your password using AuthMeReloaded.")
.detailedDescription("Command to change your password using AuthMeReloaded.") .withArgument("password", "Password", false)
.permissions(ALLOWED, PlayerPermission.CHANGE_PASSWORD) .withArgument("verifyPassword", "Verify password.", false)
.withArgument("password", "Password", false) .permissions(ALLOWED, PlayerPermission.CHANGE_PASSWORD)
.withArgument("verifyPassword", "Verify password.", false) .executableCommand(new ChangePasswordCommand())
.build(); .build();
// Register the help command // Register the help command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(helpCommandExecutable) .parent(CHANGE_PASSWORD_BASE)
.parent(CHANGE_PASSWORD_BASE) .labels(helpCommandLabels)
.labels(helpCommandLabels) .description("View help")
.description("View help") .detailedDescription("View detailed help pages about AuthMeReloaded changepassword commands.")
.detailedDescription("View detailed help pages about AuthMeReloaded changepassword commands.") .withArgument("query", "The command or query to view help for.", true)
.withArgument("query", "The command or query to view help for.", true) .executableCommand(helpCommandExecutable)
.build(); .build();
// Register the base Email command // Register the base Email command
CommandDescription EMAIL_BASE = CommandDescription.builder() CommandDescription EMAIL_BASE = CommandDescription.builder()
.executableCommand(helpCommandExecutable) .parent(null)
.parent(null) .labels("email", "mail")
.labels("email", "mail") .description("Email command")
.description("Email command") .detailedDescription("The AuthMeReloaded Email command base.")
.detailedDescription("The AuthMeReloaded Email command base.") .executableCommand(helpCommandExecutable)
.build(); .build();
// Register the help command // Register the help command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(helpCommandExecutable) .parent(EMAIL_BASE)
.parent(EMAIL_BASE) .labels(helpCommandLabels)
.labels(helpCommandLabels) .description("View help")
.description("View help") .detailedDescription("View detailed help pages about AuthMeReloaded email commands.")
.detailedDescription("View detailed help pages about AuthMeReloaded email commands.") .withArgument("query", "The command or query to view help for.", true)
.withArgument("query", "The command or query to view help for.", true) .executableCommand(helpCommandExecutable)
.build(); .build();
// Register the add command // Register the add command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new AddEmailCommand()) .parent(EMAIL_BASE)
.parent(EMAIL_BASE) .labels("add", "addemail", "addmail")
.labels("add", "addemail", "addmail") .description("Add Email")
.description("Add Email") .detailedDescription("Add a new email address to your account.")
.detailedDescription("Add a new email address to your account.") .withArgument("email", "Email address", false)
.permissions(ALLOWED, PlayerPermission.ADD_EMAIL) .withArgument("verifyEmail", "Email address verification", false)
.withArgument("email", "Email address", false) .permissions(ALLOWED, PlayerPermission.ADD_EMAIL)
.withArgument("verifyEmail", "Email address verification", false) .executableCommand(new AddEmailCommand())
.build(); .build();
// Register the change command // Register the change command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new ChangeEmailCommand()) .parent(EMAIL_BASE)
.parent(EMAIL_BASE) .labels("change", "changeemail", "changemail")
.labels("change", "changeemail", "changemail") .description("Change Email")
.description("Change Email") .detailedDescription("Change an email address of your account.")
.detailedDescription("Change an email address of your account.") .withArgument("oldEmail", "Old email address", false)
.permissions(ALLOWED, PlayerPermission.CHANGE_EMAIL) .withArgument("newEmail", "New email address", false)
.withArgument("oldEmail", "Old email address", false) .permissions(ALLOWED, PlayerPermission.CHANGE_EMAIL)
.withArgument("newEmail", "New email address", false) .executableCommand(new ChangeEmailCommand())
.build(); .build();
// Register the recover command // Register the recover command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(new RecoverEmailCommand()) .parent(EMAIL_BASE)
.parent(EMAIL_BASE) .labels("recover", "recovery", "recoveremail", "recovermail")
.labels("recover", "recovery", "recoveremail", "recovermail") .description("Recover password using Email")
.description("Recover password using Email") .detailedDescription("Recover your account using an Email address by sending a mail containing " +
.detailedDescription("Recover your account using an Email address by sending a mail containing " + "a new password.")
"a new password.") .withArgument("email", "Email address", false)
.permissions(ALLOWED, PlayerPermission.RECOVER_EMAIL) .permissions(ALLOWED, PlayerPermission.RECOVER_EMAIL)
.withArgument("email", "Email address", false) .executableCommand(new RecoverEmailCommand())
.build(); .build();
// Register the base captcha command // Register the base captcha command
CommandDescription CAPTCHA_BASE = CommandDescription.builder() CommandDescription CAPTCHA_BASE = CommandDescription.builder()
.executableCommand(new CaptchaCommand()) .parent(null)
.parent(null) .labels("captcha", "capt")
.labels("captcha", "capt") .description("Captcha Command")
.description("Captcha Command") .detailedDescription("Captcha command for AuthMeReloaded.")
.detailedDescription("Captcha command for AuthMeReloaded.") .withArgument("captcha", "The Captcha", false)
.permissions(ALLOWED, PlayerPermission.CAPTCHA) .permissions(ALLOWED, PlayerPermission.CAPTCHA)
.withArgument("captcha", "The Captcha", false) .executableCommand(new CaptchaCommand())
.build(); .build();
// Register the help command // Register the help command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(helpCommandExecutable) .parent(CAPTCHA_BASE)
.parent(CAPTCHA_BASE) .labels(helpCommandLabels)
.labels(helpCommandLabels) .description("View help")
.description("View help") .detailedDescription("View detailed help pages about AuthMeReloaded captcha commands.")
.detailedDescription("View detailed help pages about AuthMeReloaded captcha commands.") .withArgument("query", "The command or query to view help for.", true)
.withArgument("query", "The command or query to view help for.", true) .executableCommand(helpCommandExecutable)
.build(); .build();
// Register the base converter command // Register the base converter command
CommandDescription CONVERTER_BASE = CommandDescription.builder() CommandDescription CONVERTER_BASE = CommandDescription.builder()
.executableCommand(new ConverterCommand()) .parent(null)
.parent(null) .labels("converter", "convert", "conv")
.labels("converter", "convert", "conv") .description("Converter Command")
.description("Converter Command") .detailedDescription("Converter command for AuthMeReloaded.")
.detailedDescription("Converter command for AuthMeReloaded.") .withArgument("job", "Conversion job: flattosql / flattosqlite /| xauth / crazylogin / rakamak / " +
.permissions(OP_ONLY, AdminPermission.CONVERTER) "royalauth / vauth / sqltoflat", false)
.withArgument("job", "Conversion job: flattosql / flattosqlite /| xauth / crazylogin / rakamak / " + .permissions(OP_ONLY, AdminPermission.CONVERTER)
"royalauth / vauth / sqltoflat", false) .executableCommand(new ConverterCommand())
.build(); .build();
// Register the help command // Register the help command
CommandDescription.builder() CommandDescription.builder()
.executableCommand(helpCommandExecutable) .parent(CONVERTER_BASE)
.parent(CONVERTER_BASE) .labels(helpCommandLabels)
.labels(helpCommandLabels) .description("View help")
.description("View help") .detailedDescription("View detailed help pages about AuthMeReloaded converter commands.")
.detailedDescription("View detailed help pages about AuthMeReloaded converter commands.") .withArgument("query", "The command or query to view help for.", true)
.withArgument("query", "The command or query to view help for.", true) .executableCommand(helpCommandExecutable)
.build(); .build();
// Add the base commands to the commands array // Add the base commands to the commands array
baseCommands = new HashSet<>(Arrays.asList( baseCommands = ImmutableSet.of(
AUTHME_BASE, AUTHME_BASE,
LOGIN_BASE, LOGIN_BASE,
LOGOUT_BASE, LOGOUT_BASE,
@ -504,6 +504,6 @@ public final class CommandInitializer {
CHANGE_PASSWORD_BASE, CHANGE_PASSWORD_BASE,
EMAIL_BASE, EMAIL_BASE,
CAPTCHA_BASE, CAPTCHA_BASE,
CONVERTER_BASE)); CONVERTER_BASE);
} }
} }

View File

@ -1,78 +0,0 @@
package fr.xephi.authme.command;
import fr.xephi.authme.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
/**
*/
public class CommandParts {
/**
* The list of parts for this command.
*/
private final List<String> parts = new ArrayList<>();
/**
* Constructor.
*
* @param part The part to add.
*/
public CommandParts(String part) {
this.parts.add(part);
}
/**
* Constructor.
*
* @param parts The list of parts.
*/
public CommandParts(List<String> parts) {
this.parts.addAll(parts);
}
/**
* Get the command parts.
*
* @return Command parts.
*/
public List<String> getList() {
return this.parts;
}
/**
* Get the number of parts.
*
* @return Part count.
*/
public int getCount() {
return this.parts.size();
}
/**
* Get a part by its index.
*
* @param i Part index.
*
* @return The part.
*/
public String get(int i) {
// Make sure the index is in-bound
if (i < 0 || i >= getCount())
return null;
// Get and return the argument
return this.parts.get(i);
}
/**
* Convert the parts to a string.
*
* @return The part as a string.
*/
@Override
public String toString() {
return StringUtils.join(" ", this.parts);
}
}

View File

@ -1,11 +1,7 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.permission.DefaultPermission; import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionNode;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List; import java.util.List;
@ -42,38 +38,6 @@ public class CommandPermissions {
return this.permissionNodes; return this.permissionNodes;
} }
/**
* Check whether this command requires any permission to be executed. This is based on the getPermission() method.
*
* @param sender CommandSender
*
* @return True if this command requires any permission to be executed by a player.
*/
public boolean hasPermission(CommandSender sender) {
// Make sure any permission node is set
if (permissionNodes.isEmpty()) {
return true;
}
PermissionsManager permissionsManager = AuthMe.getInstance().getPermissionsManager();
final boolean defaultPermission = getDefaultPermissionCommandSender(sender);
// Make sure the command sender is a player, if not use the default
if (!(sender instanceof Player)) {
return defaultPermission;
}
// Get the player instance
Player player = (Player) sender;
// Get the permissions manager, and make sure it's instance is valid
if (permissionsManager == null)
return false;
// Check whether the player has permission, return the result
return permissionsManager.hasPermission(player, this.permissionNodes, defaultPermission);
}
/** /**
* Get the default permission if the permission nodes couldn't be used. * Get the default permission if the permission nodes couldn't be used.
@ -85,24 +49,4 @@ public class CommandPermissions {
} }
/**
* Get the default permission for a specified command sender.
*
* @param sender The command sender to get the default permission for.
*
* @return True if the command sender has permission by default, false otherwise.
*/
public boolean getDefaultPermissionCommandSender(CommandSender sender) {
switch (getDefaultPermission()) {
case ALLOWED:
return true;
case OP_ONLY:
return sender.isOp();
case NOT_ALLOWED:
default:
return false;
}
}
} }

View File

@ -1,7 +1,6 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
@ -25,9 +24,10 @@ public final class CommandUtils {
/** /**
* Provide a textual representation of a list of labels to show it as a command. For example, a list containing * Provide a textual representation of a list of labels to show it as a command. For example, a list containing
* the items ["authme", "register", "player"] it will return "authme register player". * the items ["authme", "register", "player"] will return "authme register player".
* *
* @param labels The labels to format * @param labels The labels to format
*
* @return The space-separated labels * @return The space-separated labels
*/ */
public static String labelsToString(Iterable<String> labels) { public static String labelsToString(Iterable<String> labels) {
@ -35,35 +35,22 @@ public final class CommandUtils {
} }
public static String constructCommandPath(CommandDescription command) { public static String constructCommandPath(CommandDescription command) {
List<String> labels = new ArrayList<>(); StringBuilder sb = new StringBuilder();
String prefix = "/";
for (CommandDescription ancestor : constructParentList(command)) {
sb.append(prefix).append(ancestor.getLabels().get(0));
prefix = " ";
}
return sb.toString();
}
public static List<CommandDescription> constructParentList(CommandDescription command) {
List<CommandDescription> commands = new ArrayList<>();
CommandDescription currentCommand = command; CommandDescription currentCommand = command;
while (currentCommand != null) { while (currentCommand != null) {
labels.add(currentCommand.getLabels().get(0)); commands.add(currentCommand);
currentCommand = currentCommand.getParent(); currentCommand = currentCommand.getParent();
} }
return "/" + labelsToString(Lists.reverse(labels)); return Lists.reverse(commands);
} }
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

@ -2,19 +2,18 @@ package fr.xephi.authme.command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.List;
/** /**
* Base class for AuthMe commands that can be executed. * Base class for AuthMe commands that can be executed.
*/ */
public abstract class ExecutableCommand { public abstract class ExecutableCommand {
/** /**
* Execute the command. * Execute the command with the given arguments.
* *
* @param sender The command sender. * @param sender The command sender.
* @param commandReference The command reference. * @param arguments The arguments.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/ */
public abstract boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments); public abstract void executeCommand(CommandSender sender, List<String> arguments);
} }

View File

@ -1,149 +1,88 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import org.bukkit.command.CommandSender; import java.util.List;
/** /**
* Result of a command mapping by {@link CommandHandler}. An object of this class represents a successful mapping
* as well as erroneous ones, as communicated with {@link FoundResultStatus}.
* <p />
* Fields other than {@link FoundResultStatus} are available depending, among other factors, on the status:
* <ul>
* <li>{@link FoundResultStatus#SUCCESS} entails that mapping the input to a command was successful. Therefore,
* the command description, labels and arguments are set. The difference is 0.0.</li>
* <li>{@link FoundResultStatus#INCORRECT_ARGUMENTS}: The received parts could be mapped to a command but the argument
* count doesn't match. Guarantees that the command description field is not null; difference is 0.0</li>
* <li>{@link FoundResultStatus#UNKNOWN_LABEL}: The labels could not be mapped to a command. The command description
* may be set to the most similar command, or it may be null. Difference is above 0.0.</li>
* <li>{@link FoundResultStatus#MISSING_BASE_COMMAND} should never occur. All other fields may be null and any further
* processing of the object should be aborted.</li>
* </ul>
*/ */
public class FoundCommandResult { public class FoundCommandResult {
/** /**
* The command description instance. * The command description instance.
*/ */
private CommandDescription commandDescription; private final CommandDescription commandDescription;
/** /**
* The command 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 commandReference; private final List<String> labels;
/** /** The command arguments. */
* The command arguments. private final List<String> arguments;
*/ /** The difference between the matched command and the supplied labels. */
private final CommandParts commandArguments; private final double difference;
/** /** The status of the result (see class description). */
* The original search query reference. private final FoundResultStatus resultStatus;
*/
private final CommandParts queryReference;
/** /**
* Constructor. * Constructor.
* *
* @param commandDescription The command description. * @param commandDescription The command description.
* @param commandReference The command reference. * @param labels The labels used to access the command.
* @param commandArguments The command arguments. * @param arguments The command arguments.
* @param queryReference The original query reference. * @param difference The difference between the supplied labels and the matched command.
* @param resultStatus The status of the result.
*/ */
public FoundCommandResult(CommandDescription commandDescription, CommandParts commandReference, CommandParts commandArguments, CommandParts queryReference) { public FoundCommandResult(CommandDescription commandDescription, List<String> labels, List<String> arguments,
double difference, FoundResultStatus resultStatus) {
this.commandDescription = commandDescription; this.commandDescription = commandDescription;
this.commandReference = commandReference; this.labels = labels;
this.commandArguments = commandArguments; this.arguments = arguments;
this.queryReference = queryReference; this.difference = difference;
this.resultStatus = resultStatus;
} }
/** /**
* Check whether the command was suitable. * Constructor for a fully successfully matched command.
* *
* @return True if the command was suitable, false otherwise. * @param commandDescription The matched command description.
* @param labels The labels used to access the command.
* @param arguments The command arguments.
*/ */
public boolean hasProperArguments() { public FoundCommandResult(CommandDescription commandDescription, List<String> labels, List<String> arguments) {
// Make sure the command description is set this(commandDescription, labels, arguments, 0.0, FoundResultStatus.SUCCESS);
if (this.commandDescription == null)
return false;
// Get and return the result
return getCommandDescription().getSuitableArgumentsDifference(this.queryReference) == 0;
} }
/**
* Get the command description.
*
* @return Command description.
*/
public CommandDescription getCommandDescription() { public CommandDescription getCommandDescription() {
return this.commandDescription; return this.commandDescription;
} }
/** public List<String> getArguments() {
* Check whether the command is executable. return this.arguments;
*
* @return True if the command is executable, false otherwise.
*/
public boolean isExecutable() {
return commandDescription != null;
} }
/** public List<String> getLabels() {
* Execute the command. return this.labels;
*
* @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.
*
* @return The command arguments.
*/
public CommandParts getCommandArguments() {
return this.commandArguments;
}
/**
* Get the original query reference.
*
* @return Original query reference.
*/
public CommandParts getQueryReference() {
return this.queryReference;
}
/**
* 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
return CommandUtils.getDifference(queryReference.getList(), commandReference.getList(), true);
} }
public FoundResultStatus getResultStatus() {
return resultStatus;
}
} }

View File

@ -0,0 +1,16 @@
package fr.xephi.authme.command;
/**
* Result status for mapping command parts. See {@link FoundCommandResult} for a detailed description of the states.
*/
public enum FoundResultStatus {
SUCCESS,
INCORRECT_ARGUMENTS,
UNKNOWN_LABEL,
MISSING_BASE_COMMAND
}

View File

@ -1,27 +1,56 @@
package fr.xephi.authme.command.executable; package fr.xephi.authme.command.executable;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.command.FoundResultStatus;
import fr.xephi.authme.command.help.HelpProvider; import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.util.Wrapper;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
/** import java.util.List;
*/
import static fr.xephi.authme.command.FoundResultStatus.MISSING_BASE_COMMAND;
import static fr.xephi.authme.command.FoundResultStatus.UNKNOWN_LABEL;
public class HelpCommand extends ExecutableCommand { public class HelpCommand extends ExecutableCommand {
// Convention: arguments is not the actual invoked arguments but the command that was invoked,
// e.g. "/authme help register" would typically be arguments = [register], but here we pass [authme, register]
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Check whether quick help should be shown // TODO #306 ljacqu 20151213: Get command handler from non-static context
boolean quickHelp = commandArguments.getCount() == 0; CommandHandler commandHandler = Wrapper.getInstance().getAuthMe().getCommandHandler();
FoundCommandResult foundCommandResult = commandHandler.mapPartsToCommand(arguments);
// Set the proper command arguments for the quick help and show it // TODO ljacqu 20151213: This is essentially the same logic as in CommandHandler and we'd like to have the same
if (quickHelp) { // messages. Maybe we can have another method in CommandHandler where the end command isn't executed upon
commandArguments = new CommandParts(commandReference.get(0)); // success.
HelpProvider.showHelp(sender, commandReference, commandArguments, false, false, false, false, false, true); FoundResultStatus resultStatus = foundCommandResult.getResultStatus();
} else { if (MISSING_BASE_COMMAND.equals(resultStatus)) {
HelpProvider.showHelp(sender, commandReference, commandArguments); sender.sendMessage(ChatColor.DARK_RED + "Could not get base command");
return;
} else if (UNKNOWN_LABEL.equals(resultStatus)) {
if (foundCommandResult.getCommandDescription() == null) {
sender.sendMessage(ChatColor.DARK_RED + "Unknown command");
return;
} else {
sender.sendMessage(ChatColor.GOLD + "Assuming " + ChatColor.WHITE
+ CommandUtils.constructCommandPath(foundCommandResult.getCommandDescription()));
}
}
PermissionsManager permissionsManager = Wrapper.getInstance().getAuthMe().getPermissionsManager();
List<String> lines = arguments.size() == 1
? HelpProvider.printHelp(foundCommandResult, HelpProvider.SHOW_CHILDREN)
: HelpProvider.printHelp(foundCommandResult, sender, permissionsManager, HelpProvider.ALL_OPTIONS);
for (String line : lines) {
sender.sendMessage(line);
} }
return true;
} }
} }

View File

@ -2,7 +2,6 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
@ -10,31 +9,21 @@ import org.bukkit.command.CommandSender;
import java.util.List; import java.util.List;
/**
*/
public class AccountsCommand extends ExecutableCommand { public class AccountsCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(final CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(final CommandSender sender, List<String> arguments) {
// AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance(); final AuthMe plugin = AuthMe.getInstance();
// Messages instance
final Messages m = plugin.getMessages(); final Messages m = plugin.getMessages();
// Get the player query final String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
String playerQuery = sender.getName();
if (commandArguments.getCount() >= 1) {
playerQuery = commandArguments.get(0);
}
final String playerQueryFinal = playerQuery;
// Command logic // Command logic
if (!playerQueryFinal.contains(".")) { if (!playerName.contains(".")) {
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override @Override
public void run() { public void run() {
PlayerAuth auth = plugin.database.getAuth(playerQueryFinal.toLowerCase()); PlayerAuth auth = plugin.database.getAuth(playerName.toLowerCase());
if (auth == null) { if (auth == null) {
m.send(sender, MessageKey.UNKNOWN_USER); m.send(sender, MessageKey.UNKNOWN_USER);
return; return;
@ -46,7 +35,7 @@ public class AccountsCommand extends ExecutableCommand {
return; return;
} }
if (accountList.size() == 1) { if (accountList.size() == 1) {
sender.sendMessage("[AuthMe] " + playerQueryFinal + " is a single account player"); sender.sendMessage("[AuthMe] " + playerName + " is a single account player");
return; return;
} }
int i = 0; int i = 0;
@ -59,24 +48,24 @@ public class AccountsCommand extends ExecutableCommand {
message.append('.'); message.append('.');
} }
} }
sender.sendMessage("[AuthMe] " + playerQueryFinal + " has " sender.sendMessage("[AuthMe] " + playerName + " has "
+ String.valueOf(accountList.size()) + " accounts."); + String.valueOf(accountList.size()) + " accounts.");
sender.sendMessage(message.toString()); sender.sendMessage(message.toString());
} }
}); });
return true; return;
} else { } else {
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override @Override
public void run() { public void run() {
List<String> accountList = plugin.database.getAllAuthsByIp(playerQueryFinal); List<String> accountList = plugin.database.getAllAuthsByIp(playerName);
StringBuilder message = new StringBuilder("[AuthMe] "); StringBuilder message = new StringBuilder("[AuthMe] ");
if (accountList.isEmpty()) { if (accountList.isEmpty()) {
sender.sendMessage("[AuthMe] This IP does not exist in the database."); sender.sendMessage("[AuthMe] This IP does not exist in the database.");
return; return;
} }
if (accountList.size() == 1) { if (accountList.size() == 1) {
sender.sendMessage("[AuthMe] " + playerQueryFinal + " is a single account player"); sender.sendMessage("[AuthMe] " + playerName + " is a single account player");
return; return;
} }
int i = 0; int i = 0;
@ -89,12 +78,11 @@ public class AccountsCommand extends ExecutableCommand {
message.append('.'); message.append('.');
} }
} }
sender.sendMessage("[AuthMe] " + playerQueryFinal + " has " sender.sendMessage("[AuthMe] " + playerName + " has "
+ String.valueOf(accountList.size()) + " accounts."); + String.valueOf(accountList.size()) + " accounts.");
sender.sendMessage(message.toString()); sender.sendMessage(message.toString());
} }
}); });
return true;
} }
} }
} }

View File

@ -1,21 +1,24 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.List;
/** /**
* AuthMe base command; shows the version and some command pointers.
*/ */
public class AuthMeCommand extends ExecutableCommand { public class AuthMeCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Show some version info sender.sendMessage(ChatColor.GREEN + "This server is running " + AuthMe.getPluginName() + " v"
sender.sendMessage(ChatColor.GREEN + "This server is running " + AuthMe.getPluginName() + " v" + AuthMe.getPluginVersion() + " b" + AuthMe.getPluginBuildNumber()+ "! " + ChatColor.RED + "<3"); + AuthMe.getPluginVersion() + " b" + AuthMe.getPluginBuildNumber()+ "! " + ChatColor.RED + "<3");
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + commandReference.get(0) + " help" + ChatColor.YELLOW + " to view help."); sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/authme help" + ChatColor.YELLOW
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + commandReference.get(0) + " about" + ChatColor.YELLOW + " to view about."); + " to view help.");
return true; sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/authme about" + ChatColor.YELLOW
+ " to view about.");
} }
} }

View File

@ -4,16 +4,16 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.List;
/** /**
* Admin command for changing a player's password. * Admin command for changing a player's password.
@ -21,14 +21,13 @@ import java.security.NoSuchAlgorithmException;
public class ChangePasswordAdminCommand extends ExecutableCommand { public class ChangePasswordAdminCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(final CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(final CommandSender sender, List<String> arguments) {
final AuthMe plugin = AuthMe.getInstance(); final AuthMe plugin = AuthMe.getInstance();
// Messages instance
final Messages m = plugin.getMessages(); final Messages m = plugin.getMessages();
// Get the player and password // Get the player and password
String playerName = commandArguments.get(0); String playerName = arguments.get(0);
final String playerPass = commandArguments.get(1); final String playerPass = arguments.get(1);
// Validate the password // Validate the password
String playerPassLowerCase = playerPass.toLowerCase(); String playerPassLowerCase = playerPass.toLowerCase();
@ -38,20 +37,20 @@ public class ChangePasswordAdminCommand extends ExecutableCommand {
|| playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null") || playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null")
|| !playerPassLowerCase.matches(Settings.getPassRegex)) { || !playerPassLowerCase.matches(Settings.getPassRegex)) {
m.send(sender, MessageKey.PASSWORD_MATCH_ERROR); m.send(sender, MessageKey.PASSWORD_MATCH_ERROR);
return true; return;
} }
if (playerPassLowerCase.equalsIgnoreCase(playerName)) { if (playerPassLowerCase.equalsIgnoreCase(playerName)) {
m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
return true; return;
} }
if (playerPassLowerCase.length() < Settings.getPasswordMinLen if (playerPassLowerCase.length() < Settings.getPasswordMinLen
|| playerPassLowerCase.length() > Settings.passwordMaxLength) { || playerPassLowerCase.length() > Settings.passwordMaxLength) {
m.send(sender, MessageKey.INVALID_PASSWORD_LENGTH); m.send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
return true; return;
} }
if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(playerPassLowerCase)) { if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(playerPassLowerCase)) {
m.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR); m.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
return true; return;
} }
// Set the password // Set the password
final String playerNameLowerCase = playerName.toLowerCase(); final String playerNameLowerCase = playerName.toLowerCase();
@ -90,6 +89,5 @@ public class ChangePasswordAdminCommand extends ExecutableCommand {
} }
}); });
return true;
} }
} }

View File

@ -1,18 +1,17 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.Spawn; import fr.xephi.authme.settings.Spawn;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** import java.util.List;
*/
public class FirstSpawnCommand extends ExecutableCommand { public class FirstSpawnCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Make sure the command executor is a player // Make sure the command executor is a player
try { try {
if (sender instanceof Player) { if (sender instanceof Player) {
@ -26,6 +25,5 @@ public class FirstSpawnCommand extends ExecutableCommand {
// TODO ljacqu 20151119: Catching NullPointerException is never a good idea. Find what can cause one instead // TODO ljacqu 20151119: Catching NullPointerException is never a good idea. Find what can cause one instead
ConsoleLogger.showError(ex.getMessage()); ConsoleLogger.showError(ex.getMessage());
} }
return true;
} }
} }

View File

@ -1,45 +1,45 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.permission.PlayerPermission;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.List;
/** /**
*/ */
public class ForceLoginCommand extends ExecutableCommand { public class ForceLoginCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// AuthMe plugin instance // AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance(); final AuthMe plugin = AuthMe.getInstance();
// Get the player query // Get the player query
String playerName = sender.getName(); String playerName = sender.getName();
if (commandArguments.getCount() >= 1) if (arguments.size() >= 1) {
playerName = commandArguments.get(0); playerName = arguments.get(0);
}
// Command logic // Command logic
try { try {
@SuppressWarnings("deprecation") // TODO ljacqu 20151212: Retrieve player via Utils method instead
Player player = Bukkit.getPlayer(playerName); Player player = Bukkit.getPlayer(playerName);
if (player == null || !player.isOnline()) { if (player == null || !player.isOnline()) {
sender.sendMessage("Player needs to be online!"); sender.sendMessage("Player needs to be online!");
return true; return;
} }
if (!plugin.getPermissionsManager().hasPermission(player, PlayerPermission.CAN_LOGIN_BE_FORCED)) { if (!plugin.getPermissionsManager().hasPermission(player, PlayerPermission.CAN_LOGIN_BE_FORCED)) {
sender.sendMessage("You cannot force login for the player " + playerName + "!"); sender.sendMessage("You cannot force login for the player " + playerName + "!");
return true; return;
} }
plugin.getManagement().performLogin(player, "dontneed", true); plugin.getManagement().performLogin(player, "dontneed", true);
sender.sendMessage("Force Login for " + playerName + " performed!"); sender.sendMessage("Force Login for " + playerName + " performed!");
} catch (Exception e) { } catch (Exception e) {
sender.sendMessage("An error occurred while trying to get that player!"); sender.sendMessage("An error occurred while trying to get that player!");
} }
return true;
} }
} }

View File

@ -2,31 +2,18 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
/** import java.util.List;
*/
public class GetEmailCommand extends ExecutableCommand { public class GetEmailCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Get the player name String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
String playerName = sender.getName();
if (commandArguments.getCount() >= 1)
playerName = commandArguments.get(0);
// Get the authenticated user // Get the authenticated user
AuthMe plugin = AuthMe.getInstance(); AuthMe plugin = AuthMe.getInstance();
@ -34,11 +21,10 @@ public class GetEmailCommand extends ExecutableCommand {
PlayerAuth auth = plugin.database.getAuth(playerName.toLowerCase()); PlayerAuth auth = plugin.database.getAuth(playerName.toLowerCase());
if (auth == null) { if (auth == null) {
m.send(sender, MessageKey.UNKNOWN_USER); m.send(sender, MessageKey.UNKNOWN_USER);
return true; return;
} }
// Show the email address // Show the email address
sender.sendMessage("[AuthMe] " + playerName + "'s email: " + auth.getEmail()); sender.sendMessage("[AuthMe] " + playerName + "'s email: " + auth.getEmail());
return true;
} }
} }

View File

@ -1,34 +1,32 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** import java.util.List;
*/
public class GetIpCommand extends ExecutableCommand { public class GetIpCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance(); final AuthMe plugin = AuthMe.getInstance();
// Get the player query // Get the player query
String playerName = sender.getName(); String playerName = (arguments.size() >= 1) ? arguments.get(0) : sender.getName();
if (commandArguments.getCount() >= 1)
playerName = commandArguments.get(0);
@SuppressWarnings("deprecation") // TODO ljacqu 20151212: Use the Utils function instead
Player player = Bukkit.getPlayer(playerName); Player player = Bukkit.getPlayer(playerName);
if (player == null) { if (player == null) {
sender.sendMessage("This player is not actually online"); sender.sendMessage("The player is not online");
return true; return;
} }
sender.sendMessage(player.getName() + "'s actual IP is : " + player.getAddress().getAddress().getHostAddress() + ":" + player.getAddress().getPort());
// TODO ljacqu 20151212: Revise the messages (actual IP vs. real IP...?)
sender.sendMessage(player.getName() + "'s actual IP is : " + player.getAddress().getAddress().getHostAddress()
+ ":" + player.getAddress().getPort());
sender.sendMessage(player.getName() + "'s real IP is : " + plugin.getIP(player)); sender.sendMessage(player.getName() + "'s real IP is : " + plugin.getIP(player));
return true;
} }
} }

View File

@ -2,24 +2,22 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
*/ */
public class LastLoginCommand extends ExecutableCommand { public class LastLoginCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Get the player // Get the player
String playerName = sender.getName(); String playerName = (arguments.size() >= 1) ? arguments.get(0) : sender.getName();
if (commandArguments.getCount() >= 1)
playerName = commandArguments.get(0);
// Validate the player // Validate the player
AuthMe plugin = AuthMe.getInstance(); AuthMe plugin = AuthMe.getInstance();
@ -30,11 +28,11 @@ public class LastLoginCommand extends ExecutableCommand {
auth = plugin.database.getAuth(playerName.toLowerCase()); auth = plugin.database.getAuth(playerName.toLowerCase());
} catch (NullPointerException e) { } catch (NullPointerException e) {
m.send(sender, MessageKey.UNKNOWN_USER); m.send(sender, MessageKey.UNKNOWN_USER);
return true; return;
} }
if (auth == null) { if (auth == null) {
m.send(sender, MessageKey.USER_NOT_REGISTERED); m.send(sender, MessageKey.USER_NOT_REGISTERED);
return true; return;
} }
// Get the last login date // Get the last login date
@ -45,7 +43,8 @@ public class LastLoginCommand extends ExecutableCommand {
final long diff = System.currentTimeMillis() - lastLogin; final long diff = System.currentTimeMillis() - lastLogin;
// Build the message // Build the message
final String msg = (int) (diff / 86400000) + " days " + (int) (diff / 3600000 % 24) + " hours " + (int) (diff / 60000 % 60) + " mins " + (int) (diff / 1000 % 60) + " secs."; final String msg = (int) (diff / 86400000) + " days " + (int) (diff / 3600000 % 24) + " hours "
+ (int) (diff / 60000 % 60) + " mins " + (int) (diff / 1000 % 60) + " secs.";
// Get the player's last IP // Get the player's last IP
String lastIP = auth.getIp(); String lastIP = auth.getIp();
@ -54,6 +53,5 @@ public class LastLoginCommand extends ExecutableCommand {
sender.sendMessage("[AuthMe] " + playerName + " last login : " + date.toString()); sender.sendMessage("[AuthMe] " + playerName + " last login : " + date.toString());
sender.sendMessage("[AuthMe] The player " + auth.getNickname() + " is unlogged since " + msg); sender.sendMessage("[AuthMe] The player " + auth.getNickname() + " is unlogged since " + msg);
sender.sendMessage("[AuthMe] Last Player's IP: " + lastIP); sender.sendMessage("[AuthMe] Last Player's IP: " + lastIP);
return true;
} }
} }

View File

@ -1,7 +1,6 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -10,21 +9,10 @@ import org.bukkit.command.CommandSender;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/**
*/
public class PurgeBannedPlayersCommand extends ExecutableCommand { public class PurgeBannedPlayersCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// AuthMe plugin instance // AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance(); final AuthMe plugin = AuthMe.getInstance();
@ -47,6 +35,5 @@ public class PurgeBannedPlayersCommand extends ExecutableCommand {
// Show a status message // Show a status message
sender.sendMessage("[AuthMe] Database has been purged correctly"); sender.sendMessage("[AuthMe] Database has been purged correctly");
return true;
} }
} }

View File

@ -1,7 +1,6 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -10,40 +9,29 @@ import org.bukkit.command.CommandSender;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
/**
*/
public class PurgeCommand extends ExecutableCommand { public class PurgeCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// AuthMe plugin instance // AuthMe plugin instance
AuthMe plugin = AuthMe.getInstance(); AuthMe plugin = AuthMe.getInstance();
// Get the days parameter // Get the days parameter
String daysStr = commandArguments.get(0); String daysStr = arguments.get(0);
// Convert the days string to an integer value, and make sure it's valid // Convert the days string to an integer value, and make sure it's valid
int days; int days;
try { try {
days = Integer.valueOf(daysStr); days = Integer.parseInt(daysStr);
} catch (Exception ex) { } catch (NumberFormatException ex) {
sender.sendMessage(ChatColor.RED + "The value you've entered is invalid!"); sender.sendMessage(ChatColor.RED + "The value you've entered is invalid!");
return true; return;
} }
// Validate the value // Validate the value
if (days < 30) { if (days < 30) {
sender.sendMessage(ChatColor.RED + "You can only purge data older than 30 days"); sender.sendMessage(ChatColor.RED + "You can only purge data older than 30 days");
return true; return;
} }
// Create a calender instance to determine the date // Create a calender instance to determine the date
@ -69,6 +57,5 @@ public class PurgeCommand extends ExecutableCommand {
// Show a status message // Show a status message
sender.sendMessage(ChatColor.GREEN + "[AuthMe] Database has been purged correctly"); sender.sendMessage(ChatColor.GREEN + "[AuthMe] Database has been purged correctly");
return true;
} }
} }

View File

@ -3,38 +3,24 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** import java.util.List;
*/
public class PurgeLastPositionCommand extends ExecutableCommand { public class PurgeLastPositionCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(final CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(final CommandSender sender, List<String> arguments) {
// AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance(); final AuthMe plugin = AuthMe.getInstance();
// Messages instance
final Messages m = plugin.getMessages(); final Messages m = plugin.getMessages();
String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
// Get the player // Get the player
String playerName = sender.getName();
if (commandArguments.getCount() >= 1)
playerName = commandArguments.get(0);
String playerNameLowerCase = playerName.toLowerCase(); String playerNameLowerCase = playerName.toLowerCase();
// Purge the last position of the player // Purge the last position of the player
@ -43,7 +29,7 @@ public class PurgeLastPositionCommand extends ExecutableCommand {
PlayerAuth auth = plugin.database.getAuth(playerNameLowerCase); PlayerAuth auth = plugin.database.getAuth(playerNameLowerCase);
if (auth == null) { if (auth == null) {
m.send(sender, MessageKey.UNKNOWN_USER); m.send(sender, MessageKey.UNKNOWN_USER);
return true; return;
} }
// Set the last position // Set the last position
@ -62,6 +48,5 @@ public class PurgeLastPositionCommand extends ExecutableCommand {
if (sender instanceof Player) if (sender instanceof Player)
sender.sendMessage("An error occurred while trying to reset location or player do not exist, please see logs"); sender.sendMessage("An error occurred while trying to reset location or player do not exist, please see logs");
} }
return true;
} }
} }

View File

@ -3,33 +3,24 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.List;
/** /**
* Admin command to register a user. * Admin command to register a user.
*/ */
public class RegisterAdminCommand extends ExecutableCommand { public class RegisterAdminCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(final CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(final CommandSender sender, List<String> arguments) {
// AuthMe plugin instance // AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance(); final AuthMe plugin = AuthMe.getInstance();
@ -37,8 +28,8 @@ public class RegisterAdminCommand extends ExecutableCommand {
final Messages m = plugin.getMessages(); final Messages m = plugin.getMessages();
// Get the player name and password // Get the player name and password
final String playerName = commandArguments.get(0); final String playerName = arguments.get(0);
final String playerPass = commandArguments.get(1); final String playerPass = arguments.get(1);
final String playerNameLowerCase = playerName.toLowerCase(); final String playerNameLowerCase = playerName.toLowerCase();
final String playerPassLowerCase = playerPass.toLowerCase(); final String playerPassLowerCase = playerPass.toLowerCase();
@ -49,20 +40,20 @@ public class RegisterAdminCommand extends ExecutableCommand {
|| playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null") || playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null")
|| !playerPassLowerCase.matches(Settings.getPassRegex)) { || !playerPassLowerCase.matches(Settings.getPassRegex)) {
m.send(sender, MessageKey.PASSWORD_MATCH_ERROR); m.send(sender, MessageKey.PASSWORD_MATCH_ERROR);
return true; return;
} }
if (playerPassLowerCase.equalsIgnoreCase(playerName)) { if (playerPassLowerCase.equalsIgnoreCase(playerName)) {
m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
return true; return;
} }
if (playerPassLowerCase.length() < Settings.getPasswordMinLen || playerPassLowerCase.length() > Settings.passwordMaxLength) { if (playerPassLowerCase.length() < Settings.getPasswordMinLen || playerPassLowerCase.length() > Settings.passwordMaxLength) {
m.send(sender, MessageKey.INVALID_PASSWORD_LENGTH); m.send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
return true; return;
} }
if (!Settings.unsafePasswords.isEmpty()) { if (!Settings.unsafePasswords.isEmpty()) {
if (Settings.unsafePasswords.contains(playerPassLowerCase)) { if (Settings.unsafePasswords.contains(playerPassLowerCase)) {
m.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR); m.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
return true; return;
} }
} }
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@ -95,6 +86,5 @@ public class RegisterAdminCommand extends ExecutableCommand {
} }
}); });
return true;
} }
} }

View File

@ -1,10 +1,7 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
//import org.bukkit.ChatColor;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
@ -12,21 +9,12 @@ import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Profiler; import fr.xephi.authme.util.Profiler;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
/** import java.util.List;
*/
public class ReloadCommand extends ExecutableCommand { public class ReloadCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Profile the reload process // Profile the reload process
Profiler p = new Profiler(true); Profiler p = new Profiler(true);
@ -48,7 +36,6 @@ public class ReloadCommand extends ExecutableCommand {
ConsoleLogger.showError("Fatal error occurred! AuthMe instance ABORTED!"); ConsoleLogger.showError("Fatal error occurred! AuthMe instance ABORTED!");
ConsoleLogger.writeStackTrace(e); ConsoleLogger.writeStackTrace(e);
plugin.stopOrUnload(); plugin.stopOrUnload();
return false;
} }
// Show a status message // Show a status message
@ -57,6 +44,5 @@ public class ReloadCommand extends ExecutableCommand {
// AuthMeReloaded reloaded, show a status message // AuthMeReloaded reloaded, show a status message
// sender.sendMessage(ChatColor.GREEN + "AuthMeReloaded has been reloaded successfully, took " + p.getTimeFormatted() + "!"); // sender.sendMessage(ChatColor.GREEN + "AuthMeReloaded has been reloaded successfully, took " + p.getTimeFormatted() + "!");
return true;
} }
} }

View File

@ -1,44 +0,0 @@
package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import org.bukkit.command.CommandSender;
import java.util.List;
/**
*/
// TODO: remove if not used
public class ResetNameCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) {
// AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance();
// Command logic
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
List<PlayerAuth> authentications = plugin.database.getAllAuths();
for (PlayerAuth auth : authentications) {
auth.setRealName("Player");
plugin.database.updateSession(auth);
}
}
});
return true;
}
}

View File

@ -3,28 +3,18 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
/** import java.util.List;
*/
public class SetEmailCommand extends ExecutableCommand { public class SetEmailCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(final CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(final CommandSender sender, List<String> arguments) {
// AuthMe plugin instance // AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance(); final AuthMe plugin = AuthMe.getInstance();
@ -32,13 +22,13 @@ public class SetEmailCommand extends ExecutableCommand {
final Messages m = plugin.getMessages(); final Messages m = plugin.getMessages();
// Get the player name and email address // Get the player name and email address
final String playerName = commandArguments.get(0); final String playerName = arguments.get(0);
final String playerEmail = commandArguments.get(1); final String playerEmail = arguments.get(1);
// Validate the email address // Validate the email address
if (!Settings.isEmailCorrect(playerEmail)) { if (!Settings.isEmailCorrect(playerEmail)) {
m.send(sender, MessageKey.INVALID_EMAIL); m.send(sender, MessageKey.INVALID_EMAIL);
return true; return;
} }
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@ -69,6 +59,5 @@ public class SetEmailCommand extends ExecutableCommand {
} }
}); });
return true;
} }
} }

View File

@ -1,27 +1,17 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.Spawn; import fr.xephi.authme.settings.Spawn;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** import java.util.List;
*/
public class SetFirstSpawnCommand extends ExecutableCommand { public class SetFirstSpawnCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
try { try {
if (sender instanceof Player) { if (sender instanceof Player) {
if (Spawn.getInstance().setFirstSpawn(((Player) sender).getLocation())) if (Spawn.getInstance().setFirstSpawn(((Player) sender).getLocation()))
@ -33,6 +23,5 @@ public class SetFirstSpawnCommand extends ExecutableCommand {
} catch (NullPointerException ex) { } catch (NullPointerException ex) {
ConsoleLogger.showError(ex.getMessage()); ConsoleLogger.showError(ex.getMessage());
} }
return true;
} }
} }

View File

@ -1,27 +1,17 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.Spawn; import fr.xephi.authme.settings.Spawn;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** import java.util.List;
*/
public class SetSpawnCommand extends ExecutableCommand { public class SetSpawnCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Make sure the command executor is a player // Make sure the command executor is a player
try { try {
if (sender instanceof Player) { if (sender instanceof Player) {
@ -36,6 +26,5 @@ public class SetSpawnCommand extends ExecutableCommand {
} catch (NullPointerException ex) { } catch (NullPointerException ex) {
ConsoleLogger.showError(ex.getMessage()); ConsoleLogger.showError(ex.getMessage());
} }
return true;
} }
} }

View File

@ -1,27 +1,17 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.Spawn; import fr.xephi.authme.settings.Spawn;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** import java.util.List;
*/
public class SpawnCommand extends ExecutableCommand { public class SpawnCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Make sure the command executor is a player // Make sure the command executor is a player
try { try {
if (sender instanceof Player) { if (sender instanceof Player) {
@ -29,11 +19,10 @@ public class SpawnCommand extends ExecutableCommand {
((Player) sender).teleport(Spawn.getInstance().getSpawn()); ((Player) sender).teleport(Spawn.getInstance().getSpawn());
else sender.sendMessage("[AuthMe] Spawn has failed, please try to define the spawn"); else sender.sendMessage("[AuthMe] Spawn has failed, please try to define the spawn");
} else { } else {
sender.sendMessage("[AuthMe] Please use that command in game"); sender.sendMessage("[AuthMe] Please use the command in game");
} }
} catch (NullPointerException ex) { } catch (NullPointerException ex) {
ConsoleLogger.showError(ex.getMessage()); ConsoleLogger.showError(ex.getMessage());
} }
return true;
} }
} }

View File

@ -1,64 +1,43 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AntiBot; import fr.xephi.authme.AntiBot;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandUtils; import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.command.help.HelpProvider; import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.util.CollectionUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.Arrays;
import java.util.List; import java.util.List;
/**
*/
public class SwitchAntiBotCommand extends ExecutableCommand { public class SwitchAntiBotCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(final CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(final CommandSender sender, List<String> arguments) {
// Get the new state if (arguments.isEmpty()) {
String newState = null;
if (commandArguments.getCount() == 1) {
newState = commandArguments.get(0);
} else if(commandArguments.getCount() == 0) {
sender.sendMessage("[AuthMe] AntiBot status: " + AntiBot.getAntiBotStatus().name()); sender.sendMessage("[AuthMe] AntiBot status: " + AntiBot.getAntiBotStatus().name());
return true; return;
} }
// Enable the mod String newState = arguments.get(0);
// Enable or disable the mod
if ("ON".equalsIgnoreCase(newState)) { if ("ON".equalsIgnoreCase(newState)) {
AntiBot.overrideAntiBotStatus(true); AntiBot.overrideAntiBotStatus(true);
sender.sendMessage("[AuthMe] AntiBot Manual Override: enabled!"); sender.sendMessage("[AuthMe] AntiBot Manual Override: enabled!");
return true; } else if ("OFF".equalsIgnoreCase(newState)) {
}
// Disable the mod
if ("OFF".equalsIgnoreCase(newState)) {
AntiBot.overrideAntiBotStatus(false); AntiBot.overrideAntiBotStatus(false);
sender.sendMessage("[AuthMe] AntiBotMod Manual Override: disabled!"); sender.sendMessage("[AuthMe] AntiBotMod Manual Override: disabled!");
return true; } else {
sender.sendMessage(ChatColor.DARK_RED + "Invalid AntiBot mode!");
// TODO ljacqu 20151213: Fix static retrieval of command handler
CommandHandler commandHandler = AuthMe.getInstance().getCommandHandler();
FoundCommandResult foundCommandResult =
commandHandler.mapPartsToCommand(Arrays.asList("authme", "antibot"));
HelpProvider.printHelp(foundCommandResult, HelpProvider.SHOW_ARGUMENTS);
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/authme help antibot");
} }
// Show the invalid arguments warning
sender.sendMessage(ChatColor.DARK_RED + "Invalid AntiBot mode!");
// Show the command argument help
HelpProvider.showHelp(sender, commandReference, commandReference, true, false, true, false, false, false);
// Show the command to use for detailed help
List<String> helpCommandReference = CollectionUtils.getRange(commandReference.getList(), 1);
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/"
+ commandReference.get(0) + " help " + CommandUtils.labelsToString(helpCommandReference));
return true;
} }
} }

View File

@ -4,7 +4,6 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
@ -19,22 +18,16 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import java.util.List;
/** /**
* Admin command to unregister a player. * Admin command to unregister a player.
*/ */
public class UnregisterAdminCommand extends ExecutableCommand { public class UnregisterAdminCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(final CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(final CommandSender sender, List<String> arguments) {
// AuthMe plugin instance // AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance(); final AuthMe plugin = AuthMe.getInstance();
@ -42,19 +35,19 @@ public class UnregisterAdminCommand extends ExecutableCommand {
final Messages m = plugin.getMessages(); final Messages m = plugin.getMessages();
// Get the player name // Get the player name
String playerName = commandArguments.get(0); String playerName = arguments.get(0);
String playerNameLowerCase = playerName.toLowerCase(); String playerNameLowerCase = playerName.toLowerCase();
// Make sure the user is valid // Make sure the user is valid
if (!plugin.database.isAuthAvailable(playerNameLowerCase)) { if (!plugin.database.isAuthAvailable(playerNameLowerCase)) {
m.send(sender, MessageKey.UNKNOWN_USER); m.send(sender, MessageKey.UNKNOWN_USER);
return true; return;
} }
// Remove the player // Remove the player
if (!plugin.database.removeAuth(playerNameLowerCase)) { if (!plugin.database.removeAuth(playerNameLowerCase)) {
m.send(sender, MessageKey.ERROR); m.send(sender, MessageKey.ERROR);
return true; return;
} }
// Unregister the player // Unregister the player
@ -85,6 +78,5 @@ public class UnregisterAdminCommand extends ExecutableCommand {
// Show a status message // Show a status message
m.send(sender, MessageKey.UNREGISTERED_SUCCESS); m.send(sender, MessageKey.UNREGISTERED_SUCCESS);
ConsoleLogger.info(playerName + " unregistered"); ConsoleLogger.info(playerName + " unregistered");
return true;
} }
} }

View File

@ -1,30 +1,19 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** import java.util.List;
*/
public class VersionCommand extends ExecutableCommand { public class VersionCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Show some version info // Show some version info
sender.sendMessage(ChatColor.GOLD + "==========[ " + Settings.helpHeader.toUpperCase() + " ABOUT ]=========="); sender.sendMessage(ChatColor.GOLD + "==========[ " + Settings.helpHeader.toUpperCase() + " ABOUT ]==========");
sender.sendMessage(ChatColor.GOLD + "Version: " + ChatColor.WHITE + AuthMe.getPluginName() + " v" + AuthMe.getPluginVersion() + ChatColor.GRAY + " (build: " + AuthMe.getPluginBuildNumber() + ")"); sender.sendMessage(ChatColor.GOLD + "Version: " + ChatColor.WHITE + AuthMe.getPluginName() + " v" + AuthMe.getPluginVersion() + ChatColor.GRAY + " (build: " + AuthMe.getPluginBuildNumber() + ")");
@ -37,7 +26,6 @@ public class VersionCommand extends ExecutableCommand {
sender.sendMessage(ChatColor.GOLD + "Website: " + ChatColor.WHITE + "http://dev.bukkit.org/bukkit-plugins/authme-reloaded/"); sender.sendMessage(ChatColor.GOLD + "Website: " + ChatColor.WHITE + "http://dev.bukkit.org/bukkit-plugins/authme-reloaded/");
sender.sendMessage(ChatColor.GOLD + "License: " + ChatColor.WHITE + "GNU GPL v3.0" + ChatColor.GRAY + ChatColor.ITALIC + " (See LICENSE file)"); sender.sendMessage(ChatColor.GOLD + "License: " + ChatColor.WHITE + "GNU GPL v3.0" + ChatColor.GRAY + ChatColor.ITALIC + " (See LICENSE file)");
sender.sendMessage(ChatColor.GOLD + "Copyright: " + ChatColor.WHITE + "Copyright (c) Xephi 2015. All rights reserved."); sender.sendMessage(ChatColor.GOLD + "Copyright: " + ChatColor.WHITE + "Copyright (c) Xephi 2015. All rights reserved.");
return true;
} }
/** /**

View File

@ -2,25 +2,24 @@ package fr.xephi.authme.command.executable.captcha;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** import java.util.List;
*/
public class CaptchaCommand extends ExecutableCommand { public class CaptchaCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Make sure the current command executor is a player // Make sure the current command executor is a player
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
return true; return;
} }
// Get the player instance and name // Get the player instance and name
@ -28,7 +27,7 @@ public class CaptchaCommand extends ExecutableCommand {
final String playerNameLowerCase = player.getName().toLowerCase(); final String playerNameLowerCase = player.getName().toLowerCase();
// Get the parameter values // Get the parameter values
String captcha = commandArguments.get(0); String captcha = arguments.get(0);
// AuthMe plugin instance // AuthMe plugin instance
final Wrapper wrapper = Wrapper.getInstance(); final Wrapper wrapper = Wrapper.getInstance();
@ -40,18 +39,18 @@ public class CaptchaCommand extends ExecutableCommand {
// Command logic // Command logic
if (PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) { if (PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) {
m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
return true; return;
} }
if (!Settings.useCaptcha) { if (!Settings.useCaptcha) {
m.send(player, MessageKey.USAGE_LOGIN); m.send(player, MessageKey.USAGE_LOGIN);
return true; return;
} }
if (!plugin.cap.containsKey(playerNameLowerCase)) { if (!plugin.cap.containsKey(playerNameLowerCase)) {
m.send(player, MessageKey.USAGE_LOGIN); m.send(player, MessageKey.USAGE_LOGIN);
return true; return;
} }
if (Settings.useCaptcha && !captcha.equals(plugin.cap.get(playerNameLowerCase))) { if (Settings.useCaptcha && !captcha.equals(plugin.cap.get(playerNameLowerCase))) {
@ -59,7 +58,7 @@ public class CaptchaCommand extends ExecutableCommand {
String randStr = new RandomString(Settings.captchaLength).nextString(); String randStr = new RandomString(Settings.captchaLength).nextString();
plugin.cap.put(playerNameLowerCase, randStr); plugin.cap.put(playerNameLowerCase, randStr);
m.send(player, MessageKey.CAPTCHA_WRONG_ERROR, plugin.cap.get(playerNameLowerCase)); m.send(player, MessageKey.CAPTCHA_WRONG_ERROR, plugin.cap.get(playerNameLowerCase));
return true; return;
} }
plugin.captcha.remove(playerNameLowerCase); plugin.captcha.remove(playerNameLowerCase);
@ -68,6 +67,5 @@ public class CaptchaCommand extends ExecutableCommand {
// Show a status message // Show a status message
m.send(player, MessageKey.CAPTCHA_SUCCESS); m.send(player, MessageKey.CAPTCHA_SUCCESS);
m.send(player, MessageKey.LOGIN_MESSAGE); m.send(player, MessageKey.LOGIN_MESSAGE);
return true;
} }
} }

View File

@ -2,7 +2,6 @@ package fr.xephi.authme.command.executable.changepassword;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
@ -12,24 +11,26 @@ import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.List;
/** /**
* The command for a player to change his password with. * The command for a player to change his password with.
*/ */
public class ChangePasswordCommand extends ExecutableCommand { public class ChangePasswordCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Make sure the current command executor is a player // Make sure the current command executor is a player
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
return true; return;
} }
final Wrapper wrapper = Wrapper.getInstance(); final Wrapper wrapper = Wrapper.getInstance();
final Messages m = wrapper.getMessages(); final Messages m = wrapper.getMessages();
// Get the passwords // Get the passwords
String oldPassword = commandArguments.get(0); String oldPassword = arguments.get(0);
String newPassword = commandArguments.get(1); String newPassword = arguments.get(1);
// Get the player instance and make sure he's authenticated // Get the player instance and make sure he's authenticated
Player player = (Player) sender; Player player = (Player) sender;
@ -37,7 +38,7 @@ public class ChangePasswordCommand extends ExecutableCommand {
final PlayerCache playerCache = wrapper.getPlayerCache(); final PlayerCache playerCache = wrapper.getPlayerCache();
if (!playerCache.isAuthenticated(name)) { if (!playerCache.isAuthenticated(name)) {
m.send(player, MessageKey.NOT_LOGGED_IN); m.send(player, MessageKey.NOT_LOGGED_IN);
return true; return;
} }
// Make sure the password is allowed // Make sure the password is allowed
@ -48,26 +49,25 @@ public class ChangePasswordCommand extends ExecutableCommand {
|| playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null") || playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null")
|| !playerPassLowerCase.matches(Settings.getPassRegex)) { || !playerPassLowerCase.matches(Settings.getPassRegex)) {
m.send(player, MessageKey.PASSWORD_MATCH_ERROR); m.send(player, MessageKey.PASSWORD_MATCH_ERROR);
return true; return;
} }
if (playerPassLowerCase.equalsIgnoreCase(name)) { if (playerPassLowerCase.equalsIgnoreCase(name)) {
m.send(player, MessageKey.PASSWORD_IS_USERNAME_ERROR); m.send(player, MessageKey.PASSWORD_IS_USERNAME_ERROR);
return true; return;
} }
if (playerPassLowerCase.length() < Settings.getPasswordMinLen if (playerPassLowerCase.length() < Settings.getPasswordMinLen
|| playerPassLowerCase.length() > Settings.passwordMaxLength) { || playerPassLowerCase.length() > Settings.passwordMaxLength) {
m.send(player, MessageKey.INVALID_PASSWORD_LENGTH); m.send(player, MessageKey.INVALID_PASSWORD_LENGTH);
return true; return;
} }
if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(playerPassLowerCase)) { if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(playerPassLowerCase)) {
m.send(player, MessageKey.PASSWORD_UNSAFE_ERROR); m.send(player, MessageKey.PASSWORD_UNSAFE_ERROR);
return true; return;
} }
// Set the password // Set the password
final AuthMe plugin = wrapper.getAuthMe(); final AuthMe plugin = wrapper.getAuthMe();
wrapper.getScheduler().runTaskAsynchronously(plugin, wrapper.getScheduler().runTaskAsynchronously(plugin,
new ChangePasswordTask(plugin, player, oldPassword, newPassword)); new ChangePasswordTask(plugin, player, oldPassword, newPassword));
return true;
} }
} }

View File

@ -1,29 +1,27 @@
package fr.xephi.authme.command.executable.converter; package fr.xephi.authme.command.executable.converter;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.converter.*; import fr.xephi.authme.converter.Converter;
import fr.xephi.authme.converter.CrazyLoginConverter;
import fr.xephi.authme.converter.FlatToSql;
import fr.xephi.authme.converter.FlatToSqlite;
import fr.xephi.authme.converter.RakamakConverter;
import fr.xephi.authme.converter.RoyalAuthConverter;
import fr.xephi.authme.converter.SqlToFlat;
import fr.xephi.authme.converter.vAuthConverter;
import fr.xephi.authme.converter.xAuthConverter;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
/** import java.util.List;
*/
public class ConverterCommand extends ExecutableCommand { public class ConverterCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// AuthMe plugin instance // AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance(); final AuthMe plugin = AuthMe.getInstance();
@ -31,40 +29,40 @@ public class ConverterCommand extends ExecutableCommand {
final Messages m = plugin.getMessages(); final Messages m = plugin.getMessages();
// Get the conversion job // Get the conversion job
String job = commandArguments.get(0); String job = arguments.get(0);
// Determine the job type // Determine the job type
ConvertType jobType = ConvertType.fromName(job); ConvertType jobType = ConvertType.fromName(job);
if (jobType == null) { if (jobType == null) {
m.send(sender, MessageKey.ERROR); m.send(sender, MessageKey.ERROR);
return true; return;
} }
// Get the proper converter instance // Get the proper converter instance
Converter converter = null; Converter converter = null;
switch (jobType) { switch (jobType) {
case ftsql: case FTSQL:
converter = new FlatToSql(); converter = new FlatToSql();
break; break;
case ftsqlite: case FTSQLITE:
converter = new FlatToSqlite(sender); converter = new FlatToSqlite(sender);
break; break;
case xauth: case XAUTH:
converter = new xAuthConverter(plugin, sender); converter = new xAuthConverter(plugin, sender);
break; break;
case crazylogin: case CRAZYLOGIN:
converter = new CrazyLoginConverter(plugin, sender); converter = new CrazyLoginConverter(plugin, sender);
break; break;
case rakamak: case RAKAMAK:
converter = new RakamakConverter(plugin, sender); converter = new RakamakConverter(plugin, sender);
break; break;
case royalauth: case ROYALAUTH:
converter = new RoyalAuthConverter(plugin); converter = new RoyalAuthConverter(plugin);
break; break;
case vauth: case VAUTH:
converter = new vAuthConverter(plugin, sender); converter = new vAuthConverter(plugin, sender);
break; break;
case sqltoflat: case SQLTOFLAT:
converter = new SqlToFlat(plugin, sender); converter = new SqlToFlat(plugin, sender);
break; break;
default: default:
@ -76,52 +74,33 @@ public class ConverterCommand extends ExecutableCommand {
// Show a status message // Show a status message
sender.sendMessage("[AuthMe] Successfully converted from " + jobType.getName()); sender.sendMessage("[AuthMe] Successfully converted from " + jobType.getName());
return true;
} }
/**
*/
public enum ConvertType { public enum ConvertType {
ftsql("flattosql"), FTSQL("flattosql"),
ftsqlite("flattosqlite"), FTSQLITE("flattosqlite"),
xauth("xauth"), XAUTH("xauth"),
crazylogin("crazylogin"), CRAZYLOGIN("crazylogin"),
rakamak("rakamak"), RAKAMAK("rakamak"),
royalauth("royalauth"), ROYALAUTH("royalauth"),
vauth("vauth"), VAUTH("vauth"),
sqltoflat("sqltoflat"); SQLTOFLAT("sqltoflat");
final String name; final String name;
/**
* Constructor for ConvertType.
*
* @param name String
*/
ConvertType(String name) { ConvertType(String name) {
this.name = name; this.name = name;
} }
/**
* Method fromName.
*
* @param name String
*
* @return ConvertType
*/
public static ConvertType fromName(String name) { public static ConvertType fromName(String name) {
for (ConvertType type : ConvertType.values()) { for (ConvertType type : ConvertType.values()) {
if (type.getName().equalsIgnoreCase(name)) if (type.getName().equalsIgnoreCase(name)) {
return type; return type;
}
} }
return null; return null;
} }
/**
* Method getName.
*
* @return String
*/
String getName() { String getName() {
return this.name; return this.name;
} }

View File

@ -1,31 +1,29 @@
package fr.xephi.authme.command.executable.email; package fr.xephi.authme.command.executable.email;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** import java.util.List;
*/
public class AddEmailCommand extends ExecutableCommand { public class AddEmailCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Make sure the current command executor is a player // Make sure the current command executor is a player
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
return true; return;
} }
// Get the parameter values // Get the parameter values
String playerMail = commandArguments.get(0); String playerMail = arguments.get(0);
String playerMailVerify = commandArguments.get(1); String playerMailVerify = arguments.get(1);
// Get the player and perform email addition // Get the player and perform email addition
final AuthMe plugin = Wrapper.getInstance().getAuthMe(); final AuthMe plugin = Wrapper.getInstance().getAuthMe();
final Player player = (Player) sender; final Player player = (Player) sender;
plugin.getManagement().performAddEmail(player, playerMail, playerMailVerify); plugin.getManagement().performAddEmail(player, playerMail, playerMailVerify);
return true;
} }
} }

View File

@ -1,31 +1,31 @@
package fr.xephi.authme.command.executable.email; package fr.xephi.authme.command.executable.email;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.List;
/** /**
*/ */
public class ChangeEmailCommand extends ExecutableCommand { public class ChangeEmailCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Make sure the current command executor is a player // Make sure the current command executor is a player
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
return true; return;
} }
// Get the parameter values // Get the parameter values
String playerMailOld = commandArguments.get(0); String playerMailOld = arguments.get(0);
String playerMailNew = commandArguments.get(1); String playerMailNew = arguments.get(1);
// Get the player instance and execute action // Get the player instance and execute action
final AuthMe plugin = Wrapper.getInstance().getAuthMe(); final AuthMe plugin = Wrapper.getInstance().getAuthMe();
final Player player = (Player) sender; final Player player = (Player) sender;
plugin.getManagement().performChangeEmail(player, playerMailOld, playerMailNew); plugin.getManagement().performChangeEmail(player, playerMailOld, playerMailNew);
return true;
} }
} }

View File

@ -4,32 +4,30 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.List;
/**
*/
public class RecoverEmailCommand extends ExecutableCommand { public class RecoverEmailCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Make sure the current command executor is a player // Make sure the current command executor is a player
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
return true; return;
} }
// Get the parameter values // Get the parameter values
String playerMail = commandArguments.get(0); String playerMail = arguments.get(0);
// Get the player instance and name // Get the player instance and name
final Player player = (Player) sender; final Player player = (Player) sender;
@ -42,12 +40,12 @@ public class RecoverEmailCommand extends ExecutableCommand {
if (plugin.mail == null) { if (plugin.mail == null) {
m.send(player, MessageKey.ERROR); m.send(player, MessageKey.ERROR);
return true; return;
} }
if (plugin.database.isAuthAvailable(playerName)) { if (plugin.database.isAuthAvailable(playerName)) {
if (PlayerCache.getInstance().isAuthenticated(playerName)) { if (PlayerCache.getInstance().isAuthenticated(playerName)) {
m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
return true; return;
} }
try { try {
RandomString rand = new RandomString(Settings.getRecoveryPassLength); RandomString rand = new RandomString(Settings.getRecoveryPassLength);
@ -60,16 +58,17 @@ public class RecoverEmailCommand extends ExecutableCommand {
auth = plugin.database.getAuth(playerName); auth = plugin.database.getAuth(playerName);
} else { } else {
m.send(player, MessageKey.UNKNOWN_USER); m.send(player, MessageKey.UNKNOWN_USER);
return true; return;
} }
if (Settings.getmailAccount.equals("") || Settings.getmailAccount.isEmpty()) { if (Settings.getmailAccount.equals("") || Settings.getmailAccount.isEmpty()) {
m.send(player, MessageKey.ERROR); m.send(player, MessageKey.ERROR);
return true; return;
} }
if (!playerMail.equalsIgnoreCase(auth.getEmail()) || playerMail.equalsIgnoreCase("your@email.com") || auth.getEmail().equalsIgnoreCase("your@email.com")) { if (!playerMail.equalsIgnoreCase(auth.getEmail()) || playerMail.equalsIgnoreCase("your@email.com")
|| auth.getEmail().equalsIgnoreCase("your@email.com")) {
m.send(player, MessageKey.INVALID_EMAIL); m.send(player, MessageKey.INVALID_EMAIL);
return true; return;
} }
auth.setHash(hashNew); auth.setHash(hashNew);
plugin.database.updatePassword(auth); plugin.database.updatePassword(auth);
@ -83,7 +82,5 @@ public class RecoverEmailCommand extends ExecutableCommand {
} else { } else {
m.send(player, MessageKey.REGISTER_EMAIL_MESSAGE); m.send(player, MessageKey.REGISTER_EMAIL_MESSAGE);
} }
return true;
} }
} }

View File

@ -1,30 +1,28 @@
package fr.xephi.authme.command.executable.login; package fr.xephi.authme.command.executable.login;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** import java.util.List;
*/
public class LoginCommand extends ExecutableCommand { public class LoginCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Make sure the current command executor is a player // Make sure the current command executor is a player
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
return true; return;
} }
// Get the necessary objects // Get the necessary objects
final AuthMe plugin = Wrapper.getInstance().getAuthMe(); final AuthMe plugin = Wrapper.getInstance().getAuthMe();
final Player player = (Player) sender; final Player player = (Player) sender;
final String password = commandArguments.get(0); final String password = arguments.get(0);
// Log the player in // Log the player in
plugin.getManagement().performLogin(player, password, false); plugin.getManagement().performLogin(player, password, false);
return true;
} }
} }

View File

@ -1,21 +1,22 @@
package fr.xephi.authme.command.executable.logout; package fr.xephi.authme.command.executable.logout;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.List;
/** /**
*/ */
public class LogoutCommand extends ExecutableCommand { public class LogoutCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Make sure the current command executor is a player // Make sure the current command executor is a player
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
return true; return;
} }
// Get the player instance // Get the player instance
@ -24,6 +25,5 @@ public class LogoutCommand extends ExecutableCommand {
// Logout the player // Logout the player
plugin.getManagement().performLogout(player); plugin.getManagement().performLogout(player);
return true;
} }
} }

View File

@ -1,28 +1,26 @@
package fr.xephi.authme.command.executable.register; package fr.xephi.authme.command.executable.register;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** import java.util.List;
*/
public class RegisterCommand extends ExecutableCommand { public class RegisterCommand extends ExecutableCommand {
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// Make sure the sender is a player // Make sure the sender is a player
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
sender.sendMessage("Player Only! Use 'authme register <playername> <password>' instead"); sender.sendMessage("Player Only! Use 'authme register <playername> <password>' instead");
return true; return;
} }
final Wrapper wrapper = Wrapper.getInstance(); final Wrapper wrapper = Wrapper.getInstance();
@ -31,35 +29,32 @@ public class RegisterCommand extends ExecutableCommand {
// Make sure the command arguments are valid // Make sure the command arguments are valid
final Player player = (Player) sender; final Player player = (Player) sender;
if (commandArguments.getCount() == 0 || (Settings.getEnablePasswordVerifier && commandArguments.getCount() < 2)) { if (arguments.isEmpty() || (Settings.getEnablePasswordVerifier && arguments.size() < 2)) {
m.send(player, MessageKey.USAGE_REGISTER); m.send(player, MessageKey.USAGE_REGISTER);
return true; return;
} }
final Management management = plugin.getManagement(); final Management management = plugin.getManagement();
if (Settings.emailRegistration && !Settings.getmailAccount.isEmpty()) { if (Settings.emailRegistration && !Settings.getmailAccount.isEmpty()) {
if (Settings.doubleEmailCheck) { if (Settings.doubleEmailCheck && arguments.size() < 2 || !arguments.get(0).equals(arguments.get(1))) {
if (commandArguments.getCount() < 2 || !commandArguments.get(0).equals(commandArguments.get(1))) { m.send(player, MessageKey.USAGE_REGISTER);
m.send(player, MessageKey.USAGE_REGISTER); return;
return true;
}
} }
final String email = commandArguments.get(0); final String email = arguments.get(0);
if (!Settings.isEmailCorrect(email)) { if (!Settings.isEmailCorrect(email)) {
m.send(player, MessageKey.INVALID_EMAIL); m.send(player, MessageKey.INVALID_EMAIL);
return true; return;
} }
final String thePass = new RandomString(Settings.getRecoveryPassLength).nextString(); final String thePass = new RandomString(Settings.getRecoveryPassLength).nextString();
management.performRegister(player, thePass, email); management.performRegister(player, thePass, email);
return true; return;
} }
if (commandArguments.getCount() > 1 && Settings.getEnablePasswordVerifier) { if (arguments.size() > 1 && Settings.getEnablePasswordVerifier) {
if (!commandArguments.get(0).equals(commandArguments.get(1))) { if (!arguments.get(0).equals(arguments.get(1))) {
m.send(player, MessageKey.PASSWORD_MATCH_ERROR); m.send(player, MessageKey.PASSWORD_MATCH_ERROR);
return true; return;
} }
} }
management.performRegister(player, commandArguments.get(0), ""); management.performRegister(player, arguments.get(0), "");
return true;
} }
} }

View File

@ -2,41 +2,28 @@ package fr.xephi.authme.command.executable.unregister;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** import java.util.List;
*/
public class UnregisterCommand extends ExecutableCommand { public class UnregisterCommand extends ExecutableCommand {
/**
* Execute the command.
*
* @param sender The command sender.
* @param commandReference The command reference.
* @param commandArguments The command arguments.
*
* @return True if the command was executed successfully, false otherwise.
*/
@Override @Override
public boolean executeCommand(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public void executeCommand(CommandSender sender, List<String> arguments) {
// AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance();
// Messages instance
final Messages m = plugin.getMessages();
// Make sure the current command executor is a player // Make sure the current command executor is a player
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
return true; return;
} }
final AuthMe plugin = AuthMe.getInstance();
final Messages m = plugin.getMessages();
// Get the password // Get the password
String playerPass = commandArguments.get(0); String playerPass = arguments.get(0);
// Get the player instance and name // Get the player instance and name
final Player player = (Player) sender; final Player player = (Player) sender;
@ -45,11 +32,10 @@ public class UnregisterCommand extends ExecutableCommand {
// Make sure the player is authenticated // Make sure the player is authenticated
if (!PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) { if (!PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) {
m.send(player, MessageKey.NOT_LOGGED_IN); m.send(player, MessageKey.NOT_LOGGED_IN);
return true; return;
} }
// Unregister the player // Unregister the player
plugin.getManagement().performUnregister(player, playerPass, false); plugin.getManagement().performUnregister(player, playerPass, false);
return true;
} }
} }

View File

@ -0,0 +1,36 @@
package fr.xephi.authme.command.help;
import fr.xephi.authme.command.CommandArgumentDescription;
import fr.xephi.authme.command.CommandDescription;
import org.bukkit.ChatColor;
import java.util.List;
/**
* Helper class for displaying the syntax of a command properly to a user.
*/
class CommandSyntaxHelper {
private CommandSyntaxHelper() {
}
public static String getSyntax(CommandDescription command, List<String> correctLabels) {
String commandSyntax = ChatColor.WHITE + "/" + correctLabels.get(0) + ChatColor.YELLOW;
for (int i = 1; i < correctLabels.size(); ++i) {
commandSyntax += " " + correctLabels.get(i);
}
for (CommandArgumentDescription argument : command.getArguments()) {
commandSyntax += " " + formatArgument(argument);
}
return commandSyntax;
}
/** Format a command argument with the proper type of brackets. */
private static String formatArgument(CommandArgumentDescription argument) {
if (argument.isOptional()) {
return "[" + argument.getName() + "]";
}
return "<" + argument.getName() + ">";
}
}

View File

@ -1,194 +0,0 @@
package fr.xephi.authme.command.help;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandArgumentDescription;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.CommandPermissions;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils;
/**
*/
public class HelpPrinter {
/**
* Print the command help information.
*
* @param sender The command sender to print the help to.
* @param command The command to print.
* @param commandReference The command reference used.
*/
public static void printCommand(CommandSender sender, CommandDescription command, CommandParts commandReference) {
// Print the proper command syntax
sender.sendMessage(ChatColor.GOLD + "Command: " + HelpSyntaxHelper.getCommandSyntax(command, commandReference, null, true));
}
/**
* Print the command help description information. This will print both the short, as the detailed description if available.
*
* @param sender The command sender to print the help to.
* @param command The command to print the description help for.
*/
public static void printCommandDescription(CommandSender sender, CommandDescription command) {
sender.sendMessage(ChatColor.GOLD + "Short Description: " + ChatColor.WHITE + command.getDescription());
// Print the detailed description, if available
if (!StringUtils.isEmpty(command.getDetailedDescription())) {
sender.sendMessage(ChatColor.GOLD + "Detailed Description:");
sender.sendMessage(ChatColor.WHITE + " " + command.getDetailedDescription());
}
}
/**
* Print the command help arguments information if available.
*
* @param sender The command sender to print the help to.
* @param command The command to print the argument help for.
*/
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
public static void printArguments(CommandSender sender, CommandDescription command) {
// Make sure there are any commands to print
if (!command.hasArguments())
return;
// Print the header
sender.sendMessage(ChatColor.GOLD + "Arguments:");
// Print each argument
for (CommandArgumentDescription arg : command.getArguments()) {
// Create a string builder to build the syntax in
StringBuilder argString = new StringBuilder();
argString.append(" " + ChatColor.YELLOW + ChatColor.ITALIC + arg.getLabel() + " : " + ChatColor.WHITE + arg.getDescription());
// Suffix a note if the command is optional
if (arg.isOptional())
argString.append(ChatColor.GRAY + "" + ChatColor.ITALIC + " (Optional)");
// Print the syntax
sender.sendMessage(argString.toString());
}
}
/**
* Print the command help permissions information if available.
*
* @param sender The command sender to print the help to.
* @param command The command to print the permissions help for.
*/
public static void printPermissions(CommandSender sender, CommandDescription command) {
// Get the permissions and make sure they aren't missing
CommandPermissions permissions = command.getCommandPermissions();
if (permissions == null || CollectionUtils.isEmpty(permissions.getPermissionNodes())) {
return;
}
// Print the header
sender.sendMessage(ChatColor.GOLD + "Permissions:");
// Print each node
for (PermissionNode node : permissions.getPermissionNodes()) {
boolean nodePermission = true;
if (sender instanceof Player)
nodePermission = AuthMe.getInstance().getPermissionsManager().hasPermission((Player) sender, node);
final String nodePermsString = ChatColor.GRAY + (nodePermission ? ChatColor.ITALIC + " (Permission!)" : ChatColor.ITALIC + " (No Permission!)");
sender.sendMessage(" " + ChatColor.YELLOW + ChatColor.ITALIC + node.getNode() + nodePermsString);
}
// Print the default permission
// TODO ljacqu 20151205: This is duplicating the logic in PermissionsManager#evaluateDefaultPermission
// Either use the command manager here, or if that's too heavy, look into moving certain permissions logic
// into a Utils class
switch (permissions.getDefaultPermission()) {
case ALLOWED:
sender.sendMessage(ChatColor.GOLD + " Default: " + ChatColor.GRAY + ChatColor.ITALIC + "Permission!");
break;
case OP_ONLY:
final String defaultPermsString = ChatColor.GRAY + (sender.isOp() ? ChatColor.ITALIC + " (Permission!)" : ChatColor.ITALIC + " (No Permission!)");
sender.sendMessage(ChatColor.GOLD + " Default: " + ChatColor.YELLOW + ChatColor.ITALIC + "OP's Only!" + defaultPermsString);
break;
case NOT_ALLOWED:
default:
sender.sendMessage(ChatColor.GOLD + " Default: " + ChatColor.GRAY + ChatColor.ITALIC + "No Permission!");
break;
}
// Print the permission result
if (permissions.hasPermission(sender))
sender.sendMessage(ChatColor.GOLD + " Result: " + ChatColor.GREEN + ChatColor.ITALIC + "Permission!");
else
sender.sendMessage(ChatColor.GOLD + " Result: " + ChatColor.DARK_RED + ChatColor.ITALIC + "No Permission!");
}
/**
* Print the command help alternatives information if available.
*
* @param sender The command sender to print the help to.
* @param command The command used.
* @param commandReference The original command reference used for this command.
*/
public static void printAlternatives(CommandSender sender, CommandDescription command, CommandParts commandReference) {
// Make sure there are any alternatives
if (command.getLabels().size() <= 1)
return;
// Print the header
sender.sendMessage(ChatColor.GOLD + "Alternatives:");
// Get the label used
final String usedLabel = commandReference.get(command.getParentCount());
// Create a list of alternatives
List<String> alternatives = new ArrayList<>();
for (String entry : command.getLabels()) {
// Exclude the proper argument
if (entry.equalsIgnoreCase(usedLabel))
continue;
alternatives.add(entry);
}
// Sort the alternatives
Collections.sort(alternatives, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return Double.compare(StringUtils.getDifference(usedLabel, o1), StringUtils.getDifference(usedLabel, o2));
}
});
// Print each alternative with proper syntax
for (String alternative : alternatives)
sender.sendMessage(" " + HelpSyntaxHelper.getCommandSyntax(command, commandReference, alternative, true));
}
/**
* Print the command help child's information if available.
*
* @param sender The command sender to print the help to.
* @param command The command to print the help for.
* @param commandReference The original command reference used for this command.
*/
public static void printChildren(CommandSender sender, CommandDescription command, CommandParts commandReference) {
// Make sure there are child's
if (command.getChildren().size() <= 0)
return;
// Print the header
sender.sendMessage(ChatColor.GOLD + "Commands:");
// Loop through each child
for (CommandDescription child : command.getChildren())
sender.sendMessage(" " + HelpSyntaxHelper.getCommandSyntax(child, commandReference, null, false) + ChatColor.GRAY + ChatColor.ITALIC + " : " + child.getDescription());
}
}

View File

@ -1,12 +1,16 @@
package fr.xephi.authme.command.help; package fr.xephi.authme.command.help;
import fr.xephi.authme.AuthMe; import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import fr.xephi.authme.command.CommandArgumentDescription;
import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandPermissions;
import fr.xephi.authme.command.CommandUtils; import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.command.FoundCommandResult; import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.CollectionUtils; import fr.xephi.authme.util.CollectionUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -14,120 +18,182 @@ import org.bukkit.command.CommandSender;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
/** /**
* Help syntax generator for AuthMe commands.
*/ */
public class HelpProvider { public final class HelpProvider {
/** // --- Bit flags ---
* Show help for a specific command. /** Set to <i>not</i> show the command. */
* public static final int HIDE_COMMAND = 0x001;
* @param sender The command sender the help needs to be shown to. /** Set to show the detailed description of a command. */
* @param reference The command reference to the help command. public static final int SHOW_LONG_DESCRIPTION = 0x002;
* @param helpQuery The query to show help for. /** Set to include the arguments the command takes. */
*/ public static final int SHOW_ARGUMENTS = 0x004;
public static void showHelp(CommandSender sender, CommandParts reference, CommandParts helpQuery) { /** Set to show the permissions required to execute the command. */
showHelp(sender, reference, helpQuery, true, true, true, true, true, true); public static final int SHOW_PERMISSIONS = 0x008;
/** Set to show alternative labels for the command. */
public static final int SHOW_ALTERNATIVES = 0x010;
/** Set to show the child commands of the command. */
public static final int SHOW_CHILDREN = 0x020;
/** Shortcut for setting all options apart from {@link HelpProvider#HIDE_COMMAND}. */
public static final int ALL_OPTIONS = ~HIDE_COMMAND;
private HelpProvider() {
} }
/** public static List<String> printHelp(FoundCommandResult foundCommand, int options) {
* Show help for a specific command. return printHelp(foundCommand, null, null, options);
* }
* @param sender The command sender the help needs to be shown to.
* @param reference The command reference to the help command.
* @param helpQuery The query to show help for.
* @param showCommand True to show the command.
* @param showDescription True to show the command description, both the short and detailed description.
* @param showArguments True to show the command argument help.
* @param showPermissions True to show the command permission help.
* @param showAlternatives True to show the command alternatives.
* @param showCommands True to show the child commands.
*/
public static void showHelp(CommandSender sender, CommandParts reference, CommandParts helpQuery, boolean showCommand, boolean showDescription, boolean showArguments, boolean showPermissions, boolean showAlternatives, boolean showCommands) {
// Find the command for this help query, one with and one without a prefixed base command
FoundCommandResult result = AuthMe.getInstance().getCommandHandler().findCommand(new CommandParts(helpQuery.getList()));
// TODO ljacqu 20151204 Fix me to nicer code // sender and permissions manager may be null if SHOW_PERMISSIONS is not set
List<String> parts = new ArrayList<>(helpQuery.getList()); public static List<String> printHelp(FoundCommandResult foundCommand, CommandSender sender,
parts.add(0, reference.get(0)); PermissionsManager permissionsManager, int options) {
CommandParts commandReferenceOther = new CommandParts(parts); if (foundCommand.getCommandDescription() == null) {
return singletonList(ChatColor.DARK_RED + "Failed to retrieve any help information!");
FoundCommandResult resultOther = AuthMe.getInstance().getCommandHandler().findCommand(commandReferenceOther);
if (resultOther != null) {
if (result == null)
result = resultOther;
else if (result.getDifference() > resultOther.getDifference())
result = resultOther;
} }
// Make sure a result was found List<String> lines = new ArrayList<>();
if (result == null) { lines.add(ChatColor.GOLD + "==========[ " + Settings.helpHeader + " HELP ]==========");
// Show a warning message
sender.sendMessage(ChatColor.DARK_RED + "" + ChatColor.ITALIC + helpQuery); CommandDescription command = foundCommand.getCommandDescription();
sender.sendMessage(ChatColor.DARK_RED + "Couldn't show any help information for this help query."); List<String> labels = ImmutableList.copyOf(foundCommand.getLabels());
List<String> correctLabels = ImmutableList.copyOf(filterCorrectLabels(command, labels));
if (!hasFlag(HIDE_COMMAND, options)) {
lines.add(ChatColor.GOLD + "Command: " + CommandSyntaxHelper.getSyntax(command, correctLabels));
}
if (hasFlag(SHOW_LONG_DESCRIPTION, options)) {
printDetailedDescription(command, lines);
}
if (hasFlag(SHOW_ARGUMENTS, options)) {
printArguments(command, lines);
}
if (hasFlag(SHOW_PERMISSIONS, options) && sender != null && permissionsManager != null) {
printPermissions(command, sender, permissionsManager, lines);
}
if (hasFlag(SHOW_ALTERNATIVES, options)) {
printAlternatives(command, correctLabels, lines);
}
if (hasFlag(SHOW_CHILDREN, options)) {
printChildren(command, labels, lines);
}
return lines;
}
private static void printDetailedDescription(CommandDescription command, List<String> lines) {
lines.add(ChatColor.GOLD + "Short Description: " + ChatColor.WHITE + command.getDescription());
lines.add(ChatColor.GOLD + "Detailed Description:");
lines.add(ChatColor.WHITE + " " + command.getDetailedDescription());
}
private static void printArguments(CommandDescription command, List<String> lines) {
if (command.getArguments().isEmpty()) {
return; return;
} }
// Get the command description, and make sure it's valid lines.add(ChatColor.GOLD + "Arguments:");
CommandDescription command = result.getCommandDescription(); for (CommandArgumentDescription argument : command.getArguments()) {
if (command == null) { StringBuilder argString = new StringBuilder();
// Show a warning message argString.append(" ").append(ChatColor.YELLOW).append(ChatColor.ITALIC).append(argument.getName())
sender.sendMessage(ChatColor.DARK_RED + "Failed to retrieve any help information!"); .append(": ").append(ChatColor.WHITE).append(argument.getDescription());
return;
}
// Get the proper command reference to use for the help page if (argument.isOptional()) {
CommandParts commandReference = command.getCommandReference(result.getQueryReference()); argString.append(ChatColor.GRAY).append(ChatColor.ITALIC).append(" (Optional)");
// Get the base command
String baseCommand = commandReference.get(0);
// Make sure the difference between the command reference and the actual command isn't too big
final double commandDifference = result.getDifference();
if (commandDifference > 0.20) {
// Show the unknown command warning
sender.sendMessage(ChatColor.DARK_RED + "No help found for '" + helpQuery + "'!");
// Show a command suggestion if available and the difference isn't too big
if (commandDifference < 0.75 && result.getCommandDescription() != null) {
// Get the suggested command
List<String> suggestedCommandParts = CollectionUtils.getRange(
result.getCommandDescription().getCommandReference(commandReference).getList(), 1);
sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/" + baseCommand
+ " help " + CommandUtils.labelsToString(suggestedCommandParts) + ChatColor.YELLOW + "?");
} }
lines.add(argString.toString());
}
}
// Show the help command private static void printAlternatives(CommandDescription command, List<String> correctLabels, List<String> lines) {
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help" + ChatColor.YELLOW + " to view help."); // TODO ljacqu 20151219: Need to show alternatives for base labels too? E.g. /r for /register
if (command.getLabels().size() <= 1) {
return; return;
} }
// Show a message when the command handler is assuming a command lines.add(ChatColor.GOLD + "Alternatives:");
if (commandDifference > 0) { // Get the label used
// Get the suggested command final String parentLabel = correctLabels.get(0);
List<String> suggestedCommandParts = CollectionUtils.getRange( final String childLabel = correctLabels.get(1);
result.getCommandDescription().getCommandReference(commandReference).getList(), 1);
// Show the suggested command // Create a list of alternatives
sender.sendMessage(ChatColor.DARK_RED + "No help found, assuming '" + ChatColor.GOLD for (String entry : command.getLabels()) {
+ CommandUtils.labelsToString(suggestedCommandParts) + ChatColor.DARK_RED + "'!"); if (!entry.equalsIgnoreCase(childLabel)) {
lines.add(" " + CommandSyntaxHelper.getSyntax(command, asList(parentLabel, entry)));
}
}
}
private static void printPermissions(CommandDescription command, CommandSender sender,
PermissionsManager permissionsManager, List<String> lines) {
CommandPermissions permissions = command.getCommandPermissions();
if (permissions == null || CollectionUtils.isEmpty(permissions.getPermissionNodes())) {
return;
}
lines.add(ChatColor.GOLD + "Permissions:");
for (PermissionNode node : permissions.getPermissionNodes()) {
boolean hasPermission = permissionsManager.hasPermission(sender, node);
final String nodePermsString = "" + ChatColor.GRAY + ChatColor.ITALIC
+ (hasPermission ? " (You have permission)" : " (No permission)");
lines.add(" " + ChatColor.YELLOW + ChatColor.ITALIC + node.getNode() + nodePermsString);
} }
// Print the help header // Addendum to the line to specify whether the sender has permission or not when default is OP_ONLY
sender.sendMessage(ChatColor.GOLD + "==========[ " + Settings.helpHeader.toUpperCase() + " HELP ]=========="); final DefaultPermission defaultPermission = permissions.getDefaultPermission();
String addendum = "";
if (DefaultPermission.OP_ONLY.equals(defaultPermission)) {
addendum = PermissionsManager.evaluateDefaultPermission(defaultPermission, sender)
? " (You have permission)"
: " (No permission)";
}
lines.add(ChatColor.GOLD + "Default: " + ChatColor.GRAY + ChatColor.ITALIC
+ defaultPermission.getTitle() + addendum);
// Print the command help information // Evaluate if the sender has permission to the command
if (showCommand) if (permissionsManager.hasPermission(sender, command)) {
HelpPrinter.printCommand(sender, command, commandReference); lines.add(ChatColor.GOLD + " Result: " + ChatColor.GREEN + ChatColor.ITALIC + "You have permission");
if (showDescription) } else {
HelpPrinter.printCommandDescription(sender, command); lines.add(ChatColor.GOLD + " Result: " + ChatColor.DARK_RED + ChatColor.ITALIC + "No permission");
if (showArguments) }
HelpPrinter.printArguments(sender, command);
if (showPermissions)
HelpPrinter.printPermissions(sender, command);
if (showAlternatives)
HelpPrinter.printAlternatives(sender, command, commandReference);
if (showCommands)
HelpPrinter.printChildren(sender, command, commandReference);
} }
private static void printChildren(CommandDescription command, List<String> parentLabels, List<String> lines) {
if (command.getChildren().isEmpty()) {
return;
}
lines.add(ChatColor.GOLD + "Commands:");
String parentCommandPath = CommandUtils.labelsToString(parentLabels);
for (CommandDescription child : command.getChildren()) {
lines.add(" /" + parentCommandPath + " " + child.getLabels().get(0)
+ ChatColor.GRAY + ChatColor.ITALIC + ": " + child.getDescription());
}
}
private static boolean hasFlag(int flag, int options) {
return (flag & options) != 0;
}
@VisibleForTesting
protected static List<String> filterCorrectLabels(CommandDescription command, List<String> labels) {
List<CommandDescription> commands = CommandUtils.constructParentList(command);
List<String> correctLabels = new ArrayList<>();
boolean foundIncorrectLabel = false;
for (int i = 0; i < commands.size(); ++i) {
if (!foundIncorrectLabel && i < labels.size() && commands.get(i).hasLabel(labels.get(i))) {
correctLabels.add(labels.get(i));
} else {
foundIncorrectLabel = true;
correctLabels.add(commands.get(i).getLabels().get(0));
}
}
return correctLabels;
}
} }

View File

@ -1,76 +0,0 @@
package fr.xephi.authme.command.help;
import fr.xephi.authme.command.CommandArgumentDescription;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.ChatColor;
/**
* Helper class for formatting a command's structure (name and arguments)
* for a Minecraft user.
*/
public final class HelpSyntaxHelper {
private HelpSyntaxHelper() {
// Helper class
}
/**
* Get the formatted syntax for a command.
*
* @param commandDescription The command to build the syntax for.
* @param commandReference The reference of the command.
* @param alternativeLabel The alternative label to use for this command syntax.
* @param highlight True to highlight the important parts of this command.
*
* @return The command with proper syntax.
*/
public static String getCommandSyntax(CommandDescription commandDescription, CommandParts commandReference,
String alternativeLabel, boolean highlight) {
// Create a string builder with white color and prefixed slash
StringBuilder sb = new StringBuilder()
.append(ChatColor.WHITE)
.append("/");
// Get the help command reference, and the command label
CommandParts helpCommandReference = commandDescription.getCommandReference(commandReference);
final String parentCommand = CommandUtils.labelsToString(
CollectionUtils.getRange(helpCommandReference.getList(), 0, helpCommandReference.getCount() - 1));
// Check whether the alternative label should be used
String commandLabel;
if (StringUtils.isEmpty(alternativeLabel)) {
commandLabel = helpCommandReference.get(helpCommandReference.getCount() - 1);
} else {
commandLabel = alternativeLabel;
}
// Show the important bit of the command, highlight this part if required
sb.append(parentCommand)
.append(" ")
.append(highlight ? ChatColor.YELLOW.toString() + ChatColor.BOLD : "")
.append(commandLabel);
if (highlight) {
sb.append(ChatColor.YELLOW);
}
// Add each command argument
for (CommandArgumentDescription arg : commandDescription.getArguments()) {
sb.append(ChatColor.ITALIC).append(formatArgument(arg));
}
// Return the build command syntax
return sb.toString();
}
private static String formatArgument(CommandArgumentDescription argument) {
if (argument.isOptional()) {
return " [" + argument.getLabel() + "]";
}
return " <" + argument.getLabel() + ">";
}
}

View File

@ -6,11 +6,28 @@ package fr.xephi.authme.permission;
public enum DefaultPermission { public enum DefaultPermission {
/** No one can execute the command. */ /** No one can execute the command. */
NOT_ALLOWED, NOT_ALLOWED("No permission"),
/** Only players with the OP status may execute the command. */ /** Only players with the OP status may execute the command. */
OP_ONLY, OP_ONLY("OP's only"),
/** The command can be executed by anyone. */ /** The command can be executed by anyone. */
ALLOWED ALLOWED("Everyone allowed");
/** Textual representation of the default permission. */
private final String title;
/**
* Constructor.
* @param title The textual representation
*/
DefaultPermission(String title) {
this.title = title;
}
/** Return the textual representation. */
public String getTitle() {
return title;
}
} }

View File

@ -280,19 +280,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);
} }
@ -306,15 +311,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

@ -1,27 +1,33 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import fr.xephi.authme.command.executable.HelpCommand;
import fr.xephi.authme.permission.DefaultPermission; import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.util.WrapperMock;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.stringContainsInOrder; import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyListOf;
import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@ -35,70 +41,316 @@ public class CommandHandlerTest {
private static Set<CommandDescription> commands; private static Set<CommandDescription> commands;
private static CommandHandler handler; private static CommandHandler handler;
private static PermissionsManager permissionsManagerMock;
@BeforeClass @BeforeClass
public static void setUpCommandHandler() { public static void setUpCommandHandler() {
WrapperMock.createInstance(); // Register /authme
CommandDescription authMeBase = createCommand(null, null, singletonList("authme")); CommandDescription authMeBase = createCommand(null, null, singletonList("authme"));
// Register /authme login <password>
createCommand(PlayerPermission.LOGIN, authMeBase, singletonList("login"), newArgument("password", false)); createCommand(PlayerPermission.LOGIN, authMeBase, singletonList("login"), newArgument("password", false));
// Register /authme register <password> <confirmation>, alias: /authme reg
createCommand(PlayerPermission.LOGIN, authMeBase, asList("register", "reg"), createCommand(PlayerPermission.LOGIN, authMeBase, asList("register", "reg"),
newArgument("password", false), newArgument("confirmation", false)); newArgument("password", false), newArgument("confirmation", false));
CommandDescription testBase = createCommand(null, null, singletonList("test"), newArgument("test", true)); // Register /email [player]
commands = new HashSet<>(asList(authMeBase, testBase)); CommandDescription emailBase = createCommand(null, null, singletonList("email"));
handler = new CommandHandler(commands); // Register /email helptest -- use only to test for help command arguments special case
CommandDescription.builder().parent(emailBase).labels("helptest").executableCommand(mock(HelpCommand.class))
.description("test").detailedDescription("Test.").withArgument("Query", "", false).build();
// Register /unregister <player>, alias: /unreg
CommandDescription unregisterBase = createCommand(null, null, asList("unregister", "unreg"),
newArgument("player", false));
commands = newHashSet(authMeBase, emailBase, unregisterBase);
} }
@Before
public void setUpMocks() {
permissionsManagerMock = mock(PermissionsManager.class);
handler = new CommandHandler(commands, permissionsManagerMock);
}
// -----------
// mapPartsToCommand() tests
// -----------
@Test @Test
@Ignore public void shouldMapPartsToLoginChildCommand() {
public void shouldForwardCommandToExecutable() {
// given // given
CommandSender sender = Mockito.mock(CommandSender.class); List<String> parts = Arrays.asList("authme", "login", "test1");
given(sender.isOp()).willReturn(true);
String bukkitLabel = "authme";
String[] args = {"login", "password"};
// when // when
handler.processCommand(sender, bukkitLabel, args); FoundCommandResult result = handler.mapPartsToCommand(parts);
// then // then
final CommandDescription loginCmd = getChildWithLabel("login", getCommandWithLabel("authme", commands)); assertThat(result.getCommandDescription(), equalTo(getChildWithLabel("login", "authme")));
verify(sender, never()).sendMessage(anyString()); assertThat(result.getResultStatus(), equalTo(FoundResultStatus.SUCCESS));
verify(loginCmd.getExecutableCommand()).executeCommand( assertThat(result.getArguments(), contains("test1"));
eq(sender), any(CommandParts.class), any(CommandParts.class)); assertThat(result.getDifference(), equalTo(0.0));
assertThat(result.getLabels(), equalTo(parts.subList(0, 2)));
assertThat(result.getArguments(), contains(parts.get(2)));
}
@Test
public void shouldMapPartsToCommandWithNoCaseSensitivity() {
// given
List<String> parts = Arrays.asList("Authme", "REG", "arg1", "arg2");
// when
FoundCommandResult result = handler.mapPartsToCommand(parts);
// then
assertThat(result.getCommandDescription(), equalTo(getChildWithLabel("register", "authme")));
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.SUCCESS));
assertThat(result.getLabels(), equalTo(parts.subList(0, 2)));
assertThat(result.getArguments(), contains("arg1", "arg2"));
assertThat(result.getDifference(), equalTo(0.0));
} }
@Test @Test
@Ignore // TODO ljacqu Fix test --> command classes too tightly coupled at the moment
public void shouldRejectCommandWithTooManyArguments() { public void shouldRejectCommandWithTooManyArguments() {
// given // given
CommandSender sender = Mockito.mock(CommandSender.class); List<String> parts = Arrays.asList("authme", "register", "pass123", "pass123", "pass123");
given(sender.isOp()).willReturn(true);
String bukkitLabel = "authme";
String[] args = {"login", "password", "__unneededArgument__"};
// when // when
boolean result = handler.processCommand(sender, bukkitLabel, args); FoundCommandResult result = handler.mapPartsToCommand(parts);
// then // then
assertThat(result, equalTo(true)); assertThat(result.getCommandDescription(), equalTo(getChildWithLabel("register", "authme")));
assertSenderGotMessageContaining("help", sender); assertThat(result.getResultStatus(), equalTo(FoundResultStatus.INCORRECT_ARGUMENTS));
assertThat(result.getDifference(), equalTo(0.0));
assertThat(result.getLabels(), equalTo(parts.subList(0, 2)));
assertThat(result.getArguments(), equalTo(parts.subList(2, 5)));
} }
@Test
public void shouldRejectCommandWithTooFewArguments() {
// given
List<String> parts = Arrays.asList("authme", "Reg");
// when
FoundCommandResult result = handler.mapPartsToCommand(parts);
// then
assertThat(result.getCommandDescription(), equalTo(getChildWithLabel("register", "authme")));
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.INCORRECT_ARGUMENTS));
assertThat(result.getDifference(), equalTo(0.0));
assertThat(result.getLabels(), equalTo(parts));
assertThat(result.getArguments(), empty());
}
@Test
public void shouldSuggestCommandWithSimilarLabel() {
// given
List<String> parts = Arrays.asList("authme", "reh", "pass123", "pass123");
// when
FoundCommandResult result = handler.mapPartsToCommand(parts);
// then
assertThat(result.getCommandDescription(), equalTo(getChildWithLabel("register", "authme")));
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.UNKNOWN_LABEL));
assertThat(result.getDifference() < 0.75, equalTo(true));
assertThat(result.getLabels(), equalTo(parts.subList(0, 2)));
assertThat(result.getArguments(), contains("pass123", "pass123"));
}
/** In contrast to the previous test, we test a command request with a very apart label. */
@Test
public void shouldSuggestMostSimilarCommand() {
// given
List<String> parts = Arrays.asList("authme", "asdfawetawty4asdca");
// when
FoundCommandResult result = handler.mapPartsToCommand(parts);
// then
assertThat(result.getCommandDescription(), not(nullValue()));
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.UNKNOWN_LABEL));
assertThat(result.getDifference() > 0.75, equalTo(true));
assertThat(result.getLabels(), equalTo(parts));
assertThat(result.getArguments(), empty());
}
@Test
public void shouldHandleBaseWithWrongArguments() {
// given
List<String> parts = singletonList("unregister");
// when
FoundCommandResult result = handler.mapPartsToCommand(parts);
// then
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.INCORRECT_ARGUMENTS));
assertThat(result.getCommandDescription(), equalTo(getCommandWithLabel("unregister", commands)));
assertThat(result.getDifference(), equalTo(0.0));
assertThat(result.getArguments(), empty());
assertThat(result.getLabels(), equalTo(parts));
}
@Test
public void shouldHandleUnknownBase() {
// given
List<String> parts = asList("bogus", "label1", "arg1");
// when
FoundCommandResult result = handler.mapPartsToCommand(parts);
// then
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.MISSING_BASE_COMMAND));
assertThat(result.getCommandDescription(), nullValue());
}
@Test
public void shouldHandleNullInput() {
// given / when
FoundCommandResult result = handler.mapPartsToCommand(null);
// then
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.MISSING_BASE_COMMAND));
assertThat(result.getCommandDescription(), nullValue());
}
@Test
public void shouldMapToBaseWithProperArguments() {
// given
List<String> parts = asList("Unreg", "player1");
// when
FoundCommandResult result = handler.mapPartsToCommand(parts);
// then
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.SUCCESS));
assertThat(result.getCommandDescription(), equalTo(getCommandWithLabel("unregister", commands)));
assertThat(result.getDifference(), equalTo(0.0));
assertThat(result.getArguments(), contains("player1"));
assertThat(result.getLabels(), contains("Unreg"));
}
@Test
public void shouldReturnChildlessBaseCommandWithArgCountError() {
// given
List<String> parts = asList("unregistER", "player1", "wrongArg");
// when
FoundCommandResult result = handler.mapPartsToCommand(parts);
// then
assertThat(result.getResultStatus(), equalTo(FoundResultStatus.INCORRECT_ARGUMENTS));
assertThat(result.getCommandDescription(), equalTo(getCommandWithLabel("unregister", commands)));
assertThat(result.getDifference(), equalTo(0.0));
assertThat(result.getArguments(), contains("player1", "wrongArg"));
assertThat(result.getLabels(), contains("unregistER"));
}
// ----------
// processCommand() tests
// ----------
@Test
public void shouldCallMappedCommandWithArgs() {
// given
String bukkitLabel = "Authme";
String[] bukkitArgs = {"Login", "myPass"};
CommandSender sender = mock(CommandSender.class);
CommandDescription command = getChildWithLabel("login", "authme");
given(permissionsManagerMock.hasPermission(sender, command)).willReturn(true);
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
ArgumentCaptor<List> argsCaptor = ArgumentCaptor.forClass(List.class);
verify(command.getExecutableCommand()).executeCommand(eq(sender), argsCaptor.capture());
List<String> argument = argsCaptor.getValue();
assertThat(argument, contains("myPass"));
// Ensure that no error message was issued to the command sender
verify(sender, never()).sendMessage(anyString());
}
@Test
public void shouldNotCallExecutableCommandIfNoPermission() {
// given
String bukkitLabel = "unreg";
String[] bukkitArgs = {"testPlayer"};
CommandSender sender = mock(CommandSender.class);
given(permissionsManagerMock.hasPermission(any(CommandSender.class), any(CommandDescription.class)))
.willReturn(false);
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
CommandDescription command = getCommandWithLabel("unregister", commands);
verify(permissionsManagerMock).hasPermission(sender, command);
verify(command.getExecutableCommand(), never())
.executeCommand(any(CommandSender.class), anyListOf(String.class));
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
verify(sender).sendMessage(messageCaptor.capture());
String message = messageCaptor.getValue();
assertThat(message, stringContainsInOrder("You don't have permission"));
}
@Test
public void shouldStripWhitespace() {
// given
String bukkitLabel = "AuthMe";
String[] bukkitArgs = {" ", "", "LOGIN", " ", "testArg", " "};
CommandSender sender = mock(CommandSender.class);
CommandDescription command = getChildWithLabel("login", "authme");
given(permissionsManagerMock.hasPermission(sender, command)).willReturn(true);
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
ArgumentCaptor<List> argsCaptor = ArgumentCaptor.forClass(List.class);
verify(command.getExecutableCommand()).executeCommand(eq(sender), argsCaptor.capture());
List<String> arguments = argsCaptor.getValue();
assertThat(arguments, contains("testArg"));
verify(sender, never()).sendMessage(anyString());
}
@Test
public void shouldPassCommandPathAsArgumentsToHelpCommand() {
// given
String bukkitLabel = "email";
String[] bukkitArgs = {"helptest", "arg1"};
CommandSender sender = mock(CommandSender.class);
CommandDescription command = getChildWithLabel("helptest", "email");
given(permissionsManagerMock.hasPermission(sender, command)).willReturn(true);
// when
handler.processCommand(sender, bukkitLabel, bukkitArgs);
// then
ArgumentCaptor<List> argsCaptor = ArgumentCaptor.forClass(List.class);
verify(command.getExecutableCommand()).executeCommand(eq(sender), argsCaptor.capture());
List<String> arguments = argsCaptor.getValue();
assertThat(arguments, contains("email", "arg1"));
}
// ----------
// Helper methods
// ----------
private static CommandDescription createCommand(PlayerPermission permission, CommandDescription parent, private static CommandDescription createCommand(PlayerPermission permission, CommandDescription parent,
List<String> labels, CommandArgumentDescription... arguments) { List<String> labels, CommandArgumentDescription... arguments) {
CommandDescription.CommandBuilder command = CommandDescription.builder() CommandDescription.CommandBuilder command = CommandDescription.builder()
.labels(labels) .labels(labels)
.parent(parent) .parent(parent)
.permissions(DefaultPermission.OP_ONLY, permission) .permissions(DefaultPermission.OP_ONLY, permission)
.description("Test") .description(labels.get(0))
.detailedDescription("Test command") .detailedDescription("'" + labels.get(0) + "' test command")
.executableCommand(mock(ExecutableCommand.class)); .executableCommand(mock(ExecutableCommand.class));
if (arguments != null && arguments.length > 0) { if (arguments != null && arguments.length > 0) {
for (CommandArgumentDescription argument : arguments) { for (CommandArgumentDescription argument : arguments) {
command.withArgument(argument.getLabel(), "Test description", argument.isOptional()); command.withArgument(argument.getName(), "Test description", argument.isOptional());
} }
} }
@ -109,27 +361,17 @@ public class CommandHandlerTest {
return new CommandArgumentDescription(label, "Test description", isOptional); return new CommandArgumentDescription(label, "Test description", isOptional);
} }
private void assertSenderGotMessageContaining(String text, CommandSender sender) { private static CommandDescription getChildWithLabel(String childLabel, String parentLabel) {
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); CommandDescription parent = getCommandWithLabel(parentLabel, commands);
verify(sender).sendMessage(captor.capture()); return getCommandWithLabel(childLabel, parent.getChildren());
assertThat(captor.getValue(), stringContainsInOrder(text));
} }
private static CommandDescription getCommandWithLabel(String label, Collection<CommandDescription> commands) { private static CommandDescription getCommandWithLabel(String label, Collection<CommandDescription> commands) {
for (CommandDescription command : commands) { for (CommandDescription child : commands) {
if (command.getLabels().contains(label)) { if (child.hasLabel(label)) {
return command;
}
}
return null;
}
private static CommandDescription getChildWithLabel(String label, CommandDescription command) {
for (CommandDescription child : command.getChildren()) {
if (child.getLabels().contains(label)) {
return child; return child;
} }
} }
return null; throw new RuntimeException("Could not find command with label '" + label + "'");
} }
} }

View File

@ -77,7 +77,7 @@ public class CommandInitializerTest {
BiConsumer connectionTester = new BiConsumer() { BiConsumer connectionTester = new BiConsumer() {
@Override @Override
public void accept(CommandDescription command, int depth) { public void accept(CommandDescription command, int depth) {
if (command.hasChildren()) { if (!command.getChildren().isEmpty()) {
for (CommandDescription child : command.getChildren()) { for (CommandDescription child : command.getChildren()) {
assertThat(command.equals(child.getParent()), equalTo(true)); assertThat(command.equals(child.getParent()), equalTo(true));
} }
@ -223,7 +223,7 @@ public class CommandInitializerTest {
public void accept(CommandDescription command, int depth) { public void accept(CommandDescription command, int depth) {
// Fail if the command has children and has arguments at the same time // Fail if the command has children and has arguments at the same time
// Exception: If the parent only has one child defining the help label, it is acceptable // Exception: If the parent only has one child defining the help label, it is acceptable
if (command.hasChildren() && command.hasArguments() if (!command.getChildren().isEmpty() && !command.getArguments().isEmpty()
&& (command.getChildren().size() != 1 || !command.getChildren().get(0).hasLabel("help"))) { && (command.getChildren().size() != 1 || !command.getChildren().get(0).hasLabel("help"))) {
fail("Parent command (labels='" + command.getLabels() + "') should not have any arguments"); fail("Parent command (labels='" + command.getLabels() + "') should not have any arguments");
} }
@ -317,7 +317,7 @@ public class CommandInitializerTest {
private static void walkThroughCommands(Collection<CommandDescription> commands, BiConsumer consumer, int depth) { private static void walkThroughCommands(Collection<CommandDescription> commands, BiConsumer consumer, int depth) {
for (CommandDescription command : commands) { for (CommandDescription command : commands) {
consumer.accept(command, depth); consumer.accept(command, depth);
if (command.hasChildren()) { if (!command.getChildren().isEmpty()) {
walkThroughCommands(command.getChildren(), consumer, depth + 1); walkThroughCommands(command.getChildren(), consumer, depth + 1);
} }
} }

View File

@ -1,39 +0,0 @@
package fr.xephi.authme.command;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
/**
* Test for {@link CommandParts}.
*/
public class CommandPartsTest {
@Test
public void shouldPrintPartsForStringRepresentation() {
// given
CommandParts parts = new CommandParts(Arrays.asList("some", "parts", "for", "test"));
// when
String str = parts.toString();
// then
assertThat(str, equalTo("some parts for test"));
}
@Test
public void shouldPrintEmptyStringForNoArguments() {
// given
CommandParts parts = new CommandParts(Collections.EMPTY_LIST);
// when
String str = parts.toString();
// then
assertThat(str, equalTo(""));
}
}

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.command;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
@ -14,6 +15,30 @@ import static org.mockito.Mockito.mock;
*/ */
public class CommandUtilsTest { public class CommandUtilsTest {
@Test
public void shouldPrintPartsForStringRepresentation() {
// given
Iterable<String> parts = Arrays.asList("some", "parts", "for", "test");
// when
String str = CommandUtils.labelsToString(parts);
// then
assertThat(str, equalTo("some parts for test"));
}
@Test
public void shouldPrintEmptyStringForNoArguments() {
// given
List<String> parts = Collections.EMPTY_LIST;
// when
String str = CommandUtils.labelsToString(parts);
// then
assertThat(str, equalTo(""));
}
@Test @Test
public void shouldPrintLabels() { public void shouldPrintLabels() {
// given // given

View File

@ -1,7 +1,6 @@
package fr.xephi.authme.command.executable.captcha; package fr.xephi.authme.command.executable.captcha;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
@ -15,7 +14,7 @@ import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.Collections; import java.util.ArrayList;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
@ -42,10 +41,9 @@ public class CaptchaCommandTest {
ExecutableCommand command = new CaptchaCommand(); ExecutableCommand command = new CaptchaCommand();
// when // when
boolean result = command.executeCommand(sender, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST)); command.executeCommand(sender, new ArrayList<String>());
// then // then
assertThat(result, equalTo(true));
assertThat(wrapperMock.wasMockCalled(AuthMe.class), equalTo(false)); assertThat(wrapperMock.wasMockCalled(AuthMe.class), equalTo(false));
assertThat(wrapperMock.wasMockCalled(Messages.class), equalTo(false)); assertThat(wrapperMock.wasMockCalled(Messages.class), equalTo(false));
} }
@ -58,10 +56,9 @@ public class CaptchaCommandTest {
ExecutableCommand command = new CaptchaCommand(); ExecutableCommand command = new CaptchaCommand();
// when // when
boolean result = command.executeCommand(player, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST)); command.executeCommand(player, new ArrayList<String>());
// then // then
assertThat(result, equalTo(true));
verify(wrapperMock.getMessages()).send(player, MessageKey.USAGE_LOGIN); verify(wrapperMock.getMessages()).send(player, MessageKey.USAGE_LOGIN);
} }

View File

@ -3,7 +3,6 @@ package fr.xephi.authme.command.executable.changepassword;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
@ -17,14 +16,19 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/** /**
* Test for {@link ChangePasswordCommand}. * Test for {@link ChangePasswordCommand}.
@ -53,13 +57,11 @@ public class ChangePasswordCommandTest {
// given // given
CommandSender sender = mock(BlockCommandSender.class); CommandSender sender = mock(BlockCommandSender.class);
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
CommandParts arguments = mock(CommandParts.class);
// when // when
command.executeCommand(sender, newParts(), arguments); command.executeCommand(sender, new ArrayList<String>());
// then // then
verify(arguments, never()).get(anyInt());
assertThat(wrapperMock.wasMockCalled(Server.class), equalTo(false)); assertThat(wrapperMock.wasMockCalled(Server.class), equalTo(false));
} }
@ -70,7 +72,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
// when // when
command.executeCommand(sender, newParts(), new CommandParts("pass")); command.executeCommand(sender, Arrays.asList("pass", "pass"));
// then // then
verify(messagesMock).send(sender, MessageKey.NOT_LOGGED_IN); verify(messagesMock).send(sender, MessageKey.NOT_LOGGED_IN);
@ -84,7 +86,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
// when // when
command.executeCommand(sender, newParts(), newParts("old123", "!pass")); command.executeCommand(sender, Arrays.asList("old123", "!pass"));
// then // then
verify(messagesMock).send(sender, MessageKey.PASSWORD_MATCH_ERROR); verify(messagesMock).send(sender, MessageKey.PASSWORD_MATCH_ERROR);
@ -99,7 +101,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
// when // when
command.executeCommand(sender, newParts(), newParts("old_", "Tester")); command.executeCommand(sender, Arrays.asList("old_", "Tester"));
// then // then
verify(messagesMock).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); verify(messagesMock).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
@ -114,7 +116,7 @@ public class ChangePasswordCommandTest {
Settings.passwordMaxLength = 3; Settings.passwordMaxLength = 3;
// when // when
command.executeCommand(sender, newParts(), newParts("12", "test")); command.executeCommand(sender, Arrays.asList("12", "test"));
// then // then
verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH); verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
@ -129,7 +131,7 @@ public class ChangePasswordCommandTest {
Settings.getPasswordMinLen = 7; Settings.getPasswordMinLen = 7;
// when // when
command.executeCommand(sender, newParts(), newParts("oldverylongpassword", "tester")); command.executeCommand(sender, Arrays.asList("oldverylongpassword", "tester"));
// then // then
verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH); verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
@ -144,7 +146,7 @@ public class ChangePasswordCommandTest {
Settings.unsafePasswords = asList("test", "abc123"); Settings.unsafePasswords = asList("test", "abc123");
// when // when
command.executeCommand(sender, newParts(), newParts("oldpw", "abc123")); command.executeCommand(sender, Arrays.asList("oldpw", "abc123"));
// then // then
verify(messagesMock).send(sender, MessageKey.PASSWORD_UNSAFE_ERROR); verify(messagesMock).send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
@ -158,7 +160,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
// when // when
command.executeCommand(sender, newParts(), newParts("abc123", "abc123")); command.executeCommand(sender, Arrays.asList("abc123", "abc123"));
// then // then
verify(messagesMock, never()).send(eq(sender), any(MessageKey.class)); verify(messagesMock, never()).send(eq(sender), any(MessageKey.class));
@ -176,8 +178,4 @@ public class ChangePasswordCommandTest {
return player; return player;
} }
private static CommandParts newParts(String... parts) {
return new CommandParts(Arrays.asList(parts));
}
} }

View File

@ -1,7 +1,6 @@
package fr.xephi.authme.command.executable.email; package fr.xephi.authme.command.executable.email;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.util.WrapperMock; import fr.xephi.authme.util.WrapperMock;
import org.bukkit.command.BlockCommandSender; import org.bukkit.command.BlockCommandSender;
@ -41,7 +40,7 @@ public class AddEmailCommandTest {
AddEmailCommand command = new AddEmailCommand(); AddEmailCommand command = new AddEmailCommand();
// when // when
command.executeCommand(sender, newParts(), newParts()); command.executeCommand(sender, new ArrayList<String>());
// then // then
verify(authMeMock, never()).getManagement(); verify(authMeMock, never()).getManagement();
@ -54,15 +53,11 @@ public class AddEmailCommandTest {
AddEmailCommand command = new AddEmailCommand(); AddEmailCommand command = new AddEmailCommand();
// when // when
command.executeCommand(sender, newParts(), command.executeCommand(sender, Arrays.asList("mail@example", "other_example"));
new CommandParts(Arrays.asList("mail@example", "other_example")));
// then // then
verify(authMeMock).getManagement(); verify(authMeMock).getManagement();
verify(managementMock).performAddEmail(sender, "mail@example", "other_example"); verify(managementMock).performAddEmail(sender, "mail@example", "other_example");
} }
private static CommandParts newParts() {
return new CommandParts(new ArrayList<String>());
}
} }

View File

@ -1,7 +1,6 @@
package fr.xephi.authme.command.executable.email; package fr.xephi.authme.command.executable.email;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.util.WrapperMock; import fr.xephi.authme.util.WrapperMock;
import org.bukkit.command.BlockCommandSender; import org.bukkit.command.BlockCommandSender;
@ -41,7 +40,7 @@ public class ChangeEmailCommandTest {
ChangeEmailCommand command = new ChangeEmailCommand(); ChangeEmailCommand command = new ChangeEmailCommand();
// when // when
command.executeCommand(sender, newParts(), newParts()); command.executeCommand(sender, new ArrayList<String>());
// then // then
verify(authMeMock, never()).getManagement(); verify(authMeMock, never()).getManagement();
@ -54,15 +53,11 @@ public class ChangeEmailCommandTest {
ChangeEmailCommand command = new ChangeEmailCommand(); ChangeEmailCommand command = new ChangeEmailCommand();
// when // when
command.executeCommand(sender, newParts(), command.executeCommand(sender, Arrays.asList("new.mail@example.org", "old_mail@example.org"));
new CommandParts(Arrays.asList("new.mail@example.org", "old_mail@example.org")));
// then // then
verify(authMeMock).getManagement(); verify(authMeMock).getManagement();
verify(managementMock).performChangeEmail(sender, "new.mail@example.org", "old_mail@example.org"); verify(managementMock).performChangeEmail(sender, "new.mail@example.org", "old_mail@example.org");
} }
private static CommandParts newParts() {
return new CommandParts(new ArrayList<String>());
}
} }

View File

@ -1,6 +1,5 @@
package fr.xephi.authme.command.executable.email; package fr.xephi.authme.command.executable.email;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.util.WrapperMock; import fr.xephi.authme.util.WrapperMock;
import org.bukkit.command.BlockCommandSender; import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -9,7 +8,7 @@ import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.Collections; import java.util.ArrayList;
/** /**
* Test for {@link RecoverEmailCommand}. * Test for {@link RecoverEmailCommand}.
@ -29,7 +28,7 @@ public class RecoverEmailCommandTest {
RecoverEmailCommand command = new RecoverEmailCommand(); RecoverEmailCommand command = new RecoverEmailCommand();
// when // when
command.executeCommand(sender, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST)); command.executeCommand(sender, new ArrayList<String>());
// then // then
} }

View File

@ -1,6 +1,5 @@
package fr.xephi.authme.command.executable.login; package fr.xephi.authme.command.executable.login;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.WrapperMock; import fr.xephi.authme.util.WrapperMock;
@ -12,6 +11,7 @@ import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import static org.mockito.Matchers.*; import static org.mockito.Matchers.*;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@ -40,7 +40,7 @@ public class LoginCommandTest {
LoginCommand command = new LoginCommand(); LoginCommand command = new LoginCommand();
// when // when
command.executeCommand(sender, newParts(), newParts()); command.executeCommand(sender, new ArrayList<String>());
// then // then
Mockito.verify(managementMock, never()).performLogin(any(Player.class), anyString(), anyBoolean()); Mockito.verify(managementMock, never()).performLogin(any(Player.class), anyString(), anyBoolean());
@ -53,28 +53,10 @@ public class LoginCommandTest {
LoginCommand command = new LoginCommand(); LoginCommand command = new LoginCommand();
// when // when
command.executeCommand(sender, newParts(), new CommandParts("password")); command.executeCommand(sender, Collections.singletonList("password"));
// then // then
Mockito.verify(managementMock).performLogin(eq(sender), eq("password"), eq(false)); Mockito.verify(managementMock).performLogin(eq(sender), eq("password"), eq(false));
} }
@Test
public void shouldHandleMissingPassword() {
// given
Player sender = mock(Player.class);
LoginCommand command = new LoginCommand();
// when
command.executeCommand(sender, newParts(), newParts());
// then
// TODO ljacqu 20151121: May make sense to handle null password in LoginCommand instead of forwarding the call
String password = null;
Mockito.verify(managementMock).performLogin(eq(sender), eq(password), eq(false));
}
private static CommandParts newParts() {
return new CommandParts(new ArrayList<String>());
}
} }

View File

@ -1,7 +1,6 @@
package fr.xephi.authme.command.executable.logout; package fr.xephi.authme.command.executable.logout;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.WrapperMock; import fr.xephi.authme.util.WrapperMock;
@ -13,6 +12,7 @@ import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@ -42,7 +42,7 @@ public class LogoutCommandTest {
LogoutCommand command = new LogoutCommand(); LogoutCommand command = new LogoutCommand();
// when // when
command.executeCommand(sender, new CommandParts(new ArrayList<String>()), new CommandParts(new ArrayList<String>())); command.executeCommand(sender, new ArrayList<String>());
// then // then
Mockito.verify(managementMock, never()).performLogout(any(Player.class)); Mockito.verify(managementMock, never()).performLogout(any(Player.class));
@ -55,7 +55,7 @@ public class LogoutCommandTest {
LogoutCommand command = new LogoutCommand(); LogoutCommand command = new LogoutCommand();
// when // when
command.executeCommand(sender, new CommandParts(new ArrayList<String>()), new CommandParts("password")); command.executeCommand(sender, Collections.singletonList("password"));
// then // then
Mockito.verify(managementMock).performLogout(sender); Mockito.verify(managementMock).performLogout(sender);

View File

@ -1,6 +1,5 @@
package fr.xephi.authme.command.executable.register; package fr.xephi.authme.command.executable.register;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages; import fr.xephi.authme.output.Messages;
@ -15,6 +14,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
@ -50,7 +50,7 @@ public class RegisterCommandTest {
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
// when // when
command.executeCommand(sender, newParts(), newParts()); command.executeCommand(sender, new ArrayList<String>());
// then // then
verify(sender).sendMessage(messageCaptor.capture()); verify(sender).sendMessage(messageCaptor.capture());
@ -65,7 +65,7 @@ public class RegisterCommandTest {
RegisterCommand command = new RegisterCommand(); RegisterCommand command = new RegisterCommand();
// when // when
command.executeCommand(sender, newParts(), newParts()); command.executeCommand(sender, new ArrayList<String>());
// then // then
verify(messagesMock).send(sender, MessageKey.USAGE_REGISTER); verify(messagesMock).send(sender, MessageKey.USAGE_REGISTER);
@ -79,13 +79,10 @@ public class RegisterCommandTest {
RegisterCommand command = new RegisterCommand(); RegisterCommand command = new RegisterCommand();
// when // when
command.executeCommand(sender, newParts(), new CommandParts("password")); command.executeCommand(sender, Collections.singletonList("password"));
// then // then
verify(managementMock).performRegister(sender, "password", ""); verify(managementMock).performRegister(sender, "password", "");
} }
private static CommandParts newParts() {
return new CommandParts(new ArrayList<String>());
}
} }

View File

@ -0,0 +1,65 @@
package fr.xephi.authme.command.help;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.ExecutableCommand;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
/**
* Test for {@link HelpProvider}.
*/
public class HelpProviderTest {
private static CommandDescription parent;
private static CommandDescription child;
@BeforeClass
public static void setUpCommands() {
parent = CommandDescription.builder()
.executableCommand(mock(ExecutableCommand.class))
.labels("base", "b")
.description("Parent")
.detailedDescription("Test base command.")
.build();
child = CommandDescription.builder()
.executableCommand(mock(ExecutableCommand.class))
.parent(parent)
.labels("child", "c")
.description("Child")
.detailedDescription("Child test command.")
.withArgument("Argument", "The argument", false)
.build();
}
@Test
public void shouldRetainCorrectLabels() {
// given
List<String> labels = Arrays.asList("b", "child");
// when
List<String> result = HelpProvider.filterCorrectLabels(child, labels);
// then
assertThat(result, contains("b", "child"));
}
@Test
public void shouldReplaceIncorrectLabels() {
// given
List<String> labels = Arrays.asList("base", "wrong");
// when
List<String> result = HelpProvider.filterCorrectLabels(child, labels);
// then
assertThat(result, contains("base", "child"));
}
}

View File

@ -1,132 +0,0 @@
package fr.xephi.authme.command.help;
import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.command.executable.authme.RegisterAdminCommand;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
import static org.bukkit.ChatColor.BOLD;
import static org.bukkit.ChatColor.ITALIC;
import static org.bukkit.ChatColor.WHITE;
import static org.bukkit.ChatColor.YELLOW;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
/**
* Test for {@link HelpSyntaxHelper}.
*/
public class HelpSyntaxHelperTest {
@Test
public void shouldFormatSimpleCommand() {
// given
CommandDescription description = getDescriptionBuilder()
.withArgument("name", "The name", true)
.build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", false);
// then
assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]"));
}
@Test
public void shouldFormatSimpleCommandWithOptionalParam() {
// given
CommandDescription description = getDescriptionBuilder()
.withArgument("test", "", false)
.build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), null, false);
// then
assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " <test>"));
}
@Test
public void shouldFormatCommandWithMultipleParams() {
// given
CommandDescription description = getDescriptionBuilder()
.withArgument("name", "", true)
.withArgument("test", "", false)
.build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", false);
// then
assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]" + ITALIC + " <test>"));
}
@Test
public void shouldHighlightCommandWithMultipleParams() {
// given
CommandDescription description = getDescriptionBuilder()
.withArgument("name", "", true)
.withArgument("test", "", false)
.build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", true);
// then
assertThat(result, equalTo(WHITE + "/authme "
+ YELLOW + BOLD + "register"
+ YELLOW + ITALIC + " [name]" + ITALIC + " <test>"));
}
@Test
public void shouldHighlightCommandWithNoParams() {
// given
CommandDescription description = getDescriptionBuilder().build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), null, true);
// then
assertThat(result, equalTo(WHITE + "/authme " + YELLOW + BOLD + "register" + YELLOW));
}
@Test
public void shouldFormatSimpleCommandWithAlternativeLabel() {
// given
CommandDescription description = getDescriptionBuilder()
.withArgument("name", "The name", true)
.build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "alt", false);
// then
assertThat(result, equalTo(WHITE + "/authme alt" + ITALIC + " [name]"));
}
private static CommandParts newParts() {
// TODO ljacqu 20151204: Remove this method once CommandParts has been removed
return new CommandParts(new ArrayList<String>());
}
private static CommandDescription.CommandBuilder getDescriptionBuilder() {
CommandDescription base = CommandDescription.builder()
.labels("authme")
.description("Base command")
.detailedDescription("AuthMe base command")
.parent(null)
.executableCommand(Mockito.mock(ExecutableCommand.class))
.build();
return CommandDescription.builder()
.executableCommand(Mockito.mock(RegisterAdminCommand.class))
.labels("register", "r")
.description("Register a player")
.detailedDescription("Register the specified player with the specified password.")
.parent(base)
.executableCommand(Mockito.mock(ExecutableCommand.class));
}
}