mirror of
https://github.com/PaperMC/Paper.git
synced 2025-07-30 19:52:06 -07:00
106 lines
5.7 KiB
Diff
106 lines
5.7 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
|
Date: Tue, 20 Feb 2024 18:24:16 -0800
|
|
Subject: [PATCH] Fix entity tracker desync when new players are added to the
|
|
tracker
|
|
|
|
The delta position packet instructs the client to update
|
|
the entity position by a position difference. However, this position
|
|
difference is relative to the last position in the entity tracker
|
|
state, not the last position which has been sent to the player. As
|
|
a result, if the last position the player has recorded is different
|
|
than the one stored in the entity tracker (which occurs when a new
|
|
player is added to an existing entity tracker state) then the sent
|
|
position difference will cause a position desync for the client.
|
|
|
|
We can resolve this problem by either tracking the last position
|
|
sent per-player, or by simply resetting the last sent position
|
|
in the entity tracker state every time a new player is added.
|
|
Resetting the last sent position every time a new player is
|
|
added to the tracker is just easier to do, so that is what
|
|
this patch does.
|
|
|
|
This patch also fixes entities appearing to disappear when
|
|
teleporting to players by changing the initial position
|
|
in the spawn packet to the entities current tracking position.
|
|
When teleporting, the spawn packet will contain the old position
|
|
which is most likely in an unloaded chunk - which means that the
|
|
client will not tick the entity and thus not lerp the entity
|
|
from its old position to its new position.
|
|
|
|
diff --git a/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java b/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
|
|
index db31989ebe3d7021cfd2311439e9a00f819b0841..1373977b339405ef59bb3ea03d195285c96dd3fe 100644
|
|
--- a/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
|
|
+++ b/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
|
|
@@ -42,9 +42,11 @@ public class ClientboundAddEntityPacket implements Packet<ClientGamePacketListen
|
|
this(
|
|
entity.getId(),
|
|
entity.getUUID(),
|
|
- serverEntity.getPositionBase().x(),
|
|
- serverEntity.getPositionBase().y(),
|
|
- serverEntity.getPositionBase().z(),
|
|
+ // Paper start - fix entity tracker desync
|
|
+ entity.trackingPosition().x(),
|
|
+ entity.trackingPosition().y(),
|
|
+ entity.trackingPosition().z(),
|
|
+ // Paper end - fix entity tracker desync
|
|
serverEntity.getLastSentXRot(),
|
|
serverEntity.getLastSentYRot(),
|
|
entity.getType(),
|
|
diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java
|
|
index 52d05c6b0fbb7719aaa67748050cb2d88dcbf41b..86ba02916c4a1c1311eeca5b1fb10a46626ba9ab 100644
|
|
--- a/net/minecraft/server/level/ChunkMap.java
|
|
+++ b/net/minecraft/server/level/ChunkMap.java
|
|
@@ -1275,6 +1275,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
this.serverEntity.addPairing(player);
|
|
}
|
|
// Paper end - entity tracking events
|
|
+ this.serverEntity.onPlayerAdd(); // Paper - fix desync when a player is added to the tracker
|
|
}
|
|
} else if (this.seenBy.remove(player.connection)) {
|
|
this.serverEntity.removePairing(player);
|
|
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
|
|
index 3d5a8163a7dd78a195b77c4aaebdee2dc3dee64b..e96d4dee14c05f2fa329bfb1588ec795d4e3d730 100644
|
|
--- a/net/minecraft/server/level/ServerEntity.java
|
|
+++ b/net/minecraft/server/level/ServerEntity.java
|
|
@@ -103,6 +103,13 @@ public class ServerEntity {
|
|
this.trackedDataValues = entity.getEntityData().getNonDefaultValues();
|
|
}
|
|
|
|
+ // Paper start - fix desync when a player is added to the tracker
|
|
+ private boolean forceStateResync;
|
|
+ public void onPlayerAdd() {
|
|
+ this.forceStateResync = true;
|
|
+ }
|
|
+ // Paper end - fix desync when a player is added to the tracker
|
|
+
|
|
public void sendChanges() {
|
|
// Paper start - optimise collisions
|
|
if (((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)this.entity).moonrise$isHardColliding()) {
|
|
@@ -141,7 +148,7 @@ public class ServerEntity {
|
|
this.sendDirtyEntityData();
|
|
}
|
|
|
|
- if (this.tickCount % this.updateInterval == 0 || this.entity.hasImpulse || this.entity.getEntityData().isDirty()) {
|
|
+ if (this.forceStateResync || this.tickCount % this.updateInterval == 0 || this.entity.hasImpulse || this.entity.getEntityData().isDirty()) { // Paper - fix desync when a player is added to the tracker
|
|
byte b = Mth.packDegrees(this.entity.getYRot());
|
|
byte b1 = Mth.packDegrees(this.entity.getXRot());
|
|
boolean flag = Math.abs(b - this.lastSentYRot) >= 1 || Math.abs(b1 - this.lastSentXRot) >= 1;
|
|
@@ -176,7 +183,7 @@ public class ServerEntity {
|
|
long l1 = this.positionCodec.encodeY(vec3);
|
|
long l2 = this.positionCodec.encodeZ(vec3);
|
|
boolean flag5 = l < -32768L || l > 32767L || l1 < -32768L || l1 > 32767L || l2 < -32768L || l2 > 32767L;
|
|
- if (this.entity.getRequiresPrecisePosition()
|
|
+ if (this.forceStateResync || this.entity.getRequiresPrecisePosition() // Paper - fix desync when a player is added to the tracker
|
|
|| flag5
|
|
|| this.teleportDelay > 400
|
|
|| this.wasRiding
|
|
@@ -245,6 +252,7 @@ public class ServerEntity {
|
|
}
|
|
|
|
this.entity.hasImpulse = false;
|
|
+ this.forceStateResync = false; // Paper - fix desync when a player is added to the tracker
|
|
}
|
|
|
|
this.tickCount++;
|