From 8cd8c32f4d0e94e0c1d4591c3cbb28329d54e1dd Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 6 Nov 2017 21:08:22 -0500
Subject: [PATCH] API to get a BlockState without a snapshot

This allows you to get a BlockState without creating a snapshot, operating
on the real tile entity.

This is useful for where performance is needed

diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
index 537e4b15..8e2d55a7 100644
--- a/src/main/java/net/minecraft/server/TileEntity.java
+++ b/src/main/java/net/minecraft/server/TileEntity.java
@@ -264,7 +264,12 @@ public abstract class TileEntity {
     }
 
     // CraftBukkit start - add method
+    // Paper start
     public InventoryHolder getOwner() {
+        return getOwner(true);
+    }
+    public InventoryHolder getOwner(boolean useSnapshot) {
+        // Paper end
         if (world == null) return null;
         // Spigot start
         org.bukkit.block.Block block = world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ());
@@ -273,7 +278,7 @@ public abstract class TileEntity {
             return null;
         }
         // Spigot end
-        org.bukkit.block.BlockState state = block.getState();
+        org.bukkit.block.BlockState state = block.getState(useSnapshot); // Paper
         if (state instanceof InventoryHolder) return (InventoryHolder) state;
         return null;
     }
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 46670c34..a9d3f12b 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -260,7 +260,22 @@ public class CraftBlock implements Block {
         }
     }
 
+
     public BlockState getState() {
+        // Paper start - allow disabling the use of snapshots
+        return getState(true);
+    }
+    public BlockState getState(boolean useSnapshot) {
+        boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT;
+        CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot;
+        try {
+            return getState0();
+        } finally {
+            CraftBlockEntityState.DISABLE_SNAPSHOT = prev;
+        }
+    }
+    public BlockState getState0() {
+        // Paper end
         Material material = getType();
 
         switch (material) {
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
index 22dcaea7..3b5a90c3 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
@@ -22,17 +22,34 @@ public class CraftBlockEntityState<T extends TileEntity> extends CraftBlockState
         CraftWorld world = (CraftWorld) this.getWorld();
         this.tileEntity = tileEntityClass.cast(world.getTileEntityAt(this.getX(), this.getY(), this.getZ()));
 
+        // Paper start
+        this.snapshotDisabled = DISABLE_SNAPSHOT;
+        if (DISABLE_SNAPSHOT) {
+            this.snapshot = tileEntity;
+            return;
+        }
+        // Paper end
         // copy tile entity data:
         this.snapshot = this.createSnapshot(tileEntity);
         if(this.snapshot != null) // Paper - avoid NPE during load
         this.load(snapshot);
     }
 
+    public final boolean snapshotDisabled; // Paper
+    public static boolean DISABLE_SNAPSHOT = false; // Paper
+
     public CraftBlockEntityState(Material material, T tileEntity) {
         super(material);
 
         this.tileEntityClass = (Class<T>) tileEntity.getClass();
         this.tileEntity = tileEntity;
+        // Paper start
+        this.snapshotDisabled = DISABLE_SNAPSHOT;
+        if (DISABLE_SNAPSHOT) {
+            this.snapshot = tileEntity;
+            return;
+        }
+        // Paper end
 
         // copy tile entity data:
         this.snapshot = this.createSnapshot(tileEntity);
-- 
2.14.3