diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/templatesystem/StructurePlaceSettings.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/templatesystem/StructurePlaceSettings.java.patch similarity index 63% rename from paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/templatesystem/StructurePlaceSettings.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/templatesystem/StructurePlaceSettings.java.patch index 60b3e8e667..dc109e1327 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/templatesystem/StructurePlaceSettings.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/templatesystem/StructurePlaceSettings.java.patch @@ -1,25 +1,25 @@ --- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructurePlaceSettings.java +++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructurePlaceSettings.java -@@ -22,7 +22,7 @@ - private LiquidSettings liquidSettings; +@@ -21,7 +_,7 @@ + private LiquidSettings liquidSettings = LiquidSettings.APPLY_WATERLOGGING; @Nullable private RandomSource random; - private int palette; + public int palette = -1; // CraftBukkit - Set initial value so we know if the palette has been set forcefully - private final List processors; + private final List processors = Lists.newArrayList(); private boolean knownShape; private boolean finalizeEntities; -@@ -149,6 +149,13 @@ - - if (i == 0) { +@@ -142,6 +_,13 @@ + int size = palettes.size(); + if (size == 0) { throw new IllegalStateException("No palettes"); + // CraftBukkit start + } else if (this.palette >= 0) { -+ if (this.palette >= i) { -+ throw new IllegalArgumentException("Palette index out of bounds. Got " + this.palette + " where there are only " + i + " palettes available."); ++ if (this.palette >= size) { ++ throw new IllegalArgumentException("Palette index out of bounds. Got " + this.palette + " where there are only " + size + " palettes available."); + } -+ return infoLists.get(this.palette); ++ return palettes.get(this.palette); + // CraftBukkit end } else { - return (StructureTemplate.Palette) infoLists.get(this.getRandom(pos).nextInt(i)); + return palettes.get(this.getRandom(pos).nextInt(size)); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch new file mode 100644 index 0000000000..7839e3322c --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch @@ -0,0 +1,168 @@ +--- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java ++++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java +@@ -25,6 +_,7 @@ + import net.minecraft.nbt.IntTag; + import net.minecraft.nbt.ListTag; + import net.minecraft.nbt.NbtUtils; ++import net.minecraft.nbt.Tag; + import net.minecraft.resources.ResourceLocation; + import net.minecraft.util.RandomSource; + import net.minecraft.world.Clearable; +@@ -54,6 +_,10 @@ + import net.minecraft.world.phys.Vec3; + import net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape; + import net.minecraft.world.phys.shapes.DiscreteVoxelShape; ++// CraftBukkit start ++import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; ++import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; ++// CraftBukkit end + + public class StructureTemplate { + public static final String PALETTE_TAG = "palette"; +@@ -71,6 +_,10 @@ + public final List entityInfoList = Lists.newArrayList(); + private Vec3i size = Vec3i.ZERO; + private String author = "?"; ++ // CraftBukkit start - data containers ++ private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); ++ public CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(StructureTemplate.DATA_TYPE_REGISTRY); ++ // CraftBukkit end + + public Vec3i getSize() { + return this.size; +@@ -245,6 +_,19 @@ + if (this.palettes.isEmpty()) { + return false; + } else { ++ // CraftBukkit start ++ // We only want the TransformerGeneratorAccess at certain locations because in here are many "block update" calls that shouldn't be transformed ++ ServerLevelAccessor wrappedAccess = serverLevel; ++ org.bukkit.craftbukkit.util.CraftStructureTransformer structureTransformer = null; ++ if (wrappedAccess instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) { ++ serverLevel = transformerAccess.getHandle(); ++ structureTransformer = transformerAccess.getStructureTransformer(); ++ // The structureTransformer is not needed if we can not transform blocks therefore we can save a little bit of performance doing this ++ if (structureTransformer != null && !structureTransformer.canTransformBlocks()) { ++ structureTransformer = null; ++ } ++ } ++ // CraftBukkit end + List list = settings.getRandomPalette(this.palettes, offset).blocks(); + if ((!list.isEmpty() || !settings.isIgnoreEntities() && !this.entityInfoList.isEmpty()) + && this.size.getX() >= 1 +@@ -268,10 +_,29 @@ + BlockState blockState = structureBlockInfo.state.mirror(settings.getMirror()).rotate(settings.getRotation()); + if (structureBlockInfo.nbt != null) { + BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos); +- Clearable.tryClear(blockEntity); ++ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock ++ if (!(serverLevel instanceof net.minecraft.world.level.WorldGenLevel)) { ++ Clearable.tryClear(blockEntity); ++ } ++ // Paper end - Fix NBT pieces overriding a block entity during worldgen deadlock + serverLevel.setBlock(blockPos, Blocks.BARRIER.defaultBlockState(), 20); + } + ++ // CraftBukkit start ++ if (structureTransformer != null) { ++ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(serverLevel, blockPos, blockState, null); ++ if (structureBlockInfo.nbt != null && craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState entityState) { ++ entityState.loadData(structureBlockInfo.nbt); ++ if (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftLootable craftLootable) { ++ craftLootable.setSeed(random.nextLong()); ++ } ++ } ++ craftBlockState = structureTransformer.transformCraftState(craftBlockState); ++ blockState = craftBlockState.getHandle(); ++ structureBlockInfo = new StructureTemplate.StructureBlockInfo(blockPos, blockState, (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState craftBlockEntityState ? craftBlockEntityState.getSnapshotNBT() : null)); ++ } ++ // CraftBukkit end ++ + if (serverLevel.setBlock(blockPos, blockState, flags)) { + i = Math.min(i, blockPos.getX()); + i1 = Math.min(i1, blockPos.getY()); +@@ -283,7 +_,7 @@ + if (structureBlockInfo.nbt != null) { + BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos); + if (blockEntity != null) { +- if (blockEntity instanceof RandomizableContainer) { ++ if (structureTransformer == null && blockEntity instanceof RandomizableContainer) { // CraftBukkit - only process if don't have a transformer access (Was already set above) - SPIGOT-7520: Use structureTransformer as check, so that it is the same as above + structureBlockInfo.nbt.putLong("LootTableSeed", random.nextLong()); + } + +@@ -366,7 +_,11 @@ + if (pair1.getSecond() != null) { + BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos4); + if (blockEntity != null) { +- blockEntity.setChanged(); ++ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock ++ if (!(serverLevel instanceof net.minecraft.world.level.WorldGenLevel)) { ++ blockEntity.setChanged(); ++ } ++ // Paper end - Fix NBT pieces overriding a block entity during worldgen deadlock + } + } + } +@@ -374,7 +_,7 @@ + + if (!settings.isIgnoreEntities()) { + this.placeEntities( +- serverLevel, ++ wrappedAccess, // CraftBukkit + offset, + settings.getMirror(), + settings.getRotation(), +@@ -491,11 +_,13 @@ + } + + private static Optional createEntityIgnoreException(ServerLevelAccessor level, CompoundTag tag) { +- try { +- return EntityType.create(tag, level.getLevel(), EntitySpawnReason.STRUCTURE); +- } catch (Exception var3) { +- return Optional.empty(); +- } ++ // CraftBukkit start ++ // try { ++ return EntityType.create(tag, level.getLevel(), EntitySpawnReason.STRUCTURE, true); // Paper - Don't fire sync event during generation ++ // } catch (Exception var3) { ++ // return Optional.empty(); ++ // } ++ // CraftBukkit end + } + + public Vec3i getSize(Rotation rotation) { +@@ -688,6 +_,11 @@ + + tag.put("entities", listTag3); + tag.put("size", this.newIntegerList(this.size.getX(), this.size.getY(), this.size.getZ())); ++ // CraftBukkit start - PDC ++ if (!this.persistentDataContainer.isEmpty()) { ++ tag.put("BukkitValues", this.persistentDataContainer.toTagCompound()); ++ } ++ // CraftBukkit end + return NbtUtils.addCurrentDataVersion(tag); + } + +@@ -720,6 +_,13 @@ + this.entityInfoList.add(new StructureTemplate.StructureEntityInfo(vec3, blockPos, compound1)); + } + } ++ ++ // CraftBukkit start - PDC ++ Tag base = tag.get("BukkitValues"); ++ if (base instanceof CompoundTag) { ++ this.persistentDataContainer.putAll((CompoundTag) base); ++ } ++ // CraftBukkit end + } + + private void loadPalette(HolderGetter blockGetter, ListTag paletteTag, ListTag blocksTag) { +@@ -828,7 +_,7 @@ + + public static final class Palette { + private final List blocks; +- private final Map> cache = Maps.newHashMap(); ++ private final Map> cache = Maps.newConcurrentMap(); // Paper - Fix CME due to this collection being shared across threads + @Nullable + private List cachedJigsaws; + diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch deleted file mode 100644 index 6bbbc67254..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch +++ /dev/null @@ -1,182 +0,0 @@ ---- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java -+++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java -@@ -25,6 +25,7 @@ - import net.minecraft.nbt.IntTag; - import net.minecraft.nbt.ListTag; - import net.minecraft.nbt.NbtUtils; -+import net.minecraft.nbt.Tag; - import net.minecraft.resources.ResourceLocation; - import net.minecraft.util.RandomSource; - import net.minecraft.world.Clearable; -@@ -55,6 +56,9 @@ - import net.minecraft.world.phys.Vec3; - import net.minecraft.world.phys.shapes.BitSetDiscreteVoxelShape; - import net.minecraft.world.phys.shapes.DiscreteVoxelShape; -+import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; -+import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; -+// CraftBukkit end - - public class StructureTemplate { - -@@ -74,6 +78,11 @@ - private Vec3i size; - private String author; - -+ // CraftBukkit start - data containers -+ private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); -+ public CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(StructureTemplate.DATA_TYPE_REGISTRY); -+ // CraftBukkit end -+ - public StructureTemplate() { - this.size = Vec3i.ZERO; - this.author = "?"; -@@ -147,7 +156,7 @@ - } - - private static List buildInfoList(List fullBlocks, List blocksWithNbt, List otherBlocks) { -- Comparator comparator = Comparator.comparingInt((definedstructure_blockinfo) -> { -+ Comparator comparator = Comparator.comparingInt((definedstructure_blockinfo) -> { // CraftBukkit - decompile error - return definedstructure_blockinfo.pos.getY(); - }).thenComparingInt((definedstructure_blockinfo) -> { - return definedstructure_blockinfo.pos.getX(); -@@ -253,6 +262,19 @@ - if (this.palettes.isEmpty()) { - return false; - } else { -+ // CraftBukkit start -+ // We only want the TransformerGeneratorAccess at certain locations because in here are many "block update" calls that shouldn't be transformed -+ ServerLevelAccessor wrappedAccess = world; -+ org.bukkit.craftbukkit.util.CraftStructureTransformer structureTransformer = null; -+ if (wrappedAccess instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) { -+ world = transformerAccess.getHandle(); -+ structureTransformer = transformerAccess.getStructureTransformer(); -+ // The structureTransformer is not needed if we can not transform blocks therefore we can save a little bit of performance doing this -+ if (structureTransformer != null && !structureTransformer.canTransformBlocks()) { -+ structureTransformer = null; -+ } -+ } -+ // CraftBukkit end - List list = placementData.getRandomPalette(this.palettes, pos).blocks(); - - if ((!list.isEmpty() || !placementData.isIgnoreEntities() && !this.entityInfoList.isEmpty()) && this.size.getX() >= 1 && this.size.getY() >= 1 && this.size.getZ() >= 1) { -@@ -281,9 +303,27 @@ - - if (definedstructure_blockinfo.nbt != null) { - tileentity = world.getBlockEntity(blockposition2); -- Clearable.tryClear(tileentity); -+ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock -+ if (!(world instanceof net.minecraft.world.level.WorldGenLevel)) { -+ Clearable.tryClear(tileentity); -+ } -+ // Paper end - Fix NBT pieces overriding a block entity during worldgen deadlock - world.setBlock(blockposition2, Blocks.BARRIER.defaultBlockState(), 20); - } -+ // CraftBukkit start -+ if (structureTransformer != null) { -+ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world, blockposition2, iblockdata, null); -+ if (definedstructure_blockinfo.nbt != null && craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState entityState) { -+ entityState.loadData(definedstructure_blockinfo.nbt); -+ if (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftLootable craftLootable) { -+ craftLootable.setSeed(random.nextLong()); -+ } -+ } -+ craftBlockState = structureTransformer.transformCraftState(craftBlockState); -+ iblockdata = craftBlockState.getHandle(); -+ definedstructure_blockinfo = new StructureTemplate.StructureBlockInfo(blockposition2, iblockdata, (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState craftBlockEntityState ? craftBlockEntityState.getSnapshotNBT() : null)); -+ } -+ // CraftBukkit end - - if (world.setBlock(blockposition2, iblockdata, flags)) { - j = Math.min(j, blockposition2.getX()); -@@ -296,7 +336,7 @@ - if (definedstructure_blockinfo.nbt != null) { - tileentity = world.getBlockEntity(blockposition2); - if (tileentity != null) { -- if (tileentity instanceof RandomizableContainer) { -+ if (structureTransformer == null && tileentity instanceof RandomizableContainer) { // CraftBukkit - only process if don't have a transformer access (Was already set above) - SPIGOT-7520: Use structureTransformer as check, so that it is the same as above - definedstructure_blockinfo.nbt.putLong("LootTableSeed", random.nextLong()); - } - -@@ -394,14 +434,18 @@ - if (pair1.getSecond() != null) { - tileentity = world.getBlockEntity(blockposition6); - if (tileentity != null) { -- tileentity.setChanged(); -+ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock -+ if (!(world instanceof net.minecraft.world.level.WorldGenLevel)) { -+ tileentity.setChanged(); -+ } -+ // Paper end - Fix NBT pieces overriding a block entity during worldgen deadlock - } - } - } - } - - if (!placementData.isIgnoreEntities()) { -- this.placeEntities(world, pos, placementData.getMirror(), placementData.getRotation(), placementData.getRotationPivot(), structureboundingbox, placementData.shouldFinalizeEntities()); -+ this.placeEntities(wrappedAccess, pos, placementData.getMirror(), placementData.getRotation(), placementData.getRotationPivot(), structureboundingbox, placementData.shouldFinalizeEntities()); // CraftBukkit - } - - return true; -@@ -503,11 +547,13 @@ - } - - private static Optional createEntityIgnoreException(ServerLevelAccessor world, CompoundTag nbt) { -- try { -- return EntityType.create(nbt, world.getLevel(), EntitySpawnReason.STRUCTURE); -- } catch (Exception exception) { -- return Optional.empty(); -- } -+ // CraftBukkit start -+ // try { -+ return EntityType.create(nbt, world.getLevel(), EntitySpawnReason.STRUCTURE, true); // Paper - Don't fire sync event during generation -+ // } catch (Exception exception) { -+ // return Optional.empty(); -+ // } -+ // CraftBukkit end - } - - public Vec3i getSize(Rotation rotation) { -@@ -721,6 +767,11 @@ - - nbt.put("entities", nbttaglist3); - nbt.put("size", this.newIntegerList(this.size.getX(), this.size.getY(), this.size.getZ())); -+ // CraftBukkit start - PDC -+ if (!this.persistentDataContainer.isEmpty()) { -+ nbt.put("BukkitValues", this.persistentDataContainer.toTagCompound()); -+ } -+ // CraftBukkit end - return NbtUtils.addCurrentDataVersion(nbt); - } - -@@ -760,6 +811,12 @@ - } - } - -+ // CraftBukkit start - PDC -+ Tag base = nbt.get("BukkitValues"); -+ if (base instanceof CompoundTag) { -+ this.persistentDataContainer.putAll((CompoundTag) base); -+ } -+ // CraftBukkit end - } - - private void loadPalette(HolderGetter blockLookup, ListTag palette, ListTag blocks) { -@@ -840,7 +897,7 @@ - public static final class Palette { - - private final List blocks; -- private final Map> cache = Maps.newHashMap(); -+ private final Map> cache = Maps.newConcurrentMap(); // Paper - Fix CME due to this collection being shared across threads - @Nullable - private List cachedJigsaws; - -@@ -924,7 +981,7 @@ - public BlockState stateFor(int id) { - BlockState iblockdata = (BlockState) this.ids.byId(id); - -- return iblockdata == null ? StructureTemplate.SimplePalette.DEFAULT_BLOCK_STATE : iblockdata; -+ return iblockdata == null ? SimplePalette.DEFAULT_BLOCK_STATE : iblockdata; // CraftBukkit - decompile error - } - - public Iterator iterator() {