Cap bounce effect by last y-distances. Set last h/v dist differently.

This should prevent bouncing higher and higher (cheat).

Missing:
* The bounce effect should be set considering the last yDistance, in
order to allow negative vertical velocity to work.
This commit is contained in:
asofold 2015-10-26 02:08:07 +01:00
parent bb25a0da0b
commit 0febcfef66
6 changed files with 101 additions and 38 deletions

View File

@ -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;
}

View File

@ -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.<br>
* 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);

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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