Async user loading/saving :D

This commit is contained in:
Harry5573OP 2014-05-18 19:22:12 +01:00
parent ead716ef0d
commit 2f74d53dbe
7 changed files with 269 additions and 229 deletions

View File

@ -37,9 +37,8 @@ public interface DatabaseManager {
* Save a user to the database. * Save a user to the database.
* *
* @param profile The profile of the player to save * @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. * Retrieve leaderboard info.

View File

@ -206,88 +206,90 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
return worked; return worked;
} }
public boolean saveUser(PlayerProfile profile) { public void saveUser(final PlayerProfile profile) {
String playerName = profile.getPlayerName(); mcMMO.p.getServer().getScheduler().runTaskAsynchronously(mcMMO.p, new Runnable() {
@Override
public void run() {
String playerName = profile.getPlayerName();
BufferedReader in = null; BufferedReader in = null;
FileWriter out = null; FileWriter out = null;
String usersFilePath = mcMMO.getUsersFilePath(); String usersFilePath = mcMMO.getUsersFilePath();
synchronized (fileWritingLock) { synchronized (fileWritingLock) {
try { try {
// Open the file // Open the file
in = new BufferedReader(new FileReader(usersFilePath)); in = new BufferedReader(new FileReader(usersFilePath));
StringBuilder writer = new StringBuilder(); StringBuilder writer = new StringBuilder();
String line; String line;
// While not at the end of the file // While not at the end of the file
while ((line = in.readLine()) != null) { while ((line = in.readLine()) != null) {
// Read the line in and copy it to the output it's not the player we want to edit // 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)) { if (!line.split(":")[0].equalsIgnoreCase(playerName)) {
writer.append(line).append("\r\n"); writer.append(line).append("\r\n");
} } else {
else { // Otherwise write the new player information
// Otherwise write the new player information writer.append(playerName).append(":");
writer.append(playerName).append(":"); writer.append(profile.getSkillLevel(SkillType.MINING)).append(":");
writer.append(profile.getSkillLevel(SkillType.MINING)).append(":"); writer.append(":");
writer.append(":"); writer.append(":");
writer.append(":"); writer.append(profile.getSkillXpLevel(SkillType.MINING)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.MINING)).append(":"); writer.append(profile.getSkillLevel(SkillType.WOODCUTTING)).append(":");
writer.append(profile.getSkillLevel(SkillType.WOODCUTTING)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.WOODCUTTING)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.WOODCUTTING)).append(":"); writer.append(profile.getSkillLevel(SkillType.REPAIR)).append(":");
writer.append(profile.getSkillLevel(SkillType.REPAIR)).append(":"); writer.append(profile.getSkillLevel(SkillType.UNARMED)).append(":");
writer.append(profile.getSkillLevel(SkillType.UNARMED)).append(":"); writer.append(profile.getSkillLevel(SkillType.HERBALISM)).append(":");
writer.append(profile.getSkillLevel(SkillType.HERBALISM)).append(":"); writer.append(profile.getSkillLevel(SkillType.EXCAVATION)).append(":");
writer.append(profile.getSkillLevel(SkillType.EXCAVATION)).append(":"); writer.append(profile.getSkillLevel(SkillType.ARCHERY)).append(":");
writer.append(profile.getSkillLevel(SkillType.ARCHERY)).append(":"); writer.append(profile.getSkillLevel(SkillType.SWORDS)).append(":");
writer.append(profile.getSkillLevel(SkillType.SWORDS)).append(":"); writer.append(profile.getSkillLevel(SkillType.AXES)).append(":");
writer.append(profile.getSkillLevel(SkillType.AXES)).append(":"); writer.append(profile.getSkillLevel(SkillType.ACROBATICS)).append(":");
writer.append(profile.getSkillLevel(SkillType.ACROBATICS)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.REPAIR)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.REPAIR)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.UNARMED)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.UNARMED)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.HERBALISM)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.HERBALISM)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.EXCAVATION)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.EXCAVATION)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.ARCHERY)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.ARCHERY)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.SWORDS)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.SWORDS)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.AXES)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.AXES)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.ACROBATICS)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.ACROBATICS)).append(":"); writer.append(":");
writer.append(":"); writer.append(profile.getSkillLevel(SkillType.TAMING)).append(":");
writer.append(profile.getSkillLevel(SkillType.TAMING)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.TAMING)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.TAMING)).append(":"); writer.append((int) profile.getAbilityDATS(AbilityType.BERSERK)).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.GIGA_DRILL_BREAKER)).append(":"); writer.append((int) profile.getAbilityDATS(AbilityType.TREE_FELLER)).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.GREEN_TERRA)).append(":"); writer.append((int) profile.getAbilityDATS(AbilityType.SERRATED_STRIKES)).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.SKULL_SPLITTER)).append(":"); writer.append((int) profile.getAbilityDATS(AbilityType.SUPER_BREAKER)).append(":");
writer.append((int) profile.getAbilityDATS(AbilityType.SUPER_BREAKER)).append(":"); writer.append(":");
writer.append(":"); writer.append(profile.getSkillLevel(SkillType.FISHING)).append(":");
writer.append(profile.getSkillLevel(SkillType.FISHING)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.FISHING)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.FISHING)).append(":"); writer.append((int) profile.getAbilityDATS(AbilityType.BLAST_MINING)).append(":");
writer.append((int) profile.getAbilityDATS(AbilityType.BLAST_MINING)).append(":"); writer.append(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":");
writer.append(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":"); MobHealthbarType mobHealthbarType = profile.getMobHealthbarType();
MobHealthbarType mobHealthbarType = profile.getMobHealthbarType(); writer.append(mobHealthbarType == null ? Config.getInstance().getMobHealthbarDefault().toString() : mobHealthbarType.toString()).append(":");
writer.append(mobHealthbarType == null ? Config.getInstance().getMobHealthbarDefault().toString() : mobHealthbarType.toString()).append(":"); writer.append(profile.getSkillLevel(SkillType.ALCHEMY)).append(":");
writer.append(profile.getSkillLevel(SkillType.ALCHEMY)).append(":"); writer.append(profile.getSkillXpLevel(SkillType.ALCHEMY)).append(":");
writer.append(profile.getSkillXpLevel(SkillType.ALCHEMY)).append(":"); writer.append("\r\n");
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<PlayerStat> readLeaderboard(SkillType skill, int pageNumber, int statsPerPage) { public List<PlayerStat> readLeaderboard(SkillType skill, int pageNumber, int statsPerPage) {

View File

@ -115,79 +115,83 @@ public final class SQLDatabaseManager implements DatabaseManager {
return success; return success;
} }
public boolean saveUser(PlayerProfile profile) { public void saveUser(final PlayerProfile profile) {
if (!checkConnected()) { if (!checkConnected()) {
return false; return;
} }
int userId = readId(profile.getPlayerName()); mcMMO.p.getServer().getScheduler().runTaskAsynchronously(mcMMO.p, new Runnable() {
if (userId == -1) { @Override
newUser(profile.getPlayerName()); public void run() {
userId = readId(profile.getPlayerName()); int userId = readId(profile.getPlayerName());
if (userId == -1) { if (userId == -1) {
return false; 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<PlayerStat> readLeaderboard(SkillType skill, int pageNumber, int statsPerPage) { public List<PlayerStat> readLeaderboard(SkillType skill, int pageNumber, int statsPerPage) {
@ -351,7 +355,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
return loadPlayerProfile(playerName, create, true); return loadPlayerProfile(playerName, create, true);
} }
private PlayerProfile loadPlayerProfile(String playerName, boolean create, boolean retry) { private PlayerProfile loadPlayerProfile(String playerName, boolean create, boolean retry) {
if (!checkConnected()) { if (!checkConnected()) {
return new PlayerProfile(playerName, false); // return fake profile if not connected return new PlayerProfile(playerName, false); // return fake profile if not connected
} }
@ -458,15 +464,13 @@ public final class SQLDatabaseManager implements DatabaseManager {
resultSet.next(); resultSet.next();
destination.saveUser(loadFromResult(playerName, resultSet)); destination.saveUser(loadFromResult(playerName, resultSet));
resultSet.close(); resultSet.close();
} } catch (SQLException e) {
catch (SQLException e) {
// Ignore // Ignore
} }
convertedUsers++; convertedUsers++;
Misc.printProgress(convertedUsers, progressInterval, startMillis); Misc.printProgress(convertedUsers, progressInterval, startMillis);
} }
} } catch (SQLException e) {
catch (SQLException e) {
printErrors(e); printErrors(e);
} }
finally { finally {

View File

@ -1,19 +1,5 @@
package com.gmail.nossr50.datatypes.player; 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.AdvancedConfig;
import com.gmail.nossr50.config.Config; import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig; 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.ToolType;
import com.gmail.nossr50.datatypes.skills.XPGainReason; import com.gmail.nossr50.datatypes.skills.XPGainReason;
import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.party.PartyManager; import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.party.ShareHandler; import com.gmail.nossr50.party.ShareHandler;
import com.gmail.nossr50.runnables.skills.AbilityDisableTask; 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.ParticleEffectUtils;
import com.gmail.nossr50.util.skills.PerksUtils; import com.gmail.nossr50.util.skills.PerksUtils;
import com.gmail.nossr50.util.skills.SkillUtils; 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.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 { public class McMMOPlayer {
private Player player; private Player player;
private PlayerProfile profile; private PlayerProfile playerProfile;
private final Map<SkillType, SkillManager> skillManagers = new HashMap<SkillType, SkillManager>(); private final ConcurrentHashMap<SkillType, SkillManager> skillManagers = new ConcurrentHashMap<SkillType, SkillManager>();
private Party party; private Party party;
private Party invite; private Party invite;
@ -91,43 +91,80 @@ public class McMMOPlayer {
private boolean isUsingUnarmed; private boolean isUsingUnarmed;
private final FixedMetadataValue playerMetadata; private final FixedMetadataValue playerMetadata;
public interface Callback {
public void done(String playerName, PlayerProfile profile);
}
public Callback pendingCallback;
public McMMOPlayer(Player player) { public McMMOPlayer(Player player) {
String playerName = player.getName(); final String playerName = player.getName();
this.player = player; this.player = player;
playerMetadata = new FixedMetadataValue(mcMMO.p, playerName); playerMetadata = new FixedMetadataValue(mcMMO.p, playerName);
profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName, true);
party = PartyManager.getPlayerParty(playerName);
ptpRecord = new PartyTeleportRecord();
/* //Fake the profile
* I'm using this method because it makes code shorter and safer (we don't have to add all SkillTypes manually), playerProfile = new PlayerProfile(playerName, false);
* 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 pendingCallback = new Callback() {
*/ public void done(String playerName, PlayerProfile p) {
try { playerProfile = p;
for (SkillType skillType : SkillType.values()) {
skillManagers.put(skillType, skillType.getManagerClass().getConstructor(McMMOPlayer.class).newInstance(this)); 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()) { mcMMO.p.getServer().getScheduler().runTaskAsynchronously(mcMMO.p, new Runnable() {
abilityMode.put(abilityType, false); @Override
abilityInformed.put(abilityType, true); // This is intended public void run() {
} pendingCallback.done(playerName, mcMMO.getDatabaseManager().loadPlayerProfile(playerName, true));
}
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);
}
} }
private class RetryProfileLoadingTask extends BukkitRunnable { private class RetryProfileLoadingTask extends BukkitRunnable {
@ -184,7 +221,7 @@ public class McMMOPlayer {
// No database access permitted // No database access permitted
@Override @Override
public void run() { public void run() {
McMMOPlayer.this.profile = profile; McMMOPlayer.this.playerProfile = profile;
} }
} }
@ -548,7 +585,7 @@ public class McMMOPlayer {
break; break;
} }
xpRemoved += profile.levelUp(skillType); xpRemoved += playerProfile.levelUp(skillType);
levelsGained++; levelsGained++;
} }
@ -572,7 +609,7 @@ public class McMMOPlayer {
} }
public PlayerProfile getProfile() { public PlayerProfile getProfile() {
return profile; return playerProfile;
} }
/* /*
@ -798,7 +835,7 @@ public class McMMOPlayer {
SkillUtils.sendSkillMessage(player, ability.getAbilityPlayer(player)); SkillUtils.sendSkillMessage(player, ability.getAbilityPlayer(player));
// Enable the ability // 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); setAbilityMode(ability, true);
if (ability == AbilityType.SUPER_BREAKER || ability == AbilityType.GIGA_DRILL_BREAKER) { 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 * @return the number of seconds remaining before the cooldown expires
*/ */
public int calculateTimeRemaining(AbilityType ability) { 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); 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. * 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) { public int getSkillLevel(SkillType skill) {
return profile.getSkillLevel(skill); return playerProfile.getSkillLevel(skill);
} }
public float getSkillXpLevelRaw(SkillType skill) { public float getSkillXpLevelRaw(SkillType skill) {
return profile.getSkillXpLevelRaw(skill); return playerProfile.getSkillXpLevelRaw(skill);
} }
public int getSkillXpLevel(SkillType skill) { public int getSkillXpLevel(SkillType skill) {
return profile.getSkillXpLevel(skill); return playerProfile.getSkillXpLevel(skill);
} }
public void setSkillXpLevel(SkillType skill, float xpLevel) { public void setSkillXpLevel(SkillType skill, float xpLevel) {
profile.setSkillXpLevel(skill, xpLevel); playerProfile.setSkillXpLevel(skill, xpLevel);
} }
public int getXpToLevel(SkillType skill) { public int getXpToLevel(SkillType skill) {
return profile.getXpToLevel(skill); return playerProfile.getXpToLevel(skill);
} }
public void removeXp(SkillType skill, int xp) { public void removeXp(SkillType skill, int xp) {
profile.removeXp(skill, xp); playerProfile.removeXp(skill, xp);
} }
public void modifySkill(SkillType skill, int level) { public void modifySkill(SkillType skill, int level) {
profile.modifySkill(skill, level); playerProfile.modifySkill(skill, level);
} }
public void addLevels(SkillType skill, int levels) { public void addLevels(SkillType skill, int levels) {
profile.addLevels(skill, levels); playerProfile.addLevels(skill, levels);
} }
public void addXp(SkillType skill, float xp) { public void addXp(SkillType skill, float xp) {
profile.addXp(skill, xp); playerProfile.addXp(skill, xp);
} }
public void setAbilityDATS(AbilityType ability, long DATS) { public void setAbilityDATS(AbilityType ability, long DATS) {
profile.setAbilityDATS(ability, DATS); playerProfile.setAbilityDATS(ability, DATS);
} }
public void resetCooldowns() { public void resetCooldowns() {
profile.resetCooldowns(); playerProfile.resetCooldowns();
} }
public FixedMetadataValue getPlayerMetadata() { public FixedMetadataValue getPlayerMetadata() {

View File

@ -65,11 +65,8 @@ public class PlayerProfile {
return; return;
} }
changed = !mcMMO.getDatabaseManager().saveUser(new PlayerProfile(playerName, ImmutableMap.copyOf(skills), ImmutableMap.copyOf(skillsXp), ImmutableMap.copyOf(abilityDATS), mobHealthbarType)); mcMMO.getDatabaseManager().saveUser(new PlayerProfile(playerName, ImmutableMap.copyOf(skills), ImmutableMap.copyOf(skillsXp), ImmutableMap.copyOf(abilityDATS), mobHealthbarType));
changed = false;
if (changed) {
mcMMO.p.getLogger().warning("PlayerProfile for " + playerName + " failed to save");
}
} }
public String getPlayerName() { public String getPlayerName() {

View File

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

View File

@ -1,16 +1,17 @@
package com.gmail.nossr50.skills.alchemy; 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.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.bukkit.Location; 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 final class Alchemy {
public enum Tier { public enum Tier {
EIGHT(8), EIGHT(8),
@ -53,7 +54,7 @@ public final class Alchemy {
public static double catalysisMinSpeed = AdvancedConfig.getInstance().getCatalysisMinSpeed(); public static double catalysisMinSpeed = AdvancedConfig.getInstance().getCatalysisMinSpeed();
public static double catalysisMaxSpeed = AdvancedConfig.getInstance().getCatalysisMaxSpeed(); public static double catalysisMaxSpeed = AdvancedConfig.getInstance().getCatalysisMaxSpeed();
public static Map<Location, AlchemyBrewTask> brewingStandMap = new HashMap<Location, AlchemyBrewTask>(); public static ConcurrentMap<Location, AlchemyBrewTask> brewingStandMap = new ConcurrentHashMap<Location, AlchemyBrewTask>();
private Alchemy() {} private Alchemy() {}