From ec956a9be0cac65d9fd566f375e53e0a2e17b676 Mon Sep 17 00:00:00 2001 From: asofold Date: Mon, 22 Jul 2013 16:47:11 +0200 Subject: [PATCH] SF: Fix horizontal buffer allowing negative values + adjust tags. * Horizontal buffer is not modeled such that it can't become negative. * hvel tag added for using horizontal velocity. * hspeed tag is only added on hspeed violations. --- .../checks/fight/FightListener.java | 4 +- .../nocheatplus/checks/moving/MovingData.java | 6 +- .../checks/moving/SurvivalFly.java | 71 ++++++++++--------- 3 files changed, 45 insertions(+), 36 deletions(-) diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java index 1fca1df9..cf8331fa 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/fight/FightListener.java @@ -26,6 +26,7 @@ import fr.neatmonster.nocheatplus.checks.inventory.Items; import fr.neatmonster.nocheatplus.checks.moving.MovingConfig; import fr.neatmonster.nocheatplus.checks.moving.MovingData; import fr.neatmonster.nocheatplus.checks.moving.MovingListener; +import fr.neatmonster.nocheatplus.checks.moving.SurvivalFly; import fr.neatmonster.nocheatplus.compat.BridgeHealth; import fr.neatmonster.nocheatplus.components.JoinLeaveListener; import fr.neatmonster.nocheatplus.permissions.Permissions; @@ -231,7 +232,8 @@ public class FightListener extends CheckListener implements JoinLeaveListener{ if (mData.fromX != Double.MAX_VALUE){ // TODO: What would mData.lostSprintCount > 0 mean here? final double hDist = TrigUtil.distance(loc.getX(), loc.getZ(), mData.fromX, mData.fromZ); - if (hDist >= 0.23 && mData.sfHorizontalBuffer > 0.5){ + if (hDist >= 0.23 && mData.sfHorizontalBuffer > 0.5 * SurvivalFly.hBufMax) { + // TODO: Might remove checking sfHorizontalBuffer. final MovingConfig mc = MovingConfig.getConfig(player); // Check if fly checks is an issue at all, re-check "real sprinting". if (now <= mData.timeSprinting + mc.sprintingGrace && MovingListener.shouldCheckSurvivalFly(player, mData, mc)){ diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingData.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingData.java index 08faf3b6..2cff76a0 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingData.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingData.java @@ -169,7 +169,7 @@ public class MovingData extends ACheckData { public double passableVL; // Data of the survival fly check. - public double sfHorizontalBuffer = 0; + public double sfHorizontalBuffer = 0.0; /** Event-counter to cover up for sprinting resetting server side only. Set in the FighListener. */ public int lostSprintCount = 0; public int sfJumpPhase = 0; @@ -218,7 +218,7 @@ public class MovingData extends ACheckData { clearAccounting(); clearNoFallData(); removeAllVelocity(); - sfHorizontalBuffer = 0; + sfHorizontalBuffer = 0.0; lostSprintCount = 0; toWasReset = fromWasReset = false; // TODO: true maybe sfHoverTicks = sfHoverLoginTicks = -1; @@ -248,7 +248,7 @@ public class MovingData extends ACheckData { // Keep jump amplifier // Keep bunny-hop delay (?) // keep jump phase. - sfHorizontalBuffer = Math.min(0, sfHorizontalBuffer); + sfHorizontalBuffer = 0.0; lostSprintCount = 0; toWasReset = fromWasReset = false; // TODO: true maybe sfHoverTicks = -1; diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java index 3b108b3d..ceec5099 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/SurvivalFly.java @@ -51,7 +51,10 @@ public class SurvivalFly extends Check { public static final double modIce = 2.5D; /** Faster moving down stream (water mainly). */ - public static final double modDownStream = 0.19 / (walkSpeed * modSwim); + public static final double modDownStream = 0.19 / (walkSpeed * modSwim); + + /** Maximal horizontal buffer. It can be higher, but normal resetting should keep this limit. */ + public static final double hBufMax = 1.0; // Vertical speeds/modifiers. public static final double climbSpeed = walkSpeed * modSprint; // TODO. @@ -115,6 +118,7 @@ public class SurvivalFly extends Check { final boolean sprinting; if (data.lostSprintCount > 0) { // Sprint got toggled off, though the client is still (legitimately) moving at sprinting speed. + // NOTE: This could extend the "sprinting grace" period, theoretically, until on ground. if (resetTo && (fromOnGround || from.isResetCond()) || hDistance <= walkSpeed){ // Invalidate. data.lostSprintCount = 0; @@ -193,10 +197,8 @@ public class SurvivalFly extends Check { else{ data.hVelActive.clear(); hFreedom = 0.0; - if (hDistance != 0D){ - // TODO: Confine conditions further ? - // TODO: Code duplication: hDistAfterFailure - data.sfHorizontalBuffer = Math.min(1D, data.sfHorizontalBuffer - hDistanceAboveLimit); + if (data.sfHorizontalBuffer < hBufMax && hDistance > 0.0){ + hBufRegain(hDistance, hDistanceAboveLimit, data); } } @@ -206,7 +208,7 @@ public class SurvivalFly extends Check { // TODO: Complete re-modeling. if (hDistanceAboveLimit <= 0D && hDistance > 0.1D && yDistance == 0D && data.sfLastYDist == 0D && !toOnGround && !fromOnGround && BlockProperties.isLiquid(to.getTypeId())) { // TODO: Relative hdistance. - // TODO: Might check actual bounds, might implement + use BlockProperties.getCorrectedBounds. + // TODO: Might check actual bounds (collidesBlock). Might implement + use BlockProperties.getCorrectedBounds or getSomeHeight. hDistanceAboveLimit = Math.max(hDistanceAboveLimit, hDistance); tags.add("waterwalk"); } @@ -798,8 +800,7 @@ public class SurvivalFly extends Check { */ private double[] hDistAfterFailure(final Player player, final PlayerLocation from, final PlayerLocation to, double hAllowedDistance, final double hDistance, double hDistanceAboveLimit, final double yDistance, final boolean sprinting, final boolean downStream, final MovingData data, final MovingConfig cc) { - // TODO: Check bunny first ? - // TODO: check hdist first ? + // TODO: Not entirely sure about this checking order. // Check velocity. double hFreedom = 0.0; // Horizontal velocity used (!). @@ -810,23 +811,18 @@ public class SurvivalFly extends Check { hFreedom += data.useHorizontalVelocity(hDistanceAboveLimit - hFreedom); } if (hFreedom > 0.0){ + tags.add("hvel"); hDistanceAboveLimit = Math.max(0.0, hDistanceAboveLimit - hFreedom); } - - - // TODO: Checking order with bunny/normal-buffer ? // After failure permission checks ( + speed modifier + sneaking + blocking + speeding) and velocity (!). if (hDistanceAboveLimit > 0.0){ hAllowedDistance = getAllowedhDist(player, from, to, sprinting, downStream, hDistance, walkSpeed, data, cc, true); hDistanceAboveLimit = hDistance - hAllowedDistance; if (hFreedom > 0.0){ + // Duplicates above, due to re-checking the allowed distance. hDistanceAboveLimit -= hFreedom; } - if (hAllowedDistance > 0.0){ // TODO: Fix ! - // (Horizontal buffer might still get used.) - tags.add("hspeed"); - } } // "Bunny-hop". @@ -856,7 +852,7 @@ public class SurvivalFly extends Check { // Increase buffer by the needed amount. final double amount = hDistance - hAllowedDistance; // TODO: Might use min(hAllowedDistance and some maximal thing like sprinting speed?) - data.sfHorizontalBuffer = Math.min(1D, data.sfHorizontalBuffer) + amount; // Cheat ! + data.sfHorizontalBuffer = Math.min(hBufMax, data.sfHorizontalBuffer) + amount; // Cheat ! tags.add("bunnyfly"); } } @@ -864,29 +860,40 @@ public class SurvivalFly extends Check { } // Horizontal buffer. - if (hDistanceAboveLimit > 0D && data.sfHorizontalBuffer != 0D) { - if (data.sfHorizontalBuffer > 0D) { + if (hDistanceAboveLimit > 0.0) { + // Handle buffer only if moving too far. + if (data.sfHorizontalBuffer > 0.0) { + // Consume buffer. tags.add("hbufuse"); + final double amount = Math.min(data.sfHorizontalBuffer, hDistanceAboveLimit); + hDistanceAboveLimit -= amount; + // Ensure we never end up below zero. + data.sfHorizontalBuffer = Math.max(0.0, data.sfHorizontalBuffer - amount); } - else { - tags.add("hbufpen"); - } - // Try to consume the "buffer". - hDistanceAboveLimit -= data.sfHorizontalBuffer; - data.sfHorizontalBuffer = 0D; - - // Put back the "over-consumed" buffer. - if (hDistanceAboveLimit < 0D) { - data.sfHorizontalBuffer = -hDistanceAboveLimit; - } - } else if (hDistance != 0D){ - // TODO: Code duplication (see check). - data.sfHorizontalBuffer = Math.min(1D, data.sfHorizontalBuffer - hDistanceAboveLimit); + // else: No consumption. + } else if (data.sfHorizontalBuffer < hBufMax && hDistance > 0.0) { + hBufRegain(hDistance, hDistanceAboveLimit, data); } + // Add the hspeed tag on violation. + if (hDistanceAboveLimit > 0.0){ + tags.add("hspeed"); + } return new double[]{hAllowedDistance, hDistanceAboveLimit, hFreedom}; } + /** + * Legitimate move: increase horizontal buffer somehow. + * @param hDistance + * @param hDistanceAboveLimit + * @param data + */ + private void hBufRegain(final double hDistance, final double hDistanceAboveLimit, final MovingData data){ + // TODO: Consider different concepts (full resetting with harder conditions | maximum regain amount). + // TODO: Confine general conditions for buffer regain further ? + data.sfHorizontalBuffer = Math.min(hBufMax, data.sfHorizontalBuffer - hDistanceAboveLimit); + } + /** * Inside liquids vertical speed checking. * @param from