use of fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveData in project NoCheatPlus by NoCheatPlus.
the class LostGround method lostGroundAscend.
/**
* Check if a ground-touch has been lost due to event-sending-frequency or other reasons.<br>
* This is for ascending only (yDistance >= 0). Needs last move data.
* @param player
* @param from
* @param loc
* @param to
* @param hDistance
* @param yDistance
* @param sprinting
* @param data
* @param cc
* @return
*/
private static boolean lostGroundAscend(final Player player, final PlayerLocation from, final PlayerLocation to, final double hDistance, final double yDistance, final boolean sprinting, final PlayerMoveData lastMove, final MovingData data, final MovingConfig cc, final Collection<String> tags) {
final PlayerMoveData thisMove = data.playerMoves.getCurrentMove();
final double setBackYDistance = from.getY() - data.getSetBackY();
// TODO: || yDistance <= jump estimate?
if (yDistance <= cc.sfStepHeight && hDistance <= 1.5) {
// hDistance is arbitrary, just to confine.
final double setBackYMargin = data.liftOffEnvelope.getMaxJumpHeight(data.jumpAmplifier) - setBackYDistance;
if (setBackYMargin >= 0.0) {
// TODO: && hDistance < 0.5 ~ switch to about 2.2 * baseSpeed once available.
if (to.isOnGround() && setBackYMargin >= yDistance) {
// TODO: hDistance > 0.0
if (lastMove.yDistance < 0.0 || yDistance <= cc.sfStepHeight && from.isOnGround(cc.sfStepHeight - yDistance)) {
return applyLostGround(player, from, true, thisMove, data, "step", tags);
}
}
// Noob tower (moving up placing blocks underneath). Rather since 1.9: player jumps off with 0.4 speed but ground within 0.42.
// TODO: Re-test with legacy.
// TODO: Confine by actually having placed a block nearby.
// TODO: Jump phase can be 6/7 - also confine by typical max jump phase (!)
final double maxJumpGain = data.liftOffEnvelope.getMaxJumpGain(data.jumpAmplifier);
if (maxJumpGain > yDistance && (// Typical: distance to ground + yDistance roughly covers maxJumpGain.
yDistance > 0.0 && // Rather -0.15 or so.
lastMove.yDistance < 0.0 && Math.abs(lastMove.yDistance) + Magic.GRAVITY_MAX + yDistance > cc.yOnGround + maxJumpGain && from.isOnGround(0.025) || /*
* Rather rare: Come to rest above the block.
* Multiple 0-dist moves with looking packets.
* Not sure this happens with hdist > 0 at all.
*/
lastMove.yDistance == 0.0 && noobTowerStillCommon(to, yDistance))) {
// TODO: Ensure set back is slightly lower, if still on ground.
return applyLostGround(player, from, true, thisMove, data, "nbtwr", tags);
}
}
// Could step up (but might move to another direction, potentially).
if (lastMove.yDistance < 0.0) {
// TODO: Should this also be checked vs. last from?
if (BlockProperties.isOnGroundShuffled(to.getBlockCache(), from.getX(), from.getY() + cc.sfStepHeight, from.getZ(), to.getX(), to.getY(), to.getZ(), 0.1 + from.getBoxMarginHorizontal(), to.getyOnGround(), 0.0)) {
// TODO: !to.isOnGround?
return applyLostGround(player, from, false, thisMove, data, "couldstep", tags);
}
// Possibly confine by more criteria.
if (!to.isOnGround()) {
// TODO: A ray-tracing version of isOnground?
if (lostGroundEdgeAsc(player, from.getBlockCache(), from.getWorld(), from.getX(), from.getY(), from.getZ(), from.getBoxMarginHorizontal(), from.getyOnGround(), lastMove, data, "asc1", tags, from.getMCAccess())) {
return true;
}
// Special cases.
if (yDistance == 0.0 && lastMove.yDistance <= -0.1515 && // Uh oh / dirty flag?
(hDistance <= lastMove.hDistance * 1.1)) {
// Similar to couldstep, with 0 y-distance but slightly above any ground nearby (no micro move!).
// TODO: (hDistance <= data.sfLastHDist || hDistance <= hDistanceBaseRef)
// TODO: Confining in x/z direction in general: should detect if collided in that direction (then skip the x/z dist <= last time).
// TODO: Temporary test (should probably be covered by one of the above instead).
// TODO: Code duplication with edgeasc7 below.
/*
* xzMargin 0.15: equipped end portal frame (observed
* and supposedly fixed on MC 1.12.2) - might use an
* even lower tolerance value here, once there is time
* to testing this.
*/
final double xzMargin = lastMove.yDistance <= -0.23 ? 0.3 : 0.15;
if (lostGroundEdgeAsc(player, from.getBlockCache(), to.getWorld(), to.getX(), to.getY(), to.getZ(), from.getX(), from.getY(), from.getZ(), hDistance, to.getBoxMarginHorizontal(), xzMargin, data, "asc5", tags, from.getMCAccess())) {
return true;
}
} else if (from.isOnGround(from.getyOnGround(), 0.0625, 0.0)) {
// Maybe true ?
return applyLostGround(player, from, false, thisMove, data, "edgeasc2", tags);
}
}
}
}
// Nothing found.
return false;
}
use of fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveData in project NoCheatPlus by NoCheatPlus.
the class SurvivalFly method outputDebug.
/**
* Debug output.
* @param player
* @param to
* @param data
* @param cc
* @param hDistance
* @param hAllowedDistance
* @param hFreedom
* @param yDistance
* @param vAllowedDistance
* @param fromOnGround
* @param resetFrom
* @param toOnGround
* @param resetTo
*/
private void outputDebug(final Player player, final PlayerLocation to, final MovingData data, final MovingConfig cc, final double hDistance, final double hAllowedDistance, final double hFreedom, final double yDistance, final double vAllowedDistance, final boolean fromOnGround, final boolean resetFrom, final boolean toOnGround, final boolean resetTo, final PlayerMoveData thisMove) {
// TODO: Show player name once (!)
final PlayerMoveData lastMove = data.playerMoves.getFirstPastMove();
final StringBuilder builder = new StringBuilder(500);
builder.append(CheckUtils.getLogMessagePrefix(player, type));
final String hBuf = (data.sfHorizontalBuffer < 1.0 ? ((" hbuf=" + StringUtil.fdec3.format(data.sfHorizontalBuffer))) : "");
final String lostSprint = (data.lostSprintCount > 0 ? (" lostSprint=" + data.lostSprintCount) : "");
final String hVelUsed = hFreedom > 0 ? " hVelUsed=" + StringUtil.fdec3.format(hFreedom) : "";
builder.append("\nonground: " + (thisMove.headObstructed ? "(head obstr.) " : "") + (thisMove.touchedGroundWorkaround ? "(touched ground) " : "") + (fromOnGround ? "onground -> " : (resetFrom ? "resetcond -> " : "--- -> ")) + (toOnGround ? "onground" : (resetTo ? "resetcond" : "---")) + ", jumpphase: " + data.sfJumpPhase + ", liftoff: " + data.liftOffEnvelope.name() + "(" + data.insideMediumCount + ")");
final String dHDist = lastMove.toIsValid ? " (" + StringUtil.formatDiff(hDistance, lastMove.hDistance) + ")" : "";
final String dYDist = lastMove.toIsValid ? " (" + StringUtil.formatDiff(yDistance, lastMove.yDistance) + ")" : "";
builder.append("\n" + " hDist: " + StringUtil.fdec3.format(hDistance) + dHDist + " / " + StringUtil.fdec3.format(hAllowedDistance) + hBuf + lostSprint + hVelUsed + " , vDist: " + StringUtil.fdec3.format(yDistance) + dYDist + " / " + StringUtil.fdec3.format(vAllowedDistance) + " , sby=" + (data.hasSetBack() ? (data.getSetBackY() + " (" + StringUtil.fdec3.format(to.getY() - data.getSetBackY()) + " / " + data.liftOffEnvelope.getMaxJumpHeight(data.jumpAmplifier) + ")") : "?"));
if (lastMove.toIsValid) {
builder.append(" , fdsq: " + StringUtil.fdec3.format(thisMove.distanceSquared / lastMove.distanceSquared));
}
if (thisMove.verVelUsed != null) {
builder.append(" , vVelUsed: " + thisMove.verVelUsed + " ");
}
data.addVerticalVelocity(builder);
// if (data.horizontalVelocityCounter > 0 || data.horizontalFreedom >= 0.001) {
// builder.append("\n" + player.getName() + " horizontal freedom: " + StringUtil.fdec3.format(data.horizontalFreedom) + " (counter=" + data.horizontalVelocityCounter +"/used="+data.horizontalVelocityUsed);
// }
data.addHorizontalVelocity(builder);
if (!resetFrom && !resetTo) {
if (cc.survivalFlyAccountingV && data.vDistAcc.count() > data.vDistAcc.bucketCapacity()) {
builder.append("\n" + " vacc: " + data.vDistAcc.toInformalString());
}
}
if (data.combinedMediumHCount > 0) {
// TODO: if hacc activated:
builder.append("\n hacc: " + StringUtil.fdec3.format(data.combinedMediumHValue / (double) data.combinedMediumHCount) + "(" + data.combinedMediumHCount + ")");
}
if (player.isSleeping()) {
tags.add("sleeping");
}
if (player.getFoodLevel() <= 5 && player.isSprinting()) {
// Exception: does not take into account latency.
tags.add("lowfoodsprint");
}
if (Bridge1_9.isWearingElytra(player)) {
// Just wearing (not isGliding).
tags.add("elytra_off");
}
if (!tags.isEmpty()) {
builder.append("\n" + " tags: " + StringUtil.join(tags, "+"));
}
if (!justUsedWorkarounds.isEmpty()) {
builder.append("\n" + " workarounds: " + StringUtil.join(justUsedWorkarounds, "+"));
}
builder.append("\n");
// builder.append(data.stats.getStatsStr(false));
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, builder.toString());
}
use of fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveData in project NoCheatPlus by NoCheatPlus.
the class SurvivalFly method vDistAir.
/**
* Core y-distance checks for in-air movement (may include air -> other).
* @return
*/
private double[] vDistAir(final long now, final Player player, final PlayerLocation from, final boolean fromOnGround, final boolean resetFrom, final PlayerLocation to, final boolean toOnGround, final boolean resetTo, final double hDistance, final double yDistance, final int multiMoveCount, final PlayerMoveData lastMove, final MovingData data, final MovingConfig cc, final IPlayerData pData) {
final PlayerMoveData thisMove = data.playerMoves.getCurrentMove();
// Y-distance for normal jumping, like in air.
double vAllowedDistance = 0.0;
double vDistanceAboveLimit = 0.0;
// Change seen from last yDistance.
final double yDistChange = lastMove.toIsValid ? yDistance - lastMove.yDistance : Double.MAX_VALUE;
// Hacks.
final boolean envelopeHack;
if (!resetFrom && !resetTo && MagicAir.venvHacks(from, to, yDistance, yDistChange, thisMove, lastMove, data)) {
envelopeHack = true;
tags.add("hack_venv");
} else {
envelopeHack = false;
}
// Relative distance (friction, lift-off).
// Estimate expected yDistance.
// TODO: Friction might need same treatment as with horizontal (medium transitions: data.lastFrictionVertical).
// TODO: lostground_pyramid(yDist < 0.0) -> step up (yDist 0.5). Needs better last-move modeling.
// TODO: lostground_edgedesc(yDist <0.0) -> Bunny (yDist > .72, e_jump). Needs better last-move modeling.
// TODO: air->ground...small-range-tp...air-air+vDist==0.0 (might work around with fromWasReset?).
// TODO: bunny after vDist<0.0... vdistsb. Might need set back detection. [solved with setFrictionJumpPhase?]
// TODO: Other edge cases?
// TODO: Cleanup pending.
final boolean strictVdistRel;
final double maxJumpGain = data.liftOffEnvelope.getMaxJumpGain(data.jumpAmplifier);
// TODO: Model differently, workarounds where needed. 0.05 interferes with max height vs. velocity (<= 0.47 gain).
final double jumpGainMargin = 0.005;
// TODO: Add/set 'allow starting to fall' first (data reset / from ground on if no speed).
if (lastMove.toIsValid && Magic.fallingEnvelope(yDistance, lastMove.yDistance, data.lastFrictionVertical, 0.0)) {
// Less headache: Always allow falling.
// TODO: Base should be data.lastFrictionVertical? Problem: "not set" detection?
// Upper bound.
vAllowedDistance = lastMove.yDistance * data.lastFrictionVertical - Magic.GRAVITY_MIN;
strictVdistRel = true;
} else if (resetFrom || thisMove.touchedGroundWorkaround) {
// TODO: More concise conditions? Some workaround may allow more.
if (toOnGround) {
// Hack for boats (coarse: allows minecarts too).
if (yDistance > cc.sfStepHeight && yDistance - cc.sfStepHeight < 0.00000003 && to.isOnGroundDueToStandingOnAnEntity()) {
vAllowedDistance = yDistance;
} else {
vAllowedDistance = Math.max(cc.sfStepHeight, maxJumpGain + jumpGainMargin);
}
} else {
// Code duplication with the absolute limit below.
if (yDistance < 0.0 || yDistance > cc.sfStepHeight || !tags.contains("lostground_couldstep")) {
vAllowedDistance = maxJumpGain + jumpGainMargin;
} else {
// lostground_couldstep
// TODO: Other conditions / envelopes?
vAllowedDistance = yDistance;
}
}
strictVdistRel = false;
} else if (lastMove.toIsValid) {
if (lastMove.yDistance >= -Math.max(Magic.GRAVITY_MAX / 2.0, 1.3 * Math.abs(yDistance)) && lastMove.yDistance <= 0.0 && (lastMove.touchedGround || lastMove.to.extraPropertiesValid && lastMove.to.resetCond)) {
if (resetTo) {
// TODO: Might have to use max if resetto.
vAllowedDistance = cc.sfStepHeight;
} else {
// TODO: Needs more precise confinement + setting set back or distance to ground or estYDist.
vAllowedDistance = maxJumpGain + jumpGainMargin;
}
strictVdistRel = false;
} else {
// Friction.
// TODO: data.lastFrictionVertical (see above).
// Upper bound.
vAllowedDistance = lastMove.yDistance * data.lastFrictionVertical - Magic.GRAVITY_MIN;
strictVdistRel = true;
}
} else {
// Teleport/join/respawn.
vAllowedDistance = vAllowedDistanceNoData(thisMove, lastMove, maxJumpGain, jumpGainMargin, data, cc);
strictVdistRel = false;
}
// Compare yDistance to expected, use velocity on violation.
// TODO: Quick detect valid envelope and move workaround code into a method.
// TODO: data.noFallAssumeGround needs more precise flags (refactor to per move data objects, store 123)
boolean vDistRelVL = false;
// Difference from vAllowedDistance to yDistance.
final double yDistDiffEx = yDistance - vAllowedDistance;
if (envelopeHack || yDistDiffEx <= 0.0 && yDistDiffEx > -Magic.GRAVITY_SPAN) {
// (Clearly accepted envelopes first.)
vDistRelVL = false;
// vAllowedDistance = yDistance;
} else if (yDistDiffEx > 0.0) {
// && (yDistance > 0.0 || (!resetTo && !data.noFallAssumeGround))
if (yDistance <= 0.0 && (resetTo || thisMove.touchedGround)) {
// Allow falling shorter than expected, if onto ground.
// Note resetFrom should usually mean that allowed dist is > 0 ?
} else if (lastMove.toIsValid) {
// TODO: Sort in workarounds to methods, unless extremely frequent.
if (yDistance < 0.0 && lastMove.yDistance < 0.0 && yDistChange > -Magic.GRAVITY_MAX && (from.isOnGround(Math.abs(yDistance) + 0.001) || BlockProperties.isLiquid(to.getTypeId(to.getBlockX(), Location.locToBlock(to.getY() - 0.5), to.getBlockZ())))) {
// Pretty coarse workaround, should instead do a proper modeling for from.getDistanceToGround.
// (OR loc... needs different model, distanceToGround, proper set back, moveHitGround)
// TODO: Slightly too short move onto the same level as snow (0.75), but into air (yDistance > -0.5).
// TODO: Better on-ground model (adapt to actual client code).
} else // }
if (// && data.fromWasReset
yDistDiffEx < Magic.GRAVITY_MIN / 2.0 && data.sfJumpPhase == 1 && // TODO: Test with demanding && (data.noFallAssumeGround || data.liftOffEnvelope != LiftOffEnvelope.NORMAL)
to.getY() - data.getSetBackY() <= data.liftOffEnvelope.getMaxJumpHeight(data.jumpAmplifier) && lastMove.yDistance <= maxJumpGain && yDistance > -Magic.GRAVITY_MAX && yDistance < lastMove.yDistance && lastMove.yDistance - yDistance > Magic.GRAVITY_ODD / 3.0) {
// Special jump (water/edges/assume-ground), too small decrease.
} else if (yDistDiffEx < Magic.GRAVITY_MIN && data.sfJumpPhase == 1 && data.liftOffEnvelope != LiftOffEnvelope.NORMAL && lastMove.from.extraPropertiesValid && lastMove.from.inLiquid && lastMove.yDistance < -Magic.GRAVITY_ODD / 2.0 && lastMove.yDistance > -Magic.GRAVITY_MAX - Magic.GRAVITY_SPAN && yDistance < lastMove.yDistance - 0.001) {
// Odd decrease with water.
} else if (MagicAir.oddJunction(from, to, yDistance, yDistChange, yDistDiffEx, maxJumpGain, resetTo, thisMove, lastMove, data, cc)) {
// Several types of odd in-air moves, mostly with gravity near maximum, friction, medium change.
} else if (yDistDiffEx < 0.025 && Magic.noobJumpsOffTower(yDistance, maxJumpGain, thisMove, lastMove, data)) {
/*
* On (noob) tower up, the second move has a higher distance
* than expected, because the first had been starting
* slightly above the top.
*/
} else {
// Violation.
vDistRelVL = true;
}
} else {
// Violation.
vDistRelVL = true;
}
} else // else: yDistDiffEx <= 0.0
if (yDistance >= 0.0) {
// Moved too short.
if (!strictVdistRel || Math.abs(yDistDiffEx) <= Magic.GRAVITY_SPAN || vAllowedDistance <= 0.2) {
// Allow jumping less high unless within "strict envelope".
// TODO: Extreme anti-jump effects, perhaps.
} else if (yDistance > 0.0 && lastMove.toIsValid && lastMove.yDistance > yDistance && lastMove.yDistance - yDistance <= lastMove.yDistance / 4.0 && data.isVelocityJumpPhase()) {
// Too strong decrease with velocity.
// TODO: Observed when moving off water, might be confined by that.
} else if (thisMove.headObstructed || lastMove.toIsValid && lastMove.headObstructed && lastMove.yDistance >= 0.0) {
// Head is blocked, thus a shorter move.
} else if (lastMove.toIsValid && MagicAir.oddJunction(from, to, yDistance, yDistChange, yDistDiffEx, maxJumpGain, resetTo, thisMove, lastMove, data, cc)) {
// Several types of odd in-air moves, mostly with gravity near maximum, friction, medium change.
} else if (thisMove.yDistance < 1.0 && thisMove.yDistance > 0.9 && lastMove.yDistance >= 1.5 && data.sfJumpPhase <= 2 && lastMove.verVelUsed != null && (lastMove.verVelUsed.flags & (VelocityFlags.ORIGIN_BLOCK_MOVE | VelocityFlags.ORIGIN_BLOCK_BOUNCE)) != 0) {
// Allow too strong decrease.
// TODO: Another magic check here? Route most checks through methods anyway?
} else {
vDistRelVL = true;
}
// else: Allow moving up less. Note: possibility of low jump.
} else {
// if (yDistance < 0.0) // Rather too fast falling.
if (yDistance < -3.0 && lastMove.yDistance < -3.0 && Math.abs(yDistDiffEx) < 5.0 * Magic.GRAVITY_MAX) {
// Disregard not falling faster at some point (our constants don't match 100%).
} else if (resetTo && (yDistDiffEx > -Magic.GRAVITY_SPAN || !fromOnGround && !thisMove.touchedGround && yDistChange >= 0.0)) {
// Moving onto ground allows a shorter move.
// TODO: Any lost-ground cases?
} else if (yDistance > lastMove.yDistance - Magic.GRAVITY_MAX - Magic.GRAVITY_SPAN && (resetTo || thisMove.touchedGround)) {
// Mirrored case for yDistance > yAllowedDistance, hitting ground.
// TODO: Needs more efficient structure.
} else if (resetFrom && yDistance >= -0.5 && (yDistance > -0.31 || (resetTo || to.isAboveStairs()) && (lastMove.yDistance < 0.0))) {
// Stairs and other cases moving off ground or ground-to-ground.
// TODO: Margins !?
} else if (data.liftOffEnvelope == LiftOffEnvelope.LIMIT_LIQUID && data.sfJumpPhase == 1 && lastMove.toIsValid && lastMove.from.inLiquid && !(lastMove.to.extraPropertiesValid && lastMove.to.inLiquid) && !resetFrom && // TODO: There might be other cases (possibly wrong bounding box).
resetTo && lastMove.yDistance > 0.0 && lastMove.yDistance < 0.5 * Magic.GRAVITY_ODD && yDistance < 0.0 && Math.abs(Math.abs(yDistance) - lastMove.yDistance) < Magic.GRAVITY_SPAN / 2.0) {
// LIMIT_LIQUID, vDist inversion (!).
} else if (yDistance <= 0.0 && yDistance > -Magic.GRAVITY_MAX - Magic.GRAVITY_SPAN && (thisMove.headObstructed || lastMove.toIsValid && lastMove.headObstructed && lastMove.yDistance >= 0.0)) {
// Head was blocked, thus faster decrease than expected.
} else if (lastMove.toIsValid && MagicAir.oddJunction(from, to, yDistance, yDistChange, yDistDiffEx, maxJumpGain, resetTo, thisMove, lastMove, data, cc)) {
// Several types of odd in-air moves, mostly with gravity near maximum, friction, medium change.
} else {
// Violation.
vDistRelVL = true;
}
// else Accept small aberrations !?
}
if (vDistRelVL) {
if (data.getOrUseVerticalVelocity(yDistance) == null) {
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, Math.abs(yDistance - vAllowedDistance));
tags.add("vdistrel");
}
}
// Absolute y-distance to set back.
if (yDistance > 0.0 && !data.isVelocityJumpPhase()) {
// TODO: Maintain a value in data, adjusting to velocity?
// TODO: LIMIT_JUMP
final double vAllowedAbsoluteDistance = data.liftOffEnvelope.getMaxJumpHeight(data.jumpAmplifier);
final double totalVDistViolation = to.getY() - data.getSetBackY() - vAllowedAbsoluteDistance;
if (totalVDistViolation > 0.0) {
// Skip actually stepping up.
if ((fromOnGround || thisMove.touchedGroundWorkaround || lastMove.touchedGround) && toOnGround && yDistance <= cc.sfStepHeight) {
// Ignore: Legitimate step.
} else // Skip if the player could step up by lostground_couldstep.
if (yDistance <= cc.sfStepHeight && thisMove.touchedGroundWorkaround && tags.contains("lostground_couldstep")) {
// Ignore: Envelope already checked.
} else // Teleport to in-air (PaperSpigot 1.7.10).
if (Magic.skipPaper(thisMove, lastMove, data)) {
// Tag already set above.
} else // Attempt to use velocity.
if (data.getOrUseVerticalVelocity(yDistance) == null) {
// Violation.
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, totalVDistViolation);
tags.add("vdistsb");
}
}
}
if (data.sfLowJump) {
tags.add("lowjump");
}
// TODO: move into the in air checking above !?
if (!envelopeHack && !resetFrom && !resetTo) {
// "On-air" checks (vertical, already use velocity if needed).
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, inAirChecks(now, from, to, hDistance, yDistance, thisMove, lastMove, data, cc));
}
// (Actual step cheats are probably better detected by generalized patterns.)
if (vDistanceAboveLimit <= 0D && yDistance > cc.sfStepHeight && yDistance < data.liftOffEnvelope.getMinJumpGain(data.jumpAmplifier) && !thisMove.headObstructed && !thisMove.from.resetCond && !thisMove.to.resetCond && (thisMove.from.onGround || thisMove.touchedGroundWorkaround) && thisMove.to.onGround) {
// Exclude a lost-ground case.
if (thisMove.touchedGroundWorkaround && lastMove.toIsValid && lastMove.yDistance <= 0.0 && yDistance + Math.abs(lastMove.yDistance) <= 2.0 * (maxJumpGain + 0.1)) {
// TODO: Review: still needed?
} else {
// Potential violation.
if (!pData.hasPermission(Permissions.MOVING_SURVIVALFLY_STEP, player) && data.getOrUseVerticalVelocity(yDistance) == null) {
vDistanceAboveLimit = yDistance - cc.sfStepHeight;
tags.add("step");
}
}
}
// Air-stay-time.
// TODO: max-phase only when from is not reset !?
final int maxJumpPhase = data.liftOffEnvelope.getMaxJumpPhase(data.jumpAmplifier);
if (!envelopeHack && data.sfJumpPhase > maxJumpPhase && !data.isVelocityJumpPhase()) {
if (yDistance < 0) {
// Ignore falling, and let accounting deal with it.
} else if (resetFrom) {
// Ignore bunny etc.
} else {
// Violation (Too high jumping or step).
if (data.getOrUseVerticalVelocity(yDistance) == null) {
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, Math.max(yDistance, 0.15));
tags.add("maxphase");
}
}
}
return new double[] { vAllowedDistance, vDistanceAboveLimit };
}
use of fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveData in project NoCheatPlus by NoCheatPlus.
the class MovingUtil method ensureChunksLoaded.
/**
* Ensure nearby chunks are loaded. Further skip chunk loading if the latest
* stored past move has extra properties set and is close by.
*
* @param player
* @param loc
* @param tag
* The type of context/event for debug logging.
* @param data
* @param cc
*/
public static void ensureChunksLoaded(final Player player, final Location loc, final String tag, final MovingData data, final MovingConfig cc, final IPlayerData pData) {
final PlayerMoveData lastMove = data.playerMoves.getFirstPastMove();
final double x0 = loc.getX();
final double z0 = loc.getZ();
// Heuristic for if loading may be necessary at all.
if (lastMove.toIsValid && lastMove.to.extraPropertiesValid) {
if (TrigUtil.distanceSquared(lastMove.to, x0, z0) < 1.0) {
return;
}
} else if (lastMove.valid && lastMove.from.extraPropertiesValid && cc.loadChunksOnJoin) {
// TODO: Might need to distinguish join/teleport/world-change later.
if (TrigUtil.distanceSquared(lastMove.from, x0, z0) < 1.0) {
return;
}
}
int loaded = MapUtil.ensureChunksLoaded(loc.getWorld(), loc.getX(), loc.getZ(), Magic.CHUNK_LOAD_MARGIN_MIN);
if (loaded > 0 && pData.isDebugActive(CheckType.MOVING)) {
StaticLog.logInfo("Player " + tag + ": Loaded " + loaded + " chunk" + (loaded == 1 ? "" : "s") + " for the world " + loc.getWorld().getName() + " for player: " + player.getName());
}
}
use of fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveData in project NoCheatPlus by NoCheatPlus.
the class VehicleChecks method onPlayerVehicleLeave.
/**
* Call on leaving or just having left a vehicle.
* @param player
* @param vehicle May be null in case of "not possible to determine".
*/
private void onPlayerVehicleLeave(final Player player, final Entity vehicle) {
final IPlayerData pData = DataManager.getPlayerData(player);
final MovingData data = pData.getGenericInstance(MovingData.class);
final boolean debug = pData.isDebugActive(checkType);
data.wasInVehicle = false;
data.joinOrRespawn = false;
// if (data.vehicleSetBackTaskId != -1) {
// // Await set back.
// // TODO: might still set ordinary set backs ?
// return;
// }
final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
// TODO: Loc can be inconsistent, determine which to use !
final Location pLoc = player.getLocation(useLoc1);
// The location to use as set back.
Location loc = pLoc;
// final Entity vehicle = player.getVehicle();
if (vehicle != null) {
final Location vLoc = vehicle.getLocation(useLoc2);
// Workaround for some entities/animals that don't fire VehicleMoveEventS.
if (!normalVehicles.contains(vehicle.getType()) || cc.noFallVehicleReset) {
// Might allow one time cheat.
data.noFallSkipAirCheck = true;
data.clearNoFallData();
}
// Check consistency with vehicle location.
if (MoveConsistency.getConsistency(vLoc, null, pLoc) == MoveConsistency.INCONSISTENT) {
// TODO: Consider teleporting the player (...)
// TODO: What with the case of vehicle moved to another world !?
//
loc = vLoc;
if (data.vehicleConsistency != MoveConsistency.INCONSISTENT) {
// TODO: This may need re-setting on player move -> vehicle move.
final PlayerMoveData lastMove = data.playerMoves.getFirstPastMove();
if (lastMove.toIsValid) {
final Location oldLoc = new Location(pLoc.getWorld(), lastMove.to.getX(), lastMove.to.getY(), lastMove.to.getZ());
if (MoveConsistency.getConsistency(oldLoc, null, pLoc) != MoveConsistency.INCONSISTENT) {
loc = oldLoc;
}
}
}
}
if (debug) {
debug(player, "Vehicle leave: " + vehicle.getType() + "@" + pLoc.distance(vLoc));
}
}
// Adjust loc if in liquid (meant for boats !?).
if (BlockProperties.isLiquid(loc.getBlock().getType())) {
loc.setY(Location.locToBlock(loc.getY()) + 1.25);
}
if (debug) {
debug(player, "Vehicle leave: " + pLoc.toString() + (pLoc.equals(loc) ? "" : " / player at: " + pLoc.toString()));
}
aux.resetPositionsAndMediumProperties(player, loc, data, cc);
data.setSetBack(loc);
// Give some freedom to allow the "exiting move".
data.removeAllVelocity();
// TODO: Use-once entries usually are intended to allow one offset, but not jumping/flying on.
data.addHorizontalVelocity(new AccountEntry(0.9, 1, 1));
// TODO: Typical margin?
data.addVerticalVelocity(new SimpleEntry(0.6, 1));
useLoc1.setWorld(null);
useLoc2.setWorld(null);
}
Aggregations