diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index e96b58783..fe23a67a6 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -283,19 +283,17 @@ public class AuthMe extends JavaPlugin { } // Reload support hook - if (Settings.reloadSupport) { - if (database != null) { - int playersOnline = Utils.getOnlinePlayers().size(); - if (playersOnline < 1) { - database.purgeLogged(); - } else { - for (PlayerAuth auth : database.getLoggedPlayers()) { - if (auth == null) - continue; - auth.setLastLogin(new Date().getTime()); - database.updateSession(auth); - PlayerCache.getInstance().addPlayer(auth); - } + if (database != null) { + int playersOnline = Utils.getOnlinePlayers().size(); + if (playersOnline < 1) { + database.purgeLogged(); + } else if (Settings.reloadSupport) { + for (PlayerAuth auth : database.getLoggedPlayers()) { + if (auth == null) + continue; + auth.setLastLogin(new Date().getTime()); + database.updateSession(auth); + PlayerCache.getInstance().addPlayer(auth); } } } @@ -362,11 +360,6 @@ public class AuthMe extends JavaPlugin { } } - // Close the database - if (database != null) { - database.close(); - } - // Do backup on stop if enabled if (Settings.isBackupActivated && Settings.isBackupOnStop) { boolean Backup = new PerformBackup(this).doBackup(); @@ -378,6 +371,11 @@ public class AuthMe extends JavaPlugin { // Unload modules moduleManager.unloadModules(); + // Close the database + if (database != null) { + database.close(); + } + // Disabled correctly ConsoleLogger.info("AuthMe " + this.getDescription().getVersion() + " disabled!"); } @@ -584,7 +582,6 @@ public class AuthMe extends JavaPlugin { } } PlayerCache.getInstance().removePlayer(name); - database.setUnlogged(name); player.saveData(); } diff --git a/src/main/java/fr/xephi/authme/commands/AdminCommand.java b/src/main/java/fr/xephi/authme/commands/AdminCommand.java index d21c5ba16..b7b6c698f 100644 --- a/src/main/java/fr/xephi/authme/commands/AdminCommand.java +++ b/src/main/java/fr/xephi/authme/commands/AdminCommand.java @@ -234,6 +234,7 @@ public class AdminCommand implements CommandExecutor { return true; } final String name = args[1].toLowerCase(); + final String realName = args[1]; final String lowpass = args[2].toLowerCase(); if (lowpass.contains("delete") || lowpass.contains("where") || lowpass.contains("insert") || lowpass.contains("modify") || lowpass.contains("from") || lowpass.contains("select") || lowpass.contains(";") || lowpass.contains("null") || !lowpass.matches(Settings.getPassRegex)) { m.send(sender, "password_error"); @@ -262,7 +263,7 @@ public class AdminCommand implements CommandExecutor { return; } String hash = PasswordSecurity.getHash(Settings.getPasswordHash, lowpass, name); - PlayerAuth auth = new PlayerAuth(name, hash, "192.168.0.1", 0L, "your@email.com", name); + PlayerAuth auth = new PlayerAuth(name, hash, "192.168.0.1", 0L, "your@email.com", realName); if (PasswordSecurity.userSalt.containsKey(name) && PasswordSecurity.userSalt.get(name) != null) auth.setSalt(PasswordSecurity.userSalt.get(name)); else auth.setSalt(""); @@ -270,6 +271,9 @@ public class AdminCommand implements CommandExecutor { m.send(sender, "error"); return; } + plugin.database.setUnlogged(name); + if (Bukkit.getPlayerExact(realName) != null) + Bukkit.getPlayerExact(realName).kickPlayer("An admin just registered you, please log again"); m.send(sender, "registered"); ConsoleLogger.info(name + " registered"); } catch (NoSuchAlgorithmException ex) { diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java index 28b85ee4e..1d76a68e4 100644 --- a/src/main/java/fr/xephi/authme/datasource/MySQL.java +++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java @@ -19,6 +19,8 @@ import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.settings.Settings; +import org.bukkit.Bukkit; + public class MySQL implements DataSource { private String host; @@ -106,9 +108,15 @@ public class MySQL implements DataSource { config.setJdbcUrl("jdbc:mysql://" + this.host + ":" + this.port + "/" + this.database); config.setUsername(this.username); config.setPassword(this.password); - config.addDataSourceProperty("cachePrepStmts", "true"); - config.addDataSourceProperty("prepStmtCacheSize", "250"); - config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); + if (Settings.isMySQLWebsite) + { + config.addDataSourceProperty("cachePrepStmts", "false"); + } + else { + config.addDataSourceProperty("cachePrepStmts", "true"); + config.addDataSourceProperty("prepStmtCacheSize", "250"); + config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); + } config.addDataSourceProperty("autoReconnect", false); config.setInitializationFailFast(true); // Don't start the plugin if the database is unavariable config.setMaxLifetime(180000); // 3 Min @@ -128,9 +136,24 @@ public class MySQL implements DataSource { } private synchronized Connection getConnection() throws SQLException { - Connection con; - con = ds.getConnection(); - return con; + if (!ds.isClosed()) + { + Connection con; + con = ds.getConnection(); + return con; + } + ConsoleLogger.showError("Can't open a database connection!"); + if (Settings.isStopEnabled) + { + ConsoleLogger.showError("Server will ShuttingDown for Security reason"); + Bukkit.getScheduler().scheduleSyncDelayedTask(AuthMe.getInstance(), new Runnable(){ + @Override + public void run() { + AuthMe.getInstance().getServer().shutdown(); + } + }); + } + return null; } private synchronized void setupConnection() throws SQLException { @@ -138,7 +161,8 @@ public class MySQL implements DataSource { Statement st = null; ResultSet rs = null; try { - con = getConnection(); + if ((con = getConnection()) == null) + return; st = con.createStatement(); st.executeUpdate("CREATE TABLE IF NOT EXISTS " + tableName + " (" + columnID + " INTEGER AUTO_INCREMENT," + columnName + " VARCHAR(255) NOT NULL UNIQUE," + columnPassword + " VARCHAR(255) NOT NULL," + columnIp + " VARCHAR(40) NOT NULL DEFAULT '127.0.0.1'," + columnLastLogin + " BIGINT NOT NULL DEFAULT '" + System.currentTimeMillis() + "'," + lastlocX + " DOUBLE NOT NULL DEFAULT '0.0'," + lastlocY + " DOUBLE NOT NULL DEFAULT '0.0'," + lastlocZ + " DOUBLE NOT NULL DEFAULT '0.0'," + lastlocWorld + " VARCHAR(255) NOT NULL DEFAULT '" + Settings.defaultWorld + "'," + columnEmail + " VARCHAR(255) DEFAULT 'your@email.com'," + columnLogged + " SMALLINT NOT NULL DEFAULT '0'," + "CONSTRAINT table_const_prim PRIMARY KEY (" + columnID + "));"); rs = con.getMetaData().getColumns(null, null, tableName, columnPassword); @@ -185,6 +209,8 @@ public class MySQL implements DataSource { if (!rs.next()) { st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + columnRealName + " VARCHAR(255) NOT NULL DEFAULT 'Player' AFTER " + columnLogged + ";"); } + if (Settings.isMySQLWebsite) + st.execute("SET GLOBAL query_cache_size = 0; SET GLOBAL query_cache_type = 0;"); } finally { close(rs); close(st); @@ -199,7 +225,8 @@ public class MySQL implements DataSource { PreparedStatement pst = null; ResultSet rs = null; try { - con = getConnection(); + if ((con = getConnection()) == null) + return true; pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE LOWER(" + columnName + ")=LOWER(?);"); pst.setString(1, user); rs = pst.executeQuery(); @@ -222,7 +249,8 @@ public class MySQL implements DataSource { PlayerAuth pAuth = null; int id; try { - con = getConnection(); + if ((con = getConnection()) == null) + return null; pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE LOWER(" + columnName + ")=LOWER(?);"); pst.setString(1, user); rs = pst.executeQuery(); @@ -272,7 +300,8 @@ public class MySQL implements DataSource { PreparedStatement pst = null; ResultSet rs = null; try { - con = getConnection(); + if ((con = getConnection()) == null) + return false; if ((columnSalt == null || columnSalt.isEmpty()) || (auth.getSalt() == null || auth.getSalt().isEmpty())) { pst = con.prepareStatement("INSERT INTO " + tableName + "(" + columnName + "," + columnPassword + "," + columnIp + "," + columnLastLogin + "," + columnRealName + ") VALUES (?,?,?,?,?);"); pst.setString(1, auth.getNickname()); @@ -478,7 +507,8 @@ public class MySQL implements DataSource { PreparedStatement pst = null; ResultSet rs = null; try { - con = getConnection(); + if ((con = getConnection()) == null) + return false; pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnPassword + "=? WHERE LOWER(" + columnName + ")=?;"); pst.setString(1, auth.getHash()); pst.setString(2, auth.getNickname()); @@ -521,7 +551,8 @@ public class MySQL implements DataSource { Connection con = null; PreparedStatement pst = null; try { - con = getConnection(); + if ((con = getConnection()) == null) + return false; pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnIp + "=?, " + columnLastLogin + "=?, " + columnRealName + "=? WHERE LOWER(" + columnName + ")=?;"); pst.setString(1, auth.getIp()); pst.setLong(2, auth.getLastLogin()); @@ -543,7 +574,8 @@ public class MySQL implements DataSource { Connection con = null; PreparedStatement pst = null; try { - con = getConnection(); + if ((con = getConnection()) == null) + return 0; pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnLastLogin + " list = new ArrayList<>(); try { - con = getConnection(); + if ((con = getConnection()) == null) + return list; pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnLastLogin + " countIp = new ArrayList<>(); try { - con = getConnection(); + if ((con = getConnection()) == null) + return countIp; pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnIp + "=?;"); pst.setString(1, auth.getIp()); rs = pst.executeQuery(); @@ -775,7 +814,8 @@ public class MySQL implements DataSource { ResultSet rs = null; List countIp = new ArrayList<>(); try { - con = getConnection(); + if ((con = getConnection()) == null) + return countIp; pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnIp + "=?;"); pst.setString(1, ip); rs = pst.executeQuery(); @@ -800,7 +840,8 @@ public class MySQL implements DataSource { ResultSet rs = null; List countEmail = new ArrayList<>(); try { - con = getConnection(); + if ((con = getConnection()) == null) + return countEmail; pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnEmail + "=?;"); pst.setString(1, email); rs = pst.executeQuery(); @@ -823,8 +864,9 @@ public class MySQL implements DataSource { Connection con = null; PreparedStatement pst = null; try { + if ((con = getConnection()) == null) + return; for (String name : banned) { - con = getConnection(); pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE LOWER(" + columnName + ")=?;"); pst.setString(1, name); pst.executeUpdate(); @@ -848,7 +890,8 @@ public class MySQL implements DataSource { PreparedStatement pst = null; ResultSet rs = null; try { - con = getConnection(); + if ((con = getConnection()) == null) + return false; pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE LOWER(" + columnName + ")=?;"); pst.setString(1, user); rs = pst.executeQuery(); @@ -870,7 +913,8 @@ public class MySQL implements DataSource { Connection con = null; PreparedStatement pst = null; try { - con = getConnection(); + if ((con = getConnection()) == null) + return; pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnLogged + "=? WHERE LOWER(" + columnName + ")=?;"); pst.setInt(1, 1); pst.setString(2, user); @@ -889,7 +933,8 @@ public class MySQL implements DataSource { PreparedStatement pst = null; if (user != null) try { - con = getConnection(); + if ((con = getConnection()) == null) + return; pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnLogged + "=? WHERE LOWER(" + columnName + ")=?;"); pst.setInt(1, 0); pst.setString(2, user); @@ -907,7 +952,8 @@ public class MySQL implements DataSource { Connection con = null; PreparedStatement pst = null; try { - con = getConnection(); + if ((con = getConnection()) == null) + return; pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnLogged + "=? WHERE " + columnLogged + "=?;"); pst.setInt(1, 0); pst.setInt(2, 1); @@ -927,7 +973,8 @@ public class MySQL implements DataSource { PreparedStatement pst = null; ResultSet rs; try { - con = getConnection(); + if ((con = getConnection()) == null) + return result; pst = con.prepareStatement("SELECT COUNT(*) FROM " + tableName + ";"); rs = pst.executeQuery(); if (rs != null && rs.next()) { @@ -948,7 +995,8 @@ public class MySQL implements DataSource { Connection con = null; PreparedStatement pst = null; try { - con = getConnection(); + if ((con = getConnection()) == null) + return; pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnName + "=? WHERE LOWER(" + columnName + ")=?;"); pst.setString(1, newone); pst.setString(2, oldone); @@ -968,7 +1016,8 @@ public class MySQL implements DataSource { PreparedStatement pst = null; ResultSet rs = null; try { - con = getConnection(); + if ((con = getConnection()) == null) + return auths; pst = con.prepareStatement("SELECT * FROM " + tableName + ";"); rs = pst.executeQuery(); while (rs.next()) { @@ -1018,7 +1067,8 @@ public class MySQL implements DataSource { PreparedStatement pst = null; ResultSet rs = null; try { - con = getConnection(); + if ((con = getConnection()) == null) + return auths; pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnLogged + "=1;"); rs = pst.executeQuery(); while (rs.next()) { diff --git a/src/main/java/fr/xephi/authme/process/login/ProcessSyncronousPlayerLogin.java b/src/main/java/fr/xephi/authme/process/login/ProcessSyncronousPlayerLogin.java index 20eacdf2e..00322f68d 100644 --- a/src/main/java/fr/xephi/authme/process/login/ProcessSyncronousPlayerLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/ProcessSyncronousPlayerLogin.java @@ -69,12 +69,8 @@ public class ProcessSyncronousPlayerLogin implements Runnable { protected void teleportBackFromSpawn() { AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(player, limbo.getLoc()); pm.callEvent(tpEvent); - if (!tpEvent.isCancelled()) { - Location fLoc = tpEvent.getTo(); - if (!fLoc.getChunk().isLoaded()) { - fLoc.getChunk().load(); - } - player.teleport(fLoc); + if (!tpEvent.isCancelled() && tpEvent.getTo() != null) { + player.teleport(tpEvent.getTo()); } } @@ -82,12 +78,8 @@ public class ProcessSyncronousPlayerLogin implements Runnable { Location spawnL = plugin.getSpawnLocation(player); SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnL, true); pm.callEvent(tpEvent); - if (!tpEvent.isCancelled()) { - Location fLoc = tpEvent.getTo(); - if (!fLoc.getChunk().isLoaded()) { - fLoc.getChunk().load(); - } - player.teleport(fLoc); + if (!tpEvent.isCancelled() && tpEvent.getTo() != null) { + player.teleport(tpEvent.getTo()); } } diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index 930d6f289..156e269ba 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -74,7 +74,7 @@ public final class Settings extends YamlConfiguration { enableProtection, enableAntiBot, recallEmail, useWelcomeMessage, broadcastWelcomeMessage, forceRegKick, forceRegLogin, checkVeryGames, delayJoinMessage, noTeleport, applyBlindEffect, - customAttributes, generateImage, isRemoveSpeedEnabled; + customAttributes, generateImage, isRemoveSpeedEnabled, isMySQLWebsite; public static String getNickRegex, getUnloggedinGroup, getMySQLHost, getMySQLPort, getMySQLUsername, getMySQLPassword, getMySQLDatabase, @@ -281,6 +281,7 @@ public final class Settings extends YamlConfiguration { forceRegisterCommandsAsConsole = configFile.getStringList("settings.forceRegisterCommandsAsConsole"); customAttributes = configFile.getBoolean("Hooks.customAttributes"); generateImage = configFile.getBoolean("Email.generateImage", true); + isMySQLWebsite = configFile.getBoolean("DataSource.mySQLWebsite", false); // Load the welcome message getWelcomeMessage(); @@ -482,6 +483,10 @@ public final class Settings extends YamlConfiguration { set("DataSource.mySQLRealName", "realname"); changes = true; } + if (!contains("DataSource.mySQLQueryCache")) { + set("DataSource.mySQLWebsite", false); + changes = true; + } if (changes) { plugin.getLogger().warning("Merged new Config Options - I'm not an error, please don't report me"); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c10c977e7..ef9fd2144 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -43,12 +43,14 @@ DataSource: mySQLlastlocWorld: world # Column for RealName mySQLRealName: realname + # Enable this when you allow registration through a website + mySQLWebsite: false settings: sessions: - # Do you want to enable the session feature? + # Do you want to enable the session feature? # If enabled, when a player authenticates successfully, # his IP and his nickname is saved. - # The next time the player joins the server, if his IP + # The next time the player joins the server, if his IP # is the same of the last time, and the timeout time # hasn't expired, he will not need to authenticate. enabled: false @@ -62,7 +64,7 @@ settings: # another IP Address? sessionExpireOnIpChange: true restrictions: - # Can not authenticated players chat and see the chat log? + # Can not authenticated players chat and see the chat log? # Care that this feature blocks also all the commands not # listed in the list below. allowChat: false @@ -109,7 +111,7 @@ settings: # After the authentication they will be teleported back to # their normal position. teleportUnAuthedToSpawn: false - # Minimum allowed nick length + # Minimum allowed nick length minNicknameLength: 4 # Can unregistered players walk around? allowMovement: false @@ -161,25 +163,25 @@ settings: security: # minimum Length of password minPasswordLength: 5 - # this is very important options, + # this is very important options, # every time player join the server, - # if they are registered, AuthMe will switch him + # if they are registered, AuthMe will switch him # to unLoggedInGroup, this - # should prevent all major exploit. + # should prevent all major exploit. # So you can set up on your Permission Plugin - # this special group with 0 permissions, or permissions to chat, + # this special group with 0 permissions, or permissions to chat, # or permission to - # send private message or all other perms that you want, + # send private message or all other perms that you want, # the better way is to set up # this group with few permissions, # so if player try to exploit some account, # they can # do anything except what you set in perm Group. - # After a correct logged-in player will be + # After a correct logged-in player will be # moved to his correct permissions group! - # Pay attention group name is case sensitive, - # so Admin is different from admin, - # otherwise your group will be wiped, + # Pay attention group name is case sensitive, + # so Admin is different from admin, + # otherwise your group will be wiped, # and player join in default group []! # Example unLoggedinGroup: NotLogged unLoggedinGroup: unLoggedinGroup @@ -244,7 +246,7 @@ settings: # Force these commands after /register as a server console, without any '/', use %p for replace with player name forceRegisterCommandsAsConsole: [] # Do we need to display the welcome message (welcome.txt) after a register or a login? - # You can use colors in this welcome.txt + some replaced strings : + # You can use colors in this welcome.txt + some replaced strings : # {PLAYER} : player name, {ONLINE} : display number of online players, {MAXPLAYERS} : display server slots, # {IP} : player ip, {LOGINS} : number of players logged, {WORLD} : player current world, {SERVER} : server name # {VERSION} : get current bukkit version, {COUNTRY} : player country