From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 11 Apr 2020 21:23:42 -0400
Subject: [PATCH] Delay unsafe actions until after entity ticking is done

This will help prevent many cases of unregistering entities during entity ticking

1.17: Not used anywhere in 1.16.5 server, and no more tickingEntities bool on ServerLevel (moved to Level?)

diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 4e75cc5e52a5295e32ccadb371702a405bb518bb..b9978d296b83e73d3395b8254c0e8ccd9b36d0fa 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -172,6 +172,16 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
     public final List<ServerPlayer> players = Lists.newArrayList(); // Paper - private -> public
     public final ServerChunkCache chunkSource; // Paper - public
     boolean tickingEntities;
+    // Paper start
+    List<java.lang.Runnable> afterEntityTickingTasks = Lists.newArrayList();
+    public void doIfNotEntityTicking(java.lang.Runnable run) {
+        if (tickingEntities) {
+            afterEntityTickingTasks.add(run);
+        } else {
+            run.run();
+        }
+    }
+    // Paper end
     private final MinecraftServer server;
     public final PrimaryLevelData worldDataServer; // CraftBukkit - type
     public boolean noSave;
@@ -641,6 +651,16 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
             timings.entityTick.stopTiming(); // Spigot
 
             this.tickingEntities = false;
+            // Paper start
+            for (java.lang.Runnable run : this.afterEntityTickingTasks) {
+                try {
+                    run.run();
+                } catch (Exception e) {
+                    LOGGER.error("Error in After Entity Ticking Task", e);
+                }
+            }
+            this.afterEntityTickingTasks.clear();
+            // Paper end
             this.getServer().midTickLoadChunks(); // Paper
 
             Entity entity2;
