diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch index 615c1970ee..b2ac6c60fe 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch @@ -19,14 +19,22 @@ private static final Logger LOGGER = LogUtils.getLogger(); private final BlockEntityType type; @Nullable -@@ -74,8 +84,17 @@ +@@ -43,6 +53,7 @@ + this.worldPosition = pos.immutable(); + this.validateBlockState(state); + this.blockState = state; ++ this.persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); // Paper - always init + } + + private void validateBlockState(BlockState state) { +@@ -74,8 +85,17 @@ return this.level != null; } - protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider registries) {} + // CraftBukkit start - read container + protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider registries) { -+ 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) { @@ -38,7 +46,7 @@ public final void loadWithComponents(CompoundTag nbt, HolderLookup.Provider registries) { this.loadAdditional(nbt, registries); BlockEntity.ComponentHelper.COMPONENTS_CODEC.parse(registries.createSerializationContext(NbtOps.INSTANCE), nbt).resultOrPartial((s) -> { -@@ -114,6 +133,11 @@ +@@ -114,6 +134,11 @@ }).ifPresent((nbtbase) -> { nbttagcompound.merge((CompoundTag) nbtbase); }); @@ -50,7 +58,7 @@ return nbttagcompound; } -@@ -234,7 +258,12 @@ +@@ -234,7 +259,12 @@ public void fillCrashReportCategory(CrashReportCategory crashReportSection) { crashReportSection.setDetail("Name", this::getNameForReporting); if (this.level != null) { @@ -64,7 +72,7 @@ CrashReportCategory.populateBlockDetails(crashReportSection, this.level, this.worldPosition, this.level.getBlockState(this.worldPosition)); } } -@@ -263,13 +292,19 @@ +@@ -263,13 +293,19 @@ } public final void applyComponents(DataComponentMap defaultComponents, DataComponentPatch components) { @@ -86,7 +94,7 @@ @Nullable @Override public T get(DataComponentType type) { -@@ -284,9 +319,13 @@ +@@ -284,9 +320,13 @@ } }); Objects.requireNonNull(set); @@ -101,14 +109,21 @@ } protected void collectImplicitComponents(DataComponentMap.Builder builder) {} -@@ -321,6 +360,15 @@ +@@ -321,6 +361,22 @@ } } + // 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/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java index c9b1167b15..e163ff416f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/paper-server/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/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java index 483a89ba47..80418a05d5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java @@ -24,15 +24,26 @@ public class CraftBlockEntityState 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 state, Location location) { @@ -184,4 +195,11 @@ public class CraftBlockEntityState extends CraftBlockStat public CraftBlockEntityState copy(Location location) { return new CraftBlockEntityState<>(this, location); } + + // Paper start + @Override + public boolean isSnapshot() { + return !this.snapshotDisabled; + } + // Paper end } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java index b849ed6eef..1a8dcde39a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java @@ -393,15 +393,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 } @Deprecated diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java index dbb9a5b2f8..3001bb0e3d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java +++ b/paper-server/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 }