Browse Source

Acrobatics now uses much better anti-exploit prevention

nossr50 6 years ago
parent
commit
55821f7703

+ 1 - 0
Changelog.txt

@@ -10,6 +10,7 @@ Key:
 Version 2.1.1
     = Fixed an issue where excavation wasn't using the correct permission node
     = Added protection against AFK fishing
+    = Acrobatics now uses much better anti-exploit detection
 
 Version 2.1.0
  + mcMMO now features XP bars! Configurable in experience.yml

+ 57 - 0
src/main/java/com/gmail/nossr50/datatypes/LimitedSizeList.java

@@ -0,0 +1,57 @@
+package com.gmail.nossr50.datatypes;
+
+
+import org.bukkit.Location;
+
+public class LimitedSizeList {
+    public Location[] limitedSizeOrderedList;
+    private final int size;
+
+
+    public LimitedSizeList(int size)
+    {
+        this.size = size;
+        limitedSizeOrderedList = new Location[size];
+    }
+
+    /**
+     * Adds objects to our limited size ordered list
+     * New objects are added to the front
+     * @param newItem
+     */
+    public void add(Location newItem)
+    {
+        Location[] newList = new Location[size];
+
+        for(int i = 0; i < size-1; i++)
+        {
+            if(i != 0)
+                newList[i] = limitedSizeOrderedList[i-1];
+            else
+                newList[i] = newItem;
+        }
+
+        limitedSizeOrderedList = newList;
+    }
+
+    /**
+     * Returns true if the object is anywhere in our list
+     * @param targetLoc the object to check for
+     * @return true if the object is in our list
+     */
+    public boolean contains(Location targetLoc)
+    {
+        for(Location iter : limitedSizeOrderedList)
+        {
+            if(iter == null)
+                continue;
+
+            if(iter.getX() == targetLoc.getX()
+                    && iter.getY() == targetLoc.getY()
+                    && iter.getZ() == targetLoc.getZ())
+                return true;
+        }
+
+        return false;
+    }
+}

+ 45 - 9
src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java

@@ -3,6 +3,7 @@ package com.gmail.nossr50.datatypes.skills.subskills.acrobatics;
 import com.gmail.nossr50.config.AdvancedConfig;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.experience.ExperienceConfig;
+import com.gmail.nossr50.datatypes.LimitedSizeList;
 import com.gmail.nossr50.datatypes.interactions.NotificationType;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
@@ -18,6 +19,7 @@ import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.random.RandomChanceSkill;
 import com.gmail.nossr50.util.random.RandomChanceUtil;
 import com.gmail.nossr50.util.skills.PerksUtils;
+import com.gmail.nossr50.util.skills.RankUtils;
 import com.gmail.nossr50.util.skills.SkillActivationType;
 import com.gmail.nossr50.util.skills.SkillUtils;
 import com.gmail.nossr50.util.sounds.SoundManager;
@@ -33,12 +35,14 @@ import org.bukkit.event.EventPriority;
 import org.bukkit.event.entity.EntityDamageEvent;
 import org.bukkit.inventory.ItemStack;
 
+import java.util.HashMap;
+
 public class Roll extends AcrobaticsSubSkill {
-    private int fallTries = 0;
-    protected Location lastFallLocation;
+    protected HashMap<Player, LimitedSizeList> fallLocationMap;
 
     public Roll() {
         super("Roll", EventPriority.HIGHEST, SubSkillType.ACROBATICS_ROLL);
+        fallLocationMap = new HashMap<>();
     }
 
     /**
@@ -75,7 +79,6 @@ public class Roll extends AcrobaticsSubSkill {
                  */
                 Player player = (Player) ((EntityDamageEvent) event).getEntity();
                 if (canRoll(player)) {
-                    if(Permissions.isSubSkillEnabled(player, SubSkillType.ACROBATICS_ROLL))
                     entityDamageEvent.setDamage(rollCheck(player, mcMMOPlayer, entityDamageEvent.getDamage()));
 
                     if (entityDamageEvent.getFinalDamage() == 0) {
@@ -182,7 +185,7 @@ public class Roll extends AcrobaticsSubSkill {
     }
 
     private boolean canRoll(Player player) {
-        return !isExploiting(player) && Permissions.isSubSkillEnabled(player, SubSkillType.ACROBATICS_ROLL);
+        return RankUtils.hasUnlockedSubskill(player, SubSkillType.ACROBATICS_ROLL) && Permissions.isSubSkillEnabled(player, SubSkillType.ACROBATICS_ROLL);
     }
 
     /**
@@ -208,19 +211,21 @@ public class Roll extends AcrobaticsSubSkill {
             //player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.Text"));
 
             //if (!SkillUtils.cooldownExpired((long) mcMMOPlayer.getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) {
+            if(!isExploiting(player))
                 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))
                 SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, false), XPGainReason.PVE);
             //}
         }
 
-        lastFallLocation = player.getLocation();
-
+        addFallLocation(player);
         return damage;
     }
 
@@ -245,12 +250,17 @@ 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);
-            SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE);
+            if(!isExploiting(player))
+                SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE);
 
+            addFallLocation(player);
             return modifiedDamage;
         }
         else if (!isFatal(player, damage)) {
-            SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, false), XPGainReason.PVE);
+            if(!isExploiting(player))
+                SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, false), XPGainReason.PVE);
+            
+            addFallLocation(player);
         }
 
         return damage;
@@ -271,6 +281,16 @@ public class Roll extends AcrobaticsSubSkill {
             return true;
         }
 
+        if(fallLocationMap.get(player) == null)
+            fallLocationMap.put(player, new LimitedSizeList(20));
+
+        LimitedSizeList fallLocations = fallLocationMap.get(player);
+        
+        if(fallLocations.contains(getBlockLocation(player)))
+            return true;
+
+        return false; //NOT EXPLOITING
+/*
         Location fallLocation = player.getLocation();
         int maxTries = Config.getInstance().getAcrobaticsAFKMaxTries();
 
@@ -279,7 +299,7 @@ public class Roll extends AcrobaticsSubSkill {
         fallTries = sameLocation ? Math.min(fallTries + 1, maxTries) : Math.max(fallTries - 1, 0);
         lastFallLocation = fallLocation;
 
-        return fallTries + 1 > maxTries;
+        return fallTries + 1 > maxTries;*/
     }
 
     private float calculateRollXP(Player player, double damage, boolean isRoll) {
@@ -404,4 +424,20 @@ public class Roll extends AcrobaticsSubSkill {
         Double[] stats = { playerChanceRoll, playerChanceGrace }; //DEBUG
         return stats;
     }
+
+    public void addFallLocation(Player player)
+    {
+        if(fallLocationMap.get(player) == null)
+            fallLocationMap.put(player, new LimitedSizeList(20));
+
+        LimitedSizeList fallLocations = fallLocationMap.get(player);
+
+        Location loc = getBlockLocation(player);
+        fallLocations.add(loc);
+    }
+
+    public Location getBlockLocation(Player player)
+    {
+        return player.getLocation().getBlock().getLocation();
+    }
 }