From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar 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 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) 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 serialize() { return (Map) CraftNBTTagConfigSerializer.serialize(toTagCompound()); } + + // Paper start + public void clear() { + this.customDataTags.clear(); + } + // Paper end }