mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-25 06:36:45 +01:00
Merge master 2.1.40
This commit is contained in:
commit
1fe4fef75a
@ -158,6 +158,17 @@ Version 2.2.0
|
|||||||
Added API method to check if player parties are size capped
|
Added API method to check if player parties are size capped
|
||||||
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
|
||||||
|
Version 2.1.40
|
||||||
|
(API) mcMMO will now return null in all cases for UserManager.getPlayerProfile() if they have not been loaded yet
|
||||||
|
(API) Roll stores exploit data in AcrobaticsManager now
|
||||||
|
Added new locale string "Profile.Loading.FailureNotice"
|
||||||
|
Added new locale string "Profile.Loading.FailurePlayer"
|
||||||
|
mcMMO no longer gives up forever if a player profile fails to load and the player is still online
|
||||||
|
mcMMO will attempt to save a profile up to 10 times now, previously it would only try one time.
|
||||||
|
Fixed an ArrayIndexOutOfBounds error with Party Chat
|
||||||
|
Player data for mcMMO is now loaded 3 seconds after a player connects in order to give any ongoing save tasks from other servers a small grace period to finish. This will mostly be useful to Bungee servers.
|
||||||
|
|
||||||
|
NOTES: I received reports from some users saying that saving and loading was failing could fail and not recover, I have implemented some fail safes to greatly reduce the the odds of that happening.
|
||||||
|
|
||||||
Version 2.1.39
|
Version 2.1.39
|
||||||
Salvaging an item should now only play the item break sound (was playing the anvil sound simultaneously before)
|
Salvaging an item should now only play the item break sound (was playing the anvil sound simultaneously before)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.gmail.nossr50.chat;
|
package com.gmail.nossr50.chat;
|
||||||
|
|
||||||
import com.gmail.nossr50.datatypes.party.Party;
|
import com.gmail.nossr50.datatypes.party.Party;
|
||||||
|
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||||
import com.gmail.nossr50.events.chat.McMMOChatEvent;
|
import com.gmail.nossr50.events.chat.McMMOChatEvent;
|
||||||
import com.gmail.nossr50.events.chat.McMMOPartyChatEvent;
|
import com.gmail.nossr50.events.chat.McMMOPartyChatEvent;
|
||||||
import com.gmail.nossr50.locale.LocaleLoader;
|
import com.gmail.nossr50.locale.LocaleLoader;
|
||||||
@ -46,12 +47,14 @@ public abstract class ChatManager {
|
|||||||
McMMOPartyChatEvent partyChatEvent = (McMMOPartyChatEvent) event;
|
McMMOPartyChatEvent partyChatEvent = (McMMOPartyChatEvent) event;
|
||||||
|
|
||||||
//Find the people with permissions
|
//Find the people with permissions
|
||||||
for(Player player : event.getPlugin().getServer().getOnlinePlayers())
|
for(McMMOPlayer mcMMOPlayer : UserManager.getPlayers())
|
||||||
{
|
{
|
||||||
|
Player player = mcMMOPlayer.getPlayer();
|
||||||
|
|
||||||
//Check for toggled players
|
//Check for toggled players
|
||||||
if(UserManager.getPlayer(player).isPartyChatSpying())
|
if(mcMMOPlayer.isPartyChatSpying())
|
||||||
{
|
{
|
||||||
Party adminParty = UserManager.getPlayer(player).getParty();
|
Party adminParty = mcMMOPlayer.getParty();
|
||||||
|
|
||||||
//Only message admins not part of this party
|
//Only message admins not part of this party
|
||||||
if(adminParty != null)
|
if(adminParty != null)
|
||||||
|
@ -27,6 +27,7 @@ public class PlayerProfile {
|
|||||||
/* HUDs */
|
/* HUDs */
|
||||||
private MobHealthbarType mobHealthbarType;
|
private MobHealthbarType mobHealthbarType;
|
||||||
private int scoreboardTipsShown;
|
private int scoreboardTipsShown;
|
||||||
|
private int saveAttempts = 0;
|
||||||
|
|
||||||
/* Skill Data */
|
/* Skill Data */
|
||||||
private final Map<PrimarySkillType, Integer> skills = new HashMap<>(); // Skill & Level
|
private final Map<PrimarySkillType, Integer> skills = new HashMap<>(); // Skill & Level
|
||||||
@ -34,9 +35,9 @@ public class PlayerProfile {
|
|||||||
private final Map<SuperAbilityType, Integer> abilityDATS = new HashMap<>(); // Ability & Cooldown
|
private final Map<SuperAbilityType, Integer> abilityDATS = new HashMap<>(); // Ability & Cooldown
|
||||||
private final Map<UniqueDataType, Integer> uniquePlayerData = new HashMap<>(); //Misc data that doesn't fit into other categories (chimaera wing, etc..)
|
private final Map<UniqueDataType, Integer> uniquePlayerData = new HashMap<>(); //Misc data that doesn't fit into other categories (chimaera wing, etc..)
|
||||||
|
|
||||||
// Store previous XP gains for deminished returns
|
// Store previous XP gains for diminished returns
|
||||||
private DelayQueue<SkillXpGain> gainedSkillsXp = new DelayQueue<>();
|
private DelayQueue<SkillXpGain> gainedSkillsXp = new DelayQueue<SkillXpGain>();
|
||||||
private HashMap<PrimarySkillType, Float> rollingSkillsXp = new HashMap<>();
|
private HashMap<PrimarySkillType, Float> rollingSkillsXp = new HashMap<PrimarySkillType, Float>();
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public PlayerProfile(String playerName) {
|
public PlayerProfile(String playerName) {
|
||||||
@ -92,8 +93,13 @@ public class PlayerProfile {
|
|||||||
new PlayerProfileSaveTask(this).runTaskAsynchronously(mcMMO.p);
|
new PlayerProfileSaveTask(this).runTaskAsynchronously(mcMMO.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void scheduleAsyncSaveDelay() {
|
||||||
|
new PlayerProfileSaveTask(this).runTaskLaterAsynchronously(mcMMO.p, 20);
|
||||||
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
if (!changed || !loaded) {
|
if (!changed || !loaded) {
|
||||||
|
saveAttempts = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,8 +108,29 @@ public class PlayerProfile {
|
|||||||
changed = !mcMMO.getDatabaseManager().saveUser(profileCopy);
|
changed = !mcMMO.getDatabaseManager().saveUser(profileCopy);
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
mcMMO.p.getLogger().warning("PlayerProfile saving failed for player: " + playerName + " " + uuid);
|
mcMMO.p.getLogger().severe("PlayerProfile saving failed for player: " + playerName + " " + uuid);
|
||||||
|
|
||||||
|
if(saveAttempts > 0)
|
||||||
|
{
|
||||||
|
mcMMO.p.getLogger().severe("Attempted to save profile for player "+getPlayerName()
|
||||||
|
+ " resulted in failure. "+saveAttempts+" have been made so far.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(saveAttempts < 10)
|
||||||
|
{
|
||||||
|
saveAttempts++;
|
||||||
|
scheduleAsyncSaveDelay();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
mcMMO.p.getLogger().severe("mcMMO has failed to save the profile for "
|
||||||
|
+getPlayerName()+" numerous times." +
|
||||||
|
" mcMMO will now stop attempting to save this profile." +
|
||||||
|
" Check your console for errors and inspect your DB for issues.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
saveAttempts = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPlayerName() {
|
public String getPlayerName() {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.gmail.nossr50.datatypes.skills.subskills.acrobatics;
|
package com.gmail.nossr50.datatypes.skills.subskills.acrobatics;
|
||||||
|
|
||||||
import com.gmail.nossr50.config.AdvancedConfig;
|
import com.gmail.nossr50.config.AdvancedConfig;
|
||||||
import com.gmail.nossr50.datatypes.LimitedSizeList;
|
|
||||||
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
||||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||||
@ -32,15 +31,11 @@ import org.bukkit.event.EventPriority;
|
|||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
public class Roll extends AcrobaticsSubSkill {
|
public class Roll extends AcrobaticsSubSkill {
|
||||||
protected HashMap<Player, LimitedSizeList> fallLocationMap;
|
|
||||||
|
|
||||||
public Roll() {
|
public Roll() {
|
||||||
super("Roll", EventPriority.HIGHEST, SubSkillType.ACROBATICS_ROLL);
|
super("Roll", EventPriority.HIGHEST, SubSkillType.ACROBATICS_ROLL);
|
||||||
if(mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().isPreventAcrobaticsAbuse())
|
|
||||||
fallLocationMap = new HashMap<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -287,12 +282,7 @@ public class Roll extends AcrobaticsSubSkill {
|
|||||||
if(System.currentTimeMillis() < UserManager.getPlayer(player).getTeleportATS())
|
if(System.currentTimeMillis() < UserManager.getPlayer(player).getTeleportATS())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if(fallLocationMap.get(player) == null)
|
if(UserManager.getPlayer(player).getAcrobaticsManager().hasFallenInLocationBefore(getBlockLocation(player)))
|
||||||
fallLocationMap.put(player, new LimitedSizeList(mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().getAcrobaticLocationLimit()));
|
|
||||||
|
|
||||||
LimitedSizeList fallLocations = fallLocationMap.get(player);
|
|
||||||
|
|
||||||
if(fallLocations.contains(getBlockLocation(player)))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -423,16 +413,7 @@ public class Roll extends AcrobaticsSubSkill {
|
|||||||
|
|
||||||
public void addFallLocation(Player player)
|
public void addFallLocation(Player player)
|
||||||
{
|
{
|
||||||
if(!mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().isPreventAcrobaticsAbuse())
|
UserManager.getPlayer(player).getAcrobaticsManager().addLocationToFallMap(getBlockLocation(player));
|
||||||
return;
|
|
||||||
|
|
||||||
if(fallLocationMap.get(player) == null)
|
|
||||||
fallLocationMap.put(player, new LimitedSizeList(mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().getAcrobaticLocationLimit()));
|
|
||||||
|
|
||||||
LimitedSizeList fallLocations = fallLocationMap.get(player);
|
|
||||||
|
|
||||||
Location loc = getBlockLocation(player);
|
|
||||||
fallLocations.add(loc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location getBlockLocation(Player player)
|
public Location getBlockLocation(Player player)
|
||||||
|
@ -495,7 +495,8 @@ public class PlayerListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
|
//Delay loading for 3 seconds in case the player has a save task running, its hacky but it should do the trick
|
||||||
|
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 60);
|
||||||
|
|
||||||
if (mcMMO.getConfigManager().getConfigMOTD().isEnableMOTD()) {
|
if (mcMMO.getConfigManager().getConfigMOTD().isEnableMOTD()) {
|
||||||
Motd.displayAll(player);
|
Motd.displayAll(player);
|
||||||
|
@ -14,7 +14,6 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
public class PlayerProfileLoadingTask extends BukkitRunnable {
|
public class PlayerProfileLoadingTask extends BukkitRunnable {
|
||||||
private static final int MAX_TRIES = 5;
|
|
||||||
private final Player player;
|
private final Player player;
|
||||||
private int attempt = 0;
|
private int attempt = 0;
|
||||||
|
|
||||||
@ -37,9 +36,6 @@ public class PlayerProfileLoadingTask extends BukkitRunnable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increment attempt counter and try
|
|
||||||
attempt++;
|
|
||||||
|
|
||||||
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(player.getName(), player.getUniqueId(), true);
|
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(player.getName(), player.getUniqueId(), true);
|
||||||
// If successful, schedule the apply
|
// If successful, schedule the apply
|
||||||
if (profile.isLoaded()) {
|
if (profile.isLoaded()) {
|
||||||
@ -47,14 +43,24 @@ public class PlayerProfileLoadingTask extends BukkitRunnable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we've failed five times, give up
|
// Print errors to console/logs if we're failing at least 2 times in a row to load the profile
|
||||||
if (attempt >= MAX_TRIES) {
|
if (attempt >= 3)
|
||||||
mcMMO.p.getLogger().severe("Giving up on attempting to load the PlayerProfile for " + player.getName());
|
{
|
||||||
mcMMO.p.getServer().broadcast(LocaleLoader.getString("Profile.Loading.AdminFailureNotice", player.getName()), Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
|
//Log the error
|
||||||
player.sendMessage(LocaleLoader.getString("Profile.Loading.Failure").split("\n"));
|
mcMMO.p.getLogger().severe(LocaleLoader.getString("Profile.Loading.FailureNotice",
|
||||||
return;
|
player.getName(), String.valueOf(attempt)));
|
||||||
|
|
||||||
|
//Notify the admins
|
||||||
|
mcMMO.p.getServer().broadcast(LocaleLoader.getString("Profile.Loading.FailureNotice", player.getName()), Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
|
||||||
|
|
||||||
|
//Notify the player
|
||||||
|
player.sendMessage(LocaleLoader.getString("Profile.Loading.FailurePlayer", String.valueOf(attempt)).split("\n"));
|
||||||
}
|
}
|
||||||
new PlayerProfileLoadingTask(player, attempt).runTaskLaterAsynchronously(mcMMO.p, 100 * attempt);
|
|
||||||
|
// Increment attempt counter and try
|
||||||
|
attempt++;
|
||||||
|
|
||||||
|
new PlayerProfileLoadingTask(player, attempt).runTaskLaterAsynchronously(mcMMO.p, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ApplySuccessfulProfile extends BukkitRunnable {
|
private class ApplySuccessfulProfile extends BukkitRunnable {
|
||||||
@ -90,7 +96,6 @@ public class PlayerProfileLoadingTask extends BukkitRunnable {
|
|||||||
player.sendMessage(LocaleLoader.getString("Profile.Loading.Success"));
|
player.sendMessage(LocaleLoader.getString("Profile.Loading.Success"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.gmail.nossr50.skills.acrobatics;
|
package com.gmail.nossr50.skills.acrobatics;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.datatypes.LimitedSizeList;
|
||||||
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
||||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||||
@ -15,6 +16,7 @@ import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
|||||||
import com.gmail.nossr50.util.skills.RankUtils;
|
import com.gmail.nossr50.util.skills.RankUtils;
|
||||||
import com.gmail.nossr50.util.skills.SkillActivationType;
|
import com.gmail.nossr50.util.skills.SkillActivationType;
|
||||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
@ -23,11 +25,26 @@ public class AcrobaticsManager extends SkillManager {
|
|||||||
public AcrobaticsManager(McMMOPlayer mcMMOPlayer) {
|
public AcrobaticsManager(McMMOPlayer mcMMOPlayer) {
|
||||||
super(mcMMOPlayer, PrimarySkillType.ACROBATICS);
|
super(mcMMOPlayer, PrimarySkillType.ACROBATICS);
|
||||||
rollXPInterval = (1000 * mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().getRollXPGainCooldownSeconds());
|
rollXPInterval = (1000 * mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().getRollXPGainCooldownSeconds());
|
||||||
|
|
||||||
|
//Save some memory if exploit prevention is off
|
||||||
|
if(mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().isPreventAcrobaticsAbuse())
|
||||||
|
fallLocationMap = new LimitedSizeList(mcMMO.getConfigManager().getConfigExploitPrevention().getAcrobaticLocationLimit());
|
||||||
}
|
}
|
||||||
|
|
||||||
private long rollXPCooldown = 0;
|
private long rollXPCooldown = 0;
|
||||||
private long rollXPInterval;
|
private long rollXPInterval;
|
||||||
private long rollXPIntervalLengthen = (1000 * 10); //10 Seconds
|
private long rollXPIntervalLengthen = (1000 * 10); //10 Seconds
|
||||||
|
private LimitedSizeList fallLocationMap;
|
||||||
|
|
||||||
|
public boolean hasFallenInLocationBefore(Location location)
|
||||||
|
{
|
||||||
|
return fallLocationMap.contains(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLocationToFallMap(Location location)
|
||||||
|
{
|
||||||
|
fallLocationMap.add(location);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean canGainRollXP()
|
public boolean canGainRollXP()
|
||||||
{
|
{
|
||||||
|
@ -96,7 +96,11 @@ public final class UserManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static McMMOPlayer getPlayer(Player player) {
|
public static McMMOPlayer getPlayer(Player player) {
|
||||||
|
//Avoid Array Index out of bounds
|
||||||
|
if(player.hasMetadata(mcMMO.playerDataKey))
|
||||||
return (McMMOPlayer) player.getMetadata(mcMMO.playerDataKey).get(0).value();
|
return (McMMOPlayer) player.getMetadata(mcMMO.playerDataKey).get(0).value();
|
||||||
|
else
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static McMMOPlayer retrieveMcMMOPlayer(String playerName, boolean offlineValid) {
|
private static McMMOPlayer retrieveMcMMOPlayer(String playerName, boolean offlineValid) {
|
||||||
|
@ -1073,8 +1073,8 @@ Scoreboard.Misc.Overall=[[GOLD]]Overall
|
|||||||
Scoreboard.Misc.Ability=Super Ability
|
Scoreboard.Misc.Ability=Super Ability
|
||||||
#DATABASE RECOVERY
|
#DATABASE RECOVERY
|
||||||
Profile.Loading.Success=[[GREEN]]Your mcMMO profile has been loaded.
|
Profile.Loading.Success=[[GREEN]]Your mcMMO profile has been loaded.
|
||||||
Profile.Loading.Failure=[[RED]]mcMMO still cannot load your data. You may want to [[AQUA]]contact the server owner.\n[[YELLOW]]You can still play on the server, but you will have [[BOLD]]no mcMMO levels[[YELLOW]] and any XP you get [[BOLD]]will not be saved[[YELLOW]].
|
Profile.Loading.FailurePlayer=[[RED]]mcMMO is having trouble loading your data, we have attempted to load it [[GREEN]]{0}[[RED]] times.[[LIGHT_GRAY]] You may want to contact the server admins about this issue. mcMMO will attempt to load your data until you disconnect, you will not gain XP or be able to use skills while the data is not loaded.
|
||||||
Profile.Loading.AdminFailureNotice=[[DARK_RED]][A][[RED]] mcMMO was unable to load the player data for [[YELLOW]]{0}[[RED]]. [[LIGHT_PURPLE]]Please inspect your database setup.
|
Profile.Loading.FailureNotice=[[DARK_RED]][A][[RED]] mcMMO was unable to load the player data for [[YELLOW]]{0}[[RED]]. [[LIGHT_PURPLE]]Please inspect your database setup. Attempts made so far {1}.
|
||||||
#Holiday
|
#Holiday
|
||||||
Holiday.AprilFools.Levelup=[[GOLD]]{0} is now level [[GREEN]]{1}[[GOLD]]!
|
Holiday.AprilFools.Levelup=[[GOLD]]{0} is now level [[GREEN]]{1}[[GOLD]]!
|
||||||
Holiday.Anniversary=[[BLUE]]Happy {0} Year Anniversary!\n[[BLUE]]In honor of all of nossr50's work and all the devs, here's a firework show!
|
Holiday.Anniversary=[[BLUE]]Happy {0} Year Anniversary!\n[[BLUE]]In honor of all of nossr50's work and all the devs, here's a firework show!
|
||||||
|
Loading…
Reference in New Issue
Block a user