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.
This commit is contained in:
Spottedleaf
2025-06-24 05:10:19 -07:00
parent 38c1ddb52a
commit 2f083acbed
5 changed files with 21 additions and 12 deletions

View File

@@ -984,16 +984,25 @@
ObjectArrayList<GameProfile> 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();