Paper/patches/server/1031-Fix-entity-tracker-desync-when-new-players-are-added.patch
Bjarne Koll 77a5779e24
Updated Upstream (Bukkit/CraftBukkit/Spigot) (#11197)
Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
2ec53f49 PR-1050: Fix empty result check for Complex Recipes
10671012 PR-1044: Add CrafterCraftEvent
4d87ffe0 Use correct method in JavaDoc
ae5e5817 SPIGOT-7850: Add API for Bogged shear state
46b6d445 SPIGOT-7837: Support data pack banner patterns
d5d0cefc Fix JavaDoc error
b3c2b83d PR-1036: Add API for InventoryView derivatives
1fe2c75a SPIGOT-7809: Add ShieldMeta

CraftBukkit Changes:
8ee6fd1b8 SPIGOT-7857: Improve ItemMeta block data deserialization
8f26c30c6 SPIGOT-7857: Fix spurious internal NBT tag when deserializing BlockStateMeta
759061b93 SPIGOT-7855: Fire does not spread or burn blocks
00fc9fb64 SPIGOT-7853: AnvilInventory#getRepairCost() always returns 0
7501e2e04 PR-1450: Add CrafterCraftEvent
8c51673e7 SPIGOT-5731: PortalCreateEvent#getEntity returns null for nether portals ignited by flint and steel
d53d0d0b1 PR-1456: Fix inverted logic in CraftCrafterView#setSlotDisabled
682a678c8 SPIGOT-7850: Add API for Bogged shear state
fccf5243a SPIGOT-7837: Support data pack banner patterns
9c3bd4390 PR-1431: Add API for InventoryView derivatives
0cc6acbc4 SPIGOT-7849: Fix FoodComponent serialize with "using-converts-to" using null
2c5474952 Don't rely on tags for CraftItemMetas
20d107e46 SPIGOT-7846: Fix ItemMeta for hanging signs
76f59e315 Remove redundant clone in Dropper InventoryMoveItemEvent
e61a53d25 SPIGOT-7817: Call InventoryMoveItemEvent for Crafters
894682e2d SPIGOT-7839: Remove redundant Java version checks
2c12b2187 SPIGOT-7809: Add ShieldMeta and fix setting shield base colours

Spigot Changes:
fb8fb722 Rebuild patches
34bd42b7 SPIGOT-7835: Fix issue with custom hopper settings
2024-08-09 22:05:50 +02:00

106 lines
6.0 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/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
index 1a5e73fd97781f3903e5ef13aa0352c64fbc2cc1..4126d82e83810126eb4a41b4587dc993542f3793 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
@@ -42,9 +42,11 @@ public class ClientboundAddEntityPacket implements Packet<ClientGamePacketListen
this(
entity.getId(),
entity.getUUID(),
- entityTrackerEntry.getPositionBase().x(),
- entityTrackerEntry.getPositionBase().y(),
- entityTrackerEntry.getPositionBase().z(),
+ // Paper start - fix entity tracker desync
+ entity.trackingPosition().x(),
+ entity.trackingPosition().y(),
+ entity.trackingPosition().z(),
+ // Paper end - fix entity tracker desync
entityTrackerEntry.getLastSentXRot(),
entityTrackerEntry.getLastSentYRot(),
entity.getType(),
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index a183414631a2e640f68370772fe59110c30be98c..1e0a6e5a3c907ab55ee6f2780a7d43bd455f2b7b 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1268,6 +1268,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/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index 12d86f27d04bffed8c3844e36b42fbc2f84dacff..8ea2f24695f5dad55e21f238b69442513e7a90c6 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -96,6 +96,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()) {
@@ -145,7 +152,7 @@ public class ServerEntity {
}
}
- 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
int i;
int j;
@@ -185,7 +192,7 @@ public class ServerEntity {
long i1 = this.positionCodec.encodeZ(vec3d);
boolean flag6 = k < -32768L || k > 32767L || l < -32768L || l > 32767L || i1 < -32768L || i1 > 32767L;
- if (!flag6 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround()) {
+ if (!this.forceStateResync && !flag6 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround()) { // Paper - fix desync when a player is added to the tracker
if ((!flag2 || !flag3) && !(this.entity instanceof AbstractArrow)) {
if (flag2) {
packet1 = new ClientboundMoveEntityPacket.Pos(this.entity.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), this.entity.onGround());
@@ -249,6 +256,7 @@ public class ServerEntity {
}
this.entity.hasImpulse = false;
+ this.forceStateResync = false; // Paper - fix desync when a player is added to the tracker
}
++this.tickCount;