PaperMC/Spigot-Server-Patches/0179-API-to-get-a-BlockState-without-a-snapshot.patch
Mariell Hoversholm 0f78e95250 More work
2021-03-18 18:03:22 +01:00

147 lines
6.7 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/TileEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TileEntity.java
index fd6364dfc68c2eb9f560e7bc403dea874193828e..3ff9e389fcf15044c2740fb884c9438428d7a681 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/TileEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/TileEntity.java
@@ -47,6 +47,7 @@ public abstract class TileEntity implements net.minecraft.server.KeyedObject { /
public TileEntity(TileEntityTypes<?> tileentitytypes) {
this.position = BlockPosition.ZERO;
this.tileType = tileentitytypes;
+ persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); // Paper - always init
}
// Paper start
@@ -95,7 +96,7 @@ public abstract class TileEntity implements net.minecraft.server.KeyedObject { /
public void load(IBlockData iblockdata, NBTTagCompound nbttagcompound) {
this.position = new BlockPosition(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z"));
// CraftBukkit start - read container
- this.persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY);
+ this.persistentDataContainer.clear(); // Paper - clear instead of reinit
net.minecraft.nbt.NBTBase persistentDataTag = nbttagcompound.get("PublicBukkitValues");
if (persistentDataTag instanceof NBTTagCompound) {
@@ -245,7 +246,12 @@ public abstract class TileEntity 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 (world == null) return null;
// Spigot start
org.bukkit.block.Block block = world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ());
@@ -254,7 +260,7 @@ public abstract class TileEntity 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 7654c0f8b57785225ecaa0c22e34c92f1d058d21..e4fe55bb830cd43680de9d61652448b1ea879063 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -316,6 +316,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 dcf3f9265b0b00a7bbb9ff428e10da3c198ba08a..2f0b48869077c27d0cacea81a99c9e34ff59c684 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 TileEntity> extends CraftBlockState
this.tileEntity = tileEntityClass.cast(world.getHandle().getTileEntity(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 f342feee4e2274cdc51fef6caace52cc31eefb18..a4c888236bf09a25f234831a041ca5a4a2c972ef 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
}