aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0161-API-to-get-a-BlockState-without-a-snapshot.patch
blob: 423d4538747fbd8408e46db299b4ebc41674e75a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
From 0000000000000000000000000000000000000000 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

also Avoid NPE during CraftBlockEntityState load if could not get TE

If Tile Entity was null, correct Sign to return empty lines instead of null

diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
index 66757716b401d4f5b690c895effbbaa46f169238..53443b472d21633f49c102b330c8406c92f09d8d 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -44,6 +44,7 @@ public abstract class BlockEntity {
         this.type = type;
         this.worldPosition = pos.immutable();
         this.blockState = state;
+        this.persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); // Paper - always init
     }
 
     public static BlockPos getPosFromTag(CompoundTag nbt) {
@@ -65,7 +66,7 @@ public abstract class BlockEntity {
 
     // CraftBukkit start - read container
     public void load(CompoundTag nbt) {
-        this.persistentDataContainer = new CraftPersistentDataContainer(BlockEntity.DATA_TYPE_REGISTRY);
+        this.persistentDataContainer.clear(); // Paper - clear instead of init
 
         net.minecraft.nbt.Tag persistentDataTag = nbt.get("PublicBukkitValues");
         if (persistentDataTag instanceof CompoundTag) {
@@ -239,8 +240,15 @@ public abstract class BlockEntity {
 
     // CraftBukkit start - add method
     public InventoryHolder getOwner() {
+        // Paper start
+        return getOwner(true);
+    }
+    public InventoryHolder getOwner(boolean useSnapshot) {
+        // Paper end
         if (this.level == null) return null;
-        org.bukkit.block.BlockState state = this.level.getWorld().getBlockAt(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ()).getState();
+        org.bukkit.block.Block block = this.level.getWorld().getBlockAt(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ());
+        if (block.getType() == org.bukkit.Material.AIR) return null;
+        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 a1c1a101aa424e74309f6f4c0a53a6a8db5df441..013298c424025cd88f15d61e50d196f70fa4c58b 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -328,6 +328,13 @@ public class CraftBlock implements Block {
         return CraftBlockStates.getBlockState(this);
     }
 
+    // Paper start
+    @Override
+    public BlockState getState(boolean useSnapshot) {
+        return CraftBlockStates.getBlockState(this, useSnapshot);
+    }
+    // Paper end
+
     @Override
     public Biome getBiome() {
         return this.getWorld().getBiome(this.getX(), this.getY(), this.getZ());
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
index 22af1b41eec06d660dbe47c463014bcdd96fc5b6..f046f507a095e0cb8f839b9b4b06add3a671486b 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
@@ -17,15 +17,26 @@ public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockStat
 
     private final T tileEntity;
     private final T snapshot;
+    public boolean snapshotDisabled; // Paper
+    public static boolean DISABLE_SNAPSHOT = false; // Paper
 
     public CraftBlockEntityState(World world, T tileEntity) {
         super(world, tileEntity.getBlockPos(), tileEntity.getBlockState());
 
         this.tileEntity = tileEntity;
 
+        // Paper start
+        this.snapshotDisabled = DISABLE_SNAPSHOT;
+        if (DISABLE_SNAPSHOT) {
+            this.snapshot = this.tileEntity;
+        } else {
+            this.snapshot = this.createSnapshot(tileEntity);
+        }
         // copy tile entity data:
-        this.snapshot = this.createSnapshot(tileEntity);
-        this.load(this.snapshot);
+        if (this.snapshot != null) {
+            this.load(this.snapshot);
+        }
+        // Paper end
     }
 
     protected CraftBlockEntityState(CraftBlockEntityState<T> state) {
@@ -136,4 +147,11 @@ public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockStat
     public CraftBlockEntityState<T> copy() {
         return new CraftBlockEntityState<>(this);
     }
+
+    // Paper start
+    @Override
+    public boolean isSnapshot() {
+        return !this.snapshotDisabled;
+    }
+    // Paper end
 }
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
index 8b454bdb8a9a202ece4912320f3ac373e4fff65c..76a3f4ad26718f95f4cf64206efe16e598fa2285 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
@@ -382,15 +382,30 @@ public final class CraftBlockStates {
     }
 
     public static BlockState getBlockState(Block block) {
+        // Paper start
+        return CraftBlockStates.getBlockState(block, true);
+    }
+    public static BlockState getBlockState(Block block, boolean useSnapshot) {
+        // Paper end
         Preconditions.checkNotNull(block, "block is null");
         CraftBlock craftBlock = (CraftBlock) block;
         CraftWorld world = (CraftWorld) block.getWorld();
         BlockPos blockPosition = craftBlock.getPosition();
         net.minecraft.world.level.block.state.BlockState blockData = craftBlock.getNMS();
         BlockEntity tileEntity = craftBlock.getHandle().getBlockEntity(blockPosition);
+        // Paper start - block state snapshots
+        boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT;
+        CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot;
+        try {
+        // Paper end
         CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPosition, blockData, tileEntity);
         blockState.setWorldHandle(craftBlock.getHandle()); // Inject the block's generator access
         return blockState;
+        // Paper start
+        } finally {
+            CraftBlockEntityState.DISABLE_SNAPSHOT = prev;
+        }
+        // Paper end
     }
 
     public static BlockState getBlockState(Material material, @Nullable CompoundTag blockEntityTag) {
diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
index dbb9a5b2f8d3bc0b13e0f56f6e8a0d9a7b761327..3001bb0e3d4af9b16645a0136093db594b89ab01 100644
--- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
+++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
@@ -177,4 +177,10 @@ public class CraftPersistentDataContainer implements PersistentDataContainer {
     public String serialize() {
         return CraftNBTTagConfigSerializer.serialize(this.toTagCompound());
     }
+
+    // Paper start
+    public void clear() {
+        this.customDataTags.clear();
+    }
+    // Paper end
 }