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/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java index 9d777fce673c8f6b3ee2d69f5a6360a8a5ad8e84..c3706b87ad36332a837caffb58bd4575cbc0172a 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 @@ -31,7 +31,7 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject { // CraftBukkit end private static final Logger LOGGER = LogManager.getLogger(); public boolean isLoadingStructure = false; // Paper - private final BlockEntityType type; public BlockEntityType getTileEntityType() { return type; } // Paper - OBFHELPER + private final BlockEntityType type; @Nullable protected Level level; protected final BlockPos worldPosition; @@ -42,6 +42,7 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject { this.type = type; this.worldPosition = pos.immutable(); this.blockState = state; + persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); // Paper - always init } // Paper start @@ -79,7 +80,7 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject { // CraftBukkit start - read container public void load(CompoundTag nbt) { - this.persistentDataContainer = new CraftPersistentDataContainer(BlockEntity.DATA_TYPE_REGISTRY); + this.persistentDataContainer.clear(); net.minecraft.nbt.Tag persistentDataTag = nbt.get("PublicBukkitValues"); if (persistentDataTag instanceof CompoundTag) { @@ -221,8 +222,13 @@ public abstract class BlockEntity implements net.minecraft.server.KeyedObject { } // CraftBukkit start - add method + // Paper start public InventoryHolder getOwner() { - if (this.level == null) return null; + return getOwner(true); + } + public InventoryHolder getOwner(boolean useSnapshot) { + // Paper end + if (level == null) return null; // Spigot start org.bukkit.block.Block block = this.level.getWorld().getBlockAt(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ()); if (block == null) { @@ -230,7 +236,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 6128eb5a793365822d9b00a86629ad4d86c61da9..ca03ed4b1581df2b7db272d6f330174a9d277153 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -313,7 +313,21 @@ public class CraftBlock implements Block { @Override public BlockState getState() { - Material material = this.getType(); + // 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) { case ACACIA_SIGN: diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java index d57b32090cebfc952ac0a71b8aada85f49275241..9a30770a2f68e1253afe3ca8ecdae19c988248f9 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 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) 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 ddd7b63f0452042baa3fca04bb9fbdb42fcecbfd..b638351581fa09c488425a2318b782a5812140ce 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(this.toTagCompound()); } + + // Paper start + public void clear() { + this.customDataTags.clear(); + } + // Paper end }