From 2f74d53dbeba606dd2cc73cb8be9159df93023da Mon Sep 17 00:00:00 2001 From: Harry5573OP Date: Sun, 18 May 2014 19:22:12 +0100 Subject: [PATCH] Async user loading/saving :D --- .../nossr50/database/DatabaseManager.java | 3 +- .../database/FlatfileDatabaseManager.java | 154 ++++++++-------- .../nossr50/database/SQLDatabaseManager.java | 150 ++++++++-------- .../nossr50/datatypes/player/McMMOPlayer.java | 165 +++++++++++------- .../datatypes/player/PlayerProfile.java | 7 +- .../nossr50/listeners/PlayerListener.java | 8 +- .../gmail/nossr50/skills/alchemy/Alchemy.java | 11 +- 7 files changed, 269 insertions(+), 229 deletions(-) diff --git a/src/main/java/com/gmail/nossr50/database/DatabaseManager.java b/src/main/java/com/gmail/nossr50/database/DatabaseManager.java index 5d99fde64..a065c9864 100644 --- a/src/main/java/com/gmail/nossr50/database/DatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/DatabaseManager.java @@ -37,9 +37,8 @@ public interface DatabaseManager { * Save a user to the database. * * @param profile The profile of the player to save - * @return true if successful, false on failure */ - public boolean saveUser(PlayerProfile profile); + public void saveUser(PlayerProfile profile); /** * Retrieve leaderboard info. diff --git a/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java b/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java index 1dd0e8950..c20db29fd 100644 --- a/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java @@ -206,88 +206,90 @@ public final class FlatfileDatabaseManager implements DatabaseManager { return worked; } - public boolean saveUser(PlayerProfile profile) { - String playerName = profile.getPlayerName(); + public void saveUser(final PlayerProfile profile) { + mcMMO.p.getServer().getScheduler().runTaskAsynchronously(mcMMO.p, new Runnable() { + @Override + public void run() { + String playerName = profile.getPlayerName(); - BufferedReader in = null; - FileWriter out = null; - String usersFilePath = mcMMO.getUsersFilePath(); + BufferedReader in = null; + FileWriter out = null; + String usersFilePath = mcMMO.getUsersFilePath(); - synchronized (fileWritingLock) { - try { - // Open the file - in = new BufferedReader(new FileReader(usersFilePath)); - StringBuilder writer = new StringBuilder(); - String line; + synchronized (fileWritingLock) { + 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.getAbilityDATS(AbilityType.BERSERK)).append(":"); - writer.append((int) profile.getAbilityDATS(AbilityType.GIGA_DRILL_BREAKER)).append(":"); - writer.append((int) profile.getAbilityDATS(AbilityType.TREE_FELLER)).append(":"); - writer.append((int) profile.getAbilityDATS(AbilityType.GREEN_TERRA)).append(":"); - writer.append((int) profile.getAbilityDATS(AbilityType.SERRATED_STRIKES)).append(":"); - writer.append((int) profile.getAbilityDATS(AbilityType.SKULL_SPLITTER)).append(":"); - writer.append((int) profile.getAbilityDATS(AbilityType.SUPER_BREAKER)).append(":"); - writer.append(":"); - writer.append(profile.getSkillLevel(SkillType.FISHING)).append(":"); - writer.append(profile.getSkillXpLevel(SkillType.FISHING)).append(":"); - writer.append((int) profile.getAbilityDATS(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(profile.getSkillLevel(SkillType.ALCHEMY)).append(":"); - writer.append(profile.getSkillXpLevel(SkillType.ALCHEMY)).append(":"); - writer.append("\r\n"); + // 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.getAbilityDATS(AbilityType.BERSERK)).append(":"); + writer.append((int) profile.getAbilityDATS(AbilityType.GIGA_DRILL_BREAKER)).append(":"); + writer.append((int) profile.getAbilityDATS(AbilityType.TREE_FELLER)).append(":"); + writer.append((int) profile.getAbilityDATS(AbilityType.GREEN_TERRA)).append(":"); + writer.append((int) profile.getAbilityDATS(AbilityType.SERRATED_STRIKES)).append(":"); + writer.append((int) profile.getAbilityDATS(AbilityType.SKULL_SPLITTER)).append(":"); + writer.append((int) profile.getAbilityDATS(AbilityType.SUPER_BREAKER)).append(":"); + writer.append(":"); + writer.append(profile.getSkillLevel(SkillType.FISHING)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.FISHING)).append(":"); + writer.append((int) profile.getAbilityDATS(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(profile.getSkillLevel(SkillType.ALCHEMY)).append(":"); + writer.append(profile.getSkillXpLevel(SkillType.ALCHEMY)).append(":"); + writer.append("\r\n"); + } + } + + // Write the new file + out = new FileWriter(usersFilePath); + out.write(writer.toString()); + return; + } catch (Exception e) { + e.printStackTrace(); + return; + } finally { + tryClose(in); + tryClose(out); } } - - // Write the new file - out = new FileWriter(usersFilePath); - out.write(writer.toString()); - return true; } - catch (Exception e) { - e.printStackTrace(); - return false; - } - finally { - tryClose(in); - tryClose(out); - } - } + }); } public List readLeaderboard(SkillType skill, int pageNumber, int statsPerPage) { diff --git a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java index b0eeff586..52e75424f 100644 --- a/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java @@ -115,79 +115,83 @@ public final class SQLDatabaseManager implements DatabaseManager { return success; } - public boolean saveUser(PlayerProfile profile) { + public void saveUser(final PlayerProfile profile) { if (!checkConnected()) { - return false; + return; } - int userId = readId(profile.getPlayerName()); - if (userId == -1) { - newUser(profile.getPlayerName()); - userId = readId(profile.getPlayerName()); - if (userId == -1) { - return false; + mcMMO.p.getServer().getScheduler().runTaskAsynchronously(mcMMO.p, new Runnable() { + @Override + public void run() { + int userId = readId(profile.getPlayerName()); + if (userId == -1) { + newUser(profile.getPlayerName()); + userId = readId(profile.getPlayerName()); + if (userId == -1) { + return; + } + } + MobHealthbarType mobHealthbarType = profile.getMobHealthbarType(); + + saveLogin(userId, ((int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR))); + saveHuds(userId, (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.getAbilityDATS(AbilityType.SUPER_BREAKER), + profile.getAbilityDATS(AbilityType.TREE_FELLER), + profile.getAbilityDATS(AbilityType.BERSERK), + profile.getAbilityDATS(AbilityType.GREEN_TERRA), + profile.getAbilityDATS(AbilityType.GIGA_DRILL_BREAKER), + profile.getAbilityDATS(AbilityType.SERRATED_STRIKES), + profile.getAbilityDATS(AbilityType.SKULL_SPLITTER), + profile.getAbilityDATS(AbilityType.BLAST_MINING)); + saveIntegers( + "UPDATE " + tablePrefix + "skills SET " + + " taming = ?, mining = ?, repair = ?, woodcutting = ?" + + ", unarmed = ?, herbalism = ?, excavation = ?" + + ", archery = ?, swords = ?, axes = ?, acrobatics = ?" + + ", fishing = ?, alchemy = ? 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), + profile.getSkillLevel(SkillType.ALCHEMY), + userId); + saveIntegers( + "UPDATE " + tablePrefix + "experience SET " + + " taming = ?, mining = ?, repair = ?, woodcutting = ?" + + ", unarmed = ?, herbalism = ?, excavation = ?" + + ", archery = ?, swords = ?, axes = ?, acrobatics = ?" + + ", fishing = ?, alchemy = ? 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), + profile.getSkillXpLevel(SkillType.ALCHEMY), + userId); + return; } - } - boolean success = true; - MobHealthbarType mobHealthbarType = profile.getMobHealthbarType(); - - success &= saveLogin(userId, ((int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR))); - success &= saveHuds(userId, (mobHealthbarType == null ? Config.getInstance().getMobHealthbarDefault().toString() : mobHealthbarType.toString())); - success &= saveLongs( - "UPDATE " + tablePrefix + "cooldowns SET " - + " mining = ?, woodcutting = ?, unarmed = ?" - + ", herbalism = ?, excavation = ?, swords = ?" - + ", axes = ?, blast_mining = ? WHERE user_id = ?", - userId, - profile.getAbilityDATS(AbilityType.SUPER_BREAKER), - profile.getAbilityDATS(AbilityType.TREE_FELLER), - profile.getAbilityDATS(AbilityType.BERSERK), - profile.getAbilityDATS(AbilityType.GREEN_TERRA), - profile.getAbilityDATS(AbilityType.GIGA_DRILL_BREAKER), - profile.getAbilityDATS(AbilityType.SERRATED_STRIKES), - profile.getAbilityDATS(AbilityType.SKULL_SPLITTER), - profile.getAbilityDATS(AbilityType.BLAST_MINING)); - success &= saveIntegers( - "UPDATE " + tablePrefix + "skills SET " - + " taming = ?, mining = ?, repair = ?, woodcutting = ?" - + ", unarmed = ?, herbalism = ?, excavation = ?" - + ", archery = ?, swords = ?, axes = ?, acrobatics = ?" - + ", fishing = ?, alchemy = ? 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), - profile.getSkillLevel(SkillType.ALCHEMY), - userId); - success &= saveIntegers( - "UPDATE " + tablePrefix + "experience SET " - + " taming = ?, mining = ?, repair = ?, woodcutting = ?" - + ", unarmed = ?, herbalism = ?, excavation = ?" - + ", archery = ?, swords = ?, axes = ?, acrobatics = ?" - + ", fishing = ?, alchemy = ? 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), - profile.getSkillXpLevel(SkillType.ALCHEMY), - userId); - return success; + }); } public List readLeaderboard(SkillType skill, int pageNumber, int statsPerPage) { @@ -351,7 +355,9 @@ public final class SQLDatabaseManager implements DatabaseManager { return loadPlayerProfile(playerName, create, true); } + private PlayerProfile loadPlayerProfile(String playerName, boolean create, boolean retry) { + if (!checkConnected()) { return new PlayerProfile(playerName, false); // return fake profile if not connected } @@ -458,15 +464,13 @@ public final class SQLDatabaseManager implements DatabaseManager { resultSet.next(); destination.saveUser(loadFromResult(playerName, resultSet)); resultSet.close(); - } - catch (SQLException e) { + } catch (SQLException e) { // Ignore } convertedUsers++; Misc.printProgress(convertedUsers, progressInterval, startMillis); } - } - catch (SQLException e) { + } catch (SQLException e) { printErrors(e); } finally { diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java index e913b649d..032f60f09 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java @@ -1,19 +1,5 @@ package com.gmail.nossr50.datatypes.player; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.bukkit.GameMode; -import org.bukkit.Location; -import org.bukkit.Server; -import org.bukkit.Sound; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.metadata.FixedMetadataValue; -import org.bukkit.scheduler.BukkitRunnable; - -import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.config.AdvancedConfig; import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.experience.ExperienceConfig; @@ -26,6 +12,7 @@ import com.gmail.nossr50.datatypes.skills.SkillType; import com.gmail.nossr50.datatypes.skills.ToolType; import com.gmail.nossr50.datatypes.skills.XPGainReason; import com.gmail.nossr50.locale.LocaleLoader; +import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.party.PartyManager; import com.gmail.nossr50.party.ShareHandler; import com.gmail.nossr50.runnables.skills.AbilityDisableTask; @@ -53,14 +40,27 @@ import com.gmail.nossr50.util.StringUtils; import com.gmail.nossr50.util.skills.ParticleEffectUtils; import com.gmail.nossr50.util.skills.PerksUtils; import com.gmail.nossr50.util.skills.SkillUtils; - +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; import org.apache.commons.lang.Validate; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.scheduler.BukkitRunnable; public class McMMOPlayer { private Player player; - private PlayerProfile profile; + private PlayerProfile playerProfile; - private final Map skillManagers = new HashMap(); + private final ConcurrentHashMap skillManagers = new ConcurrentHashMap(); private Party party; private Party invite; @@ -91,43 +91,80 @@ public class McMMOPlayer { private boolean isUsingUnarmed; private final FixedMetadataValue playerMetadata; - public McMMOPlayer(Player player) { - String playerName = player.getName(); + public interface Callback { + public void done(String playerName, PlayerProfile profile); + } + + public Callback pendingCallback; + + public McMMOPlayer(Player player) { + final String playerName = player.getName(); + this.player = player; playerMetadata = new FixedMetadataValue(mcMMO.p, playerName); - profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName, true); - party = PartyManager.getPlayerParty(playerName); - ptpRecord = new PartyTeleportRecord(); - /* - * I'm using this method because it makes code shorter and safer (we don't have to add all SkillTypes manually), - * but I actually have no idea about the performance impact, if there is any. - * If in the future someone wants to remove this, don't forget to also remove what is in the SkillType enum. - bm01 - */ - try { - for (SkillType skillType : SkillType.values()) { - skillManagers.put(skillType, skillType.getManagerClass().getConstructor(McMMOPlayer.class).newInstance(this)); + //Fake the profile + playerProfile = new PlayerProfile(playerName, false); + + pendingCallback = new Callback() { + public void done(String playerName, PlayerProfile p) { + playerProfile = p; + + party = PartyManager.getPlayerParty(playerName); + ptpRecord = new PartyTeleportRecord(); + + /* + * I'm using this method because it makes code shorter and safer (we don't have to add all SkillTypes manually), + * but I actually have no idea about the performance impact, if there is any. + * If in the future someone wants to remove this, don't forget to also remove what is in the SkillType enum. - bm01 + */ + try { + for (SkillType skillType : SkillType.values()) { + skillManagers.put(skillType, skillType.getManagerClass().getConstructor(McMMOPlayer.class).newInstance(McMMOPlayer.this)); + } + } catch (IllegalAccessException e) { + mcMMO.p.getPluginLoader().disablePlugin(mcMMO.p); + e.printStackTrace(); + } catch (IllegalArgumentException e) { + mcMMO.p.getPluginLoader().disablePlugin(mcMMO.p); + e.printStackTrace(); + } catch (InstantiationException e) { + mcMMO.p.getPluginLoader().disablePlugin(mcMMO.p); + e.printStackTrace(); + } catch (NoSuchMethodException e) { + mcMMO.p.getPluginLoader().disablePlugin(mcMMO.p); + e.printStackTrace(); + } catch (SecurityException e) { + mcMMO.p.getPluginLoader().disablePlugin(mcMMO.p); + e.printStackTrace(); + } catch (InvocationTargetException e) { + mcMMO.p.getPluginLoader().disablePlugin(mcMMO.p); + e.printStackTrace(); + } + + for (AbilityType abilityType : AbilityType.values()) { + abilityMode.put(abilityType, false); + abilityInformed.put(abilityType, true); // This is intended + } + + for (ToolType toolType : ToolType.values()) { + toolMode.put(toolType, false); + } + + if (!playerProfile.isLoaded()) { + mcMMO.p.getLogger().log(Level.WARNING, "Unable to load the PlayerProfile for {0}. Will retry over the next several seconds.", playerName); + new RetryProfileLoadingTask().runTaskTimerAsynchronously(mcMMO.p, 11L, 31L); + } } - } - catch (Exception e) { - e.printStackTrace(); - mcMMO.p.getPluginLoader().disablePlugin(mcMMO.p); - } + }; - for (AbilityType abilityType : AbilityType.values()) { - abilityMode.put(abilityType, false); - abilityInformed.put(abilityType, true); // This is intended - } - - for (ToolType toolType : ToolType.values()) { - toolMode.put(toolType, false); - } - - if (!profile.isLoaded()) { - mcMMO.p.getLogger().warning("Unable to load the PlayerProfile for " + playerName + ". Will retry over the next several seconds."); - new RetryProfileLoadingTask().runTaskTimerAsynchronously(mcMMO.p, 11L, 31L); - } + mcMMO.p.getServer().getScheduler().runTaskAsynchronously(mcMMO.p, new Runnable() { + @Override + public void run() { + pendingCallback.done(playerName, mcMMO.getDatabaseManager().loadPlayerProfile(playerName, true)); + } + }); } private class RetryProfileLoadingTask extends BukkitRunnable { @@ -184,7 +221,7 @@ public class McMMOPlayer { // No database access permitted @Override public void run() { - McMMOPlayer.this.profile = profile; + McMMOPlayer.this.playerProfile = profile; } } @@ -548,7 +585,7 @@ public class McMMOPlayer { break; } - xpRemoved += profile.levelUp(skillType); + xpRemoved += playerProfile.levelUp(skillType); levelsGained++; } @@ -572,7 +609,7 @@ public class McMMOPlayer { } public PlayerProfile getProfile() { - return profile; + return playerProfile; } /* @@ -798,7 +835,7 @@ public class McMMOPlayer { SkillUtils.sendSkillMessage(player, ability.getAbilityPlayer(player)); // Enable the ability - profile.setAbilityDATS(ability, System.currentTimeMillis() + (ticks * Misc.TIME_CONVERSION_FACTOR)); + playerProfile.setAbilityDATS(ability, System.currentTimeMillis() + (ticks * Misc.TIME_CONVERSION_FACTOR)); setAbilityMode(ability, true); if (ability == AbilityType.SUPER_BREAKER || ability == AbilityType.GIGA_DRILL_BREAKER) { @@ -863,7 +900,7 @@ public class McMMOPlayer { * @return the number of seconds remaining before the cooldown expires */ public int calculateTimeRemaining(AbilityType ability) { - long deactivatedTimestamp = profile.getAbilityDATS(ability) * Misc.TIME_CONVERSION_FACTOR; + long deactivatedTimestamp = playerProfile.getAbilityDATS(ability) * Misc.TIME_CONVERSION_FACTOR; return (int) (((deactivatedTimestamp + (PerksUtils.handleCooldownPerks(player, ability.getCooldown()) * Misc.TIME_CONVERSION_FACTOR)) - System.currentTimeMillis()) / Misc.TIME_CONVERSION_FACTOR); } @@ -875,47 +912,47 @@ public class McMMOPlayer { * These functions are wrapped from PlayerProfile so that we don't always have to store it alongside the McMMOPlayer object. */ public int getSkillLevel(SkillType skill) { - return profile.getSkillLevel(skill); + return playerProfile.getSkillLevel(skill); } public float getSkillXpLevelRaw(SkillType skill) { - return profile.getSkillXpLevelRaw(skill); + return playerProfile.getSkillXpLevelRaw(skill); } public int getSkillXpLevel(SkillType skill) { - return profile.getSkillXpLevel(skill); + return playerProfile.getSkillXpLevel(skill); } public void setSkillXpLevel(SkillType skill, float xpLevel) { - profile.setSkillXpLevel(skill, xpLevel); + playerProfile.setSkillXpLevel(skill, xpLevel); } public int getXpToLevel(SkillType skill) { - return profile.getXpToLevel(skill); + return playerProfile.getXpToLevel(skill); } public void removeXp(SkillType skill, int xp) { - profile.removeXp(skill, xp); + playerProfile.removeXp(skill, xp); } public void modifySkill(SkillType skill, int level) { - profile.modifySkill(skill, level); + playerProfile.modifySkill(skill, level); } public void addLevels(SkillType skill, int levels) { - profile.addLevels(skill, levels); + playerProfile.addLevels(skill, levels); } public void addXp(SkillType skill, float xp) { - profile.addXp(skill, xp); + playerProfile.addXp(skill, xp); } public void setAbilityDATS(AbilityType ability, long DATS) { - profile.setAbilityDATS(ability, DATS); + playerProfile.setAbilityDATS(ability, DATS); } public void resetCooldowns() { - profile.resetCooldowns(); + playerProfile.resetCooldowns(); } public FixedMetadataValue getPlayerMetadata() { 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 af1084249..04725fe64 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java @@ -65,11 +65,8 @@ public class PlayerProfile { return; } - changed = !mcMMO.getDatabaseManager().saveUser(new PlayerProfile(playerName, ImmutableMap.copyOf(skills), ImmutableMap.copyOf(skillsXp), ImmutableMap.copyOf(abilityDATS), mobHealthbarType)); - - if (changed) { - mcMMO.p.getLogger().warning("PlayerProfile for " + playerName + " failed to save"); - } + mcMMO.getDatabaseManager().saveUser(new PlayerProfile(playerName, ImmutableMap.copyOf(skills), ImmutableMap.copyOf(skillsXp), ImmutableMap.copyOf(abilityDATS), mobHealthbarType)); + changed = false; } public String getPlayerName() { diff --git a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java index bc67f955e..9e816b729 100644 --- a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java @@ -344,9 +344,9 @@ public class PlayerListener implements Listener { /** * Monitor PlayerQuitEvents. *

- * These events are monitored for the purpose of resetting player - * variables and other garbage collection tasks that must take place when - * a player exits the server. + * These events are monitored for the purpose of resetting player variables + * and other garbage collection tasks that must take place when a player + * exits the server. * * @param event The event to monitor */ @@ -407,7 +407,7 @@ public class PlayerListener implements Listener { } } - /** + /**e * Monitor PlayerRespawnEvents. *

* These events are monitored for the purpose of setting the diff --git a/src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java b/src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java index e992c490f..48fc09002 100644 --- a/src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java +++ b/src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java @@ -1,16 +1,17 @@ package com.gmail.nossr50.skills.alchemy; +import com.gmail.nossr50.config.AdvancedConfig; +import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.runnables.skills.AlchemyBrewTask; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import org.bukkit.Location; -import com.gmail.nossr50.mcMMO; -import com.gmail.nossr50.config.AdvancedConfig; -import com.gmail.nossr50.runnables.skills.AlchemyBrewTask; - public final class Alchemy { public enum Tier { EIGHT(8), @@ -53,7 +54,7 @@ public final class Alchemy { public static double catalysisMinSpeed = AdvancedConfig.getInstance().getCatalysisMinSpeed(); public static double catalysisMaxSpeed = AdvancedConfig.getInstance().getCatalysisMaxSpeed(); - public static Map brewingStandMap = new HashMap(); + public static ConcurrentMap brewingStandMap = new ConcurrentHashMap(); private Alchemy() {}