From 2f083acbedfc895a8fe611a8be4bc5723d84b4e1 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Tue, 24 Jun 2025 05:10:19 -0700 Subject: [PATCH] Ensure player entity schedulers are ticked when they are dead If the player dies, then they are removed from the world and as a result are not present in the world entity map. To guarantee that the player entity scheduler is ticked, we can tick all schedulers for players in the server player list, and then skip all players we find in the world entity map. This problem is not present on Folia since Folia must guarantee that the player remains in the world. --- ...0006-Optimize-Collision-to-not-load-chunks.patch | 8 ++++---- .../0016-Moonrise-optimisation-patches.patch | 6 +++--- .../patches/features/0028-Optimize-Hoppers.patch | 4 ++-- .../net/minecraft/server/MinecraftServer.java.patch | 13 +++++++++++-- .../net/minecraft/world/entity/Entity.java.patch | 2 +- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch b/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch index 359fd9036a..af170c1201 100644 --- a/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch +++ b/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch @@ -14,17 +14,17 @@ movement will load only the chunk the player enters anyways and avoids loading massive amounts of surrounding chunks due to large AABB lookups. diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 7453ddb09f349b7836f966573e4933646a75cba6..58eda0d6426f30cda604f4120f1ddb012316c108 100644 +index 23dfc87db1d5e90099270627197abc0f787a4393..27a01fd28ea565221768f31df02f0a2ddf242fce 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -229,6 +229,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - // Paper end - Share random for entities to make them more random +@@ -230,6 +230,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason + private volatile @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity; // Paper - Folia schedulers - volatile + public boolean collisionLoadChunks = false; // Paper - private @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity; public org.bukkit.craftbukkit.entity.CraftEntity getBukkitEntity() { + if (this.bukkitEntity == null) { diff --git a/net/minecraft/world/level/BlockCollisions.java b/net/minecraft/world/level/BlockCollisions.java index ed6e4f9fd0c7ad1219e66bc1cb4038191dd6edd8..45a20dbb935b12d429153463dba5d6fd3385dd7a 100644 --- a/net/minecraft/world/level/BlockCollisions.java diff --git a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index 7dc38ba475..afe87b7c97 100644 --- a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -23866,7 +23866,7 @@ index 46de98a6bbbae48c4837e1e588ba198a363d2dde..fd3553bdc1c3cdbf6aa3dc00e0a4987f thread1 -> { DedicatedServer dedicatedServer1 = new DedicatedServer( diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index aea96ab1c5f2dae9f2a19126e8be314d06b99bc3..388bf752fd09745e8c470b5bca4d004708a2d82f 100644 +index 75aba65cbe1a943f21c7464ff9465e64f63e8e5b..32475c0958fd7e0f1f9b494b0cc78a4a718d12b8 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -173,7 +173,7 @@ import net.minecraft.world.phys.Vec2; @@ -24058,7 +24058,7 @@ index aea96ab1c5f2dae9f2a19126e8be314d06b99bc3..388bf752fd09745e8c470b5bca4d0047 return true; } else { boolean ret = false; // Paper - force execution of all worlds, do not just bias the first -@@ -2469,6 +2557,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent serverLevel.updateLagCompensationTick(); // Paper - lag compensation diff --git a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch index ae7e78ecfe..a26cf11045 100644 --- a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch @@ -984,16 +984,25 @@ ObjectArrayList list = new ObjectArrayList<>(min); int randomInt = Mth.nextInt(this.random, 0, players.size() - min); -@@ -1040,17 +_,66 @@ +@@ -1040,17 +_,75 @@ protected void tickChildren(BooleanSupplier hasTimeLeft) { ProfilerFiller profilerFiller = Profiler.get(); this.getPlayerList().getPlayers().forEach(serverPlayer1 -> serverPlayer1.connection.suspendFlushing()); + this.server.getScheduler().mainThreadHeartbeat(); // CraftBukkit + // Paper start - Folia scheduler API + ((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) org.bukkit.Bukkit.getGlobalRegionScheduler()).tick(); ++ for (ServerPlayer player : this.playerList.players) { ++ if (!this.playerList.players.contains(player)) { ++ continue; ++ } ++ final org.bukkit.craftbukkit.entity.CraftEntity bukkit = player.getBukkitEntityRaw(); ++ if (bukkit != null) { ++ bukkit.taskScheduler.executeTick(); ++ } ++ } + getAllLevels().forEach(level -> { + for (final net.minecraft.world.entity.Entity entity : io.papermc.paper.FeatureHooks.getAllEntities(level)) { -+ if (entity.isRemoved()) { ++ if (entity.isRemoved() || entity instanceof ServerPlayer) { + continue; + } + final org.bukkit.craftbukkit.entity.CraftEntity bukkit = entity.getBukkitEntityRaw(); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch index 742ae285da..a5c67c10ec 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -85,7 +85,7 @@ + // Paper end - Share random for entities to make them more random + public @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason + -+ private @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity; ++ private volatile @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity; // Paper - Folia schedulers - volatile + + public org.bukkit.craftbukkit.entity.CraftEntity getBukkitEntity() { + if (this.bukkitEntity == null) {