Prevent ascension over max jump phase for normal jumping/moving.

Adds a "dirty"-flag, set on receiving velocity. If a player still
ascends while exceeding max-jump-phase, a violation will be triggered,
regardless of the taken distance. This has not been tested against hacks
yet, and might well have little effect. It does aim against step and
block-jumping on protected regions, but there might be another limiting
method necessary to make this fully effective.
This commit is contained in:
asofold 2013-01-31 10:01:46 +01:00
parent f38822e4d5
commit 7e4ad21f4f
3 changed files with 49 additions and 16 deletions

View File

@ -125,6 +125,8 @@ public class MovingData extends ACheckData {
// Data of the survival fly check.
public double sfHorizontalBuffer = 0;
public int sfJumpPhase = 0;
/** "Dirty" flag, for receiving velocity and similar while in air. */
public boolean sfDirty = false;
/**
* Last valid y distance covered by a move. Integer.MAX_VALUE indicates "not set".
*/
@ -162,6 +164,7 @@ public class MovingData extends ACheckData {
sfHorizontalBuffer = 0;
toWasReset = fromWasReset = false; // TODO: true maybe
sfHoverTicks = -1;
sfDirty = false;
}
/**
@ -188,6 +191,7 @@ public class MovingData extends ACheckData {
sfHorizontalBuffer = Math.min(0, sfHorizontalBuffer);
toWasReset = fromWasReset = false; // TODO: true maybe
sfHoverTicks = -1;
sfDirty = false;
}
/**
@ -239,6 +243,7 @@ public class MovingData extends ACheckData {
fromY = toY = y;
fromZ = toZ = z;
sfLastYDist = Double.MAX_VALUE;
sfDirty = false;
}
/**

View File

@ -888,6 +888,9 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
data.horizontalFreedom += newVal;
data.horizontalVelocityCounter = 30;
}
// Set dirty flag here.
data.sfDirty = true;
}
/**

View File

@ -201,9 +201,20 @@ public class SurvivalFly extends Check {
} else if (hDistance != 0D){
data.sfHorizontalBuffer = Math.min(1D, data.sfHorizontalBuffer - hDistanceAboveLimit);
}
// 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{
tags.add("dirty");
}
}
// Calculate the vertical speed limit based on the current jump phase.
double vAllowedDistance, vDistanceAboveLimit;
double vAllowedDistance, vDistanceAboveLimit = 0;
if (from.isInWeb()){
// Very simple: force players to descend or stay.
vAllowedDistance = from.isOnGround() ? 0.1D : 0;
@ -274,11 +285,19 @@ public class SurvivalFly extends Check {
else maxJumpPhase = 6;
// TODO: consider tags for jumping as well (!).
if (data.sfJumpPhase > maxJumpPhase && data.verticalVelocityCounter <= 0){
vAllowedDistance -= Math.max(0, (data.sfJumpPhase - maxJumpPhase) * 0.15D);
// Could use dirty flag here !
if (data.sfDirty || yDistance < 0){
vAllowedDistance -= Math.max(0, (data.sfJumpPhase - maxJumpPhase) * 0.15D);
}
else if (!data.sfDirty){
// Violation (Too high jumping or step).
tags.add("maxphase");
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, 1.0);
}
}
// TODO: This might need max(0, for ydiff)
vDistanceAboveLimit = to.getY() - data.getSetBackY() - vAllowedDistance;
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, to.getY() - data.getSetBackY() - vAllowedDistance);
if (vDistanceAboveLimit > 0) tags.add("vdist");
@ -300,23 +319,12 @@ public class SurvivalFly extends Check {
// "On-air" checks (vertical)
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, verticalAccounting(now, yDistance, data, cc));
}
final double result = (Math.max(hDistanceAboveLimit, 0D) + Math.max(vDistanceAboveLimit, 0D)) * 100D;
if (cc.debug) {
// TODO: also show resetcond (!)
StringBuilder builder = new StringBuilder(500);
builder.append(player.getName() + " ground: " + (data.noFallAssumeGround ? "(assumeonground) " : "") + (fromOnGround ? "onground -> " : (resetFrom ? "resetcond -> " : "--- -> ")) + (toOnGround ? "onground" : (resetTo ? "resetcond" : "---")) + "\n");
builder.append(player.getName() + " hDist: " + StringUtil.fdec3.format(hDistance) + " / " + StringUtil.fdec3.format(hAllowedDistance) + " , vDist: " + StringUtil.fdec3.format(yDistance) + " / " + StringUtil.fdec3.format(vAllowedDistance) + "\n");
builder.append(player.getName() + " vfreedom: " + StringUtil.fdec3.format(data.verticalFreedom) + " (vv=" + StringUtil.fdec3.format(data.verticalVelocity) + "/vvc=" + data.verticalVelocityCounter + "), jumpphase: " + data.sfJumpPhase + "\n");
if (!resetFrom && !resetTo) {
// if (cc.survivalFlyAccountingH && data.hDistCount.bucketScore(1) > 0 && data.hDistCount.bucketScore(2) > 0) builder.append(player.getName() + " hacc=" + data.hDistSum.bucketScore(2) + "->" + data.hDistSum.bucketScore(1) + "\n");
if (cc.survivalFlyAccountingV && data.vDistCount.bucketScore(1) > 0 && data.vDistCount.bucketScore(2) > 0) builder.append(player.getName() + " vacc=" + data.vDistSum.bucketScore(2) + "->" + data.vDistSum.bucketScore(1) + "\n");
}
if (player.isSleeping()) tags.add("sleeping");
if (!tags.isEmpty()) builder.append(player.getName() + " tags: " + StringUtil.join(tags, "+") + "\n");
System.out.print(builder.toString());
// Put in a method for shorter code.
outputDebug(player, data, cc, hDistanceAboveLimit, hAllowedDistance, yDistance, vAllowedDistance, fromOnGround, resetFrom, toOnGround, resetTo);
}
data.sfJumpPhase++;
@ -350,6 +358,23 @@ public class SurvivalFly extends Check {
return null;
}
private void outputDebug(final Player player, final MovingData data, final MovingConfig cc,
final double hDistance, final double hAllowedDistance, final double yDistance, final double vAllowedDistance,
final boolean fromOnGround, final boolean resetFrom, final boolean toOnGround, final boolean resetTo) {
// TODO: also show resetcond (!)
StringBuilder builder = new StringBuilder(500);
builder.append(player.getName() + " ground: " + (data.noFallAssumeGround ? "(assumeonground) " : "") + (fromOnGround ? "onground -> " : (resetFrom ? "resetcond -> " : "--- -> ")) + (toOnGround ? "onground" : (resetTo ? "resetcond" : "---")) + "\n");
builder.append(player.getName() + " hDist: " + StringUtil.fdec3.format(hDistance) + " / " + StringUtil.fdec3.format(hAllowedDistance) + " , vDist: " + StringUtil.fdec3.format(yDistance) + " / " + StringUtil.fdec3.format(vAllowedDistance) + "\n");
builder.append(player.getName() + " vfreedom: " + StringUtil.fdec3.format(data.verticalFreedom) + " (vv=" + StringUtil.fdec3.format(data.verticalVelocity) + "/vvc=" + data.verticalVelocityCounter + "), jumpphase: " + data.sfJumpPhase + "\n");
if (!resetFrom && !resetTo) {
// if (cc.survivalFlyAccountingH && data.hDistCount.bucketScore(1) > 0 && data.hDistCount.bucketScore(2) > 0) builder.append(player.getName() + " hacc=" + data.hDistSum.bucketScore(2) + "->" + data.hDistSum.bucketScore(1) + "\n");
if (cc.survivalFlyAccountingV && data.vDistCount.bucketScore(1) > 0 && data.vDistCount.bucketScore(2) > 0) builder.append(player.getName() + " vacc=" + data.vDistSum.bucketScore(2) + "->" + data.vDistSum.bucketScore(1) + "\n");
}
if (player.isSleeping()) tags.add("sleeping");
if (!tags.isEmpty()) builder.append(player.getName() + " tags: " + StringUtil.join(tags, "+") + "\n");
System.out.print(builder.toString());
}
private boolean lostGround(final Player player, final PlayerLocation from, final PlayerLocation to, final double yDistance, final MovingData data, final MovingConfig cc) {
// Don't set "useWorkaround = x()", to avoid potential trouble with
// reordering to come, and similar.