Work around loss of precision when unpacking entity velocity

Solution was discussed on discord (https://discord.com/channels/721686193061888071/721686193515003966/1313231483225378946)

Closes #1074

Co-authored-by: booky10 <boooky10@gmail.com>
This commit is contained in:
Beanesandbooky10 authored and booky10 committed 2024-12-02 21:26:55 +01:00
1 parent a0fc7f6978
commit 9819db60cd
1 file changed
+14 -1
@@ -25,6 +25,15 @@ import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class WrapperPlayServerEntityVelocity extends PacketWrapper<WrapperPlayServerEntityVelocity> {
// with larger short values there is a loss of precision and
// re-encoding packets may cause the velocity to change
//
// as vanilla just casts to an int instead of properly rounding,
// packetevents has to add a small number to the calculated velocity
// to work around the loss of precision
private static final double PRECISION_LOSS_FIX = 1e-11d;
private int entityID;
private Vector3d velocity;
@@ -48,7 +57,11 @@ public class WrapperPlayServerEntityVelocity extends PacketWrapper<WrapperPlaySe
double velX = (double) readShort() / 8000.0;
double velY = (double) readShort() / 8000.0;
double velZ = (double) readShort() / 8000.0;
velocity = new Vector3d(velX, velY, velZ);
velocity = new Vector3d(
velX + Math.copySign(PRECISION_LOSS_FIX, velX),
velY + Math.copySign(PRECISION_LOSS_FIX, velY),
velZ + Math.copySign(PRECISION_LOSS_FIX, velZ)
);
}
@Override