diff --git a/src/main/java/com/gmail/nossr50/commands/player/MctopCommand.java b/src/main/java/com/gmail/nossr50/commands/player/MctopCommand.java index cc296cfca..d688aa2af 100644 --- a/src/main/java/com/gmail/nossr50/commands/player/MctopCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/player/MctopCommand.java @@ -3,7 +3,6 @@ package com.gmail.nossr50.commands.player; import java.util.ArrayList; import java.util.List; -import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; @@ -12,10 +11,7 @@ import org.bukkit.util.StringUtil; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.config.Config; -import com.gmail.nossr50.database.FlatfileDatabaseManager; -import com.gmail.nossr50.datatypes.database.PlayerStat; import com.gmail.nossr50.datatypes.skills.SkillType; -import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.runnables.commands.MctopCommandAsyncTask; import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.StringUtils; @@ -84,39 +80,11 @@ public class MctopCommand implements TabExecutor { ScoreboardManager.enableGlobalStatsScoreboard((Player) sender, skill, page); } else { - if (Config.getInstance().getUseMySQL()) { - sqlDisplay(page, skill, sender); - } - else { - flatfileDisplay(page, skill, sender); - } + display(page, skill, sender); } } - private void flatfileDisplay(int page, String skill, CommandSender sender) { - FlatfileDatabaseManager.updateLeaderboards(); // Make sure we have the latest information - - if (skill.equalsIgnoreCase("all")) { - sender.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Leaderboard")); - } - else { - sender.sendMessage(LocaleLoader.getString("Commands.Skill.Leaderboard", StringUtils.getCapitalized(skill))); - } - - int position = (page * 10) - 9; - - for (PlayerStat stat : FlatfileDatabaseManager.retrieveInfo(skill, page, 10)) { - String digit = (position < 10) ? "0" : "" + String.valueOf(position); - - // Format: 1. Playername - skill value - sender.sendMessage(digit + ". " + ChatColor.GREEN + stat.name + " - " + ChatColor.WHITE + stat.statVal); - position++; - } - - sender.sendMessage(LocaleLoader.getString("Commands.mctop.Tip")); - } - - private void sqlDisplay(int page, String query, CommandSender sender) { + private void display(int page, String query, CommandSender sender) { new MctopCommandAsyncTask(page, query, sender).runTaskAsynchronously(mcMMO.p); } diff --git a/src/main/java/com/gmail/nossr50/database/DatabaseManager.java b/src/main/java/com/gmail/nossr50/database/DatabaseManager.java index ecf62411c..bbe3ad7e8 100644 --- a/src/main/java/com/gmail/nossr50/database/DatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/DatabaseManager.java @@ -1,63 +1,79 @@ package com.gmail.nossr50.database; -import java.io.File; -import java.io.IOException; +import java.util.List; +import java.util.Map; -import com.gmail.nossr50.mcMMO; -import com.gmail.nossr50.util.Misc; +import com.gmail.nossr50.config.Config; +import com.gmail.nossr50.datatypes.database.PlayerStat; +import com.gmail.nossr50.datatypes.player.PlayerProfile; -public class DatabaseManager { - private final mcMMO plugin; - private final boolean isUsingSQL; - private File usersFile; +public interface DatabaseManager { + public final long PURGE_TIME = 2630000000L * Config.getInstance().getOldUsersCutoff(); - public DatabaseManager(final mcMMO plugin, final boolean isUsingSQL) { - this.plugin = plugin; - this.isUsingSQL = isUsingSQL; + /** + * Purge users with 0 power level from the database. + */ + public void purgePowerlessUsers(); - if (isUsingSQL) { - SQLDatabaseManager.checkConnected(); - SQLDatabaseManager.createStructure(); - } - else { - usersFile = new File(mcMMO.getUsersFilePath()); - createFlatfileDatabase(); - FlatfileDatabaseManager.updateLeaderboards(); - } - } + /** + * Purge users who haven't logged on in over a certain time frame from the database. + */ + public void purgeOldUsers(); - public void purgePowerlessUsers() { - plugin.getLogger().info("Purging powerless users..."); - plugin.getLogger().info("Purged " + (isUsingSQL ? SQLDatabaseManager.purgePowerlessSQL() : FlatfileDatabaseManager.purgePowerlessFlatfile()) + " users from the database."); - } + /** + * Remove a user from the database. + * + * @param playerName The name of the user to remove + * @return true if the user was successfully removed, false otherwise + */ + public boolean removeUser(String playerName); - public void purgeOldUsers() { - plugin.getLogger().info("Purging old users..."); - plugin.getLogger().info("Purged " + (isUsingSQL ? SQLDatabaseManager.purgeOldSQL() : FlatfileDatabaseManager.removeOldFlatfileUsers()) + " users from the database."); - } + /** + * Save a user to the database. + * + * @param profile The profile of the player to save + */ + public void saveUser(PlayerProfile profile); - public boolean removeUser(String playerName) { - if (isUsingSQL ? SQLDatabaseManager.removeUserSQL(playerName) : FlatfileDatabaseManager.removeFlatFileUser(playerName)) { - Misc.profileCleanup(playerName); - return true; - } + /** + * Retrieve leaderboard info. + * + * @param skillName The skill to retrieve info on + * @param pageNumber Which page in the leaderboards to retrieve + * @param statsPerPage The number of stats per page + * @return the requested leaderboard information + */ + public List readLeaderboard(String skillName, int pageNumber, int statsPerPage); - return false; - } + /** + * Retrieve rank info. + * + * @param playerName The name of the user to retrieve the rankings for + * @return the requested rank information + */ + public Map readRank(String playerName); - private void createFlatfileDatabase() { - if (usersFile.exists()) { - return; - } + /** + * Add a new user to the database. + * + * @param playerName The name of the player to be added to the database + */ + public void newUser(String playerName); - usersFile.getParentFile().mkdir(); + /** + * Load a player from the database. + * + * @param playerName The name of the player to load from the database + * @return The player's data + */ + public List loadPlayerData(String playerName); - try { - plugin.debug("Creating mcmmo.users file..."); - new File(mcMMO.getUsersFilePath()).createNewFile(); - } - catch (IOException e) { - e.printStackTrace(); - } - } + /** + * Convert player data to a different storage format. + * + * @param data The player's data + * @return true if the conversion was successful, false otherwise + * @throws Exception + */ + public boolean convert(String[] data) throws Exception; } diff --git a/src/main/java/com/gmail/nossr50/database/DatabaseManagerFactory.java b/src/main/java/com/gmail/nossr50/database/DatabaseManagerFactory.java new file mode 100644 index 000000000..9f9b12ab6 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/database/DatabaseManagerFactory.java @@ -0,0 +1,9 @@ +package com.gmail.nossr50.database; + +import com.gmail.nossr50.config.Config; + +public class DatabaseManagerFactory { + public static DatabaseManager getDatabaseManager() { + return Config.getInstance().getUseMySQL() ? new SQLDatabaseManager() : new FlatfileDatabaseManager(); + } +} diff --git a/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java b/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java index 33d6f2102..c6e202046 100644 --- a/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java @@ -1,6 +1,8 @@ package com.gmail.nossr50.database; import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; @@ -11,26 +13,376 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.bukkit.entity.Player; + import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.config.Config; +import com.gmail.nossr50.datatypes.MobHealthbarType; import com.gmail.nossr50.datatypes.database.PlayerStat; +import com.gmail.nossr50.datatypes.player.McMMOPlayer; +import com.gmail.nossr50.datatypes.player.PlayerProfile; +import com.gmail.nossr50.datatypes.skills.AbilityType; import com.gmail.nossr50.datatypes.skills.SkillType; -import com.gmail.nossr50.util.StringUtils; +import com.gmail.nossr50.datatypes.spout.huds.HudType; +import com.gmail.nossr50.util.Misc; +import com.gmail.nossr50.util.player.UserManager; -public final class FlatfileDatabaseManager { - private static HashMap> playerStatHash = new HashMap>(); - private static List powerLevels = new ArrayList(); - private static long lastUpdate = 0; +public final class FlatfileDatabaseManager implements DatabaseManager { + private final HashMap> playerStatHash = new HashMap>(); + private final List powerLevels = new ArrayList(); + private long lastUpdate = 0; - private static final long UPDATE_WAIT_TIME = 600000L; // 10 minutes - private static final long ONE_MONTH = 2630000000L; + private final long UPDATE_WAIT_TIME = 600000L; // 10 minutes + private final File usersFile; - private FlatfileDatabaseManager() {} + public FlatfileDatabaseManager() { + usersFile = new File(mcMMO.getUsersFilePath()); + createDatabase(); + updateLeaderboards(); + } + + public void purgePowerlessUsers() { + int purgedUsers = 0; + + mcMMO.p.getLogger().info("Purging powerless users..."); + + for (PlayerStat stat : powerLevels) { + if (stat.statVal == 0 && mcMMO.p.getServer().getPlayerExact(stat.name) == null && removeUser(stat.name)) { + purgedUsers++; + } + } + + mcMMO.p.getLogger().info("Purged " + purgedUsers + " users from the database."); + } + + public void purgeOldUsers() { + int removedPlayers = 0; + long currentTime = System.currentTimeMillis(); + + mcMMO.p.getLogger().info("Purging old users..."); + + for (McMMOPlayer mcMMOPlayer : UserManager.getPlayers().values()) { + Player player = mcMMOPlayer.getPlayer(); + + if (currentTime - player.getLastPlayed() > PURGE_TIME && removeUser(player.getName())) { + removedPlayers++; + } + } + + mcMMO.p.getLogger().info("Purged " + removedPlayers + " users from the database."); + } + + public boolean removeUser(String playerName) { + boolean worked = false; + + BufferedReader in = null; + FileWriter out = null; + String usersFilePath = mcMMO.getUsersFilePath(); + + try { + in = new BufferedReader(new FileReader(usersFilePath)); + StringBuilder writer = new StringBuilder(); + String line = ""; + + while ((line = in.readLine()) != null) { + // Write out the same file but when we get to the player we want to remove, we skip his line. + if (!worked && line.split(":")[0].equalsIgnoreCase(playerName)) { + mcMMO.p.getLogger().info("User found, removing..."); + worked = true; + continue; // Skip the player + } + + writer.append(line).append("\r\n"); + } + + out = new FileWriter(usersFilePath); // Write out the new file + out.write(writer.toString()); + } + catch (Exception e) { + mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString()); + } + finally { + if (in != null) { + try { + in.close(); + } + catch (IOException ex) { + ex.printStackTrace(); + } + } + + if (out != null) { + try { + out.close(); + } + catch (IOException ex) { + ex.printStackTrace(); + } + } + } + + Misc.profileCleanup(playerName); + + return worked; + } + + public void saveUser(PlayerProfile profile) { + String playerName = profile.getPlayerName(); + + BufferedReader in = null; + FileWriter out = null; + String usersFilePath = mcMMO.getUsersFilePath(); + + try { + // Open the file + in = new BufferedReader(new FileReader(usersFilePath)); + 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(profile.getSkillLevel(SkillType.MINING)).append(":"); + writer.append(":"); + writer.append(":"); + writer.append(profile.getSkillXpLevel(SkillType.MINING)).append(":"); + writer.append(profile.getSkillLevel(SkillType.WOODCUTTING)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.WOODCUTTING)).append(":"); + writer.append(profile.getSkillLevel(SkillType.REPAIR)).append(":"); + writer.append(profile.getSkillLevel(SkillType.UNARMED)).append(":"); + writer.append(profile.getSkillLevel(SkillType.HERBALISM)).append(":"); + writer.append(profile.getSkillLevel(SkillType.EXCAVATION)).append(":"); + writer.append(profile.getSkillLevel(SkillType.ARCHERY)).append(":"); + writer.append(profile.getSkillLevel(SkillType.SWORDS)).append(":"); + writer.append(profile.getSkillLevel(SkillType.AXES)).append(":"); + writer.append(profile.getSkillLevel(SkillType.ACROBATICS)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.REPAIR)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.UNARMED)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.HERBALISM)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.EXCAVATION)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.ARCHERY)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.SWORDS)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.AXES)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.ACROBATICS)).append(":"); + writer.append(":"); + writer.append(profile.getSkillLevel(SkillType.TAMING)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.TAMING)).append(":"); + writer.append((int) profile.getSkillDATS(AbilityType.BERSERK)).append(":"); + writer.append((int) profile.getSkillDATS(AbilityType.GIGA_DRILL_BREAKER)).append(":"); + writer.append((int) profile.getSkillDATS(AbilityType.TREE_FELLER)).append(":"); + writer.append((int) profile.getSkillDATS(AbilityType.GREEN_TERRA)).append(":"); + writer.append((int) profile.getSkillDATS(AbilityType.SERRATED_STRIKES)).append(":"); + writer.append((int) profile.getSkillDATS(AbilityType.SKULL_SPLITTER)).append(":"); + writer.append((int) profile.getSkillDATS(AbilityType.SUPER_BREAKER)).append(":"); + HudType hudType = profile.getHudType(); + writer.append(hudType == null ? "STANDARD" : hudType.toString()).append(":"); + writer.append(profile.getSkillLevel(SkillType.FISHING)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.FISHING)).append(":"); + writer.append((int) profile.getSkillDATS(AbilityType.BLAST_MINING)).append(":"); + writer.append(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":"); + MobHealthbarType mobHealthbarType = profile.getMobHealthbarType(); + writer.append(mobHealthbarType == null ? Config.getInstance().getMobHealthbarDefault().toString() : mobHealthbarType.toString()).append(":"); + writer.append("\r\n"); + } + } + + // Write the new file + out = new FileWriter(usersFilePath); + out.write(writer.toString()); + } + catch (Exception e) { + e.printStackTrace(); + } + finally { + if (in != null) { + try { + in.close(); + } + catch (IOException ex) { + ex.printStackTrace(); + } + } + + if (out != null) { + try { + out.close(); + } + catch (IOException ex) { + ex.printStackTrace(); + } + } + } + } + + public List readLeaderboard(String skillName, int pageNumber, int statsPerPage) { + updateLeaderboards(); + List statsList = skillName.equalsIgnoreCase("all") ? powerLevels : playerStatHash.get(SkillType.getSkill(skillName)); + int fromIndex = (Math.max(pageNumber, 1) - 1) * statsPerPage; + + return statsList.subList(Math.min(fromIndex, statsList.size()), Math.min(fromIndex + statsPerPage, statsList.size())); + } + + public Map readRank(String playerName) { + updateLeaderboards(); + + Map skills = new HashMap(); + + for (SkillType skill : SkillType.nonChildSkills()) { + skills.put(skill.name(), getPlayerRank(playerName, playerStatHash.get(skill))); + } + + skills.put("ALL", getPlayerRank(playerName, powerLevels)); + + return skills; + } + + public void newUser(String playerName) { + 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("STANDARD").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(Config.getInstance().getMobHealthbarDefault().toString()).append(":"); // Mob Healthbar HUD + + // Add more in the same format as the line above + + out.newLine(); + out.close(); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public List loadPlayerData(String playerName) { + List playerData = new ArrayList(); + 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; + } + + // Skill levels + playerData.add(character[24]); // Taming + playerData.add(character[1]); // Mining + playerData.add(character[7]); // Repair + playerData.add(character[5]); // Woodcutting + playerData.add(character[8]); // Unarmed + playerData.add(character[9]); // Herbalism + playerData.add(character[10]); // Excavation + playerData.add(character[11]); // Archery + playerData.add(character[12]); // Swords + playerData.add(character[13]); // Axes + playerData.add(character[14]); // Acrobatics + playerData.add(character[34]); // Fishing + + // Experience + playerData.add(character[25]); // Taming + playerData.add(character[4]); // Mining + playerData.add(character[15]); // Repair + playerData.add(character[6]); // Woodcutting + playerData.add(character[16]); // Unarmed + playerData.add(character[17]); // Herbalism + playerData.add(character[18]); // Excavation + playerData.add(character[19]); // Archery + playerData.add(character[20]); // Swords + playerData.add(character[21]); // Axes + playerData.add(character[22]); // Acrobatics + playerData.add(character[35]); // Fishing + + // Cooldowns + playerData.add(null); // Taming + playerData.add(character[32]); // SuperBreaker + playerData.add(null); // Repair + playerData.add(character[28]); // Tree Feller + playerData.add(character[26]); // Beserk + playerData.add(character[29]); // Green Terra + playerData.add(character[27]); // Giga Drill Breaker + playerData.add(null); // Archery + playerData.add(character[30]); // Serrated Strikes + playerData.add(character[31]); // Skull Splitter + playerData.add(null); // Acrobatics + playerData.add(character[36]); // Blast Mining + + playerData.add(character.length > 33 ? character[33] : null); // HudType + playerData.add(character.length > 38 ? character[38] : null); // MobHealthBar + } + + in.close(); + } + catch (Exception e) { + e.printStackTrace(); + } + + return playerData; + } + + public boolean convert(String[] character) throws Exception { + // Not implemented + return false; + } + + public boolean checkConnected() { + // Not implemented + return false; + } /** - * Update the leader boards. - */ - public static void updateLeaderboards() { +* Update the leader boards. +*/ + private void updateLeaderboards() { // Only update FFS leaderboards every 10 minutes.. this puts a lot of strain on the server (depending on the size of the database) and should not be done frequently if (System.currentTimeMillis() < lastUpdate + UPDATE_WAIT_TIME) { return; @@ -41,18 +393,18 @@ public final class FlatfileDatabaseManager { powerLevels.clear(); // Clear old values from the power levels // Initialize lists - List mining = new ArrayList(); + List mining = new ArrayList(); List woodcutting = new ArrayList(); - List herbalism = new ArrayList(); - List excavation = new ArrayList(); - List acrobatics = new ArrayList(); - List repair = new ArrayList(); - List swords = new ArrayList(); - List axes = new ArrayList(); - List archery = new ArrayList(); - List unarmed = new ArrayList(); - List taming = new ArrayList(); - List fishing = new ArrayList(); + List herbalism = new ArrayList(); + List excavation = new ArrayList(); + List acrobatics = new ArrayList(); + List repair = new ArrayList(); + List swords = new ArrayList(); + List axes = new ArrayList(); + List archery = new ArrayList(); + List unarmed = new ArrayList(); + List taming = new ArrayList(); + List fishing = new ArrayList(); // Read from the FlatFile database and fill our arrays with information try { @@ -62,7 +414,6 @@ public final class FlatfileDatabaseManager { while ((line = in.readLine()) != null) { String[] data = line.split(":"); - String playerName = data[0]; int powerLevel = 0; @@ -124,160 +475,29 @@ public final class FlatfileDatabaseManager { playerStatHash.put(SkillType.FISHING, fishing); } - /** - * Retrieve leaderboard info. - * - * @param skillType Skill to retrieve info on. - * @param pageNumber Which page in the leaderboards to retrieve - * @return the requested leaderboard information - */ - public static List retrieveInfo(String skillType, int pageNumber, int statsPerPage) { - List statsList = skillType.equalsIgnoreCase("all") ? powerLevels : playerStatHash.get(SkillType.getSkill(skillType)); - int fromIndex = (Math.max(pageNumber, 1) - 1) * statsPerPage; + private void createDatabase() { + if (usersFile.exists()) { + return; + } - return statsList.subList(Math.min(fromIndex, statsList.size()), Math.min(fromIndex + statsPerPage, statsList.size())); - } - - public static boolean removeFlatFileUser(String playerName) { - boolean worked = false; - - BufferedReader in = null; - FileWriter out = null; - String usersFilePath = mcMMO.getUsersFilePath(); + usersFile.getParentFile().mkdir(); try { - FileReader file = new FileReader(usersFilePath); - in = new BufferedReader(file); - StringBuilder writer = new StringBuilder(); - String line = ""; - - while ((line = in.readLine()) != null) { - - // Write out the same file but when we get to the player we want to remove, we skip his line. - if (!line.split(":")[0].equalsIgnoreCase(playerName)) { - writer.append(line).append("\r\n"); - } - else { - mcMMO.p.getLogger().info("User found, removing..."); - worked = true; - continue; // Skip the player - } - } - - out = new FileWriter(usersFilePath); // Write out the new file - out.write(writer.toString()); + mcMMO.p.debug("Creating mcmmo.users file..."); + new File(mcMMO.getUsersFilePath()).createNewFile(); } - catch (Exception e) { - mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString()); + catch (IOException e) { + e.printStackTrace(); } - finally { - if (in != null) { - try { - in.close(); - } - catch (IOException ex) { - ex.printStackTrace(); - } - } - - if (out != null) { - try { - out.close(); - } - catch (IOException ex) { - ex.printStackTrace(); - } - } - } - - return worked; } - public static int purgePowerlessFlatfile() { - mcMMO.p.getLogger().info("Purging powerless users..."); - - int purgedUsers = 0; - - for (PlayerStat stat : powerLevels) { - if (stat.statVal == 0 && !mcMMO.p.getServer().getOfflinePlayer(stat.name).isOnline() && removeFlatFileUser(stat.name)) { - purgedUsers++; - } - } - - return purgedUsers; - } - - public static int removeOldFlatfileUsers() { - int removedPlayers = 0; - long currentTime = System.currentTimeMillis(); - long purgeTime = ONE_MONTH * Config.getInstance().getOldUsersCutoff(); - - BufferedReader in = null; - FileWriter out = null; - String usersFilePath = mcMMO.getUsersFilePath(); - - try { - FileReader file = new FileReader(usersFilePath); - in = new BufferedReader(file); - StringBuilder writer = new StringBuilder(); - String line = ""; - - while ((line = in.readLine()) != null) { - - // Write out the same file but when we get to the player we want to remove, we skip his line. - String[] splitLine = line.split(":"); - - if (splitLine.length > 37) { - if (currentTime - (StringUtils.getLong(line.split(":")[37]) * 1000) <= purgeTime) { - writer.append(line).append("\r\n"); - } - else { - mcMMO.p.getLogger().info("User found, removing..."); - removedPlayers++; - continue; // Skip the player - } - } - else { - writer.append(line).append("\r\n"); - } - } - - out = new FileWriter(usersFilePath); // Write out the new file - out.write(writer.toString()); - } - catch (Exception e) { - mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString()); - } - finally { - if (in != null) { - try { - in.close(); - } - catch (IOException ex) { - ex.printStackTrace(); - } - } - - if (out != null) { - try { - out.close(); - } - catch (IOException ex) { - ex.printStackTrace(); - } - } - } - - return removedPlayers; - } - - private static Integer getPlayerRank(String playerName, List statsList) { - int currentPos = 1; - + private Integer getPlayerRank(String playerName, List statsList) { if (statsList == null) { return null; } + int currentPos = 1; + for (PlayerStat stat : statsList) { if (stat.name.equalsIgnoreCase(playerName)) { return currentPos; @@ -289,36 +509,18 @@ public final class FlatfileDatabaseManager { return null; } - public static Map getPlayerRanks(String playerName) { - updateLeaderboards(); - - Map skills = new HashMap(); - - for (SkillType skill : SkillType.nonChildSkills()) { - skills.put(skill.name(), getPlayerRank(playerName, playerStatHash.get(skill))); + private int loadStat(List statList, String playerName, String[] data, int dataIndex) { + if (data.length <= dataIndex) { + return 0; } - skills.put("ALL", getPlayerRank(playerName, powerLevels)); + int statValue = Integer.parseInt(data[dataIndex]); + statList.add(new PlayerStat(playerName, statValue)); - return skills; + return statValue; } - public static List getPlayerStats(String skillName) { - return (skillName.equalsIgnoreCase("all")) ? powerLevels : playerStatHash.get(SkillType.getSkill(skillName)); - } - - private static int loadStat(List 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 { + private class SkillComparator implements Comparator { @Override public int compare(PlayerStat o1, PlayerStat o2) { return (o2.statVal - o1.statVal); diff --git a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java index 5c9dc55f6..b26d0e21c 100644 --- a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java @@ -8,214 +8,296 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Properties; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.config.Config; +import com.gmail.nossr50.datatypes.MobHealthbarType; import com.gmail.nossr50.datatypes.database.DatabaseUpdateType; +import com.gmail.nossr50.datatypes.database.PlayerStat; +import com.gmail.nossr50.datatypes.player.PlayerProfile; +import com.gmail.nossr50.datatypes.skills.AbilityType; import com.gmail.nossr50.datatypes.skills.SkillType; +import com.gmail.nossr50.datatypes.spout.huds.HudType; import com.gmail.nossr50.runnables.database.SQLReconnectTask; import com.gmail.nossr50.util.Misc; +import com.gmail.nossr50.util.StringUtils; -public final class SQLDatabaseManager { - private static String connectionString; - - private static String tablePrefix = Config.getInstance().getMySQLTablePrefix(); - private static Connection connection = null; +public final class SQLDatabaseManager implements DatabaseManager { + private String connectionString; + private String tablePrefix = Config.getInstance().getMySQLTablePrefix(); + private Connection connection = null; // Scale waiting time by this much per failed attempt - private static final double SCALING_FACTOR = 40; + private final double SCALING_FACTOR = 40.0; // Minimum wait in nanoseconds (default 500ms) - private static final long MIN_WAIT = 500L * 1000000L; + private 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; + private 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; + private final int VALID_TIMEOUT = 3; // When next to try connecting to Database in nanoseconds - private static long nextReconnectTimestamp = 0L; + private long nextReconnectTimestamp = 0L; // How many connection attempts have failed - private static int reconnectAttempt = 0; + private 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!"); - } - } + public SQLDatabaseManager() { + checkConnected(); + createStructure(); } - /** - * 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`)) 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 '" + Config.getInstance().getMobHealthbarDefault() + "'," - + "PRIMARY KEY (`user_id`)) " - + "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`)) " - + "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`)) " - + "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`)) " - + "DEFAULT CHARSET=latin1;"); + public void purgePowerlessUsers() { + mcMMO.p.getLogger().info("Purging powerless users..."); - checkDatabaseStructure(DatabaseUpdateType.FISHING); - checkDatabaseStructure(DatabaseUpdateType.BLAST_MINING); - checkDatabaseStructure(DatabaseUpdateType.INDEX); - checkDatabaseStructure(DatabaseUpdateType.MOB_HEALTHBARS); - checkDatabaseStructure(DatabaseUpdateType.PARTY_NAMES); - checkDatabaseStructure(DatabaseUpdateType.KILL_ORPHANS); + Collection> 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").values(); + + write("DELETE FROM u, e, h, s, c USING " + tablePrefix + "users u " + + "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " + + "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " + + "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " + + "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " + + "WHERE (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"); + + processPurge(usernames); + mcMMO.p.getLogger().info("Purged " + usernames.size() + " 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; - } + public void purgeOldUsers() { + long currentTime = System.currentTimeMillis(); - PreparedStatement statement = null; - try { - statement = connection.prepareStatement(sql); - statement.executeUpdate(); - return true; - } - catch (SQLException ex) { - if (!sql.equalsIgnoreCase("ALTER TABLE `" + tablePrefix + "users` DROP COLUMN `party` ;")) { - printErrors(ex); - } - return false; - } - finally { - if (statement != null) { - try { - statement.close(); - } - catch (SQLException e) { - printErrors(e); - } - } - } + mcMMO.p.getLogger().info("Purging old users..."); + + Collection> usernames = read("SELECT user FROM " + tablePrefix + "users WHERE ((" + currentTime + " - lastlogin * " + Misc.TIME_CONVERSION_FACTOR + ") > " + PURGE_TIME + ")").values(); + + write("DELETE FROM u, e, h, s, c USING " + tablePrefix + "users u " + + "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " + + "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " + + "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " + + "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " + + "WHERE ((" + currentTime + " - lastlogin * " + Misc.TIME_CONVERSION_FACTOR + ") > " + PURGE_TIME + ")"); + + processPurge(usernames); + mcMMO.p.getLogger().info("Purged " + usernames.size() + " users from the database.");; } - public static boolean removeUserSQL(String playerName) { - return SQLDatabaseManager.update("DELETE FROM u, e, h, s, c " + + public boolean removeUser(String playerName) { + boolean success = update("DELETE FROM u, e, h, s, c " + "USING " + tablePrefix + "users u " + "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " + "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " + "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " + "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " + "WHERE u.user = '" + playerName + "'") != 0; + + Misc.profileCleanup(playerName); + + return success; } - /** - * 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; + public void saveUser(PlayerProfile profile) { + int userId = readId(profile.getPlayerName()); + MobHealthbarType mobHealthbarType = profile.getMobHealthbarType(); + HudType hudType = profile.getHudType(); + + saveLogin(userId, ((int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR))); + saveHuds(userId, (hudType == null ? "STANDARD" : hudType.toString()), (mobHealthbarType == null ? Config.getInstance().getMobHealthbarDefault().toString() : mobHealthbarType.toString())); + saveLongs( + "UPDATE " + tablePrefix + "cooldowns SET " + + " mining = ?, woodcutting = ?, unarmed = ?" + + ", herbalism = ?, excavation = ?, swords = ?" + + ", axes = ?, blast_mining = ? WHERE user_id = ?", + userId, + profile.getSkillDATS(AbilityType.SUPER_BREAKER), + profile.getSkillDATS(AbilityType.TREE_FELLER), + profile.getSkillDATS(AbilityType.BERSERK), + profile.getSkillDATS(AbilityType.GREEN_TERRA), + profile.getSkillDATS(AbilityType.GIGA_DRILL_BREAKER), + profile.getSkillDATS(AbilityType.SERRATED_STRIKES), + profile.getSkillDATS(AbilityType.SKULL_SPLITTER), + profile.getSkillDATS(AbilityType.BLAST_MINING)); + saveIntegers( + "UPDATE " + tablePrefix + "skills SET " + + " taming = ?, mining = ?, repair = ?, woodcutting = ?" + + ", unarmed = ?, herbalism = ?, excavation = ?" + + ", archery = ?, swords = ?, axes = ?, acrobatics = ?" + + ", fishing = ? WHERE user_id = ?", + profile.getSkillLevel(SkillType.TAMING), + profile.getSkillLevel(SkillType.MINING), + profile.getSkillLevel(SkillType.REPAIR), + profile.getSkillLevel(SkillType.WOODCUTTING), + profile.getSkillLevel(SkillType.UNARMED), + profile.getSkillLevel(SkillType.HERBALISM), + profile.getSkillLevel(SkillType.EXCAVATION), + profile.getSkillLevel(SkillType.ARCHERY), + profile.getSkillLevel(SkillType.SWORDS), + profile.getSkillLevel(SkillType.AXES), + profile.getSkillLevel(SkillType.ACROBATICS), + profile.getSkillLevel(SkillType.FISHING), + userId); + saveIntegers( + "UPDATE " + tablePrefix + "experience SET " + + " taming = ?, mining = ?, repair = ?, woodcutting = ?" + + ", unarmed = ?, herbalism = ?, excavation = ?" + + ", archery = ?, swords = ?, axes = ?, acrobatics = ?" + + ", fishing = ? WHERE user_id = ?", + profile.getSkillXpLevel(SkillType.TAMING), + profile.getSkillXpLevel(SkillType.MINING), + profile.getSkillXpLevel(SkillType.REPAIR), + profile.getSkillXpLevel(SkillType.WOODCUTTING), + profile.getSkillXpLevel(SkillType.UNARMED), + profile.getSkillXpLevel(SkillType.HERBALISM), + profile.getSkillXpLevel(SkillType.EXCAVATION), + profile.getSkillXpLevel(SkillType.ARCHERY), + profile.getSkillXpLevel(SkillType.SWORDS), + profile.getSkillXpLevel(SkillType.AXES), + profile.getSkillXpLevel(SkillType.ACROBATICS), + profile.getSkillXpLevel(SkillType.FISHING), + userId); + } + + public List readLeaderboard(String skillName, int pageNumber, int statsPerPage) { + List stats = new ArrayList(); + + if (checkConnected()) { + String query = skillName.equalsIgnoreCase("ALL") ? "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing" : skillName; + ResultSet resultSet = null; + PreparedStatement statement = null; + + try { + statement = connection.prepareStatement("SELECT " + query + ", user, NOW() FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 ORDER BY " + query + " DESC, user LIMIT ?, ?"); + statement.setInt(1, (pageNumber * statsPerPage) - statsPerPage); + statement.setInt(2, statsPerPage); + resultSet = statement.executeQuery(); + + while (resultSet.next()) { + ArrayList column = new ArrayList(); + + for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) { + column.add(resultSet.getString(i)); + } + + stats.add(new PlayerStat(column.get(1), Integer.valueOf(column.get(0)))); + } + } + catch (SQLException ex) { + printErrors(ex); + } + finally { + if (statement != null) { + try { + statement.close(); + } + catch (SQLException e) { + // Ignore + } + } + } } - int rows = 0; + return stats; + } + public Map readRank(String playerName) { + Map skills = new HashMap(); + + if (checkConnected()) { + ResultSet resultSet; + + try { + for (SkillType skillType : SkillType.nonChildSkills()) { + 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.close(); + + 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"); + + statement.close(); + + 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 void newUser(String playerName) { PreparedStatement statement = null; + try { - statement = connection.prepareStatement(sql); - rows = statement.executeUpdate(); + statement = connection.prepareStatement("INSERT INTO " + tablePrefix + "users (user, lastlogin) VALUES (?, ?)"); + statement.setString(1, playerName); + statement.setLong(2, System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR); + statement.execute(); + + writeMissingRows(readId(playerName)); } catch (SQLException ex) { printErrors(ex); @@ -226,35 +308,46 @@ public final class SQLDatabaseManager { statement.close(); } catch (SQLException e) { - printErrors(e); + // Ignore } } } - - 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; - + public List loadPlayerData(String playerName) { + List playerData = null; PreparedStatement statement = null; try { - statement = connection.prepareStatement(sql); - ResultSet resultSet = statement.executeQuery(); + statement = connection.prepareStatement( + "SELECT " + + "s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, " + + "e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, " + + "c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, " + + "h.hudtype, h.mobhealthbar " + + "FROM " + tablePrefix + "users u " + + "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " + + "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " + + "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " + + "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " + + "WHERE u.user = ?"); + statement.setString(1, playerName); - if (resultSet.next()) { - result = resultSet.getInt(1); + playerData = readRow(statement); + + if (playerData == null || playerData.size() == 0) { + int userId = readId(playerName); + + // Check if user doesn't exist + if (userId == 0) { + return playerData; + } + + // Write missing table rows + writeMissingRows(userId); + + // Re-read data + playerData = loadPlayerData(playerName); } } catch (SQLException ex) { @@ -266,30 +359,128 @@ public final class SQLDatabaseManager { statement.close(); } catch (SQLException e) { - printErrors(e); + // Ignore } } } + return playerData; + } - return result; + public boolean convert(String[] data) throws Exception { + String playerName = data[0]; + + // Check for things we don't want put in the DB + if (playerName == null || playerName.equalsIgnoreCase("null") || playerName.length() > 16) { + return false; + } + + String mining = (data.length > 1) ? data[1] : null; + String woodcutting = (data.length > 5) ? data[5] : null; + String repair = (data.length > 7) ? data[7] : null; + String unarmed = (data.length > 8) ? data[8] : null; + String herbalism = (data.length > 9) ? data[9] : null; + String excavation = (data.length > 10) ? data[10] : null; + String archery = (data.length > 11) ? data[11] : null; + String swords = (data.length > 12) ? data[12] : null; + String axes = (data.length > 13) ? data[13] : null; + String acrobatics = (data.length > 14) ? data[14] : null; + String taming = (data.length > 24) ? data[24] : null; + String fishing = (data.length > 34) ? data[34] : null; + + String miningXP = (data.length > 4) ? data[4] : null; + String woodCuttingXP = (data.length > 6) ? data[6] : null;; + String repairXP = (data.length > 15) ? data[15] : null; + String unarmedXP = (data.length > 16) ? data[16] : null; + String herbalismXP = (data.length > 17) ? data[17] : null; + String excavationXP = (data.length > 18) ? data[18] : null; + String archeryXP = (data.length > 19) ? data[19] : null; + String swordsXP = (data.length > 20) ? data[20] : null; + String axesXP = (data.length > 21) ? data[21] : null; + String acrobaticsXP = (data.length > 22) ? data[22] : null; + String tamingXP = (data.length > 25) ? data[25] : null; + String fishingXP = (data.length > 35) ? data[35] : null; + + String superBreakerCooldown = (data.length > 32) ? data[32] : null; + String treeFellerCooldown = (data.length > 28) ? data[28] : null; + String berserkCooldown = (data.length > 26) ? data[26] : null; + String greenTerraCooldown = (data.length > 29) ? data[29] : null; + String gigaDrillBreakerCooldown = (data.length > 27) ? data[27] : null; + String serratedStrikesCooldown = (data.length > 30) ? data[30] : null; + String skullSplitterCooldown = (data.length > 31) ? data[31] : null; + String blastMiningCooldown = (data.length > 36) ? data[36] : null; + + String hudType = (data.length > 33) ? data[33] : null; + String mobHealthbarType = (data.length > 38 ? data[38] : null); + long lastLogin = mcMMO.p.getServer().getOfflinePlayer(playerName).getLastPlayed(); + + int id = readId(playerName); // Check to see if the user is in the DB + + // Create the user if they don't exist + if (id == 0) { + newUser(playerName); + id = readId(playerName); + } + + saveLogin(id, lastLogin); + saveIntegers( + "UPDATE " + tablePrefix + "skills SET " + + " taming = ?, mining = ?, repair = ?, woodcutting = ?" + + ", unarmed = ?, herbalism = ?, excavation = ?" + + ", archery = ?, swords = ?, axes = ?, acrobatics = ?" + + ", fishing = ? WHERE user_id = ?", + StringUtils.getInt(taming), StringUtils.getInt(mining), + StringUtils.getInt(repair), StringUtils.getInt(woodcutting), + StringUtils.getInt(unarmed), StringUtils.getInt(herbalism), + StringUtils.getInt(excavation), StringUtils.getInt(archery), + StringUtils.getInt(swords), StringUtils.getInt(axes), + StringUtils.getInt(acrobatics), StringUtils.getInt(fishing), + id); + saveIntegers( + "UPDATE " + tablePrefix + "experience SET " + + " taming = ?, mining = ?, repair = ?, woodcutting = ?" + + ", unarmed = ?, herbalism = ?, excavation = ?" + + ", archery = ?, swords = ?, axes = ?, acrobatics = ?" + + ", fishing = ? WHERE user_id = ?", + StringUtils.getInt(tamingXP), StringUtils.getInt(miningXP), + StringUtils.getInt(repairXP), StringUtils.getInt(woodCuttingXP), + StringUtils.getInt(unarmedXP), StringUtils.getInt(herbalismXP), + StringUtils.getInt(excavationXP), StringUtils.getInt(archeryXP), + StringUtils.getInt(swordsXP), StringUtils.getInt(axesXP), + StringUtils.getInt(acrobaticsXP), StringUtils.getInt(fishingXP), + id); + saveLongs( + "UPDATE " + tablePrefix + "cooldowns SET " + + " taming = ?, mining = ?, repair = ?, woodcutting = ?" + + ", unarmed = ?, herbalism = ?, excavation = ?" + + ", archery = ?, swords = ?, axes = ?, acrobatics = ?" + + ", blast_mining = ? WHERE user_id = ?", + id, + StringUtils.getLong(null), StringUtils.getLong(superBreakerCooldown), + StringUtils.getLong(null), StringUtils.getInt(treeFellerCooldown), + StringUtils.getLong(berserkCooldown), StringUtils.getLong(greenTerraCooldown), + StringUtils.getLong(gigaDrillBreakerCooldown), StringUtils.getLong(null), + StringUtils.getLong(serratedStrikesCooldown), StringUtils.getLong(skullSplitterCooldown), + StringUtils.getLong(null), StringUtils.getLong(blastMiningCooldown)); + saveHuds(id, hudType, mobHealthbarType); + return true; } /** - * 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() { + * 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 attempting a database connection each + * time McMMO needs the database. + * + * @return the boolean value for whether or not we are connected + */ + public boolean checkConnected() { boolean isClosed = true; boolean isValid = false; boolean exists = (connection != null); @@ -360,188 +551,131 @@ public final class SQLDatabaseManager { } reconnectAttempt++; - nextReconnectTimestamp = (long)(System.nanoTime() + Math.min(MAX_WAIT, (reconnectAttempt * SCALING_FACTOR * MIN_WAIT))); + 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> read(String sql) { - ResultSet resultSet; - HashMap> rows = new HashMap>(); + * Attempt to connect to the mySQL database. + */ + private void connect() { + connectionString = "jdbc:mysql://" + Config.getInstance().getMySQLServerName() + ":" + Config.getInstance().getMySQLServerPort() + "/" + Config.getInstance().getMySQLDatabaseName(); - if (checkConnected()) { - PreparedStatement statement = null; + try { + mcMMO.p.getLogger().info("Attempting connection to MySQL..."); - try { - statement = connection.prepareStatement(sql); - resultSet = statement.executeQuery(); + // Force driver to load if not yet loaded + Class.forName("com.mysql.jdbc.Driver"); + Properties connectionProperties = new Properties(); + connectionProperties.put("user", Config.getInstance().getMySQLUserName()); + connectionProperties.put("password", Config.getInstance().getMySQLUserPassword()); + connectionProperties.put("autoReconnect", "false"); + connectionProperties.put("maxReconnects", "0"); + connection = DriverManager.getConnection(connectionString, connectionProperties); - while (resultSet.next()) { - ArrayList column = new ArrayList(); + mcMMO.p.getLogger().info("Connection to MySQL was a success!"); + } + catch (SQLException ex) { + connection = null; - 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); - } - } + if (reconnectAttempt == 0 || reconnectAttempt >= 11) { + mcMMO.p.getLogger().info("Connection to MySQL failed!"); } } + catch (ClassNotFoundException ex) { + connection = null; - return rows; - } - - public static Map readSQLRank(String playerName) { - ResultSet resultSet; - Map skills = new HashMap(); - - if (checkConnected()) { - try { - for (SkillType skillType : SkillType.nonChildSkills()) { - 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); + if (reconnectAttempt == 0 || reconnectAttempt >= 11) { + mcMMO.p.getLogger().info("MySQL database driver not found!"); } } - - return skills; - } - - public static int purgePowerlessSQL() { - HashMap> 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 u, e, h, s, c USING " + tablePrefix + "users u " + - "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " + - "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " + - "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " + - "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " + - "WHERE (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"); - return processPurge(usernames.values()); - } - - public static int purgeOldSQL() { - long currentTime = System.currentTimeMillis(); - long purgeTime = ONE_MONTH * Config.getInstance().getOldUsersCutoff(); - - HashMap> usernames = read("SELECT user FROM " + tablePrefix + "users WHERE ((" + currentTime + " - lastlogin*1000) > " + purgeTime + ")"); - write("DELETE FROM u, e, h, s, c USING " + tablePrefix + "users u " + - "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " + - "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " + - "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " + - "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " + - "WHERE ((" + currentTime + " - lastlogin*1000) > " + purgeTime + ")"); - - return processPurge(usernames.values()); - } - - private static int processPurge(Collection> usernames) { - int purgedUsers = 0; - - for (ArrayList 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> rows = new HashMap>(); + * Attempt to create the database structure. + */ + private 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`)) 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 '" + Config.getInstance().getMobHealthbarDefault() + "'," + + "PRIMARY KEY (`user_id`)) " + + "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`)) " + + "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'," + + "`fishing` int(10) unsigned NOT NULL DEFAULT '0'," + + "PRIMARY KEY (`user_id`)) " + + "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'," + + "`fishing` int(10) unsigned NOT NULL DEFAULT '0'," + + "PRIMARY KEY (`user_id`)) " + + "DEFAULT CHARSET=latin1;"); + + for (DatabaseUpdateType updateType : DatabaseUpdateType.values()) { + checkDatabaseStructure(updateType); + } + } + + /** + * Check database structure for missing values. + * + * @param update Type of data to check updates for + */ + private void checkDatabaseStructure(DatabaseUpdateType update) { + String sql = ""; switch (update) { case BLAST_MINING: - sql = "SELECT * FROM `" + tablePrefix + "cooldowns` ORDER BY `" + tablePrefix + "cooldowns`.`blast_mining` ASC LIMIT 0 , 30"; + sql = "SELECT * FROM `" + tablePrefix + "cooldowns` ORDER BY `" + tablePrefix + "cooldowns`.`blast_mining` ASC LIMIT 0 , 30"; break; case FISHING: - sql = "SELECT * FROM `" + tablePrefix + "experience` ORDER BY `" + tablePrefix + "experience`.`fishing` ASC LIMIT 0 , 30"; + sql = "SELECT * FROM `" + tablePrefix + "experience` ORDER BY `" + tablePrefix + "experience`.`fishing` ASC LIMIT 0 , 30"; break; case INDEX: @@ -563,7 +697,7 @@ public final class SQLDatabaseManager { return; case MOB_HEALTHBARS: - sql = "SELECT * FROM `" + tablePrefix + "huds` ORDER BY `" + tablePrefix + "huds`.`mobhealthbar` ASC LIMIT 0 , 30"; + sql = "SELECT * FROM `" + tablePrefix + "huds` ORDER BY `" + tablePrefix + "huds`.`mobhealthbar` ASC LIMIT 0 , 30"; break; case PARTY_NAMES: @@ -575,26 +709,26 @@ public final class SQLDatabaseManager { write( "DELETE FROM " + tablePrefix + "experience " + "WHERE NOT EXISTS (SELECT * FROM " + - tablePrefix + "users u WHERE " + - tablePrefix + "experience.user_id = u.id);" + tablePrefix + "users u WHERE " + + tablePrefix + "experience.user_id = u.id);" ); write( "DELETE FROM " + tablePrefix + "huds " + "WHERE NOT EXISTS (SELECT * FROM " + - tablePrefix + "users u WHERE " + - tablePrefix + "huds.user_id = u.id);" + tablePrefix + "users u WHERE " + + tablePrefix + "huds.user_id = u.id);" ); write( "DELETE FROM " + tablePrefix + "cooldowns " + "WHERE NOT EXISTS (SELECT * FROM " + - tablePrefix + "users u WHERE " + - tablePrefix + "cooldowns.user_id = u.id);" + tablePrefix + "users u WHERE " + + tablePrefix + "cooldowns.user_id = u.id);" ); write( "DELETE FROM " + tablePrefix + "skills " + "WHERE NOT EXISTS (SELECT * FROM " + - tablePrefix + "users u WHERE " + - tablePrefix + "skills.user_id = u.id);" + tablePrefix + "users u WHERE " + + tablePrefix + "skills.user_id = u.id);" ); return; @@ -602,7 +736,10 @@ public final class SQLDatabaseManager { break; } + ResultSet resultSet = null; + HashMap> rows = new HashMap>(); PreparedStatement statement = null; + try { if (!checkConnected()) { return; @@ -655,9 +792,359 @@ public final class SQLDatabaseManager { } } - private static void printErrors(SQLException ex) { + /** + * Attempt to write the SQL query. + * + * @param sql Query to write. + * @return true if the query was successfully written, false otherwise. + */ + private boolean write(String sql) { + if (!checkConnected()) { + return false; + } + + PreparedStatement statement = null; + try { + statement = connection.prepareStatement(sql); + statement.executeUpdate(); + return true; + } + catch (SQLException ex) { + if (!sql.equalsIgnoreCase("ALTER TABLE `" + tablePrefix + "users` DROP COLUMN `party` ;")) { + printErrors(ex); + } + return false; + } + finally { + if (statement != null) { + try { + statement.close(); + } + catch (SQLException e) { + // Ignore + } + } + } + } + + /** + * 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 + */ + private int update(String sql) { + int rows = 0; + + if (checkConnected()) { + 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) { + // Ignore + } + } + } + } + + return rows; + } + + /** + * Read SQL query. + * + * @param sql SQL query to read + * @return the rows in this SQL query + */ + private HashMap> read(String sql) { + HashMap> rows = new HashMap>(); + + if (checkConnected()) { + PreparedStatement statement = null; + ResultSet resultSet; + + try { + statement = connection.prepareStatement(sql); + resultSet = statement.executeQuery(); + + while (resultSet.next()) { + ArrayList column = new ArrayList(); + + 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) { + // Ignore + } + } + } + } + + return rows; + } + + private ArrayList readRow(PreparedStatement statement) { + ArrayList playerData = new ArrayList(); + + if (checkConnected()) { + ResultSet resultSet = null; + + try { + resultSet = statement.executeQuery(); + + if (resultSet.next()) { + for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) { + playerData.add(resultSet.getString(i)); + } + } + } + catch (SQLException ex) { + printErrors(ex); + } + finally { + if (statement != null) { + try { + statement.close(); + } + catch (SQLException e) { + // Ignore + } + } + } + } + + return playerData; + } + + /** + * Get the Integer. Only return first row / first field. + * + * @param sql SQL query to execute + * @return the value in the first row / first field + */ + private int readInt(PreparedStatement statement) { + int result = 0; + + if (checkConnected()) { + ResultSet resultSet = null; + + try { + 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) { + // Ignore + } + } + } + } + + return result; + } + + private void writeMissingRows(int id) { + PreparedStatement statement = null; + + try { + statement = connection.prepareStatement("INSERT IGNORE INTO " + tablePrefix + "experience (user_id) VALUES (?)"); + statement.setInt(1, id); + statement.execute(); + statement.close(); + + statement = connection.prepareStatement("INSERT IGNORE INTO " + tablePrefix + "skills (user_id) VALUES (?)"); + statement.setInt(1, id); + statement.execute(); + statement.close(); + + statement = connection.prepareStatement("INSERT IGNORE INTO " + tablePrefix + "cooldowns (user_id) VALUES (?)"); + statement.setInt(1, id); + statement.execute(); + statement.close(); + + statement = connection.prepareStatement("INSERT IGNORE INTO " + tablePrefix + "huds (user_id, mobhealthbar) VALUES (? ,'" + Config.getInstance().getMobHealthbarDefault().name() + "')"); + statement.setInt(1, id); + statement.execute(); + statement.close(); + } + catch (SQLException ex) { + printErrors(ex); + } + finally { + if (statement != null) { + try { + statement.close(); + } + catch (SQLException e) { + // Ignore + } + } + } + } + + private void processPurge(Collection> usernames) { + for (ArrayList user : usernames) { + Misc.profileCleanup(user.get(0)); + } + } + + private void saveIntegers(String sql, int... args) { + PreparedStatement statement = null; + + try { + statement = connection.prepareStatement(sql); + int i = 1; + + for (int arg : args) { + statement.setInt(i++, arg); + } + + statement.execute(); + } + catch (SQLException ex) { + printErrors(ex); + } + finally { + if (statement != null) { + try { + statement.close(); + } + catch (SQLException e) { + // Ignore + } + } + } + } + + private void saveLongs(String sql, int id, long... args) { + PreparedStatement statement = null; + + try { + statement = connection.prepareStatement(sql); + int i = 1; + + for (long arg : args) { + statement.setLong(i++, arg); + } + + statement.setInt(i++, id); + statement.execute(); + } + catch (SQLException ex) { + printErrors(ex); + } + finally { + if (statement != null) { + try { + statement.close(); + } + catch (SQLException e) { + // Ignore + } + } + } + } + + private int readId(String playerName) { + int id = 0; + + try { + PreparedStatement statement = connection.prepareStatement("SELECT id FROM " + tablePrefix + "users WHERE user = ?"); + statement.setString(1, playerName); + id = readInt(statement); + } + catch (SQLException ex) { + printErrors(ex); + } + + return id; + } + + private void saveLogin(int id, long login) { + PreparedStatement statement = null; + + try { + statement = connection.prepareStatement("UPDATE " + tablePrefix + "users SET lastlogin = ? WHERE id = ?"); + statement.setLong(1, login); + statement.setInt(2, id); + statement.execute(); + } + catch (SQLException ex) { + printErrors(ex); + } + finally { + if (statement != null) { + try { + statement.close(); + } + catch (SQLException e) { + // Ignore + } + } + } + } + + private void saveHuds(int userId, String hudType, String mobHealthBar) { + PreparedStatement statement = null; + + try { + statement = connection.prepareStatement("UPDATE " + tablePrefix + "huds SET hudtype = ?, mobhealthbar = ? WHERE user_id = ?"); + statement.setString(1, hudType); + statement.setString(2, mobHealthBar); + statement.setInt(3, userId); + statement.execute(); + } + catch (SQLException ex) { + printErrors(ex); + } + finally { + if (statement != null) { + try { + statement.close(); + } + catch (SQLException e) { + // Ignore + } + } + } + } + + private 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()); } -} +} \ No newline at end of file diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java index 328e6f8e7..6caa04731 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java @@ -1,11 +1,7 @@ package com.gmail.nossr50.datatypes.player; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.FileReader; -import java.io.FileWriter; -import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; @@ -14,18 +10,15 @@ import org.bukkit.scoreboard.Scoreboard; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.spout.SpoutConfig; -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; 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; public class PlayerProfile { private final String playerName; - private int userId; private boolean loaded; /* HUDs */ @@ -36,7 +29,7 @@ public class PlayerProfile { /* Skill Data */ private final Map skills = new HashMap(); // Skill & Level - private final Map skillsXp = new HashMap(); // Skill & XP + private final Map skillsXp = new HashMap(); // Skill & XP private final Map skillsDATS = new HashMap(); // Ability & Cooldown public PlayerProfile(String playerName, boolean addNew) { @@ -55,18 +48,13 @@ public class PlayerProfile { } if (!loadPlayer() && addNew) { - addPlayer(); + mcMMO.getDatabaseManager().newUser(playerName); loaded = true; } } public void save() { - if (Config.getInstance().getUseMySQL()) { - saveMySQL(); - } - else { - saveFlatfile(); - } + mcMMO.getDatabaseManager().saveUser(this); } public String getPlayerName() { @@ -138,7 +126,7 @@ public class PlayerProfile { /** * Set the current DATS of a skill. * - * @param abilityType Ability to set the DATS for + * @param abilityType Ability to set the DATS for * @param DATS the DATS of the ability */ public void setSkillDATS(AbilityType abilityType, long DATS) { @@ -268,123 +256,60 @@ public class PlayerProfile { } 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(); - - ArrayList playerData = SQLDatabaseManager.read( - "SELECT " + - "u.id, " + - "s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, " + - "e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, " + - "c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, " + - "h.hudtype, h.mobhealthbar " + - "FROM " + tablePrefix + "users u " + - "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " + - "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " + - "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " + - "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " + - "WHERE u.user = '" + playerName + "'" - ).get(1); - - if (playerData == null || playerData.size() == 0) { - userId = SQLDatabaseManager.getInt("SELECT id FROM " + tablePrefix + "users WHERE user = '" + playerName + "'"); - - // Check if user doesn't exist - if (userId == 0) { - return false; - } - - // Write missing table rows - SQLDatabaseManager.write("INSERT IGNORE INTO " + tablePrefix + "skills (user_id) VALUES (" + userId + ")"); - SQLDatabaseManager.write("INSERT IGNORE INTO " + tablePrefix + "experience (user_id) VALUES (" + userId + ")"); - SQLDatabaseManager.write("INSERT IGNORE INTO " + tablePrefix + "cooldowns (user_id) VALUES (" + userId + ")"); - SQLDatabaseManager.write("INSERT IGNORE INTO " + tablePrefix + "huds (user_id, mobhealthbar) VALUES (" + userId + ",'" + mobHealthbarType.name() + "')"); - - // Re-read data - playerData = SQLDatabaseManager.read( - "SELECT " + - "u.id, " + - "s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, " + - "e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, " + - "c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, " + - "h.hudtype, h.mobhealthbar " + - "FROM " + tablePrefix + "users u " + - "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " + - "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " + - "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " + - "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " + - "WHERE u.user = '" + playerName + "'" - ).get(1); - - // Should never happen but just in case - if (playerData == null || playerData.size() == 0) { - return false; - } + List playerData = mcMMO.getDatabaseManager().loadPlayerData(playerName); + + if (playerData == null || playerData.isEmpty()) { + return false; } - userId = Integer.valueOf(playerData.get(0)); + skills.put(SkillType.TAMING, Integer.valueOf(playerData.get(0))); + skills.put(SkillType.MINING, Integer.valueOf(playerData.get(1))); + skills.put(SkillType.REPAIR, Integer.valueOf(playerData.get(2))); + skills.put(SkillType.WOODCUTTING, Integer.valueOf(playerData.get(3))); + skills.put(SkillType.UNARMED, Integer.valueOf(playerData.get(4))); + skills.put(SkillType.HERBALISM, Integer.valueOf(playerData.get(5))); + skills.put(SkillType.EXCAVATION, Integer.valueOf(playerData.get(6))); + skills.put(SkillType.ARCHERY, Integer.valueOf(playerData.get(7))); + skills.put(SkillType.SWORDS, Integer.valueOf(playerData.get(8))); + skills.put(SkillType.AXES, Integer.valueOf(playerData.get(9))); + skills.put(SkillType.ACROBATICS, Integer.valueOf(playerData.get(10))); + skills.put(SkillType.FISHING, Integer.valueOf(playerData.get(11))); - skills.put(SkillType.TAMING, Integer.valueOf(playerData.get(1))); - skills.put(SkillType.MINING, Integer.valueOf(playerData.get(2))); - skills.put(SkillType.REPAIR, Integer.valueOf(playerData.get(3))); - skills.put(SkillType.WOODCUTTING, Integer.valueOf(playerData.get(4))); - skills.put(SkillType.UNARMED, Integer.valueOf(playerData.get(5))); - skills.put(SkillType.HERBALISM, Integer.valueOf(playerData.get(6))); - skills.put(SkillType.EXCAVATION, Integer.valueOf(playerData.get(7))); - skills.put(SkillType.ARCHERY, Integer.valueOf(playerData.get(8))); - skills.put(SkillType.SWORDS, Integer.valueOf(playerData.get(9))); - skills.put(SkillType.AXES, Integer.valueOf(playerData.get(10))); - skills.put(SkillType.ACROBATICS, Integer.valueOf(playerData.get(11))); - skills.put(SkillType.FISHING, Integer.valueOf(playerData.get(12))); + skillsXp.put(SkillType.TAMING, (float) Integer.valueOf(playerData.get(12))); + skillsXp.put(SkillType.MINING, (float) Integer.valueOf(playerData.get(13))); + skillsXp.put(SkillType.REPAIR, (float) Integer.valueOf(playerData.get(14))); + skillsXp.put(SkillType.WOODCUTTING, (float) Integer.valueOf(playerData.get(15))); + skillsXp.put(SkillType.UNARMED, (float) Integer.valueOf(playerData.get(16))); + skillsXp.put(SkillType.HERBALISM, (float) Integer.valueOf(playerData.get(17))); + skillsXp.put(SkillType.EXCAVATION, (float) Integer.valueOf(playerData.get(18))); + skillsXp.put(SkillType.ARCHERY, (float) Integer.valueOf(playerData.get(19))); + skillsXp.put(SkillType.SWORDS, (float) Integer.valueOf(playerData.get(20))); + skillsXp.put(SkillType.AXES, (float) Integer.valueOf(playerData.get(21))); + skillsXp.put(SkillType.ACROBATICS, (float) Integer.valueOf(playerData.get(22))); + skillsXp.put(SkillType.FISHING, (float) Integer.valueOf(playerData.get(23))); - skillsXp.put(SkillType.TAMING, (float) Integer.valueOf(playerData.get(13))); - skillsXp.put(SkillType.MINING, (float) Integer.valueOf(playerData.get(14))); - skillsXp.put(SkillType.REPAIR, (float) Integer.valueOf(playerData.get(15))); - skillsXp.put(SkillType.WOODCUTTING, (float) Integer.valueOf(playerData.get(16))); - skillsXp.put(SkillType.UNARMED, (float) Integer.valueOf(playerData.get(17))); - skillsXp.put(SkillType.HERBALISM, (float) Integer.valueOf(playerData.get(18))); - skillsXp.put(SkillType.EXCAVATION, (float) Integer.valueOf(playerData.get(19))); - skillsXp.put(SkillType.ARCHERY, (float) Integer.valueOf(playerData.get(20))); - skillsXp.put(SkillType.SWORDS, (float) Integer.valueOf(playerData.get(21))); - skillsXp.put(SkillType.AXES, (float) Integer.valueOf(playerData.get(22))); - skillsXp.put(SkillType.ACROBATICS, (float) Integer.valueOf(playerData.get(23))); - skillsXp.put(SkillType.FISHING, (float) Integer.valueOf(playerData.get(24))); - - // Taming 25 - Unused - skillsDATS.put(AbilityType.SUPER_BREAKER, Integer.valueOf(playerData.get(26))); - // Repair 27 - Unused - skillsDATS.put(AbilityType.TREE_FELLER, Integer.valueOf(playerData.get(28))); - skillsDATS.put(AbilityType.BERSERK, Integer.valueOf(playerData.get(29))); - skillsDATS.put(AbilityType.GREEN_TERRA, Integer.valueOf(playerData.get(30))); - skillsDATS.put(AbilityType.GIGA_DRILL_BREAKER, Integer.valueOf(playerData.get(31))); - // Archery 32 - Unused - skillsDATS.put(AbilityType.SERRATED_STRIKES, Integer.valueOf(playerData.get(33))); - skillsDATS.put(AbilityType.SKULL_SPLITTER, Integer.valueOf(playerData.get(34))); - // Acrobatics 35 - Unused - skillsDATS.put(AbilityType.BLAST_MINING, Integer.valueOf(playerData.get(36))); + // Taming 24 - Unused + skillsDATS.put(AbilityType.SUPER_BREAKER, Integer.valueOf(playerData.get(25))); + // Repair 26 - Unused + skillsDATS.put(AbilityType.TREE_FELLER, Integer.valueOf(playerData.get(27))); + skillsDATS.put(AbilityType.BERSERK, Integer.valueOf(playerData.get(28))); + skillsDATS.put(AbilityType.GREEN_TERRA, Integer.valueOf(playerData.get(29))); + skillsDATS.put(AbilityType.GIGA_DRILL_BREAKER, Integer.valueOf(playerData.get(30))); + // Archery 31 - Unused + skillsDATS.put(AbilityType.SERRATED_STRIKES, Integer.valueOf(playerData.get(32))); + skillsDATS.put(AbilityType.SKULL_SPLITTER, Integer.valueOf(playerData.get(33))); + // Acrobatics 34 - Unused + skillsDATS.put(AbilityType.BLAST_MINING, Integer.valueOf(playerData.get(35))); try { - hudType = HudType.valueOf(playerData.get(37)); + hudType = HudType.valueOf(playerData.get(36)); } catch (Exception e) { - // Shouldn't happen unless database is being tampered with - hudType = HudType.STANDARD; + hudType = HudType.STANDARD; // Shouldn't happen unless database is being tampered with } try { - mobHealthbarType = MobHealthbarType.valueOf(playerData.get(38)); + mobHealthbarType = MobHealthbarType.valueOf(playerData.get(37)); } catch (Exception e) { mobHealthbarType = Config.getInstance().getMobHealthbarDefault(); @@ -393,277 +318,4 @@ public class PlayerProfile { 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 == null ? "STANDARD" : 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 == null ? Config.getInstance().getMobHealthbarDefault().toString() : 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 == null ? "STANDARD" : hudType.toString() + "'") - + ", mobhealthbar = '" + (mobHealthbarType == null ? Config.getInstance().getMobHealthbarDefault().toString() : 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 = " + getSkillXpLevel(SkillType.TAMING) - + ", mining = " + getSkillXpLevel(SkillType.MINING) - + ", repair = " + getSkillXpLevel(SkillType.REPAIR) - + ", woodcutting = " + getSkillXpLevel(SkillType.WOODCUTTING) - + ", unarmed = " + getSkillXpLevel(SkillType.UNARMED) - + ", herbalism = " + getSkillXpLevel(SkillType.HERBALISM) - + ", excavation = " + getSkillXpLevel(SkillType.EXCAVATION) - + ", archery = " + getSkillXpLevel(SkillType.ARCHERY) - + ", swords = " + getSkillXpLevel(SkillType.SWORDS) - + ", axes = " + getSkillXpLevel(SkillType.AXES) - + ", acrobatics = " + getSkillXpLevel(SkillType.ACROBATICS) - + ", fishing = " + getSkillXpLevel(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(getSkillXpLevel(SkillType.MINING)).append(":"); - writer.append(skills.get(SkillType.WOODCUTTING)).append(":"); - writer.append(getSkillXpLevel(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(getSkillXpLevel(SkillType.REPAIR)).append(":"); - writer.append(getSkillXpLevel(SkillType.UNARMED)).append(":"); - writer.append(getSkillXpLevel(SkillType.HERBALISM)).append(":"); - writer.append(getSkillXpLevel(SkillType.EXCAVATION)).append(":"); - writer.append(getSkillXpLevel(SkillType.ARCHERY)).append(":"); - writer.append(getSkillXpLevel(SkillType.SWORDS)).append(":"); - writer.append(getSkillXpLevel(SkillType.AXES)).append(":"); - writer.append(getSkillXpLevel(SkillType.ACROBATICS)).append(":"); - writer.append(":"); - writer.append(skills.get(SkillType.TAMING)).append(":"); - writer.append(getSkillXpLevel(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 == null ? "STANDARD" : hudType.toString()).append(":"); - writer.append(skills.get(SkillType.FISHING)).append(":"); - writer.append(getSkillXpLevel(SkillType.FISHING)).append(":"); - writer.append(skillsDATS.get(AbilityType.BLAST_MINING)).append(":"); - writer.append(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":"); - writer.append(mobHealthbarType == null ? Config.getInstance().getMobHealthbarDefault().toString() : 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, (float) 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])); - } - } } diff --git a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java index 5ad6bd38e..d987a2300 100644 --- a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java @@ -21,8 +21,6 @@ import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerFishEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.event.player.PlayerLoginEvent.Result; import org.bukkit.event.player.PlayerPickupItemEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index 989057dc2..e129b2871 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -23,6 +23,7 @@ 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.DatabaseManagerFactory; import com.gmail.nossr50.listeners.BlockListener; import com.gmail.nossr50.listeners.EntityListener; import com.gmail.nossr50.listeners.InventoryListener; @@ -109,7 +110,7 @@ public class mcMMO extends JavaPlugin { combatTagEnabled = getServer().getPluginManager().getPlugin("CombatTag") != null; - databaseManager = new DatabaseManager(this, Config.getInstance().getUseMySQL()); + databaseManager = DatabaseManagerFactory.getDatabaseManager(); registerEvents(); registerCustomRecipes(); @@ -227,12 +228,17 @@ public class mcMMO extends JavaPlugin { return placeStore; } + public static RepairableManager getRepairableManager() { + return repairableManager; + } + public static DatabaseManager getDatabaseManager() { return databaseManager; } - public static RepairableManager getRepairableManager() { - return repairableManager; + @Deprecated + public static void setDatabaseManager(DatabaseManager databaseManager) { + mcMMO.databaseManager = databaseManager; } public static boolean isSpoutEnabled() { diff --git a/src/main/java/com/gmail/nossr50/runnables/commands/McrankCommandAsyncTask.java b/src/main/java/com/gmail/nossr50/runnables/commands/McrankCommandAsyncTask.java index a9df5c3fe..64326e9a2 100644 --- a/src/main/java/com/gmail/nossr50/runnables/commands/McrankCommandAsyncTask.java +++ b/src/main/java/com/gmail/nossr50/runnables/commands/McrankCommandAsyncTask.java @@ -6,9 +6,6 @@ import org.bukkit.command.CommandSender; import org.bukkit.scheduler.BukkitRunnable; import com.gmail.nossr50.mcMMO; -import com.gmail.nossr50.config.Config; -import com.gmail.nossr50.database.FlatfileDatabaseManager; -import com.gmail.nossr50.database.SQLDatabaseManager; public class McrankCommandAsyncTask extends BukkitRunnable { private final String playerName; @@ -21,8 +18,9 @@ public class McrankCommandAsyncTask extends BukkitRunnable { @Override public void run() { - Map skills = Config.getInstance().getUseMySQL() ? SQLDatabaseManager.readSQLRank(playerName) : FlatfileDatabaseManager.getPlayerRanks(playerName); + Map skills = mcMMO.getDatabaseManager().readRank(playerName); new McrankCommandDisplayTask(skills, sender, playerName).runTaskLater(mcMMO.p, 1); } } + diff --git a/src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandAsyncTask.java b/src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandAsyncTask.java index a74757a1b..881c881b8 100644 --- a/src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandAsyncTask.java +++ b/src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandAsyncTask.java @@ -1,31 +1,28 @@ package com.gmail.nossr50.runnables.commands; -import java.util.ArrayList; -import java.util.Collection; +import java.util.List; import org.bukkit.command.CommandSender; import org.bukkit.scheduler.BukkitRunnable; import com.gmail.nossr50.mcMMO; -import com.gmail.nossr50.config.Config; -import com.gmail.nossr50.database.SQLDatabaseManager; +import com.gmail.nossr50.datatypes.database.PlayerStat; public class MctopCommandAsyncTask extends BukkitRunnable { private CommandSender sender; - private String query; + private String skill; private int page; - public MctopCommandAsyncTask(int page, String query, CommandSender sender) { + public MctopCommandAsyncTask(int page, String skill, CommandSender sender) { this.page = page; - this.query = query.equalsIgnoreCase("ALL") ? "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing" : query; + this.skill = skill; this.sender = sender; } @Override public void run() { - String tablePrefix = Config.getInstance().getMySQLTablePrefix(); - final Collection> userStats = 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").values(); + final List userStats = mcMMO.getDatabaseManager().readLeaderboard(skill, page, 10); - new MctopCommandDisplayTask(userStats, page, tablePrefix, sender).runTaskLater(mcMMO.p, 1); + new MctopCommandDisplayTask(userStats, page, skill, sender).runTaskLater(mcMMO.p, 1); } } diff --git a/src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandDisplayTask.java b/src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandDisplayTask.java index d50eba990..07a568d6c 100644 --- a/src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandDisplayTask.java +++ b/src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandDisplayTask.java @@ -1,44 +1,44 @@ package com.gmail.nossr50.runnables.commands; -import java.util.ArrayList; -import java.util.Collection; +import java.util.List; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.scheduler.BukkitRunnable; +import com.gmail.nossr50.datatypes.database.PlayerStat; import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.util.StringUtils; public class MctopCommandDisplayTask extends BukkitRunnable { - private Collection> userStats; + private List userStats; private CommandSender sender; - private String query; + private String skill; private int page; - public MctopCommandDisplayTask(Collection> userStats, int page, String query, CommandSender sender) { + public MctopCommandDisplayTask(List userStats, int page, String skill, CommandSender sender) { this.userStats = userStats; this.page = page; - this.query = query; + this.skill = skill; this.sender = sender; } @Override public void run() { - if (query.equalsIgnoreCase("taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing")) { + if (skill.equalsIgnoreCase("all")) { sender.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Leaderboard")); } else { - sender.sendMessage(LocaleLoader.getString("Commands.Skill.Leaderboard", StringUtils.getCapitalized(query))); + sender.sendMessage(LocaleLoader.getString("Commands.Skill.Leaderboard", StringUtils.getCapitalized(skill))); } int place = (page * 10) - 9; - for (ArrayList stat : userStats) { + for (PlayerStat stat : userStats) { String digit = (place < 10) ? "0" : "" + String.valueOf(place); // Format: 1. Playername - skill value - sender.sendMessage(digit + ". " + ChatColor.GREEN + stat.get(1) + " - " + ChatColor.WHITE + stat.get(0)); + sender.sendMessage(digit + ". " + ChatColor.GREEN + stat.name + " - " + ChatColor.WHITE + stat.statVal); place++; } diff --git a/src/main/java/com/gmail/nossr50/runnables/database/SQLConversionTask.java b/src/main/java/com/gmail/nossr50/runnables/database/SQLConversionTask.java index 57fed6328..722a496cc 100644 --- a/src/main/java/com/gmail/nossr50/runnables/database/SQLConversionTask.java +++ b/src/main/java/com/gmail/nossr50/runnables/database/SQLConversionTask.java @@ -6,270 +6,28 @@ import java.io.FileReader; import org.bukkit.scheduler.BukkitRunnable; import com.gmail.nossr50.mcMMO; -import com.gmail.nossr50.config.Config; -import com.gmail.nossr50.database.SQLDatabaseManager; -import com.gmail.nossr50.util.Misc; -import com.gmail.nossr50.util.StringUtils; public class SQLConversionTask extends BukkitRunnable { - private String tablePrefix = Config.getInstance().getMySQLTablePrefix(); @Override public void run() { String location = mcMMO.getUsersFilePath(); try { - FileReader file = new FileReader(location); - BufferedReader in = new BufferedReader(file); + BufferedReader in = new BufferedReader(new FileReader(location)); String line = ""; - String playerName = null; - String mining = null; - String woodcutting = null; - String repair = null; - String unarmed = null; - String herbalism = null; - String excavation = null; - String archery = null; - String swords = null; - String axes = null; - String acrobatics = null; - String taming = null; - String fishing = null; - String miningXP = null; - String woodCuttingXP = null; - String repairXP = null; - String unarmedXP = null; - String herbalismXP = null; - String excavationXP = null; - String archeryXP = null; - String swordsXP = null; - String axesXP = null; - String acrobaticsXP = null; - String tamingXP = null; - String fishingXP = null; - int id = 0; - int theCount = 0; + int converted = 0; while ((line = in.readLine()) != null) { // Find if the line contains the player we want. - String[] character = line.split(":"); - playerName = character[0]; - - // Check for things we don't want put in the DB - if (playerName == null || playerName.equalsIgnoreCase("null") || playerName.equalsIgnoreCase("#Storage place for user information")) { - continue; - } - - if (character.length > 1) { - mining = character[1]; - } - - if (character.length > 4) { - miningXP = character[4]; - } - - if (character.length > 5) { - woodcutting = character[5]; - } - - if (character.length > 6) { - woodCuttingXP = character[6]; - } - - if (character.length > 7) { - repair = character[7]; - } - - if (character.length > 8) { - unarmed = character[8]; - } - - if (character.length > 9) { - herbalism = character[9]; - } - - if (character.length > 10) { - excavation = character[10]; - } - - if (character.length > 11) { - archery = character[11]; - } - - if (character.length > 12) { - swords = character[12]; - } - - if (character.length > 13) { - axes = character[13]; - } - - if (character.length > 14) { - acrobatics = character[14]; - } - - if (character.length > 15) { - repairXP = character[15]; - } - - if (character.length > 16) { - unarmedXP = character[16]; - } - - if (character.length > 17) { - herbalismXP = character[17]; - } - - if (character.length > 18) { - excavationXP = character[18]; - } - - if (character.length > 19) { - archeryXP = character[19]; - } - - if (character.length > 20) { - swordsXP = character[20]; - } - - if (character.length > 21) { - axesXP = character[21]; - } - - if (character.length > 22) { - acrobaticsXP = character[22]; - } - - if (character.length > 24) { - taming = character[24]; - } - - if (character.length > 25) { - tamingXP = character[25]; - } - - if (character.length > 34) { - fishing = character[34]; - } - - if (character.length > 35) { - fishingXP = character[35]; - } - - // Check to see if the user is in the DB - id = SQLDatabaseManager.getInt("SELECT id FROM " - + tablePrefix - + "users WHERE user = '" + playerName + "'"); - - if (id > 0) { - theCount++; - - // Update the skill values - SQLDatabaseManager.write("UPDATE " - + tablePrefix - + "users SET lastlogin = " + 0 - + " WHERE id = " + id); - SQLDatabaseManager.write("UPDATE " - + tablePrefix - + "skills SET " - + " taming = taming+" + StringUtils.getInt(taming) - + ", mining = mining+" + StringUtils.getInt(mining) - + ", repair = repair+" + StringUtils.getInt(repair) - + ", woodcutting = woodcutting+" + StringUtils.getInt(woodcutting) - + ", unarmed = unarmed+" + StringUtils.getInt(unarmed) - + ", herbalism = herbalism+" + StringUtils.getInt(herbalism) - + ", excavation = excavation+" + StringUtils.getInt(excavation) - + ", archery = archery+" + StringUtils.getInt(archery) - + ", swords = swords+" + StringUtils.getInt(swords) - + ", axes = axes+" + StringUtils.getInt(axes) - + ", acrobatics = acrobatics+" + StringUtils.getInt(acrobatics) - + ", fishing = fishing+" + StringUtils.getInt(fishing) - + " WHERE user_id = " + id); - SQLDatabaseManager.write("UPDATE " - + tablePrefix - + "experience SET " - + " taming = " + StringUtils.getInt(tamingXP) - + ", mining = " + StringUtils.getInt(miningXP) - + ", repair = " + StringUtils.getInt(repairXP) - + ", woodcutting = " + StringUtils.getInt(woodCuttingXP) - + ", unarmed = " + StringUtils.getInt(unarmedXP) - + ", herbalism = " + StringUtils.getInt(herbalismXP) - + ", excavation = " + StringUtils.getInt(excavationXP) - + ", archery = " + StringUtils.getInt(archeryXP) - + ", swords = " + StringUtils.getInt(swordsXP) - + ", axes = " + StringUtils.getInt(axesXP) - + ", acrobatics = " + StringUtils.getInt(acrobaticsXP) - + ", fishing = " + StringUtils.getInt(fishingXP) - + " WHERE user_id = " + id); - } - else { - theCount++; - - // Create the user in the DB - SQLDatabaseManager.write("INSERT INTO " - + tablePrefix - + "users (user, lastlogin) VALUES ('" - + playerName + "'," - + System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR + ")"); - id = SQLDatabaseManager.getInt("SELECT id FROM " - + tablePrefix - + "users WHERE user = '" - + playerName + "'"); - SQLDatabaseManager.write("INSERT INTO " - + tablePrefix - + "skills (user_id) VALUES (" + id + ")"); - SQLDatabaseManager.write("INSERT INTO " - + tablePrefix - + "experience (user_id) VALUES (" + id - + ")"); - // Update the skill values - SQLDatabaseManager.write("UPDATE " - + tablePrefix - + "users SET lastlogin = " + 0 - + " WHERE id = " + id); - /* - Database.write("UPDATE " - + tablePrefix - + "users SET party = '" + party - + "' WHERE id = " + id); - */ - SQLDatabaseManager.write("UPDATE " - + tablePrefix - + "skills SET " - + " taming = taming+" + StringUtils.getInt(taming) - + ", mining = mining+" + StringUtils.getInt(mining) - + ", repair = repair+" + StringUtils.getInt(repair) - + ", woodcutting = woodcutting+" + StringUtils.getInt(woodcutting) - + ", unarmed = unarmed+" + StringUtils.getInt(unarmed) - + ", herbalism = herbalism+" + StringUtils.getInt(herbalism) - + ", excavation = excavation+" + StringUtils.getInt(excavation) - + ", archery = archery+" + StringUtils.getInt(archery) - + ", swords = swords+" + StringUtils.getInt(swords) - + ", axes = axes+" + StringUtils.getInt(axes) - + ", acrobatics = acrobatics+" + StringUtils.getInt(acrobatics) - + ", fishing = fishing+" + StringUtils.getInt(fishing) - + " WHERE user_id = " + id); - SQLDatabaseManager.write("UPDATE " - + tablePrefix - + "experience SET " - + " taming = " + StringUtils.getInt(tamingXP) - + ", mining = " + StringUtils.getInt(miningXP) - + ", repair = " + StringUtils.getInt(repairXP) - + ", woodcutting = " + StringUtils.getInt(woodCuttingXP) - + ", unarmed = " + StringUtils.getInt(unarmedXP) - + ", herbalism = " + StringUtils.getInt(herbalismXP) - + ", excavation = " + StringUtils.getInt(excavationXP) - + ", archery = " + StringUtils.getInt(archeryXP) - + ", swords = " + StringUtils.getInt(swordsXP) - + ", axes = " + StringUtils.getInt(axesXP) - + ", acrobatics = " + StringUtils.getInt(acrobaticsXP) - + ", fishing = " + StringUtils.getInt(fishingXP) - + " WHERE user_id = " + id); + String[] playerData = line.split(":"); + if (mcMMO.getDatabaseManager().convert(playerData)) { + converted++; } } - mcMMO.p.getLogger().info("[mcMMO] MySQL Updated from users file, " + theCount + " items added/updated to MySQL DB"); + mcMMO.p.getLogger().info("MySQL Updated from users file, " + converted + " items added/updated to MySQL DB"); in.close(); } catch (Exception e) { diff --git a/src/main/java/com/gmail/nossr50/runnables/database/SQLReconnectTask.java b/src/main/java/com/gmail/nossr50/runnables/database/SQLReconnectTask.java index 830cc3ea4..d60591d3b 100644 --- a/src/main/java/com/gmail/nossr50/runnables/database/SQLReconnectTask.java +++ b/src/main/java/com/gmail/nossr50/runnables/database/SQLReconnectTask.java @@ -10,7 +10,7 @@ import com.gmail.nossr50.util.player.UserManager; public class SQLReconnectTask extends BukkitRunnable { @Override public void run() { - if (SQLDatabaseManager.checkConnected()) { + if (((SQLDatabaseManager) mcMMO.getDatabaseManager()).checkConnected()) { UserManager.saveAll(); // Save all profiles UserManager.clearAll(); // Clear the profiles diff --git a/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardManager.java b/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardManager.java index f6d0b167d..3d5c8ad15 100644 --- a/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardManager.java +++ b/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardManager.java @@ -1,7 +1,6 @@ package com.gmail.nossr50.util.scoreboards; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -15,8 +14,6 @@ import org.bukkit.scoreboard.Scoreboard; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.config.Config; -import com.gmail.nossr50.database.FlatfileDatabaseManager; -import com.gmail.nossr50.database.SQLDatabaseManager; import com.gmail.nossr50.datatypes.database.PlayerStat; import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.player.PlayerProfile; @@ -199,7 +196,7 @@ public class ScoreboardManager { Server server = mcMMO.p.getServer(); Integer rank; - Map skills = Config.getInstance().getUseMySQL() ? SQLDatabaseManager.readSQLRank(playerName) : FlatfileDatabaseManager.getPlayerRanks(playerName); + Map skills = mcMMO.getDatabaseManager().readRank(playerName); for (SkillType skill : SkillType.nonChildSkills()) { if (!Permissions.skillEnabled(player, skill)) { @@ -226,7 +223,7 @@ public class ScoreboardManager { Server server = mcMMO.p.getServer(); Integer rank; - Map skills = Config.getInstance().getUseMySQL() ? SQLDatabaseManager.readSQLRank(targetName) : FlatfileDatabaseManager.getPlayerRanks(targetName); + Map skills = mcMMO.getDatabaseManager().readRank(targetName); for (SkillType skill : SkillType.nonChildSkills()) { rank = skills.get(skill.name()); @@ -289,33 +286,15 @@ public class ScoreboardManager { String endPosition = String.valueOf(position + 14); Server server = mcMMO.p.getServer(); - if (Config.getInstance().getUseMySQL()) { - String tablePrefix = Config.getInstance().getMySQLTablePrefix(); - String query = (skillName.equalsIgnoreCase("all") ? "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing" : skillName); - final Collection> userStats = 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 " + ((pageNumber * 15) - 15) + ",15").values(); + for (PlayerStat stat : mcMMO.getDatabaseManager().readLeaderboard(skillName, pageNumber, 15)) { + String playerName = stat.name; + playerName = (playerName.equals(player.getName()) ? ChatColor.GOLD : "") + playerName; - for (ArrayList stat : userStats) { - String playerName = stat.get(1); - playerName = (playerName.equals(player.getName()) ? ChatColor.GOLD : "") + playerName; - - if (playerName.length() > 16) { - playerName = playerName.substring(0, 16); - } - - objective.getScore(server.getOfflinePlayer(playerName)).setScore(Integer.valueOf(stat.get(0))); + if (playerName.length() > 16) { + playerName = playerName.substring(0, 16); } - } - else { - for (PlayerStat stat : FlatfileDatabaseManager.retrieveInfo(skillName, pageNumber, 15)) { - String playerName = stat.name; - playerName = (playerName.equals(player.getName()) ? ChatColor.GOLD : "") + playerName; - if (playerName.length() > 16) { - playerName = playerName.substring(0, 16); - } - - objective.getScore(server.getOfflinePlayer(playerName)).setScore(stat.statVal); - } + objective.getScore(server.getOfflinePlayer(playerName)).setScore(stat.statVal); } objective.setDisplayName(objective.getDisplayName() + " (" + startPosition + " - " + endPosition + ")");