Merge branch 'master' of github.com:mcMMO-Dev/mcMMO into configurable

This commit is contained in:
nossr50 2019-06-06 01:58:52 -07:00
commit fc2077ffdb
9 changed files with 95 additions and 34 deletions

View File

@ -161,6 +161,11 @@ Version 2.2.0
Added API method to grab the level cap of a skill by its PrimarySkillType ENUM definition Added API method to grab the level cap of a skill by its PrimarySkillType ENUM definition
Added API method to check if a skill was being level capped Added API method to check if a skill was being level capped
Added 'UndefinedSkillBehaviour' for trying to use a method that has no behaviour defined for the provided skill Added 'UndefinedSkillBehaviour' for trying to use a method that has no behaviour defined for the provided skill
Version 2.1.69
Fixed a few places where mcMMO would not save player data immediately which may cause players to lose a few minutes of progress
A big thanks to Sleepyflea for helping test this patch and report this bug.
Version 2.1.68 Version 2.1.68
Updated Japanese locale (thanks Snake) Updated Japanese locale (thanks Snake)
Fixed a bug where consuming food in the off hand did not trigger the Diet abilities Fixed a bug where consuming food in the off hand did not trigger the Diet abilities

View File

@ -1073,7 +1073,7 @@ public final class ExperienceAPI {
PlayerProfile profile = getOfflineProfile(playerUniqueId); PlayerProfile profile = getOfflineProfile(playerUniqueId);
profile.addXp(skill, XP); profile.addXp(skill, XP);
profile.save(); profile.save(true);
} }
@Deprecated @Deprecated

View File

@ -90,9 +90,10 @@ public class McMMOPlayer {
private Location teleportCommence; private Location teleportCommence;
private boolean isUsingUnarmed; private boolean isUsingUnarmed;
private HashMap<PrimarySkillType, Double> personalXPModifiers; private HashMap<PrimarySkillType, Double> personalXPModifiers;
private String playerName;
public McMMOPlayer(Player player, PlayerProfile profile) { public McMMOPlayer(Player player, PlayerProfile profile) {
String playerName = player.getName(); this.playerName = player.getName();
UUID uuid = player.getUniqueId(); UUID uuid = player.getUniqueId();
this.player = player; this.player = player;
@ -159,6 +160,10 @@ public class McMMOPlayer {
return personalXPModifiers.get(primarySkillType); return personalXPModifiers.get(primarySkillType);
} }
public String getPlayerName() {
return playerName;
}
/*public void hideXpBar(PrimarySkillType primarySkillType) /*public void hideXpBar(PrimarySkillType primarySkillType)
{ {
experienceBarManager.hideExperienceBar(primarySkillType); experienceBarManager.hideExperienceBar(primarySkillType);
@ -1005,7 +1010,7 @@ public class McMMOPlayer {
BleedTimerTask.bleedOut(thisPlayer); BleedTimerTask.bleedOut(thisPlayer);
if (syncSave) { if (syncSave) {
getProfile().save(); getProfile().save(true);
} else { } else {
getProfile().scheduleAsyncSave(); getProfile().scheduleAsyncSave();
} }

View File

@ -85,14 +85,23 @@ public class PlayerProfile {
} }
public void scheduleAsyncSave() { public void scheduleAsyncSave() {
new PlayerProfileSaveTask(this).runTaskAsynchronously(mcMMO.p); new PlayerProfileSaveTask(this, false).runTaskAsynchronously(mcMMO.p);
}
public void scheduleSyncSave() {
new PlayerProfileSaveTask(this, true).runTask(mcMMO.p);
} }
public void scheduleAsyncSaveDelay() { public void scheduleAsyncSaveDelay() {
new PlayerProfileSaveTask(this).runTaskLaterAsynchronously(mcMMO.p, 20); new PlayerProfileSaveTask(this, false).runTaskLaterAsynchronously(mcMMO.p, 20);
} }
public void save() { @Deprecated
public void scheduleSyncSaveDelay() {
new PlayerProfileSaveTask(this, true).runTaskLater(mcMMO.p, 20);
}
public void save(boolean useSync) {
if (!changed || !loaded) { if (!changed || !loaded) {
saveAttempts = 0; saveAttempts = 0;
return; return;
@ -112,7 +121,12 @@ public class PlayerProfile {
if (saveAttempts < 10) { if (saveAttempts < 10) {
saveAttempts++; saveAttempts++;
scheduleAsyncSaveDelay();
if(useSync)
scheduleSyncSave(); //Execute sync saves immediately
else
scheduleAsyncSaveDelay();
return; return;
} else { } else {
mcMMO.p.getLogger().severe("mcMMO has failed to save the profile for " mcMMO.p.getLogger().severe("mcMMO has failed to save the profile for "
@ -121,9 +135,9 @@ public class PlayerProfile {
" Check your console for errors and inspect your DB for issues."); " Check your console for errors and inspect your DB for issues.");
} }
} else {
saveAttempts = 0;
} }
saveAttempts = 0;
} }
public String getPlayerName() { public String getPlayerName() {
@ -135,7 +149,7 @@ public class PlayerProfile {
} }
public void setUniqueId(UUID uuid) { public void setUniqueId(UUID uuid) {
changed = true; markProfileDirty();
this.uuid = uuid; this.uuid = uuid;
} }
@ -153,17 +167,24 @@ public class PlayerProfile {
} }
public void setMobHealthbarType(MobHealthbarType mobHealthbarType) { public void setMobHealthbarType(MobHealthbarType mobHealthbarType) {
changed = true; markProfileDirty();
this.mobHealthbarType = mobHealthbarType; this.mobHealthbarType = mobHealthbarType;
} }
/**
* Marks the profile as "dirty" which flags a profile to be saved in the next save operation
*/
public void markProfileDirty() {
changed = true;
}
public int getScoreboardTipsShown() { public int getScoreboardTipsShown() {
return scoreboardTipsShown; return scoreboardTipsShown;
} }
public void setScoreboardTipsShown(int scoreboardTipsShown) { public void setScoreboardTipsShown(int scoreboardTipsShown) {
changed = true; markProfileDirty();
this.scoreboardTipsShown = scoreboardTipsShown; this.scoreboardTipsShown = scoreboardTipsShown;
} }
@ -181,12 +202,12 @@ public class PlayerProfile {
} }
protected void setChimaeraWingDATS(int DATS) { protected void setChimaeraWingDATS(int DATS) {
changed = true; markProfileDirty();
uniquePlayerData.put(UniqueDataType.CHIMAERA_WING_DATS, DATS); uniquePlayerData.put(UniqueDataType.CHIMAERA_WING_DATS, DATS);
} }
public void setUniqueData(UniqueDataType uniqueDataType, int newData) { public void setUniqueData(UniqueDataType uniqueDataType, int newData) {
changed = true; markProfileDirty();
uniquePlayerData.put(uniqueDataType, newData); uniquePlayerData.put(uniqueDataType, newData);
} }
@ -211,7 +232,7 @@ public class PlayerProfile {
* @param DATS the DATS of the ability * @param DATS the DATS of the ability
*/ */
protected void setAbilityDATS(SuperAbilityType ability, long DATS) { protected void setAbilityDATS(SuperAbilityType ability, long DATS) {
changed = true; markProfileDirty();
abilityDATS.put(ability, (int) (DATS * .001D)); abilityDATS.put(ability, (int) (DATS * .001D));
} }
@ -220,7 +241,7 @@ public class PlayerProfile {
* Reset all ability cooldowns. * Reset all ability cooldowns.
*/ */
protected void resetCooldowns() { protected void resetCooldowns() {
changed = true; markProfileDirty();
for (SuperAbilityType ability : abilityDATS.keySet()) { for (SuperAbilityType ability : abilityDATS.keySet()) {
abilityDATS.put(ability, 0); abilityDATS.put(ability, 0);
@ -248,7 +269,7 @@ public class PlayerProfile {
return; return;
} }
changed = true; markProfileDirty();
skillsXp.put(skill, xpLevel); skillsXp.put(skill, xpLevel);
} }
@ -256,7 +277,7 @@ public class PlayerProfile {
protected double levelUp(PrimarySkillType skill) { protected double levelUp(PrimarySkillType skill) {
double xpRemoved = getXpToLevel(skill); double xpRemoved = getXpToLevel(skill);
changed = true; markProfileDirty();
skills.put(skill, skills.get(skill) + 1); skills.put(skill, skills.get(skill) + 1);
skillsXp.put(skill, skillsXp.get(skill) - xpRemoved); skillsXp.put(skill, skillsXp.get(skill) - xpRemoved);
@ -275,7 +296,7 @@ public class PlayerProfile {
return; return;
} }
changed = true; markProfileDirty();
skillsXp.put(skill, skillsXp.get(skill) - xp); skillsXp.put(skill, skillsXp.get(skill) - xp);
} }
@ -285,7 +306,7 @@ public class PlayerProfile {
return; return;
} }
changed = true; markProfileDirty();
skillsXp.put(skill, skillsXp.get(skill) - xp); skillsXp.put(skill, skillsXp.get(skill) - xp);
} }
@ -301,7 +322,7 @@ public class PlayerProfile {
return; return;
} }
changed = true; markProfileDirty();
//Don't allow levels to be negative //Don't allow levels to be negative
if (level < 0) if (level < 0)
@ -328,7 +349,7 @@ public class PlayerProfile {
* @param xp Number of experience to add * @param xp Number of experience to add
*/ */
public void addXp(PrimarySkillType skill, double xp) { public void addXp(PrimarySkillType skill, double xp) {
changed = true; markProfileDirty();
if (skill.isChildSkill()) { if (skill.isChildSkill()) {
Set<PrimarySkillType> parentSkills = FamilyTree.getParents(skill); Set<PrimarySkillType> parentSkills = FamilyTree.getParents(skill);

View File

@ -492,7 +492,9 @@ public class PlayerListener implements Listener {
} }
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player); McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
mcMMOPlayer.logout(false); //There's an issue with using Async saves on player quit
//Basically there are conditions in which an async task does not execute fast enough to save the data if the server shutdown shortly after this task was scheduled
mcMMOPlayer.logout(true);
} }
/** /**

View File

@ -196,7 +196,6 @@ public class mcMMO extends JavaPlugin {
@Override @Override
public void onDisable() { public void onDisable() {
try { try {
// Alchemy.finishAllBrews(); // Finish all partially complete AlchemyBrewTasks to prevent vanilla brewing continuation on restart
UserManager.saveAll(); // Make sure to save player information if the server shuts down UserManager.saveAll(); // Make sure to save player information if the server shuts down
UserManager.clearAll(); UserManager.clearAll();
PartyManager.saveParties(); // Save our parties PartyManager.saveParties(); // Save our parties

View File

@ -14,7 +14,7 @@ public class SaveTimerTask extends BukkitRunnable {
int count = 1; int count = 1;
for (McMMOPlayer mcMMOPlayer : UserManager.getPlayers()) { for (McMMOPlayer mcMMOPlayer : UserManager.getPlayers()) {
new PlayerProfileSaveTask(mcMMOPlayer.getProfile()).runTaskLaterAsynchronously(mcMMO.p, count); new PlayerProfileSaveTask(mcMMOPlayer.getProfile(), false).runTaskLaterAsynchronously(mcMMO.p, count);
count++; count++;
} }

View File

@ -5,13 +5,15 @@ import org.bukkit.scheduler.BukkitRunnable;
public class PlayerProfileSaveTask extends BukkitRunnable { public class PlayerProfileSaveTask extends BukkitRunnable {
private PlayerProfile playerProfile; private PlayerProfile playerProfile;
private boolean isSync;
public PlayerProfileSaveTask(PlayerProfile playerProfile) { public PlayerProfileSaveTask(PlayerProfile playerProfile, boolean isSync) {
this.playerProfile = playerProfile; this.playerProfile = playerProfile;
this.isSync = isSync;
} }
@Override @Override
public void run() { public void run() {
playerProfile.save(); playerProfile.save(isSync);
} }
} }

View File

@ -11,11 +11,14 @@ import org.bukkit.metadata.FixedMetadataValue;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet;
public final class UserManager { public final class UserManager {
private UserManager() { private UserManager() {
} }
private static HashSet<McMMOPlayer> playerDataSet; //Used to track players for sync saves on shutdown
/** /**
* Track a new user. * Track a new user.
@ -24,6 +27,16 @@ public final class UserManager {
*/ */
public static void track(McMMOPlayer mcMMOPlayer) { public static void track(McMMOPlayer mcMMOPlayer) {
mcMMOPlayer.getPlayer().setMetadata(MetadataConstants.PLAYER_DATA_METAKEY, new FixedMetadataValue(mcMMO.p, mcMMOPlayer)); mcMMOPlayer.getPlayer().setMetadata(MetadataConstants.PLAYER_DATA_METAKEY, new FixedMetadataValue(mcMMO.p, mcMMOPlayer));
if(playerDataSet == null)
playerDataSet = new HashSet<>();
playerDataSet.add(mcMMOPlayer); //for sync saves on shutdown
}
public static void cleanupPlayer(McMMOPlayer mcMMOPlayer) {
if(playerDataSet != null && playerDataSet.contains(mcMMOPlayer))
playerDataSet.remove(mcMMOPlayer);
} }
/** /**
@ -32,7 +45,11 @@ public final class UserManager {
* @param player The Player object * @param player The Player object
*/ */
public static void remove(Player player) { public static void remove(Player player) {
McMMOPlayer mcMMOPlayer = getPlayer(player);
player.removeMetadata(MetadataConstants.PLAYER_DATA_METAKEY, mcMMO.p); player.removeMetadata(MetadataConstants.PLAYER_DATA_METAKEY, mcMMO.p);
if(playerDataSet != null && playerDataSet.contains(mcMMOPlayer))
playerDataSet.remove(mcMMOPlayer); //Clear sync save tracking
} }
/** /**
@ -42,22 +59,32 @@ public final class UserManager {
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) { for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
remove(player); remove(player);
} }
if(playerDataSet != null)
playerDataSet.clear(); //Clear sync save tracking
} }
/** /**
* Save all users ON THIS THREAD. * Save all users ON THIS THREAD.
*/ */
public static void saveAll() { public static void saveAll() {
ImmutableList<Player> onlinePlayers = ImmutableList.copyOf(mcMMO.p.getServer().getOnlinePlayers()); ImmutableList<McMMOPlayer> trackedSyncData = ImmutableList.copyOf(playerDataSet);
mcMMO.p.debug("Saving mcMMOPlayers... (" + onlinePlayers.size() + ")");
for (Player player : onlinePlayers) { mcMMO.p.getLogger().info("Saving mcMMOPlayers... (" + trackedSyncData.size() + ")");
try {
getPlayer(player).getProfile().save(); for (McMMOPlayer playerData : trackedSyncData) {
} catch (Exception e) { try
mcMMO.p.getLogger().warning("Could not save mcMMO player data for player: " + player.getName()); {
mcMMO.p.getLogger().info("Saving data for player: "+playerData.getPlayerName());
playerData.getProfile().save(true);
}
catch (Exception e)
{
mcMMO.p.getLogger().warning("Could not save mcMMO player data for player: " + playerData.getPlayerName());
} }
} }
mcMMO.p.getLogger().info("Finished save operation for "+trackedSyncData.size()+" players!");
} }
public static Collection<McMMOPlayer> getPlayers() { public static Collection<McMMOPlayer> getPlayers() {