mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-02-05 22:31:26 +01:00
[SAFETY COMMIT] Freeze changes to vertical velocity.
Since other fixes migth be in focus, some changes are commited merged/commented out: * Prepare AxisVelocity to carry positive and negative values. * Prepare MovingData to use vertical AxisVelocity. Rename hVel. * Prepare CreativeFly (...), do not count velocity for height limit. (Most preparations were unfinished, just hinting at the direction.)
This commit is contained in:
parent
3ea098876f
commit
af974a85ac
@ -11,12 +11,19 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class AxisVelocity {
|
public class AxisVelocity {
|
||||||
|
|
||||||
|
/** Velocity with a smaller absolute amount is removed. */
|
||||||
|
private static final double minValue = 0.001;
|
||||||
|
|
||||||
|
private static final double frictionFactor = 0.93;
|
||||||
|
|
||||||
private final List<Velocity> queued = new ArrayList<Velocity>();
|
private final List<Velocity> queued = new ArrayList<Velocity>();
|
||||||
private final List<Velocity> active = new ArrayList<Velocity>();
|
private final List<Velocity> active = new ArrayList<Velocity>();
|
||||||
|
|
||||||
public void add(Velocity vel) {
|
public void add(Velocity vel) {
|
||||||
// TODO: Merging behavior?
|
// TODO: Merging behavior?
|
||||||
queued.add(vel);
|
if (Math.abs(vel.value) != 0.0) {
|
||||||
|
queued.add(vel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasActive() {
|
public boolean hasActive() {
|
||||||
@ -34,10 +41,11 @@ public class AxisVelocity {
|
|||||||
// Decrease counts for active.
|
// Decrease counts for active.
|
||||||
// TODO: Actual friction. Could pass as an argument (special value for not to be used).
|
// TODO: Actual friction. Could pass as an argument (special value for not to be used).
|
||||||
// TODO: Consider removing already invalidated here.
|
// TODO: Consider removing already invalidated here.
|
||||||
|
// TODO: Consider working removeInvalid into this ?
|
||||||
for (final Velocity vel : active) {
|
for (final Velocity vel : active) {
|
||||||
vel.valCount --;
|
vel.valCount --;
|
||||||
vel.sum += vel.value;
|
vel.sum += vel.value;
|
||||||
vel.value *= 0.93; // vel.frictionFactor;
|
vel.value *= frictionFactor; // vel.frictionFactor;
|
||||||
// (Altered entries should be kept, since they get used right away.)
|
// (Altered entries should be kept, since they get used right away.)
|
||||||
}
|
}
|
||||||
// Decrease counts for queued.
|
// Decrease counts for queued.
|
||||||
@ -61,7 +69,7 @@ public class AxisVelocity {
|
|||||||
final Velocity vel = it.next();
|
final Velocity vel = it.next();
|
||||||
// TODO: 0.001 can be stretched somewhere else, most likely...
|
// TODO: 0.001 can be stretched somewhere else, most likely...
|
||||||
// TODO: Somehow use tick here too (actCount, valCount)?
|
// TODO: Somehow use tick here too (actCount, valCount)?
|
||||||
if (vel.valCount <= 0 || vel.value <= 0.001) {
|
if (vel.valCount <= 0 || Math.abs(vel.value) <= minValue) {
|
||||||
// System.out.prsintln("Invalidate active: " + vel);
|
// System.out.prsintln("Invalidate active: " + vel);
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
@ -69,6 +77,7 @@ public class AxisVelocity {
|
|||||||
// Queued.
|
// Queued.
|
||||||
it = queued.iterator();
|
it = queued.iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
|
// TODO: Could check for alternating signum (error).
|
||||||
final Velocity vel = it.next();
|
final Velocity vel = it.next();
|
||||||
if (vel.actCount <= 0 || vel.tick < tick) {
|
if (vel.actCount <= 0 || vel.tick < tick) {
|
||||||
// System.out.println("Invalidate queued: " + vel);
|
// System.out.println("Invalidate queued: " + vel);
|
||||||
@ -79,10 +88,10 @@ public class AxisVelocity {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the sum of active velocity values.
|
* Get the sum of active velocity values.
|
||||||
* @return
|
* @return Can be positive or negative.
|
||||||
*/
|
*/
|
||||||
public double getFreedom() {
|
public double getFreedom() {
|
||||||
// TODO: model/calculate it as accurate as possible...
|
// TODO: model/calculate it as accurate as possible...
|
||||||
double f = 0;
|
double f = 0;
|
||||||
for (final Velocity vel : active) {
|
for (final Velocity vel : active) {
|
||||||
f += vel.value;
|
f += vel.value;
|
||||||
@ -95,18 +104,31 @@ public class AxisVelocity {
|
|||||||
* Amount is the horizontal distance that is to be covered by velocity (active has already been checked).
|
* Amount is the horizontal distance that is to be covered by velocity (active has already been checked).
|
||||||
* <br>
|
* <br>
|
||||||
* If the modeling changes (max instead of sum or similar), then this will be affected.
|
* If the modeling changes (max instead of sum or similar), then this will be affected.
|
||||||
* @param amount The amount used.
|
* @param amount The amount used, should be negative or positive depending on direction.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public double use(final double amount) {
|
public double use(final double amount) {
|
||||||
|
if (!active.isEmpty()) {
|
||||||
|
// Invalidate active on "direction change" [direction of consumption].
|
||||||
|
if (amount * active.get(0).value < 0.0) {
|
||||||
|
active.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
final Iterator<Velocity> it = queued.iterator();
|
final Iterator<Velocity> it = queued.iterator();
|
||||||
double used = 0;
|
double used = 0;
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
final Velocity vel = it.next();
|
final Velocity vel = it.next();
|
||||||
|
if (vel.value * amount < 0.0) {
|
||||||
|
// Not aligned.
|
||||||
|
// TODO: This could be a problem with small amounts of velocity.
|
||||||
|
// TODO: break or remove !? -> need find "next fitting one" and remove all non-fitting before (iff fitting found) ...
|
||||||
|
it.remove(); // TODO: queues ~ continue? vs. invalidate (remove) vs. break; vs. collect and invalidate non-matching BEFORE.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
used += vel.value;
|
used += vel.value;
|
||||||
active.add(vel);
|
active.add(vel);
|
||||||
it.remove();
|
it.remove();
|
||||||
if (used >= amount) {
|
if (Math.abs(used) >= Math.abs(amount)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,9 +50,10 @@ public class CreativeFly extends Check {
|
|||||||
|
|
||||||
// Before doing anything, do a basic height check to determine if players are flying too high.
|
// Before doing anything, do a basic height check to determine if players are flying too high.
|
||||||
final int maximumHeight = cc.creativeFlyMaxHeight + player.getWorld().getMaxHeight();
|
final int maximumHeight = cc.creativeFlyMaxHeight + player.getWorld().getMaxHeight();
|
||||||
if (to.getY() - data.verticalFreedom > maximumHeight)
|
if (to.getY() > maximumHeight) {
|
||||||
return new Location(player.getWorld(), data.getSetBackX(), maximumHeight - 10D, data.getSetBackZ(),
|
// TODO: USE velocity if possible.
|
||||||
to.getYaw(), to.getPitch());
|
return new Location(player.getWorld(), data.getSetBackX(), Math.max(maximumHeight - 10D, to.getWorld().getMaxHeight()), data.getSetBackZ(), to.getYaw(), to.getPitch());
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate some distances.
|
// Calculate some distances.
|
||||||
final double xDistance = to.getX() - from.getX();
|
final double xDistance = to.getX() - from.getX();
|
||||||
@ -96,7 +97,7 @@ public class CreativeFly extends Check {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
data.clearActiveHVel(); // TODO: test/check !
|
data.clearActiveHorVel(); // TODO: test/check !
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean sprinting = time <= data.timeSprinting + cc.sprintingGrace;
|
final boolean sprinting = time <= data.timeSprinting + cc.sprintingGrace;
|
||||||
@ -119,8 +120,16 @@ public class CreativeFly extends Check {
|
|||||||
|
|
||||||
// Super simple, just check distance compared to max distance vertical.
|
// Super simple, just check distance compared to max distance vertical.
|
||||||
// TODO: max descending speed ! [max fall speed, use maximum with speed or added ?]
|
// TODO: max descending speed ! [max fall speed, use maximum with speed or added ?]
|
||||||
|
|
||||||
|
// TODO:_ signum considerations (aligned ...).
|
||||||
|
// double vDistanceAboveLimit = yDistance - data.getVerticalFreedom() - limitV;
|
||||||
|
// if (vDistanceAboveLimit > 0.0) {
|
||||||
|
// // TODO: consume / use vvel
|
||||||
|
// }
|
||||||
|
// 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 resultV = (yDistance - data.verticalFreedom - limitV) * 100D;
|
||||||
|
|
||||||
final double result = Math.max(0.0, resultH) + Math.max(0D, resultV);
|
final double result = Math.max(0.0, resultH) + Math.max(0D, resultV);
|
||||||
|
|
||||||
// The player went to far, either horizontal or vertical.
|
// The player went to far, either horizontal or vertical.
|
||||||
|
@ -116,12 +116,15 @@ public class MovingData extends ACheckData {
|
|||||||
|
|
||||||
// Velocity handling.
|
// Velocity handling.
|
||||||
// TODO: consider resetting these with clearFlyData and onSetBack.
|
// 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 int verticalVelocityCounter;
|
||||||
public double verticalFreedom;
|
public double verticalFreedom;
|
||||||
public double verticalVelocity;
|
public double verticalVelocity;
|
||||||
public int verticalVelocityUsed = 0;
|
public int verticalVelocityUsed = 0;
|
||||||
|
|
||||||
/** Horizontal velocity modeled as an axis (always positive) */
|
/** Horizontal velocity modeled as an axis (always positive) */
|
||||||
private final AxisVelocity hVel = new AxisVelocity();
|
private final AxisVelocity horVel = new AxisVelocity();
|
||||||
|
|
||||||
// Coordinates.
|
// Coordinates.
|
||||||
/** Last from coordinates. */
|
/** Last from coordinates. */
|
||||||
@ -515,18 +518,26 @@ public class MovingData extends ACheckData {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add horizontal velocity (distance). <br>
|
* Add horizontal velocity (distance). <br>
|
||||||
* Since velocity is seldom an access method should be better. Flying players are expensive anyway, so this should not matter too much.
|
* @param vel Assumes positive values always.
|
||||||
* @param vel
|
|
||||||
*/
|
*/
|
||||||
public void addHorizontalVelocity(final Velocity vel) {
|
public void addHorizontalVelocity(final Velocity vel) {
|
||||||
hVel.add(vel);
|
horVel.add(vel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add vertical velocity (distance). <br>
|
||||||
|
* @param vel
|
||||||
|
*/
|
||||||
|
public void addVerticalVelocity(final Velocity vel) {
|
||||||
|
horVel.add(vel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently only applies to horizontal velocity.
|
* Remove all vertical and horizontal velocity.
|
||||||
*/
|
*/
|
||||||
public void removeAllVelocity() {
|
public void removeAllVelocity() {
|
||||||
hVel.clear();
|
horVel.clear();
|
||||||
|
// verVel.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -535,32 +546,49 @@ public class MovingData extends ACheckData {
|
|||||||
* @param tick All velocity added before this tick gets removed.
|
* @param tick All velocity added before this tick gets removed.
|
||||||
*/
|
*/
|
||||||
public void removeInvalidVelocity(final int tick) {
|
public void removeInvalidVelocity(final int tick) {
|
||||||
hVel.removeInvalid(tick);
|
horVel.removeInvalid(tick);
|
||||||
|
// verVel.removeInvalid(tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear only active horizontal velocity.
|
* Clear only active horizontal velocity.
|
||||||
*/
|
*/
|
||||||
public void clearActiveHVel() {
|
public void clearActiveHorVel() {
|
||||||
hVel.clearActive();
|
horVel.clearActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear only active horizontal velocity.
|
||||||
|
*/
|
||||||
|
public void clearActiveVerVel() {
|
||||||
|
horVel.clearActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasActiveHVel() {
|
public boolean hasActiveHorVel() {
|
||||||
return hVel.hasActive();
|
return horVel.hasActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasQueuedHVel() {
|
public boolean hasQueuedHorVel() {
|
||||||
return hVel.hasQueued();
|
return horVel.hasQueued();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public boolean hasActiveVerVel() {
|
||||||
|
// return verVel.hasActive();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public boolean hasQueuedVerVel() {
|
||||||
|
// return verVel.hasQueued();
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called for moving events, increase age of velocity, decrease amounts, check which entries are invalid. Both horizontal and vertical.
|
* Called for moving events, increase age of velocity, decrease amounts, check which entries are invalid. Both horizontal and vertical.
|
||||||
*/
|
*/
|
||||||
public void velocityTick() {
|
public void velocityTick() {
|
||||||
// Horizontal velocity (intermediate concept).
|
// Horizontal velocity (intermediate concept).
|
||||||
hVel.tick();
|
horVel.tick();
|
||||||
|
|
||||||
// Vertical velocity (old concept).
|
// Vertical velocity (new concept).
|
||||||
|
// verVel.tick();
|
||||||
if (verticalVelocity <= 0.09D) {
|
if (verticalVelocity <= 0.09D) {
|
||||||
verticalVelocityUsed ++;
|
verticalVelocityUsed ++;
|
||||||
verticalVelocityCounter--;
|
verticalVelocityCounter--;
|
||||||
@ -590,7 +618,7 @@ public class MovingData extends ACheckData {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public double getHorizontalFreedom() {
|
public double getHorizontalFreedom() {
|
||||||
return hVel.getFreedom();
|
return horVel.getFreedom();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -602,7 +630,7 @@ public class MovingData extends ACheckData {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public double useHorizontalVelocity(final double amount) {
|
public double useHorizontalVelocity(final double amount) {
|
||||||
return hVel.use(amount);
|
return horVel.use(amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -610,13 +638,13 @@ public class MovingData extends ACheckData {
|
|||||||
* @param builder
|
* @param builder
|
||||||
*/
|
*/
|
||||||
public void addHorizontalVelocity(final StringBuilder builder) {
|
public void addHorizontalVelocity(final StringBuilder builder) {
|
||||||
if (hVel.hasActive()) {
|
if (horVel.hasActive()) {
|
||||||
builder.append("\n" + " horizontal velocity (active):");
|
builder.append("\n" + " horizontal velocity (active):");
|
||||||
hVel.addActive(builder);
|
horVel.addActive(builder);
|
||||||
}
|
}
|
||||||
if (hVel.hasQueued()) {
|
if (horVel.hasQueued()) {
|
||||||
builder.append("\n" + " horizontal velocity (queued):");
|
builder.append("\n" + " horizontal velocity (queued):");
|
||||||
hVel.AddQueued(builder);
|
horVel.AddQueued(builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ public class SurvivalFly extends Check {
|
|||||||
hFreedom = res[2];
|
hFreedom = res[2];
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
data.clearActiveHVel();
|
data.clearActiveHorVel();
|
||||||
hFreedom = 0.0;
|
hFreedom = 0.0;
|
||||||
if (resetFrom && data.bunnyhopDelay <= 6) {
|
if (resetFrom && data.bunnyhopDelay <= 6) {
|
||||||
data.bunnyhopDelay = 0;
|
data.bunnyhopDelay = 0;
|
||||||
@ -223,7 +223,7 @@ public class SurvivalFly extends Check {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prevent players from sprinting if they're moving backwards (allow buffers to cover up !?).
|
// Prevent players from sprinting if they're moving backwards (allow buffers to cover up !?).
|
||||||
if (sprinting && data.lostSprintCount == 0 && !cc.assumeSprint && hDistance > walkSpeed && !data.hasActiveHVel()) {
|
if (sprinting && data.lostSprintCount == 0 && !cc.assumeSprint && hDistance > walkSpeed && !data.hasActiveHorVel()) {
|
||||||
// (Ignore some cases, in order to prevent false positives.)
|
// (Ignore some cases, in order to prevent false positives.)
|
||||||
// TODO: speed effects ?
|
// TODO: speed effects ?
|
||||||
if (TrigUtil.isMovingBackwards(xDistance, zDistance, from.getYaw()) && !player.hasPermission(Permissions.MOVING_SURVIVALFLY_SPRINTING)) {
|
if (TrigUtil.isMovingBackwards(xDistance, zDistance, from.getYaw()) && !player.hasPermission(Permissions.MOVING_SURVIVALFLY_SPRINTING)) {
|
||||||
@ -474,7 +474,7 @@ public class SurvivalFly extends Check {
|
|||||||
// TODO: Should there be other side conditions?
|
// TODO: Should there be other side conditions?
|
||||||
// Invalidate used horizontal velocity.
|
// Invalidate used horizontal velocity.
|
||||||
// System.out.println("*** INVALIDATE ON SPEED");
|
// System.out.println("*** INVALIDATE ON SPEED");
|
||||||
data.clearActiveHVel();
|
data.clearActiveHorVel();
|
||||||
// if (data.horizontalVelocityUsed > cc.velocityGraceTicks) {
|
// if (data.horizontalVelocityUsed > cc.velocityGraceTicks) {
|
||||||
// data.horizontalFreedom = 0;
|
// data.horizontalFreedom = 0;
|
||||||
// data.horizontalVelocityCounter = 0;
|
// data.horizontalVelocityCounter = 0;
|
||||||
@ -727,6 +727,8 @@ public class SurvivalFly extends Check {
|
|||||||
private double yDirChange(final PlayerLocation from, final PlayerLocation to, final double yDistance, double vDistanceAboveLimit, final MovingData data) {
|
private double yDirChange(final PlayerLocation from, final PlayerLocation to, final double yDistance, double vDistanceAboveLimit, final MovingData data) {
|
||||||
// TODO: Does this account for velocity in a sufficient way?
|
// TODO: Does this account for velocity in a sufficient way?
|
||||||
if (yDistance > 0) {
|
if (yDistance > 0) {
|
||||||
|
// TODO: Clear active vertical velocity here ?
|
||||||
|
// TODO: Demand consuming queued velocity for valid change (!).
|
||||||
// Increase
|
// Increase
|
||||||
if (data.toWasReset) {
|
if (data.toWasReset) {
|
||||||
tags.add("ychinc");
|
tags.add("ychinc");
|
||||||
@ -747,6 +749,7 @@ public class SurvivalFly extends Check {
|
|||||||
// Decrease
|
// Decrease
|
||||||
tags.add("ychdec");
|
tags.add("ychdec");
|
||||||
// Detect low jumping.
|
// 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.sfDirty && data.mediumLiftOff == MediumLiftOff.GROUND) {
|
||||||
final double setBackYDistance = to.getY() - data.getSetBackY();
|
final double setBackYDistance = to.getY() - data.getSetBackY();
|
||||||
if (setBackYDistance > 0.0) {
|
if (setBackYDistance > 0.0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user