mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-03-12 14:39:12 +01:00
[BREAKING] Use MoveData for more 'last123'-type properties.
Does break use of MovingData for last coordinates and distances (not officially exposed API). Other changes: * Position resetting on teleport events has been altered. * Some blocks/methods are guarded by checking for lastMove.toIsValid. * Possibly other.
This commit is contained in:
parent
2145a6a0d3
commit
16a1e08f57
@ -31,6 +31,7 @@ import fr.neatmonster.nocheatplus.checks.moving.MovingData;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.locations.LocationTrace;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.locations.LocationTrace.TraceEntry;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.model.LiftOffEnvelope;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.util.MovingUtil;
|
||||
import fr.neatmonster.nocheatplus.compat.BridgeEnchant;
|
||||
import fr.neatmonster.nocheatplus.compat.BridgeHealth;
|
||||
@ -283,8 +284,9 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
||||
if (!cancelled && TrigUtil.distance(loc.getX(), loc.getZ(), damagedLoc.getX(), damagedLoc.getZ()) < 4.5){
|
||||
final MovingData mData = MovingData.getData(player);
|
||||
// Check if fly checks is an issue at all, re-check "real sprinting".
|
||||
if (mData.fromX != Double.MAX_VALUE && mData.liftOffEnvelope == LiftOffEnvelope.NORMAL) {
|
||||
final double hDist = TrigUtil.distance(loc.getX(), loc.getZ(), mData.fromX, mData.fromZ);
|
||||
final MoveData lastMove = mData.moveData.getFirst();
|
||||
if (lastMove.valid && mData.liftOffEnvelope == LiftOffEnvelope.NORMAL) {
|
||||
final double hDist = TrigUtil.distance(loc.getX(), loc.getZ(), lastMove.fromX, lastMove.fromZ);
|
||||
if (hDist >= 0.23) {
|
||||
// TODO: Might need to check hDist relative to speed / modifiers.
|
||||
final MovingConfig mc = MovingConfig.getConfig(player);
|
||||
|
@ -45,6 +45,7 @@ public class CreativeFly extends Check {
|
||||
|
||||
// Edge data for this move.
|
||||
final MoveData thisMove = data.thisMove;
|
||||
final MoveData lastMove = data.moveData.getFirst();
|
||||
|
||||
// Ensure we have a set-back location.
|
||||
if (!data.hasSetBack()) {
|
||||
@ -139,9 +140,9 @@ public class CreativeFly extends Check {
|
||||
limitV *= data.flySpeed / 0.1;
|
||||
}
|
||||
|
||||
if (data.lastYDist != Double.MAX_VALUE) {
|
||||
if (lastMove.toIsValid) {
|
||||
// (Disregard gravity.)
|
||||
double frictionDist = data.lastYDist * SurvivalFly.FRICTION_MEDIUM_AIR;
|
||||
double frictionDist = lastMove.yDistance * SurvivalFly.FRICTION_MEDIUM_AIR;
|
||||
if (!flying) {
|
||||
frictionDist -= SurvivalFly.GRAVITY_MIN;
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.access.ACheckData;
|
||||
import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory;
|
||||
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
|
||||
@ -127,16 +126,6 @@ public class MovingData extends ACheckData {
|
||||
/** Last time the player was actually sprinting. */
|
||||
public long timeSprinting = 0;
|
||||
public double multSprinting = 1.30000002; // Multiplier at the last time sprinting.
|
||||
/**
|
||||
* Last valid y distance covered by a move. Integer.MAX_VALUE indicates "not set".
|
||||
*/
|
||||
public double lastYDist = Double.MAX_VALUE;
|
||||
/**
|
||||
* Last valid horizontal distance covered by a move. Integer.MAX_VALUE indicates "not set".
|
||||
*/
|
||||
public double lastHDist = Double.MAX_VALUE;
|
||||
/** Last flying check used (creativefly, survivalfly, unknown), used for hacks. */
|
||||
public CheckType lastFlyCheck = CheckType.UNKNOWN;
|
||||
/** Just used velocity, during processing of moving checks. */
|
||||
public SimpleEntry verVelUsed = null;
|
||||
/** Compatibility entry for bouncing of slime blocks and the like. */
|
||||
@ -169,12 +158,6 @@ public class MovingData extends ACheckData {
|
||||
private final FrictionAxisVelocity horVel = new FrictionAxisVelocity();
|
||||
|
||||
// Coordinates.
|
||||
/** Last from coordinates. X is at Double.MAX_VALUE, if not set. */
|
||||
public double fromX = Double.MAX_VALUE, fromY, fromZ;
|
||||
/** Last to coordinates. X is at Double.MAX_VALUE, if not set. */
|
||||
public double toX = Double.MAX_VALUE, toY, toZ;
|
||||
/** Last to looking direction. Yaw is at Float.MAX_VALUE if not set. */
|
||||
public float toYaw = Float.MAX_VALUE, toPitch ;
|
||||
/** Moving trace (to-positions, use tick as time). This is initialized on "playerJoins, i.e. MONITOR, and set to null on playerLeaves." */
|
||||
private LocationTrace trace = null;
|
||||
|
||||
@ -306,11 +289,7 @@ public class MovingData extends ACheckData {
|
||||
sfJumpPhase = 0;
|
||||
jumpAmplifier = 0;
|
||||
setBack = null;
|
||||
lastYDist = lastHDist = Double.MAX_VALUE;
|
||||
lastFlyCheck = CheckType.UNKNOWN;
|
||||
sfZeroVdist = 0;
|
||||
fromX = toX = Double.MAX_VALUE;
|
||||
toYaw = Float.MAX_VALUE;
|
||||
clearAccounting();
|
||||
clearNoFallData();
|
||||
removeAllVelocity();
|
||||
@ -370,8 +349,6 @@ public class MovingData extends ACheckData {
|
||||
invalidateMoveData();
|
||||
clearAccounting();
|
||||
sfJumpPhase = 0;
|
||||
lastYDist = lastHDist = Double.MAX_VALUE;
|
||||
lastFlyCheck = CheckType.UNKNOWN;
|
||||
sfZeroVdist = 0;
|
||||
toWasReset = false;
|
||||
fromWasReset = false;
|
||||
@ -441,34 +418,21 @@ public class MovingData extends ACheckData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset edge data for last moves.
|
||||
* Invalidate all past moves data and set the last position to the given
|
||||
* coordinates.
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/
|
||||
public void resetPositions(final double x, final double y, final double z, final float yaw, final float pitch) {
|
||||
invalidateMoveData();
|
||||
moveData.get(0).set(x, y, z, yaw, pitch);
|
||||
fromX = toX = x;
|
||||
fromY = toY = y;
|
||||
fromZ = toZ = z;
|
||||
toYaw = yaw;
|
||||
toPitch = pitch;
|
||||
lastYDist = lastHDist = Double.MAX_VALUE;
|
||||
lastFlyCheck = CheckType.UNKNOWN;
|
||||
sfZeroVdist = 0;
|
||||
sfDirty = false;
|
||||
sfLowJump = false;
|
||||
liftOffEnvelope = defaultLiftOffEnvelope;
|
||||
insideMediumCount = 0;
|
||||
lastFrictionHorizontal = lastFrictionVertical = 0.0;
|
||||
verticalBounce = null;
|
||||
// TODO: other buffers ?
|
||||
// No reset of vehicleConsistency.
|
||||
resetPositions();
|
||||
moveData.getFirst().set(x, y, z, yaw, pitch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Just reset the "last locations" references.
|
||||
* Invalidate all past moves data and set last position if not null.
|
||||
*
|
||||
* @param loc
|
||||
*/
|
||||
public void resetPositions(PlayerLocation loc) {
|
||||
@ -481,7 +445,8 @@ public class MovingData extends ACheckData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Just reset the "last locations" references.
|
||||
* Invalidate all past moves data and set last position if not null.
|
||||
*
|
||||
* @param loc
|
||||
*/
|
||||
public void resetPositions(final Location loc) {
|
||||
@ -494,32 +459,19 @@ public class MovingData extends ACheckData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the "last locations" to "not set".
|
||||
* Invalidate all past moves data.
|
||||
*/
|
||||
public void resetPositions() {
|
||||
resetPositions(Double.MAX_VALUE, 0.0, 0.0, Float.MAX_VALUE, 0f);
|
||||
}
|
||||
|
||||
public void resetLastDistances() {
|
||||
// TODO: Will change with moveData in use.
|
||||
lastHDist = lastYDist = Double.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set positions according to a move (just to and from).
|
||||
* @param from
|
||||
* @param to
|
||||
*/
|
||||
public void setPositions(final Location from, final Location to) {
|
||||
// TODO: Will change with moveData in use..
|
||||
fromX = from.getX();
|
||||
fromY = from.getY();
|
||||
fromZ = from.getZ();
|
||||
toX = to.getX();
|
||||
toY = to.getY();
|
||||
toZ = to.getZ();
|
||||
toYaw = to.getYaw();
|
||||
toPitch = to.getPitch();
|
||||
invalidateMoveData();
|
||||
sfZeroVdist = 0;
|
||||
sfDirty = false;
|
||||
sfLowJump = false;
|
||||
liftOffEnvelope = defaultLiftOffEnvelope;
|
||||
insideMediumCount = 0;
|
||||
lastFrictionHorizontal = lastFrictionVertical = 0.0;
|
||||
verticalBounce = null;
|
||||
// TODO: other buffers ?
|
||||
// No reset of vehicleConsistency.
|
||||
}
|
||||
|
||||
/**
|
||||
@ -702,18 +654,6 @@ public class MovingData extends ACheckData {
|
||||
setBack = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just set the last "to-coordinates", no world check.
|
||||
* @param to
|
||||
*/
|
||||
public final void setTo(final Location to) {
|
||||
toX = to.getX();
|
||||
toY = to.getY();
|
||||
toZ = to.getZ();
|
||||
toYaw = to.getYaw();
|
||||
toPitch = to.getPitch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add velocity to internal book-keeping.
|
||||
* @param player
|
||||
|
@ -56,6 +56,7 @@ import fr.neatmonster.nocheatplus.checks.moving.locations.MoveInfo;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.locations.VehicleSetBack;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.model.LiftOffEnvelope;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.model.MoveConsistency;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.util.MovingUtil;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.velocity.AccountEntry;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.velocity.SimpleEntry;
|
||||
@ -403,8 +404,10 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
final MovingConfig cc = MovingConfig.getConfig(player);
|
||||
final MoveInfo moveInfo = useMoveInfo();
|
||||
final Location loc = player.getLocation(moveInfo.useLoc);
|
||||
final MoveData lastMove = data.moveData.getFirst();
|
||||
// TODO: On pistons pulling the player back: -1.15 yDistance for split move 1 (untracked position > 0.5 yDistance!).
|
||||
if (TrigUtil.isSamePos(from, loc)
|
||||
|| TrigUtil.isSamePos(loc, data.fromX, data.fromY, data.fromZ)
|
||||
|| lastMove.valid && TrigUtil.isSamePos(loc, lastMove.fromX, lastMove.fromY, lastMove.fromZ)
|
||||
// Could also be other envelopes (0.9 velocity upwards), too tedious to research.
|
||||
//&& data.lastYDist < -SurvivalFly.GRAVITY_MIN && data.lastYDist > -SurvivalFly.GRAVITY_MAX - SurvivalFly.GRAVITY_MIN
|
||||
) {
|
||||
@ -545,6 +548,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
|
||||
// Set some data for this move.
|
||||
data.thisMove.set(pFrom, pTo);
|
||||
final MoveData lastMove = data.moveData.getFirst();
|
||||
|
||||
// Potion effect "Jump".
|
||||
final double jumpAmplifier = survivalFly.getJumpAmplifier(player);
|
||||
@ -611,7 +615,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// Fake use velocity here.
|
||||
data.prependVerticalVelocity(new SimpleEntry(tick, 0.0, 1));
|
||||
data.getOrUseVerticalVelocity(0.0);
|
||||
if (data.lastYDist < 0.0) {
|
||||
if (lastMove.toIsValid && lastMove.yDistance < 0.0) {
|
||||
// Renew the bounce effect.
|
||||
data.verticalBounce = new SimpleEntry(tick, data.verticalBounce.value, 1);
|
||||
}
|
||||
@ -658,7 +662,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
}
|
||||
|
||||
// Hack: Add velocity for transitions between creativefly and survivalfly.
|
||||
if (data.lastFlyCheck == CheckType.MOVING_CREATIVEFLY && data.lastHDist != Double.MAX_VALUE) {
|
||||
if (lastMove.toIsValid && lastMove.flyCheck == CheckType.MOVING_CREATIVEFLY) {
|
||||
workaroundFlyNoFlyTransition(tick, data);
|
||||
}
|
||||
|
||||
@ -705,7 +709,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
}
|
||||
}
|
||||
}
|
||||
data.lastFlyCheck = CheckType.MOVING_SURVIVALFLY;
|
||||
data.thisMove.flyCheck = CheckType.MOVING_SURVIVALFLY;
|
||||
}
|
||||
else if (checkCf) {
|
||||
// CreativeFly
|
||||
@ -714,7 +718,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
}
|
||||
data.sfHoverTicks = -1;
|
||||
data.sfLowJump = false;
|
||||
data.lastFlyCheck = CheckType.MOVING_CREATIVEFLY;
|
||||
data.thisMove.flyCheck = CheckType.MOVING_CREATIVEFLY;
|
||||
}
|
||||
else {
|
||||
// No fly checking :(.
|
||||
@ -740,14 +744,12 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
|
||||
|
||||
if (newTo == null) {
|
||||
// Allowed move.
|
||||
// Bounce effects.
|
||||
if (verticalBounce) {
|
||||
processBounce(player, pFrom.getY(), pTo.getY(), data, cc);
|
||||
}
|
||||
// Set positions.
|
||||
data.setPositions(from, to);
|
||||
data.lastHDist = data.thisMove.hDistance;
|
||||
data.lastYDist = data.thisMove.yDistance;
|
||||
// Finished move processing.
|
||||
data.finishThisMove();
|
||||
return false;
|
||||
}
|
||||
@ -766,9 +768,10 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
* @param data
|
||||
*/
|
||||
private static void workaroundFlyNoFlyTransition(final int tick, final MovingData data) {
|
||||
final double amount = data.lastHDist * SurvivalFly.FRICTION_MEDIUM_AIR;
|
||||
final MoveData lastMove = data.moveData.getFirst();
|
||||
final double amount = lastMove.hDistance * SurvivalFly.FRICTION_MEDIUM_AIR;
|
||||
data.addHorizontalVelocity(new AccountEntry(tick, amount, 1, MovingData.getHorVelValCount(amount)));
|
||||
data.addVerticalVelocity(new SimpleEntry(data.lastYDist, 2));
|
||||
data.addVerticalVelocity(new SimpleEntry(lastMove.yDistance, 2));
|
||||
data.addVerticalVelocity(new SimpleEntry(0.0, 2));
|
||||
data.setFrictionJumpPhase();
|
||||
}
|
||||
@ -789,9 +792,10 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
final double fallDistance = MovingUtil.getRealisticFallDistance(player, fromY, toY, data);
|
||||
final double base = Math.sqrt(fallDistance) / 3.3;
|
||||
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) {
|
||||
final MoveData lastMove = data.moveData.getFirst();
|
||||
if (effect > 0.42 && lastMove.toIsValid) {
|
||||
// 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;
|
||||
final double max_gain = Math.abs(lastMove.yDistance < 0.0 ? Math.min(lastMove.yDistance, toY - fromY) : (toY - fromY)) - SurvivalFly.GRAVITY_SPAN;
|
||||
if (max_gain < effect) {
|
||||
effect = max_gain;
|
||||
if (data.debug) {
|
||||
@ -976,7 +980,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
* @param mData
|
||||
*/
|
||||
private void onMoveMonitorNotCancelled(final Player player, final Location from, final Location to, final long now, final long tick, final CombinedData data, final MovingData mData) {
|
||||
data.lastMoveTime = now; // TODO: Evaluate moving this to MovingData !?
|
||||
data.lastMoveTime = now; // TODO: Move to MovingData ?
|
||||
final String toWorldName = to.getWorld().getName();
|
||||
Combined.feedYawRate(player, to.getYaw(), now, toWorldName, data);
|
||||
// TODO: maybe even not count vehicles at all ?
|
||||
@ -988,11 +992,19 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
mData.updateTrace(player, to, tick); // TODO: Can you become invincible by sending special moves?
|
||||
}
|
||||
else if (!from.getWorld().getName().equals(toWorldName)) {
|
||||
// A teleport event should follow.
|
||||
mData.resetPositions(to);
|
||||
mData.resetTrace(player, to, tick);
|
||||
}
|
||||
else {
|
||||
mData.setTo(to); // Called on lowest too.
|
||||
// TODO: Detect differing location (a teleport event would follow).
|
||||
final MoveData lastMove = mData.moveData.getFirst();
|
||||
if (!lastMove.toIsValid || !TrigUtil.isSamePos(to, lastMove.toX, lastMove.toY, lastMove.toZ)) {
|
||||
// Something odd happened.
|
||||
mData.resetPositions(to);
|
||||
} else {
|
||||
// Normal move, nothing to do.
|
||||
}
|
||||
mData.updateTrace(player, to, tick);
|
||||
}
|
||||
}
|
||||
@ -1091,7 +1103,8 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
if (TrigUtil.distance(from, to) < margin) {
|
||||
smallRange = true;
|
||||
}
|
||||
else if (data.toX != Double.MAX_VALUE && data.hasSetBack()) {
|
||||
else if (data.hasSetBack()) {
|
||||
// (Removed demand for a past move to be present - remember on issues.)
|
||||
final Location setBack = data.getSetBack(to);
|
||||
if (TrigUtil.distance(to.getX(), to.getY(), to.getZ(), setBack.getX(), setBack.getY(), setBack.getZ()) < margin) {
|
||||
smallRange = true;
|
||||
@ -1140,9 +1153,10 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
ref = data.getSetBack(to);
|
||||
event.setTo(ref);
|
||||
adjustLiftOffEnvelope(player, ref, data, cc);
|
||||
data.resetPositions(ref);
|
||||
}
|
||||
else {
|
||||
ref = from; // Player.getLocation ?
|
||||
ref = from;
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@ -1161,6 +1175,13 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
final MoveData lastMove = data.moveData.getFirst();
|
||||
if (lastMove.toIsValid) {
|
||||
// TODO: Could keep on ground
|
||||
lastMove.set(lastMove.toX, lastMove.toY, lastMove.toZ, ref.getYaw(), ref.getPitch());
|
||||
} else {
|
||||
data.resetPositions(ref);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// "real" teleport
|
||||
@ -1169,7 +1190,6 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
final LiftOffEnvelope oldEnv = data.liftOffEnvelope; // Remember for workarounds.
|
||||
data.clearMorePacketsData();
|
||||
data.clearFlyData();
|
||||
data.resetPositions(to);
|
||||
if (TrigUtil.maxDistance(from.getX(), from.getY(), from.getZ(), to.getX(), to.getY(), to.getZ()) <= 12.0) {
|
||||
// TODO: Might happen with bigger distances (mainly ender pearl thrown at others).
|
||||
// Keep old lift-off envelope.
|
||||
@ -1190,6 +1210,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
data.noFallSkipAirCheck = true;
|
||||
}
|
||||
data.sfHoverTicks = -1; // Important against concurrent modification exception.
|
||||
data.resetPositions(ref);
|
||||
}
|
||||
|
||||
if (data.debug && BuildParameters.debugLevel > 0) {
|
||||
@ -1208,9 +1229,8 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
|
||||
}
|
||||
// Reset stuff.
|
||||
Combined.resetYawRate(player, ref.getYaw(), System.currentTimeMillis(), true);
|
||||
Combined.resetYawRate(player, ref.getYaw(), System.currentTimeMillis(), true); // TODO: Not sure.
|
||||
data.resetTeleported();
|
||||
data.resetLastDistances();
|
||||
// Prevent further moving processing for nested events.
|
||||
processingEvents.remove(player.getName());
|
||||
}
|
||||
@ -1489,7 +1509,6 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
}
|
||||
// (Note: resetPositions resets lastFlyCheck and other.)
|
||||
|
||||
data.resetLastDistances();
|
||||
data.clearMorePacketsData();
|
||||
data.removeAllVelocity();
|
||||
data.resetTrace(loc, tick, cc.traceSize, cc.traceMergeDist); // Might reset to loc instead of set-back ?
|
||||
@ -1555,8 +1574,9 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// Check for missed moves.
|
||||
// TODO: Consider to catch all, at least (debug-) logging-wise.
|
||||
if (!BlockProperties.isPassable(loc)) {
|
||||
if (data.toX != Double.MAX_VALUE) {
|
||||
final Location refLoc = new Location(loc.getWorld(), data.toX, data.toY, data.toZ);
|
||||
final MoveData lastMove = data.moveData.getFirst();
|
||||
if (lastMove.toIsValid) {
|
||||
final Location refLoc = new Location(loc.getWorld(), lastMove.toX, lastMove.toY, lastMove.toZ);
|
||||
final double d = refLoc.distanceSquared(loc);
|
||||
if (d > 0.0) {
|
||||
// TODO: Consider to always set back here. Might skip on big distances.
|
||||
@ -1675,9 +1695,12 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// TODO: What with the case of vehicle moved to another world !?
|
||||
loc = vLoc; //
|
||||
if (data.vehicleConsistency != MoveConsistency.INCONSISTENT) {
|
||||
final Location oldLoc = new Location(pLoc.getWorld(), data.toX, data.toY, data.toZ);
|
||||
if (data.toX != Double.MAX_VALUE && MoveConsistency.getConsistency(oldLoc, null, pLoc) != MoveConsistency.INCONSISTENT) {
|
||||
loc = oldLoc;
|
||||
final MoveData lastMove = data.moveData.getFirst();
|
||||
if (lastMove.toIsValid) {
|
||||
final Location oldLoc = new Location(pLoc.getWorld(), lastMove.toX, lastMove.toY, lastMove.toZ);
|
||||
if (MoveConsistency.getConsistency(oldLoc, null, pLoc) != MoveConsistency.INCONSISTENT) {
|
||||
loc = oldLoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1817,7 +1840,8 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
}
|
||||
|
||||
private Location enforceLocation(final Player player, final Location loc, final MovingData data) {
|
||||
if (data.toX != Double.MAX_VALUE && TrigUtil.distanceSquared(data.toX, data.toY, data.toZ, loc.getX(), loc.getY(), loc.getZ()) > 1.0 / 256.0) {
|
||||
final MoveData lastMove = data.moveData.getFirst();
|
||||
if (lastMove.toIsValid && TrigUtil.distanceSquared(lastMove.toX, lastMove.toY, lastMove.toZ, loc.getX(), loc.getY(), loc.getZ()) > 1.0 / 256.0) {
|
||||
// Teleport back.
|
||||
// TODO: Add history / alert?
|
||||
//player.sendMessage(ChatColor.RED + "NCP: enforce location !"); // TODO: DEBUG - REMOVE.
|
||||
@ -1826,7 +1850,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// Could use a flexible set-back policy (switch to in-air on login).
|
||||
return data.getSetBack(loc);
|
||||
} else {
|
||||
return new Location(player.getWorld(), data.toX, data.toY, data.toZ, loc.getYaw(), loc.getPitch());
|
||||
return new Location(player.getWorld(), lastMove.toX, lastMove.toY, lastMove.toZ, loc.getYaw(), loc.getPitch());
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,16 +1,21 @@
|
||||
package fr.neatmonster.nocheatplus.checks.moving.model;
|
||||
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
|
||||
import fr.neatmonster.nocheatplus.utilities.TrigUtil;
|
||||
|
||||
/**
|
||||
* Carry data of a move, involving from- and to- locations.
|
||||
* Carry data of a move, involving from- and to- locations. This is for
|
||||
* temporary storage and often resetting, also to encapsulate some data during
|
||||
* checking.
|
||||
*
|
||||
* @author asofold
|
||||
*
|
||||
*/
|
||||
public class MoveData {
|
||||
|
||||
// TODO: Use objects for from and to (could lead to redesign, think of PlayerLocation)?
|
||||
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Guaranteed to be initialized with set.
|
||||
@ -21,25 +26,61 @@ public class MoveData {
|
||||
*/
|
||||
public boolean valid = false;
|
||||
|
||||
/** Double.MAX_VALUE if not available, e.g. after a teleport. */
|
||||
public double yDistance = Double.MAX_VALUE;
|
||||
/** Double.MAX_VALUE if not available, e.g. after a teleport. */
|
||||
public double hDistance = Double.MAX_VALUE;
|
||||
/**
|
||||
* Start position coordinates.
|
||||
*/
|
||||
public double fromX, fromY, fromZ;
|
||||
/** Looking direction of the start position. */
|
||||
public float fromYaw, fromPitch;
|
||||
|
||||
/**
|
||||
* Indicate if coordinates for a move end-point and distances are present.
|
||||
* Always set on setPositions call.
|
||||
*/
|
||||
public boolean toIsValid = false;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// Only set if a move end-point is set, i.e. toIsValid set to true.
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** End-point of a move. Only valid if toIsValid is set to true. */
|
||||
public double toX, toY, toZ;
|
||||
|
||||
/** Looking direction of a move end-point. Only valid if toIsValid is set to true. */
|
||||
public float toYaw, toPitch;
|
||||
|
||||
/**
|
||||
* The vertical distance covered by a move. Note the sign for moving up or
|
||||
* down. Only valid if toIsValid is set to true.
|
||||
*/
|
||||
public double yDistance;
|
||||
|
||||
/**
|
||||
* The horizontal distance covered by a move. Note the sign for moving up or
|
||||
* down. Only valid if toIsValid is set to true.
|
||||
*/
|
||||
public double hDistance;
|
||||
|
||||
// TODO: Last coords,
|
||||
// TODO: Velocity used, fly check, ...
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// Reset with set, could be lazily initialized.
|
||||
// Reset with set, could be lazily set during checking.
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Head is obstructed. Should expect descending next move, if in air. <br>
|
||||
* Set at the beginning of SurvivalFly.check, if either end point is not on ground.
|
||||
* Set at the beginning of SurvivalFly.check, if either end-point is not on
|
||||
* ground.
|
||||
*/
|
||||
public boolean headObstructed = false;
|
||||
|
||||
|
||||
/**
|
||||
* The fly check that was using the current data. One of MOVING_SURVIVALFLY,
|
||||
* MOVING_CREATIVEFLY, UNKNOWN.
|
||||
*/
|
||||
public CheckType flyCheck = CheckType.UNKNOWN;
|
||||
|
||||
// TODO: ground/reset/web/...
|
||||
|
||||
/**
|
||||
@ -59,6 +100,17 @@ public class MoveData {
|
||||
final double toX, final double toY, final double toZ, final float toYaw, final float toPitch) {
|
||||
yDistance = toY - fromY;
|
||||
hDistance = TrigUtil.distance(fromX, fromZ, toX, toZ);
|
||||
this.fromX = fromX;
|
||||
this.fromY = fromY;
|
||||
this.fromZ = fromZ;
|
||||
this.fromYaw = fromYaw;
|
||||
this.fromPitch = fromPitch;
|
||||
this.toX = toX;
|
||||
this.toY = toY;
|
||||
this.toZ = toZ;
|
||||
this.toYaw = toYaw;
|
||||
this.toPitch = toPitch;
|
||||
toIsValid = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,12 +122,17 @@ public class MoveData {
|
||||
* @param pitch
|
||||
*/
|
||||
private void setPositions(final double x, final double y, final double z, final float yaw, final float pitch) {
|
||||
yDistance = Double.MAX_VALUE;
|
||||
hDistance = Double.MAX_VALUE;
|
||||
this.fromX = x;
|
||||
this.fromY = y;
|
||||
this.fromZ = z;
|
||||
this.fromYaw = yaw;
|
||||
this.fromPitch = pitch;
|
||||
toIsValid = false;
|
||||
}
|
||||
|
||||
private void resetBase() {
|
||||
headObstructed = false;
|
||||
flyCheck = CheckType.UNKNOWN;
|
||||
valid = true;
|
||||
}
|
||||
|
||||
@ -109,6 +166,7 @@ public class MoveData {
|
||||
*/
|
||||
public void invalidate() {
|
||||
valid = false;
|
||||
toIsValid = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.MovingConfig;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
|
||||
import fr.neatmonster.nocheatplus.compat.BridgeMisc;
|
||||
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
|
||||
import fr.neatmonster.nocheatplus.logging.StaticLog;
|
||||
@ -149,12 +150,13 @@ public class MovingUtil {
|
||||
if (TrigUtil.isSamePos(loc, refLoc) && (entity instanceof Player)) {
|
||||
final Player other = (Player) entity;
|
||||
final MovingData otherData = MovingData.getData(other);
|
||||
if (otherData.toX == Double.MAX_VALUE) {
|
||||
final MoveData otherLastMove = otherData.moveData.getFirst();
|
||||
if (!otherLastMove.toIsValid) {
|
||||
// Data might have been removed.
|
||||
// TODO: Consider counting as tracked?
|
||||
continue;
|
||||
}
|
||||
else if (TrigUtil.isSamePos(refLoc, otherData.toX, otherData.toY, otherData.toZ)) {
|
||||
else if (TrigUtil.isSamePos(refLoc, otherLastMove.toX, otherLastMove.toY, otherLastMove.toZ)) {
|
||||
// Tracked.
|
||||
return null;
|
||||
}
|
||||
@ -163,7 +165,7 @@ public class MovingUtil {
|
||||
// TODO: Discard locations in the same block, if passable.
|
||||
// TODO: Sanity check distance?
|
||||
// More leniency: allow moving inside of the same block.
|
||||
if (TrigUtil.isSameBlock(loc, otherData.toX, otherData.toY, otherData.toZ) && !BlockProperties.isPassable(refLoc.getWorld(), otherData.toX, otherData.toY, otherData.toZ)) {
|
||||
if (TrigUtil.isSameBlock(loc, otherLastMove.toX, otherLastMove.toY, otherLastMove.toZ) && !BlockProperties.isPassable(refLoc.getWorld(), otherLastMove.toX, otherLastMove.toY, otherLastMove.toZ)) {
|
||||
continue;
|
||||
}
|
||||
untrackedData = otherData;
|
||||
@ -176,7 +178,8 @@ public class MovingUtil {
|
||||
}
|
||||
else {
|
||||
// TODO: Count and log to TRACE_FILE, if multiple locations would match (!).
|
||||
return new Location(loc.getWorld(), untrackedData.toX, untrackedData.toY, untrackedData.toZ, loc.getYaw(), loc.getPitch());
|
||||
final MoveData lastMove = untrackedData.moveData.getFirst();
|
||||
return new Location(loc.getWorld(), lastMove.toX, lastMove.toY, lastMove.toZ, loc.getYaw(), loc.getPitch());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,8 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import fr.neatmonster.nocheatplus.checks.Check;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
|
||||
import fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying;
|
||||
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
|
||||
import fr.neatmonster.nocheatplus.utilities.TrigUtil;
|
||||
|
||||
/**
|
||||
* Frequency of (pos/look/) flying packets checking.
|
||||
@ -44,76 +42,4 @@ public class FlyingFrequency extends Check {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Currently not used (too many potential and actual issues).</b><br>
|
||||
* Skip packets that are not going to cause a moving event to fire, in case
|
||||
* the frequency of packets is high.
|
||||
*
|
||||
* @param player
|
||||
* @param packetData
|
||||
* @param allScore
|
||||
* @param time
|
||||
* @param data
|
||||
* @param cc
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private boolean checkRedundantPackets(final Player player, final DataPacketFlying packetData, final float allScore, final long time, final NetData data, final NetConfig cc) {
|
||||
// TODO: Debug logging (better with integration into DataManager).
|
||||
// TODO: Consider to compare to moving data directly, skip keeping track extra.
|
||||
|
||||
final MovingData mData = MovingData.getData(player);
|
||||
if (mData.toX == Double.MAX_VALUE && mData.toYaw == Float.MAX_VALUE) {
|
||||
// Can not check.
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean onGroundSkip = false;
|
||||
|
||||
// Allow at least one on-ground change per state and second.
|
||||
// TODO: Consider to verify on ground somehow (could tell MovingData the state).
|
||||
if (packetData.onGround != data.flyingFrequencyOnGround) {
|
||||
// Regard as not redundant only if sending the same state happened at least a second ago.
|
||||
final long lastTime;
|
||||
if (packetData.onGround) {
|
||||
lastTime = data.flyingFrequencyTimeOnGround;
|
||||
data.flyingFrequencyTimeOnGround = time;
|
||||
} else {
|
||||
lastTime = data.flyingFrequencyTimeNotOnGround;
|
||||
data.flyingFrequencyTimeNotOnGround = time;
|
||||
}
|
||||
if (time < lastTime || time - lastTime > 1000) {
|
||||
// Override
|
||||
onGroundSkip = true;
|
||||
}
|
||||
}
|
||||
data.flyingFrequencyOnGround = packetData.onGround;
|
||||
|
||||
if (packetData.hasPos) {
|
||||
if (TrigUtil.distanceSquared(packetData.x, packetData.y, packetData.z, mData.toX, mData.toY, mData.toZ) > minMoveDistSq) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (packetData.hasLook) {
|
||||
if (Math.abs(TrigUtil.yawDiff(packetData.yaw, mData.toYaw)) > minLookChange || Math.abs(TrigUtil.yawDiff(packetData.pitch, mData.toPitch)) > minLookChange) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (onGroundSkip) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Packet is redundant, if more than 20 packets per second arrive.
|
||||
if (allScore / cc.flyingFrequencySeconds > 20f && !hasBypass(player)) {
|
||||
// (Must re-check bypass here.)
|
||||
data.flyingFrequencyRedundantFreq.add(time, 1f);
|
||||
if (executeActions(player, data.flyingFrequencyRedundantFreq.score(1f) / cc.flyingFrequencyRedundantSeconds, 1.0 / cc.flyingFrequencyRedundantSeconds, cc.flyingFrequencyRedundantActions)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user