diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/CreativeFly.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/CreativeFly.java index c464cc08..210c9878 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/CreativeFly.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/CreativeFly.java @@ -12,6 +12,7 @@ import fr.neatmonster.nocheatplus.checks.Check; import fr.neatmonster.nocheatplus.checks.CheckType; import fr.neatmonster.nocheatplus.checks.ViolationData; import fr.neatmonster.nocheatplus.checks.moving.model.ModelFlying; +import fr.neatmonster.nocheatplus.checks.moving.model.MoveData; import fr.neatmonster.nocheatplus.compat.BridgeMisc; import fr.neatmonster.nocheatplus.logging.Streams; import fr.neatmonster.nocheatplus.utilities.PlayerLocation; @@ -40,7 +41,7 @@ public class CreativeFly extends Check { * @param time Millis. * @return */ - public Location check(final Player player, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc, final long time) { + public Location check(final Player player, final PlayerLocation from, final PlayerLocation to, final MoveData moveData, final MovingData data, final MovingConfig cc, final long time) { // Ensure we have a set-back location. if (!data.hasSetBack()) { @@ -58,12 +59,8 @@ public class CreativeFly extends Check { } // Calculate some distances. - final double xDistance = to.getX() - from.getX(); - final double yDistance = to.getY() - from.getY(); - final double zDistance = to.getZ() - from.getZ(); - - // How far did the player move horizontally? - final double hDistance = Math.sqrt(xDistance * xDistance + zDistance * zDistance); + final double yDistance = moveData.yDistance; + final double hDistance = moveData.hDistance; // Sprinting. final boolean sprinting = time <= data.timeSprinting + cc.sprintingGrace; @@ -188,8 +185,6 @@ public class CreativeFly extends Check { // Adjust the set-back and other last distances. data.setSetBack(to); - data.lastHDist = hDistance; - data.lastYDist = yDistance; return null; } 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 1704e4ba..4c4a236e 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 @@ -542,6 +542,9 @@ public class MovingListener extends CheckListener implements TickListener, IRemo onVehicleLeaveMiss(player, data, cc); } + // Set some data for this move. + moveInfo.data.set(pFrom, pTo); + // Potion effect "Jump". final double jumpAmplifier = survivalFly.getJumpAmplifier(player); if (jumpAmplifier > data.jumpAmplifier) { @@ -657,7 +660,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo // Actual check. if (newTo == null) { // Only check if passable has not already set back. - newTo = survivalFly.check(player, pFrom, pTo, isSamePos, data, cc, time); + newTo = survivalFly.check(player, pFrom, pTo, isSamePos, moveInfo.data, data, cc, time); } // Only check NoFall, if not already vetoed. if (checkNf) { @@ -701,7 +704,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo else if (checkCf) { // CreativeFly if (newTo == null) { - newTo = creativeFly.check(player, pFrom, pTo, data, cc, time); + newTo = creativeFly.check(player, pFrom, pTo, moveInfo.data, data, cc, time); } data.sfHoverTicks = -1; data.sfLowJump = false; @@ -730,13 +733,15 @@ public class MovingListener extends CheckListener implements TickListener, IRemo if (newTo == null) { - // Set positions. - // TODO: Consider setting in Monitor (concept missing for changing coordinates, could double-check). - data.setPositions(from, to); // Bounce effects. if (verticalBounce) { processBounce(player, pFrom.getY(), pTo.getY(), data, cc); } + // Set positions. + // TODO: Consider setting in Monitor (concept missing for changing coordinates, could double-check). + data.setPositions(from, to); + data.lastHDist = moveInfo.data.hDistance; + data.lastYDist = moveInfo.data.yDistance; return false; } else { @@ -749,7 +754,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo /** * Adjust data to allow bouncing back and/or removing fall damage.
* yDistance is < 0, the middle of the player is above a slime block (to) + - * on ground. + * on ground. This might be a micro-move onto ground. * * @param player * @param from @@ -761,7 +766,17 @@ public class MovingListener extends CheckListener implements TickListener, IRemo // Prepare velocity. final double fallDistance = MovingUtil.getRealisticFallDistance(player, fromY, toY, data); final double base = Math.sqrt(fallDistance) / 3.3; - final double effect = Math.min(3.14, base + Math.min(base / 10.0, SurvivalFly.GRAVITY_MAX)); // Ancient Greek technology with gravity added. + double effect = Math.min(3.5, base + Math.min(base / 10.0, SurvivalFly.GRAVITY_MAX)); // Ancient Greek technology with gravity added. + if (effect > 0.42) { + // Extra cap by last y distance(s). + final double max_gain = Math.abs(data.lastYDist < 0.0 ? Math.min(data.lastYDist, toY - fromY) : (toY - fromY)) - SurvivalFly.GRAVITY_SPAN; + if (max_gain < effect) { + effect = max_gain; + if (data.debug) { + DebugUtil.debug(player.getName() + " Cap bounce effect by recent y-distances."); + } + } + } // (Actually observed max. is near 3.5.) TODO: Why 3.14 then? if (data.debug) { NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " Bounce effect (dY=" + fallDistance + "): " + effect); 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 983f965f..432413fd 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 @@ -16,6 +16,7 @@ import fr.neatmonster.nocheatplus.checks.Check; import fr.neatmonster.nocheatplus.checks.CheckType; import fr.neatmonster.nocheatplus.checks.ViolationData; import fr.neatmonster.nocheatplus.checks.moving.model.LiftOffEnvelope; +import fr.neatmonster.nocheatplus.checks.moving.model.MoveData; import fr.neatmonster.nocheatplus.compat.BridgeEnchant; import fr.neatmonster.nocheatplus.logging.Streams; import fr.neatmonster.nocheatplus.permissions.Permissions; @@ -112,7 +113,7 @@ public class SurvivalFly extends Check { * @param isSamePos * @return the location */ - public Location check(final Player player, final PlayerLocation from, final PlayerLocation to, final boolean isSamePos, final MovingData data, final MovingConfig cc, final long now) { + public Location check(final Player player, final PlayerLocation from, final PlayerLocation to, final boolean isSamePos, final MoveData moveData, final MovingData data, final MovingConfig cc, final long now) { tags.clear(); // Calculate some distances. @@ -124,14 +125,14 @@ public class SurvivalFly extends Check { hasHdist = false; } else { xDistance = to.getX() - from.getX(); - yDistance = to.getY() - from.getY(); + yDistance = moveData.yDistance; zDistance = to.getZ() - from.getZ(); if (xDistance == 0.0 && zDistance == 0.0) { hDistance = 0.0; hasHdist = false; } else { - hDistance = Math.sqrt(xDistance * xDistance + zDistance * zDistance); hasHdist = true; + hDistance = moveData.hDistance; } } @@ -517,8 +518,6 @@ public class SurvivalFly extends Check { // } } // Adjust data. - data.lastHDist = hDistance; - data.lastYDist = yDistance; data.toWasReset = resetTo || data.noFallAssumeGround; data.fromWasReset = resetFrom || data.noFallAssumeGround; data.lastFrictionHorizontal = data.nextFrictionHorizontal; diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/locations/MoveInfo.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/locations/MoveInfo.java index af2cf058..2eca4478 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/locations/MoveInfo.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/locations/MoveInfo.java @@ -3,38 +3,50 @@ package fr.neatmonster.nocheatplus.checks.moving.locations; import org.bukkit.Location; import org.bukkit.entity.Player; +import fr.neatmonster.nocheatplus.checks.moving.model.MoveData; import fr.neatmonster.nocheatplus.compat.MCAccess; import fr.neatmonster.nocheatplus.utilities.BlockCache; import fr.neatmonster.nocheatplus.utilities.PlayerLocation; /** - * Coupling from and to PlayerLocation objects with a block cache for easy storage and reuse. + * Coupling from and to PlayerLocation objects with a block cache for easy + * storage and reuse. + * * @author mc_dev * */ public class MoveInfo { - - /** For temporary use. Might need cloning for passing to external API. Only use after calling MoveInfo.set! */ + + /** + * Might need cloning for passing to external API. This is not initialized + * in set. World is set to null on cleanup! + */ public final Location useLoc = new Location(null, 0, 0, 0); - public final BlockCache cache; + public final BlockCache cache; public final PlayerLocation from; public final PlayerLocation to; - + /** Not initialized in set. */ + public final MoveData data = new MoveData(); + public MoveInfo(final MCAccess mcAccess){ - cache = mcAccess.getBlockCache(null); - from = new PlayerLocation(mcAccess, null); - to = new PlayerLocation(mcAccess, null); + cache = mcAccess.getBlockCache(null); + from = new PlayerLocation(mcAccess, null); + to = new PlayerLocation(mcAccess, null); } - + /** - * Initialize from, and if given to. Note that useLoc is left untouched (!). + * Initialize from, and if given to. Note that useLoc and data are left + * untouched. + * * @param player - * @param from Must not be null. - * @param to Can be null. + * @param from + * Must not be null. + * @param to + * Can be null. * @param yOnGround */ public final void set(final Player player, final Location from, final Location to, final double yOnGround){ - this.cache.setAccess(from.getWorld()); + this.cache.setAccess(from.getWorld()); this.from.set(from, player, yOnGround); this.from.setBlockCache(cache); if (to != null){ @@ -43,15 +55,17 @@ public class MoveInfo { } // Note: using set to reset to by passing null won't work. } - + /** - * Clear caches and remove World references and such. Also resets the world of useLoc. + * Clear caches and remove World references and such. Also resets the world + * of useLoc. */ public final void cleanup(){ - useLoc.setWorld(null); + useLoc.setWorld(null); from.cleanup(); to.cleanup(); cache.cleanup(); + data.reset(); } - + } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/model/MoveData.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/model/MoveData.java new file mode 100644 index 00000000..fe0879d0 --- /dev/null +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/model/MoveData.java @@ -0,0 +1,29 @@ +package fr.neatmonster.nocheatplus.checks.moving.model; + +import fr.neatmonster.nocheatplus.utilities.PlayerLocation; +import fr.neatmonster.nocheatplus.utilities.TrigUtil; + +/** + * Carry data of a move, involving from- and to- location. + * + * @author asofold + * + */ +public class MoveData { + + // TODO: Invalidation flag? + + public double yDistance = Double.MAX_VALUE; + public double hDistance = Double.MAX_VALUE; + + public void set(PlayerLocation from, PlayerLocation to) { + yDistance = to.getY()- from.getY(); + hDistance = TrigUtil.xzDistance(from, to); + } + + public void reset() { + yDistance = Double.MAX_VALUE; + hDistance = Double.MAX_VALUE; + } + +} diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/TrigUtil.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/TrigUtil.java index 65a821a0..11a96767 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/TrigUtil.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/TrigUtil.java @@ -300,6 +300,17 @@ public class TrigUtil { return distance(location1.getX(), location1.getZ(), location2.getX(), location2.getZ()); } + /** + * 2D-distance in x-z plane. + * @param location1 + * @param location2 + * @return + */ + public static final double xzDistance(final PlayerLocation location1, final PlayerLocation location2) + { + return distance(location1.getX(), location1.getZ(), location2.getX(), location2.getZ()); + } + /** * 2D-distance. * @param x1