Lagback: Difference between revisions

From Minecraft Parkour Wiki
Content added Content deleted
(added simplified code)
(simplified code)
Line 9: Line 9:


== Explanation ==
== Explanation ==
The lagback itself is caused by this portion of code (in class NetHandlerPlayServer):<syntaxhighlight lang="java" line="1">
In singleplayer, the lagback itself is caused by this portion of code (in class NetHandlerPlayServer):<syntaxhighlight lang="java" line="1">
public void processPlayer(PacketPlayer packetIn)
public void processPlayer(PacketPlayer packetIn)
{
{
//heavily simplified, ignores exceptional cases where the player is considered inactive (sleeping, teleporting, watching end credits, noclip, flying, mounted)
//heavily simplified, ignores exceptional cases (flying, sleeping, teleporting, , noclip, mounted, respawning...)
double posX = this.playerEntity.posX;
double posY = this.playerEntity.posY;
double posZ = this.playerEntity.posZ;
double norm_squared = 0.0D;
double distX = packetIn.getPositionX() - this.lastPosX;
double distY = packetIn.getPositionY() - this.lastPosY;
double distZ = packetIn.getPositionZ() - this.lastPosZ;

double posY_original = this.playerEntity.posY;
double posY_original = this.playerEntity.posY;
this.lastPosX = this.playerEntity.posX;
this.lastPosX = this.playerEntity.posX;
this.lastPosY = this.playerEntity.posY;
this.lastPosY = this.playerEntity.posY;
this.lastPosZ = this.playerEntity.posZ;
this.lastPosZ = this.playerEntity.posZ;
double e_posX = packetIn.getPositionX();
double posX = packetIn.getPositionX();
double e_posY = packetIn.getPositionY();
double posY = packetIn.getPositionY();
double e_posZ = packetIn.getPositionZ();
double posZ = packetIn.getPositionZ();
float yaw = this.playerEntity.rotationYaw;
float yaw = this.playerEntity.rotationYaw;
Line 35: Line 27:
this.playerEntity.onUpdateEntity();
this.playerEntity.onUpdateEntity();
this.playerEntity.setPositionAndRotation(this.lastPosX, this.lastPosY, this.lastPosZ, yaw, pitch);
this.playerEntity.setPositionAndRotation(this.lastPosX, this.lastPosY, this.lastPosZ, yaw, pitch);

//the code may stop here under certain circumstances, to be determined.
double deltaX = e_posX - this.playerEntity.posX;
double deltaX = posX - this.playerEntity.posX;
double deltaY = e_posY - this.playerEntity.posY;
double deltaY = posY - this.playerEntity.posY;
double deltaZ = e_posZ - this.playerEntity.posZ;
double deltaZ = posZ - this.playerEntity.posZ;


boolean noCollisionInside = worldserver.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.getEntityBoundingBox().contract(0.0625, 0.0625, 0.0625).isEmpty();
boolean noCollisionInside = worldserver.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.getEntityBoundingBox().contract(0.0625, 0.0625, 0.0625).isEmpty();
Line 50: Line 40:
this.playerEntity.onGround = packetIn.isOnGround();
this.playerEntity.onGround = packetIn.isOnGround();
double errorX = e_posX - this.playerEntity.posX;
double errorX = posX - this.playerEntity.posX;
double errorZ = e_posZ - this.playerEntity.posZ;
double errorZ = posZ - this.playerEntity.posZ;
double error_squared = deltaX * deltaX + deltaZ * deltaZ;
double error_squared = errorX * errorX + errorZ * errorZ;
boolean movedWrongly = (delta_squared > 0.0625D && !this.playerEntity.theItemInWorldManager.isCreative());
boolean movedWrongly = (delta_squared > 0.0625D && !this.playerEntity.theItemInWorldManager.isCreative());


this.playerEntity.setPositionAndRotation(e_posX, e_posY, e_posZ, yaw, pitch);
this.playerEntity.setPositionAndRotation(posX, posY, posZ, yaw, pitch);
boolean noCollisionInside_updated = worldserver.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.getEntityBoundingBox().contract(0.0625, 0.0625, 0.0625).isEmpty();
boolean noCollisionInside_updated = worldserver.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.getEntityBoundingBox().contract(0.0625, 0.0625, 0.0625).isEmpty();


//detects a desync - "lagbacks" the player to their previous position
if (noCollisionInside && (movedWrongly || !noCollisionInside_updated) && !this.playerEntity.isPlayerSleeping())
if (noCollisionInside && (movedWrongly || !noCollisionInside_updated))
{
{
this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, yaw, pitch);
this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, yaw, pitch);
return;
return;
}
AxisAlignedBB axisalignedbb = this.playerEntity.getEntityBoundingBox().expand(0.0625, 0.0625, 0.0625.addCoord(0.0, -0.55, 0.0);

if (!this.serverController.isFlightAllowed() && !this.playerEntity.capabilities.allowFlying && !worldserver.checkBlockCollision(axisalignedbb))
{
if (deltaY >= -0.03125D)
{
++this.floatingTickCount;
if (this.floatingTickCount > 80)
{
this.kickPlayerFromServer("Flying is not enabled on this server");
return;
}
}
}
else
{
this.floatingTickCount = 0;
}
}


Line 87: Line 59:
this.playerEntity.handleFalling(this.playerEntity.posY - posY_original, packetIn.isOnGround());
this.playerEntity.handleFalling(this.playerEntity.posY - posY_original, packetIn.isOnGround());
}
}
</syntaxhighlight>The reason for the desynchronization is still being determined.
</syntaxhighlight>There are essentially two ways to trigger a lagback:

* Moving "wrongly".
* Moving into a collision box.

The latter only seems to happen when colliding with boats. The next section shall be dedicated to detailing how the player can move "wrongly".

Revision as of 15:31, 5 September 2022

Lagback refers to getting teleported back to a previous position. It can be abused to clip inside walls, or jump higher in a similar fashion as Blips. This practice may be a bannable offense on multiplayer servers. In this article, we solely focus on singleplayer 1.8.

Known causes for lagback

  • Colliding with a boat
  • Falling and sneaking at the last moment
  • Moving inside a cobweb too quickly
  • Stepping up with an obscene amount of speed (Speed 100, for example)

Explanation

In singleplayer, the lagback itself is caused by this portion of code (in class NetHandlerPlayServer):

public void processPlayer(PacketPlayer packetIn)
{
    //heavily simplified, ignores exceptional cases (flying, sleeping, teleporting, , noclip, mounted, respawning...)
    double posY_original = this.playerEntity.posY;
    this.lastPosX = this.playerEntity.posX;
    this.lastPosY = this.playerEntity.posY;
    this.lastPosZ = this.playerEntity.posZ;
    double posX = packetIn.getPositionX();
    double posY = packetIn.getPositionY();
    double posZ = packetIn.getPositionZ();
    
    float yaw = this.playerEntity.rotationYaw;
    float pitch = this.playerEntity.rotationPitch;
    if (packetIn.getRotating()) {yaw = packetIn.getYaw(); pitch = packetIn.getPitch();}

    this.playerEntity.onUpdateEntity();
    this.playerEntity.setPositionAndRotation(this.lastPosX, this.lastPosY, this.lastPosZ, yaw, pitch);
    
    double deltaX = posX - this.playerEntity.posX;
    double deltaY = posY - this.playerEntity.posY;
    double deltaZ = posZ - this.playerEntity.posZ;

    boolean noCollisionInside = worldserver.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.getEntityBoundingBox().contract(0.0625, 0.0625, 0.0625).isEmpty();

    if (this.playerEntity.onGround && !packetIn.isOnGround() && deltaY > 0.0D)
        this.playerEntity.jump();

    this.playerEntity.moveEntity(deltaX, deltaY, deltaZ);
    this.playerEntity.onGround = packetIn.isOnGround();
                    
    double errorX = posX - this.playerEntity.posX;
    double errorZ = posZ - this.playerEntity.posZ;
    double error_squared = errorX * errorX + errorZ * errorZ;
    boolean movedWrongly = (delta_squared > 0.0625D && !this.playerEntity.theItemInWorldManager.isCreative());

    this.playerEntity.setPositionAndRotation(posX, posY, posZ, yaw, pitch);
    
    boolean noCollisionInside_updated = worldserver.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.getEntityBoundingBox().contract(0.0625, 0.0625, 0.0625).isEmpty();

    //detects a desync - "lagbacks" the player to their previous position
    if (noCollisionInside && (movedWrongly || !noCollisionInside_updated))
    {
        this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, yaw, pitch);
        return;
    }

    this.playerEntity.onGround = packetIn.isOnGround();
    this.playerEntity.handleFalling(this.playerEntity.posY - posY_original, packetIn.isOnGround());
}

There are essentially two ways to trigger a lagback:

  • Moving "wrongly".
  • Moving into a collision box.

The latter only seems to happen when colliding with boats. The next section shall be dedicated to detailing how the player can move "wrongly".