diff options
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.java | 170 |
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); + } + } +} |