mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-11-04 11:03:43 +01:00 
			
		
		
		
	Abstract our database operations into a single class.
This allows the logic between SQL and Flatfile to remain more hidden in most cases and makes the code easier to read.
This commit is contained in:
		@@ -6,9 +6,8 @@ import org.bukkit.command.Command;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.command.TabExecutor;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
import com.gmail.nossr50.database.DatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.database.LeaderboardManager;
 | 
			
		||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
			
		||||
import com.gmail.nossr50.util.Permissions;
 | 
			
		||||
 | 
			
		||||
@@ -24,19 +23,10 @@ public class McpurgeCommand implements TabExecutor {
 | 
			
		||||
 | 
			
		||||
        switch (args.length) {
 | 
			
		||||
            case 0:
 | 
			
		||||
                if (Config.getInstance().getUseMySQL()) {
 | 
			
		||||
                    DatabaseManager.purgePowerlessSQL();
 | 
			
		||||
                mcMMO.databaseManager.purgePowerlessUsers();
 | 
			
		||||
 | 
			
		||||
                    if (Config.getInstance().getOldUsersCutoff() != -1) {
 | 
			
		||||
                        DatabaseManager.purgeOldSQL();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    LeaderboardManager.purgePowerlessFlatfile();
 | 
			
		||||
 | 
			
		||||
                    if (Config.getInstance().getOldUsersCutoff() != -1) {
 | 
			
		||||
                        LeaderboardManager.purgeOldFlatfile();
 | 
			
		||||
                    }
 | 
			
		||||
                if (Config.getInstance().getOldUsersCutoff() != -1) {
 | 
			
		||||
                    mcMMO.databaseManager.purgeOldUsers();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                sender.sendMessage(LocaleLoader.getString("Commands.mcpurge.Success"));
 | 
			
		||||
 
 | 
			
		||||
@@ -9,12 +9,9 @@ import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.command.TabExecutor;
 | 
			
		||||
import org.bukkit.util.StringUtil;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
import com.gmail.nossr50.database.DatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.database.LeaderboardManager;
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.datatypes.player.PlayerProfile;
 | 
			
		||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
			
		||||
import com.gmail.nossr50.util.Misc;
 | 
			
		||||
import com.gmail.nossr50.util.Permissions;
 | 
			
		||||
import com.gmail.nossr50.util.commands.CommandUtils;
 | 
			
		||||
import com.gmail.nossr50.util.player.UserManager;
 | 
			
		||||
@@ -35,20 +32,11 @@ public class McremoveCommand implements TabExecutor {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* MySQL */
 | 
			
		||||
                if (Config.getInstance().getUseMySQL()) {
 | 
			
		||||
                    String tablePrefix = Config.getInstance().getMySQLTablePrefix();
 | 
			
		||||
 | 
			
		||||
                    if (DatabaseManager.update("DELETE FROM " + tablePrefix + "users WHERE " + tablePrefix + "users.user = '" + args[0] + "'") != 0) {
 | 
			
		||||
                        Misc.profileCleanup(args[0]);
 | 
			
		||||
                        sender.sendMessage(LocaleLoader.getString("Commands.mcremove.Success", args[0]));
 | 
			
		||||
                    }
 | 
			
		||||
                if (mcMMO.databaseManager.removeUser(args[0])) {
 | 
			
		||||
                    sender.sendMessage(LocaleLoader.getString("Commands.mcremove.Success", args[0]));
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    if (LeaderboardManager.removeFlatFileUser(args[0])) {
 | 
			
		||||
                        Misc.profileCleanup(args[0]);
 | 
			
		||||
                        sender.sendMessage(LocaleLoader.getString("Commands.mcremove.Success", args[0]));
 | 
			
		||||
                    }
 | 
			
		||||
                    sender.sendMessage(args[0] + " could not be removed from the database."); // Pretty sure this should NEVER happen.
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -10,18 +10,12 @@ import org.bukkit.command.TabExecutor;
 | 
			
		||||
import org.bukkit.util.StringUtil;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
import com.gmail.nossr50.database.LeaderboardManager;
 | 
			
		||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 | 
			
		||||
import com.gmail.nossr50.datatypes.player.PlayerProfile;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SkillType;
 | 
			
		||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
			
		||||
import com.gmail.nossr50.runnables.commands.McrankCommandAsyncTask;
 | 
			
		||||
import com.gmail.nossr50.util.Permissions;
 | 
			
		||||
import com.gmail.nossr50.util.commands.CommandUtils;
 | 
			
		||||
import com.gmail.nossr50.util.player.UserManager;
 | 
			
		||||
import com.gmail.nossr50.util.skills.SkillUtils;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.ImmutableList;
 | 
			
		||||
 | 
			
		||||
public class McrankCommand implements TabExecutor {
 | 
			
		||||
@@ -38,13 +32,7 @@ public class McrankCommand implements TabExecutor {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (Config.getInstance().getUseMySQL()) {
 | 
			
		||||
                    sqlDisplay(sender, sender.getName());
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    flatfileDisplay(sender, sender.getName());
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                display(sender, sender.getName());
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            case 1:
 | 
			
		||||
@@ -62,18 +50,12 @@ public class McrankCommand implements TabExecutor {
 | 
			
		||||
                    if (CommandUtils.tooFar(sender, mcMMOPlayer.getPlayer(), Permissions.mcrankFar(sender))) {
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                } else if (CommandUtils.inspectOffline(sender, new PlayerProfile(playerName, false), Permissions.mcrankOffline(sender))) {
 | 
			
		||||
                }
 | 
			
		||||
                else if (CommandUtils.inspectOffline(sender, new PlayerProfile(playerName, false), Permissions.mcrankOffline(sender))) {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (Config.getInstance().getUseMySQL()) {
 | 
			
		||||
                    sqlDisplay(sender, playerName);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    flatfileDisplay(sender, playerName);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                display(sender, playerName);
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
@@ -92,39 +74,7 @@ public class McrankCommand implements TabExecutor {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void flatfileDisplay(CommandSender sender, String playerName) {
 | 
			
		||||
        LeaderboardManager.updateLeaderboards(); // Make sure the information is up to date
 | 
			
		||||
 | 
			
		||||
        sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Heading"));
 | 
			
		||||
        sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Player", playerName));
 | 
			
		||||
 | 
			
		||||
        for (SkillType skillType : SkillType.values()) {
 | 
			
		||||
            int[] rankInts = LeaderboardManager.getPlayerRank(playerName, skillType);
 | 
			
		||||
 | 
			
		||||
            if (!Permissions.skillEnabled(sender, skillType) || skillType.isChildSkill()) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (rankInts[1] == 0) {
 | 
			
		||||
                sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", SkillUtils.getSkillName(skillType), LocaleLoader.getString("Commands.mcrank.Unranked"))); // Don't bother showing ranking for players without skills
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", SkillUtils.getSkillName(skillType), rankInts[0]));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Show the powerlevel ranking
 | 
			
		||||
        int[] rankInts = LeaderboardManager.getPlayerRank(playerName);
 | 
			
		||||
 | 
			
		||||
        if (rankInts[1] == 0) {
 | 
			
		||||
            sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Overall", LocaleLoader.getString("Commands.mcrank.Unranked"))); // Don't bother showing ranking for players without skills
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Overall", rankInts[0]));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void sqlDisplay(CommandSender sender, String playerName) {
 | 
			
		||||
    private void display(CommandSender sender, String playerName) {
 | 
			
		||||
        new McrankCommandAsyncTask(playerName, sender).runTaskAsynchronously(mcMMO.p);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ import org.bukkit.util.StringUtil;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
import com.gmail.nossr50.database.LeaderboardManager;
 | 
			
		||||
import com.gmail.nossr50.database.FlatfileDatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SkillType;
 | 
			
		||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
			
		||||
import com.gmail.nossr50.runnables.commands.MctopCommandAsyncTask;
 | 
			
		||||
@@ -26,17 +26,14 @@ public class MctopCommand implements TabExecutor {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
 | 
			
		||||
        boolean useMySQL = Config.getInstance().getUseMySQL();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        switch (args.length) {
 | 
			
		||||
            case 0:
 | 
			
		||||
                display(1, "ALL", sender, useMySQL, command);
 | 
			
		||||
                display(1, "ALL", sender, command);
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            case 1:
 | 
			
		||||
                if (StringUtils.isInt(args[0])) {
 | 
			
		||||
                    display(Math.abs(Integer.parseInt(args[0])), "ALL", sender, useMySQL, command);
 | 
			
		||||
                    display(Math.abs(Integer.parseInt(args[0])), "ALL", sender, command);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -44,7 +41,7 @@ public class MctopCommand implements TabExecutor {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                display(1, skill.toString(), sender, useMySQL, command);
 | 
			
		||||
                display(1, skill.toString(), sender, command);
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            case 2:
 | 
			
		||||
@@ -56,7 +53,7 @@ public class MctopCommand implements TabExecutor {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                display(Math.abs(Integer.parseInt(args[1])), skill.toString(), sender, useMySQL, command);
 | 
			
		||||
                display(Math.abs(Integer.parseInt(args[1])), skill.toString(), sender, command);
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
@@ -74,19 +71,14 @@ public class MctopCommand implements TabExecutor {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void display(int page, String skill, CommandSender sender, boolean sql, Command command) {
 | 
			
		||||
    private void display(int page, String skill, CommandSender sender, Command command) {
 | 
			
		||||
        if (!skill.equalsIgnoreCase("all") && !Permissions.mctop(sender, this.skill)) {
 | 
			
		||||
            sender.sendMessage(command.getPermissionMessage());
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (sql) {
 | 
			
		||||
            if (skill.equalsIgnoreCase("all")) {
 | 
			
		||||
                sqlDisplay(page, "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing", sender);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                sqlDisplay(page, skill, sender);
 | 
			
		||||
            }
 | 
			
		||||
        if (Config.getInstance().getUseMySQL()) {
 | 
			
		||||
            sqlDisplay(page, skill, sender);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            flatfileDisplay(page, skill, sender);
 | 
			
		||||
@@ -94,7 +86,7 @@ public class MctopCommand implements TabExecutor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void flatfileDisplay(int page, String skill, CommandSender sender) {
 | 
			
		||||
        LeaderboardManager.updateLeaderboards(); // Make sure we have the latest information
 | 
			
		||||
        FlatfileDatabaseManager.updateLeaderboards(); // Make sure we have the latest information
 | 
			
		||||
 | 
			
		||||
        if (skill.equalsIgnoreCase("all")) {
 | 
			
		||||
            sender.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Leaderboard"));
 | 
			
		||||
@@ -105,7 +97,7 @@ public class MctopCommand implements TabExecutor {
 | 
			
		||||
 | 
			
		||||
        int position = (page * 10) - 9;
 | 
			
		||||
 | 
			
		||||
        for (String playerStat : LeaderboardManager.retrieveInfo(skill, page)) {
 | 
			
		||||
        for (String playerStat : FlatfileDatabaseManager.retrieveInfo(skill, page)) {
 | 
			
		||||
            if (playerStat == null) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,643 +1,63 @@
 | 
			
		||||
package com.gmail.nossr50.database;
 | 
			
		||||
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.DriverManager;
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
import com.gmail.nossr50.datatypes.database.DatabaseUpdateType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SkillType;
 | 
			
		||||
import com.gmail.nossr50.runnables.database.SQLReconnectTask;
 | 
			
		||||
import com.gmail.nossr50.util.Misc;
 | 
			
		||||
 | 
			
		||||
public final class DatabaseManager {
 | 
			
		||||
    private static String connectionString;
 | 
			
		||||
public class DatabaseManager {
 | 
			
		||||
    private final mcMMO plugin;
 | 
			
		||||
    private final boolean isUsingSQL;
 | 
			
		||||
    private File usersFile;
 | 
			
		||||
 | 
			
		||||
    private static String tablePrefix = Config.getInstance().getMySQLTablePrefix();
 | 
			
		||||
    private static Connection connection = null;
 | 
			
		||||
    public DatabaseManager(final mcMMO plugin, final boolean isUsingSQL) {
 | 
			
		||||
        this.plugin = plugin;
 | 
			
		||||
        this.isUsingSQL = isUsingSQL;
 | 
			
		||||
 | 
			
		||||
    // Scale waiting time by this much per failed attempt
 | 
			
		||||
    private static final double SCALING_FACTOR = 40;
 | 
			
		||||
 | 
			
		||||
    // Minimum wait in nanoseconds (default 500ms)
 | 
			
		||||
    private static final long MIN_WAIT = 500L * 1000000L;
 | 
			
		||||
 | 
			
		||||
    // Maximum time to wait between reconnects (default 5 minutes)
 | 
			
		||||
    private static final long MAX_WAIT = 5L * 60L * 1000L * 1000000L;
 | 
			
		||||
 | 
			
		||||
    // How long to wait when checking if connection is valid (default 3 seconds)
 | 
			
		||||
    private static final int VALID_TIMEOUT = 3;
 | 
			
		||||
 | 
			
		||||
    // When next to try connecting to Database in nanoseconds
 | 
			
		||||
    private static long nextReconnectTimestamp = 0L;
 | 
			
		||||
 | 
			
		||||
    // How many connection attempts have failed
 | 
			
		||||
    private static int reconnectAttempt = 0;
 | 
			
		||||
 | 
			
		||||
    private static final long ONE_MONTH = 2630000000L;
 | 
			
		||||
 | 
			
		||||
    private DatabaseManager() {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attempt to connect to the mySQL database.
 | 
			
		||||
     */
 | 
			
		||||
    public static void connect() {
 | 
			
		||||
        Config configInstance = Config.getInstance();
 | 
			
		||||
        connectionString = "jdbc:mysql://" + configInstance.getMySQLServerName() + ":" + configInstance.getMySQLServerPort() + "/" + configInstance.getMySQLDatabaseName();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            mcMMO.p.getLogger().info("Attempting connection to MySQL...");
 | 
			
		||||
 | 
			
		||||
            // Force driver to load if not yet loaded
 | 
			
		||||
            Class.forName("com.mysql.jdbc.Driver");
 | 
			
		||||
            Properties connectionProperties = new Properties();
 | 
			
		||||
            connectionProperties.put("user", configInstance.getMySQLUserName());
 | 
			
		||||
            connectionProperties.put("password", configInstance.getMySQLUserPassword());
 | 
			
		||||
            connectionProperties.put("autoReconnect", "false");
 | 
			
		||||
            connectionProperties.put("maxReconnects", "0");
 | 
			
		||||
            connection = DriverManager.getConnection(connectionString, connectionProperties);
 | 
			
		||||
 | 
			
		||||
            mcMMO.p.getLogger().info("Connection to MySQL was a success!");
 | 
			
		||||
        if (isUsingSQL) {
 | 
			
		||||
            SQLDatabaseManager.checkConnected();
 | 
			
		||||
            SQLDatabaseManager.createStructure();
 | 
			
		||||
        }
 | 
			
		||||
        catch (SQLException ex) {
 | 
			
		||||
            connection = null;
 | 
			
		||||
 | 
			
		||||
            if (reconnectAttempt == 0 || reconnectAttempt >= 11) {
 | 
			
		||||
                mcMMO.p.getLogger().info("Connection to MySQL failed!");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (ClassNotFoundException ex) {
 | 
			
		||||
            connection = null;
 | 
			
		||||
 | 
			
		||||
            if (reconnectAttempt == 0 || reconnectAttempt >= 11) {
 | 
			
		||||
                mcMMO.p.getLogger().info("MySQL database driver not found!");
 | 
			
		||||
            }
 | 
			
		||||
        else {
 | 
			
		||||
            usersFile = new File(mcMMO.getUsersFilePath());
 | 
			
		||||
            createFlatfileDatabase();
 | 
			
		||||
            FlatfileDatabaseManager.updateLeaderboards();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attempt to create the database structure.
 | 
			
		||||
     */
 | 
			
		||||
    public static void createStructure() {
 | 
			
		||||
        write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` ("
 | 
			
		||||
                + "`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
 | 
			
		||||
                + "`user` varchar(40) NOT NULL,"
 | 
			
		||||
                + "`lastlogin` int(32) unsigned NOT NULL,"
 | 
			
		||||
                + "PRIMARY KEY (`id`),"
 | 
			
		||||
                + "UNIQUE KEY `user` (`user`)) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;");
 | 
			
		||||
        write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "huds` ("
 | 
			
		||||
                + "`user_id` int(10) unsigned NOT NULL,"
 | 
			
		||||
                + "`hudtype` varchar(50) NOT NULL DEFAULT 'STANDARD',"
 | 
			
		||||
                + "`mobhealthbar` varchar(50) NOT NULL DEFAULT 'HEARTS',"
 | 
			
		||||
                + "PRIMARY KEY (`user_id`),"
 | 
			
		||||
                + "FOREIGN KEY (`user_id`) REFERENCES `" + tablePrefix + "users` (`id`) "
 | 
			
		||||
                + "ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
 | 
			
		||||
        write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "cooldowns` ("
 | 
			
		||||
                + "`user_id` int(10) unsigned NOT NULL,"
 | 
			
		||||
                + "`taming` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`mining` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`woodcutting` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`repair` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`unarmed` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`herbalism` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`excavation` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`archery` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`swords` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`axes` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`acrobatics` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`blast_mining` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "PRIMARY KEY (`user_id`),"
 | 
			
		||||
                + "FOREIGN KEY (`user_id`) REFERENCES `" + tablePrefix + "users` (`id`) "
 | 
			
		||||
                + "ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
 | 
			
		||||
        write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "skills` ("
 | 
			
		||||
                + "`user_id` int(10) unsigned NOT NULL,"
 | 
			
		||||
                + "`taming` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`mining` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`woodcutting` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`repair` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`unarmed` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`herbalism` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`excavation` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`archery` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`swords` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`axes` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`acrobatics` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "PRIMARY KEY (`user_id`),"
 | 
			
		||||
                + "FOREIGN KEY (`user_id`) REFERENCES `" + tablePrefix + "users` (`id`) "
 | 
			
		||||
                + "ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
 | 
			
		||||
        write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "experience` ("
 | 
			
		||||
                + "`user_id` int(10) unsigned NOT NULL,"
 | 
			
		||||
                + "`taming` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`mining` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`woodcutting` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`repair` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`unarmed` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`herbalism` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`excavation` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`archery` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`swords` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`axes` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`acrobatics` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "PRIMARY KEY (`user_id`),"
 | 
			
		||||
                + "FOREIGN KEY (`user_id`) REFERENCES `" + tablePrefix + "users` (`id`) "
 | 
			
		||||
                + "ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
 | 
			
		||||
 | 
			
		||||
        checkDatabaseStructure(DatabaseUpdateType.FISHING);
 | 
			
		||||
        checkDatabaseStructure(DatabaseUpdateType.BLAST_MINING);
 | 
			
		||||
        checkDatabaseStructure(DatabaseUpdateType.CASCADE_DELETE);
 | 
			
		||||
        checkDatabaseStructure(DatabaseUpdateType.INDEX);
 | 
			
		||||
        checkDatabaseStructure(DatabaseUpdateType.MOB_HEALTHBARS);
 | 
			
		||||
    public void purgePowerlessUsers() {
 | 
			
		||||
        plugin.getLogger().info("Purging powerless users...");
 | 
			
		||||
        plugin.getLogger().info("Purged " + (isUsingSQL ? SQLDatabaseManager.purgePowerlessSQL() : FlatfileDatabaseManager.purgePowerlessFlatfile()) + " users from the database.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attempt to write the SQL query.
 | 
			
		||||
     *
 | 
			
		||||
     * @param sql Query to write.
 | 
			
		||||
     * @return true if the query was successfully written, false otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean write(String sql) {
 | 
			
		||||
        if (!checkConnected()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        PreparedStatement statement = null;
 | 
			
		||||
        try {
 | 
			
		||||
            statement = connection.prepareStatement(sql);
 | 
			
		||||
            statement.executeUpdate();
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        catch (SQLException ex) {
 | 
			
		||||
            printErrors(ex);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        finally {
 | 
			
		||||
            if (statement != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    statement.close();
 | 
			
		||||
                }
 | 
			
		||||
                catch (SQLException e) {
 | 
			
		||||
                    printErrors(e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    public void purgeOldUsers() {
 | 
			
		||||
        plugin.getLogger().info("Purging old users...");
 | 
			
		||||
        plugin.getLogger().info("Purged " + (isUsingSQL ? SQLDatabaseManager.purgeOldSQL() : FlatfileDatabaseManager.removeOldFlatfileUsers()) + " users from the database.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the number of rows affected by either a DELETE or UPDATE query
 | 
			
		||||
     *
 | 
			
		||||
     * @param sql SQL query to execute
 | 
			
		||||
     * @return the number of rows affected
 | 
			
		||||
     */
 | 
			
		||||
    public static int update(String sql) {
 | 
			
		||||
        if (!checkConnected()) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int rows = 0;
 | 
			
		||||
 | 
			
		||||
        PreparedStatement statement = null;
 | 
			
		||||
        try {
 | 
			
		||||
            statement = connection.prepareStatement(sql);
 | 
			
		||||
            rows = statement.executeUpdate();
 | 
			
		||||
        }
 | 
			
		||||
        catch (SQLException ex) {
 | 
			
		||||
            printErrors(ex);
 | 
			
		||||
        }
 | 
			
		||||
        finally {
 | 
			
		||||
            if (statement != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    statement.close();
 | 
			
		||||
                }
 | 
			
		||||
                catch (SQLException e) {
 | 
			
		||||
                    printErrors(e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return rows;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the Integer. Only return first row / first field.
 | 
			
		||||
     *
 | 
			
		||||
     * @param sql SQL query to execute
 | 
			
		||||
     * @return the value in the first row / first field
 | 
			
		||||
     */
 | 
			
		||||
    public static int getInt(String sql) {
 | 
			
		||||
        if (!checkConnected()) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int result = 0;
 | 
			
		||||
 | 
			
		||||
        PreparedStatement statement = null;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            statement = connection.prepareStatement(sql);
 | 
			
		||||
            ResultSet resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
            if (resultSet.next()) {
 | 
			
		||||
                result = resultSet.getInt(1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (SQLException ex) {
 | 
			
		||||
            printErrors(ex);
 | 
			
		||||
        }
 | 
			
		||||
        finally {
 | 
			
		||||
            if (statement != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    statement.close();
 | 
			
		||||
                }
 | 
			
		||||
                catch (SQLException e) {
 | 
			
		||||
                    printErrors(e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check connection status and re-establish if dead or stale.
 | 
			
		||||
     *
 | 
			
		||||
     * If the very first immediate attempt fails, further attempts
 | 
			
		||||
     * will be made in progressively larger intervals up to MAX_WAIT
 | 
			
		||||
     * intervals.
 | 
			
		||||
     *
 | 
			
		||||
     * This allows for MySQL to time out idle connections as needed by
 | 
			
		||||
     * server operator, without affecting McMMO, while still providing
 | 
			
		||||
     * protection against a database outage taking down Bukkit's tick
 | 
			
		||||
     * processing loop due to attemping a database connection each
 | 
			
		||||
     * time McMMO needs the database.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the boolean value for whether or not we are connected
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean checkConnected() {
 | 
			
		||||
        boolean isClosed = true;
 | 
			
		||||
        boolean isValid = false;
 | 
			
		||||
        boolean exists = (connection != null);
 | 
			
		||||
 | 
			
		||||
        // If we're waiting for server to recover then leave early
 | 
			
		||||
        if (nextReconnectTimestamp > 0 && nextReconnectTimestamp > System.nanoTime()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (exists) {
 | 
			
		||||
            try {
 | 
			
		||||
                isClosed = connection.isClosed();
 | 
			
		||||
            }
 | 
			
		||||
            catch (SQLException e) {
 | 
			
		||||
                isClosed = true;
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
                printErrors(e);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!isClosed) {
 | 
			
		||||
                try {
 | 
			
		||||
                    isValid = connection.isValid(VALID_TIMEOUT);
 | 
			
		||||
                }
 | 
			
		||||
                catch (SQLException e) {
 | 
			
		||||
                    // Don't print stack trace because it's valid to lose idle connections to the server and have to restart them.
 | 
			
		||||
                    isValid = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Leave if all ok
 | 
			
		||||
        if (exists && !isClosed && isValid) {
 | 
			
		||||
            // Housekeeping
 | 
			
		||||
            nextReconnectTimestamp = 0;
 | 
			
		||||
            reconnectAttempt = 0;
 | 
			
		||||
    public boolean removeUser(String playerName) {
 | 
			
		||||
        if (isUsingSQL ? SQLDatabaseManager.removeUserSQL(playerName) : FlatfileDatabaseManager.removeFlatFileUser(playerName)) {
 | 
			
		||||
            Misc.profileCleanup(playerName);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Cleanup after ourselves for GC and MySQL's sake
 | 
			
		||||
        if (exists && !isClosed) {
 | 
			
		||||
            try {
 | 
			
		||||
                connection.close();
 | 
			
		||||
            }
 | 
			
		||||
            catch (SQLException ex) {
 | 
			
		||||
                // This is a housekeeping exercise, ignore errors
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Try to connect again
 | 
			
		||||
        connect();
 | 
			
		||||
 | 
			
		||||
        // Leave if connection is good
 | 
			
		||||
        try {
 | 
			
		||||
            if (connection != null && !connection.isClosed()) {
 | 
			
		||||
                // Schedule a database save if we really had an outage
 | 
			
		||||
                if (reconnectAttempt > 1) {
 | 
			
		||||
                    new SQLReconnectTask().runTaskLater(mcMMO.p, 5);
 | 
			
		||||
                }
 | 
			
		||||
                nextReconnectTimestamp = 0;
 | 
			
		||||
                reconnectAttempt = 0;
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (SQLException e) {
 | 
			
		||||
            // Failed to check isClosed, so presume connection is bad and attempt later
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            printErrors(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        reconnectAttempt++;
 | 
			
		||||
        nextReconnectTimestamp = (long)(System.nanoTime() + Math.min(MAX_WAIT, (reconnectAttempt * SCALING_FACTOR * MIN_WAIT)));
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read SQL query.
 | 
			
		||||
     *
 | 
			
		||||
     * @param sql SQL query to read
 | 
			
		||||
     * @return the rows in this SQL query
 | 
			
		||||
     */
 | 
			
		||||
    public static HashMap<Integer, ArrayList<String>> read(String sql) {
 | 
			
		||||
        ResultSet resultSet;
 | 
			
		||||
        HashMap<Integer, ArrayList<String>> rows = new HashMap<Integer, ArrayList<String>>();
 | 
			
		||||
 | 
			
		||||
        if (checkConnected()) {
 | 
			
		||||
            PreparedStatement statement = null;
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                statement = connection.prepareStatement(sql);
 | 
			
		||||
                resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
                while (resultSet.next()) {
 | 
			
		||||
                    ArrayList<String> column = new ArrayList<String>();
 | 
			
		||||
 | 
			
		||||
                    for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
 | 
			
		||||
                        column.add(resultSet.getString(i));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    rows.put(resultSet.getRow(), column);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (SQLException ex) {
 | 
			
		||||
                printErrors(ex);
 | 
			
		||||
            }
 | 
			
		||||
            finally {
 | 
			
		||||
                if (statement != null) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        statement.close();
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (SQLException e) {
 | 
			
		||||
                        printErrors(e);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
    private void createFlatfileDatabase() {
 | 
			
		||||
        if (usersFile.exists()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return rows;
 | 
			
		||||
    }
 | 
			
		||||
        usersFile.getParentFile().mkdir();
 | 
			
		||||
 | 
			
		||||
    public static Map<String, Integer> readSQLRank(String playerName) {
 | 
			
		||||
        ResultSet resultSet;
 | 
			
		||||
        Map<String, Integer> skills = new HashMap<String, Integer>();
 | 
			
		||||
 | 
			
		||||
        if (checkConnected()) {
 | 
			
		||||
            try {
 | 
			
		||||
                for (SkillType skillType : SkillType.values()) {
 | 
			
		||||
                    if (skillType.isChildSkill()) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    String skillName = skillType.name().toLowerCase();
 | 
			
		||||
                    String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
 | 
			
		||||
                                 "AND " + skillName + " > (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
 | 
			
		||||
                                 "WHERE user = ?)";
 | 
			
		||||
 | 
			
		||||
                    PreparedStatement statement = connection.prepareStatement(sql);
 | 
			
		||||
                    statement.setString(1, playerName);
 | 
			
		||||
                    resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
                    resultSet.next();
 | 
			
		||||
 | 
			
		||||
                    int rank = resultSet.getInt("rank");
 | 
			
		||||
 | 
			
		||||
                    sql = "SELECT user, " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
 | 
			
		||||
                          "AND " + skillName + " = (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
 | 
			
		||||
                          "WHERE user = '" + playerName + "') ORDER BY user";
 | 
			
		||||
 | 
			
		||||
                    statement = connection.prepareStatement(sql);
 | 
			
		||||
                    resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
                    while (resultSet.next()) {
 | 
			
		||||
                        if (resultSet.getString("user").equalsIgnoreCase(playerName)) {
 | 
			
		||||
                            skills.put(skillType.name(), rank + resultSet.getRow());
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    statement.close();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
 | 
			
		||||
                             "WHERE taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing > 0 " +
 | 
			
		||||
                             "AND taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing > " +
 | 
			
		||||
                             "(SELECT taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing " +
 | 
			
		||||
                             "FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE user = ?)";
 | 
			
		||||
 | 
			
		||||
                PreparedStatement statement = connection.prepareStatement(sql);
 | 
			
		||||
                statement.setString(1, playerName);
 | 
			
		||||
                resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
                resultSet.next();
 | 
			
		||||
 | 
			
		||||
                int rank = resultSet.getInt("rank");
 | 
			
		||||
 | 
			
		||||
                sql = "SELECT user, taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing " +
 | 
			
		||||
                      "FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
 | 
			
		||||
                      "WHERE taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing > 0 " +
 | 
			
		||||
                      "AND taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing = " +
 | 
			
		||||
                      "(SELECT taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing " +
 | 
			
		||||
                      "FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE user = ?) ORDER BY user";
 | 
			
		||||
 | 
			
		||||
                statement = connection.prepareStatement(sql);
 | 
			
		||||
                statement.setString(1, playerName);
 | 
			
		||||
                resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
                while (resultSet.next()) {
 | 
			
		||||
                    if (resultSet.getString("user").equalsIgnoreCase(playerName)) {
 | 
			
		||||
                        skills.put("ALL", rank + resultSet.getRow());
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                statement.close();
 | 
			
		||||
            }
 | 
			
		||||
            catch (SQLException ex) {
 | 
			
		||||
                printErrors(ex);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return skills;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void purgePowerlessSQL() {
 | 
			
		||||
        mcMMO.p.getLogger().info("Purging powerless users...");
 | 
			
		||||
        HashMap<Integer, ArrayList<String>> usernames;
 | 
			
		||||
 | 
			
		||||
        usernames = read("SELECT u.user FROM " + tablePrefix + "skills AS s, " + tablePrefix + "users AS u " + "WHERE s.user_id = u.id AND " +
 | 
			
		||||
                "(s.taming+s.mining+s.woodcutting+s.repair+s.unarmed+s.herbalism+s.excavation+s.archery+s.swords+s.axes+s.acrobatics+s.fishing) = 0");
 | 
			
		||||
 | 
			
		||||
        write("DELETE FROM " + tablePrefix + "users WHERE " + tablePrefix + "users.id IN (SELECT * FROM " +
 | 
			
		||||
                "(SELECT u.id FROM " + tablePrefix + "skills AS s, " + tablePrefix + "users AS u " + "WHERE s.user_id = u.id " +
 | 
			
		||||
                "AND (s.taming+s.mining+s.woodcutting+s.repair+s.unarmed+s.herbalism+s.excavation+s.archery+s.swords+s.axes+s.acrobatics+s.fishing) = 0) AS p)");
 | 
			
		||||
 | 
			
		||||
        int purgedUsers = 0;
 | 
			
		||||
        for (int i = 1; i <= usernames.size(); i++) {
 | 
			
		||||
            String playerName = usernames.get(i).get(0);
 | 
			
		||||
 | 
			
		||||
            if (playerName == null || mcMMO.p.getServer().getOfflinePlayer(playerName).isOnline()) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Misc.profileCleanup(playerName);
 | 
			
		||||
            purgedUsers++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mcMMO.p.getLogger().info("Purged " + purgedUsers + " users from the database.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void purgeOldSQL() {
 | 
			
		||||
        mcMMO.p.getLogger().info("Purging old users...");
 | 
			
		||||
        long currentTime = System.currentTimeMillis();
 | 
			
		||||
        long purgeTime = ONE_MONTH * Config.getInstance().getOldUsersCutoff();
 | 
			
		||||
        HashMap<Integer, ArrayList<String>> usernames = read("SELECT user FROM " + tablePrefix + "users WHERE ((" + currentTime + " - lastlogin*1000) > " + purgeTime + ")");
 | 
			
		||||
        write("DELETE FROM " + tablePrefix + "users WHERE " + tablePrefix + "users.id IN (SELECT * FROM (SELECT id FROM " + tablePrefix + "users WHERE ((" + currentTime + " - lastlogin*1000) > " + purgeTime + ")) AS p)");
 | 
			
		||||
 | 
			
		||||
        int purgedUsers = 0;
 | 
			
		||||
        for (int i = 1; i <= usernames.size(); i++) {
 | 
			
		||||
            String playerName = usernames.get(i).get(0);
 | 
			
		||||
 | 
			
		||||
            if (playerName == null) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Misc.profileCleanup(playerName);
 | 
			
		||||
            purgedUsers++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mcMMO.p.getLogger().info("Purged " + purgedUsers + " users from the database.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check database structure for missing values.
 | 
			
		||||
     *
 | 
			
		||||
     * @param update Type of data to check updates for
 | 
			
		||||
     */
 | 
			
		||||
    private static void checkDatabaseStructure(DatabaseUpdateType update) {
 | 
			
		||||
        String sql = null;
 | 
			
		||||
        ResultSet resultSet = null;
 | 
			
		||||
        HashMap<Integer, ArrayList<String>> rows = new HashMap<Integer, ArrayList<String>>();
 | 
			
		||||
 | 
			
		||||
        switch (update) {
 | 
			
		||||
            case BLAST_MINING:
 | 
			
		||||
                sql = "SELECT * FROM  `" + tablePrefix + "cooldowns` ORDER BY  `" + tablePrefix + "cooldowns`.`blast_mining` ASC LIMIT 0 , 30";
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case CASCADE_DELETE:
 | 
			
		||||
                write("ALTER TABLE `" + tablePrefix + "huds` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;");
 | 
			
		||||
                write("ALTER TABLE `" + tablePrefix + "experience` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;");
 | 
			
		||||
                write("ALTER TABLE `" + tablePrefix + "cooldowns` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;");
 | 
			
		||||
                write("ALTER TABLE `" + tablePrefix + "skills` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;");
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case FISHING:
 | 
			
		||||
                sql = "SELECT * FROM  `" + tablePrefix + "experience` ORDER BY  `" + tablePrefix + "experience`.`fishing` ASC LIMIT 0 , 30";
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case INDEX:
 | 
			
		||||
                if (read("SHOW INDEX FROM " + tablePrefix + "skills").size() != 13 && checkConnected()) {
 | 
			
		||||
                    mcMMO.p.getLogger().info("Indexing tables, this may take a while on larger databases");
 | 
			
		||||
                    write("ALTER TABLE `" + tablePrefix + "skills` ADD INDEX `idx_taming` (`taming`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_mining` (`mining`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_woodcutting` (`woodcutting`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_repair` (`repair`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_unarmed` (`unarmed`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_herbalism` (`herbalism`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_excavation` (`excavation`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_archery` (`archery`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_swords` (`swords`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_axes` (`axes`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_acrobatics` (`acrobatics`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_fishing` (`fishing`) USING BTREE;");
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case MOB_HEALTHBARS:
 | 
			
		||||
                sql = "SELECT * FROM  `" + tablePrefix + "huds` ORDER BY  `" + tablePrefix + "huds`.`mobhealthbar` ASC LIMIT 0 , 30";
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        PreparedStatement statement = null;
 | 
			
		||||
        try {
 | 
			
		||||
            if (!checkConnected()) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            statement = connection.prepareStatement(sql);
 | 
			
		||||
            resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
            while (resultSet.next()) {
 | 
			
		||||
                ArrayList<String> column = new ArrayList<String>();
 | 
			
		||||
 | 
			
		||||
                for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
 | 
			
		||||
                    column.add(resultSet.getString(i));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                rows.put(resultSet.getRow(), column);
 | 
			
		||||
            }
 | 
			
		||||
            plugin.debug("Creating mcmmo.users file...");
 | 
			
		||||
            new File(mcMMO.getUsersFilePath()).createNewFile();
 | 
			
		||||
        }
 | 
			
		||||
        catch (SQLException ex) {
 | 
			
		||||
            switch (update) {
 | 
			
		||||
                case BLAST_MINING:
 | 
			
		||||
                    mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Blast Mining...");
 | 
			
		||||
                    write("ALTER TABLE `"+tablePrefix + "cooldowns` ADD `blast_mining` int(32) NOT NULL DEFAULT '0' ;");
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case FISHING:
 | 
			
		||||
                    mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Fishing...");
 | 
			
		||||
                    write("ALTER TABLE `"+tablePrefix + "skills` ADD `fishing` int(10) NOT NULL DEFAULT '0' ;");
 | 
			
		||||
                    write("ALTER TABLE `"+tablePrefix + "experience` ADD `fishing` int(10) NOT NULL DEFAULT '0' ;");
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case MOB_HEALTHBARS:
 | 
			
		||||
                    mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for mob healthbars...");
 | 
			
		||||
                    write("ALTER TABLE `" + tablePrefix + "huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT 'HEARTS' ;");
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        finally {
 | 
			
		||||
            if (statement != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    statement.close();
 | 
			
		||||
                }
 | 
			
		||||
                catch (SQLException e) {
 | 
			
		||||
                    // Ignore the error, we're leaving
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void printErrors(SQLException ex) {
 | 
			
		||||
        mcMMO.p.getLogger().severe("SQLException: " + ex.getMessage());
 | 
			
		||||
        mcMMO.p.getLogger().severe("SQLState: " + ex.getSQLState());
 | 
			
		||||
        mcMMO.p.getLogger().severe("VendorError: " + ex.getErrorCode());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import java.util.Collections;
 | 
			
		||||
import java.util.Comparator;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
@@ -16,7 +17,7 @@ import com.gmail.nossr50.datatypes.database.PlayerStat;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SkillType;
 | 
			
		||||
import com.gmail.nossr50.util.StringUtils;
 | 
			
		||||
 | 
			
		||||
public final class LeaderboardManager {
 | 
			
		||||
public final class FlatfileDatabaseManager {
 | 
			
		||||
    private static HashMap<SkillType, List<PlayerStat>> playerStatHash = new HashMap<SkillType, List<PlayerStat>>();
 | 
			
		||||
    private static List<PlayerStat> powerLevels = new ArrayList<PlayerStat>();
 | 
			
		||||
    private static long lastUpdate = 0;
 | 
			
		||||
@@ -24,7 +25,7 @@ public final class LeaderboardManager {
 | 
			
		||||
    private static final long UPDATE_WAIT_TIME = 600000L; // 10 minutes
 | 
			
		||||
    private static final long ONE_MONTH = 2630000000L;
 | 
			
		||||
 | 
			
		||||
    private LeaderboardManager() {}
 | 
			
		||||
    private FlatfileDatabaseManager() {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Update the leader boards.
 | 
			
		||||
@@ -35,6 +36,7 @@ public final class LeaderboardManager {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String usersFilePath = mcMMO.getUsersFilePath();
 | 
			
		||||
        lastUpdate = System.currentTimeMillis(); // Log when the last update was run
 | 
			
		||||
        powerLevels.clear(); // Clear old values from the power levels
 | 
			
		||||
 | 
			
		||||
@@ -54,8 +56,7 @@ public final class LeaderboardManager {
 | 
			
		||||
 | 
			
		||||
        // Read from the FlatFile database and fill our arrays with information
 | 
			
		||||
        try {
 | 
			
		||||
            FileReader file = new FileReader(mcMMO.getUsersFilePath());
 | 
			
		||||
            BufferedReader in = new BufferedReader(file);
 | 
			
		||||
            BufferedReader in = new BufferedReader(new FileReader(usersFilePath));
 | 
			
		||||
            String line = "";
 | 
			
		||||
            ArrayList<String> players = new ArrayList<String>();
 | 
			
		||||
 | 
			
		||||
@@ -72,72 +73,25 @@ public final class LeaderboardManager {
 | 
			
		||||
 | 
			
		||||
                players.add(playerName);
 | 
			
		||||
 | 
			
		||||
                if (data.length > 1 && StringUtils.isInt(data[1])) {
 | 
			
		||||
                    mining.add(new PlayerStat(playerName, Integer.parseInt(data[1])));
 | 
			
		||||
                    powerLevel += Integer.parseInt(data[1]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (data.length > 5 && StringUtils.isInt(data[5])) {
 | 
			
		||||
                    woodcutting.add(new PlayerStat(playerName, Integer.parseInt(data[5])));
 | 
			
		||||
                    powerLevel += Integer.parseInt(data[5]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (data.length > 7 && StringUtils.isInt(data[7])) {
 | 
			
		||||
                    repair.add(new PlayerStat(playerName, Integer.parseInt(data[7])));
 | 
			
		||||
                    powerLevel += Integer.parseInt(data[7]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (data.length > 8 && StringUtils.isInt(data[8])) {
 | 
			
		||||
                    unarmed.add(new PlayerStat(playerName, Integer.parseInt(data[8])));
 | 
			
		||||
                    powerLevel += Integer.parseInt(data[8]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (data.length > 9 && StringUtils.isInt(data[9])) {
 | 
			
		||||
                    herbalism.add(new PlayerStat(playerName, Integer.parseInt(data[9])));
 | 
			
		||||
                    powerLevel += Integer.parseInt(data[9]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (data.length > 10 && StringUtils.isInt(data[10])) {
 | 
			
		||||
                    excavation.add(new PlayerStat(playerName, Integer.parseInt(data[10])));
 | 
			
		||||
                    powerLevel += Integer.parseInt(data[10]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (data.length > 11 && StringUtils.isInt(data[11])) {
 | 
			
		||||
                    archery.add(new PlayerStat(playerName, Integer.parseInt(data[11])));
 | 
			
		||||
                    powerLevel += Integer.parseInt(data[11]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (data.length > 12 && StringUtils.isInt(data[12])) {
 | 
			
		||||
                    swords.add(new PlayerStat(playerName, Integer.parseInt(data[12])));
 | 
			
		||||
                    powerLevel += Integer.parseInt(data[12]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (data.length > 13 && StringUtils.isInt(data[13])) {
 | 
			
		||||
                    axes.add(new PlayerStat(playerName, Integer.parseInt(data[13])));
 | 
			
		||||
                    powerLevel += Integer.parseInt(data[13]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (data.length > 14 && StringUtils.isInt(data[14])) {
 | 
			
		||||
                    acrobatics.add(new PlayerStat(playerName, Integer.parseInt(data[14])));
 | 
			
		||||
                    powerLevel += Integer.parseInt(data[14]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (data.length > 24 && StringUtils.isInt(data[24])) {
 | 
			
		||||
                    taming.add(new PlayerStat(playerName, Integer.parseInt(data[24])));
 | 
			
		||||
                    powerLevel += Integer.parseInt(data[24]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (data.length > 34 && StringUtils.isInt(data[34])) {
 | 
			
		||||
                    fishing.add(new PlayerStat(playerName, Integer.parseInt(data[34])));
 | 
			
		||||
                    powerLevel += Integer.parseInt(data[34]);
 | 
			
		||||
                }
 | 
			
		||||
                powerLevel += loadStat(mining, playerName, data, 1);
 | 
			
		||||
                powerLevel += loadStat(woodcutting, playerName, data, 5);
 | 
			
		||||
                powerLevel += loadStat(repair, playerName, data, 7);
 | 
			
		||||
                powerLevel += loadStat(unarmed, playerName, data, 8);
 | 
			
		||||
                powerLevel += loadStat(herbalism, playerName, data, 9);
 | 
			
		||||
                powerLevel += loadStat(excavation, playerName, data, 10);
 | 
			
		||||
                powerLevel += loadStat(archery, playerName, data, 11);
 | 
			
		||||
                powerLevel += loadStat(swords, playerName, data, 12);
 | 
			
		||||
                powerLevel += loadStat(axes, playerName, data, 13);
 | 
			
		||||
                powerLevel += loadStat(acrobatics, playerName, data, 14);
 | 
			
		||||
                powerLevel += loadStat(taming, playerName, data, 24);
 | 
			
		||||
                powerLevel += loadStat(fishing, playerName, data, 34);
 | 
			
		||||
 | 
			
		||||
                powerLevels.add(new PlayerStat(playerName, powerLevel));
 | 
			
		||||
            }
 | 
			
		||||
            in.close();
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e) {
 | 
			
		||||
            mcMMO.p.getLogger().severe("Exception while reading " + mcMMO.getUsersFilePath() + " (Are you sure you formatted it correctly?)" + e.toString());
 | 
			
		||||
            mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SkillComparator c = new SkillComparator();
 | 
			
		||||
@@ -203,14 +157,6 @@ public final class LeaderboardManager {
 | 
			
		||||
        return info;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static int[] getPlayerRank(String playerName) {
 | 
			
		||||
        return getPlayerRank(playerName, powerLevels);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static int[] getPlayerRank(String playerName, SkillType skillType) {
 | 
			
		||||
        return getPlayerRank(playerName, playerStatHash.get(skillType));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean removeFlatFileUser(String playerName) {
 | 
			
		||||
        boolean worked = false;
 | 
			
		||||
 | 
			
		||||
@@ -266,7 +212,7 @@ public final class LeaderboardManager {
 | 
			
		||||
        return worked;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void purgePowerlessFlatfile() {
 | 
			
		||||
    public static int purgePowerlessFlatfile() {
 | 
			
		||||
        mcMMO.p.getLogger().info("Purging powerless users...");
 | 
			
		||||
 | 
			
		||||
        int purgedUsers = 0;
 | 
			
		||||
@@ -277,16 +223,10 @@ public final class LeaderboardManager {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mcMMO.p.getLogger().info("Purged " + purgedUsers + " users from the database.");
 | 
			
		||||
        return purgedUsers;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void purgeOldFlatfile() {
 | 
			
		||||
        mcMMO.p.getLogger().info("Purging old users...");
 | 
			
		||||
        int purgedUsers = removeOldFlatfileUsers();
 | 
			
		||||
        mcMMO.p.getLogger().info("Purged " + purgedUsers + " users from the database.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static int removeOldFlatfileUsers() {
 | 
			
		||||
    public static int removeOldFlatfileUsers() {
 | 
			
		||||
        int removedPlayers = 0;
 | 
			
		||||
        long currentTime = System.currentTimeMillis();
 | 
			
		||||
        long purgeTime = ONE_MONTH * Config.getInstance().getOldUsersCutoff();
 | 
			
		||||
@@ -350,22 +290,47 @@ public final class LeaderboardManager {
 | 
			
		||||
        return removedPlayers;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static int[] getPlayerRank(String playerName, List<PlayerStat> statsList) {
 | 
			
		||||
    private static Integer getPlayerRank(String playerName, List<PlayerStat> statsList) {
 | 
			
		||||
        int currentPos = 1;
 | 
			
		||||
 | 
			
		||||
        if (statsList == null) {
 | 
			
		||||
            return new int[] {0, 0};
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (PlayerStat stat : statsList) {
 | 
			
		||||
            if (stat.name.equalsIgnoreCase(playerName)) {
 | 
			
		||||
                return new int[] {currentPos, stat.statVal};
 | 
			
		||||
                return currentPos;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            currentPos++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new int[] {0, 0};
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Map<String, Integer> getPlayerRanks(String playerName) {
 | 
			
		||||
        updateLeaderboards();
 | 
			
		||||
 | 
			
		||||
        Map<String, Integer> skills = new HashMap<String, Integer>();
 | 
			
		||||
 | 
			
		||||
        for (SkillType skill : SkillType.values()) {
 | 
			
		||||
            skills.put(playerName, getPlayerRank(playerName, playerStatHash.get(skill)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        skills.put("ALL", getPlayerRank(playerName, powerLevels));
 | 
			
		||||
 | 
			
		||||
        return skills;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static int loadStat(List<PlayerStat> statList, String playerName, String[] data, int dataIndex) {
 | 
			
		||||
        if (data.length > dataIndex) {
 | 
			
		||||
            int statValue = Integer.parseInt(data[dataIndex]);
 | 
			
		||||
 | 
			
		||||
            statList.add(new PlayerStat(playerName, statValue));
 | 
			
		||||
            return statValue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static class SkillComparator implements Comparator<PlayerStat> {
 | 
			
		||||
							
								
								
									
										628
									
								
								src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										628
									
								
								src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,628 @@
 | 
			
		||||
package com.gmail.nossr50.database;
 | 
			
		||||
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.DriverManager;
 | 
			
		||||
import java.sql.PreparedStatement;
 | 
			
		||||
import java.sql.ResultSet;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
import com.gmail.nossr50.datatypes.database.DatabaseUpdateType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SkillType;
 | 
			
		||||
import com.gmail.nossr50.runnables.database.SQLReconnectTask;
 | 
			
		||||
import com.gmail.nossr50.util.Misc;
 | 
			
		||||
 | 
			
		||||
public final class SQLDatabaseManager {
 | 
			
		||||
    private static String connectionString;
 | 
			
		||||
 | 
			
		||||
    private static String tablePrefix = Config.getInstance().getMySQLTablePrefix();
 | 
			
		||||
    private static Connection connection = null;
 | 
			
		||||
 | 
			
		||||
    // Scale waiting time by this much per failed attempt
 | 
			
		||||
    private static final double SCALING_FACTOR = 40;
 | 
			
		||||
 | 
			
		||||
    // Minimum wait in nanoseconds (default 500ms)
 | 
			
		||||
    private static final long MIN_WAIT = 500L * 1000000L;
 | 
			
		||||
 | 
			
		||||
    // Maximum time to wait between reconnects (default 5 minutes)
 | 
			
		||||
    private static final long MAX_WAIT = 5L * 60L * 1000L * 1000000L;
 | 
			
		||||
 | 
			
		||||
    // How long to wait when checking if connection is valid (default 3 seconds)
 | 
			
		||||
    private static final int VALID_TIMEOUT = 3;
 | 
			
		||||
 | 
			
		||||
    // When next to try connecting to Database in nanoseconds
 | 
			
		||||
    private static long nextReconnectTimestamp = 0L;
 | 
			
		||||
 | 
			
		||||
    // How many connection attempts have failed
 | 
			
		||||
    private static int reconnectAttempt = 0;
 | 
			
		||||
 | 
			
		||||
    private static final long ONE_MONTH = 2630000000L;
 | 
			
		||||
 | 
			
		||||
    private SQLDatabaseManager() {}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attempt to connect to the mySQL database.
 | 
			
		||||
     */
 | 
			
		||||
    public static void connect() {
 | 
			
		||||
        Config configInstance = Config.getInstance();
 | 
			
		||||
        connectionString = "jdbc:mysql://" + configInstance.getMySQLServerName() + ":" + configInstance.getMySQLServerPort() + "/" + configInstance.getMySQLDatabaseName();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            mcMMO.p.getLogger().info("Attempting connection to MySQL...");
 | 
			
		||||
 | 
			
		||||
            // Force driver to load if not yet loaded
 | 
			
		||||
            Class.forName("com.mysql.jdbc.Driver");
 | 
			
		||||
            Properties connectionProperties = new Properties();
 | 
			
		||||
            connectionProperties.put("user", configInstance.getMySQLUserName());
 | 
			
		||||
            connectionProperties.put("password", configInstance.getMySQLUserPassword());
 | 
			
		||||
            connectionProperties.put("autoReconnect", "false");
 | 
			
		||||
            connectionProperties.put("maxReconnects", "0");
 | 
			
		||||
            connection = DriverManager.getConnection(connectionString, connectionProperties);
 | 
			
		||||
 | 
			
		||||
            mcMMO.p.getLogger().info("Connection to MySQL was a success!");
 | 
			
		||||
        }
 | 
			
		||||
        catch (SQLException ex) {
 | 
			
		||||
            connection = null;
 | 
			
		||||
 | 
			
		||||
            if (reconnectAttempt == 0 || reconnectAttempt >= 11) {
 | 
			
		||||
                mcMMO.p.getLogger().info("Connection to MySQL failed!");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (ClassNotFoundException ex) {
 | 
			
		||||
            connection = null;
 | 
			
		||||
 | 
			
		||||
            if (reconnectAttempt == 0 || reconnectAttempt >= 11) {
 | 
			
		||||
                mcMMO.p.getLogger().info("MySQL database driver not found!");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attempt to create the database structure.
 | 
			
		||||
     */
 | 
			
		||||
    public static void createStructure() {
 | 
			
		||||
        write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` ("
 | 
			
		||||
                + "`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
 | 
			
		||||
                + "`user` varchar(40) NOT NULL,"
 | 
			
		||||
                + "`lastlogin` int(32) unsigned NOT NULL,"
 | 
			
		||||
                + "PRIMARY KEY (`id`),"
 | 
			
		||||
                + "UNIQUE KEY `user` (`user`)) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;");
 | 
			
		||||
        write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "huds` ("
 | 
			
		||||
                + "`user_id` int(10) unsigned NOT NULL,"
 | 
			
		||||
                + "`hudtype` varchar(50) NOT NULL DEFAULT 'STANDARD',"
 | 
			
		||||
                + "`mobhealthbar` varchar(50) NOT NULL DEFAULT 'HEARTS',"
 | 
			
		||||
                + "PRIMARY KEY (`user_id`),"
 | 
			
		||||
                + "FOREIGN KEY (`user_id`) REFERENCES `" + tablePrefix + "users` (`id`) "
 | 
			
		||||
                + "ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
 | 
			
		||||
        write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "cooldowns` ("
 | 
			
		||||
                + "`user_id` int(10) unsigned NOT NULL,"
 | 
			
		||||
                + "`taming` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`mining` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`woodcutting` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`repair` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`unarmed` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`herbalism` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`excavation` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`archery` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`swords` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`axes` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`acrobatics` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`blast_mining` int(32) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "PRIMARY KEY (`user_id`),"
 | 
			
		||||
                + "FOREIGN KEY (`user_id`) REFERENCES `" + tablePrefix + "users` (`id`) "
 | 
			
		||||
                + "ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
 | 
			
		||||
        write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "skills` ("
 | 
			
		||||
                + "`user_id` int(10) unsigned NOT NULL,"
 | 
			
		||||
                + "`taming` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`mining` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`woodcutting` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`repair` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`unarmed` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`herbalism` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`excavation` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`archery` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`swords` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`axes` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`acrobatics` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "PRIMARY KEY (`user_id`),"
 | 
			
		||||
                + "FOREIGN KEY (`user_id`) REFERENCES `" + tablePrefix + "users` (`id`) "
 | 
			
		||||
                + "ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
 | 
			
		||||
        write("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "experience` ("
 | 
			
		||||
                + "`user_id` int(10) unsigned NOT NULL,"
 | 
			
		||||
                + "`taming` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`mining` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`woodcutting` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`repair` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`unarmed` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`herbalism` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`excavation` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`archery` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`swords` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`axes` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "`acrobatics` int(10) unsigned NOT NULL DEFAULT '0',"
 | 
			
		||||
                + "PRIMARY KEY (`user_id`),"
 | 
			
		||||
                + "FOREIGN KEY (`user_id`) REFERENCES `" + tablePrefix + "users` (`id`) "
 | 
			
		||||
                + "ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1;");
 | 
			
		||||
 | 
			
		||||
        checkDatabaseStructure(DatabaseUpdateType.FISHING);
 | 
			
		||||
        checkDatabaseStructure(DatabaseUpdateType.BLAST_MINING);
 | 
			
		||||
        checkDatabaseStructure(DatabaseUpdateType.CASCADE_DELETE);
 | 
			
		||||
        checkDatabaseStructure(DatabaseUpdateType.INDEX);
 | 
			
		||||
        checkDatabaseStructure(DatabaseUpdateType.MOB_HEALTHBARS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attempt to write the SQL query.
 | 
			
		||||
     *
 | 
			
		||||
     * @param sql Query to write.
 | 
			
		||||
     * @return true if the query was successfully written, false otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean write(String sql) {
 | 
			
		||||
        if (!checkConnected()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        PreparedStatement statement = null;
 | 
			
		||||
        try {
 | 
			
		||||
            statement = connection.prepareStatement(sql);
 | 
			
		||||
            statement.executeUpdate();
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        catch (SQLException ex) {
 | 
			
		||||
            printErrors(ex);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        finally {
 | 
			
		||||
            if (statement != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    statement.close();
 | 
			
		||||
                }
 | 
			
		||||
                catch (SQLException e) {
 | 
			
		||||
                    printErrors(e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean removeUserSQL(String playerName) {
 | 
			
		||||
        return SQLDatabaseManager.update("DELETE FROM " + tablePrefix + "users WHERE " + tablePrefix + "users.user = '" + playerName + "'") != 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the number of rows affected by either a DELETE or UPDATE query
 | 
			
		||||
     *
 | 
			
		||||
     * @param sql SQL query to execute
 | 
			
		||||
     * @return the number of rows affected
 | 
			
		||||
     */
 | 
			
		||||
    public static int update(String sql) {
 | 
			
		||||
        if (!checkConnected()) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int rows = 0;
 | 
			
		||||
 | 
			
		||||
        PreparedStatement statement = null;
 | 
			
		||||
        try {
 | 
			
		||||
            statement = connection.prepareStatement(sql);
 | 
			
		||||
            rows = statement.executeUpdate();
 | 
			
		||||
        }
 | 
			
		||||
        catch (SQLException ex) {
 | 
			
		||||
            printErrors(ex);
 | 
			
		||||
        }
 | 
			
		||||
        finally {
 | 
			
		||||
            if (statement != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    statement.close();
 | 
			
		||||
                }
 | 
			
		||||
                catch (SQLException e) {
 | 
			
		||||
                    printErrors(e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return rows;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the Integer. Only return first row / first field.
 | 
			
		||||
     *
 | 
			
		||||
     * @param sql SQL query to execute
 | 
			
		||||
     * @return the value in the first row / first field
 | 
			
		||||
     */
 | 
			
		||||
    public static int getInt(String sql) {
 | 
			
		||||
        if (!checkConnected()) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int result = 0;
 | 
			
		||||
 | 
			
		||||
        PreparedStatement statement = null;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            statement = connection.prepareStatement(sql);
 | 
			
		||||
            ResultSet resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
            if (resultSet.next()) {
 | 
			
		||||
                result = resultSet.getInt(1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (SQLException ex) {
 | 
			
		||||
            printErrors(ex);
 | 
			
		||||
        }
 | 
			
		||||
        finally {
 | 
			
		||||
            if (statement != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    statement.close();
 | 
			
		||||
                }
 | 
			
		||||
                catch (SQLException e) {
 | 
			
		||||
                    printErrors(e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check connection status and re-establish if dead or stale.
 | 
			
		||||
     *
 | 
			
		||||
     * If the very first immediate attempt fails, further attempts
 | 
			
		||||
     * will be made in progressively larger intervals up to MAX_WAIT
 | 
			
		||||
     * intervals.
 | 
			
		||||
     *
 | 
			
		||||
     * This allows for MySQL to time out idle connections as needed by
 | 
			
		||||
     * server operator, without affecting McMMO, while still providing
 | 
			
		||||
     * protection against a database outage taking down Bukkit's tick
 | 
			
		||||
     * processing loop due to attemping a database connection each
 | 
			
		||||
     * time McMMO needs the database.
 | 
			
		||||
     *
 | 
			
		||||
     * @return the boolean value for whether or not we are connected
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean checkConnected() {
 | 
			
		||||
        boolean isClosed = true;
 | 
			
		||||
        boolean isValid = false;
 | 
			
		||||
        boolean exists = (connection != null);
 | 
			
		||||
 | 
			
		||||
        // If we're waiting for server to recover then leave early
 | 
			
		||||
        if (nextReconnectTimestamp > 0 && nextReconnectTimestamp > System.nanoTime()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (exists) {
 | 
			
		||||
            try {
 | 
			
		||||
                isClosed = connection.isClosed();
 | 
			
		||||
            }
 | 
			
		||||
            catch (SQLException e) {
 | 
			
		||||
                isClosed = true;
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
                printErrors(e);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!isClosed) {
 | 
			
		||||
                try {
 | 
			
		||||
                    isValid = connection.isValid(VALID_TIMEOUT);
 | 
			
		||||
                }
 | 
			
		||||
                catch (SQLException e) {
 | 
			
		||||
                    // Don't print stack trace because it's valid to lose idle connections to the server and have to restart them.
 | 
			
		||||
                    isValid = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Leave if all ok
 | 
			
		||||
        if (exists && !isClosed && isValid) {
 | 
			
		||||
            // Housekeeping
 | 
			
		||||
            nextReconnectTimestamp = 0;
 | 
			
		||||
            reconnectAttempt = 0;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Cleanup after ourselves for GC and MySQL's sake
 | 
			
		||||
        if (exists && !isClosed) {
 | 
			
		||||
            try {
 | 
			
		||||
                connection.close();
 | 
			
		||||
            }
 | 
			
		||||
            catch (SQLException ex) {
 | 
			
		||||
                // This is a housekeeping exercise, ignore errors
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Try to connect again
 | 
			
		||||
        connect();
 | 
			
		||||
 | 
			
		||||
        // Leave if connection is good
 | 
			
		||||
        try {
 | 
			
		||||
            if (connection != null && !connection.isClosed()) {
 | 
			
		||||
                // Schedule a database save if we really had an outage
 | 
			
		||||
                if (reconnectAttempt > 1) {
 | 
			
		||||
                    new SQLReconnectTask().runTaskLater(mcMMO.p, 5);
 | 
			
		||||
                }
 | 
			
		||||
                nextReconnectTimestamp = 0;
 | 
			
		||||
                reconnectAttempt = 0;
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (SQLException e) {
 | 
			
		||||
            // Failed to check isClosed, so presume connection is bad and attempt later
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            printErrors(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        reconnectAttempt++;
 | 
			
		||||
        nextReconnectTimestamp = (long)(System.nanoTime() + Math.min(MAX_WAIT, (reconnectAttempt * SCALING_FACTOR * MIN_WAIT)));
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read SQL query.
 | 
			
		||||
     *
 | 
			
		||||
     * @param sql SQL query to read
 | 
			
		||||
     * @return the rows in this SQL query
 | 
			
		||||
     */
 | 
			
		||||
    public static HashMap<Integer, ArrayList<String>> read(String sql) {
 | 
			
		||||
        ResultSet resultSet;
 | 
			
		||||
        HashMap<Integer, ArrayList<String>> rows = new HashMap<Integer, ArrayList<String>>();
 | 
			
		||||
 | 
			
		||||
        if (checkConnected()) {
 | 
			
		||||
            PreparedStatement statement = null;
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                statement = connection.prepareStatement(sql);
 | 
			
		||||
                resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
                while (resultSet.next()) {
 | 
			
		||||
                    ArrayList<String> column = new ArrayList<String>();
 | 
			
		||||
 | 
			
		||||
                    for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
 | 
			
		||||
                        column.add(resultSet.getString(i));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    rows.put(resultSet.getRow(), column);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (SQLException ex) {
 | 
			
		||||
                printErrors(ex);
 | 
			
		||||
            }
 | 
			
		||||
            finally {
 | 
			
		||||
                if (statement != null) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        statement.close();
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (SQLException e) {
 | 
			
		||||
                        printErrors(e);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return rows;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Map<String, Integer> readSQLRank(String playerName) {
 | 
			
		||||
        ResultSet resultSet;
 | 
			
		||||
        Map<String, Integer> skills = new HashMap<String, Integer>();
 | 
			
		||||
 | 
			
		||||
        if (checkConnected()) {
 | 
			
		||||
            try {
 | 
			
		||||
                for (SkillType skillType : SkillType.values()) {
 | 
			
		||||
                    if (skillType.isChildSkill()) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    String skillName = skillType.name().toLowerCase();
 | 
			
		||||
                    String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
 | 
			
		||||
                                 "AND " + skillName + " > (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
 | 
			
		||||
                                 "WHERE user = ?)";
 | 
			
		||||
 | 
			
		||||
                    PreparedStatement statement = connection.prepareStatement(sql);
 | 
			
		||||
                    statement.setString(1, playerName);
 | 
			
		||||
                    resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
                    resultSet.next();
 | 
			
		||||
 | 
			
		||||
                    int rank = resultSet.getInt("rank");
 | 
			
		||||
 | 
			
		||||
                    sql = "SELECT user, " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
 | 
			
		||||
                          "AND " + skillName + " = (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
 | 
			
		||||
                          "WHERE user = '" + playerName + "') ORDER BY user";
 | 
			
		||||
 | 
			
		||||
                    statement = connection.prepareStatement(sql);
 | 
			
		||||
                    resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
                    while (resultSet.next()) {
 | 
			
		||||
                        if (resultSet.getString("user").equalsIgnoreCase(playerName)) {
 | 
			
		||||
                            skills.put(skillType.name(), rank + resultSet.getRow());
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    statement.close();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
 | 
			
		||||
                             "WHERE taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing > 0 " +
 | 
			
		||||
                             "AND taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing > " +
 | 
			
		||||
                             "(SELECT taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing " +
 | 
			
		||||
                             "FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE user = ?)";
 | 
			
		||||
 | 
			
		||||
                PreparedStatement statement = connection.prepareStatement(sql);
 | 
			
		||||
                statement.setString(1, playerName);
 | 
			
		||||
                resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
                resultSet.next();
 | 
			
		||||
 | 
			
		||||
                int rank = resultSet.getInt("rank");
 | 
			
		||||
 | 
			
		||||
                sql = "SELECT user, taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing " +
 | 
			
		||||
                      "FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
 | 
			
		||||
                      "WHERE taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing > 0 " +
 | 
			
		||||
                      "AND taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing = " +
 | 
			
		||||
                      "(SELECT taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing " +
 | 
			
		||||
                      "FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE user = ?) ORDER BY user";
 | 
			
		||||
 | 
			
		||||
                statement = connection.prepareStatement(sql);
 | 
			
		||||
                statement.setString(1, playerName);
 | 
			
		||||
                resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
                while (resultSet.next()) {
 | 
			
		||||
                    if (resultSet.getString("user").equalsIgnoreCase(playerName)) {
 | 
			
		||||
                        skills.put("ALL", rank + resultSet.getRow());
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                statement.close();
 | 
			
		||||
            }
 | 
			
		||||
            catch (SQLException ex) {
 | 
			
		||||
                printErrors(ex);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return skills;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static int purgePowerlessSQL() {
 | 
			
		||||
        HashMap<Integer, ArrayList<String>> usernames = read("SELECT u.user FROM " + tablePrefix + "skills AS s, " + tablePrefix + "users AS u WHERE s.user_id = u.id AND (s.taming+s.mining+s.woodcutting+s.repair+s.unarmed+s.herbalism+s.excavation+s.archery+s.swords+s.axes+s.acrobatics+s.fishing) = 0");
 | 
			
		||||
        write("DELETE FROM " + tablePrefix + "users WHERE " + tablePrefix + "users.id IN (SELECT * FROM (SELECT u.id FROM " + tablePrefix + "skills AS s, " + tablePrefix + "users AS u WHERE s.user_id = u.id AND (s.taming+s.mining+s.woodcutting+s.repair+s.unarmed+s.herbalism+s.excavation+s.archery+s.swords+s.axes+s.acrobatics+s.fishing) = 0) AS p)");
 | 
			
		||||
 | 
			
		||||
        return processPurge(usernames.values());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static int purgeOldSQL() {
 | 
			
		||||
        long currentTime = System.currentTimeMillis();
 | 
			
		||||
        long purgeTime = ONE_MONTH * Config.getInstance().getOldUsersCutoff();
 | 
			
		||||
 | 
			
		||||
        HashMap<Integer, ArrayList<String>> usernames = read("SELECT user FROM " + tablePrefix + "users WHERE ((" + currentTime + " - lastlogin*1000) > " + purgeTime + ")");
 | 
			
		||||
        write("DELETE FROM " + tablePrefix + "users WHERE " + tablePrefix + "users.id IN (SELECT * FROM (SELECT id FROM " + tablePrefix + "users WHERE ((" + currentTime + " - lastlogin*1000) > " + purgeTime + ")) AS p)");
 | 
			
		||||
 | 
			
		||||
        return processPurge(usernames.values());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static int processPurge(Collection<ArrayList<String>> usernames) {
 | 
			
		||||
        int purgedUsers = 0;
 | 
			
		||||
 | 
			
		||||
        for (ArrayList<String> user : usernames) {
 | 
			
		||||
            Misc.profileCleanup(user.get(0));
 | 
			
		||||
            purgedUsers++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return purgedUsers;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check database structure for missing values.
 | 
			
		||||
     *
 | 
			
		||||
     * @param update Type of data to check updates for
 | 
			
		||||
     */
 | 
			
		||||
    private static void checkDatabaseStructure(DatabaseUpdateType update) {
 | 
			
		||||
        String sql = null;
 | 
			
		||||
        ResultSet resultSet = null;
 | 
			
		||||
        HashMap<Integer, ArrayList<String>> rows = new HashMap<Integer, ArrayList<String>>();
 | 
			
		||||
 | 
			
		||||
        switch (update) {
 | 
			
		||||
            case BLAST_MINING:
 | 
			
		||||
                sql = "SELECT * FROM  `" + tablePrefix + "cooldowns` ORDER BY  `" + tablePrefix + "cooldowns`.`blast_mining` ASC LIMIT 0 , 30";
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case CASCADE_DELETE:
 | 
			
		||||
                write("ALTER TABLE `" + tablePrefix + "huds` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;");
 | 
			
		||||
                write("ALTER TABLE `" + tablePrefix + "experience` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;");
 | 
			
		||||
                write("ALTER TABLE `" + tablePrefix + "cooldowns` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;");
 | 
			
		||||
                write("ALTER TABLE `" + tablePrefix + "skills` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE;");
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case FISHING:
 | 
			
		||||
                sql = "SELECT * FROM  `" + tablePrefix + "experience` ORDER BY  `" + tablePrefix + "experience`.`fishing` ASC LIMIT 0 , 30";
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case INDEX:
 | 
			
		||||
                if (read("SHOW INDEX FROM " + tablePrefix + "skills").size() != 13 && checkConnected()) {
 | 
			
		||||
                    mcMMO.p.getLogger().info("Indexing tables, this may take a while on larger databases");
 | 
			
		||||
                    write("ALTER TABLE `" + tablePrefix + "skills` ADD INDEX `idx_taming` (`taming`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_mining` (`mining`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_woodcutting` (`woodcutting`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_repair` (`repair`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_unarmed` (`unarmed`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_herbalism` (`herbalism`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_excavation` (`excavation`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_archery` (`archery`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_swords` (`swords`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_axes` (`axes`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_acrobatics` (`acrobatics`) USING BTREE, "
 | 
			
		||||
                            + "ADD INDEX `idx_fishing` (`fishing`) USING BTREE;");
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case MOB_HEALTHBARS:
 | 
			
		||||
                sql = "SELECT * FROM  `" + tablePrefix + "huds` ORDER BY  `" + tablePrefix + "huds`.`mobhealthbar` ASC LIMIT 0 , 30";
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        PreparedStatement statement = null;
 | 
			
		||||
        try {
 | 
			
		||||
            if (!checkConnected()) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            statement = connection.prepareStatement(sql);
 | 
			
		||||
            resultSet = statement.executeQuery();
 | 
			
		||||
 | 
			
		||||
            while (resultSet.next()) {
 | 
			
		||||
                ArrayList<String> column = new ArrayList<String>();
 | 
			
		||||
 | 
			
		||||
                for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
 | 
			
		||||
                    column.add(resultSet.getString(i));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                rows.put(resultSet.getRow(), column);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (SQLException ex) {
 | 
			
		||||
            switch (update) {
 | 
			
		||||
                case BLAST_MINING:
 | 
			
		||||
                    mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Blast Mining...");
 | 
			
		||||
                    write("ALTER TABLE `"+tablePrefix + "cooldowns` ADD `blast_mining` int(32) NOT NULL DEFAULT '0' ;");
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case FISHING:
 | 
			
		||||
                    mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Fishing...");
 | 
			
		||||
                    write("ALTER TABLE `"+tablePrefix + "skills` ADD `fishing` int(10) NOT NULL DEFAULT '0' ;");
 | 
			
		||||
                    write("ALTER TABLE `"+tablePrefix + "experience` ADD `fishing` int(10) NOT NULL DEFAULT '0' ;");
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case MOB_HEALTHBARS:
 | 
			
		||||
                    mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for mob healthbars...");
 | 
			
		||||
                    write("ALTER TABLE `" + tablePrefix + "huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT 'HEARTS' ;");
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        finally {
 | 
			
		||||
            if (statement != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    statement.close();
 | 
			
		||||
                }
 | 
			
		||||
                catch (SQLException e) {
 | 
			
		||||
                    // Ignore the error, we're leaving
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void printErrors(SQLException ex) {
 | 
			
		||||
        mcMMO.p.getLogger().severe("SQLException: " + ex.getMessage());
 | 
			
		||||
        mcMMO.p.getLogger().severe("SQLState: " + ex.getSQLState());
 | 
			
		||||
        mcMMO.p.getLogger().severe("VendorError: " + ex.getErrorCode());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -12,7 +12,7 @@ import java.util.Set;
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
import com.gmail.nossr50.config.spout.SpoutConfig;
 | 
			
		||||
import com.gmail.nossr50.database.DatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.database.SQLDatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.datatypes.MobHealthbarType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.AbilityType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SkillType;
 | 
			
		||||
@@ -20,514 +20,56 @@ import com.gmail.nossr50.datatypes.spout.huds.HudType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.spout.huds.McMMOHud;
 | 
			
		||||
import com.gmail.nossr50.skills.child.FamilyTree;
 | 
			
		||||
import com.gmail.nossr50.util.Misc;
 | 
			
		||||
import com.gmail.nossr50.util.StringUtils;
 | 
			
		||||
 | 
			
		||||
public class PlayerProfile {
 | 
			
		||||
    private String playerName;
 | 
			
		||||
 | 
			
		||||
    // HUD
 | 
			
		||||
    private McMMOHud spoutHud;
 | 
			
		||||
    private HudType  hudType;
 | 
			
		||||
    private MobHealthbarType mobHealthbarType;
 | 
			
		||||
 | 
			
		||||
    // mySQL Stuff
 | 
			
		||||
    private final String playerName;
 | 
			
		||||
    private int userId;
 | 
			
		||||
 | 
			
		||||
    private boolean loaded;
 | 
			
		||||
 | 
			
		||||
    private Map<SkillType, Integer>   skills     = new HashMap<SkillType, Integer>(); // Skills and Levels
 | 
			
		||||
    private Map<SkillType, Integer>   skillsXp   = new HashMap<SkillType, Integer>(); // Skills and Xp
 | 
			
		||||
    private Map<AbilityType, Integer> skillsDATS = new HashMap<AbilityType, Integer>();
 | 
			
		||||
    /* HUDs */
 | 
			
		||||
    private HudType hudType;
 | 
			
		||||
    private MobHealthbarType mobHealthbarType;
 | 
			
		||||
    private McMMOHud spoutHud;
 | 
			
		||||
 | 
			
		||||
    private final static String location = mcMMO.getUsersFilePath();
 | 
			
		||||
    /* Skill Data */
 | 
			
		||||
    private final Map<SkillType, Integer>   skills     = new HashMap<SkillType, Integer>();   // Skill & Level
 | 
			
		||||
    private final Map<SkillType, Integer>   skillsXp   = new HashMap<SkillType, Integer>();   // Skill & XP
 | 
			
		||||
    private final Map<AbilityType, Integer> skillsDATS = new HashMap<AbilityType, Integer>(); // Ability & Cooldown
 | 
			
		||||
 | 
			
		||||
    public PlayerProfile(String playerName, boolean addNew) {
 | 
			
		||||
        this.playerName = playerName;
 | 
			
		||||
 | 
			
		||||
        hudType = mcMMO.spoutEnabled ? SpoutConfig.getInstance().getDefaultHudType() : HudType.DISABLED;
 | 
			
		||||
        mobHealthbarType = Config.getInstance().getMobHealthbarDefault();
 | 
			
		||||
 | 
			
		||||
        if (mcMMO.spoutEnabled) {
 | 
			
		||||
            hudType = SpoutConfig.getInstance().getDefaultHudType();
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            hudType = HudType.DISABLED;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (AbilityType abilityType : AbilityType.values()) {
 | 
			
		||||
            skillsDATS.put(abilityType, 0);
 | 
			
		||||
            skillsDATS.put(abilityType, 0); 
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (SkillType skillType : SkillType.values()) {
 | 
			
		||||
            if (!skillType.isChildSkill()) {
 | 
			
		||||
                skills.put(skillType, 0);
 | 
			
		||||
                skillsXp.put(skillType, 0);
 | 
			
		||||
            if (skillType.isChildSkill()) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            skills.put(skillType, 0);
 | 
			
		||||
            skillsXp.put(skillType, 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (Config.getInstance().getUseMySQL()) {
 | 
			
		||||
            if (!loadMySQL() && addNew) {
 | 
			
		||||
                addMySQLPlayer();
 | 
			
		||||
                loaded = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (!load() && addNew) {
 | 
			
		||||
        if (!loadPlayer() && addNew) {
 | 
			
		||||
            addPlayer();
 | 
			
		||||
            loaded = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getPlayerName() {
 | 
			
		||||
        return playerName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean loadMySQL() {
 | 
			
		||||
        String tablePrefix = Config.getInstance().getMySQLTablePrefix();
 | 
			
		||||
 | 
			
		||||
        userId = DatabaseManager.getInt("SELECT id FROM " + tablePrefix + "users WHERE user = '" + playerName + "'");
 | 
			
		||||
 | 
			
		||||
        if (userId == 0) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        HashMap<Integer, ArrayList<String>> huds = DatabaseManager.read("SELECT hudtype FROM " + tablePrefix + "huds WHERE user_id = " + userId);
 | 
			
		||||
 | 
			
		||||
        if (huds.get(1) == null) {
 | 
			
		||||
            DatabaseManager.write("INSERT INTO " + tablePrefix + "huds (user_id) VALUES (" + userId + ")");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            hudType = HudType.valueOf(huds.get(1).get(0));
 | 
			
		||||
            mobHealthbarType = MobHealthbarType.valueOf(DatabaseManager.read("SELECT mobhealthbar FROM " + tablePrefix + "huds WHERE user_id = " + userId).get(1).get(0));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        HashMap<Integer, ArrayList<String>> cooldowns = DatabaseManager.read("SELECT mining, woodcutting, unarmed, herbalism, excavation, swords, axes, blast_mining FROM " + tablePrefix + "cooldowns WHERE user_id = " + userId);
 | 
			
		||||
        ArrayList<String> cooldownValues = cooldowns.get(1);
 | 
			
		||||
 | 
			
		||||
        if (cooldownValues == null) {
 | 
			
		||||
            DatabaseManager.write("INSERT INTO " + tablePrefix + "cooldowns (user_id) VALUES (" + userId + ")");
 | 
			
		||||
            mcMMO.p.getLogger().warning(playerName + "does not exist in the cooldown table. Their cooldowns will be reset.");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            skillsDATS.put(AbilityType.SUPER_BREAKER, Integer.valueOf(cooldownValues.get(0)));
 | 
			
		||||
            skillsDATS.put(AbilityType.TREE_FELLER, Integer.valueOf(cooldownValues.get(1)));
 | 
			
		||||
            skillsDATS.put(AbilityType.BERSERK, Integer.valueOf(cooldownValues.get(2)));
 | 
			
		||||
            skillsDATS.put(AbilityType.GREEN_TERRA, Integer.valueOf(cooldownValues.get(3)));
 | 
			
		||||
            skillsDATS.put(AbilityType.GIGA_DRILL_BREAKER, Integer.valueOf(cooldownValues.get(4)));
 | 
			
		||||
            skillsDATS.put(AbilityType.SERRATED_STRIKES, Integer.valueOf(cooldownValues.get(5)));
 | 
			
		||||
            skillsDATS.put(AbilityType.SKULL_SPLITTER, Integer.valueOf(cooldownValues.get(6)));
 | 
			
		||||
            skillsDATS.put(AbilityType.BLAST_MINING, Integer.valueOf(cooldownValues.get(7)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        HashMap<Integer, ArrayList<String>> stats = DatabaseManager.read("SELECT taming, mining, repair, woodcutting, unarmed, herbalism, excavation, archery, swords, axes, acrobatics, fishing FROM " + tablePrefix + "skills WHERE user_id = " + userId);
 | 
			
		||||
        ArrayList<String> statValues = stats.get(1);
 | 
			
		||||
 | 
			
		||||
        if (statValues == null) {
 | 
			
		||||
            DatabaseManager.write("INSERT INTO " + tablePrefix + "skills (user_id) VALUES (" + userId + ")");
 | 
			
		||||
            mcMMO.p.getLogger().warning(playerName + "does not exist in the skills table. Their stats will be reset.");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            skills.put(SkillType.TAMING, Integer.valueOf(statValues.get(0)));
 | 
			
		||||
            skills.put(SkillType.MINING, Integer.valueOf(statValues.get(1)));
 | 
			
		||||
            skills.put(SkillType.REPAIR, Integer.valueOf(statValues.get(2)));
 | 
			
		||||
            skills.put(SkillType.WOODCUTTING, Integer.valueOf(statValues.get(3)));
 | 
			
		||||
            skills.put(SkillType.UNARMED, Integer.valueOf(statValues.get(4)));
 | 
			
		||||
            skills.put(SkillType.HERBALISM, Integer.valueOf(statValues.get(5)));
 | 
			
		||||
            skills.put(SkillType.EXCAVATION, Integer.valueOf(statValues.get(6)));
 | 
			
		||||
            skills.put(SkillType.ARCHERY, Integer.valueOf(statValues.get(7)));
 | 
			
		||||
            skills.put(SkillType.SWORDS, Integer.valueOf(statValues.get(8)));
 | 
			
		||||
            skills.put(SkillType.AXES, Integer.valueOf(statValues.get(9)));
 | 
			
		||||
            skills.put(SkillType.ACROBATICS, Integer.valueOf(statValues.get(10)));
 | 
			
		||||
            skills.put(SkillType.FISHING, Integer.valueOf(statValues.get(11)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        HashMap<Integer, ArrayList<String>> experience = DatabaseManager.read("SELECT taming, mining, repair, woodcutting, unarmed, herbalism, excavation, archery, swords, axes, acrobatics, fishing FROM " + tablePrefix + "experience WHERE user_id = " + userId);
 | 
			
		||||
        ArrayList<String> experienceValues = experience.get(1);
 | 
			
		||||
 | 
			
		||||
        if (experienceValues == null) {
 | 
			
		||||
            DatabaseManager.write("INSERT INTO " + tablePrefix + "experience (user_id) VALUES (" + userId + ")");
 | 
			
		||||
            mcMMO.p.getLogger().warning(playerName + "does not exist in the experience table. Their experience will be reset.");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            skillsXp.put(SkillType.TAMING, Integer.valueOf(experienceValues.get(0)));
 | 
			
		||||
            skillsXp.put(SkillType.MINING, Integer.valueOf(experienceValues.get(1)));
 | 
			
		||||
            skillsXp.put(SkillType.REPAIR, Integer.valueOf(experienceValues.get(2)));
 | 
			
		||||
            skillsXp.put(SkillType.WOODCUTTING, Integer.valueOf(experienceValues.get(3)));
 | 
			
		||||
            skillsXp.put(SkillType.UNARMED, Integer.valueOf(experienceValues.get(4)));
 | 
			
		||||
            skillsXp.put(SkillType.HERBALISM, Integer.valueOf(experienceValues.get(5)));
 | 
			
		||||
            skillsXp.put(SkillType.EXCAVATION, Integer.valueOf(experienceValues.get(6)));
 | 
			
		||||
            skillsXp.put(SkillType.ARCHERY, Integer.valueOf(experienceValues.get(7)));
 | 
			
		||||
            skillsXp.put(SkillType.SWORDS, Integer.valueOf(experienceValues.get(8)));
 | 
			
		||||
            skillsXp.put(SkillType.AXES, Integer.valueOf(experienceValues.get(9)));
 | 
			
		||||
            skillsXp.put(SkillType.ACROBATICS, Integer.valueOf(experienceValues.get(10)));
 | 
			
		||||
            skillsXp.put(SkillType.FISHING, Integer.valueOf(experienceValues.get(11)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        loaded = true;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addMySQLPlayer() {
 | 
			
		||||
        String tablePrefix = Config.getInstance().getMySQLTablePrefix();
 | 
			
		||||
 | 
			
		||||
        DatabaseManager.write("INSERT INTO " + tablePrefix + "users (user, lastlogin) VALUES ('" + playerName + "'," + System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR + ")");
 | 
			
		||||
        userId = DatabaseManager.getInt("SELECT id FROM " + tablePrefix + "users WHERE user = '" + playerName + "'");
 | 
			
		||||
 | 
			
		||||
        DatabaseManager.write("INSERT INTO " + tablePrefix + "cooldowns (user_id) VALUES (" + userId + ")");
 | 
			
		||||
        DatabaseManager.write("INSERT INTO " + tablePrefix + "skills (user_id) VALUES (" + userId + ")");
 | 
			
		||||
        DatabaseManager.write("INSERT INTO " + tablePrefix + "experience (user_id) VALUES (" + userId + ")");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean load() {
 | 
			
		||||
        try {
 | 
			
		||||
            // Open the user file
 | 
			
		||||
            FileReader file = new FileReader(location);
 | 
			
		||||
            BufferedReader in = new BufferedReader(file);
 | 
			
		||||
            String line;
 | 
			
		||||
 | 
			
		||||
            while ((line = in.readLine()) != null) {
 | 
			
		||||
                // Find if the line contains the player we want.
 | 
			
		||||
                String[] character = line.split(":");
 | 
			
		||||
 | 
			
		||||
                if (!character[0].equalsIgnoreCase(playerName)) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 1 && StringUtils.isInt(character[1])) {
 | 
			
		||||
                    skills.put(SkillType.MINING, Integer.valueOf(character[1]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 4 && StringUtils.isInt(character[4])) {
 | 
			
		||||
                    skillsXp.put(SkillType.MINING, Integer.valueOf(character[4]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 5 && StringUtils.isInt(character[5])) {
 | 
			
		||||
                    skills.put(SkillType.WOODCUTTING, Integer.valueOf(character[5]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 6 && StringUtils.isInt(character[6])) {
 | 
			
		||||
                    skillsXp.put(SkillType.WOODCUTTING, Integer.valueOf(character[6]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 7 && StringUtils.isInt(character[7])) {
 | 
			
		||||
                    skills.put(SkillType.REPAIR, Integer.valueOf(character[7]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 8 && StringUtils.isInt(character[8])) {
 | 
			
		||||
                    skills.put(SkillType.UNARMED,  Integer.valueOf(character[8]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 9 && StringUtils.isInt(character[9])) {
 | 
			
		||||
                    skills.put(SkillType.HERBALISM, Integer.valueOf(character[9]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 10 && StringUtils.isInt(character[10])) {
 | 
			
		||||
                    skills.put(SkillType.EXCAVATION, Integer.valueOf(character[10]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 11 && StringUtils.isInt(character[11])) {
 | 
			
		||||
                    skills.put(SkillType.ARCHERY, Integer.valueOf(character[11]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 12 && StringUtils.isInt(character[12])) {
 | 
			
		||||
                    skills.put(SkillType.SWORDS, Integer.valueOf(character[12]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 13 && StringUtils.isInt(character[13])) {
 | 
			
		||||
                    skills.put(SkillType.AXES, Integer.valueOf(character[13]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 14 && StringUtils.isInt(character[14])) {
 | 
			
		||||
                    skills.put(SkillType.ACROBATICS, Integer.valueOf(character[14]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 15 && StringUtils.isInt(character[15])) {
 | 
			
		||||
                    skillsXp.put(SkillType.REPAIR, Integer.valueOf(character[15]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 16 && StringUtils.isInt(character[16])) {
 | 
			
		||||
                    skillsXp.put(SkillType.UNARMED, Integer.valueOf(character[16]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 17 && StringUtils.isInt(character[17])) {
 | 
			
		||||
                    skillsXp.put(SkillType.HERBALISM, Integer.valueOf(character[17]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 18 && StringUtils.isInt(character[18])) {
 | 
			
		||||
                    skillsXp.put(SkillType.EXCAVATION, Integer.valueOf(character[18]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 19 && StringUtils.isInt(character[19])) {
 | 
			
		||||
                    skillsXp.put(SkillType.ARCHERY, Integer.valueOf(character[19]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 20 && StringUtils.isInt(character[20])) {
 | 
			
		||||
                    skillsXp.put(SkillType.SWORDS, Integer.valueOf(character[20]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 21 && StringUtils.isInt(character[21])) {
 | 
			
		||||
                    skillsXp.put(SkillType.AXES, Integer.valueOf(character[21]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 22 && StringUtils.isInt(character[22])) {
 | 
			
		||||
                    skillsXp.put(SkillType.ACROBATICS, Integer.valueOf(character[22]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 24 && StringUtils.isInt(character[24])) {
 | 
			
		||||
                    skills.put(SkillType.TAMING, Integer.valueOf(character[24]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 25 && StringUtils.isInt(character[25])) {
 | 
			
		||||
                    skillsXp.put(SkillType.TAMING, Integer.valueOf(character[25]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 26) {
 | 
			
		||||
                    skillsDATS.put(AbilityType.BERSERK, Integer.valueOf(character[26]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 27) {
 | 
			
		||||
                    skillsDATS.put(AbilityType.GIGA_DRILL_BREAKER, Integer.valueOf(character[27]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 28) {
 | 
			
		||||
                    skillsDATS.put(AbilityType.TREE_FELLER, Integer.valueOf(character[28]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 29) {
 | 
			
		||||
                    skillsDATS.put(AbilityType.GREEN_TERRA, Integer.valueOf(character[29]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 30) {
 | 
			
		||||
                    skillsDATS.put(AbilityType.SERRATED_STRIKES, Integer.valueOf(character[30]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 31) {
 | 
			
		||||
                    skillsDATS.put(AbilityType.SKULL_SPLITTER, Integer.valueOf(character[31]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 32) {
 | 
			
		||||
                    skillsDATS.put(AbilityType.SUPER_BREAKER, Integer.valueOf(character[32]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 33) {
 | 
			
		||||
                    hudType = HudType.valueOf(character[33]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 34) {
 | 
			
		||||
                    skills.put(SkillType.FISHING, Integer.valueOf(character[34]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 35) {
 | 
			
		||||
                    skillsXp.put(SkillType.FISHING, Integer.valueOf(character[35]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 36) {
 | 
			
		||||
                    skillsDATS.put(AbilityType.BLAST_MINING, Integer.valueOf(character[36]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (character.length > 38) {
 | 
			
		||||
                    mobHealthbarType = MobHealthbarType.valueOf(character[38]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                loaded = true;
 | 
			
		||||
 | 
			
		||||
                in.close();
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            in.close();
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void save() {
 | 
			
		||||
        Long timestamp = System.currentTimeMillis();
 | 
			
		||||
 | 
			
		||||
        // If we are using mysql save to database
 | 
			
		||||
        if (Config.getInstance().getUseMySQL()) {
 | 
			
		||||
            String tablePrefix = Config.getInstance().getMySQLTablePrefix();
 | 
			
		||||
 | 
			
		||||
            DatabaseManager.write("UPDATE " + tablePrefix + "huds SET hudtype = '" + hudType.toString() + "' WHERE user_id = " + userId);
 | 
			
		||||
            DatabaseManager.write("UPDATE " + tablePrefix + "huds SET mobhealthbar = '" + mobHealthbarType.toString() + "' WHERE user_id = " + userId);
 | 
			
		||||
            DatabaseManager.write("UPDATE " + tablePrefix + "users SET lastlogin = " + ((int) (timestamp / Misc.TIME_CONVERSION_FACTOR)) + " WHERE id = " + userId);
 | 
			
		||||
            DatabaseManager.write("UPDATE " + tablePrefix + "cooldowns SET "
 | 
			
		||||
                    + " mining = " + skillsDATS.get(AbilityType.SUPER_BREAKER)
 | 
			
		||||
                    + ", woodcutting = " + skillsDATS.get(AbilityType.TREE_FELLER)
 | 
			
		||||
                    + ", unarmed = " + skillsDATS.get(AbilityType.BERSERK)
 | 
			
		||||
                    + ", herbalism = " + skillsDATS.get(AbilityType.GREEN_TERRA)
 | 
			
		||||
                    + ", excavation = " + skillsDATS.get(AbilityType.GIGA_DRILL_BREAKER)
 | 
			
		||||
                    + ", swords = " + skillsDATS.get(AbilityType.SERRATED_STRIKES)
 | 
			
		||||
                    + ", axes = " + skillsDATS.get(AbilityType.SKULL_SPLITTER)
 | 
			
		||||
                    + ", blast_mining = " + skillsDATS.get(AbilityType.BLAST_MINING)
 | 
			
		||||
                    + " WHERE user_id = " + userId);
 | 
			
		||||
            DatabaseManager.write("UPDATE " + tablePrefix + "skills SET "
 | 
			
		||||
                    + " taming = " + skills.get(SkillType.TAMING)
 | 
			
		||||
                    + ", mining = " + skills.get(SkillType.MINING)
 | 
			
		||||
                    + ", repair = " + skills.get(SkillType.REPAIR)
 | 
			
		||||
                    + ", woodcutting = " + skills.get(SkillType.WOODCUTTING)
 | 
			
		||||
                    + ", unarmed = " + skills.get(SkillType.UNARMED)
 | 
			
		||||
                    + ", herbalism = " + skills.get(SkillType.HERBALISM)
 | 
			
		||||
                    + ", excavation = " + skills.get(SkillType.EXCAVATION)
 | 
			
		||||
                    + ", archery = " + skills.get(SkillType.ARCHERY)
 | 
			
		||||
                    + ", swords = " + skills.get(SkillType.SWORDS)
 | 
			
		||||
                    + ", axes = " + skills.get(SkillType.AXES)
 | 
			
		||||
                    + ", acrobatics = " + skills.get(SkillType.ACROBATICS)
 | 
			
		||||
                    + ", fishing = " + skills.get(SkillType.FISHING)
 | 
			
		||||
                    + " WHERE user_id = " + userId);
 | 
			
		||||
            DatabaseManager.write("UPDATE " + tablePrefix + "experience SET "
 | 
			
		||||
                    + "  taming = " + skillsXp.get(SkillType.TAMING)
 | 
			
		||||
                    + ", mining = " + skillsXp.get(SkillType.MINING)
 | 
			
		||||
                    + ", repair = " + skillsXp.get(SkillType.REPAIR)
 | 
			
		||||
                    + ", woodcutting = " + skillsXp.get(SkillType.WOODCUTTING)
 | 
			
		||||
                    + ", unarmed = " + skillsXp.get(SkillType.UNARMED)
 | 
			
		||||
                    + ", herbalism = " + skillsXp.get(SkillType.HERBALISM)
 | 
			
		||||
                    + ", excavation = " + skillsXp.get(SkillType.EXCAVATION)
 | 
			
		||||
                    + ", archery = " + skillsXp.get(SkillType.ARCHERY)
 | 
			
		||||
                    + ", swords = " + skillsXp.get(SkillType.SWORDS)
 | 
			
		||||
                    + ", axes = " + skillsXp.get(SkillType.AXES)
 | 
			
		||||
                    + ", acrobatics = " + skillsXp.get(SkillType.ACROBATICS)
 | 
			
		||||
                    + ", fishing = " + skillsXp.get(SkillType.FISHING)
 | 
			
		||||
                    + " WHERE user_id = " + userId);
 | 
			
		||||
            saveMySQL();
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            // Otherwise save to flatfile
 | 
			
		||||
            try {
 | 
			
		||||
                // Open the file
 | 
			
		||||
                FileReader file = new FileReader(location);
 | 
			
		||||
                BufferedReader in = new BufferedReader(file);
 | 
			
		||||
                StringBuilder writer = new StringBuilder();
 | 
			
		||||
                String line;
 | 
			
		||||
 | 
			
		||||
                // While not at the end of the file
 | 
			
		||||
                while ((line = in.readLine()) != null) {
 | 
			
		||||
                    // Read the line in and copy it to the output it's not the player we want to edit
 | 
			
		||||
                    if (!line.split(":")[0].equalsIgnoreCase(playerName)) {
 | 
			
		||||
                        writer.append(line).append("\r\n");
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        // Otherwise write the new player information
 | 
			
		||||
                        writer.append(playerName).append(":");
 | 
			
		||||
                        writer.append(skills.get(SkillType.MINING)).append(":");
 | 
			
		||||
                        writer.append(":");
 | 
			
		||||
                        writer.append(":");
 | 
			
		||||
                        writer.append(skillsXp.get(SkillType.MINING)).append(":");
 | 
			
		||||
                        writer.append(skills.get(SkillType.WOODCUTTING)).append(":");
 | 
			
		||||
                        writer.append(skillsXp.get(SkillType.WOODCUTTING)).append(":");
 | 
			
		||||
                        writer.append(skills.get(SkillType.REPAIR)).append(":");
 | 
			
		||||
                        writer.append(skills.get(SkillType.UNARMED)).append(":");
 | 
			
		||||
                        writer.append(skills.get(SkillType.HERBALISM)).append(":");
 | 
			
		||||
                        writer.append(skills.get(SkillType.EXCAVATION)).append(":");
 | 
			
		||||
                        writer.append(skills.get(SkillType.ARCHERY)).append(":");
 | 
			
		||||
                        writer.append(skills.get(SkillType.SWORDS)).append(":");
 | 
			
		||||
                        writer.append(skills.get(SkillType.AXES)).append(":");
 | 
			
		||||
                        writer.append(skills.get(SkillType.ACROBATICS)).append(":");
 | 
			
		||||
                        writer.append(skillsXp.get(SkillType.REPAIR)).append(":");
 | 
			
		||||
                        writer.append(skillsXp.get(SkillType.UNARMED)).append(":");
 | 
			
		||||
                        writer.append(skillsXp.get(SkillType.HERBALISM)).append(":");
 | 
			
		||||
                        writer.append(skillsXp.get(SkillType.EXCAVATION)).append(":");
 | 
			
		||||
                        writer.append(skillsXp.get(SkillType.ARCHERY)).append(":");
 | 
			
		||||
                        writer.append(skillsXp.get(SkillType.SWORDS)).append(":");
 | 
			
		||||
                        writer.append(skillsXp.get(SkillType.AXES)).append(":");
 | 
			
		||||
                        writer.append(skillsXp.get(SkillType.ACROBATICS)).append(":");
 | 
			
		||||
                        writer.append(":");
 | 
			
		||||
                        writer.append(skills.get(SkillType.TAMING)).append(":");
 | 
			
		||||
                        writer.append(skillsXp.get(SkillType.TAMING)).append(":");
 | 
			
		||||
                        writer.append(skillsDATS.get(AbilityType.BERSERK)).append(":");
 | 
			
		||||
                        writer.append(skillsDATS.get(AbilityType.GIGA_DRILL_BREAKER)).append(":");
 | 
			
		||||
                        writer.append(skillsDATS.get(AbilityType.TREE_FELLER)).append(":");
 | 
			
		||||
                        writer.append(skillsDATS.get(AbilityType.GREEN_TERRA)).append(":");
 | 
			
		||||
                        writer.append(skillsDATS.get(AbilityType.SERRATED_STRIKES)).append(":");
 | 
			
		||||
                        writer.append(skillsDATS.get(AbilityType.SKULL_SPLITTER)).append(":");
 | 
			
		||||
                        writer.append(skillsDATS.get(AbilityType.SUPER_BREAKER)).append(":");
 | 
			
		||||
                        writer.append(hudType.toString()).append(":");
 | 
			
		||||
                        writer.append(skills.get(SkillType.FISHING)).append(":");
 | 
			
		||||
                        writer.append(skillsXp.get(SkillType.FISHING)).append(":");
 | 
			
		||||
                        writer.append(skillsDATS.get(AbilityType.BLAST_MINING)).append(":");
 | 
			
		||||
                        writer.append(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":");
 | 
			
		||||
                        writer.append(mobHealthbarType.toString()).append(":");
 | 
			
		||||
                        writer.append("\r\n");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                in.close();
 | 
			
		||||
 | 
			
		||||
                // Write the new file
 | 
			
		||||
                FileWriter out = new FileWriter(location);
 | 
			
		||||
                out.write(writer.toString());
 | 
			
		||||
                out.flush();
 | 
			
		||||
                out.close();
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e) {
 | 
			
		||||
                e.printStackTrace();
 | 
			
		||||
            }
 | 
			
		||||
            saveFlatfile();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addPlayer() {
 | 
			
		||||
        try {
 | 
			
		||||
            // Open the file to write the player
 | 
			
		||||
            FileWriter file = new FileWriter(location, true);
 | 
			
		||||
            BufferedWriter out = new BufferedWriter(file);
 | 
			
		||||
 | 
			
		||||
            // Add the player to the end
 | 
			
		||||
            out.append(playerName).append(":");
 | 
			
		||||
            out.append("0:"); // Mining
 | 
			
		||||
            out.append(":");
 | 
			
		||||
            out.append(":");
 | 
			
		||||
            out.append("0:"); // Xp
 | 
			
		||||
            out.append("0:"); // Woodcutting
 | 
			
		||||
            out.append("0:"); // WoodCuttingXp
 | 
			
		||||
            out.append("0:"); // Repair
 | 
			
		||||
            out.append("0:"); // Unarmed
 | 
			
		||||
            out.append("0:"); // Herbalism
 | 
			
		||||
            out.append("0:"); // Excavation
 | 
			
		||||
            out.append("0:"); // Archery
 | 
			
		||||
            out.append("0:"); // Swords
 | 
			
		||||
            out.append("0:"); // Axes
 | 
			
		||||
            out.append("0:"); // Acrobatics
 | 
			
		||||
            out.append("0:"); // RepairXp
 | 
			
		||||
            out.append("0:"); // UnarmedXp
 | 
			
		||||
            out.append("0:"); // HerbalismXp
 | 
			
		||||
            out.append("0:"); // ExcavationXp
 | 
			
		||||
            out.append("0:"); // ArcheryXp
 | 
			
		||||
            out.append("0:"); // SwordsXp
 | 
			
		||||
            out.append("0:"); // AxesXp
 | 
			
		||||
            out.append("0:"); // AcrobaticsXp
 | 
			
		||||
            out.append(":");
 | 
			
		||||
            out.append("0:"); // Taming
 | 
			
		||||
            out.append("0:"); // TamingXp
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append(hudType.toString()).append(":"); // HUD
 | 
			
		||||
            out.append("0:"); // Fishing
 | 
			
		||||
            out.append("0:"); // FishingXp
 | 
			
		||||
            out.append("0:"); // Blast Mining
 | 
			
		||||
            out.append(String.valueOf(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR)).append(":"); // LastLogin
 | 
			
		||||
            out.append(mobHealthbarType.toString()).append(":"); // Mob Healthbar HUD
 | 
			
		||||
 | 
			
		||||
            // Add more in the same format as the line above
 | 
			
		||||
 | 
			
		||||
            out.newLine();
 | 
			
		||||
            out.close();
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * mySQL Stuff
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    public int getMySQLuserId() {
 | 
			
		||||
        return userId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isLoaded() {
 | 
			
		||||
        return loaded;
 | 
			
		||||
    }
 | 
			
		||||
@@ -594,8 +136,8 @@ public class PlayerProfile {
 | 
			
		||||
     * Reset all skill cooldowns.
 | 
			
		||||
     */
 | 
			
		||||
    public void resetCooldowns() {
 | 
			
		||||
        for (AbilityType x : skillsDATS.keySet()) {
 | 
			
		||||
            skillsDATS.put(x, 0);
 | 
			
		||||
        for (AbilityType ability : skillsDATS.keySet()) {
 | 
			
		||||
            skillsDATS.put(ability, 0);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -611,17 +153,6 @@ public class PlayerProfile {
 | 
			
		||||
        return skills.get(skillType);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getChildSkillLevel(SkillType skillType) {
 | 
			
		||||
        Set<SkillType> parents = FamilyTree.getParents(skillType);
 | 
			
		||||
        int sum = 0;
 | 
			
		||||
 | 
			
		||||
        for (SkillType parent : parents) {
 | 
			
		||||
            sum += Math.min(getSkillLevel(parent), 1000);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return sum / parents.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getSkillXpLevel(SkillType skillType) {
 | 
			
		||||
        return skillsXp.get(skillType);
 | 
			
		||||
    }
 | 
			
		||||
@@ -705,4 +236,384 @@ public class PlayerProfile {
 | 
			
		||||
    public int getXpToLevel(SkillType skillType) {
 | 
			
		||||
        return 1020 + (skills.get(skillType) *  Config.getInstance().getFormulaMultiplierCurve());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private int getChildSkillLevel(SkillType skillType) {
 | 
			
		||||
        Set<SkillType> parents = FamilyTree.getParents(skillType);
 | 
			
		||||
        int sum = 0;
 | 
			
		||||
 | 
			
		||||
        for (SkillType parent : parents) {
 | 
			
		||||
            sum += Math.min(getSkillLevel(parent), 1000);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return sum / parents.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean loadPlayer() {
 | 
			
		||||
        return Config.getInstance().getUseMySQL() ? loadMySQL() : loadFlatfile();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void addPlayer() {
 | 
			
		||||
        if (Config.getInstance().getUseMySQL()) {
 | 
			
		||||
            addMySQLPlayer();
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            addFlatfilePlayer();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean loadMySQL() {
 | 
			
		||||
        String tablePrefix = Config.getInstance().getMySQLTablePrefix();
 | 
			
		||||
 | 
			
		||||
        userId = SQLDatabaseManager.getInt("SELECT id FROM " + tablePrefix + "users WHERE user = '" + playerName + "'");
 | 
			
		||||
 | 
			
		||||
        if (userId == 0) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ArrayList<String> hudValues = SQLDatabaseManager.read("SELECT hudtype, mobhealthbar FROM " + tablePrefix + "huds WHERE user_id = " + userId).get(1);
 | 
			
		||||
 | 
			
		||||
        if (hudValues == null) {
 | 
			
		||||
            SQLDatabaseManager.write("INSERT INTO " + tablePrefix + "huds (user_id, mobhealthbar) VALUES (" + userId + "," + mobHealthbarType.name() + ")");
 | 
			
		||||
            mcMMO.p.getLogger().warning(playerName + "does not exist in the HUD table. Their HUDs will be reset.");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            hudType = HudType.valueOf(hudValues.get(0));
 | 
			
		||||
            mobHealthbarType = MobHealthbarType.valueOf(hudValues.get(1));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ArrayList<String> cooldownValues = SQLDatabaseManager.read("SELECT mining, woodcutting, unarmed, herbalism, excavation, swords, axes, blast_mining FROM " + tablePrefix + "cooldowns WHERE user_id = " + userId).get(1);
 | 
			
		||||
 | 
			
		||||
        if (cooldownValues == null) {
 | 
			
		||||
            SQLDatabaseManager.write("INSERT INTO " + tablePrefix + "cooldowns (user_id) VALUES (" + userId + ")");
 | 
			
		||||
            mcMMO.p.getLogger().warning(playerName + "does not exist in the cooldown table. Their cooldowns will be reset.");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            skillsDATS.put(AbilityType.SUPER_BREAKER, Integer.valueOf(cooldownValues.get(0)));
 | 
			
		||||
            skillsDATS.put(AbilityType.TREE_FELLER, Integer.valueOf(cooldownValues.get(1)));
 | 
			
		||||
            skillsDATS.put(AbilityType.BERSERK, Integer.valueOf(cooldownValues.get(2)));
 | 
			
		||||
            skillsDATS.put(AbilityType.GREEN_TERRA, Integer.valueOf(cooldownValues.get(3)));
 | 
			
		||||
            skillsDATS.put(AbilityType.GIGA_DRILL_BREAKER, Integer.valueOf(cooldownValues.get(4)));
 | 
			
		||||
            skillsDATS.put(AbilityType.SERRATED_STRIKES, Integer.valueOf(cooldownValues.get(5)));
 | 
			
		||||
            skillsDATS.put(AbilityType.SKULL_SPLITTER, Integer.valueOf(cooldownValues.get(6)));
 | 
			
		||||
            skillsDATS.put(AbilityType.BLAST_MINING, Integer.valueOf(cooldownValues.get(7)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ArrayList<String> statValues = SQLDatabaseManager.read("SELECT taming, mining, repair, woodcutting, unarmed, herbalism, excavation, archery, swords, axes, acrobatics, fishing FROM " + tablePrefix + "skills WHERE user_id = " + userId).get(1);
 | 
			
		||||
 | 
			
		||||
        if (statValues == null) {
 | 
			
		||||
            SQLDatabaseManager.write("INSERT INTO " + tablePrefix + "skills (user_id) VALUES (" + userId + ")");
 | 
			
		||||
            mcMMO.p.getLogger().warning(playerName + "does not exist in the skills table. Their stats will be reset.");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            skills.put(SkillType.TAMING, Integer.valueOf(statValues.get(0)));
 | 
			
		||||
            skills.put(SkillType.MINING, Integer.valueOf(statValues.get(1)));
 | 
			
		||||
            skills.put(SkillType.REPAIR, Integer.valueOf(statValues.get(2)));
 | 
			
		||||
            skills.put(SkillType.WOODCUTTING, Integer.valueOf(statValues.get(3)));
 | 
			
		||||
            skills.put(SkillType.UNARMED, Integer.valueOf(statValues.get(4)));
 | 
			
		||||
            skills.put(SkillType.HERBALISM, Integer.valueOf(statValues.get(5)));
 | 
			
		||||
            skills.put(SkillType.EXCAVATION, Integer.valueOf(statValues.get(6)));
 | 
			
		||||
            skills.put(SkillType.ARCHERY, Integer.valueOf(statValues.get(7)));
 | 
			
		||||
            skills.put(SkillType.SWORDS, Integer.valueOf(statValues.get(8)));
 | 
			
		||||
            skills.put(SkillType.AXES, Integer.valueOf(statValues.get(9)));
 | 
			
		||||
            skills.put(SkillType.ACROBATICS, Integer.valueOf(statValues.get(10)));
 | 
			
		||||
            skills.put(SkillType.FISHING, Integer.valueOf(statValues.get(11)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ArrayList<String> experienceValues = SQLDatabaseManager.read("SELECT taming, mining, repair, woodcutting, unarmed, herbalism, excavation, archery, swords, axes, acrobatics, fishing FROM " + tablePrefix + "experience WHERE user_id = " + userId).get(1);
 | 
			
		||||
 | 
			
		||||
        if (experienceValues == null) {
 | 
			
		||||
            SQLDatabaseManager.write("INSERT INTO " + tablePrefix + "experience (user_id) VALUES (" + userId + ")");
 | 
			
		||||
            mcMMO.p.getLogger().warning(playerName + "does not exist in the experience table. Their experience will be reset.");
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            skillsXp.put(SkillType.TAMING, Integer.valueOf(experienceValues.get(0)));
 | 
			
		||||
            skillsXp.put(SkillType.MINING, Integer.valueOf(experienceValues.get(1)));
 | 
			
		||||
            skillsXp.put(SkillType.REPAIR, Integer.valueOf(experienceValues.get(2)));
 | 
			
		||||
            skillsXp.put(SkillType.WOODCUTTING, Integer.valueOf(experienceValues.get(3)));
 | 
			
		||||
            skillsXp.put(SkillType.UNARMED, Integer.valueOf(experienceValues.get(4)));
 | 
			
		||||
            skillsXp.put(SkillType.HERBALISM, Integer.valueOf(experienceValues.get(5)));
 | 
			
		||||
            skillsXp.put(SkillType.EXCAVATION, Integer.valueOf(experienceValues.get(6)));
 | 
			
		||||
            skillsXp.put(SkillType.ARCHERY, Integer.valueOf(experienceValues.get(7)));
 | 
			
		||||
            skillsXp.put(SkillType.SWORDS, Integer.valueOf(experienceValues.get(8)));
 | 
			
		||||
            skillsXp.put(SkillType.AXES, Integer.valueOf(experienceValues.get(9)));
 | 
			
		||||
            skillsXp.put(SkillType.ACROBATICS, Integer.valueOf(experienceValues.get(10)));
 | 
			
		||||
            skillsXp.put(SkillType.FISHING, Integer.valueOf(experienceValues.get(11)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        loaded = true;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void addMySQLPlayer() {
 | 
			
		||||
        String tablePrefix = Config.getInstance().getMySQLTablePrefix();
 | 
			
		||||
 | 
			
		||||
        SQLDatabaseManager.write("INSERT INTO " + tablePrefix + "users (user, lastlogin) VALUES ('" + playerName + "'," + System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR + ")");
 | 
			
		||||
        userId = SQLDatabaseManager.getInt("SELECT id FROM " + tablePrefix + "users WHERE user = '" + playerName + "'");
 | 
			
		||||
 | 
			
		||||
        SQLDatabaseManager.write("INSERT INTO " + tablePrefix + "huds (user_id, mobhealthbar) VALUES (" + userId + "," + mobHealthbarType.name() + ")");
 | 
			
		||||
        SQLDatabaseManager.write("INSERT INTO " + tablePrefix + "cooldowns (user_id) VALUES (" + userId + ")");
 | 
			
		||||
        SQLDatabaseManager.write("INSERT INTO " + tablePrefix + "skills (user_id) VALUES (" + userId + ")");
 | 
			
		||||
        SQLDatabaseManager.write("INSERT INTO " + tablePrefix + "experience (user_id) VALUES (" + userId + ")");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private void addFlatfilePlayer() {
 | 
			
		||||
        try {
 | 
			
		||||
            // Open the file to write the player
 | 
			
		||||
            BufferedWriter out = new BufferedWriter(new FileWriter(mcMMO.getUsersFilePath(), true));
 | 
			
		||||
 | 
			
		||||
            // Add the player to the end
 | 
			
		||||
            out.append(playerName).append(":");
 | 
			
		||||
            out.append("0:"); // Mining
 | 
			
		||||
            out.append(":");
 | 
			
		||||
            out.append(":");
 | 
			
		||||
            out.append("0:"); // Xp
 | 
			
		||||
            out.append("0:"); // Woodcutting
 | 
			
		||||
            out.append("0:"); // WoodCuttingXp
 | 
			
		||||
            out.append("0:"); // Repair
 | 
			
		||||
            out.append("0:"); // Unarmed
 | 
			
		||||
            out.append("0:"); // Herbalism
 | 
			
		||||
            out.append("0:"); // Excavation
 | 
			
		||||
            out.append("0:"); // Archery
 | 
			
		||||
            out.append("0:"); // Swords
 | 
			
		||||
            out.append("0:"); // Axes
 | 
			
		||||
            out.append("0:"); // Acrobatics
 | 
			
		||||
            out.append("0:"); // RepairXp
 | 
			
		||||
            out.append("0:"); // UnarmedXp
 | 
			
		||||
            out.append("0:"); // HerbalismXp
 | 
			
		||||
            out.append("0:"); // ExcavationXp
 | 
			
		||||
            out.append("0:"); // ArcheryXp
 | 
			
		||||
            out.append("0:"); // SwordsXp
 | 
			
		||||
            out.append("0:"); // AxesXp
 | 
			
		||||
            out.append("0:"); // AcrobaticsXp
 | 
			
		||||
            out.append(":");
 | 
			
		||||
            out.append("0:"); // Taming
 | 
			
		||||
            out.append("0:"); // TamingXp
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append("0:"); // DATS
 | 
			
		||||
            out.append(hudType.toString()).append(":"); // HUD
 | 
			
		||||
            out.append("0:"); // Fishing
 | 
			
		||||
            out.append("0:"); // FishingXp
 | 
			
		||||
            out.append("0:"); // Blast Mining
 | 
			
		||||
            out.append(String.valueOf(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR)).append(":"); // LastLogin
 | 
			
		||||
            out.append(mobHealthbarType.toString()).append(":"); // Mob Healthbar HUD
 | 
			
		||||
 | 
			
		||||
            // Add more in the same format as the line above
 | 
			
		||||
 | 
			
		||||
            out.newLine();
 | 
			
		||||
            out.close();
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean loadFlatfile() {
 | 
			
		||||
        try {
 | 
			
		||||
            // Open the user file
 | 
			
		||||
            FileReader file = new FileReader(mcMMO.getUsersFilePath());
 | 
			
		||||
            BufferedReader in = new BufferedReader(file);
 | 
			
		||||
            String line;
 | 
			
		||||
 | 
			
		||||
            while ((line = in.readLine()) != null) {
 | 
			
		||||
                // Find if the line contains the player we want.
 | 
			
		||||
                String[] character = line.split(":");
 | 
			
		||||
 | 
			
		||||
                if (!character[0].equalsIgnoreCase(playerName)) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                loadSkillData(SkillType.MINING, character, 1);
 | 
			
		||||
                loadSkillData(SkillType.WOODCUTTING, character, 5);
 | 
			
		||||
                loadSkillData(SkillType.REPAIR, character, 7);
 | 
			
		||||
                loadSkillData(SkillType.UNARMED, character, 8);
 | 
			
		||||
                loadSkillData(SkillType.HERBALISM, character, 9);
 | 
			
		||||
                loadSkillData(SkillType.EXCAVATION, character, 10);
 | 
			
		||||
                loadSkillData(SkillType.ARCHERY, character, 11);
 | 
			
		||||
                loadSkillData(SkillType.SWORDS, character, 12);
 | 
			
		||||
                loadSkillData(SkillType.AXES, character, 13);
 | 
			
		||||
                loadSkillData(SkillType.ACROBATICS, character, 14);
 | 
			
		||||
                loadSkillData(SkillType.TAMING, character, 24);
 | 
			
		||||
                loadSkillData(SkillType.FISHING, character, 34);
 | 
			
		||||
 | 
			
		||||
                loadSkillXpData(SkillType.MINING, character, 4);
 | 
			
		||||
                loadSkillXpData(SkillType.WOODCUTTING, character, 6);
 | 
			
		||||
                loadSkillXpData(SkillType.REPAIR, character, 15);
 | 
			
		||||
                loadSkillXpData(SkillType.UNARMED, character, 16);
 | 
			
		||||
                loadSkillXpData(SkillType.HERBALISM, character, 17);
 | 
			
		||||
                loadSkillXpData(SkillType.EXCAVATION, character, 18);
 | 
			
		||||
                loadSkillXpData(SkillType.ARCHERY, character, 19);
 | 
			
		||||
                loadSkillXpData(SkillType.SWORDS, character, 20);
 | 
			
		||||
                loadSkillXpData(SkillType.AXES, character, 21);
 | 
			
		||||
                loadSkillXpData(SkillType.ACROBATICS, character, 22);
 | 
			
		||||
                loadSkillXpData(SkillType.TAMING, character, 25);
 | 
			
		||||
                loadSkillXpData(SkillType.FISHING, character, 35);
 | 
			
		||||
 | 
			
		||||
                loadDATSData(AbilityType.BERSERK, character, 26);
 | 
			
		||||
                loadDATSData(AbilityType.GIGA_DRILL_BREAKER, character, 27);
 | 
			
		||||
                loadDATSData(AbilityType.TREE_FELLER, character, 28);
 | 
			
		||||
                loadDATSData(AbilityType.GREEN_TERRA, character, 29);
 | 
			
		||||
                loadDATSData(AbilityType.SERRATED_STRIKES, character, 30);
 | 
			
		||||
                loadDATSData(AbilityType.SKULL_SPLITTER, character, 31);
 | 
			
		||||
                loadDATSData(AbilityType.SUPER_BREAKER, character, 32);
 | 
			
		||||
                loadDATSData(AbilityType.BLAST_MINING, character, 36);
 | 
			
		||||
 | 
			
		||||
                hudType = character.length > 33 ? HudType.valueOf(character[33]) : null;
 | 
			
		||||
                mobHealthbarType = character.length > 38 ? MobHealthbarType.valueOf(character[38]) : null;
 | 
			
		||||
 | 
			
		||||
                loaded = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            in.close();
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return loaded;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void saveMySQL() {
 | 
			
		||||
        if (Config.getInstance().getUseMySQL()) {
 | 
			
		||||
            String tablePrefix = Config.getInstance().getMySQLTablePrefix();
 | 
			
		||||
 | 
			
		||||
            SQLDatabaseManager.write("UPDATE " + tablePrefix + "users SET lastlogin = " + ((int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR)) + " WHERE id = " + userId);
 | 
			
		||||
            SQLDatabaseManager.write("UPDATE " + tablePrefix + "huds SET "
 | 
			
		||||
                    + "  hudtype = " + hudType.toString()
 | 
			
		||||
                    + ", mobhealthbar = " + mobHealthbarType.toString()
 | 
			
		||||
                    + "  WHERE user_id = " + userId);
 | 
			
		||||
            SQLDatabaseManager.write("UPDATE " + tablePrefix + "cooldowns SET "
 | 
			
		||||
                    + "  mining = " + skillsDATS.get(AbilityType.SUPER_BREAKER)
 | 
			
		||||
                    + ", woodcutting = " + skillsDATS.get(AbilityType.TREE_FELLER)
 | 
			
		||||
                    + ", unarmed = " + skillsDATS.get(AbilityType.BERSERK)
 | 
			
		||||
                    + ", herbalism = " + skillsDATS.get(AbilityType.GREEN_TERRA)
 | 
			
		||||
                    + ", excavation = " + skillsDATS.get(AbilityType.GIGA_DRILL_BREAKER)
 | 
			
		||||
                    + ", swords = " + skillsDATS.get(AbilityType.SERRATED_STRIKES)
 | 
			
		||||
                    + ", axes = " + skillsDATS.get(AbilityType.SKULL_SPLITTER)
 | 
			
		||||
                    + ", blast_mining = " + skillsDATS.get(AbilityType.BLAST_MINING)
 | 
			
		||||
                    + "  WHERE user_id = " + userId);
 | 
			
		||||
            SQLDatabaseManager.write("UPDATE " + tablePrefix + "skills SET "
 | 
			
		||||
                    + "  taming = " + skills.get(SkillType.TAMING)
 | 
			
		||||
                    + ", mining = " + skills.get(SkillType.MINING)
 | 
			
		||||
                    + ", repair = " + skills.get(SkillType.REPAIR)
 | 
			
		||||
                    + ", woodcutting = " + skills.get(SkillType.WOODCUTTING)
 | 
			
		||||
                    + ", unarmed = " + skills.get(SkillType.UNARMED)
 | 
			
		||||
                    + ", herbalism = " + skills.get(SkillType.HERBALISM)
 | 
			
		||||
                    + ", excavation = " + skills.get(SkillType.EXCAVATION)
 | 
			
		||||
                    + ", archery = " + skills.get(SkillType.ARCHERY)
 | 
			
		||||
                    + ", swords = " + skills.get(SkillType.SWORDS)
 | 
			
		||||
                    + ", axes = " + skills.get(SkillType.AXES)
 | 
			
		||||
                    + ", acrobatics = " + skills.get(SkillType.ACROBATICS)
 | 
			
		||||
                    + ", fishing = " + skills.get(SkillType.FISHING)
 | 
			
		||||
                    + "  WHERE user_id = " + userId);
 | 
			
		||||
            SQLDatabaseManager.write("UPDATE " + tablePrefix + "experience SET "
 | 
			
		||||
                    + "  taming = " + skillsXp.get(SkillType.TAMING)
 | 
			
		||||
                    + ", mining = " + skillsXp.get(SkillType.MINING)
 | 
			
		||||
                    + ", repair = " + skillsXp.get(SkillType.REPAIR)
 | 
			
		||||
                    + ", woodcutting = " + skillsXp.get(SkillType.WOODCUTTING)
 | 
			
		||||
                    + ", unarmed = " + skillsXp.get(SkillType.UNARMED)
 | 
			
		||||
                    + ", herbalism = " + skillsXp.get(SkillType.HERBALISM)
 | 
			
		||||
                    + ", excavation = " + skillsXp.get(SkillType.EXCAVATION)
 | 
			
		||||
                    + ", archery = " + skillsXp.get(SkillType.ARCHERY)
 | 
			
		||||
                    + ", swords = " + skillsXp.get(SkillType.SWORDS)
 | 
			
		||||
                    + ", axes = " + skillsXp.get(SkillType.AXES)
 | 
			
		||||
                    + ", acrobatics = " + skillsXp.get(SkillType.ACROBATICS)
 | 
			
		||||
                    + ", fishing = " + skillsXp.get(SkillType.FISHING)
 | 
			
		||||
                    + "  WHERE user_id = " + userId);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void saveFlatfile() {
 | 
			
		||||
        try {
 | 
			
		||||
            // Open the file
 | 
			
		||||
            BufferedReader in = new BufferedReader(new FileReader(mcMMO.getUsersFilePath()));
 | 
			
		||||
            StringBuilder writer = new StringBuilder();
 | 
			
		||||
            String line;
 | 
			
		||||
 | 
			
		||||
            // While not at the end of the file
 | 
			
		||||
            while ((line = in.readLine()) != null) {
 | 
			
		||||
                // Read the line in and copy it to the output it's not the player we want to edit
 | 
			
		||||
                if (!line.split(":")[0].equalsIgnoreCase(playerName)) {
 | 
			
		||||
                    writer.append(line).append("\r\n");
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    // Otherwise write the new player information
 | 
			
		||||
                    writer.append(playerName).append(":");
 | 
			
		||||
                    writer.append(skills.get(SkillType.MINING)).append(":");
 | 
			
		||||
                    writer.append(":");
 | 
			
		||||
                    writer.append(":");
 | 
			
		||||
                    writer.append(skillsXp.get(SkillType.MINING)).append(":");
 | 
			
		||||
                    writer.append(skills.get(SkillType.WOODCUTTING)).append(":");
 | 
			
		||||
                    writer.append(skillsXp.get(SkillType.WOODCUTTING)).append(":");
 | 
			
		||||
                    writer.append(skills.get(SkillType.REPAIR)).append(":");
 | 
			
		||||
                    writer.append(skills.get(SkillType.UNARMED)).append(":");
 | 
			
		||||
                    writer.append(skills.get(SkillType.HERBALISM)).append(":");
 | 
			
		||||
                    writer.append(skills.get(SkillType.EXCAVATION)).append(":");
 | 
			
		||||
                    writer.append(skills.get(SkillType.ARCHERY)).append(":");
 | 
			
		||||
                    writer.append(skills.get(SkillType.SWORDS)).append(":");
 | 
			
		||||
                    writer.append(skills.get(SkillType.AXES)).append(":");
 | 
			
		||||
                    writer.append(skills.get(SkillType.ACROBATICS)).append(":");
 | 
			
		||||
                    writer.append(skillsXp.get(SkillType.REPAIR)).append(":");
 | 
			
		||||
                    writer.append(skillsXp.get(SkillType.UNARMED)).append(":");
 | 
			
		||||
                    writer.append(skillsXp.get(SkillType.HERBALISM)).append(":");
 | 
			
		||||
                    writer.append(skillsXp.get(SkillType.EXCAVATION)).append(":");
 | 
			
		||||
                    writer.append(skillsXp.get(SkillType.ARCHERY)).append(":");
 | 
			
		||||
                    writer.append(skillsXp.get(SkillType.SWORDS)).append(":");
 | 
			
		||||
                    writer.append(skillsXp.get(SkillType.AXES)).append(":");
 | 
			
		||||
                    writer.append(skillsXp.get(SkillType.ACROBATICS)).append(":");
 | 
			
		||||
                    writer.append(":");
 | 
			
		||||
                    writer.append(skills.get(SkillType.TAMING)).append(":");
 | 
			
		||||
                    writer.append(skillsXp.get(SkillType.TAMING)).append(":");
 | 
			
		||||
                    writer.append(skillsDATS.get(AbilityType.BERSERK)).append(":");
 | 
			
		||||
                    writer.append(skillsDATS.get(AbilityType.GIGA_DRILL_BREAKER)).append(":");
 | 
			
		||||
                    writer.append(skillsDATS.get(AbilityType.TREE_FELLER)).append(":");
 | 
			
		||||
                    writer.append(skillsDATS.get(AbilityType.GREEN_TERRA)).append(":");
 | 
			
		||||
                    writer.append(skillsDATS.get(AbilityType.SERRATED_STRIKES)).append(":");
 | 
			
		||||
                    writer.append(skillsDATS.get(AbilityType.SKULL_SPLITTER)).append(":");
 | 
			
		||||
                    writer.append(skillsDATS.get(AbilityType.SUPER_BREAKER)).append(":");
 | 
			
		||||
                    writer.append(hudType.toString()).append(":");
 | 
			
		||||
                    writer.append(skills.get(SkillType.FISHING)).append(":");
 | 
			
		||||
                    writer.append(skillsXp.get(SkillType.FISHING)).append(":");
 | 
			
		||||
                    writer.append(skillsDATS.get(AbilityType.BLAST_MINING)).append(":");
 | 
			
		||||
                    writer.append(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":");
 | 
			
		||||
                    writer.append(mobHealthbarType.toString()).append(":");
 | 
			
		||||
                    writer.append("\r\n");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            in.close();
 | 
			
		||||
 | 
			
		||||
            // Write the new file
 | 
			
		||||
            FileWriter out = new FileWriter(mcMMO.getUsersFilePath());
 | 
			
		||||
            out.write(writer.toString());
 | 
			
		||||
            out.flush();
 | 
			
		||||
            out.close();
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void loadSkillXpData(SkillType skill, String[] data, int dataIndex) {
 | 
			
		||||
        if (data.length > dataIndex) {
 | 
			
		||||
            skillsXp.put(skill, Integer.valueOf(data[dataIndex]));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void loadSkillData(SkillType skill, String[] data, int dataIndex) {
 | 
			
		||||
        if (data.length > dataIndex) {
 | 
			
		||||
            skills.put(skill, Integer.valueOf(data[dataIndex]));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void loadDATSData(AbilityType ability, String[] data, int dataIndex) {
 | 
			
		||||
        if (data.length > dataIndex) {
 | 
			
		||||
            skillsDATS.put(ability, Integer.valueOf(data[dataIndex]));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,6 @@ import com.gmail.nossr50.config.mods.CustomToolConfig;
 | 
			
		||||
import com.gmail.nossr50.config.spout.SpoutConfig;
 | 
			
		||||
import com.gmail.nossr50.config.treasure.TreasureConfig;
 | 
			
		||||
import com.gmail.nossr50.database.DatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.database.LeaderboardManager;
 | 
			
		||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.AbilityType;
 | 
			
		||||
import com.gmail.nossr50.listeners.BlockListener;
 | 
			
		||||
@@ -65,8 +64,9 @@ public class mcMMO extends JavaPlugin {
 | 
			
		||||
 | 
			
		||||
    public static mcMMO p;
 | 
			
		||||
 | 
			
		||||
    public static ChunkManager  placeStore;
 | 
			
		||||
    public static ChunkManager placeStore;
 | 
			
		||||
    public static RepairableManager repairableManager;
 | 
			
		||||
    public static DatabaseManager databaseManager;
 | 
			
		||||
 | 
			
		||||
    // Jar Stuff
 | 
			
		||||
    public static File mcmmo;
 | 
			
		||||
@@ -111,25 +111,13 @@ public class mcMMO extends JavaPlugin {
 | 
			
		||||
            setupSpout();
 | 
			
		||||
            loadConfigFiles();
 | 
			
		||||
 | 
			
		||||
            if (!Config.getInstance().getUseMySQL()) {
 | 
			
		||||
                UserManager.loadUsers();
 | 
			
		||||
            }
 | 
			
		||||
            databaseManager = new DatabaseManager(this, Config.getInstance().getUseMySQL());
 | 
			
		||||
 | 
			
		||||
            registerEvents();
 | 
			
		||||
            registerCustomRecipes();
 | 
			
		||||
 | 
			
		||||
            PartyManager.loadParties();
 | 
			
		||||
 | 
			
		||||
            // Setup the leader boards
 | 
			
		||||
            if (Config.getInstance().getUseMySQL()) {
 | 
			
		||||
                // TODO: Why do we have to check for a connection that hasn't be made yet?
 | 
			
		||||
                DatabaseManager.checkConnected();
 | 
			
		||||
                DatabaseManager.createStructure();
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                LeaderboardManager.updateLeaderboards();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (Player player : getServer().getOnlinePlayers()) {
 | 
			
		||||
                UserManager.addUser(player); // In case of reload add all users back into UserManager
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,9 @@ import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.database.DatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
import com.gmail.nossr50.database.SQLDatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.database.FlatfileDatabaseManager;
 | 
			
		||||
 | 
			
		||||
public class McrankCommandAsyncTask extends BukkitRunnable {
 | 
			
		||||
    private final String playerName;
 | 
			
		||||
@@ -19,7 +21,7 @@ public class McrankCommandAsyncTask extends BukkitRunnable {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void run() {
 | 
			
		||||
        Map<String, Integer> skills = DatabaseManager.readSQLRank(playerName);
 | 
			
		||||
        Map<String, Integer> skills = Config.getInstance().getUseMySQL() ? SQLDatabaseManager.readSQLRank(playerName) : FlatfileDatabaseManager.getPlayerRanks(playerName);
 | 
			
		||||
 | 
			
		||||
        new McrankCommandDisplayTask(skills, sender, playerName).runTaskLater(mcMMO.p, 1);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SkillType;
 | 
			
		||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
			
		||||
import com.gmail.nossr50.util.Permissions;
 | 
			
		||||
@@ -24,27 +25,22 @@ public class McrankCommandDisplayTask extends BukkitRunnable {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void run() {
 | 
			
		||||
        Player player = mcMMO.p.getServer().getPlayer(playerName);
 | 
			
		||||
        Integer rank;
 | 
			
		||||
 | 
			
		||||
        sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Heading"));
 | 
			
		||||
        sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Player", playerName));
 | 
			
		||||
 | 
			
		||||
        for (SkillType skillType : SkillType.values()) {
 | 
			
		||||
            if ((sender instanceof Player && !Permissions.skillEnabled(sender, skillType)) || skillType.isChildSkill()) {
 | 
			
		||||
        for (SkillType skill : SkillType.values()) {
 | 
			
		||||
            if (skill.isChildSkill() || !Permissions.skillEnabled(player, skill)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (skills.get(skillType.name()) == null) {
 | 
			
		||||
                sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", SkillUtils.getSkillName(skillType), LocaleLoader.getString("Commands.mcrank.Unranked")));
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", SkillUtils.getSkillName(skillType), skills.get(skillType.name())));
 | 
			
		||||
            }
 | 
			
		||||
            rank = skills.get(skill.name());
 | 
			
		||||
            sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", SkillUtils.getSkillName(skill), (rank == null ? LocaleLoader.getString("Commands.mcrank.Unranked") : rank)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (skills.get("ALL") == null) {
 | 
			
		||||
            sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Overall", LocaleLoader.getString("Commands.mcrank.Unranked")));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Overall", skills.get("ALL")));
 | 
			
		||||
        }
 | 
			
		||||
        rank = skills.get("ALL");
 | 
			
		||||
        sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Overall", (rank == null ? LocaleLoader.getString("Commands.mcrank.Unranked") : rank)));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
import com.gmail.nossr50.database.DatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.database.SQLDatabaseManager;
 | 
			
		||||
 | 
			
		||||
public class MctopCommandAsyncTask extends BukkitRunnable {
 | 
			
		||||
 | 
			
		||||
@@ -18,14 +18,14 @@ public class MctopCommandAsyncTask extends BukkitRunnable {
 | 
			
		||||
 | 
			
		||||
    public MctopCommandAsyncTask(int page, String query, CommandSender sender) {
 | 
			
		||||
        this.page = page;
 | 
			
		||||
        this.query = query;
 | 
			
		||||
        this.query = query.equalsIgnoreCase("ALL") ? "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing" : query;
 | 
			
		||||
        this.sender = sender;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void run() {
 | 
			
		||||
        String tablePrefix = Config.getInstance().getMySQLTablePrefix();
 | 
			
		||||
        final HashMap<Integer, ArrayList<String>> userslist = DatabaseManager.read("SELECT " + query + ", user, NOW() FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 ORDER BY " + query + " DESC, user LIMIT " + ((page * 10) - 10) + ",10");
 | 
			
		||||
        final HashMap<Integer, ArrayList<String>> userslist = SQLDatabaseManager.read("SELECT " + query + ", user, NOW() FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 ORDER BY " + query + " DESC, user LIMIT " + ((page * 10) - 10) + ",10");
 | 
			
		||||
 | 
			
		||||
        new MctopCommandDisplayTask(userslist, page, tablePrefix, sender).runTaskLater(mcMMO.p, 1);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
import com.gmail.nossr50.database.DatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.database.SQLDatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.util.Misc;
 | 
			
		||||
import com.gmail.nossr50.util.StringUtils;
 | 
			
		||||
 | 
			
		||||
@@ -158,7 +158,7 @@ public class SQLConversionTask extends BukkitRunnable {
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Check to see if the user is in the DB
 | 
			
		||||
                id = DatabaseManager.getInt("SELECT id FROM "
 | 
			
		||||
                id = SQLDatabaseManager.getInt("SELECT id FROM "
 | 
			
		||||
                        + tablePrefix
 | 
			
		||||
                        + "users WHERE user = '" + playerName + "'");
 | 
			
		||||
 | 
			
		||||
@@ -166,11 +166,11 @@ public class SQLConversionTask extends BukkitRunnable {
 | 
			
		||||
                    theCount++;
 | 
			
		||||
 | 
			
		||||
                    // Update the skill values
 | 
			
		||||
                    DatabaseManager.write("UPDATE "
 | 
			
		||||
                    SQLDatabaseManager.write("UPDATE "
 | 
			
		||||
                            + tablePrefix
 | 
			
		||||
                            + "users SET lastlogin = " + 0
 | 
			
		||||
                            + " WHERE id = " + id);
 | 
			
		||||
                    DatabaseManager.write("UPDATE "
 | 
			
		||||
                    SQLDatabaseManager.write("UPDATE "
 | 
			
		||||
                            + tablePrefix
 | 
			
		||||
                            + "skills SET "
 | 
			
		||||
                            + "  taming = taming+" + StringUtils.getInt(taming)
 | 
			
		||||
@@ -186,7 +186,7 @@ public class SQLConversionTask extends BukkitRunnable {
 | 
			
		||||
                            + ", acrobatics = acrobatics+" + StringUtils.getInt(acrobatics)
 | 
			
		||||
                            + ", fishing = fishing+" + StringUtils.getInt(fishing)
 | 
			
		||||
                            + " WHERE user_id = " + id);
 | 
			
		||||
                    DatabaseManager.write("UPDATE "
 | 
			
		||||
                    SQLDatabaseManager.write("UPDATE "
 | 
			
		||||
                            + tablePrefix
 | 
			
		||||
                            + "experience SET "
 | 
			
		||||
                            + "  taming = " + StringUtils.getInt(tamingXP)
 | 
			
		||||
@@ -207,24 +207,24 @@ public class SQLConversionTask extends BukkitRunnable {
 | 
			
		||||
                    theCount++;
 | 
			
		||||
 | 
			
		||||
                    // Create the user in the DB
 | 
			
		||||
                    DatabaseManager.write("INSERT INTO "
 | 
			
		||||
                    SQLDatabaseManager.write("INSERT INTO "
 | 
			
		||||
                            + tablePrefix
 | 
			
		||||
                            + "users (user, lastlogin) VALUES ('"
 | 
			
		||||
                            + playerName + "',"
 | 
			
		||||
                            + System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR + ")");
 | 
			
		||||
                    id = DatabaseManager.getInt("SELECT id FROM "
 | 
			
		||||
                    id = SQLDatabaseManager.getInt("SELECT id FROM "
 | 
			
		||||
                            + tablePrefix
 | 
			
		||||
                            + "users WHERE user = '"
 | 
			
		||||
                            + playerName + "'");
 | 
			
		||||
                    DatabaseManager.write("INSERT INTO "
 | 
			
		||||
                    SQLDatabaseManager.write("INSERT INTO "
 | 
			
		||||
                            + tablePrefix
 | 
			
		||||
                            + "skills (user_id) VALUES (" + id + ")");
 | 
			
		||||
                    DatabaseManager.write("INSERT INTO "
 | 
			
		||||
                    SQLDatabaseManager.write("INSERT INTO "
 | 
			
		||||
                            + tablePrefix
 | 
			
		||||
                            + "experience (user_id) VALUES (" + id
 | 
			
		||||
                            + ")");
 | 
			
		||||
                    // Update the skill values
 | 
			
		||||
                    DatabaseManager.write("UPDATE "
 | 
			
		||||
                    SQLDatabaseManager.write("UPDATE "
 | 
			
		||||
                            + tablePrefix
 | 
			
		||||
                            + "users SET lastlogin = " + 0
 | 
			
		||||
                            + " WHERE id = " + id);
 | 
			
		||||
@@ -234,7 +234,7 @@ public class SQLConversionTask extends BukkitRunnable {
 | 
			
		||||
                            + "users SET party = '" + party
 | 
			
		||||
                            + "' WHERE id = " + id);
 | 
			
		||||
                    */
 | 
			
		||||
                    DatabaseManager.write("UPDATE "
 | 
			
		||||
                    SQLDatabaseManager.write("UPDATE "
 | 
			
		||||
                            + tablePrefix
 | 
			
		||||
                            + "skills SET "
 | 
			
		||||
                            + "  taming = taming+" + StringUtils.getInt(taming)
 | 
			
		||||
@@ -250,7 +250,7 @@ public class SQLConversionTask extends BukkitRunnable {
 | 
			
		||||
                            + ", acrobatics = acrobatics+" + StringUtils.getInt(acrobatics)
 | 
			
		||||
                            + ", fishing = fishing+" + StringUtils.getInt(fishing)
 | 
			
		||||
                            + " WHERE user_id = " + id);
 | 
			
		||||
                    DatabaseManager.write("UPDATE "
 | 
			
		||||
                    SQLDatabaseManager.write("UPDATE "
 | 
			
		||||
                            + tablePrefix
 | 
			
		||||
                            + "experience SET "
 | 
			
		||||
                            + "  taming = " + StringUtils.getInt(tamingXP)
 | 
			
		||||
 
 | 
			
		||||
@@ -4,13 +4,13 @@ import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.database.DatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.database.SQLDatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.util.player.UserManager;
 | 
			
		||||
 | 
			
		||||
public class SQLReconnectTask extends BukkitRunnable {
 | 
			
		||||
    @Override
 | 
			
		||||
    public void run() {
 | 
			
		||||
        if (DatabaseManager.checkConnected()) {
 | 
			
		||||
        if (SQLDatabaseManager.checkConnected()) {
 | 
			
		||||
            UserManager.saveAll();  // Save all profiles
 | 
			
		||||
            UserManager.clearAll(); // Clear the profiles
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,26 +2,16 @@ package com.gmail.nossr50.runnables.database;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.mcMMO;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
import com.gmail.nossr50.database.DatabaseManager;
 | 
			
		||||
import com.gmail.nossr50.database.LeaderboardManager;
 | 
			
		||||
 | 
			
		||||
public class UserPurgeTask extends BukkitRunnable {
 | 
			
		||||
    @Override
 | 
			
		||||
    public void run() {
 | 
			
		||||
        if (Config.getInstance().getUseMySQL()) {
 | 
			
		||||
            DatabaseManager.purgePowerlessSQL();
 | 
			
		||||
        mcMMO.databaseManager.purgePowerlessUsers();
 | 
			
		||||
 | 
			
		||||
            if (Config.getInstance().getOldUsersCutoff() != -1) {
 | 
			
		||||
                DatabaseManager.purgeOldSQL();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            LeaderboardManager.purgePowerlessFlatfile();
 | 
			
		||||
 | 
			
		||||
            if (Config.getInstance().getOldUsersCutoff() != -1) {
 | 
			
		||||
                LeaderboardManager.purgeOldFlatfile();
 | 
			
		||||
            }
 | 
			
		||||
        if (Config.getInstance().getOldUsersCutoff() != -1) {
 | 
			
		||||
            mcMMO.databaseManager.purgeOldUsers();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
package com.gmail.nossr50.runnables.player;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 | 
			
		||||
@@ -19,8 +20,10 @@ public class PlayerProfileSaveTask extends BukkitRunnable {
 | 
			
		||||
    public void run() {
 | 
			
		||||
        playerProfile.save();
 | 
			
		||||
 | 
			
		||||
        if (!mcMMOPlayer.getPlayer().isOnline()) {
 | 
			
		||||
            UserManager.remove(playerProfile.getPlayerName());
 | 
			
		||||
        Player player = mcMMOPlayer.getPlayer();
 | 
			
		||||
 | 
			
		||||
        if (!player.isOnline()) {
 | 
			
		||||
            UserManager.remove(player.getName());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
package com.gmail.nossr50.util.player;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
@@ -17,20 +15,6 @@ public final class UserManager {
 | 
			
		||||
 | 
			
		||||
    private UserManager() {};
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Load users.
 | 
			
		||||
     */
 | 
			
		||||
    public static void loadUsers() {
 | 
			
		||||
        new File(mcMMO.getFlatFileDirectory()).mkdir();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            new File(mcMMO.getUsersFilePath()).createNewFile();
 | 
			
		||||
        }
 | 
			
		||||
        catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a new user.
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -48,10 +48,8 @@ public class ZipLibrary {
 | 
			
		||||
 | 
			
		||||
        // Create the Source List, and add directories/etc to the file.
 | 
			
		||||
        List<File> sources = new ArrayList<File>();
 | 
			
		||||
        if (!Config.getInstance().getUseMySQL()) {
 | 
			
		||||
            sources.add(FlatFileDirectory);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        sources.add(FlatFileDirectory);
 | 
			
		||||
        sources.add(ConfigFile);
 | 
			
		||||
        sources.add(TreasuresFile);
 | 
			
		||||
        sources.add(AdvancedConfigFile);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user