mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-29 12:27:59 +01:00
106 lines
5.9 KiB
Diff
106 lines
5.9 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 f8f145cd9614f7e38d6aa72501fe31837340a8bb..fa48e63fea42f387dcd154c08af54cfb0d3b08af 100644
|
|
--- a/net/minecraft/server/level/ChunkMap.java
|
|
+++ b/net/minecraft/server/level/ChunkMap.java
|
|
@@ -1419,6 +1419,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 4c891706c2a3efc8e8c44fc1c031e8a1d21efb60..66f7926a2639ade41cb89419e38e12053314c982 100644
|
|
--- a/net/minecraft/server/level/ServerEntity.java
|
|
+++ b/net/minecraft/server/level/ServerEntity.java
|
|
@@ -90,6 +90,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() {
|
|
List<Entity> passengers = this.entity.getPassengers();
|
|
if (!passengers.equals(this.lastPassengers)) {
|
|
@@ -125,7 +132,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;
|
|
@@ -160,7 +167,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 (flag5 || this.teleportDelay > 400 || this.wasRiding || this.wasOnGround != this.entity.onGround()) {
|
|
+ if (this.forceStateResync || flag5 || this.teleportDelay > 400 || this.wasRiding || this.wasOnGround != this.entity.onGround()) { // Paper - fix desync when a player is added to the tracker
|
|
this.wasOnGround = this.entity.onGround();
|
|
this.teleportDelay = 0;
|
|
packet = ClientboundEntityPositionSyncPacket.of(this.entity);
|
|
@@ -225,6 +232,7 @@ public class ServerEntity {
|
|
}
|
|
|
|
this.entity.hasImpulse = false;
|
|
+ this.forceStateResync = false; // Paper - fix desync when a player is added to the tracker
|
|
}
|
|
|
|
this.tickCount++;
|