From 39620f1aab8ece5cc7512595003c9eddb006dff6 Mon Sep 17 00:00:00 2001 From: nossr50 Date: Thu, 22 Mar 2012 12:59:26 -0700 Subject: [PATCH] Changes to MySQL reconnection stuff and OnDisable() --- Changelog.txt | 2 + src/main/java/com/gmail/nossr50/Database.java | 88 +++++++++++-------- .../nossr50/datatypes/DatabaseUpdate.java | 2 +- .../nossr50/listeners/mcSpoutListener.java | 4 +- src/main/java/com/gmail/nossr50/mcMMO.java | 4 +- 5 files changed, 58 insertions(+), 42 deletions(-) diff --git a/Changelog.txt b/Changelog.txt index d8d849c74..b5b20004e 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -30,6 +30,8 @@ Version 2.0.00-dev = Fixed exploit where falling sand & gravel weren't tracked = Fixed exploit where Acrobatics could be leveled via Dodge on party members. = Fixed exploit where you could gain combat XP on animals summoned by Call of the Wild + ! Changed MySQL to try to reconnect every 60 seconds rather than infinitely which caused server hangs + ! Changed mcMMO to be better about saving player information on server shutdown ! Changed PTP to prevent teleporting if you've been hurt in the last 30 seconds (configurable) ! Changed Chimera Wing failure check to use the maxWorldHeight. ! Changed inspect failed message to say inspect rather than whois diff --git a/src/main/java/com/gmail/nossr50/Database.java b/src/main/java/com/gmail/nossr50/Database.java index 895696a14..87811df52 100644 --- a/src/main/java/com/gmail/nossr50/Database.java +++ b/src/main/java/com/gmail/nossr50/Database.java @@ -17,10 +17,12 @@ import com.gmail.nossr50.datatypes.DatabaseUpdate; public class Database { private String connectionString = "jdbc:mysql://" + LoadProperties.MySQLserverName + ":" + LoadProperties.MySQLport + "/" + LoadProperties.MySQLdbName + "?user=" + LoadProperties.MySQLuserName + "&password=" + LoadProperties.MySQLdbPass; - private boolean isConnected; private Connection conn = null; + private mcMMO plugin = null; + private long reconnectTimestamp = 0; public Database(mcMMO instance) { + plugin = instance; connect(); //Connect to MySQL // Load the driver instance @@ -44,14 +46,13 @@ public class Database { try { System.out.println("[mcMMO] Attempting connection to MySQL..."); Properties conProperties = new Properties(); - conProperties.put("autoReconnect", "true"); - conProperties.put("maxReconnects", "3"); + conProperties.put("autoReconnect", "false"); + conProperties.put("maxReconnects", "0"); conn = DriverManager.getConnection(connectionString, conProperties); - isConnected = true; - System.out.println("[mcMMO] Connection to MySQL established!"); + System.out.println("[mcMMO] Connection to MySQL was a success!"); } catch (SQLException ex) { - isConnected = false; + System.out.println("[mcMMO] Connection to MySQL failed!"); ex.printStackTrace(); printErrors(ex); } @@ -111,10 +112,6 @@ public class Database { + "`acrobatics` int(10) unsigned NOT NULL DEFAULT '0'," + "PRIMARY KEY (`user_id`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;"); - write("DROP TABLE IF EXISTS `"+LoadProperties.MySQLtablePrefix+"skills2`"); - write("DROP TABLE IF EXISTS `"+LoadProperties.MySQLtablePrefix+"experience2`"); - write("DROP TABLE IF EXISTS `"+LoadProperties.MySQLtablePrefix+"spawn`"); - checkDatabaseStructure(DatabaseUpdate.FISHING); checkDatabaseStructure(DatabaseUpdate.BLAST_MINING); } @@ -174,7 +171,7 @@ public class Database { * @return true if the query was successfully written, false otherwise. */ public boolean write(String sql) { - if (conn != null) { + if (isConnected()) { try { PreparedStatement stmt = conn.prepareStatement(sql); stmt.executeUpdate(); @@ -186,14 +183,7 @@ public class Database { } } else { - isConnected = false; - connect(); //Attempt to reconnect - if (isConnected) { - write(sql); //Try the same operation again now that we are connected - } - else { - System.out.println("[mcMMO] Unable to connect to MySQL! Make sure the SQL server is online!"); - } + attemptReconnect(); } return false; } @@ -208,7 +198,7 @@ public class Database { ResultSet rs = null; Integer result = 0; - if (conn != null) { + if (isConnected()) { try { PreparedStatement stmt = conn.prepareStatement(sql); stmt = conn.prepareStatement(sql); @@ -228,17 +218,46 @@ public class Database { } } else { - isConnected = false; - connect(); //Attempt to reconnect - if (isConnected) { - getInt(sql); //Try the same operation again now that we are connected - } - else { - System.out.println("[mcMMO] Unable to connect to MySQL! Make sure the SQL server is online!"); - } + attemptReconnect(); } return result; } + + /** + * Get connection status + * + * @return the boolean value for whether or not we are connected + */ + public boolean isConnected() { + if(conn == null) + return false; + + try { + return conn.isValid(3); + } catch (SQLException e) { + return false; + } + } + + /** + * Schedules a Sync Delayed Task with the Bukkit Scheduler to attempt reconnection after a minute has elapsed + * This will check for a connection being present or not to prevent unneeded reconnection attempts + */ + public void attemptReconnect() { + if(reconnectTimestamp+60000 < System.currentTimeMillis()) //Only reconnect if another attempt hasn't been made recently + { + System.out.println("[mcMMO] Connection to MySQL was lost! Attempting to reconnect in 60 seconds..."); + reconnectTimestamp = System.currentTimeMillis(); + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, + new Runnable() { + public void run() { + if (!isConnected()) { + connect(); + } + } + }, 20*60); + } + } /** * Read SQL query. @@ -250,7 +269,7 @@ public class Database { ResultSet rs = null; HashMap> Rows = new HashMap>(); - if (conn != null) { + if (isConnected()) { try { PreparedStatement stmt = conn.prepareStatement(sql); if (stmt.executeQuery() != null) { @@ -270,14 +289,7 @@ public class Database { } } else { - isConnected = false; - connect(); //Attempt to reconnect - if (isConnected) { - read(sql); //Attempt the same operation again now that we are connected - } - else { - System.out.println("[mcMMO] Unable to connect to MySQL! Make sure the SQL server is online!"); - } + attemptReconnect(); } return Rows; } @@ -287,4 +299,4 @@ public class Database { System.out.println("SQLState: " + ex.getSQLState()); System.out.println("VendorError: " + ex.getErrorCode()); } -} +} \ No newline at end of file diff --git a/src/main/java/com/gmail/nossr50/datatypes/DatabaseUpdate.java b/src/main/java/com/gmail/nossr50/datatypes/DatabaseUpdate.java index 75b11929c..60ee23b22 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/DatabaseUpdate.java +++ b/src/main/java/com/gmail/nossr50/datatypes/DatabaseUpdate.java @@ -3,4 +3,4 @@ package com.gmail.nossr50.datatypes; public enum DatabaseUpdate { FISHING, BLAST_MINING; -} +} \ No newline at end of file diff --git a/src/main/java/com/gmail/nossr50/listeners/mcSpoutListener.java b/src/main/java/com/gmail/nossr50/listeners/mcSpoutListener.java index 0ef163356..f53ffa5ec 100644 --- a/src/main/java/com/gmail/nossr50/listeners/mcSpoutListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/mcSpoutListener.java @@ -6,6 +6,7 @@ import org.getspout.spoutapi.event.spout.SpoutCraftEnableEvent; import org.getspout.spoutapi.player.SpoutPlayer; import com.gmail.nossr50.Users; +import com.gmail.nossr50.m; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.datatypes.HUDmmo; import com.gmail.nossr50.spout.SpoutStuff; @@ -30,6 +31,7 @@ public class mcSpoutListener implements Listener { if (sPlayer.isSpoutCraftEnabled()) { SpoutStuff.playerHUDs.put(sPlayer, new HUDmmo(sPlayer)); //Setup Party HUD stuff Users.getProfile(sPlayer).toggleSpoutEnabled(); + sPlayer.setTitle(String.valueOf(m.getPowerLevel(sPlayer, Users.getProfile(sPlayer)))); } } -} +} \ No newline at end of file diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index 44c77fed3..465aeff10 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -301,8 +301,8 @@ public class mcMMO extends JavaPlugin { public void onDisable() { //Make sure to save player information if the server shuts down - for (Player x : Bukkit.getOnlinePlayers()) { - Users.getProfile(x).save(); + for (PlayerProfile x : Users.getProfiles().values()) { + x.save(); } Bukkit.getServer().getScheduler().cancelTasks(this); //This removes our tasks