Reset player before running place logic

As part of Folia's place logic, the player's health is sent
after the respawn packet.

Since the health is <= 0.0, this would cause the client to
die again. This would cause the respawn screen to appear again,
and would additionally cause other players to see the player as
dead as well.

There is a small window where this would not have occurred, and
that is where the server would send the correct health before
the client ticks again. This is why the issue was not reproducable
locally, as there was is almost zero delay between those events
on an idle server and on perfect 0ms ping.

Fixes https://github.com/PaperMC/Folia/issues/112
This commit is contained in:
Spottedleaf 2023-08-07 14:35:18 -07:00
parent b2d7bdb0bb
commit 3cf16eeaf2
2 changed files with 13 additions and 14 deletions

View File

@ -14675,7 +14675,7 @@ index 18aac3da3c88f33b1a71a5920a8daa27e9723913..bb07ad1bb895297356b88dfc4cd17e5e
for (ServerPlayer player : ServerLevel.this.players) {
player.getBukkitEntity().onEntityRemove(entity);
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 9d46536f80b5b3e6641fd377c02166a431edfd77..abbc8992523e55a665318df07dd732af8a9e8791 100644
index 9d46536f80b5b3e6641fd377c02166a431edfd77..7c4ec191dc64968d349b244818f65c64ba7ab308 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -190,7 +190,7 @@ import org.bukkit.inventory.MainHand;
@ -14892,7 +14892,7 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..abbc8992523e55a665318df07dd732af
return horizontalSpawnArea <= 16 ? horizontalSpawnArea - 1 : 17;
}
@@ -1161,6 +1258,345 @@ public class ServerPlayer extends Player {
@@ -1161,6 +1258,344 @@ public class ServerPlayer extends Player {
}
}
@ -14957,9 +14957,13 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..abbc8992523e55a665318df07dd732af
+ EntityTreeNode passengerTree = this.makePassengerTree();
+
+ this.isChangingDimension = true;
+ // must be manually removed from connections
+ this.serverLevel().getCurrentWorldData().connections.remove(this.connection.connection);
+ origin.removePlayerImmediately(this, RemovalReason.CHANGED_DIMENSION);
+ // reset player if needed, only after removal from world
+ if (!alive) {
+ ServerPlayer.this.reset();
+ }
+ // must be manually removed from connections, delay until after reset() so that we do not trip any thread checks
+ this.serverLevel().getCurrentWorldData().connections.remove(this.connection.connection);
+
+ BlockPos respawnPos = this.getRespawnPosition();
+ float respawnAngle = this.getRespawnAngle();
@ -14987,11 +14991,6 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..abbc8992523e55a665318df07dd732af
+ TELEPORT_FLAG_LOAD_CHUNK | TELEPORT_FLAGS_PLAYER_RESPAWN | TELEPORT_FLAGS_AVOID_SUFFOCATION,
+ passengerTree, // note: we expect this to just be the player, no passengers
+ (entity) -> {
+ // reset player if needed
+ // only after placing, so that we don't trip thread checks
+ if (!alive) {
+ ServerPlayer.this.reset();
+ }
+ // now the player is in the world, and can receive sound
+ if (usedRespawnAnchor[0]) {
+ ServerPlayer.this.connection.send(
@ -15238,7 +15237,7 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..abbc8992523e55a665318df07dd732af
@Nullable
@Override
public Entity changeDimension(ServerLevel destination) {
@@ -1170,6 +1606,11 @@ public class ServerPlayer extends Player {
@@ -1170,6 +1605,11 @@ public class ServerPlayer extends Player {
@Nullable
public Entity changeDimension(ServerLevel worldserver, PlayerTeleportEvent.TeleportCause cause) {
@ -15250,7 +15249,7 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..abbc8992523e55a665318df07dd732af
// CraftBukkit end
if (this.isSleeping()) return this; // CraftBukkit - SPIGOT-3154
// this.isChangingDimension = true; // CraftBukkit - Moved down and into PlayerList#changeDimension
@@ -2114,6 +2555,12 @@ public class ServerPlayer extends Player {
@@ -2114,6 +2554,12 @@ public class ServerPlayer extends Player {
public void setCamera(@Nullable Entity entity) {
Entity entity1 = this.getCamera();
@ -15263,7 +15262,7 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..abbc8992523e55a665318df07dd732af
this.camera = (Entity) (entity == null ? this : entity);
if (entity1 != this.camera) {
// Paper start - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity Event
@@ -2307,7 +2754,7 @@ public class ServerPlayer extends Player {
@@ -2307,7 +2753,7 @@ public class ServerPlayer extends Player {
}
public void untrackChunk(ChunkPos chunkPos) {
@ -15272,7 +15271,7 @@ index 9d46536f80b5b3e6641fd377c02166a431edfd77..abbc8992523e55a665318df07dd732af
this.connection.send(new ClientboundForgetLevelChunkPacket(chunkPos.x, chunkPos.z));
// Paper start
if(io.papermc.paper.event.packet.PlayerChunkUnloadEvent.getHandlerList().getRegisteredListeners().length > 0){
@@ -2626,7 +3073,7 @@ public class ServerPlayer extends Player {
@@ -2626,7 +3072,7 @@ public class ServerPlayer extends Player {
this.experienceLevel = this.newLevel;
this.totalExperience = this.newTotalExp;
this.experienceProgress = 0;

View File

@ -9,7 +9,7 @@ data deserialization and is racey even in Vanilla. But in Folia,
some accesses may throw and as such we need to fix this directly.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index abbc8992523e55a665318df07dd732af8a9e8791..febd0ba72922462364eb65243640dcb693129e21 100644
index 7c4ec191dc64968d349b244818f65c64ba7ab308..c0ad878cd29e2f72b7899d9539031b15ccbf6193 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -629,7 +629,7 @@ public class ServerPlayer extends Player {