From 718d970f97478edd5373b0133c06ddcd27805ca8 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sat, 14 Dec 2024 11:38:01 -0800 Subject: [PATCH] net.minecraft.world.level.levelgen.structure --- .../LegacyStructureDataHandler.java.patch | 33 ++++ .../structure/StructureCheck.java.patch | 36 ++-- .../structure/StructurePiece.java.patch | 128 ++++++++++++++ .../structure/StructureStart.java.patch | 54 ++++++ .../LegacyStructureDataHandler.java.patch | 32 ---- .../structure/StructurePiece.java.patch | 164 ------------------ .../structure/StructureStart.java.patch | 59 ------- 7 files changed, 233 insertions(+), 273 deletions(-) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/level/levelgen/structure/StructureCheck.java.patch (67%) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler.java.patch new file mode 100644 index 0000000000..f363fd7dbb --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler.java.patch @@ -0,0 +1,33 @@ +--- a/net/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler.java ++++ b/net/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler.java +@@ -18,7 +_,7 @@ + import net.minecraft.resources.ResourceKey; + import net.minecraft.util.datafix.DataFixTypes; + import net.minecraft.world.level.ChunkPos; +-import net.minecraft.world.level.Level; ++import net.minecraft.world.level.dimension.LevelStem; + import net.minecraft.world.level.storage.DimensionDataStorage; + + public class LegacyStructureDataHandler { +@@ -217,17 +_,17 @@ + } + } + +- public static LegacyStructureDataHandler getLegacyStructureHandler(ResourceKey level, @Nullable DimensionDataStorage storage) { +- if (level == Level.OVERWORLD) { ++ public static LegacyStructureDataHandler getLegacyStructureHandler(ResourceKey level, @Nullable DimensionDataStorage storage) { // CraftBukkit ++ if (level == LevelStem.OVERWORLD) { // CraftBukkit + return new LegacyStructureDataHandler( + storage, + ImmutableList.of("Monument", "Stronghold", "Village", "Mineshaft", "Temple", "Mansion"), + ImmutableList.of("Village", "Mineshaft", "Mansion", "Igloo", "Desert_Pyramid", "Jungle_Pyramid", "Swamp_Hut", "Stronghold", "Monument") + ); +- } else if (level == Level.NETHER) { ++ } else if (level == LevelStem.NETHER) { // CraftBukkit + List list = ImmutableList.of("Fortress"); + return new LegacyStructureDataHandler(storage, list, list); +- } else if (level == Level.END) { ++ } else if (level == LevelStem.END) { // CraftBukkit + List list = ImmutableList.of("EndCity"); + return new LegacyStructureDataHandler(storage, list, list); + } else { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/StructureCheck.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructureCheck.java.patch similarity index 67% rename from paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/StructureCheck.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructureCheck.java.patch index 9e6cb9ad46..d79e90f861 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/StructureCheck.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructureCheck.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/levelgen/structure/StructureCheck.java +++ b/net/minecraft/world/level/levelgen/structure/StructureCheck.java -@@ -40,7 +40,7 @@ +@@ -40,7 +_,7 @@ private final ChunkScanAccess storageAccess; private final RegistryAccess registryAccess; private final StructureTemplateManager structureTemplateManager; @@ -9,17 +9,17 @@ private final ChunkGenerator chunkGenerator; private final RandomState randomState; private final LevelHeightAccessor heightAccessor; -@@ -54,7 +54,7 @@ - ChunkScanAccess chunkIoWorker, - RegistryAccess registryManager, +@@ -54,7 +_,7 @@ + ChunkScanAccess storageAccess, + RegistryAccess registryAccess, StructureTemplateManager structureTemplateManager, -- ResourceKey worldKey, -+ ResourceKey worldKey, // Paper - fix missing CB diff +- ResourceKey dimension, ++ ResourceKey dimension, // Paper - fix missing CB diff ChunkGenerator chunkGenerator, - RandomState noiseConfig, - LevelHeightAccessor world, -@@ -74,6 +74,20 @@ - this.fixerUpper = dataFixer; + RandomState randomState, + LevelHeightAccessor heightAccessor, +@@ -74,6 +_,20 @@ + this.fixerUpper = fixerUpper; } + // Paper start - add missing structure salt configs @@ -36,15 +36,15 @@ + } + // Paper end - add missing structure seed configs + - public StructureCheckResult checkStart(ChunkPos pos, Structure type, StructurePlacement placement, boolean skipReferencedStructures) { - long l = pos.toLong(); - Object2IntMap object2IntMap = this.loadedChunks.get(l); -@@ -83,7 +97,7 @@ - StructureCheckResult structureCheckResult = this.tryLoadFromStorage(pos, type, skipReferencedStructures, l); + public StructureCheckResult checkStart(ChunkPos chunkPos, Structure structure, StructurePlacement placement, boolean skipKnownStructures) { + long packedChunkPos = chunkPos.toLong(); + Object2IntMap map = this.loadedChunks.get(packedChunkPos); +@@ -83,7 +_,7 @@ + StructureCheckResult structureCheckResult = this.tryLoadFromStorage(chunkPos, structure, skipKnownStructures, packedChunkPos); if (structureCheckResult != null) { return structureCheckResult; -- } else if (!placement.applyAdditionalChunkRestrictions(pos.x, pos.z, this.seed)) { -+ } else if (!placement.applyAdditionalChunkRestrictions(pos.x, pos.z, this.seed, this.getSaltOverride(type))) { // Paper - add missing structure seed configs +- } else if (!placement.applyAdditionalChunkRestrictions(chunkPos.x, chunkPos.z, this.seed)) { ++ } else if (!placement.applyAdditionalChunkRestrictions(chunkPos.x, chunkPos.z, this.seed, this.getSaltOverride(structure))) { // Paper - add missing structure seed configs return StructureCheckResult.START_NOT_PRESENT; } else { - boolean bl = this.featureChecks + boolean flag = this.featureChecks diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch new file mode 100644 index 0000000000..e53e4b3cd9 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch @@ -0,0 +1,128 @@ +--- a/net/minecraft/world/level/levelgen/structure/StructurePiece.java ++++ b/net/minecraft/world/level/levelgen/structure/StructurePiece.java +@@ -26,8 +_,6 @@ + import net.minecraft.world.level.block.Mirror; + import net.minecraft.world.level.block.Rotation; + import net.minecraft.world.level.block.entity.BlockEntity; +-import net.minecraft.world.level.block.entity.ChestBlockEntity; +-import net.minecraft.world.level.block.entity.DispenserBlockEntity; + import net.minecraft.world.level.block.state.BlockState; + import net.minecraft.world.level.chunk.ChunkGenerator; + import net.minecraft.world.level.levelgen.Heightmap; +@@ -47,7 +_,7 @@ + private Rotation rotation; + protected int genDepth; + private final StructurePieceType type; +- private static final Set SHAPE_CHECK_BLOCKS = ImmutableSet.builder() ++ public static final Set SHAPE_CHECK_BLOCKS = ImmutableSet.builder() // PAIL private -> public + .add(Blocks.NETHER_BRICK_FENCE) + .add(Blocks.TORCH) + .add(Blocks.WALL_TORCH) +@@ -189,6 +_,11 @@ + } + + level.setBlock(worldPos, blockstate, 2); ++ // CraftBukkit start - fluid handling is already done if we have a transformer generator access ++ if (level instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess) { ++ return; ++ } ++ // CraftBukkit end + FluidState fluidState = level.getFluidState(worldPos); + if (!fluidState.isEmpty()) { + level.scheduleTick(worldPos, fluidState.getType(), 0); +@@ -201,6 +_,38 @@ + } + } + ++ // CraftBukkit start ++ protected boolean placeCraftBlockEntity(ServerLevelAccessor serverLevelAccessor, BlockPos pos, org.bukkit.craftbukkit.block.CraftBlockEntityState craftBlockEntityState, int flags) { ++ if (serverLevelAccessor instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) { ++ return transformerAccess.setCraftBlock(pos, craftBlockEntityState, flags); ++ } ++ boolean result = serverLevelAccessor.setBlock(pos, craftBlockEntityState.getHandle(), flags); ++ BlockEntity tileEntity = serverLevelAccessor.getBlockEntity(pos); ++ if (tileEntity != null) { ++ tileEntity.loadWithComponents(craftBlockEntityState.getSnapshotNBT(), serverLevelAccessor.registryAccess()); ++ } ++ return result; ++ } ++ ++ protected void placeCraftSpawner(ServerLevelAccessor worldAccess, BlockPos position, org.bukkit.entity.EntityType entityType, int i) { ++ // This method is used in structures that are generated by code and place spawners as they set the entity after the block was placed making it impossible for plugins to access that information ++ org.bukkit.craftbukkit.block.CraftCreatureSpawner spawner = (org.bukkit.craftbukkit.block.CraftCreatureSpawner) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(worldAccess, position, Blocks.SPAWNER.defaultBlockState(), null); ++ spawner.setSpawnedType(entityType); ++ this.placeCraftBlockEntity(worldAccess, position, spawner, i); ++ } ++ ++ protected void setCraftLootTable(ServerLevelAccessor worldAccess, BlockPos position, RandomSource randomSource, ResourceKey loottableKey) { ++ // This method is used in structures that use data markers to a loot table to loot containers as otherwise plugins won't have access to that information. ++ net.minecraft.world.level.block.entity.BlockEntity tileEntity = worldAccess.getBlockEntity(position); ++ if (tileEntity instanceof net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity tileEntityLootable) { ++ tileEntityLootable.setLootTable(loottableKey, randomSource.nextLong()); ++ if (worldAccess instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) { ++ transformerAccess.setCraftBlock(position, (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(worldAccess, position, tileEntity.getBlockState(), tileEntityLootable.saveWithFullMetadata(worldAccess.registryAccess())), 3); ++ } ++ } ++ } ++ // CraftBukkit end ++ + protected boolean canBeReplaced(LevelReader level, int x, int y, int z, BoundingBox box) { + return true; + } +@@ -429,11 +_,17 @@ + state = reorient(level, pos, Blocks.CHEST.defaultBlockState()); + } + +- level.setBlock(pos, state, 2); +- BlockEntity blockEntity = level.getBlockEntity(pos); +- if (blockEntity instanceof ChestBlockEntity) { +- ((ChestBlockEntity)blockEntity).setLootTable(lootTable, random.nextLong()); +- } ++ // CraftBukkit start ++ // level.setBlock(pos, state, 2); ++ // BlockEntity blockEntity = level.getBlockEntity(pos); ++ // if (blockEntity instanceof ChestBlockEntity) { ++ // ((ChestBlockEntity)blockEntity).setLootTable(lootTable, random.nextLong()); ++ // } ++ org.bukkit.craftbukkit.block.CraftChest chestState = (org.bukkit.craftbukkit.block.CraftChest) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(level, pos, state, null); ++ chestState.setLootTable(org.bukkit.craftbukkit.CraftLootTable.minecraftToBukkit(lootTable)); ++ chestState.setSeed(random.nextLong()); ++ this.placeCraftBlockEntity(level, pos, chestState, 2); ++ // CraftBukkit end + + return true; + } else { +@@ -446,11 +_,28 @@ + ) { + BlockPos worldPos = this.getWorldPos(x, y, z); + if (box.isInside(worldPos) && !level.getBlockState(worldPos).is(Blocks.DISPENSER)) { +- this.placeBlock(level, Blocks.DISPENSER.defaultBlockState().setValue(DispenserBlock.FACING, facing), x, y, z, box); +- BlockEntity blockEntity = level.getBlockEntity(worldPos); +- if (blockEntity instanceof DispenserBlockEntity) { +- ((DispenserBlockEntity)blockEntity).setLootTable(lootTable, random.nextLong()); +- } ++ // CraftBukkit start ++ // this.placeBlock(level, Blocks.DISPENSER.defaultBlockState().setValue(DispenserBlock.FACING, facing), x, y, z, box); ++ // BlockEntity blockEntity = level.getBlockEntity(worldPos); ++ // if (blockEntity instanceof DispenserBlockEntity) { ++ // ((DispenserBlockEntity)blockEntity).setLootTable(lootTable, random.nextLong()); ++ // } ++ if (!this.canBeReplaced(level, x, y, z, this.boundingBox)) { ++ return true; ++ } ++ BlockState dispenserBlockState = Blocks.DISPENSER.defaultBlockState().setValue(DispenserBlock.FACING, facing); ++ if (this.mirror != Mirror.NONE) { ++ dispenserBlockState = dispenserBlockState.mirror(this.mirror); ++ } ++ if (this.rotation != Rotation.NONE) { ++ dispenserBlockState = dispenserBlockState.rotate(this.rotation); ++ } ++ ++ org.bukkit.craftbukkit.block.CraftDispenser dispenserState = (org.bukkit.craftbukkit.block.CraftDispenser) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(level, worldPos, dispenserBlockState, null); ++ dispenserState.setLootTable(org.bukkit.craftbukkit.CraftLootTable.minecraftToBukkit(lootTable)); ++ dispenserState.setSeed(random.nextLong()); ++ this.placeCraftBlockEntity(level, worldPos, dispenserState, 2); ++ // CraftBukkit end + + return true; + } else { diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch new file mode 100644 index 0000000000..9efa80e8e3 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch @@ -0,0 +1,54 @@ +--- a/net/minecraft/world/level/levelgen/structure/StructureStart.java ++++ b/net/minecraft/world/level/levelgen/structure/StructureStart.java +@@ -30,6 +_,12 @@ + @Nullable + private volatile BoundingBox cachedBoundingBox; + ++ // CraftBukkit start ++ private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry(); ++ public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(StructureStart.DATA_TYPE_REGISTRY); ++ public org.bukkit.event.world.AsyncStructureGenerateEvent.Cause generationEventCause = org.bukkit.event.world.AsyncStructureGenerateEvent.Cause.WORLD_GENERATION; ++ // CraftBukkit end ++ + public StructureStart(Structure structure, ChunkPos chunkPos, int references, PiecesContainer pieceContainer) { + this.structure = structure; + this.chunkPos = chunkPos; +@@ -87,11 +_,23 @@ + BlockPos center = boundingBox.getCenter(); + BlockPos blockPos = new BlockPos(center.getX(), boundingBox.minY(), center.getZ()); + +- for (StructurePiece structurePiece : list) { +- if (structurePiece.getBoundingBox().intersects(box)) { +- structurePiece.postProcess(level, structureManager, generator, random, box, chunkPos, blockPos); ++ // CraftBukkit start ++ // for (StructurePiece structurePiece : list) { ++ // if (structurePiece.getBoundingBox().intersects(box)) { ++ // structurePiece.postProcess(level, structureManager, generator, random, box, chunkPos, blockPos); ++ // } ++ // } ++ List pieces = list.stream().filter(piece -> piece.getBoundingBox().intersects(box)).toList(); ++ if (!pieces.isEmpty()) { ++ org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess = new org.bukkit.craftbukkit.util.TransformerGeneratorAccess(); ++ transformerAccess.setHandle(level); ++ transformerAccess.setStructureTransformer(new org.bukkit.craftbukkit.util.CraftStructureTransformer(this.generationEventCause, level, structureManager, this.structure, box, chunkPos)); ++ for (StructurePiece piece : pieces) { ++ piece.postProcess(transformerAccess, structureManager, generator, random, box, chunkPos, blockPos); + } ++ transformerAccess.getStructureTransformer().discard(); + } ++ // CraftBukkit end + + this.structure.afterPlace(level, structureManager, generator, random, box, chunkPos, this.pieceContainer); + } +@@ -99,6 +_,11 @@ + + public CompoundTag createTag(StructurePieceSerializationContext context, ChunkPos chunkPos) { + CompoundTag compoundTag = new CompoundTag(); ++ // CraftBukkit start - store persistent data in nbt ++ if (!this.persistentDataContainer.isEmpty()) { ++ compoundTag.put("StructureBukkitValues", this.persistentDataContainer.toTagCompound()); ++ } ++ // CraftBukkit end + if (this.isValid()) { + compoundTag.putString("id", context.registryAccess().lookupOrThrow(Registries.STRUCTURE).getKey(this.structure).toString()); + compoundTag.putInt("ChunkX", chunkPos.x); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler.java.patch deleted file mode 100644 index 04607e1797..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler.java.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- a/net/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler.java -+++ b/net/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler.java -@@ -18,7 +18,7 @@ - import net.minecraft.resources.ResourceKey; - import net.minecraft.util.datafix.DataFixTypes; - import net.minecraft.world.level.ChunkPos; --import net.minecraft.world.level.Level; -+import net.minecraft.world.level.dimension.LevelStem; - import net.minecraft.world.level.storage.DimensionDataStorage; - - public class LegacyStructureDataHandler { -@@ -233,16 +233,16 @@ - } - } - -- public static LegacyStructureDataHandler getLegacyStructureHandler(ResourceKey world, @Nullable DimensionDataStorage persistentStateManager) { -- if (world == Level.OVERWORLD) { -+ public static LegacyStructureDataHandler getLegacyStructureHandler(ResourceKey world, @Nullable DimensionDataStorage persistentStateManager) { // CraftBukkit -+ if (world == LevelStem.OVERWORLD) { // CraftBukkit - return new LegacyStructureDataHandler(persistentStateManager, ImmutableList.of("Monument", "Stronghold", "Village", "Mineshaft", "Temple", "Mansion"), ImmutableList.of("Village", "Mineshaft", "Mansion", "Igloo", "Desert_Pyramid", "Jungle_Pyramid", "Swamp_Hut", "Stronghold", "Monument")); - } else { - ImmutableList immutablelist; - -- if (world == Level.NETHER) { -+ if (world == LevelStem.NETHER) { // CraftBukkit - immutablelist = ImmutableList.of("Fortress"); - return new LegacyStructureDataHandler(persistentStateManager, immutablelist, immutablelist); -- } else if (world == Level.END) { -+ } else if (world == LevelStem.END) { // CraftBukkit - immutablelist = ImmutableList.of("EndCity"); - return new LegacyStructureDataHandler(persistentStateManager, immutablelist, immutablelist); - } else { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch deleted file mode 100644 index 918d4c34ed..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch +++ /dev/null @@ -1,164 +0,0 @@ ---- a/net/minecraft/world/level/levelgen/structure/StructurePiece.java -+++ b/net/minecraft/world/level/levelgen/structure/StructurePiece.java -@@ -29,8 +29,6 @@ - import net.minecraft.world.level.block.Mirror; - import net.minecraft.world.level.block.Rotation; - import net.minecraft.world.level.block.entity.BlockEntity; --import net.minecraft.world.level.block.entity.ChestBlockEntity; --import net.minecraft.world.level.block.entity.DispenserBlockEntity; - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.chunk.ChunkGenerator; - import net.minecraft.world.level.levelgen.Heightmap; -@@ -51,7 +49,7 @@ - private Rotation rotation; - protected int genDepth; - private final StructurePieceType type; -- private static final Set SHAPE_CHECK_BLOCKS = ImmutableSet.builder().add(Blocks.NETHER_BRICK_FENCE).add(Blocks.TORCH).add(Blocks.WALL_TORCH).add(Blocks.OAK_FENCE).add(Blocks.SPRUCE_FENCE).add(Blocks.DARK_OAK_FENCE).add(Blocks.PALE_OAK_FENCE).add(Blocks.ACACIA_FENCE).add(Blocks.BIRCH_FENCE).add(Blocks.JUNGLE_FENCE).add(Blocks.LADDER).add(Blocks.IRON_BARS).build(); -+ public static final Set SHAPE_CHECK_BLOCKS = ImmutableSet.builder().add(Blocks.NETHER_BRICK_FENCE).add(Blocks.TORCH).add(Blocks.WALL_TORCH).add(Blocks.OAK_FENCE).add(Blocks.SPRUCE_FENCE).add(Blocks.DARK_OAK_FENCE).add(Blocks.PALE_OAK_FENCE).add(Blocks.ACACIA_FENCE).add(Blocks.BIRCH_FENCE).add(Blocks.JUNGLE_FENCE).add(Blocks.LADDER).add(Blocks.IRON_BARS).build(); // CraftBukkit - decompile error / PAIL private -> public - - protected StructurePiece(StructurePieceType type, int length, BoundingBox boundingBox) { - this.type = type; -@@ -80,13 +78,11 @@ - CompoundTag nbttagcompound = new CompoundTag(); - - nbttagcompound.putString("id", BuiltInRegistries.STRUCTURE_PIECE.getKey(this.getType()).toString()); -- DataResult dataresult = BoundingBox.CODEC.encodeStart(NbtOps.INSTANCE, this.boundingBox); -- Logger logger = StructurePiece.LOGGER; -- -- Objects.requireNonNull(logger); -- dataresult.resultOrPartial(logger::error).ifPresent((nbtbase) -> { -- nbttagcompound.put("BB", nbtbase); -+ // CraftBukkit start - decompile error -+ BoundingBox.CODEC.encodeStart(NbtOps.INSTANCE, this.boundingBox).resultOrPartial(Objects.requireNonNull(StructurePiece.LOGGER)::error).ifPresent((nbtbase) -> { -+ nbttagcompound.put("BB", nbtbase); - }); -+ // CraftBukkit end - Direction enumdirection = this.getOrientation(); - - nbttagcompound.putInt("O", enumdirection == null ? -1 : enumdirection.get2DDataValue()); -@@ -186,6 +182,11 @@ - } - - world.setBlock(blockposition_mutableblockposition, block, 2); -+ // CraftBukkit start - fluid handling is already done if we have a transformer generator access -+ if (world instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess) { -+ return; -+ } -+ // CraftBukkit end - FluidState fluid = world.getFluidState(blockposition_mutableblockposition); - - if (!fluid.isEmpty()) { -@@ -195,10 +196,42 @@ - if (StructurePiece.SHAPE_CHECK_BLOCKS.contains(block.getBlock())) { - world.getChunk(blockposition_mutableblockposition).markPosForPostprocessing(blockposition_mutableblockposition); - } -+ -+ } -+ } -+ } -+ -+ // CraftBukkit start -+ protected boolean placeCraftBlockEntity(ServerLevelAccessor worldAccess, BlockPos position, org.bukkit.craftbukkit.block.CraftBlockEntityState craftBlockEntityState, int i) { -+ if (worldAccess instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) { -+ return transformerAccess.setCraftBlock(position, craftBlockEntityState, i); -+ } -+ boolean result = worldAccess.setBlock(position, craftBlockEntityState.getHandle(), i); -+ BlockEntity tileEntity = worldAccess.getBlockEntity(position); -+ if (tileEntity != null) { -+ tileEntity.loadWithComponents(craftBlockEntityState.getSnapshotNBT(), worldAccess.registryAccess()); -+ } -+ return result; -+ } - -+ protected void placeCraftSpawner(ServerLevelAccessor worldAccess, BlockPos position, org.bukkit.entity.EntityType entityType, int i) { -+ // This method is used in structures that are generated by code and place spawners as they set the entity after the block was placed making it impossible for plugins to access that information -+ org.bukkit.craftbukkit.block.CraftCreatureSpawner spawner = (org.bukkit.craftbukkit.block.CraftCreatureSpawner) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(worldAccess, position, Blocks.SPAWNER.defaultBlockState(), null); -+ spawner.setSpawnedType(entityType); -+ this.placeCraftBlockEntity(worldAccess, position, spawner, i); -+ } -+ -+ protected void setCraftLootTable(ServerLevelAccessor worldAccess, BlockPos position, RandomSource randomSource, ResourceKey loottableKey) { -+ // This method is used in structures that use data markers to a loot table to loot containers as otherwise plugins won't have access to that information. -+ net.minecraft.world.level.block.entity.BlockEntity tileEntity = worldAccess.getBlockEntity(position); -+ if (tileEntity instanceof net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity tileEntityLootable) { -+ tileEntityLootable.setLootTable(loottableKey, randomSource.nextLong()); -+ if (worldAccess instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) { -+ transformerAccess.setCraftBlock(position, (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(worldAccess, position, tileEntity.getBlockState(), tileEntityLootable.saveWithFullMetadata(worldAccess.registryAccess())), 3); - } - } - } -+ // CraftBukkit end - - protected boolean canBeReplaced(LevelReader world, int x, int y, int z, BoundingBox box) { - return true; -@@ -393,12 +426,20 @@ - block = StructurePiece.reorient(world, pos, Blocks.CHEST.defaultBlockState()); - } - -- world.setBlock(pos, block, 2); -- BlockEntity tileentity = world.getBlockEntity(pos); -+ // CraftBukkit start -+ /* -+ worldaccess.setBlock(blockposition, iblockdata, 2); -+ TileEntity tileentity = worldaccess.getBlockEntity(blockposition); - -- if (tileentity instanceof ChestBlockEntity) { -- ((ChestBlockEntity) tileentity).setLootTable(lootTable, random.nextLong()); -+ if (tileentity instanceof TileEntityChest) { -+ ((TileEntityChest) tileentity).setLootTable(resourcekey, randomsource.nextLong()); - } -+ */ -+ org.bukkit.craftbukkit.block.CraftChest chestState = (org.bukkit.craftbukkit.block.CraftChest) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world, pos, block, null); -+ chestState.setLootTable(org.bukkit.craftbukkit.CraftLootTable.minecraftToBukkit(lootTable)); -+ chestState.setSeed(random.nextLong()); -+ this.placeCraftBlockEntity(world, pos, chestState, 2); -+ // CraftBukkit end - - return true; - } else { -@@ -410,13 +451,32 @@ - BlockPos.MutableBlockPos blockposition_mutableblockposition = this.getWorldPos(x, y, z); - - if (boundingBox.isInside(blockposition_mutableblockposition) && !world.getBlockState(blockposition_mutableblockposition).is(Blocks.DISPENSER)) { -- this.placeBlock(world, (BlockState) Blocks.DISPENSER.defaultBlockState().setValue(DispenserBlock.FACING, facing), x, y, z, boundingBox); -- BlockEntity tileentity = world.getBlockEntity(blockposition_mutableblockposition); -+ // CraftBukkit start -+ /* -+ this.placeBlock(generatoraccessseed, (IBlockData) Blocks.DISPENSER.defaultBlockState().setValue(BlockDispenser.FACING, enumdirection), i, j, k, structureboundingbox); -+ TileEntity tileentity = generatoraccessseed.getBlockEntity(blockposition_mutableblockposition); - -- if (tileentity instanceof DispenserBlockEntity) { -- ((DispenserBlockEntity) tileentity).setLootTable(lootTable, random.nextLong()); -+ if (tileentity instanceof TileEntityDispenser) { -+ ((TileEntityDispenser) tileentity).setLootTable(resourcekey, randomsource.nextLong()); - } -+ */ -+ if (!this.canBeReplaced(world, x, y, z, boundingBox)) { -+ return true; -+ } -+ BlockState iblockdata = Blocks.DISPENSER.defaultBlockState().setValue(DispenserBlock.FACING, facing); -+ if (this.mirror != Mirror.NONE) { -+ iblockdata = iblockdata.mirror(this.mirror); -+ } -+ if (this.rotation != Rotation.NONE) { -+ iblockdata = iblockdata.rotate(this.rotation); -+ } - -+ org.bukkit.craftbukkit.block.CraftDispenser dispenserState = (org.bukkit.craftbukkit.block.CraftDispenser) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world, blockposition_mutableblockposition, iblockdata, null); -+ dispenserState.setLootTable(org.bukkit.craftbukkit.CraftLootTable.minecraftToBukkit(lootTable)); -+ dispenserState.setSeed(random.nextLong()); -+ this.placeCraftBlockEntity(world, blockposition_mutableblockposition, dispenserState, 2); -+ // CraftBukkit end -+ - return true; - } else { - return false; -@@ -428,7 +488,7 @@ - } - - public static BoundingBox createBoundingBox(Stream pieces) { -- Stream stream1 = pieces.map(StructurePiece::getBoundingBox); -+ Stream stream1 = pieces.map(StructurePiece::getBoundingBox); // CraftBukkit - decompile error - - Objects.requireNonNull(stream1); - return (BoundingBox) BoundingBox.encapsulatingBoxes(stream1::iterator).orElseThrow(() -> { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch deleted file mode 100644 index 83539110a1..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch +++ /dev/null @@ -1,59 +0,0 @@ ---- a/net/minecraft/world/level/levelgen/structure/StructureStart.java -+++ b/net/minecraft/world/level/levelgen/structure/StructureStart.java -@@ -32,6 +32,12 @@ - @Nullable - private volatile BoundingBox cachedBoundingBox; - -+ // CraftBukkit start -+ private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry(); -+ public org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.DirtyCraftPersistentDataContainer(StructureStart.DATA_TYPE_REGISTRY); -+ public org.bukkit.event.world.AsyncStructureGenerateEvent.Cause generationEventCause = org.bukkit.event.world.AsyncStructureGenerateEvent.Cause.WORLD_GENERATION; -+ // CraftBukkit end -+ - public StructureStart(Structure structure, ChunkPos pos, int references, PiecesContainer children) { - this.structure = structure; - this.chunkPos = pos; -@@ -91,15 +97,29 @@ - BoundingBox structureboundingbox1 = ((StructurePiece) list.get(0)).boundingBox; - BlockPos blockposition = structureboundingbox1.getCenter(); - BlockPos blockposition1 = new BlockPos(blockposition.getX(), structureboundingbox1.minY(), blockposition.getZ()); -+ // CraftBukkit start -+ /* - Iterator iterator = list.iterator(); - - while (iterator.hasNext()) { - StructurePiece structurepiece = (StructurePiece) iterator.next(); - -- if (structurepiece.getBoundingBox().intersects(chunkBox)) { -- structurepiece.postProcess(world, structureAccessor, chunkGenerator, random, chunkBox, chunkPos, blockposition1); -+ if (structurepiece.getBoundingBox().intersects(structureboundingbox)) { -+ structurepiece.postProcess(generatoraccessseed, structuremanager, chunkgenerator, randomsource, structureboundingbox, chunkcoordintpair, blockposition1); - } - } -+ */ -+ List pieces = list.stream().filter(piece -> piece.getBoundingBox().intersects(chunkBox)).toList(); -+ if (!pieces.isEmpty()) { -+ org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess = new org.bukkit.craftbukkit.util.TransformerGeneratorAccess(); -+ transformerAccess.setHandle(world); -+ transformerAccess.setStructureTransformer(new org.bukkit.craftbukkit.util.CraftStructureTransformer(this.generationEventCause, world, structureAccessor, this.structure, chunkBox, chunkPos)); -+ for (StructurePiece piece : pieces) { -+ piece.postProcess(transformerAccess, structureAccessor, chunkGenerator, random, chunkBox, chunkPos, blockposition1); -+ } -+ transformerAccess.getStructureTransformer().discard(); -+ } -+ // CraftBukkit end - - this.structure.afterPlace(world, structureAccessor, chunkGenerator, random, chunkBox, chunkPos, this.pieceContainer); - } -@@ -107,6 +127,11 @@ - - public CompoundTag createTag(StructurePieceSerializationContext context, ChunkPos chunkPos) { - CompoundTag nbttagcompound = new CompoundTag(); -+ // CraftBukkit start - store persistent data in nbt -+ if (!this.persistentDataContainer.isEmpty()) { -+ nbttagcompound.put("StructureBukkitValues", this.persistentDataContainer.toTagCompound()); -+ } -+ // CraftBukkit end - - if (this.isValid()) { - nbttagcompound.putString("id", context.registryAccess().lookupOrThrow(Registries.STRUCTURE).getKey(this.structure).toString());