mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-27 18:01:33 +01:00
[BLEEDING] Split off untracked moves. Elaborate on slime blocks.
MISSING: * Micro move onto ground, fall distance resets before sf check is run. Done: * Split PlayerMoveEvent processing to from -> loc + from -> to. Just if from isn't the same coordinates as player.getLocation. This reduces the complexity of workarounds. * You do take fall damage falling onto slime blocks while sneaking. * Queue bounce effect, only if the move is valid. Skip NoFall then. * Apply bounce effect once moving up, to allow overriding. * Cover more odd cases. Unrelated: * Use data.debug instead of cc.debug.
This commit is contained in:
parent
537b387fbf
commit
8de7907522
@ -74,7 +74,7 @@ public class SoundDistance extends BaseAdapter {
|
||||
final Location loc = player.getLocation(useLoc);
|
||||
final StructureModifier<Integer> ints = packetContainer.getIntegers();
|
||||
final double dSq = TrigUtil.distanceSquared(ints.read(0) / 8, ints.read(2) / 8, loc.getX(), loc.getZ());
|
||||
// if (cc.debug) {
|
||||
// if (data.debug) {
|
||||
// NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " SoundDistance(" + soundName + "): " + StringUtil.fdec1.format(Math.sqrt(dSq)));
|
||||
// }
|
||||
if (dSq > cc.soundDistanceSq) {
|
||||
|
@ -152,7 +152,7 @@ public class CreativeFly extends Check {
|
||||
|
||||
final double result = Math.max(0.0, resultH) + Math.max(0D, resultV);
|
||||
|
||||
if (cc.debug) {
|
||||
if (data.debug) {
|
||||
outpuDebugMove(player, hDistance, limitH, yDistance, limitV, data);
|
||||
}
|
||||
|
||||
|
@ -80,8 +80,9 @@ public class MovingConfig extends ACheckConfig {
|
||||
|
||||
public static final double Y_ON_GROUND_MIN = 0.00001;
|
||||
public static final double Y_ON_GROUND_MAX = 0.0626;
|
||||
// TODO: Model workarounds as lost ground ?
|
||||
public static final double Y_ON_GROUND_DEFAULT = 0.016; // TODO: Jumping upwards while placing blocks (otherwise use MIN).
|
||||
// TODO: Model workarounds as lost ground, use Y_ON_GROUND_MIN?
|
||||
public static final double Y_ON_GROUND_DEFAULT = 0.016; // Jump upwards, while placing blocks.
|
||||
// public static final double Y_ON_GROUND_DEFAULT = 0.029; // Bounce off slime blocks.
|
||||
|
||||
|
||||
public final boolean ignoreCreative;
|
||||
|
@ -100,7 +100,7 @@ public class MovingData extends ACheckData {
|
||||
* TODO: Test, might be better ground.
|
||||
*/
|
||||
private static final LiftOffEnvelope defaultLiftOffEnvelope = LiftOffEnvelope.NO_JUMP;
|
||||
|
||||
|
||||
/** Tolerance value for using vertical velocity (the client sends different values than received with fight damage). */
|
||||
private static final double TOL_VVEL = 0.0625;
|
||||
|
||||
@ -134,6 +134,9 @@ public class MovingData extends ACheckData {
|
||||
/** Only used during processing, to keep track of sub-checks using velocity. Reset in velocityTick, before checks run. */
|
||||
public SimpleEntry verVelUsed = null;
|
||||
|
||||
/** Compatibility entry for bouncing of slime blocks and the like. */
|
||||
public SimpleEntry verticalBounce = null;
|
||||
|
||||
/** Tick at which walk/fly speeds got changed last time. */
|
||||
public int speedTick = 0;
|
||||
public float walkSpeed = 0.0f;
|
||||
@ -267,6 +270,7 @@ public class MovingData extends ACheckData {
|
||||
vehicleConsistency = MoveConsistency.INCONSISTENT;
|
||||
lastFrictionHorizontal = lastFrictionVertical = 0.0;
|
||||
verVelUsed = null;
|
||||
verticalBounce = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -300,6 +304,7 @@ public class MovingData extends ACheckData {
|
||||
removeAllVelocity();
|
||||
vehicleConsistency = MoveConsistency.INCONSISTENT; // Not entirely sure here.
|
||||
lastFrictionHorizontal = lastFrictionVertical = 0.0;
|
||||
verticalBounce = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -311,6 +316,7 @@ public class MovingData extends ACheckData {
|
||||
lastYDist = lastHDist = Double.MAX_VALUE;
|
||||
toWasReset = false;
|
||||
fromWasReset = false;
|
||||
verticalBounce = null;
|
||||
// Remember where we send the player to.
|
||||
setTeleported(loc);
|
||||
// TODO: sfHoverTicks ?
|
||||
@ -366,6 +372,7 @@ public class MovingData extends ACheckData {
|
||||
sfLowJump = false;
|
||||
liftOffEnvelope = defaultLiftOffEnvelope;
|
||||
lastFrictionHorizontal = lastFrictionVertical = 0.0;
|
||||
verticalBounce = null;
|
||||
// TODO: other buffers ?
|
||||
// No reset of vehicleConsistency.
|
||||
}
|
||||
@ -616,6 +623,10 @@ public class MovingData extends ACheckData {
|
||||
|
||||
}
|
||||
|
||||
public void prependVerticalVelocity(final SimpleEntry entry) {
|
||||
verVel.addToFront(entry);
|
||||
}
|
||||
|
||||
public void addVerticalVelocity(final SimpleEntry entry) {
|
||||
verVel.add(entry);
|
||||
}
|
||||
@ -982,4 +993,14 @@ public class MovingData extends ACheckData {
|
||||
sfDirty = true;
|
||||
}
|
||||
|
||||
public void useVerticalBounce(final Player player) {
|
||||
// CHEATING: Ensure fall distance is reset.
|
||||
player.setFallDistance(0f);
|
||||
noFallMaxY = 0.0;
|
||||
noFallFallDistance = 0f;
|
||||
noFallSkipAirCheck = true;
|
||||
prependVerticalVelocity(verticalBounce);
|
||||
verticalBounce = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
data.prepareSetBack(target); // Should be enough. | new Location(target.getWorld(), target.getX(), target.getY(), target.getZ(), target.getYaw(), target.getPitch());
|
||||
player.teleport(target, TeleportCause.PLUGIN);// TODO: schedule / other measures ?
|
||||
}
|
||||
else{
|
||||
else {
|
||||
// Reset bed ...
|
||||
CombinedData.getData(player).wasInBed = false;
|
||||
}
|
||||
@ -335,8 +335,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
final Player player = event.getPlayer();
|
||||
|
||||
// Store the event for monitor level checks.
|
||||
final String playerName = player.getName();
|
||||
processingEvents.put(playerName, event);
|
||||
processingEvents.put(player.getName(), event);
|
||||
|
||||
final MovingData data = MovingData.getData(player);
|
||||
|
||||
@ -397,11 +396,66 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
}
|
||||
// newTo should be null here.
|
||||
|
||||
// Fire one or two moves here.
|
||||
final Location loc = player.getLocation(useLoc);
|
||||
final MovingConfig cc = MovingConfig.getConfig(player);
|
||||
final MoveInfo moveInfo = useMoveInfo();
|
||||
if (TrigUtil.isSamePos(from, loc)
|
||||
|| TrigUtil.isSamePos(loc, data.fromX, data.fromY, data.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
|
||||
) {
|
||||
// Fire move from -> to
|
||||
// (Special case: Location has not been updated last moving event.)
|
||||
moveInfo.set(player, from, to, cc.yOnGround);
|
||||
checkPlayerMove(player, from, to, false, moveInfo, data, cc, event);
|
||||
}
|
||||
else {
|
||||
// Split into two moves.
|
||||
// 1. Process from -> loc.
|
||||
if (data.debug) {
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " Split move 1 (from -> loc):");
|
||||
}
|
||||
moveInfo.set(player, from, loc, cc.yOnGround);
|
||||
if (!checkPlayerMove(player, from, loc, true, moveInfo, data, cc, event) && processingEvents.containsKey(event)) {
|
||||
// Between -> set data accordingly (compare: onPlayerMoveMonitor).
|
||||
onMoveMonitorNotCancelled(player, from, loc, System.currentTimeMillis(), TickTask.getTick(), CombinedData.getData(player), data);
|
||||
data.joinOrRespawn = false;
|
||||
// 2. Process loc -> to.
|
||||
if (data.debug) {
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " Split move 2 (loc -> to):");
|
||||
}
|
||||
moveInfo.set(player, loc, to, cc.yOnGround);
|
||||
checkPlayerMove(player, loc, to, false, moveInfo, data, cc, event);
|
||||
}
|
||||
}
|
||||
// Cleanup.
|
||||
data.joinOrRespawn = false;
|
||||
returnMoveInfo(moveInfo);
|
||||
useLoc.setWorld(null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param player
|
||||
* @param from
|
||||
* @param to
|
||||
* @param mightBeMultipleMoves
|
||||
* @param moveInfo
|
||||
* @param data
|
||||
* @param cc
|
||||
* @param event
|
||||
* @return If cancelled/done, i.e. not to process further split moves.
|
||||
*/
|
||||
private boolean checkPlayerMove(final Player player, final Location from, final Location to,
|
||||
final boolean mightBeMultipleMoves, final MoveInfo moveInfo, final MovingData data, final MovingConfig cc,
|
||||
final PlayerMoveEvent event) {
|
||||
|
||||
Location newTo = null;
|
||||
|
||||
// TODO: Order this to above "early return"?
|
||||
// Set up data / caching.
|
||||
final MoveInfo moveInfo = useMoveInfo();
|
||||
final MovingConfig cc = MovingConfig.getConfig(player);
|
||||
moveInfo.set(player, from, to, cc.yOnGround);
|
||||
|
||||
// TODO: Data resetting above ?
|
||||
data.noFallAssumeGround = false;
|
||||
data.resetTeleported();
|
||||
@ -413,9 +467,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
if ((moveInfo.from.hasIllegalCoords() || moveInfo.to.hasIllegalCoords()) ||
|
||||
!cc.ignoreStance && (moveInfo.from.hasIllegalStance() || moveInfo.to.hasIllegalStance())) {
|
||||
MovingUtil.handleIllegalMove(event, player, data, cc);
|
||||
moveInfo.cleanup();
|
||||
parkedInfo.add(moveInfo);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
{
|
||||
@ -441,7 +493,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final String playerName = player.getName(); // TODO: Could switch to UUID here (needs more changes).
|
||||
|
||||
// Check for location consistency.
|
||||
if (cc.enforceLocation && playersEnforce.contains(playerName)) {
|
||||
@ -516,35 +568,43 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
data.adjustFlySpeed(player.getFlySpeed(), tick, cc.speedGrace);
|
||||
data.adjustWalkSpeed(player.getWalkSpeed(), tick, cc.speedGrace);
|
||||
}
|
||||
else{
|
||||
else {
|
||||
checkCf = checkSf = false;
|
||||
}
|
||||
|
||||
boolean checkNf = true;
|
||||
boolean verticalBounce = false;
|
||||
if (checkSf || checkCf) {
|
||||
// Check jumping on things like slime blocks.
|
||||
// The center of the player must be above the block.
|
||||
// TODO: Apply effects later, if the move has not been not cancelled.
|
||||
if (to.getY() < from.getY() && player.getFallDistance() > 1f
|
||||
if (to.getY() < from.getY()
|
||||
&& (BlockProperties.getBlockFlags(pTo.getTypeIdBelow()) & BlockProperties.F_BOUNCE25) != 0L
|
||||
&& to.getY() - to.getBlockY() <= Math.max(cc.yOnGround, cc.noFallyOnGround)) {
|
||||
&& !survivalFly.isReallySneaking(player)
|
||||
&& (to.getY() - to.getBlockY() <= Math.max(cc.yOnGround, cc.noFallyOnGround) && player.getFallDistance() > 1f
|
||||
|| to.getY() - to.getBlockY() < 0.286 && to.getY() - from.getY() > -0.5 && to.getY() - from.getY() < -SurvivalFly.GRAVITY_MAX - SurvivalFly.GRAVITY_SPAN && !pTo.isOnGround())
|
||||
) {
|
||||
// Prepare bounce: The center of the player must be above the block.
|
||||
// TODO: Check other side conditions (fluids, web, max. distance to the block top (!))
|
||||
// Apply changes to NoFall and other.
|
||||
processTrampoline(player, pFrom, pTo, data, cc);
|
||||
verticalBounce = true;
|
||||
// Skip NoFall.
|
||||
checkNf = false;
|
||||
}
|
||||
else if (data.verticalBounce != null) {
|
||||
if (to.getY() > from.getY()) {
|
||||
// Apply bounce.
|
||||
checkNf = false;
|
||||
data.useVerticalBounce(player);
|
||||
} else {
|
||||
data.verticalBounce = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The players location.
|
||||
final Location loc = (cc.passableCheck || checkNf || checkSf) ? player.getLocation(moveInfo.useLoc) : null;
|
||||
|
||||
// Check passable first to prevent set-back override.
|
||||
// TODO: Redesign to set set-backs later (queue + invalidate).
|
||||
boolean mightSkipNoFall = false; // If to skip nofall check (mainly on violation of other checks).
|
||||
if (newTo == null && cc.passableCheck && player.getGameMode() != BridgeMisc.GAME_MODE_SPECTATOR && !NCPExemptionManager.isExempted(player, CheckType.MOVING_PASSABLE) && !player.hasPermission(Permissions.MOVING_PASSABLE)) {
|
||||
// Passable is checked first to get the original set-back locations from the other checks, if needed.
|
||||
newTo = passable.check(player, loc, pFrom, pTo, data, cc);
|
||||
newTo = passable.check(player, pFrom, pTo, data, cc);
|
||||
if (newTo != null) {
|
||||
// Check if to skip the nofall check.
|
||||
mightSkipNoFall = true;
|
||||
@ -565,7 +625,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// Sets all properties, but only once.
|
||||
pTo.prepare(pFrom);
|
||||
}
|
||||
else{
|
||||
else {
|
||||
// Might collect block flags for small distances with the containing bounds for both.
|
||||
pTo.collectBlockFlags(maxYNoFall);
|
||||
}
|
||||
@ -573,7 +633,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, loc, pTo, isSamePos, data, cc, time);
|
||||
newTo = survivalFly.check(player, pFrom, pTo, isSamePos, data, cc, time);
|
||||
}
|
||||
// Only check NoFall, if not already vetoed.
|
||||
if (checkNf) {
|
||||
@ -587,15 +647,15 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
hoverTicks.add(playerName);
|
||||
data.sfHoverTicks = 0;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
data.sfHoverTicks = -1;
|
||||
}
|
||||
// NoFall.
|
||||
if (checkNf) {
|
||||
noFall.check(player, loc, pFrom, pTo, data, cc);
|
||||
noFall.check(player, pFrom, pTo, data, cc);
|
||||
}
|
||||
}
|
||||
else{
|
||||
else {
|
||||
if (checkNf && cc.sfSetBackPolicyFallDamage) {
|
||||
if (noFall.estimateDamage(player, from.getY(), data) < 1.0) {
|
||||
// TODO: Consider making this / damage amount configurable.
|
||||
@ -609,7 +669,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
}
|
||||
if (!mightSkipNoFall && (!pTo.isResetCond() || !pFrom.isResetCond())) {
|
||||
// (Don't deal damage where no fall damage is possible.)
|
||||
noFall.checkDamage(player, data, Math.min(Math.min(from.getY(), to.getY()), loc.getY()));
|
||||
noFall.checkDamage(player, data, Math.min(from.getY(), to.getY()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -622,7 +682,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
data.sfHoverTicks = -1;
|
||||
data.sfLowJump = false;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
// No fly checking :(.
|
||||
data.clearFlyData();
|
||||
}
|
||||
@ -649,58 +709,50 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// 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, pTo, data, cc);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// Set-back handling.
|
||||
onSetBack(player, event, newTo, data, cc);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Cleanup.
|
||||
data.joinOrRespawn = false;
|
||||
returnMoveInfo(moveInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* yDistance is < 0, the middle of the player is above a slime block (to) +
|
||||
* on ground.
|
||||
*
|
||||
* @param player
|
||||
* @param from
|
||||
* @param to
|
||||
* @param data
|
||||
* @param cc
|
||||
*/
|
||||
private void processTrampoline(final Player player, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc) {
|
||||
// CHEATING: Add velocity.
|
||||
if (!survivalFly.isReallySneaking(player)) {
|
||||
final double fallDistance;
|
||||
if (noFall.isEnabled(player, cc)) {
|
||||
// (NoFall will not be checked, if this method is called.)
|
||||
if (data.noFallMaxY >= from.getY() ) {
|
||||
fallDistance = data.noFallMaxY - to.getY();
|
||||
} else {
|
||||
fallDistance = from.getY() - to.getY();
|
||||
}
|
||||
private void processBounce(final Player player, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc) {
|
||||
// CHEATING: Prepare velocity.
|
||||
final double fallDistance;
|
||||
if (noFall.isEnabled(player, cc)) {
|
||||
// (NoFall will not be checked, if this method is called.)
|
||||
if (data.noFallMaxY >= from.getY() ) {
|
||||
fallDistance = data.noFallMaxY - to.getY();
|
||||
} else {
|
||||
fallDistance = player.getFallDistance() + from.getY() - to.getY();
|
||||
fallDistance = from.getY() - to.getY();
|
||||
}
|
||||
final double effect = Math.min(3.14, Math.sqrt(fallDistance) / 3.3 + SurvivalFly.GRAVITY_MAX); // Ancient Greek technology with gravity added.
|
||||
// (Actually observed max. is near 3.5.) TODO: Why 3.14 then?
|
||||
if (cc.debug) {
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " Trampoline effect (dY=" + fallDistance + "): " + effect);
|
||||
}
|
||||
data.addVerticalVelocity(new SimpleEntry(effect, 2)); // Not logged at present.
|
||||
} else {
|
||||
if (cc.debug) {
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " Trampoline effect (sneaking).");
|
||||
}
|
||||
fallDistance = player.getFallDistance() + from.getY() - to.getY();
|
||||
}
|
||||
final double effect = Math.min(3.14, Math.sqrt(fallDistance) / 3.3 + SurvivalFly.GRAVITY_MAX); // Ancient Greek technology with gravity added.
|
||||
// (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);
|
||||
}
|
||||
// CHEATING: Remove fall distance:
|
||||
player.setFallDistance(0f);
|
||||
// (Ignore if NoFall is enabled or not here.)
|
||||
data.noFallFallDistance = 0f;
|
||||
data.noFallMaxY = 0.0;
|
||||
data.noFallSkipAirCheck = true;
|
||||
// (After this the NoFall check should be skipped.)
|
||||
data.verticalBounce = new SimpleEntry(effect, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -811,44 +863,62 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isDead() || player.isSleeping()) return;
|
||||
if (player.isDead() || player.isSleeping()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Feed combined check.
|
||||
final CombinedData data = CombinedData.getData(player);
|
||||
data.lastMoveTime = now; // TODO: Evaluate moving this to MovingData !?
|
||||
|
||||
|
||||
final Location from = event.getFrom();
|
||||
final String fromWorldName = from.getWorld().getName();
|
||||
|
||||
// Feed yawrate and reset moving data positions if necessary.
|
||||
final MovingData mData = MovingData.getData(player);
|
||||
final long time = TickTask.getTick();
|
||||
final long tick = TickTask.getTick();
|
||||
if (!event.isCancelled()) {
|
||||
final Location to = event.getTo();
|
||||
final String toWorldName = to.getWorld().getName();
|
||||
Combined.feedYawRate(player, to.getYaw(), now, toWorldName, data);
|
||||
// TODO: maybe even not count vehicles at all ?
|
||||
if (player.isInsideVehicle()) {
|
||||
// TODO: refine (!).
|
||||
final Location ref = player.getVehicle().getLocation(useLoc);
|
||||
mData.resetPositions(ref); // TODO: Consider using to and intercept cheat attempts in another way.
|
||||
useLoc.setWorld(null);
|
||||
mData.updateTrace(player, to, time); // TODO: Can you become invincible by sending special moves?
|
||||
}
|
||||
else if (!fromWorldName.equals(toWorldName)) {
|
||||
mData.resetPositions(to);
|
||||
mData.resetTrace(player, to, time);
|
||||
}
|
||||
else{
|
||||
mData.setTo(to); // Called on lowest too.
|
||||
mData.updateTrace(player, to, time);
|
||||
}
|
||||
final Location pLoc = player.getLocation();
|
||||
onMoveMonitorNotCancelled(player, TrigUtil.isSamePosAndLook(pLoc, from) ? from : pLoc, event.getTo(), now, tick, data, mData);
|
||||
useLoc.setWorld(null);
|
||||
}
|
||||
else {
|
||||
data.lastMoveTime = now; // TODO: Evaluate moving this to MovingData !?
|
||||
// TODO: teleported + other resetting ?
|
||||
Combined.feedYawRate(player, from.getYaw(), now, fromWorldName, data);
|
||||
Combined.feedYawRate(player, from.getYaw(), now, from.getWorld().getName(), data);
|
||||
mData.resetPositions(from);
|
||||
mData.resetTrace(player, from, time); // TODO: Should probably leave this to the teleport event!
|
||||
mData.resetTrace(player, from, tick); // TODO: Should probably leave this to the teleport event!
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides useLoc if in vehicle.
|
||||
* @param player
|
||||
* @param from
|
||||
* @param to
|
||||
* @param now
|
||||
* @param tick
|
||||
* @param data
|
||||
* @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 !?
|
||||
final String toWorldName = to.getWorld().getName();
|
||||
Combined.feedYawRate(player, to.getYaw(), now, toWorldName, data);
|
||||
// TODO: maybe even not count vehicles at all ?
|
||||
if (player.isInsideVehicle()) {
|
||||
// TODO: refine (!).
|
||||
final Location ref = player.getVehicle().getLocation(useLoc);
|
||||
mData.resetPositions(ref); // TODO: Consider using to and intercept cheat attempts in another way.
|
||||
useLoc.setWorld(null);
|
||||
mData.updateTrace(player, to, tick); // TODO: Can you become invincible by sending special moves?
|
||||
}
|
||||
else if (!from.getWorld().getName().equals(toWorldName)) {
|
||||
mData.resetPositions(to);
|
||||
mData.resetTrace(player, to, tick);
|
||||
}
|
||||
else {
|
||||
mData.setTo(to); // Called on lowest too.
|
||||
mData.updateTrace(player, to, tick);
|
||||
}
|
||||
}
|
||||
|
||||
@ -875,11 +945,11 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
public void onPlayerDeath(final PlayerDeathEvent event) {
|
||||
final Player player = event.getEntity();
|
||||
final MovingData data = MovingData.getData(player);
|
||||
final MovingConfig cc = MovingConfig.getConfig(player);
|
||||
//final MovingConfig cc = MovingConfig.getConfig(player);
|
||||
data.clearFlyData();
|
||||
data.clearMorePacketsData();
|
||||
data.setSetBack(player.getLocation(useLoc)); // TODO: Monitor this change (!).
|
||||
if (cc.debug) {
|
||||
if (data.debug) {
|
||||
// Log location.
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " death: " + player.getLocation(useLoc));
|
||||
}
|
||||
@ -918,7 +988,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
event.setFrom(teleported);
|
||||
ref = teleported;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
// Not cancelled but NCP teleport.
|
||||
ref = to;
|
||||
}
|
||||
@ -964,7 +1034,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// Not check on-ground: Check the second throw.
|
||||
cancel = true;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
// pass = true;
|
||||
}
|
||||
}
|
||||
@ -996,7 +1066,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
event.setTo(ref);
|
||||
adjustLiftOffEnvelope(player, ref, data, cc);
|
||||
}
|
||||
else{
|
||||
else {
|
||||
ref = from; // Player.getLocation ?
|
||||
event.setCancelled(true);
|
||||
}
|
||||
@ -1017,7 +1087,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// });
|
||||
// }
|
||||
}
|
||||
else{
|
||||
else {
|
||||
// "real" teleport
|
||||
ref = to;
|
||||
double fallDistance = data.noFallFallDistance;
|
||||
@ -1051,7 +1121,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " TP" + (smallRange ? " (small-range)" : "") + (cancel ? " (cancelled)" : "") + ": " + to);
|
||||
}
|
||||
}
|
||||
else{
|
||||
else {
|
||||
// Cancelled, not a set back, ignore it, basically.
|
||||
// Better reset teleported (compatibility). Might have drawbacks.
|
||||
data.resetTeleported();
|
||||
@ -1180,7 +1250,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// If the player is handled by the more packets vehicle check, execute it.
|
||||
newTo = morePacketsVehicle.check(player, from, to, data, cc);
|
||||
}
|
||||
else{
|
||||
else {
|
||||
// Otherwise we need to clear their data.
|
||||
data.clearMorePacketsData();
|
||||
}
|
||||
@ -1238,7 +1308,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
allowReset = false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
else {
|
||||
// Legitimate damage: clear accounting data.
|
||||
data.vDistAcc.clear();
|
||||
// TODO: Also reset other properties.
|
||||
@ -1265,7 +1335,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// Normal fall damage, reset data.
|
||||
data.clearNoFallData();
|
||||
}
|
||||
else{
|
||||
else {
|
||||
// Minecraft/NCP bug or cheating.
|
||||
// (Do not cancel the event, otherwise: "moved too quickly exploit".)
|
||||
if (cc.noFallViolationReset) {
|
||||
@ -1371,7 +1441,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// if (LocUtil.needsDirectionCorrection(useLoc.getYaw(), useLoc.getPitch())) {
|
||||
// DataManager.getPlayerData(player).task.correctDirection();
|
||||
// }
|
||||
if (cc.debug) {
|
||||
if (data.debug) {
|
||||
// Log location.
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " " + tag + ": " + loc);
|
||||
}
|
||||
@ -1393,7 +1463,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
data.sfHoverLoginTicks = cc.sfHoverLoginTicks;
|
||||
hoverTicks.add(player.getName());
|
||||
}
|
||||
else{
|
||||
else {
|
||||
data.sfHoverLoginTicks = 0;
|
||||
data.sfHoverTicks = -1;
|
||||
}
|
||||
@ -1712,7 +1782,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
res = true;
|
||||
data.sfHoverTicks = 0;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
if (data.sfHoverTicks > cc.sfHoverTicks) {
|
||||
// Re-Check if survivalfly can apply at all.
|
||||
if (MovingUtil.shouldCheckSurvivalFly(player, data, cc)) {
|
||||
@ -1721,7 +1791,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
res = false;
|
||||
data.sfHoverTicks = 0;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
// Reset hover ticks and check next period.
|
||||
res = false;
|
||||
data.sfHoverTicks = 0;
|
||||
|
@ -122,7 +122,7 @@ public class NoFall extends Check {
|
||||
* @param to
|
||||
* the to
|
||||
*/
|
||||
public void check(final Player player, final Location loc, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc) {
|
||||
public void check(final Player player, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc) {
|
||||
|
||||
final double fromY = from.getY();
|
||||
final double toY = to.getY();
|
||||
@ -151,8 +151,7 @@ public class NoFall extends Check {
|
||||
|
||||
// TODO: early returns (...)
|
||||
|
||||
final double pY = loc.getY();
|
||||
final double minY = Math.min(fromY, Math.min(toY, pY));
|
||||
final double minY = Math.min(fromY, toY);
|
||||
|
||||
if (fromReset) {
|
||||
// Just reset.
|
||||
@ -190,7 +189,7 @@ public class NoFall extends Check {
|
||||
|
||||
// Set reference y for nofall (always).
|
||||
// TODO: Consider setting this before handleOnGround (at least for resetTo).
|
||||
data.noFallMaxY = Math.max(Math.max(fromY, Math.max(toY, pY)), data.noFallMaxY);
|
||||
data.noFallMaxY = Math.max(Math.max(fromY, toY), data.noFallMaxY);
|
||||
|
||||
// TODO: fall distance might be behind (!)
|
||||
// TODO: should be the data.noFallMaxY be counted in ?
|
||||
|
@ -26,7 +26,7 @@ public class Passable extends Check {
|
||||
rayTracing.setMaxSteps(60); // TODO: Configurable ?
|
||||
}
|
||||
|
||||
public Location check(final Player player, Location loc, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc)
|
||||
public Location check(final Player player, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc)
|
||||
{
|
||||
// TODO: if (!from.isSameCoords(loc)) {...check passable for loc -> from !?... + sf etc too?}
|
||||
// TODO: Future: Account for the players bounding box? [test very-strict setting for at least the end points...]
|
||||
@ -80,20 +80,14 @@ public class Passable extends Check {
|
||||
data.passableVL *= 0.99;
|
||||
return null;
|
||||
} else {
|
||||
return potentialViolation(player, loc, from, to, manhattan, tags, data, cc);
|
||||
return potentialViolation(player, from, to, manhattan, tags, data, cc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Location potentialViolation(final Player player, final Location loc, final PlayerLocation from, final PlayerLocation to, final int manhattan, String tags, final MovingData data, final MovingConfig cc) {
|
||||
private Location potentialViolation(final Player player, final PlayerLocation from, final PlayerLocation to, final int manhattan, String tags, final MovingData data, final MovingConfig cc) {
|
||||
// Moving into a block, possibly a violation.
|
||||
|
||||
// Check the players location if different from others.
|
||||
// (It provides a better set-back for some exploits.)
|
||||
final int lbX = loc.getBlockX();
|
||||
final int lbY = loc.getBlockY();
|
||||
final int lbZ = loc.getBlockZ();
|
||||
Location setBackLoc = null; // Alternative to from.getLocation().
|
||||
// First check if the player is moving from a passable location.
|
||||
// If not, the move might still be allowed, if moving inside of the same block, or from and to have head position passable.
|
||||
if (from.isPassable()) {
|
||||
@ -107,19 +101,12 @@ public class Passable extends Check {
|
||||
}
|
||||
// From should be the set-back.
|
||||
tags += "into";
|
||||
} else if (BlockProperties.isPassable(from.getBlockCache(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(lbX, lbY, lbZ))) {
|
||||
// Keep loc, because it it is passable.
|
||||
tags += "into_shift";
|
||||
setBackLoc = loc;
|
||||
}
|
||||
|
||||
// } else if (BlockProperties.isPassableExact(from.getBlockCache(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(lbX, lbY, lbZ))) {
|
||||
// (Mind that this can be the case on the same block theoretically.)
|
||||
// Keep loc as set-back.
|
||||
// }
|
||||
else if (!from.isSameBlock(lbX, lbY, lbZ)) {
|
||||
// Both loc and from are not passable. Use from as set.back (earliest).
|
||||
tags += "cross_shift";
|
||||
}
|
||||
else if (manhattan == 1 && to.isBlockAbove(from) && BlockProperties.isPassable(from.getBlockCache(), from.getX(), from.getY() + player.getEyeHeight(), from.getZ(), from.getTypeId(from.getBlockX(), Location.locToBlock(from.getY() + player.getEyeHeight()), from.getBlockZ()))) {
|
||||
// else if (to.isBlockAbove(from) && BlockProperties.isPassableExact(from.getBlockCache(), from.getX(), from.getY() + player.getEyeHeight(), from.getZ(), from.getTypeId(from.getBlockX(), Location.locToBlock(from.getY() + player.getEyeHeight()), from.getBlockZ()))) {
|
||||
// Allow the move up if the head is free.
|
||||
@ -135,24 +122,13 @@ public class Passable extends Check {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Discard inconsistent locations.
|
||||
// TODO: Might get rid of using the in-between loc - needs use-case checking.
|
||||
if (setBackLoc != null && (TrigUtil.distance(from, to) > 0.75 || TrigUtil.distance(from, setBackLoc) > 0.125)) {
|
||||
setBackLoc = null;
|
||||
}
|
||||
Location setBackLoc = null; // Alternative to from.getLocation().
|
||||
|
||||
// Prefer the set-back location from the data.
|
||||
if (data.hasSetBack()) {
|
||||
// TODO: Review or make configurable.
|
||||
final Location ref = data.getSetBack(to);
|
||||
if (BlockProperties.isPassable(from.getBlockCache(), ref) || setBackLoc == null || TrigUtil.distance(from, setBackLoc) > 0.13) {
|
||||
// if (BlockProperties.isPassableExact(from.getBlockCache(), ref)) {
|
||||
setBackLoc = ref;
|
||||
if (data.debug) {
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " Using set-back location for passable.");
|
||||
}
|
||||
} else if (data.debug) {
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " Ignoring set-back for passable.");
|
||||
setBackLoc = data.getSetBack(to);;
|
||||
if (data.debug) {
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " Using set-back location for passable.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ public class SurvivalFly extends Check {
|
||||
* @param isSamePos
|
||||
* @return the location
|
||||
*/
|
||||
public Location check(final Player player, final PlayerLocation from, final Location loc, 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 MovingData data, final MovingConfig cc, final long now) {
|
||||
tags.clear();
|
||||
|
||||
// Calculate some distances.
|
||||
@ -144,7 +144,7 @@ public class SurvivalFly extends Check {
|
||||
(from.isOnGround() || from.isResetCond())) {
|
||||
// TODO: Move most to a method?
|
||||
// TODO: Is a margin needed for from.isOnGround()? [bukkitapionly]
|
||||
if (cc.debug) {
|
||||
if (data.debug) {
|
||||
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, player.getName() + " SurvivalFly\nAdjust set-back after join/respawn: " + from.getLocation());
|
||||
}
|
||||
data.setSetBack(from);
|
||||
@ -214,7 +214,7 @@ public class SurvivalFly extends Check {
|
||||
// TODO: This isn't correct, needs redesign.
|
||||
if (data.lastHDist != Double.MAX_VALUE && data.lastHDist > 0.0 && data.lastYDist < -0.3) {
|
||||
// Note that to is not on ground either.
|
||||
resetFrom = lostGroundStill(player, from, loc, to, hDistance, yDistance, sprinting, data, cc);
|
||||
resetFrom = lostGroundStill(player, from, to, hDistance, yDistance, sprinting, data, cc);
|
||||
} else {
|
||||
resetFrom = false;
|
||||
}
|
||||
@ -224,7 +224,7 @@ public class SurvivalFly extends Check {
|
||||
// TODO: More refined conditions possible ?
|
||||
// TODO: Consider if (!resetTo) ?
|
||||
// Check lost-ground workarounds.
|
||||
resetFrom = lostGround(player, from, loc, to, hDistance, yDistance, sprinting, data, cc);
|
||||
resetFrom = lostGround(player, from, to, hDistance, yDistance, sprinting, data, cc);
|
||||
// Note: if not setting resetFrom, other places have to check assumeGround...
|
||||
}
|
||||
|
||||
@ -381,7 +381,9 @@ public class SurvivalFly extends Check {
|
||||
final double result = (Math.max(hDistanceAboveLimit, 0D) + Math.max(vDistanceAboveLimit, 0D)) * 100D;
|
||||
if (result > 0D) {
|
||||
final Location vLoc = handleViolation(now, result, player, from, to, data, cc);
|
||||
if (vLoc != null) return vLoc;
|
||||
if (vLoc != null) {
|
||||
return vLoc;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Slowly reduce the level with each event, if violations have not recently happened.
|
||||
@ -690,7 +692,7 @@ public class SurvivalFly extends Check {
|
||||
* @param cc
|
||||
* @return If touching the ground was lost.
|
||||
*/
|
||||
private boolean lostGround(final Player player, final PlayerLocation from, final Location loc, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final MovingData data, final MovingConfig cc) {
|
||||
private boolean lostGround(final Player player, final PlayerLocation from, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final MovingData data, final MovingConfig cc) {
|
||||
// TODO: Regroup with appropriate conditions (toOnGround first?).
|
||||
// TODO: Some workarounds allow step height (0.6 on MC 1.8).
|
||||
// TODO: yDistance limit does not seem to be appropriate.
|
||||
@ -698,13 +700,13 @@ public class SurvivalFly extends Check {
|
||||
// "Mild" Ascending / descending.
|
||||
//Ascending
|
||||
if (yDistance >= 0) {
|
||||
if (lostGroundAscend(player, from, loc, to, hDistance, yDistance, sprinting, data, cc)) {
|
||||
if (lostGroundAscend(player, from, to, hDistance, yDistance, sprinting, data, cc)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Descending.
|
||||
if (yDistance <= 0) {
|
||||
if (lostGroundDescend(player, from, loc, to, hDistance, yDistance, sprinting, data, cc)) {
|
||||
if (lostGroundDescend(player, from, to, hDistance, yDistance, sprinting, data, cc)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -741,6 +743,7 @@ public class SurvivalFly extends Check {
|
||||
// TODO: Cleanup pending.
|
||||
final boolean strictVdistRel;
|
||||
final double maxJumpGain = data.liftOffEnvelope.getMaxJumpGain(data.jumpAmplifier);
|
||||
final double jumpGainMargin = 0.005; // TODO: Model differently, workarounds where needed. 0.05 interferes with max height vs. velocity (<= 0.47 gain).
|
||||
if (fallingEnvelope(yDistance, data.lastYDist, 0.0)) {
|
||||
// Less headache: Always allow falling.
|
||||
vAllowedDistance = data.lastYDist * FRICTION_MEDIUM_AIR - GRAVITY_MIN; // Upper bound.
|
||||
@ -753,7 +756,7 @@ public class SurvivalFly extends Check {
|
||||
} else {
|
||||
// Code duplication with the absolute limit below.
|
||||
if (yDistance < 0.0 || yDistance > cc.sfStepHeight || !tags.contains("lostground_couldstep")) {
|
||||
vAllowedDistance = maxJumpGain + 0.05; // TODO: Margin
|
||||
vAllowedDistance = maxJumpGain + jumpGainMargin;
|
||||
} else {
|
||||
// lostground_couldstep
|
||||
vAllowedDistance = yDistance;
|
||||
@ -768,7 +771,7 @@ public class SurvivalFly extends Check {
|
||||
}
|
||||
else {
|
||||
// TODO: Needs more precise confinement + setting set back or distance to ground or estYDist.
|
||||
vAllowedDistance = maxJumpGain + 0.05; // TODO: Margin
|
||||
vAllowedDistance = maxJumpGain + jumpGainMargin;
|
||||
}
|
||||
strictVdistRel = false;
|
||||
} else {
|
||||
@ -821,7 +824,7 @@ public class SurvivalFly extends Check {
|
||||
else if (oddLiquid(yDistance, yDistDiffEx, maxJumpGain, resetTo, data)) {
|
||||
// Jump after leaving the liquid near ground.
|
||||
}
|
||||
else if (oddGravity(from, yDistance, yDistChange, data)) {
|
||||
else if (oddGravity(from, to, yDistance, yDistChange, data)) {
|
||||
// Starting to fall / gravity effects.
|
||||
}
|
||||
else if (oddSlope(to, yDistance, maxJumpGain, yDistDiffEx, data)) {
|
||||
@ -837,7 +840,7 @@ public class SurvivalFly extends Check {
|
||||
// Allow jumping less high unless within "strict envelope".
|
||||
// TODO: Extreme anti-jump effects, perhaps.
|
||||
}
|
||||
else if (oddGravity(from, yDistance, yDistChange, data)) {
|
||||
else if (oddGravity(from, to, yDistance, yDistChange, data)) {
|
||||
// Starting to fall.
|
||||
}
|
||||
else if (oddSlope(to, yDistance, maxJumpGain, yDistDiffEx, data)) {
|
||||
@ -882,7 +885,7 @@ public class SurvivalFly extends Check {
|
||||
) {
|
||||
// LIMIT_LIQUID, vDist inversion (!).
|
||||
}
|
||||
else if (oddGravity(from, yDistance, yDistChange, data)) {
|
||||
else if (oddGravity(from, to, yDistance, yDistChange, data)) {
|
||||
// Starting to fall.
|
||||
}
|
||||
else {
|
||||
@ -1042,7 +1045,7 @@ public class SurvivalFly extends Check {
|
||||
* @param data
|
||||
* @return If the condition applies, i.e. if to exempt.
|
||||
*/
|
||||
private static boolean oddGravity(final PlayerLocation from, final double yDistance, final double yDistChange, final MovingData data) {
|
||||
private static boolean oddGravity(final PlayerLocation from, final PlayerLocation to, final double yDistance, final double yDistChange, final MovingData data) {
|
||||
// TODO: Identify spots only to apply with limited LiftOffEnvelope (some guards got removed before switching to that).
|
||||
// TODO: Cleanup pending.
|
||||
// Old condition (normal lift-off envelope).
|
||||
@ -1069,44 +1072,53 @@ public class SurvivalFly extends Check {
|
||||
&& yDistance >= -GRAVITY_MAX - GRAVITY_SPAN && yDistance <= GRAVITY_MIN
|
||||
// Slope with slimes (also near ground without velocityJumpPhase, rather lowjump but not always).
|
||||
|| data.lastYDist < -GRAVITY_MAX && yDistChange < - GRAVITY_ODD / 2.0 && yDistChange > -GRAVITY_MIN
|
||||
// Near ground (slime block).
|
||||
|| data.lastYDist == 0.0 && yDistance < -GRAVITY_ODD / 2.5 && yDistance > -GRAVITY_MIN && to.isOnGround(GRAVITY_MIN)
|
||||
)
|
||||
|| data.isVelocityJumpPhase()
|
||||
&& (
|
||||
// Near zero inversion with slimes (rather dirty phase).
|
||||
data.lastYDist > GRAVITY_ODD && data.lastYDist < GRAVITY_MAX + GRAVITY_MIN
|
||||
&& yDistance <= -data.lastYDist && yDistance > -data.lastYDist - GRAVITY_MAX - GRAVITY_ODD
|
||||
// Odd mini-decrease with dirty phase (slime).
|
||||
|| data.lastYDist < -0.204 && yDistance > -0.26
|
||||
&& yDistChange > -GRAVITY_MIN && yDistChange < -GRAVITY_ODD / 4.0
|
||||
)
|
||||
// Jump-effect-specific
|
||||
// TODO: Jump effect at reduced lift off envelope -> skip this?
|
||||
|| data.jumpAmplifier > 0 && data.lastYDist < GRAVITY_MAX + GRAVITY_MIN / 2.0 && data.lastYDist > -2.0 * GRAVITY_MAX - 0.5 * GRAVITY_MIN
|
||||
&& yDistance > -2.0 * GRAVITY_MAX - 2.0 * GRAVITY_MIN && yDistance < GRAVITY_MIN
|
||||
&& yDistChange < -GRAVITY_SPAN
|
||||
// Another near 0 yDistance case. TODO: Inaugurate into some more generic envelope.
|
||||
|| data.lastYDist > -GRAVITY_MAX && data.lastYDist < GRAVITY_MIN && !data.toWasReset
|
||||
&& yDistance < data.lastYDist - GRAVITY_MIN / 2.0 && yDistance > data.lastYDist - GRAVITY_MAX - 0.5 * GRAVITY_MIN
|
||||
// Reduced jumping envelope.
|
||||
|| data.liftOffEnvelope != LiftOffEnvelope.NORMAL
|
||||
&& (
|
||||
// Wild-card allow half gravity near 0 yDistance. TODO: Check for removal of included cases elsewhere.
|
||||
data.lastYDist > -10.0 * GRAVITY_ODD / 2.0 && data.lastYDist < 10.0 * GRAVITY_ODD
|
||||
&& yDistance < data.lastYDist - GRAVITY_MIN / 2.0 && yDistance > data.lastYDist - GRAVITY_MAX
|
||||
//
|
||||
|| data.lastYDist < GRAVITY_MAX + GRAVITY_SPAN && data.lastYDist > GRAVITY_ODD
|
||||
&& yDistance > 0.4 * GRAVITY_ODD && yDistance - data.lastYDist < -GRAVITY_ODD / 2.0
|
||||
//
|
||||
|| data.lastYDist < 0.2 && data.lastYDist >= 0.0 && yDistance > -0.2 && yDistance < 2.0 * GRAVITY_MAX
|
||||
//
|
||||
|| data.lastYDist > 0.4 * GRAVITY_ODD && data.lastYDist < GRAVITY_MIN && yDistance == 0.0
|
||||
// Too small decrease, right after lift off.
|
||||
|| data.sfJumpPhase == 1 && data.lastYDist > -GRAVITY_ODD && data.lastYDist <= GRAVITY_MAX + GRAVITY_SPAN
|
||||
&& yDistance - data.lastYDist < 0.0114
|
||||
// Any leaving liquid and keeping distance once.
|
||||
|| data.sfJumpPhase == 1
|
||||
&& Math.abs(yDistance) <= swimBaseSpeedV() && yDistance == data.lastYDist
|
||||
)
|
||||
// With velocity.
|
||||
|| data.isVelocityJumpPhase()
|
||||
&& (
|
||||
// Near zero inversion with slimes (rather dirty phase).
|
||||
data.lastYDist > GRAVITY_ODD && data.lastYDist < GRAVITY_MAX + GRAVITY_MIN
|
||||
&& yDistance <= -data.lastYDist && yDistance > -data.lastYDist - GRAVITY_MAX - GRAVITY_ODD
|
||||
// Odd mini-decrease with dirty phase (slime).
|
||||
|| data.lastYDist < -0.204 && yDistance > -0.26
|
||||
&& yDistChange > -GRAVITY_MIN && yDistChange < -GRAVITY_ODD / 4.0
|
||||
// Lot's of decrease near zero TODO: merge later.
|
||||
|| data.lastYDist < -GRAVITY_ODD && data.lastYDist > -GRAVITY_MIN
|
||||
&& yDistance > -2.0 * GRAVITY_MAX - 2.0 * GRAVITY_MIN && yDistance < -GRAVITY_MAX
|
||||
// Odd decrease less near zero.
|
||||
|| yDistChange > -GRAVITY_MIN && yDistChange < -GRAVITY_ODD
|
||||
&& data.lastYDist < 0.5 && data.lastYDist > 0.4
|
||||
)
|
||||
// Jump-effect-specific
|
||||
// TODO: Jump effect at reduced lift off envelope -> skip this?
|
||||
|| data.jumpAmplifier > 0 && data.lastYDist < GRAVITY_MAX + GRAVITY_MIN / 2.0 && data.lastYDist > -2.0 * GRAVITY_MAX - 0.5 * GRAVITY_MIN
|
||||
&& yDistance > -2.0 * GRAVITY_MAX - 2.0 * GRAVITY_MIN && yDistance < GRAVITY_MIN
|
||||
&& yDistChange < -GRAVITY_SPAN
|
||||
// Another near 0 yDistance case. TODO: Inaugurate into some more generic envelope.
|
||||
|| data.lastYDist > -GRAVITY_MAX && data.lastYDist < GRAVITY_MIN && !data.toWasReset
|
||||
&& yDistance < data.lastYDist - GRAVITY_MIN / 2.0 && yDistance > data.lastYDist - GRAVITY_MAX - 0.5 * GRAVITY_MIN
|
||||
// Reduced jumping envelope.
|
||||
|| data.liftOffEnvelope != LiftOffEnvelope.NORMAL
|
||||
&& (
|
||||
// Wild-card allow half gravity near 0 yDistance. TODO: Check for removal of included cases elsewhere.
|
||||
data.lastYDist > -10.0 * GRAVITY_ODD / 2.0 && data.lastYDist < 10.0 * GRAVITY_ODD
|
||||
&& yDistance < data.lastYDist - GRAVITY_MIN / 2.0 && yDistance > data.lastYDist - GRAVITY_MAX
|
||||
//
|
||||
|| data.lastYDist < GRAVITY_MAX + GRAVITY_SPAN && data.lastYDist > GRAVITY_ODD
|
||||
&& yDistance > 0.4 * GRAVITY_ODD && yDistance - data.lastYDist < -GRAVITY_ODD / 2.0
|
||||
//
|
||||
|| data.lastYDist < 0.2 && data.lastYDist >= 0.0 && yDistance > -0.2 && yDistance < 2.0 * GRAVITY_MAX
|
||||
//
|
||||
|| data.lastYDist > 0.4 * GRAVITY_ODD && data.lastYDist < GRAVITY_MIN && yDistance == 0.0
|
||||
// Too small decrease, right after lift off.
|
||||
|| data.sfJumpPhase == 1 && data.lastYDist > -GRAVITY_ODD && data.lastYDist <= GRAVITY_MAX + GRAVITY_SPAN
|
||||
&& yDistance - data.lastYDist < 0.0114
|
||||
// Any leaving liquid and keeping distance once.
|
||||
|| data.sfJumpPhase == 1
|
||||
&& Math.abs(yDistance) <= swimBaseSpeedV() && yDistance == data.lastYDist
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
@ -1688,7 +1700,7 @@ public class SurvivalFly extends Check {
|
||||
* @param cc
|
||||
* @return
|
||||
*/
|
||||
private boolean lostGroundAscend(final Player player, final PlayerLocation from, final Location loc, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final MovingData data, final MovingConfig cc) {
|
||||
private boolean lostGroundAscend(final Player player, final PlayerLocation from, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final MovingData data, final MovingConfig cc) {
|
||||
final double setBackYDistance = to.getY() - data.getSetBackY();
|
||||
// Step height related.
|
||||
// TODO: Combine / refine preconditions for step height related.
|
||||
@ -1727,14 +1739,7 @@ public class SurvivalFly extends Check {
|
||||
}
|
||||
|
||||
// Special cases.
|
||||
if (!from.isSamePos(loc)) {
|
||||
// Micro-moves: Re-check with loc instead of from.
|
||||
// TODO: These belong checked as extra moves. The untracked nature of this means potential exploits.
|
||||
if (lostGroundEdgeAsc(player, from.getBlockCache(), from.getWorld(), loc.getX(), loc.getY(), loc.getZ(), from.getWidth(), from.getyOnGround(), data, "asc3")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (yDistance == 0.0 && data.lastYDist <= -0.23 && (hDistance <= data.lastHDist * 1.1)) {
|
||||
if (yDistance == 0.0 && data.lastYDist <= -0.23 && (hDistance <= data.lastHDist * 1.1)) {
|
||||
// Similar to couldstep, with 0 y-distance but slightly above any ground nearby (no micro move!).
|
||||
// TODO: (hDistance <= data.sfLastHDist || hDistance <= hAllowedDistance)
|
||||
// TODO: Confining in x/z direction in general: should detect if collided in that direction (then skip the x/z dist <= last time).
|
||||
@ -1770,7 +1775,7 @@ public class SurvivalFly extends Check {
|
||||
* @param cc
|
||||
* @return
|
||||
*/
|
||||
private boolean lostGroundStill(final Player player, final PlayerLocation from, final Location loc, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final MovingData data, final MovingConfig cc) {
|
||||
private boolean lostGroundStill(final Player player, final PlayerLocation from, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final MovingData data, final MovingConfig cc) {
|
||||
if (data.lastYDist <= -0.23) {
|
||||
// TODO: Code duplication with edgeasc5 above.
|
||||
if (lostGroundEdgeAsc(player, from.getBlockCache(), to.getWorld(), to.getX(), to.getY(), to.getZ(), from.getX(), from.getY(), from.getZ(), hDistance, to.getWidth(), 0.3, data, "asc7")) {
|
||||
@ -1840,7 +1845,7 @@ public class SurvivalFly extends Check {
|
||||
* @param cc
|
||||
* @return
|
||||
*/
|
||||
private boolean lostGroundDescend(final Player player, final PlayerLocation from, final Location loc, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final MovingData data, final MovingConfig cc) {
|
||||
private boolean lostGroundDescend(final Player player, final PlayerLocation from, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final MovingData data, final MovingConfig cc) {
|
||||
// TODO: re-organize for faster exclusions (hDistance, yDistance).
|
||||
// TODO: more strict conditions
|
||||
|
||||
|
@ -20,6 +20,18 @@ public class SimpleAxisVelocity {
|
||||
|
||||
private final List<SimpleEntry> queued = new LinkedList<SimpleEntry>();
|
||||
|
||||
/**
|
||||
* Add to the front of the queue.
|
||||
* @param entry
|
||||
*/
|
||||
public void addToFront(SimpleEntry entry) {
|
||||
queued.add(0, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to the end of the queue.
|
||||
* @param entry
|
||||
*/
|
||||
public void add(SimpleEntry entry) {
|
||||
queued.add(entry);
|
||||
}
|
||||
|
@ -481,7 +481,19 @@ public class TrigUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if both locations have the exact same coordinates. Does not check yaw/pitch.
|
||||
* Compare position and looking direction.
|
||||
* @param loc1
|
||||
* @param loc2
|
||||
* @return Returns false if either is null.
|
||||
*/
|
||||
public static boolean isSamePosAndLook(final Location loc1, final Location loc2) {
|
||||
return isSamePos(loc1, loc2) && loc1.getPitch() == loc2.getPitch() && loc1.getYaw() == loc2.getYaw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if both locations have the exact same coordinates. Does not check
|
||||
* yaw/pitch.
|
||||
*
|
||||
* @param loc1
|
||||
* @param loc2
|
||||
* @return Returns false if either is null.
|
||||
|
Loading…
Reference in New Issue
Block a user