From 7f049616c684df1b7a8c536c77eeebd96d19342f Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 21 Nov 2015 20:06:31 +0100 Subject: [PATCH 01/82] Attempt to fix dubious isUuidInstance in vAuthFileReader --- .../fr/xephi/authme/converter/vAuthFileReader.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/main/java/fr/xephi/authme/converter/vAuthFileReader.java b/src/main/java/fr/xephi/authme/converter/vAuthFileReader.java index 8a899acdf..5702d7006 100644 --- a/src/main/java/fr/xephi/authme/converter/vAuthFileReader.java +++ b/src/main/java/fr/xephi/authme/converter/vAuthFileReader.java @@ -47,7 +47,7 @@ public class vAuthFileReader { String name = line.split(": ")[0]; String password = line.split(": ")[1]; PlayerAuth auth; - if (isUUIDinstance(password)) { + if (isUuidInstance(password)) { String pname; try { pname = Bukkit.getOfflinePlayer(UUID.fromString(name)).getName(); @@ -68,15 +68,8 @@ public class vAuthFileReader { } - /** - * Method isUUIDinstance. - * @param s String - - * @return boolean */ - private boolean isUUIDinstance(String s) { - if (String.valueOf(s.charAt(8)).equalsIgnoreCase("-")) - return true; - return true; + private static boolean isUuidInstance(String s) { + return s.length() > 8 && s.charAt(8) == '-'; } /** From da0c5d1ea2a082deafa763f515bfa2bca7da376a Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 29 Nov 2015 12:51:11 +0100 Subject: [PATCH 02/82] Split command management into initializer and handler - Create Initializer class that only initializes AuthMe commands - Move remaining method to CommandHandler - Deprecate constructors on CommandDescription in favor of the builder - Various cleanups and comments --- src/main/java/fr/xephi/authme/AuthMe.java | 3 +- .../command/CommandArgumentDescription.java | 9 +- .../authme/command/CommandDescription.java | 24 +- .../xephi/authme/command/CommandHandler.java | 103 +++----- ...ndManager.java => CommandInitializer.java} | 223 ++++++++---------- .../authme/command/help/HelpProvider.java | 4 +- .../authme/permission/PermissionsManager.java | 1 + .../authme/command/CommandManagerTest.java | 32 +-- 8 files changed, 170 insertions(+), 229 deletions(-) rename src/main/java/fr/xephi/authme/command/{CommandManager.java => CommandInitializer.java} (82%) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index ab54071a1..d6427ae1b 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -418,8 +418,7 @@ public class AuthMe extends JavaPlugin { * Set up the command handler. */ private void setupCommandHandler() { - this.commandHandler = new CommandHandler(false); - this.commandHandler.init(); + this.commandHandler = new CommandHandler(); } /** diff --git a/src/main/java/fr/xephi/authme/command/CommandArgumentDescription.java b/src/main/java/fr/xephi/authme/command/CommandArgumentDescription.java index 0440ddc0f..5a9cd9d7c 100644 --- a/src/main/java/fr/xephi/authme/command/CommandArgumentDescription.java +++ b/src/main/java/fr/xephi/authme/command/CommandArgumentDescription.java @@ -1,6 +1,7 @@ package fr.xephi.authme.command; /** + * Wrapper for the description of a command argument. */ public class CommandArgumentDescription { @@ -9,15 +10,15 @@ public class CommandArgumentDescription { /** * Argument label (one-word description of the argument). */ - private String label; + private final String label; /** * Argument description. */ - private String description; + private final String description; /** * Defines whether the argument is optional. */ - private boolean isOptional = false; + private final boolean isOptional; /** * Constructor. @@ -51,7 +52,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. */ diff --git a/src/main/java/fr/xephi/authme/command/CommandDescription.java b/src/main/java/fr/xephi/authme/command/CommandDescription.java index 3a5342461..887650a54 100644 --- a/src/main/java/fr/xephi/authme/command/CommandDescription.java +++ b/src/main/java/fr/xephi/authme/command/CommandDescription.java @@ -15,9 +15,9 @@ import java.util.List; * 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. * - * CommandDescription is built hierarchically and have one parent or {@code null} for base commands (main commands - * such as /authme) and may have multiple children extending the mapping of the parent: e.g. if /authme has a child - * whose label is "register", then "/authme register" is the command that the child defines. + * CommandDescription instances are built hierarchically and have one parent or {@code null} for base commands + * (main commands such as /authme) and may have multiple children extending the mapping of the parent: e.g. if + * /authme has a child whose label is "register", then "/authme register" is the command that the child defines. */ public class CommandDescription { @@ -68,6 +68,7 @@ public class CommandDescription { * @param detailedDescription Detailed comment description. * @param parent Parent command. */ + @Deprecated public CommandDescription(ExecutableCommand executableCommand, List labels, String description, String detailedDescription, CommandDescription parent) { this(executableCommand, labels, description, detailedDescription, parent, null); } @@ -82,6 +83,7 @@ public class CommandDescription { * @param parent Parent command. * @param arguments Command arguments. */ + @Deprecated public CommandDescription(ExecutableCommand executableCommand, List labels, String description, String detailedDescription, CommandDescription parent, List arguments) { setExecutableCommand(executableCommand); this.labels = labels; @@ -739,6 +741,9 @@ public class CommandDescription { return new Builder(); } + /** + * Builder for initializing CommandDescription objects. + */ public static final class Builder { private List labels; private String description; @@ -750,7 +755,8 @@ public class CommandDescription { 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 */ @@ -796,6 +802,16 @@ public class CommandDescription { 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 Builder withArgument(String label, String description, boolean isOptional) { arguments.add(new CommandArgumentDescription(label, description, isOptional)); return this; diff --git a/src/main/java/fr/xephi/authme/command/CommandHandler.java b/src/main/java/fr/xephi/authme/command/CommandHandler.java index d06c1b876..5290507ac 100644 --- a/src/main/java/fr/xephi/authme/command/CommandHandler.java +++ b/src/main/java/fr/xephi/authme/command/CommandHandler.java @@ -10,78 +10,11 @@ import java.util.Arrays; import java.util.List; /** + * 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 { - /** - * The command manager instance. - */ - private CommandManager commandManager; - - /** - * Constructor. - * - * @param init True to immediately initialize. - */ - public CommandHandler(boolean init) { - // Initialize - if (init) - init(); - } - - /** - * Initialize the command handler. - * - * @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. * @@ -92,6 +25,7 @@ public class CommandHandler { * * @return True if the command was executed, false otherwise. */ + // TODO ljacqu 20151129: Rename onCommand() method to something not suggesting it is auto-invoked by an event public boolean onCommand(CommandSender sender, org.bukkit.command.Command bukkitCommand, String bukkitCommandLabel, String[] bukkitArgs) { // Process the arguments List args = processArguments(bukkitArgs); @@ -102,7 +36,7 @@ public class CommandHandler { return false; // 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) { sender.sendMessage(ChatColor.DARK_RED + "Failed to parse " + AuthMe.getPluginName() + " command!"); return false; @@ -207,4 +141,33 @@ public class CommandHandler { // Return the argument return arguments; } + + /** + * 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; + + // TODO ljacqu 20151129: If base commands are only used in here (or in the future CommandHandler after changes), + // it might make sense to make the CommandInitializer package-private and to return its result into this class + // instead of regularly fetching the list of base commands from the other class. + for (CommandDescription commandDescription : CommandInitializer.getBaseCommands()) { + // 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; + } } diff --git a/src/main/java/fr/xephi/authme/command/CommandManager.java b/src/main/java/fr/xephi/authme/command/CommandInitializer.java similarity index 82% rename from src/main/java/fr/xephi/authme/command/CommandManager.java rename to src/main/java/fr/xephi/authme/command/CommandInitializer.java index cc335561c..fd0c4e786 100644 --- a/src/main/java/fr/xephi/authme/command/CommandManager.java +++ b/src/main/java/fr/xephi/authme/command/CommandInitializer.java @@ -1,7 +1,26 @@ package fr.xephi.authme.command; 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.converter.ConverterCommand; import fr.xephi.authme.command.executable.email.AddEmailCommand; @@ -11,6 +30,7 @@ import fr.xephi.authme.command.executable.login.LoginCommand; import fr.xephi.authme.command.executable.logout.LogoutCommand; import fr.xephi.authme.permission.AdminPermission; import fr.xephi.authme.permission.UserPermission; +import fr.xephi.authme.util.Wrapper; import java.util.ArrayList; import java.util.Arrays; @@ -20,132 +40,125 @@ import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.ALLOW import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.OP_ONLY; /** + * Initializes all available AuthMe commands. */ -public class CommandManager { +public final class CommandInitializer { - /** - * The list of commandDescriptions. - */ - private final List commandDescriptions = new ArrayList<>(); + private static List baseCommands; - /** - * Constructor. - * - * @param registerCommands True to register the commands, false otherwise. - */ - public CommandManager(boolean registerCommands) { - // Register the commands - if (registerCommands) - registerCommands(); + private CommandInitializer() { + // Helper class } - /** - * Register all commands. - */ - public void registerCommands() { + public static List getBaseCommands() { + if (baseCommands == null) { + Wrapper.getInstance().getLogger().info("Initializing AuthMe commands"); + initializeCommands(); + } + return baseCommands; + } + + private static void initializeCommands() { // Create a list of help command labels final List helpCommandLabels = Arrays.asList("help", "hlp", "h", "sos", "?"); - ExecutableCommand helpCommandExecutable = new HelpCommand(); + final ExecutableCommand helpCommandExecutable = new HelpCommand(); // Register the base AuthMe Reloaded command - CommandDescription authMeBaseCommand = CommandDescription.builder() - .executableCommand(new AuthMeCommand()) + final CommandDescription AUTHME_BASE = CommandDescription.builder() .labels("authme") .description("Main command") .detailedDescription("The main AuthMeReloaded command. The root for all admin commands.") - .parent(null) + .executableCommand(new AuthMeCommand()) .build(); // Register the help command - CommandDescription authMeHelpCommand = CommandDescription.builder() - .executableCommand(helpCommandExecutable) + CommandDescription.builder() + .parent(AUTHME_BASE) .labels(helpCommandLabels) .description("View help") .detailedDescription("View detailed help pages about AuthMeReloaded commands.") - .parent(authMeBaseCommand) .withArgument("query", "The command or query to view help for.", true) + .executableCommand(helpCommandExecutable) .build(); // Register the register command - CommandDescription registerCommand = CommandDescription.builder() - .executableCommand(new RegisterCommand()) + CommandDescription.builder() + .parent(AUTHME_BASE) .labels("register", "reg", "r") .description("Register a player") .detailedDescription("Register the specified player with the specified password.") - .parent(authMeBaseCommand) - .permissions(OP_ONLY, UserPermission.REGISTER) .withArgument("player", "Player name", false) .withArgument("password", "Password", false) + .permissions(OP_ONLY, UserPermission.REGISTER) + .executableCommand(new RegisterCommand()) .build(); // Register the unregister command - CommandDescription unregisterCommand = CommandDescription.builder() - .executableCommand(new UnregisterCommand()) + CommandDescription.builder() + .parent(AUTHME_BASE) .labels("unregister", "unreg", "unr") .description("Unregister a player") .detailedDescription("Unregister the specified player.") - .parent(authMeBaseCommand) - .permissions(OP_ONLY, UserPermission.UNREGISTER) .withArgument("player", "Player name", false) + .permissions(OP_ONLY, UserPermission.UNREGISTER) + .executableCommand(new UnregisterCommand()) .build(); // Register the forcelogin command - CommandDescription forceLoginCommand = CommandDescription.builder() - .executableCommand(new ForceLoginCommand()) + CommandDescription.builder() + .parent(AUTHME_BASE) .labels("forcelogin", "login") .description("Enforce login player") .detailedDescription("Enforce the specified player to login.") - .parent(authMeBaseCommand) - .permissions(OP_ONLY, UserPermission.CAN_LOGIN_BE_FORCED) .withArgument("player", "Online player name", true) + .permissions(OP_ONLY, UserPermission.CAN_LOGIN_BE_FORCED) + .executableCommand(new ForceLoginCommand()) .build(); // Register the changepassword command - CommandDescription changePasswordCommand = CommandDescription.builder() - .executableCommand(new ChangePasswordCommand()) + CommandDescription.builder() + .parent(AUTHME_BASE) .labels("password", "changepassword", "changepass", "cp") .description("Change a player's password") .detailedDescription("Change the password of a player.") - .parent(authMeBaseCommand) - .permissions(OP_ONLY, UserPermission.CHANGE_PASSWORD) .withArgument("player", "Player name", false) .withArgument("pwd", "New password", false) + .permissions(OP_ONLY, UserPermission.CHANGE_PASSWORD) + .executableCommand(new ChangePasswordCommand()) .build(); // Register the last login command - CommandDescription lastLoginCommand = CommandDescription.builder() - .executableCommand(new LastLoginCommand()) + CommandDescription.builder() + .parent(AUTHME_BASE) .labels("lastlogin", "ll") .description("Player's 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) + .permissions(OP_ONLY, AdminPermission.LAST_LOGIN) + .executableCommand(new LastLoginCommand()) .build(); // Register the accounts command - CommandDescription accountsCommand = CommandDescription.builder() - .executableCommand(new AccountsCommand()) + CommandDescription.builder() + .parent(AUTHME_BASE) .labels("accounts", "account") .description("Display player accounts") .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) + .permissions(OP_ONLY, AdminPermission.ACCOUNTS) + .executableCommand(new AccountsCommand()) .build(); // Register the getemail command - CommandDescription getEmailCommand = new CommandDescription(new GetEmailCommand(), new ArrayList() { - - { - add("getemail"); - add("getmail"); - add("email"); - add("mail"); - } - }, "Display player's email", "Display the email address of the specified player if set.", authMeBaseCommand); - getEmailCommand.setCommandPermissions(AdminPermission.GET_EMAIL, OP_ONLY); - getEmailCommand.addArgument(new CommandArgumentDescription("player", "Player name", true)); + CommandDescription.builder() + .parent(AUTHME_BASE) + .labels("getemail", "getmail", "email", "mail") + .description("Display player's email") + .detailedDescription("Display the email address of the specified player if set.") + .withArgument("player", "Player name", true) + .permissions(OP_ONLY, AdminPermission.GET_EMAIL) + .executableCommand(new GetEmailCommand()) + .build(); // Register the setemail command CommandDescription setEmailCommand = new CommandDescription(new SetEmailCommand(), new ArrayList() { @@ -156,7 +169,7 @@ public class CommandManager { add("setemail"); add("setmail"); } - }, "Change player's email", "Change the email address of the specified player.", authMeBaseCommand); + }, "Change player's email", "Change the email address of the specified player.", AUTHME_BASE); setEmailCommand.setCommandPermissions(AdminPermission.CHANGE_EMAIL, OP_ONLY); setEmailCommand.addArgument(new CommandArgumentDescription("player", "Player name", false)); setEmailCommand.addArgument(new CommandArgumentDescription("email", "Player email", false)); @@ -168,7 +181,7 @@ public class CommandManager { add("getip"); 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.addArgument(new CommandArgumentDescription("player", "Online player name", true)); @@ -179,7 +192,7 @@ public class CommandManager { add("spawn"); 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); // Register the setspawn command @@ -189,7 +202,7 @@ public class CommandManager { add("setspawn"); 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); // Register the firstspawn command @@ -199,7 +212,7 @@ public class CommandManager { add("firstspawn"); 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); // Register the setfirstspawn command @@ -209,7 +222,7 @@ public class CommandManager { add("setfirstspawn"); 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); // Register the purge command @@ -219,7 +232,7 @@ public class CommandManager { add("purge"); 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.addArgument(new CommandArgumentDescription("days", "Number of days", false)); @@ -234,7 +247,7 @@ public class CommandManager { add("resetlastposition"); 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.addArgument(new CommandArgumentDescription("player", "Player name", true)); @@ -247,7 +260,7 @@ public class CommandManager { add("deletebannedplayers"); 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); // Register the switchantibot command @@ -258,7 +271,7 @@ public class CommandManager { add("toggleantibot"); 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.addArgument(new CommandArgumentDescription("mode", "ON / OFF", true)); @@ -282,7 +295,7 @@ public class CommandManager { add("reload"); add("rld"); } - }, "Reload plugin", "Reload the AuthMeReloaded plugin.", authMeBaseCommand); + }, "Reload plugin", "Reload the AuthMeReloaded plugin.", AUTHME_BASE); reloadCommand.setCommandPermissions(AdminPermission.RELOAD, OP_ONLY); // Register the version command @@ -292,7 +305,7 @@ public class CommandManager { .description("Version info") .detailedDescription("Show detailed information about the installed AuthMeReloaded version, and shows the " + "developers, contributors, license and other information.") - .parent(authMeBaseCommand) + .parent(AUTHME_BASE) .build(); // Register the base login command @@ -461,59 +474,15 @@ public class CommandManager { converterHelpCommand.addArgument(new CommandArgumentDescription("query", "The command or query to view help for.", true)); // Add the base commands to the commands array - this.commandDescriptions.add(authMeBaseCommand); - this.commandDescriptions.add(loginBaseCommand); - this.commandDescriptions.add(logoutBaseCommand); - this.commandDescriptions.add(registerBaseCommand); - this.commandDescriptions.add(unregisterBaseCommand); - this.commandDescriptions.add(changePasswordBaseCommand); - this.commandDescriptions.add(emailBaseCommand); - this.commandDescriptions.add(captchaBaseCommand); - this.commandDescriptions.add(converterBaseCommand); - } - - /** - * Get the list of command descriptions - * - * @return List of command descriptions. - */ - public List 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; + baseCommands = Arrays.asList( + AUTHME_BASE, + loginBaseCommand, + logoutBaseCommand, + registerBaseCommand, + unregisterBaseCommand, + changePasswordBaseCommand, + emailBaseCommand, + captchaBaseCommand, + converterBaseCommand); } } diff --git a/src/main/java/fr/xephi/authme/command/help/HelpProvider.java b/src/main/java/fr/xephi/authme/command/help/HelpProvider.java index ce4e83173..b53bba6ed 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpProvider.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpProvider.java @@ -37,9 +37,9 @@ 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) { // 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); + FoundCommandResult resultOther = AuthMe.getInstance().getCommandHandler().findCommand(commandReferenceOther); if (resultOther != null) { if (result == null) result = resultOther; diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java index 1cff42a5c..04f08434f 100644 --- a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java +++ b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java @@ -260,6 +260,7 @@ public class PermissionsManager { * * @param event Event instance. */ + // TODO ljacqu 20151129: Misleading name since onPluginEnable is a typical event-based method name public void onPluginEnable(PluginEnableEvent event) { // Get the plugin and it's name Plugin plugin = event.getPlugin(); diff --git a/src/test/java/fr/xephi/authme/command/CommandManagerTest.java b/src/test/java/fr/xephi/authme/command/CommandManagerTest.java index c15b203d7..ff6a1a382 100644 --- a/src/test/java/fr/xephi/authme/command/CommandManagerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandManagerTest.java @@ -18,7 +18,7 @@ import static org.junit.Assert.assertThat; 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 { @@ -28,24 +28,20 @@ public class CommandManagerTest { */ private static int MAX_ALLOWED_DEPTH = 1; - private static CommandManager manager; + private static List commands; @BeforeClass public static void initializeCommandManager() { - manager = new CommandManager(true); + commands = CommandInitializer.getBaseCommands(); } @Test public void shouldInitializeCommands() { - // given/when - int commandCount = manager.getCommandDescriptionCount(); - List commands = manager.getCommandDescriptions(); - - // then + // given/when/then // 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 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, "register"), equalTo(true)); assertThat(commandsIncludeLabel(commands, "help"), equalTo(false)); @@ -62,7 +58,7 @@ public class CommandManagerTest { }; // when/then - walkThroughCommands(manager.getCommandDescriptions(), descriptionTester); + walkThroughCommands(commands, descriptionTester); } /** Ensure that all children of a command stored the parent. */ @@ -84,7 +80,7 @@ public class CommandManagerTest { }; // when/then - walkThroughCommands(manager.getCommandDescriptions(), connectionTester); + walkThroughCommands(commands, connectionTester); } @Test @@ -105,7 +101,7 @@ public class CommandManagerTest { }; // when/then - walkThroughCommands(manager.getCommandDescriptions(), uniqueMappingTester); + walkThroughCommands(commands, uniqueMappingTester); } /** @@ -132,7 +128,7 @@ public class CommandManagerTest { }; // when/then - walkThroughCommands(manager.getCommandDescriptions(), descriptionTester); + walkThroughCommands(commands, descriptionTester); } /** @@ -143,7 +139,6 @@ public class CommandManagerTest { public void shouldNotHaveMultipleInstancesOfSameExecutableCommandSubType() { // given final Map, ExecutableCommand> implementations = new HashMap<>(); - CommandManager manager = new CommandManager(true); BiConsumer descriptionTester = new BiConsumer() { @Override public void accept(CommandDescription command, int depth) { @@ -160,10 +155,7 @@ public class CommandManagerTest { } }; - // when - List commands = manager.getCommandDescriptions(); - - // then + // when/then walkThroughCommands(commands, descriptionTester); } @@ -186,7 +178,7 @@ public class CommandManagerTest { }; // when/then - walkThroughCommands(manager.getCommandDescriptions(), argumentOrderTester); + walkThroughCommands(commands, argumentOrderTester); } /** @@ -209,7 +201,7 @@ public class CommandManagerTest { }; // when/then - walkThroughCommands(manager.getCommandDescriptions(), noArgumentForParentChecker); + walkThroughCommands(commands, noArgumentForParentChecker); } From 174ad3b29c71f183c3b3b2f3b9e5ce6eca73f92e Mon Sep 17 00:00:00 2001 From: Xephi Date: Mon, 30 Nov 2015 19:21:15 +0100 Subject: [PATCH 03/82] Fix Conflict --- .../java/fr/xephi/authme/converter/vAuthFileReader.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/fr/xephi/authme/converter/vAuthFileReader.java b/src/main/java/fr/xephi/authme/converter/vAuthFileReader.java index 9cc306ce2..bca9af2cf 100644 --- a/src/main/java/fr/xephi/authme/converter/vAuthFileReader.java +++ b/src/main/java/fr/xephi/authme/converter/vAuthFileReader.java @@ -45,13 +45,13 @@ public class vAuthFileReader { if (isUuidInstance(password)) { String pname; try { - playerName = Bukkit.getOfflinePlayer(UUID.fromString(name)).getName(); + pname = Bukkit.getOfflinePlayer(UUID.fromString(name)).getName(); } catch (Exception | NoSuchMethodError e) { - playerName = getName(UUID.fromString(name)); + pname = getName(UUID.fromString(name)); } - if (playerName == null) + if (pname == null) continue; - auth = new PlayerAuth(playerName.toLowerCase(), password, "127.0.0.1", System.currentTimeMillis(), "your@email.com", playerName); + auth = new PlayerAuth(pname.toLowerCase(), password, "127.0.0.1", System.currentTimeMillis(), "your@email.com", pname); } else { auth = new PlayerAuth(name.toLowerCase(), password, "127.0.0.1", System.currentTimeMillis(), "your@email.com", name); } From 029214c080a4cef4e9b518ac0bb581a2a677f799 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Tue, 1 Dec 2015 01:29:56 +0700 Subject: [PATCH 04/82] Fix npe after register. --- .../xephi/authme/cache/limbo/LimboCache.java | 10 ++-- .../xephi/authme/cache/limbo/LimboPlayer.java | 21 ++++++++- .../authme/process/join/AsynchronousJoin.java | 8 ++-- .../ProcessSyncronousPasswordRegister.java | 46 +++++++++++-------- 4 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java b/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java index 69774e221..33cef3ded 100644 --- a/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java +++ b/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java @@ -117,7 +117,10 @@ public class LimboCache { * @param name String */ public void deleteLimboPlayer(String name) { - cache.remove(name); + if(cache.containsKey(name)) { + cache.get(name).clearTask(); + cache.remove(name); + } } /** @@ -148,8 +151,9 @@ public class LimboCache { * @param player Player */ public void updateLimboPlayer(Player player) { - if (this.hasLimboPlayer(player.getName().toLowerCase())) { - this.deleteLimboPlayer(player.getName().toLowerCase()); + String name = player.getName().toLowerCase(); + if (hasLimboPlayer(name)) { + deleteLimboPlayer(name); } addLimboPlayer(player); } diff --git a/src/main/java/fr/xephi/authme/cache/limbo/LimboPlayer.java b/src/main/java/fr/xephi/authme/cache/limbo/LimboPlayer.java index 96c5a9ee9..76ed21e8e 100644 --- a/src/main/java/fr/xephi/authme/cache/limbo/LimboPlayer.java +++ b/src/main/java/fr/xephi/authme/cache/limbo/LimboPlayer.java @@ -108,8 +108,9 @@ public class LimboPlayer { * @param i BukkitTask */ public void setTimeoutTaskId(BukkitTask i) { - if (this.timeoutTaskId != null) + if (this.timeoutTaskId != null) { this.timeoutTaskId.cancel(); + } this.timeoutTaskId = i; } @@ -128,11 +129,27 @@ public class LimboPlayer { * @param messageTaskId BukkitTask */ public void setMessageTaskId(BukkitTask messageTaskId) { - if (this.messageTaskId != null) + if (this.messageTaskId != null) { this.messageTaskId.cancel(); + } this.messageTaskId = messageTaskId; } + /** + * Method clearTask. + * + */ + public void clearTask() { + if (messageTaskId != null) { + messageTaskId.cancel(); + } + messageTaskId = null; + if (timeoutTaskId != null) { + timeoutTaskId.cancel(); + } + timeoutTaskId = null; + } + /** * Method isFlying. * diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java index aa49d3f29..01724b3a1 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -50,14 +50,12 @@ public class AsynchronousJoin { } public void process() { - if (AuthMePlayerListener.gameMode.containsKey(name)) - AuthMePlayerListener.gameMode.remove(name); - AuthMePlayerListener.gameMode.putIfAbsent(name, player.getGameMode()); - - if (Utils.isNPC(player) || Utils.isUnrestricted(player)) { + if (Utils.isUnrestricted(player)) { return; } + AuthMePlayerListener.gameMode.put(name, player.getGameMode()); + if (plugin.ess != null && Settings.disableSocialSpy) { plugin.ess.getUser(player).setSocialSpyEnabled(false); } diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncronousPasswordRegister.java b/src/main/java/fr/xephi/authme/process/register/ProcessSyncronousPasswordRegister.java index 28faa5bf3..bd1bb174f 100644 --- a/src/main/java/fr/xephi/authme/process/register/ProcessSyncronousPasswordRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/ProcessSyncronousPasswordRegister.java @@ -41,15 +41,13 @@ public class ProcessSyncronousPasswordRegister implements Runnable { this.plugin = plugin; } - protected void forceCommands() { + private void forceCommands() { for (String command : Settings.forceRegisterCommands) { - try { - player.performCommand(command.replace("%p", player.getName())); - } catch (Exception ignored) { - } + player.performCommand(command.replace("%p", player.getName())); } for (String command : Settings.forceRegisterCommandsAsConsole) { - Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), command.replace("%p", player.getName())); + Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), + command.replace("%p", player.getName())); } } @@ -58,20 +56,21 @@ public class ProcessSyncronousPasswordRegister implements Runnable { * * @param player Player */ - protected void forceLogin(Player player) { + private void forceLogin(Player player) { Utils.teleportToSpawn(player); - if (LimboCache.getInstance().hasLimboPlayer(name)) - LimboCache.getInstance().deleteLimboPlayer(name); - LimboCache.getInstance().addLimboPlayer(player); + LimboCache cache = LimboCache.getInstance(); + cache.updateLimboPlayer(player); int delay = Settings.getRegistrationTimeout * 20; int interval = Settings.getWarnMessageInterval; BukkitScheduler sched = plugin.getServer().getScheduler(); + BukkitTask task; if (delay != 0) { - BukkitTask id = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), delay); - LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id); + task = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), delay); + cache.getLimboPlayer(name).setTimeoutTaskId(task); } - BukkitTask msgT = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, m.retrieve(MessageKey.LOGIN_MESSAGE), interval)); - LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT); + task = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, + m.retrieve(MessageKey.LOGIN_MESSAGE), interval)); + cache.getLimboPlayer(name).setMessageTaskId(task); if (player.isInsideVehicle() && player.getVehicle() != null) { player.getVehicle().eject(); } @@ -97,33 +96,39 @@ public class ProcessSyncronousPasswordRegister implements Runnable { } } - limbo.getTimeoutTaskId().cancel(); - limbo.getMessageTaskId().cancel(); LimboCache.getInstance().deleteLimboPlayer(name); } if (!Settings.getRegisteredGroup.isEmpty()) { Utils.setGroup(player, Utils.GroupType.REGISTERED); } + m.send(player, MessageKey.REGISTER_SUCCESS); - if (!Settings.getmailAccount.isEmpty()) + + if (!Settings.getmailAccount.isEmpty()) { m.send(player, MessageKey.ADD_EMAIL_MESSAGE); + } if (player.getGameMode() != GameMode.CREATIVE && !Settings.isMovementAllowed) { player.setAllowFlight(false); player.setFlying(false); } - if (Settings.applyBlindEffect) + + if (Settings.applyBlindEffect) { player.removePotionEffect(PotionEffectType.BLINDNESS); + } + if (!Settings.isMovementAllowed && Settings.isRemoveSpeedEnabled) { player.setWalkSpeed(0.2f); player.setFlySpeed(0.1f); } + // The LoginEvent now fires (as intended) after everything is processed plugin.getServer().getPluginManager().callEvent(new LoginEvent(player, true)); player.saveData(); - if (!Settings.noConsoleSpam) + if (!Settings.noConsoleSpam) { ConsoleLogger.info(player.getName() + " registered " + plugin.getIP(player)); + } // Kick Player after Registration is enabled, kick the player if (Settings.forceRegKick) { @@ -138,7 +143,7 @@ public class ProcessSyncronousPasswordRegister implements Runnable { } // Register is finish and player is logged, display welcome message - if (Settings.useWelcomeMessage) + if (Settings.useWelcomeMessage) { if (Settings.broadcastWelcomeMessage) { for (String s : Settings.welcomeMsg) { plugin.getServer().broadcastMessage(plugin.replaceAllInfo(s, player)); @@ -148,6 +153,7 @@ public class ProcessSyncronousPasswordRegister implements Runnable { player.sendMessage(plugin.replaceAllInfo(s, player)); } } + } // Register is now finish , we can force all commands forceCommands(); From d6925300351ad4d48bbcbbfc8f1e88069053e1e5 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Tue, 1 Dec 2015 01:35:30 +0700 Subject: [PATCH 05/82] Moved is player can connect check into prelogin event. --- .../authme/listener/AuthMePlayerListener.java | 6 ++++++ .../authme/process/join/AsynchronousJoin.java | 15 --------------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java index 8400d572f..ae0e83ca0 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java @@ -198,6 +198,12 @@ public class AuthMePlayerListener implements Listener { @EventHandler(priority = EventPriority.HIGHEST) public void onPreLogin(AsyncPlayerPreLoginEvent event) { + if (!plugin.canConnect()) { + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + event.setKickMessage("Server is loading, please wait before joining!"); + return; + } + final String name = event.getName().toLowerCase(); final Player player = Utils.getPlayer(name); if (player == null || Utils.isNPC(player)) { diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java index 01724b3a1..407554637 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -60,21 +60,6 @@ public class AsynchronousJoin { plugin.ess.getUser(player).setSocialSpyEnabled(false); } - if (!plugin.canConnect()) { - final GameMode gM = AuthMePlayerListener.gameMode.get(name); - sched.scheduleSyncDelayedTask(plugin, new Runnable() { - - @Override - public void run() { - AuthMePlayerListener.causeByAuthMe.putIfAbsent(name, true); - player.setGameMode(gM); - player.kickPlayer("Server is loading, please wait before joining!"); - } - - }); - return; - } - final String ip = plugin.getIP(player); if (Settings.isAllowRestrictedIp && !Settings.getRestrictedIp(name, ip)) { final GameMode gM = AuthMePlayerListener.gameMode.get(name); From e387a801f78bc67c858212b801ea3877408b6e17 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Tue, 1 Dec 2015 02:06:51 +0700 Subject: [PATCH 06/82] Removed some unnecessary player check. --- .../authme/listener/AuthMePlayerListener.java | 95 +++++++++---------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java index ae0e83ca0..fef123bbb 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java @@ -54,7 +54,7 @@ public class AuthMePlayerListener implements Listener { final Player player = event.getPlayer(); - if(Utils.checkAuth(player)) { + if (Utils.checkAuth(player)) { for (Player p : Utils.getOnlinePlayers()) { if (!PlayerCache.getInstance().isAuthenticated(p.getName())) { event.getRecipients().remove(p); // TODO: it should be configurable @@ -206,32 +206,26 @@ public class AuthMePlayerListener implements Listener { final String name = event.getName().toLowerCase(); final Player player = Utils.getPlayer(name); - if (player == null || Utils.isNPC(player)) { + if (player == null) { return; } // Check if forceSingleSession is set to true, so kick player that has // joined with same nick of online player - if (Settings.isForceSingleSessionEnabled && player.isOnline()) { - event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, m.getString("same_nick")); - if (LimboCache.getInstance().hasLimboPlayer(name)) - Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { - - @Override - public void run() { - LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name); - if (limbo != null && PlayerCache.getInstance().isAuthenticated(name)) { - Utils.addNormal(player, limbo.getGroup()); - LimboCache.getInstance().deleteLimboPlayer(name); - } - } - }); + if (Settings.isForceSingleSessionEnabled) { + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + event.setKickMessage(m.retrieveSingle(MessageKey.USERNAME_ALREADY_ONLINE_ERROR)); + LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name); + if (limbo != null && PlayerCache.getInstance().isAuthenticated(name)) { + Utils.addNormal(player, limbo.getGroup()); + LimboCache.getInstance().deleteLimboPlayer(name); + } } } @EventHandler(priority = EventPriority.HIGHEST) public void onPlayerLogin(PlayerLoginEvent event) { - if (event.getPlayer() == null) { + if (event.getPlayer() == null || Utils.isUnrestricted(event.getPlayer())) { return; } @@ -266,10 +260,6 @@ public class AuthMePlayerListener implements Listener { return; } - if (Utils.isNPC(player) || Utils.isUnrestricted(player)) { - return; - } - final String name = player.getName().toLowerCase(); boolean isAuthAvailable = plugin.database.isAuthAvailable(name); @@ -333,7 +323,7 @@ public class AuthMePlayerListener implements Listener { Player player = event.getPlayer(); - if (!Utils.checkAuth(player) && Settings.delayJoinLeaveMessages) { + if (Settings.delayJoinLeaveMessages && !Utils.checkAuth(player)) { event.setQuitMessage(null); } @@ -346,7 +336,8 @@ public class AuthMePlayerListener implements Listener { return; } - if ((!Settings.isForceSingleSessionEnabled) && (event.getReason().contains(m.getString("same_nick")))) { + if ((!Settings.isForceSingleSessionEnabled) + && (event.getReason().equals(m.retrieveSingle(MessageKey.USERNAME_ALREADY_ONLINE_ERROR)))) { event.setCancelled(true); return; } @@ -357,31 +348,34 @@ public class AuthMePlayerListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onPlayerPickupItem(PlayerPickupItemEvent event) { - if (Utils.checkAuth(event.getPlayer())) + if (Utils.checkAuth(event.getPlayer())) { return; + } event.setCancelled(true); } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onPlayerInteract(PlayerInteractEvent event) { - Player player = event.getPlayer(); - if (player == null || Utils.checkAuth(player)) + if (Utils.checkAuth(event.getPlayer())) { return; + } event.setCancelled(true); } @EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) public void onPlayerConsumeItem(PlayerItemConsumeEvent event) { - if (Utils.checkAuth(event.getPlayer())) + if (Utils.checkAuth(event.getPlayer())) { return; + } event.setCancelled(true); } @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onPlayerInventoryOpen(InventoryOpenEvent event) { final Player player = (Player) event.getPlayer(); - if (Utils.checkAuth(player)) + if (Utils.checkAuth(player)) { return; + } event.setCancelled(true); /* @@ -389,7 +383,6 @@ public class AuthMePlayerListener implements Listener { * real, cause no packet is send to server by client for the main inv */ Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { - @Override public void run() { player.closeInventory(); @@ -414,46 +407,51 @@ public class AuthMePlayerListener implements Listener { if (!(damager instanceof Player)) { return; } - if (Utils.checkAuth((Player) damager)) + if (Utils.checkAuth((Player) damager)) { return; - + } event.setCancelled(true); } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { - Player player = event.getPlayer(); - if (player == null || Utils.checkAuth(player)) + if (Utils.checkAuth(event.getPlayer())) { return; + } event.setCancelled(true); } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onPlayerDropItem(PlayerDropItemEvent event) { - if (Utils.checkAuth(event.getPlayer())) + if (Utils.checkAuth(event.getPlayer())) { return; + } event.setCancelled(true); } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onPlayerBedEnter(PlayerBedEnterEvent event) { - if (Utils.checkAuth(event.getPlayer())) + if (Utils.checkAuth(event.getPlayer())) { return; + } event.setCancelled(true); } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onSignChange(SignChangeEvent event) { - if (Utils.checkAuth(event.getPlayer())) + if (Utils.checkAuth(event.getPlayer())) { return; + } event.setCancelled(true); } - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onPlayerRespawn(PlayerRespawnEvent event) { - Player player = event.getPlayer(); - if (player == null || Utils.checkAuth(player)) + if (Utils.checkAuth(event.getPlayer())) { return; + } + + Player player = event.getPlayer(); String name = player.getName().toLowerCase(); Location spawn = plugin.getSpawnLocation(player); if (Settings.isSaveQuitLocationEnabled && plugin.database.isAuthAvailable(name)) { @@ -467,13 +465,14 @@ public class AuthMePlayerListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) { + if (Utils.checkAuth(event.getPlayer())) { + return; + } + Player player = event.getPlayer(); - if (player == null) - return; - if (plugin.getPermissionsManager().hasPermission(player, UserPermission.BYPASS_FORCE_SURVIVAL)) - return; - if (Utils.checkAuth(player)) + if (plugin.getPermissionsManager().hasPermission(player, UserPermission.BYPASS_FORCE_SURVIVAL)) { return; + } String name = player.getName().toLowerCase(); if (causeByAuthMe.containsKey(name)) { @@ -485,17 +484,17 @@ public class AuthMePlayerListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) public void onPlayerShear(PlayerShearEntityEvent event) { - Player player = event.getPlayer(); - if (player == null || Utils.checkAuth(player)) + if (Utils.checkAuth(event.getPlayer())) { return; + } event.setCancelled(true); } @EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) public void onPlayerFish(PlayerFishEvent event) { - Player player = event.getPlayer(); - if (player == null || Utils.checkAuth(player)) + if (Utils.checkAuth(event.getPlayer())) { return; + } event.setCancelled(true); } From 8a6ab3edb51d8972f4b1350b00046766d1914a96 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Tue, 1 Dec 2015 02:14:28 +0700 Subject: [PATCH 07/82] Setup unrestricted names into lowercase. --- src/main/java/fr/xephi/authme/settings/Settings.java | 9 +++++++-- src/main/java/fr/xephi/authme/util/Utils.java | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index 7a2096808..f9ed10be2 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -184,7 +184,12 @@ public final class Settings extends YamlConfiguration { getMySQLColumnRealName = configFile.getString("DataSource.mySQLRealName", "realname"); getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1); unRegisteredGroup = configFile.getString("GroupOptions.UnregisteredPlayerGroup", ""); - getUnrestrictedName = configFile.getStringList("settings.unrestrictions.UnrestrictedName"); + + getUnrestrictedName = new ArrayList<>(); + for (String name : configFile.getStringList("settings.unrestrictions.UnrestrictedName")) { + getUnrestrictedName.add(name.toLowerCase()); + } + getRegisteredGroup = configFile.getString("GroupOptions.RegisteredPlayerGroup", ""); getEnablePasswordVerifier = configFile.getBoolean("settings.restrictions.enablePasswordVerifier", true); @@ -689,7 +694,7 @@ public final class Settings extends YamlConfiguration { /** * Saves current configuration (plus defaults) to disk. - *

+ *

* If defaults and configuration are empty, saves blank file. * * @return True if saved successfully diff --git a/src/main/java/fr/xephi/authme/util/Utils.java b/src/main/java/fr/xephi/authme/util/Utils.java index e3e298b94..e94dd94ee 100644 --- a/src/main/java/fr/xephi/authme/util/Utils.java +++ b/src/main/java/fr/xephi/authme/util/Utils.java @@ -156,8 +156,9 @@ public final class Utils { } public static boolean isUnrestricted(Player player) { - return Settings.isAllowRestrictedIp && !Settings.getUnrestrictedName.isEmpty() - && (Settings.getUnrestrictedName.contains(player.getName())); + return Settings.isAllowRestrictedIp + && !Settings.getUnrestrictedName.isEmpty() + && (Settings.getUnrestrictedName.contains(player.getName().toLowerCase())); } /** From 37b24d4e724f58dce23425ebee5419ea5401187c Mon Sep 17 00:00:00 2001 From: DNx5 Date: Tue, 1 Dec 2015 02:17:07 +0700 Subject: [PATCH 08/82] Fix "new config options message" always printed on reload. --- src/main/java/fr/xephi/authme/settings/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index f9ed10be2..b1bd141b2 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -681,7 +681,7 @@ public final class Settings extends YamlConfiguration { set("DataSource.mySQLRealName", "realname"); changes = true; } - if (!contains("DataSource.mySQLQueryCache")) { + if (!contains("DataSource.mySQLWebsite")) { set("DataSource.mySQLWebsite", false); changes = true; } From 2fdd5ef3252fae58d45de128919ce81e1167cba7 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Tue, 1 Dec 2015 02:36:44 +0700 Subject: [PATCH 09/82] Handle country blacklist effectively --- .../authme/listener/AuthMePlayerListener.java | 32 ++++++++----------- .../authme/listener/AuthMeServerListener.java | 16 +++------- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java index fef123bbb..fa783ec3c 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java @@ -204,6 +204,20 @@ public class AuthMePlayerListener implements Listener { return; } + if (Settings.enableProtection) { + String countryCode = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress()); + if (!Settings.countriesBlacklist.isEmpty() && Settings.countriesBlacklist.contains(countryCode)) { + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR)); + return; + } + if (!Settings.countries.isEmpty() && !Settings.countries.contains(countryCode)) { + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR)); + return; + } + } + final String name = event.getName().toLowerCase(); final Player player = Utils.getPlayer(name); if (player == null) { @@ -263,24 +277,6 @@ public class AuthMePlayerListener implements Listener { final String name = player.getName().toLowerCase(); boolean isAuthAvailable = plugin.database.isAuthAvailable(name); - if (!Settings.countriesBlacklist.isEmpty() && !isAuthAvailable && !permsMan.hasPermission(player, UserPermission.BYPASS_ANTIBOT)) { - String code = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress()); - if (Settings.countriesBlacklist.contains(code)) { - event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR)); - event.setResult(PlayerLoginEvent.Result.KICK_OTHER); - return; - } - } - - if (Settings.enableProtection && !Settings.countries.isEmpty() && !isAuthAvailable && !permsMan.hasPermission(player, UserPermission.BYPASS_ANTIBOT)) { - String code = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress()); - if (!Settings.countries.contains(code)) { - event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR)); - event.setResult(PlayerLoginEvent.Result.KICK_OTHER); - return; - } - } - // TODO: Add message to the messages file!!! if (Settings.isKickNonRegisteredEnabled && !isAuthAvailable) { if (Settings.antiBotInAction) { diff --git a/src/main/java/fr/xephi/authme/listener/AuthMeServerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMeServerListener.java index 3b5a3c803..2866fd755 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMeServerListener.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMeServerListener.java @@ -43,19 +43,13 @@ public class AuthMeServerListener implements Listener { } String countryCode = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress()); - if (!Settings.countriesBlacklist.isEmpty()) { - if (Settings.countriesBlacklist.contains(countryCode)) { - event.setMotd(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR)); - return; - } + if (!Settings.countriesBlacklist.isEmpty() && Settings.countriesBlacklist.contains(countryCode)) { + event.setMotd(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR)); + return; } - if (!Settings.countries.isEmpty()) { - if (Settings.countries.contains(countryCode)) { - event.setMotd(plugin.getServer().getMotd()); - } else { - event.setMotd(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR)); - } + if (!Settings.countries.isEmpty() && !Settings.countries.contains(countryCode)) { + event.setMotd(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR)); } } From a4c45e126e92f1e1a2f86869db072cb0594901cc Mon Sep 17 00:00:00 2001 From: ljacqu Date: Mon, 30 Nov 2015 21:09:52 +0100 Subject: [PATCH 10/82] Start refactoring of command handling (work in progress) Preparation: - Remove unused API - Move some logic from "data classes" elsewhere --- src/main/java/fr/xephi/authme/AuthMe.java | 7 +- .../authme/command/CommandDescription.java | 211 +++--------------- .../xephi/authme/command/CommandHandler.java | 107 ++++++--- .../fr/xephi/authme/command/CommandParts.java | 11 - .../fr/xephi/authme/command/CommandUtils.java | 21 ++ .../authme/command/help/HelpPrinter.java | 9 +- .../authme/command/help/HelpSyntaxHelper.java | 2 +- 7 files changed, 140 insertions(+), 228 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/command/CommandUtils.java diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index d6427ae1b..715bebc8f 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -24,6 +24,7 @@ import fr.xephi.authme.settings.*; import fr.xephi.authme.util.GeoLiteAPI; import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.Utils; +import fr.xephi.authme.util.Wrapper; import net.minelink.ctplus.CombatTagPlus; import org.apache.logging.log4j.LogManager; import org.bukkit.Bukkit; @@ -72,6 +73,7 @@ public class AuthMe extends JavaPlugin { private static AuthMe plugin; private static Server server; + private static Wrapper wrapper = Wrapper.getInstance(); public Management management; public NewAPI api; @@ -942,9 +944,10 @@ public class AuthMe extends JavaPlugin { public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { // Get the command handler, and make sure it's valid - CommandHandler commandHandler = this.getCommandHandler(); - if (commandHandler == null) + if (commandHandler == null) { + wrapper.getLogger().warning("AuthMe command handler is not available"); return false; + } // Handle the command, return the result return commandHandler.onCommand(sender, cmd, commandLabel, args); diff --git a/src/main/java/fr/xephi/authme/command/CommandDescription.java b/src/main/java/fr/xephi/authme/command/CommandDescription.java index 887650a54..76948aeb0 100644 --- a/src/main/java/fr/xephi/authme/command/CommandDescription.java +++ b/src/main/java/fr/xephi/authme/command/CommandDescription.java @@ -25,7 +25,7 @@ public class CommandDescription { * Defines the labels to execute the command. For example, if labels are "register" and "r" and the parent is * the command for "/authme", then both "/authme register" and "/authme r" will be handled by this command. */ - private List labels; + private List labels = new ArrayList<>(); // TODO remove field initialization /** * Command description. */ @@ -49,11 +49,11 @@ public class CommandDescription { /** * The arguments the command takes. */ - private List arguments; + private List arguments = new ArrayList<>(); // TODO remove field initialization /** * Defines whether there is an argument maximum or not. */ - private boolean noArgumentMaximum; + private boolean noArgumentMaximum = false; // TODO remove field initialization /** * Defines the command permissions. */ @@ -70,7 +70,8 @@ public class CommandDescription { */ @Deprecated public CommandDescription(ExecutableCommand executableCommand, List labels, String description, String detailedDescription, CommandDescription parent) { - this(executableCommand, labels, description, detailedDescription, parent, null); + this(executableCommand, labels, description, detailedDescription, parent, + new ArrayList()); } /** @@ -90,7 +91,7 @@ public class CommandDescription { this.description = description; this.detailedDescription = detailedDescription; setParent(parent); - setArguments(arguments); + this.arguments = arguments; } /** @@ -122,25 +123,6 @@ public class CommandDescription { } } - /** - * Check whether two labels are equal to each other. - * - * @param commandLabel The first command label. - * @param otherCommandLabel The other command label. - * - * @return True if the labels are equal to each other. - */ - private static boolean commandLabelEquals(String commandLabel, String otherCommandLabel) { - // Trim the command labels from unwanted whitespaces - commandLabel = commandLabel.trim(); - otherCommandLabel = otherCommandLabel.trim(); - - // Check whether the the two command labels are equal (case insensitive) - return (commandLabel.equalsIgnoreCase(otherCommandLabel)); - } - - - /** * Get the label most similar to the reference. The first label will be returned if no reference was supplied. * @@ -192,12 +174,11 @@ public class CommandDescription { * @return True if this command label equals to the param command. */ public boolean hasLabel(String commandLabel) { - // Check whether any command matches with the argument - for (String entry : this.labels) - if (commandLabelEquals(entry, commandLabel)) + for (String label : this.labels) { + if (label.equalsIgnoreCase(commandLabel)) { return true; - - // No match found, return false + } + } return false; } @@ -215,48 +196,16 @@ public class CommandDescription { return false; // Get the parent count + //getParent() = getParent().getParentCount() + 1 String element = commandReference.get(getParentCount()); // Check whether this command description has this command label - return hasLabel(element); - } - - /** - * Get the absolute command label, without a starting slash. - * - * @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(); + for (String label : labels) { + if (label.equalsIgnoreCase(element)) { + return true; + } + } + return false; } /** @@ -463,7 +412,7 @@ public class CommandDescription { */ public boolean isChild(CommandDescription commandDescription) { // Make sure the description is valid - if (commandDescription == null) // TODO: After builder, commandDescription == null -> never + if (commandDescription == null) return false; // Check whether this child exists, return the result @@ -482,10 +431,6 @@ public class CommandDescription { if (argument == null) return false; - // Make sure the argument isn't added already - if (hasArgument(argument)) - return true; - // Add the argument, return the result return this.arguments.add(argument); } @@ -499,81 +444,17 @@ public class CommandDescription { 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 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. * * @return True if this command has any arguments. */ 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(); + public boolean hasMaximumArguments() { + return !noArgumentMaximum; // TODO ljacqu 20151130 Change variable name } /** @@ -582,16 +463,7 @@ public class CommandDescription { * @return Command description. */ public String getDescription() { - return hasDescription() ? this.description : this.detailedDescription; - } - - /** - * Check whether this command has any description. - * - * @return True if this command has any description. - */ - public boolean hasDescription() { - return !StringUtils.isEmpty(description); + return description; } /** @@ -600,7 +472,7 @@ public class CommandDescription { * @return Command detailed description. */ public String getDetailedDescription() { - return !StringUtils.isEmpty(detailedDescription) ? this.detailedDescription : this.description; + return detailedDescription; } /** @@ -616,12 +488,13 @@ public class CommandDescription { return null; // Check whether this description is for the last element in the command reference, if so return the current command - if (queryReference.getCount() <= getParentCount() + 1) + if (queryReference.getCount() <= getParentCount() + 1) { return new FoundCommandResult( this, getCommandReference(queryReference), new CommandParts(), queryReference); + } // Get the new command reference and arguments CommandParts newReference = new CommandParts(queryReference.getRange(0, getParentCount() + 1)); @@ -665,28 +538,6 @@ public class CommandDescription { 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, * and get the difference in argument count. @@ -705,16 +556,18 @@ public class CommandDescription { int remainingElementCount = commandReference.getCount() - getParentCount() - 1; // Check if there are too few arguments - if (getMinimumArguments() > remainingElementCount) { - return Math.abs(getMinimumArguments() - remainingElementCount); + int minArguments = CommandUtils.getMinNumberOfArguments(this); + if (minArguments > remainingElementCount) { + return Math.abs(minArguments - remainingElementCount); } // Check if there are too many arguments - if (getMaximumArguments() < remainingElementCount && getMaximumArguments() >= 0) { - return Math.abs(remainingElementCount - getMaximumArguments()); + int maxArguments = CommandUtils.getMaxNumberOfArguments(this); + 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; } diff --git a/src/main/java/fr/xephi/authme/command/CommandHandler.java b/src/main/java/fr/xephi/authme/command/CommandHandler.java index 5290507ac..6a6a53207 100644 --- a/src/main/java/fr/xephi/authme/command/CommandHandler.java +++ b/src/main/java/fr/xephi/authme/command/CommandHandler.java @@ -2,11 +2,12 @@ package fr.xephi.authme.command; import fr.xephi.authme.AuthMe; import fr.xephi.authme.command.help.HelpProvider; +import fr.xephi.authme.util.StringUtils; import org.bukkit.ChatColor; +import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** @@ -15,6 +16,18 @@ import java.util.List; */ public class CommandHandler { + /** + * The threshold for assuming an existing command. If the difference is below this value, we assume + * that the user meant the similar command and we will run it. + */ + private static final double ASSUME_COMMAND_THRESHOLD = 0.12; + + /** + * The threshold for suggesting a similar command. If the difference is below this value, we will + * ask the player whether he meant the similar command. + */ + private static final double SUGGEST_COMMAND_THRESHOLD = 0.75; + /** * Process a command. * @@ -26,12 +39,11 @@ public class CommandHandler { * @return True if the command was executed, false otherwise. */ // TODO ljacqu 20151129: Rename onCommand() method to something not suggesting it is auto-invoked by an event - public boolean onCommand(CommandSender sender, org.bukkit.command.Command bukkitCommand, String bukkitCommandLabel, String[] bukkitArgs) { - // Process the arguments - List args = processArguments(bukkitArgs); + public boolean onCommand(CommandSender sender, Command bukkitCommand, String bukkitCommandLabel, String[] bukkitArgs) { + List commandArgs = skipEmptyArguments(bukkitArgs); - // Create a command reference, and make sure at least one command part is available - CommandParts commandReference = new CommandParts(bukkitCommandLabel, args); + // Make sure the command isn't empty (does this happen?) + CommandParts commandReference = new CommandParts(bukkitCommandLabel, commandArgs); if (commandReference.getCount() == 0) return false; @@ -47,12 +59,12 @@ public class CommandHandler { // Make sure the difference between the command reference and the actual command isn't too big 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 - if (commandDifference < 0.75) + if (commandDifference < SUGGEST_COMMAND_THRESHOLD) if (result.getCommandDescription() != null) sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/" + result.getCommandDescription().getCommandReference(commandReference) + ChatColor.YELLOW + "?"); @@ -113,33 +125,29 @@ public class CommandHandler { } /** - * Process the command arguments, and return them as an array list. + * Skips all entries of the given array that are simply whitespace. * - * @param args The command arguments to process. - * - * @return The processed command arguments. + * @param args The array to process + * @return List of the items that are not empty */ - private List processArguments(String[] args) { - // Convert the array into a list of arguments - List arguments = new ArrayList<>(Arrays.asList(args)); - - /// Remove all empty arguments - 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--; + private static List skipEmptyArguments(String[] args) { + List cleanArguments = new ArrayList<>(args.length); + for (String argument : args) { + if (!StringUtils.isEmpty(argument)) { + cleanArguments.add(argument); } } + 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; } /** @@ -170,4 +178,43 @@ public class CommandHandler { // 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. + */ + public CommandDescription findCommand(List 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 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 commands) { + if (commands == null) { + return null; + } + for (CommandDescription command : commands) { + if (command.getLabels().contains(label)) { + return command; + } + } + return null; + } } diff --git a/src/main/java/fr/xephi/authme/command/CommandParts.java b/src/main/java/fr/xephi/authme/command/CommandParts.java index 1c677f225..35e895746 100644 --- a/src/main/java/fr/xephi/authme/command/CommandParts.java +++ b/src/main/java/fr/xephi/authme/command/CommandParts.java @@ -162,17 +162,6 @@ public class CommandParts { 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. * diff --git a/src/main/java/fr/xephi/authme/command/CommandUtils.java b/src/main/java/fr/xephi/authme/command/CommandUtils.java new file mode 100644 index 000000000..f8e78c46e --- /dev/null +++ b/src/main/java/fr/xephi/authme/command/CommandUtils.java @@ -0,0 +1,21 @@ +package fr.xephi.authme.command; + +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.hasMaximumArguments() + ? command.getArguments().size() + : -1; + } + +} diff --git a/src/main/java/fr/xephi/authme/command/help/HelpPrinter.java b/src/main/java/fr/xephi/authme/command/help/HelpPrinter.java index d67647621..a3244c914 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpPrinter.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpPrinter.java @@ -5,6 +5,7 @@ import fr.xephi.authme.command.CommandArgumentDescription; import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandPermissions; +import fr.xephi.authme.command.CommandUtils; import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.util.StringUtils; import org.bukkit.ChatColor; @@ -39,9 +40,7 @@ public class HelpPrinter { * @param command The command to print the description help for. */ public static void printCommandDescription(CommandSender sender, CommandDescription command) { - // Print the regular description, if available - if (command.hasDescription()) - sender.sendMessage(ChatColor.GOLD + "Short Description: " + ChatColor.WHITE + command.getDescription()); + sender.sendMessage(ChatColor.GOLD + "Short Description: " + ChatColor.WHITE + command.getDescription()); // Print the detailed description, if available if (!StringUtils.isEmpty(command.getDetailedDescription())) { @@ -59,7 +58,7 @@ public class HelpPrinter { @SuppressWarnings("StringConcatenationInsideStringBufferAppend") public static void printArguments(CommandSender sender, CommandDescription command) { // Make sure there are any commands to print - if (!command.hasArguments() && command.getMaximumArguments() >= 0) + if (!command.hasArguments()) return; // Print the header @@ -80,7 +79,7 @@ public class HelpPrinter { } // Show the unlimited arguments argument - if (command.getMaximumArguments() < 0) + if (!command.hasMaximumArguments()) sender.sendMessage(" " + ChatColor.YELLOW + ChatColor.ITALIC + "... : " + ChatColor.WHITE + "Any additional arguments." + ChatColor.GRAY + ChatColor.ITALIC + " (Optional)"); } diff --git a/src/main/java/fr/xephi/authme/command/help/HelpSyntaxHelper.java b/src/main/java/fr/xephi/authme/command/help/HelpSyntaxHelper.java index 90a9c7716..024914c9a 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpSyntaxHelper.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpSyntaxHelper.java @@ -62,7 +62,7 @@ public final class HelpSyntaxHelper { } // Add some dots if the command allows unlimited arguments - if (commandDescription.getMaximumArguments() < 0) { + if (!commandDescription.hasMaximumArguments()) { sb.append(ChatColor.ITALIC).append(" ..."); } From 44eef346b90bc32521082cf2e3bfe4971c662ef0 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Mon, 30 Nov 2015 21:18:58 +0100 Subject: [PATCH 11/82] Add test to verify the format of command labels - Fix test class throwing NPE when run isolation -> attempts to get Logger from Wrapper --- ...rTest.java => CommandInitializerTest.java} | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) rename src/test/java/fr/xephi/authme/command/{CommandManagerTest.java => CommandInitializerTest.java} (91%) diff --git a/src/test/java/fr/xephi/authme/command/CommandManagerTest.java b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java similarity index 91% rename from src/test/java/fr/xephi/authme/command/CommandManagerTest.java rename to src/test/java/fr/xephi/authme/command/CommandInitializerTest.java index ff6a1a382..2cc424c01 100644 --- a/src/test/java/fr/xephi/authme/command/CommandManagerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java @@ -1,6 +1,7 @@ package fr.xephi.authme.command; import fr.xephi.authme.util.StringUtils; +import fr.xephi.authme.util.WrapperMock; import org.junit.BeforeClass; import org.junit.Test; @@ -10,6 +11,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Pattern; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; @@ -20,7 +22,7 @@ import static org.junit.Assert.fail; /** * 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. @@ -32,6 +34,7 @@ public class CommandManagerTest { @BeforeClass public static void initializeCommandManager() { + WrapperMock.createInstance(); commands = CommandInitializer.getBaseCommands(); } @@ -83,6 +86,27 @@ public class CommandManagerTest { 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 public void shouldNotDefineSameLabelTwice() { // given From 23e01c8b263e2bf92c12f25d5ef38a0fdd2edd08 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Tue, 1 Dec 2015 12:19:13 +0700 Subject: [PATCH 12/82] Create builder for PlayerAuth. --- .../xephi/authme/cache/auth/PlayerAuth.java | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java b/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java index 5b1273259..01622c177 100644 --- a/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java +++ b/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java @@ -497,4 +497,97 @@ public class PlayerAuth { this.y = Double.parseDouble(args[10]); this.z = Double.parseDouble(args[11]); } + + public static Builder builder() { + return new Builder(); + } + + public static final class Builder { + private String name; + private String realName; + private String hash; + private String salt; + private String ip; + private String world; + private double x; + private double y; + private double z; + private long lastLogin; + private int groupId; + private String email; + + public PlayerAuth build() { + return new PlayerAuth( + name, + hash, + salt, + groupId, + ip, + lastLogin, + x, y, z, world, + email, + realName + ); + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder realName(String realName) { + this.realName = realName; + return this; + } + + public Builder hash(String hash) { + this.hash = hash; + return this; + } + + public Builder salt(String salt) { + this.salt = salt; + return this; + } + + public Builder ip(String ip) { + this.ip = ip; + return this; + } + + public Builder locWorld(String world) { + this.world = world; + return this; + } + + public Builder locX(double x) { + this.x = x; + return this; + } + + public Builder locY(double y) { + this.y = y; + return this; + } + + public Builder locZ(double z) { + this.z = z; + return this; + } + + public Builder lastLogin(long lastLogin) { + this.lastLogin = lastLogin; + return this; + } + + public Builder groupId(int groupId) { + this.groupId = groupId; + return this; + } + + public Builder email(String email) { + this.email = email; + return this; + } + } } From 92f57090bee728849d40874559057ce600b2a717 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Tue, 1 Dec 2015 16:07:58 +0700 Subject: [PATCH 13/82] Set default value for the Builder --- .../xephi/authme/cache/auth/PlayerAuth.java | 93 +++++++++---------- 1 file changed, 45 insertions(+), 48 deletions(-) diff --git a/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java b/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java index 01622c177..618c50189 100644 --- a/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java +++ b/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java @@ -23,9 +23,8 @@ public class PlayerAuth { /** * */ - public PlayerAuth(String serialized) - { - this.unserialize(serialized); + public PlayerAuth(String serialized) { + this.deserialize(serialized); } /** @@ -455,47 +454,45 @@ public class PlayerAuth { } /** - * Method to serialize playerauth + * Method to serialize PlayerAuth * * @return String */ - public String serialize() - { - StringBuilder str = new StringBuilder(); - str.append(this.nickname).append(';'); - str.append(this.realName).append(';'); - str.append(this.ip).append(';'); - str.append(this.email).append(';'); - str.append(this.hash).append(';'); - str.append(this.salt).append(';'); - str.append(this.groupId).append(';'); - str.append(this.lastLogin).append(';'); - str.append(this.world).append(';'); - str.append(this.x).append(';'); - str.append(this.y).append(';'); - str.append(this.z); - return str.toString(); + public String serialize() { + StringBuilder str = new StringBuilder(); + char d = ';'; + str.append(this.nickname).append(d); + str.append(this.realName).append(d); + str.append(this.ip).append(d); + str.append(this.email).append(d); + str.append(this.hash).append(d); + str.append(this.salt).append(d); + str.append(this.groupId).append(d); + str.append(this.lastLogin).append(d); + str.append(this.world).append(d); + str.append(this.x).append(d); + str.append(this.y).append(d); + str.append(this.z); + return str.toString(); } /** - * Method to unserialize playerauth - * + * Method to deserialize PlayerAuth */ - public void unserialize(String str) - { - String[] args = str.split(";"); - this.nickname = args[0]; - this.realName = args[1]; - this.ip = args[2]; - this.email = args[3]; - this.hash = args[4]; - this.salt = args[5]; - this.groupId = Integer.parseInt(args[6]); - this.lastLogin = Long.parseLong(args[7]); - this.world = args[8]; - this.x = Double.parseDouble(args[9]); - this.y = Double.parseDouble(args[10]); - this.z = Double.parseDouble(args[11]); + public void deserialize(String str) { + String[] args = str.split(";"); + this.nickname = args[0]; + this.realName = args[1]; + this.ip = args[2]; + this.email = args[3]; + this.hash = args[4]; + this.salt = args[5]; + this.groupId = Integer.parseInt(args[6]); + this.lastLogin = Long.parseLong(args[7]); + this.world = args[8]; + this.x = Double.parseDouble(args[9]); + this.y = Double.parseDouble(args[10]); + this.z = Double.parseDouble(args[11]); } public static Builder builder() { @@ -504,17 +501,17 @@ public class PlayerAuth { public static final class Builder { private String name; - private String realName; - private String hash; - private String salt; - private String ip; - private String world; - private double x; - private double y; - private double z; - private long lastLogin; - private int groupId; - private String email; + private String realName = "Player"; + private String hash = ""; + private String salt = ""; + private String ip = "127.0.0.1"; + private String world = "world"; + private double x = 0.0f; + private double y = 0.0f; + private double z = 0.0f; + private long lastLogin = System.currentTimeMillis(); + private int groupId = -1; + private String email = "your@email.com"; public PlayerAuth build() { return new PlayerAuth( From 00c6b17f3e5a88570f459a831c813eecb1ac34c5 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Tue, 1 Dec 2015 15:42:02 +0100 Subject: [PATCH 14/82] Add customizable anto bot message --- .../java/fr/xephi/authme/listener/AuthMePlayerListener.java | 2 +- src/main/java/fr/xephi/authme/settings/MessageKey.java | 2 ++ src/main/resources/messages/messages_en.yml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java index 8400d572f..03c3f70f8 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java @@ -288,7 +288,7 @@ public class AuthMePlayerListener implements Listener { // TODO: Add message to the messages file!!! if (Settings.isKickNonRegisteredEnabled && !isAuthAvailable) { if (Settings.antiBotInAction) { - event.setKickMessage("AntiBot service in action! You actually need to be registered!"); + event.setKickMessage(m.retrieveSingle(MessageKey.KICK_ANTIBOT)); event.setResult(PlayerLoginEvent.Result.KICK_OTHER); return; } else { diff --git a/src/main/java/fr/xephi/authme/settings/MessageKey.java b/src/main/java/fr/xephi/authme/settings/MessageKey.java index 2fc1520ad..72e71b631 100644 --- a/src/main/java/fr/xephi/authme/settings/MessageKey.java +++ b/src/main/java/fr/xephi/authme/settings/MessageKey.java @@ -5,6 +5,8 @@ package fr.xephi.authme.settings; */ public enum MessageKey { + KICK_ANTIBOT("kick_antibot"), + UNKNOWN_USER("unknown_user"), UNSAFE_QUIT_LOCATION("unsafe_spawn"), diff --git a/src/main/resources/messages/messages_en.yml b/src/main/resources/messages/messages_en.yml index dd191d24c..fdb361a31 100644 --- a/src/main/resources/messages/messages_en.yml +++ b/src/main/resources/messages/messages_en.yml @@ -1,3 +1,4 @@ +kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.' unknown_user: '&cCan''t find the requested user in the database!' unsafe_spawn: '&cYour quit location was unsafe, you have been teleported to the world''s spawnpoint.' not_logged_in: '&cYou''re not logged in!' From 3b9b1b7b8a2416845cef7dd62f35214c84937972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:14:59 +0100 Subject: [PATCH 15/82] Refactored name of command builder, to specify it a little better --- .../authme/command/CommandDescription.java | 26 +++++++++---------- .../command/help/HelpSyntaxHelperTest.java | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/fr/xephi/authme/command/CommandDescription.java b/src/main/java/fr/xephi/authme/command/CommandDescription.java index 3a5342461..44989a20b 100644 --- a/src/main/java/fr/xephi/authme/command/CommandDescription.java +++ b/src/main/java/fr/xephi/authme/command/CommandDescription.java @@ -735,11 +735,11 @@ public class CommandDescription { this.permissions = new CommandPermissions(permissionNode, defaultPermission); } - public static Builder builder() { - return new Builder(); + public static CommandBuilder builder() { + return new CommandBuilder(); } - public static final class Builder { + public static final class CommandBuilder { private List labels; private String description; private String detailedDescription; @@ -767,47 +767,47 @@ public class CommandDescription { ); } - public Builder labels(List labels) { + public CommandBuilder labels(List labels) { this.labels = labels; return this; } - public Builder labels(String... labels) { + public CommandBuilder labels(String... labels) { return labels(asMutableList(labels)); } - public Builder description(String description) { + public CommandBuilder description(String description) { this.description = description; return this; } - public Builder detailedDescription(String detailedDescription) { + public CommandBuilder detailedDescription(String detailedDescription) { this.detailedDescription = detailedDescription; return this; } - public Builder executableCommand(ExecutableCommand executableCommand) { + public CommandBuilder executableCommand(ExecutableCommand executableCommand) { this.executableCommand = executableCommand; return this; } - public Builder parent(CommandDescription parent) { + public CommandBuilder parent(CommandDescription parent) { this.parent = parent; return this; } - public Builder withArgument(String label, String description, boolean isOptional) { + public CommandBuilder withArgument(String label, String description, boolean isOptional) { arguments.add(new CommandArgumentDescription(label, description, isOptional)); return this; } - public Builder noArgumentMaximum(boolean noArgumentMaximum) { + public CommandBuilder noArgumentMaximum(boolean noArgumentMaximum) { this.noArgumentMaximum = noArgumentMaximum; return this; } - public Builder permissions(CommandPermissions.DefaultPermission defaultPermission, - PermissionNode... permissionNodes) { + public CommandBuilder permissions(CommandPermissions.DefaultPermission defaultPermission, + PermissionNode... permissionNodes) { this.permissions = new CommandPermissions(asMutableList(permissionNodes), defaultPermission); return this; } diff --git a/src/test/java/fr/xephi/authme/command/help/HelpSyntaxHelperTest.java b/src/test/java/fr/xephi/authme/command/help/HelpSyntaxHelperTest.java index 1c3b45146..496dd93fb 100644 --- a/src/test/java/fr/xephi/authme/command/help/HelpSyntaxHelperTest.java +++ b/src/test/java/fr/xephi/authme/command/help/HelpSyntaxHelperTest.java @@ -131,7 +131,7 @@ public class HelpSyntaxHelperTest { } - private static CommandDescription.Builder getDescriptionBuilder() { + private static CommandDescription.CommandBuilder getDescriptionBuilder() { CommandDescription base = CommandDescription.builder() .labels("authme") .description("Base command") From 8bea153005b3d4ca8c365f6dc87fd83a59531731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:17:37 +0100 Subject: [PATCH 16/82] Rebased administration command permission nodes --- .../xephi/authme/command/CommandManager.java | 22 ----------- .../authme/permission/AdminPermission.java | 37 +++++++++---------- 2 files changed, 18 insertions(+), 41 deletions(-) diff --git a/src/main/java/fr/xephi/authme/command/CommandManager.java b/src/main/java/fr/xephi/authme/command/CommandManager.java index cc335561c..5769e0554 100644 --- a/src/main/java/fr/xephi/authme/command/CommandManager.java +++ b/src/main/java/fr/xephi/authme/command/CommandManager.java @@ -136,7 +136,6 @@ public class CommandManager { // Register the getemail command CommandDescription getEmailCommand = new CommandDescription(new GetEmailCommand(), new ArrayList() { - { add("getemail"); add("getmail"); @@ -149,7 +148,6 @@ public class CommandManager { // Register the setemail command CommandDescription setEmailCommand = new CommandDescription(new SetEmailCommand(), new ArrayList() { - { add("chgemail"); add("chgmail"); @@ -163,7 +161,6 @@ public class CommandManager { // Register the getip command CommandDescription getIpCommand = new CommandDescription(new GetIpCommand(), new ArrayList() { - { add("getip"); add("ip"); @@ -174,7 +171,6 @@ public class CommandManager { // Register the spawn command CommandDescription spawnCommand = new CommandDescription(new SpawnCommand(), new ArrayList() { - { add("spawn"); add("home"); @@ -184,7 +180,6 @@ public class CommandManager { // Register the setspawn command CommandDescription setSpawnCommand = new CommandDescription(new SetSpawnCommand(), new ArrayList() { - { add("setspawn"); add("chgspawn"); @@ -194,7 +189,6 @@ public class CommandManager { // Register the firstspawn command CommandDescription firstSpawnCommand = new CommandDescription(new FirstSpawnCommand(), new ArrayList() { - { add("firstspawn"); add("firsthome"); @@ -204,7 +198,6 @@ public class CommandManager { // Register the setfirstspawn command CommandDescription setFirstSpawnCommand = new CommandDescription(new SetFirstSpawnCommand(), new ArrayList() { - { add("setfirstspawn"); add("chgfirstspawn"); @@ -214,7 +207,6 @@ public class CommandManager { // Register the purge command CommandDescription purgeCommand = new CommandDescription(new PurgeCommand(), new ArrayList() { - { add("purge"); add("delete"); @@ -225,7 +217,6 @@ public class CommandManager { // Register the purgelastposition command CommandDescription purgeLastPositionCommand = new CommandDescription(new PurgeLastPositionCommand(), new ArrayList() { - { add("resetpos"); add("purgelastposition"); @@ -240,7 +231,6 @@ public class CommandManager { // Register the purgebannedplayers command CommandDescription purgeBannedPlayersCommand = new CommandDescription(new PurgeBannedPlayersCommand(), new ArrayList() { - { add("purgebannedplayers"); add("purgebannedplayer"); @@ -252,7 +242,6 @@ public class CommandManager { // Register the switchantibot command CommandDescription switchAntiBotCommand = new CommandDescription(new SwitchAntiBotCommand(), new ArrayList() { - { add("switchantibot"); add("toggleantibot"); @@ -277,7 +266,6 @@ public class CommandManager { // Register the reload command CommandDescription reloadCommand = new CommandDescription(new ReloadCommand(), new ArrayList() { - { add("reload"); add("rld"); @@ -313,7 +301,6 @@ public class CommandManager { // Register the base logout command CommandDescription logoutBaseCommand = new CommandDescription(new LogoutCommand(), new ArrayList() { - { add("logout"); } @@ -327,7 +314,6 @@ public class CommandManager { // Register the base register command CommandDescription registerBaseCommand = new CommandDescription(new fr.xephi.authme.command.executable.register.RegisterCommand(), new ArrayList() { - { add("register"); add("reg"); @@ -344,7 +330,6 @@ public class CommandManager { // Register the base unregister command CommandDescription unregisterBaseCommand = new CommandDescription(new fr.xephi.authme.command.executable.unregister.UnregisterCommand(), new ArrayList() { - { add("unregister"); add("unreg"); @@ -359,7 +344,6 @@ public class CommandManager { // Register the base changepassword command CommandDescription changePasswordBaseCommand = new CommandDescription(new fr.xephi.authme.command.executable.changepassword.ChangePasswordCommand(), new ArrayList() { - { add("changepassword"); add("changepass"); @@ -376,7 +360,6 @@ public class CommandManager { // Register the base Dungeon Maze command CommandDescription emailBaseCommand = new CommandDescription(helpCommandExecutable, new ArrayList() { - { add("email"); add("mail"); @@ -390,7 +373,6 @@ public class CommandManager { // Register the add command CommandDescription addEmailCommand = new CommandDescription(new AddEmailCommand(), new ArrayList() { - { add("add"); add("addemail"); @@ -403,7 +385,6 @@ public class CommandManager { // Register the change command CommandDescription changeEmailCommand = new CommandDescription(new ChangeEmailCommand(), new ArrayList() { - { add("change"); add("changeemail"); @@ -416,7 +397,6 @@ public class CommandManager { // Register the recover command CommandDescription recoverEmailCommand = new CommandDescription(new RecoverEmailCommand(), new ArrayList() { - { add("recover"); add("recovery"); @@ -429,7 +409,6 @@ public class CommandManager { // Register the base captcha command CommandDescription captchaBaseCommand = new CommandDescription(new CaptchaCommand(), new ArrayList() { - { add("captcha"); add("capt"); @@ -445,7 +424,6 @@ public class CommandManager { // Register the base converter command CommandDescription converterBaseCommand = new CommandDescription(new ConverterCommand(), new ArrayList() { - { add("converter"); add("convert"); diff --git a/src/main/java/fr/xephi/authme/permission/AdminPermission.java b/src/main/java/fr/xephi/authme/permission/AdminPermission.java index 846c83227..979328bd3 100644 --- a/src/main/java/fr/xephi/authme/permission/AdminPermission.java +++ b/src/main/java/fr/xephi/authme/permission/AdminPermission.java @@ -5,41 +5,41 @@ package fr.xephi.authme.permission; */ public enum AdminPermission implements PermissionNode { - REGISTER("authme.admin.register"), + REGISTER("authme.command.admin.register"), - UNREGISTER("authme.admin.unregister"), + UNREGISTER("authme.command.admin.unregister"), - FORCE_LOGIN("authme.admin.forcelogin"), + FORCE_LOGIN("authme.command.admin.forcelogin"), - CHANGE_PASSWORD("authme.admin.changepassword"), + CHANGE_PASSWORD("authme.command.admin.changepassword"), - LAST_LOGIN("authme.admin.lastlogin"), + LAST_LOGIN("authme.command.admin.lastlogin"), - ACCOUNTS("authme.admin.accounts"), + ACCOUNTS("authme.command.admin.accounts"), - GET_EMAIL("authme.admin.getemail"), + GET_EMAIL("authme.command.admin.getemail"), - CHANGE_EMAIL("authme.admin.chgemail"), + CHANGE_EMAIL("authme.command.admin.chgemail"), - GET_IP("authme.admin.getip"), + GET_IP("authme.command.admin.getip"), - SPAWN("authme.admin.spawn"), + SPAWN("authme.command.admin.spawn"), - SET_SPAWN("authme.admin.setspawn"), + SET_SPAWN("authme.command.admin.setspawn"), - FIRST_SPAWN("authme.admin.firstspawn"), + FIRST_SPAWN("authme.command.admin.firstspawn"), - SET_FIRST_SPAWN("authme.admin.setfirstspawn"), + SET_FIRST_SPAWN("authme.command.admin.setfirstspawn"), - PURGE("authme.admin.purge"), + PURGE("authme.command.admin.purge"), - PURGE_LAST_POSITION("authme.admin.purgelastpos"), + PURGE_LAST_POSITION("authme.command.admin.purgelastpos"), - PURGE_BANNED_PLAYERS("authme.admin.purgebannedplayers"), + PURGE_BANNED_PLAYERS("authme.command.admin.purgebannedplayers"), - SWITCH_ANTIBOT("authme.admin.switchantibot"), + SWITCH_ANTIBOT("authme.command.admin.switchantibot"), - RELOAD("authme.admin.reload"); + RELOAD("authme.command.admin.reload"); private String node; @@ -51,5 +51,4 @@ public enum AdminPermission implements PermissionNode { AdminPermission(String node) { this.node = node; } - } From 7f54838ad4bc552de1cc1ca6b50e811170b10e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:18:16 +0100 Subject: [PATCH 17/82] Rebased player command permission nodes --- .../authme/permission/UserPermission.java | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/main/java/fr/xephi/authme/permission/UserPermission.java b/src/main/java/fr/xephi/authme/permission/UserPermission.java index 30c3dc877..b0653e62a 100644 --- a/src/main/java/fr/xephi/authme/permission/UserPermission.java +++ b/src/main/java/fr/xephi/authme/permission/UserPermission.java @@ -5,37 +5,37 @@ package fr.xephi.authme.permission; */ public enum UserPermission implements PermissionNode { - BYPASS_ANTIBOT("authme.bypassantibot"), + BYPASS_ANTIBOT("authme.command.player.bypassantibot"), - IS_VIP("authme.vip"), + IS_VIP("authme.command.player.vip"), - LOGIN("authme.login"), + LOGIN("authme.command.player.login"), - LOGOUT("authme.logout"), + LOGOUT("authme.command.player.logout"), - REGISTER("authme.register"), + REGISTER("authme.command.player.register"), - UNREGISTER("authme.unregister"), + UNREGISTER("authme.command.player.unregister"), - CHANGE_PASSWORD("authme.changepassword"), + CHANGE_PASSWORD("authme.command.player.changepassword"), - ADD_EMAIL("authme.email.add"), + ADD_EMAIL("authme.command.player.email.add"), - CHANGE_EMAIL("authme.email.change"), + CHANGE_EMAIL("authme.command.player.email.change"), - RECOVER_EMAIL("authme.email.recover"), + RECOVER_EMAIL("authme.command.player.email.recover"), - CAPTCHA("authme.captcha"), + CAPTCHA("authme.command.player.captcha"), - CONVERTER("authme.converter"), + CONVERTER("authme.command.player.converter"), - CAN_LOGIN_BE_FORCED("authme.canbeforced"), + CAN_LOGIN_BE_FORCED("authme.command.player.canbeforced"), - BYPASS_FORCE_SURVIVAL("authme.bypassforcesurvival"), + BYPASS_FORCE_SURVIVAL("authme.command.player.bypassforcesurvival"), - ALLOW_MULTIPLE_ACCOUNTS("authme.allow2accounts"), + ALLOW_MULTIPLE_ACCOUNTS("authme.command.player.allow2accounts"), - SEE_OTHER_ACCOUNTS("authme.seeOtherAccounts"); + SEE_OTHER_ACCOUNTS("authme.command.player.seeOtherAccounts"); private String node; @@ -47,6 +47,4 @@ public enum UserPermission implements PermissionNode { UserPermission(String node) { this.node = node; } - - } From fdc747d007bc60a425b46a9612b6a4be8c23d2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:19:05 +0100 Subject: [PATCH 18/82] Refactored player permissions enum, to make the name suit better --- src/main/java/fr/xephi/authme/AntiBot.java | 4 +-- src/main/java/fr/xephi/authme/AuthMe.java | 4 +-- .../xephi/authme/command/CommandManager.java | 30 +++++++++---------- .../executable/authme/ForceLoginCommand.java | 4 +-- .../authme/listener/AuthMePlayerListener.java | 10 +++---- ...rPermission.java => PlayerPermission.java} | 6 ++-- .../process/email/AsyncChangeEmail.java | 4 +-- .../authme/process/join/AsynchronousJoin.java | 4 +-- .../process/login/AsynchronousLogin.java | 6 ++-- .../process/register/AsyncRegister.java | 8 ++--- src/main/java/fr/xephi/authme/util/Utils.java | 4 +-- ...ionTest.java => PlayerPermissionTest.java} | 8 ++--- .../java/fr/xephi/authme/util/UtilsTest.java | 8 ++--- 13 files changed, 50 insertions(+), 50 deletions(-) rename src/main/java/fr/xephi/authme/permission/{UserPermission.java => PlayerPermission.java} (87%) rename src/test/java/fr/xephi/authme/permission/{UserPermissionTest.java => PlayerPermissionTest.java} (84%) diff --git a/src/main/java/fr/xephi/authme/AntiBot.java b/src/main/java/fr/xephi/authme/AntiBot.java index 194e4cdf6..afe7e2b68 100644 --- a/src/main/java/fr/xephi/authme/AntiBot.java +++ b/src/main/java/fr/xephi/authme/AntiBot.java @@ -1,6 +1,6 @@ package fr.xephi.authme; -import fr.xephi.authme.permission.UserPermission; +import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.settings.Messages; import fr.xephi.authme.settings.Settings; @@ -73,7 +73,7 @@ public class AntiBot { if (antiBotStatus == AntiBotStatus.ACTIVE || antiBotStatus == AntiBotStatus.DISABLED) { return; } - if (plugin.getPermissionsManager().hasPermission(player, UserPermission.BYPASS_ANTIBOT)) { + if (plugin.getPermissionsManager().hasPermission(player, PlayerPermission.BYPASS_ANTIBOT)) { return; } diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 4f1886fcd..4b07701f7 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -18,7 +18,7 @@ import fr.xephi.authme.hooks.EssSpawn; import fr.xephi.authme.listener.*; import fr.xephi.authme.modules.ModuleManager; import fr.xephi.authme.permission.PermissionsManager; -import fr.xephi.authme.permission.UserPermission; +import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.process.Management; import fr.xephi.authme.settings.*; import fr.xephi.authme.util.GeoLiteAPI; @@ -735,7 +735,7 @@ public class AuthMe extends JavaPlugin { public Player generateKickPlayer(Collection collection) { Player player = null; for (Player p : collection) { - if (!getPermissionsManager().hasPermission(p, UserPermission.IS_VIP)) { + if (!getPermissionsManager().hasPermission(p, PlayerPermission.IS_VIP)) { player = p; break; } diff --git a/src/main/java/fr/xephi/authme/command/CommandManager.java b/src/main/java/fr/xephi/authme/command/CommandManager.java index 5769e0554..4d4f3f5c7 100644 --- a/src/main/java/fr/xephi/authme/command/CommandManager.java +++ b/src/main/java/fr/xephi/authme/command/CommandManager.java @@ -10,7 +10,7 @@ import fr.xephi.authme.command.executable.email.RecoverEmailCommand; import fr.xephi.authme.command.executable.login.LoginCommand; import fr.xephi.authme.command.executable.logout.LogoutCommand; import fr.xephi.authme.permission.AdminPermission; -import fr.xephi.authme.permission.UserPermission; +import fr.xephi.authme.permission.PlayerPermission; import java.util.ArrayList; import java.util.Arrays; @@ -73,7 +73,7 @@ public class CommandManager { .description("Register a player") .detailedDescription("Register the specified player with the specified password.") .parent(authMeBaseCommand) - .permissions(OP_ONLY, UserPermission.REGISTER) + .permissions(OP_ONLY, PlayerPermission.REGISTER) .withArgument("player", "Player name", false) .withArgument("password", "Password", false) .build(); @@ -85,7 +85,7 @@ public class CommandManager { .description("Unregister a player") .detailedDescription("Unregister the specified player.") .parent(authMeBaseCommand) - .permissions(OP_ONLY, UserPermission.UNREGISTER) + .permissions(OP_ONLY, PlayerPermission.UNREGISTER) .withArgument("player", "Player name", false) .build(); @@ -96,7 +96,7 @@ public class CommandManager { .description("Enforce login player") .detailedDescription("Enforce the specified player to login.") .parent(authMeBaseCommand) - .permissions(OP_ONLY, UserPermission.CAN_LOGIN_BE_FORCED) + .permissions(OP_ONLY, PlayerPermission.CAN_LOGIN_BE_FORCED) .withArgument("player", "Online player name", true) .build(); @@ -107,7 +107,7 @@ public class CommandManager { .description("Change a player's password") .detailedDescription("Change the password of a player.") .parent(authMeBaseCommand) - .permissions(OP_ONLY, UserPermission.CHANGE_PASSWORD) + .permissions(OP_ONLY, PlayerPermission.CHANGE_PASSWORD) .withArgument("player", "Player name", false) .withArgument("pwd", "New password", false) .build(); @@ -290,7 +290,7 @@ public class CommandManager { .description("Login command") .detailedDescription("Command to log in using AuthMeReloaded.") .parent(null) - .permissions(ALLOWED, UserPermission.LOGIN) + .permissions(ALLOWED, PlayerPermission.LOGIN) .withArgument("password", "Login password", false) .build(); @@ -305,7 +305,7 @@ public class CommandManager { add("logout"); } }, "Logout command", "Command to logout using AuthMeReloaded.", null); - logoutBaseCommand.setCommandPermissions(UserPermission.LOGOUT, CommandPermissions.DefaultPermission.ALLOWED); + logoutBaseCommand.setCommandPermissions(PlayerPermission.LOGOUT, CommandPermissions.DefaultPermission.ALLOWED); // Register the help command CommandDescription logoutHelpCommand = new CommandDescription(helpCommandExecutable, helpCommandLabels, @@ -319,7 +319,7 @@ public class CommandManager { add("reg"); } }, "Registration command", "Command to register using AuthMeReloaded.", null); - registerBaseCommand.setCommandPermissions(UserPermission.REGISTER, CommandPermissions.DefaultPermission.ALLOWED); + registerBaseCommand.setCommandPermissions(PlayerPermission.REGISTER, CommandPermissions.DefaultPermission.ALLOWED); registerBaseCommand.addArgument(new CommandArgumentDescription("password", "Password", false)); registerBaseCommand.addArgument(new CommandArgumentDescription("verifyPassword", "Verify password", false)); @@ -335,7 +335,7 @@ public class CommandManager { add("unreg"); } }, "Unregistration command", "Command to unregister using AuthMeReloaded.", null); - unregisterBaseCommand.setCommandPermissions(UserPermission.UNREGISTER, CommandPermissions.DefaultPermission.ALLOWED); + unregisterBaseCommand.setCommandPermissions(PlayerPermission.UNREGISTER, CommandPermissions.DefaultPermission.ALLOWED); unregisterBaseCommand.addArgument(new CommandArgumentDescription("password", "Password", false)); // Register the help command @@ -349,7 +349,7 @@ public class CommandManager { add("changepass"); } }, "Change password command", "Command to change your password using AuthMeReloaded.", null); - changePasswordBaseCommand.setCommandPermissions(UserPermission.CHANGE_PASSWORD, CommandPermissions.DefaultPermission.ALLOWED); + changePasswordBaseCommand.setCommandPermissions(PlayerPermission.CHANGE_PASSWORD, CommandPermissions.DefaultPermission.ALLOWED); changePasswordBaseCommand.addArgument(new CommandArgumentDescription("password", "Password", false)); changePasswordBaseCommand.addArgument(new CommandArgumentDescription("verifyPassword", "Verify password", false)); @@ -379,7 +379,7 @@ public class CommandManager { add("addmail"); } }, "Add E-mail", "Add an new E-Mail address to your account.", emailBaseCommand); - addEmailCommand.setCommandPermissions(UserPermission.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("verifyEmail", "Email address verification", false)); @@ -391,7 +391,7 @@ public class CommandManager { add("changemail"); } }, "Change E-mail", "Change an E-Mail address of your account.", emailBaseCommand); - changeEmailCommand.setCommandPermissions(UserPermission.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("newEmail", "New email address", false)); @@ -404,7 +404,7 @@ public class CommandManager { add("recovermail"); } }, "Recover using E-mail", "Recover your account using an E-mail address.", emailBaseCommand); - recoverEmailCommand.setCommandPermissions(UserPermission.RECOVER_EMAIL, CommandPermissions.DefaultPermission.ALLOWED); + recoverEmailCommand.setCommandPermissions(PlayerPermission.RECOVER_EMAIL, CommandPermissions.DefaultPermission.ALLOWED); recoverEmailCommand.addArgument(new CommandArgumentDescription("email", "Email address", false)); // Register the base captcha command @@ -414,7 +414,7 @@ public class CommandManager { add("capt"); } }, "Captcha command", "Captcha command for AuthMeReloaded.", null); - captchaBaseCommand.setCommandPermissions(UserPermission.CAPTCHA, CommandPermissions.DefaultPermission.ALLOWED); + captchaBaseCommand.setCommandPermissions(PlayerPermission.CAPTCHA, CommandPermissions.DefaultPermission.ALLOWED); captchaBaseCommand.addArgument(new CommandArgumentDescription("captcha", "The captcha", false)); // Register the help command @@ -430,7 +430,7 @@ public class CommandManager { add("conv"); } }, "Convert command", "Convert command for AuthMeReloaded.", null); - converterBaseCommand.setCommandPermissions(UserPermission.CONVERTER, OP_ONLY); + converterBaseCommand.setCommandPermissions(PlayerPermission.CONVERTER, OP_ONLY); converterBaseCommand.addArgument(new CommandArgumentDescription("job", "Conversion job: flattosql / flattosqlite /| xauth / crazylogin / rakamak / royalauth / vauth / sqltoflat", false)); // Register the help command diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ForceLoginCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ForceLoginCommand.java index 7d8c99792..b5fa337eb 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/ForceLoginCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/ForceLoginCommand.java @@ -3,7 +3,7 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.AuthMe; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; -import fr.xephi.authme.permission.UserPermission; +import fr.xephi.authme.permission.PlayerPermission; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -30,7 +30,7 @@ public class ForceLoginCommand extends ExecutableCommand { sender.sendMessage("Player needs to be online!"); return true; } - if (!plugin.getPermissionsManager().hasPermission(player, UserPermission.CAN_LOGIN_BE_FORCED)) { + if (!plugin.getPermissionsManager().hasPermission(player, PlayerPermission.CAN_LOGIN_BE_FORCED)) { sender.sendMessage("You cannot force login for the player " + playerName + "!"); return true; } diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java index 03c3f70f8..095484e5d 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java @@ -10,7 +10,7 @@ import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.permission.PermissionsManager; -import fr.xephi.authme.permission.UserPermission; +import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.settings.Messages; import fr.xephi.authme.settings.Settings; @@ -254,7 +254,7 @@ public class AuthMePlayerListener implements Listener { PermissionsManager permsMan = plugin.getPermissionsManager(); final Player player = event.getPlayer(); - if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL && !permsMan.hasPermission(player, UserPermission.IS_VIP)) { + if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL && !permsMan.hasPermission(player, PlayerPermission.IS_VIP)) { event.setKickMessage(m.retrieveSingle(MessageKey.KICK_FULL_SERVER)); event.setResult(PlayerLoginEvent.Result.KICK_FULL); return; @@ -267,7 +267,7 @@ public class AuthMePlayerListener implements Listener { final String name = player.getName().toLowerCase(); boolean isAuthAvailable = plugin.database.isAuthAvailable(name); - if (!Settings.countriesBlacklist.isEmpty() && !isAuthAvailable && !permsMan.hasPermission(player, UserPermission.BYPASS_ANTIBOT)) { + if (!Settings.countriesBlacklist.isEmpty() && !isAuthAvailable && !permsMan.hasPermission(player, PlayerPermission.BYPASS_ANTIBOT)) { String code = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress()); if (Settings.countriesBlacklist.contains(code)) { event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR)); @@ -276,7 +276,7 @@ public class AuthMePlayerListener implements Listener { } } - if (Settings.enableProtection && !Settings.countries.isEmpty() && !isAuthAvailable && !permsMan.hasPermission(player, UserPermission.BYPASS_ANTIBOT)) { + if (Settings.enableProtection && !Settings.countries.isEmpty() && !isAuthAvailable && !permsMan.hasPermission(player, PlayerPermission.BYPASS_ANTIBOT)) { String code = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress()); if (!Settings.countries.contains(code)) { event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR)); @@ -464,7 +464,7 @@ public class AuthMePlayerListener implements Listener { Player player = event.getPlayer(); if (player == null) return; - if (plugin.getPermissionsManager().hasPermission(player, UserPermission.BYPASS_FORCE_SURVIVAL)) + if (plugin.getPermissionsManager().hasPermission(player, PlayerPermission.BYPASS_FORCE_SURVIVAL)) return; if (Utils.checkAuth(player)) return; diff --git a/src/main/java/fr/xephi/authme/permission/UserPermission.java b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java similarity index 87% rename from src/main/java/fr/xephi/authme/permission/UserPermission.java rename to src/main/java/fr/xephi/authme/permission/PlayerPermission.java index b0653e62a..739845196 100644 --- a/src/main/java/fr/xephi/authme/permission/UserPermission.java +++ b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java @@ -1,9 +1,9 @@ package fr.xephi.authme.permission; /** - * AuthMe user permission nodes. + * AuthMe player permission nodes, for regular players. */ -public enum UserPermission implements PermissionNode { +public enum PlayerPermission implements PermissionNode { BYPASS_ANTIBOT("authme.command.player.bypassantibot"), @@ -44,7 +44,7 @@ public enum UserPermission implements PermissionNode { return node; } - UserPermission(String node) { + PlayerPermission(String node) { this.node = node; } } diff --git a/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java b/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java index be186598c..b6cb623dc 100644 --- a/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java +++ b/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java @@ -4,7 +4,7 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; -import fr.xephi.authme.permission.UserPermission; +import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.settings.Messages; import fr.xephi.authme.settings.Settings; @@ -39,7 +39,7 @@ public class AsyncChangeEmail { String playerName = player.getName().toLowerCase(); if (Settings.getmaxRegPerEmail > 0) { - if (!plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) + if (!plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS) && plugin.database.getAllAuthsByEmail(newEmail).size() >= Settings.getmaxRegPerEmail) { m.send(player, MessageKey.MAX_REGISTER_EXCEEDED); return; diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java index aa49d3f29..cee3a687c 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -10,7 +10,7 @@ import fr.xephi.authme.events.FirstSpawnTeleportEvent; import fr.xephi.authme.events.ProtectInventoryEvent; import fr.xephi.authme.events.SpawnTeleportEvent; import fr.xephi.authme.listener.AuthMePlayerListener; -import fr.xephi.authme.permission.UserPermission; +import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.settings.Messages; import fr.xephi.authme.settings.Settings; @@ -95,7 +95,7 @@ public class AsynchronousJoin { return; } if (Settings.getMaxJoinPerIp > 0 - && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) + && !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS) && !ip.equalsIgnoreCase("127.0.0.1") && !ip.equalsIgnoreCase("localhost")) { if (plugin.hasJoinedIp(player.getName(), ip)) { diff --git a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java index aae9397f3..1333fd98d 100644 --- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java @@ -8,7 +8,7 @@ import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent; import fr.xephi.authme.listener.AuthMePlayerListener; -import fr.xephi.authme.permission.UserPermission; +import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.RandomString; import fr.xephi.authme.settings.MessageKey; @@ -120,7 +120,7 @@ public class AsynchronousLogin { } return null; } - if (Settings.getMaxLoginPerIp > 0 && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) && !getIP().equalsIgnoreCase("127.0.0.1") && !getIP().equalsIgnoreCase("localhost")) { + if (Settings.getMaxLoginPerIp > 0 && !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS) && !getIP().equalsIgnoreCase("127.0.0.1") && !getIP().equalsIgnoreCase("localhost")) { if (plugin.isLoggedIp(name, getIP())) { m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); return null; @@ -268,7 +268,7 @@ public class AsynchronousLogin { * uuidaccounts + "."; } } */ for (Player player : Utils.getOnlinePlayers()) { - if (plugin.getPermissionsManager().hasPermission(player, UserPermission.SEE_OTHER_ACCOUNTS)) { + if (plugin.getPermissionsManager().hasPermission(player, PlayerPermission.SEE_OTHER_ACCOUNTS)) { player.sendMessage("[AuthMe] The player " + auth.getNickname() + " has " + auths.size() + " accounts"); player.sendMessage(message.toString()); // player.sendMessage(uuidaccounts.replace("%size%", diff --git a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java index 0007ccf3c..6aaac37fe 100644 --- a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java @@ -5,7 +5,7 @@ import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.permission.UserPermission; +import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.settings.MessageKey; import fr.xephi.authme.settings.Messages; @@ -65,7 +65,7 @@ public class AsyncRegister { m.send(player, MessageKey.NAME_ALREADY_REGISTERED); return false; } else if (Settings.getmaxRegPerIp > 0 - && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) + && !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS) && database.getAllAuthsByIp(getIp()).size() >= Settings.getmaxRegPerIp && !getIp().equalsIgnoreCase("127.0.0.1") && !getIp().equalsIgnoreCase("localhost")) { @@ -82,7 +82,7 @@ public class AsyncRegister { } if (!email.isEmpty() && !email.equals("")) { if (Settings.getmaxRegPerEmail > 0 - && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) + && !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS) && database.getAllAuthsByEmail(email).size() >= Settings.getmaxRegPerEmail) { m.send(player, MessageKey.MAX_REGISTER_EXCEEDED); return; @@ -100,7 +100,7 @@ public class AsyncRegister { protected void emailRegister() throws Exception { if (Settings.getmaxRegPerEmail > 0 - && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) + && !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS) && database.getAllAuthsByEmail(email).size() >= Settings.getmaxRegPerEmail) { m.send(player, MessageKey.MAX_REGISTER_EXCEEDED); return; diff --git a/src/main/java/fr/xephi/authme/util/Utils.java b/src/main/java/fr/xephi/authme/util/Utils.java index e3e298b94..5005b8439 100644 --- a/src/main/java/fr/xephi/authme/util/Utils.java +++ b/src/main/java/fr/xephi/authme/util/Utils.java @@ -7,7 +7,7 @@ import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.events.AuthMeTeleportEvent; import fr.xephi.authme.permission.PermissionsManager; -import fr.xephi.authme.permission.UserPermission; +import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.settings.Settings; import org.bukkit.Bukkit; import org.bukkit.GameMode; @@ -201,7 +201,7 @@ public final class Utils { * @param player the player to modify. */ public static void forceGM(Player player) { - if (!plugin.getPermissionsManager().hasPermission(player, UserPermission.BYPASS_FORCE_SURVIVAL)) { + if (!plugin.getPermissionsManager().hasPermission(player, PlayerPermission.BYPASS_FORCE_SURVIVAL)) { player.setGameMode(GameMode.SURVIVAL); } } diff --git a/src/test/java/fr/xephi/authme/permission/UserPermissionTest.java b/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java similarity index 84% rename from src/test/java/fr/xephi/authme/permission/UserPermissionTest.java rename to src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java index 48d4bbed8..92b3c7d91 100644 --- a/src/test/java/fr/xephi/authme/permission/UserPermissionTest.java +++ b/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java @@ -8,9 +8,9 @@ import java.util.Set; import static org.junit.Assert.fail; /** - * Test for {@link UserPermission}. + * Test for {@link PlayerPermission}. */ -public class UserPermissionTest { +public class PlayerPermissionTest { @Test public void shouldStartWithRegularAuthMePrefix() { @@ -19,7 +19,7 @@ public class UserPermissionTest { String adminPrefix = "authme.admin"; // when/then - for (UserPermission perm : UserPermission.values()) { + for (PlayerPermission perm : PlayerPermission.values()) { if (!perm.getNode().startsWith(requiredPrefix)) { fail("The permission '" + perm + "' does not start with the required prefix '" + requiredPrefix + "'"); } else if (perm.getNode().startsWith(adminPrefix)) { @@ -35,7 +35,7 @@ public class UserPermissionTest { Set nodes = new HashSet<>(); // when/then - for (UserPermission perm : UserPermission.values()) { + for (PlayerPermission perm : PlayerPermission.values()) { if (nodes.contains(perm.getNode())) { fail("More than one enum value defines the node '" + perm.getNode() + "'"); } diff --git a/src/test/java/fr/xephi/authme/util/UtilsTest.java b/src/test/java/fr/xephi/authme/util/UtilsTest.java index 4c632187f..2b9df6ad6 100644 --- a/src/test/java/fr/xephi/authme/util/UtilsTest.java +++ b/src/test/java/fr/xephi/authme/util/UtilsTest.java @@ -3,7 +3,7 @@ package fr.xephi.authme.util; import fr.xephi.authme.AuthMe; import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.permission.PermissionsManager; -import fr.xephi.authme.permission.UserPermission; +import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.settings.Settings; import org.bukkit.GameMode; import org.bukkit.entity.Player; @@ -54,7 +54,7 @@ public class UtilsTest { public void shouldForceSurvivalGameMode() { // given Player player = mock(Player.class); - given(permissionsManagerMock.hasPermission(player, UserPermission.BYPASS_FORCE_SURVIVAL)).willReturn(false); + given(permissionsManagerMock.hasPermission(player, PlayerPermission.BYPASS_FORCE_SURVIVAL)).willReturn(false); // when Utils.forceGM(player); @@ -68,14 +68,14 @@ public class UtilsTest { public void shouldNotForceGameModeForUserWithBypassPermission() { // given Player player = mock(Player.class); - given(permissionsManagerMock.hasPermission(player, UserPermission.BYPASS_FORCE_SURVIVAL)).willReturn(true); + given(permissionsManagerMock.hasPermission(player, PlayerPermission.BYPASS_FORCE_SURVIVAL)).willReturn(true); // when Utils.forceGM(player); // then verify(authMeMock).getPermissionsManager(); - verify(permissionsManagerMock).hasPermission(player, UserPermission.BYPASS_FORCE_SURVIVAL); + verify(permissionsManagerMock).hasPermission(player, PlayerPermission.BYPASS_FORCE_SURVIVAL); verify(player, never()).setGameMode(any(GameMode.class)); } From 369a7ccd65898db5eabdc8bfd476b3f5f51ae972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:19:39 +0100 Subject: [PATCH 19/82] Lowercase'd player permission node --- src/main/java/fr/xephi/authme/permission/PlayerPermission.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java index 739845196..3e8925b44 100644 --- a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java +++ b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java @@ -35,7 +35,7 @@ public enum PlayerPermission implements PermissionNode { ALLOW_MULTIPLE_ACCOUNTS("authme.command.player.allow2accounts"), - SEE_OTHER_ACCOUNTS("authme.command.player.seeOtherAccounts"); + SEE_OTHER_ACCOUNTS("authme.command.player.seeotheraccounts"); private String node; From 999c08956d134e98c637a2549b853a87ef642f23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:20:21 +0100 Subject: [PATCH 20/82] Changed 'changemail' permission to keep the nodes consistent --- src/main/java/fr/xephi/authme/permission/AdminPermission.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/permission/AdminPermission.java b/src/main/java/fr/xephi/authme/permission/AdminPermission.java index 979328bd3..3af0c6bce 100644 --- a/src/main/java/fr/xephi/authme/permission/AdminPermission.java +++ b/src/main/java/fr/xephi/authme/permission/AdminPermission.java @@ -19,7 +19,7 @@ public enum AdminPermission implements PermissionNode { GET_EMAIL("authme.command.admin.getemail"), - CHANGE_EMAIL("authme.command.admin.chgemail"), + CHANGE_EMAIL("authme.command.admin.changemail"), GET_IP("authme.command.admin.getip"), From 4afef9714d0c853918e9c35cdc3ec94e988f347a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:24:24 +0100 Subject: [PATCH 21/82] Converted two commands to use the builder --- .../xephi/authme/command/CommandManager.java | 40 +++++++++---------- .../authme/permission/AdminPermission.java | 2 +- .../authme/permission/PlayerPermission.java | 2 +- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/main/java/fr/xephi/authme/command/CommandManager.java b/src/main/java/fr/xephi/authme/command/CommandManager.java index 4d4f3f5c7..501a00b88 100644 --- a/src/main/java/fr/xephi/authme/command/CommandManager.java +++ b/src/main/java/fr/xephi/authme/command/CommandManager.java @@ -135,29 +135,27 @@ public class CommandManager { .build(); // Register the getemail command - CommandDescription getEmailCommand = new CommandDescription(new GetEmailCommand(), new ArrayList() { - { - add("getemail"); - add("getmail"); - add("email"); - add("mail"); - } - }, "Display player's email", "Display the email address of the specified player if set.", authMeBaseCommand); - getEmailCommand.setCommandPermissions(AdminPermission.GET_EMAIL, OP_ONLY); - getEmailCommand.addArgument(new CommandArgumentDescription("player", "Player name", true)); + CommandDescription getEmailCommand = CommandDescription.builder() + .executableCommand(new GetEmailCommand()) + .labels("getemail", "getmail", "email", "mail") + .description("Display player's email") + .detailedDescription("Display the email address of the specified player if set.") + .parent(authMeBaseCommand) + .permissions(OP_ONLY, AdminPermission.GET_EMAIL) + .withArgument("player", "Player name", true) + .build(); // Register the setemail command - CommandDescription setEmailCommand = new CommandDescription(new SetEmailCommand(), new ArrayList() { - { - add("chgemail"); - add("chgmail"); - add("setemail"); - add("setmail"); - } - }, "Change player's email", "Change the email address of the specified player.", authMeBaseCommand); - setEmailCommand.setCommandPermissions(AdminPermission.CHANGE_EMAIL, OP_ONLY); - setEmailCommand.addArgument(new CommandArgumentDescription("player", "Player name", false)); - setEmailCommand.addArgument(new CommandArgumentDescription("email", "Player email", false)); + CommandDescription setEmailCommand = CommandDescription.builder() + .executableCommand(new SetEmailCommand()) + .labels("chgemail", "chgmail", "setemail", "setmail") + .description("Change player's email") + .detailedDescription("Change the email address of the specified player.") + .parent(authMeBaseCommand) + .permissions(OP_ONLY, AdminPermission.CHANGE_EMAIL) + .withArgument("player", "Player name", false) + .withArgument("email", "Player email", false) + .build(); // Register the getip command CommandDescription getIpCommand = new CommandDescription(new GetIpCommand(), new ArrayList() { diff --git a/src/main/java/fr/xephi/authme/permission/AdminPermission.java b/src/main/java/fr/xephi/authme/permission/AdminPermission.java index 3af0c6bce..a65a63211 100644 --- a/src/main/java/fr/xephi/authme/permission/AdminPermission.java +++ b/src/main/java/fr/xephi/authme/permission/AdminPermission.java @@ -1,7 +1,7 @@ package fr.xephi.authme.permission; /** - * AuthMe admin permissions. + * AuthMe admin command permissions. */ public enum AdminPermission implements PermissionNode { diff --git a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java index 3e8925b44..e44617f5a 100644 --- a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java +++ b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java @@ -1,7 +1,7 @@ package fr.xephi.authme.permission; /** - * AuthMe player permission nodes, for regular players. + * AuthMe player command permission nodes, for regular players. */ public enum PlayerPermission implements PermissionNode { From 42cebacd60ad062f3f4b401a39dc23267f4d134e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:29:47 +0100 Subject: [PATCH 22/82] Added JavaDocs to AdminPermission class --- .../authme/permission/AdminPermission.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/main/java/fr/xephi/authme/permission/AdminPermission.java b/src/main/java/fr/xephi/authme/permission/AdminPermission.java index a65a63211..cfc777a6a 100644 --- a/src/main/java/fr/xephi/authme/permission/AdminPermission.java +++ b/src/main/java/fr/xephi/authme/permission/AdminPermission.java @@ -5,49 +5,115 @@ package fr.xephi.authme.permission; */ public enum AdminPermission implements PermissionNode { + /** + * Administrator command to register a new user. + */ REGISTER("authme.command.admin.register"), + /** + * Administrator command to unregister an existing user. + */ UNREGISTER("authme.command.admin.unregister"), + /** + * Administrator command to force-login an existing user. + */ FORCE_LOGIN("authme.command.admin.forcelogin"), + /** + * Administrator command to change the password of a user. + */ CHANGE_PASSWORD("authme.command.admin.changepassword"), + /** + * Administrator command to see the last login date and time of an user. + */ LAST_LOGIN("authme.command.admin.lastlogin"), + /** + * Administrator command to see all accounts associated with an user. + */ ACCOUNTS("authme.command.admin.accounts"), + /** + * Administrator command to get the email address of an user, if set. + */ GET_EMAIL("authme.command.admin.getemail"), + /** + * Administrator command to set or change the email adress of an user. + */ CHANGE_EMAIL("authme.command.admin.changemail"), + /** + * Administrator command to get the last known IP of an user. + */ GET_IP("authme.command.admin.getip"), + /** + * Administrator command to teleport to the AuthMe spawn. + */ SPAWN("authme.command.admin.spawn"), + /** + * Administrator command to set the AuthMe spawn. + */ SET_SPAWN("authme.command.admin.setspawn"), + /** + * Administrator command to teleport to the first AuthMe spawn. + */ FIRST_SPAWN("authme.command.admin.firstspawn"), + /** + * Administrator command to set the first AuthMe spawn. + */ SET_FIRST_SPAWN("authme.command.admin.setfirstspawn"), + /** + * Administrator command to purge old user data. + */ PURGE("authme.command.admin.purge"), + /** + * Administrator command to purge the last position of an user. + */ PURGE_LAST_POSITION("authme.command.admin.purgelastpos"), + /** + * Administrator command to purge all data associated with banned players. + */ PURGE_BANNED_PLAYERS("authme.command.admin.purgebannedplayers"), + /** + * Administrator command to toggle the AntiBot protection status. + */ SWITCH_ANTIBOT("authme.command.admin.switchantibot"), + /** + * Administrator command to reload the plugin configuration. + */ RELOAD("authme.command.admin.reload"); + /** + * Permission node. + */ private String node; + /** + * Get the permission node. + * @return + */ @Override public String getNode() { return node; } + /** + * Constructor. + * + * @param node Permission node. + */ AdminPermission(String node) { this.node = node; } From 3d0bf674bdc3e6e6f51363098c28ce88c1c9075a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:34:22 +0100 Subject: [PATCH 23/82] Added JavaDocs to PlayerPermission class, fixed various permission nodes --- .../authme/permission/PlayerPermission.java | 69 +++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java index e44617f5a..a125014aa 100644 --- a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java +++ b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java @@ -1,49 +1,110 @@ package fr.xephi.authme.permission; /** - * AuthMe player command permission nodes, for regular players. + * AuthMe player permission nodes, for regular players. */ public enum PlayerPermission implements PermissionNode { - BYPASS_ANTIBOT("authme.command.player.bypassantibot"), + /** + * Permission node to bypass AntiBot protection. + */ + BYPASS_ANTIBOT("authme.player.bypassantibot"), - IS_VIP("authme.command.player.vip"), + /** + * Permission node to identify VIP users. + */ + IS_VIP("authme.player.vip"), + /** + * Command permission to login. + */ LOGIN("authme.command.player.login"), + /** + * Command permission to logout. + */ LOGOUT("authme.command.player.logout"), + /** + * Command permission to register. + */ REGISTER("authme.command.player.register"), + /** + * Command permission to unregister. + */ UNREGISTER("authme.command.player.unregister"), + /** + * Command permission to change the password. + */ CHANGE_PASSWORD("authme.command.player.changepassword"), + /** + * Command permission to add an email address. + */ ADD_EMAIL("authme.command.player.email.add"), + /** + * Command permission to change the email address. + */ CHANGE_EMAIL("authme.command.player.email.change"), + /** + * Command permission to recover an account using it's email address. + */ RECOVER_EMAIL("authme.command.player.email.recover"), + /** + * Command permission to use captcha. + */ CAPTCHA("authme.command.player.captcha"), + /** + * Administrator command to convert old or other data to AuthMe data. + */ CONVERTER("authme.command.player.converter"), - CAN_LOGIN_BE_FORCED("authme.command.player.canbeforced"), + /** + * Permission for users a login can be forced to. + */ + CAN_LOGIN_BE_FORCED("authme.player.canbeforced"), + /** + * Permission for users to bypass force-survival mode. + */ BYPASS_FORCE_SURVIVAL("authme.command.player.bypassforcesurvival"), + /** + * Permission for users to allow two accounts. + */ ALLOW_MULTIPLE_ACCOUNTS("authme.command.player.allow2accounts"), + /** + * Permission for user to see other accounts. + */ SEE_OTHER_ACCOUNTS("authme.command.player.seeotheraccounts"); + /** + * Permission node. + */ private String node; + /** + * Get the permission node. + * + * @return Permission node. + */ @Override public String getNode() { return node; } + /** + * Constructor. + * + * @param node Permission node. + */ PlayerPermission(String node) { this.node = node; } From a0ed5545143806cb18ab41c1bd35cdd5990fedc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:34:54 +0100 Subject: [PATCH 24/82] Moved permission from player to admin space --- .../java/fr/xephi/authme/permission/AdminPermission.java | 5 +++++ .../java/fr/xephi/authme/permission/PlayerPermission.java | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/fr/xephi/authme/permission/AdminPermission.java b/src/main/java/fr/xephi/authme/permission/AdminPermission.java index cfc777a6a..335875a87 100644 --- a/src/main/java/fr/xephi/authme/permission/AdminPermission.java +++ b/src/main/java/fr/xephi/authme/permission/AdminPermission.java @@ -90,6 +90,11 @@ public enum AdminPermission implements PermissionNode { */ SWITCH_ANTIBOT("authme.command.admin.switchantibot"), + /** + * Administrator command to convert old or other data to AuthMe data. + */ + CONVERTER("authme.command.admin.converter"), + /** * Administrator command to reload the plugin configuration. */ diff --git a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java index a125014aa..0488a67ad 100644 --- a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java +++ b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java @@ -60,11 +60,6 @@ public enum PlayerPermission implements PermissionNode { */ CAPTCHA("authme.command.player.captcha"), - /** - * Administrator command to convert old or other data to AuthMe data. - */ - CONVERTER("authme.command.player.converter"), - /** * Permission for users a login can be forced to. */ From ccb9e24ce5b1ee505b0e36605620886acd819ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:35:28 +0100 Subject: [PATCH 25/82] Fixed invalid permission reference. --- src/main/java/fr/xephi/authme/command/CommandManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/command/CommandManager.java b/src/main/java/fr/xephi/authme/command/CommandManager.java index 501a00b88..1faa7f917 100644 --- a/src/main/java/fr/xephi/authme/command/CommandManager.java +++ b/src/main/java/fr/xephi/authme/command/CommandManager.java @@ -428,7 +428,7 @@ public class CommandManager { add("conv"); } }, "Convert command", "Convert command for AuthMeReloaded.", null); - converterBaseCommand.setCommandPermissions(PlayerPermission.CONVERTER, OP_ONLY); + converterBaseCommand.setCommandPermissions(AdminPermission.CONVERTER, OP_ONLY); converterBaseCommand.addArgument(new CommandArgumentDescription("job", "Conversion job: flattosql / flattosqlite /| xauth / crazylogin / rakamak / royalauth / vauth / sqltoflat", false)); // Register the help command From 7ac39d80fd6b308ef53b42f7aa9a986eae362795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:40:00 +0100 Subject: [PATCH 26/82] Fixed admin permission tests --- .../authme/permission/AdminPermissionTest.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java b/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java index 14bf58b54..34de95a7b 100644 --- a/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java +++ b/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java @@ -13,9 +13,9 @@ import static org.junit.Assert.fail; public class AdminPermissionTest { @Test - public void shouldStartWithAuthMeAdminPrefix() { + public void shouldStartWithAuthMePrefix() { // given - String requiredPrefix = "authme.admin."; + String requiredPrefix = "authme."; // when/then for (AdminPermission perm : AdminPermission.values()) { @@ -25,6 +25,19 @@ public class AdminPermissionTest { } } + @Test + public void shouldContainAdminBranch() { + // given + String requiredBranch = ".admin."; + + // when/then + for (AdminPermission perm : AdminPermission.values()) { + if (!perm.getNode().contains(requiredBranch)) { + fail("The permission '" + perm + "' does not contain with the required branch '" + requiredBranch + "'"); + } + } + } + @Test public void shouldHaveUniqueNodes() { // given From 2550e041126a01557dcaf9e7498d5f5dac8b357d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Vis=C3=A9e?= Date: Tue, 1 Dec 2015 16:44:49 +0100 Subject: [PATCH 27/82] Fixed player permission tests, improved test structure consistency --- .../permission/AdminPermissionTest.java | 20 +++++----- .../permission/PlayerPermissionTest.java | 39 +++++++++++++------ 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java b/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java index 34de95a7b..c3a89b723 100644 --- a/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java +++ b/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java @@ -18,9 +18,9 @@ public class AdminPermissionTest { String requiredPrefix = "authme."; // when/then - for (AdminPermission perm : AdminPermission.values()) { - if (!perm.getNode().startsWith(requiredPrefix)) { - fail("The permission '" + perm + "' does not start with the required prefix '" + requiredPrefix + "'"); + for (AdminPermission permission : AdminPermission.values()) { + if (!permission.getNode().startsWith(requiredPrefix)) { + fail("The permission '" + permission + "' does not start with the required prefix '" + requiredPrefix + "'"); } } } @@ -31,9 +31,9 @@ public class AdminPermissionTest { String requiredBranch = ".admin."; // when/then - for (AdminPermission perm : AdminPermission.values()) { - if (!perm.getNode().contains(requiredBranch)) { - fail("The permission '" + perm + "' does not contain with the required branch '" + requiredBranch + "'"); + for (AdminPermission permission : AdminPermission.values()) { + if (!permission.getNode().contains(requiredBranch)) { + fail("The permission '" + permission + "' does not contain with the required branch '" + requiredBranch + "'"); } } } @@ -44,11 +44,11 @@ public class AdminPermissionTest { Set nodes = new HashSet<>(); // when/then - for (AdminPermission perm : AdminPermission.values()) { - if (nodes.contains(perm.getNode())) { - fail("More than one enum value defines the node '" + perm.getNode() + "'"); + for (AdminPermission permission : AdminPermission.values()) { + if (nodes.contains(permission.getNode())) { + fail("More than one enum value defines the node '" + permission.getNode() + "'"); } - nodes.add(perm.getNode()); + nodes.add(permission.getNode()); } } diff --git a/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java b/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java index 92b3c7d91..81893373f 100644 --- a/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java +++ b/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java @@ -13,18 +13,33 @@ import static org.junit.Assert.fail; public class PlayerPermissionTest { @Test - public void shouldStartWithRegularAuthMePrefix() { + public void shouldStartWithAuthMePrefix() { // given String requiredPrefix = "authme."; - String adminPrefix = "authme.admin"; // when/then - for (PlayerPermission perm : PlayerPermission.values()) { - if (!perm.getNode().startsWith(requiredPrefix)) { - fail("The permission '" + perm + "' does not start with the required prefix '" + requiredPrefix + "'"); - } else if (perm.getNode().startsWith(adminPrefix)) { - fail("The permission '" + perm + "' should not use a node with the admin-specific prefix '" - + adminPrefix + "'"); + for (PlayerPermission permission : PlayerPermission.values()) { + if (!permission.getNode().startsWith(requiredPrefix)) { + fail("The permission '" + permission + "' does not start with the required prefix '" + requiredPrefix + "'"); + } + } + } + + @Test + public void shouldContainPlayerBranch() { + // given + String playerBranch = ".player."; + String adminBranch = ".admin."; + + // when/then + for (PlayerPermission permission : PlayerPermission.values()) { + if (permission.getNode().contains(adminBranch)) { + fail("The permission '" + permission + "' should not use a node with the admin-specific branch '" + + adminBranch + "'"); + + } else if (!permission.getNode().contains(playerBranch)) { + fail("The permission '" + permission + "' should use a node with the player-specific branch '" + + playerBranch + "'"); } } } @@ -35,11 +50,11 @@ public class PlayerPermissionTest { Set nodes = new HashSet<>(); // when/then - for (PlayerPermission perm : PlayerPermission.values()) { - if (nodes.contains(perm.getNode())) { - fail("More than one enum value defines the node '" + perm.getNode() + "'"); + for (PlayerPermission permission : PlayerPermission.values()) { + if (nodes.contains(permission.getNode())) { + fail("More than one enum value defines the node '" + permission.getNode() + "'"); } - nodes.add(perm.getNode()); + nodes.add(permission.getNode()); } } } From 54d8ede5bce24ef7955453ffdd822ebba64158df Mon Sep 17 00:00:00 2001 From: ljacqu Date: Tue, 1 Dec 2015 20:44:44 +0100 Subject: [PATCH 28/82] Add changes missed during merge --- .../java/fr/xephi/authme/Log4JFilter.java | 18 ++++++-------- .../authme/command/CommandInitializer.java | 24 +++++++------------ .../java/fr/xephi/authme/Log4JFilterTest.java | 2 -- 3 files changed, 15 insertions(+), 29 deletions(-) diff --git a/src/main/java/fr/xephi/authme/Log4JFilter.java b/src/main/java/fr/xephi/authme/Log4JFilter.java index 581699f08..e0eac14e0 100644 --- a/src/main/java/fr/xephi/authme/Log4JFilter.java +++ b/src/main/java/fr/xephi/authme/Log4JFilter.java @@ -3,6 +3,7 @@ package fr.xephi.authme; import fr.xephi.authme.util.StringUtils; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.Logger; import org.apache.logging.log4j.message.Message; @@ -11,9 +12,8 @@ import org.apache.logging.log4j.message.Message; * Implements a filter for Log4j to skip sensitive AuthMe commands. * * @author Xephi59 - * @version $Revision: 1.0 $ */ -public class Log4JFilter implements org.apache.logging.log4j.core.Filter { +public class Log4JFilter implements Filter { /** * List of commands (lower-case) to skip. @@ -30,8 +30,7 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter { /** * Validates a Message instance and returns the {@link Result} value - * depending 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 * @@ -46,7 +45,7 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter { /** * Validates a message and returns the {@link Result} value depending - * depending on whether the message contains sensitive AuthMe data. + * on whether the message contains sensitive AuthMe data. * * @param message the message to verify * @@ -74,14 +73,12 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter { } @Override - public Result filter(Logger arg0, Level arg1, Marker arg2, String message, - Object... arg4) { + public Result filter(Logger arg0, Level arg1, Marker arg2, String message, Object... arg4) { return validateMessage(message); } @Override - public Result filter(Logger arg0, Level arg1, Marker arg2, Object message, - Throwable arg4) { + public Result filter(Logger arg0, Level arg1, Marker arg2, Object message, Throwable arg4) { if (message == null) { return Result.NEUTRAL; } @@ -89,8 +86,7 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter { } @Override - public Result filter(Logger arg0, Level arg1, Marker arg2, Message message, - Throwable arg4) { + public Result filter(Logger arg0, Level arg1, Marker arg2, Message message, Throwable arg4) { return validateMessage(message); } diff --git a/src/main/java/fr/xephi/authme/command/CommandInitializer.java b/src/main/java/fr/xephi/authme/command/CommandInitializer.java index 132c416e0..04658f5ce 100644 --- a/src/main/java/fr/xephi/authme/command/CommandInitializer.java +++ b/src/main/java/fr/xephi/authme/command/CommandInitializer.java @@ -87,11 +87,9 @@ public final class CommandInitializer { .labels("register", "reg", "r") .description("Register a player") .detailedDescription("Register the specified player with the specified password.") - .parent(authMeBaseCommand) - .permissions(OP_ONLY, PlayerPermission.REGISTER) .withArgument("player", "Player name", false) .withArgument("password", "Password", false) - .permissions(OP_ONLY, UserPermission.REGISTER) + .permissions(OP_ONLY, PlayerPermission.REGISTER) .executableCommand(new RegisterCommand()) .build(); @@ -101,10 +99,8 @@ public final class CommandInitializer { .labels("unregister", "unreg", "unr") .description("Unregister a player") .detailedDescription("Unregister the specified player.") - .parent(authMeBaseCommand) - .permissions(OP_ONLY, PlayerPermission.UNREGISTER) .withArgument("player", "Player name", false) - .permissions(OP_ONLY, UserPermission.UNREGISTER) + .permissions(OP_ONLY, PlayerPermission.UNREGISTER) .executableCommand(new UnregisterCommand()) .build(); @@ -114,10 +110,8 @@ public final class CommandInitializer { .labels("forcelogin", "login") .description("Enforce login player") .detailedDescription("Enforce the specified player to login.") - .parent(authMeBaseCommand) - .permissions(OP_ONLY, PlayerPermission.CAN_LOGIN_BE_FORCED) .withArgument("player", "Online player name", true) - .permissions(OP_ONLY, UserPermission.CAN_LOGIN_BE_FORCED) + .permissions(OP_ONLY, PlayerPermission.CAN_LOGIN_BE_FORCED) .executableCommand(new ForceLoginCommand()) .build(); @@ -127,11 +121,9 @@ public final class CommandInitializer { .labels("password", "changepassword", "changepass", "cp") .description("Change a player's password") .detailedDescription("Change the password of a player.") - .parent(authMeBaseCommand) - .permissions(OP_ONLY, PlayerPermission.CHANGE_PASSWORD) .withArgument("player", "Player name", false) .withArgument("pwd", "New password", false) - .permissions(OP_ONLY, UserPermission.CHANGE_PASSWORD) + .permissions(OP_ONLY, PlayerPermission.CHANGE_PASSWORD) .executableCommand(new ChangePasswordCommand()) .build(); @@ -158,23 +150,23 @@ public final class CommandInitializer { .build(); // Register the getemail command - CommandDescription getEmailCommand = CommandDescription.builder() - .executableCommand(new GetEmailCommand()) + CommandDescription.builder() + .parent(AUTHME_BASE) .labels("getemail", "getmail", "email", "mail") .description("Display player's email") .detailedDescription("Display the email address of the specified player if set.") - .parent(authMeBaseCommand) .permissions(OP_ONLY, AdminPermission.GET_EMAIL) .withArgument("player", "Player name", true) + .executableCommand(new GetEmailCommand()) .build(); // Register the setemail command CommandDescription setEmailCommand = CommandDescription.builder() .executableCommand(new SetEmailCommand()) + .parent(AUTHME_BASE) .labels("chgemail", "chgmail", "setemail", "setmail") .description("Change player's email") .detailedDescription("Change the email address of the specified player.") - .parent(authMeBaseCommand) .permissions(OP_ONLY, AdminPermission.CHANGE_EMAIL) .withArgument("player", "Player name", false) .withArgument("email", "Player email", false) diff --git a/src/test/java/fr/xephi/authme/Log4JFilterTest.java b/src/test/java/fr/xephi/authme/Log4JFilterTest.java index f8d185d34..466bc0da2 100644 --- a/src/test/java/fr/xephi/authme/Log4JFilterTest.java +++ b/src/test/java/fr/xephi/authme/Log4JFilterTest.java @@ -12,8 +12,6 @@ import org.mockito.Mockito; /** * Test for {@link Log4JFilter}. - * @author Gabriele - * @version $Revision: 1.0 $ */ public class Log4JFilterTest { From 7ec79afe4a36537d1831c918c32d5680767e34c5 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Wed, 2 Dec 2015 03:22:27 +0700 Subject: [PATCH 29/82] Set speed into 0.0 --- .../process/register/ProcessSyncronousPasswordRegister.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncronousPasswordRegister.java b/src/main/java/fr/xephi/authme/process/register/ProcessSyncronousPasswordRegister.java index bd1bb174f..27f060e14 100644 --- a/src/main/java/fr/xephi/authme/process/register/ProcessSyncronousPasswordRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/ProcessSyncronousPasswordRegister.java @@ -118,8 +118,8 @@ public class ProcessSyncronousPasswordRegister implements Runnable { } if (!Settings.isMovementAllowed && Settings.isRemoveSpeedEnabled) { - player.setWalkSpeed(0.2f); - player.setFlySpeed(0.1f); + player.setWalkSpeed(0.0f); + player.setFlySpeed(0.0f); } // The LoginEvent now fires (as intended) after everything is processed From 690a8d67a30a3d5729827c8717690322bbdbafc2 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Tue, 1 Dec 2015 21:45:02 +0100 Subject: [PATCH 30/82] Abstract Messages into two layers; move to new 'output' package - Abstract Messages into two layers: the top layer 'Messages' is how Messages can be retrieved and sent as before. In the background, package-private, MessagesManager actually does the file read and worries about I/O while Messages takes care of higher-level things (such as joining two lines or checking the current language). --- src/main/java/fr/xephi/authme/AntiBot.java | 4 +- src/main/java/fr/xephi/authme/AuthMe.java | 4 +- .../executable/authme/AccountsCommand.java | 4 +- .../authme/ChangePasswordCommand.java | 4 +- .../executable/authme/GetEmailCommand.java | 4 +- .../executable/authme/LastLoginCommand.java | 4 +- .../authme/PurgeLastPositionCommand.java | 4 +- .../executable/authme/RegisterCommand.java | 4 +- .../executable/authme/ReloadCommand.java | 6 +- .../executable/authme/SetEmailCommand.java | 4 +- .../executable/authme/UnregisterCommand.java | 4 +- .../executable/captcha/CaptchaCommand.java | 4 +- .../changepassword/ChangePasswordCommand.java | 4 +- .../converter/ConverterCommand.java | 4 +- .../executable/email/RecoverEmailCommand.java | 4 +- .../executable/register/RegisterCommand.java | 4 +- .../unregister/UnregisterCommand.java | 4 +- .../fr/xephi/authme/converter/SqlToFlat.java | 2 +- .../authme/listener/AuthMePlayerListener.java | 11 +- .../authme/listener/AuthMeServerListener.java | 4 +- .../{settings => output}/MessageKey.java | 2 +- .../java/fr/xephi/authme/output/Messages.java | 72 +++++++++++ .../xephi/authme/output/MessagesManager.java | 59 +++++++++ .../process/email/AsyncChangeEmail.java | 4 +- .../authme/process/join/AsynchronousJoin.java | 4 +- .../process/login/AsynchronousLogin.java | 4 +- .../process/logout/AsynchronousLogout.java | 4 +- .../logout/ProcessSyncronousPlayerLogout.java | 4 +- .../process/register/AsyncRegister.java | 4 +- .../register/ProcessSyncEmailRegister.java | 4 +- .../ProcessSyncronousPasswordRegister.java | 4 +- .../unregister/AsynchronousUnregister.java | 4 +- .../fr/xephi/authme/settings/Messages.java | 115 ------------------ .../xephi/authme/task/ChangePasswordTask.java | 4 +- .../fr/xephi/authme/task/TimeoutTask.java | 4 +- .../java/fr/xephi/authme/util/Wrapper.java | 2 +- .../ChangePasswordCommandTest.java | 4 +- .../register/RegisterCommandTest.java | 4 +- .../{settings => output}/MessageKeyTest.java | 2 +- .../MessagesIntegrationTest.java} | 10 +- .../fr/xephi/authme/util/WrapperMock.java | 2 +- 41 files changed, 213 insertions(+), 190 deletions(-) rename src/main/java/fr/xephi/authme/{settings => output}/MessageKey.java (98%) create mode 100644 src/main/java/fr/xephi/authme/output/Messages.java create mode 100644 src/main/java/fr/xephi/authme/output/MessagesManager.java delete mode 100644 src/main/java/fr/xephi/authme/settings/Messages.java rename src/test/java/fr/xephi/authme/{settings => output}/MessageKeyTest.java (96%) rename src/test/java/fr/xephi/authme/{settings/MessagesTest.java => output/MessagesIntegrationTest.java} (93%) diff --git a/src/main/java/fr/xephi/authme/AntiBot.java b/src/main/java/fr/xephi/authme/AntiBot.java index afe7e2b68..2ca1a8a0e 100644 --- a/src/main/java/fr/xephi/authme/AntiBot.java +++ b/src/main/java/fr/xephi/authme/AntiBot.java @@ -1,8 +1,8 @@ package fr.xephi.authme; import fr.xephi.authme.permission.PlayerPermission; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.Wrapper; import org.bukkit.Bukkit; diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 4b07701f7..3018fd0fa 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -17,6 +17,8 @@ import fr.xephi.authme.hooks.BungeeCordMessage; import fr.xephi.authme.hooks.EssSpawn; import fr.xephi.authme.listener.*; import fr.xephi.authme.modules.ModuleManager; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.process.Management; @@ -227,7 +229,7 @@ public class AuthMe extends JavaPlugin { this.otherAccounts = OtherAccounts.getInstance(); // Setup messages - this.messages = new Messages(Settings.messageFile, Settings.messagesLanguage); + this.messages = Messages.getInstance(); // Set up Metrics setupMetrics(); diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/AccountsCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/AccountsCommand.java index b5f07d1af..ba34491a6 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/AccountsCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/AccountsCommand.java @@ -5,8 +5,8 @@ import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordCommand.java index 83ea810f5..1753a8307 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordCommand.java @@ -7,8 +7,8 @@ import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.security.PasswordSecurity; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/GetEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/GetEmailCommand.java index 94db21cec..cc0ac9b86 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/GetEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/GetEmailCommand.java @@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import org.bukkit.command.CommandSender; /** diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/LastLoginCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/LastLoginCommand.java index 3f3835f35..ecae052b9 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/LastLoginCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/LastLoginCommand.java @@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import org.bukkit.command.CommandSender; import java.util.Date; diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommand.java index dc4172638..e9e3c9ad3 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommand.java @@ -5,8 +5,8 @@ import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/RegisterCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/RegisterCommand.java index 8ddbfefdf..38e73d017 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/RegisterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/RegisterCommand.java @@ -6,8 +6,8 @@ import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.security.PasswordSecurity; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java index e94b5b72f..1eaf3717e 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java @@ -6,8 +6,8 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.Profiler; import org.bukkit.command.CommandSender; @@ -41,7 +41,7 @@ public class ReloadCommand extends ExecutableCommand { try { Settings.reload(); - plugin.setMessages(new Messages(Settings.messageFile, Settings.messagesLanguage)); + Messages.getInstance().reloadManager(); plugin.getModuleManager().reloadModules(); plugin.setupDatabase(); } catch (Exception e) { diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/SetEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/SetEmailCommand.java index 35816fbf5..278bf13c4 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/SetEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/SetEmailCommand.java @@ -5,8 +5,8 @@ import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import org.bukkit.command.CommandSender; diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/UnregisterCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/UnregisterCommand.java index f10116205..e5a8396fd 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/UnregisterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/UnregisterCommand.java @@ -6,8 +6,8 @@ import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.TimeoutTask; diff --git a/src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java b/src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java index a5a194c62..4fa2bbef9 100644 --- a/src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java @@ -5,8 +5,8 @@ import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.security.RandomString; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; diff --git a/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java b/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java index 45d05ee32..c88ceaa87 100644 --- a/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java @@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.task.ChangePasswordTask; import fr.xephi.authme.util.Wrapper; diff --git a/src/main/java/fr/xephi/authme/command/executable/converter/ConverterCommand.java b/src/main/java/fr/xephi/authme/command/executable/converter/ConverterCommand.java index a2da7b376..883149973 100644 --- a/src/main/java/fr/xephi/authme/command/executable/converter/ConverterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/converter/ConverterCommand.java @@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.converter.*; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; diff --git a/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java index ab50cdb10..2af4f65a7 100644 --- a/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java @@ -8,8 +8,8 @@ import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.RandomString; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.Wrapper; import org.bukkit.command.CommandSender; diff --git a/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java b/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java index a36443b7b..070d795b2 100644 --- a/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java @@ -5,8 +5,8 @@ import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.process.Management; import fr.xephi.authme.security.RandomString; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.Wrapper; import org.bukkit.command.CommandSender; diff --git a/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java b/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java index 96c8b3cfc..22ef35661 100644 --- a/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java @@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.ExecutableCommand; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; diff --git a/src/main/java/fr/xephi/authme/converter/SqlToFlat.java b/src/main/java/fr/xephi/authme/converter/SqlToFlat.java index ee1375084..1af5594cf 100644 --- a/src/main/java/fr/xephi/authme/converter/SqlToFlat.java +++ b/src/main/java/fr/xephi/authme/converter/SqlToFlat.java @@ -5,7 +5,7 @@ import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.FlatFile; -import fr.xephi.authme.settings.MessageKey; +import fr.xephi.authme.output.MessageKey; import org.bukkit.command.CommandSender; import java.util.List; diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java index 095484e5d..773ed8d5d 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java @@ -11,8 +11,8 @@ import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PlayerPermission; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.GeoLiteAPI; import fr.xephi.authme.util.Utils; @@ -32,6 +32,8 @@ import org.bukkit.event.player.*; import java.util.concurrent.ConcurrentHashMap; +import static fr.xephi.authme.output.MessageKey.USERNAME_ALREADY_ONLINE_ERROR; + /** */ public class AuthMePlayerListener implements Listener { @@ -207,7 +209,7 @@ public class AuthMePlayerListener implements Listener { // Check if forceSingleSession is set to true, so kick player that has // joined with same nick of online player if (Settings.isForceSingleSessionEnabled && player.isOnline()) { - event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, m.getString("same_nick")); + event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, m.retrieveSingle(USERNAME_ALREADY_ONLINE_ERROR)); if (LimboCache.getInstance().hasLimboPlayer(name)) Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { @@ -340,7 +342,8 @@ public class AuthMePlayerListener implements Listener { return; } - if ((!Settings.isForceSingleSessionEnabled) && (event.getReason().contains(m.getString("same_nick")))) { + if (!Settings.isForceSingleSessionEnabled && event.getReason().contains( + m.retrieveSingle(USERNAME_ALREADY_ONLINE_ERROR))) { event.setCancelled(true); return; } diff --git a/src/main/java/fr/xephi/authme/listener/AuthMeServerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMeServerListener.java index 3b5a3c803..9a1cbde48 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMeServerListener.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMeServerListener.java @@ -2,8 +2,8 @@ package fr.xephi.authme.listener; import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.GeoLiteAPI; import org.bukkit.event.EventHandler; diff --git a/src/main/java/fr/xephi/authme/settings/MessageKey.java b/src/main/java/fr/xephi/authme/output/MessageKey.java similarity index 98% rename from src/main/java/fr/xephi/authme/settings/MessageKey.java rename to src/main/java/fr/xephi/authme/output/MessageKey.java index 72e71b631..bc024abf7 100644 --- a/src/main/java/fr/xephi/authme/settings/MessageKey.java +++ b/src/main/java/fr/xephi/authme/output/MessageKey.java @@ -1,4 +1,4 @@ -package fr.xephi.authme.settings; +package fr.xephi.authme.output; /** * Keys for translatable messages managed by {@link Messages}. diff --git a/src/main/java/fr/xephi/authme/output/Messages.java b/src/main/java/fr/xephi/authme/output/Messages.java new file mode 100644 index 000000000..44930ba48 --- /dev/null +++ b/src/main/java/fr/xephi/authme/output/Messages.java @@ -0,0 +1,72 @@ +package fr.xephi.authme.output; + +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.util.StringUtils; +import org.bukkit.command.CommandSender; + +/** + * Class for retrieving and sending translatable messages to players. + */ +public class Messages { + + private static Messages singleton; + private final String language; + private MessagesManager manager; + + + private Messages(String language, MessagesManager manager) { + this.language = language; + this.manager = manager; + } + + public static Messages getInstance() { + if (singleton == null) { + MessagesManager manager = new MessagesManager(Settings.messageFile); + singleton = new Messages(Settings.messagesLanguage, manager); + } + return singleton; + } + + /** + * Send the given message code to the player. + * + * @param sender The entity to send the message to + * @param key The key of the message to send + */ + public void send(CommandSender sender, MessageKey key) { + String[] lines = manager.retrieve(key.getKey()); + for (String line : lines) { + sender.sendMessage(line); + } + } + + /** + * Retrieve the message from the text file and return it split by new line as an array. + * + * @param key The message key to retrieve + * + * @return The message split by new lines + */ + public String[] retrieve(MessageKey key) { + if (!Settings.messagesLanguage.equalsIgnoreCase(language)) { + reloadManager(); + } + return manager.retrieve(key.getKey()); + } + + /** + * Retrieve the message from the text file. + * + * @param key The message key to retrieve + * + * @return The message from the file + */ + public String retrieveSingle(MessageKey key) { + return StringUtils.join("\n", retrieve(key)); + } + + public void reloadManager() { + manager = new MessagesManager(Settings.messageFile); + } + +} diff --git a/src/main/java/fr/xephi/authme/output/MessagesManager.java b/src/main/java/fr/xephi/authme/output/MessagesManager.java new file mode 100644 index 000000000..0a973b908 --- /dev/null +++ b/src/main/java/fr/xephi/authme/output/MessagesManager.java @@ -0,0 +1,59 @@ +package fr.xephi.authme.output; + +import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.settings.CustomConfiguration; + +import java.io.File; + +/** + * Class for retrieving and sending translatable messages to players. + */ +class MessagesManager extends CustomConfiguration { + + /** The section symbol, used in Minecraft for formatting codes. */ + private static final String SECTION_SIGN = "\u00a7"; + + + /** + * Constructor for Messages. + * + * @param file the configuration file + */ + MessagesManager(File file) { + super(file); + load(); + } + + /** + * Retrieve the message from the configuration file. + * + * @param key The key to retrieve + * + * @return The message + */ + String[] retrieve(String key) { + String message = (String) get(key); + if (message != null) { + return formatMessage(message); + } + + // Message is null: log key not being found and send error back as message + String retrievalError = "Error getting message with key '" + key + "'. "; + ConsoleLogger.showError(retrievalError + "Please verify your config file at '" + + getConfigFile().getName() + "'"); + return new String[]{ + retrievalError + "Please contact the admin to verify or update the AuthMe messages file."}; + } + + static String[] formatMessage(String message) { + // TODO: Check that the codes actually exist, i.e. replace &c but not &y + // TODO: Allow '&' to be retained with the code '&&' + String[] lines = message.split("&n"); + for (int i = 0; i < lines.length; ++i) { + // We don't initialize a StringBuilder here because mostly we will only have one entry + lines[i] = lines[i].replace("&", SECTION_SIGN); + } + return lines; + } + +} diff --git a/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java b/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java index b6cb623dc..5cc1f9ec8 100644 --- a/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java +++ b/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java @@ -5,8 +5,8 @@ import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.permission.PlayerPermission; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import org.bukkit.entity.Player; diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java index cee3a687c..3160ddcc4 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -11,8 +11,8 @@ import fr.xephi.authme.events.ProtectInventoryEvent; import fr.xephi.authme.events.SpawnTeleportEvent; import fr.xephi.authme.listener.AuthMePlayerListener; import fr.xephi.authme.permission.PlayerPermission; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Spawn; import fr.xephi.authme.task.MessageTask; diff --git a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java index 1333fd98d..b3caf159a 100644 --- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java @@ -11,8 +11,8 @@ import fr.xephi.authme.listener.AuthMePlayerListener; import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.RandomString; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.util.Utils; diff --git a/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java b/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java index 6714c4dd1..3e719060a 100644 --- a/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java +++ b/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java @@ -5,8 +5,8 @@ import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.util.Utils; import fr.xephi.authme.util.Utils.GroupType; import org.bukkit.entity.Player; diff --git a/src/main/java/fr/xephi/authme/process/logout/ProcessSyncronousPlayerLogout.java b/src/main/java/fr/xephi/authme/process/logout/ProcessSyncronousPlayerLogout.java index 811dbcb0c..6b4b9c0ed 100644 --- a/src/main/java/fr/xephi/authme/process/logout/ProcessSyncronousPlayerLogout.java +++ b/src/main/java/fr/xephi/authme/process/logout/ProcessSyncronousPlayerLogout.java @@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.events.LogoutEvent; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.TimeoutTask; diff --git a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java index 6aaac37fe..f5f8a13c5 100644 --- a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java @@ -7,8 +7,8 @@ import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.security.PasswordSecurity; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import org.bukkit.entity.Player; diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java b/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java index 33636af48..dc95e33de 100644 --- a/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java @@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.TimeoutTask; diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncronousPasswordRegister.java b/src/main/java/fr/xephi/authme/process/register/ProcessSyncronousPasswordRegister.java index 28faa5bf3..def20eeef 100644 --- a/src/main/java/fr/xephi/authme/process/register/ProcessSyncronousPasswordRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/ProcessSyncronousPasswordRegister.java @@ -6,8 +6,8 @@ import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.events.LoginEvent; import fr.xephi.authme.events.RestoreInventoryEvent; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.TimeoutTask; diff --git a/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java b/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java index 2268f4235..da5d19f9f 100644 --- a/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java +++ b/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java @@ -7,8 +7,8 @@ import fr.xephi.authme.cache.backup.JsonCache; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.security.PasswordSecurity; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.TimeoutTask; diff --git a/src/main/java/fr/xephi/authme/settings/Messages.java b/src/main/java/fr/xephi/authme/settings/Messages.java deleted file mode 100644 index 55ce0b584..000000000 --- a/src/main/java/fr/xephi/authme/settings/Messages.java +++ /dev/null @@ -1,115 +0,0 @@ -package fr.xephi.authme.settings; - -import fr.xephi.authme.ConsoleLogger; -import fr.xephi.authme.util.StringUtils; -import org.bukkit.command.CommandSender; - -import java.io.File; - -/** - * Class for retrieving and sending translatable messages to players. - */ -// TODO ljacqu 20151124: This class is a weird mix between singleton and POJO -// TODO: change it into POJO -public class Messages extends CustomConfiguration { - - /** The section symbol, used in Minecraft for formatting codes. */ - private static final String SECTION_SIGN = "\u00a7"; - private static Messages singleton; - private String language; - - - /** - * Constructor for Messages. - * - * @param file the configuration file - * @param lang the code of the language to use - */ - public Messages(File file, String lang) { - super(file); - load(); - this.language = lang; - } - - public static Messages getInstance() { - if (singleton == null) { - singleton = new Messages(Settings.messageFile, Settings.messagesLanguage); - } - return singleton; - } - - /** - * Send the given message code to the player. - * - * @param sender The entity to send the message to - * @param key The key of the message to send - */ - public void send(CommandSender sender, MessageKey key) { - String[] lines = retrieve(key); - for (String line : lines) { - sender.sendMessage(line); - } - } - - /** - * Retrieve the message from the text file and return it split by new line as an array. - * - * @param key The message key to retrieve - * - * @return The message split by new lines - */ - public String[] retrieve(MessageKey key) { - return retrieve(key.getKey()); - } - - /** - * Retrieve the message from the text file. - * - * @param key The message key to retrieve - * - * @return The message from the file - */ - public String retrieveSingle(MessageKey key) { - return StringUtils.join("\n", retrieve(key.getKey())); - } - - /** - * Retrieve the message from the configuration file. - * - * @param key The key to retrieve - * - * @return The message - */ - private String[] retrieve(String key) { - if (!Settings.messagesLanguage.equalsIgnoreCase(language)) { - reloadMessages(); - } - String message = (String) get(key); - if (message != null) { - return formatMessage(message); - } - - // Message is null: log key not being found and send error back as message - String retrievalError = "Error getting message with key '" + key + "'. "; - ConsoleLogger.showError(retrievalError + "Please verify your config file at '" - + getConfigFile().getName() + "'"); - return new String[]{ - retrievalError + "Please contact the admin to verify or update the AuthMe messages file."}; - } - - private static String[] formatMessage(String message) { - // TODO: Check that the codes actually exist, i.e. replace &c but not &y - // TODO: Allow '&' to be retained with the code '&&' - String[] lines = message.split("&n"); - for (int i = 0; i < lines.length; ++i) { - // We don't initialize a StringBuilder here because mostly we will only have one entry - lines[i] = lines[i].replace("&", SECTION_SIGN); - } - return lines; - } - - public void reloadMessages() { - singleton = new Messages(Settings.messageFile, Settings.messagesLanguage); - } - -} diff --git a/src/main/java/fr/xephi/authme/task/ChangePasswordTask.java b/src/main/java/fr/xephi/authme/task/ChangePasswordTask.java index 05d93dfb5..9b4dfac51 100644 --- a/src/main/java/fr/xephi/authme/task/ChangePasswordTask.java +++ b/src/main/java/fr/xephi/authme/task/ChangePasswordTask.java @@ -5,8 +5,8 @@ import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.security.PasswordSecurity; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import org.bukkit.entity.Player; diff --git a/src/main/java/fr/xephi/authme/task/TimeoutTask.java b/src/main/java/fr/xephi/authme/task/TimeoutTask.java index dc5d06ddf..eedf08755 100644 --- a/src/main/java/fr/xephi/authme/task/TimeoutTask.java +++ b/src/main/java/fr/xephi/authme/task/TimeoutTask.java @@ -2,8 +2,8 @@ package fr.xephi.authme.task; import fr.xephi.authme.AuthMe; import fr.xephi.authme.cache.auth.PlayerCache; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import org.bukkit.Bukkit; import org.bukkit.entity.Player; diff --git a/src/main/java/fr/xephi/authme/util/Wrapper.java b/src/main/java/fr/xephi/authme/util/Wrapper.java index 0666630b9..77f65cff5 100644 --- a/src/main/java/fr/xephi/authme/util/Wrapper.java +++ b/src/main/java/fr/xephi/authme/util/Wrapper.java @@ -2,7 +2,7 @@ package fr.xephi.authme.util; import fr.xephi.authme.AuthMe; import fr.xephi.authme.cache.auth.PlayerCache; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.Messages; import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.scheduler.BukkitScheduler; diff --git a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java index 7d33a60ef..87f113cc5 100644 --- a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java @@ -4,8 +4,8 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.command.CommandParts; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.task.ChangePasswordTask; import fr.xephi.authme.util.WrapperMock; diff --git a/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java index bc6229c10..02bb65a73 100644 --- a/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java @@ -2,8 +2,8 @@ package fr.xephi.authme.command.executable.register; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.process.Management; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +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; diff --git a/src/test/java/fr/xephi/authme/settings/MessageKeyTest.java b/src/test/java/fr/xephi/authme/output/MessageKeyTest.java similarity index 96% rename from src/test/java/fr/xephi/authme/settings/MessageKeyTest.java rename to src/test/java/fr/xephi/authme/output/MessageKeyTest.java index 2eab88aa8..101306bf9 100644 --- a/src/test/java/fr/xephi/authme/settings/MessageKeyTest.java +++ b/src/test/java/fr/xephi/authme/output/MessageKeyTest.java @@ -1,4 +1,4 @@ -package fr.xephi.authme.settings; +package fr.xephi.authme.output; import fr.xephi.authme.util.StringUtils; import org.junit.Test; diff --git a/src/test/java/fr/xephi/authme/settings/MessagesTest.java b/src/test/java/fr/xephi/authme/output/MessagesIntegrationTest.java similarity index 93% rename from src/test/java/fr/xephi/authme/settings/MessagesTest.java rename to src/test/java/fr/xephi/authme/output/MessagesIntegrationTest.java index b721987ec..aa7367e2b 100644 --- a/src/test/java/fr/xephi/authme/settings/MessagesTest.java +++ b/src/test/java/fr/xephi/authme/output/MessagesIntegrationTest.java @@ -1,5 +1,6 @@ -package fr.xephi.authme.settings; +package fr.xephi.authme.output; +import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.WrapperMock; import org.bukkit.entity.Player; import org.junit.Before; @@ -18,7 +19,7 @@ import static org.mockito.Mockito.verify; /** * Test for {@link Messages}. */ -public class MessagesTest { +public class MessagesIntegrationTest { private static final String YML_TEST_FILE = "messages_test.yml"; private Messages messages; @@ -38,8 +39,9 @@ public class MessagesTest { throw new RuntimeException("File '" + YML_TEST_FILE + "' could not be loaded"); } - File file = new File(url.getFile()); - messages = new Messages(file, "en"); + Settings.messageFile = new File(url.getFile()); + Settings.messagesLanguage = "en"; + messages = Messages.getInstance(); } @Test diff --git a/src/test/java/fr/xephi/authme/util/WrapperMock.java b/src/test/java/fr/xephi/authme/util/WrapperMock.java index f622c00bd..83ed23cd2 100644 --- a/src/test/java/fr/xephi/authme/util/WrapperMock.java +++ b/src/test/java/fr/xephi/authme/util/WrapperMock.java @@ -2,7 +2,7 @@ package fr.xephi.authme.util; import fr.xephi.authme.AuthMe; import fr.xephi.authme.cache.auth.PlayerCache; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.output.Messages; import org.bukkit.Server; import org.bukkit.scheduler.BukkitScheduler; import org.mockito.Mockito; From b0e619d4124c84b7a444992f2af8872ef3b7d26f Mon Sep 17 00:00:00 2001 From: ljacqu Date: Tue, 1 Dec 2015 21:53:18 +0100 Subject: [PATCH 31/82] Refine JavaDoc and move Log filters to 'output' --- src/main/java/fr/xephi/authme/AuthMe.java | 2 ++ .../fr/xephi/authme/{ => output}/ConsoleFilter.java | 13 +------------ .../fr/xephi/authme/{ => output}/Log4JFilter.java | 3 +-- src/main/java/fr/xephi/authme/output/Messages.java | 10 ++++++++++ .../fr/xephi/authme/output/MessagesManager.java | 5 ++++- .../xephi/authme/{ => output}/Log4JFilterTest.java | 4 +--- .../authme/permission/PlayerPermissionTest.java | 3 ++- 7 files changed, 21 insertions(+), 19 deletions(-) rename src/main/java/fr/xephi/authme/{ => output}/ConsoleFilter.java (81%) rename src/main/java/fr/xephi/authme/{ => output}/Log4JFilter.java (98%) rename src/test/java/fr/xephi/authme/{ => output}/Log4JFilterTest.java (98%) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 3018fd0fa..775b22aa2 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -17,6 +17,8 @@ import fr.xephi.authme.hooks.BungeeCordMessage; import fr.xephi.authme.hooks.EssSpawn; import fr.xephi.authme.listener.*; import fr.xephi.authme.modules.ModuleManager; +import fr.xephi.authme.output.ConsoleFilter; +import fr.xephi.authme.output.Log4JFilter; import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.Messages; import fr.xephi.authme.permission.PermissionsManager; diff --git a/src/main/java/fr/xephi/authme/ConsoleFilter.java b/src/main/java/fr/xephi/authme/output/ConsoleFilter.java similarity index 81% rename from src/main/java/fr/xephi/authme/ConsoleFilter.java rename to src/main/java/fr/xephi/authme/output/ConsoleFilter.java index 7e12ef10e..be1c6bec7 100644 --- a/src/main/java/fr/xephi/authme/ConsoleFilter.java +++ b/src/main/java/fr/xephi/authme/output/ConsoleFilter.java @@ -1,4 +1,4 @@ -package fr.xephi.authme; +package fr.xephi.authme.output; import java.util.logging.Filter; import java.util.logging.LogRecord; @@ -7,20 +7,9 @@ import java.util.logging.LogRecord; * Console filter Class * * @author Xephi59 - * @version $Revision: 1.0 $ */ public class ConsoleFilter implements Filter { - public ConsoleFilter() { - } - - /** - * Method isLoggable. - * - * @param record LogRecord - * - * @return boolean * @see java.util.logging.Filter#isLoggable(LogRecord) - */ @Override public boolean isLoggable(LogRecord record) { try { diff --git a/src/main/java/fr/xephi/authme/Log4JFilter.java b/src/main/java/fr/xephi/authme/output/Log4JFilter.java similarity index 98% rename from src/main/java/fr/xephi/authme/Log4JFilter.java rename to src/main/java/fr/xephi/authme/output/Log4JFilter.java index 581699f08..aa43beed1 100644 --- a/src/main/java/fr/xephi/authme/Log4JFilter.java +++ b/src/main/java/fr/xephi/authme/output/Log4JFilter.java @@ -1,4 +1,4 @@ -package fr.xephi.authme; +package fr.xephi.authme.output; import fr.xephi.authme.util.StringUtils; import org.apache.logging.log4j.Level; @@ -11,7 +11,6 @@ import org.apache.logging.log4j.message.Message; * Implements a filter for Log4j to skip sensitive AuthMe commands. * * @author Xephi59 - * @version $Revision: 1.0 $ */ public class Log4JFilter implements org.apache.logging.log4j.core.Filter { diff --git a/src/main/java/fr/xephi/authme/output/Messages.java b/src/main/java/fr/xephi/authme/output/Messages.java index 44930ba48..ad586fd12 100644 --- a/src/main/java/fr/xephi/authme/output/Messages.java +++ b/src/main/java/fr/xephi/authme/output/Messages.java @@ -6,6 +6,8 @@ import org.bukkit.command.CommandSender; /** * Class for retrieving and sending translatable messages to players. + * This class detects when the language settings have changed and will + * automatically update to use a new language file. */ public class Messages { @@ -19,6 +21,11 @@ public class Messages { this.manager = manager; } + /** + * Get the instance of Messages. + * + * @return The Messages instance + */ public static Messages getInstance() { if (singleton == null) { MessagesManager manager = new MessagesManager(Settings.messageFile); @@ -65,6 +72,9 @@ public class Messages { return StringUtils.join("\n", retrieve(key)); } + /** + * Reload the messages manager. + */ public void reloadManager() { manager = new MessagesManager(Settings.messageFile); } diff --git a/src/main/java/fr/xephi/authme/output/MessagesManager.java b/src/main/java/fr/xephi/authme/output/MessagesManager.java index 0a973b908..3221e334f 100644 --- a/src/main/java/fr/xephi/authme/output/MessagesManager.java +++ b/src/main/java/fr/xephi/authme/output/MessagesManager.java @@ -6,7 +6,10 @@ import fr.xephi.authme.settings.CustomConfiguration; import java.io.File; /** - * Class for retrieving and sending translatable messages to players. + * Class responsible for reading messages from a file and formatting them for Minecraft. + *

+ * This class is used within {@link Messages}, which offers a high-level interface for accessing + * or sending messages from a properties file. */ class MessagesManager extends CustomConfiguration { diff --git a/src/test/java/fr/xephi/authme/Log4JFilterTest.java b/src/test/java/fr/xephi/authme/output/Log4JFilterTest.java similarity index 98% rename from src/test/java/fr/xephi/authme/Log4JFilterTest.java rename to src/test/java/fr/xephi/authme/output/Log4JFilterTest.java index f8d185d34..fdd338919 100644 --- a/src/test/java/fr/xephi/authme/Log4JFilterTest.java +++ b/src/test/java/fr/xephi/authme/output/Log4JFilterTest.java @@ -1,4 +1,4 @@ -package fr.xephi.authme; +package fr.xephi.authme.output; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; @@ -12,8 +12,6 @@ import org.mockito.Mockito; /** * Test for {@link Log4JFilter}. - * @author Gabriele - * @version $Revision: 1.0 $ */ public class Log4JFilterTest { diff --git a/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java b/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java index 81893373f..6afc0ac07 100644 --- a/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java +++ b/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java @@ -20,7 +20,8 @@ public class PlayerPermissionTest { // when/then for (PlayerPermission permission : PlayerPermission.values()) { if (!permission.getNode().startsWith(requiredPrefix)) { - fail("The permission '" + permission + "' does not start with the required prefix '" + requiredPrefix + "'"); + fail("The permission '" + permission + "' does not start with the required prefix '" + requiredPrefix + + "'"); } } } From e02af46d65506e4506bd2bd1643cf629592d2930 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Wed, 2 Dec 2015 04:10:56 +0700 Subject: [PATCH 32/82] Lowercase the name input. --- src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java b/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java index 618c50189..5339ac3a3 100644 --- a/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java +++ b/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java @@ -528,7 +528,7 @@ public class PlayerAuth { } public Builder name(String name) { - this.name = name; + this.name = name.toLowerCase(); return this; } From 8d9e212b15f151de329d7b3aed5ff12d5ede4848 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Wed, 2 Dec 2015 04:14:18 +0700 Subject: [PATCH 33/82] Improve register process. * Removed double check for email settings * Use builder for PlayerAuth * Handle exceptions in process method --- .../process/register/AsyncRegister.java | 89 ++++++++++--------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java index 0007ccf3c..22f5b65a0 100644 --- a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java @@ -12,9 +12,6 @@ import fr.xephi.authme.settings.Messages; import fr.xephi.authme.settings.Settings; import org.bukkit.entity.Player; -import java.security.NoSuchAlgorithmException; -import java.util.Date; - /** */ public class AsyncRegister { @@ -22,7 +19,8 @@ public class AsyncRegister { protected final Player player; protected final String name; protected final String password; - protected String email = ""; + private final String ip; + private String email = ""; private final AuthMe plugin; private final DataSource database; private final Messages m; @@ -35,13 +33,10 @@ public class AsyncRegister { this.email = email; this.plugin = plugin; this.database = data; + this.ip = plugin.getIP(player); } - protected String getIp() { - return plugin.getIP(player); - } - - protected boolean preRegisterCheck() throws Exception { + private boolean preRegisterCheck() throws Exception { String passLow = password.toLowerCase(); if (PlayerCache.getInstance().isAuthenticated(name)) { m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); @@ -65,10 +60,10 @@ public class AsyncRegister { m.send(player, MessageKey.NAME_ALREADY_REGISTERED); return false; } else if (Settings.getmaxRegPerIp > 0 - && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) - && database.getAllAuthsByIp(getIp()).size() >= Settings.getmaxRegPerIp - && !getIp().equalsIgnoreCase("127.0.0.1") - && !getIp().equalsIgnoreCase("localhost")) { + && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) + && !ip.equalsIgnoreCase("127.0.0.1") + && !ip.equalsIgnoreCase("localhost") + && database.getAllAuthsByIp(ip).size() >= Settings.getmaxRegPerIp) { m.send(player, MessageKey.MAX_REGISTER_EXCEEDED); return false; } @@ -81,16 +76,10 @@ public class AsyncRegister { return; } if (!email.isEmpty() && !email.equals("")) { - if (Settings.getmaxRegPerEmail > 0 - && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) - && database.getAllAuthsByEmail(email).size() >= Settings.getmaxRegPerEmail) { - m.send(player, MessageKey.MAX_REGISTER_EXCEEDED); - return; - } emailRegister(); - return; + } else { + passwordRegister(); } - passwordRegister(); } catch (Exception e) { ConsoleLogger.showError(e.getMessage()); ConsoleLogger.writeStackTrace(e); @@ -98,20 +87,32 @@ public class AsyncRegister { } } - protected void emailRegister() throws Exception { + private void emailRegister() throws Exception { if (Settings.getmaxRegPerEmail > 0 - && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) - && database.getAllAuthsByEmail(email).size() >= Settings.getmaxRegPerEmail) { + && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) + && database.getAllAuthsByEmail(email).size() >= Settings.getmaxRegPerEmail) { m.send(player, MessageKey.MAX_REGISTER_EXCEEDED); return; } - PlayerAuth auth; final String hashNew = PasswordSecurity.getHash(Settings.getPasswordHash, password, name); - auth = new PlayerAuth(name, hashNew, getIp(), 0, (int) player.getLocation().getX(), (int) player.getLocation().getY(), (int) player.getLocation().getZ(), player.getLocation().getWorld().getName(), email, player.getName()); - if (PasswordSecurity.userSalt.containsKey(name)) { - auth.setSalt(PasswordSecurity.userSalt.get(name)); + final String salt = PasswordSecurity.userSalt.get(name); + PlayerAuth auth = PlayerAuth.builder() + .name(name) + .realName(player.getName()) + .hash(hashNew) + .ip(ip) + .locWorld(player.getLocation().getWorld().getName()) + .locX(player.getLocation().getX()) + .locY(player.getLocation().getY()) + .locZ(player.getLocation().getZ()) + .email(email) + .salt(salt != null ? salt : "") + .build(); + + if (!database.saveAuth(auth)) { + m.send(player, MessageKey.ERROR); + return; } - database.saveAuth(auth); database.updateEmail(auth); database.updateSession(auth); plugin.mail.main(auth, password); @@ -120,21 +121,21 @@ public class AsyncRegister { } - protected void passwordRegister() { - PlayerAuth auth; - String hash; - try { - hash = PasswordSecurity.getHash(Settings.getPasswordHash, password, name); - } catch (NoSuchAlgorithmException e) { - ConsoleLogger.showError(e.getMessage()); - m.send(player, MessageKey.ERROR); - return; - } - if (Settings.getMySQLColumnSalt.isEmpty() && !PasswordSecurity.userSalt.containsKey(name)) { - auth = new PlayerAuth(name, hash, getIp(), new Date().getTime(), "your@email.com", player.getName()); - } else { - auth = new PlayerAuth(name, hash, PasswordSecurity.userSalt.get(name), getIp(), new Date().getTime(), player.getName()); - } + private void passwordRegister() throws Exception { + final String hashNew = PasswordSecurity.getHash(Settings.getPasswordHash, password, name); + final String salt = PasswordSecurity.userSalt.get(name); + PlayerAuth auth = PlayerAuth.builder() + .name(name) + .realName(player.getName()) + .hash(hashNew) + .ip(ip) + .locWorld(player.getLocation().getWorld().getName()) + .locX(player.getLocation().getX()) + .locY(player.getLocation().getY()) + .locZ(player.getLocation().getZ()) + .salt(salt != null ? salt : "") + .build(); + if (!database.saveAuth(auth)) { m.send(player, MessageKey.ERROR); return; From 923020bf071352acac0732a3658f3d5e46ecb55d Mon Sep 17 00:00:00 2001 From: ljacqu Date: Tue, 1 Dec 2015 22:17:18 +0100 Subject: [PATCH 34/82] Reduce duplication in Log filter implementations --- .../fr/xephi/authme/output/ConsoleFilter.java | 21 ++--- .../fr/xephi/authme/output/Log4JFilter.java | 50 ++++-------- .../xephi/authme/output/LogFilterHelper.java | 34 ++++++++ .../authme/output/ConsoleFilterTest.java | 77 +++++++++++++++++++ .../permission/AdminPermissionTest.java | 6 +- 5 files changed, 139 insertions(+), 49 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/output/LogFilterHelper.java create mode 100644 src/test/java/fr/xephi/authme/output/ConsoleFilterTest.java diff --git a/src/main/java/fr/xephi/authme/output/ConsoleFilter.java b/src/main/java/fr/xephi/authme/output/ConsoleFilter.java index be1c6bec7..975cc4cc3 100644 --- a/src/main/java/fr/xephi/authme/output/ConsoleFilter.java +++ b/src/main/java/fr/xephi/authme/output/ConsoleFilter.java @@ -4,7 +4,7 @@ import java.util.logging.Filter; import java.util.logging.LogRecord; /** - * Console filter Class + * Console filter to replace sensitive AuthMe commands with a generic message. * * @author Xephi59 */ @@ -12,20 +12,15 @@ public class ConsoleFilter implements Filter { @Override public boolean isLoggable(LogRecord record) { - try { - if (record == null || record.getMessage() == null) - return true; - String logM = record.getMessage().toLowerCase(); - if (!logM.contains("issued server command:")) - return true; - if (!logM.contains("/login ") && !logM.contains("/l ") && !logM.contains("/reg ") && !logM.contains("/changepassword ") && !logM.contains("/unregister ") && !logM.contains("/authme register ") && !logM.contains("/authme changepassword ") && !logM.contains("/authme reg ") && !logM.contains("/authme cp ") && !logM.contains("/register ")) - return true; - String playerName = record.getMessage().split(" ")[0]; - record.setMessage(playerName + " issued an AuthMe command!"); - return true; - } catch (NullPointerException npe) { + if (record == null || record.getMessage() == null) { return true; } + + if (LogFilterHelper.isSensitiveAuthMeCommand(record.getMessage())) { + String playerName = record.getMessage().split(" ")[0]; + record.setMessage(playerName + " issued an AuthMe command"); + } + return true; } } diff --git a/src/main/java/fr/xephi/authme/output/Log4JFilter.java b/src/main/java/fr/xephi/authme/output/Log4JFilter.java index aa43beed1..89d77ebe9 100644 --- a/src/main/java/fr/xephi/authme/output/Log4JFilter.java +++ b/src/main/java/fr/xephi/authme/output/Log4JFilter.java @@ -1,8 +1,8 @@ package fr.xephi.authme.output; -import fr.xephi.authme.util.StringUtils; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.core.Filter; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.Logger; import org.apache.logging.log4j.message.Message; @@ -12,14 +12,7 @@ import org.apache.logging.log4j.message.Message; * * @author Xephi59 */ -public class Log4JFilter implements org.apache.logging.log4j.core.Filter { - - /** - * List of commands (lower-case) to skip. - */ - private static final String[] COMMANDS_TO_SKIP = {"/login ", "/l ", "/reg ", "/changepassword ", - "/unregister ", "/authme register ", "/authme changepassword ", "/authme reg ", "/authme cp ", - "/register "}; +public class Log4JFilter implements Filter { /** * Constructor. @@ -28,13 +21,12 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter { } /** - * Validates a Message instance and returns the {@link Result} value - * depending depending on whether the message contains sensitive AuthMe - * data. + * Validate a Message instance and return the {@link Result} value + * depending on whether the message contains sensitive AuthMe data. * - * @param message the Message object to verify + * @param message The Message object to verify * - * @return the Result value + * @return The Result value */ private static Result validateMessage(Message message) { if (message == null) { @@ -44,24 +36,17 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter { } /** - * Validates a message and returns the {@link Result} value depending - * depending on whether the message contains sensitive AuthMe data. + * Validate a message and return the {@link Result} value depending + * on whether the message contains sensitive AuthMe data. * - * @param message the message to verify + * @param message The message to verify * - * @return the Result value + * @return The Result value */ private static Result validateMessage(String message) { - if (message == null) { - return Result.NEUTRAL; - } - - String lowerMessage = message.toLowerCase(); - if (lowerMessage.contains("issued server command:") - && StringUtils.containsAny(lowerMessage, COMMANDS_TO_SKIP)) { - return Result.DENY; - } - return Result.NEUTRAL; + return LogFilterHelper.isSensitiveAuthMeCommand(message) + ? Result.DENY + : Result.NEUTRAL; } @Override @@ -73,14 +58,12 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter { } @Override - public Result filter(Logger arg0, Level arg1, Marker arg2, String message, - Object... arg4) { + public Result filter(Logger arg0, Level arg1, Marker arg2, String message, Object... arg4) { return validateMessage(message); } @Override - public Result filter(Logger arg0, Level arg1, Marker arg2, Object message, - Throwable arg4) { + public Result filter(Logger arg0, Level arg1, Marker arg2, Object message, Throwable arg4) { if (message == null) { return Result.NEUTRAL; } @@ -88,8 +71,7 @@ public class Log4JFilter implements org.apache.logging.log4j.core.Filter { } @Override - public Result filter(Logger arg0, Level arg1, Marker arg2, Message message, - Throwable arg4) { + public Result filter(Logger arg0, Level arg1, Marker arg2, Message message, Throwable arg4) { return validateMessage(message); } diff --git a/src/main/java/fr/xephi/authme/output/LogFilterHelper.java b/src/main/java/fr/xephi/authme/output/LogFilterHelper.java new file mode 100644 index 000000000..605283ac2 --- /dev/null +++ b/src/main/java/fr/xephi/authme/output/LogFilterHelper.java @@ -0,0 +1,34 @@ +package fr.xephi.authme.output; + +import fr.xephi.authme.util.StringUtils; + +/** + * Service class for the log filters. + */ +public final class LogFilterHelper { + + private static final String ISSUED_COMMAND_TEXT = "issued server command:"; + + private static final String[] COMMANDS_TO_SKIP = {"/login ", "/l ", "/reg ", "/changepassword ", + "/unregister ", "/authme register ", "/authme changepassword ", "/authme reg ", "/authme cp ", + "/register "}; + + private LogFilterHelper() { + // Util class + } + + /** + * Validate a message and return whether the message contains a sensitive AuthMe command. + * + * @param message The message to verify + * + * @return True if it is a sensitive AuthMe command, false otherwise + */ + public static boolean isSensitiveAuthMeCommand(String message) { + if (message == null) { + return false; + } + String lowerMessage = message.toLowerCase(); + return lowerMessage.contains(ISSUED_COMMAND_TEXT) && StringUtils.containsAny(lowerMessage, COMMANDS_TO_SKIP); + } +} diff --git a/src/test/java/fr/xephi/authme/output/ConsoleFilterTest.java b/src/test/java/fr/xephi/authme/output/ConsoleFilterTest.java new file mode 100644 index 000000000..8975068f6 --- /dev/null +++ b/src/test/java/fr/xephi/authme/output/ConsoleFilterTest.java @@ -0,0 +1,77 @@ +package fr.xephi.authme.output; + +import org.junit.Test; +import org.mockito.Mockito; + +import java.util.logging.LogRecord; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + * Test for {@link ConsoleFilter}. + */ +public class ConsoleFilterTest { + + private final ConsoleFilter filter = new ConsoleFilter(); + + private static final String SENSITIVE_COMMAND = "User issued server command: /login test test"; + private static final String NORMAL_COMMAND = "User issued server command: /motd 2"; + + + @Test + public void shouldReplaceSensitiveRecord() { + // given + LogRecord record = createRecord(SENSITIVE_COMMAND); + + // when + boolean result = filter.isLoggable(record); + + // then + assertThat(result, equalTo(true)); + verify(record).setMessage("User issued an AuthMe command"); + } + + @Test + public void shouldNotFilterRegularCommand() { + // given + LogRecord record = createRecord(NORMAL_COMMAND); + + // when + boolean result = filter.isLoggable(record); + + // then + assertThat(result, equalTo(true)); + verify(record, never()).setMessage("User issued an AuthMe command"); + } + + @Test + public void shouldManageRecordWithNullMessage() { + // given + LogRecord record = createRecord(null); + + // when + boolean result = filter.isLoggable(record); + + // then + assertThat(result, equalTo(true)); + verify(record, never()).setMessage("User issued an AuthMe command"); + } + + + /** + * Creates a mock of {@link LogRecord} and sets it to return the given message. + * + * @param message The message to set. + * + * @return Mock of LogRecord + */ + private static LogRecord createRecord(String message) { + LogRecord record = Mockito.mock(LogRecord.class); + when(record.getMessage()).thenReturn(message); + return record; + } +} diff --git a/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java b/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java index c3a89b723..9a8625ac0 100644 --- a/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java +++ b/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java @@ -20,7 +20,8 @@ public class AdminPermissionTest { // when/then for (AdminPermission permission : AdminPermission.values()) { if (!permission.getNode().startsWith(requiredPrefix)) { - fail("The permission '" + permission + "' does not start with the required prefix '" + requiredPrefix + "'"); + fail("The permission '" + permission + "' does not start with the required prefix '" + + requiredPrefix + "'"); } } } @@ -33,7 +34,8 @@ public class AdminPermissionTest { // when/then for (AdminPermission permission : AdminPermission.values()) { if (!permission.getNode().contains(requiredBranch)) { - fail("The permission '" + permission + "' does not contain with the required branch '" + requiredBranch + "'"); + fail("The permission '" + permission + "' does not contain with the required branch '" + + requiredBranch + "'"); } } } From a8f3a441d55961831cb3846c3401cf800808dc39 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Wed, 2 Dec 2015 04:53:12 +0700 Subject: [PATCH 35/82] Lowercase PlayerAuth nickname in constructor and setter. --- .../xephi/authme/cache/auth/PlayerAuth.java | 101 +++++++++--------- 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java b/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java index 01622c177..b21aa9d4b 100644 --- a/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java +++ b/src/main/java/fr/xephi/authme/cache/auth/PlayerAuth.java @@ -23,9 +23,8 @@ public class PlayerAuth { /** * */ - public PlayerAuth(String serialized) - { - this.unserialize(serialized); + public PlayerAuth(String serialized) { + this.deserialize(serialized); } /** @@ -163,8 +162,10 @@ public class PlayerAuth { * @param email String * @param realName String */ - public PlayerAuth(String nickname, String hash, String salt, int groupId, String ip, long lastLogin, double x, double y, double z, String world, String email, String realName) { - this.nickname = nickname; + public PlayerAuth(String nickname, String hash, String salt, int groupId, String ip, + long lastLogin, double x, double y, double z, String world, String email, + String realName) { + this.nickname = nickname.toLowerCase(); this.hash = hash; this.ip = ip; this.lastLogin = lastLogin; @@ -203,7 +204,7 @@ public class PlayerAuth { * @param nickname String */ public void setName(String nickname) { - this.nickname = nickname; + this.nickname = nickname.toLowerCase(); } /** @@ -455,47 +456,45 @@ public class PlayerAuth { } /** - * Method to serialize playerauth + * Method to serialize PlayerAuth * * @return String */ - public String serialize() - { - StringBuilder str = new StringBuilder(); - str.append(this.nickname).append(';'); - str.append(this.realName).append(';'); - str.append(this.ip).append(';'); - str.append(this.email).append(';'); - str.append(this.hash).append(';'); - str.append(this.salt).append(';'); - str.append(this.groupId).append(';'); - str.append(this.lastLogin).append(';'); - str.append(this.world).append(';'); - str.append(this.x).append(';'); - str.append(this.y).append(';'); - str.append(this.z); - return str.toString(); + public String serialize() { + StringBuilder str = new StringBuilder(); + char d = ';'; + str.append(this.nickname).append(d); + str.append(this.realName).append(d); + str.append(this.ip).append(d); + str.append(this.email).append(d); + str.append(this.hash).append(d); + str.append(this.salt).append(d); + str.append(this.groupId).append(d); + str.append(this.lastLogin).append(d); + str.append(this.world).append(d); + str.append(this.x).append(d); + str.append(this.y).append(d); + str.append(this.z); + return str.toString(); } /** - * Method to unserialize playerauth - * + * Method to deserialize PlayerAuth */ - public void unserialize(String str) - { - String[] args = str.split(";"); - this.nickname = args[0]; - this.realName = args[1]; - this.ip = args[2]; - this.email = args[3]; - this.hash = args[4]; - this.salt = args[5]; - this.groupId = Integer.parseInt(args[6]); - this.lastLogin = Long.parseLong(args[7]); - this.world = args[8]; - this.x = Double.parseDouble(args[9]); - this.y = Double.parseDouble(args[10]); - this.z = Double.parseDouble(args[11]); + public void deserialize(String str) { + String[] args = str.split(";"); + this.nickname = args[0]; + this.realName = args[1]; + this.ip = args[2]; + this.email = args[3]; + this.hash = args[4]; + this.salt = args[5]; + this.groupId = Integer.parseInt(args[6]); + this.lastLogin = Long.parseLong(args[7]); + this.world = args[8]; + this.x = Double.parseDouble(args[9]); + this.y = Double.parseDouble(args[10]); + this.z = Double.parseDouble(args[11]); } public static Builder builder() { @@ -504,17 +503,17 @@ public class PlayerAuth { public static final class Builder { private String name; - private String realName; - private String hash; - private String salt; - private String ip; - private String world; - private double x; - private double y; - private double z; - private long lastLogin; - private int groupId; - private String email; + private String realName = "Player"; + private String hash = ""; + private String salt = ""; + private String ip = "127.0.0.1"; + private String world = "world"; + private double x = 0.0f; + private double y = 0.0f; + private double z = 0.0f; + private long lastLogin = System.currentTimeMillis(); + private int groupId = -1; + private String email = "your@email.com"; public PlayerAuth build() { return new PlayerAuth( From 35d73b2d4afbccaa136589d5f631ae034f4eec35 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Wed, 2 Dec 2015 06:29:43 +0700 Subject: [PATCH 36/82] Mysql Improvements. * Contains lot of changes --- .../fr/xephi/authme/datasource/MySQL.java | 1214 ++++++++--------- .../fr/xephi/authme/settings/Settings.java | 7 +- 2 files changed, 560 insertions(+), 661 deletions(-) diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java index 455361a49..fd7261a5f 100644 --- a/src/main/java/fr/xephi/authme/datasource/MySQL.java +++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java @@ -1,6 +1,5 @@ package fr.xephi.authme.datasource; -import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.pool.PoolInitializationException; import fr.xephi.authme.AuthMe; @@ -36,10 +35,9 @@ public class MySQL implements DataSource { private final String columnEmail; private final String columnID; private final String columnLogged; + private final String columnRealName; private final List columnOthers; private HikariDataSource ds; - private final String columnRealName; - private final int maxConnections; /** * Constructor for MySQL. @@ -68,7 +66,6 @@ public class MySQL implements DataSource { this.columnID = Settings.getMySQLColumnId; this.columnLogged = Settings.getMySQLColumnLogged; this.columnRealName = Settings.getMySQLColumnRealName; - this.maxConnections = Settings.getMySQLMaxConnections; // Set the connection arguments (and check if connection is ok) try { @@ -76,15 +73,15 @@ public class MySQL implements DataSource { } catch (RuntimeException e) { if (e instanceof IllegalArgumentException) { ConsoleLogger.showError("Invalid database arguments! Please check your configuration!"); - ConsoleLogger.showError("If this error persists, please report it to the developer! SHUTDOWN..."); + ConsoleLogger.showError("If this error persists, please report it to the developer!"); throw new IllegalArgumentException(e); } if (e instanceof PoolInitializationException) { ConsoleLogger.showError("Can't initialize database connection! Please check your configuration!"); - ConsoleLogger.showError("If this error persists, please report it to the developer! SHUTDOWN..."); + ConsoleLogger.showError("If this error persists, please report it to the developer!"); throw new PoolInitializationException(e); } - ConsoleLogger.showError("Can't use the Hikari Connection Pool! Please, report this error to the developer! SHUTDOWN..."); + ConsoleLogger.showError("Can't use the Hikari Connection Pool! Please, report this error to the developer!"); throw e; } @@ -94,7 +91,7 @@ public class MySQL implements DataSource { } catch (SQLException e) { this.close(); ConsoleLogger.showError("Can't initialize the MySQL database... Please check your database settings in the config.yml file! SHUTDOWN..."); - ConsoleLogger.showError("If this error persists, please report it to the developer! SHUTDOWN..."); + ConsoleLogger.showError("If this error persists, please report it to the developer!"); throw e; } } @@ -102,34 +99,29 @@ public class MySQL implements DataSource { /** * Method setConnectionArguments. * - * @throws ClassNotFoundException * @throws IllegalArgumentException + * @throws RuntimeException */ - private synchronized void setConnectionArguments() - throws IllegalArgumentException { - HikariConfig config = new HikariConfig(); - config.setPoolName("AuthMeMYSQLPool"); - config.setDriverClassName("com.mysql.jdbc.Driver"); - config.setJdbcUrl("jdbc:mysql://" + this.host + ":" + this.port + "/" + this.database); - config.setUsername(this.username); - config.setPassword(this.password); - config.addDataSourceProperty("cachePrepStmts", "false"); - config.addDataSourceProperty("autoReconnect", false); - config.setInitializationFailFast(true); // Don't start the plugin if the database is unavailable - config.setMaxLifetime(180000); // 3 Min - config.setIdleTimeout(60000); // 1 Min - config.setMinimumIdle(2); - config.setMaximumPoolSize(maxConnections); - ds = new HikariDataSource(config); + private synchronized void setConnectionArguments() throws RuntimeException { + ds = new HikariDataSource(); + ds.setPoolName("AuthMeMYSQLPool"); + ds.setDriverClassName("com.mysql.jdbc.Driver"); + ds.setJdbcUrl("jdbc:mysql://" + this.host + ":" + this.port + "/" + this.database + "?rewriteBatchedStatements=true"); + ds.setUsername(this.username); + ds.setPassword(this.password); + ds.setInitializationFailFast(true); // Don't start the plugin if the database is unavailable + ds.setMaxLifetime(180000); // 3 Min + ds.setIdleTimeout(60000); // 1 Min + ds.setMinimumIdle(2); + ds.setMaximumPoolSize((Runtime.getRuntime().availableProcessors() * 2) + 1); ConsoleLogger.info("Connection arguments loaded, Hikari ConnectionPool ready!"); } /** * Method reloadArguments. * - * @throws ClassNotFoundException * @throws IllegalArgumentException + * @throws RuntimeException */ - private synchronized void reloadArguments() - throws ClassNotFoundException, IllegalArgumentException { + private synchronized void reloadArguments() throws RuntimeException { if (ds != null) { ds.close(); } @@ -152,64 +144,102 @@ public class MySQL implements DataSource { * @throws SQLException */ private synchronized void setupConnection() throws SQLException { - Connection con = null; - Statement st = null; - ResultSet rs = null; - try { - if ((con = getConnection()) == null) - return; - st = con.createStatement(); - st.executeUpdate("CREATE TABLE IF NOT EXISTS " + tableName + " (" + columnID + " INTEGER AUTO_INCREMENT," + columnName + " VARCHAR(255) NOT NULL UNIQUE," + columnPassword + " VARCHAR(255) NOT NULL," + columnIp + " VARCHAR(40) NOT NULL DEFAULT '127.0.0.1'," + columnLastLogin + " BIGINT NOT NULL DEFAULT '" + System.currentTimeMillis() + "'," + lastlocX + " DOUBLE NOT NULL DEFAULT '0.0'," + lastlocY + " DOUBLE NOT NULL DEFAULT '0.0'," + lastlocZ + " DOUBLE NOT NULL DEFAULT '0.0'," + lastlocWorld + " VARCHAR(255) NOT NULL DEFAULT '" + Settings.defaultWorld + "'," + columnEmail + " VARCHAR(255) DEFAULT 'your@email.com'," + columnLogged + " SMALLINT NOT NULL DEFAULT '0'," + "CONSTRAINT table_const_prim PRIMARY KEY (" + columnID + "));"); - rs = con.getMetaData().getColumns(null, null, tableName, columnPassword); + try (Connection con = getConnection()) { + Statement st = con.createStatement(); + DatabaseMetaData md = con.getMetaData(); + // Create table if not exists. + String sql = "CREATE TABLE IF NOT EXISTS " + tableName + " (" + + columnID + " INTEGER AUTO_INCREMENT," + + columnName + " VARCHAR(255) NOT NULL UNIQUE," + + columnRealName + " VARCHAR(255) NOT NULL," + + columnPassword + " VARCHAR(255) NOT NULL," + + columnIp + " VARCHAR(40) NOT NULL DEFAULT '127.0.0.1'," + + columnLastLogin + " BIGINT NOT NULL DEFAULT '" + System.currentTimeMillis() + "'," + + lastlocX + " DOUBLE NOT NULL DEFAULT '0.0'," + + lastlocY + " DOUBLE NOT NULL DEFAULT '0.0'," + + lastlocZ + " DOUBLE NOT NULL DEFAULT '0.0'," + + lastlocWorld + " VARCHAR(255) NOT NULL DEFAULT '" + Settings.defaultWorld + "'," + + columnEmail + " VARCHAR(255) DEFAULT 'your@email.com'," + + columnLogged + " SMALLINT NOT NULL DEFAULT '0'," + + "CONSTRAINT table_const_prim PRIMARY KEY (" + columnID + ")" + + ");"; + st.executeUpdate(sql); + + ResultSet rs = md.getColumns(null, null, tableName, columnName); if (!rs.next()) { - st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + columnPassword + " VARCHAR(255) NOT NULL;"); + st.executeUpdate("ALTER TABLE " + tableName + + " ADD COLUMN " + columnName + " VARCHAR(255) NOT NULL UNIQUE AFTER " + columnID + ";"); } rs.close(); - rs = con.getMetaData().getColumns(null, null, tableName, columnIp); + + rs = md.getColumns(null, null, tableName, columnRealName); if (!rs.next()) { - st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + columnIp + " VARCHAR(40) NOT NULL;"); + st.executeUpdate("ALTER TABLE " + tableName + + " ADD COLUMN " + columnRealName + " VARCHAR(255) NOT NULL AFTER " + columnName + ";"); } rs.close(); - rs = con.getMetaData().getColumns(null, null, tableName, columnLastLogin); + + rs = md.getColumns(null, null, tableName, columnPassword); if (!rs.next()) { - st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + columnLastLogin + " BIGINT;"); + st.executeUpdate("ALTER TABLE " + tableName + + " ADD COLUMN " + columnPassword + " VARCHAR(255) NOT NULL;"); } rs.close(); - rs = con.getMetaData().getColumns(null, null, tableName, lastlocX); + + rs = md.getColumns(null, null, tableName, columnIp); if (!rs.next()) { - st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + lastlocX + " DOUBLE NOT NULL DEFAULT '0.0' AFTER " + columnLastLogin + " , ADD " + lastlocY + " DOUBLE NOT NULL DEFAULT '0.0' AFTER " + lastlocX + " , ADD " + lastlocZ + " DOUBLE NOT NULL DEFAULT '0.0' AFTER " + lastlocY + ";"); + st.executeUpdate("ALTER TABLE " + tableName + + " ADD COLUMN " + columnIp + " VARCHAR(40) NOT NULL;"); } rs.close(); - rs = con.getMetaData().getColumns(null, null, tableName, lastlocWorld); + + rs = md.getColumns(null, null, tableName, columnLastLogin); if (!rs.next()) { - st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + lastlocWorld + " VARCHAR(255) NOT NULL DEFAULT 'world' AFTER " + lastlocZ + ";"); + st.executeUpdate("ALTER TABLE " + tableName + + " ADD COLUMN " + columnLastLogin + " BIGINT;"); } rs.close(); - rs = con.getMetaData().getColumns(null, null, tableName, columnEmail); + + rs = md.getColumns(null, null, tableName, lastlocX); if (!rs.next()) { - st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + columnEmail + " VARCHAR(255) DEFAULT 'your@email.com' AFTER " + lastlocWorld + ";"); + st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + + lastlocX + " DOUBLE NOT NULL DEFAULT '0.0' AFTER " + columnLastLogin + " , ADD " + + lastlocY + " DOUBLE NOT NULL DEFAULT '0.0' AFTER " + lastlocX + " , ADD " + + lastlocZ + " DOUBLE NOT NULL DEFAULT '0.0' AFTER " + lastlocY); } rs.close(); - rs = con.getMetaData().getColumns(null, null, tableName, columnLogged); - if (!rs.next()) { - st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + columnLogged + " SMALLINT NOT NULL DEFAULT '0' AFTER " + columnEmail + ";"); - } - rs.close(); - rs = con.getMetaData().getColumns(null, null, tableName, lastlocX); + + rs = md.getColumns(null, null, tableName, lastlocX); if (rs.next()) { - st.executeUpdate("ALTER TABLE " + tableName + " MODIFY " + lastlocX + " DOUBLE NOT NULL DEFAULT '0.0', MODIFY " + lastlocY + " DOUBLE NOT NULL DEFAULT '0.0', MODIFY " + lastlocZ + " DOUBLE NOT NULL DEFAULT '0.0';"); + st.executeUpdate("ALTER TABLE " + tableName + " MODIFY " + + lastlocX + " DOUBLE NOT NULL DEFAULT '0.0', MODIFY " + + lastlocY + " DOUBLE NOT NULL DEFAULT '0.0', MODIFY " + + lastlocZ + " DOUBLE NOT NULL DEFAULT '0.0';"); } rs.close(); - rs = con.getMetaData().getColumns(null, null, tableName, columnRealName); + + rs = md.getColumns(null, null, tableName, lastlocWorld); if (!rs.next()) { - st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + columnRealName + " VARCHAR(255) NOT NULL DEFAULT 'Player' AFTER " + columnLogged + ";"); + st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + + lastlocWorld + " VARCHAR(255) NOT NULL DEFAULT 'world' AFTER " + lastlocZ); } - if (Settings.isMySQLWebsite) - st.execute("SET GLOBAL query_cache_size = 0; SET GLOBAL query_cache_type = 0;"); - } finally { - close(rs); - close(st); - close(con); + rs.close(); + + rs = md.getColumns(null, null, tableName, columnEmail); + if (!rs.next()) { + st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + + columnEmail + " VARCHAR(255) DEFAULT 'your@email.com' AFTER " + lastlocWorld); + } + rs.close(); + + rs = md.getColumns(null, null, tableName, columnLogged); + if (!rs.next()) { + st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + + columnLogged + " SMALLINT NOT NULL DEFAULT '0' AFTER " + columnEmail); + } + rs.close(); + + st.close(); } ConsoleLogger.info("MySQL Setup finished"); } @@ -223,24 +253,16 @@ public class MySQL implements DataSource { */ @Override public synchronized boolean isAuthAvailable(String user) { - Connection con = null; - PreparedStatement pst = null; - ResultSet rs = null; - try { - if ((con = getConnection()) == null) - return true; - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE LOWER(" + columnName + ")=LOWER(?);"); - pst.setString(1, user); - rs = pst.executeQuery(); + try (Connection con = getConnection()) { + String sql = "SELECT " + columnName + " FROM " + tableName + " WHERE " + columnName + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); + pst.setString(1, user.toLowerCase()); + ResultSet rs = pst.executeQuery(); return rs.next(); } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return false; - } finally { - close(rs); - close(pst); - close(con); } + return false; } /** @@ -252,53 +274,50 @@ public class MySQL implements DataSource { */ @Override public synchronized PlayerAuth getAuth(String user) { - Connection con = null; - PreparedStatement pst = null; - ResultSet rs = null; - PlayerAuth pAuth = null; - int id; - try { - if ((con = getConnection()) == null) + PlayerAuth pAuth; + try (Connection con = getConnection()) { + String sql = "SELECT * FROM " + tableName + " WHERE " + columnName + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); + pst.setString(1, user.toLowerCase()); + ResultSet rs = pst.executeQuery(); + if (!rs.next()) { return null; - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE LOWER(" + columnName + ")=LOWER(?);"); - pst.setString(1, user); - rs = pst.executeQuery(); - if (rs.next()) { - id = rs.getInt(columnID); - if (rs.getString(columnIp).isEmpty() && rs.getString(columnIp) != null) { - pAuth = new PlayerAuth(rs.getString(columnName).toLowerCase(), rs.getString(columnPassword), "192.168.0.1", rs.getLong(columnLastLogin), rs.getDouble(lastlocX), rs.getDouble(lastlocY), rs.getDouble(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail), rs.getString(columnRealName)); - } else { - if (!columnSalt.isEmpty()) { - if (!columnGroup.isEmpty()) - pAuth = new PlayerAuth(rs.getString(columnName).toLowerCase(), rs.getString(columnPassword), rs.getString(columnSalt), rs.getInt(columnGroup), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getDouble(lastlocX), rs.getDouble(lastlocY), rs.getDouble(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail), rs.getString(columnRealName)); - else - pAuth = new PlayerAuth(rs.getString(columnName).toLowerCase(), rs.getString(columnPassword), rs.getString(columnSalt), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getDouble(lastlocX), rs.getDouble(lastlocY), rs.getDouble(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail), rs.getString(columnRealName)); - } else { - pAuth = new PlayerAuth(rs.getString(columnName).toLowerCase(), rs.getString(columnPassword), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getDouble(lastlocX), rs.getDouble(lastlocY), rs.getDouble(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail), rs.getString(columnRealName)); - } + } + + String salt = !columnSalt.isEmpty() ? rs.getString(columnSalt) : ""; + int group = !salt.isEmpty() && !columnGroup.isEmpty() ? rs.getInt(columnGroup) : -1; + + pAuth = PlayerAuth.builder() + .name(rs.getString(columnName)) + .realName(rs.getString(columnRealName)) + .hash(rs.getString(columnPassword)) + .lastLogin(rs.getLong(columnLastLogin)) + .ip(rs.getString(columnIp)) + .locWorld(rs.getString(lastlocWorld)) + .locX(rs.getDouble(lastlocX)) + .locY(rs.getDouble(lastlocY)) + .locZ(rs.getDouble(lastlocZ)) + .email(rs.getString(columnEmail)) + .salt(salt) + .groupId(group) + .build(); + + if (Settings.getPasswordHash == HashAlgorithm.XENFORO) { + int id = rs.getInt(columnID); + rs.close(); + pst.close(); + pst = con.prepareStatement("SELECT data FROM xf_user_authenticate WHERE " + columnID + "=?;"); + pst.setInt(1, id); + rs = pst.executeQuery(); + if (rs.next()) { + Blob blob = rs.getBlob("data"); + byte[] bytes = blob.getBytes(1, (int) blob.length()); + pAuth.setHash(new String(bytes)); } - if (Settings.getPasswordHash == HashAlgorithm.XENFORO) { - rs.close(); - pst.close(); - pst = con.prepareStatement("SELECT * FROM xf_user_authenticate WHERE " + columnID + "=?;"); - pst.setInt(1, id); - rs = pst.executeQuery(); - if (rs.next()) { - Blob blob = rs.getBlob("data"); - byte[] bytes = blob.getBytes(1, (int) blob.length()); - pAuth.setHash(new String(bytes)); - } - } - } else { - return null; } } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); return null; - } finally { - close(rs); - close(pst); - close(con); } return pAuth; } @@ -308,36 +327,36 @@ public class MySQL implements DataSource { * * @param auth PlayerAuth * - * @return boolean * @see fr.xephi.authme.datasource.DataSource#saveAuth(PlayerAuth) + * @return boolean + * + * @see fr.xephi.authme.datasource.DataSource#saveAuth(PlayerAuth) */ @Override public synchronized boolean saveAuth(PlayerAuth auth) { - Connection con = null; - PreparedStatement pst = null; - ResultSet rs = null; - try { - if ((con = getConnection()) == null) - return false; - if ((columnSalt == null || columnSalt.isEmpty()) || (auth.getSalt() == null || auth.getSalt().isEmpty())) { - pst = con.prepareStatement("INSERT INTO " + tableName + "(" + columnName + "," + columnPassword + "," + columnIp + "," + columnLastLogin + "," + columnRealName + ") VALUES (?,?,?,?,?);"); - pst.setString(1, auth.getNickname()); - pst.setString(2, auth.getHash()); - pst.setString(3, auth.getIp()); - pst.setLong(4, auth.getLastLogin()); - pst.setString(5, auth.getRealName()); - pst.executeUpdate(); - pst.close(); - } else { - pst = con.prepareStatement("INSERT INTO " + tableName + "(" + columnName + "," + columnPassword + "," + columnIp + "," + columnLastLogin + "," + columnSalt + "," + columnRealName + ") VALUES (?,?,?,?,?,?);"); - pst.setString(1, auth.getNickname()); - pst.setString(2, auth.getHash()); - pst.setString(3, auth.getIp()); - pst.setLong(4, auth.getLastLogin()); - pst.setString(5, auth.getSalt()); - pst.setString(6, auth.getRealName()); - pst.executeUpdate(); - pst.close(); + try (Connection con = getConnection()) { + PreparedStatement pst; + PreparedStatement pst2; + ResultSet rs; + String sql; + + boolean useSalt = !columnSalt.isEmpty() || !auth.getSalt().isEmpty(); + sql = "INSERT INTO " + tableName + "(" + + columnName + "," + columnPassword + "," + columnIp + "," + + columnLastLogin + "," + columnRealName + + (useSalt ? "," + columnSalt : "") + + ") VALUES (?,?,?,?,?" + (useSalt ? ",?" : "") + ");"; + pst = con.prepareStatement(sql); + pst.setString(1, auth.getNickname()); + pst.setString(2, auth.getHash()); + pst.setString(3, auth.getIp()); + pst.setLong(4, auth.getLastLogin()); + pst.setString(5, auth.getRealName()); + if (useSalt) { + pst.setString(6, auth.getSalt()); } + pst.executeUpdate(); + pst.close(); + if (!columnOthers.isEmpty()) { for (String column : columnOthers) { pst = con.prepareStatement("UPDATE " + tableName + " SET " + column + "=? WHERE " + columnName + "=?;"); @@ -347,174 +366,168 @@ public class MySQL implements DataSource { pst.close(); } } + if (Settings.getPasswordHash == HashAlgorithm.PHPBB) { - PreparedStatement pst2 = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnName + "=?;"); - pst2.setString(1, auth.getNickname()); - rs = pst2.executeQuery(); - if (rs.next()) { - int id = rs.getInt(columnID); - // Insert player in phpbb_user_group - pst = con.prepareStatement("INSERT INTO " + Settings.getPhpbbPrefix + "user_group (group_id, user_id, group_leader, user_pending) VALUES (?,?,?,?);"); - pst.setInt(1, Settings.getPhpbbGroup); - pst.setInt(2, id); - pst.setInt(3, 0); - pst.setInt(4, 0); - pst.executeUpdate(); - pst.close(); - // Update username_clean in phpbb_users - pst = con.prepareStatement("UPDATE " + tableName + " SET " + tableName + ".username_clean=? WHERE " + columnName + "=?;"); - pst.setString(1, auth.getNickname().toLowerCase()); - pst.setString(2, auth.getNickname()); - pst.executeUpdate(); - pst.close(); - // Update player group in phpbb_users - pst = con.prepareStatement("UPDATE " + tableName + " SET " + tableName + ".group_id=? WHERE " + columnName + "=?;"); - pst.setInt(1, Settings.getPhpbbGroup); - pst.setString(2, auth.getNickname()); - pst.executeUpdate(); - pst.close(); - // Get current time without ms - long time = System.currentTimeMillis() / 1000; - // Update user_regdate - pst = con.prepareStatement("UPDATE " + tableName + " SET " + tableName + ".user_regdate=? WHERE " + columnName + "=?;"); - pst.setLong(1, time); - pst.setString(2, auth.getNickname()); - pst.executeUpdate(); - pst.close(); - // Update user_lastvisit - pst = con.prepareStatement("UPDATE " + tableName + " SET " + tableName + ".user_lastvisit=? WHERE " + columnName + "=?;"); - pst.setLong(1, time); - pst.setString(2, auth.getNickname()); - pst.executeUpdate(); - pst.close(); - // Increment num_users - pst = con.prepareStatement("UPDATE " + Settings.getPhpbbPrefix + "config SET config_value = config_value + 1 WHERE config_name = 'num_users';"); - pst.executeUpdate(); - pst.close(); - } - rs.close(); - pst2.close(); - } - if (Settings.getPasswordHash == HashAlgorithm.WORDPRESS) { - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnName + "=?;"); + sql = "SELECT " + columnID + " FROM " + tableName + " WHERE " + columnName + "=?;"; + pst = con.prepareStatement(sql); pst.setString(1, auth.getNickname()); rs = pst.executeQuery(); if (rs.next()) { int id = rs.getInt(columnID); - // First Name - pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "first_name"); - pst.setString(3, ""); - pst.executeUpdate(); - pst.close(); - // Last Name - pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "last_name"); - pst.setString(3, ""); - pst.executeUpdate(); - pst.close(); - // Nick Name - pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "nickname"); - pst.setString(3, auth.getNickname()); - pst.executeUpdate(); - pst.close(); - // Description - pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "description"); - pst.setString(3, ""); - pst.executeUpdate(); - pst.close(); - // Rich_Editing - pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "rich_editing"); - pst.setString(3, "true"); - pst.executeUpdate(); - pst.close(); - // Comments_Shortcuts - pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "comment_shortcuts"); - pst.setString(3, "false"); - pst.executeUpdate(); - pst.close(); - // admin_color - pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "admin_color"); - pst.setString(3, "fresh"); - pst.executeUpdate(); - pst.close(); - // use_ssl - pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "use_ssl"); - pst.setString(3, "0"); - pst.executeUpdate(); - pst.close(); - // show_admin_bar_front - pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "show_admin_bar_front"); - pst.setString(3, "true"); - pst.executeUpdate(); - pst.close(); - // wp_capabilities - pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "wp_capabilities"); - pst.setString(3, "a:1:{s:10:\"subscriber\";b:1;}"); - pst.executeUpdate(); - pst.close(); - // wp_user_level - pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "wp_user_level"); - pst.setString(3, "0"); - pst.executeUpdate(); - pst.close(); - // default_password_nag - pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "default_password_nag"); - pst.setString(3, ""); - pst.executeUpdate(); - pst.close(); + // Insert player in phpbb_user_group + sql = "INSERT INTO " + Settings.getPhpbbPrefix + + "user_group (group_id, user_id, group_leader, user_pending) VALUES (?,?,?,?);"; + pst2 = con.prepareStatement(sql); + pst2.setInt(1, Settings.getPhpbbGroup); + pst2.setInt(2, id); + pst2.setInt(3, 0); + pst2.setInt(4, 0); + pst2.executeUpdate(); + pst2.close(); + // Update username_clean in phpbb_users + sql = "UPDATE " + tableName + " SET " + tableName + + ".username_clean=? WHERE " + columnName + "=?;"; + pst2 = con.prepareStatement(sql); + pst2.setString(1, auth.getNickname()); + pst2.setString(2, auth.getNickname()); + pst2.executeUpdate(); + pst2.close(); + // Update player group in phpbb_users + sql = "UPDATE " + tableName + " SET " + tableName + + ".group_id=? WHERE " + columnName + "=?;"; + pst2 = con.prepareStatement(sql); + pst2.setInt(1, Settings.getPhpbbGroup); + pst2.setString(2, auth.getNickname()); + pst2.executeUpdate(); + pst2.close(); + // Get current time without ms + long time = System.currentTimeMillis() / 1000; + // Update user_regdate + sql = "UPDATE " + tableName + " SET " + tableName + + ".user_regdate=? WHERE " + columnName + "=?;"; + pst2 = con.prepareStatement(sql); + pst2.setLong(1, time); + pst2.setString(2, auth.getNickname()); + pst2.executeUpdate(); + pst2.close(); + // Update user_lastvisit + sql = "UPDATE " + tableName + " SET " + tableName + + ".user_lastvisit=? WHERE " + columnName + "=?;"; + pst2 = con.prepareStatement(sql); + pst2.setLong(1, time); + pst2.setString(2, auth.getNickname()); + pst2.executeUpdate(); + pst2.close(); + // Increment num_users + sql = "UPDATE " + Settings.getPhpbbPrefix + + "config SET config_value = config_value + 1 WHERE config_name = 'num_users';"; + pst2 = con.prepareStatement(sql); + pst2.executeUpdate(); + pst2.close(); } rs.close(); - } - if (Settings.getPasswordHash == HashAlgorithm.XENFORO) { - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnName + "=?;"); + pst.close(); + } else if (Settings.getPasswordHash == HashAlgorithm.WORDPRESS) { + pst = con.prepareStatement("SELECT " + columnID + " FROM " + tableName + " WHERE " + columnName + "=?;"); + pst.setString(1, auth.getNickname()); + rs = pst.executeQuery(); + if (rs.next()) { + int id = rs.getInt(columnID); + sql = "INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"; + pst2 = con.prepareStatement(sql); + // First Name + pst2.setInt(1, id); + pst2.setString(2, "first_name"); + pst2.setString(3, ""); + pst2.addBatch(); + // Last Name + pst2.setInt(1, id); + pst2.setString(2, "last_name"); + pst2.setString(3, ""); + pst2.addBatch(); + // Nick Name + pst2.setInt(1, id); + pst2.setString(2, "nickname"); + pst2.setString(3, auth.getNickname()); + pst2.addBatch(); + // Description + pst2.setInt(1, id); + pst2.setString(2, "description"); + pst2.setString(3, ""); + pst2.addBatch(); + // Rich_Editing + pst2.setInt(1, id); + pst2.setString(2, "rich_editing"); + pst2.setString(3, "true"); + pst2.addBatch(); + // Comments_Shortcuts + pst2.setInt(1, id); + pst2.setString(2, "comment_shortcuts"); + pst2.setString(3, "false"); + pst2.addBatch(); + // admin_color + pst2.setInt(1, id); + pst2.setString(2, "admin_color"); + pst2.setString(3, "fresh"); + pst2.addBatch(); + // use_ssl + pst2.setInt(1, id); + pst2.setString(2, "use_ssl"); + pst2.setString(3, "0"); + pst2.addBatch(); + // show_admin_bar_front + pst2.setInt(1, id); + pst2.setString(2, "show_admin_bar_front"); + pst2.setString(3, "true"); + pst2.addBatch(); + // wp_capabilities + pst2.setInt(1, id); + pst2.setString(2, "wp_capabilities"); + pst2.setString(3, "a:1:{s:10:\"subscriber\";b:1;}"); + pst2.addBatch(); + // wp_user_level + pst2.setInt(1, id); + pst2.setString(2, "wp_user_level"); + pst2.setString(3, "0"); + pst2.addBatch(); + // default_password_nag + pst2.setInt(1, id); + pst2.setString(2, "default_password_nag"); + pst2.setString(3, ""); + pst2.addBatch(); + + // Execute queries + pst2.executeBatch(); + pst2.clearBatch(); + pst2.close(); + } + rs.close(); + pst.close(); + } else if (Settings.getPasswordHash == HashAlgorithm.XENFORO) { + pst = con.prepareStatement("SELECT " + columnID + " FROM " + tableName + " WHERE " + columnName + "=?;"); pst.setString(1, auth.getNickname()); rs = pst.executeQuery(); if (rs.next()) { int id = rs.getInt(columnID); // Insert password in the correct table - pst = con.prepareStatement("INSERT INTO xf_user_authenticate (user_id, scheme_class, data) VALUES (?,?,?);"); - pst.setInt(1, id); - pst.setString(2, "XenForo_Authentication_Core12"); + pst2 = con.prepareStatement("INSERT INTO xf_user_authenticate (user_id, scheme_class, data) VALUES (?,?,?);"); + pst2.setInt(1, id); + pst2.setString(2, "XenForo_Authentication_Core12"); byte[] bytes = auth.getHash().getBytes(); Blob blob = con.createBlob(); blob.setBytes(1, bytes); - pst.setBlob(3, blob); - pst.executeUpdate(); + pst2.setBlob(3, blob); + pst2.executeUpdate(); + pst2.close(); } rs.close(); + pst.close(); } + return true; } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return false; - } finally { - close(rs); - close(pst); - close(con); } - return true; + return false; } /** @@ -522,51 +535,52 @@ public class MySQL implements DataSource { * * @param auth PlayerAuth * - * @return boolean * @see fr.xephi.authme.datasource.DataSource#updatePassword(PlayerAuth) + * @return boolean + * + * @see fr.xephi.authme.datasource.DataSource#updatePassword(PlayerAuth) */ @Override public synchronized boolean updatePassword(PlayerAuth auth) { - Connection con = null; - PreparedStatement pst = null; - ResultSet rs = null; - try { - if ((con = getConnection()) == null) - return false; - pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnPassword + "=? WHERE LOWER(" + columnName + ")=?;"); + try (Connection con = getConnection()) { + String sql = "UPDATE " + tableName + " SET " + columnPassword + "=? WHERE " + columnName + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, auth.getHash()); pst.setString(2, auth.getNickname()); pst.executeUpdate(); pst.close(); if (Settings.getPasswordHash == HashAlgorithm.XENFORO) { - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE LOWER(" + columnName + ")=?;"); + sql = "SELECT " + columnID + " FROM " + tableName + " WHERE " + columnName + "=?;"; + pst = con.prepareStatement(sql); pst.setString(1, auth.getNickname()); - rs = pst.executeQuery(); + ResultSet rs = pst.executeQuery(); if (rs.next()) { int id = rs.getInt(columnID); // Insert password in the correct table - pst = con.prepareStatement("UPDATE xf_user_authenticate SET data=? WHERE " + columnID + "=?;"); + sql = "UPDATE xf_user_authenticate SET data=? WHERE " + columnID + "=?;"; + PreparedStatement pst2 = con.prepareStatement(sql); byte[] bytes = auth.getHash().getBytes(); Blob blob = con.createBlob(); blob.setBytes(1, bytes); - pst.setBlob(1, blob); - pst.setInt(2, id); - pst.executeUpdate(); - pst = con.prepareStatement("UPDATE xf_user_authenticate SET scheme_class=? WHERE " + columnID + "=?;"); - pst.setString(1, "XenForo_Authentication_Core12"); - pst.setInt(2, id); - pst.executeUpdate(); + pst2.setBlob(1, blob); + pst2.setInt(2, id); + pst2.executeUpdate(); + pst2.close(); + // ... + sql = "UPDATE xf_user_authenticate SET scheme_class=? WHERE " + columnID + "=?;"; + pst2 = con.prepareStatement(sql); + pst2.setString(1, "XenForo_Authentication_Core12"); + pst2.setInt(2, id); + pst2.executeUpdate(); + pst2.close(); } rs.close(); + pst.close(); } + return true; } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return false; - } finally { - close(rs); - close(pst); - close(con); } - return true; + return false; } /** @@ -574,29 +588,27 @@ public class MySQL implements DataSource { * * @param auth PlayerAuth * - * @return boolean * @see fr.xephi.authme.datasource.DataSource#updateSession(PlayerAuth) + * @return boolean + * + * @see fr.xephi.authme.datasource.DataSource#updateSession(PlayerAuth) */ @Override public synchronized boolean updateSession(PlayerAuth auth) { - Connection con = null; - PreparedStatement pst = null; - try { - if ((con = getConnection()) == null) - return false; - pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnIp + "=?, " + columnLastLogin + "=?, " + columnRealName + "=? WHERE LOWER(" + columnName + ")=?;"); + try (Connection con = getConnection()) { + String sql = "UPDATE " + tableName + " SET " + + columnIp + "=?, " + columnLastLogin + "=?, " + columnRealName + "=? WHERE " + columnName + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, auth.getIp()); pst.setLong(2, auth.getLastLogin()); pst.setString(3, auth.getRealName()); pst.setString(4, auth.getNickname()); pst.executeUpdate(); + pst.close(); + return true; } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return false; - } finally { - close(pst); - close(con); } - return true; + return false; } /** @@ -604,25 +616,22 @@ public class MySQL implements DataSource { * * @param until long * - * @return int * @see fr.xephi.authme.datasource.DataSource#purgeDatabase(long) + * @return int + * + * @see fr.xephi.authme.datasource.DataSource#purgeDatabase(long) */ @Override public synchronized int purgeDatabase(long until) { - Connection con = null; - PreparedStatement pst = null; - try { - if ((con = getConnection()) == null) - return 0; - pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnLastLogin + " * @see fr.xephi.authme.datasource.DataSource#autoPurgeDatabase(long) + * @return List + * + * @see fr.xephi.authme.datasource.DataSource#autoPurgeDatabase(long) */ @Override public synchronized List autoPurgeDatabase(long until) { - Connection con = null; - PreparedStatement pst = null; - ResultSet rs = null; List list = new ArrayList<>(); - try { - if ((con = getConnection()) == null) - return list; - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnLastLogin + "(); - } finally { - close(rs); - close(pst); - close(con); } + return list; } /** @@ -667,43 +667,39 @@ public class MySQL implements DataSource { * * @param user String * - * @return boolean * @see fr.xephi.authme.datasource.DataSource#removeAuth(String) + * @return boolean + * + * @see fr.xephi.authme.datasource.DataSource#removeAuth(String) */ @Override public synchronized boolean removeAuth(String user) { - Connection con = null; - PreparedStatement pst = null; - try { - if ((con = getConnection()) == null) - return false; + user = user.toLowerCase(); + try (Connection con = getConnection()) { + String sql; + PreparedStatement pst; if (Settings.getPasswordHash == HashAlgorithm.XENFORO) { - int id; - ResultSet rs; - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE LOWER(" + columnName + ")=?;"); + sql = "SELECT " + columnID + " FROM " + tableName + " WHERE " + columnName + "=?;"; + pst = con.prepareStatement(sql); pst.setString(1, user); - rs = pst.executeQuery(); + ResultSet rs = pst.executeQuery(); if (rs.next()) { - id = rs.getInt(columnID); - // Remove data - PreparedStatement pst2 = con.prepareStatement("DELETE FROM xf_user_authenticate WHERE " + columnID + "=?;"); - pst2.setInt(1, id); - pst2.executeUpdate(); - pst2.close(); + int id = rs.getInt(columnID); + sql = "DELETE FROM xf_user_authenticate WHERE " + columnID + "=" + id; + Statement st = con.createStatement(); + st.executeUpdate(sql); + st.close(); } - } - if (pst != null && !pst.isClosed()) + rs.close(); pst.close(); - pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE LOWER(" + columnName + ")=?;"); + } + pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnName + "=?;"); pst.setString(1, user); pst.executeUpdate(); + return true; } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return false; - } finally { - close(pst); - close(con); } - return true; + return false; } /** @@ -711,30 +707,29 @@ public class MySQL implements DataSource { * * @param auth PlayerAuth * - * @return boolean * @see fr.xephi.authme.datasource.DataSource#updateQuitLoc(PlayerAuth) + * @return boolean + * + * @see fr.xephi.authme.datasource.DataSource#updateQuitLoc(PlayerAuth) */ @Override public synchronized boolean updateQuitLoc(PlayerAuth auth) { - Connection con = null; - PreparedStatement pst = null; - try { - if ((con = getConnection()) == null) - return false; - pst = con.prepareStatement("UPDATE " + tableName + " SET " + lastlocX + " =?, " + lastlocY + "=?, " + lastlocZ + "=?, " + lastlocWorld + "=? WHERE LOWER(" + columnName + ")=?;"); + try (Connection con = getConnection()) { + String sql = "UPDATE " + tableName + + " SET " + lastlocX + " =?, " + lastlocY + "=?, " + lastlocZ + "=?, " + lastlocWorld + "=?" + + " WHERE " + columnName + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setDouble(1, auth.getQuitLocX()); pst.setDouble(2, auth.getQuitLocY()); pst.setDouble(3, auth.getQuitLocZ()); pst.setString(4, auth.getWorld()); pst.setString(5, auth.getNickname()); pst.executeUpdate(); + pst.close(); + return true; } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return false; - } finally { - close(pst); - close(con); } - return true; + return false; } /** @@ -742,32 +737,27 @@ public class MySQL implements DataSource { * * @param ip String * - * @return int * @see fr.xephi.authme.datasource.DataSource#getIps(String) + * @return int + * + * @see fr.xephi.authme.datasource.DataSource#getIps(String) */ @Override public synchronized int getIps(String ip) { - Connection con = null; - PreparedStatement pst = null; - ResultSet rs = null; int countIp = 0; - try { - if ((con = getConnection()) == null) - return 0; - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnIp + "=?;"); + try (Connection con = getConnection()) { + String sql = "SELECT COUNT(*) FROM " + tableName + " WHERE " + columnIp + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, ip); - rs = pst.executeQuery(); + ResultSet rs = pst.executeQuery(); while (rs.next()) { - countIp++; + countIp = rs.getInt(1); } - return countIp; + rs.close(); + pst.close(); } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return 0; - } finally { - close(rs); - close(pst); - close(con); } + return countIp; } /** @@ -775,28 +765,25 @@ public class MySQL implements DataSource { * * @param auth PlayerAuth * - * @return boolean * @see fr.xephi.authme.datasource.DataSource#updateEmail(PlayerAuth) + * @return boolean + * + * @see fr.xephi.authme.datasource.DataSource#updateEmail(PlayerAuth) */ @Override public synchronized boolean updateEmail(PlayerAuth auth) { - Connection con = null; - PreparedStatement pst = null; - try { - if ((con = getConnection()) == null) - return false; - pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnEmail + " =? WHERE LOWER(" + columnName + ")=?;"); + try (Connection con = getConnection()) { + String sql = "UPDATE " + tableName + " SET " + columnEmail + " =? WHERE " + columnName + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, auth.getEmail()); pst.setString(2, auth.getNickname()); pst.executeUpdate(); + pst.close(); + return true; } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); ConsoleLogger.writeStackTrace(ex); - return false; - } finally { - close(pst); - close(con); } - return true; + return false; } /** @@ -804,30 +791,27 @@ public class MySQL implements DataSource { * * @param auth PlayerAuth * - * @return boolean * @see fr.xephi.authme.datasource.DataSource#updateSalt(PlayerAuth) + * @return boolean + * + * @see fr.xephi.authme.datasource.DataSource#updateSalt(PlayerAuth) */ @Override public synchronized boolean updateSalt(PlayerAuth auth) { if (columnSalt.isEmpty()) { return false; } - Connection con = null; - PreparedStatement pst = null; - try { - if ((con = getConnection()) == null) - return false; - pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnSalt + " =? WHERE LOWER(" + columnName + ")=?;"); + try (Connection con = getConnection()) { + String sql = "UPDATE " + tableName + " SET " + columnSalt + " =? WHERE " + columnName + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, auth.getSalt()); pst.setString(2, auth.getNickname()); pst.executeUpdate(); + pst.close(); + return true; } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return false; - } finally { - close(pst); - close(con); } - return true; + return false; } /** @@ -841,12 +825,8 @@ public class MySQL implements DataSource { reloadArguments(); } catch (Exception e) { ConsoleLogger.showError(e.getMessage()); - ConsoleLogger.showError("Can't reconnect to MySQL database... Please check your MySQL informations ! SHUTDOWN..."); - if (Settings.isStopEnabled) { - AuthMe.getInstance().getServer().shutdown(); - } - if (!Settings.isStopEnabled) - AuthMe.getInstance().getServer().getPluginManager().disablePlugin(AuthMe.getInstance()); + ConsoleLogger.showError("Can't reconnect to MySQL database... Please check your MySQL configuration!"); + AuthMe.getInstance().stopOrUnload(); } } @@ -857,23 +837,8 @@ public class MySQL implements DataSource { */ @Override public synchronized void close() { - if (ds != null && !ds.isClosed()) + if (ds != null && !ds.isClosed()) { ds.close(); - } - - /** - * Method close. - * - * @param o AutoCloseable - */ - private void close(AutoCloseable o) { - if (o != null) { - try { - o.close(); - } catch (Exception ex) { - ConsoleLogger.showError(ex.getMessage()); - ConsoleLogger.writeStackTrace(ex); - } } } @@ -882,32 +847,27 @@ public class MySQL implements DataSource { * * @param auth PlayerAuth * - * @return List * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByName(PlayerAuth) + * @return List + * + * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByName(PlayerAuth) */ @Override public synchronized List getAllAuthsByName(PlayerAuth auth) { - Connection con = null; - PreparedStatement pst = null; - ResultSet rs = null; - List countIp = new ArrayList<>(); - try { - if ((con = getConnection()) == null) - return countIp; - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnIp + "=?;"); + List result = new ArrayList<>(); + try (Connection con = getConnection()) { + String sql = "SELECT " + columnName + " FROM " + tableName + " WHERE " + columnIp + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, auth.getIp()); - rs = pst.executeQuery(); + ResultSet rs = pst.executeQuery(); while (rs.next()) { - countIp.add(rs.getString(columnName)); + result.add(rs.getString(columnName)); } - return countIp; + rs.close(); + pst.close(); } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return new ArrayList<>(); - } finally { - close(rs); - close(pst); - close(con); } + return result; } /** @@ -915,32 +875,27 @@ public class MySQL implements DataSource { * * @param ip String * - * @return List * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByIp(String) + * @return List + * + * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByIp(String) */ @Override public synchronized List getAllAuthsByIp(String ip) { - Connection con = null; - PreparedStatement pst = null; - ResultSet rs = null; - List countIp = new ArrayList<>(); - try { - if ((con = getConnection()) == null) - return countIp; - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnIp + "=?;"); + List result = new ArrayList<>(); + try (Connection con = getConnection()) { + String sql = "SELECT " + columnName + " FROM " + tableName + " WHERE " + columnIp + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, ip); - rs = pst.executeQuery(); + ResultSet rs = pst.executeQuery(); while (rs.next()) { - countIp.add(rs.getString(columnName)); + result.add(rs.getString(columnName)); } - return countIp; + rs.close(); + pst.close(); } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return new ArrayList<>(); - } finally { - close(rs); - close(pst); - close(con); } + return result; } /** @@ -948,27 +903,25 @@ public class MySQL implements DataSource { * * @param email String * - * @return List * @throws SQLException * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByEmail(String) + * @return List + * + * @throws SQLException + * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByEmail(String) */ @Override public synchronized List getAllAuthsByEmail(String email) throws SQLException { - final Connection con = getConnection(); - PreparedStatement pst = null; - ResultSet rs = null; List countEmail = new ArrayList<>(); - - try { - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnEmail + "=?;"); + try (Connection con = getConnection()) { + String sql = "SELECT " + columnName + " FROM " + tableName + " WHERE " + columnEmail + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, email); - rs = pst.executeQuery(); + ResultSet rs = pst.executeQuery(); while (rs.next()) { countEmail.add(rs.getString(columnName)); } + rs.close(); + pst.close(); return countEmail; - } finally { - close(rs); - close(pst); - close(con); } } @@ -977,25 +930,19 @@ public class MySQL implements DataSource { * * @param banned List * - * @see fr.xephi.authme.datasource.DataSource#purgeBanned(List) + * @see fr.xephi.authme.datasource.DataSource#purgeBanned(List) */ @Override public synchronized void purgeBanned(List banned) { - Connection con = null; - PreparedStatement pst = null; - try { - if ((con = getConnection()) == null) - return; + try (Connection con = getConnection()) { + PreparedStatement pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnName + "=?;"); for (String name : banned) { - pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE LOWER(" + columnName + ")=?;"); pst.setString(1, name); pst.executeUpdate(); } + pst.close(); } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - } finally { - close(pst); - close(con); } } @@ -1018,26 +965,17 @@ public class MySQL implements DataSource { */ @Override public boolean isLogged(String user) { - Connection con = null; - PreparedStatement pst = null; - ResultSet rs = null; - try { - if ((con = getConnection()) == null) - return false; - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE LOWER(" + columnName + ")=?;"); + boolean isLogged = false; + try (Connection con = getConnection()) { + String sql = "SELECT " + columnLogged + " FROM " + tableName + " WHERE " + columnName + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, user); - rs = pst.executeQuery(); - if (rs.next()) - return (rs.getInt(columnLogged) == 1); + ResultSet rs = pst.executeQuery(); + isLogged = rs.next() && (rs.getInt(columnLogged) == 1); } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return false; - } finally { - close(rs); - close(pst); - close(con); } - return false; + return isLogged; } /** @@ -1049,20 +987,15 @@ public class MySQL implements DataSource { */ @Override public void setLogged(String user) { - Connection con = null; - PreparedStatement pst = null; - try { - if ((con = getConnection()) == null) - return; - pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnLogged + "=? WHERE LOWER(" + columnName + ")=?;"); + try (Connection con = getConnection()) { + String sql = "UPDATE " + tableName + " SET " + columnLogged + "=? WHERE " + columnName + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setInt(1, 1); - pst.setString(2, user); + pst.setString(2, user.toLowerCase()); pst.executeUpdate(); + pst.close(); } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - } finally { - close(pst); - close(con); } } @@ -1075,22 +1008,16 @@ public class MySQL implements DataSource { */ @Override public void setUnlogged(String user) { - Connection con = null; - PreparedStatement pst = null; - if (user != null) - try { - if ((con = getConnection()) == null) - return; - pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnLogged + "=? WHERE LOWER(" + columnName + ")=?;"); - pst.setInt(1, 0); - pst.setString(2, user); - pst.executeUpdate(); - } catch (Exception ex) { - ConsoleLogger.showError(ex.getMessage()); - } finally { - close(pst); - close(con); - } + try (Connection con = getConnection()) { + String sql = "UPDATE " + tableName + " SET " + columnLogged + "=? WHERE " + columnName + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); + pst.setInt(1, 0); + pst.setString(2, user.toLowerCase()); + pst.executeUpdate(); + pst.close(); + } catch (Exception ex) { + ConsoleLogger.showError(ex.getMessage()); + } } /** @@ -1100,48 +1027,38 @@ public class MySQL implements DataSource { */ @Override public void purgeLogged() { - Connection con = null; - PreparedStatement pst = null; - try { - if ((con = getConnection()) == null) - return; - pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnLogged + "=? WHERE " + columnLogged + "=?;"); + try (Connection con = getConnection()) { + String sql = "UPDATE " + tableName + " SET " + columnLogged + "=? WHERE " + columnLogged + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setInt(1, 0); pst.setInt(2, 1); pst.executeUpdate(); + pst.close(); } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - } finally { - close(pst); - close(con); } } /** * Method getAccountsRegistered. * - * @return int * @see fr.xephi.authme.datasource.DataSource#getAccountsRegistered() + * @return int + * + * @see fr.xephi.authme.datasource.DataSource#getAccountsRegistered() */ @Override public int getAccountsRegistered() { int result = 0; - Connection con = null; - PreparedStatement pst = null; - ResultSet rs; - try { - if ((con = getConnection()) == null) - return result; - pst = con.prepareStatement("SELECT COUNT(*) FROM " + tableName + ";"); - rs = pst.executeQuery(); - if (rs != null && rs.next()) { + try (Connection con = getConnection()) { + PreparedStatement pst = con.prepareStatement("SELECT COUNT(*) FROM " + tableName + ";"); + ResultSet rs = pst.executeQuery(); + if (rs.next()) { result = rs.getInt(1); } + rs.close(); + pst.close(); } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return result; - } finally { - close(pst); - close(con); } return result; } @@ -1156,75 +1073,67 @@ public class MySQL implements DataSource { */ @Override public void updateName(String oldOne, String newOne) { - Connection con = null; - PreparedStatement pst = null; - try { - if ((con = getConnection()) == null) - return; - pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnName + "=? WHERE LOWER(" + columnName + ")=?;"); + try (Connection con = getConnection()) { + String sql = "UPDATE " + tableName + " SET " + columnName + "=? WHERE " + columnName + "=?;"; + PreparedStatement pst = con.prepareStatement(sql); pst.setString(1, newOne); pst.setString(2, oldOne); pst.executeUpdate(); } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - } finally { - close(pst); - close(con); } } /** * Method getAllAuths. * - * @return List * @see fr.xephi.authme.datasource.DataSource#getAllAuths() + * @return List + * + * @see fr.xephi.authme.datasource.DataSource#getAllAuths() */ @Override public List getAllAuths() { List auths = new ArrayList<>(); - Connection con = null; - PreparedStatement pst = null; - ResultSet rs = null; - try { - if ((con = getConnection()) == null) - return auths; - pst = con.prepareStatement("SELECT * FROM " + tableName + ";"); - rs = pst.executeQuery(); + try (Connection con = getConnection()) { + Statement st = con.createStatement(); + ResultSet rs = st.executeQuery("SELECT * FROM " + tableName); + PreparedStatement pst = con.prepareStatement("SELECT data FROM xf_user_authenticate WHERE " + columnID + "=?;"); while (rs.next()) { - PlayerAuth pAuth; - int id = rs.getInt(columnID); - if (rs.getString(columnIp).isEmpty() && rs.getString(columnIp) != null) { - pAuth = new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), "192.168.0.1", rs.getLong(columnLastLogin), rs.getDouble(lastlocX), rs.getDouble(lastlocY), rs.getDouble(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail), rs.getString(columnRealName)); - } else { - if (!columnSalt.isEmpty()) { - if (!columnGroup.isEmpty()) - pAuth = new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), rs.getString(columnSalt), rs.getInt(columnGroup), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getDouble(lastlocX), rs.getDouble(lastlocY), rs.getDouble(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail), rs.getString(columnRealName)); - else - pAuth = new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), rs.getString(columnSalt), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getDouble(lastlocX), rs.getDouble(lastlocY), rs.getDouble(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail), rs.getString(columnRealName)); - } else { - pAuth = new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getDouble(lastlocX), rs.getDouble(lastlocY), rs.getDouble(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail), rs.getString(columnRealName)); - } - } + String salt = !columnSalt.isEmpty() ? rs.getString(columnSalt) : ""; + int group = !salt.isEmpty() && !columnGroup.isEmpty() ? rs.getInt(columnGroup) : -1; + PlayerAuth pAuth = PlayerAuth.builder() + .name(rs.getString(columnName)) + .realName(rs.getString(columnRealName)) + .hash(rs.getString(columnPassword)) + .lastLogin(rs.getLong(columnLastLogin)) + .ip(rs.getString(columnIp)) + .locWorld(rs.getString(lastlocWorld)) + .locX(rs.getDouble(lastlocX)) + .locY(rs.getDouble(lastlocY)) + .locZ(rs.getDouble(lastlocZ)) + .email(rs.getString(columnEmail)) + .salt(salt) + .groupId(group) + .build(); + if (Settings.getPasswordHash == HashAlgorithm.XENFORO) { - ResultSet rsid; - pst = con.prepareStatement("SELECT * FROM xf_user_authenticate WHERE " + columnID + "=?;"); + int id = rs.getInt(columnID); pst.setInt(1, id); - rsid = pst.executeQuery(); - if (rsid.next()) { - Blob blob = rsid.getBlob("data"); + ResultSet rs2 = pst.executeQuery(); + if (rs2.next()) { + Blob blob = rs2.getBlob("data"); byte[] bytes = blob.getBytes(1, (int) blob.length()); pAuth.setHash(new String(bytes)); } - rsid.close(); + rs2.close(); } auths.add(pAuth); } + pst.close(); + rs.close(); + st.close(); } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return auths; - } finally { - close(pst); - close(con); - close(rs); } return auths; } @@ -1232,55 +1141,50 @@ public class MySQL implements DataSource { /** * Method getLoggedPlayers. * - * @return List * @see fr.xephi.authme.datasource.DataSource#getLoggedPlayers() + * @return List + * + * @see fr.xephi.authme.datasource.DataSource#getLoggedPlayers() */ @Override public List getLoggedPlayers() { List auths = new ArrayList<>(); - Connection con = null; - PreparedStatement pst = null; - ResultSet rs = null; - try { - if ((con = getConnection()) == null) - return auths; - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnLogged + "=1;"); - rs = pst.executeQuery(); + try (Connection con = getConnection()) { + Statement st = con.createStatement(); + ResultSet rs = st.executeQuery("SELECT * FROM " + tableName + " WHERE " + columnLogged + "=1;"); + PreparedStatement pst = con.prepareStatement("SELECT data FROM xf_user_authenticate WHERE " + columnID + "=?;"); while (rs.next()) { - PlayerAuth pAuth; - int id = rs.getInt(columnID); - if (rs.getString(columnIp).isEmpty() && rs.getString(columnIp) != null) { - pAuth = new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), "192.168.0.1", rs.getLong(columnLastLogin), rs.getDouble(lastlocX), rs.getDouble(lastlocY), rs.getDouble(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail), rs.getString(columnRealName)); - } else { - if (!columnSalt.isEmpty()) { - if (!columnGroup.isEmpty()) - pAuth = new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), rs.getString(columnSalt), rs.getInt(columnGroup), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getDouble(lastlocX), rs.getDouble(lastlocY), rs.getDouble(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail), rs.getString(columnRealName)); - else - pAuth = new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), rs.getString(columnSalt), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getDouble(lastlocX), rs.getDouble(lastlocY), rs.getDouble(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail), rs.getString(columnRealName)); - } else { - pAuth = new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getDouble(lastlocX), rs.getDouble(lastlocY), rs.getDouble(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail), rs.getString(columnRealName)); - } - } + String salt = !columnSalt.isEmpty() ? rs.getString(columnSalt) : ""; + int group = !salt.isEmpty() && !columnGroup.isEmpty() ? rs.getInt(columnGroup) : -1; + PlayerAuth pAuth = PlayerAuth.builder() + .name(rs.getString(columnName)) + .realName(rs.getString(columnRealName)) + .hash(rs.getString(columnPassword)) + .lastLogin(rs.getLong(columnLastLogin)) + .ip(rs.getString(columnIp)) + .locWorld(rs.getString(lastlocWorld)) + .locX(rs.getDouble(lastlocX)) + .locY(rs.getDouble(lastlocY)) + .locZ(rs.getDouble(lastlocZ)) + .email(rs.getString(columnEmail)) + .salt(salt) + .groupId(group) + .build(); + if (Settings.getPasswordHash == HashAlgorithm.XENFORO) { - ResultSet rsid; - pst = con.prepareStatement("SELECT * FROM xf_user_authenticate WHERE " + columnID + "=?;"); + int id = rs.getInt(columnID); pst.setInt(1, id); - rsid = pst.executeQuery(); - if (rsid.next()) { - Blob blob = rsid.getBlob("data"); + ResultSet rs2 = pst.executeQuery(); + if (rs2.next()) { + Blob blob = rs2.getBlob("data"); byte[] bytes = blob.getBytes(1, (int) blob.length()); pAuth.setHash(new String(bytes)); } - rsid.close(); + rs2.close(); } auths.add(pAuth); } } catch (Exception ex) { ConsoleLogger.showError(ex.getMessage()); - return auths; - } finally { - close(pst); - close(rs); - close(con); } return auths; } diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index 7a2096808..2b9f2129e 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -68,7 +68,7 @@ public final class Settings extends YamlConfiguration { enableProtection, enableAntiBot, recallEmail, useWelcomeMessage, broadcastWelcomeMessage, forceRegKick, forceRegLogin, checkVeryGames, delayJoinLeaveMessages, noTeleport, applyBlindEffect, - customAttributes, generateImage, isRemoveSpeedEnabled, isMySQLWebsite; + customAttributes, generateImage, isRemoveSpeedEnabled; public static String helpHeader, getNickRegex, getUnloggedinGroup, getMySQLHost, getMySQLPort, getMySQLUsername, getMySQLPassword, getMySQLDatabase, getMySQLTablename, getMySQLColumnName, getMySQLColumnPassword, @@ -284,7 +284,6 @@ public final class Settings extends YamlConfiguration { forceRegisterCommandsAsConsole = configFile.getStringList("settings.forceRegisterCommandsAsConsole"); customAttributes = configFile.getBoolean("Hooks.customAttributes"); generateImage = configFile.getBoolean("Email.generateImage", false); - isMySQLWebsite = configFile.getBoolean("DataSource.mySQLWebsite", false); // Load the welcome message getWelcomeMessage(); @@ -676,10 +675,6 @@ public final class Settings extends YamlConfiguration { set("DataSource.mySQLRealName", "realname"); changes = true; } - if (!contains("DataSource.mySQLQueryCache")) { - set("DataSource.mySQLWebsite", false); - changes = true; - } if (changes) { plugin.getLogger().warning("Merged new Config Options - I'm not an error, please don't report me"); From ee3fe45d7faa98a3f426400ec7f6655ae2a427ae Mon Sep 17 00:00:00 2001 From: DNx5 Date: Wed, 2 Dec 2015 06:36:41 +0700 Subject: [PATCH 37/82] Fix unclosed Statement object. --- src/main/java/fr/xephi/authme/datasource/MySQL.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java index fd7261a5f..17d2cdfdf 100644 --- a/src/main/java/fr/xephi/authme/datasource/MySQL.java +++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java @@ -283,10 +283,9 @@ public class MySQL implements DataSource { if (!rs.next()) { return null; } - String salt = !columnSalt.isEmpty() ? rs.getString(columnSalt) : ""; int group = !salt.isEmpty() && !columnGroup.isEmpty() ? rs.getInt(columnGroup) : -1; - + int id = rs.getInt(columnID); pAuth = PlayerAuth.builder() .name(rs.getString(columnName)) .realName(rs.getString(columnRealName)) @@ -301,11 +300,9 @@ public class MySQL implements DataSource { .salt(salt) .groupId(group) .build(); - + rs.close(); + pst.close(); if (Settings.getPasswordHash == HashAlgorithm.XENFORO) { - int id = rs.getInt(columnID); - rs.close(); - pst.close(); pst = con.prepareStatement("SELECT data FROM xf_user_authenticate WHERE " + columnID + "=?;"); pst.setInt(1, id); rs = pst.executeQuery(); From 42416c4bdc7a2bf1147f2c0af82566f147665e6c Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Wed, 2 Dec 2015 16:28:00 +0100 Subject: [PATCH 38/82] Update config.yml --- src/main/resources/config.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 5abd17eb8..0c7607e3c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -388,12 +388,13 @@ Protection: # Enable some servers protection ( country based login, antibot ) enableProtection: false # Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes + # PLEASE USE QUOTES! countries: - - US - - GB + - 'US' + - 'GB' # Countries blacklisted automatically ( without any needed to enable protection ) countriesBlacklist: - - A1 + - 'A1' # Do we need to enable automatic antibot system? enableAntiBot: false # Max number of player allowed to login in 5 secs before enable AntiBot system automatically From 41b6b4184ebc51dbfee6729b11fa33cd4baefb76 Mon Sep 17 00:00:00 2001 From: Xephi Date: Wed, 2 Dec 2015 16:34:28 +0100 Subject: [PATCH 39/82] Remove StackTrace for production --- src/main/java/fr/xephi/authme/SendMailSSL.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/fr/xephi/authme/SendMailSSL.java b/src/main/java/fr/xephi/authme/SendMailSSL.java index 397ddac91..1c3a4f449 100644 --- a/src/main/java/fr/xephi/authme/SendMailSSL.java +++ b/src/main/java/fr/xephi/authme/SendMailSSL.java @@ -86,8 +86,7 @@ public class SendMailSSL { try { email.send(); } catch (Exception e) { - e.printStackTrace(); - ConsoleLogger.showError("Fail to send a mail to " + mail); + ConsoleLogger.showError("Fail to send a mail to " + mail + " cause " + e.getLocalizedMessage()); } if (file != null) //noinspection ResultOfMethodCallIgnored From 75d4f73f3ea4e5d046c57753930117ad62b87c1a Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Wed, 2 Dec 2015 16:41:32 +0100 Subject: [PATCH 40/82] Update team.txt --- team.txt | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/team.txt b/team.txt index e1c7e8604..98b60aa52 100644 --- a/team.txt +++ b/team.txt @@ -3,18 +3,16 @@ AuthMe-Team: Active staff: Xephi (Xephi59) - Leader, Main developer DNx5 - Developer -games647 - Developer +ljacqu - Developer TimVisee - Developer +games647 - Developer Gabriele C. (sgdc3) - Project Manager, Contributor -Staff to contact: -CryLegend - Contributor, AuthMeBridge Developer (Needs activation) +AuthMeBridge staff: +CryLegend - Main developer, We need to contact him! -External Contributors: -Gnat008 - Contributor - -Inactive staff: -Maxetto - Ticket Manager, Italian Translator, Basic Developer, Contributor (Inactive) +Retired staff: +Maxetto - Ticket Manager, IT translator darkwarriors (d4rkwarriors) - Original AuthMeReloaded Author (Inactive) Translators: From cafad5b0888367cf2ab5c4f1a22634deef5c2bf3 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Wed, 2 Dec 2015 21:42:39 +0100 Subject: [PATCH 41/82] Fix #296 Reloading doesn't update settings - Replace Settings to encapsulate a YamlConfiguration instance provided by AuthMe, rather than loading the config file again. --- .../fr/xephi/authme/settings/Settings.java | 69 ++++++------------- 1 file changed, 20 insertions(+), 49 deletions(-) diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index 2b9f2129e..df9e0b0a8 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -17,7 +17,7 @@ import java.util.regex.Pattern; /** */ -public final class Settings extends YamlConfiguration { +public final class Settings { public static final File PLUGIN_FOLDER = Wrapper.getInstance().getDataFolder(); public static final File MODULE_FOLDER = new File(PLUGIN_FOLDER, "modules"); @@ -105,18 +105,13 @@ public final class Settings extends YamlConfiguration { configFile = (YamlConfiguration) plugin.getConfig(); } - /** - * Method reload. - * - * @throws Exception - */ public static void reload() throws Exception { plugin.getLogger().info("Loading Configuration File..."); boolean exist = SETTINGS_FILE.exists(); if (!exist) { plugin.saveDefaultConfig(); } - instance.load(SETTINGS_FILE); + configFile.load(SETTINGS_FILE); if (exist) { instance.mergeConfig(); } @@ -290,22 +285,11 @@ public final class Settings extends YamlConfiguration { } - /** - * Method setValue. - * - * @param key String - * @param value Object - */ public static void setValue(String key, Object value) { instance.set(key, value); save(); } - /** - * Method getPasswordHash. - * - * @return HashAlgorithm - */ private static HashAlgorithm getPasswordHash() { String key = "settings.security.passwordHash"; try { @@ -316,11 +300,6 @@ public final class Settings extends YamlConfiguration { } } - /** - * Method getDataSource. - * - * @return DataSourceType - */ private static DataSourceType getDataSource() { String key = "DataSource.backend"; try { @@ -367,20 +346,13 @@ public final class Settings extends YamlConfiguration { */ public static boolean save() { try { - instance.save(SETTINGS_FILE); + configFile.save(SETTINGS_FILE); return true; - } catch (Exception ex) { + } catch (IOException ex) { return false; } } - /** - * Method checkLang. - * - * @param lang String - * - * @return String - */ public static String checkLang(String lang) { if (new File(PLUGIN_FOLDER, "messages" + File.separator + "messages_" + lang + ".yml").exists()) { ConsoleLogger.info("Set Language to: " + lang); @@ -394,11 +366,6 @@ public final class Settings extends YamlConfiguration { return "en"; } - /** - * Method switchAntiBotMod. - * - * @param mode boolean - */ public static void switchAntiBotMod(boolean mode) { if (mode) { isKickNonRegisteredEnabled = true; @@ -440,13 +407,6 @@ public final class Settings extends YamlConfiguration { } } - /** - * Method isEmailCorrect. - * - * @param email String - * - * @return boolean - */ public static boolean isEmailCorrect(String email) { if (!email.contains("@")) return false; @@ -587,7 +547,7 @@ public final class Settings extends YamlConfiguration { set("VeryGames.enableIpCheck", false); changes = true; } - if (getString("settings.restrictions.allowedNicknameCharacters").equals("[a-zA-Z0-9_?]*")) { + if (configFile.getString("settings.restrictions.allowedNicknameCharacters").equals("[a-zA-Z0-9_?]*")) { set("settings.restrictions.allowedNicknameCharacters", "[a-zA-Z0-9_]*"); changes = true; } @@ -682,6 +642,15 @@ public final class Settings extends YamlConfiguration { } } + private static boolean contains(String path) { + return configFile.contains(path); + } + + // public because it's used in AuthMe at one place + public void set(String path, Object value) { + configFile.set(path, value); + } + /** * Saves current configuration (plus defaults) to disk. *

@@ -690,11 +659,13 @@ public final class Settings extends YamlConfiguration { * @return True if saved successfully */ public final boolean saveDefaults() { - options().copyDefaults(true); - options().copyHeader(true); + configFile.options() + .copyDefaults(true) + .copyHeader(true); boolean success = save(); - options().copyDefaults(false); - options().copyHeader(false); + configFile.options() + .copyDefaults(false) + .copyHeader(false); return success; } } From 1ca6bcffe1fa94399edebab74a4114746ab14e72 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Wed, 2 Dec 2015 22:13:43 +0100 Subject: [PATCH 42/82] Make AuthMe.management private; create test for CaptchaCommand --- src/main/java/fr/xephi/authme/AuthMe.java | 2 +- src/main/java/fr/xephi/authme/api/API.java | 2 +- src/main/java/fr/xephi/authme/api/NewAPI.java | 8 +-- .../executable/authme/ForceLoginCommand.java | 2 +- .../executable/captcha/CaptchaCommand.java | 6 +- .../unregister/UnregisterCommand.java | 2 +- .../authme/listener/AuthMePlayerListener.java | 4 +- .../authme/process/join/AsynchronousJoin.java | 2 +- .../captcha/CaptchaCommandTest.java | 71 +++++++++++++++++++ 9 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index c1d4a4d69..9fb59f289 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -73,7 +73,7 @@ public class AuthMe extends JavaPlugin { private static Server server; private static Wrapper wrapper = Wrapper.getInstance(); - public Management management; + private Management management; public NewAPI api; public SendMailSSL mail; public DataManager dataManager; diff --git a/src/main/java/fr/xephi/authme/api/API.java b/src/main/java/fr/xephi/authme/api/API.java index e849e7950..1f1ac69d8 100644 --- a/src/main/java/fr/xephi/authme/api/API.java +++ b/src/main/java/fr/xephi/authme/api/API.java @@ -170,7 +170,7 @@ public class API { */ @Deprecated public static void forceLogin(Player player) { - instance.management.performLogin(player, "dontneed", true); + instance.getManagement().performLogin(player, "dontneed", true); } /** diff --git a/src/main/java/fr/xephi/authme/api/NewAPI.java b/src/main/java/fr/xephi/authme/api/NewAPI.java index cfe4508f0..908f75df0 100644 --- a/src/main/java/fr/xephi/authme/api/NewAPI.java +++ b/src/main/java/fr/xephi/authme/api/NewAPI.java @@ -170,7 +170,7 @@ public class NewAPI { * @param 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 */ public void forceLogout(Player player) { - plugin.management.performLogout(player); + plugin.getManagement().performLogout(player); } /** @@ -189,7 +189,7 @@ public class NewAPI { * @param password String */ 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 */ public void forceUnregister(Player player) { - plugin.management.performUnregister(player, "", true); + plugin.getManagement().performUnregister(player, "", true); } } diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ForceLoginCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ForceLoginCommand.java index b5fa337eb..f6f3efef5 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/ForceLoginCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/ForceLoginCommand.java @@ -34,7 +34,7 @@ public class ForceLoginCommand extends ExecutableCommand { sender.sendMessage("You cannot force login for the player " + playerName + "!"); return true; } - plugin.management.performLogin(player, "dontneed", true); + plugin.getManagement().performLogin(player, "dontneed", true); sender.sendMessage("Force Login for " + playerName + " performed!"); } catch (Exception e) { sender.sendMessage("An error occurred while trying to get that player!"); diff --git a/src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java b/src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java index 4fa2bbef9..696773537 100644 --- a/src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java @@ -8,6 +8,7 @@ import fr.xephi.authme.security.RandomString; import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.util.Wrapper; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -30,10 +31,11 @@ public class CaptchaCommand extends ExecutableCommand { String captcha = commandArguments.get(0); // AuthMe plugin instance - final AuthMe plugin = AuthMe.getInstance(); + final Wrapper wrapper = Wrapper.getInstance(); + final AuthMe plugin = wrapper.getAuthMe(); // Messages instance - final Messages m = plugin.getMessages(); + final Messages m = wrapper.getMessages(); // Command logic if (PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) { diff --git a/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java b/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java index 22ef35661..8ff40ed3d 100644 --- a/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java @@ -49,7 +49,7 @@ public class UnregisterCommand extends ExecutableCommand { } // Unregister the player - plugin.management.performUnregister(player, playerPass, false); + plugin.getManagement().performUnregister(player, playerPass, false); return true; } } diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java index 773ed8d5d..52fc51ab9 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java @@ -333,7 +333,7 @@ public class AuthMePlayerListener implements Listener { event.setQuitMessage(null); } - plugin.management.performQuit(player, false); + plugin.getManagement().performQuit(player, false); } @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) @@ -349,7 +349,7 @@ public class AuthMePlayerListener implements Listener { } Player player = event.getPlayer(); - plugin.management.performQuit(player, true); + plugin.getManagement().performQuit(player, true); } @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java index 3160ddcc4..724c334fc 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -238,7 +238,7 @@ public class AsynchronousJoin { PlayerCache.getInstance().removePlayer(name); if (auth != null && auth.getIp().equals(ip)) { m.send(player, MessageKey.SESSION_RECONNECTION); - plugin.management.performLogin(player, "dontneed", true); + plugin.getManagement().performLogin(player, "dontneed", true); return; } else if (Settings.sessionExpireOnIpChange) { m.send(player, MessageKey.SESSION_EXPIRED); diff --git a/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java new file mode 100644 index 000000000..36169db05 --- /dev/null +++ b/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java @@ -0,0 +1,71 @@ +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 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(), new CommandParts()); + + // 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(), new CommandParts()); + + // 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; + } +} From 1fbe4e0c3b312624197869533c11a7f28dafa9fa Mon Sep 17 00:00:00 2001 From: ljacqu Date: Thu, 3 Dec 2015 22:07:18 +0100 Subject: [PATCH 43/82] #298 Change password shows wrong 'pw cant be username' error - Change MessageKey to the proper message - Change permissions for admin changepassword to admin - Rename player changepassword command arguments to reflect their actual meaning --- .../xephi/authme/command/CommandManager.java | 2 +- .../authme/ChangePasswordCommand.java | 20 +++++++++++------- .../changepassword/ChangePasswordCommand.java | 14 ++++++------- .../ChangePasswordCommandTest.java | 21 +++++++++++-------- 4 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/main/java/fr/xephi/authme/command/CommandManager.java b/src/main/java/fr/xephi/authme/command/CommandManager.java index 1faa7f917..6c2f1c845 100644 --- a/src/main/java/fr/xephi/authme/command/CommandManager.java +++ b/src/main/java/fr/xephi/authme/command/CommandManager.java @@ -107,7 +107,7 @@ public class CommandManager { .description("Change a player's password") .detailedDescription("Change the password of a player.") .parent(authMeBaseCommand) - .permissions(OP_ONLY, PlayerPermission.CHANGE_PASSWORD) + .permissions(OP_ONLY, AdminPermission.CHANGE_PASSWORD) .withArgument("player", "Player name", false) .withArgument("pwd", "New password", false) .build(); diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordCommand.java index 1753a8307..06255128f 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordCommand.java @@ -16,6 +16,7 @@ import org.bukkit.command.CommandSender; import java.security.NoSuchAlgorithmException; /** + * Admin command for changing a player's password. */ public class ChangePasswordCommand extends ExecutableCommand { @@ -31,23 +32,26 @@ public class ChangePasswordCommand extends ExecutableCommand { // Validate the password String playerPassLowerCase = playerPass.toLowerCase(); - if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where") || playerPassLowerCase.contains("insert") || playerPassLowerCase.contains("modify") || playerPassLowerCase.contains("from") || playerPassLowerCase.contains("select") || playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null") || !playerPassLowerCase.matches(Settings.getPassRegex)) { - m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); + if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where") + || playerPassLowerCase.contains("insert") || playerPassLowerCase.contains("modify") + || playerPassLowerCase.contains("from") || playerPassLowerCase.contains("select") + || playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null") + || !playerPassLowerCase.matches(Settings.getPassRegex)) { + m.send(sender, MessageKey.PASSWORD_MATCH_ERROR); return true; } if (playerPassLowerCase.equalsIgnoreCase(playerName)) { m.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); return true; } - if (playerPassLowerCase.length() < Settings.getPasswordMinLen || playerPassLowerCase.length() > Settings.passwordMaxLength) { + if (playerPassLowerCase.length() < Settings.getPasswordMinLen + || playerPassLowerCase.length() > Settings.passwordMaxLength) { m.send(sender, MessageKey.INVALID_PASSWORD_LENGTH); return true; } - if (!Settings.unsafePasswords.isEmpty()) { - if (Settings.unsafePasswords.contains(playerPassLowerCase)) { - m.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR); - return true; - } + if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(playerPassLowerCase)) { + m.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR); + return true; } // Set the password final String playerNameLowerCase = playerName.toLowerCase(); diff --git a/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java b/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java index c88ceaa87..f9219aba6 100644 --- a/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java @@ -13,6 +13,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; /** + * The command for a player to change his password with. */ public class ChangePasswordCommand extends ExecutableCommand { @@ -27,10 +28,10 @@ public class ChangePasswordCommand extends ExecutableCommand { final Messages m = wrapper.getMessages(); // Get the passwords - String playerPass = commandArguments.get(0); - String playerPassVerify = commandArguments.get(1); + String oldPassword = commandArguments.get(0); + String newPassword = commandArguments.get(1); - // Get the player instance and make sure it's authenticated + // Get the player instance and make sure he's authenticated Player player = (Player) sender; String name = player.getName().toLowerCase(); final PlayerCache playerCache = wrapper.getPlayerCache(); @@ -40,8 +41,7 @@ public class ChangePasswordCommand extends ExecutableCommand { } // Make sure the password is allowed - // TODO ljacqu 20151121: The password confirmation appears to be never verified - String playerPassLowerCase = playerPass.toLowerCase(); + String playerPassLowerCase = newPassword.toLowerCase(); if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where") || playerPassLowerCase.contains("insert") || playerPassLowerCase.contains("modify") || playerPassLowerCase.contains("from") || playerPassLowerCase.contains("select") @@ -66,8 +66,8 @@ public class ChangePasswordCommand extends ExecutableCommand { // Set the password final AuthMe plugin = wrapper.getAuthMe(); - wrapper.getServer().getScheduler().runTaskAsynchronously(plugin, - new ChangePasswordTask(plugin, player, playerPass, playerPassVerify)); + wrapper.getScheduler().runTaskAsynchronously(plugin, + new ChangePasswordTask(plugin, player, oldPassword, newPassword)); return true; } } diff --git a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java index 87f113cc5..a81611a5d 100644 --- a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java @@ -18,6 +18,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; +import java.util.Arrays; import java.util.Collections; import static java.util.Arrays.asList; @@ -85,7 +86,7 @@ public class ChangePasswordCommandTest { ChangePasswordCommand command = new ChangePasswordCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts("!pass")); + command.executeCommand(sender, new CommandParts(), newParts("old123", "!pass")); // then verify(messagesMock).send(sender, MessageKey.PASSWORD_MATCH_ERROR); @@ -100,7 +101,7 @@ public class ChangePasswordCommandTest { ChangePasswordCommand command = new ChangePasswordCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts("Tester")); + command.executeCommand(sender, new CommandParts(), newParts("old_", "Tester")); // then verify(messagesMock).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); @@ -115,7 +116,7 @@ public class ChangePasswordCommandTest { Settings.passwordMaxLength = 3; // when - command.executeCommand(sender, new CommandParts(), new CommandParts("test")); + command.executeCommand(sender, new CommandParts(), newParts("12", "test")); // then verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH); @@ -130,7 +131,7 @@ public class ChangePasswordCommandTest { Settings.getPasswordMinLen = 7; // when - command.executeCommand(sender, new CommandParts(), new CommandParts("tester")); + command.executeCommand(sender, new CommandParts(), newParts("oldverylongpassword", "tester")); // then verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH); @@ -145,7 +146,7 @@ public class ChangePasswordCommandTest { Settings.unsafePasswords = asList("test", "abc123"); // when - command.executeCommand(sender, new CommandParts(), new CommandParts("abc123")); + command.executeCommand(sender, new CommandParts(), newParts("oldpw", "abc123")); // then verify(messagesMock).send(sender, MessageKey.PASSWORD_UNSAFE_ERROR); @@ -157,16 +158,14 @@ public class ChangePasswordCommandTest { // given CommandSender sender = initPlayerWithName("parker", true); ChangePasswordCommand command = new ChangePasswordCommand(); - BukkitScheduler schedulerMock = mock(BukkitScheduler.class); - given(wrapperMock.getServer().getScheduler()).willReturn(schedulerMock); // when - command.executeCommand(sender, new CommandParts(), new CommandParts(asList("abc123", "abc123"))); + command.executeCommand(sender, new CommandParts(), newParts("abc123", "abc123")); // then verify(messagesMock, never()).send(eq(sender), any(MessageKey.class)); ArgumentCaptor taskCaptor = ArgumentCaptor.forClass(ChangePasswordTask.class); - verify(schedulerMock).runTaskAsynchronously(any(AuthMe.class), taskCaptor.capture()); + verify(wrapperMock.getScheduler()).runTaskAsynchronously(any(AuthMe.class), taskCaptor.capture()); ChangePasswordTask task = taskCaptor.getValue(); assertThat((String) ReflectionTestUtils.getFieldValue(ChangePasswordTask.class, task, "newPassword"), equalTo("abc123")); @@ -179,4 +178,8 @@ public class ChangePasswordCommandTest { return player; } + private static CommandParts newParts(String... parts) { + return new CommandParts(Arrays.asList(parts)); + } + } From a1f963adf80066839cb17b73d36aaf74bd896841 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Fri, 4 Dec 2015 13:23:17 +0100 Subject: [PATCH 44/82] update hikari --- pom.xml | 8 ++++++-- src/main/java/fr/xephi/authme/datasource/MySQL.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index ceeaefcaf..c928c9a6f 100644 --- a/pom.xml +++ b/pom.xml @@ -285,7 +285,7 @@ com.zaxxer HikariCP - 2.4.1 + 2.4.2 compile @@ -298,7 +298,7 @@ org.slf4j slf4j-jdk14 - 1.7.12 + 1.7.13 compile true @@ -502,6 +502,10 @@ AllPay com.fernferret.allpay + + Vault + net.milkbowl.vault + VaultAPI net.milkbowl.vault diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java index 17d2cdfdf..69c10e824 100644 --- a/src/main/java/fr/xephi/authme/datasource/MySQL.java +++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java @@ -1,7 +1,7 @@ package fr.xephi.authme.datasource; import com.zaxxer.hikari.HikariDataSource; -import com.zaxxer.hikari.pool.PoolInitializationException; +import com.zaxxer.hikari.pool.HikariPool.PoolInitializationException; import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerAuth; From 0d1cf8c7e234a5235d599792c6e072dde8f1afc1 Mon Sep 17 00:00:00 2001 From: Xephi Date: Fri, 4 Dec 2015 17:17:35 +0100 Subject: [PATCH 45/82] Idk how it can be null, but well ... --- src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java | 6 ++++++ .../fr/xephi/authme/process/join/AsynchronousJoin.java | 7 +++++-- src/main/resources/config.yml | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java b/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java index 69774e221..2495d68b6 100644 --- a/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java +++ b/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java @@ -117,6 +117,8 @@ public class LimboCache { * @param name String */ public void deleteLimboPlayer(String name) { + if (name == null) + return; cache.remove(name); } @@ -128,6 +130,8 @@ public class LimboCache { * @return LimboPlayer */ public LimboPlayer getLimboPlayer(String name) { + if (name == null) + return null; return cache.get(name); } @@ -139,6 +143,8 @@ public class LimboCache { * @return boolean */ public boolean hasLimboPlayer(String name) { + if (name == null) + return false; return cache.containsKey(name); } diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java index 3160ddcc4..8fae6f0f6 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -253,8 +253,11 @@ public class AsynchronousJoin { ? m.retrieve(MessageKey.REGISTER_EMAIL_MESSAGE) : m.retrieve(MessageKey.REGISTER_MESSAGE); } - BukkitTask msgTask = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, msg, msgInterval)); - LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgTask); + if (LimboCache.getInstance().getLimboPlayer(name) != null) + { + BukkitTask msgTask = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, msg, msgInterval)); + LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgTask); + } } private boolean needFirstSpawn() { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0c7607e3c..fd73b7733 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -393,6 +393,7 @@ Protection: - 'US' - 'GB' # Countries blacklisted automatically ( without any needed to enable protection ) + # PLEASE USE QUOTES! countriesBlacklist: - 'A1' # Do we need to enable automatic antibot system? From 8336dc848eea8e19c64331100587b2d7110cc205 Mon Sep 17 00:00:00 2001 From: Xephi Date: Fri, 4 Dec 2015 17:24:56 +0100 Subject: [PATCH 46/82] Fix #301 --- .../authme/command/executable/register/RegisterCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java b/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java index 070d795b2..1f366deaa 100644 --- a/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java @@ -55,7 +55,7 @@ public class RegisterCommand extends ExecutableCommand { } if (commandArguments.getCount() > 1 && Settings.getEnablePasswordVerifier) { if (!commandArguments.get(0).equals(commandArguments.get(1))) { - m.send(player, MessageKey.PASSWORD_IS_USERNAME_ERROR); + m.send(player, MessageKey.PASSWORD_MATCH_ERROR); return true; } } From e781115d7cf66db57a436de8d21693aa05d50be3 Mon Sep 17 00:00:00 2001 From: Xephi Date: Fri, 4 Dec 2015 17:57:10 +0100 Subject: [PATCH 47/82] Change from mailText to a dedicated file email.html --- .../java/fr/xephi/authme/SendMailSSL.java | 4 +- .../fr/xephi/authme/settings/Settings.java | 48 ++++++++++++++++++- src/main/resources/email.html | 16 +++++++ 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/email.html diff --git a/src/main/java/fr/xephi/authme/SendMailSSL.java b/src/main/java/fr/xephi/authme/SendMailSSL.java index 1c3a4f449..8eb1a92be 100644 --- a/src/main/java/fr/xephi/authme/SendMailSSL.java +++ b/src/main/java/fr/xephi/authme/SendMailSSL.java @@ -48,7 +48,7 @@ public class SendMailSSL { final String subject = Settings.getMailSubject; final String smtp = Settings.getmailSMTP; final String password = Settings.getmailPassword; - final String mailText = Settings.getMailText.replace("", auth.getNickname()).replace("", plugin.getServer().getServerName()).replace("", newPass); + final String mailText = Settings.getMailText.replace("%playername%", auth.getNickname()).replace("%servername%", plugin.getServer().getServerName()).replace("%generatedpass%", newPass); final String mail = auth.getEmail(); Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { @@ -76,7 +76,7 @@ public class SendMailSSL { ImageIO.write(gen.generateImage(), "jpg", file); DataSource source = new FileDataSource(file); String tag = email.embed(source, auth.getNickname() + "_new_pass.jpg"); - content = content.replace("", ""); + content = content.replace("%image%", ""); } catch (Exception e) { ConsoleLogger.showError("Unable to send new password as image! Using normal text! Dest: " + mail); } diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index df9e0b0a8..0c245e022 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -8,7 +8,11 @@ import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.util.Wrapper; import org.bukkit.configuration.file.YamlConfiguration; +import com.google.common.base.Charsets; +import com.google.common.io.Files; + import java.io.*; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -23,6 +27,7 @@ public final class Settings { public static final File MODULE_FOLDER = new File(PLUGIN_FOLDER, "modules"); public static final File CACHE_FOLDER = new File(PLUGIN_FOLDER, "cache"); public static final File AUTH_FILE = new File(PLUGIN_FOLDER, "auths.db"); + public static final File EMAIL_FILE = new File(PLUGIN_FOLDER, "email.html"); public static final File SETTINGS_FILE = new File(PLUGIN_FOLDER, "config.yml"); public static final File LOG_FILE = new File(PLUGIN_FOLDER, "authme.log"); // This is not an option! @@ -221,7 +226,7 @@ public final class Settings { maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5); captchaLength = configFile.getInt("Security.captcha.captchaLength", 5); getMailSubject = configFile.getString("Email.mailSubject", "Your new AuthMe Password"); - getMailText = configFile.getString("Email.mailText", "Dear ,

This is your new AuthMe password for the server

:



Do not forget to change password after login!
/changepassword newPassword"); + getMailText = loadEmailText(); emailRegistration = configFile.getBoolean("settings.registration.enableEmailRegistrationSystem", false); saltLength = configFile.getInt("settings.security.doubleMD5SaltLength", 8); getmaxRegPerEmail = configFile.getInt("Email.maxRegPerEmail", 1); @@ -285,7 +290,40 @@ public final class Settings { } - public static void setValue(String key, Object value) { + private static String loadEmailText() { + if (!EMAIL_FILE.exists()) + saveDefaultEmailText(); + StringBuilder str = new StringBuilder(); + try { + BufferedReader in = new BufferedReader(new FileReader(EMAIL_FILE)); + String s; + while ((s = in.readLine()) != null) + str.append(s); + in.close(); + } catch(IOException e) + { + } + return str.toString(); + } + + private static void saveDefaultEmailText() { + InputStream file = plugin.getResource("email.html"); + StringBuilder str = new StringBuilder(); + try { + BufferedReader in = new BufferedReader(new InputStreamReader(file, Charset.forName("utf-8"))); + String s; + while ((s = in.readLine()) != null) + str.append(s); + in.close(); + Files.touch(EMAIL_FILE); + Files.write(str.toString(), EMAIL_FILE, Charsets.UTF_8); + } + catch(Exception e) + { + } + } + + public static void setValue(String key, Object value) { instance.set(key, value); save(); } @@ -636,6 +674,12 @@ public final class Settings { changes = true; } + if (contains("Email.mailText")) + { + set("Email.mailText", null); + ConsoleLogger.showError("Remove Email.mailText from config, we now use the email.html file"); + } + if (changes) { plugin.getLogger().warning("Merged new Config Options - I'm not an error, please don't report me"); plugin.getLogger().warning("Please check your config.yml file for new configs!"); diff --git a/src/main/resources/email.html b/src/main/resources/email.html new file mode 100644 index 000000000..12f6cbd5d --- /dev/null +++ b/src/main/resources/email.html @@ -0,0 +1,16 @@ +

+Dear %playername%, +

+ +

+This is your new AuthMe password for the server %servername%: + +%generatedpass% + +%image% + +Do not forget to change password after login! +/changepassword %generatedpass% newPassword' + +See you on %servername%! +

\ No newline at end of file From c78e12de046c331bc3947ed335a195d10d505183 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Fri, 4 Dec 2015 21:33:50 +0100 Subject: [PATCH 48/82] Refactorings - prepare to remove FoundCommandResult - Reduce tight coupling by passing list of available commands as param to CommandHandler - Split command processing method into several smaller ones - Remove unfinished logic for unlimited command arguments (reason: was not implemented and not used, probably needs another way to handle it once the need for it arises) - Create test for CommandHandler --- src/main/java/fr/xephi/authme/AuthMe.java | 11 +- .../authme/command/CommandDescription.java | 32 +--- .../xephi/authme/command/CommandHandler.java | 171 ++++++++++-------- .../fr/xephi/authme/command/CommandUtils.java | 4 +- .../authme/command/FoundCommandResult.java | 16 +- .../authme/command/help/HelpPrinter.java | 5 - .../authme/command/help/HelpSyntaxHelper.java | 5 - .../authme/command/CommandHandlerTest.java | 115 ++++++++++++ .../command/help/HelpSyntaxHelperTest.java | 37 +--- 9 files changed, 223 insertions(+), 173 deletions(-) create mode 100644 src/test/java/fr/xephi/authme/command/CommandHandlerTest.java diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 9fb59f289..655a1f33b 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -10,6 +10,7 @@ import fr.xephi.authme.cache.backup.JsonCache; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.command.CommandHandler; +import fr.xephi.authme.command.CommandInitializer; import fr.xephi.authme.converter.Converter; import fr.xephi.authme.converter.ForceFlatToSqlite; import fr.xephi.authme.datasource.*; @@ -433,7 +434,7 @@ public class AuthMe extends JavaPlugin { * Set up the command handler. */ private void setupCommandHandler() { - this.commandHandler = new CommandHandler(); + this.commandHandler = new CommandHandler(CommandInitializer.getBaseCommands()); } /** @@ -956,14 +957,14 @@ public class AuthMe extends JavaPlugin { @Override public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { - // Get the command handler, and make sure it's valid + // Make sure the command handler has been initialized if (commandHandler == null) { - wrapper.getLogger().warning("AuthMe command handler is not available"); + wrapper.getLogger().severe("AuthMe command handler is not available"); return false; } - // Handle the command, return the result - return commandHandler.onCommand(sender, cmd, commandLabel, args); + // Handle the command + return commandHandler.processCommand(sender, commandLabel, args); } /** diff --git a/src/main/java/fr/xephi/authme/command/CommandDescription.java b/src/main/java/fr/xephi/authme/command/CommandDescription.java index 34a265ee8..faeb0d746 100644 --- a/src/main/java/fr/xephi/authme/command/CommandDescription.java +++ b/src/main/java/fr/xephi/authme/command/CommandDescription.java @@ -50,10 +50,6 @@ public class CommandDescription { * The arguments the command takes. */ private List arguments = new ArrayList<>(); // TODO remove field initialization - /** - * Defines whether there is an argument maximum or not. - */ - private boolean noArgumentMaximum = false; // TODO remove field initialization /** * Defines the command permissions. */ @@ -106,15 +102,13 @@ public class CommandDescription { */ private CommandDescription(List labels, String description, String detailedDescription, ExecutableCommand executableCommand, CommandDescription parent, - List arguments, boolean noArgumentMaximum, - CommandPermissions permissions) { + List arguments, 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) { @@ -279,15 +273,6 @@ public class CommandDescription { 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. * @@ -298,10 +283,6 @@ public class CommandDescription { * @return True on success, false on failure. */ 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 return getExecutableCommand().executeCommand(sender, commandReference, commandArguments); } @@ -453,10 +434,6 @@ public class CommandDescription { return !getArguments().isEmpty(); } - public boolean hasMaximumArguments() { - return !noArgumentMaximum; // TODO ljacqu 20151130 Change variable name - } - /** * Get the command description. * @@ -604,7 +581,6 @@ public class CommandDescription { private ExecutableCommand executableCommand; private CommandDescription parent; private List arguments = new ArrayList<>(); - private boolean noArgumentMaximum; private CommandPermissions permissions; /** @@ -621,7 +597,6 @@ public class CommandDescription { getOrThrow(executableCommand, "executableCommand"), firstNonNull(parent, null), arguments, - noArgumentMaximum, firstNonNull(permissions, null) ); } @@ -670,11 +645,6 @@ public class CommandDescription { return this; } - public CommandBuilder noArgumentMaximum(boolean noArgumentMaximum) { - this.noArgumentMaximum = noArgumentMaximum; - return this; - } - public CommandBuilder permissions(CommandPermissions.DefaultPermission defaultPermission, PermissionNode... permissionNodes) { this.permissions = new CommandPermissions(asMutableList(permissionNodes), defaultPermission); diff --git a/src/main/java/fr/xephi/authme/command/CommandHandler.java b/src/main/java/fr/xephi/authme/command/CommandHandler.java index 6a6a53207..653a47646 100644 --- a/src/main/java/fr/xephi/authme/command/CommandHandler.java +++ b/src/main/java/fr/xephi/authme/command/CommandHandler.java @@ -4,7 +4,6 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.command.help.HelpProvider; import fr.xephi.authme.util.StringUtils; import org.bukkit.ChatColor; -import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import java.util.ArrayList; @@ -28,104 +27,70 @@ public class CommandHandler { */ private static final double SUGGEST_COMMAND_THRESHOLD = 0.75; + private List commands; + /** - * Process a command. + * Create a command handler. + * + * @param commands The collection of available AuthMe commands + */ + public CommandHandler(List commands) { + this.commands = commands; + } + + /** + * Map a command that was invoked to the proper {@link CommandDescription} or return a useful error + * message upon failure. * * @param sender The command sender (Bukkit). - * @param bukkitCommand The command (Bukkit). * @param bukkitCommandLabel The command label (Bukkit). * @param bukkitArgs The command arguments (Bukkit). * * @return True if the command was executed, false otherwise. */ - // TODO ljacqu 20151129: Rename onCommand() method to something not suggesting it is auto-invoked by an event - public boolean onCommand(CommandSender sender, Command bukkitCommand, String bukkitCommandLabel, String[] bukkitArgs) { + public boolean processCommand(CommandSender sender, String bukkitCommandLabel, String[] bukkitArgs) { List commandArgs = skipEmptyArguments(bukkitArgs); + // Add the Bukkit command label to the front so we get something like [authme, register, pass, passConfirm] + commandArgs.add(0, bukkitCommandLabel); - // Make sure the command isn't empty (does this happen?) - CommandParts commandReference = new CommandParts(bukkitCommandLabel, commandArgs); - if (commandReference.getCount() == 0) - return false; + // TODO: remove commandParts + CommandParts commandReference = new CommandParts(commandArgs); // Get a suitable command for this reference, and make sure it isn't null FoundCommandResult result = findCommand(commandReference); if (result == null) { + // TODO ljacqu 20151204: Log more information to the console (bukkitCommandLabel) sender.sendMessage(ChatColor.DARK_RED + "Failed to parse " + AuthMe.getPluginName() + " command!"); 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 final double commandDifference = result.getDifference(); - if (commandDifference > ASSUME_COMMAND_THRESHOLD) { - // Show the unknown command warning - sender.sendMessage(ChatColor.DARK_RED + "Unknown command!"); + if (commandDifference <= ASSUME_COMMAND_THRESHOLD) { - // Show a command suggestion if available and the difference isn't too big - if (commandDifference < SUGGEST_COMMAND_THRESHOLD) - if (result.getCommandDescription() != null) - sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/" + result.getCommandDescription().getCommandReference(commandReference) + ChatColor.YELLOW + "?"); + // Show a message when the command handler is assuming a command + if (commandDifference > 0) { + sendCommandAssumptionMessage(sender, result, commandReference); + } - // Show the help command - sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help" + ChatColor.YELLOW + " to view help."); - return true; + if (!result.hasPermission(sender)) { + sender.sendMessage(ChatColor.DARK_RED + "You don't have permission to use this command!"); + } else if (!result.hasProperArguments()) { + sendImproperArgumentsMessage(sender, result, commandReference, baseCommand); + } else { + return result.executeCommand(sender); + } + } else { + sendUnknownCommandMessage(sender, commandDifference, result, baseCommand); } - - // 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); + return true; } /** - * Skips all entries of the given array that are simply whitespace. + * Skip all entries of the given array that are simply whitespace. * * @param args The array to process * @return List of the items that are not empty @@ -162,10 +127,7 @@ public class CommandHandler { if (queryReference.getCount() <= 0) return null; - // TODO ljacqu 20151129: If base commands are only used in here (or in the future CommandHandler after changes), - // it might make sense to make the CommandInitializer package-private and to return its result into this class - // instead of regularly fetching the list of base commands from the other class. - for (CommandDescription commandDescription : CommandInitializer.getBaseCommands()) { + for (CommandDescription commandDescription : commands) { // Check whether there's a command description available for the // current command if (!commandDescription.isSuitableLabel(queryReference)) @@ -186,7 +148,7 @@ public class CommandHandler { * * @return The command found, or null. */ - public CommandDescription findCommand(List commandParts) { + private CommandDescription findCommand(List commandParts) { // Make sure the command reference is valid if (commandParts.isEmpty()) { return null; @@ -211,10 +173,63 @@ public class CommandHandler { return null; } for (CommandDescription command : commands) { - if (command.getLabels().contains(label)) { + 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 + 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); + } + + private static void sendCommandAssumptionMessage(CommandSender sender, FoundCommandResult result, + CommandParts commandReference) { + CommandParts assumedCommandParts = + new CommandParts(result.getCommandDescription().getCommandReference(commandReference)); + + sender.sendMessage(ChatColor.DARK_RED + "Unknown command, assuming " + ChatColor.GOLD + "/" + + assumedCommandParts + ChatColor.DARK_RED + "!"); + } } diff --git a/src/main/java/fr/xephi/authme/command/CommandUtils.java b/src/main/java/fr/xephi/authme/command/CommandUtils.java index f8e78c46e..6d5e2b551 100644 --- a/src/main/java/fr/xephi/authme/command/CommandUtils.java +++ b/src/main/java/fr/xephi/authme/command/CommandUtils.java @@ -13,9 +13,7 @@ public final class CommandUtils { } public static int getMaxNumberOfArguments(CommandDescription command) { - return command.hasMaximumArguments() - ? command.getArguments().size() - : -1; + return command.getArguments().size(); } } diff --git a/src/main/java/fr/xephi/authme/command/FoundCommandResult.java b/src/main/java/fr/xephi/authme/command/FoundCommandResult.java index d369a8a70..1ee4fbd9d 100644 --- a/src/main/java/fr/xephi/authme/command/FoundCommandResult.java +++ b/src/main/java/fr/xephi/authme/command/FoundCommandResult.java @@ -61,27 +61,13 @@ public class FoundCommandResult { 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. * * @return True if the command is executable, false otherwise. */ public boolean isExecutable() { - // Make sure the command description is valid - if (this.commandDescription == null) - return false; - - // Check whether the command is executable, return the result - return this.commandDescription.isExecutable(); + return commandDescription != null; } /** diff --git a/src/main/java/fr/xephi/authme/command/help/HelpPrinter.java b/src/main/java/fr/xephi/authme/command/help/HelpPrinter.java index a3244c914..7ae189836 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpPrinter.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpPrinter.java @@ -5,7 +5,6 @@ import fr.xephi.authme.command.CommandArgumentDescription; import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandPermissions; -import fr.xephi.authme.command.CommandUtils; import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.util.StringUtils; import org.bukkit.ChatColor; @@ -77,10 +76,6 @@ public class HelpPrinter { // Print the syntax sender.sendMessage(argString.toString()); } - - // Show the unlimited arguments argument - if (!command.hasMaximumArguments()) - sender.sendMessage(" " + ChatColor.YELLOW + ChatColor.ITALIC + "... : " + ChatColor.WHITE + "Any additional arguments." + ChatColor.GRAY + ChatColor.ITALIC + " (Optional)"); } /** diff --git a/src/main/java/fr/xephi/authme/command/help/HelpSyntaxHelper.java b/src/main/java/fr/xephi/authme/command/help/HelpSyntaxHelper.java index 024914c9a..023e4085b 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpSyntaxHelper.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpSyntaxHelper.java @@ -61,11 +61,6 @@ public final class HelpSyntaxHelper { sb.append(ChatColor.ITALIC).append(formatArgument(arg)); } - // Add some dots if the command allows unlimited arguments - if (!commandDescription.hasMaximumArguments()) { - sb.append(ChatColor.ITALIC).append(" ..."); - } - // Return the build command syntax return sb.toString(); } diff --git a/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java b/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java new file mode 100644 index 000000000..99358ef55 --- /dev/null +++ b/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java @@ -0,0 +1,115 @@ +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.List; + +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 List 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 = 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 = commands.get(0).getChildren().get(0); + 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)); + final CommandDescription loginCmd = commands.get(0).getChildren().get(0); + assertSenderGotMessageContaining("help", sender); + verify(loginCmd.getExecutableCommand()).executeCommand( + eq(sender), any(CommandParts.class), any(CommandParts.class)); + } + + private static CommandDescription createCommand(PlayerPermission permission, CommandDescription parent, + List 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 captor = ArgumentCaptor.forClass(String.class); + verify(sender).sendMessage(captor.capture()); + assertThat(captor.getValue(), stringContainsInOrder(text)); + } +} diff --git a/src/test/java/fr/xephi/authme/command/help/HelpSyntaxHelperTest.java b/src/test/java/fr/xephi/authme/command/help/HelpSyntaxHelperTest.java index 496dd93fb..f9fa9a6a0 100644 --- a/src/test/java/fr/xephi/authme/command/help/HelpSyntaxHelperTest.java +++ b/src/test/java/fr/xephi/authme/command/help/HelpSyntaxHelperTest.java @@ -27,8 +27,7 @@ public class HelpSyntaxHelperTest { .build(); // when - String result = HelpSyntaxHelper.getCommandSyntax( - description, new CommandParts(), "", false); + String result = HelpSyntaxHelper.getCommandSyntax(description, new CommandParts(), "", false); // then assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]")); @@ -42,8 +41,7 @@ public class HelpSyntaxHelperTest { .build(); // when - String result = HelpSyntaxHelper.getCommandSyntax( - description, new CommandParts(), null, false); + String result = HelpSyntaxHelper.getCommandSyntax(description, new CommandParts(), null, false); // then assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " ")); @@ -58,8 +56,7 @@ public class HelpSyntaxHelperTest { .build(); // when - String result = HelpSyntaxHelper.getCommandSyntax( - description, new CommandParts(), "", false); + String result = HelpSyntaxHelper.getCommandSyntax(description, new CommandParts(), "", false); // then assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]" + ITALIC + " ")); @@ -74,8 +71,7 @@ public class HelpSyntaxHelperTest { .build(); // when - String result = HelpSyntaxHelper.getCommandSyntax( - description, new CommandParts(), "", true); + String result = HelpSyntaxHelper.getCommandSyntax(description, new CommandParts(), "", true); // then assertThat(result, equalTo(WHITE + "/authme " @@ -89,8 +85,7 @@ public class HelpSyntaxHelperTest { CommandDescription description = getDescriptionBuilder().build(); // when - String result = HelpSyntaxHelper.getCommandSyntax( - description, new CommandParts(), null, true); + String result = HelpSyntaxHelper.getCommandSyntax(description, new CommandParts(), null, true); // then assertThat(result, equalTo(WHITE + "/authme " + YELLOW + BOLD + "register" + YELLOW)); @@ -104,32 +99,12 @@ public class HelpSyntaxHelperTest { .build(); // when - String result = HelpSyntaxHelper.getCommandSyntax( - description, new CommandParts(), "alt", false); + String result = HelpSyntaxHelper.getCommandSyntax(description, new CommandParts(), "alt", false); // then assertThat(result, equalTo(WHITE + "/authme alt" + ITALIC + " [name]")); } - @Test - public void shouldHighlightCommandWithAltLabelAndUnlimitedArguments() { - // given - 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 + " " + ITALIC + " ...")); - } - private static CommandDescription.CommandBuilder getDescriptionBuilder() { CommandDescription base = CommandDescription.builder() From fda7822644a5fabf9e26554a6eeeef3c8a1f15d5 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Sat, 5 Dec 2015 03:45:52 +0700 Subject: [PATCH 49/82] Merge please --- .../xephi/authme/cache/limbo/LimboCache.java | 22 ++++++++--------- .../authme/listener/AuthMePlayerListener.java | 24 ++++++++----------- .../process/register/AsyncRegister.java | 8 +++---- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java b/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java index 2495d68b6..b1f957de8 100644 --- a/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java +++ b/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java @@ -14,6 +14,8 @@ import org.bukkit.entity.Player; import java.util.concurrent.ConcurrentHashMap; +import static com.google.common.base.Preconditions.checkNotNull; + /** */ public class LimboCache { @@ -117,9 +119,8 @@ public class LimboCache { * @param name String */ public void deleteLimboPlayer(String name) { - if (name == null) - return; - cache.remove(name); + checkNotNull(name); + cache.remove(name.toLowerCase()); } /** @@ -130,9 +131,8 @@ public class LimboCache { * @return LimboPlayer */ public LimboPlayer getLimboPlayer(String name) { - if (name == null) - return null; - return cache.get(name); + checkNotNull(name); + return cache.get(name.toLowerCase()); } /** @@ -143,9 +143,8 @@ public class LimboCache { * @return boolean */ public boolean hasLimboPlayer(String name) { - if (name == null) - return false; - return cache.containsKey(name); + checkNotNull(name); + return cache.containsKey(name.toLowerCase()); } /** @@ -154,9 +153,8 @@ public class LimboCache { * @param player Player */ public void updateLimboPlayer(Player player) { - if (this.hasLimboPlayer(player.getName().toLowerCase())) { - this.deleteLimboPlayer(player.getName().toLowerCase()); - } + checkNotNull(player); + deleteLimboPlayer(player.getName().toLowerCase()); addLimboPlayer(player); } diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java index 6451f270c..96139ce32 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java @@ -9,10 +9,10 @@ import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; import fr.xephi.authme.permission.PermissionsManager; -import fr.xephi.authme.permission.UserPermission; -import fr.xephi.authme.settings.MessageKey; -import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.GeoLiteAPI; import fr.xephi.authme.util.Utils; @@ -32,8 +32,6 @@ import org.bukkit.event.player.*; import java.util.concurrent.ConcurrentHashMap; -import static fr.xephi.authme.output.MessageKey.USERNAME_ALREADY_ONLINE_ERROR; - /** */ public class AuthMePlayerListener implements Listener { @@ -169,20 +167,21 @@ public class AuthMePlayerListener implements Listener { } } - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.LOWEST) public void onPlayerJoin(PlayerJoinEvent event) { if (event.getPlayer() == null || Utils.isNPC(event.getPlayer())) { return; } final Player player = event.getPlayer(); - final String name = player.getName().toLowerCase(); - final String joinMsg = event.getJoinMessage(); - final boolean delay = Settings.delayJoinLeaveMessages && joinMsg != null; + String name = player.getName().toLowerCase(); + String joinMsg = event.getJoinMessage(); + boolean delay = Settings.delayJoinLeaveMessages && joinMsg != null; // Remove the join message while the player isn't logging in if (delay) { event.setJoinMessage(null); + joinMessage.put(name, joinMsg); } // Shedule login task so works after the prelogin @@ -190,9 +189,6 @@ public class AuthMePlayerListener implements Listener { Bukkit.getScheduler().runTask(plugin, new Runnable() { @Override public void run() { - if (delay) { - joinMessage.put(name, joinMsg); - } plugin.getManagement().performJoin(player); } }); @@ -453,7 +449,7 @@ public class AuthMePlayerListener implements Listener { String name = player.getName().toLowerCase(); Location spawn = plugin.getSpawnLocation(player); if (Settings.isSaveQuitLocationEnabled && plugin.database.isAuthAvailable(name)) { - final PlayerAuth auth = new PlayerAuth(name, spawn.getX(), spawn.getY(), spawn.getZ(), spawn.getWorld().getName(), player.getName()); + PlayerAuth auth = new PlayerAuth(name, spawn.getX(), spawn.getY(), spawn.getZ(), spawn.getWorld().getName(), player.getName()); plugin.database.updateQuitLoc(auth); } if (spawn != null && spawn.getWorld() != null) { @@ -468,7 +464,7 @@ public class AuthMePlayerListener implements Listener { } Player player = event.getPlayer(); - if (plugin.getPermissionsManager().hasPermission(player, UserPermission.BYPASS_FORCE_SURVIVAL)) { + if (plugin.getPermissionsManager().hasPermission(player, PlayerPermission.BYPASS_FORCE_SURVIVAL)) { return; } diff --git a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java index f9ceddb97..7a6352cf7 100644 --- a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java @@ -5,10 +5,10 @@ import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.permission.PlayerPermission; -import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.Messages; +import fr.xephi.authme.permission.PlayerPermission; +import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.settings.Settings; import org.bukkit.entity.Player; @@ -60,7 +60,7 @@ public class AsyncRegister { m.send(player, MessageKey.NAME_ALREADY_REGISTERED); return false; } else if (Settings.getmaxRegPerIp > 0 - && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) + && !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS) && !ip.equalsIgnoreCase("127.0.0.1") && !ip.equalsIgnoreCase("localhost") && database.getAllAuthsByIp(ip).size() >= Settings.getmaxRegPerIp) { @@ -89,7 +89,7 @@ public class AsyncRegister { private void emailRegister() throws Exception { if (Settings.getmaxRegPerEmail > 0 - && !plugin.getPermissionsManager().hasPermission(player, UserPermission.ALLOW_MULTIPLE_ACCOUNTS) + && !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS) && database.getAllAuthsByEmail(email).size() >= Settings.getmaxRegPerEmail) { m.send(player, MessageKey.MAX_REGISTER_EXCEEDED); return; From 9140ebe60293c517988df4f290696969623befef Mon Sep 17 00:00:00 2001 From: ljacqu Date: Fri, 4 Dec 2015 21:58:16 +0100 Subject: [PATCH 50/82] Change initialized command descriptions to Set - Set is more efficient if it's frequently used for `contains()`, which is what we use it for after initialization --- .../xephi/authme/command/CommandHandler.java | 7 +- .../authme/command/CommandInitializer.java | 108 +++++++++--------- .../authme/command/CommandHandlerTest.java | 30 ++++- .../command/CommandInitializerTest.java | 13 +-- 4 files changed, 86 insertions(+), 72 deletions(-) diff --git a/src/main/java/fr/xephi/authme/command/CommandHandler.java b/src/main/java/fr/xephi/authme/command/CommandHandler.java index 653a47646..bb0b1298c 100644 --- a/src/main/java/fr/xephi/authme/command/CommandHandler.java +++ b/src/main/java/fr/xephi/authme/command/CommandHandler.java @@ -8,6 +8,7 @@ import org.bukkit.command.CommandSender; import java.util.ArrayList; import java.util.List; +import java.util.Set; /** * The AuthMe command handler, responsible for mapping incoming commands to the correct {@link CommandDescription} @@ -27,14 +28,14 @@ public class CommandHandler { */ private static final double SUGGEST_COMMAND_THRESHOLD = 0.75; - private List commands; + private final Set commands; /** * Create a command handler. * * @param commands The collection of available AuthMe commands */ - public CommandHandler(List commands) { + public CommandHandler(Set commands) { this.commands = commands; } @@ -50,7 +51,7 @@ public class CommandHandler { */ public boolean processCommand(CommandSender sender, String bukkitCommandLabel, String[] bukkitArgs) { List commandArgs = skipEmptyArguments(bukkitArgs); - // Add the Bukkit command label to the front so we get something like [authme, register, pass, passConfirm] + // Add the Bukkit command label to the front so we get a list like [authme, register, pass, passConfirm] commandArgs.add(0, bukkitCommandLabel); // TODO: remove commandParts diff --git a/src/main/java/fr/xephi/authme/command/CommandInitializer.java b/src/main/java/fr/xephi/authme/command/CommandInitializer.java index ed618e5de..7fcd0f023 100644 --- a/src/main/java/fr/xephi/authme/command/CommandInitializer.java +++ b/src/main/java/fr/xephi/authme/command/CommandInitializer.java @@ -32,9 +32,7 @@ import fr.xephi.authme.permission.AdminPermission; import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.util.Wrapper; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.ALLOWED; import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.OP_ONLY; @@ -44,13 +42,13 @@ import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.OP_ON */ public final class CommandInitializer { - private static List baseCommands; + private static Set baseCommands; private CommandInitializer() { // Helper class } - public static List getBaseCommands() { + public static Set getBaseCommands() { if (baseCommands == null) { Wrapper.getInstance().getLogger().info("Initializing AuthMe commands"); initializeCommands(); @@ -287,17 +285,17 @@ public final class CommandInitializer { reloadCommand.setCommandPermissions(AdminPermission.RELOAD, OP_ONLY); // Register the version command - CommandDescription versionCommand = CommandDescription.builder() - .executableCommand(new VersionCommand()) + CommandDescription.builder() + .parent(AUTHME_BASE) .labels("version", "ver", "v", "about", "info") .description("Version info") .detailedDescription("Show detailed information about the installed AuthMeReloaded version, and shows the " + "developers, contributors, license and other information.") - .parent(AUTHME_BASE) + .executableCommand(new VersionCommand()) .build(); // Register the base login command - CommandDescription loginBaseCommand = CommandDescription.builder() + final CommandDescription LOGIN_BASE = CommandDescription.builder() .executableCommand(new LoginCommand()) .labels("login", "l") .description("Login command") @@ -309,70 +307,72 @@ public final class CommandInitializer { // Register the help command 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)); // Register the base logout command - CommandDescription logoutBaseCommand = new CommandDescription(new LogoutCommand(), new ArrayList() { + CommandDescription LOGOUT_BASE = new CommandDescription(new LogoutCommand(), new ArrayList() { { add("logout"); } }, "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 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)); // Register the base register command - CommandDescription registerBaseCommand = new CommandDescription(new fr.xephi.authme.command.executable.register.RegisterCommand(), new ArrayList() { - { - add("register"); - add("reg"); - } - }, "Registration command", "Command to register using AuthMeReloaded.", null); - registerBaseCommand.setCommandPermissions(PlayerPermission.REGISTER, CommandPermissions.DefaultPermission.ALLOWED); - registerBaseCommand.addArgument(new CommandArgumentDescription("password", "Password", false)); - registerBaseCommand.addArgument(new CommandArgumentDescription("verifyPassword", "Verify password", false)); + final CommandDescription REGISTER_BASE = CommandDescription.builder() + .parent(null) + .labels("register", "reg") + .description("Registration command") + .detailedDescription("Command to register using AuthMeReloaded.") + .withArgument("password", "Password", false) + .withArgument("verifyPassword", "Verify password", false) + .permissions(ALLOWED, PlayerPermission.REGISTER) + .executableCommand(new fr.xephi.authme.command.executable.register.RegisterCommand()) + .build(); // Register the help command 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)); // Register the base unregister command - CommandDescription unregisterBaseCommand = new CommandDescription(new fr.xephi.authme.command.executable.unregister.UnregisterCommand(), new ArrayList() { + CommandDescription UNREGISTER_BASE = new CommandDescription(new fr.xephi.authme.command.executable.unregister.UnregisterCommand(), new ArrayList() { { add("unregister"); add("unreg"); } }, "Unregistration command", "Command to unregister using AuthMeReloaded.", null); - unregisterBaseCommand.setCommandPermissions(PlayerPermission.UNREGISTER, CommandPermissions.DefaultPermission.ALLOWED); - unregisterBaseCommand.addArgument(new CommandArgumentDescription("password", "Password", false)); + UNREGISTER_BASE.setCommandPermissions(PlayerPermission.UNREGISTER, CommandPermissions.DefaultPermission.ALLOWED); + UNREGISTER_BASE.addArgument(new CommandArgumentDescription("password", "Password", false)); // 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)); // Register the base changepassword command - CommandDescription changePasswordBaseCommand = new CommandDescription(new fr.xephi.authme.command.executable.changepassword.ChangePasswordCommand(), new ArrayList() { + final CommandDescription CHANGE_PASSWORD_BASE = new CommandDescription( + new fr.xephi.authme.command.executable.changepassword.ChangePasswordCommand(), new ArrayList() { { add("changepassword"); add("changepass"); } }, "Change password command", "Command to change your password using AuthMeReloaded.", null); - changePasswordBaseCommand.setCommandPermissions(PlayerPermission.CHANGE_PASSWORD, CommandPermissions.DefaultPermission.ALLOWED); - changePasswordBaseCommand.addArgument(new CommandArgumentDescription("password", "Password", false)); - changePasswordBaseCommand.addArgument(new CommandArgumentDescription("verifyPassword", "Verify password", false)); + CHANGE_PASSWORD_BASE.setCommandPermissions(PlayerPermission.CHANGE_PASSWORD, CommandPermissions.DefaultPermission.ALLOWED); + CHANGE_PASSWORD_BASE.addArgument(new CommandArgumentDescription("password", "Password", false)); + CHANGE_PASSWORD_BASE.addArgument(new CommandArgumentDescription("verifyPassword", "Verify password", false)); // Register the help command 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)); // Register the base Dungeon Maze command - CommandDescription emailBaseCommand = new CommandDescription(helpCommandExecutable, new ArrayList() { + CommandDescription EMAIL_BASE = new CommandDescription(helpCommandExecutable, new ArrayList() { { add("email"); add("mail"); @@ -381,7 +381,7 @@ public final class CommandInitializer { // Register the help command 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)); // Register the add command @@ -391,7 +391,7 @@ public final class CommandInitializer { add("addemail"); 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.addArgument(new CommandArgumentDescription("email", "Email address", false)); addEmailCommand.addArgument(new CommandArgumentDescription("verifyEmail", "Email address verification", false)); @@ -403,7 +403,7 @@ public final class CommandInitializer { add("changeemail"); 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.addArgument(new CommandArgumentDescription("oldEmail", "Old email address", false)); changeEmailCommand.addArgument(new CommandArgumentDescription("newEmail", "New email address", false)); @@ -416,51 +416,51 @@ public final class CommandInitializer { add("recoveremail"); 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.addArgument(new CommandArgumentDescription("email", "Email address", false)); // Register the base captcha command - CommandDescription captchaBaseCommand = new CommandDescription(new CaptchaCommand(), new ArrayList() { + CommandDescription CAPTCHA_BASE = new CommandDescription(new CaptchaCommand(), new ArrayList() { { add("captcha"); add("capt"); } }, "Captcha command", "Captcha command for AuthMeReloaded.", null); - captchaBaseCommand.setCommandPermissions(PlayerPermission.CAPTCHA, CommandPermissions.DefaultPermission.ALLOWED); - captchaBaseCommand.addArgument(new CommandArgumentDescription("captcha", "The captcha", false)); + CAPTCHA_BASE.setCommandPermissions(PlayerPermission.CAPTCHA, CommandPermissions.DefaultPermission.ALLOWED); + CAPTCHA_BASE.addArgument(new CommandArgumentDescription("captcha", "The captcha", false)); // Register the help command 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)); // Register the base converter command - CommandDescription converterBaseCommand = new CommandDescription(new ConverterCommand(), new ArrayList() { + CommandDescription CONVERTER_BASE = new CommandDescription(new ConverterCommand(), new ArrayList() { { add("converter"); add("convert"); add("conv"); } }, "Convert command", "Convert command for AuthMeReloaded.", null); - converterBaseCommand.setCommandPermissions(AdminPermission.CONVERTER, OP_ONLY); - converterBaseCommand.addArgument(new CommandArgumentDescription("job", "Conversion job: flattosql / flattosqlite /| xauth / crazylogin / rakamak / royalauth / vauth / sqltoflat", false)); + CONVERTER_BASE.setCommandPermissions(AdminPermission.CONVERTER, OP_ONLY); + CONVERTER_BASE.addArgument(new CommandArgumentDescription("job", "Conversion job: flattosql / flattosqlite /| xauth / crazylogin / rakamak / royalauth / vauth / sqltoflat", false)); // Register the help command 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)); // Add the base commands to the commands array - baseCommands = Arrays.asList( + baseCommands = new HashSet<>(Arrays.asList( AUTHME_BASE, - loginBaseCommand, - logoutBaseCommand, - registerBaseCommand, - unregisterBaseCommand, - changePasswordBaseCommand, - emailBaseCommand, - captchaBaseCommand, - converterBaseCommand); + LOGIN_BASE, + LOGOUT_BASE, + REGISTER_BASE, + UNREGISTER_BASE, + CHANGE_PASSWORD_BASE, + EMAIL_BASE, + CAPTCHA_BASE, + CONVERTER_BASE)); } } diff --git a/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java b/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java index 99358ef55..9043bd7e1 100644 --- a/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java @@ -9,7 +9,10 @@ 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; @@ -29,7 +32,7 @@ import static org.mockito.Mockito.verify; */ public class CommandHandlerTest { - private static List commands; + private static Set commands; private static CommandHandler handler; @BeforeClass @@ -42,7 +45,7 @@ public class CommandHandlerTest { newArgument("password", false), newArgument("confirmation", false)); CommandDescription testBase = createCommand(null, null, singletonList("test"), newArgument("test", true)); - commands = asList(authMeBase, testBase); + commands = new HashSet<>(asList(authMeBase, testBase)); handler = new CommandHandler(commands); } @@ -58,7 +61,7 @@ public class CommandHandlerTest { handler.processCommand(sender, bukkitLabel, args); // then - final CommandDescription loginCmd = commands.get(0).getChildren().get(0); + 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)); @@ -78,10 +81,7 @@ public class CommandHandlerTest { // then assertThat(result, equalTo(true)); - final CommandDescription loginCmd = commands.get(0).getChildren().get(0); assertSenderGotMessageContaining("help", sender); - verify(loginCmd.getExecutableCommand()).executeCommand( - eq(sender), any(CommandParts.class), any(CommandParts.class)); } private static CommandDescription createCommand(PlayerPermission permission, CommandDescription parent, @@ -112,4 +112,22 @@ public class CommandHandlerTest { verify(sender).sendMessage(captor.capture()); assertThat(captor.getValue(), stringContainsInOrder(text)); } + + private static CommandDescription getCommandWithLabel(String label, Collection 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; + } } diff --git a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java index 2cc424c01..dcbec20ed 100644 --- a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java @@ -5,12 +5,7 @@ import fr.xephi.authme.util.WrapperMock; import org.junit.BeforeClass; import org.junit.Test; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.regex.Pattern; import static org.hamcrest.Matchers.equalTo; @@ -30,7 +25,7 @@ public class CommandInitializerTest { */ private static int MAX_ALLOWED_DEPTH = 1; - private static List commands; + private static Set commands; @BeforeClass public static void initializeCommandManager() { @@ -232,11 +227,11 @@ public class CommandInitializerTest { // ------------ // Helper methods // ------------ - private static void walkThroughCommands(List commands, BiConsumer consumer) { + private static void walkThroughCommands(Collection commands, BiConsumer consumer) { walkThroughCommands(commands, consumer, 0); } - private static void walkThroughCommands(List commands, BiConsumer consumer, int depth) { + private static void walkThroughCommands(Collection commands, BiConsumer consumer, int depth) { for (CommandDescription command : commands) { consumer.accept(command, depth); if (command.hasChildren()) { From 2faad44ffaf0c963dbb3a9cf12acd050b7f47d98 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Fri, 4 Dec 2015 23:19:37 +0100 Subject: [PATCH 51/82] Move most API of CommandParts to util classes Gradual transition to removing CommandParts altogether. - Move logic from CommandParts to utils classes --- .../authme/command/CommandDescription.java | 14 ++- .../fr/xephi/authme/command/CommandParts.java | 73 +------------ .../fr/xephi/authme/command/CommandUtils.java | 39 +++++++ .../authme/command/FoundCommandResult.java | 5 +- .../authme/command/help/HelpProvider.java | 10 +- .../fr/xephi/authme/util/CollectionUtils.java | 47 ++++++++ .../fr/xephi/authme/util/StringUtils.java | 3 +- .../command/CommandInitializerTest.java | 6 +- .../authme/command/CommandPartsTest.java | 3 +- .../captcha/CaptchaCommandTest.java | 6 +- .../ChangePasswordCommandTest.java | 17 +-- .../executable/email/AddEmailCommandTest.java | 9 +- .../email/ChangeEmailCommandTest.java | 9 +- .../email/RecoverEmailCommandTest.java | 4 +- .../executable/login/LoginCommandTest.java | 12 ++- .../executable/logout/LogoutCommandTest.java | 6 +- .../register/RegisterCommandTest.java | 12 ++- .../command/help/HelpSyntaxHelperTest.java | 18 ++-- .../authme/util/CollectionUtilsTest.java | 102 ++++++++++++++++++ 19 files changed, 278 insertions(+), 117 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/util/CollectionUtils.java create mode 100644 src/test/java/fr/xephi/authme/util/CollectionUtilsTest.java diff --git a/src/main/java/fr/xephi/authme/command/CommandDescription.java b/src/main/java/fr/xephi/authme/command/CommandDescription.java index faeb0d746..2911055de 100644 --- a/src/main/java/fr/xephi/authme/command/CommandDescription.java +++ b/src/main/java/fr/xephi/authme/command/CommandDescription.java @@ -1,6 +1,7 @@ package fr.xephi.authme.command; import fr.xephi.authme.permission.PermissionNode; +import fr.xephi.authme.util.CollectionUtils; import fr.xephi.authme.util.StringUtils; import org.bukkit.command.CommandSender; @@ -185,10 +186,6 @@ public class CommandDescription { * @return True if the command reference is suitable to this command label, false otherwise. */ public boolean isSuitableLabel(CommandParts commandReference) { - // Make sure the command reference is valid - if (commandReference.getCount() <= 0) - return false; - // Get the parent count //getParent() = getParent().getParentCount() + 1 String element = commandReference.get(getParentCount()); @@ -252,7 +249,8 @@ public class CommandDescription { CommandParts reference = getCommandReference(other); // 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); } /** @@ -469,13 +467,13 @@ public class CommandDescription { return new FoundCommandResult( this, getCommandReference(queryReference), - new CommandParts(), + new CommandParts(new ArrayList()), queryReference); } // Get the new command reference and arguments - CommandParts newReference = new CommandParts(queryReference.getRange(0, getParentCount() + 1)); - CommandParts newArguments = new CommandParts(queryReference.getRange(getParentCount() + 1)); + CommandParts newReference = new CommandParts(CollectionUtils.getRange(queryReference.getList(), 0, getParentCount() + 1)); + CommandParts newArguments = new CommandParts(CollectionUtils.getRange(queryReference.getList(), getParentCount() + 1)); // Handle the child's, if this command has any if (getChildren().size() > 0) { diff --git a/src/main/java/fr/xephi/authme/command/CommandParts.java b/src/main/java/fr/xephi/authme/command/CommandParts.java index 35e895746..58df26011 100644 --- a/src/main/java/fr/xephi/authme/command/CommandParts.java +++ b/src/main/java/fr/xephi/authme/command/CommandParts.java @@ -14,12 +14,6 @@ public class CommandParts { */ private final List parts = new ArrayList<>(); - /** - * Constructor. - */ - public CommandParts() { - } - /** * Constructor. * @@ -47,17 +41,6 @@ public class CommandParts { this.parts.addAll(parts); } - /** - * Constructor. - * - * @param base The base part. - * @param parts The list of additional parts. - */ - public CommandParts(String base, List parts) { - this.parts.add(base); - this.parts.addAll(parts); - } - /** * Get the command parts. * @@ -67,41 +50,6 @@ public class CommandParts { 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 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. * @@ -146,6 +94,7 @@ public class CommandParts { * * @return The parts range. Parts that were out of bound are not included. */ + @Deprecated public List getRange(int start, int count) { // Create a new list to put the range into List elements = new ArrayList<>(); @@ -162,27 +111,7 @@ public class CommandParts { return elements; } - /** - * 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. diff --git a/src/main/java/fr/xephi/authme/command/CommandUtils.java b/src/main/java/fr/xephi/authme/command/CommandUtils.java index 6d5e2b551..6903ff7a4 100644 --- a/src/main/java/fr/xephi/authme/command/CommandUtils.java +++ b/src/main/java/fr/xephi/authme/command/CommandUtils.java @@ -1,5 +1,11 @@ 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) { @@ -16,4 +22,37 @@ public final class CommandUtils { 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 labels) { + return StringUtils.join(" ", labels); + } + + public static double getDifference(List labels1, List 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))); + } + + + + + } diff --git a/src/main/java/fr/xephi/authme/command/FoundCommandResult.java b/src/main/java/fr/xephi/authme/command/FoundCommandResult.java index 1ee4fbd9d..915516500 100644 --- a/src/main/java/fr/xephi/authme/command/FoundCommandResult.java +++ b/src/main/java/fr/xephi/authme/command/FoundCommandResult.java @@ -139,10 +139,11 @@ public class FoundCommandResult { */ public double getDifference() { // Get the difference through the command found - if (this.commandDescription != null) + if (this.commandDescription != null) { return this.commandDescription.getCommandDifference(this.queryReference); + } // Get the difference from the query reference - return this.queryReference.getDifference(commandReference, true); + return CommandUtils.getDifference(queryReference.getList(), commandReference.getList(), true); } } diff --git a/src/main/java/fr/xephi/authme/command/help/HelpProvider.java b/src/main/java/fr/xephi/authme/command/help/HelpProvider.java index 03dab7b4f..a2f3d1f2c 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpProvider.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpProvider.java @@ -9,6 +9,9 @@ import fr.xephi.authme.settings.Settings; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; +import java.util.ArrayList; +import java.util.List; + /** */ public class HelpProvider { @@ -40,7 +43,12 @@ 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) { // Find the command for this help query, one with and one without a prefixed base command FoundCommandResult result = AuthMe.getInstance().getCommandHandler().findCommand(new CommandParts(helpQuery.getList())); - CommandParts commandReferenceOther = new CommandParts(reference.get(0), helpQuery.getList()); + + // TODO ljacqu 20151204 Fix me to nicer code + List 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 (result == null) diff --git a/src/main/java/fr/xephi/authme/util/CollectionUtils.java b/src/main/java/fr/xephi/authme/util/CollectionUtils.java new file mode 100644 index 000000000..4d43757e1 --- /dev/null +++ b/src/main/java/fr/xephi/authme/util/CollectionUtils.java @@ -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 getRange(List 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 getRange(List list, int start) { + if (start >= list.size()) { + return new ArrayList<>(); + } + return getRange(list, start, list.size() - start); + } +} diff --git a/src/main/java/fr/xephi/authme/util/StringUtils.java b/src/main/java/fr/xephi/authme/util/StringUtils.java index 74fe04756..2e37bfce0 100644 --- a/src/main/java/fr/xephi/authme/util/StringUtils.java +++ b/src/main/java/fr/xephi/authme/util/StringUtils.java @@ -29,8 +29,9 @@ public final class StringUtils { */ public static double getDifference(String first, String second) { // Make sure the strings are valid. - if (first == null || second == null) + if (first == null || second == null) { return 1.0; + } // Create a string similarity service instance, to allow comparison StringSimilarityService service = new StringSimilarityServiceImpl(new LevenshteinDistanceStrategy()); diff --git a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java index dcbec20ed..51a8e3cdc 100644 --- a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java @@ -254,12 +254,12 @@ public class CommandInitializerTest { } /** - * 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. * - * @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 getAbsoluteLabels(CommandDescription command) { String parentPath = ""; diff --git a/src/test/java/fr/xephi/authme/command/CommandPartsTest.java b/src/test/java/fr/xephi/authme/command/CommandPartsTest.java index 62d22b5fa..163f52d4c 100644 --- a/src/test/java/fr/xephi/authme/command/CommandPartsTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandPartsTest.java @@ -3,6 +3,7 @@ package fr.xephi.authme.command; import org.junit.Test; import java.util.Arrays; +import java.util.Collections; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; @@ -27,7 +28,7 @@ public class CommandPartsTest { @Test public void shouldPrintEmptyStringForNoArguments() { // given - CommandParts parts = new CommandParts(); + CommandParts parts = new CommandParts(Collections.EMPTY_LIST); // when String str = parts.toString(); diff --git a/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java index 36169db05..6b183e35a 100644 --- a/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java @@ -15,6 +15,8 @@ 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; @@ -40,7 +42,7 @@ public class CaptchaCommandTest { ExecutableCommand command = new CaptchaCommand(); // when - boolean result = command.executeCommand(sender, new CommandParts(), new CommandParts()); + boolean result = command.executeCommand(sender, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST)); // then assertThat(result, equalTo(true)); @@ -56,7 +58,7 @@ public class CaptchaCommandTest { ExecutableCommand command = new CaptchaCommand(); // when - boolean result = command.executeCommand(player, new CommandParts(), new CommandParts()); + boolean result = command.executeCommand(player, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST)); // then assertThat(result, equalTo(true)); diff --git a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java index a81611a5d..9092205aa 100644 --- a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java @@ -18,6 +18,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -58,7 +59,7 @@ public class ChangePasswordCommandTest { CommandParts arguments = mock(CommandParts.class); // when - command.executeCommand(sender, new CommandParts(), arguments); + command.executeCommand(sender, newParts(), arguments); // then verify(arguments, never()).get(anyInt()); @@ -72,7 +73,7 @@ public class ChangePasswordCommandTest { ChangePasswordCommand command = new ChangePasswordCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts("pass")); + command.executeCommand(sender, newParts(), new CommandParts("pass")); // then verify(messagesMock).send(sender, MessageKey.NOT_LOGGED_IN); @@ -86,7 +87,7 @@ public class ChangePasswordCommandTest { ChangePasswordCommand command = new ChangePasswordCommand(); // when - command.executeCommand(sender, new CommandParts(), newParts("old123", "!pass")); + command.executeCommand(sender, newParts(), newParts("old123", "!pass")); // then verify(messagesMock).send(sender, MessageKey.PASSWORD_MATCH_ERROR); @@ -101,7 +102,7 @@ public class ChangePasswordCommandTest { ChangePasswordCommand command = new ChangePasswordCommand(); // when - command.executeCommand(sender, new CommandParts(), newParts("old_", "Tester")); + command.executeCommand(sender, newParts(), newParts("old_", "Tester")); // then verify(messagesMock).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); @@ -116,7 +117,7 @@ public class ChangePasswordCommandTest { Settings.passwordMaxLength = 3; // when - command.executeCommand(sender, new CommandParts(), newParts("12", "test")); + command.executeCommand(sender, newParts(), newParts("12", "test")); // then verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH); @@ -131,7 +132,7 @@ public class ChangePasswordCommandTest { Settings.getPasswordMinLen = 7; // when - command.executeCommand(sender, new CommandParts(), newParts("oldverylongpassword", "tester")); + command.executeCommand(sender, newParts(), newParts("oldverylongpassword", "tester")); // then verify(messagesMock).send(sender, MessageKey.INVALID_PASSWORD_LENGTH); @@ -146,7 +147,7 @@ public class ChangePasswordCommandTest { Settings.unsafePasswords = asList("test", "abc123"); // when - command.executeCommand(sender, new CommandParts(), newParts("oldpw", "abc123")); + command.executeCommand(sender, newParts(), newParts("oldpw", "abc123")); // then verify(messagesMock).send(sender, MessageKey.PASSWORD_UNSAFE_ERROR); @@ -160,7 +161,7 @@ public class ChangePasswordCommandTest { ChangePasswordCommand command = new ChangePasswordCommand(); // when - command.executeCommand(sender, new CommandParts(), newParts("abc123", "abc123")); + command.executeCommand(sender, newParts(), newParts("abc123", "abc123")); // then verify(messagesMock, never()).send(eq(sender), any(MessageKey.class)); diff --git a/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java index a06cff220..d377fc0f8 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java @@ -11,6 +11,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import java.util.ArrayList; import java.util.Arrays; import static org.mockito.Mockito.never; @@ -40,7 +41,7 @@ public class AddEmailCommandTest { AddEmailCommand command = new AddEmailCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts()); + command.executeCommand(sender, newParts(), newParts()); // then verify(authMeMock, never()).getManagement(); @@ -53,11 +54,15 @@ public class AddEmailCommandTest { AddEmailCommand command = new AddEmailCommand(); // when - command.executeCommand(sender, new CommandParts(), + command.executeCommand(sender, newParts(), new CommandParts(Arrays.asList("mail@example", "other_example"))); // then verify(authMeMock).getManagement(); verify(managementMock).performAddEmail(sender, "mail@example", "other_example"); } + + private static CommandParts newParts() { + return new CommandParts(new ArrayList()); + } } diff --git a/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java index 0f2c05e6e..2dc25c96b 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java @@ -11,6 +11,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import java.util.ArrayList; import java.util.Arrays; import static org.mockito.Mockito.never; @@ -40,7 +41,7 @@ public class ChangeEmailCommandTest { ChangeEmailCommand command = new ChangeEmailCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts()); + command.executeCommand(sender, newParts(), newParts()); // then verify(authMeMock, never()).getManagement(); @@ -53,11 +54,15 @@ public class ChangeEmailCommandTest { ChangeEmailCommand command = new ChangeEmailCommand(); // when - command.executeCommand(sender, new CommandParts(), + command.executeCommand(sender, newParts(), new CommandParts(Arrays.asList("new.mail@example.org", "old_mail@example.org"))); // then verify(authMeMock).getManagement(); verify(managementMock).performChangeEmail(sender, "new.mail@example.org", "old_mail@example.org"); } + + private static CommandParts newParts() { + return new CommandParts(new ArrayList()); + } } diff --git a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java index 9857a2d4c..a1403c5ac 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java @@ -9,6 +9,8 @@ import org.junit.Ignore; import org.junit.Test; import org.mockito.Mockito; +import java.util.Collections; + /** * Test for {@link RecoverEmailCommand}. */ @@ -27,7 +29,7 @@ public class RecoverEmailCommandTest { RecoverEmailCommand command = new RecoverEmailCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts()); + command.executeCommand(sender, new CommandParts(Collections.EMPTY_LIST), new CommandParts(Collections.EMPTY_LIST)); // then } diff --git a/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java index 6f06a5fff..52a71891b 100644 --- a/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java @@ -11,6 +11,8 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import java.util.ArrayList; + import static org.mockito.Matchers.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -38,7 +40,7 @@ public class LoginCommandTest { LoginCommand command = new LoginCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts()); + command.executeCommand(sender, newParts(), newParts()); // then Mockito.verify(managementMock, never()).performLogin(any(Player.class), anyString(), anyBoolean()); @@ -51,7 +53,7 @@ public class LoginCommandTest { LoginCommand command = new LoginCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts("password")); + command.executeCommand(sender, newParts(), new CommandParts("password")); // then Mockito.verify(managementMock).performLogin(eq(sender), eq("password"), eq(false)); @@ -64,11 +66,15 @@ public class LoginCommandTest { LoginCommand command = new LoginCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts()); + command.executeCommand(sender, newParts(), newParts()); // then // TODO ljacqu 20151121: May make sense to handle null password in LoginCommand instead of forwarding the call String password = null; Mockito.verify(managementMock).performLogin(eq(sender), eq(password), eq(false)); } + + private static CommandParts newParts() { + return new CommandParts(new ArrayList()); + } } diff --git a/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java index c8774978c..65f246397 100644 --- a/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java @@ -12,6 +12,8 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import java.util.ArrayList; + import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -40,7 +42,7 @@ public class LogoutCommandTest { LogoutCommand command = new LogoutCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts()); + command.executeCommand(sender, new CommandParts(new ArrayList()), new CommandParts(new ArrayList())); // then Mockito.verify(managementMock, never()).performLogout(any(Player.class)); @@ -53,7 +55,7 @@ public class LogoutCommandTest { LogoutCommand command = new LogoutCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts("password")); + command.executeCommand(sender, new CommandParts(new ArrayList()), new CommandParts("password")); // then Mockito.verify(managementMock).performLogout(sender); diff --git a/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java index 02bb65a73..6dd19eb25 100644 --- a/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java @@ -14,6 +14,8 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +import java.util.ArrayList; + import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.any; @@ -48,7 +50,7 @@ public class RegisterCommandTest { ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); // when - command.executeCommand(sender, new CommandParts(), new CommandParts()); + command.executeCommand(sender, newParts(), newParts()); // then verify(sender).sendMessage(messageCaptor.capture()); @@ -63,7 +65,7 @@ public class RegisterCommandTest { RegisterCommand command = new RegisterCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts()); + command.executeCommand(sender, newParts(), newParts()); // then verify(messagesMock).send(sender, MessageKey.USAGE_REGISTER); @@ -77,9 +79,13 @@ public class RegisterCommandTest { RegisterCommand command = new RegisterCommand(); // when - command.executeCommand(sender, new CommandParts(), new CommandParts("password")); + command.executeCommand(sender, newParts(), new CommandParts("password")); // then verify(managementMock).performRegister(sender, "password", ""); } + + private static CommandParts newParts() { + return new CommandParts(new ArrayList()); + } } diff --git a/src/test/java/fr/xephi/authme/command/help/HelpSyntaxHelperTest.java b/src/test/java/fr/xephi/authme/command/help/HelpSyntaxHelperTest.java index f9fa9a6a0..acfe90282 100644 --- a/src/test/java/fr/xephi/authme/command/help/HelpSyntaxHelperTest.java +++ b/src/test/java/fr/xephi/authme/command/help/HelpSyntaxHelperTest.java @@ -7,6 +7,8 @@ import fr.xephi.authme.command.executable.authme.RegisterCommand; import org.junit.Test; import org.mockito.Mockito; +import java.util.ArrayList; + import static org.bukkit.ChatColor.BOLD; import static org.bukkit.ChatColor.ITALIC; import static org.bukkit.ChatColor.WHITE; @@ -27,7 +29,7 @@ public class HelpSyntaxHelperTest { .build(); // when - String result = HelpSyntaxHelper.getCommandSyntax(description, new CommandParts(), "", false); + String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", false); // then assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]")); @@ -41,7 +43,7 @@ public class HelpSyntaxHelperTest { .build(); // when - String result = HelpSyntaxHelper.getCommandSyntax(description, new CommandParts(), null, false); + String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), null, false); // then assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " ")); @@ -56,7 +58,7 @@ public class HelpSyntaxHelperTest { .build(); // when - String result = HelpSyntaxHelper.getCommandSyntax(description, new CommandParts(), "", false); + String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", false); // then assertThat(result, equalTo(WHITE + "/authme register" + ITALIC + " [name]" + ITALIC + " ")); @@ -71,7 +73,7 @@ public class HelpSyntaxHelperTest { .build(); // when - String result = HelpSyntaxHelper.getCommandSyntax(description, new CommandParts(), "", true); + String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "", true); // then assertThat(result, equalTo(WHITE + "/authme " @@ -85,7 +87,7 @@ public class HelpSyntaxHelperTest { CommandDescription description = getDescriptionBuilder().build(); // when - String result = HelpSyntaxHelper.getCommandSyntax(description, new CommandParts(), null, true); + String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), null, true); // then assertThat(result, equalTo(WHITE + "/authme " + YELLOW + BOLD + "register" + YELLOW)); @@ -99,12 +101,16 @@ public class HelpSyntaxHelperTest { .build(); // when - String result = HelpSyntaxHelper.getCommandSyntax(description, new CommandParts(), "alt", false); + String result = HelpSyntaxHelper.getCommandSyntax(description, newParts(), "alt", false); // then assertThat(result, equalTo(WHITE + "/authme alt" + ITALIC + " [name]")); } + private static CommandParts newParts() { + // TODO ljacqu 20151204: Remove this method once CommandParts has been removed + return new CommandParts(new ArrayList()); + } private static CommandDescription.CommandBuilder getDescriptionBuilder() { CommandDescription base = CommandDescription.builder() diff --git a/src/test/java/fr/xephi/authme/util/CollectionUtilsTest.java b/src/test/java/fr/xephi/authme/util/CollectionUtilsTest.java new file mode 100644 index 000000000..f359f0883 --- /dev/null +++ b/src/test/java/fr/xephi/authme/util/CollectionUtilsTest.java @@ -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 list = Arrays.asList("test", "1", "2", "3", "4"); + + // when + List result = CollectionUtils.getRange(list, 0, 24); + + // then + assertThat(result, equalTo(list)); + } + + @Test + public void shouldReturnEmptyListForZeroCount() { + // given + List list = Arrays.asList("test", "1", "2", "3", "4"); + + // when + List result = CollectionUtils.getRange(list, 2, 0); + + // then + assertThat(result, empty()); + } + + + @Test + public void shouldReturnEmptyListForTooHighStart() { + // given + List list = Arrays.asList("test", "1", "2", "3", "4"); + + // when + List result = CollectionUtils.getRange(list, 12, 2); + + // then + assertThat(result, empty()); + } + + @Test + public void shouldReturnSubList() { + // given + List list = Arrays.asList("test", "1", "2", "3", "4"); + + // when + List result = CollectionUtils.getRange(list, 1, 3); + + // then + assertThat(result, contains("1", "2", "3")); + } + + @Test + public void shouldReturnTillEnd() { + // given + List list = Arrays.asList("test", "1", "2", "3", "4"); + + // when + List result = CollectionUtils.getRange(list, 2, 3); + + // then + assertThat(result, contains("2", "3", "4")); + } + + @Test + public void shouldRemoveFirstTwo() { + // given + List list = Arrays.asList("test", "1", "2", "3", "4"); + + // when + List result = CollectionUtils.getRange(list, 2); + + // then + assertThat(result, contains("2", "3", "4")); + } + + @Test + public void shouldHandleNegativeStart() { + // given + List list = Arrays.asList("test", "1", "2", "3", "4"); + + // when + List result = CollectionUtils.getRange(list, -4); + + // then + assertThat(result, equalTo(list)); + } +} From 8eb1b38d217085a805d7fce94306d53062193497 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Fri, 4 Dec 2015 23:47:48 +0100 Subject: [PATCH 52/82] Slim down CommandParts API - Remove all methods that aren't constructors / fancy get() on list; almost possible to remove class entirely --- .../java/fr/xephi/authme/ConsoleLogger.java | 13 ++--- .../authme/command/CommandDescription.java | 3 +- .../xephi/authme/command/CommandHandler.java | 17 ++++--- .../fr/xephi/authme/command/CommandParts.java | 49 +------------------ .../authme/SwitchAntiBotCommand.java | 17 ++++--- .../authme/command/help/HelpProvider.java | 21 +++++--- .../authme/command/help/HelpSyntaxHelper.java | 6 ++- .../fr/xephi/authme/util/StringUtils.java | 2 - 8 files changed, 47 insertions(+), 81 deletions(-) diff --git a/src/main/java/fr/xephi/authme/ConsoleLogger.java b/src/main/java/fr/xephi/authme/ConsoleLogger.java index 890318046..fee14296d 100644 --- a/src/main/java/fr/xephi/authme/ConsoleLogger.java +++ b/src/main/java/fr/xephi/authme/ConsoleLogger.java @@ -2,7 +2,6 @@ package fr.xephi.authme; import com.google.common.base.Throwables; import fr.xephi.authme.settings.Settings; -import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.Wrapper; import java.io.IOException; @@ -17,8 +16,10 @@ import java.util.Date; */ 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 final DateFormat df = new SimpleDateFormat("[MM-dd HH:mm:ss]"); private ConsoleLogger() { // Service class @@ -57,11 +58,11 @@ public final class ConsoleLogger { */ private static void writeLog(String message) { String dateTime; - synchronized (df) { - dateTime = df.format(new Date()); + synchronized (DATE_FORMAT) { + dateTime = DATE_FORMAT.format(new Date()); } 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.CREATE); } catch (IOException ignored) { @@ -77,6 +78,6 @@ public final class ConsoleLogger { if (!Settings.useLogging) { return; } - writeLog("" + Throwables.getStackTraceAsString(ex)); + writeLog(Throwables.getStackTraceAsString(ex)); } } diff --git a/src/main/java/fr/xephi/authme/command/CommandDescription.java b/src/main/java/fr/xephi/authme/command/CommandDescription.java index 2911055de..4623ddd6c 100644 --- a/src/main/java/fr/xephi/authme/command/CommandDescription.java +++ b/src/main/java/fr/xephi/authme/command/CommandDescription.java @@ -211,8 +211,9 @@ public class CommandDescription { List referenceList = new ArrayList<>(); // 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()); + } // Get the current label referenceList.add(getLabel(reference)); diff --git a/src/main/java/fr/xephi/authme/command/CommandHandler.java b/src/main/java/fr/xephi/authme/command/CommandHandler.java index bb0b1298c..67a4fbe64 100644 --- a/src/main/java/fr/xephi/authme/command/CommandHandler.java +++ b/src/main/java/fr/xephi/authme/command/CommandHandler.java @@ -2,6 +2,7 @@ package fr.xephi.authme.command; import fr.xephi.authme.AuthMe; 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.command.CommandSender; @@ -209,28 +210,28 @@ public class CommandHandler { private static void sendImproperArgumentsMessage(CommandSender sender, FoundCommandResult result, CommandParts commandReference, String baseCommand) { // Get the command and the suggested command reference - CommandParts suggestedCommandReference = - new CommandParts(result.getCommandDescription().getCommandReference(commandReference)); - CommandParts helpCommandReference = new CommandParts(suggestedCommandReference.getRange(1)); + List suggestedCommandReference = + result.getCommandDescription().getCommandReference(commandReference).getList(); + List 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, suggestedCommandReference, + 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 " + helpCommandReference); + + " help " + CommandUtils.labelsToString(helpCommandReference)); } private static void sendCommandAssumptionMessage(CommandSender sender, FoundCommandResult result, CommandParts commandReference) { - CommandParts assumedCommandParts = - new CommandParts(result.getCommandDescription().getCommandReference(commandReference)); + List assumedCommandParts = + result.getCommandDescription().getCommandReference(commandReference).getList(); sender.sendMessage(ChatColor.DARK_RED + "Unknown command, assuming " + ChatColor.GOLD + "/" - + assumedCommandParts + ChatColor.DARK_RED + "!"); + + CommandUtils.labelsToString(assumedCommandParts) + ChatColor.DARK_RED + "!"); } } diff --git a/src/main/java/fr/xephi/authme/command/CommandParts.java b/src/main/java/fr/xephi/authme/command/CommandParts.java index 58df26011..eb6299db5 100644 --- a/src/main/java/fr/xephi/authme/command/CommandParts.java +++ b/src/main/java/fr/xephi/authme/command/CommandParts.java @@ -23,15 +23,6 @@ public class CommandParts { this.parts.add(part); } - /** - * Constructor. - * - * @param commandParts The command parts instance. - */ - public CommandParts(CommandParts commandParts) { - this.parts.addAll(commandParts.getList()); - } - /** * Constructor. * @@ -60,7 +51,7 @@ public class CommandParts { } /** - * Get a part by it's index. + * Get a part by its index. * * @param i Part index. * @@ -75,44 +66,6 @@ public class CommandParts { 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 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. - */ - @Deprecated - public List getRange(int start, int count) { - // Create a new list to put the range into - List 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; - } - - - /** * Convert the parts to a string. * diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/SwitchAntiBotCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/SwitchAntiBotCommand.java index fb844c607..3c0478676 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/SwitchAntiBotCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/SwitchAntiBotCommand.java @@ -2,11 +2,15 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.AntiBot; import fr.xephi.authme.command.CommandParts; +import fr.xephi.authme.command.CommandUtils; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.help.HelpProvider; +import fr.xephi.authme.util.CollectionUtils; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; +import java.util.List; + /** */ public class SwitchAntiBotCommand extends ExecutableCommand { @@ -32,16 +36,16 @@ public class SwitchAntiBotCommand extends ExecutableCommand { } // Enable the mod - if (newState.equalsIgnoreCase("ON")) { + if ("ON".equalsIgnoreCase(newState)) { AntiBot.overrideAntiBotStatus(true); - sender.sendMessage("[AuthMe] AntiBot Manual Ovverride: enabled!"); + sender.sendMessage("[AuthMe] AntiBot Manual Override: enabled!"); return true; } // Disable the mod - if (newState.equalsIgnoreCase("OFF")) { + if ("OFF".equalsIgnoreCase(newState)) { AntiBot.overrideAntiBotStatus(false); - sender.sendMessage("[AuthMe] AntiBotMod Manual Ovverride: disabled!"); + sender.sendMessage("[AuthMe] AntiBotMod Manual Override: disabled!"); return true; } @@ -52,8 +56,9 @@ public class SwitchAntiBotCommand extends ExecutableCommand { HelpProvider.showHelp(sender, commandReference, commandReference, true, false, true, false, false, false); // Show the command to use for detailed help - CommandParts helpCommandReference = new CommandParts(commandReference.getRange(1)); - sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + commandReference.get(0) + " help " + helpCommandReference); + List helpCommandReference = CollectionUtils.getRange(commandReference.getList(), 1); + sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/" + + commandReference.get(0) + " help " + CommandUtils.labelsToString(helpCommandReference)); return true; } } diff --git a/src/main/java/fr/xephi/authme/command/help/HelpProvider.java b/src/main/java/fr/xephi/authme/command/help/HelpProvider.java index a2f3d1f2c..7f088acf3 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpProvider.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpProvider.java @@ -3,9 +3,11 @@ package fr.xephi.authme.command.help; import fr.xephi.authme.AuthMe; import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandParts; +import fr.xephi.authme.command.CommandUtils; import fr.xephi.authme.command.FoundCommandResult; import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.util.CollectionUtils; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -86,13 +88,14 @@ public class HelpProvider { // Show the unknown command warning 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 - if (commandDifference < 0.75) - if (result.getCommandDescription() != null) - sender.sendMessage(ChatColor.YELLOW + "Did you mean " + ChatColor.GOLD + "/" + baseCommand + " help " + suggestedCommandParts + ChatColor.YELLOW + "?"); + if (commandDifference < 0.75 && result.getCommandDescription() != null) { + // Get the suggested command + List 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 sender.sendMessage(ChatColor.YELLOW + "Use the command " + ChatColor.GOLD + "/" + baseCommand + " help" + ChatColor.YELLOW + " to view help."); @@ -102,10 +105,12 @@ public class HelpProvider { // 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).getRange(1)); + List suggestedCommandParts = CollectionUtils.getRange( + result.getCommandDescription().getCommandReference(commandReference).getList(), 1); // 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 diff --git a/src/main/java/fr/xephi/authme/command/help/HelpSyntaxHelper.java b/src/main/java/fr/xephi/authme/command/help/HelpSyntaxHelper.java index 023e4085b..5fa3f5e06 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpSyntaxHelper.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpSyntaxHelper.java @@ -3,6 +3,8 @@ package fr.xephi.authme.command.help; import fr.xephi.authme.command.CommandArgumentDescription; import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandParts; +import fr.xephi.authme.command.CommandUtils; +import fr.xephi.authme.util.CollectionUtils; import fr.xephi.authme.util.StringUtils; import org.bukkit.ChatColor; @@ -35,8 +37,8 @@ public final class HelpSyntaxHelper { // Get the help command reference, and the command label CommandParts helpCommandReference = commandDescription.getCommandReference(commandReference); - final String parentCommand = new CommandParts( - helpCommandReference.getRange(0, helpCommandReference.getCount() - 1)).toString(); + final String parentCommand = CommandUtils.labelsToString( + CollectionUtils.getRange(helpCommandReference.getList(), 0, helpCommandReference.getCount() - 1)); // Check whether the alternative label should be used String commandLabel; diff --git a/src/main/java/fr/xephi/authme/util/StringUtils.java b/src/main/java/fr/xephi/authme/util/StringUtils.java index 2e37bfce0..1751461d8 100644 --- a/src/main/java/fr/xephi/authme/util/StringUtils.java +++ b/src/main/java/fr/xephi/authme/util/StringUtils.java @@ -13,8 +13,6 @@ import java.util.Arrays; */ public final class StringUtils { - public static final String newline = System.getProperty("line.separator"); - private StringUtils() { // Utility class } From 44aa91dfffb2d674c85d096df71092be3283afe8 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 5 Dec 2015 00:10:45 +0100 Subject: [PATCH 53/82] Remove unnecessary constructor in CommandDescription - Remove one of two unnecessary constructors in CommandDescription (in favor of the builder) - Remove TODO about unlimited arguments (not currently a priority, will create a story instead of leaving a dangling TODO for ages in the code) --- .../command/CommandArgumentDescription.java | 2 - .../authme/command/CommandDescription.java | 65 +++++++++---------- 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/main/java/fr/xephi/authme/command/CommandArgumentDescription.java b/src/main/java/fr/xephi/authme/command/CommandArgumentDescription.java index 5a9cd9d7c..f846b7893 100644 --- a/src/main/java/fr/xephi/authme/command/CommandArgumentDescription.java +++ b/src/main/java/fr/xephi/authme/command/CommandArgumentDescription.java @@ -5,8 +5,6 @@ package fr.xephi.authme.command; */ public class CommandArgumentDescription { - // TODO: Allow argument to consist of infinite parts.