diff --git a/CHANGELOG.md b/CHANGELOG.md index ab5ea79f..10ceeec0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ +######1.0 + +* Massive refactor to handle errors on force actions safely +* force Methods now runs async too +* force methods now returns a boolean to reflect if the method was successful +* isRegistered method should now throw an exception if the plugin was unable to query the requested data + ######0.8 - * Fixed BungeeCord support for the Bukkit module +* Fixed BungeeCord support for the Bukkit module * Added database storage to save the premium state * Fix logical error on /premium (Thanks to @NorbiPeti) * Fixed issues with host lookup from hosts file (Thanks to @NorbiPeti) diff --git a/bukkit/pom.xml b/bukkit/pom.xml index 9d50d22e..8728060e 100644 --- a/bukkit/pom.xml +++ b/bukkit/pom.xml @@ -5,7 +5,7 @@ com.github.games647 fastlogin - 0.8 + 1.0 ../pom.xml diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/ForceLoginTask.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/ForceLoginTask.java index 577b3d77..a241763b 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/ForceLoginTask.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/ForceLoginTask.java @@ -2,11 +2,8 @@ package com.github.games647.fastlogin.bukkit; import com.github.games647.fastlogin.bukkit.hooks.BukkitAuthPlugin; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; import java.util.logging.Level; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.metadata.FixedMetadataValue; @@ -55,37 +52,17 @@ public class ForceLoginTask implements Runnable { } if (success) { - performForceAction(session, authPlugin); + if (session.needsRegistration()) { + forceRegister(authPlugin, player); + } else { + forceLogin(authPlugin, player); + } } } else if (playerProfile != null) { storage.save(playerProfile); } } - private void performForceAction(PlayerSession session, final BukkitAuthPlugin authPlugin) { - try { - if (session.needsRegistration()) { - Bukkit.getScheduler().callSyncMethod(plugin, new Callable() { - @Override - public Object call() throws Exception { - forceRegister(authPlugin, player); - return null; - } - }).get(); - } else { - Bukkit.getScheduler().callSyncMethod(plugin, new Callable() { - @Override - public Object call() throws Exception { - forceLogin(authPlugin, player); - return null; - } - }).get(); - } - } catch (InterruptedException | ExecutionException exception) { - plugin.getLogger().log(Level.SEVERE, "Failed to perform sync force action", exception); - } - } - private void forceRegister(BukkitAuthPlugin authPlugin, Player player) { plugin.getLogger().log(Level.FINE, "Register player {0}", player.getName()); diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/AuthMeHook.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/AuthMeHook.java index ab97469a..f1c9e240 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/AuthMeHook.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/AuthMeHook.java @@ -14,18 +14,22 @@ import org.bukkit.entity.Player; public class AuthMeHook implements BukkitAuthPlugin { @Override - public void forceLogin(Player player) { + public boolean forceLogin(Player player) { //skips registration and login NewAPI.getInstance().forceLogin(player); + //commented because the operation above is performed async -> race conditions +// return NewAPI.getInstance().isAuthenticated(player); + return true; } @Override - public boolean isRegistered(String playerName) { + public boolean isRegistered(String playerName) throws Exception { return NewAPI.getInstance().isRegistered(playerName); } @Override - public void forceRegister(Player player, String password) { + public boolean forceRegister(Player player, String password) { NewAPI.getInstance().forceRegister(player, password); + return true; } } diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/BukkitAuthPlugin.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/BukkitAuthPlugin.java index 0010a82d..6fbf8438 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/BukkitAuthPlugin.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/BukkitAuthPlugin.java @@ -11,9 +11,13 @@ public interface BukkitAuthPlugin { * Login the premium (paid account) player after * the player joined successfully the server. * + * This operation will be performed async while the player successfully + * joined the server. + * * @param player the player that needs to be logged in + * @return if the operation was successful */ - void forceLogin(Player player); + boolean forceLogin(Player player); /** * Checks whether an account exists for this player name. @@ -23,16 +27,19 @@ public interface BukkitAuthPlugin { * of that player. * * This operation will be performed async while the player is - * connecting + * connecting. * * @param playerName player name * @return if the player has an account + * @throws Exception if an error occurred */ - boolean isRegistered(String playerName); + boolean isRegistered(String playerName) throws Exception; /** * Forces a register in order to protect the paid account. - * The method will be invoked after the player joined the server. + * + * This operation will be performed async while the player successfully + * joined the server. * * After a successful registration the player should be logged * in too. @@ -41,12 +48,13 @@ public interface BukkitAuthPlugin { * So it's recommended to set additionally premium property * if possible. * - * If we don't register an account, cracked players + * Background: If we don't register an account, cracked players * could steal the unregistered account from the paid * player account * * @param player the premium account * @param password a strong random generated password + * @return if the operation was successful */ - void forceRegister(Player player, String password); + boolean forceRegister(Player player, String password); } diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/CrazyLoginHook.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/CrazyLoginHook.java index 8556a2f0..9712bb0a 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/CrazyLoginHook.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/CrazyLoginHook.java @@ -7,6 +7,9 @@ import de.st_ddt.crazylogin.data.LoginPlayerData; import de.st_ddt.crazylogin.databases.CrazyLoginDataDatabase; import de.st_ddt.crazylogin.listener.PlayerListener; import de.st_ddt.crazylogin.metadata.Authenticated; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.logging.Level; @@ -22,91 +25,92 @@ import org.bukkit.entity.Player; */ public class CrazyLoginHook implements BukkitAuthPlugin { + protected final CrazyLogin crazyLoginPlugin = CrazyLogin.getPlugin(); private final PlayerListener playerListener = getListener(); @Override - public void forceLogin(Player player) { - final CrazyLogin crazyLoginPlugin = CrazyLogin.getPlugin(); + public boolean forceLogin(final Player player) { + //not thread-safe operation + Future future = Bukkit.getScheduler().callSyncMethod(crazyLoginPlugin + , new Callable() { + @Override + public LoginPlayerData call() throws Exception { + LoginPlayerData playerData = crazyLoginPlugin.getPlayerData(player.getName()); + if (playerData != null) { + //mark the account as logged in + playerData.setLoggedIn(true); - final LoginPlayerData playerData = crazyLoginPlugin.getPlayerData(player.getName()); - if (playerData != null) { - //mark the account as logged in - playerData.setLoggedIn(true); - - String ip = player.getAddress().getAddress().getHostAddress(); + String ip = player.getAddress().getAddress().getHostAddress(); //this should be done after login to restore the inventory, unhide players, prevent potential memory leaks... //from: https://github.com/ST-DDT/CrazyLogin/blob/master/src/main/java/de/st_ddt/crazylogin/CrazyLogin.java#L1948 - playerData.resetLoginFails(); - player.setFireTicks(0); + playerData.resetLoginFails(); + player.setFireTicks(0); - if (playerListener != null) { - playerListener.removeMovementBlocker(player); - playerListener.disableHidenInventory(player); - playerListener.disableSaveLogin(player); - playerListener.unhidePlayer(player); - } + if (playerListener != null) { + playerListener.removeMovementBlocker(player); + playerListener.disableHidenInventory(player); + playerListener.disableSaveLogin(player); + playerListener.unhidePlayer(player); + } - //loginFailuresPerIP.remove(IP); - //illegalCommandUsesPerIP.remove(IP); - //tempBans.remove(IP); - playerData.addIP(ip); - player.setMetadata("Authenticated", new Authenticated(crazyLoginPlugin, player)); - crazyLoginPlugin.unregisterDynamicHooks(); - Bukkit.getScheduler().runTaskAsynchronously(crazyLoginPlugin, new Runnable() { - @Override - public void run() { - //SQL-Queries should run async - crazyLoginPlugin.getCrazyDatabase().saveWithoutPassword(playerData); + //loginFailuresPerIP.remove(IP); + //illegalCommandUsesPerIP.remove(IP); + //tempBans.remove(IP); + playerData.addIP(ip); + player.setMetadata("Authenticated", new Authenticated(crazyLoginPlugin, player)); + crazyLoginPlugin.unregisterDynamicHooks(); + return playerData; } - }); + + return null; + } + }); + + try { + LoginPlayerData result = future.get(); + if (result != null) { + //SQL-Queries should run async + crazyLoginPlugin.getCrazyDatabase().saveWithoutPassword(result); + return true; + } + } catch (InterruptedException | ExecutionException ex) { + crazyLoginPlugin.getLogger().log(Level.SEVERE, "Failed to forceLogin", ex); + return false; } + + return false; } @Override - public boolean isRegistered(String playerName) { - CrazyLogin crazyLoginPlugin = CrazyLogin.getPlugin(); + public boolean isRegistered(String playerName) throws Exception { return crazyLoginPlugin.getPlayerData(playerName) != null; } @Override - public void forceRegister(final Player player, String password) { - final CrazyLogin crazyLoginPlugin = CrazyLogin.getPlugin(); + public boolean forceRegister(final Player player, String password) { final CrazyLoginDataDatabase crazyDatabase = crazyLoginPlugin.getCrazyDatabase(); //this executes a sql query and accesses only thread safe collections so we can run it async - Bukkit.getScheduler().runTaskAsynchronously(crazyLoginPlugin, new Runnable() { - @Override - public void run() { - LoginPlayerData playerData = crazyLoginPlugin.getPlayerData(player.getName()); - if (playerData == null) { - //create a fake account - this will be saved to the database with the password=FAILEDLOADING - //user cannot login with that password unless the admin uses plain text - //this automatically marks the player as logged in - playerData = new LoginPlayerData(player); - crazyDatabase.save(playerData); + LoginPlayerData playerData = crazyLoginPlugin.getPlayerData(player.getName()); + if (playerData == null) { + //create a fake account - this will be saved to the database with the password=FAILEDLOADING + //user cannot login with that password unless the admin uses plain text + //this automatically marks the player as logged in + playerData = new LoginPlayerData(player); + crazyDatabase.save(playerData); - //this method is not thread-safe and requires the existence of the account - //so reschedule it to the main thread - Bukkit.getScheduler().runTask(crazyLoginPlugin, new Runnable() { - @Override - public void run() { - //login the player after registration - forceLogin(player); - } - }); - } - } - }); + return forceLogin(player); + } + + return false; } private PlayerListener getListener() { - CrazyLogin pluginInstance = CrazyLogin.getPlugin(); - PlayerListener listener; try { - listener = FuzzyReflection.getFieldValue(pluginInstance, PlayerListener.class, true); + listener = FuzzyReflection.getFieldValue(crazyLoginPlugin, PlayerListener.class, true); } catch (Exception ex) { - pluginInstance.getLogger().log(Level.SEVERE, "Failed to get the listener instance for auto login", ex); + crazyLoginPlugin.getLogger().log(Level.SEVERE, "Failed to get the listener instance for auto login", ex); listener = null; } diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/LoginSecurityHook.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/LoginSecurityHook.java index c1cf8447..aa589df3 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/LoginSecurityHook.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/LoginSecurityHook.java @@ -7,8 +7,12 @@ import com.lenis0012.bukkit.ls.data.DataManager; import java.net.InetAddress; import java.util.UUID; - +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.logging.Level; import org.bukkit.Bukkit; + import org.bukkit.entity.Player; /** @@ -22,25 +26,41 @@ import org.bukkit.entity.Player; */ public class LoginSecurityHook implements BukkitAuthPlugin { + protected final LoginSecurity securityPlugin = LoginSecurity.instance; + @Override - public void forceLogin(Player player) { + public boolean forceLogin(final Player player) { //Login command of this plugin: (How the plugin logs the player in) //https://github.com/lenis0012/LoginSecurity-2/blob/master/src/main/java/com/lenis0012/bukkit/ls/commands/LoginCommand.java#L39 - LoginSecurity securityPlugin = LoginSecurity.instance; - String name = player.getName().toLowerCase(); - //mark the user as logged in - securityPlugin.authList.remove(name); - //cancel timeout timer - securityPlugin.thread.timeout.remove(name); - //remove effects and restore location - securityPlugin.rehabPlayer(player, name); + //not thread-safe operation + Future future = Bukkit.getScheduler().callSyncMethod(securityPlugin, new Callable() { + @Override + public Boolean call() throws Exception { + String name = player.getName().toLowerCase(); + + //mark the user as logged in + securityPlugin.authList.remove(name); + //cancel timeout timer + securityPlugin.thread.timeout.remove(name); + //remove effects and restore location + securityPlugin.rehabPlayer(player, name); + + return true; + } + }); + + try { + return future.get(); + } catch (InterruptedException | ExecutionException ex) { + securityPlugin.getLogger().log(Level.SEVERE, "Failed to forceLogin", ex); + return false; + } } @Override - public boolean isRegistered(String playerName) { + public boolean isRegistered(String playerName) throws Exception { //https://github.com/lenis0012/LoginSecurity-2/blob/master/src/main/java/com/lenis0012/bukkit/ls/LoginSecurity.java#L296 - LoginSecurity securityPlugin = LoginSecurity.instance; DataManager dataManager = securityPlugin.data; //https://github.com/lenis0012/LoginSecurity-2/blob/master/src/main/java/com/lenis0012/bukkit/ls/LoginSecurity.java#L283 @@ -51,8 +71,7 @@ public class LoginSecurityHook implements BukkitAuthPlugin { } @Override - public void forceRegister(final Player player, final String password) { - final LoginSecurity securityPlugin = LoginSecurity.instance; + public boolean forceRegister(final Player player, final String password) { final DataManager dataManager = securityPlugin.data; UUID playerUUID = player.getUniqueId(); @@ -61,19 +80,7 @@ public class LoginSecurityHook implements BukkitAuthPlugin { final String passwordHash = securityPlugin.hasher.hash(password); //this executes a sql query without interacting with other parts so we can run it async. - Bukkit.getScheduler().runTaskAsynchronously(securityPlugin, new Runnable() { - @Override - public void run() { - dataManager.register(uuidString, passwordHash, securityPlugin.hasher.getTypeId(), ipAddress.toString()); - //run forcelogin only if it was successfull - Bukkit.getScheduler().runTask(securityPlugin, new Runnable() { - @Override - public void run() { - //notify the plugin that this player can be logged in - forceLogin(player); - } - }); - } - }); + dataManager.register(uuidString, passwordHash, securityPlugin.hasher.getTypeId(), ipAddress.toString()); + return forceLogin(player); } } diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/RoyalAuthHook.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/RoyalAuthHook.java index 1d1168ba..f792ab28 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/RoyalAuthHook.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/RoyalAuthHook.java @@ -1,8 +1,15 @@ package com.github.games647.fastlogin.bukkit.hooks; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.logging.Level; + +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.royaldev.royalauth.AuthPlayer; import org.royaldev.royalauth.Config; +import org.royaldev.royalauth.RoyalAuth; /** * Github: https://github.com/RoyalDev/RoyalAuth @@ -13,28 +20,49 @@ import org.royaldev.royalauth.Config; */ public class RoyalAuthHook implements BukkitAuthPlugin { + private final RoyalAuth royalAuthPlugin = (RoyalAuth) Bukkit.getPluginManager().getPlugin("RoyalAuth"); + @Override - public void forceLogin(Player player) { - AuthPlayer authPlayer = AuthPlayer.getAuthPlayer(player); + public boolean forceLogin(final Player player) { + //not thread-safe + Future future = Bukkit.getScheduler().callSyncMethod(royalAuthPlugin, new Callable() { + @Override + public Boolean call() throws Exception { + AuthPlayer authPlayer = AuthPlayer.getAuthPlayer(player); //https://github.com/RoyalDev/RoyalAuth/blob/master/src/main/java/org/royaldev/royalauth/commands/CmdLogin.java#L62 - //not thread-safe - authPlayer.login(); + //not thread-safe + authPlayer.login(); + + return true; + } + }); + + try { + return future.get(); + } catch (InterruptedException | ExecutionException ex) { + royalAuthPlugin.getLogger().log(Level.SEVERE, "Failed to forceLogin", ex); + return false; + } } @Override - public boolean isRegistered(String playerName) { + public boolean isRegistered(String playerName) throws Exception { AuthPlayer authPlayer = AuthPlayer.getAuthPlayer(playerName); return authPlayer.isRegistered(); } @Override - public void forceRegister(Player player, String password) { + public boolean forceRegister(Player player, String password) { //https://github.com/RoyalDev/RoyalAuth/blob/master/src/main/java/org/royaldev/royalauth/commands/CmdRegister.java#L50 AuthPlayer authPlayer = AuthPlayer.getAuthPlayer(player); - authPlayer.setPassword(password, Config.passwordHashType); - //login in the player after registration - forceLogin(player); + boolean registerSuccess = authPlayer.setPassword(password, Config.passwordHashType); + if (registerSuccess) { + //login in the player after registration + return forceLogin(player); + } + + return false; } } diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/UltraAuthHook.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/UltraAuthHook.java index 9431dab7..8a200b3f 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/UltraAuthHook.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/UltraAuthHook.java @@ -7,6 +7,9 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.logging.Level; import org.bukkit.Achievement; import org.bukkit.Bukkit; @@ -65,25 +68,36 @@ import ultraauth.main.Main; */ public class UltraAuthHook implements BukkitAuthPlugin { + private final Plugin ultraAuthPlugin = Main.main; + @Override - public void forceLogin(Player player) { - UltraAuthAPI.authenticatedPlayer(player); + public boolean forceLogin(final Player player) { + try { + //not thread-safe + Bukkit.getScheduler().callSyncMethod(ultraAuthPlugin, new Callable() { + @Override + public Object call() throws Exception { + UltraAuthAPI.authenticatedPlayer(player); + return null; + } + }).get(); + } catch (InterruptedException | ExecutionException ex) { + ultraAuthPlugin.getLogger().log(Level.SEVERE, "Failed to forceLogin", ex); + return false; + } + + return true; } @Override - public boolean isRegistered(String playerName) { + public boolean isRegistered(String playerName) throws Exception { return UltraAuthAPI.isRegisterd(new FakePlayer(playerName)); } @Override - public void forceRegister(final Player player, final String password) { - Bukkit.getScheduler().runTaskAsynchronously(Main.main, new Runnable() { - @Override - public void run() { - UltraAuthAPI.setPlayerPasswordOnline(player, password); - forceLogin(player); - } - }); + public boolean forceRegister(final Player player, final String password) { + UltraAuthAPI.setPlayerPasswordOnline(player, password); + return forceLogin(player); } class FakePlayer implements Player { diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/xAuthHook.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/xAuthHook.java index 4c96c9d5..de9d9942 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/xAuthHook.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hooks/xAuthHook.java @@ -3,6 +3,13 @@ package com.github.games647.fastlogin.bukkit.hooks; import de.luricos.bukkit.xAuth.xAuth; import de.luricos.bukkit.xAuth.xAuthPlayer; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.logging.Level; + +import org.bukkit.Bukkit; + import org.bukkit.entity.Player; /** @@ -14,41 +21,71 @@ import org.bukkit.entity.Player; */ public class xAuthHook implements BukkitAuthPlugin { + protected final xAuth xAuthPlugin = xAuth.getPlugin(); + @Override - public void forceLogin(Player player) { - xAuth xAuthPlugin = xAuth.getPlugin(); + public boolean forceLogin(final Player player) { + //not thread-safe + Future future = Bukkit.getScheduler().callSyncMethod(xAuthPlugin, new Callable() { + @Override + public Boolean call() throws Exception { + xAuthPlayer xAuthPlayer = xAuthPlugin.getPlayerManager().getPlayer(player); + if (xAuthPlayer != null) { + //we checked that the player is premium (paid account) + //unprotect the inventory, op status... + xAuthPlayer.setPremium(true); - xAuthPlayer xAuthPlayer = xAuthPlugin.getPlayerManager().getPlayer(player); - if (xAuthPlayer != null) { - //we checked that the player is premium (paid account) - //unprotect the inventory, op status... - xAuthPlayer.setPremium(true); + xAuthPlugin.getPlayerManager().doLogin(xAuthPlayer); + return true; + } - //not thread-safe - xAuthPlugin.getPlayerManager().doLogin(xAuthPlayer); + return false; + } + }); + + try { + return future.get(); + } catch (InterruptedException | ExecutionException ex) { + xAuthPlugin.getLogger().log(Level.SEVERE, "Failed to forceLogin", ex); + return false; } } @Override - public boolean isRegistered(String playerName) { - xAuth xAuthPlugin = xAuth.getPlugin(); + public boolean isRegistered(String playerName) throws Exception { //this will load the player if it's not in the cache xAuthPlayer xAuthPlayer = xAuthPlugin.getPlayerManager().getPlayer(playerName); return xAuthPlayer != null && xAuthPlayer.isRegistered(); } @Override - public void forceRegister(Player player, String password) { - xAuth xAuthPlugin = xAuth.getPlugin(); + public boolean forceRegister(final Player player, final String password) { + //not thread-safe + Future future = Bukkit.getScheduler().callSyncMethod(xAuthPlugin, new Callable() { + @Override + public Boolean call() throws Exception { + xAuthPlayer xAuthPlayer = xAuthPlugin.getPlayerManager().getPlayer(player); + if (xAuthPlayer != null) { + //this should run async because the plugin executes a sql query, but the method + //accesses non thread-safe collections :( + boolean registerSuccess = xAuthPlugin.getAuthClass(xAuthPlayer) + .adminRegister(player.getName(), password, null); - xAuthPlayer xAuthPlayer = xAuthPlugin.getPlayerManager().getPlayer(player); - if (xAuthPlayer != null) { - //this should run async because the plugin executes a sql query, but the method - //accesses non thread-safe collections :( - xAuthPlugin.getAuthClass(xAuthPlayer).adminRegister(player.getName(), password, null); + if (registerSuccess) { + //login in the player after registration + return forceLogin(player); + } + } - //login in the player after registration - forceLogin(player); + return false; + } + }); + + try { + return future.get(); + } catch (InterruptedException | ExecutionException ex) { + xAuthPlugin.getLogger().log(Level.SEVERE, "Failed to forceLogin", ex); + return false; } } } diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BungeeCordListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BungeeCordListener.java index 59b35eb4..8e29ce2c 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BungeeCordListener.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BungeeCordListener.java @@ -28,7 +28,7 @@ public class BungeeCordListener implements PluginMessageListener { private static final String FILE_NAME = "proxy-whitelist.txt"; - private final FastLoginBukkit plugin; + protected final FastLoginBukkit plugin; //null if whitelist is empty so bungeecord support is disabled private final UUID proxyId; @@ -72,9 +72,13 @@ public class BungeeCordListener implements PluginMessageListener { @Override public void run() { BukkitAuthPlugin authPlugin = plugin.getAuthPlugin(); - //we need to check if the player is registered on Bukkit too - if (authPlugin != null && !authPlugin.isRegistered(playerName)) { - plugin.getSessions().put(checkedPlayer.getAddress().toString(), playerSession); + try { + //we need to check if the player is registered on Bukkit too + if (authPlugin != null && !authPlugin.isRegistered(playerName)) { + plugin.getSessions().put(checkedPlayer.getAddress().toString(), playerSession); + } + } catch (Exception ex) { + plugin.getLogger().log(Level.SEVERE, "Failed to query isRegistered", ex); } } }); diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ProtocolSupportListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ProtocolSupportListener.java index f34d7cdd..99c7f6de 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ProtocolSupportListener.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ProtocolSupportListener.java @@ -43,12 +43,16 @@ public class ProtocolSupportListener implements Listener { } else if (playerProfile.getUserId() == -1) { //user not exists in the db BukkitAuthPlugin authPlugin = plugin.getAuthPlugin(); - if (plugin.getConfig().getBoolean("autoRegister") && !authPlugin.isRegistered(username)) { - UUID premiumUUID = plugin.getApiConnector().getPremiumUUID(username); - if (premiumUUID != null) { - plugin.getLogger().log(Level.FINER, "Player {0} uses a premium username", username); - startPremiumSession(username, loginStartEvent, false); + try { + if (plugin.getConfig().getBoolean("autoRegister") && !authPlugin.isRegistered(username)) { + UUID premiumUUID = plugin.getApiConnector().getPremiumUUID(username); + if (premiumUUID != null) { + plugin.getLogger().log(Level.FINER, "Player {0} uses a premium username", username); + startPremiumSession(username, loginStartEvent, false); + } } + } catch (Exception ex) { + plugin.getLogger().log(Level.SEVERE, "Failed to query isRegistered", ex); } } } diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/StartPacketListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/StartPacketListener.java index c927eb7c..b5cb209b 100644 --- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/StartPacketListener.java +++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/StartPacketListener.java @@ -84,12 +84,16 @@ public class StartPacketListener extends PacketAdapter { } else if (playerProfile.getUserId() == -1) { //user not exists in the db BukkitAuthPlugin authPlugin = plugin.getAuthPlugin(); - if (plugin.getConfig().getBoolean("autoRegister") && !authPlugin.isRegistered(username)) { - UUID premiumUUID = plugin.getApiConnector().getPremiumUUID(username); - if (premiumUUID != null) { - plugin.getLogger().log(Level.FINER, "Player {0} uses a premium username", username); - enablePremiumLogin(username, sessionKey, player, packetEvent, false); + try { + if (plugin.getConfig().getBoolean("autoRegister") && !authPlugin.isRegistered(username)) { + UUID premiumUUID = plugin.getApiConnector().getPremiumUUID(username); + if (premiumUUID != null) { + plugin.getLogger().log(Level.FINER, "Player {0} uses a premium username", username); + enablePremiumLogin(username, sessionKey, player, packetEvent, false); + } } + } catch (Exception ex) { + plugin.getLogger().log(Level.SEVERE, "Failed to query isRegistered", ex); } } } diff --git a/bungee/pom.xml b/bungee/pom.xml index ad5da301..0968786c 100644 --- a/bungee/pom.xml +++ b/bungee/pom.xml @@ -5,7 +5,7 @@ com.github.games647 fastlogin - 0.8 + 1.0 ../pom.xml diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/PlayerConnectionListener.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/PlayerConnectionListener.java index 95fd2a3d..17f204b0 100644 --- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/PlayerConnectionListener.java +++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/PlayerConnectionListener.java @@ -65,6 +65,8 @@ public class PlayerConnectionListener implements Listener { } } } + } catch (Exception ex) { + plugin.getLogger().log(Level.SEVERE, "Failed to check premium state", ex); } finally { preLoginEvent.completeIntent(plugin); } diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/hooks/BungeeAuthHook.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/hooks/BungeeAuthHook.java index 3009bff3..e5d8fe57 100644 --- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/hooks/BungeeAuthHook.java +++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/hooks/BungeeAuthHook.java @@ -25,7 +25,7 @@ public class BungeeAuthHook implements BungeeAuthPlugin { private final Tables databaseConnection = new Tables(); @Override - public void forceLogin(final ProxiedPlayer player) { + public boolean forceLogin(final ProxiedPlayer player) { //https://github.com/MatteCarra/BungeeAuth/blob/master/src/me/vik1395/BungeeAuth/Login.java#L92-95 Main.plonline.add(player.getName()); @@ -42,18 +42,21 @@ public class BungeeAuthHook implements BungeeAuthPlugin { ListenerClass.prelogin.get(player.getName()).cancel(); } catch (Exception ex) { Main.plugin.getLogger().severe("[BungeeAuth] Error force loging in player"); + return false; } + + return true; } @Override - public boolean isRegistered(String playerName) { + public boolean isRegistered(String playerName) throws Exception { //https://github.com/MatteCarra/BungeeAuth/blob/master/src/me/vik1395/BungeeAuth/Register.java#L46 //renamed t to databaseConnection return databaseConnection.checkPlayerEntry(playerName); } @Override - public void forceRegister(final ProxiedPlayer player, String password) { + public boolean forceRegister(final ProxiedPlayer player, String password) { //https://github.com/MatteCarra/BungeeAuth/blob/master/src/me/vik1395/BungeeAuth/Register.java#L102 PasswordHandler ph = new PasswordHandler(); Random rand = new Random(); @@ -84,7 +87,10 @@ public class BungeeAuthHook implements BungeeAuthPlugin { forceLogin(player); } catch (Exception ex) { Main.plugin.getLogger().severe("[BungeeAuth] Error when creating a new player in the Database"); + return false; } + + return true; } //pail ;( diff --git a/bungee/src/main/java/com/github/games647/fastlogin/bungee/hooks/BungeeAuthPlugin.java b/bungee/src/main/java/com/github/games647/fastlogin/bungee/hooks/BungeeAuthPlugin.java index b1c41e00..39259cbb 100644 --- a/bungee/src/main/java/com/github/games647/fastlogin/bungee/hooks/BungeeAuthPlugin.java +++ b/bungee/src/main/java/com/github/games647/fastlogin/bungee/hooks/BungeeAuthPlugin.java @@ -2,6 +2,9 @@ package com.github.games647.fastlogin.bungee.hooks; import net.md_5.bungee.api.connection.ProxiedPlayer; +/** + * Represents a supporting authentication plugin in BungeeCord/Waterfall/... servers + */ public interface BungeeAuthPlugin { /** @@ -9,8 +12,9 @@ public interface BungeeAuthPlugin { * the player joined successfully a server. * * @param player the player that needs to be logged in + * @return if the operation was successful */ - void forceLogin(ProxiedPlayer player); + boolean forceLogin(ProxiedPlayer player); /** * Checks whether an account exists for this player name. @@ -24,8 +28,9 @@ public interface BungeeAuthPlugin { * * @param playerName player name * @return if the player has an account + * @throws Exception if an error occurred */ - boolean isRegistered(String playerName); + boolean isRegistered(String playerName) throws Exception; /** * Forces a register in order to protect the paid account. @@ -44,6 +49,7 @@ public interface BungeeAuthPlugin { * * @param player the premium account * @param password a strong random generated password + * @return if the operation was successful */ - void forceRegister(ProxiedPlayer player, String password); + boolean forceRegister(ProxiedPlayer player, String password); } diff --git a/pom.xml b/pom.xml index e498c4b0..13f6efea 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ pom FastLogin - 0.8 + 1.0 2015 https://www.spigotmc.org/resources/fastlogin.14153/ diff --git a/universal/pom.xml b/universal/pom.xml index 5426e22f..a5e6747e 100644 --- a/universal/pom.xml +++ b/universal/pom.xml @@ -5,7 +5,7 @@ com.github.games647 fastlogin - 0.8 + 1.0 ../pom.xml