--- a/net/minecraft/world/level/block/entity/TileEntity.java +++ b/net/minecraft/world/level/block/entity/TileEntity.java @@ -33,8 +33,18 @@ import net.minecraft.world.level.block.state.IBlockData; import org.slf4j.Logger; +// CraftBukkit start +import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; +import org.bukkit.inventory.InventoryHolder; +// CraftBukkit end + public abstract class TileEntity { + // CraftBukkit start - data containers + private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); + public CraftPersistentDataContainer persistentDataContainer; + // CraftBukkit end private static final Codec> TYPE_CODEC = BuiltInRegistries.BLOCK_ENTITY_TYPE.byNameCodec(); private static final Logger LOGGER = LogUtils.getLogger(); private final TileEntityTypes type; @@ -72,7 +82,7 @@ int l = SectionPosition.blockToSectionCoord(i); int i1 = SectionPosition.blockToSectionCoord(k); - if (l != chunkcoordintpair.x || i1 != chunkcoordintpair.z) { + if (chunkcoordintpair != null && (l != chunkcoordintpair.x || i1 != chunkcoordintpair.z)) { // CraftBukkit - allow null TileEntity.LOGGER.warn("Block entity {} found in a wrong chunk, expected position from chunk {}", nbttagcompound, chunkcoordintpair); i = chunkcoordintpair.getBlockX(SectionPosition.sectionRelative(i)); k = chunkcoordintpair.getBlockZ(SectionPosition.sectionRelative(k)); @@ -94,7 +104,16 @@ return this.level != null; } - protected void loadAdditional(NBTTagCompound nbttagcompound, HolderLookup.a holderlookup_a) {} + // CraftBukkit start - read container + protected void loadAdditional(NBTTagCompound nbttagcompound, HolderLookup.a holderlookup_a) { + this.persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); + + net.minecraft.nbt.NBTBase persistentDataTag = nbttagcompound.get("PublicBukkitValues"); + if (persistentDataTag instanceof NBTTagCompound) { + this.persistentDataContainer.putAll((NBTTagCompound) persistentDataTag); + } + } + // CraftBukkit end public final void loadWithComponents(NBTTagCompound nbttagcompound, HolderLookup.a holderlookup_a) { this.loadAdditional(nbttagcompound, holderlookup_a); @@ -126,6 +145,11 @@ this.saveAdditional(nbttagcompound, holderlookup_a); nbttagcompound.store(TileEntity.a.COMPONENTS_CODEC, holderlookup_a.createSerializationContext(DynamicOpsNBT.INSTANCE), this.components); + // CraftBukkit start - store container + if (this.persistentDataContainer != null && !this.persistentDataContainer.isEmpty()) { + nbttagcompound.put("PublicBukkitValues", this.persistentDataContainer.toTagCompound()); + } + // CraftBukkit end return nbttagcompound; } @@ -160,7 +184,7 @@ @Nullable public static TileEntity loadStatic(BlockPosition blockposition, IBlockData iblockdata, NBTTagCompound nbttagcompound, HolderLookup.a holderlookup_a) { - TileEntityTypes tileentitytypes = (TileEntityTypes) nbttagcompound.read("id", TileEntity.TYPE_CODEC).orElse((Object) null); + TileEntityTypes tileentitytypes = (TileEntityTypes) nbttagcompound.read("id", TileEntity.TYPE_CODEC).orElse(null); // CraftBukkit - decompile error if (tileentitytypes == null) { TileEntity.LOGGER.error("Skipping block entity with invalid type: {}", nbttagcompound.get("id")); @@ -285,6 +309,12 @@ } public final void applyComponents(DataComponentMap datacomponentmap, DataComponentPatch datacomponentpatch) { + // CraftBukkit start + this.applyComponentsSet(datacomponentmap, datacomponentpatch); + } + + public final Set> applyComponentsSet(DataComponentMap datacomponentmap, DataComponentPatch datacomponentpatch) { + // CraftBukkit end final Set> set = new HashSet(); set.add(DataComponents.BLOCK_ENTITY_DATA); @@ -309,6 +339,11 @@ DataComponentPatch datacomponentpatch1 = datacomponentpatch.forget(set::contains); this.components = datacomponentpatch1.split().added(); + // CraftBukkit start + set.remove(DataComponents.BLOCK_ENTITY_DATA); // Remove as never actually added by applyImplicitComponents + set.remove(DataComponents.BLOCK_STATE); // Remove as never actually added by applyImplicitComponents + return set; + // CraftBukkit end } protected void collectImplicitComponents(DataComponentMap.a datacomponentmap_a) {} @@ -337,9 +372,18 @@ public static IChatBaseComponent parseCustomNameSafe(@Nullable NBTBase nbtbase, HolderLookup.a holderlookup_a) { return nbtbase == null ? null : (IChatBaseComponent) ComponentSerialization.CODEC.parse(holderlookup_a.createSerializationContext(DynamicOpsNBT.INSTANCE), nbtbase).resultOrPartial((s) -> { TileEntity.LOGGER.warn("Failed to parse custom name, discarding: {}", s); - }).orElse((Object) null); + }).orElse(null); // CraftBukkit - decompile error } + // CraftBukkit start - add method + public InventoryHolder getOwner() { + if (level == null) return null; + org.bukkit.block.BlockState state = level.getWorld().getBlockAt(worldPosition.getX(), worldPosition.getY(), worldPosition.getZ()).getState(); + if (state instanceof InventoryHolder) return (InventoryHolder) state; + return null; + } + // CraftBukkit end + private static class a { public static final MapCodec COMPONENTS_CODEC = DataComponentMap.CODEC.optionalFieldOf("components", DataComponentMap.EMPTY);