Merge pull request #79 from AuthMe-Team/command-perms-refactor

Command perms refactor
This commit is contained in:
ljacqu 2015-12-05 00:22:33 +01:00
commit 955c4c8de4
37 changed files with 1004 additions and 864 deletions

View File

@ -10,6 +10,7 @@ import fr.xephi.authme.cache.backup.JsonCache;
import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.command.CommandHandler; import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.command.CommandInitializer;
import fr.xephi.authme.converter.Converter; import fr.xephi.authme.converter.Converter;
import fr.xephi.authme.converter.ForceFlatToSqlite; import fr.xephi.authme.converter.ForceFlatToSqlite;
import fr.xephi.authme.datasource.*; import fr.xephi.authme.datasource.*;
@ -28,6 +29,7 @@ import fr.xephi.authme.settings.*;
import fr.xephi.authme.util.GeoLiteAPI; import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils; import fr.xephi.authme.util.Utils;
import fr.xephi.authme.util.Wrapper;
import net.minelink.ctplus.CombatTagPlus; import net.minelink.ctplus.CombatTagPlus;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -70,8 +72,9 @@ public class AuthMe extends JavaPlugin {
private static AuthMe plugin; private static AuthMe plugin;
private static Server server; private static Server server;
private static Wrapper wrapper = Wrapper.getInstance();
public Management management; private Management management;
public NewAPI api; public NewAPI api;
public SendMailSSL mail; public SendMailSSL mail;
public DataManager dataManager; public DataManager dataManager;
@ -431,8 +434,7 @@ public class AuthMe extends JavaPlugin {
* Set up the command handler. * Set up the command handler.
*/ */
private void setupCommandHandler() { private void setupCommandHandler() {
this.commandHandler = new CommandHandler(false); this.commandHandler = new CommandHandler(CommandInitializer.getBaseCommands());
this.commandHandler.init();
} }
/** /**
@ -955,13 +957,14 @@ public class AuthMe extends JavaPlugin {
@Override @Override
public boolean onCommand(CommandSender sender, Command cmd, public boolean onCommand(CommandSender sender, Command cmd,
String commandLabel, String[] args) { String commandLabel, String[] args) {
// Get the command handler, and make sure it's valid // Make sure the command handler has been initialized
CommandHandler commandHandler = this.getCommandHandler(); if (commandHandler == null) {
if (commandHandler == null) wrapper.getLogger().severe("AuthMe command handler is not available");
return false; return false;
}
// Handle the command, return the result // Handle the command
return commandHandler.onCommand(sender, cmd, commandLabel, args); return commandHandler.processCommand(sender, commandLabel, args);
} }
/** /**

View File

@ -2,7 +2,6 @@ package fr.xephi.authme;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Wrapper; import fr.xephi.authme.util.Wrapper;
import java.io.IOException; import java.io.IOException;
@ -17,8 +16,10 @@ import java.util.Date;
*/ */
public final class ConsoleLogger { public final class ConsoleLogger {
private static final String NEW_LINE = System.getProperty("line.separator");
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("[MM-dd HH:mm:ss]");
private static Wrapper wrapper = Wrapper.getInstance(); private static Wrapper wrapper = Wrapper.getInstance();
private static final DateFormat df = new SimpleDateFormat("[MM-dd HH:mm:ss]");
private ConsoleLogger() { private ConsoleLogger() {
// Service class // Service class
@ -57,11 +58,11 @@ public final class ConsoleLogger {
*/ */
private static void writeLog(String message) { private static void writeLog(String message) {
String dateTime; String dateTime;
synchronized (df) { synchronized (DATE_FORMAT) {
dateTime = df.format(new Date()); dateTime = DATE_FORMAT.format(new Date());
} }
try { try {
Files.write(Settings.LOG_FILE.toPath(), (dateTime + ": " + message + StringUtils.newline).getBytes(), Files.write(Settings.LOG_FILE.toPath(), (dateTime + ": " + message + NEW_LINE).getBytes(),
StandardOpenOption.APPEND, StandardOpenOption.APPEND,
StandardOpenOption.CREATE); StandardOpenOption.CREATE);
} catch (IOException ignored) { } catch (IOException ignored) {
@ -77,6 +78,6 @@ public final class ConsoleLogger {
if (!Settings.useLogging) { if (!Settings.useLogging) {
return; return;
} }
writeLog("" + Throwables.getStackTraceAsString(ex)); writeLog(Throwables.getStackTraceAsString(ex));
} }
} }

View File

@ -170,7 +170,7 @@ public class API {
*/ */
@Deprecated @Deprecated
public static void forceLogin(Player player) { public static void forceLogin(Player player) {
instance.management.performLogin(player, "dontneed", true); instance.getManagement().performLogin(player, "dontneed", true);
} }
/** /**

View File

@ -170,7 +170,7 @@ public class NewAPI {
* @param player * player * @param player * player
*/ */
public void forceLogin(Player player) { public void forceLogin(Player player) {
plugin.management.performLogin(player, "dontneed", true); plugin.getManagement().performLogin(player, "dontneed", true);
} }
/** /**
@ -179,7 +179,7 @@ public class NewAPI {
* @param player * player * @param player * player
*/ */
public void forceLogout(Player player) { public void forceLogout(Player player) {
plugin.management.performLogout(player); plugin.getManagement().performLogout(player);
} }
/** /**
@ -189,7 +189,7 @@ public class NewAPI {
* @param password String * @param password String
*/ */
public void forceRegister(Player player, String password) { public void forceRegister(Player player, String password) {
plugin.management.performRegister(player, password, null); plugin.getManagement().performRegister(player, password, null);
} }
/** /**
@ -198,6 +198,6 @@ public class NewAPI {
* @param player * player * @param player * player
*/ */
public void forceUnregister(Player player) { public void forceUnregister(Player player) {
plugin.management.performUnregister(player, "", true); plugin.getManagement().performUnregister(player, "", true);
} }
} }

View File

@ -1,23 +1,22 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
/** /**
* Wrapper for the description of a command argument.
*/ */
public class CommandArgumentDescription { public class CommandArgumentDescription {
// TODO: Allow argument to consist of infinite parts. <label ...>
/** /**
* Argument label (one-word description of the argument). * Argument label (one-word description of the argument).
*/ */
private String label; private final String label;
/** /**
* Argument description. * Argument description.
*/ */
private String description; private final String description;
/** /**
* Defines whether the argument is optional. * Defines whether the argument is optional.
*/ */
private boolean isOptional = false; private final boolean isOptional;
/** /**
* Constructor. * Constructor.
@ -51,7 +50,7 @@ public class CommandArgumentDescription {
} }
/** /**
* Check whether the argument is optional. * Return whether the argument is optional.
* *
* @return True if the argument is optional, false otherwise. * @return True if the argument is optional, false otherwise.
*/ */

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -15,9 +16,9 @@ import java.util.List;
* 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.
* *
* CommandDescription is built hierarchically and have one parent or {@code null} for base commands (main commands * CommandDescription instances are built hierarchically and have one parent or {@code null} for base commands
* such as /authme) and may have multiple children extending the mapping of the parent: e.g. if /authme has a child * (main commands such as /authme) and may have multiple children extending the mapping of the parent: e.g. if
* whose label is "register", then "/authme register" is the command that the child defines. * /authme has a child whose label is "register", then "/authme register" is the command that the child defines.
*/ */
public class CommandDescription { public class CommandDescription {
@ -50,10 +51,6 @@ public class CommandDescription {
* The arguments the command takes. * The arguments the command takes.
*/ */
private List<CommandArgumentDescription> arguments; private List<CommandArgumentDescription> arguments;
/**
* Defines whether there is an argument maximum or not.
*/
private boolean noArgumentMaximum;
/** /**
* Defines the command permissions. * Defines the command permissions.
*/ */
@ -68,77 +65,58 @@ public class CommandDescription {
* @param detailedDescription Detailed comment description. * @param detailedDescription Detailed comment description.
* @param parent Parent command. * @param parent Parent command.
*/ */
@Deprecated
public CommandDescription(ExecutableCommand executableCommand, List<String> labels, String description, String detailedDescription, CommandDescription parent) { public CommandDescription(ExecutableCommand executableCommand, List<String> labels, String description, String detailedDescription, CommandDescription parent) {
this(executableCommand, labels, description, detailedDescription, parent, null);
}
/**
* Constructor.
*
* @param executableCommand The executable command, or null.
* @param labels List of command labels.
* @param description Command description.
* @param detailedDescription Detailed comment description.
* @param parent Parent command.
* @param arguments Command arguments.
*/
public CommandDescription(ExecutableCommand executableCommand, List<String> labels, String description, String detailedDescription, CommandDescription parent, List<CommandArgumentDescription> arguments) {
setExecutableCommand(executableCommand); setExecutableCommand(executableCommand);
this.labels = labels; this.labels = labels;
this.description = description; this.description = description;
this.detailedDescription = detailedDescription; this.detailedDescription = detailedDescription;
setParent(parent); setParent(parent);
setArguments(arguments); this.arguments = new ArrayList<>();
} }
/** /**
* Private constructor. Use {@link CommandDescription#builder()} to create instances of this class. * Private constructor. Use {@link CommandDescription#builder()} to create instances of this class.
* * <p />
* @param executableCommand The executable command, or null. * Note for developers: Instances should be created with {@link CommandDescription#createInstance} to be properly
* @param labels List of command labels. * registered in the command tree.
* @param description Command description.
* @param detailedDescription Detailed comment description.
* @param parent Parent command.
* @param arguments Command arguments.
*/ */
private CommandDescription(List<String> labels, String description, String detailedDescription, private CommandDescription() {
ExecutableCommand executableCommand, CommandDescription parent,
List<CommandArgumentDescription> arguments, boolean noArgumentMaximum,
CommandPermissions permissions) {
this.labels = labels;
this.description = description;
this.detailedDescription = detailedDescription;
this.executableCommand = executableCommand;
this.parent = parent;
this.arguments = arguments;
this.noArgumentMaximum = noArgumentMaximum;
this.permissions = permissions;
if (parent != null) {
// Passing `this` in constructor is not very nice; consider creating a "static create()" method instead
parent.addChild(this);
}
} }
/** /**
* Check whether two labels are equal to each other. * Create an instance for internal use.
* *
* @param commandLabel The first command label. * @param labels List of command labels.
* @param otherCommandLabel The other command label. * @param description Command description.
* @param detailedDescription Detailed comment description.
* @param executableCommand The executable command, or null.
* @param parent Parent command.
* @param arguments Command arguments.
* @param permissions The permissions required to execute this command.
* *
* @return True if the labels are equal to each other. * @return The created instance
* @see CommandDescription#builder()
*/ */
private static boolean commandLabelEquals(String commandLabel, String otherCommandLabel) { private static CommandDescription createInstance(List<String> labels, String description,
// Trim the command labels from unwanted whitespaces String detailedDescription, ExecutableCommand executableCommand,
commandLabel = commandLabel.trim(); CommandDescription parent, List<CommandArgumentDescription> arguments,
otherCommandLabel = otherCommandLabel.trim(); CommandPermissions permissions) {
CommandDescription instance = new CommandDescription();
instance.labels = labels;
instance.description = description;
instance.detailedDescription = detailedDescription;
instance.executableCommand = executableCommand;
instance.parent = parent;
instance.arguments = arguments;
instance.permissions = permissions;
// Check whether the the two command labels are equal (case insensitive) if (parent != null) {
return (commandLabel.equalsIgnoreCase(otherCommandLabel)); parent.addChild(instance);
}
return instance;
} }
/** /**
* Get the label most similar to the reference. The first label will be returned if no reference was supplied. * Get the label most similar to the reference. The first label will be returned if no reference was supplied.
* *
@ -190,12 +168,11 @@ public class CommandDescription {
* @return True if this command label equals to the param command. * @return True if this command label equals to the param command.
*/ */
public boolean hasLabel(String commandLabel) { public boolean hasLabel(String commandLabel) {
// Check whether any command matches with the argument for (String label : this.labels) {
for (String entry : this.labels) if (label.equalsIgnoreCase(commandLabel)) {
if (commandLabelEquals(entry, commandLabel))
return true; return true;
}
// No match found, return false }
return false; return false;
} }
@ -208,53 +185,17 @@ public class CommandDescription {
* @return True if the command reference is suitable to this command label, false otherwise. * @return True if the command reference is suitable to this command label, false otherwise.
*/ */
public boolean isSuitableLabel(CommandParts commandReference) { public boolean isSuitableLabel(CommandParts commandReference) {
// Make sure the command reference is valid
if (commandReference.getCount() <= 0)
return false;
// Get the parent count // Get the parent count
//getParent() = getParent().getParentCount() + 1
String element = commandReference.get(getParentCount()); String element = commandReference.get(getParentCount());
// Check whether this command description has this command label // Check whether this command description has this command label
return hasLabel(element); for (String label : labels) {
} if (label.equalsIgnoreCase(element)) {
return true;
/** }
* Get the absolute command label, without a starting slash. }
* return false;
* @return The absolute label
*/
public String getAbsoluteLabel() {
return getAbsoluteLabel(false);
}
/**
* Get the absolute command label.
*
* @param includeSlash boolean
*
* @return Absolute command label.
*/
public String getAbsoluteLabel(boolean includeSlash) {
return getAbsoluteLabel(includeSlash, null);
}
/**
* Get the absolute command label.
*
* @param includeSlash
* @param reference
*
* @return Absolute command label.
*/
public String getAbsoluteLabel(boolean includeSlash, CommandParts reference) {
// Get the command reference, and make sure it is valid
CommandParts out = getCommandReference(reference);
if (out == null)
return "";
// Return the result
return (includeSlash ? "/" : "") + out.toString();
} }
/** /**
@ -269,8 +210,9 @@ public class CommandDescription {
List<String> referenceList = new ArrayList<>(); List<String> referenceList = new ArrayList<>();
// Check whether this command has a parent, if so, add the absolute parent command // Check whether this command has a parent, if so, add the absolute parent command
if (getParent() != null) if (getParent() != null) {
referenceList.addAll(getParent().getCommandReference(reference).getList()); referenceList.addAll(getParent().getCommandReference(reference).getList());
}
// Get the current label // Get the current label
referenceList.add(getLabel(reference)); referenceList.add(getLabel(reference));
@ -307,7 +249,8 @@ public class CommandDescription {
CommandParts reference = getCommandReference(other); CommandParts reference = getCommandReference(other);
// Compare the two references, return the result // Compare the two references, return the result
return reference.getDifference(new CommandParts(other.getRange(0, reference.getCount())), fullCompare); return CommandUtils.getDifference(reference.getList(),
CollectionUtils.getRange(other.getList(), 0, reference.getList().size()), fullCompare);
} }
/** /**
@ -328,15 +271,6 @@ public class CommandDescription {
this.executableCommand = executableCommand; this.executableCommand = executableCommand;
} }
/**
* Check whether this command is executable, based on the assigned executable command.
*
* @return True if this command is executable.
*/
public boolean isExecutable() {
return this.executableCommand != null;
}
/** /**
* Execute the command, if possible. * Execute the command, if possible.
* *
@ -347,10 +281,6 @@ public class CommandDescription {
* @return True on success, false on failure. * @return True on success, false on failure.
*/ */
public boolean execute(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { public boolean execute(CommandSender sender, CommandParts commandReference, CommandParts commandArguments) {
// Make sure the command is executable
if (!isExecutable())
return false;
// Execute the command, return the result // Execute the command, return the result
return getExecutableCommand().executeCommand(sender, commandReference, commandArguments); return getExecutableCommand().executeCommand(sender, commandReference, commandArguments);
} }
@ -461,7 +391,7 @@ public class CommandDescription {
*/ */
public boolean isChild(CommandDescription commandDescription) { public boolean isChild(CommandDescription commandDescription) {
// Make sure the description is valid // Make sure the description is valid
if (commandDescription == null) // TODO: After builder, commandDescription == null -> never if (commandDescription == null)
return false; return false;
// Check whether this child exists, return the result // Check whether this child exists, return the result
@ -480,10 +410,6 @@ public class CommandDescription {
if (argument == null) if (argument == null)
return false; return false;
// Make sure the argument isn't added already
if (hasArgument(argument))
return true;
// Add the argument, return the result // Add the argument, return the result
return this.arguments.add(argument); return this.arguments.add(argument);
} }
@ -497,81 +423,13 @@ public class CommandDescription {
return this.arguments; return this.arguments;
} }
/**
* Set the arguments of this command.
*
* @param arguments New command arguments. Null to clear the list of arguments.
*/
public void setArguments(List<CommandArgumentDescription> arguments) {
// Convert null into an empty argument list
if (arguments == null) {
// Note ljacqu 20151128: Temporary workaround to avoid null pointer exception. Soon we won't need setters
// on the main class (-> complete instantiation via Builder)
// TODO Remove this method once unused
this.arguments = new ArrayList<>();
} else {
this.arguments = arguments;
}
}
/**
* Check whether an argument exists.
*
* @param argument The argument to check for.
*
* @return True if this argument already exists, false otherwise.
*/
public boolean hasArgument(CommandArgumentDescription argument) {
return argument != null && arguments.contains(argument);
}
/** /**
* Check whether this command has any arguments. * Check whether this command has any arguments.
* *
* @return True if this command has any arguments. * @return True if this command has any arguments.
*/ */
public boolean hasArguments() { public boolean hasArguments() {
return !arguments.isEmpty(); return !getArguments().isEmpty();
}
/**
* The minimum number of arguments required for this command.
*
* @return The minimum number of required arguments.
*/
public int getMinimumArguments() {
// Get the number of required and optional arguments
int requiredArguments = 0;
int optionalArgument = 0;
// Loop through each argument
for (CommandArgumentDescription argument : this.arguments) {
// Check whether the command is optional
if (!argument.isOptional()) {
requiredArguments += optionalArgument + 1;
optionalArgument = 0;
} else
optionalArgument++;
}
// Return the number of required arguments
return requiredArguments;
}
/**
* Get the maximum number of arguments.
*
* @return The maximum number of arguments. A negative number will be returned if there's no maximum.
*/
public int getMaximumArguments() {
// Check whether there is a maximum set
if (this.noArgumentMaximum)
// TODO ljacqu 20151128: Magic number
return -1;
// Return the maximum based on the registered arguments
return this.arguments.size();
} }
/** /**
@ -580,16 +438,7 @@ public class CommandDescription {
* @return Command description. * @return Command description.
*/ */
public String getDescription() { public String getDescription() {
return hasDescription() ? this.description : this.detailedDescription; return description;
}
/**
* Check whether this command has any description.
*
* @return True if this command has any description.
*/
public boolean hasDescription() {
return !StringUtils.isEmpty(description);
} }
/** /**
@ -598,7 +447,7 @@ public class CommandDescription {
* @return Command detailed description. * @return Command detailed description.
*/ */
public String getDetailedDescription() { public String getDetailedDescription() {
return !StringUtils.isEmpty(detailedDescription) ? this.detailedDescription : this.description; return detailedDescription;
} }
/** /**
@ -614,16 +463,17 @@ public class CommandDescription {
return null; return null;
// Check whether this description is for the last element in the command reference, if so return the current command // Check whether this description is for the last element in the command reference, if so return the current command
if (queryReference.getCount() <= getParentCount() + 1) if (queryReference.getCount() <= getParentCount() + 1) {
return new FoundCommandResult( return new FoundCommandResult(
this, this,
getCommandReference(queryReference), getCommandReference(queryReference),
new CommandParts(), new CommandParts(new ArrayList<String>()),
queryReference); queryReference);
}
// Get the new command reference and arguments // Get the new command reference and arguments
CommandParts newReference = new CommandParts(queryReference.getRange(0, getParentCount() + 1)); CommandParts newReference = new CommandParts(CollectionUtils.getRange(queryReference.getList(), 0, getParentCount() + 1));
CommandParts newArguments = new CommandParts(queryReference.getRange(getParentCount() + 1)); CommandParts newArguments = new CommandParts(CollectionUtils.getRange(queryReference.getList(), getParentCount() + 1));
// Handle the child's, if this command has any // Handle the child's, if this command has any
if (getChildren().size() > 0) { if (getChildren().size() > 0) {
@ -663,28 +513,6 @@ public class CommandDescription {
return null; return null;
} }
/**
* Check whether there's any command description that matches the specified command reference.
*
* @param commandReference The command reference.
*
* @return True if so, false otherwise.
*/
public boolean hasSuitableCommand(CommandParts commandReference) {
return findCommand(commandReference) != null;
}
/**
* Check if the remaining command reference elements are suitable with arguments of the current command description.
*
* @param commandReference The command reference.
*
* @return True if the arguments are suitable, false otherwise.
*/
public boolean hasSuitableArguments(CommandParts commandReference) {
return getSuitableArgumentsDifference(commandReference) == 0;
}
/** /**
* Check if the remaining command reference elements are suitable with arguments of the current command description, * Check if the remaining command reference elements are suitable with arguments of the current command description,
* and get the difference in argument count. * and get the difference in argument count.
@ -703,16 +531,18 @@ public class CommandDescription {
int remainingElementCount = commandReference.getCount() - getParentCount() - 1; int remainingElementCount = commandReference.getCount() - getParentCount() - 1;
// Check if there are too few arguments // Check if there are too few arguments
if (getMinimumArguments() > remainingElementCount) { int minArguments = CommandUtils.getMinNumberOfArguments(this);
return Math.abs(getMinimumArguments() - remainingElementCount); if (minArguments > remainingElementCount) {
return Math.abs(minArguments - remainingElementCount);
} }
// Check if there are too many arguments // Check if there are too many arguments
if (getMaximumArguments() < remainingElementCount && getMaximumArguments() >= 0) { int maxArguments = CommandUtils.getMaxNumberOfArguments(this);
return Math.abs(remainingElementCount - getMaximumArguments()); if (maxArguments >= 0 && maxArguments < remainingElementCount) {
return Math.abs(remainingElementCount - maxArguments);
} }
// The arguments seem to be EQUALS, return the result // The argument count is the same
return 0; return 0;
} }
@ -739,6 +569,9 @@ public class CommandDescription {
return new CommandBuilder(); return new CommandBuilder();
} }
/**
* Builder for initializing CommandDescription objects.
*/
public static final class CommandBuilder { public static final class CommandBuilder {
private List<String> labels; private List<String> labels;
private String description; private String description;
@ -746,23 +579,22 @@ public class CommandDescription {
private ExecutableCommand executableCommand; private ExecutableCommand executableCommand;
private CommandDescription parent; private CommandDescription parent;
private List<CommandArgumentDescription> arguments = new ArrayList<>(); private List<CommandArgumentDescription> arguments = new ArrayList<>();
private boolean noArgumentMaximum;
private CommandPermissions permissions; private CommandPermissions permissions;
/** /**
* Build a CommandDescription from the builder. * Build a CommandDescription from the builder or throw an exception if mandatory
* fields have not been set.
* *
* @return The generated CommandDescription object * @return The generated CommandDescription object
*/ */
public CommandDescription build() { public CommandDescription build() {
return new CommandDescription( return createInstance(
getOrThrow(labels, "labels"), getOrThrow(labels, "labels"),
firstNonNull(description, ""), firstNonNull(description, ""),
firstNonNull(detailedDescription, ""), firstNonNull(detailedDescription, ""),
getOrThrow(executableCommand, "executableCommand"), getOrThrow(executableCommand, "executableCommand"),
firstNonNull(parent, null), firstNonNull(parent, null),
arguments, arguments,
noArgumentMaximum,
firstNonNull(permissions, null) firstNonNull(permissions, null)
); );
} }
@ -796,16 +628,21 @@ public class CommandDescription {
return this; return this;
} }
/**
* Add an argument that the command description requires. This method can be called multiples times to add
* multiple arguments.
*
* @param label The label of the argument (single word name of the argument)
* @param description The description of the argument
* @param isOptional True if the argument is option, false if it is mandatory
*
* @return The builder
*/
public CommandBuilder withArgument(String label, String description, boolean isOptional) { public CommandBuilder withArgument(String label, String description, boolean isOptional) {
arguments.add(new CommandArgumentDescription(label, description, isOptional)); arguments.add(new CommandArgumentDescription(label, description, isOptional));
return this; return this;
} }
public CommandBuilder noArgumentMaximum(boolean noArgumentMaximum) {
this.noArgumentMaximum = noArgumentMaximum;
return this;
}
public CommandBuilder permissions(CommandPermissions.DefaultPermission defaultPermission, public CommandBuilder permissions(CommandPermissions.DefaultPermission defaultPermission,
PermissionNode... permissionNodes) { PermissionNode... permissionNodes) {
this.permissions = new CommandPermissions(asMutableList(permissionNodes), defaultPermission); this.permissions = new CommandPermissions(asMutableList(permissionNodes), defaultPermission);

View File

@ -2,209 +2,236 @@ package fr.xephi.authme.command;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.help.HelpProvider; import fr.xephi.authme.command.help.HelpProvider;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* The AuthMe command handler, responsible for mapping incoming commands to the correct {@link CommandDescription}
* or to display help messages for unknown invocations.
*/ */
public class CommandHandler { public class CommandHandler {
/** /**
* The command manager instance. * 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 CommandManager commandManager; private static final double ASSUME_COMMAND_THRESHOLD = 0.12;
/** /**
* Constructor. * 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.
* @param init True to immediately initialize.
*/ */
public CommandHandler(boolean init) { private static final double SUGGEST_COMMAND_THRESHOLD = 0.75;
// Initialize
if (init) private final Set<CommandDescription> commands;
init();
/**
* Create a command handler.
*
* @param commands The collection of available AuthMe commands
*/
public CommandHandler(Set<CommandDescription> commands) {
this.commands = commands;
} }
/** /**
* Initialize the command handler. * Map a command that was invoked to the proper {@link CommandDescription} or return a useful error
* * message upon failure.
* @return True if succeed, false on failure. True will also be returned if the command handler was already
* initialized.
*/
public boolean init() {
// Make sure the handler isn't initialized already
if (isInit())
return true;
// Initialize the command manager
this.commandManager = new CommandManager(false);
this.commandManager.registerCommands();
// Return the result
return true;
}
/**
* Check whether the command handler is initialized.
*
* @return True if the command handler is initialized.
*/
public boolean isInit() {
return this.commandManager != null;
}
/**
* Destroy the command handler.
*
* @return True if the command handler was destroyed successfully, false otherwise. True will also be returned if
* the command handler wasn't initialized.
*/
public boolean destroy() {
// Make sure the command handler is initialized
if (!isInit())
return true;
// Unset the command manager
this.commandManager = null;
return true;
}
/**
* Get the command manager.
*
* @return Command manager instance.
*/
public CommandManager getCommandManager() {
return this.commandManager;
}
/**
* Process a command.
* *
* @param sender The command sender (Bukkit). * @param sender The command sender (Bukkit).
* @param bukkitCommand The command (Bukkit).
* @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 onCommand(CommandSender sender, org.bukkit.command.Command bukkitCommand, String bukkitCommandLabel, String[] bukkitArgs) { public boolean processCommand(CommandSender sender, String bukkitCommandLabel, String[] bukkitArgs) {
// Process the arguments List<String> commandArgs = skipEmptyArguments(bukkitArgs);
List<String> args = processArguments(bukkitArgs); // Add the Bukkit command label to the front so we get a list like [authme, register, pass, passConfirm]
commandArgs.add(0, bukkitCommandLabel);
// Create a command reference, and make sure at least one command part is available // TODO: remove commandParts
CommandParts commandReference = new CommandParts(bukkitCommandLabel, args); CommandParts commandReference = new CommandParts(commandArgs);
if (commandReference.getCount() == 0)
return false;
// Get a suitable command for this reference, and make sure it isn't null // Get a suitable command for this reference, and make sure it isn't null
FoundCommandResult result = this.commandManager.findCommand(commandReference); FoundCommandResult result = findCommand(commandReference);
if (result == null) { if (result == null) {
// TODO ljacqu 20151204: Log more information to the console (bukkitCommandLabel)
sender.sendMessage(ChatColor.DARK_RED + "Failed to parse " + AuthMe.getPluginName() + " command!"); sender.sendMessage(ChatColor.DARK_RED + "Failed to parse " + AuthMe.getPluginName() + " command!");
return false; return false;
} }
// Get the base command
String baseCommand = commandReference.get(0); String baseCommand = commandArgs.get(0);
// Make sure the difference between the command reference and the actual command isn't too big // Make sure the difference between the command reference and the actual command isn't too big
final double commandDifference = result.getDifference(); final double commandDifference = result.getDifference();
if (commandDifference > 0.12) { if (commandDifference <= ASSUME_COMMAND_THRESHOLD) {
// Show the unknown command warning
sender.sendMessage(ChatColor.DARK_RED + "Unknown command!");
// Show a command suggestion if available and the difference isn't too big // Show a message when the command handler is assuming a command
if (commandDifference < 0.75) if (commandDifference > 0) {
if (result.getCommandDescription() != null) sendCommandAssumptionMessage(sender, result, commandReference);
sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/" + result.getCommandDescription().getCommandReference(commandReference) + ChatColor.YELLOW + "?"); }
// Show the help command if (!result.hasPermission(sender)) {
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help" + ChatColor.YELLOW + " to view help."); sender.sendMessage(ChatColor.DARK_RED + "You don't have permission to use this command!");
return true; } else if (!result.hasProperArguments()) {
sendImproperArgumentsMessage(sender, result, commandReference, baseCommand);
} else {
return result.executeCommand(sender);
}
} else {
sendUnknownCommandMessage(sender, commandDifference, result, baseCommand);
} }
return true;
// Show a message when the command handler is assuming a command
if (commandDifference > 0) {
// Get the suggested command
CommandParts suggestedCommandParts = new CommandParts(result.getCommandDescription().getCommandReference(commandReference));
// Show the suggested command
sender.sendMessage(ChatColor.DARK_RED + "Unknown command, assuming " + ChatColor.GOLD + "/" + suggestedCommandParts +
ChatColor.DARK_RED + "!");
}
// Make sure the command is executable
if (!result.isExecutable()) {
// Get the command reference
CommandParts helpCommandReference = new CommandParts(result.getCommandReference().getRange(1));
// Show the unknown command warning
sender.sendMessage(ChatColor.DARK_RED + "Invalid command!");
// Show the help command
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help " + helpCommandReference + ChatColor.YELLOW + " to view help.");
return true;
}
// Make sure the command sender has permission
if (!result.hasPermission(sender)) {
// Show the no permissions warning
sender.sendMessage(ChatColor.DARK_RED + "You don't have permission to use this command!");
return true;
}
// Make sure the command sender has permission
if (!result.hasProperArguments()) {
// Get the command and the suggested command reference
CommandParts suggestedCommandReference = new CommandParts(result.getCommandDescription().getCommandReference(commandReference));
CommandParts helpCommandReference = new CommandParts(suggestedCommandReference.getRange(1));
// Show the invalid arguments warning
sender.sendMessage(ChatColor.DARK_RED + "Incorrect command arguments!");
// Show the command argument help
HelpProvider.showHelp(sender, commandReference, suggestedCommandReference, true, false, true, false, false, false);
// Show the command to use for detailed help
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + baseCommand + " help " + helpCommandReference);
return true;
}
// Execute the command if it's suitable
return result.executeCommand(sender);
} }
/** /**
* Process the command arguments, and return them as an array list. * Skip all entries of the given array that are simply whitespace.
* *
* @param args The command arguments to process. * @param args The array to process
* * @return List of the items that are not empty
* @return The processed command arguments.
*/ */
private List<String> processArguments(String[] args) { private static List<String> skipEmptyArguments(String[] args) {
// Convert the array into a list of arguments List<String> cleanArguments = new ArrayList<>(args.length);
List<String> arguments = new ArrayList<>(Arrays.asList(args)); for (String argument : args) {
if (!StringUtils.isEmpty(argument)) {
/// Remove all empty arguments cleanArguments.add(argument);
for (int i = 0; i < arguments.size(); i++) {
// Get the argument value
final String arg = arguments.get(i);
// Check whether the argument value is empty
if (arg.trim().length() == 0) {
// Remove the current argument
arguments.remove(i);
// Decrease the index by one, continue to the next argument
i--;
} }
} }
return cleanArguments;
}
// Return the argument
return arguments; 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
* the defined threshold.
*
* @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 baseCommand The base command (TODO: This is probably already in FoundCommandResult)
*/
private static void sendUnknownCommandMessage(CommandSender sender, double commandDifference,
FoundCommandResult result, String baseCommand) {
CommandParts commandReference = result.getCommandReference();
sender.sendMessage(ChatColor.DARK_RED + "Unknown command!");
// Show a command suggestion if available and the difference isn't too big
if (commandDifference < SUGGEST_COMMAND_THRESHOLD && result.getCommandDescription() != null) {
sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/"
+ result.getCommandDescription().getCommandReference(commandReference) + ChatColor.YELLOW + "?");
}
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help"
+ ChatColor.YELLOW + " to view help.");
}
private static void sendImproperArgumentsMessage(CommandSender sender, FoundCommandResult result,
CommandParts commandReference, String baseCommand) {
// Get the command and the suggested command reference
List<String> suggestedCommandReference =
result.getCommandDescription().getCommandReference(commandReference).getList();
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
HelpProvider.showHelp(sender, commandReference, new CommandParts(suggestedCommandReference),
true, false, true, false, false, false);
// Show the command to use for detailed help
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + baseCommand
+ " help " + CommandUtils.labelsToString(helpCommandReference));
}
private static void sendCommandAssumptionMessage(CommandSender sender, FoundCommandResult result,
CommandParts commandReference) {
List<String> assumedCommandParts =
result.getCommandDescription().getCommandReference(commandReference).getList();
sender.sendMessage(ChatColor.DARK_RED + "Unknown command, assuming " + ChatColor.GOLD + "/"
+ CommandUtils.labelsToString(assumedCommandParts) + ChatColor.DARK_RED + "!");
} }
} }

View File

@ -1,7 +1,26 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import fr.xephi.authme.command.executable.HelpCommand; import fr.xephi.authme.command.executable.HelpCommand;
import fr.xephi.authme.command.executable.authme.*; import fr.xephi.authme.command.executable.authme.AccountsCommand;
import fr.xephi.authme.command.executable.authme.AuthMeCommand;
import fr.xephi.authme.command.executable.authme.ChangePasswordCommand;
import fr.xephi.authme.command.executable.authme.FirstSpawnCommand;
import fr.xephi.authme.command.executable.authme.ForceLoginCommand;
import fr.xephi.authme.command.executable.authme.GetEmailCommand;
import fr.xephi.authme.command.executable.authme.GetIpCommand;
import fr.xephi.authme.command.executable.authme.LastLoginCommand;
import fr.xephi.authme.command.executable.authme.PurgeBannedPlayersCommand;
import fr.xephi.authme.command.executable.authme.PurgeCommand;
import fr.xephi.authme.command.executable.authme.PurgeLastPositionCommand;
import fr.xephi.authme.command.executable.authme.RegisterCommand;
import fr.xephi.authme.command.executable.authme.ReloadCommand;
import fr.xephi.authme.command.executable.authme.SetEmailCommand;
import fr.xephi.authme.command.executable.authme.SetFirstSpawnCommand;
import fr.xephi.authme.command.executable.authme.SetSpawnCommand;
import fr.xephi.authme.command.executable.authme.SpawnCommand;
import fr.xephi.authme.command.executable.authme.SwitchAntiBotCommand;
import fr.xephi.authme.command.executable.authme.UnregisterCommand;
import fr.xephi.authme.command.executable.authme.VersionCommand;
import fr.xephi.authme.command.executable.captcha.CaptchaCommand; import fr.xephi.authme.command.executable.captcha.CaptchaCommand;
import fr.xephi.authme.command.executable.converter.ConverterCommand; import fr.xephi.authme.command.executable.converter.ConverterCommand;
import fr.xephi.authme.command.executable.email.AddEmailCommand; import fr.xephi.authme.command.executable.email.AddEmailCommand;
@ -11,147 +30,141 @@ import fr.xephi.authme.command.executable.login.LoginCommand;
import fr.xephi.authme.command.executable.logout.LogoutCommand; import fr.xephi.authme.command.executable.logout.LogoutCommand;
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.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.List;
import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.ALLOWED; import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.ALLOWED;
import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.OP_ONLY; import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.OP_ONLY;
/** /**
* Initializes all available AuthMe commands.
*/ */
public class CommandManager { public final class CommandInitializer {
/** private static Set<CommandDescription> baseCommands;
* The list of commandDescriptions.
*/
private final List<CommandDescription> commandDescriptions = new ArrayList<>();
/** private CommandInitializer() {
* Constructor. // Helper class
*
* @param registerCommands True to register the commands, false otherwise.
*/
public CommandManager(boolean registerCommands) {
// Register the commands
if (registerCommands)
registerCommands();
} }
/** public static Set<CommandDescription> getBaseCommands() {
* Register all commands. if (baseCommands == null) {
*/ Wrapper.getInstance().getLogger().info("Initializing AuthMe commands");
public void registerCommands() { initializeCommands();
}
return baseCommands;
}
private static void initializeCommands() {
// Create a list of help command labels // Create a list of help command labels
final List<String> helpCommandLabels = Arrays.asList("help", "hlp", "h", "sos", "?"); final List<String> helpCommandLabels = Arrays.asList("help", "hlp", "h", "sos", "?");
ExecutableCommand helpCommandExecutable = new HelpCommand(); final ExecutableCommand helpCommandExecutable = new HelpCommand();
// Register the base AuthMe Reloaded command // Register the base AuthMe Reloaded command
CommandDescription authMeBaseCommand = CommandDescription.builder() final CommandDescription AUTHME_BASE = CommandDescription.builder()
.executableCommand(new AuthMeCommand())
.labels("authme") .labels("authme")
.description("Main command") .description("Main command")
.detailedDescription("The main AuthMeReloaded command. The root for all admin commands.") .detailedDescription("The main AuthMeReloaded command. The root for all admin commands.")
.parent(null) .executableCommand(new AuthMeCommand())
.build(); .build();
// Register the help command // Register the help command
CommandDescription authMeHelpCommand = CommandDescription.builder() CommandDescription.builder()
.executableCommand(helpCommandExecutable) .parent(AUTHME_BASE)
.labels(helpCommandLabels) .labels(helpCommandLabels)
.description("View help") .description("View help")
.detailedDescription("View detailed help pages about AuthMeReloaded commands.") .detailedDescription("View detailed help pages about AuthMeReloaded commands.")
.parent(authMeBaseCommand)
.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 register command // Register the register command
CommandDescription registerCommand = CommandDescription.builder() CommandDescription.builder()
.executableCommand(new RegisterCommand()) .parent(AUTHME_BASE)
.labels("register", "reg", "r") .labels("register", "reg", "r")
.description("Register a player") .description("Register a player")
.detailedDescription("Register the specified player with the specified password.") .detailedDescription("Register the specified player with the specified password.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, PlayerPermission.REGISTER)
.withArgument("player", "Player name", false) .withArgument("player", "Player name", false)
.withArgument("password", "Password", false) .withArgument("password", "Password", false)
.permissions(OP_ONLY, PlayerPermission.REGISTER)
.executableCommand(new RegisterCommand())
.build(); .build();
// Register the unregister command // Register the unregister command
CommandDescription unregisterCommand = CommandDescription.builder() CommandDescription.builder()
.executableCommand(new UnregisterCommand()) .parent(AUTHME_BASE)
.labels("unregister", "unreg", "unr") .labels("unregister", "unreg", "unr")
.description("Unregister a player") .description("Unregister a player")
.detailedDescription("Unregister the specified player.") .detailedDescription("Unregister the specified player.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, PlayerPermission.UNREGISTER)
.withArgument("player", "Player name", false) .withArgument("player", "Player name", false)
.permissions(OP_ONLY, PlayerPermission.UNREGISTER)
.executableCommand(new UnregisterCommand())
.build(); .build();
// Register the forcelogin command // Register the forcelogin command
CommandDescription forceLoginCommand = CommandDescription.builder() CommandDescription.builder()
.executableCommand(new ForceLoginCommand()) .parent(AUTHME_BASE)
.labels("forcelogin", "login") .labels("forcelogin", "login")
.description("Enforce login player") .description("Enforce login player")
.detailedDescription("Enforce the specified player to login.") .detailedDescription("Enforce the specified player to login.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, PlayerPermission.CAN_LOGIN_BE_FORCED)
.withArgument("player", "Online player name", true) .withArgument("player", "Online player name", true)
.permissions(OP_ONLY, PlayerPermission.CAN_LOGIN_BE_FORCED)
.executableCommand(new ForceLoginCommand())
.build(); .build();
// Register the changepassword command // Register the changepassword command
CommandDescription changePasswordCommand = CommandDescription.builder() CommandDescription.builder()
.executableCommand(new ChangePasswordCommand()) .parent(AUTHME_BASE)
.labels("password", "changepassword", "changepass", "cp") .labels("password", "changepassword", "changepass", "cp")
.description("Change a player's password") .description("Change a player's password")
.detailedDescription("Change the password of a player.") .detailedDescription("Change the password of a player.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, AdminPermission.CHANGE_PASSWORD)
.withArgument("player", "Player name", false) .withArgument("player", "Player name", false)
.withArgument("pwd", "New password", false) .withArgument("pwd", "New password", false)
.permissions(OP_ONLY, AdminPermission.CHANGE_PASSWORD)
.executableCommand(new ChangePasswordCommand())
.build(); .build();
// Register the last login command // Register the last login command
CommandDescription lastLoginCommand = CommandDescription.builder() CommandDescription.builder()
.executableCommand(new LastLoginCommand()) .parent(AUTHME_BASE)
.labels("lastlogin", "ll") .labels("lastlogin", "ll")
.description("Player's last login") .description("Player's last login")
.detailedDescription("View the date of the specified players last login.") .detailedDescription("View the date of the specified players last login.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, AdminPermission.LAST_LOGIN)
.withArgument("player", "Player name", true) .withArgument("player", "Player name", true)
.permissions(OP_ONLY, AdminPermission.LAST_LOGIN)
.executableCommand(new LastLoginCommand())
.build(); .build();
// Register the accounts command // Register the accounts command
CommandDescription accountsCommand = CommandDescription.builder() CommandDescription.builder()
.executableCommand(new AccountsCommand()) .parent(AUTHME_BASE)
.labels("accounts", "account") .labels("accounts", "account")
.description("Display player accounts") .description("Display player accounts")
.detailedDescription("Display all accounts of a player by his player name or IP.") .detailedDescription("Display all accounts of a player by his player name or IP.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, AdminPermission.ACCOUNTS)
.withArgument("player", "Player name or IP", true) .withArgument("player", "Player name or IP", true)
.permissions(OP_ONLY, AdminPermission.ACCOUNTS)
.executableCommand(new AccountsCommand())
.build(); .build();
// Register the getemail command // Register the getemail command
CommandDescription getEmailCommand = CommandDescription.builder() CommandDescription.builder()
.executableCommand(new GetEmailCommand()) .parent(AUTHME_BASE)
.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.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, AdminPermission.GET_EMAIL) .permissions(OP_ONLY, AdminPermission.GET_EMAIL)
.withArgument("player", "Player name", true) .withArgument("player", "Player name", true)
.executableCommand(new GetEmailCommand())
.build(); .build();
// Register the setemail command // Register the setemail command
CommandDescription setEmailCommand = CommandDescription.builder() CommandDescription setEmailCommand = CommandDescription.builder()
.executableCommand(new SetEmailCommand()) .executableCommand(new SetEmailCommand())
.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.")
.parent(authMeBaseCommand)
.permissions(OP_ONLY, AdminPermission.CHANGE_EMAIL) .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)
@ -163,7 +176,7 @@ public class CommandManager {
add("getip"); add("getip");
add("ip"); add("ip");
} }
}, "Get player's IP", "Get the IP address of the specified online player.", authMeBaseCommand); }, "Get player's IP", "Get the IP address of the specified online player.", AUTHME_BASE);
getIpCommand.setCommandPermissions(AdminPermission.GET_IP, OP_ONLY); getIpCommand.setCommandPermissions(AdminPermission.GET_IP, OP_ONLY);
getIpCommand.addArgument(new CommandArgumentDescription("player", "Online player name", true)); getIpCommand.addArgument(new CommandArgumentDescription("player", "Online player name", true));
@ -173,7 +186,7 @@ public class CommandManager {
add("spawn"); add("spawn");
add("home"); add("home");
} }
}, "Teleport to spawn", "Teleport to the spawn.", authMeBaseCommand); }, "Teleport to spawn", "Teleport to the spawn.", AUTHME_BASE);
spawnCommand.setCommandPermissions(AdminPermission.SPAWN, OP_ONLY); spawnCommand.setCommandPermissions(AdminPermission.SPAWN, OP_ONLY);
// Register the setspawn command // Register the setspawn command
@ -182,7 +195,7 @@ public class CommandManager {
add("setspawn"); add("setspawn");
add("chgspawn"); add("chgspawn");
} }
}, "Change the spawn", "Change the player's spawn to your current position.", authMeBaseCommand); }, "Change the spawn", "Change the player's spawn to your current position.", AUTHME_BASE);
setSpawnCommand.setCommandPermissions(AdminPermission.SET_SPAWN, OP_ONLY); setSpawnCommand.setCommandPermissions(AdminPermission.SET_SPAWN, OP_ONLY);
// Register the firstspawn command // Register the firstspawn command
@ -191,7 +204,7 @@ public class CommandManager {
add("firstspawn"); add("firstspawn");
add("firsthome"); add("firsthome");
} }
}, "Teleport to first spawn", "Teleport to the first spawn.", authMeBaseCommand); }, "Teleport to first spawn", "Teleport to the first spawn.", AUTHME_BASE);
firstSpawnCommand.setCommandPermissions(AdminPermission.FIRST_SPAWN, OP_ONLY); firstSpawnCommand.setCommandPermissions(AdminPermission.FIRST_SPAWN, OP_ONLY);
// Register the setfirstspawn command // Register the setfirstspawn command
@ -200,7 +213,7 @@ public class CommandManager {
add("setfirstspawn"); add("setfirstspawn");
add("chgfirstspawn"); add("chgfirstspawn");
} }
}, "Change the first spawn", "Change the first player's spawn to your current position.", authMeBaseCommand); }, "Change the first spawn", "Change the first player's spawn to your current position.", AUTHME_BASE);
setFirstSpawnCommand.setCommandPermissions(AdminPermission.SET_FIRST_SPAWN, OP_ONLY); setFirstSpawnCommand.setCommandPermissions(AdminPermission.SET_FIRST_SPAWN, OP_ONLY);
// Register the purge command // Register the purge command
@ -209,7 +222,7 @@ public class CommandManager {
add("purge"); add("purge");
add("delete"); add("delete");
} }
}, "Purge old data", "Purge old AuthMeReloaded data longer than the specified amount of days ago.", authMeBaseCommand); }, "Purge old data", "Purge old AuthMeReloaded data longer than the specified amount of days ago.", AUTHME_BASE);
purgeCommand.setCommandPermissions(AdminPermission.PURGE, OP_ONLY); purgeCommand.setCommandPermissions(AdminPermission.PURGE, OP_ONLY);
purgeCommand.addArgument(new CommandArgumentDescription("days", "Number of days", false)); purgeCommand.addArgument(new CommandArgumentDescription("days", "Number of days", false));
@ -223,7 +236,7 @@ public class CommandManager {
add("resetlastposition"); add("resetlastposition");
add("resetlastpos"); add("resetlastpos");
} }
}, "Purge player's last position", "Purge the last know position of the specified player.", authMeBaseCommand); }, "Purge player's last position", "Purge the last know position of the specified player.", AUTHME_BASE);
purgeLastPositionCommand.setCommandPermissions(AdminPermission.PURGE_LAST_POSITION, OP_ONLY); purgeLastPositionCommand.setCommandPermissions(AdminPermission.PURGE_LAST_POSITION, OP_ONLY);
purgeLastPositionCommand.addArgument(new CommandArgumentDescription("player", "Player name", true)); purgeLastPositionCommand.addArgument(new CommandArgumentDescription("player", "Player name", true));
@ -235,7 +248,7 @@ public class CommandManager {
add("deletebannedplayers"); add("deletebannedplayers");
add("deletebannedplayer"); add("deletebannedplayer");
} }
}, "Purge banned palyers data", "Purge all AuthMeReloaded data for banned players.", authMeBaseCommand); }, "Purge banned palyers data", "Purge all AuthMeReloaded data for banned players.", AUTHME_BASE);
purgeBannedPlayersCommand.setCommandPermissions(AdminPermission.PURGE_BANNED_PLAYERS, OP_ONLY); purgeBannedPlayersCommand.setCommandPermissions(AdminPermission.PURGE_BANNED_PLAYERS, OP_ONLY);
// Register the switchantibot command // Register the switchantibot command
@ -245,7 +258,7 @@ public class CommandManager {
add("toggleantibot"); add("toggleantibot");
add("antibot"); add("antibot");
} }
}, "Switch AntiBot mode", "Switch or toggle the AntiBot mode to the specified state.", authMeBaseCommand); }, "Switch AntiBot mode", "Switch or toggle the AntiBot mode to the specified state.", AUTHME_BASE);
switchAntiBotCommand.setCommandPermissions(AdminPermission.SWITCH_ANTIBOT, OP_ONLY); switchAntiBotCommand.setCommandPermissions(AdminPermission.SWITCH_ANTIBOT, OP_ONLY);
switchAntiBotCommand.addArgument(new CommandArgumentDescription("mode", "ON / OFF", true)); switchAntiBotCommand.addArgument(new CommandArgumentDescription("mode", "ON / OFF", true));
@ -268,21 +281,21 @@ public class CommandManager {
add("reload"); add("reload");
add("rld"); add("rld");
} }
}, "Reload plugin", "Reload the AuthMeReloaded plugin.", authMeBaseCommand); }, "Reload plugin", "Reload the AuthMeReloaded plugin.", AUTHME_BASE);
reloadCommand.setCommandPermissions(AdminPermission.RELOAD, OP_ONLY); reloadCommand.setCommandPermissions(AdminPermission.RELOAD, OP_ONLY);
// Register the version command // Register the version command
CommandDescription versionCommand = CommandDescription.builder() CommandDescription.builder()
.executableCommand(new VersionCommand()) .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, and shows the "
+ "developers, contributors, license and other information.") + "developers, contributors, license and other information.")
.parent(authMeBaseCommand) .executableCommand(new VersionCommand())
.build(); .build();
// Register the base login command // Register the base login command
CommandDescription loginBaseCommand = CommandDescription.builder() final CommandDescription LOGIN_BASE = CommandDescription.builder()
.executableCommand(new LoginCommand()) .executableCommand(new LoginCommand())
.labels("login", "l") .labels("login", "l")
.description("Login command") .description("Login command")
@ -294,70 +307,72 @@ public class CommandManager {
// Register the help command // Register the help command
CommandDescription loginHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels, CommandDescription loginHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded login commands.", loginBaseCommand); "View help", "View detailed help pages about AuthMeReloaded login commands.", LOGIN_BASE);
loginHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true)); loginHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the base logout command // Register the base logout command
CommandDescription logoutBaseCommand = new CommandDescription(new LogoutCommand(), new ArrayList<String>() { CommandDescription LOGOUT_BASE = new CommandDescription(new LogoutCommand(), new ArrayList<String>() {
{ {
add("logout"); add("logout");
} }
}, "Logout command", "Command to logout using AuthMeReloaded.", null); }, "Logout command", "Command to logout using AuthMeReloaded.", null);
logoutBaseCommand.setCommandPermissions(PlayerPermission.LOGOUT, CommandPermissions.DefaultPermission.ALLOWED); LOGOUT_BASE.setCommandPermissions(PlayerPermission.LOGOUT, CommandPermissions.DefaultPermission.ALLOWED);
// Register the help command // Register the help command
CommandDescription logoutHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels, CommandDescription logoutHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded logout commands.", logoutBaseCommand); "View help", "View detailed help pages about AuthMeReloaded logout commands.", LOGOUT_BASE);
logoutHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true)); logoutHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the base register command // Register the base register command
CommandDescription registerBaseCommand = new CommandDescription(new fr.xephi.authme.command.executable.register.RegisterCommand(), new ArrayList<String>() { final CommandDescription REGISTER_BASE = CommandDescription.builder()
{ .parent(null)
add("register"); .labels("register", "reg")
add("reg"); .description("Registration command")
} .detailedDescription("Command to register using AuthMeReloaded.")
}, "Registration command", "Command to register using AuthMeReloaded.", null); .withArgument("password", "Password", false)
registerBaseCommand.setCommandPermissions(PlayerPermission.REGISTER, CommandPermissions.DefaultPermission.ALLOWED); .withArgument("verifyPassword", "Verify password", false)
registerBaseCommand.addArgument(new CommandArgumentDescription("password", "Password", false)); .permissions(ALLOWED, PlayerPermission.REGISTER)
registerBaseCommand.addArgument(new CommandArgumentDescription("verifyPassword", "Verify password", false)); .executableCommand(new fr.xephi.authme.command.executable.register.RegisterCommand())
.build();
// Register the help command // Register the help command
CommandDescription registerHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels, CommandDescription registerHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded register commands.", registerBaseCommand); "View help", "View detailed help pages about AuthMeReloaded register commands.", REGISTER_BASE);
registerHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true)); registerHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the base unregister command // Register the base unregister command
CommandDescription unregisterBaseCommand = new CommandDescription(new fr.xephi.authme.command.executable.unregister.UnregisterCommand(), new ArrayList<String>() { CommandDescription UNREGISTER_BASE = new CommandDescription(new fr.xephi.authme.command.executable.unregister.UnregisterCommand(), new ArrayList<String>() {
{ {
add("unregister"); add("unregister");
add("unreg"); add("unreg");
} }
}, "Unregistration command", "Command to unregister using AuthMeReloaded.", null); }, "Unregistration command", "Command to unregister using AuthMeReloaded.", null);
unregisterBaseCommand.setCommandPermissions(PlayerPermission.UNREGISTER, CommandPermissions.DefaultPermission.ALLOWED); UNREGISTER_BASE.setCommandPermissions(PlayerPermission.UNREGISTER, CommandPermissions.DefaultPermission.ALLOWED);
unregisterBaseCommand.addArgument(new CommandArgumentDescription("password", "Password", false)); UNREGISTER_BASE.addArgument(new CommandArgumentDescription("password", "Password", false));
// Register the help command // Register the help command
CommandDescription unregisterHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels, "View help", "View detailed help pages about AuthMeReloaded unregister commands.", unregisterBaseCommand); CommandDescription unregisterHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels, "View help", "View detailed help pages about AuthMeReloaded unregister commands.", UNREGISTER_BASE);
unregisterHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true)); unregisterHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the base changepassword command // Register the base changepassword command
CommandDescription changePasswordBaseCommand = new CommandDescription(new fr.xephi.authme.command.executable.changepassword.ChangePasswordCommand(), new ArrayList<String>() { final CommandDescription CHANGE_PASSWORD_BASE = new CommandDescription(
new fr.xephi.authme.command.executable.changepassword.ChangePasswordCommand(), new ArrayList<String>() {
{ {
add("changepassword"); add("changepassword");
add("changepass"); add("changepass");
} }
}, "Change password command", "Command to change your password using AuthMeReloaded.", null); }, "Change password command", "Command to change your password using AuthMeReloaded.", null);
changePasswordBaseCommand.setCommandPermissions(PlayerPermission.CHANGE_PASSWORD, CommandPermissions.DefaultPermission.ALLOWED); CHANGE_PASSWORD_BASE.setCommandPermissions(PlayerPermission.CHANGE_PASSWORD, CommandPermissions.DefaultPermission.ALLOWED);
changePasswordBaseCommand.addArgument(new CommandArgumentDescription("password", "Password", false)); CHANGE_PASSWORD_BASE.addArgument(new CommandArgumentDescription("password", "Password", false));
changePasswordBaseCommand.addArgument(new CommandArgumentDescription("verifyPassword", "Verify password", false)); CHANGE_PASSWORD_BASE.addArgument(new CommandArgumentDescription("verifyPassword", "Verify password", false));
// Register the help command // Register the help command
CommandDescription changePasswordHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels, CommandDescription changePasswordHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded change password commands.", changePasswordBaseCommand); "View help", "View detailed help pages about AuthMeReloaded change password commands.", CHANGE_PASSWORD_BASE);
changePasswordHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true)); changePasswordHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the base Dungeon Maze command // Register the base Dungeon Maze command
CommandDescription emailBaseCommand = new CommandDescription(helpCommandExecutable, new ArrayList<String>() { CommandDescription EMAIL_BASE = new CommandDescription(helpCommandExecutable, new ArrayList<String>() {
{ {
add("email"); add("email");
add("mail"); add("mail");
@ -366,7 +381,7 @@ public class CommandManager {
// Register the help command // Register the help command
CommandDescription emailHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels, CommandDescription emailHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded help commands.", emailBaseCommand); "View help", "View detailed help pages about AuthMeReloaded help commands.", EMAIL_BASE);
emailHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true)); emailHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the add command // Register the add command
@ -376,7 +391,7 @@ public class CommandManager {
add("addemail"); add("addemail");
add("addmail"); add("addmail");
} }
}, "Add E-mail", "Add an new E-Mail address to your account.", emailBaseCommand); }, "Add E-mail", "Add an new E-Mail address to your account.", EMAIL_BASE);
addEmailCommand.setCommandPermissions(PlayerPermission.ADD_EMAIL, CommandPermissions.DefaultPermission.ALLOWED); addEmailCommand.setCommandPermissions(PlayerPermission.ADD_EMAIL, CommandPermissions.DefaultPermission.ALLOWED);
addEmailCommand.addArgument(new CommandArgumentDescription("email", "Email address", false)); addEmailCommand.addArgument(new CommandArgumentDescription("email", "Email address", false));
addEmailCommand.addArgument(new CommandArgumentDescription("verifyEmail", "Email address verification", false)); addEmailCommand.addArgument(new CommandArgumentDescription("verifyEmail", "Email address verification", false));
@ -388,7 +403,7 @@ public class CommandManager {
add("changeemail"); add("changeemail");
add("changemail"); add("changemail");
} }
}, "Change E-mail", "Change an E-Mail address of your account.", emailBaseCommand); }, "Change E-mail", "Change an E-Mail address of your account.", EMAIL_BASE);
changeEmailCommand.setCommandPermissions(PlayerPermission.CHANGE_EMAIL, CommandPermissions.DefaultPermission.ALLOWED); changeEmailCommand.setCommandPermissions(PlayerPermission.CHANGE_EMAIL, CommandPermissions.DefaultPermission.ALLOWED);
changeEmailCommand.addArgument(new CommandArgumentDescription("oldEmail", "Old email address", false)); changeEmailCommand.addArgument(new CommandArgumentDescription("oldEmail", "Old email address", false));
changeEmailCommand.addArgument(new CommandArgumentDescription("newEmail", "New email address", false)); changeEmailCommand.addArgument(new CommandArgumentDescription("newEmail", "New email address", false));
@ -401,95 +416,51 @@ public class CommandManager {
add("recoveremail"); add("recoveremail");
add("recovermail"); add("recovermail");
} }
}, "Recover using E-mail", "Recover your account using an E-mail address.", emailBaseCommand); }, "Recover using E-mail", "Recover your account using an E-mail address.", EMAIL_BASE);
recoverEmailCommand.setCommandPermissions(PlayerPermission.RECOVER_EMAIL, CommandPermissions.DefaultPermission.ALLOWED); recoverEmailCommand.setCommandPermissions(PlayerPermission.RECOVER_EMAIL, CommandPermissions.DefaultPermission.ALLOWED);
recoverEmailCommand.addArgument(new CommandArgumentDescription("email", "Email address", false)); recoverEmailCommand.addArgument(new CommandArgumentDescription("email", "Email address", false));
// Register the base captcha command // Register the base captcha command
CommandDescription captchaBaseCommand = new CommandDescription(new CaptchaCommand(), new ArrayList<String>() { CommandDescription CAPTCHA_BASE = new CommandDescription(new CaptchaCommand(), new ArrayList<String>() {
{ {
add("captcha"); add("captcha");
add("capt"); add("capt");
} }
}, "Captcha command", "Captcha command for AuthMeReloaded.", null); }, "Captcha command", "Captcha command for AuthMeReloaded.", null);
captchaBaseCommand.setCommandPermissions(PlayerPermission.CAPTCHA, CommandPermissions.DefaultPermission.ALLOWED); CAPTCHA_BASE.setCommandPermissions(PlayerPermission.CAPTCHA, CommandPermissions.DefaultPermission.ALLOWED);
captchaBaseCommand.addArgument(new CommandArgumentDescription("captcha", "The captcha", false)); CAPTCHA_BASE.addArgument(new CommandArgumentDescription("captcha", "The captcha", false));
// Register the help command // Register the help command
CommandDescription captchaHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels, CommandDescription captchaHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded change captcha commands.", captchaBaseCommand); "View help", "View detailed help pages about AuthMeReloaded change captcha commands.", CAPTCHA_BASE);
captchaHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true)); captchaHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Register the base converter command // Register the base converter command
CommandDescription converterBaseCommand = new CommandDescription(new ConverterCommand(), new ArrayList<String>() { CommandDescription CONVERTER_BASE = new CommandDescription(new ConverterCommand(), new ArrayList<String>() {
{ {
add("converter"); add("converter");
add("convert"); add("convert");
add("conv"); add("conv");
} }
}, "Convert command", "Convert command for AuthMeReloaded.", null); }, "Convert command", "Convert command for AuthMeReloaded.", null);
converterBaseCommand.setCommandPermissions(AdminPermission.CONVERTER, OP_ONLY); CONVERTER_BASE.setCommandPermissions(AdminPermission.CONVERTER, OP_ONLY);
converterBaseCommand.addArgument(new CommandArgumentDescription("job", "Conversion job: flattosql / flattosqlite /| xauth / crazylogin / rakamak / royalauth / vauth / sqltoflat", false)); CONVERTER_BASE.addArgument(new CommandArgumentDescription("job", "Conversion job: flattosql / flattosqlite /| xauth / crazylogin / rakamak / royalauth / vauth / sqltoflat", false));
// Register the help command // Register the help command
CommandDescription converterHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels, CommandDescription converterHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels,
"View help", "View detailed help pages about AuthMeReloaded change captcha commands.", converterBaseCommand); "View help", "View detailed help pages about AuthMeReloaded change captcha commands.", CONVERTER_BASE);
converterHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true)); converterHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true));
// Add the base commands to the commands array // Add the base commands to the commands array
this.commandDescriptions.add(authMeBaseCommand); baseCommands = new HashSet<>(Arrays.asList(
this.commandDescriptions.add(loginBaseCommand); AUTHME_BASE,
this.commandDescriptions.add(logoutBaseCommand); LOGIN_BASE,
this.commandDescriptions.add(registerBaseCommand); LOGOUT_BASE,
this.commandDescriptions.add(unregisterBaseCommand); REGISTER_BASE,
this.commandDescriptions.add(changePasswordBaseCommand); UNREGISTER_BASE,
this.commandDescriptions.add(emailBaseCommand); CHANGE_PASSWORD_BASE,
this.commandDescriptions.add(captchaBaseCommand); EMAIL_BASE,
this.commandDescriptions.add(converterBaseCommand); CAPTCHA_BASE,
} CONVERTER_BASE));
/**
* Get the list of command descriptions
*
* @return List of command descriptions.
*/
public List<CommandDescription> getCommandDescriptions() {
return this.commandDescriptions;
}
/**
* Get the number of command description count.
*
* @return Command description count.
*/
public int getCommandDescriptionCount() {
return this.getCommandDescriptions().size();
}
/**
* 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;
// Get the base command description
for (CommandDescription commandDescription : this.commandDescriptions) {
// 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;
} }
} }

View File

@ -14,12 +14,6 @@ public class CommandParts {
*/ */
private final List<String> parts = new ArrayList<>(); private final List<String> parts = new ArrayList<>();
/**
* Constructor.
*/
public CommandParts() {
}
/** /**
* Constructor. * Constructor.
* *
@ -29,15 +23,6 @@ public class CommandParts {
this.parts.add(part); this.parts.add(part);
} }
/**
* Constructor.
*
* @param commandParts The command parts instance.
*/
public CommandParts(CommandParts commandParts) {
this.parts.addAll(commandParts.getList());
}
/** /**
* Constructor. * Constructor.
* *
@ -47,17 +32,6 @@ public class CommandParts {
this.parts.addAll(parts); this.parts.addAll(parts);
} }
/**
* Constructor.
*
* @param base The base part.
* @param parts The list of additional parts.
*/
public CommandParts(String base, List<String> parts) {
this.parts.add(base);
this.parts.addAll(parts);
}
/** /**
* Get the command parts. * Get the command parts.
* *
@ -67,41 +41,6 @@ public class CommandParts {
return this.parts; return this.parts;
} }
/**
* Add a part.
*
* @param part The part to add.
*
* @return The result.
*/
public boolean add(String part) {
return this.parts.add(part);
}
/**
* Add some parts.
*
* @param parts The parts to add.
*
* @return The result.
*/
public boolean add(List<String> parts) {
return this.parts.addAll(parts);
}
/**
* Add some parts.
*
* @param parts The parts to add.
*
* @return The result.
*/
public boolean add(String[] parts) {
for (String entry : parts)
add(entry);
return true;
}
/** /**
* Get the number of parts. * Get the number of parts.
* *
@ -112,7 +51,7 @@ public class CommandParts {
} }
/** /**
* Get a part by it's index. * Get a part by its index.
* *
* @param i Part index. * @param i Part index.
* *
@ -127,74 +66,6 @@ public class CommandParts {
return this.parts.get(i); return this.parts.get(i);
} }
/**
* Get a range of the parts starting at the specified index up to the end of the range.
*
* @param start The starting index.
*
* @return The parts range. Arguments that were out of bound are not included.
*/
public List<String> getRange(int start) {
return getRange(start, getCount() - start);
}
/**
* Get a range of the parts.
*
* @param start The starting index.
* @param count The number of parts to get.
*
* @return The parts range. Parts that were out of bound are not included.
*/
public List<String> getRange(int start, int count) {
// Create a new list to put the range into
List<String> elements = new ArrayList<>();
// Get the range
for (int i = start; i < start + count; i++) {
// Get the part and add it if it's valid
String element = get(i);
if (element != null)
elements.add(element);
}
// Return the list of parts
return elements;
}
/**
* Get the difference value between two references. This won't do a full compare, just the last reference parts instead.
*
* @param other The other reference.
*
* @return The result from zero to above. A negative number will be returned on error.
*/
public double getDifference(CommandParts other) {
return getDifference(other, false);
}
/**
* Get the difference value between two references.
*
* @param other The other reference.
* @param fullCompare True to compare the full references as far as the range reaches.
*
* @return The result from zero to above. A negative number will be returned on error.
*/
public double getDifference(CommandParts other, boolean fullCompare) {
// Make sure the other reference is correct
if (other == null)
return -1;
// Get the range to use
int range = Math.min(this.getCount(), other.getCount());
// Get and the difference
if (fullCompare)
return StringUtils.getDifference(this.toString(), other.toString());
return StringUtils.getDifference(this.getRange(range - 1, 1).toString(), other.getRange(range - 1, 1).toString());
}
/** /**
* Convert the parts to a string. * Convert the parts to a string.
* *

View File

@ -0,0 +1,58 @@
package fr.xephi.authme.command;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
public final class CommandUtils {
public static int getMinNumberOfArguments(CommandDescription command) {
int mandatoryArguments = 0;
for (CommandArgumentDescription argument : command.getArguments()) {
if (!argument.isOptional()) {
++mandatoryArguments;
}
}
return mandatoryArguments;
}
public static int getMaxNumberOfArguments(CommandDescription command) {
return command.getArguments().size();
}
/**
* 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".
*
* @param labels The labels to format
* @return The space-separated labels
*/
public static String labelsToString(Iterable<String> labels) {
return StringUtils.join(" ", labels);
}
public static double getDifference(List<String> labels1, List<String> labels2, boolean fullCompare) {
// Make sure the other reference is correct
if (labels1 == null || labels2 == null) {
return -1;
}
// Get the range to use
int range = Math.min(labels1.size(), labels2.size());
// Get and the difference
if (fullCompare) {
return StringUtils.getDifference(CommandUtils.labelsToString(labels1), CommandUtils.labelsToString(labels2));
}
return StringUtils.getDifference(
labelsToString(CollectionUtils.getRange(labels1, range - 1, 1)),
labelsToString(CollectionUtils.getRange(labels2, range - 1, 1)));
}
}

View File

@ -61,27 +61,13 @@ public class FoundCommandResult {
return this.commandDescription; return this.commandDescription;
} }
/**
* Set the command description.
*
* @param commandDescription The command description.
*/
public void setCommandDescription(CommandDescription commandDescription) {
this.commandDescription = commandDescription;
}
/** /**
* Check whether the command is executable. * Check whether the command is executable.
* *
* @return True if the command is executable, false otherwise. * @return True if the command is executable, false otherwise.
*/ */
public boolean isExecutable() { public boolean isExecutable() {
// Make sure the command description is valid return commandDescription != null;
if (this.commandDescription == null)
return false;
// Check whether the command is executable, return the result
return this.commandDescription.isExecutable();
} }
/** /**
@ -153,10 +139,11 @@ public class FoundCommandResult {
*/ */
public double getDifference() { public double getDifference() {
// Get the difference through the command found // Get the difference through the command found
if (this.commandDescription != null) if (this.commandDescription != null) {
return this.commandDescription.getCommandDifference(this.queryReference); return this.commandDescription.getCommandDifference(this.queryReference);
}
// Get the difference from the query reference // Get the difference from the query reference
return this.queryReference.getDifference(commandReference, true); return CommandUtils.getDifference(queryReference.getList(), commandReference.getList(), true);
} }
} }

View File

@ -34,7 +34,7 @@ public class ForceLoginCommand extends ExecutableCommand {
sender.sendMessage("You cannot force login for the player " + playerName + "!"); sender.sendMessage("You cannot force login for the player " + playerName + "!");
return true; return true;
} }
plugin.management.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!");

View File

@ -2,11 +2,15 @@ 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.command.CommandParts;
import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
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.List;
/** /**
*/ */
public class SwitchAntiBotCommand extends ExecutableCommand { public class SwitchAntiBotCommand extends ExecutableCommand {
@ -32,16 +36,16 @@ public class SwitchAntiBotCommand extends ExecutableCommand {
} }
// Enable the mod // Enable the mod
if (newState.equalsIgnoreCase("ON")) { if ("ON".equalsIgnoreCase(newState)) {
AntiBot.overrideAntiBotStatus(true); AntiBot.overrideAntiBotStatus(true);
sender.sendMessage("[AuthMe] AntiBot Manual Ovverride: enabled!"); sender.sendMessage("[AuthMe] AntiBot Manual Override: enabled!");
return true; return true;
} }
// Disable the mod // Disable the mod
if (newState.equalsIgnoreCase("OFF")) { if ("OFF".equalsIgnoreCase(newState)) {
AntiBot.overrideAntiBotStatus(false); AntiBot.overrideAntiBotStatus(false);
sender.sendMessage("[AuthMe] AntiBotMod Manual Ovverride: disabled!"); sender.sendMessage("[AuthMe] AntiBotMod Manual Override: disabled!");
return true; return true;
} }
@ -52,8 +56,9 @@ public class SwitchAntiBotCommand extends ExecutableCommand {
HelpProvider.showHelp(sender, commandReference, commandReference, true, false, true, false, false, false); HelpProvider.showHelp(sender, commandReference, commandReference, true, false, true, false, false, false);
// Show the command to use for detailed help // Show the command to use for detailed help
CommandParts helpCommandReference = new CommandParts(commandReference.getRange(1)); List<String> helpCommandReference = CollectionUtils.getRange(commandReference.getList(), 1);
sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + commandReference.get(0) + " help " + helpCommandReference); sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/"
+ commandReference.get(0) + " help " + CommandUtils.labelsToString(helpCommandReference));
return true; return true;
} }
} }

View File

@ -8,6 +8,7 @@ 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.settings.Settings; import fr.xephi.authme.settings.Settings;
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;
@ -30,10 +31,11 @@ public class CaptchaCommand extends ExecutableCommand {
String captcha = commandArguments.get(0); String captcha = commandArguments.get(0);
// AuthMe plugin instance // AuthMe plugin instance
final AuthMe plugin = AuthMe.getInstance(); final Wrapper wrapper = Wrapper.getInstance();
final AuthMe plugin = wrapper.getAuthMe();
// Messages instance // Messages instance
final Messages m = plugin.getMessages(); final Messages m = wrapper.getMessages();
// Command logic // Command logic
if (PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) { if (PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) {

View File

@ -49,7 +49,7 @@ public class UnregisterCommand extends ExecutableCommand {
} }
// Unregister the player // Unregister the player
plugin.management.performUnregister(player, playerPass, false); plugin.getManagement().performUnregister(player, playerPass, false);
return true; return true;
} }
} }

View File

@ -39,9 +39,7 @@ public class HelpPrinter {
* @param command The command to print the description help for. * @param command The command to print the description help for.
*/ */
public static void printCommandDescription(CommandSender sender, CommandDescription command) { public static void printCommandDescription(CommandSender sender, CommandDescription command) {
// Print the regular description, if available sender.sendMessage(ChatColor.GOLD + "Short Description: " + ChatColor.WHITE + command.getDescription());
if (command.hasDescription())
sender.sendMessage(ChatColor.GOLD + "Short Description: " + ChatColor.WHITE + command.getDescription());
// Print the detailed description, if available // Print the detailed description, if available
if (!StringUtils.isEmpty(command.getDetailedDescription())) { if (!StringUtils.isEmpty(command.getDetailedDescription())) {
@ -59,7 +57,7 @@ public class HelpPrinter {
@SuppressWarnings("StringConcatenationInsideStringBufferAppend") @SuppressWarnings("StringConcatenationInsideStringBufferAppend")
public static void printArguments(CommandSender sender, CommandDescription command) { public static void printArguments(CommandSender sender, CommandDescription command) {
// Make sure there are any commands to print // Make sure there are any commands to print
if (!command.hasArguments() && command.getMaximumArguments() >= 0) if (!command.hasArguments())
return; return;
// Print the header // Print the header
@ -78,10 +76,6 @@ public class HelpPrinter {
// Print the syntax // Print the syntax
sender.sendMessage(argString.toString()); sender.sendMessage(argString.toString());
} }
// Show the unlimited arguments argument
if (command.getMaximumArguments() < 0)
sender.sendMessage(" " + ChatColor.YELLOW + ChatColor.ITALIC + "... : " + ChatColor.WHITE + "Any additional arguments." + ChatColor.GRAY + ChatColor.ITALIC + " (Optional)");
} }
/** /**

View File

@ -3,12 +3,17 @@ package fr.xephi.authme.command.help;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandDescription;
import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.CommandUtils;
import fr.xephi.authme.command.FoundCommandResult; import fr.xephi.authme.command.FoundCommandResult;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
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.ArrayList;
import java.util.List;
/** /**
*/ */
public class HelpProvider { public class HelpProvider {
@ -39,9 +44,14 @@ public class HelpProvider {
*/ */
public static void showHelp(CommandSender sender, CommandParts reference, CommandParts helpQuery, boolean showCommand, boolean showDescription, boolean showArguments, boolean showPermissions, boolean showAlternatives, boolean showCommands) { 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 // Find the command for this help query, one with and one without a prefixed base command
FoundCommandResult result = AuthMe.getInstance().getCommandHandler().getCommandManager().findCommand(new CommandParts(helpQuery.getList())); FoundCommandResult result = AuthMe.getInstance().getCommandHandler().findCommand(new CommandParts(helpQuery.getList()));
CommandParts commandReferenceOther = new CommandParts(reference.get(0), helpQuery.getList());
FoundCommandResult resultOther = AuthMe.getInstance().getCommandHandler().getCommandManager().findCommand(commandReferenceOther); // TODO ljacqu 20151204 Fix me to nicer code
List<String> parts = new ArrayList<>(helpQuery.getList());
parts.add(0, reference.get(0));
CommandParts commandReferenceOther = new CommandParts(parts);
FoundCommandResult resultOther = AuthMe.getInstance().getCommandHandler().findCommand(commandReferenceOther);
if (resultOther != null) { if (resultOther != null) {
if (result == null) if (result == null)
result = resultOther; result = resultOther;
@ -78,13 +88,14 @@ public class HelpProvider {
// Show the unknown command warning // Show the unknown command warning
sender.sendMessage(ChatColor.DARK_RED + "No help found for '" + helpQuery + "'!"); sender.sendMessage(ChatColor.DARK_RED + "No help found for '" + helpQuery + "'!");
// Get the suggested command
CommandParts suggestedCommandParts = new CommandParts(result.getCommandDescription().getCommandReference(commandReference).getRange(1));
// 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 < 0.75) if (commandDifference < 0.75 && result.getCommandDescription() != null) {
if (result.getCommandDescription() != null) // Get the suggested command
sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/" + baseCommand + " help " + suggestedCommandParts + ChatColor.YELLOW + "?"); 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 + "?");
}
// Show the help command // Show the help command
sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help" + ChatColor.YELLOW + " to view help."); sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help" + ChatColor.YELLOW + " to view help.");
@ -94,10 +105,12 @@ public class HelpProvider {
// Show a message when the command handler is assuming a command // Show a message when the command handler is assuming a command
if (commandDifference > 0) { if (commandDifference > 0) {
// Get the suggested command // Get the suggested command
CommandParts suggestedCommandParts = new CommandParts(result.getCommandDescription().getCommandReference(commandReference).getRange(1)); List<String> suggestedCommandParts = CollectionUtils.getRange(
result.getCommandDescription().getCommandReference(commandReference).getList(), 1);
// Show the suggested command // Show the suggested command
sender.sendMessage(ChatColor.DARK_RED + "No help found, assuming '" + ChatColor.GOLD + suggestedCommandParts + ChatColor.DARK_RED + "'!"); sender.sendMessage(ChatColor.DARK_RED + "No help found, assuming '" + ChatColor.GOLD
+ CommandUtils.labelsToString(suggestedCommandParts) + ChatColor.DARK_RED + "'!");
} }
// Print the help header // Print the help header

View File

@ -3,6 +3,8 @@ package fr.xephi.authme.command.help;
import fr.xephi.authme.command.CommandArgumentDescription; 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.CommandParts;
import fr.xephi.authme.command.CommandUtils;
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;
@ -35,8 +37,8 @@ public final class HelpSyntaxHelper {
// Get the help command reference, and the command label // Get the help command reference, and the command label
CommandParts helpCommandReference = commandDescription.getCommandReference(commandReference); CommandParts helpCommandReference = commandDescription.getCommandReference(commandReference);
final String parentCommand = new CommandParts( final String parentCommand = CommandUtils.labelsToString(
helpCommandReference.getRange(0, helpCommandReference.getCount() - 1)).toString(); CollectionUtils.getRange(helpCommandReference.getList(), 0, helpCommandReference.getCount() - 1));
// Check whether the alternative label should be used // Check whether the alternative label should be used
String commandLabel; String commandLabel;
@ -61,11 +63,6 @@ public final class HelpSyntaxHelper {
sb.append(ChatColor.ITALIC).append(formatArgument(arg)); sb.append(ChatColor.ITALIC).append(formatArgument(arg));
} }
// Add some dots if the command allows unlimited arguments
if (commandDescription.getMaximumArguments() < 0) {
sb.append(ChatColor.ITALIC).append(" ...");
}
// Return the build command syntax // Return the build command syntax
return sb.toString(); return sb.toString();
} }

View File

@ -321,7 +321,7 @@ public class AuthMePlayerListener implements Listener {
event.setQuitMessage(null); event.setQuitMessage(null);
} }
plugin.management.performQuit(player, false); plugin.getManagement().performQuit(player, false);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
@ -337,7 +337,7 @@ public class AuthMePlayerListener implements Listener {
} }
Player player = event.getPlayer(); Player player = event.getPlayer();
plugin.management.performQuit(player, true); plugin.getManagement().performQuit(player, true);
} }
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)

View File

@ -21,7 +21,7 @@ public class Log4JFilter implements Filter {
} }
/** /**
* Validate a Message instance and return the {@link Result} value * Validates a Message instance and returns the {@link Result} value
* depending on whether the message contains sensitive AuthMe data. * depending on whether the message contains sensitive AuthMe data.
* *
* @param message The Message object to verify * @param message The Message object to verify
@ -36,7 +36,7 @@ public class Log4JFilter implements Filter {
} }
/** /**
* Validate a message and return the {@link Result} value depending * Validates a message and returns the {@link Result} value depending
* on whether the message contains sensitive AuthMe data. * on whether the message contains sensitive AuthMe data.
* *
* @param message The message to verify * @param message The message to verify

View File

@ -260,6 +260,7 @@ public class PermissionsManager {
* *
* @param event Event instance. * @param event Event instance.
*/ */
// TODO ljacqu 20151129: Misleading name since onPluginEnable is a typical event-based method name
public void onPluginEnable(PluginEnableEvent event) { public void onPluginEnable(PluginEnableEvent event) {
// Get the plugin and it's name // Get the plugin and it's name
Plugin plugin = event.getPlugin(); Plugin plugin = event.getPlugin();

View File

@ -221,7 +221,7 @@ public class AsynchronousJoin {
PlayerCache.getInstance().removePlayer(name); PlayerCache.getInstance().removePlayer(name);
if (auth != null && auth.getIp().equals(ip)) { if (auth != null && auth.getIp().equals(ip)) {
m.send(player, MessageKey.SESSION_RECONNECTION); m.send(player, MessageKey.SESSION_RECONNECTION);
plugin.management.performLogin(player, "dontneed", true); plugin.getManagement().performLogin(player, "dontneed", true);
return; return;
} else if (Settings.sessionExpireOnIpChange) { } else if (Settings.sessionExpireOnIpChange) {
m.send(player, MessageKey.SESSION_EXPIRED); m.send(player, MessageKey.SESSION_EXPIRED);

View File

@ -0,0 +1,47 @@
package fr.xephi.authme.util;
import java.util.ArrayList;
import java.util.List;
/**
* Utils class for collections.
*/
public final class CollectionUtils {
private CollectionUtils() {
}
/**
* Get a range from a list based on start and count parameters in a safe way.
*
* @param start The start index
* @param count The number of elements to add
*
* @return The sublist consisting at most of {@code count} elements (less if the parameters
* exceed the size of the list)
*/
public static List<String> getRange(List<String> list, int start, int count) {
if (start >= list.size() || count <= 0) {
return new ArrayList<>();
} else if (start < 0) {
start = 0;
}
int end = Math.min(list.size(), start + count);
return list.subList(start, end);
}
/**
* Get all elements from a list starting from the given index.
*
* @param start The start index
*
* @return The sublist of all elements from index {@code start} and on; empty list
* if the start index exceeds the list's size
*/
public static List<String> getRange(List<String> list, int start) {
if (start >= list.size()) {
return new ArrayList<>();
}
return getRange(list, start, list.size() - start);
}
}

View File

@ -13,8 +13,6 @@ import java.util.Arrays;
*/ */
public final class StringUtils { public final class StringUtils {
public static final String newline = System.getProperty("line.separator");
private StringUtils() { private StringUtils() {
// Utility class // Utility class
} }
@ -29,8 +27,9 @@ public final class StringUtils {
*/ */
public static double getDifference(String first, String second) { public static double getDifference(String first, String second) {
// Make sure the strings are valid. // Make sure the strings are valid.
if (first == null || second == null) if (first == null || second == null) {
return 1.0; return 1.0;
}
// Create a string similarity service instance, to allow comparison // Create a string similarity service instance, to allow comparison
StringSimilarityService service = new StringSimilarityServiceImpl(new LevenshteinDistanceStrategy()); StringSimilarityService service = new StringSimilarityServiceImpl(new LevenshteinDistanceStrategy());

View File

@ -0,0 +1,133 @@
package fr.xephi.authme.command;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.util.WrapperMock;
import org.bukkit.command.CommandSender;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
* Test for {@link CommandHandler}.
*/
public class CommandHandlerTest {
private static Set<CommandDescription> commands;
private static CommandHandler handler;
@BeforeClass
public static void setUpCommandHandler() {
WrapperMock.createInstance();
CommandDescription authMeBase = createCommand(null, null, singletonList("authme"));
createCommand(PlayerPermission.LOGIN, authMeBase, singletonList("login"), newArgument("password", false));
createCommand(PlayerPermission.LOGIN, authMeBase, asList("register", "reg"),
newArgument("password", false), newArgument("confirmation", false));
CommandDescription testBase = createCommand(null, null, singletonList("test"), newArgument("test", true));
commands = new HashSet<>(asList(authMeBase, testBase));
handler = new CommandHandler(commands);
}
@Test
public void shouldForwardCommandToExecutable() {
// given
CommandSender sender = Mockito.mock(CommandSender.class);
given(sender.isOp()).willReturn(true);
String bukkitLabel = "authme";
String[] args = {"login", "password"};
// when
handler.processCommand(sender, bukkitLabel, args);
// then
final CommandDescription loginCmd = getChildWithLabel("login", getCommandWithLabel("authme", commands));
verify(sender, never()).sendMessage(anyString());
verify(loginCmd.getExecutableCommand()).executeCommand(
eq(sender), any(CommandParts.class), any(CommandParts.class));
}
@Test
@Ignore // TODO ljacqu Fix test --> command classes too tightly coupled at the moment
public void shouldRejectCommandWithTooManyArguments() {
// given
CommandSender sender = Mockito.mock(CommandSender.class);
given(sender.isOp()).willReturn(true);
String bukkitLabel = "authme";
String[] args = {"login", "password", "__unneededArgument__"};
// when
boolean result = handler.processCommand(sender, bukkitLabel, args);
// then
assertThat(result, equalTo(true));
assertSenderGotMessageContaining("help", sender);
}
private static CommandDescription createCommand(PlayerPermission permission, CommandDescription parent,
List<String> labels, CommandArgumentDescription... arguments) {
CommandDescription.CommandBuilder command = CommandDescription.builder()
.labels(labels)
.parent(parent)
.permissions(CommandPermissions.DefaultPermission.OP_ONLY, permission)
.description("Test")
.detailedDescription("Test command")
.executableCommand(mock(ExecutableCommand.class));
if (arguments != null && arguments.length > 0) {
for (CommandArgumentDescription argument : arguments) {
command.withArgument(argument.getLabel(), "Test description", argument.isOptional());
}
}
return command.build();
}
private static CommandArgumentDescription newArgument(String label, boolean isOptional) {
return new CommandArgumentDescription(label, "Test description", isOptional);
}
private void assertSenderGotMessageContaining(String text, CommandSender sender) {
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(sender).sendMessage(captor.capture());
assertThat(captor.getValue(), stringContainsInOrder(text));
}
private static CommandDescription getCommandWithLabel(String label, Collection<CommandDescription> commands) {
for (CommandDescription command : commands) {
if (command.getLabels().contains(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 null;
}
}

View File

@ -1,15 +1,12 @@
package fr.xephi.authme.command; package fr.xephi.authme.command;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.WrapperMock;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap; import java.util.regex.Pattern;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
@ -18,9 +15,9 @@ import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
/** /**
* Test for {@link CommandManager}, especially to guarantee the integrity of the defined commands. * Test for {@link CommandInitializer} to guarantee the integrity of the defined commands.
*/ */
public class CommandManagerTest { public class CommandInitializerTest {
/** /**
* Defines the maximum allowed depths for nesting CommandDescription instances. * Defines the maximum allowed depths for nesting CommandDescription instances.
@ -28,24 +25,21 @@ public class CommandManagerTest {
*/ */
private static int MAX_ALLOWED_DEPTH = 1; private static int MAX_ALLOWED_DEPTH = 1;
private static CommandManager manager; private static Set<CommandDescription> commands;
@BeforeClass @BeforeClass
public static void initializeCommandManager() { public static void initializeCommandManager() {
manager = new CommandManager(true); WrapperMock.createInstance();
commands = CommandInitializer.getBaseCommands();
} }
@Test @Test
public void shouldInitializeCommands() { public void shouldInitializeCommands() {
// given/when // given/when/then
int commandCount = manager.getCommandDescriptionCount();
List<CommandDescription> commands = manager.getCommandDescriptions();
// then
// It obviously doesn't make sense to test much of the concrete data // It obviously doesn't make sense to test much of the concrete data
// that is being initialized; we just want to guarantee with this test // that is being initialized; we just want to guarantee with this test
// that data is indeed being initialized and we take a few "probes" // that data is indeed being initialized and we take a few "probes"
assertThat(commandCount, equalTo(9)); assertThat(commands.size(), equalTo(9));
assertThat(commandsIncludeLabel(commands, "authme"), equalTo(true)); assertThat(commandsIncludeLabel(commands, "authme"), equalTo(true));
assertThat(commandsIncludeLabel(commands, "register"), equalTo(true)); assertThat(commandsIncludeLabel(commands, "register"), equalTo(true));
assertThat(commandsIncludeLabel(commands, "help"), equalTo(false)); assertThat(commandsIncludeLabel(commands, "help"), equalTo(false));
@ -62,7 +56,7 @@ public class CommandManagerTest {
}; };
// when/then // when/then
walkThroughCommands(manager.getCommandDescriptions(), descriptionTester); walkThroughCommands(commands, descriptionTester);
} }
/** Ensure that all children of a command stored the parent. */ /** Ensure that all children of a command stored the parent. */
@ -84,7 +78,28 @@ public class CommandManagerTest {
}; };
// when/then // when/then
walkThroughCommands(manager.getCommandDescriptions(), connectionTester); walkThroughCommands(commands, connectionTester);
}
@Test
public void shouldUseProperLowerCaseLabels() {
// given
final Pattern invalidPattern = Pattern.compile("\\s");
BiConsumer labelFormatTester = new BiConsumer() {
@Override
public void accept(CommandDescription command, int depth) {
for (String label : command.getLabels()) {
if (!label.equals(label.toLowerCase())) {
fail("Label '" + label + "' should be lowercase");
} else if (invalidPattern.matcher(label).matches()) {
fail("Label '" + label + "' has whitespace");
}
}
}
};
// when/then
walkThroughCommands(commands, labelFormatTester);
} }
@Test @Test
@ -105,7 +120,7 @@ public class CommandManagerTest {
}; };
// when/then // when/then
walkThroughCommands(manager.getCommandDescriptions(), uniqueMappingTester); walkThroughCommands(commands, uniqueMappingTester);
} }
/** /**
@ -132,7 +147,7 @@ public class CommandManagerTest {
}; };
// when/then // when/then
walkThroughCommands(manager.getCommandDescriptions(), descriptionTester); walkThroughCommands(commands, descriptionTester);
} }
/** /**
@ -143,7 +158,6 @@ public class CommandManagerTest {
public void shouldNotHaveMultipleInstancesOfSameExecutableCommandSubType() { public void shouldNotHaveMultipleInstancesOfSameExecutableCommandSubType() {
// given // given
final Map<Class<? extends ExecutableCommand>, ExecutableCommand> implementations = new HashMap<>(); final Map<Class<? extends ExecutableCommand>, ExecutableCommand> implementations = new HashMap<>();
CommandManager manager = new CommandManager(true);
BiConsumer descriptionTester = new BiConsumer() { BiConsumer descriptionTester = new BiConsumer() {
@Override @Override
public void accept(CommandDescription command, int depth) { public void accept(CommandDescription command, int depth) {
@ -160,10 +174,7 @@ public class CommandManagerTest {
} }
}; };
// when // when/then
List<CommandDescription> commands = manager.getCommandDescriptions();
// then
walkThroughCommands(commands, descriptionTester); walkThroughCommands(commands, descriptionTester);
} }
@ -186,7 +197,7 @@ public class CommandManagerTest {
}; };
// when/then // when/then
walkThroughCommands(manager.getCommandDescriptions(), argumentOrderTester); walkThroughCommands(commands, argumentOrderTester);
} }
/** /**
@ -209,18 +220,18 @@ public class CommandManagerTest {
}; };
// when/then // when/then
walkThroughCommands(manager.getCommandDescriptions(), noArgumentForParentChecker); walkThroughCommands(commands, noArgumentForParentChecker);
} }
// ------------ // ------------
// Helper methods // Helper methods
// ------------ // ------------
private static void walkThroughCommands(List<CommandDescription> commands, BiConsumer consumer) { private static void walkThroughCommands(Collection<CommandDescription> commands, BiConsumer consumer) {
walkThroughCommands(commands, consumer, 0); walkThroughCommands(commands, consumer, 0);
} }
private static void walkThroughCommands(List<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.hasChildren()) {
@ -243,12 +254,12 @@ public class CommandManagerTest {
} }
/** /**
* Get the absolute label that a command defines. Note: Assumes that only the passed command might have * Get the absolute binding that a command defines. Note: Assumes that only the passed command can have
* multiple labels; only considering the first label for all of the command's parents. * multiple labels; only considering the first label for all of the command's parents.
* *
* @param command The command to verify * @param command The command to process
* *
* @return The full command binding * @return List of all bindings that lead to the command
*/ */
private static List<String> getAbsoluteLabels(CommandDescription command) { private static List<String> getAbsoluteLabels(CommandDescription command) {
String parentPath = ""; String parentPath = "";

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 static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
@ -27,7 +28,7 @@ public class CommandPartsTest {
@Test @Test
public void shouldPrintEmptyStringForNoArguments() { public void shouldPrintEmptyStringForNoArguments() {
// given // given
CommandParts parts = new CommandParts(); CommandParts parts = new CommandParts(Collections.EMPTY_LIST);
// when // when
String str = parts.toString(); String str = parts.toString();

View File

@ -0,0 +1,73 @@
package fr.xephi.authme.command.executable.captcha;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandParts;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.util.WrapperMock;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.Collections;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* Test for {@link CaptchaCommand}.
*/
public class CaptchaCommandTest {
private WrapperMock wrapperMock;
@Before
public void setUpWrapperMock() {
wrapperMock = WrapperMock.createInstance();
Settings.useCaptcha = true;
}
@Test
public void shouldRejectNonPlayerSender() {
// given
CommandSender sender = Mockito.mock(BlockCommandSender.class);
ExecutableCommand command = new CaptchaCommand();
// when
boolean result = command.executeCommand(sender, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST));
// then
assertThat(result, equalTo(true));
assertThat(wrapperMock.wasMockCalled(AuthMe.class), equalTo(false));
assertThat(wrapperMock.wasMockCalled(Messages.class), equalTo(false));
}
@Test
@Ignore
public void shouldRejectIfCaptchaIsNotUsed() {
// given
Player player = mockPlayerWithName("testplayer");
ExecutableCommand command = new CaptchaCommand();
// when
boolean result = command.executeCommand(player, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST));
// then
assertThat(result, equalTo(true));
verify(wrapperMock.getMessages()).send(player, MessageKey.USAGE_LOGIN);
}
private static Player mockPlayerWithName(String name) {
Player player = Mockito.mock(Player.class);
when(player.getName()).thenReturn(name);
return player;
}
}

View File

@ -18,6 +18,7 @@ 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;
@ -58,7 +59,7 @@ public class ChangePasswordCommandTest {
CommandParts arguments = mock(CommandParts.class); CommandParts arguments = mock(CommandParts.class);
// when // when
command.executeCommand(sender, new CommandParts(), arguments); command.executeCommand(sender, newParts(), arguments);
// then // then
verify(arguments, never()).get(anyInt()); verify(arguments, never()).get(anyInt());
@ -72,7 +73,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("pass")); command.executeCommand(sender, newParts(), new CommandParts("pass"));
// then // then
verify(messagesMock).send(sender, MessageKey.NOT_LOGGED_IN); verify(messagesMock).send(sender, MessageKey.NOT_LOGGED_IN);
@ -86,7 +87,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
// when // when
command.executeCommand(sender, new CommandParts(), newParts("old123", "!pass")); command.executeCommand(sender, newParts(), newParts("old123", "!pass"));
// then // then
verify(messagesMock).send(sender, MessageKey.PASSWORD_MATCH_ERROR); verify(messagesMock).send(sender, MessageKey.PASSWORD_MATCH_ERROR);
@ -101,7 +102,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
// when // when
command.executeCommand(sender, new CommandParts(), newParts("old_", "Tester")); command.executeCommand(sender, newParts(), newParts("old_", "Tester"));
// then // then
verify(messagesMock).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); verify(messagesMock).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
@ -116,7 +117,7 @@ public class ChangePasswordCommandTest {
Settings.passwordMaxLength = 3; Settings.passwordMaxLength = 3;
// when // when
command.executeCommand(sender, new CommandParts(), newParts("12", "test")); command.executeCommand(sender, newParts(), newParts("12", "test"));
// then // then
verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH); verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
@ -131,7 +132,7 @@ public class ChangePasswordCommandTest {
Settings.getPasswordMinLen = 7; Settings.getPasswordMinLen = 7;
// when // when
command.executeCommand(sender, new CommandParts(), newParts("oldverylongpassword", "tester")); command.executeCommand(sender, newParts(), newParts("oldverylongpassword", "tester"));
// then // then
verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH); verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
@ -146,7 +147,7 @@ public class ChangePasswordCommandTest {
Settings.unsafePasswords = asList("test", "abc123"); Settings.unsafePasswords = asList("test", "abc123");
// when // when
command.executeCommand(sender, new CommandParts(), newParts("oldpw", "abc123")); command.executeCommand(sender, newParts(), newParts("oldpw", "abc123"));
// then // then
verify(messagesMock).send(sender, MessageKey.PASSWORD_UNSAFE_ERROR); verify(messagesMock).send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
@ -160,7 +161,7 @@ public class ChangePasswordCommandTest {
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
// when // when
command.executeCommand(sender, new CommandParts(), newParts("abc123", "abc123")); command.executeCommand(sender, newParts(), newParts("abc123", "abc123"));
// then // then
verify(messagesMock, never()).send(eq(sender), any(MessageKey.class)); verify(messagesMock, never()).send(eq(sender), any(MessageKey.class));

View File

@ -11,6 +11,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
@ -40,7 +41,7 @@ public class AddEmailCommandTest {
AddEmailCommand command = new AddEmailCommand(); AddEmailCommand command = new AddEmailCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, newParts(), newParts());
// then // then
verify(authMeMock, never()).getManagement(); verify(authMeMock, never()).getManagement();
@ -53,11 +54,15 @@ public class AddEmailCommandTest {
AddEmailCommand command = new AddEmailCommand(); AddEmailCommand command = new AddEmailCommand();
// when // when
command.executeCommand(sender, new CommandParts(), command.executeCommand(sender, newParts(),
new CommandParts(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

@ -11,6 +11,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
@ -40,7 +41,7 @@ public class ChangeEmailCommandTest {
ChangeEmailCommand command = new ChangeEmailCommand(); ChangeEmailCommand command = new ChangeEmailCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, newParts(), newParts());
// then // then
verify(authMeMock, never()).getManagement(); verify(authMeMock, never()).getManagement();
@ -53,11 +54,15 @@ public class ChangeEmailCommandTest {
ChangeEmailCommand command = new ChangeEmailCommand(); ChangeEmailCommand command = new ChangeEmailCommand();
// when // when
command.executeCommand(sender, new CommandParts(), command.executeCommand(sender, newParts(),
new CommandParts(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

@ -9,6 +9,8 @@ import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.Collections;
/** /**
* Test for {@link RecoverEmailCommand}. * Test for {@link RecoverEmailCommand}.
*/ */
@ -27,7 +29,7 @@ public class RecoverEmailCommandTest {
RecoverEmailCommand command = new RecoverEmailCommand(); RecoverEmailCommand command = new RecoverEmailCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST));
// then // then
} }

View File

@ -11,6 +11,8 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList;
import static org.mockito.Matchers.*; import static org.mockito.Matchers.*;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
@ -38,7 +40,7 @@ public class LoginCommandTest {
LoginCommand command = new LoginCommand(); LoginCommand command = new LoginCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, newParts(), newParts());
// then // then
Mockito.verify(managementMock, never()).performLogin(any(Player.class), anyString(), anyBoolean()); Mockito.verify(managementMock, never()).performLogin(any(Player.class), anyString(), anyBoolean());
@ -51,7 +53,7 @@ public class LoginCommandTest {
LoginCommand command = new LoginCommand(); LoginCommand command = new LoginCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("password")); command.executeCommand(sender, newParts(), new CommandParts("password"));
// then // then
Mockito.verify(managementMock).performLogin(eq(sender), eq("password"), eq(false)); Mockito.verify(managementMock).performLogin(eq(sender), eq("password"), eq(false));
@ -64,11 +66,15 @@ public class LoginCommandTest {
LoginCommand command = new LoginCommand(); LoginCommand command = new LoginCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, newParts(), newParts());
// then // then
// TODO ljacqu 20151121: May make sense to handle null password in LoginCommand instead of forwarding the call // TODO ljacqu 20151121: May make sense to handle null password in LoginCommand instead of forwarding the call
String password = null; String password = null;
Mockito.verify(managementMock).performLogin(eq(sender), eq(password), eq(false)); Mockito.verify(managementMock).performLogin(eq(sender), eq(password), eq(false));
} }
private static CommandParts newParts() {
return new CommandParts(new ArrayList<String>());
}
} }

View File

@ -12,6 +12,8 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
@ -40,7 +42,7 @@ public class LogoutCommandTest {
LogoutCommand command = new LogoutCommand(); LogoutCommand command = new LogoutCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, new CommandParts(new ArrayList<String>()), new CommandParts(new ArrayList<String>()));
// then // then
Mockito.verify(managementMock, never()).performLogout(any(Player.class)); Mockito.verify(managementMock, never()).performLogout(any(Player.class));
@ -53,7 +55,7 @@ public class LogoutCommandTest {
LogoutCommand command = new LogoutCommand(); LogoutCommand command = new LogoutCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("password")); command.executeCommand(sender, new CommandParts(new ArrayList<String>()), new CommandParts("password"));
// then // then
Mockito.verify(managementMock).performLogout(sender); Mockito.verify(managementMock).performLogout(sender);

View File

@ -14,6 +14,8 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Mockito; import org.mockito.Mockito;
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;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
@ -48,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, new CommandParts(), new CommandParts()); command.executeCommand(sender, newParts(), newParts());
// then // then
verify(sender).sendMessage(messageCaptor.capture()); verify(sender).sendMessage(messageCaptor.capture());
@ -63,7 +65,7 @@ public class RegisterCommandTest {
RegisterCommand command = new RegisterCommand(); RegisterCommand command = new RegisterCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts()); command.executeCommand(sender, newParts(), newParts());
// then // then
verify(messagesMock).send(sender, MessageKey.USAGE_REGISTER); verify(messagesMock).send(sender, MessageKey.USAGE_REGISTER);
@ -77,9 +79,13 @@ public class RegisterCommandTest {
RegisterCommand command = new RegisterCommand(); RegisterCommand command = new RegisterCommand();
// when // when
command.executeCommand(sender, new CommandParts(), new CommandParts("password")); command.executeCommand(sender, newParts(), new CommandParts("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

@ -7,6 +7,8 @@ import fr.xephi.authme.command.executable.authme.RegisterCommand;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.ArrayList;
import static org.bukkit.ChatColor.BOLD; import static org.bukkit.ChatColor.BOLD;
import static org.bukkit.ChatColor.ITALIC; import static org.bukkit.ChatColor.ITALIC;
import static org.bukkit.ChatColor.WHITE; import static org.bukkit.ChatColor.WHITE;
@ -27,8 +29,7 @@ public class HelpSyntaxHelperTest {
.build(); .build();
// when // when
String result = HelpSyntaxHelper.getCommandSyntax( String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", false);
description, new CommandParts(), "", false);
// then // then
assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]")); assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]"));
@ -42,8 +43,7 @@ public class HelpSyntaxHelperTest {
.build(); .build();
// when // when
String result = HelpSyntaxHelper.getCommandSyntax( String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), null, false);
description, new CommandParts(), null, false);
// then // then
assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " <test>")); assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " <test>"));
@ -58,8 +58,7 @@ public class HelpSyntaxHelperTest {
.build(); .build();
// when // when
String result = HelpSyntaxHelper.getCommandSyntax( String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", false);
description, new CommandParts(), "", false);
// then // then
assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]" + ITALIC + " <test>")); assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]" + ITALIC + " <test>"));
@ -74,8 +73,7 @@ public class HelpSyntaxHelperTest {
.build(); .build();
// when // when
String result = HelpSyntaxHelper.getCommandSyntax( String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", true);
description, new CommandParts(), "", true);
// then // then
assertThat(result, equalTo(WHITE + "/authme " assertThat(result, equalTo(WHITE + "/authme "
@ -89,8 +87,7 @@ public class HelpSyntaxHelperTest {
CommandDescription description = getDescriptionBuilder().build(); CommandDescription description = getDescriptionBuilder().build();
// when // when
String result = HelpSyntaxHelper.getCommandSyntax( String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), null, true);
description, new CommandParts(), null, true);
// then // then
assertThat(result, equalTo(WHITE + "/authme " + YELLOW + BOLD + "register" + YELLOW)); assertThat(result, equalTo(WHITE + "/authme " + YELLOW + BOLD + "register" + YELLOW));
@ -104,33 +101,17 @@ public class HelpSyntaxHelperTest {
.build(); .build();
// when // when
String result = HelpSyntaxHelper.getCommandSyntax( String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "alt", false);
description, new CommandParts(), "alt", false);
// then // then
assertThat(result, equalTo(WHITE + "/authme alt" + ITALIC + " [name]")); assertThat(result, equalTo(WHITE + "/authme alt" + ITALIC + " [name]"));
} }
@Test private static CommandParts newParts() {
public void shouldHighlightCommandWithAltLabelAndUnlimitedArguments() { // TODO ljacqu 20151204: Remove this method once CommandParts has been removed
// given return new CommandParts(new ArrayList<String>());
CommandDescription description = getDescriptionBuilder()
.withArgument("name", "", true)
.withArgument("test", "", false)
.noArgumentMaximum(true)
.build();
// when
String result = HelpSyntaxHelper.getCommandSyntax(
description, new CommandParts(), "test", true);
// then
assertThat(result, equalTo(WHITE + "/authme "
+ YELLOW + BOLD + "test"
+ YELLOW + ITALIC + " [name]" + ITALIC + " <test>" + ITALIC + " ..."));
} }
private static CommandDescription.CommandBuilder getDescriptionBuilder() { private static CommandDescription.CommandBuilder getDescriptionBuilder() {
CommandDescription base = CommandDescription.builder() CommandDescription base = CommandDescription.builder()
.labels("authme") .labels("authme")

View File

@ -0,0 +1,102 @@
package fr.xephi.authme.util;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.empty;
/**
* Test for {@link CollectionUtils}.
*/
public class CollectionUtilsTest {
@Test
public void shouldGetFullList() {
// given
List<String> list = Arrays.asList("test", "1", "2", "3", "4");
// when
List<String> result = CollectionUtils.getRange(list, 0, 24);
// then
assertThat(result, equalTo(list));
}
@Test
public void shouldReturnEmptyListForZeroCount() {
// given
List<String> list = Arrays.asList("test", "1", "2", "3", "4");
// when
List<String> result = CollectionUtils.getRange(list, 2, 0);
// then
assertThat(result, empty());
}
@Test
public void shouldReturnEmptyListForTooHighStart() {
// given
List<String> list = Arrays.asList("test", "1", "2", "3", "4");
// when
List<String> result = CollectionUtils.getRange(list, 12, 2);
// then
assertThat(result, empty());
}
@Test
public void shouldReturnSubList() {
// given
List<String> list = Arrays.asList("test", "1", "2", "3", "4");
// when
List<String> result = CollectionUtils.getRange(list, 1, 3);
// then
assertThat(result, contains("1", "2", "3"));
}
@Test
public void shouldReturnTillEnd() {
// given
List<String> list = Arrays.asList("test", "1", "2", "3", "4");
// when
List<String> result = CollectionUtils.getRange(list, 2, 3);
// then
assertThat(result, contains("2", "3", "4"));
}
@Test
public void shouldRemoveFirstTwo() {
// given
List<String> list = Arrays.asList("test", "1", "2", "3", "4");
// when
List<String> result = CollectionUtils.getRange(list, 2);
// then
assertThat(result, contains("2", "3", "4"));
}
@Test
public void shouldHandleNegativeStart() {
// given
List<String> list = Arrays.asList("test", "1", "2", "3", "4");
// when
List<String> result = CollectionUtils.getRange(list, -4);
// then
assertThat(result, equalTo(list));
}
}