Mirror von
https://github.com/PaperMC/Paper.git
synchronisiert 2024-12-15 19:10:09 +01:00
a594d182e4
When teleporting, the spawn position packet will contain the old position. Then the following tracking update will send a teleport packet, but the client will lerp the position change over 3 ticks. However, the client does not tick entities in unloaded chunks - resulting in the lerp never occuring. We fix this by sending the current position in the spawn packet.
106 Zeilen
5.8 KiB
Diff
106 Zeilen
5.8 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 c96740a82eac9101f74edeb44edf4b64d1d633e0..8b6754525fafd1aaac3292cf69a855d6a42b9523 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
@@ -1189,6 +1189,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 1d849ce4e2c85f149af25318b8ffb6dcef6c6788..b4971813d267dffc6507502345e5c8b991541eca 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() {
|
|
List<Entity> list = this.entity.getPassengers();
|
|
|
|
@@ -140,7 +147,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;
|
|
|
|
@@ -180,7 +187,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());
|
|
@@ -244,6 +251,7 @@ public class ServerEntity {
|
|
}
|
|
|
|
this.entity.hasImpulse = false;
|
|
+ this.forceStateResync = false; // Paper - fix desync when a player is added to the tracker
|
|
}
|
|
|
|
++this.tickCount;
|