mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-26 22:40:21 +01:00
/net/minecraft/world/level/levelgen/structure/templatesystem
This commit is contained in:
parent
14f6b329a5
commit
6002fbc152
3 changed files with 178 additions and 192 deletions
|
@ -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<StructureProcessor> processors;
|
||||
private final List<StructureProcessor> 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));
|
||||
}
|
|
@ -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;
|
||||
|
|
@ -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<StructureTemplate.StructureBlockInfo> buildInfoList(List<StructureTemplate.StructureBlockInfo> fullBlocks, List<StructureTemplate.StructureBlockInfo> blocksWithNbt, List<StructureTemplate.StructureBlockInfo> otherBlocks) {
|
||||
- Comparator<StructureTemplate.StructureBlockInfo> comparator = Comparator.comparingInt((definedstructure_blockinfo) -> {
|
||||
+ Comparator<StructureTemplate.StructureBlockInfo> comparator = Comparator.<StructureTemplate.StructureBlockInfo>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<StructureTemplate.StructureBlockInfo> 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<Entity> 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<Block> blockLookup, ListTag palette, ListTag blocks) {
|
||||
@@ -840,7 +897,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;
|
||||
|
||||
@@ -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<BlockState> iterator() {
|
Loading…
Reference in a new issue