From bebf1cf7d413bc9f82bbff09dae0969bcf4991d3 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Mon, 22 Feb 2016 10:13:48 +0700 Subject: [PATCH 01/46] Clean cache on close. --- src/main/java/fr/xephi/authme/datasource/CacheDataSource.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java index 4d0d4436..45b25b9a 100644 --- a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java +++ b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java @@ -137,6 +137,7 @@ public class CacheDataSource implements DataSource { @Override public synchronized void close() { source.close(); + cachedAuths.invalidateAll(); } @Override From 4e011f437a4873d078f5786ae569c9ab633070e9 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Mon, 22 Feb 2016 22:11:03 +0700 Subject: [PATCH 02/46] Change message & timeout task to run synchronously. --- .../authme/UnregisterAdminCommand.java | 32 ++++++++--------- .../authme/process/join/AsynchronousJoin.java | 12 +++---- .../process/login/AsynchronousLogin.java | 2 +- .../logout/ProcessSyncronousPlayerLogout.java | 15 ++++---- .../authme/process/quit/AsynchronousQuit.java | 35 ++++++------------- .../register/ProcessSyncEmailRegister.java | 13 ++++--- .../register/ProcessSyncPasswordRegister.java | 27 +++++++------- .../unregister/AsynchronousUnregister.java | 7 ++-- .../fr/xephi/authme/task/MessageTask.java | 22 ++++++------ .../fr/xephi/authme/task/TimeoutTask.java | 32 ++--------------- 10 files changed, 77 insertions(+), 120 deletions(-) diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommand.java index dc5cd471..9ed65b0b 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommand.java @@ -1,14 +1,5 @@ package fr.xephi.authme.command.executable.authme; -import java.util.List; - -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitScheduler; -import org.bukkit.scheduler.BukkitTask; - import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerCache; @@ -20,6 +11,14 @@ import fr.xephi.authme.settings.Settings; import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.TimeoutTask; import fr.xephi.authme.util.Utils; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.scheduler.BukkitTask; + +import java.util.List; /** * Admin command to unregister a player. @@ -55,19 +54,20 @@ public class UnregisterAdminCommand implements ExecutableCommand { if (target != null && target.isOnline()) { Utils.teleportToSpawn(target); LimboCache.getInstance().addLimboPlayer(target); - int delay = Settings.getRegistrationTimeout * 20; + int timeOut = Settings.getRegistrationTimeout * 20; int interval = Settings.getWarnMessageInterval; BukkitScheduler scheduler = sender.getServer().getScheduler(); - if (delay != 0) { - BukkitTask id = scheduler.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, playerNameLowerCase, target), delay); + if (timeOut != 0) { + BukkitTask id = scheduler.runTaskLater(plugin, new TimeoutTask(plugin, playerNameLowerCase, target), timeOut); LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setTimeoutTaskId(id); } LimboCache.getInstance().getLimboPlayer(playerNameLowerCase).setMessageTaskId( - scheduler.runTaskAsynchronously(plugin, - new MessageTask(plugin, playerNameLowerCase, commandService.retrieveMessage(MessageKey.REGISTER_MESSAGE), interval))); + scheduler.runTask( + plugin, new MessageTask(plugin, playerNameLowerCase, MessageKey.REGISTER_MESSAGE, interval) + ) + ); if (Settings.applyBlindEffect) { - target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, - Settings.getRegistrationTimeout * 20, 2)); + target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeOut, 2)); } commandService.send(target, MessageKey.UNREGISTERED_SUCCESS); } 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 db678ad1..e9df2dad 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -205,20 +205,20 @@ public class AsynchronousJoin { int msgInterval = Settings.getWarnMessageInterval; if (timeOut > 0) { - BukkitTask id = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), timeOut); + BukkitTask id = sched.runTaskLater(plugin, new TimeoutTask(plugin, name, player), timeOut); LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id); } - String[] msg; + MessageKey msg; if (isAuthAvailable) { - msg = m.retrieve(MessageKey.LOGIN_MESSAGE); + msg = MessageKey.LOGIN_MESSAGE; } else { msg = Settings.emailRegistration - ? m.retrieve(MessageKey.REGISTER_EMAIL_MESSAGE) - : m.retrieve(MessageKey.REGISTER_MESSAGE); + ? MessageKey.REGISTER_EMAIL_MESSAGE + : MessageKey.REGISTER_MESSAGE; } if (msgInterval > 0 && LimboCache.getInstance().getLimboPlayer(name) != null) { - BukkitTask msgTask = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, msg, msgInterval)); + BukkitTask msgTask = sched.runTask(plugin, new MessageTask(plugin, name, msg, msgInterval)); LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgTask); } } 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 5a4cf425..573afe7b 100644 --- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java @@ -105,7 +105,7 @@ public class AsynchronousLogin { } else { msg = m.retrieve(MessageKey.REGISTER_MESSAGE); } - BukkitTask msgT = Bukkit.getScheduler().runTaskAsynchronously(plugin, + BukkitTask msgT = Bukkit.getScheduler().runTask(plugin, new MessageTask(plugin, name, msg, settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL))); LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT); } 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 5a8133b7..64c300ef 100644 --- a/src/main/java/fr/xephi/authme/process/logout/ProcessSyncronousPlayerLogout.java +++ b/src/main/java/fr/xephi/authme/process/logout/ProcessSyncronousPlayerLogout.java @@ -74,21 +74,24 @@ public class ProcessSyncronousPlayerLogout implements Runnable { int interval = Settings.getWarnMessageInterval; BukkitScheduler sched = player.getServer().getScheduler(); if (timeOut != 0) { - BukkitTask id = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), timeOut); + BukkitTask id = sched.runTaskLater(plugin, new TimeoutTask(plugin, name, player), timeOut); LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id); } - BukkitTask msgT = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, m.retrieve(MessageKey.LOGIN_MESSAGE), interval)); + BukkitTask msgT = sched.runTask(plugin, new MessageTask(plugin, name, MessageKey.LOGIN_MESSAGE, interval)); LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT); - if (player.isInsideVehicle() && player.getVehicle() != null) + if (player.isInsideVehicle() && player.getVehicle() != null) { player.getVehicle().eject(); - if (Settings.applyBlindEffect) - player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, Settings.getRegistrationTimeout * 20, 2)); + } + if (Settings.applyBlindEffect) { + player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeOut, 2)); + } player.setOp(false); restoreSpeedEffect(); // Player is now logout... Time to fire event ! Bukkit.getServer().getPluginManager().callEvent(new LogoutEvent(player)); - if (Settings.bungee) + if (Settings.bungee) { sendBungeeMessage(); + } m.send(player, MessageKey.LOGOUT_SUCCESS); ConsoleLogger.info(player.getName() + " logged out"); } diff --git a/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java b/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java index 00b47744..adf08d06 100644 --- a/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java +++ b/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java @@ -7,32 +7,23 @@ import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.Utils; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitTask; -/** - */ public class AsynchronousQuit { - protected final AuthMe plugin; - protected final DataSource database; - protected final Player player; + private final AuthMe plugin; + private final DataSource database; + private final Player player; private final String name; private boolean isOp = false; private boolean needToChange = false; private boolean isKick = false; - /** - * Constructor for AsynchronousQuit. - * - * @param p Player - * @param plugin AuthMe - * @param database DataSource - * @param isKick boolean - */ public AsynchronousQuit(Player p, AuthMe plugin, DataSource database, boolean isKick) { this.player = p; @@ -43,9 +34,7 @@ public class AsynchronousQuit { } public void process() { - if (player == null) - return; - if (Utils.isUnrestricted(player)) { + if (player == null || Utils.isUnrestricted(player)) { return; } @@ -54,7 +43,9 @@ public class AsynchronousQuit { if (PlayerCache.getInstance().isAuthenticated(name)) { if (Settings.isSaveQuitLocationEnabled) { Location loc = player.getLocation(); - PlayerAuth auth = new PlayerAuth(name, loc.getX(), loc.getY(), loc.getZ(), loc.getWorld().getName(), player.getName()); + PlayerAuth auth = PlayerAuth.builder() + .name(name).location(loc) + .realName(player.getName()).build(); database.updateQuitLoc(auth); } PlayerAuth auth = new PlayerAuth(name, ip, System.currentTimeMillis(), player.getName()); @@ -63,14 +54,11 @@ public class AsynchronousQuit { LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name); if (limbo != null) { - if (limbo.getGroup() != null && !limbo.getGroup().isEmpty()) + if (!StringUtils.isEmpty(limbo.getGroup())) { Utils.addNormal(player, limbo.getGroup()); + } needToChange = true; isOp = limbo.getOperator(); - if (limbo.getTimeoutTaskId() != null) - limbo.getTimeoutTaskId().cancel(); - if (limbo.getMessageTaskId() != null) - limbo.getMessageTaskId().cancel(); LimboCache.getInstance().deleteLimboPlayer(name); } if (Settings.isSessionsEnabled && !isKick) { @@ -104,8 +92,7 @@ public class AsynchronousQuit { private void postLogout() { PlayerCache.getInstance().removePlayer(name); - if (database.isLogged(name)) - database.setUnlogged(name); + database.setUnlogged(name); plugin.sessions.remove(name); } } 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 4d8dcf9e..47264c0f 100644 --- a/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java @@ -52,14 +52,13 @@ public class ProcessSyncEmailRegister implements Runnable { int msgInterval = Settings.getWarnMessageInterval; BukkitScheduler sched = plugin.getServer().getScheduler(); - if (time != 0 && limbo != null) { - limbo.getTimeoutTaskId().cancel(); - BukkitTask id = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), time); - limbo.setTimeoutTaskId(id); - } + if (limbo != null) { - limbo.getMessageTaskId().cancel(); - BukkitTask nwMsg = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, m.retrieve(MessageKey.LOGIN_MESSAGE), msgInterval)); + if (time != 0) { + BukkitTask id = sched.runTaskLater(plugin, new TimeoutTask(plugin, name, player), time); + limbo.setTimeoutTaskId(id); + } + BukkitTask nwMsg = sched.runTask(plugin, new MessageTask(plugin, name, m.retrieve(MessageKey.LOGIN_MESSAGE), msgInterval)); limbo.setMessageTaskId(nwMsg); } diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java b/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java index 60f5bc18..9f9f8919 100644 --- a/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java @@ -1,16 +1,7 @@ package fr.xephi.authme.process.register; -import fr.xephi.authme.settings.NewSetting; -import fr.xephi.authme.settings.properties.HooksSettings; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitScheduler; -import org.bukkit.scheduler.BukkitTask; - import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; - import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.limbo.LimboCache; @@ -19,10 +10,17 @@ import fr.xephi.authme.events.LoginEvent; import fr.xephi.authme.events.RestoreInventoryEvent; import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.Messages; +import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.TimeoutTask; import fr.xephi.authme.util.Utils; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.scheduler.BukkitTask; /** */ @@ -37,8 +35,8 @@ public class ProcessSyncPasswordRegister implements Runnable { /** * Constructor for ProcessSyncPasswordRegister. * - * @param player Player - * @param plugin AuthMe + * @param player Player + * @param plugin AuthMe * @param settings The plugin settings */ public ProcessSyncPasswordRegister(Player player, AuthMe plugin, NewSetting settings) { @@ -77,11 +75,10 @@ public class ProcessSyncPasswordRegister implements Runnable { BukkitScheduler sched = plugin.getServer().getScheduler(); BukkitTask task; if (delay != 0) { - task = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), delay); + task = sched.runTaskLater(plugin, new TimeoutTask(plugin, name, player), delay); cache.getLimboPlayer(name).setTimeoutTaskId(task); } - task = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, - m.retrieve(MessageKey.LOGIN_MESSAGE), interval)); + task = sched.runTask(plugin, new MessageTask(plugin, name, MessageKey.LOGIN_MESSAGE, interval)); cache.getLimboPlayer(name).setMessageTaskId(task); if (player.isInsideVehicle() && player.getVehicle() != null) { player.getVehicle().eject(); @@ -158,7 +155,7 @@ public class ProcessSyncPasswordRegister implements Runnable { // Register is now finished; we can force all commands forceCommands(); - + sendTo(); } 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 58c17694..7da80c39 100644 --- a/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java +++ b/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java @@ -73,12 +73,11 @@ public class AsynchronousUnregister { int interval = Settings.getWarnMessageInterval; BukkitScheduler scheduler = plugin.getServer().getScheduler(); if (timeOut != 0) { - BukkitTask id = scheduler.runTaskLaterAsynchronously(plugin, - new TimeoutTask(plugin, name, player), timeOut); + BukkitTask id = scheduler.runTaskLater(plugin, new TimeoutTask(plugin, name, player), timeOut); limboPlayer.setTimeoutTaskId(id); } - limboPlayer.setMessageTaskId(scheduler.runTaskAsynchronously(plugin, - new MessageTask(plugin, name, m.retrieve(MessageKey.REGISTER_MESSAGE), interval))); + limboPlayer.setMessageTaskId(scheduler.runTask(plugin, + new MessageTask(plugin, name, MessageKey.REGISTER_MESSAGE, interval))); m.send(player, MessageKey.UNREGISTERED_SUCCESS); ConsoleLogger.info(player.getDisplayName() + " unregistered himself"); return; diff --git a/src/main/java/fr/xephi/authme/task/MessageTask.java b/src/main/java/fr/xephi/authme/task/MessageTask.java index cfaa7d4a..92310f37 100644 --- a/src/main/java/fr/xephi/authme/task/MessageTask.java +++ b/src/main/java/fr/xephi/authme/task/MessageTask.java @@ -3,6 +3,7 @@ package fr.xephi.authme.task; import fr.xephi.authme.AuthMe; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.limbo.LimboCache; +import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.util.Utils; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitTask; @@ -24,32 +25,31 @@ public class MessageTask implements Runnable { * @param strings String[] * @param interval int */ - public MessageTask(AuthMe plugin, String name, String[] strings, - int interval) { + public MessageTask(AuthMe plugin, String name, String[] strings, int interval) { this.plugin = plugin; this.name = name; this.msg = strings; this.interval = interval; } - /** - * Method run. - * - * @see java.lang.Runnable#run() - */ + public MessageTask(AuthMe plugin, String name, MessageKey messageKey, int interval) { + this(plugin, name, plugin.getMessages().retrieve(messageKey), interval); + } + @Override public void run() { - if (PlayerCache.getInstance().isAuthenticated(name)) + if (PlayerCache.getInstance().isAuthenticated(name)) { return; + } for (Player player : Utils.getOnlinePlayers()) { - if (player.getName().toLowerCase().equals(name)) { + if (player.getName().equalsIgnoreCase(name)) { for (String ms : msg) { player.sendMessage(ms); } - BukkitTask late = plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, this, interval * 20); + BukkitTask nextTask = plugin.getServer().getScheduler().runTaskLater(plugin, this, interval * 20); if (LimboCache.getInstance().hasLimboPlayer(name)) { - LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(late); + LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(nextTask); } return; } diff --git a/src/main/java/fr/xephi/authme/task/TimeoutTask.java b/src/main/java/fr/xephi/authme/task/TimeoutTask.java index eedf0875..b304632d 100644 --- a/src/main/java/fr/xephi/authme/task/TimeoutTask.java +++ b/src/main/java/fr/xephi/authme/task/TimeoutTask.java @@ -4,14 +4,10 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.Messages; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -/** - */ public class TimeoutTask implements Runnable { - private final AuthMe plugin; private final String name; private final Messages m; private final Player player; @@ -25,38 +21,14 @@ public class TimeoutTask implements Runnable { */ public TimeoutTask(AuthMe plugin, String name, Player player) { this.m = plugin.getMessages(); - this.plugin = plugin; this.name = name; this.player = player; } - /** - * Method getName. - * - * @return String - */ - public String getName() { - return name; - } - - /** - * Method run. - * - * @see java.lang.Runnable#run() - */ @Override public void run() { - if (PlayerCache.getInstance().isAuthenticated(name)) { - return; + if (!PlayerCache.getInstance().isAuthenticated(name)) { + player.kickPlayer(m.retrieveSingle(MessageKey.LOGIN_TIMEOUT_ERROR)); } - - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { - @Override - public void run() { - if (player.isOnline()) { - player.kickPlayer(m.retrieveSingle(MessageKey.LOGIN_TIMEOUT_ERROR)); - } - } - }); } } From 3d90d478c2724a60eb9c98c5467b76600eafc404 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Mon, 22 Feb 2016 22:16:14 +0700 Subject: [PATCH 03/46] remove uuid, only use player's name. --- .../xephi/authme/cache/backup/JsonCache.java | 50 ++++++------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/src/main/java/fr/xephi/authme/cache/backup/JsonCache.java b/src/main/java/fr/xephi/authme/cache/backup/JsonCache.java index 91d6482d..177ccce5 100644 --- a/src/main/java/fr/xephi/authme/cache/backup/JsonCache.java +++ b/src/main/java/fr/xephi/authme/cache/backup/JsonCache.java @@ -8,7 +8,6 @@ import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; import fr.xephi.authme.ConsoleLogger; @@ -41,14 +40,8 @@ public class JsonCache { return; } - String path; - try { - path = player.getUniqueId().toString(); - } catch (Exception | Error e) { - path = player.getName().toLowerCase(); - } - - File file = new File(cacheDir, path + File.separator + "cache.json"); + String name = player.getName().toLowerCase(); + File file = new File(cacheDir, name + File.separator + "cache.json"); if (file.exists()) { return; } @@ -61,19 +54,13 @@ public class JsonCache { Files.touch(file); Files.write(data, file, Charsets.UTF_8); } catch (IOException e) { - e.printStackTrace(); + ConsoleLogger.writeStackTrace(e); } } public PlayerData readCache(Player player) { - String path; - try { - path = player.getUniqueId().toString(); - } catch (Exception | Error e) { - path = player.getName().toLowerCase(); - } - - File file = new File(cacheDir, path + File.separator + "cache.json"); + String name = player.getName().toLowerCase(); + File file = new File(cacheDir, name + File.separator + "cache.json"); if (!file.exists()) { return null; } @@ -81,20 +68,15 @@ public class JsonCache { try { String str = Files.toString(file, Charsets.UTF_8); return gson.fromJson(str, PlayerData.class); - } catch (Exception e) { - e.printStackTrace(); + } catch (IOException e) { + ConsoleLogger.writeStackTrace(e); return null; } } public void removeCache(Player player) { - String path; - try { - path = player.getUniqueId().toString(); - } catch (Exception | Error e) { - path = player.getName().toLowerCase(); - } - File file = new File(cacheDir, path); + String name = player.getName().toLowerCase(); + File file = new File(cacheDir, name); if (file.exists()) { purgeDirectory(file); if (!file.delete()) { @@ -104,19 +86,15 @@ public class JsonCache { } public boolean doesCacheExist(Player player) { - String path; - try { - path = player.getUniqueId().toString(); - } catch (Exception | Error e) { - path = player.getName().toLowerCase(); - } - File file = new File(cacheDir, path + File.separator + "cache.json"); + String name = player.getName().toLowerCase(); + File file = new File(cacheDir, name + File.separator + "cache.json"); return file.exists(); } private class PlayerDataDeserializer implements JsonDeserializer { @Override - public PlayerData deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + public PlayerData deserialize(JsonElement jsonElement, Type type, + JsonDeserializationContext context) { JsonObject jsonObject = jsonElement.getAsJsonObject(); if (jsonObject == null) { return null; @@ -143,7 +121,7 @@ public class JsonCache { private class PlayerDataSerializer implements JsonSerializer { @Override public JsonElement serialize(PlayerData playerData, Type type, - JsonSerializationContext jsonSerializationContext) { + JsonSerializationContext context) { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("group", playerData.getGroup()); jsonObject.addProperty("operator", playerData.getOperator()); From ed0ed2faf7320abc49a4d51b227f8840de551255 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Mon, 22 Feb 2016 22:26:10 +0700 Subject: [PATCH 04/46] Bring back @games647 solution. --- src/main/java/fr/xephi/authme/AuthMe.java | 38 +++++++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 71b12610..d2e18839 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -77,6 +77,7 @@ import org.bukkit.scheduler.BukkitTask; import java.io.File; import java.io.IOException; import java.net.URL; +import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; @@ -496,11 +497,41 @@ public class AuthMe extends JavaPlugin { if (newSettings != null) { new PerformBackup(plugin, newSettings).doBackup(PerformBackup.BackupCause.STOP); } + new Thread(new Runnable() { + @Override + public void run() { + List pendingTasks = new ArrayList<>(); + for (BukkitTask pendingTask : getServer().getScheduler().getPendingTasks()) { + if (pendingTask.getOwner().equals(plugin) && !pendingTask.isSync()) { + pendingTasks.add(pendingTask.getTaskId()); + } + } + ConsoleLogger.info("Waiting for " + pendingTasks.size() + " tasks to finish"); + int progress = 0; + for (int taskId : pendingTasks) { + int maxTries = 5; + while (getServer().getScheduler().isCurrentlyRunning(taskId)) { + if (maxTries <= 0) { + ConsoleLogger.info("Async task " + taskId + " times out after to many tries"); + break; + } + try { + Thread.sleep(1000); + } catch (InterruptedException ignored) { + } + maxTries--; + } + + progress++; + ConsoleLogger.info("Progress: " + progress + " / " + pendingTasks.size()); + } + if (database != null) { + database.close(); + } + } + }, "AuthMe-DataSource#close").start(); // Close the database - if (database != null) { - database.close(); - } // Disabled correctly ConsoleLogger.info("AuthMe " + this.getDescription().getVersion() + " disabled!"); @@ -666,6 +697,7 @@ public class AuthMe extends JavaPlugin { ConsoleLogger.showError("WARNING! The protectInventory feature requires ProtocolLib! Disabling it..."); Settings.protectInventoryBeforeLogInEnabled = false; newSettings.setProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN, false); + newSettings.save(); } return; } From 8536f853614c0752ca9ae6ac72bd15843861d432 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Thu, 25 Feb 2016 16:45:35 +0700 Subject: [PATCH 05/46] Fix #558 --- src/main/java/fr/xephi/authme/AuthMe.java | 39 +++++++++++------------ 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index bdc1b73e..6cfa943d 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -104,15 +104,14 @@ public class AuthMe extends JavaPlugin { // Private Instances private static AuthMe plugin; private static Server server; - private Management management; - private CommandHandler commandHandler = null; - private PermissionsManager permsMan = null; - private NewSetting newSettings; - private Messages messages; - private JsonCache playerBackup; - private PasswordSecurity passwordSecurity; - private DataSource database; - + /* + * Maps and stuff + * TODO: Clean up and Move into a manager + */ + public final ConcurrentHashMap sessions = new ConcurrentHashMap<>(); + public final ConcurrentHashMap captcha = new ConcurrentHashMap<>(); + public final ConcurrentHashMap cap = new ConcurrentHashMap<>(); + public final ConcurrentHashMap realIp = new ConcurrentHashMap<>(); /* * Public Instances * TODO #432: Encapsulation @@ -122,7 +121,6 @@ public class AuthMe extends JavaPlugin { public DataManager dataManager; public OtherAccounts otherAccounts; public Location essentialsSpawn; - /* * Plugin Hooks * TODO: Move into modules @@ -133,15 +131,14 @@ public class AuthMe extends JavaPlugin { public AuthMeInventoryPacketAdapter inventoryProtector; public AuthMeTabCompletePacketAdapter tabComplete; public AuthMeTablistPacketAdapter tablistHider; - - /* - * Maps and stuff - * TODO: Clean up and Move into a manager - */ - public final ConcurrentHashMap sessions = new ConcurrentHashMap<>(); - public final ConcurrentHashMap captcha = new ConcurrentHashMap<>(); - public final ConcurrentHashMap cap = new ConcurrentHashMap<>(); - public final ConcurrentHashMap realIp = new ConcurrentHashMap<>(); + private Management management; + private CommandHandler commandHandler = null; + private PermissionsManager permsMan = null; + private NewSetting newSettings; + private Messages messages; + private JsonCache playerBackup; + private PasswordSecurity passwordSecurity; + private DataSource database; /** * Get the plugin's instance. @@ -667,14 +664,14 @@ public class AuthMe extends JavaPlugin { if (newSettings.getProperty(RestrictionSettings.DENY_TABCOMPLETE_BEFORE_LOGIN) && tabComplete == null) { tabComplete = new AuthMeTabCompletePacketAdapter(this); tabComplete.register(); - } else if (inventoryProtector != null) { + } else if (tabComplete != null) { tabComplete.unregister(); tabComplete = null; } if (newSettings.getProperty(RestrictionSettings.HIDE_TABLIST_BEFORE_LOGIN) && tablistHider == null) { tablistHider = new AuthMeTablistPacketAdapter(this); tablistHider.register(); - } else if (inventoryProtector != null) { + } else if (tablistHider != null) { tablistHider.unregister(); tablistHider = null; } From 775e2f703952f9ace98e14a81d9fe944b3827681 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Fri, 26 Feb 2016 11:37:47 +0700 Subject: [PATCH 06/46] Async refresh. --- .../authme/datasource/CacheDataSource.java | 56 ++++++++++++------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java index 45b25b9a..0d8fc542 100644 --- a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java +++ b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java @@ -4,14 +4,19 @@ import com.google.common.base.Optional; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; -import com.google.common.cache.RemovalListener; -import com.google.common.cache.RemovalNotification; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.security.crypts.HashedPassword; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** @@ -20,6 +25,7 @@ public class CacheDataSource implements DataSource { private final DataSource source; private final LoadingCache> cachedAuths; + private final ListeningExecutorService executorService; /** * Constructor for CacheDataSource. @@ -27,25 +33,31 @@ public class CacheDataSource implements DataSource { * @param src DataSource */ public CacheDataSource(DataSource src) { - this.source = src; - this.cachedAuths = CacheBuilder.newBuilder() - .expireAfterWrite(8, TimeUnit.MINUTES) - .removalListener(new RemovalListener>() { + source = src; + executorService = MoreExecutors.listeningDecorator( + Executors.newCachedThreadPool(new ThreadFactoryBuilder() + .setDaemon(true) + .setNameFormat("AuthMe-CacheLoader") + .build()) + ); + cachedAuths = CacheBuilder.newBuilder() + .refreshAfterWrite(8, TimeUnit.MINUTES) + .build(new CacheLoader>() { @Override - public void onRemoval(RemovalNotification> removalNotification) { - String name = removalNotification.getKey(); - if (PlayerCache.getInstance().isAuthenticated(name)) { - cachedAuths.getUnchecked(name); - } + public Optional load(String key) { + return Optional.fromNullable(source.getAuth(key)); } - }) - .build( - new CacheLoader>() { - @Override - public Optional load(String key) { - return Optional.fromNullable(source.getAuth(key)); - } - }); + + @Override + public ListenableFuture> reload(final String key, Optional oldValue) { + return executorService.submit(new Callable>() { + @Override + public Optional call() { + return load(key); + } + }); + } + }); } @Override @@ -138,6 +150,12 @@ public class CacheDataSource implements DataSource { public synchronized void close() { source.close(); cachedAuths.invalidateAll(); + executorService.shutdown(); + try { + executorService.awaitTermination(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + ConsoleLogger.writeStackTrace(e); + } } @Override From 1b65b285ace7ecc1096cf4cdcf98548d4b7e22dc Mon Sep 17 00:00:00 2001 From: DNx5 Date: Fri, 26 Feb 2016 12:00:53 +0700 Subject: [PATCH 07/46] improve spawn location check. --- .../authme/settings/CustomConfiguration.java | 9 +++++ .../java/fr/xephi/authme/settings/Spawn.java | 37 +++++++++---------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/main/java/fr/xephi/authme/settings/CustomConfiguration.java b/src/main/java/fr/xephi/authme/settings/CustomConfiguration.java index ee164525..3defffe4 100644 --- a/src/main/java/fr/xephi/authme/settings/CustomConfiguration.java +++ b/src/main/java/fr/xephi/authme/settings/CustomConfiguration.java @@ -82,4 +82,13 @@ public abstract class CustomConfiguration extends YamlConfiguration { } return false; } + + public boolean containsAll(String... paths) { + for (String path : paths) { + if (!contains(path)) { + return false; + } + } + return true; + } } diff --git a/src/main/java/fr/xephi/authme/settings/Spawn.java b/src/main/java/fr/xephi/authme/settings/Spawn.java index 85f20401..e891e47f 100644 --- a/src/main/java/fr/xephi/authme/settings/Spawn.java +++ b/src/main/java/fr/xephi/authme/settings/Spawn.java @@ -2,7 +2,6 @@ package fr.xephi.authme.settings; import com.onarandombox.MultiverseCore.api.MVWorldManager; import fr.xephi.authme.AuthMe; -import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.util.StringUtils; import org.bukkit.Bukkit; @@ -73,34 +72,32 @@ public class Spawn extends CustomConfiguration { } public Location getSpawn() { - try { + if (containsAll("spawn.world", "spawn.x", "spawn.y", "spawn.z", "spawn.yaw", "spawn.pitch")) { String worldName = getString("spawn.world"); World world = Bukkit.getWorld(worldName); - if (StringUtils.isEmpty(worldName) || world == null) { - return null; + if (!StringUtils.isEmpty(worldName) && world != null) { + return new Location( + world, getDouble("spawn.x"), getDouble("spawn.y"), getDouble("spawn.z"), + Float.parseFloat(getString("spawn.yaw")), Float.parseFloat(getString("spawn.pitch")) + ); } - return new Location(world, getDouble("spawn.x"), getDouble("spawn.y"), getDouble("spawn.z"), - Float.parseFloat(getString("spawn.yaw")), Float.parseFloat(getString("spawn.pitch"))); - } catch (NumberFormatException e) { - ConsoleLogger.writeStackTrace(e); - return null; } + return null; } public Location getFirstSpawn() { - try { - String worldName; - World world; - if (StringUtils.isEmpty(worldName = getString("firstspawn.world")) || - (world = Bukkit.getWorld(worldName)) == null) { - return null; + if (containsAll("firstspawn.world", "firstspawn.x", "firstspawn.y", + "firstspawn.z", "firstspawn.yaw", "firstspawn.pitch")) { + String worldName = getString("firstspawn.world"); + World world = Bukkit.getWorld(worldName); + if (!StringUtils.isEmpty(worldName) && world != null) { + return new Location( + world, getDouble("firstspawn.x"), getDouble("firstspawn.y"), getDouble("firstspawn.z"), + Float.parseFloat(getString("firstspawn.yaw")), Float.parseFloat(getString("firstspawn.pitch")) + ); } - return new Location(world, getDouble("firstspawn.x"), getDouble("firstspawn.y"), getDouble("firstspawn.z"), - Float.parseFloat(getString("firstspawn.yaw")), Float.parseFloat(getString("firstspawn.pitch"))); - } catch (NumberFormatException e) { - ConsoleLogger.writeStackTrace(e); - return null; } + return null; } // Return the spawn location of a player From 8bf6817a5f5b33119073253508c20d6ddda8f8b5 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Fri, 26 Feb 2016 12:47:08 +0700 Subject: [PATCH 08/46] Removed unused private methods in AuthMe class. --- src/main/java/fr/xephi/authme/AuthMe.java | 38 +---------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 5ae716f5..622ceafe 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -64,7 +64,6 @@ import org.apache.logging.log4j.LogManager; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Server; -import org.bukkit.World; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -546,6 +545,7 @@ public class AuthMe extends JavaPlugin { * Sets up the data source. * * @param settings The settings instance + * * @see AuthMe#database */ public void setupDatabase(NewSetting settings) throws ClassNotFoundException, SQLException { @@ -777,42 +777,6 @@ public class AuthMe extends JavaPlugin { return Spawn.getInstance().getSpawnLocation(player); } - // Return the default spawn point of a world - private Location getDefaultSpawn(World world) { - return world.getSpawnLocation(); - } - - // Return the multiverse spawn point of a world - private Location getMultiverseSpawn(World world) { - if (multiverse != null && Settings.multiverse) { - try { - return multiverse.getMVWorldManager().getMVWorld(world).getSpawnLocation(); - } catch (Exception e) { - e.printStackTrace(); - } - } - return null; - } - - // Return the essentials spawn point - private Location getEssentialsSpawn() { - if (essentialsSpawn != null) { - return essentialsSpawn; - } - return null; - } - - // Return the AuthMe spawn point - private Location getAuthMeSpawn(Player player) { - if ((!database.isAuthAvailable(player.getName().toLowerCase()) || !player.hasPlayedBefore()) - && (Spawn.getInstance().getFirstSpawn() != null)) { - return Spawn.getInstance().getFirstSpawn(); - } else if (Spawn.getInstance().getSpawn() != null) { - return Spawn.getInstance().getSpawn(); - } - return player.getWorld().getSpawnLocation(); - } - private void scheduleRecallEmailTask() { if (!newSettings.getProperty(RECALL_PLAYERS)) { return; From b4aebb685cf5ab3b2e59a633e3bc8717e2025958 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Fri, 26 Feb 2016 13:10:49 +0700 Subject: [PATCH 09/46] Remove player from cache on quit. --- .../java/fr/xephi/authme/datasource/CacheDataSource.java | 4 ++++ .../java/fr/xephi/authme/process/quit/AsynchronousQuit.java | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java index 1aaf6c00..37695516 100644 --- a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java +++ b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java @@ -60,6 +60,10 @@ public class CacheDataSource implements DataSource { }); } + public LoadingCache> getCachedAuths() { + return cachedAuths; + } + @Override public synchronized boolean isAuthAvailable(String user) { return getAuth(user) != null; diff --git a/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java b/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java index adf08d06..7f716e7e 100644 --- a/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java +++ b/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java @@ -5,6 +5,7 @@ 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.datasource.CacheDataSource; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.StringUtils; @@ -88,6 +89,10 @@ public class AsynchronousQuit { if (plugin.isEnabled()) { Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new ProcessSyncronousPlayerQuit(plugin, player, isOp, needToChange)); } + // remove player from cache + if (database instanceof CacheDataSource) { + ((CacheDataSource) database).getCachedAuths().invalidate(name); + } } private void postLogout() { From 3f3b1cfde5f1596ca8bdfe5cea0022af67afc3d4 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Fri, 26 Feb 2016 15:31:14 +0100 Subject: [PATCH 10/46] Fix EssentialsX dependency --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 94c8b48e..1df2f97b 100644 --- a/pom.xml +++ b/pom.xml @@ -668,7 +668,7 @@ net.ess3 EssentialsX - 2.0.1-SNAPSHOT + 2.0.1 provided From 6d8e9d413f7e4e92974f2a1a409d26e13e95c406 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Fri, 26 Feb 2016 15:42:54 +0100 Subject: [PATCH 11/46] Switch to Essentials due to issues with the EssentialsX repo --- pom.xml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 1df2f97b..82dfd0b4 100644 --- a/pom.xml +++ b/pom.xml @@ -305,10 +305,10 @@ https://hub.spigotmc.org/nexus/content/repositories/snapshots - + ess-repo - http://ci.drtshock.net/plugin/repository/everything + http://repo.ess3.net/content/groups/essentials @@ -664,16 +664,20 @@ true - + net.ess3 - EssentialsX - 2.0.1 + Essentials + 2.13-SNAPSHOT provided - org.spigotmc - spigot-api + org.bukkit + bukkit + + + org.bukkit + craftbukkit true From 27b1fa770fab90f619801a6bce2547b0935f0116 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Fri, 26 Feb 2016 22:12:16 +0100 Subject: [PATCH 12/46] #392 Add datasource integration tests --- .../authme/datasource/CacheDataSource.java | 6 -- .../xephi/authme/datasource/DataSource.java | 8 -- .../fr/xephi/authme/datasource/FlatFile.java | 8 -- .../fr/xephi/authme/datasource/MySQL.java | 14 +-- .../fr/xephi/authme/datasource/SQLite.java | 15 --- .../AbstractDataSourceIntegrationTest.java | 91 +++++++++++++++++++ 6 files changed, 93 insertions(+), 49 deletions(-) diff --git a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java index 37695516..ad02c99f 100644 --- a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java +++ b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java @@ -224,12 +224,6 @@ public class CacheDataSource implements DataSource { return source.getAccountsRegistered(); } - @Override - public void updateName(final String oldOne, final String newOne) { // unused method - source.updateName(oldOne, newOne); - cachedAuths.invalidate(oldOne); - } - @Override public boolean updateRealName(String user, String realName) { boolean result = source.updateRealName(user, realName); diff --git a/src/main/java/fr/xephi/authme/datasource/DataSource.java b/src/main/java/fr/xephi/authme/datasource/DataSource.java index becccb6a..6e3bc09b 100644 --- a/src/main/java/fr/xephi/authme/datasource/DataSource.java +++ b/src/main/java/fr/xephi/authme/datasource/DataSource.java @@ -169,14 +169,6 @@ public interface DataSource { */ int getAccountsRegistered(); - /** - * Method updateName. - * - * @param oldOne String - * @param newOne String - */ - void updateName(String oldOne, String newOne); - boolean updateRealName(String user, String realName); boolean updateIp(String user, String ip); diff --git a/src/main/java/fr/xephi/authme/datasource/FlatFile.java b/src/main/java/fr/xephi/authme/datasource/FlatFile.java index 7c4a92d4..c52d8e73 100644 --- a/src/main/java/fr/xephi/authme/datasource/FlatFile.java +++ b/src/main/java/fr/xephi/authme/datasource/FlatFile.java @@ -599,14 +599,6 @@ public class FlatFile implements DataSource { return result; } - @Override - public void updateName(String oldOne, String newOne) { - PlayerAuth auth = this.getAuth(oldOne); - auth.setNickname(newOne); - this.saveAuth(auth); - this.removeAuth(oldOne); - } - @Override public boolean updateRealName(String user, String realName) { return false; diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java index e7d5c565..1ab37d5e 100644 --- a/src/main/java/fr/xephi/authme/datasource/MySQL.java +++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java @@ -1,5 +1,6 @@ package fr.xephi.authme.datasource; +import com.google.common.annotations.VisibleForTesting; import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.pool.HikariPool.PoolInitializationException; import fr.xephi.authme.AuthMe; @@ -81,6 +82,7 @@ public class MySQL implements DataSource { } } + @VisibleForTesting MySQL(NewSetting settings, HikariDataSource hikariDataSource) { this.host = settings.getProperty(DatabaseSettings.MYSQL_HOST); this.port = settings.getProperty(DatabaseSettings.MYSQL_PORT); @@ -817,18 +819,6 @@ public class MySQL implements DataSource { return result; } - @Override - public void updateName(String oldOne, String newOne) { - String sql = "UPDATE " + tableName + " SET " + col.NAME + "=? WHERE " + col.NAME + "=?;"; - try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) { - pst.setString(1, newOne); - pst.setString(2, oldOne); - pst.executeUpdate(); - } catch (SQLException ex) { - logSqlException(ex); - } - } - @Override public boolean updateRealName(String user, String realName) { String sql = "UPDATE " + tableName + " SET " + col.REAL_NAME + "=? WHERE " + col.NAME + "=?;"; diff --git a/src/main/java/fr/xephi/authme/datasource/SQLite.java b/src/main/java/fr/xephi/authme/datasource/SQLite.java index f7f18b32..d0c39e15 100644 --- a/src/main/java/fr/xephi/authme/datasource/SQLite.java +++ b/src/main/java/fr/xephi/authme/datasource/SQLite.java @@ -523,21 +523,6 @@ public class SQLite implements DataSource { return 0; } - @Override - public void updateName(String oldOne, String newOne) { - PreparedStatement pst = null; - try { - pst = con.prepareStatement("UPDATE " + tableName + " SET " + col.NAME + "=? WHERE " + col.NAME + "=?;"); - pst.setString(1, newOne); - pst.setString(2, oldOne); - pst.executeUpdate(); - } catch (SQLException ex) { - logSqlException(ex); - } finally { - close(pst); - } - } - @Override public boolean updateRealName(String user, String realName) { String sql = "UPDATE " + tableName + " SET " + col.REAL_NAME + "=? WHERE " + col.NAME + "=?;"; diff --git a/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java b/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java index dfd6f825..abe1d521 100644 --- a/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java @@ -4,15 +4,18 @@ import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.security.crypts.HashedPassword; import org.junit.Test; +import java.util.Arrays; import java.util.List; import static fr.xephi.authme.datasource.AuthMeMatchers.equalToHash; import static fr.xephi.authme.datasource.AuthMeMatchers.hasAuthBasicData; import static fr.xephi.authme.datasource.AuthMeMatchers.hasAuthLocation; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; +import static org.junit.Assume.assumeThat; /** * Abstract class for data source integration tests. @@ -201,4 +204,92 @@ public abstract class AbstractDataSourceIntegrationTest { assertThat(dataSource.getAuth("user"), hasAuthLocation(143, -42.12, 29.47, "the_end")); } + @Test + public void shouldDeletePlayers() { + // given + DataSource dataSource = getDataSource(); + List playersToDelete = Arrays.asList("bobby", "doesNotExist"); + assumeThat(dataSource.getAccountsRegistered(), equalTo(2)); + + // when + dataSource.purgeBanned(playersToDelete); + + // then + assertThat(dataSource.getAccountsRegistered(), equalTo(1)); + assertThat(dataSource.isAuthAvailable("bobby"), equalTo(false)); + assertThat(dataSource.isAuthAvailable("user"), equalTo(true)); + } + + @Test + public void shouldUpdateEmail() { + // given + DataSource dataSource = getDataSource(); + String email = "new-user@mail.tld"; + PlayerAuth userAuth = PlayerAuth.builder().name("user").email(email).build(); + PlayerAuth invalidAuth = PlayerAuth.builder().name("invalid").email("addr@example.com").build(); + + // when + boolean response1 = dataSource.updateEmail(userAuth); + boolean response2 = dataSource.updateEmail(invalidAuth); + + // then + assertThat(response1 && response2, equalTo(true)); + assertThat(dataSource.getAllAuths(), hasItem(hasAuthBasicData("user", "user", email, "34.56.78.90"))); + } + + @Test + public void shouldUpdateIp() { + // given + DataSource dataSource = getDataSource(); + String ip = "250.230.67.73"; + + // when + boolean response1 = dataSource.updateIp("bobby", ip); + boolean response2 = dataSource.updateIp("bogus", "123.123.123.123"); + + + // then + assertThat(response1 && response2, equalTo(true)); + assertThat(dataSource.getAllAuths(), hasItem(hasAuthBasicData("bobby", "Bobby", "your@email.com", ip))); + } + + @Test + public void shouldCountAuths() { + // given + DataSource dataSource = getDataSource(); + + // when + int initialCount = dataSource.getAccountsRegistered(); + for (int i = 0; i < 4; ++i) { + dataSource.saveAuth(PlayerAuth.builder().name("test-" + i).build()); + } + int endCount = dataSource.getAccountsRegistered(); + + // then + assertThat(initialCount, equalTo(2)); + assertThat(endCount, equalTo(6)); + } + + @Test + public void shouldGetAllUsersByIp() { + // given + DataSource dataSource = getDataSource(); + + // when + List initialList = dataSource.getAllAuthsByIp("123.45.67.89"); + List emptyList = dataSource.getAllAuthsByIp("8.8.8.8"); + for (int i = 0; i < 3; ++i) { + dataSource.saveAuth(PlayerAuth.builder().name("test-" + i).ip("123.45.67.89").build()); + } + List updatedList = dataSource.getAllAuthsByIp("123.45.67.89"); + + // then + assertThat(initialList, hasSize(1)); + assertThat(initialList.get(0), equalTo("bobby")); + assertThat(emptyList, hasSize(0)); + assertThat(updatedList, hasSize(4)); + assertThat(updatedList, hasItem(equalTo("bobby"))); + assertThat(updatedList, hasItem(equalTo("test-1"))); + } + } From 1b818bd8332a8f295a11acda83aceea0a2329819 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 27 Feb 2016 11:24:47 +0100 Subject: [PATCH 13/46] #457 Improve ForceFlatToSqlite conversion - Change ForceFlatToSqlite converter to use a generic datasource destination (i.e. can be used for Flat2MySQL later) - Add tests, including for FlatFile - Check that user is not present in destination datasource before adding - Persist last location from flatfile as well --- .../authme/converter/ForceFlatToSqlite.java | 60 ++++++----- .../fr/xephi/authme/datasource/FlatFile.java | 53 +++++----- .../xephi/authme/util/MigrationService.java | 19 ++-- .../{datasource => }/AuthMeMatchers.java | 2 +- .../converter/ForceFlatToSqliteTest.java | 72 +++++++++++++ .../AbstractDataSourceIntegrationTest.java | 16 +-- .../datasource/FlatFileIntegrationTest.java | 100 ++++++++++++++++++ .../datasource-integration/flatfile-test.txt | 7 ++ 8 files changed, 259 insertions(+), 70 deletions(-) rename src/test/java/fr/xephi/authme/{datasource => }/AuthMeMatchers.java (98%) create mode 100644 src/test/java/fr/xephi/authme/converter/ForceFlatToSqliteTest.java create mode 100644 src/test/java/fr/xephi/authme/datasource/FlatFileIntegrationTest.java create mode 100644 src/test/resources/datasource-integration/flatfile-test.txt diff --git a/src/main/java/fr/xephi/authme/converter/ForceFlatToSqlite.java b/src/main/java/fr/xephi/authme/converter/ForceFlatToSqlite.java index c87297d8..7919f6a0 100644 --- a/src/main/java/fr/xephi/authme/converter/ForceFlatToSqlite.java +++ b/src/main/java/fr/xephi/authme/converter/ForceFlatToSqlite.java @@ -3,39 +3,51 @@ package fr.xephi.authme.converter; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.datasource.DataSourceType; -import fr.xephi.authme.datasource.SQLite; -import fr.xephi.authme.settings.NewSetting; -import fr.xephi.authme.settings.properties.DatabaseSettings; -import java.sql.SQLException; +import fr.xephi.authme.datasource.FlatFile; +import fr.xephi.authme.util.StringUtils; + +import java.util.ArrayList; +import java.util.List; /** * Mandatory migration from the deprecated flat file datasource to SQLite. */ -public class ForceFlatToSqlite { +public class ForceFlatToSqlite implements Converter { - private final DataSource database; - private final NewSetting settings; + private final DataSource source; + private final DataSource destination; - public ForceFlatToSqlite(DataSource database, NewSetting settings) { - this.database = database; - this.settings = settings; + /** + * Constructor. + * + * @param source The datasource to convert (flatfile) + * @param destination The datasource to copy the data to (sqlite) + */ + public ForceFlatToSqlite(FlatFile source, DataSource destination) { + this.source = source; + this.destination = destination; } - public DataSource run() { - try { - DataSource sqlite = new SQLite(settings); - for (PlayerAuth auth : database.getAllAuths()) { - auth.setRealName("Player"); - sqlite.saveAuth(auth); + /** + * Perform the conversion. + */ + @Override + public void run() { + List skippedPlayers = new ArrayList<>(); + for (PlayerAuth auth : source.getAllAuths()) { + if (destination.isAuthAvailable(auth.getNickname())) { + skippedPlayers.add(auth.getNickname()); + } else { + destination.saveAuth(auth); + destination.updateQuitLoc(auth); } - settings.setProperty(DatabaseSettings.BACKEND, DataSourceType.SQLITE); - settings.save(); - ConsoleLogger.info("Database successfully converted to sqlite!"); - return sqlite; - } catch (SQLException | ClassNotFoundException e) { - ConsoleLogger.logException("Could not convert from Flatfile to SQLite:", e); } - return null; + + if (!skippedPlayers.isEmpty()) { + ConsoleLogger.showError("Warning: skipped conversion for players which were already in SQLite: " + + StringUtils.join(", ", skippedPlayers)); + } + ConsoleLogger.info("Database successfully converted from " + source.getClass().getSimpleName() + + " to " + destination.getClass().getSimpleName()); } } diff --git a/src/main/java/fr/xephi/authme/datasource/FlatFile.java b/src/main/java/fr/xephi/authme/datasource/FlatFile.java index c52d8e73..72b30184 100644 --- a/src/main/java/fr/xephi/authme/datasource/FlatFile.java +++ b/src/main/java/fr/xephi/authme/datasource/FlatFile.java @@ -1,5 +1,6 @@ package fr.xephi.authme.datasource; +import com.google.common.annotations.VisibleForTesting; import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.auth.PlayerAuth; @@ -42,7 +43,7 @@ public class FlatFile implements DataSource { try { source.createNewFile(); } catch (IOException e) { - ConsoleLogger.showError(e.getMessage()); + ConsoleLogger.logException("Cannot open flatfile", e); if (Settings.isStopEnabled) { ConsoleLogger.showError("Can't use FLAT FILE... SHUTDOWN..."); instance.getServer().shutdown(); @@ -50,10 +51,14 @@ public class FlatFile implements DataSource { if (!Settings.isStopEnabled) { instance.getServer().getPluginManager().disablePlugin(instance); } - e.printStackTrace(); } } + @VisibleForTesting + public FlatFile(File source) { + this.source = source; + } + @Override public synchronized boolean isAuthAvailable(String user) { BufferedReader br = null; @@ -601,7 +606,7 @@ public class FlatFile implements DataSource { @Override public boolean updateRealName(String user, String realName) { - return false; + throw new UnsupportedOperationException("Flat file no longer supported"); } @Override @@ -618,33 +623,25 @@ public class FlatFile implements DataSource { String line; while ((line = br.readLine()) != null) { String[] args = line.split(":"); - switch (args.length) { - case 2: - auths.add(new PlayerAuth(args[0], args[1], "192.168.0.1", 0, "your@email.com", args[0])); - break; - case 3: - auths.add(new PlayerAuth(args[0], args[1], args[2], 0, "your@email.com", args[0])); - break; - case 4: - auths.add(new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), "your@email.com", args[0])); - break; - case 7: - auths.add(new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), Double.parseDouble(args[4]), Double.parseDouble(args[5]), Double.parseDouble(args[6]), "unavailableworld", "your@email.com", args[0])); - break; - case 8: - auths.add(new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), Double.parseDouble(args[4]), Double.parseDouble(args[5]), Double.parseDouble(args[6]), args[7], "your@email.com", args[0])); - break; - case 9: - auths.add(new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), Double.parseDouble(args[4]), Double.parseDouble(args[5]), Double.parseDouble(args[6]), args[7], args[8], args[0])); - break; + // We expect to encounter 2, 3, 4, 7, 8 or 9 fields. Ignore the line otherwise + if (args.length >= 2 && args.length != 5 && args.length != 6 && args.length <= 9) { + PlayerAuth.Builder builder = PlayerAuth.builder() + .name(args[0]).realName(args[0]) + .password(args[1], null); + if (args.length >= 3) builder.ip(args[2]); + if (args.length >= 4) builder.lastLogin(Long.parseLong(args[3])); + if (args.length >= 7) { + builder.locX(Double.parseDouble(args[4])) + .locY(Double.parseDouble(args[5])) + .locZ(Double.parseDouble(args[6])); + } + if (args.length >= 8) builder.locWorld(args[7]); + if (args.length >= 9) builder.email(args[8]); + auths.add(builder.build()); } } - } catch (FileNotFoundException ex) { - ConsoleLogger.showError(ex.getMessage()); - return auths; } catch (IOException ex) { - ConsoleLogger.showError(ex.getMessage()); - return auths; + ConsoleLogger.logException("Error while getting auths from flatfile:", ex); } finally { if (br != null) { try { @@ -658,7 +655,7 @@ public class FlatFile implements DataSource { @Override public List getLoggedPlayers() { - return new ArrayList<>(); + throw new UnsupportedOperationException("Flat file no longer supported"); } @Override diff --git a/src/main/java/fr/xephi/authme/util/MigrationService.java b/src/main/java/fr/xephi/authme/util/MigrationService.java index 6da4d95e..d4ab1533 100644 --- a/src/main/java/fr/xephi/authme/util/MigrationService.java +++ b/src/main/java/fr/xephi/authme/util/MigrationService.java @@ -5,6 +5,8 @@ import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.converter.ForceFlatToSqlite; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSourceType; +import fr.xephi.authme.datasource.FlatFile; +import fr.xephi.authme.datasource.SQLite; import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.SHA256; @@ -58,12 +60,17 @@ public final class MigrationService { if (DataSourceType.FILE == settings.getProperty(DatabaseSettings.BACKEND)) { ConsoleLogger.showError("FlatFile backend has been detected and is now deprecated; it will be changed " + "to SQLite... Connection will be impossible until conversion is done!"); - ForceFlatToSqlite converter = new ForceFlatToSqlite(dataSource, settings); - DataSource result = converter.run(); - if (result == null) { - throw new IllegalStateException("Error during conversion from flatfile to SQLite"); - } else { - return result; + FlatFile flatFile = (FlatFile) dataSource; + try { + SQLite sqlite = new SQLite(settings); + ForceFlatToSqlite converter = new ForceFlatToSqlite(flatFile, sqlite); + converter.run(); + settings.setProperty(DatabaseSettings.BACKEND, DataSourceType.SQLITE); + settings.save(); + return sqlite; + } catch (Exception e) { + ConsoleLogger.logException("Error during conversion from Flatfile to SQLite", e); + throw new IllegalStateException(e); } } return null; diff --git a/src/test/java/fr/xephi/authme/datasource/AuthMeMatchers.java b/src/test/java/fr/xephi/authme/AuthMeMatchers.java similarity index 98% rename from src/test/java/fr/xephi/authme/datasource/AuthMeMatchers.java rename to src/test/java/fr/xephi/authme/AuthMeMatchers.java index 798d5315..aed77cb1 100644 --- a/src/test/java/fr/xephi/authme/datasource/AuthMeMatchers.java +++ b/src/test/java/fr/xephi/authme/AuthMeMatchers.java @@ -1,4 +1,4 @@ -package fr.xephi.authme.datasource; +package fr.xephi.authme; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.security.crypts.HashedPassword; diff --git a/src/test/java/fr/xephi/authme/converter/ForceFlatToSqliteTest.java b/src/test/java/fr/xephi/authme/converter/ForceFlatToSqliteTest.java new file mode 100644 index 00000000..17d4fb06 --- /dev/null +++ b/src/test/java/fr/xephi/authme/converter/ForceFlatToSqliteTest.java @@ -0,0 +1,72 @@ +package fr.xephi.authme.converter; + +import com.google.common.io.Files; +import fr.xephi.authme.ConsoleLoggerTestInitializer; +import fr.xephi.authme.TestHelper; +import fr.xephi.authme.cache.auth.PlayerAuth; +import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.datasource.FlatFile; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.mockito.ArgumentCaptor; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import static fr.xephi.authme.AuthMeMatchers.hasAuthBasicData; +import static fr.xephi.authme.AuthMeMatchers.hasAuthLocation; +import static org.hamcrest.Matchers.hasItem; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** + * Test for {@link ForceFlatToSqlite}. + */ +public class ForceFlatToSqliteTest { + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + private FlatFile flatFile; + + @BeforeClass + public static void setup() { + ConsoleLoggerTestInitializer.setupLogger(); + } + + @Before + public void copyFile() throws IOException { + File source = TestHelper.getJarFile("/datasource-integration/flatfile-test.txt"); + File destination = temporaryFolder.newFile(); + Files.copy(source, destination); + flatFile = new FlatFile(destination); + } + + @Test + public void shouldConvertToSqlite() { + // given + DataSource dataSource = mock(DataSource.class); + ForceFlatToSqlite converter = new ForceFlatToSqlite(flatFile, dataSource); + + // when + converter.run(); + + // then + ArgumentCaptor authCaptor = ArgumentCaptor.forClass(PlayerAuth.class); + verify(dataSource, times(7)).saveAuth(authCaptor.capture()); + List auths = authCaptor.getAllValues(); + assertThat(auths, hasItem(hasAuthBasicData("bobby", "Bobby", "your@email.com", "123.45.67.89"))); + assertThat(auths, hasItem(hasAuthLocation(1.05, 2.1, 4.2, "world"))); + assertThat(auths, hasItem(hasAuthBasicData("user", "user", "user@example.org", "34.56.78.90"))); + assertThat(auths, hasItem(hasAuthLocation(124.1, 76.3, -127.8, "nether"))); + assertThat(auths, hasItem(hasAuthBasicData("eightfields", "eightFields", "your@email.com", "6.6.6.66"))); + assertThat(auths, hasItem(hasAuthLocation(8.8, 17.6, 26.4, "eightworld"))); + } + +} diff --git a/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java b/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java index abe1d521..4295e67b 100644 --- a/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java @@ -7,9 +7,9 @@ import org.junit.Test; import java.util.Arrays; import java.util.List; -import static fr.xephi.authme.datasource.AuthMeMatchers.equalToHash; -import static fr.xephi.authme.datasource.AuthMeMatchers.hasAuthBasicData; -import static fr.xephi.authme.datasource.AuthMeMatchers.hasAuthLocation; +import static fr.xephi.authme.AuthMeMatchers.equalToHash; +import static fr.xephi.authme.AuthMeMatchers.hasAuthBasicData; +import static fr.xephi.authme.AuthMeMatchers.hasAuthLocation; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasSize; @@ -129,15 +129,9 @@ public abstract class AbstractDataSourceIntegrationTest { // then assertThat(response, equalTo(true)); assertThat(authList, hasSize(2)); + assertThat(authList, hasItem(hasAuthBasicData("bobby", "Bobby", "your@email.com", "123.45.67.89"))); assertThat(newAuthList, hasSize(3)); - boolean hasBobby = false; - for (PlayerAuth auth : authList) { - if (auth.getNickname().equals("bobby")) { - hasBobby = true; - break; - } - } - assertThat(hasBobby, equalTo(true)); + assertThat(newAuthList, hasItem(hasAuthBasicData("bobby", "Bobby", "your@email.com", "123.45.67.89"))); } @Test diff --git a/src/test/java/fr/xephi/authme/datasource/FlatFileIntegrationTest.java b/src/test/java/fr/xephi/authme/datasource/FlatFileIntegrationTest.java new file mode 100644 index 00000000..154511c2 --- /dev/null +++ b/src/test/java/fr/xephi/authme/datasource/FlatFileIntegrationTest.java @@ -0,0 +1,100 @@ +package fr.xephi.authme.datasource; + +import com.google.common.io.Files; +import fr.xephi.authme.TestHelper; +import fr.xephi.authme.cache.auth.PlayerAuth; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import static fr.xephi.authme.AuthMeMatchers.equalToHash; +import static fr.xephi.authme.AuthMeMatchers.hasAuthBasicData; +import static fr.xephi.authme.AuthMeMatchers.hasAuthLocation; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertThat; + +/** + * Integration test for the deprecated {@link FlatFile} datasource. The flatfile datasource is no longer used. + * Essentially, the only time we use it is in {@link fr.xephi.authme.converter.ForceFlatToSqlite}, + * which requires {@link FlatFile#getAllAuths()}. + */ +public class FlatFileIntegrationTest { + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + private DataSource dataSource; + + @Before + public void copyFileToTemporaryFolder() throws IOException { + File originalFile = TestHelper.getJarFile("/datasource-integration/flatfile-test.txt"); + File copy = temporaryFolder.newFile(); + Files.copy(originalFile, copy); + dataSource = new FlatFile(copy); + } + + @Test + public void shouldReturnIfAuthIsAvailableOrNot() { + // given / when + boolean isBobbyAvailable = dataSource.isAuthAvailable("bobby"); + boolean isChrisAvailable = dataSource.isAuthAvailable("chris"); + boolean isUserAvailable = dataSource.isAuthAvailable("USER"); + + // then + assertThat(isBobbyAvailable, equalTo(true)); + assertThat(isChrisAvailable, equalTo(false)); + assertThat(isUserAvailable, equalTo(true)); + } + + @Test + public void shouldReturnAllAuths() { + // given / when + List authList = dataSource.getAllAuths(); + + // then + assertThat(authList, hasSize(7)); + assertThat(getName("bobby", authList), hasAuthBasicData("bobby", "Bobby", "your@email.com", "123.45.67.89")); + assertThat(getName("bobby", authList), hasAuthLocation(1.05, 2.1, 4.2, "world")); + assertThat(getName("bobby", authList).getPassword(), equalToHash("$SHA$11aa0706173d7272$dbba966")); + assertThat(getName("twofields", authList), hasAuthBasicData("twofields", "twoFields", "your@email.com", "127.0.0.1")); + assertThat(getName("twofields", authList).getPassword(), equalToHash("hash1234")); + assertThat(getName("threefields", authList), hasAuthBasicData("threefields", "threeFields", "your@email.com", "33.33.33.33")); + assertThat(getName("fourfields", authList), hasAuthBasicData("fourfields", "fourFields", "your@email.com", "4.4.4.4")); + assertThat(getName("fourfields", authList).getLastLogin(), equalTo(404040404L)); + assertThat(getName("sevenfields", authList), hasAuthLocation(7.7, 14.14, 21.21, "world")); + assertThat(getName("eightfields", authList), hasAuthLocation(8.8, 17.6, 26.4, "eightworld")); + assertThat(getName("eightfields", authList).getLastLogin(), equalTo(1234567888L)); + assertThat(getName("eightfields", authList).getPassword(), equalToHash("hash8168")); + } + + @Test + public void shouldAddAuth() { + // given / when + boolean response = dataSource.saveAuth( + PlayerAuth.builder().name("Test").email("user@EXAMPLE.org").ip("123.45.67.77").build()); + List authList = dataSource.getAllAuths(); + + // then + assertThat(response, equalTo(true)); + assertThat(authList, hasSize(8)); + assertThat(authList, hasItem(hasAuthBasicData("test", "test", "user@EXAMPLE.org", "123.45.67.77"))); + } + + private static PlayerAuth getName(String name, Collection auths) { + for (PlayerAuth auth : auths) { + if (name.equals(auth.getNickname())) { + return auth; + } + } + throw new IllegalStateException("Did not find auth with name '" + name + "'"); + } + +} diff --git a/src/test/resources/datasource-integration/flatfile-test.txt b/src/test/resources/datasource-integration/flatfile-test.txt new file mode 100644 index 00000000..da5a1312 --- /dev/null +++ b/src/test/resources/datasource-integration/flatfile-test.txt @@ -0,0 +1,7 @@ +Bobby:$SHA$11aa0706173d7272$dbba966:123.45.67.89:1449136800:1.05:2.1:4.2:world:your@email.com +user:b28c32f624a4eb161d6adc9acb5bfc5b:34.56.78.90:1453242857:124.1:76.3:-127.8:nether:user@example.org +twoFields:hash1234 +threeFields:hash369:33.33.33.33 +fourFields:$hash$4444:4.4.4.4:404040404 +sevenFields:hash7749:5.5.5.55:1414141414:7.7:14.14:21.21 +eightFields:hash8168:6.6.6.66:1234567888:8.8:17.6:26.4:eightworld From e79f325411ca851f3f3a225e7d0c6cf4d2a48094 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 27 Feb 2016 12:18:04 +0100 Subject: [PATCH 14/46] #443 Use correct message to ask to add email after login --- src/main/java/fr/xephi/authme/AuthMe.java | 5 +++-- .../fr/xephi/authme/process/login/AsynchronousLogin.java | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 622ceafe..d7cc0efa 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -50,6 +50,7 @@ import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.SettingsMigrationService; import fr.xephi.authme.settings.Spawn; import fr.xephi.authme.settings.properties.DatabaseSettings; +import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; @@ -786,7 +787,7 @@ public class AuthMe extends JavaPlugin { public void run() { for (PlayerAuth auth : database.getLoggedPlayers()) { String email = auth.getEmail(); - if (email == null || email.isEmpty() || email.equalsIgnoreCase("your@email.com")) { + if (StringUtils.isEmpty(email) || email.equalsIgnoreCase("your@email.com")) { Player player = Utils.getPlayer(auth.getRealName()); if (player != null) { messages.send(player, MessageKey.ADD_EMAIL_MESSAGE); @@ -794,7 +795,7 @@ public class AuthMe extends JavaPlugin { } } } - }, 1, 1200 * Settings.delayRecall); + }, 1, 1200 * newSettings.getProperty(EmailSettings.DELAY_RECALL)); } public String replaceAllInfo(String message, Player player) { 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 fcc64ab0..d6f1f327 100644 --- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java @@ -175,7 +175,7 @@ public class AsynchronousLogin { displayOtherAccounts(auth); if (Settings.recallEmail && (StringUtils.isEmpty(email) || "your@email.com".equalsIgnoreCase(email))) { - m.send(player, MessageKey.EMAIL_ADDED_SUCCESS); + m.send(player, MessageKey.ADD_EMAIL_MESSAGE); } if (!Settings.noConsoleSpam) { @@ -232,8 +232,8 @@ public class AsynchronousLogin { String message = "[AuthMe] " + StringUtils.join(", ", auths) + "."; for (Player player : Utils.getOnlinePlayers()) { if (plugin.getPermissionsManager().hasPermission(player, AdminPermission.SEE_OTHER_ACCOUNTS) - || (player.getName().equals(this.player.getName()) - && plugin.getPermissionsManager().hasPermission(player, PlayerPermission.SEE_OWN_ACCOUNTS))) { + || (player.getName().equals(this.player.getName()) + && plugin.getPermissionsManager().hasPermission(player, PlayerPermission.SEE_OWN_ACCOUNTS))) { player.sendMessage("[AuthMe] The player " + auth.getNickname() + " has " + auths.size() + " accounts"); player.sendMessage(message); } From 4bf89728759b4b8cf57fe661299469715795a3f8 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sat, 27 Feb 2016 16:11:50 +0100 Subject: [PATCH 15/46] Lombok + Retrolambda expressions support --- pom.xml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/pom.xml b/pom.xml index 82dfd0b4..f913596b 100644 --- a/pom.xml +++ b/pom.xml @@ -127,7 +127,27 @@ + + + + + net.orfjackal.retrolambda + retrolambda-maven-plugin + 2.1.0 + + + + process-main + process-test + + + + + + + + org.apache.maven.plugins maven-compiler-plugin @@ -137,6 +157,7 @@ ${javaVersion} + @@ -265,6 +286,7 @@ + org.jacoco jacoco-maven-plugin @@ -278,6 +300,7 @@ + org.eluder.coveralls coveralls-maven-plugin @@ -355,6 +378,13 @@ + + + org.projectlombok + lombok + 1.16.6 + provided + com.zaxxer From b916c9b2be025796e0d0ebc0111fd952235001ce Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 27 Feb 2016 16:31:42 +0100 Subject: [PATCH 16/46] Fix javadoc warnings + #421 add javadoc for new API --- src/main/java/fr/xephi/authme/AuthMe.java | 2 + src/main/java/fr/xephi/authme/api/NewAPI.java | 54 +++++++++---------- .../fr/xephi/authme/datasource/SQLite.java | 5 +- .../events/AuthMeAsyncPreLoginEvent.java | 2 +- .../java/fr/xephi/authme/output/Messages.java | 3 +- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index d7cc0efa..267dcc7d 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -548,6 +548,8 @@ public class AuthMe extends JavaPlugin { * @param settings The settings instance * * @see AuthMe#database + * @throws ClassNotFoundException if no driver could be found for the datasource + * @throws SQLException when initialization of a SQL datasource failed */ public void setupDatabase(NewSetting settings) throws ClassNotFoundException, SQLException { if (this.database != null) { diff --git a/src/main/java/fr/xephi/authme/api/NewAPI.java b/src/main/java/fr/xephi/authme/api/NewAPI.java index 03fed1a8..0c22fb13 100644 --- a/src/main/java/fr/xephi/authme/api/NewAPI.java +++ b/src/main/java/fr/xephi/authme/api/NewAPI.java @@ -13,7 +13,10 @@ import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.util.Utils; /** - * The current API of AuthMe. + * The current API of AuthMe. Recommended method of retrieving the API object: + * + * NewAPI authmeApi = NewAPI.getInstance(); + * */ public class NewAPI { @@ -23,7 +26,7 @@ public class NewAPI { /** * Constructor for NewAPI. * - * @param plugin AuthMe + * @param plugin The AuthMe plugin instance */ public NewAPI(AuthMe plugin) { this.plugin = plugin; @@ -32,16 +35,17 @@ public class NewAPI { /** * Constructor for NewAPI. * - * @param server Server + * @param server The server instance */ public NewAPI(Server server) { this.plugin = (AuthMe) server.getPluginManager().getPlugin("AuthMe"); } /** - * Hook into AuthMe + * Get the API object for AuthMe. * - * @return The API object + * @return The API object, or null if the AuthMe plugin instance could not be retrieved + * from the server environment */ public static NewAPI getInstance() { if (singleton != null) { @@ -69,7 +73,6 @@ public class NewAPI { * Return whether the given player is authenticated. * * @param player The player to verify - * * @return true if the player is authenticated */ public boolean isAuthenticated(Player player) { @@ -77,18 +80,22 @@ public class NewAPI { } /** - * @param player a Player + * Check whether the given player is an NPC. * - * @return true if player is a npc + * @param player The player to verify + * @return true if the player is an npc */ public boolean isNPC(Player player) { return Utils.isNPC(player); } /** - * @param player a Player + * Check whether the given player is unrestricted. For such players, AuthMe will not require + * them to authenticate. * + * @param player The player to verify * @return true if the player is unrestricted + * @see fr.xephi.authme.settings.properties.RestrictionSettings#UNRESTRICTED_NAMES */ public boolean isUnrestricted(Player player) { return Utils.isUnrestricted(player); @@ -97,30 +104,21 @@ public class NewAPI { /** * Get the last location of a player. * - * @param player Player The player to process - * + * @param player The player to process * @return Location The location of the player */ public Location getLastLocation(Player player) { - try { - PlayerAuth auth = PlayerCache.getInstance().getAuth(player.getName()); - - if (auth != null) { - return new Location(Bukkit.getWorld(auth.getWorld()), auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ()); - } else { - return null; - } - - } catch (NullPointerException ex) { - return null; + PlayerAuth auth = PlayerCache.getInstance().getAuth(player.getName()); + if (auth != null) { + return new Location(Bukkit.getWorld(auth.getWorld()), auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ()); } + return null; } /** * Return whether the player is registered. * * @param playerName The player name to check - * * @return true if player is registered, false otherwise */ public boolean isRegistered(String playerName) { @@ -133,7 +131,6 @@ public class NewAPI { * * @param playerName The player to check the password for * @param passwordToCheck The password to check - * * @return true if the password is correct, false otherwise */ public boolean checkPassword(String playerName, String passwordToCheck) { @@ -141,11 +138,10 @@ public class NewAPI { } /** - * Register a player. + * Register a player with the given password. * * @param playerName The player to register * @param password The password to register the player with - * * @return true if the player was registered successfully */ public boolean registerPlayer(String playerName, String password) { @@ -163,7 +159,7 @@ public class NewAPI { } /** - * Force a player to login. + * Force a player to login, i.e. the player is logged in without needing his password. * * @param player The player to log in */ @@ -181,7 +177,7 @@ public class NewAPI { } /** - * Force a player to register. + * Register a player with the given password. * * @param player The player to register * @param password The password to use @@ -191,7 +187,7 @@ public class NewAPI { } /** - * Force a player to unregister. + * Unregister a player from AuthMe. * * @param player The player to unregister */ diff --git a/src/main/java/fr/xephi/authme/datasource/SQLite.java b/src/main/java/fr/xephi/authme/datasource/SQLite.java index d0c39e15..e741af23 100644 --- a/src/main/java/fr/xephi/authme/datasource/SQLite.java +++ b/src/main/java/fr/xephi/authme/datasource/SQLite.java @@ -30,8 +30,9 @@ public class SQLite implements DataSource { /** * Constructor for SQLite. * - * @throws ClassNotFoundException Exception - * @throws SQLException Exception + * @param settings The settings instance + * @throws ClassNotFoundException if no driver could be found for the datasource + * @throws SQLException when initialization of a SQL datasource failed */ public SQLite(NewSetting settings) throws ClassNotFoundException, SQLException { this.database = settings.getProperty(DatabaseSettings.MYSQL_DATABASE); diff --git a/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java b/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java index 963593fd..ce1d0221 100644 --- a/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java +++ b/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java @@ -6,7 +6,7 @@ import org.bukkit.event.HandlerList; /** * This event is called when a player uses the /login command with correct credentials. - * {@link #setCanLogin(boolean) {@code event.setCanLogin(false)}} prevents the player from logging in. + * {@link #setCanLogin(boolean) event.setCanLogin(false)} prevents the player from logging in. */ public class AuthMeAsyncPreLoginEvent extends CustomEvent { diff --git a/src/main/java/fr/xephi/authme/output/Messages.java b/src/main/java/fr/xephi/authme/output/Messages.java index 9ea87f44..cf029275 100644 --- a/src/main/java/fr/xephi/authme/output/Messages.java +++ b/src/main/java/fr/xephi/authme/output/Messages.java @@ -96,6 +96,7 @@ public class Messages { * * @param key The key of the message to send * @param replacements The replacements to apply for the tags + * @return The message from the file with replacements */ public String retrieveSingle(MessageKey key, String... replacements) { String message = retrieveSingle(key); @@ -111,7 +112,7 @@ public class Messages { } /** - * Reload the messages manager. + * Reset the messages manager to retrieve messages from the given file instead of the current one. * * @param messagesFile The new file to load messages from */ From 5fce849ce704f6f462859ba0b3ec8de581cec2c1 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 27 Feb 2016 21:11:35 +0100 Subject: [PATCH 17/46] Minor - Add datasource test, minor code householding --- .../java/fr/xephi/authme/datasource/SQLite.java | 5 +++-- .../authme/events/AuthMeAsyncPreLoginEvent.java | 2 +- .../java/fr/xephi/authme/settings/Settings.java | 2 +- .../settings/properties/RegistrationSettings.java | 2 +- .../AbstractDataSourceIntegrationTest.java | 14 ++++++++++++++ 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/main/java/fr/xephi/authme/datasource/SQLite.java b/src/main/java/fr/xephi/authme/datasource/SQLite.java index e741af23..abd258b8 100644 --- a/src/main/java/fr/xephi/authme/datasource/SQLite.java +++ b/src/main/java/fr/xephi/authme/datasource/SQLite.java @@ -351,8 +351,9 @@ public class SQLite implements DataSource { @Override public synchronized void close() { try { - if (con != null && !con.isClosed()) - con.close(); + if (con != null && !con.isClosed()) { + con.close(); + } } catch (SQLException ex) { logSqlException(ex); } diff --git a/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java b/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java index ce1d0221..b2a5819a 100644 --- a/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java +++ b/src/main/java/fr/xephi/authme/events/AuthMeAsyncPreLoginEvent.java @@ -6,7 +6,7 @@ import org.bukkit.event.HandlerList; /** * This event is called when a player uses the /login command with correct credentials. - * {@link #setCanLogin(boolean) event.setCanLogin(false)} prevents the player from logging in. + * {@link #setCanLogin(boolean) event.setCanLogin(false)} prevents the player from logging in. */ public class AuthMeAsyncPreLoginEvent extends CustomEvent { diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index 53a8560c..c53869c0 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -211,7 +211,7 @@ public final class Settings { countriesBlacklist = configFile.getStringList("Protection.countriesBlacklist"); broadcastWelcomeMessage = configFile.getBoolean("settings.broadcastWelcomeMessage", false); forceRegKick = configFile.getBoolean("settings.registration.forceKickAfterRegister", false); - forceRegLogin = configFile.getBoolean("settings.registration.forceLoginAfterRegister", false); + forceRegLogin = load(RegistrationSettings.FORCE_LOGIN_AFTER_REGISTER); spawnPriority = load(RestrictionSettings.SPAWN_PRIORITY); getMaxLoginPerIp = configFile.getInt("settings.restrictions.maxLoginPerIp", 0); getMaxJoinPerIp = configFile.getInt("settings.restrictions.maxJoinPerIp", 0); diff --git a/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java index 0be9f67a..14ef825e 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java @@ -39,7 +39,7 @@ public class RegistrationSettings implements SettingsClass { newProperty("settings.registration.doubleEmailCheck", false); @Comment({ - "Do we force kicking player after a successful registration?", + "Do we force kick a player after a successful registration?", "Do not use with login feature below"}) public static final Property FORCE_KICK_AFTER_REGISTER = newProperty("settings.registration.forceKickAfterRegister", false); diff --git a/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java b/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java index 4295e67b..077209f4 100644 --- a/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/datasource/AbstractDataSourceIntegrationTest.java @@ -286,4 +286,18 @@ public abstract class AbstractDataSourceIntegrationTest { assertThat(updatedList, hasItem(equalTo("test-1"))); } + @Test + public void shouldUpdateRealName() { + // given + DataSource dataSource = getDataSource(); + + // when + boolean response1 = dataSource.updateRealName("bobby", "BOBBY"); + boolean response2 = dataSource.updateRealName("notExists", "NOTEXISTS"); + + // then + assertThat(response1 && response2, equalTo(true)); + assertThat(dataSource.getAuth("bobby"), hasAuthBasicData("bobby", "BOBBY", "your@email.com", "123.45.67.89")); + } + } From 63b31b081452c6178dcd6a8e84dc40a4183cade5 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 27 Feb 2016 22:45:39 +0100 Subject: [PATCH 18/46] Create resource closing test - Generic test for MySQL and SQLite checking that all generated (Prepared)Statement and ResultSet instances are closed afterwards - Fix offending code for test to pass --- .../fr/xephi/authme/datasource/MySQL.java | 97 ++++-- .../fr/xephi/authme/datasource/SQLite.java | 36 +- .../AbstractResourceClosingTest.java | 319 ++++++++++++++++++ .../datasource/MySqlResourceClosingTest.java | 29 ++ .../datasource/SQLiteResourceClosingTest.java | 23 ++ 5 files changed, 440 insertions(+), 64 deletions(-) create mode 100644 src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java create mode 100644 src/test/java/fr/xephi/authme/datasource/MySqlResourceClosingTest.java create mode 100644 src/test/java/fr/xephi/authme/datasource/SQLiteResourceClosingTest.java diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java index 1ab37d5e..84927fe6 100644 --- a/src/main/java/fr/xephi/authme/datasource/MySQL.java +++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java @@ -42,6 +42,10 @@ public class MySQL implements DataSource { private final HashAlgorithm hashAlgorithm; private HikariDataSource ds; + private final String phpBbPrefix; + private final int phpBbGroup; + private final String wordpressPrefix; + public MySQL(NewSetting settings) throws ClassNotFoundException, SQLException, PoolInitializationException { this.host = settings.getProperty(DatabaseSettings.MYSQL_HOST); this.port = settings.getProperty(DatabaseSettings.MYSQL_PORT); @@ -52,6 +56,9 @@ public class MySQL implements DataSource { this.columnOthers = settings.getProperty(HooksSettings.MYSQL_OTHER_USERNAME_COLS); this.col = new Columns(settings); this.hashAlgorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH); + this.phpBbPrefix = settings.getProperty(HooksSettings.PHPBB_TABLE_PREFIX); + this.phpBbGroup = settings.getProperty(HooksSettings.PHPBB_ACTIVATED_GROUP_ID); + this.wordpressPrefix = settings.getProperty(HooksSettings.WORDPRESS_TABLE_PREFIX); // Set the connection arguments (and check if connection is ok) try { @@ -93,6 +100,9 @@ public class MySQL implements DataSource { this.columnOthers = settings.getProperty(HooksSettings.MYSQL_OTHER_USERNAME_COLS); this.col = new Columns(settings); this.hashAlgorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH); + this.phpBbPrefix = settings.getProperty(HooksSettings.PHPBB_TABLE_PREFIX); + this.phpBbGroup = settings.getProperty(HooksSettings.PHPBB_ACTIVATED_GROUP_ID); + this.wordpressPrefix = settings.getProperty(HooksSettings.WORDPRESS_TABLE_PREFIX); ds = hikariDataSource; } @@ -361,10 +371,10 @@ public class MySQL implements DataSource { if (rs.next()) { int id = rs.getInt(col.ID); // Insert player in phpbb_user_group - sql = "INSERT INTO " + Settings.getPhpbbPrefix + sql = "INSERT INTO " + phpBbPrefix + "user_group (group_id, user_id, group_leader, user_pending) VALUES (?,?,?,?);"; pst2 = con.prepareStatement(sql); - pst2.setInt(1, Settings.getPhpbbGroup); + pst2.setInt(1, phpBbGroup); pst2.setInt(2, id); pst2.setInt(3, 0); pst2.setInt(4, 0); @@ -382,7 +392,7 @@ public class MySQL implements DataSource { sql = "UPDATE " + tableName + " SET " + tableName + ".group_id=? WHERE " + col.NAME + "=?;"; pst2 = con.prepareStatement(sql); - pst2.setInt(1, Settings.getPhpbbGroup); + pst2.setInt(1, phpBbGroup); pst2.setString(2, auth.getNickname()); pst2.executeUpdate(); pst2.close(); @@ -405,7 +415,7 @@ public class MySQL implements DataSource { pst2.executeUpdate(); pst2.close(); // Increment num_users - sql = "UPDATE " + Settings.getPhpbbPrefix + sql = "UPDATE " + phpBbPrefix + "config SET config_value = config_value + 1 WHERE config_name = 'num_users';"; pst2 = con.prepareStatement(sql); pst2.executeUpdate(); @@ -419,7 +429,7 @@ public class MySQL implements DataSource { rs = pst.executeQuery(); if (rs.next()) { int id = rs.getInt(col.ID); - sql = "INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"; + sql = "INSERT INTO " + wordpressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);"; pst2 = con.prepareStatement(sql); // First Name pst2.setInt(1, id); @@ -622,31 +632,32 @@ public class MySQL implements DataSource { @Override public synchronized boolean removeAuth(String user) { user = user.toLowerCase(); - try (Connection con = getConnection()) { - String sql; - PreparedStatement pst; + String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;"; + PreparedStatement xfSelect = null; + PreparedStatement xfDelete = null; + try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) { if (hashAlgorithm == HashAlgorithm.XFBCRYPT) { sql = "SELECT " + col.ID + " FROM " + tableName + " WHERE " + col.NAME + "=?;"; - pst = con.prepareStatement(sql); - pst.setString(1, user); - ResultSet rs = pst.executeQuery(); - if (rs.next()) { - int id = rs.getInt(col.ID); - sql = "DELETE FROM xf_user_authenticate WHERE " + col.ID + "=?;"; - PreparedStatement st = con.prepareStatement(sql); - st.setInt(1, id); - st.executeUpdate(); - st.close(); + xfSelect = con.prepareStatement(sql); + xfSelect.setString(1, user); + try (ResultSet rs = xfSelect.executeQuery()) { + if (rs.next()) { + int id = rs.getInt(col.ID); + sql = "DELETE FROM xf_user_authenticate WHERE " + col.ID + "=?;"; + xfDelete = con.prepareStatement(sql); + xfDelete.setInt(1, id); + xfDelete.executeUpdate(); + } } - rs.close(); - pst.close(); } - pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;"); pst.setString(1, user); pst.executeUpdate(); return true; } catch (SQLException ex) { logSqlException(ex); + } finally { + close(xfSelect); + close(xfDelete); } return false; } @@ -881,22 +892,24 @@ public class MySQL implements DataSource { @Override public List getLoggedPlayers() { List auths = new ArrayList<>(); - try (Connection con = getConnection()) { - Statement st = con.createStatement(); - ResultSet rs = st.executeQuery("SELECT * FROM " + tableName + " WHERE " + col.IS_LOGGED + "=1;"); - PreparedStatement pst = con.prepareStatement("SELECT data FROM xf_user_authenticate WHERE " + col.ID + "=?;"); + String sql = "SELECT * FROM " + tableName + " WHERE " + col.IS_LOGGED + "=1;"; + try (Connection con = getConnection(); + Statement st = con.createStatement(); + ResultSet rs = st.executeQuery(sql)) { while (rs.next()) { PlayerAuth pAuth = buildAuthFromResultSet(rs); if (hashAlgorithm == HashAlgorithm.XFBCRYPT) { - int id = rs.getInt(col.ID); - pst.setInt(1, id); - ResultSet rs2 = pst.executeQuery(); - if (rs2.next()) { - Blob blob = rs2.getBlob("data"); - byte[] bytes = blob.getBytes(1, (int) blob.length()); - pAuth.setPassword(new HashedPassword(XFBCRYPT.getHashFromBlob(bytes))); + try (PreparedStatement pst = con.prepareStatement("SELECT data FROM xf_user_authenticate WHERE " + col.ID + "=?;")) { + int id = rs.getInt(col.ID); + pst.setInt(1, id); + ResultSet rs2 = pst.executeQuery(); + if (rs2.next()) { + Blob blob = rs2.getBlob("data"); + byte[] bytes = blob.getBytes(1, (int) blob.length()); + pAuth.setPassword(new HashedPassword(XFBCRYPT.getHashFromBlob(bytes))); + } + rs2.close(); } - rs2.close(); } auths.add(pAuth); } @@ -980,12 +993,22 @@ public class MySQL implements DataSource { } private static void close(ResultSet rs) { - if (rs != null) { - try { + try { + if (rs != null && !rs.isClosed()) { rs.close(); - } catch (SQLException e) { - ConsoleLogger.logException("Could not close ResultSet", e); } + } catch (SQLException e) { + ConsoleLogger.logException("Could not close ResultSet", e); + } + } + + private static void close(PreparedStatement pst) { + try { + if (pst != null && !pst.isClosed()) { + pst.close(); + } + } catch (SQLException e) { + ConsoleLogger.logException("Could not close PreparedStatement", e); } } diff --git a/src/main/java/fr/xephi/authme/datasource/SQLite.java b/src/main/java/fr/xephi/authme/datasource/SQLite.java index abd258b8..2868a59a 100644 --- a/src/main/java/fr/xephi/authme/datasource/SQLite.java +++ b/src/main/java/fr/xephi/authme/datasource/SQLite.java @@ -423,17 +423,14 @@ public class SQLite implements DataSource { @Override public void purgeBanned(List banned) { - PreparedStatement pst = null; - try { + String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;"; + try (PreparedStatement pst = con.prepareStatement(sql)) { for (String name : banned) { - pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;"); pst.setString(1, name); pst.executeUpdate(); } } catch (SQLException ex) { logSqlException(ex); - } finally { - close(pst); } } @@ -509,18 +506,13 @@ public class SQLite implements DataSource { @Override public int getAccountsRegistered() { - PreparedStatement pst = null; - ResultSet rs; - try { - pst = con.prepareStatement("SELECT COUNT(*) FROM " + tableName + ";"); - rs = pst.executeQuery(); - if (rs != null && rs.next()) { + String sql = "SELECT COUNT(*) FROM " + tableName + ";"; + try (PreparedStatement pst = con.prepareStatement(sql); ResultSet rs = pst.executeQuery()) { + if (rs.next()) { return rs.getInt(1); } } catch (SQLException ex) { logSqlException(ex); - } finally { - close(pst); } return 0; } @@ -556,19 +548,14 @@ public class SQLite implements DataSource { @Override public List getAllAuths() { List auths = new ArrayList<>(); - PreparedStatement pst = null; - ResultSet rs; - try { - pst = con.prepareStatement("SELECT * FROM " + tableName + ";"); - rs = pst.executeQuery(); + String sql = "SELECT * FROM " + tableName + ";"; + try (PreparedStatement pst = con.prepareStatement(sql); ResultSet rs = pst.executeQuery()) { while (rs.next()) { PlayerAuth auth = buildAuthFromResultSet(rs); auths.add(auth); } } catch (SQLException ex) { logSqlException(ex); - } finally { - close(pst); } return auths; } @@ -576,19 +563,14 @@ public class SQLite implements DataSource { @Override public List getLoggedPlayers() { List auths = new ArrayList<>(); - PreparedStatement pst = null; - ResultSet rs; - try { - pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + col.IS_LOGGED + "=1;"); - rs = pst.executeQuery(); + String sql = "SELECT * FROM " + tableName + " WHERE " + col.IS_LOGGED + "=1;"; + try (PreparedStatement pst = con.prepareStatement(sql); ResultSet rs = pst.executeQuery()) { while (rs.next()) { PlayerAuth auth = buildAuthFromResultSet(rs); auths.add(auth); } } catch (SQLException ex) { logSqlException(ex); - } finally { - close(pst); } return auths; } diff --git a/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java b/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java new file mode 100644 index 00000000..5b215a90 --- /dev/null +++ b/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java @@ -0,0 +1,319 @@ +package fr.xephi.authme.datasource; + +import com.google.common.base.Objects; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import fr.xephi.authme.ConsoleLoggerTestInitializer; +import fr.xephi.authme.cache.auth.PlayerAuth; +import fr.xephi.authme.security.HashAlgorithm; +import fr.xephi.authme.security.crypts.HashedPassword; +import fr.xephi.authme.settings.NewSetting; +import fr.xephi.authme.settings.domain.Property; +import fr.xephi.authme.settings.properties.SecuritySettings; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.sql.Blob; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.mockito.BDDMockito.given; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +/** + * Test class which runs through a datasource implementation and verifies that all + * instances of {@link AutoCloseable} that are created in the calls are closed again. + *

+ * Instead of an actual connection to a datasource, we pass a mock Connection object + * which is set to create additional mocks on demand for Statement and ResultSet objects. + * This test ensures that all such objects that are created will be closed again by + * keeping a list of mocks ({@link #closeables}) and then verifying that all have been + * closed {@link #verifyHaveMocksBeenClosed()}. + */ +@RunWith(Parameterized.class) +public abstract class AbstractResourceClosingTest { + + /** List of DataSource method names not to test. */ + private static final Set IGNORED_METHODS = ImmutableSet.of("reload", "close", "getType"); + + /** Collection of values to use to call methods with the parameters they expect. */ + private static final Map, Object> PARAM_VALUES = getDefaultParameters(); + + /** + * Custom list of hash algorithms to use to test a method. By default we define {@link HashAlgorithm#XFBCRYPT} as + * algorithms we use as a lot of methods execute additional statements in {@link MySQL}. If other algorithms + * have custom behaviors, they can be supplied in this map so it will be tested as well. + */ + private static final Map CUSTOM_ALGORITHMS = getCustomAlgorithmList(); + + /** Mock of a settings instance. */ + private static NewSetting settings; + + /** The datasource to test. */ + private DataSource dataSource; + + /** The DataSource method to test. */ + private Method method; + + /** Keeps track of the closeables which are created during the tested call. */ + private List closeables = new ArrayList<>(); + + /** + * Constructor for the test instance verifying the given method with the given hash algorithm. + * + * @param method The DataSource method to test + * @param name The name of the method + * @param algorithm The hash algorithm to use + */ + public AbstractResourceClosingTest(Method method, String name, HashAlgorithm algorithm) { + // Note ljacqu 20160227: The name parameter is necessary as we pass it from the @Parameters method; + // we use the method name in the annotation to name the test sensibly + this.method = method; + given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(algorithm); + } + + /** Initialize the settings mock and makes it return the default of any given property by default. */ + @BeforeClass + public static void initializeSettings() throws IOException, ClassNotFoundException { + settings = mock(NewSetting.class); + given(settings.getProperty(any(Property.class))).willAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocation) { + return ((Property) invocation.getArguments()[0]).getDefaultValue(); + } + }); + ConsoleLoggerTestInitializer.setupLogger(); + } + + /** Initialize the dataSource implementation to test based on a mock connection. */ + @Before + public void setUpMockConnection() throws Exception { + Connection connection = initConnection(); + dataSource = createDataSource(settings, connection); + } + + /** + * The actual test -- executes the method given through the constructor and then verifies that all + * AutoCloseable mocks it constructed have been closed. + */ + @Test + public void shouldCloseResources() throws IllegalAccessException, InvocationTargetException { + method.invoke(dataSource, buildParamListForMethod(method)); + verifyHaveMocksBeenClosed(); + } + + /** + * Initialization method -- provides the parameters to run the test with by scanning all DataSource + * methods. By default, we run one test per method with the default hash algorithm, XFBCRYPT. + * If the map of custom algorithms has an entry for the method name, we add an entry for each algorithm + * supplied by the map. + * + * @return Test parameters + */ + @Parameterized.Parameters(name = "{1}({2})") + public static Collection data() { + List methods = getDataSourceMethods(); + List data = new ArrayList<>(); + // Use XFBCRYPT if nothing else specified as there is a lot of specific behavior to this hash algorithm in MySQL + final HashAlgorithm[] defaultAlgorithm = new HashAlgorithm[]{HashAlgorithm.XFBCRYPT}; + for (Method method : methods) { + HashAlgorithm[] algorithms = Objects.firstNonNull(CUSTOM_ALGORITHMS.get(method.getName()), defaultAlgorithm); + for (HashAlgorithm algorithm : algorithms) { + data.add(new Object[]{method, method.getName(), algorithm}); + } + } + return data; + } + + /* Create a DataSource instance with the given mock settings and mock connection. */ + protected abstract DataSource createDataSource(NewSetting settings, Connection connection) throws Exception; + + /* Get all methods of the DataSource interface, minus the ones in the ignored list. */ + private static List getDataSourceMethods() { + List publicMethods = new ArrayList<>(); + for (Method method : DataSource.class.getDeclaredMethods()) { + if (!IGNORED_METHODS.contains(method.getName())) { + publicMethods.add(method); + } + } + return publicMethods; + } + + /** + * Verify that all AutoCloseables that have been created during the method execution have been closed. + */ + private void verifyHaveMocksBeenClosed() { + System.out.println("Found " + closeables.size() + " resources"); + try { + for (AutoCloseable autoCloseable : closeables) { + verify(autoCloseable).close(); + } + } catch (Exception e) { + throw new IllegalStateException("Error verifying if autoCloseable was closed", e); + } + } + + /** + * Helper method for building a list of test values to satisfy a method's signature. + * + * @param method The method to create a valid parameter list for + * @return Parameter list to invoke the given method with + */ + private static Object[] buildParamListForMethod(Method method) { + List params = new ArrayList<>(); + int index = 0; + for (Class paramType : method.getParameterTypes()) { + // Checking List.class == paramType instead of Class#isAssignableFrom means we really only accept List, + // but that is a sensible assumption and makes our life much easier later on when juggling with Type + Object param = (List.class == paramType) + ? getTypedList(method.getGenericParameterTypes()[index]) + : PARAM_VALUES.get(paramType); + Preconditions.checkNotNull(param, "No param type for " + paramType); + params.add(param); + ++index; + } + return params.toArray(); + } + + /** + * Return a list with some test elements that correspond to the given list type's generic type. + * + * @param type The list type to process and build a test list for + * @return Test list with sample elements of the correct type + */ + private static List getTypedList(Type type) { + if (type instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) type; + Preconditions.checkArgument(List.class == parameterizedType.getRawType(), type + " should be a List"); + Type genericType = parameterizedType.getActualTypeArguments()[0]; + + Object element = PARAM_VALUES.get(genericType); + Preconditions.checkNotNull(element, "No sample element for list of generic type " + genericType); + return Arrays.asList(element, element, element); + } + throw new IllegalStateException("Cannot build list for unexpected Type: " + type); + } + + /* Initialize the map of test values to pass to methods to satisfy their signature. */ + private static Map, Object> getDefaultParameters() { + HashedPassword hash = new HashedPassword("test", "test"); + return ImmutableMap., Object>builder() + .put(String.class, "test") + .put(int.class, 3) + .put(long.class, 102L) + .put(PlayerAuth.class, PlayerAuth.builder().name("test").realName("test").password(hash).build()) + .put(HashedPassword.class, hash) + .build(); + } + + /** + * Return the custom list of hash algorithms to test a method with to execute code specific to + * one hash algorithm. By default, XFBCRYPT is used. Only MySQL has code specific to algorithms + * but for technical reasons the custom list will be used for all tested classes. + * + * @return List of custom algorithms by method + */ + private static Map getCustomAlgorithmList() { + // We use XFBCRYPT as default encryption method so we don't have to list many of the special cases for it + return ImmutableMap.builder() + .put("saveAuth", new HashAlgorithm[]{HashAlgorithm.PHPBB, HashAlgorithm.WORDPRESS}) + .build(); + } + + // --------------------- + // Mock initialization + // --------------------- + /** + * Initialize the connection mock which produces additional AutoCloseable mocks and records them. + * + * @return Connection mock + */ + private Connection initConnection() { + Connection connection = mock(Connection.class); + try { + given(connection.prepareStatement(anyString())).willAnswer(preparedStatementAnswer()); + given(connection.createStatement()).willAnswer(preparedStatementAnswer()); + given(connection.createBlob()).willReturn(mock(Blob.class)); + return connection; + } catch (SQLException e) { + throw new IllegalStateException("Could not initialize connection mock", e); + } + } + + /* Create Answer that returns a PreparedStatement mock. */ + private Answer preparedStatementAnswer() { + return new Answer() { + @Override + public PreparedStatement answer(InvocationOnMock invocation) throws SQLException { + PreparedStatement pst = mock(PreparedStatement.class); + closeables.add(pst); + given(pst.executeQuery()).willAnswer(resultSetAnswer()); + given(pst.executeQuery(anyString())).willAnswer(resultSetAnswer()); + return pst; + } + }; + } + + /* Create Answer that returns a ResultSet mock. */ + private Answer resultSetAnswer() throws SQLException { + return new Answer() { + @Override + public ResultSet answer(InvocationOnMock invocation) throws Throwable { + ResultSet rs = initResultSet(); + closeables.add(rs); + return rs; + } + }; + } + + /* Create a ResultSet mock. */ + private ResultSet initResultSet() throws SQLException { + ResultSet rs = mock(ResultSet.class); + // Return true for ResultSet#next the first time to make sure we execute all code + given(rs.next()).willAnswer(new Answer() { + boolean isInitial = true; + @Override + public Boolean answer(InvocationOnMock invocation) { + if (isInitial) { + isInitial = false; + return true; + } + return false; + } + }); + given(rs.getString(anyInt())).willReturn("test"); + given(rs.getString(anyString())).willReturn("test"); + + Blob blob = mock(Blob.class); + given(blob.getBytes(anyLong(), anyInt())).willReturn(new byte[]{}); + given(blob.length()).willReturn(0L); + given(rs.getBlob(anyInt())).willReturn(blob); + given(rs.getBlob(anyString())).willReturn(blob); + return rs; + } + +} diff --git a/src/test/java/fr/xephi/authme/datasource/MySqlResourceClosingTest.java b/src/test/java/fr/xephi/authme/datasource/MySqlResourceClosingTest.java new file mode 100644 index 00000000..9986725c --- /dev/null +++ b/src/test/java/fr/xephi/authme/datasource/MySqlResourceClosingTest.java @@ -0,0 +1,29 @@ +package fr.xephi.authme.datasource; + +import com.zaxxer.hikari.HikariDataSource; +import fr.xephi.authme.security.HashAlgorithm; +import fr.xephi.authme.settings.NewSetting; + +import java.lang.reflect.Method; +import java.sql.Connection; + +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Resource closing test for {@link MySQL}. + */ +public class MySqlResourceClosingTest extends AbstractResourceClosingTest { + + public MySqlResourceClosingTest(Method method, String name, HashAlgorithm algorithm) { + super(method, name, algorithm); + } + + @Override + protected DataSource createDataSource(NewSetting settings, Connection connection) throws Exception { + HikariDataSource hikariDataSource = mock(HikariDataSource.class); + given(hikariDataSource.getConnection()).willReturn(connection); + return new MySQL(settings, hikariDataSource); + } + +} diff --git a/src/test/java/fr/xephi/authme/datasource/SQLiteResourceClosingTest.java b/src/test/java/fr/xephi/authme/datasource/SQLiteResourceClosingTest.java new file mode 100644 index 00000000..3275aafa --- /dev/null +++ b/src/test/java/fr/xephi/authme/datasource/SQLiteResourceClosingTest.java @@ -0,0 +1,23 @@ +package fr.xephi.authme.datasource; + +import fr.xephi.authme.security.HashAlgorithm; +import fr.xephi.authme.settings.NewSetting; + +import java.lang.reflect.Method; +import java.sql.Connection; + +/** + * Resource closing test for {@link SQLite}. + */ +public class SQLiteResourceClosingTest extends AbstractResourceClosingTest { + + public SQLiteResourceClosingTest(Method method, String name, HashAlgorithm algorithm) { + super(method, name, algorithm); + } + + @Override + protected DataSource createDataSource(NewSetting settings, Connection connection) throws Exception { + return new SQLite(settings, connection); + } + +} From 28108f00f1dc43dfcd7dc8a8e41041a5c340e42d Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 27 Feb 2016 22:55:51 +0100 Subject: [PATCH 19/46] #569 Update messages_de.yml by Platinteufel --- src/main/resources/messages/messages_de.yml | 51 ++++++++++----------- src/main/resources/messages/messages_en.yml | 2 +- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/main/resources/messages/messages_de.yml b/src/main/resources/messages/messages_de.yml index 942460ac..04345292 100644 --- a/src/main/resources/messages/messages_de.yml +++ b/src/main/resources/messages/messages_de.yml @@ -1,5 +1,5 @@ unknown_user: '&cBenutzer ist nicht in der Datenbank' -unsafe_spawn: '&cDeine Logoutposition war unsicher, du wurdest zum Spawn teleportiert' +unsafe_spawn: '&cDeine Logoutposition war unsicher, Du wurdest zum Spawn teleportiert' not_logged_in: '&cNicht eingeloggt!' reg_voluntarily: 'Du kannst dich mit folgendem Befehl registrieren "/register "' usage_log: '&cBenutze: /login ' @@ -9,11 +9,11 @@ reg_disabled: '&cRegistrierungen sind deaktiviert' valid_session: '&2Erfolgreich eingeloggt!' login: '&2Erfolgreich eingeloggt!' vb_nonActiv: '&cDein Account wurde noch nicht aktiviert. Bitte prüfe Deine E-Mails!' -user_regged: '&cBenutzername ist schon vergeben' +user_regged: '&cDieser Benutzername ist schon vergeben' usage_reg: '&cBenutze: /register ' -max_reg: '&cDu hast die maximale Anzahl an Accounts erreicht' +max_reg: '&cDu hast die maximale Anzahl an Accounts erreicht.' no_perm: '&4Du hast keine Rechte, um diese Aktion auszuführen!' -error: '&4Ein Fehler ist aufgetreten. Bitte kontaktiere einen Administrator' +error: '&4Ein Fehler ist aufgetreten. Bitte kontaktiere einen Administrator.' login_msg: '&cBitte logge Dich ein mit "/login "' reg_msg: '&3Bitte registriere Dich mit "/register "' reg_email_msg: '&3Bitte registriere Dich mit "/register "' @@ -21,44 +21,43 @@ usage_unreg: '&cBenutze: /unregister ' pwd_changed: '&2Passwort geändert!' user_unknown: '&cBenutzername nicht registriert!' password_error: '&cPasswörter stimmen nicht überein!' -password_error_nick: '&cDu kannst nicht deinen Namen als Passwort nutzen!' +password_error_nick: '&cDu kannst nicht Deinen Namen als Passwort nutzen!' password_error_unsafe: '&cDu kannst nicht unsichere Passwörter nutzen!' invalid_session: '&cUngültige Session. Bitte starte das Spiel neu oder warte, bis die Session abgelaufen ist' -reg_only: '&4Nur für registrierte Spieler! Bitte besuche http://example.com zum registrieren' +reg_only: '&4Nur für registrierte Spieler! Bitte besuche http://example.com zum Registrieren' logged_in: '&cBereits eingeloggt!' logout: '&2Erfolgreich ausgeloggt' same_nick: '&4Jemand mit diesem Namen spielt bereits auf dem Server!' registered: '&2Erfolgreich registriert!' pass_len: '&cDein Passwort ist zu kurz oder zu lang!' -reload: '&2Konfiguration und Datenbank wurden erfolgreich neu geladen' +reload: '&2Konfiguration und Datenbank wurden erfolgreich neu geladen.' timeout: '&4Zeitüberschreitung beim Login' usage_changepassword: '&cBenutze: /changepassword ' -name_len: '&4Dein Nickname ist zu kurz oder zu lang' +name_len: '&4Dein Nickname ist zu kurz oder zu lang.' regex: '&4Dein Nickname enthält nicht erlaubte Zeichen. Zulässige Zeichen: REG_EX' -add_email: '&3Bitte hinterlege Deine E-Mail Adresse: /email add ' +add_email: '&3Bitte hinterlege Deine E-Mail-Adresse: /email add ' recovery_email: '&3Passwort vergessen? Nutze "/email recovery " für ein neues Passwort' usage_captcha: '&3Um dich einzuloggen, tippe dieses Captcha so ein: /captcha ' wrong_captcha: '&cFalsches Captcha, bitte nutze: /captcha THE_CAPTCHA' valid_captcha: '&2Das Captcha ist korrekt!' -kick_forvip: '&3Ein VIP Spieler hat den vollen Server betreten!' +kick_forvip: '&3Ein VIP-Spieler hat den vollen Server betreten!' kick_fullserver: '&4Der Server ist momentan voll, Sorry!' usage_email_add: '&cBenutze: /email add ' usage_email_change: '&cBenutze: /email change ' usage_email_recovery: '&cBenutze: /email recovery ' -new_email_invalid: '&cDie neue Email ist ungültig!' -old_email_invalid: '&cDie alte Email ist ungültig!' -email_invalid: '&cUngültige Email' -email_added: '&2Email hinzugefügt!' -email_confirm: '&cBitte bestätige deine Email!' -email_changed: '&2Email aktualisiert!' -email_send: '&2Wiederherstellungs-Email wurde gesendet!' -email_exists: '&cEine Wiederherstellungs-Email wurde bereits versandt! Nutze folgenden Befehl um eine neue Email zu versenden:' -country_banned: '&4Dein Land ist gesperrt' +new_email_invalid: '&cDie neue E-Mail ist ungültig!' +old_email_invalid: '&cDie alte E-Mail ist ungültig!' +email_invalid: '&cUngültige E-Mail!' +email_added: '&2E-Mail hinzugefügt!' +email_confirm: '&cBitte bestätige Deine E-Mail!' +email_changed: '&2E-Mail aktualisiert!' +email_send: '&2Wiederherstellungs-E-Mail wurde gesendet!' +email_exists: '&cEine Wiederherstellungs-E-Mail wurde bereits versandt! Nutze folgenden Befehl um eine neue E-Mail zu versenden:' +country_banned: '&4Dein Land ist gesperrt!' antibot_auto_enabled: '&4[AntiBotService] AntiBotMod wurde aufgrund hoher Netzauslastung automatisch aktiviert!' -antibot_auto_disabled: '&2[AntiBotService] AntiBotMod wurde nach %m Minuten deaktiviert, hoffentlich ist die Invasion vorbei' -kick_antibot: 'AntiBotMod ist aktiviert! Bitte warte einige Minuten, bevor du dich mit dem Server verbindest' -# TODO two_factor_create: Missing tag %url -two_factor_create: '&2Dein geheimer Code ist %code' -# TODO email_already_used: '&4The email address is already being used' -# TODO invalid_name_case: 'You should join using username %valid, not %invalid.' -# TODO not_owner_error: 'You are not the owner of this account. Please try another name!' \ No newline at end of file +antibot_auto_disabled: '&2[AntiBotService] AntiBotMod wurde nach %m Minuten deaktiviert, hoffentlich ist die Invasion vorbei.' +kick_antibot: 'AntiBotMod ist aktiviert! Bitte warte einige Minuten, bevor Du Dich mit dem Server verbindest.' +two_factor_create: '&2Dein geheimer Code ist %code. Du kannst ihn hier abfragen: %url' +email_already_used: '&4Diese E-Mail-Adresse wird bereits genutzt.' +invalid_name_case: 'Dein registrierter Benutzername ist &2%valid&f - nicht &4%invalid&f.' +not_owner_error: 'Du bist nicht der Besitzer dieses Accounts. Bitte wähle einen anderen Namen!' diff --git a/src/main/resources/messages/messages_en.yml b/src/main/resources/messages/messages_en.yml index 64aa9099..1b1ae61e 100644 --- a/src/main/resources/messages/messages_en.yml +++ b/src/main/resources/messages/messages_en.yml @@ -59,5 +59,5 @@ antibot_auto_enabled: '&4[AntiBotService] AntiBot enabled due to the huge number antibot_auto_disabled: '&2[AntiBotService] AntiBot disabled disabled after %m minutes!' email_already_used: '&4The email address is already being used' two_factor_create: '&2Your secret code is %code. You can scan it from here %url' -not_owner_error: 'You are not the owner of this account. Please try another name!' +not_owner_error: 'You are not the owner of this account. Please choose another name!' invalid_name_case: 'You should join using username %valid, not %invalid.' From d664e7be26bc945931a2160d0e5380eeca7f0bc7 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 20 Feb 2016 19:56:45 +0100 Subject: [PATCH 20/46] #547 Create ProcessService - Create ProcessService for common tasks within processes - Integrate service into AsyncAddEmail --- src/main/java/fr/xephi/authme/AuthMe.java | 4 +- .../fr/xephi/authme/process/Management.java | 36 +++++++------ .../java/fr/xephi/authme/process/Process.java | 8 +++ .../xephi/authme/process/ProcessService.java | 34 ++++++++++++ .../authme/process/email/AsyncAddEmail.java | 42 +++++++-------- .../fr/xephi/authme/settings/Settings.java | 19 ++----- .../xephi/authme/task/ChangePasswordTask.java | 12 ++--- .../process/email/AsyncAddEmailTest.java | 54 +++++++++---------- 8 files changed, 122 insertions(+), 87 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/process/Process.java create mode 100644 src/main/java/fr/xephi/authme/process/ProcessService.java diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 267dcc7d..f70229b9 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -42,6 +42,7 @@ import fr.xephi.authme.output.Messages; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.process.Management; +import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.crypts.SHA256; import fr.xephi.authme.settings.NewSetting; @@ -304,7 +305,8 @@ public class AuthMe extends JavaPlugin { setupApi(); // Set up the management - management = new Management(this, newSettings); + ProcessService processService = new ProcessService(newSettings, messages); + management = new Management(this, processService, database, PlayerCache.getInstance()); // Set up the BungeeCord hook setupBungeeCordHook(); diff --git a/src/main/java/fr/xephi/authme/process/Management.java b/src/main/java/fr/xephi/authme/process/Management.java index 597d927e..fe7022be 100644 --- a/src/main/java/fr/xephi/authme/process/Management.java +++ b/src/main/java/fr/xephi/authme/process/Management.java @@ -2,6 +2,7 @@ package fr.xephi.authme.process; import fr.xephi.authme.AuthMe; import fr.xephi.authme.cache.auth.PlayerCache; +import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.process.email.AsyncAddEmail; import fr.xephi.authme.process.email.AsyncChangeEmail; import fr.xephi.authme.process.join.AsynchronousJoin; @@ -20,18 +21,25 @@ public class Management { private final AuthMe plugin; private final BukkitScheduler sched; + private final ProcessService processService; + private final DataSource dataSource; + private final PlayerCache playerCache; private final NewSetting settings; /** * Constructor for Management. * * @param plugin AuthMe - * @param settings The plugin settings */ - public Management(AuthMe plugin, NewSetting settings) { + public Management(AuthMe plugin, ProcessService processService, DataSource dataSource, PlayerCache playerCache) { this.plugin = plugin; this.sched = this.plugin.getServer().getScheduler(); - this.settings = settings; + this.processService = processService; + this.dataSource = dataSource; + this.playerCache = playerCache; + + // FIXME don't pass settings anymore -> go through the service in the processes + this.settings = processService.getSettings(); } public void performLogin(final Player player, final String password, final boolean forceLogin) { @@ -39,7 +47,7 @@ public class Management { @Override public void run() { - new AsynchronousLogin(player, password, forceLogin, plugin, plugin.getDataSource(), settings) + new AsynchronousLogin(player, password, forceLogin, plugin, dataSource, settings) .process(); } }); @@ -60,7 +68,7 @@ public class Management { @Override public void run() { - new AsyncRegister(player, password, email, plugin, plugin.getDataSource(), settings).process(); + new AsyncRegister(player, password, email, plugin, dataSource, settings).process(); } }); } @@ -80,7 +88,7 @@ public class Management { @Override public void run() { - new AsynchronousJoin(player, plugin, plugin.getDataSource()).process(); + new AsynchronousJoin(player, plugin, dataSource).process(); } }); @@ -91,28 +99,26 @@ public class Management { @Override public void run() { - new AsynchronousQuit(player, plugin, plugin.getDataSource(), isKick).process(); + new AsynchronousQuit(player, plugin, dataSource, isKick).process(); } }); } public void performAddEmail(final Player player, final String newEmail) { - sched.runTaskAsynchronously(plugin, new Runnable() { - @Override - public void run() { - new AsyncAddEmail(player, plugin, newEmail, plugin.getDataSource(), - PlayerCache.getInstance(), settings).process(); - } - }); + runTask(new AsyncAddEmail(player, newEmail, dataSource, playerCache, processService)); } public void performChangeEmail(final Player player, final String oldEmail, final String newEmail) { sched.runTaskAsynchronously(plugin, new Runnable() { @Override public void run() { - new AsyncChangeEmail(player, plugin, oldEmail, newEmail, plugin.getDataSource(), PlayerCache.getInstance(), settings).process(); + new AsyncChangeEmail(player, plugin, oldEmail, newEmail, dataSource, playerCache, settings).process(); } }); } + + private void runTask(Process process) { + sched.runTaskAsynchronously(plugin, process); + } } diff --git a/src/main/java/fr/xephi/authme/process/Process.java b/src/main/java/fr/xephi/authme/process/Process.java new file mode 100644 index 00000000..d6efd2b2 --- /dev/null +++ b/src/main/java/fr/xephi/authme/process/Process.java @@ -0,0 +1,8 @@ +package fr.xephi.authme.process; + +/** + * Common interface for AuthMe processes. + */ +public interface Process extends Runnable { + +} diff --git a/src/main/java/fr/xephi/authme/process/ProcessService.java b/src/main/java/fr/xephi/authme/process/ProcessService.java new file mode 100644 index 00000000..0eaddf01 --- /dev/null +++ b/src/main/java/fr/xephi/authme/process/ProcessService.java @@ -0,0 +1,34 @@ +package fr.xephi.authme.process; + +import fr.xephi.authme.output.MessageKey; +import fr.xephi.authme.output.Messages; +import fr.xephi.authme.settings.NewSetting; +import fr.xephi.authme.settings.domain.Property; +import org.bukkit.command.CommandSender; + +/** + * Service for asynchronous and synchronous processes. + */ +public class ProcessService { + + private final NewSetting settings; + private final Messages messages; + + public ProcessService(NewSetting settings, Messages messages) { + this.settings = settings; + this.messages = messages; + } + + public T getProperty(Property property) { + return settings.getProperty(property); + } + + public NewSetting getSettings() { + return settings; + } + + public void send(CommandSender sender, MessageKey key) { + messages.send(sender, key); + } + +} diff --git a/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java b/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java index d5908820..d1e49b93 100644 --- a/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java +++ b/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java @@ -1,40 +1,38 @@ package fr.xephi.authme.process.email; -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.datasource.DataSource; import fr.xephi.authme.output.MessageKey; -import fr.xephi.authme.output.Messages; -import fr.xephi.authme.settings.NewSetting; -import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.process.Process; +import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.util.Utils; import org.bukkit.entity.Player; /** * Async task to add an email to an account. */ -public class AsyncAddEmail { +public class AsyncAddEmail implements Process { private final Player player; private final String email; - private final Messages messages; + private final ProcessService service; private final DataSource dataSource; private final PlayerCache playerCache; - private final NewSetting settings; - public AsyncAddEmail(Player player, AuthMe plugin, String email, DataSource dataSource, - PlayerCache playerCache, NewSetting settings) { - this.messages = plugin.getMessages(); + public AsyncAddEmail(Player player, String email, DataSource dataSource, PlayerCache playerCache, + ProcessService service) { this.player = player; this.email = email; this.dataSource = dataSource; this.playerCache = playerCache; - this.settings = settings; + this.service = service; } - public void process() { + @Override + public void run() { String playerName = player.getName().toLowerCase(); if (playerCache.isAuthenticated(playerName)) { @@ -42,19 +40,19 @@ public class AsyncAddEmail { final String currentEmail = auth.getEmail(); if (currentEmail != null && !"your@email.com".equals(currentEmail)) { - messages.send(player, MessageKey.USAGE_CHANGE_EMAIL); - } else if (!Utils.isEmailCorrect(email, settings)) { - messages.send(player, MessageKey.INVALID_EMAIL); + service.send(player, MessageKey.USAGE_CHANGE_EMAIL); + } else if (!Utils.isEmailCorrect(email, service.getSettings())) { + service.send(player, MessageKey.INVALID_EMAIL); } else if (dataSource.isEmailStored(email)) { - messages.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR); + service.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR); } else { auth.setEmail(email); if (dataSource.updateEmail(auth)) { playerCache.updatePlayer(auth); - messages.send(player, MessageKey.EMAIL_ADDED_SUCCESS); + service.send(player, MessageKey.EMAIL_ADDED_SUCCESS); } else { ConsoleLogger.showError("Could not save email for player '" + player + "'"); - messages.send(player, MessageKey.ERROR); + service.send(player, MessageKey.ERROR); } } } else { @@ -64,11 +62,11 @@ public class AsyncAddEmail { private void sendUnloggedMessage(DataSource dataSource) { if (dataSource.isAuthAvailable(player.getName())) { - messages.send(player, MessageKey.LOGIN_MESSAGE); - } else if (Settings.emailRegistration) { - messages.send(player, MessageKey.REGISTER_EMAIL_MESSAGE); + service.send(player, MessageKey.LOGIN_MESSAGE); + } else if (service.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)) { + service.send(player, MessageKey.REGISTER_EMAIL_MESSAGE); } else { - messages.send(player, MessageKey.REGISTER_MESSAGE); + service.send(player, MessageKey.REGISTER_MESSAGE); } } diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index c53869c0..fecbdfb2 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -60,7 +60,7 @@ public final class Settings { useCaptcha, emailRegistration, multiverse, bungee, banUnsafeIp, doubleEmailCheck, sessionExpireOnIpChange, disableSocialSpy, useEssentialsMotd, usePurge, - purgePlayerDat, purgeEssentialsFile, supportOldPassword, + purgePlayerDat, purgeEssentialsFile, purgeLimitedCreative, purgeAntiXray, purgePermissions, enableProtection, enableAntiBot, recallEmail, useWelcomeMessage, broadcastWelcomeMessage, forceRegKick, forceRegLogin, @@ -72,19 +72,16 @@ public final class Settings { getMySQLColumnGroup, unRegisteredGroup, backupWindowsPath, getRegisteredGroup, rakamakUsers, rakamakUsersIp, getmailAccount, defaultWorld, - getPhpbbPrefix, getWordPressPrefix, spawnPriority, crazyloginFileName, getPassRegex, sendPlayerTo; public static int getWarnMessageInterval, getSessionTimeout, getRegistrationTimeout, getMaxNickLength, getMinNickLength, getPasswordMinLen, getMovementRadius, getmaxRegPerIp, getNonActivatedGroup, passwordMaxLength, getRecoveryPassLength, getMailPort, maxLoginTry, captchaLength, saltLength, - getmaxRegPerEmail, bCryptLog2Rounds, getPhpbbGroup, + getmaxRegPerEmail, bCryptLog2Rounds, antiBotSensibility, antiBotDuration, delayRecall, getMaxLoginPerIp, getMaxJoinPerIp; protected static FileConfiguration configFile; - private static AuthMe plugin; - private static Settings instance; /** * Constructor for Settings. @@ -92,13 +89,11 @@ public final class Settings { * @param pl AuthMe */ public Settings(AuthMe pl) { - instance = this; - plugin = pl; - configFile = plugin.getConfig(); + configFile = pl.getConfig(); loadVariables(); } - public static void loadVariables() { + private static void loadVariables() { isPermissionCheckEnabled = load(PluginSettings.ENABLE_PERMISSION_CHECK); isForcedRegistrationEnabled = configFile.getBoolean("settings.registration.force", true); isRegistrationEnabled = configFile.getBoolean("settings.registration.enabled", true); @@ -172,7 +167,7 @@ public final class Settings { useCaptcha = configFile.getBoolean("Security.captcha.useCaptcha", false); maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5); captchaLength = configFile.getInt("Security.captcha.captchaLength", 5); - emailRegistration = configFile.getBoolean("settings.registration.enableEmailRegistrationSystem", false); + emailRegistration = load(RegistrationSettings.USE_EMAIL_REGISTRATION); saltLength = configFile.getInt("settings.security.doubleMD5SaltLength", 8); getmaxRegPerEmail = configFile.getInt("Email.maxRegPerEmail", 1); multiverse = load(HooksSettings.MULTIVERSE); @@ -190,10 +185,6 @@ public final class Settings { purgePlayerDat = configFile.getBoolean("Purge.removePlayerDat", false); purgeEssentialsFile = configFile.getBoolean("Purge.removeEssentialsFile", false); defaultWorld = configFile.getString("Purge.defaultWorld", "world"); - getPhpbbPrefix = configFile.getString("ExternalBoardOptions.phpbbTablePrefix", "phpbb_"); - getPhpbbGroup = configFile.getInt("ExternalBoardOptions.phpbbActivatedGroupId", 2); - supportOldPassword = configFile.getBoolean("settings.security.supportOldPasswordHash", false); - getWordPressPrefix = configFile.getString("ExternalBoardOptions.wordpressTablePrefix", "wp_"); purgeLimitedCreative = configFile.getBoolean("Purge.removeLimitedCreativesInventories", false); purgeAntiXray = configFile.getBoolean("Purge.removeAntiXRayFile", false); purgePermissions = configFile.getBoolean("Purge.removePermissions", false); diff --git a/src/main/java/fr/xephi/authme/task/ChangePasswordTask.java b/src/main/java/fr/xephi/authme/task/ChangePasswordTask.java index 0551b8ca..c5ff5b95 100644 --- a/src/main/java/fr/xephi/authme/task/ChangePasswordTask.java +++ b/src/main/java/fr/xephi/authme/task/ChangePasswordTask.java @@ -53,12 +53,12 @@ public class ChangePasswordTask implements Runnable { @Override public void run() { - ByteArrayDataOutput out = ByteStreams.newDataOutput(); - out.writeUTF("Forward"); - out.writeUTF("ALL"); - out.writeUTF("AuthMe"); - out.writeUTF("changepassword;" + name + ";" + hash + ";" + salt); - player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray()); + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("Forward"); + out.writeUTF("ALL"); + out.writeUTF("AuthMe"); + out.writeUTF("changepassword;" + name + ";" + hash + ";" + salt); + player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray()); } }); } diff --git a/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java b/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java index 7cc7c55d..5c165039 100644 --- a/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java +++ b/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java @@ -1,14 +1,13 @@ package fr.xephi.authme.process.email; -import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLoggerTestInitializer; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.output.MessageKey; -import fr.xephi.authme.output.Messages; +import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.settings.NewSetting; -import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.util.WrapperMock; import org.bukkit.entity.Player; import org.junit.After; @@ -27,11 +26,10 @@ import static org.mockito.Mockito.when; */ public class AsyncAddEmailTest { - private Messages messages; private Player player; private DataSource dataSource; private PlayerCache playerCache; - private NewSetting settings; + private ProcessService service; @BeforeClass public static void setUp() { @@ -42,10 +40,10 @@ public class AsyncAddEmailTest { // Clean up the fields to ensure that no test uses elements of another test @After public void removeFieldValues() { - messages = null; player = null; dataSource = null; playerCache = null; + service = null; } @Test @@ -61,11 +59,11 @@ public class AsyncAddEmailTest { given(dataSource.updateEmail(any(PlayerAuth.class))).willReturn(true); // when - process.process(); + process.run(); // then verify(dataSource).updateEmail(auth); - verify(messages).send(player, MessageKey.EMAIL_ADDED_SUCCESS); + verify(service).send(player, MessageKey.EMAIL_ADDED_SUCCESS); verify(auth).setEmail("my.mail@example.org"); verify(playerCache).updatePlayer(auth); } @@ -83,11 +81,11 @@ public class AsyncAddEmailTest { given(dataSource.updateEmail(any(PlayerAuth.class))).willReturn(false); // when - process.process(); + process.run(); // then verify(dataSource).updateEmail(auth); - verify(messages).send(player, MessageKey.ERROR); + verify(service).send(player, MessageKey.ERROR); } @Test @@ -102,10 +100,10 @@ public class AsyncAddEmailTest { given(dataSource.isEmailStored("some.mail@example.org")).willReturn(false); // when - process.process(); + process.run(); // then - verify(messages).send(player, MessageKey.USAGE_CHANGE_EMAIL); + verify(service).send(player, MessageKey.USAGE_CHANGE_EMAIL); verify(playerCache, never()).updatePlayer(any(PlayerAuth.class)); } @@ -121,10 +119,10 @@ public class AsyncAddEmailTest { given(dataSource.isEmailStored("invalid_mail")).willReturn(false); // when - process.process(); + process.run(); // then - verify(messages).send(player, MessageKey.INVALID_EMAIL); + verify(service).send(player, MessageKey.INVALID_EMAIL); verify(playerCache, never()).updatePlayer(any(PlayerAuth.class)); } @@ -140,10 +138,10 @@ public class AsyncAddEmailTest { given(dataSource.isEmailStored("player@mail.tld")).willReturn(true); // when - process.process(); + process.run(); // then - verify(messages).send(player, MessageKey.EMAIL_ALREADY_USED_ERROR); + verify(service).send(player, MessageKey.EMAIL_ALREADY_USED_ERROR); verify(playerCache, never()).updatePlayer(any(PlayerAuth.class)); } @@ -156,10 +154,10 @@ public class AsyncAddEmailTest { given(dataSource.isAuthAvailable("Username12")).willReturn(true); // when - process.process(); + process.run(); // then - verify(messages).send(player, MessageKey.LOGIN_MESSAGE); + verify(service).send(player, MessageKey.LOGIN_MESSAGE); verify(playerCache, never()).updatePlayer(any(PlayerAuth.class)); } @@ -170,13 +168,13 @@ public class AsyncAddEmailTest { given(player.getName()).willReturn("user"); given(playerCache.isAuthenticated("user")).willReturn(false); given(dataSource.isAuthAvailable("user")).willReturn(false); - Settings.emailRegistration = true; + given(service.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true); // when - process.process(); + process.run(); // then - verify(messages).send(player, MessageKey.REGISTER_EMAIL_MESSAGE); + verify(service).send(player, MessageKey.REGISTER_EMAIL_MESSAGE); verify(playerCache, never()).updatePlayer(any(PlayerAuth.class)); } @@ -187,13 +185,13 @@ public class AsyncAddEmailTest { given(player.getName()).willReturn("user"); given(playerCache.isAuthenticated("user")).willReturn(false); given(dataSource.isAuthAvailable("user")).willReturn(false); - Settings.emailRegistration = false; + given(service.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(false); // when - process.process(); + process.run(); // then - verify(messages).send(player, MessageKey.REGISTER_MESSAGE); + verify(service).send(player, MessageKey.REGISTER_MESSAGE); verify(playerCache, never()).updatePlayer(any(PlayerAuth.class)); } @@ -204,14 +202,12 @@ public class AsyncAddEmailTest { * @return The created process */ private AsyncAddEmail createProcess(String email) { - messages = mock(Messages.class); - AuthMe authMe = mock(AuthMe.class); - when(authMe.getMessages()).thenReturn(messages); player = mock(Player.class); dataSource = mock(DataSource.class); playerCache = mock(PlayerCache.class); - settings = mock(NewSetting.class); - return new AsyncAddEmail(player, authMe, email, dataSource, playerCache, settings); + service = mock(ProcessService.class); + when(service.getSettings()).thenReturn(mock(NewSetting.class)); + return new AsyncAddEmail(player, email, dataSource, playerCache, service); } } From c61345fd4386632525e0b8e1859d41c66566c642 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 28 Feb 2016 00:32:14 +0100 Subject: [PATCH 21/46] cleanup + fix test crypts test on windows systems --- pom.xml | 25 +++++++++++++------ .../process/login/ProcessSyncPlayerLogin.java | 2 -- .../fr/xephi/authme/settings/Settings.java | 2 -- .../java/fr/xephi/authme/util/Profiler.java | 4 +-- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index f913596b..07150f08 100644 --- a/pom.xml +++ b/pom.xml @@ -48,7 +48,9 @@ + UTF-8 + UTF-8 AuthMe @@ -57,9 +59,6 @@ Xephi, sgdc3, DNx5, timvisee, games647, ljacqu Unknown - - 1.7 - 1.9-pre1-SNAPSHOT @@ -147,14 +146,26 @@ - + org.apache.maven.plugins maven-compiler-plugin 3.5.1 - 1.7 - ${javaVersion} + 1.8 + 1.8 + + 1.7 + 1.7 + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.15 + + -Dfile.encoding=UTF-8 @@ -717,7 +728,7 @@ net.minelink CombatTagPlus - 1.2.1-SNAPSHOT + 1.2.2-SNAPSHOT provided diff --git a/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java b/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java index 0c120b52..78995cb1 100644 --- a/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java @@ -38,7 +38,6 @@ public class ProcessSyncPlayerLogin implements Runnable { private final String name; private final PlayerAuth auth; private final AuthMe plugin; - private final DataSource database; private final PluginManager pm; private final JsonCache playerCache; private final NewSetting settings; @@ -54,7 +53,6 @@ public class ProcessSyncPlayerLogin implements Runnable { public ProcessSyncPlayerLogin(Player player, AuthMe plugin, DataSource database, NewSetting settings) { this.plugin = plugin; - this.database = database; this.pm = plugin.getServer().getPluginManager(); this.player = player; this.name = player.getName().toLowerCase(); diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index c53869c0..839e3737 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -84,7 +84,6 @@ public final class Settings { getMaxJoinPerIp; protected static FileConfiguration configFile; private static AuthMe plugin; - private static Settings instance; /** * Constructor for Settings. @@ -92,7 +91,6 @@ public final class Settings { * @param pl AuthMe */ public Settings(AuthMe pl) { - instance = this; plugin = pl; configFile = plugin.getConfig(); loadVariables(); diff --git a/src/main/java/fr/xephi/authme/util/Profiler.java b/src/main/java/fr/xephi/authme/util/Profiler.java index 0784aa65..73bdf5e4 100644 --- a/src/main/java/fr/xephi/authme/util/Profiler.java +++ b/src/main/java/fr/xephi/authme/util/Profiler.java @@ -2,15 +2,13 @@ package fr.xephi.authme.util; import java.text.DecimalFormat; -/** - */ -@SuppressWarnings("UnusedDeclaration") public class Profiler { /** * Defines the past time in milliseconds. */ private long time = 0; + /** * Defines the time in milliseconds the profiler last started at. */ From e88b4eda53ba61b7f4b1dd422598687e42d485a6 Mon Sep 17 00:00:00 2001 From: Xephi59 Date: Sun, 28 Feb 2016 00:36:06 +0100 Subject: [PATCH 22/46] Add %acc_nb tag to max_reg message - Fix #570 --- .../java/fr/xephi/authme/output/MessageKey.java | 2 +- .../authme/process/register/AsyncRegister.java | 15 +++++++++------ src/main/resources/messages/messages_en.yml | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/fr/xephi/authme/output/MessageKey.java b/src/main/java/fr/xephi/authme/output/MessageKey.java index 45cdc0be..0c96b666 100644 --- a/src/main/java/fr/xephi/authme/output/MessageKey.java +++ b/src/main/java/fr/xephi/authme/output/MessageKey.java @@ -41,7 +41,7 @@ public enum MessageKey { REGISTER_EMAIL_MESSAGE("reg_email_msg"), - MAX_REGISTER_EXCEEDED("max_reg"), + MAX_REGISTER_EXCEEDED("max_reg", "%acc_nb"), USAGE_REGISTER("usage_reg"), 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 e17c511d..97344ba0 100644 --- a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java @@ -1,5 +1,8 @@ package fr.xephi.authme.process.register; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + import fr.xephi.authme.AuthMe; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; @@ -13,8 +16,6 @@ import fr.xephi.authme.security.crypts.TwoFactor; import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.StringUtils; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; /** */ @@ -71,6 +72,7 @@ public class AsyncRegister { } //check this in both possiblities so don't use 'else if' + Integer size = 0; if (database.isAuthAvailable(name)) { m.send(player, MessageKey.NAME_ALREADY_REGISTERED); return false; @@ -78,8 +80,8 @@ public class AsyncRegister { && !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.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); + && (size = database.getAllAuthsByIp(ip).size()) >= Settings.getmaxRegPerIp) { + m.send(player, MessageKey.MAX_REGISTER_EXCEEDED, size.toString()); return false; } return true; @@ -96,10 +98,11 @@ public class AsyncRegister { } private void emailRegister() { + Integer size = 0; if (Settings.getmaxRegPerEmail > 0 && !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS) - && database.countAuthsByEmail(email) >= Settings.getmaxRegPerEmail) { - m.send(player, MessageKey.MAX_REGISTER_EXCEEDED); + && (size = database.countAuthsByEmail(email)) >= Settings.getmaxRegPerEmail) { + m.send(player, MessageKey.MAX_REGISTER_EXCEEDED, size.toString()); return; } final HashedPassword hashedPassword = plugin.getPasswordSecurity().computeHash(password, name); diff --git a/src/main/resources/messages/messages_en.yml b/src/main/resources/messages/messages_en.yml index 1b1ae61e..4e155bcf 100644 --- a/src/main/resources/messages/messages_en.yml +++ b/src/main/resources/messages/messages_en.yml @@ -12,7 +12,7 @@ login: '&2Successful login!' vb_nonActiv: '&cYour account isn''t activated yet, please check your emails!' user_regged: '&cYou already have registered this username!' usage_reg: '&cUsage: /register ' -max_reg: '&cYou have exceeded the maximum number of registrations for your connection!' +max_reg: '&cYou have exceeded the maximum number of registrations (%acc_nb) for your connection!' no_perm: '&4You don''t have the permission to perform this action!' error: '&4An unexpected error occurred, please contact an administrator!' login_msg: '&cPlease, login with the command "/login "' From a233b0e685fb3167fcfb37d91e7923990e8a4a10 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 28 Feb 2016 00:37:29 +0100 Subject: [PATCH 23/46] Update circle.yml --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index dea5e80c..80201e5e 100644 --- a/circle.yml +++ b/circle.yml @@ -1,6 +1,6 @@ machine: java: - version: oraclejdk7 + version: oraclejdk8 general: artifacts: - "target/AuthMe-*.jar" From 89256debc86a6b143db78931f9d2cbada1282e44 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 28 Feb 2016 00:37:47 +0100 Subject: [PATCH 24/46] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1645036e..3eab0c37 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ sudo: false language: java -jdk: oraclejdk7 +jdk: oraclejdk8 cache: directories: From 3c82a5a9361f4a26bff7954c30808f696f8d490d Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 28 Feb 2016 02:02:27 +0100 Subject: [PATCH 25/46] Fix test arguments --- pom.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 07150f08..b67f2b6a 100644 --- a/pom.xml +++ b/pom.xml @@ -163,9 +163,11 @@ org.apache.maven.plugins maven-surefire-plugin - 2.15 + 2.19.1 - -Dfile.encoding=UTF-8 + 3 + true + ${argLine} -Xmx512M -Dfile.encoding=UTF-8 From a96a98e4edbcb0f03c108f0718d0b64ead6252d3 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 28 Feb 2016 02:28:37 +0100 Subject: [PATCH 26/46] Speed up junit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b67f2b6a..45d9d28b 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@ 3 true - ${argLine} -Xmx512M -Dfile.encoding=UTF-8 + ${argLine} -client -Xmx512M -Dfile.encoding=UTF-8 From cfdc99cfe64bb1aae26b4baf9c772631df63b0d1 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 28 Feb 2016 03:04:43 +0100 Subject: [PATCH 27/46] Should fix mvn param --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 45d9d28b..39bb5567 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@ 3 true - ${argLine} -client -Xmx512M -Dfile.encoding=UTF-8 + -client -Xmx512M -Dfile.encoding=UTF-8 ${argLine} From aaf17e6272975758a1e9cf3d286903d9a9b96dda Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 28 Feb 2016 03:14:36 +0100 Subject: [PATCH 28/46] Damn mvn args --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 39bb5567..50a8fbfe 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@ 3 true - -client -Xmx512M -Dfile.encoding=UTF-8 ${argLine} + -Xmx512M -Dfile.encoding=UTF-8 ${argLine} From 90a0202b49eb1296ee468710adfdbc5b5b1162c0 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 28 Feb 2016 03:21:07 +0100 Subject: [PATCH 29/46] Fixed, finally! Was a jenkins side issue! --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 50a8fbfe..39bb5567 100644 --- a/pom.xml +++ b/pom.xml @@ -167,7 +167,7 @@ 3 true - -Xmx512M -Dfile.encoding=UTF-8 ${argLine} + -client -Xmx512M -Dfile.encoding=UTF-8 ${argLine} From 8832c1ac0f4250bce97ad78886f11e113ab7af95 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 28 Feb 2016 09:05:30 +0100 Subject: [PATCH 30/46] Reduce output of resource closing tests --- .../xephi/authme/datasource/AbstractResourceClosingTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java b/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java index 5b215a90..f5ba58e8 100644 --- a/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java +++ b/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java @@ -167,7 +167,9 @@ public abstract class AbstractResourceClosingTest { * Verify that all AutoCloseables that have been created during the method execution have been closed. */ private void verifyHaveMocksBeenClosed() { - System.out.println("Found " + closeables.size() + " resources"); + if (closeables.isEmpty()) { + System.out.println("Note: detected no AutoCloseables for method '" + method.getName() + "'"); + } try { for (AutoCloseable autoCloseable : closeables) { verify(autoCloseable).close(); From 2a9ab60fcde07f8a6ba8eb130b287c3f5163e63b Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 28 Feb 2016 19:11:22 +0100 Subject: [PATCH 31/46] Pom cleanup --- pom.xml | 152 ++++++++++++++++---------------------------------------- 1 file changed, 42 insertions(+), 110 deletions(-) diff --git a/pom.xml b/pom.xml index 39bb5567..71df4db6 100644 --- a/pom.xml +++ b/pom.xml @@ -48,21 +48,25 @@ - - UTF-8 - UTF-8 - + UTF-8 + ${projectEncoding} + ${projectEncoding} + 1.7 + 1.7 + + AuthMe ${pluginName}-${project.version} - fr.xephi.authme.AuthMe + ${project.groupId}.${project.artifactId}.${pluginName} Xephi, sgdc3, DNx5, timvisee, games647, ljacqu Unknown - 1.9-pre1-SNAPSHOT + 1.8.8-R0.1-SNAPSHOT + jenkins @@ -83,33 +87,21 @@ src/test/java - - . - true - src/main/resources/ - - plugin.yml - - - - . - true - src/main/resources/ - - email.html - welcome.txt - - . false + . + + LICENSE + + + + . + true src/main/resources/ - *.yml + * - - plugin.yml - ./messages/ @@ -126,37 +118,17 @@ - - - - - net.orfjackal.retrolambda - retrolambda-maven-plugin - 2.1.0 - - - - process-main - process-test - - - - - - - - + org.apache.maven.plugins maven-compiler-plugin 3.5.1 - 1.8 - 1.8 - - 1.7 - 1.7 + ${jdkVersion} + ${jdkVersion} + ${testJreVersion} + ${testJreVersion} @@ -165,9 +137,7 @@ maven-surefire-plugin 2.19.1 - 3 - true - -client -Xmx512M -Dfile.encoding=UTF-8 ${argLine} + -Dfile.encoding=${projectEncoding} ${argLine} @@ -195,33 +165,11 @@ - + com.google.gson fr.xephi.authme.libs.google - - org.mcstats - fr.xephi.authme - - com.zaxxer.hikari fr.xephi.authme.libs.hikari @@ -238,6 +186,11 @@ net.ricecode.similarity fr.xephi.authme.libs.similarity + + + org.mcstats + fr.xephi.authme + target/${jarName}-spigot.jar @@ -249,34 +202,12 @@ shade - + com.google fr.xephi.authme.libs.google - - org.mcstats - fr.xephi.authme - - com.zaxxer.hikari fr.xephi.authme.libs.hikari @@ -293,6 +224,11 @@ net.ricecode.similarity fr.xephi.authme.libs.similarity + + + org.mcstats + fr.xephi.authme + target/${jarName}-legacy.jar @@ -303,7 +239,7 @@ org.jacoco jacoco-maven-plugin - 0.7.5.201505241946 + 0.7.6.201602180812 prepare-agent @@ -318,7 +254,7 @@ org.eluder.coveralls coveralls-maven-plugin 4.1.0 - + @@ -328,7 +264,10 @@ UTF-8 UTF-8 + false true + public + false @@ -391,13 +330,6 @@ - - - org.projectlombok - lombok - 1.16.6 - provided - com.zaxxer From dede592c5565c8b9cda17bd4db1bc0d5e9cb453d Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 28 Feb 2016 20:03:06 +0100 Subject: [PATCH 32/46] #547 add process service to AsyncJoin --- src/main/java/fr/xephi/authme/AuthMe.java | 11 +- .../fr/xephi/authme/process/Management.java | 9 +- .../xephi/authme/process/ProcessService.java | 31 +++- .../authme/process/join/AsynchronousJoin.java | 140 +++++++++--------- .../fr/xephi/authme/settings/Settings.java | 22 +-- .../properties/RestrictionSettings.java | 2 +- src/main/java/fr/xephi/authme/util/Utils.java | 6 +- 7 files changed, 117 insertions(+), 104 deletions(-) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index f70229b9..047cf408 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -305,7 +305,7 @@ public class AuthMe extends JavaPlugin { setupApi(); // Set up the management - ProcessService processService = new ProcessService(newSettings, messages); + ProcessService processService = new ProcessService(newSettings, messages, this); management = new Management(this, processService, database, PlayerCache.getInstance()); // Set up the BungeeCord hook @@ -861,15 +861,6 @@ public class AuthMe extends JavaPlugin { return count >= Settings.getMaxLoginPerIp; } - public boolean hasJoinedIp(String name, String ip) { - int count = 0; - for (Player player : Utils.getOnlinePlayers()) { - if (ip.equalsIgnoreCase(getIP(player)) && !player.getName().equalsIgnoreCase(name)) - count++; - } - return count >= Settings.getMaxJoinPerIp; - } - /** * Handle Bukkit commands. * diff --git a/src/main/java/fr/xephi/authme/process/Management.java b/src/main/java/fr/xephi/authme/process/Management.java index fe7022be..a42884ae 100644 --- a/src/main/java/fr/xephi/authme/process/Management.java +++ b/src/main/java/fr/xephi/authme/process/Management.java @@ -84,14 +84,7 @@ public class Management { } public void performJoin(final Player player) { - sched.runTaskAsynchronously(plugin, new Runnable() { - - @Override - public void run() { - new AsynchronousJoin(player, plugin, dataSource).process(); - } - - }); + runTask(new AsynchronousJoin(player, plugin, dataSource, playerCache, processService)); } public void performQuit(final Player player, final boolean isKick) { diff --git a/src/main/java/fr/xephi/authme/process/ProcessService.java b/src/main/java/fr/xephi/authme/process/ProcessService.java index 0eaddf01..e52e4235 100644 --- a/src/main/java/fr/xephi/authme/process/ProcessService.java +++ b/src/main/java/fr/xephi/authme/process/ProcessService.java @@ -1,10 +1,13 @@ package fr.xephi.authme.process; +import fr.xephi.authme.AuthMe; import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.Messages; import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.domain.Property; import org.bukkit.command.CommandSender; +import org.bukkit.event.Event; +import org.bukkit.scheduler.BukkitTask; /** * Service for asynchronous and synchronous processes. @@ -13,10 +16,12 @@ public class ProcessService { private final NewSetting settings; private final Messages messages; + private final AuthMe authMe; - public ProcessService(NewSetting settings, Messages messages) { + public ProcessService(NewSetting settings, Messages messages, AuthMe authMe) { this.settings = settings; this.messages = messages; + this.authMe = authMe; } public T getProperty(Property property) { @@ -31,4 +36,28 @@ public class ProcessService { messages.send(sender, key); } + public String retrieveMessage(MessageKey key) { + return messages.retrieveSingle(key); + } + + public BukkitTask runTask(Runnable task) { + return authMe.getServer().getScheduler().runTask(authMe, task); + } + + public BukkitTask runTaskLater(Runnable task, long delay) { + return authMe.getServer().getScheduler().runTaskLater(authMe, task, delay); + } + + public int scheduleSyncDelayedTask(Runnable task) { + return authMe.getServer().getScheduler().scheduleSyncDelayedTask(authMe, task); + } + + public void callEvent(Event event) { + authMe.getServer().getPluginManager().callEvent(event); + } + + public AuthMe getAuthMe() { + return authMe; + } + } 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 e1b6096b..455c7683 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -11,66 +11,71 @@ import fr.xephi.authme.events.ProtectInventoryEvent; import fr.xephi.authme.events.SpawnTeleportEvent; import fr.xephi.authme.listener.AuthMePlayerListener; import fr.xephi.authme.output.MessageKey; -import fr.xephi.authme.output.Messages; import fr.xephi.authme.permission.PlayerStatePermission; +import fr.xephi.authme.process.Process; +import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Spawn; +import fr.xephi.authme.settings.properties.HooksSettings; +import fr.xephi.authme.settings.properties.PluginSettings; +import fr.xephi.authme.settings.properties.RegistrationSettings; +import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.TimeoutTask; import fr.xephi.authme.util.Utils; import fr.xephi.authme.util.Utils.GroupType; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitTask; /** */ -public class AsynchronousJoin { +public class AsynchronousJoin implements Process { private final AuthMe plugin; private final Player player; private final DataSource database; private final String name; - private final Messages m; - private final BukkitScheduler sched; + private final ProcessService service; + private final PlayerCache playerCache; - public AsynchronousJoin(Player player, AuthMe plugin, DataSource database) { - this.m = plugin.getMessages(); + public AsynchronousJoin(Player player, AuthMe plugin, DataSource database, PlayerCache playerCache, + ProcessService service) { this.player = player; this.plugin = plugin; - this.sched = plugin.getServer().getScheduler(); this.database = database; this.name = player.getName().toLowerCase(); + this.service = service; + this.playerCache = playerCache; } - public void process() { + @Override + public void run() { if (Utils.isUnrestricted(player)) { return; } - if (Settings.checkVeryGames) { + if (service.getProperty(HooksSettings.ENABLE_VERYGAMES_IP_CHECK)) { plugin.getVerygamesIp(player); } - if (plugin.ess != null && Settings.disableSocialSpy) { + if (plugin.ess != null && service.getProperty(HooksSettings.DISABLE_SOCIAL_SPY)) { plugin.ess.getUser(player).setSocialSpyEnabled(false); } final String ip = plugin.getIP(player); - if (Settings.isAllowRestrictedIp && isNameRestricted(name, ip, player.getAddress().getHostName())) { - sched.scheduleSyncDelayedTask(plugin, new Runnable() { - + if (isNameRestricted(name, ip, player.getAddress().getHostName(), service.getSettings())) { + service.scheduleSyncDelayedTask(new Runnable() { @Override public void run() { AuthMePlayerListener.causeByAuthMe.putIfAbsent(name, true); - player.kickPlayer(m.retrieveSingle(MessageKey.NOT_OWNER_ERROR)); + player.kickPlayer(service.retrieveMessage(MessageKey.NOT_OWNER_ERROR)); if (Settings.banUnsafeIp) { plugin.getServer().banIP(ip); } @@ -78,38 +83,34 @@ public class AsynchronousJoin { }); return; } - if (Settings.getMaxJoinPerIp > 0 + if (service.getProperty(RestrictionSettings.MAX_JOIN_PER_IP) > 0 && !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS) - && !ip.equalsIgnoreCase("127.0.0.1") - && !ip.equalsIgnoreCase("localhost") - && plugin.hasJoinedIp(player.getName(), ip)) { - sched.scheduleSyncDelayedTask(plugin, new Runnable() { - + && !"127.0.0.1".equalsIgnoreCase(ip) + && !"localhost".equalsIgnoreCase(ip) + && hasJoinedIp(player.getName(), ip, service.getSettings(), service.getAuthMe())) { + service.scheduleSyncDelayedTask(new Runnable() { @Override public void run() { player.kickPlayer("A player with the same IP is already in game!"); } - }); return; } - final Location spawnLoc = plugin.getSpawnLocation(player); + final Location spawnLoc = Spawn.getInstance().getSpawnLocation(player); final boolean isAuthAvailable = database.isAuthAvailable(name); if (isAuthAvailable) { if (!Settings.noTeleport) { if (Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) { - sched.scheduleSyncDelayedTask(plugin, new Runnable() { - + service.scheduleSyncDelayedTask(new Runnable() { @Override public void run() { - SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name)); - plugin.getServer().getPluginManager().callEvent(tpEvent); + SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, playerCache.isAuthenticated(name)); + service.callEvent(tpEvent); if (!tpEvent.isCancelled() && player.isOnline() && tpEvent.getTo() != null && tpEvent.getTo().getWorld() != null) { player.teleport(tpEvent.getTo()); } } - }); } } @@ -123,12 +124,12 @@ public class AsynchronousJoin { if (ev.isCancelled()) { plugin.inventoryProtector.sendInventoryPacket(player); if (!Settings.noConsoleSpam) { - ConsoleLogger.info("ProtectInventoryEvent has been cancelled for " + player.getName() + " ..."); + ConsoleLogger.info("ProtectInventoryEvent has been cancelled for " + player.getName() + "..."); } } } - if (Settings.isSessionsEnabled && (PlayerCache.getInstance().isAuthenticated(name) || database.isLogged(name))) { + if (service.getProperty(PluginSettings.SESSIONS_ENABLED) && (playerCache.isAuthenticated(name) || database.isLogged(name))) { if (plugin.sessions.containsKey(name)) { plugin.sessions.get(name).cancel(); plugin.sessions.remove(name); @@ -137,11 +138,11 @@ public class AsynchronousJoin { database.setUnlogged(name); PlayerCache.getInstance().removePlayer(name); if (auth != null && auth.getIp().equals(ip)) { - m.send(player, MessageKey.SESSION_RECONNECTION); + service.send(player, MessageKey.SESSION_RECONNECTION); plugin.getManagement().performLogin(player, "dontneed", true); return; } else if (Settings.sessionExpireOnIpChange) { - m.send(player, MessageKey.SESSION_EXPIRED); + service.send(player, MessageKey.SESSION_EXPIRED); } } } else { @@ -154,21 +155,18 @@ public class AsynchronousJoin { if (!Settings.noTeleport && !needFirstSpawn() && Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) { - sched.scheduleSyncDelayedTask(plugin, new Runnable() { - + service.scheduleSyncDelayedTask(new Runnable() { @Override public void run() { - SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name)); - plugin.getServer().getPluginManager().callEvent(tpEvent); - if (!tpEvent.isCancelled() && player.isOnline() && tpEvent.getTo() != null - && tpEvent.getTo().getWorld() != null) { - player.teleport(tpEvent.getTo()); + SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name)); + service.callEvent(tpEvent); + if (!tpEvent.isCancelled() && player.isOnline() && tpEvent.getTo() != null + && tpEvent.getTo().getWorld() != null) { + player.teleport(tpEvent.getTo()); + } } - } - }); } - } if (!LimboCache.getInstance().hasLimboPlayer(name)) { @@ -176,9 +174,9 @@ public class AsynchronousJoin { } Utils.setGroup(player, isAuthAvailable ? GroupType.NOTLOGGEDIN : GroupType.UNREGISTERED); - final int timeOut = Settings.getRegistrationTimeout * 20; + final int registrationTimeout = service.getProperty(RestrictionSettings.TIMEOUT) * 20; - sched.scheduleSyncDelayedTask(plugin, new Runnable() { + service.scheduleSyncDelayedTask(new Runnable() { @Override public void run() { player.setOp(false); @@ -186,27 +184,22 @@ public class AsynchronousJoin { player.setFlySpeed(0.0f); player.setWalkSpeed(0.0f); } - player.setNoDamageTicks(timeOut); - if (Settings.useEssentialsMotd) { + player.setNoDamageTicks(registrationTimeout); + if (service.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)) { player.performCommand("motd"); } - if (Settings.applyBlindEffect) { - int blindTimeOut; + if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) { // Allow infinite blindness effect - if (timeOut <= 0) { - blindTimeOut = 99999; - } else { - blindTimeOut = timeOut; - } + int blindTimeOut = (registrationTimeout <= 0) ? 99999 : registrationTimeout; player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, blindTimeOut, 2)); } } }); - int msgInterval = Settings.getWarnMessageInterval; - if (timeOut > 0) { - BukkitTask id = sched.runTaskLater(plugin, new TimeoutTask(plugin, name, player), timeOut); + int msgInterval = service.getProperty(RegistrationSettings.MESSAGE_INTERVAL); + if (registrationTimeout > 0) { + BukkitTask id = service.runTaskLater(new TimeoutTask(plugin, name, player), registrationTimeout); LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id); } @@ -219,7 +212,7 @@ public class AsynchronousJoin { : MessageKey.REGISTER_MESSAGE; } if (msgInterval > 0 && LimboCache.getInstance().getLimboPlayer(name) != null) { - BukkitTask msgTask = sched.runTask(plugin, new MessageTask(plugin, name, msg, msgInterval)); + BukkitTask msgTask = service.runTask(new MessageTask(plugin, name, msg, msgInterval)); LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgTask); } } @@ -235,13 +228,11 @@ public class AsynchronousJoin { if (!tpEvent.isCancelled()) { if (player.isOnline() && tpEvent.getTo() != null && tpEvent.getTo().getWorld() != null) { final Location fLoc = tpEvent.getTo(); - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { - + service.scheduleSyncDelayedTask(new Runnable() { @Override public void run() { player.teleport(fLoc); } - }); } } @@ -249,25 +240,23 @@ public class AsynchronousJoin { } private void placePlayerSafely(final Player player, final Location spawnLoc) { - if (spawnLoc == null) - return; - if (!Settings.noTeleport) + if (spawnLoc == null || service.getProperty(RestrictionSettings.NO_TELEPORT)) return; if (Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) return; if (!player.hasPlayedBefore()) return; - sched.scheduleSyncDelayedTask(plugin, new Runnable() { + service.scheduleSyncDelayedTask(new Runnable() { @Override public void run() { if (spawnLoc.getWorld() == null) { return; } Material cur = player.getLocation().getBlock().getType(); - Material top = player.getLocation().add(0D, 1D, 0D).getBlock().getType(); + Material top = player.getLocation().add(0, 1, 0).getBlock().getType(); if (cur == Material.PORTAL || cur == Material.ENDER_PORTAL || top == Material.PORTAL || top == Material.ENDER_PORTAL) { - m.send(player, MessageKey.UNSAFE_QUIT_LOCATION); + service.send(player, MessageKey.UNSAFE_QUIT_LOCATION); player.teleport(spawnLoc); } } @@ -281,12 +270,17 @@ public class AsynchronousJoin { * @param name The name to check * @param ip The IP address of the player * @param domain The hostname of the IP address + * @param settings The settings instance * @return True if the name is restricted (IP/domain is not allowed for the given name), * false if the restrictions are met or if the name has no restrictions to it */ - private static boolean isNameRestricted(String name, String ip, String domain) { + private static boolean isNameRestricted(String name, String ip, String domain, NewSetting settings) { + if (!settings.getProperty(RestrictionSettings.ENABLE_RESTRICTED_USERS)) { + return false; + } + boolean nameFound = false; - for (String entry : Settings.getRestrictedIp) { + for (String entry : settings.getProperty(RestrictionSettings.ALLOWED_RESTRICTED_USERS)) { String[] args = entry.split(";"); String testName = args[0]; String testIp = args[1]; @@ -301,4 +295,12 @@ public class AsynchronousJoin { return nameFound; } + private boolean hasJoinedIp(String name, String ip, NewSetting settings, AuthMe authMe) { + int count = 0; + for (Player player : Utils.getOnlinePlayers()) { + if (ip.equalsIgnoreCase(authMe.getIP(player)) && !player.getName().equalsIgnoreCase(name)) + count++; + } + return count >= settings.getProperty(RestrictionSettings.MAX_JOIN_PER_IP); + } } diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index fecbdfb2..591e55a0 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -97,19 +97,19 @@ public final class Settings { isPermissionCheckEnabled = load(PluginSettings.ENABLE_PERMISSION_CHECK); isForcedRegistrationEnabled = configFile.getBoolean("settings.registration.force", true); isRegistrationEnabled = configFile.getBoolean("settings.registration.enabled", true); - isTeleportToSpawnEnabled = configFile.getBoolean("settings.restrictions.teleportUnAuthedToSpawn", false); - getWarnMessageInterval = configFile.getInt("settings.registration.messageInterval", 5); - isSessionsEnabled = configFile.getBoolean("settings.sessions.enabled", false); + isTeleportToSpawnEnabled = load(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN); + getWarnMessageInterval = load(RegistrationSettings.MESSAGE_INTERVAL); + isSessionsEnabled = load(PluginSettings.SESSIONS_ENABLED); getSessionTimeout = configFile.getInt("settings.sessions.timeout", 10); - getRegistrationTimeout = configFile.getInt("settings.restrictions.timeout", 30); - isChatAllowed = configFile.getBoolean("settings.restrictions.allowChat", false); + getRegistrationTimeout = load(RestrictionSettings.TIMEOUT); + isChatAllowed = load(RestrictionSettings.ALLOW_CHAT); getMaxNickLength = configFile.getInt("settings.restrictions.maxNicknameLength", 20); getMinNickLength = configFile.getInt("settings.restrictions.minNicknameLength", 3); getPasswordMinLen = configFile.getInt("settings.security.minPasswordLength", 4); getNickRegex = configFile.getString("settings.restrictions.allowedNicknameCharacters", "[a-zA-Z0-9_?]*"); nickPattern = Pattern.compile(getNickRegex); - isAllowRestrictedIp = configFile.getBoolean("settings.restrictions.AllowRestrictedUser", false); - getRestrictedIp = configFile.getStringList("settings.restrictions.AllowedRestrictedUser"); + isAllowRestrictedIp = load(RestrictionSettings.ENABLE_RESTRICTED_USERS); + getRestrictedIp = load(RestrictionSettings.ALLOWED_RESTRICTED_USERS); isMovementAllowed = configFile.getBoolean("settings.restrictions.allowMovement", false); isRemoveSpeedEnabled = configFile.getBoolean("settings.restrictions.removeSpeed", true); getMovementRadius = configFile.getInt("settings.restrictions.allowedMovementRadius", 100); @@ -204,13 +204,13 @@ public final class Settings { forceRegKick = configFile.getBoolean("settings.registration.forceKickAfterRegister", false); forceRegLogin = load(RegistrationSettings.FORCE_LOGIN_AFTER_REGISTER); spawnPriority = load(RestrictionSettings.SPAWN_PRIORITY); - getMaxLoginPerIp = configFile.getInt("settings.restrictions.maxLoginPerIp", 0); - getMaxJoinPerIp = configFile.getInt("settings.restrictions.maxJoinPerIp", 0); - checkVeryGames = configFile.getBoolean("VeryGames.enableIpCheck", false); + getMaxLoginPerIp = load(RestrictionSettings.MAX_LOGIN_PER_IP); + getMaxJoinPerIp = load(RestrictionSettings.MAX_JOIN_PER_IP); + checkVeryGames = load(HooksSettings.ENABLE_VERYGAMES_IP_CHECK); removeJoinMessage = load(RegistrationSettings.REMOVE_JOIN_MESSAGE); removeLeaveMessage = load(RegistrationSettings.REMOVE_LEAVE_MESSAGE); delayJoinMessage = load(RegistrationSettings.DELAY_JOIN_MESSAGE); - noTeleport = configFile.getBoolean("settings.restrictions.noTeleport", false); + noTeleport = load(RestrictionSettings.NO_TELEPORT); crazyloginFileName = configFile.getString("Converter.CrazyLogin.fileName", "accounts.db"); getPassRegex = configFile.getString("settings.restrictions.allowedPasswordCharacters", "[\\x21-\\x7E]*"); applyBlindEffect = configFile.getBoolean("settings.applyBlindEffect", false); diff --git a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java index 4025c0be..dd26b9e7 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java @@ -64,7 +64,7 @@ public class RestrictionSettings implements SettingsClass { @Comment({ "To activate the restricted user feature you need", - "to enable this option and configure the AllowedRestrctedUser field."}) + "to enable this option and configure the AllowedRestrictedUser field."}) public static final Property ENABLE_RESTRICTED_USERS = newProperty("settings.restrictions.AllowRestrictedUser", false); diff --git a/src/main/java/fr/xephi/authme/util/Utils.java b/src/main/java/fr/xephi/authme/util/Utils.java index f12c8b34..a39ef756 100644 --- a/src/main/java/fr/xephi/authme/util/Utils.java +++ b/src/main/java/fr/xephi/authme/util/Utils.java @@ -154,8 +154,7 @@ public final class Utils { public static boolean isUnrestricted(Player player) { return Settings.isAllowRestrictedIp - && !Settings.getUnrestrictedName.isEmpty() - && (Settings.getUnrestrictedName.contains(player.getName().toLowerCase())); + && Settings.getUnrestrictedName.contains(player.getName().toLowerCase()); } public static void packCoords(double x, double y, double z, String w, final Player pl) { @@ -216,8 +215,7 @@ public final class Utils { ConsoleLogger.showError("Unknown list of online players of type " + type); } } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - ConsoleLogger.showError("Could not retrieve list of online players: [" - + e.getClass().getName() + "] " + e.getMessage()); + ConsoleLogger.logException("Could not retrieve list of online players:", e); } return Collections.emptyList(); } From 6aa22f80cefd9ca9a67e50743794e5a1a37426e1 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Mon, 29 Feb 2016 21:34:21 +0100 Subject: [PATCH 33/46] Update dependencies --- .travis.yml | 2 +- circle.yml | 2 +- pom.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3eab0c37..1645036e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ sudo: false language: java -jdk: oraclejdk8 +jdk: oraclejdk7 cache: directories: diff --git a/circle.yml b/circle.yml index 80201e5e..dea5e80c 100644 --- a/circle.yml +++ b/circle.yml @@ -1,6 +1,6 @@ machine: java: - version: oraclejdk8 + version: oraclejdk7 general: artifacts: - "target/AuthMe-*.jar" diff --git a/pom.xml b/pom.xml index 71df4db6..c980c2d9 100644 --- a/pom.xml +++ b/pom.xml @@ -347,7 +347,7 @@ org.slf4j slf4j-jdk14 - 1.7.16 + 1.7.18 compile true @@ -388,7 +388,7 @@ com.google.code.gson gson - 2.6.1 + 2.6.2 compile true From e57e457b62e1938c747c2bb3cdb01988e6ea2393 Mon Sep 17 00:00:00 2001 From: games647 Date: Tue, 1 Mar 2016 16:38:32 +0100 Subject: [PATCH 34/46] Fixed VersionCommand is not using backwards compatible players method --- .../command/executable/authme/VersionCommand.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/VersionCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/VersionCommand.java index bfbb2ebf..4a7b629c 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/VersionCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/VersionCommand.java @@ -3,14 +3,14 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.AuthMe; import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.ExecutableCommand; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; +import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER; +import fr.xephi.authme.util.Utils; import java.util.List; -import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; public class VersionCommand implements ExecutableCommand { @@ -73,7 +73,7 @@ public class VersionCommand implements ExecutableCommand { private static boolean isPlayerOnline(String minecraftName) { // Note ljacqu 20151121: Generally you should use Utils#getOnlinePlayers to retrieve the list of online players. // If it's only used in a for-each loop such as here, it's fine. For other purposes, go through the Utils class. - for (Player player : Bukkit.getOnlinePlayers()) { + for (Player player : Utils.getOnlinePlayers()) { if (player.getName().equalsIgnoreCase(minecraftName)) { return true; } From 8432e67fd8cd90efb30c06c7f7d8df387f82dfe6 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Tue, 1 Mar 2016 17:34:56 +0100 Subject: [PATCH 35/46] 1.9 API + Fix permissions (CRITICAL) #573 --- pom.xml | 2 +- src/main/java/fr/xephi/authme/command/CommandInitializer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c980c2d9..5c83dbec 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ Unknown - 1.8.8-R0.1-SNAPSHOT + 1.9-SNAPSHOT diff --git a/src/main/java/fr/xephi/authme/command/CommandInitializer.java b/src/main/java/fr/xephi/authme/command/CommandInitializer.java index 0f73effa..ca89c86a 100644 --- a/src/main/java/fr/xephi/authme/command/CommandInitializer.java +++ b/src/main/java/fr/xephi/authme/command/CommandInitializer.java @@ -92,7 +92,7 @@ public final class CommandInitializer { .description("Enforce login player") .detailedDescription("Enforce the specified player to login.") .withArgument("player", "Online player name", true) - .permissions(OP_ONLY, PlayerPermission.CAN_LOGIN_BE_FORCED) + .permissions(OP_ONLY, AdminPermission.FORCE_LOGIN) .executableCommand(new ForceLoginCommand()) .build(); From 86042070e940ff145ca9b0bc15c9f9ff80e19f88 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Tue, 1 Mar 2016 20:48:15 +0100 Subject: [PATCH 36/46] #573 Remove exclusion for permission node check in test --- .../command/CommandInitializerTest.java | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java index 62c2b890..7e62023f 100644 --- a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java @@ -1,14 +1,13 @@ package fr.xephi.authme.command; -import static fr.xephi.authme.permission.DefaultPermission.OP_ONLY; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; +import fr.xephi.authme.permission.AdminPermission; +import fr.xephi.authme.permission.PermissionNode; +import fr.xephi.authme.util.StringUtils; +import fr.xephi.authme.util.WrapperMock; +import org.junit.BeforeClass; +import org.junit.Test; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -17,13 +16,12 @@ import java.util.Map; import java.util.Set; import java.util.regex.Pattern; -import org.junit.BeforeClass; -import org.junit.Test; - -import fr.xephi.authme.permission.AdminPermission; -import fr.xephi.authme.permission.PermissionNode; -import fr.xephi.authme.util.StringUtils; -import fr.xephi.authme.util.WrapperMock; +import static fr.xephi.authme.permission.DefaultPermission.OP_ONLY; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; /** * Test for {@link CommandInitializer} to guarantee the integrity of the defined commands. @@ -241,15 +239,11 @@ public class CommandInitializerTest { public void shouldNotHavePlayerPermissionIfDefaultsToOpOnly() { // given BiConsumer adminPermissionChecker = new BiConsumer() { - // The only exception to this check is the force login command, which should default to OP_ONLY - // but semantically it is a player permission - final List forceLoginLabels = Arrays.asList("forcelogin", "login"); - @Override public void accept(CommandDescription command, int depth) { CommandPermissions permissions = command.getCommandPermissions(); if (permissions != null && OP_ONLY.equals(permissions.getDefaultPermission())) { - if (!hasAdminNode(permissions) && !command.getLabels().equals(forceLoginLabels)) { + if (!hasAdminNode(permissions)) { fail("The command with labels " + command.getLabels() + " has OP_ONLY default " + "permission but no permission node on admin level"); } From 8bd9569c1486686c6b895343c2f4a1bbcf62225c Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Tue, 1 Mar 2016 22:19:33 +0100 Subject: [PATCH 37/46] Disable the tablist hider due to bugs! (Invisible player, missing data resend after login...) --- .../authme/listener/AuthMeTablistPacketAdapter.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/fr/xephi/authme/listener/AuthMeTablistPacketAdapter.java b/src/main/java/fr/xephi/authme/listener/AuthMeTablistPacketAdapter.java index d85a5c5e..8c0001fe 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMeTablistPacketAdapter.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMeTablistPacketAdapter.java @@ -30,10 +30,15 @@ public class AuthMeTablistPacketAdapter extends PacketAdapter { } public void register() { - ProtocolLibrary.getProtocolManager().addPacketListener(this); + // TODO: + // FIXME: + // This listener hides every player not only from the tablist... From everything! (Invisible players issue) + // WE NEED ALSO TO RESEND THE DATA AFTER THE PLAYER LOGIN + ConsoleLogger.info("The HideTablistBeforeLogin feature is currently unavariable due to stability issues!"); + //ProtocolLibrary.getProtocolManager().addPacketListener(this); } public void unregister() { - ProtocolLibrary.getProtocolManager().removePacketListener(this); + //ProtocolLibrary.getProtocolManager().removePacketListener(this); } } From c5c0535fcd526060a99d7dec8e9744f928bb3949 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Wed, 2 Mar 2016 00:33:26 +0100 Subject: [PATCH 38/46] Ok, nevermind, it works. --- .../authme/listener/AuthMeTablistPacketAdapter.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/fr/xephi/authme/listener/AuthMeTablistPacketAdapter.java b/src/main/java/fr/xephi/authme/listener/AuthMeTablistPacketAdapter.java index 8c0001fe..d85a5c5e 100644 --- a/src/main/java/fr/xephi/authme/listener/AuthMeTablistPacketAdapter.java +++ b/src/main/java/fr/xephi/authme/listener/AuthMeTablistPacketAdapter.java @@ -30,15 +30,10 @@ public class AuthMeTablistPacketAdapter extends PacketAdapter { } public void register() { - // TODO: - // FIXME: - // This listener hides every player not only from the tablist... From everything! (Invisible players issue) - // WE NEED ALSO TO RESEND THE DATA AFTER THE PLAYER LOGIN - ConsoleLogger.info("The HideTablistBeforeLogin feature is currently unavariable due to stability issues!"); - //ProtocolLibrary.getProtocolManager().addPacketListener(this); + ProtocolLibrary.getProtocolManager().addPacketListener(this); } public void unregister() { - //ProtocolLibrary.getProtocolManager().removePacketListener(this); + ProtocolLibrary.getProtocolManager().removePacketListener(this); } } From 681e352bdcad7cdd43aec113e8c6cb3a137e8418 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Wed, 2 Mar 2016 17:06:02 +0100 Subject: [PATCH 39/46] Fix #570 add max_acc and reg_acc placeholders --- src/main/java/fr/xephi/authme/output/MessageKey.java | 2 +- .../xephi/authme/process/register/AsyncRegister.java | 10 ++++++---- src/main/resources/messages/messages_en.yml | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/fr/xephi/authme/output/MessageKey.java b/src/main/java/fr/xephi/authme/output/MessageKey.java index 0c96b666..1ab8aaa4 100644 --- a/src/main/java/fr/xephi/authme/output/MessageKey.java +++ b/src/main/java/fr/xephi/authme/output/MessageKey.java @@ -41,7 +41,7 @@ public enum MessageKey { REGISTER_EMAIL_MESSAGE("reg_email_msg"), - MAX_REGISTER_EXCEEDED("max_reg", "%acc_nb"), + MAX_REGISTER_EXCEEDED("max_reg", "%max_acc", "%reg_acc"), USAGE_REGISTER("usage_reg"), 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 97344ba0..0d71c6b8 100644 --- a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java @@ -73,6 +73,7 @@ public class AsyncRegister { //check this in both possiblities so don't use 'else if' Integer size = 0; + Integer maxReg = Settings.getmaxRegPerIp; if (database.isAuthAvailable(name)) { m.send(player, MessageKey.NAME_ALREADY_REGISTERED); return false; @@ -80,8 +81,8 @@ public class AsyncRegister { && !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS) && !ip.equalsIgnoreCase("127.0.0.1") && !ip.equalsIgnoreCase("localhost") - && (size = database.getAllAuthsByIp(ip).size()) >= Settings.getmaxRegPerIp) { - m.send(player, MessageKey.MAX_REGISTER_EXCEEDED, size.toString()); + && (size = database.getAllAuthsByIp(ip).size()) >= maxReg) { + m.send(player, MessageKey.MAX_REGISTER_EXCEEDED, maxReg.toString(), size.toString()); return false; } return true; @@ -98,11 +99,12 @@ public class AsyncRegister { } private void emailRegister() { + Integer maxReg = Settings.getmaxRegPerIp; Integer size = 0; if (Settings.getmaxRegPerEmail > 0 && !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS) - && (size = database.countAuthsByEmail(email)) >= Settings.getmaxRegPerEmail) { - m.send(player, MessageKey.MAX_REGISTER_EXCEEDED, size.toString()); + && (size = database.getAllAuthsByIp(ip).size()) >= maxReg) { + m.send(player, MessageKey.MAX_REGISTER_EXCEEDED, maxReg.toString(), size.toString()); return; } final HashedPassword hashedPassword = plugin.getPasswordSecurity().computeHash(password, name); diff --git a/src/main/resources/messages/messages_en.yml b/src/main/resources/messages/messages_en.yml index 4e155bcf..6c0189a3 100644 --- a/src/main/resources/messages/messages_en.yml +++ b/src/main/resources/messages/messages_en.yml @@ -12,7 +12,7 @@ login: '&2Successful login!' vb_nonActiv: '&cYour account isn''t activated yet, please check your emails!' user_regged: '&cYou already have registered this username!' usage_reg: '&cUsage: /register ' -max_reg: '&cYou have exceeded the maximum number of registrations (%acc_nb) for your connection!' +max_reg: '&cYou have exceeded the maximum number of registrations (%reg_acc/%max_acc) for your connection!' no_perm: '&4You don''t have the permission to perform this action!' error: '&4An unexpected error occurred, please contact an administrator!' login_msg: '&cPlease, login with the command "/login "' From 1e0d31ebb721a5a918310e69a76e47c75f00ee5c Mon Sep 17 00:00:00 2001 From: DNx Date: Thu, 3 Mar 2016 11:11:56 +0700 Subject: [PATCH 40/46] Don't lowercase the real name, also.. the password. Fix #578 --- .../command/executable/authme/RegisterAdminCommand.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommand.java index 7b929952..a33f3eb3 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommand.java @@ -22,8 +22,8 @@ public class RegisterAdminCommand implements ExecutableCommand { public void executeCommand(final CommandSender sender, List arguments, final CommandService commandService) { // Get the player name and password - final String playerName = arguments.get(0).toLowerCase(); - final String playerPass = arguments.get(1).toLowerCase(); + final String playerName = arguments.get(0); + final String playerPass = arguments.get(1); final String playerNameLowerCase = playerName.toLowerCase(); final String playerPassLowerCase = playerPass.toLowerCase(); From e4d2747fae25b8199214a43ddcdffa67e1768f14 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Thu, 3 Mar 2016 21:05:19 +0100 Subject: [PATCH 41/46] Finally fix #570 --- .../java/fr/xephi/authme/output/MessageKey.java | 2 +- .../authme/process/register/AsyncRegister.java | 16 +++++++++------- src/main/resources/messages/messages_en.yml | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/java/fr/xephi/authme/output/MessageKey.java b/src/main/java/fr/xephi/authme/output/MessageKey.java index 1ab8aaa4..3fd7c747 100644 --- a/src/main/java/fr/xephi/authme/output/MessageKey.java +++ b/src/main/java/fr/xephi/authme/output/MessageKey.java @@ -41,7 +41,7 @@ public enum MessageKey { REGISTER_EMAIL_MESSAGE("reg_email_msg"), - MAX_REGISTER_EXCEEDED("max_reg", "%max_acc", "%reg_acc"), + MAX_REGISTER_EXCEEDED("max_reg", "%max_acc", "%reg_count", "%reg_names"), USAGE_REGISTER("usage_reg"), 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 0d71c6b8..d30d0836 100644 --- a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java @@ -1,5 +1,7 @@ package fr.xephi.authme.process.register; +import java.util.List; + import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -99,13 +101,13 @@ public class AsyncRegister { } private void emailRegister() { - Integer maxReg = Settings.getmaxRegPerIp; - Integer size = 0; - if (Settings.getmaxRegPerEmail > 0 - && !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS) - && (size = database.getAllAuthsByIp(ip).size()) >= maxReg) { - m.send(player, MessageKey.MAX_REGISTER_EXCEEDED, maxReg.toString(), size.toString()); - return; + if(Settings.getmaxRegPerEmail > 0 && !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)) { + Integer maxReg = Settings.getmaxRegPerIp; + List otherAccounts = database.getAllAuthsByIp(ip); + if (otherAccounts.size() >= maxReg) { + m.send(player, MessageKey.MAX_REGISTER_EXCEEDED, maxReg.toString(), Integer.toString(otherAccounts.size()), otherAccounts.toString()); + return; + } } final HashedPassword hashedPassword = plugin.getPasswordSecurity().computeHash(password, name); PlayerAuth auth = PlayerAuth.builder() diff --git a/src/main/resources/messages/messages_en.yml b/src/main/resources/messages/messages_en.yml index 6c0189a3..5b474e2d 100644 --- a/src/main/resources/messages/messages_en.yml +++ b/src/main/resources/messages/messages_en.yml @@ -12,7 +12,7 @@ login: '&2Successful login!' vb_nonActiv: '&cYour account isn''t activated yet, please check your emails!' user_regged: '&cYou already have registered this username!' usage_reg: '&cUsage: /register ' -max_reg: '&cYou have exceeded the maximum number of registrations (%reg_acc/%max_acc) for your connection!' +max_reg: '&cYou have exceeded the maximum number of registrations (%reg_count/%max_acc %reg_names) for your connection!' no_perm: '&4You don''t have the permission to perform this action!' error: '&4An unexpected error occurred, please contact an administrator!' login_msg: '&cPlease, login with the command "/login "' From b0d230be600af128dcc948680198739919621753 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Thu, 3 Mar 2016 21:17:38 +0100 Subject: [PATCH 42/46] Forgot about this... #570 --- .../process/register/AsyncRegister.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 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 d30d0836..b73fd58c 100644 --- a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java @@ -74,18 +74,19 @@ public class AsyncRegister { } //check this in both possiblities so don't use 'else if' - Integer size = 0; - Integer maxReg = Settings.getmaxRegPerIp; if (database.isAuthAvailable(name)) { m.send(player, MessageKey.NAME_ALREADY_REGISTERED); return false; - } else if (Settings.getmaxRegPerIp > 0 - && !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS) + } else if(Settings.getmaxRegPerIp > 0 && !ip.equalsIgnoreCase("127.0.0.1") && !ip.equalsIgnoreCase("localhost") - && (size = database.getAllAuthsByIp(ip).size()) >= maxReg) { - m.send(player, MessageKey.MAX_REGISTER_EXCEEDED, maxReg.toString(), size.toString()); - return false; + && !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)) { + Integer maxReg = Settings.getmaxRegPerIp; + List otherAccounts = database.getAllAuthsByIp(ip); + if (otherAccounts.size() >= maxReg) { + m.send(player, MessageKey.MAX_REGISTER_EXCEEDED, maxReg.toString(), Integer.toString(otherAccounts.size()), otherAccounts.toString()); + return false; + } } return true; } @@ -101,7 +102,10 @@ public class AsyncRegister { } private void emailRegister() { - if(Settings.getmaxRegPerEmail > 0 && !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)) { + if(Settings.getmaxRegPerEmail > 0 + && !ip.equalsIgnoreCase("127.0.0.1") + && !ip.equalsIgnoreCase("localhost") + && !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)) { Integer maxReg = Settings.getmaxRegPerIp; List otherAccounts = database.getAllAuthsByIp(ip); if (otherAccounts.size() >= maxReg) { From c4684fd5f1b7caeb8d84ab607ad07a588d6720f5 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Thu, 3 Mar 2016 21:42:50 +0100 Subject: [PATCH 43/46] Booo we don't like UUIDS! (We need to keep 1.7.X compatibility!) - Removed the useless OtherAccounts class! --- README.md | 2 +- src/main/java/fr/xephi/authme/AuthMe.java | 5 - .../process/login/AsynchronousLogin.java | 1 - .../process/register/AsyncRegister.java | 1 - .../xephi/authme/settings/OtherAccounts.java | 96 ------------------- 5 files changed, 1 insertion(+), 104 deletions(-) delete mode 100644 src/main/java/fr/xephi/authme/settings/OtherAccounts.java diff --git a/README.md b/README.md index 5f82e524..934112c0 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ McStats: http://mcstats.org/plugin/AuthMe #####"The best authentication plugin for the Bukkit/Spigot API!" -

Prevent username stealing on your server! Fully compatible with UUIDs and Craftbukkit/Spigot 1.8.X!
+

Prevent username stealing on your server!
Use it to secure your Offline mode server or to increase your Online mode server's protection!

AuthMeReloaded disallows players who aren't authenticated to do actions like placing blocks, moving,
diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 047cf408..571fdbbe 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -46,7 +46,6 @@ import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.crypts.SHA256; import fr.xephi.authme.settings.NewSetting; -import fr.xephi.authme.settings.OtherAccounts; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.SettingsMigrationService; import fr.xephi.authme.settings.Spawn; @@ -121,7 +120,6 @@ public class AuthMe extends JavaPlugin { public NewAPI api; public SendMailSSL mail; public DataManager dataManager; - public OtherAccounts otherAccounts; public Location essentialsSpawn; /* * Plugin Hooks @@ -258,9 +256,6 @@ public class AuthMe extends JavaPlugin { permsMan = initializePermissionsManager(); commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings); - // Setup otherAccounts file - this.otherAccounts = OtherAccounts.getInstance(); - // Set up Metrics MetricsStarter.setupMetrics(plugin, newSettings); 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 d6f1f327..757789df 100644 --- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java @@ -185,7 +185,6 @@ public class AsynchronousLogin { // makes player isLoggedin via API PlayerCache.getInstance().addPlayer(auth); database.setLogged(name); - plugin.otherAccounts.addPlayer(player.getUniqueId()); // As the scheduling executes the Task most likely after the current // task, we schedule it in the end 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 b73fd58c..6ff41bf6 100644 --- a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java @@ -157,7 +157,6 @@ public class AsyncRegister { plugin.getManagement().performLogin(player, "dontneed", true); } - plugin.otherAccounts.addPlayer(player.getUniqueId()); ProcessSyncPasswordRegister sync = new ProcessSyncPasswordRegister(player, plugin, settings); plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, sync); diff --git a/src/main/java/fr/xephi/authme/settings/OtherAccounts.java b/src/main/java/fr/xephi/authme/settings/OtherAccounts.java deleted file mode 100644 index 6e2796a3..00000000 --- a/src/main/java/fr/xephi/authme/settings/OtherAccounts.java +++ /dev/null @@ -1,96 +0,0 @@ -package fr.xephi.authme.settings; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -/** - * @author Xephi59 - * @version $Revision: 1.0 $ - */ -public class OtherAccounts extends CustomConfiguration { - - private static OtherAccounts others = null; - - public OtherAccounts() { - super(new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "otheraccounts.yml")); - others = this; - load(); - save(); - } - - /** - * Method getInstance. - * - * @return OtherAccounts - */ - public static OtherAccounts getInstance() { - if (others == null) { - others = new OtherAccounts(); - } - return others; - } - - /** - * Method clear. - * - * @param uuid UUID - */ - public void clear(UUID uuid) { - set(uuid.toString(), new ArrayList()); - save(); - } - - /** - * Method addPlayer. - * - * @param uuid UUID - */ - public void addPlayer(UUID uuid) { - try { - Player player = Bukkit.getPlayer(uuid); - if (player == null) - return; - if (!this.getStringList(uuid.toString()).contains(player.getName())) { - this.getStringList(uuid.toString()).add(player.getName()); - save(); - } - } catch (NoSuchMethodError | Exception e) { - //ignore - } - } - - /** - * Method removePlayer. - * - * @param uuid UUID - */ - public void removePlayer(UUID uuid) { - try { - Player player = Bukkit.getPlayer(uuid); - if (player == null) - return; - if (this.getStringList(uuid.toString()).contains(player.getName())) { - this.getStringList(uuid.toString()).remove(player.getName()); - save(); - } - } catch (NoSuchMethodError | Exception e) { - //ignore - } - } - - /** - * Method getAllPlayersByUUID. - * - * @param uuid UUID - * - * @return StringList - */ - public List getAllPlayersByUUID(UUID uuid) { - return this.getStringList(uuid.toString()); - } -} From a23e0a6d30d348c68357935f1cdbf1e377f35bc1 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sat, 5 Mar 2016 13:50:58 +0100 Subject: [PATCH 44/46] Update HikariCP --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5c83dbec..90918139 100644 --- a/pom.xml +++ b/pom.xml @@ -334,7 +334,7 @@ com.zaxxer HikariCP - 2.4.3 + 2.4.5-SNAPSHOT compile From aa914b9aa7f92300899957024123ddf0f49177f6 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sat, 5 Mar 2016 13:55:40 +0100 Subject: [PATCH 45/46] Add a message about the workaround with MC 1.9 --- src/main/java/fr/xephi/authme/AuthMe.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 571fdbbe..cff14683 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -242,6 +242,8 @@ public class AuthMe extends JavaPlugin { try { setupDatabase(newSettings); } catch (Exception e) { + ConsoleLogger.showError("If you are using CraftBukkit/Spigot 1.9 please add the " + + "-Dfile.encoding=UTF-8 argument in your server startup script!"); ConsoleLogger.logException("Fatal error occurred during database connection! " + "Authme initialization aborted!", e); stopOrUnload(); From 717f962473f372d42e51c84f45427baca8a7696e Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sat, 5 Mar 2016 18:16:57 +0100 Subject: [PATCH 46/46] Revert "Add a message about the workaround with MC 1.9" This reverts commit aa914b9aa7f92300899957024123ddf0f49177f6. --- src/main/java/fr/xephi/authme/AuthMe.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index cff14683..571fdbbe 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -242,8 +242,6 @@ public class AuthMe extends JavaPlugin { try { setupDatabase(newSettings); } catch (Exception e) { - ConsoleLogger.showError("If you are using CraftBukkit/Spigot 1.9 please add the " - + "-Dfile.encoding=UTF-8 argument in your server startup script!"); ConsoleLogger.logException("Fatal error occurred during database connection! " + "Authme initialization aborted!", e); stopOrUnload();