From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 11 Mar 2021 03:03:32 -0800
Subject: [PATCH] Do not run close logic for inventories on chunk unload

Still call the event and change the active container though. We
want to avoid close logic because it's possible to load the
chunk through it. This should also be OK from a leak prevention/
state desync POV because the TE is getting unloaded anyways.

diff --git a/src/main/java/net/minecraft/server/level/EntityPlayer.java b/src/main/java/net/minecraft/server/level/EntityPlayer.java
index 980063ada85d7e9660a625d67b2f6a82f80bf535..bffc0824151a6597d91cd854b343b2586f6b9322 100644
--- a/src/main/java/net/minecraft/server/level/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/level/EntityPlayer.java
@@ -1718,6 +1718,17 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         this.playerConnection.sendPacket(new PacketPlayOutCloseWindow(this.activeContainer.windowId));
         this.o();
     }
+    // Tuinity start - special close for unloaded inventory
+    public void closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
+        // copied from above
+        CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit
+        // Paper end
+        // copied from below
+        this.playerConnection.sendPacket(new PacketPlayOutCloseWindow(this.activeContainer.windowId));
+        this.activeContainer = this.defaultContainer;
+        // do not run close logic
+    }
+    // Tuinity end - special close for unloaded inventory
 
     public void broadcastCarriedItem() {
         if (!this.e) {
diff --git a/src/main/java/net/minecraft/server/level/WorldServer.java b/src/main/java/net/minecraft/server/level/WorldServer.java
index a278a5ba17a510f784c798ad7f7f47bf7ccc301e..2d207dbad7752526c9a0b212979043c009e66386 100644
--- a/src/main/java/net/minecraft/server/level/WorldServer.java
+++ b/src/main/java/net/minecraft/server/level/WorldServer.java
@@ -1908,10 +1908,14 @@ public class WorldServer extends World implements GeneratorAccessSeed {
         // Spigot Start
         for (TileEntity tileentity : chunk.getTileEntities().values()) {
             if (tileentity instanceof net.minecraft.world.IInventory) {
+                // Tuinity start - this area looks like it can load chunks, change the behavior
+                // chests for example can apply physics to the world
+                // so instead we just change the active container and call the event
                 for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((net.minecraft.world.IInventory) tileentity).getViewers())) {
-                    h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper
+                    ((org.bukkit.craftbukkit.entity.CraftHumanEntity) h).getHandle().closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper
                 }
             }
+            // Tuiniy end
         }
         // Spigot End
         this.tileEntityListUnload.addAll(chunk.getTileEntities().values());
diff --git a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
index ec0956a98c133bcd3d4f92f696c667eab6ff98f1..44038dd278b988508047023107683e5370af54ad 100644
--- a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
+++ b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
@@ -453,6 +453,12 @@ public abstract class EntityHuman extends EntityLiving {
         this.activeContainer = this.defaultContainer;
     }
     // Paper end
+    // Tuinity start - special close for unloaded inventory
+    public void closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
+        closeInventory();
+        this.activeContainer = this.defaultContainer;
+    }
+    // Tuinity end - special close for unloaded inventory
 
     public void closeInventory() {
         this.activeContainer = this.defaultContainer;
