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 d79409f4..08faf3b6 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 @@ -184,6 +184,7 @@ public class MovingData extends ACheckData { * Last valid y distance covered by a move. Integer.MAX_VALUE indicates "not set". */ public double sfLastYDist = Double.MAX_VALUE; + public double sfLastHDist = Double.MAX_VALUE; /** Counting while the player is not on ground and not moving. A value <0 means not hovering at all. */ public int sfHoverTicks = -1; /** First count these down before incrementing sfHoverTicks. Set on join, if configured so. */ @@ -212,7 +213,7 @@ public class MovingData extends ACheckData { sfJumpPhase = 0; jumpAmplifier = 0; setBack = null; - sfLastYDist = Double.MAX_VALUE; + sfLastYDist = sfLastHDist = Double.MAX_VALUE; fromX = toX = Double.MAX_VALUE; clearAccounting(); clearNoFallData(); @@ -227,7 +228,7 @@ public class MovingData extends ACheckData { } /** - * Mildly reset the flying data without losing any important information. + * Teleport event: Mildly reset the flying data without losing any important information. * * @param setBack */ @@ -257,6 +258,20 @@ public class MovingData extends ACheckData { removeAllVelocity(); } + /** + * Move event: Mildly reset some data, prepare setting a new to-Location. + */ + public void prepareSetBack(final Location loc){ + clearAccounting(); + sfJumpPhase = 0; + sfLastYDist = sfLastHDist = Double.MAX_VALUE; + toWasReset = false; + fromWasReset = false; + // Remember where we send the player to. + setTeleported(loc); + // TODO: sfHoverTicks ? + } + /** * Just reset the "last locations" references. * @param loc @@ -285,7 +300,7 @@ public class MovingData extends ACheckData { fromX = toX = x; fromY = toY = y; fromZ = toZ = z; - sfLastYDist = Double.MAX_VALUE; + sfLastYDist = sfLastHDist = Double.MAX_VALUE; sfDirty = false; sfLowJump = false; mediumLiftOff = defaultMediumLiftOff; @@ -387,11 +402,19 @@ public class MovingData extends ACheckData { setBack.setY(y); } + /** + * Return a copy of the teleported-to Location. + * @return + */ public final Location getTeleported(){ // TODO: here a reference might do. return teleported == null ? teleported : LocUtil.clone(teleported); } + /** + * Set teleport-to location to recognize NCP set-backs. This copies the coordinates and world. + * @param loc + */ public final void setTeleported(final Location loc) { teleported = LocUtil.clone(loc); // Always overwrite. } @@ -499,9 +522,10 @@ public class MovingData extends ACheckData { } /** - * Called for moving events, increase age of velocity. + * Called for moving events, increase age of velocity, decrease amounts, check which entries are invalid. Both horizontal and vertical. */ public void velocityTick(){ + // Horizontal velocity (intermediate concept). // Decrease counts for active. // TODO: Actual friction. Could pass as an argument (special value for not to be used). // TODO: Consider removing already invalidated here. @@ -516,6 +540,29 @@ public class MovingData extends ACheckData { while (it.hasNext()){ it.next().actCount --; } + + // Vertical velocity (old concept). + if (verticalVelocity <= 0.09D){ + verticalVelocityUsed ++; + verticalVelocityCounter--; + } + else if (verticalVelocityCounter > 0D) { + verticalVelocityUsed ++; + verticalFreedom += verticalVelocity; + verticalVelocity = Math.max(0.0, verticalVelocity -0.09); + } else if (verticalFreedom > 0.001D){ + if (verticalVelocityUsed == 1 && verticalVelocity > 1.0){ + // Workarounds. + verticalVelocityUsed = 0; + verticalVelocity = 0; + verticalFreedom = 0; + } + else{ + // Counter has run out, now reduce the vertical freedom over time. + verticalVelocityUsed ++; + verticalFreedom *= 0.93D; + } + } } /** diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java index a47cefdb..6624a76f 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java @@ -517,33 +517,10 @@ public class MovingListener extends CheckListener implements TickListener, IRemo } // TODO: same for speed (once medium is introduced). - // Just try to estimate velocities over time. Not very precise, but works good enough most of the time. Do - // general data modifications one for each event. - // TODO: Rework to queued velocity entries: activation + invalidation + // Velocity tick (decrease + invalidation). + // TODO: Rework to generic (?) queued velocity entries: activation + invalidation data.removeInvalidVelocity(TickTask.getTick() - cc.velocityActivationTicks); data.velocityTick(); - // Vertical velocity. - if (data.verticalVelocity <= 0.09D){ - data.verticalVelocityUsed ++; - data.verticalVelocityCounter--; - } - else if (data.verticalVelocityCounter > 0D) { - data.verticalVelocityUsed ++; - data.verticalFreedom += data.verticalVelocity; - data.verticalVelocity = Math.max(0.0, data.verticalVelocity -0.09); - } else if (data.verticalFreedom > 0.001D){ - if (data.verticalVelocityUsed == 1 && data.verticalVelocity > 1.0){ - // Workarounds. - data.verticalVelocityUsed = 0; - data.verticalVelocity = 0; - data.verticalFreedom = 0; - } - else{ - // Counter has run out, now reduce the vertical freedom over time. - data.verticalVelocityUsed ++; - data.verticalFreedom *= 0.93D; - } - } // The players location. // TODO: Change to getLocation(moveInfo.loc) once 1.4.5 support is dropped. @@ -665,19 +642,13 @@ public class MovingListener extends CheckListener implements TickListener, IRemo // Did one of the checks decide we need a new "to"-location? if (newTo != null) { // Reset some data. - data.clearAccounting(); - data.sfJumpPhase = 0; - data.sfLastYDist = Double.MAX_VALUE; - data.toWasReset = false; - data.fromWasReset = false; - // TODO: data.sfHoverTicks ? + data.prepareSetBack(newTo); // Set new to-location. // TODO: Clone here for the case of using loc with loc = player.getLocation(moveInfo.loc). + // TODO: Actually should be a newly created location already (data.getSetBack). event.setTo(newTo); - - // Remember where we send the player to. - data.setTeleported(newTo); + // Debug. if (cc.debug){ System.out.println(player.getName() + " set back to: " + newTo.getWorld() + StringUtil.fdec3.format(newTo.getX()) + ", " + StringUtil.fdec3.format(newTo.getY()) + ", " + StringUtil.fdec3.format(newTo.getZ())); 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 15861aa9..6363b081 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 @@ -18,6 +18,7 @@ import fr.neatmonster.nocheatplus.utilities.ActionAccumulator; import fr.neatmonster.nocheatplus.utilities.BlockProperties; import fr.neatmonster.nocheatplus.utilities.PlayerLocation; import fr.neatmonster.nocheatplus.utilities.StringUtil; +import fr.neatmonster.nocheatplus.utilities.build.BuildParameters; /* * MP""""""`MM oo dP MM""""""""`M dP @@ -40,7 +41,7 @@ public class SurvivalFly extends Check { public static final double walkSpeed = 0.22D; public static final double modSneak = 0.13D / walkSpeed; - public static final double modSprint = 0.35D / walkSpeed; // TODO: without bunny 0.29 / ... + public static final double modSprint = 0.35D / walkSpeed; // TODO: without bunny 0.29 / ... // practical is 0.35 public static final double modBlock = 0.16D / walkSpeed; public static final double modSwim = 0.115D / walkSpeed; @@ -461,6 +462,7 @@ public class SurvivalFly extends Check { // } } // Adjust data. + data.sfLastHDist = hDistance; data.sfLastYDist = yDistance; data.toWasReset = resetTo || data.noFallAssumeGround; data.fromWasReset = resetFrom || data.noFallAssumeGround; @@ -827,11 +829,16 @@ public class SurvivalFly extends Check { if (hDistanceAboveLimit > 0 && sprinting){ // Try to treat it as a the "bunny-hop" problem. // TODO: sharpen the pre-conditions such that counter can be removed (add buffer ?) - if (data.bunnyhopDelay <= 0 && hDistanceAboveLimit > 0.05D && hDistanceAboveLimit < 0.28D && (data.sfJumpPhase == 0 || data.sfJumpPhase == 1 && data.noFallAssumeGround)) { - // TODO: Speed effect affects hDistanceAboveLimit? - data.bunnyhopDelay = bunnyHopMax; - hDistanceAboveLimit = 0D; // TODO: maybe relate buffer use to this + sprinting ? - tags.add("bunny"); // TODO: Which here... + if (data.bunnyhopDelay <= 0) { + if (hDistanceAboveLimit > 0.05D && hDistanceAboveLimit < 0.28D && (data.sfJumpPhase == 0 || data.sfJumpPhase == 1 && data.noFallAssumeGround)) { + // TODO: Speed effect affects hDistanceAboveLimit? + data.bunnyhopDelay = bunnyHopMax; + hDistanceAboveLimit = 0D; // TODO: maybe relate buffer use to this + sprinting ? + tags.add("bunny"); // TODO: Which here... + } + } + else { + // Might demand 0.05 decrease of speed. } } @@ -1230,13 +1237,9 @@ public class SurvivalFly extends Check { if (executeActions(vd)) { // Set-back or kick. if (data.hasSetBack()){ - data.clearAccounting(); - data.sfJumpPhase = 0; - data.sfLastYDist = Double.MAX_VALUE; - data.toWasReset = false; - data.fromWasReset = false; - data.setTeleported(data.getSetBack(loc)); - player.teleport(data.getTeleported()); + final Location newTo = data.getSetBack(loc); + data.prepareSetBack(newTo); + player.teleport(newTo); } else{ // Solve by extra actions ? Special case (probably never happens)? @@ -1272,7 +1275,7 @@ public class SurvivalFly extends Check { // Silently set back. if (!data.hasSetBack()) data.setSetBack(player.getLocation()); // ? check moment of call. data.sfJumpPhase = 0; - data.sfLastYDist = Double.MAX_VALUE; + data.sfLastYDist = data.sfLastHDist = Double.MAX_VALUE; return true; } else { return false; @@ -1325,7 +1328,8 @@ public class SurvivalFly extends Check { final String lostSprint = (data.lostSprintCount > 0 ? (" lostSprint=" + data.lostSprintCount) : ""); final String hVelUsed = hFreedom > 0 ? " hVelUsed=" + StringUtil.fdec3.format(hFreedom) : ""; builder.append(player.getName() + " SurvivalFly\nground: " + (data.noFallAssumeGround ? "(assumeonground) " : "") + (fromOnGround ? "onground -> " : (resetFrom ? "resetcond -> " : "--- -> ")) + (toOnGround ? "onground" : (resetTo ? "resetcond" : "---")) + ", jumpphase: " + data.sfJumpPhase); - builder.append("\n" + " hDist: " + StringUtil.fdec3.format(hDistance) + " / " + StringUtil.fdec3.format(hAllowedDistance) + hBuf + lostSprint + hVelUsed + " , vDist: " + StringUtil.fdec3.format(yDistance) + " (" + StringUtil.fdec3.format(to.getY() - data.getSetBackY()) + " / " + StringUtil.fdec3.format(vAllowedDistance) + "), sby=" + (data.hasSetBack() ? data.getSetBackY() : "?")); + final String dHDist = (BuildParameters.debugLevel > 0 && data.sfLastHDist != Double.MAX_VALUE && Math.abs(data.sfLastHDist - hDistance) > 0.005) ? ("(" + (hDistance > data.sfLastHDist ? "+" : "") + StringUtil.fdec3.format(hDistance - data.sfLastHDist) + ")") : ""; + builder.append("\n" + " hDist: " + StringUtil.fdec3.format(hDistance) + dHDist + " / " + StringUtil.fdec3.format(hAllowedDistance) + hBuf + lostSprint + hVelUsed + " , vDist: " + StringUtil.fdec3.format(yDistance) + " (" + StringUtil.fdec3.format(to.getY() - data.getSetBackY()) + " / " + StringUtil.fdec3.format(vAllowedDistance) + "), sby=" + (data.hasSetBack() ? data.getSetBackY() : "?")); if (data.verticalVelocityCounter > 0 || data.verticalFreedom >= 0.001){ builder.append("\n" + " vertical freedom: " + StringUtil.fdec3.format(data.verticalFreedom) + " (vel=" + StringUtil.fdec3.format(data.verticalVelocity) + "/counter=" + data.verticalVelocityCounter +"/used="+data.verticalVelocityUsed); }