/net/minecraft/world/level/levelgen/structure/templatesystem

This commit is contained in:
Shane Freeder
2024-12-14 15:41:30 +00:00
parent 14f6b329a5
commit 6002fbc152
3 changed files with 178 additions and 192 deletions

View File

@@ -0,0 +1,25 @@
--- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructurePlaceSettings.java
+++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructurePlaceSettings.java
@@ -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<StructureProcessor> processors = Lists.newArrayList();
private boolean knownShape;
private boolean finalizeEntities;
@@ -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 >= size) {
+ throw new IllegalArgumentException("Palette index out of bounds. Got " + this.palette + " where there are only " + size + " palettes available.");
+ }
+ return palettes.get(this.palette);
+ // CraftBukkit end
} else {
return palettes.get(this.getRandom(pos).nextInt(size));
}

View File

@@ -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<StructureTemplate.StructureEntityInfo> 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<StructureTemplate.StructureBlockInfo> 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<Entity> 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<Block> blockGetter, ListTag paletteTag, ListTag blocksTag) {
@@ -828,7 +_,7 @@
public static final class Palette {
private final List<StructureTemplate.StructureBlockInfo> blocks;
- private final Map<Block, List<StructureTemplate.StructureBlockInfo>> cache = Maps.newHashMap();
+ private final Map<Block, List<StructureTemplate.StructureBlockInfo>> cache = Maps.newConcurrentMap(); // Paper - Fix CME due to this collection being shared across threads
@Nullable
private List<StructureTemplate.JigsawBlockInfo> cachedJigsaws;