Przeglądaj źródła

Changes to MySQL reconnection stuff and OnDisable()

nossr50 13 lat temu
rodzic
commit
39620f1aab

+ 2 - 0
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

+ 50 - 38
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<Integer, ArrayList<String>> Rows = new HashMap<Integer, ArrayList<String>>();
 
-        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());
     }
-}
+}

+ 1 - 1
src/main/java/com/gmail/nossr50/datatypes/DatabaseUpdate.java

@@ -3,4 +3,4 @@ package com.gmail.nossr50.datatypes;
 public enum DatabaseUpdate {
     FISHING,
     BLAST_MINING;
-}
+}

+ 3 - 1
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))));
         }
     }
-}
+}

+ 2 - 2
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