mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-10-03 00:47:25 +02:00
[BLEEDING] Fixes and refactoring for vertical velocity handling.
This is not the thing (lots of yet), but it is a small step. Refactor: * Use access methods for several details on vertical velocity. Fixes: * Dont reset the current jump phase if there is vertical freedom left, because the next jump might then cause a violation. * Fix clearActiveVerVel (remainder used to clear hVel, yet unused). * Clear vertical velocity on removeAllVelocity (!). * Keep setting sfDirty if velocity is found, to prevent premature reset. Missing: * Some resetting conditions for sfDirty might be missing. * Implement an error counter increasing with velocity-add by 1.0 or slightly more , decreasing with violations, but undo violations if count is > 0.0. Use at least for vertical accounting, in order to go stricter on cheating with velocity. * Revise setting sfDirty on horizontal velocity as well. * Switch to AxisVelocity (vertical), accounting for + and -.
This commit is contained in:
parent
4180d3b20b
commit
1510f01144
@ -58,9 +58,9 @@ public class Critical extends Check {
|
||||
if (mcFallDistance > 0.0 && !player.isInsideVehicle() && !player.hasPotionEffect(PotionEffectType.BLINDNESS)) {
|
||||
// Might be a violation.
|
||||
final MovingData dataM = MovingData.getData(player);
|
||||
|
||||
|
||||
// TODO: Skip near the highest jump height (needs check if head collided with something solid, which also detects low jump).
|
||||
if (!dataM.sfDirty && (dataM.sfLowJump && !dataM.sfNoLowJump && dataM.mediumLiftOff == MediumLiftOff.GROUND
|
||||
if (!dataM.isVelocityJumpPhase() && (dataM.sfLowJump && !dataM.sfNoLowJump && dataM.mediumLiftOff == MediumLiftOff.GROUND
|
||||
|| mcFallDistance < cc.criticalFallDistance && !BlockProperties.isResetCond(player, loc, mCc.yOnGround))) {
|
||||
final MovingConfig ccM = MovingConfig.getConfig(player);
|
||||
if (MovingUtil.shouldCheckSurvivalFly(player, dataM, ccM)) {
|
||||
|
@ -143,11 +143,12 @@ public class CreativeFly extends Check {
|
||||
// final double resultV = (vDistanceAboveLimit - limitV) * 100D;
|
||||
// final double result = Math.max(0.0, resultH) + Math.max(0D, resultV);
|
||||
// Old handling.
|
||||
final double resultV = (yDistance - data.verticalFreedom - limitV) * 100D;
|
||||
final double verticalFreedom = data.getVerticalFreedom();
|
||||
final double resultV = (yDistance - verticalFreedom - limitV) * 100D;
|
||||
final double result = Math.max(0.0, resultH) + Math.max(0D, resultV);
|
||||
|
||||
if (cc.debug) {
|
||||
outpuDebugMove(player, hDistance, limitH, yDistance, data.verticalFreedom, limitV);
|
||||
outpuDebugMove(player, hDistance, limitH, yDistance, verticalFreedom, limitV);
|
||||
}
|
||||
|
||||
// The player went to far, either horizontal or vertical.
|
||||
|
@ -15,6 +15,7 @@ import fr.neatmonster.nocheatplus.logging.Streams;
|
||||
import fr.neatmonster.nocheatplus.utilities.ActionAccumulator;
|
||||
import fr.neatmonster.nocheatplus.utilities.ActionFrequency;
|
||||
import fr.neatmonster.nocheatplus.utilities.PlayerLocation;
|
||||
import fr.neatmonster.nocheatplus.utilities.StringUtil;
|
||||
import fr.neatmonster.nocheatplus.utilities.TickTask;
|
||||
|
||||
/**
|
||||
@ -118,10 +119,10 @@ public class MovingData extends ACheckData {
|
||||
// TODO: consider resetting these with clearFlyData and onSetBack.
|
||||
/** Vertical velocity modeled as an axis (positive and negative possible) */
|
||||
//private final AxisVelocity verVel = new AxisVelocity();
|
||||
public int verticalVelocityCounter;
|
||||
public double verticalFreedom;
|
||||
public double verticalVelocity;
|
||||
public int verticalVelocityUsed = 0;
|
||||
private int verticalVelocityCounter;
|
||||
private double verticalFreedom;
|
||||
private double verticalVelocity;
|
||||
private int verticalVelocityUsed = 0;
|
||||
|
||||
/** Horizontal velocity modeled as an axis (always positive) */
|
||||
private final AxisVelocity horVel = new AxisVelocity();
|
||||
@ -182,7 +183,7 @@ public class MovingData extends ACheckData {
|
||||
public int lostSprintCount = 0;
|
||||
public int sfJumpPhase = 0;
|
||||
/** "Dirty" flag, for receiving velocity and similar while in air. */
|
||||
public boolean sfDirty = false;
|
||||
private boolean sfDirty = false;
|
||||
|
||||
/** Indicate low jumping descending phase (likely cheating). */
|
||||
public boolean sfLowJump = false;
|
||||
@ -561,7 +562,8 @@ public class MovingData extends ACheckData {
|
||||
*/
|
||||
public void removeAllVelocity() {
|
||||
horVel.clear();
|
||||
// verVel.clear();
|
||||
clearActiveVerVel(); // Until we have a better method.
|
||||
sfDirty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -581,13 +583,6 @@ public class MovingData extends ACheckData {
|
||||
horVel.clearActive();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear only active horizontal velocity.
|
||||
*/
|
||||
public void clearActiveVerVel() {
|
||||
horVel.clearActive();
|
||||
}
|
||||
|
||||
public boolean hasActiveHorVel() {
|
||||
return horVel.hasActive();
|
||||
}
|
||||
@ -596,6 +591,16 @@ public class MovingData extends ACheckData {
|
||||
return horVel.hasQueued();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear active vertical velocity (until recoded, this will remove all vertical velocity).
|
||||
*/
|
||||
public void clearActiveVerVel() {
|
||||
verticalFreedom = 0.0;
|
||||
verticalVelocity = 0.0;
|
||||
verticalVelocityCounter = 0;
|
||||
verticalVelocityUsed = 0;
|
||||
}
|
||||
|
||||
// public boolean hasActiveVerVel() {
|
||||
// return verVel.hasActive();
|
||||
// }
|
||||
@ -635,6 +640,10 @@ public class MovingData extends ACheckData {
|
||||
verticalFreedom *= 0.93D;
|
||||
}
|
||||
}
|
||||
if (horVel.hasActive() || horVel.hasQueued() || verticalFreedom > 0.001) {
|
||||
// Renew the dirty phase.
|
||||
sfDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -851,4 +860,84 @@ public class MovingData extends ACheckData {
|
||||
// TODO: clear accounting here ?
|
||||
}
|
||||
|
||||
/**
|
||||
* Refactoring stage: Test if velocity has affected the in-air
|
||||
* jumping phase. Use clearActiveVerVel to force end velocity jump phase.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isVelocityJumpPhase() {
|
||||
return sfDirty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refactoring state: Get the classic verticalFreedom.
|
||||
* @return
|
||||
*/
|
||||
public double getVerticalFreedom() {
|
||||
return verticalFreedom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refactoring stage: Fake/override vertical velocity.
|
||||
* @param velocity
|
||||
* @param freedom
|
||||
* @param counter
|
||||
*/
|
||||
public void fakeVerticalFreedom(final double velocity, final double freedom, final int counter) {
|
||||
verticalVelocity = velocity;
|
||||
verticalFreedom = freedom;
|
||||
verticalVelocityCounter = counter;
|
||||
verticalVelocityUsed = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refactoring stage: Test which value sfDirty should have and set
|
||||
* accordingly. This should only be called, if the player reached ground.
|
||||
*
|
||||
* @return If the velocity jump phase is still active (sfDirty).
|
||||
*/
|
||||
public boolean resetVelocityJumpPhase() {
|
||||
if (verticalFreedom > 0.001 || horVel.hasActive() || horVel.hasQueued()) {
|
||||
sfDirty = true;
|
||||
} else {
|
||||
sfDirty = false;
|
||||
}
|
||||
return sfDirty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to builder with a leading newline, if counter or counter or freedom
|
||||
* is above threshold (0 / 0.001).
|
||||
*
|
||||
* @param builder
|
||||
*/
|
||||
public void logVerticalFreedom(StringBuilder builder) {
|
||||
if (verticalVelocityCounter > 0 || verticalFreedom >= 0.001) {
|
||||
builder.append("\n vertical freedom: " + StringUtil.fdec3.format(verticalFreedom) + " (vel=" + StringUtil.fdec3.format(verticalVelocity) + "/counter=" + verticalVelocityCounter +"/used=" + verticalVelocityUsed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refactoring stage: Invalidate vertical velocity based on checking vs.
|
||||
* configured grace ticks.
|
||||
*
|
||||
* @param velocityGraceTicks Ticks to check used ticks vs.
|
||||
* @param removeFreedom If to reset verticalFreedom and use count as well.
|
||||
* @return If actually reset.
|
||||
*/
|
||||
public boolean invalidateVerVelGrace(final int velocityGraceTicks, final boolean removeFreedom) {
|
||||
if (verticalVelocityUsed > velocityGraceTicks) {
|
||||
verticalVelocityCounter = 0;
|
||||
verticalVelocity = 0;
|
||||
if (removeFreedom) {
|
||||
verticalVelocityUsed = 0;
|
||||
verticalFreedom = 0;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1482,10 +1482,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
|
||||
// Give some freedom to allow the "exiting move".
|
||||
data.removeAllVelocity();
|
||||
data.addHorizontalVelocity(new Velocity(0.9, 1, 1));
|
||||
data.verticalVelocityCounter = 1;
|
||||
data.verticalFreedom = 1.2;
|
||||
data.verticalVelocity = 0.15;
|
||||
data.verticalVelocityUsed = 0;
|
||||
data.fakeVerticalFreedom(0.15, 1.2, 1);
|
||||
useLoc.setWorld(null);
|
||||
}
|
||||
|
||||
|
@ -261,6 +261,10 @@ public class SurvivalFly extends Check {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* TODO: Consider to log and/or remember when this was last time
|
||||
* cleared [add time distance to tags/log on violations].
|
||||
*/
|
||||
data.clearActiveHorVel();
|
||||
}
|
||||
|
||||
@ -270,14 +274,18 @@ public class SurvivalFly extends Check {
|
||||
//////////////////////////
|
||||
|
||||
// Account for "dirty"-flag (allow less for normal jumping).
|
||||
if (data.sfDirty) {
|
||||
if (resetFrom || resetTo) {
|
||||
// Not resetting for data.noFallAssumeOnGround, currently.
|
||||
data.sfDirty = false;
|
||||
}
|
||||
else{
|
||||
final boolean sfDirty;
|
||||
if (data.isVelocityJumpPhase()) {
|
||||
if (!resetFrom && !resetTo || data.resetVelocityJumpPhase()) {
|
||||
// TODO: If resetTo && !resetfrom -> too early reset ?
|
||||
sfDirty = true;
|
||||
tags.add("dirty");
|
||||
}
|
||||
else {
|
||||
sfDirty = false;
|
||||
}
|
||||
} else {
|
||||
sfDirty = false;
|
||||
}
|
||||
|
||||
// Calculate the vertical speed limit based on the current jump phase.
|
||||
@ -297,11 +305,11 @@ public class SurvivalFly extends Check {
|
||||
return data.getSetBack(to);
|
||||
}
|
||||
}
|
||||
else if (data.verticalFreedom <= 0.001 && from.isOnClimbable()) {
|
||||
else if (!sfDirty && from.isOnClimbable()) {
|
||||
// Ladder types.
|
||||
vDistanceAboveLimit = vDistClimbable(from, fromOnGround, toOnGround, yDistance, data);
|
||||
}
|
||||
else if (data.verticalFreedom <= 0.001 && from.isInLiquid() && (Math.abs(yDistance) > 0.2 || to.isInLiquid())) {
|
||||
else if (!sfDirty && from.isInLiquid() && (Math.abs(yDistance) > 0.2 || to.isInLiquid())) {
|
||||
// Swimming...
|
||||
final double[] res = vDistLiquid(from, to, toOnGround, yDistance, data);
|
||||
vAllowedDistance = res[0];
|
||||
@ -310,7 +318,7 @@ public class SurvivalFly extends Check {
|
||||
else{
|
||||
// Check y-distance for normal jumping, like in air.
|
||||
// TODO: Can it be easily transformed to a more accurate max. absolute height?
|
||||
vAllowedDistance = 1.35D + data.verticalFreedom;
|
||||
vAllowedDistance = 1.35D + data.getVerticalFreedom();
|
||||
int maxJumpPhase;
|
||||
if (data.mediumLiftOff == MediumLiftOff.LIMIT_JUMP) {
|
||||
// TODO: In normal water this is 0. Could set higher for special cases only (needs efficient data + flags collection?).
|
||||
@ -327,7 +335,7 @@ public class SurvivalFly extends Check {
|
||||
else {
|
||||
maxJumpPhase = 6;
|
||||
}
|
||||
if (data.sfJumpPhase > maxJumpPhase && data.verticalVelocityCounter <= 0 && !data.sfDirty) {
|
||||
if (data.sfJumpPhase > maxJumpPhase && data.getVerticalFreedom() <= 0 && !data.isVelocityJumpPhase()) {
|
||||
if (yDistance < 0) {
|
||||
// Ignore falling, and let accounting deal with it.
|
||||
}
|
||||
@ -453,11 +461,10 @@ public class SurvivalFly extends Check {
|
||||
|
||||
// Invalidation of vertical velocity.
|
||||
// TODO: This invalidation is wrong in case of already jumped higher (can not be repaired?).
|
||||
if (data.verticalVelocityUsed > cc.velocityGraceTicks && yDistance <= 0 && data.sfLastYDist > 0 && data.sfLastYDist != Double.MAX_VALUE) {
|
||||
// data.verticalFreedom = 0; // TODO: <- why?
|
||||
data.verticalVelocityCounter = 0;
|
||||
data.verticalVelocity = 0;
|
||||
tags.add("invalidate_vvel"); // TODO: Test / validate by logs.
|
||||
if (yDistance <= 0 && data.sfLastYDist > 0 && data.sfLastYDist != Double.MAX_VALUE
|
||||
&& data.invalidateVerVelGrace(cc.velocityGraceTicks, false)) {
|
||||
// (Only prevent counting further up, leaves the freedom.)
|
||||
tags.add("cap_vvel"); // TODO: Test / validate by logs.
|
||||
}
|
||||
|
||||
// Apply reset conditions.
|
||||
@ -470,11 +477,8 @@ public class SurvivalFly extends Check {
|
||||
tags.add("resetbunny");
|
||||
}
|
||||
// TODO: Experimental: reset vertical velocity.
|
||||
if (data.verticalVelocityUsed > cc.velocityGraceTicks && yDistance < 0) {
|
||||
data.verticalVelocityCounter = 0;
|
||||
data.verticalFreedom = 0;
|
||||
data.verticalVelocity = 0;
|
||||
data.verticalVelocityUsed = 0;
|
||||
if (yDistance < 0.0 && data.invalidateVerVelGrace(cc.velocityGraceTicks, true)) {
|
||||
tags.add("rem_vvel");
|
||||
}
|
||||
}
|
||||
// Reset data.
|
||||
@ -538,7 +542,7 @@ public class SurvivalFly extends Check {
|
||||
// multiple times if necessary.
|
||||
double hAllowedDistance = 0D;
|
||||
|
||||
final boolean sfDirty = data.sfDirty;
|
||||
final boolean sfDirty = data.isVelocityJumpPhase();
|
||||
|
||||
if (from.isInWeb()) {
|
||||
data.sfOnIce = 0;
|
||||
@ -694,7 +698,7 @@ public class SurvivalFly extends Check {
|
||||
// Allow adding 0.
|
||||
data.vDistAcc.add((float) yDistance);
|
||||
}
|
||||
else if (data.verticalFreedom <= 0.001D) {
|
||||
else if (!data.isVelocityJumpPhase()) {
|
||||
// Here yDistance can be negative and positive.
|
||||
if (yDistance != 0D) {
|
||||
data.vDistAcc.add((float) yDistance);
|
||||
@ -786,7 +790,7 @@ public class SurvivalFly extends Check {
|
||||
}
|
||||
else {
|
||||
// Moving upwards after falling without having touched the ground.
|
||||
if (data.verticalFreedom <= 0.001 && data.bunnyhopDelay < 9 && !(data.fromWasReset && data.sfLastYDist == 0D)) {
|
||||
if (!data.isVelocityJumpPhase() && data.bunnyhopDelay < 9 && !(data.fromWasReset && data.sfLastYDist == 0D)) {
|
||||
// TODO: adjust limit for bunny-hop.
|
||||
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, Math.abs(yDistance));
|
||||
tags.add("ychincfly");
|
||||
@ -801,7 +805,7 @@ public class SurvivalFly extends Check {
|
||||
tags.add("ychdec");
|
||||
// Detect low jumping.
|
||||
// TODO: sfDirty: Account for actual velocity (demands consuming queued for dir-change(!))!
|
||||
if (!data.sfNoLowJump && !data.sfDirty && data.mediumLiftOff == MediumLiftOff.GROUND) {
|
||||
if (!data.sfNoLowJump && data.mediumLiftOff == MediumLiftOff.GROUND && !data.isVelocityJumpPhase()) {
|
||||
final double setBackYDistance = to.getY() - data.getSetBackY();
|
||||
if (setBackYDistance > 0.0) {
|
||||
// Only count it if the player has actually been jumping (higher than setback).
|
||||
@ -1455,9 +1459,7 @@ public class SurvivalFly extends Check {
|
||||
builder.append(player.getName() + " SurvivalFly\nground: " + (data.noFallAssumeGround ? "(assumeonground) " : "") + (fromOnGround ? "onground -> " : (resetFrom ? "resetcond -> " : "--- -> ")) + (toOnGround ? "onground" : (resetTo ? "resetcond" : "---")) + ", jumpphase: " + data.sfJumpPhase);
|
||||
final String dHDist = (BuildParameters.debugLevel > 0 && data.sfLastHDist != Double.MAX_VALUE && Math.abs(data.sfLastHDist - hDistance) > 0.0005) ? ("(" + (hDistance > data.sfLastHDist ? "+" : "") + StringUtil.fdec3.format(hDistance - data.sfLastHDist) + ")") : "";
|
||||
builder.append("\n" + " hDist: " + StringUtil.fdec3.format(hDistance) + dHDist + " / " + StringUtil.fdec3.format(hAllowedDistance) + hBuf + lostSprint + hVelUsed + " , vDist: " + StringUtil.fdec3.format(yDistance) + " (" + StringUtil.fdec3.format(to.getY() - data.getSetBackY()) + " / " + StringUtil.fdec3.format(vAllowedDistance) + "), sby=" + (data.hasSetBack() ? data.getSetBackY() : "?"));
|
||||
if (data.verticalVelocityCounter > 0 || data.verticalFreedom >= 0.001) {
|
||||
builder.append("\n" + " vertical freedom: " + StringUtil.fdec3.format(data.verticalFreedom) + " (vel=" + StringUtil.fdec3.format(data.verticalVelocity) + "/counter=" + data.verticalVelocityCounter +"/used="+data.verticalVelocityUsed);
|
||||
}
|
||||
data.logVerticalFreedom(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);
|
||||
// }
|
||||
|
Loading…
Reference in New Issue
Block a user