summaryrefslogtreecommitdiffstats
path: root/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/checks/moving/FlyingCheck.java
diff options
context:
space:
mode:
Diffstat (limited to 'EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/checks/moving/FlyingCheck.java')
-rw-r--r--EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/checks/moving/FlyingCheck.java170
1 files changed, 170 insertions, 0 deletions
diff --git a/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/checks/moving/FlyingCheck.java b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/checks/moving/FlyingCheck.java
new file mode 100644
index 000000000..c96d9f9c3
--- /dev/null
+++ b/EssentialsAntiCheat/src/com/earth2me/essentials/anticheat/checks/moving/FlyingCheck.java
@@ -0,0 +1,170 @@
+package com.earth2me.essentials.anticheat.checks.moving;
+
+import com.earth2me.essentials.anticheat.NoCheat;
+import com.earth2me.essentials.anticheat.NoCheatPlayer;
+import com.earth2me.essentials.anticheat.actions.ParameterName;
+import com.earth2me.essentials.anticheat.data.PreciseLocation;
+import com.earth2me.essentials.anticheat.data.Statistics.Id;
+import java.util.Locale;
+
+
+/**
+ * A check designed for people that are allowed to fly. The complement to the "RunningCheck", which is for people that
+ * aren't allowed to fly, and therefore have tighter rules to obey.
+ *
+ */
+public class FlyingCheck extends MovingCheck
+{
+ public FlyingCheck(NoCheat plugin)
+ {
+ super(plugin, "moving.flying");
+ }
+ // Determined by trial and error, the flying movement speed of the creative
+ // mode
+ private static final double creativeSpeed = 0.60D;
+
+ public PreciseLocation check(NoCheatPlayer player, MovingData data, MovingConfig ccmoving)
+ {
+
+ // The setBack is the location that players may get teleported to when
+ // they fail the check
+ final PreciseLocation setBack = data.runflySetBackPoint;
+
+ final PreciseLocation from = data.from;
+ final PreciseLocation to = data.to;
+
+ // If we have no setback, define one now
+ if (!setBack.isSet())
+ {
+ setBack.set(from);
+ }
+
+ // Used to store the location where the player gets teleported to
+ PreciseLocation newToLocation = null;
+
+ // Before doing anything, do a basic height check to determine if
+ // players are flying too high
+ int maxheight = ccmoving.flyingHeightLimit + player.getPlayer().getWorld().getMaxHeight();
+
+ if (to.y - data.vertFreedom > maxheight)
+ {
+ newToLocation = new PreciseLocation();
+ newToLocation.set(setBack);
+ newToLocation.y = maxheight - 10;
+ return newToLocation;
+ }
+
+ // Calculate some distances
+ final double yDistance = to.y - from.y;
+ final double xDistance = to.x - from.x;
+ final double zDistance = to.z - from.z;
+
+ // How far did the player move horizontally
+ final double horizontalDistance = Math.sqrt((xDistance * xDistance + zDistance * zDistance));
+
+ double resultHoriz = 0;
+ double resultVert = 0;
+ double result = 0;
+
+ // In case of creative game mode give at least 0.60 speed limit horizontal
+ double speedLimitHorizontal = player.isCreative() ? Math.max(creativeSpeed, ccmoving.flyingSpeedLimitHorizontal) : ccmoving.flyingSpeedLimitHorizontal;
+
+ // If the player is affected by potion of swiftness
+ speedLimitHorizontal *= player.getSpeedAmplifier();
+
+ // Finally, determine how far the player went beyond the set limits
+ resultHoriz = Math.max(0.0D, horizontalDistance - data.horizFreedom - speedLimitHorizontal);
+
+ boolean sprinting = player.isSprinting();
+
+ data.bunnyhopdelay--;
+
+ if (resultHoriz > 0 && sprinting)
+ {
+
+ // Try to treat it as a the "bunnyhop" problem
+ // The bunnyhop problem is that landing and immediatly jumping
+ // again leads to a player moving almost twice as far in that step
+ if (data.bunnyhopdelay <= 0 && resultHoriz < 0.4D)
+ {
+ data.bunnyhopdelay = 9;
+ resultHoriz = 0;
+ }
+ }
+
+ resultHoriz *= 100;
+
+ // Is the player affected by the "jumping" potion
+ // This is really just a very, very crude estimation and far from
+ // reality
+ double jumpAmplifier = player.getJumpAmplifier();
+ if (jumpAmplifier > data.lastJumpAmplifier)
+ {
+ data.lastJumpAmplifier = jumpAmplifier;
+ }
+
+ double speedLimitVertical = ccmoving.flyingSpeedLimitVertical * data.lastJumpAmplifier;
+
+ if (data.from.y >= data.to.y && data.lastJumpAmplifier > 0)
+ {
+ data.lastJumpAmplifier--;
+ }
+
+ // super simple, just check distance compared to max distance vertical
+ resultVert = Math.max(0.0D, yDistance - data.vertFreedom - speedLimitVertical) * 100;
+
+ result = resultHoriz + resultVert;
+
+ // The player went to far, either horizontal or vertical
+ if (result > 0)
+ {
+
+ // Increment violation counter and statistics
+ data.runflyVL += result;
+ if (resultHoriz > 0)
+ {
+ incrementStatistics(player, Id.MOV_RUNNING, resultHoriz);
+ }
+
+ if (resultVert > 0)
+ {
+ incrementStatistics(player, Id.MOV_FLYING, resultVert);
+ }
+
+ // Execute whatever actions are associated with this check and the
+ // violation level and find out if we should cancel the event
+ boolean cancel = executeActions(player, ccmoving.flyingActions, data.runflyVL);
+
+ // Was one of the actions a cancel? Then really do it
+ if (cancel)
+ {
+ newToLocation = setBack;
+ }
+ }
+
+ // Slowly reduce the violation level with each event
+ data.runflyVL *= 0.97;
+
+ // If the player did not get cancelled, define a new setback point
+ if (newToLocation == null)
+ {
+ setBack.set(to);
+ }
+
+ return newToLocation;
+ }
+
+ @Override
+ public String getParameter(ParameterName wildcard, NoCheatPlayer player)
+ {
+
+ if (wildcard == ParameterName.VIOLATIONS)
+ {
+ return String.format(Locale.US, "%d", (int)getData(player).runflyVL);
+ }
+ else
+ {
+ return super.getParameter(wildcard, player);
+ }
+ }
+}