diff --git a/Changelog.txt b/Changelog.txt index 27c11d51a..9d689ced8 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,3 +1,11 @@ +Version 2.1.164 + New exploit fix setting, when disabled it will allow combat interactions with "NPC" entities from plugins like Citizens + ExploitFix.PreventPluginNPCInteraction Added to experience.yml + + NOTES: + Historically mcMMO has checked an entity for being a NPC (not a Villager) and backed out of any interaction, this was originally done because of NPCs that were meant to be invincible/etc and not give XP + However nowadays what an NPC is used for is pretty loose, mcMMO only has definitions for some NPCs (such as from Citizens) it doesn't know about most NPCs in most plugins unless they identify themselves in a similar way to the predefined parameters + Version 2.1.163 Fixed the translate URL pointing to the wrong place (thanks chew) Fixed a bug where FlatFile databases would always attempt a UUID conversion task every save operation (every 10 minutes) causing console spam diff --git a/src/main/java/com/gmail/nossr50/config/experience/ExperienceConfig.java b/src/main/java/com/gmail/nossr50/config/experience/ExperienceConfig.java index bd4e92ad6..2d84ea0c7 100644 --- a/src/main/java/com/gmail/nossr50/config/experience/ExperienceConfig.java +++ b/src/main/java/com/gmail/nossr50/config/experience/ExperienceConfig.java @@ -152,6 +152,7 @@ public class ExperienceConfig extends AutoUpdateConfigLoader { public boolean isPistonExploitPrevented() { return config.getBoolean("ExploitFix.Pistons", false); } public boolean allowUnsafeEnchantments() { return config.getBoolean("ExploitFix.UnsafeEnchantments", false); } public boolean isCOTWBreedingPrevented() { return config.getBoolean("ExploitFix.COTWBreeding", true); } + public boolean isNPCInteractionPrevented() { return config.getBoolean("ExploitFix.PreventPluginNPCInteraction", true); } public boolean isFishingExploitingPrevented() { return config.getBoolean("ExploitFix.Fishing", true); } public boolean isAcrobaticsExploitingPrevented() { return config.getBoolean("ExploitFix.Acrobatics", true); } diff --git a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java index 804c3c73a..73f9b064b 100644 --- a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java @@ -312,7 +312,8 @@ public class EntityListener implements Listener { return; } - if (Misc.isNPCEntityExcludingVillagers(defender) || !defender.isValid() || !(defender instanceof LivingEntity)) { + + if ((ExperienceConfig.getInstance().isNPCInteractionPrevented() && Misc.isNPCEntityExcludingVillagers(defender)) || !defender.isValid() || !(defender instanceof LivingEntity)) { return; } @@ -322,7 +323,7 @@ public class EntityListener implements Listener { return; } - if (Misc.isNPCEntityExcludingVillagers(attacker)) { + if (ExperienceConfig.getInstance().isNPCInteractionPrevented() && Misc.isNPCEntityExcludingVillagers(attacker)) { return; } @@ -502,7 +503,7 @@ public class EntityListener implements Listener { } */ - if (Misc.isNPCEntityExcludingVillagers(entity) || !entity.isValid() || !(entity instanceof LivingEntity)) { + if ((ExperienceConfig.getInstance().isNPCInteractionPrevented() && Misc.isNPCEntityExcludingVillagers(entity)) || !entity.isValid() || !(entity instanceof LivingEntity)) { return; } @@ -649,7 +650,7 @@ public class EntityListener implements Listener { LivingEntity entity = event.getEntity(); - if (Misc.isNPCEntityExcludingVillagers(entity)) { + if (ExperienceConfig.getInstance().isNPCInteractionPrevented() && Misc.isNPCEntityExcludingVillagers(entity)) { return; } @@ -957,7 +958,7 @@ public class EntityListener implements Listener { LivingEntity livingEntity = event.getEntity(); if (!UserManager.hasPlayerDataKey(player) - || Misc.isNPCEntityExcludingVillagers(livingEntity) + || (ExperienceConfig.getInstance().isNPCInteractionPrevented() && Misc.isNPCEntityExcludingVillagers(livingEntity)) || persistentDataLayer.hasMobFlag(MobMetaFlagType.EGG_MOB, livingEntity) || persistentDataLayer.hasMobFlag(MobMetaFlagType.MOB_SPAWNER_MOB, livingEntity)) { return; diff --git a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java index c0fb6da54..d7f727278 100644 --- a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java @@ -895,7 +895,7 @@ public class PlayerListener implements Listener { public void onPlayerChat(AsyncPlayerChatEvent event) { Player player = event.getPlayer(); - if (Misc.isNPCEntityExcludingVillagers(player) || !UserManager.hasPlayerDataKey(player)) { + if ((ExperienceConfig.getInstance().isNPCInteractionPrevented() && Misc.isNPCEntityExcludingVillagers(player)) || !UserManager.hasPlayerDataKey(player)) { return; } diff --git a/src/main/java/com/gmail/nossr50/util/EventUtils.java b/src/main/java/com/gmail/nossr50/util/EventUtils.java index 52a2f989e..a290ab0dd 100644 --- a/src/main/java/com/gmail/nossr50/util/EventUtils.java +++ b/src/main/java/com/gmail/nossr50/util/EventUtils.java @@ -1,6 +1,7 @@ package com.gmail.nossr50.util; import com.gmail.nossr50.config.Config; +import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.datatypes.experience.XPGainReason; import com.gmail.nossr50.datatypes.experience.XPGainSource; import com.gmail.nossr50.datatypes.party.Party; diff --git a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java index 616f0e562..1aaf6395f 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java @@ -321,8 +321,10 @@ public final class CombatUtils { EntityType entityType = painSource.getType(); if (target instanceof Player) { - if (Misc.isNPCEntityExcludingVillagers(target)) { - return; + if(ExperienceConfig.getInstance().isNPCInteractionPrevented()) { + if (Misc.isNPCEntityExcludingVillagers(target)) { + return; + } } Player player = (Player) target; @@ -692,7 +694,7 @@ public final class CombatUtils { break; } - if (Misc.isNPCEntityExcludingVillagers(entity) || !(entity instanceof LivingEntity) || !shouldBeAffected(attacker, entity)) { + if ((ExperienceConfig.getInstance().isNPCInteractionPrevented() && Misc.isNPCEntityExcludingVillagers(entity)) || !(entity instanceof LivingEntity) || !shouldBeAffected(attacker, entity)) { continue; } diff --git a/src/main/resources/experience.yml b/src/main/resources/experience.yml index fd0644d93..4cbbfd080 100644 --- a/src/main/resources/experience.yml +++ b/src/main/resources/experience.yml @@ -35,6 +35,10 @@ ExploitFix: TreeFellerReducedXP: true PistonCheating: true SnowGolemExcavation: true + # This include NPCs from stuff like Citizens, this is not a setting for Vanilla Minecraft Villagers (Which can be considered NPCs) + # mcMMO normally doesn't process attacks against an Entity if it is an NPC from another plugin + # Of course, mcMMO doesn't know for sure whether or not something is an NPC, it checks a few known things, see our source code to see how + PreventPluginNPCInteraction: true Experience_Bars: # Turn this to false if you wanna disable XP bars Enable: true