PaperMC/patches/server-remapped/0178-API-to-get-a-BlockState-without-a-snapshot.patch
2021-06-11 14:02:28 +02:00

147 lines
6.6 KiB
Diff

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 d08ed44884726ca2ba4578226b8aa6244778f4c7..84012c2d12817e657b046bc168cc8eddebcd3831 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
@@ -47,6 +47,7 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject {
public BlockEntity(BlockEntityType<?> type) {
this.worldPosition = BlockPos.ZERO;
this.type = type;
+ persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); // Paper - always init
}
// Paper start
@@ -95,7 +96,7 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject {
public void load(BlockState state, CompoundTag tag) {
this.worldPosition = new BlockPos(tag.getInt("x"), tag.getInt("y"), tag.getInt("z"));
// CraftBukkit start - read container
- this.persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY);
+ this.persistentDataContainer.clear(); // Paper - clear instead of reinit
net.minecraft.nbt.Tag persistentDataTag = tag.get("PublicBukkitValues");
if (persistentDataTag instanceof CompoundTag) {
@@ -245,7 +246,12 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject {
}
// CraftBukkit start - add method
+ // Paper start
public InventoryHolder getOwner() {
+ return getOwner(true);
+ }
+ public InventoryHolder getOwner(boolean useSnapshot) {
+ // Paper end
if (level == null) return null;
// Spigot start
org.bukkit.block.Block block = level.getWorld().getBlockAt(worldPosition.getX(), worldPosition.getY(), worldPosition.getZ());
@@ -254,7 +260,7 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject {
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 9d5b3801205e2800b0bcf238c5656321e3654f03..d73086970db19531db66c2e8af52da91d0b1ea28 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -313,6 +313,20 @@ public class CraftBlock implements Block {
@Override
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 e89a93082fe07fdb14df8ffef5beca5bd52d7866..730fda7f0bf02400d349959e9cc2aafaed000b21 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
@@ -26,20 +26,40 @@ public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockStat
this.tileEntity = tileEntityClass.cast(world.getHandle().getBlockEntity(this.getPosition()));
Preconditions.checkState(this.tileEntity != null, "Tile is null, asynchronous access? %s", block);
+ // Paper start
+ this.snapshotDisabled = DISABLE_SNAPSHOT;
+ if (DISABLE_SNAPSHOT) {
+ this.snapshot = this.tileEntity;
+ } else {
+ this.snapshot = this.createSnapshot(this.tileEntity);
+ }
// copy tile entity data:
- this.snapshot = this.createSnapshot(tileEntity);
- this.load(snapshot);
+ if(this.snapshot != null) {
+ this.load(this.snapshot);
+ }
+ // Paper end
}
+ 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 = this.tileEntity;
+ } else {
+ this.snapshot = this.createSnapshot(this.tileEntity);
+ }
// copy tile entity data:
- this.snapshot = this.createSnapshot(tileEntity);
- this.load(snapshot);
+ if(this.snapshot != null) {
+ this.load(this.snapshot);
+ }
+ // Paper end
}
private T createSnapshot(T tileEntity) {
diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
index e3664110bef9315cfde5b61dde98dce77016600e..10ba8b810c1759adc439f753d36108e30cf70140 100644
--- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
+++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
@@ -155,4 +155,10 @@ public final class CraftPersistentDataContainer implements PersistentDataContain
public Map<String, Object> serialize() {
return (Map<String, Object>) CraftNBTTagConfigSerializer.serialize(toTagCompound());
}
+
+ // Paper start
+ public void clear() {
+ this.customDataTags.clear();
+ }
+ // Paper end
}