Re-model extra horizontal buffer to a counter for "lost sprint".

The problems with attacking + sprint/bunny seems to be that the player 
moves on as if sprinting, thus we reformulate it as the "lost sprint"
problem. The sprintback check is skipped during lostsprint phases.

This should be worth a ticket for Mojang/CB, sprint + jump + attack 
somewhere around touch down time (+-) - server side sprinting turns off,
but the player moves on as if sprinting.
This commit is contained in:
asofold 2013-07-19 22:57:10 +02:00
parent 471579d595
commit 2856919409
4 changed files with 60 additions and 47 deletions

View File

@ -222,20 +222,24 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
data.lastAttackedZ = targetLoc.getZ();
// data.lastAttackedDist = targetDist;
// Velocity freedom adaption.
if (!cancelled && player.isSprinting() && TrigUtil.distance(loc.getX(), loc.getZ(), targetLoc.getX(), targetLoc.getZ()) < 3.0){
// TODO: Refine conditions by jumpphase / on ground and similar
// Add "mini" freedom.
// Care for the "lost sprint problem": sprint resets, client moves as if still...
if (!cancelled && player.isSprinting() && TrigUtil.distance(loc.getX(), loc.getZ(), targetLoc.getX(), targetLoc.getZ()) < 4.5){
// TODO: Refine/more conditions.
// TODO: For pvp make use of "player was there" heuristic later on.
final MovingData mData = MovingData.getData(player);
// TODO: Check distance of other entity.
if (mData.fromX != Double.MAX_VALUE){
final double hDist = TrigUtil.distance(loc.getX(), loc.getZ(), mData.fromX, mData.fromZ) ;
if (hDist >= 0.23 && mData.sfHorizontalBuffer > 0.5 && MovingListener.shouldCheckSurvivalFly(player, mData, MovingConfig.getConfig(player))){
// Allow extra consumption with buffer.
// TODO: Add to normal buffer or add velocity entry.
mData.sfHBufExtra = 7;
if (cc.debug && BuildParameters.debugLevel > 0){
System.out.println(player.getName() + " attacks, hDist to last from: " + hDist + " | targetdist=" + TrigUtil.distance(loc.getX(), loc.getZ(), targetLoc.getX(), targetLoc.getZ()) + " | sprinting=" + player.isSprinting() + " | food=" + player.getFoodLevel() +" | hbuf=" + mData.sfHorizontalBuffer);
// TODO: What would mData.lostSprintCount > 0 mean here?
final double hDist = TrigUtil.distance(loc.getX(), loc.getZ(), mData.fromX, mData.fromZ);
if (hDist >= 0.23 && mData.sfHorizontalBuffer > 0.5){
final MovingConfig mc = MovingConfig.getConfig(player);
// Check if fly checks is an issue at all, re-check "real sprinting".
if (now <= mData.timeSprinting + mc.sprintingGrace && MovingListener.shouldCheckSurvivalFly(player, mData, mc)){
// Judge as "lost sprint" problem.
mData.lostSprintCount = 7;
if (cc.debug && BuildParameters.debugLevel > 0){
System.out.println(player.getName() + " (lostsprint) hDist to last from: " + hDist + " | targetdist=" + TrigUtil.distance(loc.getX(), loc.getZ(), targetLoc.getX(), targetLoc.getZ()) + " | sprinting=" + player.isSprinting() + " | food=" + player.getFoodLevel() +" | hbuf=" + mData.sfHorizontalBuffer);
}
}
}
}

View File

@ -170,8 +170,8 @@ public class MovingData extends ACheckData {
// Data of the survival fly check.
public double sfHorizontalBuffer = 0;
/** Times to add extra horizontal buffer if necessary. */
public int sfHBufExtra = 0;
/** Event-counter to cover up for sprinting resetting server side only. Set in the FighListener. */
public int lostSprintCount = 0;
public int sfJumpPhase = 0;
/** "Dirty" flag, for receiving velocity and similar while in air. */
public boolean sfDirty = false;
@ -218,7 +218,7 @@ public class MovingData extends ACheckData {
clearNoFallData();
removeAllVelocity();
sfHorizontalBuffer = 0;
sfHBufExtra = 0;
lostSprintCount = 0;
toWasReset = fromWasReset = false; // TODO: true maybe
sfHoverTicks = sfHoverLoginTicks = -1;
sfDirty = false;
@ -248,7 +248,7 @@ public class MovingData extends ACheckData {
// Keep bunny-hop delay (?)
// keep jump phase.
sfHorizontalBuffer = Math.min(0, sfHorizontalBuffer);
sfHBufExtra = 0;
lostSprintCount = 0;
toWasReset = fromWasReset = false; // TODO: true maybe
sfHoverTicks = -1;
sfDirty = false;

View File

@ -105,16 +105,41 @@ public class SurvivalFly extends Check {
final boolean resetTo = toOnGround || to.isResetCond();
final boolean resetFrom;
// A player is considered sprinting if the flag is set and if he has enough food level.
final boolean sprinting = now <= data.timeSprinting + cc.sprintingGrace;
if (sprinting && now != data.timeSprinting){
tags.add("sprintgrace");
}
// Use the player-specific walk speed.
// Use the player-specific walk speed.
// TODO: Might get from listener.
// TODO: Use in lostground?
final double walkSpeed = SurvivalFly.walkSpeed * ((double) player.getWalkSpeed() / 0.2);
// Determine if the player is actually sprinting.
final boolean sprinting;
if (data.lostSprintCount > 0) {
// Sprint got toggled off, though the client is still (legitimately) moving at sprinting speed.
if (resetTo && (fromOnGround || from.isResetCond()) || hDistance <= walkSpeed){
// Invalidate.
data.lostSprintCount = 0;
// TODO: Check fp with this very one.
tags.add("invalidate_lostsprint");
sprinting = false;
}
else{
tags.add("lostsprint");
sprinting = true;
if (data.lostSprintCount < 3 && to.isOnGround() || to.isResetCond()){
data.lostSprintCount = 0;
}
else{
data.lostSprintCount --;
}
}
}
else if (now <= data.timeSprinting + cc.sprintingGrace) {
// Within grace period for hunger level being too low for sprinting on server side (latency).
tags.add("sprintgrace");
sprinting = true;
}
else{
sprinting = false;
}
/////////////////////////////////
// Mixed checks (lost ground).
@ -162,7 +187,6 @@ public class SurvivalFly extends Check {
}
else{
data.hVelActive.clear();
data.sfHBufExtra = 0; // TODO: Doesn't this render it ineffective !?
hFreedom = 0.0;
if (hDistance != 0D){
// TODO: Confine conditions further ?
@ -180,7 +204,8 @@ public class SurvivalFly extends Check {
}
// Prevent players from sprinting if they're moving backwards (allow buffers to cover up !?).
if (sprinting) {
if (sprinting && data.lostSprintCount == 0) {
// (Ignore if lost sprint is active, in order to forestall false positives.)
// TODO: Check if still necessary to check here with timeSprinting change (...).
// TODO: Find more ways to confine conditions.
final float yaw = from.getYaw();
@ -762,23 +787,6 @@ public class SurvivalFly extends Check {
* @return hAllowedDistance, hDistanceAboveLimit, hFreedom
*/
private double[] hDistAfterFailure(final Player player, final PlayerLocation from, final PlayerLocation to, double hAllowedDistance, final double hDistance, double hDistanceAboveLimit, final boolean sprinting, final boolean downStream, final MovingData data, final MovingConfig cc) {
// Extra buffer.
// Used for attacking+bunny.
// TODO: rather switch to velocity entry with max-use-amount: problem: unique + special invalidation.
final double extraUsed;
if (data.sfHBufExtra > 0){
extraUsed = 0.11;
hDistanceAboveLimit = Math.max(0.0, hDistanceAboveLimit - extraUsed);
data.sfHBufExtra --;
tags.add("hbufextra");
if (data.sfHBufExtra < 3 && to.isOnGround() || to.isResetCond()){
data.sfHBufExtra = 0;
}
}
else{
extraUsed = 0.0;
}
// Check velocity.
double hFreedom = 0.0; // Horizontal velocity used (!).
@ -802,11 +810,9 @@ public class SurvivalFly extends Check {
// After failure permission checks ( + speed modifier + sneaking + blocking + speeding) and velocity (!).
if (hDistanceAboveLimit > 0.0){
hAllowedDistance = getAllowedhDist(player, from, to, sprinting, downStream, hDistance, walkSpeed, data, cc, true);
hDistanceAboveLimit = hDistance - hAllowedDistance;
if (hFreedom > 0.0){
hDistanceAboveLimit = hDistance - hAllowedDistance - extraUsed - hFreedom;
}
else{
hDistanceAboveLimit = hDistance - hAllowedDistance - extraUsed;
hDistanceAboveLimit -= hFreedom;
}
if (hAllowedDistance > 0.0){ // TODO: Fix !
// (Horizontal buffer might still get used.)
@ -1313,10 +1319,10 @@ public class SurvivalFly extends Check {
// TODO: Show player name once (!)
final StringBuilder builder = new StringBuilder(500);
final String hBuf = (data.sfHorizontalBuffer < 1.0 ? ((" hbuf=" + StringUtil.fdec3.format(data.sfHorizontalBuffer))) : "");
final String hBufExtra = (data.sfHBufExtra > 0 ? (" hbufextra=" + data.sfHBufExtra) : "");
final String lostSprint = (data.lostSprintCount > 0 ? (" lostSprint=" + data.lostSprintCount) : "");
final String hVelUsed = hFreedom > 0 ? " hVelUsed=" + StringUtil.fdec3.format(hFreedom) : "";
builder.append(player.getName() + " SurvivalFly\nground: " + (data.noFallAssumeGround ? "(assumeonground) " : "") + (fromOnGround ? "onground -> " : (resetFrom ? "resetcond -> " : "--- -> ")) + (toOnGround ? "onground" : (resetTo ? "resetcond" : "---")) + ", jumpphase: " + data.sfJumpPhase);
builder.append("\n" + " hDist: " + StringUtil.fdec3.format(hDistance) + " / " + StringUtil.fdec3.format(hAllowedDistance) + hBuf + hBufExtra + hVelUsed + " , vDist: " + StringUtil.fdec3.format(yDistance) + " (" + StringUtil.fdec3.format(to.getY() - data.getSetBackY()) + " / " + StringUtil.fdec3.format(vAllowedDistance) + "), sby=" + (data.hasSetBack() ? data.getSetBackY() : "?"));
builder.append("\n" + " hDist: " + StringUtil.fdec3.format(hDistance) + " / " + 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);
}

View File

@ -180,6 +180,9 @@ public class DebugUtil {
if (player.isSprinting()){
builder.append("(sprinting)");
}
if (player.isSneaking()){
builder.append("(sneaking)");
}
}
if (speed != Double.NEGATIVE_INFINITY || jump != Double.NEGATIVE_INFINITY){
builder.append(" (" + (speed != Double.NEGATIVE_INFINITY ? ("e_speed=" + (speed + 1)) : "") + (jump != Double.NEGATIVE_INFINITY ? ("e_jump=" + (jump + 1)) : "") + ")");