diff --git a/Changelog.txt b/Changelog.txt index 65d1601da..b89fee751 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -30,6 +30,8 @@ Version 2.2.0 Added toggle for pistons marking natural blocks as unnatural after being moved to prevent afk stone farms Added toggle for marking spawned mobs for giving modified XP Added toggle for tamed mobs to give combat XP when struck + Added toggle for acrobatics exploit prevention + Added customizable limit for the number of locations acrobatics tracks for exploit prevention Settings related to Player Leveling are now found in "player_leveling.conf" Player Leveling's "TruncateSkills" renamed -> "Reduce-Player-Skills-Above-Cap" diff --git a/src/main/java/com/gmail/nossr50/config/hocon/antiexploit/ConfigExploitPrevention.java b/src/main/java/com/gmail/nossr50/config/hocon/antiexploit/ConfigExploitPrevention.java index 55f80f754..6c066c15c 100644 --- a/src/main/java/com/gmail/nossr50/config/hocon/antiexploit/ConfigExploitPrevention.java +++ b/src/main/java/com/gmail/nossr50/config/hocon/antiexploit/ConfigExploitPrevention.java @@ -38,6 +38,9 @@ public class ConfigExploitPrevention { "\nDefault value: "+TAMED_MOB_DEFAULT) private boolean preventTamedMobXp = TAMED_MOB_DEFAULT; + @Setting(value = "Acrobatics", comment = "Exploit settings related to Acrobatics") + private ConfigSectionExploitAcrobatics configSectionExploitAcrobatics = new ConfigSectionExploitAcrobatics(); + public boolean getEndermenEndermiteFix() { return endermenEndermiteFix; @@ -54,4 +57,8 @@ public class ConfigExploitPrevention { public boolean doTamedEntitiesGiveXP() { return preventTamedMobXp; } + + public ConfigSectionExploitAcrobatics getConfigSectionExploitAcrobatics() { + return configSectionExploitAcrobatics; + } } diff --git a/src/main/java/com/gmail/nossr50/config/hocon/antiexploit/ConfigSectionExploitAcrobatics.java b/src/main/java/com/gmail/nossr50/config/hocon/antiexploit/ConfigSectionExploitAcrobatics.java new file mode 100644 index 000000000..4758a93c6 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/config/hocon/antiexploit/ConfigSectionExploitAcrobatics.java @@ -0,0 +1,37 @@ +package com.gmail.nossr50.config.hocon.antiexploit; + +import ninja.leaping.configurate.objectmapping.Setting; +import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable; + +@ConfigSerializable +public class ConfigSectionExploitAcrobatics { + + public static final int ACROBATIC_LOCATION_LIMIT_DEFAULT = 50; + public static final boolean PREVENT_ACROBATICS_ABUSE_DEFAULT = true; + + @Setting(value = "Player-Fall-Location-Tracking", + comment = "The amount of locations to keep track of for player falls." + + "\nThis setting does nothing if Prevent-Acrobatics-Farming is disabled" + + "\nEach player has their own individual list with up to 50 locations stored, locations are not shared between players." + + "\nPlayers cannot gain XP from falling in the same location twice." + + "\nIt's best you do not raise this number unless you have some kind of god computer," + + "\n mcMMO processes the entire tracked location list anytime a player takes fall damage so the bigger this is the more expensive that calculation is." + + "\nDefault value: "+ACROBATIC_LOCATION_LIMIT_DEFAULT) + private int acrobaticLocationLimit = ACROBATIC_LOCATION_LIMIT_DEFAULT; + + @Setting(value = "Prevent-Acrobatics-Farming", + comment = "Prevents many common exploits for farming Acrobatics XP" + + "\nEnabled tracking player fall locations" + + "\nEnables tracking when a player last teleported" + + "\nEnables tracking when a player last respawned" + + "\nDefault value: "+PREVENT_ACROBATICS_ABUSE_DEFAULT) + private boolean preventAcrobaticsAbuse = PREVENT_ACROBATICS_ABUSE_DEFAULT; + + public int getAcrobaticLocationLimit() { + return acrobaticLocationLimit; + } + + public boolean isPreventAcrobaticsAbuse() { + return preventAcrobaticsAbuse; + } +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java b/src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java index ca1ba1089..bf989a067 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java +++ b/src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java @@ -41,7 +41,8 @@ public class Roll extends AcrobaticsSubSkill { public Roll() { super("Roll", EventPriority.HIGHEST, SubSkillType.ACROBATICS_ROLL); - fallLocationMap = new HashMap<>(); + if(mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().isPreventAcrobaticsAbuse()) + fallLocationMap = new HashMap<>(); } /** @@ -207,21 +208,20 @@ public class Roll extends AcrobaticsSubSkill { && RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.ACROBATICS_ROLL, player)) { NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Roll.Text"); SoundManager.sendCategorizedSound(player, player.getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS); - //player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.Text")); - //if (!SkillUtils.cooldownExpired((long) mcMMOPlayer.getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) { - if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP()) + if(!mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().isPreventAcrobaticsAbuse()) + SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE); + else if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP()) SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE); - //} addFallLocation(player); return modifiedDamage; } else if (!isFatal(player, damage)) { - //if (!SkillUtils.cooldownExpired((long) mcMMOPlayer.getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) { - if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP()) + if(!mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().isPreventAcrobaticsAbuse()) + SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE); + else if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP()) SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, false), XPGainReason.PVE); - //} } addFallLocation(player); @@ -249,14 +249,19 @@ public class Roll extends AcrobaticsSubSkill { { NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Ability.Proc"); SoundManager.sendCategorizedSound(player, player.getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS,0.5F); - if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP()) + + if(!mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().isPreventAcrobaticsAbuse()) + SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE); + else if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP()) SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE); addFallLocation(player); return modifiedDamage; } else if (!isFatal(player, damage)) { - if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP()) + if(!mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().isPreventAcrobaticsAbuse()) + SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE); + else if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP()) SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, false), XPGainReason.PVE); addFallLocation(player); @@ -281,24 +286,14 @@ public class Roll extends AcrobaticsSubSkill { } if(fallLocationMap.get(player) == null) - fallLocationMap.put(player, new LimitedSizeList(50)); + fallLocationMap.put(player, new LimitedSizeList(mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().getAcrobaticLocationLimit())); LimitedSizeList fallLocations = fallLocationMap.get(player); if(fallLocations.contains(getBlockLocation(player))) return true; - return false; //NOT EXPLOITING -/* - Location fallLocation = player.getLocation(); - int maxTries = MainConfig.getInstance().getAcrobaticsAFKMaxTries(); - - boolean sameLocation = (lastFallLocation != null && Misc.isNear(lastFallLocation, fallLocation, 2)); - - fallTries = sameLocation ? Math.min(fallTries + 1, maxTries) : Math.max(fallTries - 1, 0); - lastFallLocation = fallLocation; - - return fallTries + 1 > maxTries;*/ + return false; } private float calculateRollXP(Player player, double damage, boolean isRoll) { @@ -426,8 +421,11 @@ public class Roll extends AcrobaticsSubSkill { public void addFallLocation(Player player) { + if(!mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().isPreventAcrobaticsAbuse()) + return; + if(fallLocationMap.get(player) == null) - fallLocationMap.put(player, new LimitedSizeList(50)); + fallLocationMap.put(player, new LimitedSizeList(mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().getAcrobaticLocationLimit())); LimitedSizeList fallLocations = fallLocationMap.get(player); diff --git a/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java b/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java index 35abe80f7..2cd3ff8d3 100644 --- a/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java +++ b/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java @@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.interactions.NotificationType; import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType; +import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.skills.SkillManager; import com.gmail.nossr50.util.Misc; import com.gmail.nossr50.util.Permissions; @@ -75,7 +76,9 @@ public class AcrobaticsManager extends SkillManager { } //Check respawn to prevent abuse - if (SkillUtils.cooldownExpired(mcMMOPlayer.getRespawnATS(), Misc.PLAYER_RESPAWN_COOLDOWN_SECONDS)) { + if(!mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitAcrobatics().isPreventAcrobaticsAbuse()) + applyXpGain((float) (damage * Acrobatics.dodgeXpModifier), XPGainReason.PVP); + else if (SkillUtils.cooldownExpired(mcMMOPlayer.getRespawnATS(), Misc.PLAYER_RESPAWN_COOLDOWN_SECONDS)) { applyXpGain((float) (damage * Acrobatics.dodgeXpModifier), XPGainReason.PVP); }