diff options
author | MiniDigger | Martin <[email protected]> | 2024-01-14 11:04:49 +0100 |
---|---|---|
committer | MiniDigger | Martin <[email protected]> | 2024-01-14 11:04:49 +0100 |
commit | bee74680e607c2e29b038329f62181238911cd83 (patch) | |
tree | 708fd1a4a0227d9071243adf2a42d5e9e96cde4a /patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk | |
parent | 0a44692ef6ff6e255d48eb3ba1bb114166eafda9 (diff) | |
download | Paper-softspoon.tar.gz Paper-softspoon.zip |
add remapped patches as a testsoftspoon
Diffstat (limited to 'patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk')
11 files changed, 783 insertions, 0 deletions
diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/ChunkAccess.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/ChunkAccess.java.patch new file mode 100644 index 0000000000..b8de6931b4 --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/ChunkAccess.java.patch @@ -0,0 +1,77 @@ +--- a/net/minecraft/world/level/chunk/ChunkAccess.java ++++ b/net/minecraft/world/level/chunk/ChunkAccess.java +@@ -80,15 +82,12 @@ + protected final LevelHeightAccessor levelHeightAccessor; + protected final LevelChunkSection[] sections; + +- public ChunkAccess( +- ChunkPos chunkPos, +- UpgradeData upgradeData, +- LevelHeightAccessor levelHeightAccessor, +- Registry<Biome> biomeRegistry, +- long inhabitedTime, +- @Nullable LevelChunkSection[] sections, +- @Nullable BlendingData blendingData +- ) { ++ // CraftBukkit start - SPIGOT-6814: move to IChunkAccess to account for 1.17 to 1.18 chunk upgrading. ++ 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(DATA_TYPE_REGISTRY); ++ // CraftBukkit end ++ ++ public ChunkAccess(ChunkPos chunkPos, UpgradeData upgradeData, LevelHeightAccessor levelHeightAccessor, Registry<Biome> biomeRegistry, long inhabitedTime, @Nullable LevelChunkSection[] achunksection, @Nullable BlendingData sections) { + this.chunkPos = chunkPos; + this.upgradeData = upgradeData; + this.levelHeightAccessor = levelHeightAccessor; +@@ -106,7 +105,11 @@ + } + + replaceMissingSections(biomeRegistry, this.sections); ++ // CraftBukkit start ++ this.biomeRegistry = biomeRegistry; + } ++ public final Registry<Biome> biomeRegistry; ++ // CraftBukkit end + + private static void replaceMissingSections(Registry<Biome> biomeRegistry, LevelChunkSection[] sections) { + for (int i = 0; i < sections.length; i++) { +@@ -263,10 +272,11 @@ + + public void setUnsaved(boolean unsaved) { + this.unsaved = unsaved; ++ if (!unsaved) this.persistentDataContainer.dirty(false); // CraftBukkit - SPIGOT-6814: chunk was saved, pdc is no longer dirty + } + + public boolean isUnsaved() { +- return this.unsaved; ++ return this.unsaved || this.persistentDataContainer.dirty(); // CraftBukkit - SPIGOT-6814: chunk is unsaved if pdc was mutated + } + + public abstract ChunkStatus getStatus(); +@@ -430,6 +452,27 @@ + } + } + ++ // CraftBukkit start ++ public void setBiome(int i, int j, int k, Holder<Biome> biome) { ++ try { ++ int l = QuartPos.fromBlock(this.getMinBuildHeight()); ++ int i1 = l + QuartPos.fromBlock(this.getHeight()) - 1; ++ int j1 = Mth.clamp(j, l, i1); ++ int k1 = this.getSectionIndex(QuartPos.toBlock(j1)); ++ ++ this.sections[k1].setBiome(i & 3, j1 & 3, k & 3, biome); ++ } catch (Throwable throwable) { ++ CrashReport crashreport = CrashReport.forThrowable(throwable, "Setting biome"); ++ CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Biome being set"); ++ ++ crashreportsystemdetails.setDetail("Location", () -> { ++ return CrashReportCategory.formatLocation(this, i, j, k); ++ }); ++ throw new ReportedException(crashreport); ++ } ++ } ++ // CraftBukkit end ++ + public void fillBiomesFromNoise(BiomeResolver resolver, Climate.Sampler sampler) { + ChunkPos pos = this.getPos(); + int i = QuartPos.fromBlock(pos.getMinBlockX()); diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/ChunkGenerator.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/ChunkGenerator.java.patch new file mode 100644 index 0000000000..6e1646322f --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/ChunkGenerator.java.patch @@ -0,0 +1,104 @@ +--- a/net/minecraft/world/level/chunk/ChunkGenerator.java ++++ b/net/minecraft/world/level/chunk/ChunkGenerator.java +@@ -314,19 +306,8 @@ + } + } + +- public void applyBiomeDecoration(WorldGenLevel level, ChunkAccess chunk, StructureManager structureManager) { +- ChunkPos pos = chunk.getPos(); +- if (!SharedConstants.debugVoidTerrain(pos)) { +- SectionPos sectionPos = SectionPos.of(pos, level.getMinSection()); +- BlockPos blockPos = sectionPos.origin(); +- Registry<Structure> registry = level.registryAccess().registryOrThrow(Registries.STRUCTURE); +- Map<Integer, List<Structure>> map = registry.stream().collect(Collectors.groupingBy(structure1 -> structure1.step().ordinal())); +- List<FeatureSorter.StepFeatureData> list = this.featuresPerStep.get(); +- WorldgenRandom worldgenRandom = new WorldgenRandom(new XoroshiroRandomSource(RandomSupport.generateUniqueSeed())); +- long l = worldgenRandom.setDecorationSeed(level.getSeed(), blockPos.getX(), blockPos.getZ()); +- Set<Holder<Biome>> set = new ObjectArraySet<>(); +- ChunkPos.rangeClosed(sectionPos.chunk(), 1).forEach(chunkPos -> { +- ChunkAccess chunk1 = level.getChunk(chunkPos.x, chunkPos.z); ++ public void addVanillaDecorations(WorldGenLevel generatoraccessseed, ChunkAccess ichunkaccess, StructureManager structuremanager) { // CraftBukkit ++ ChunkPos chunkcoordintpair = ichunkaccess.getPos(); + + for (LevelChunkSection levelChunkSection : chunk1.getSections()) { + levelChunkSection.getBiomes().getAll(set::add); +@@ -410,6 +439,33 @@ + } + } + ++ // CraftBukkit start ++ public void applyBiomeDecoration(WorldGenLevel level, ChunkAccess chunk, StructureManager structureManager) { ++ applyBiomeDecoration(level, chunk, structureManager, true); ++ } ++ ++ public void applyBiomeDecoration(WorldGenLevel generatoraccessseed, ChunkAccess ichunkaccess, StructureManager structuremanager, boolean vanilla) { ++ if (vanilla) { ++ addVanillaDecorations(generatoraccessseed, ichunkaccess, structuremanager); ++ } ++ ++ org.bukkit.World world = generatoraccessseed.getMinecraftWorld().getWorld(); ++ // only call when a populator is present (prevents unnecessary entity conversion) ++ if (!world.getPopulators().isEmpty()) { ++ org.bukkit.craftbukkit.generator.CraftLimitedRegion limitedRegion = new org.bukkit.craftbukkit.generator.CraftLimitedRegion(generatoraccessseed, ichunkaccess.getPos()); ++ int x = ichunkaccess.getPos().x; ++ int z = ichunkaccess.getPos().z; ++ for (org.bukkit.generator.BlockPopulator populator : world.getPopulators()) { ++ WorldgenRandom seededrandom = new WorldgenRandom(new net.minecraft.world.level.levelgen.LegacyRandomSource(generatoraccessseed.getSeed())); ++ seededrandom.setDecorationSeed(generatoraccessseed.getSeed(), x, z); ++ populator.populate(world, new org.bukkit.craftbukkit.util.RandomSourceWrapper.RandomWrapper(seededrandom), x, z, limitedRegion); ++ } ++ limitedRegion.saveEntities(); ++ limitedRegion.breakLink(); ++ } ++ } ++ // CraftBukkit end ++ + private static BoundingBox getWritableArea(ChunkAccess chunk) { + ChunkPos pos = chunk.getPos(); + int minBlockX = pos.getMinBlockX(); +@@ -545,26 +593,25 @@ + ); + } + +- private boolean tryGenerateStructure( +- StructureSet.StructureSelectionEntry structureSelectionEntry, +- StructureManager structureManager, +- RegistryAccess registryAccess, +- RandomState random, +- StructureTemplateManager structureTemplateManager, +- long seed, +- ChunkAccess chunk, +- ChunkPos chunkPos, +- SectionPos sectionPos +- ) { +- Structure structure = structureSelectionEntry.structure().value(); +- int i = fetchReferences(structureManager, chunk, sectionPos, structure); +- HolderSet<Biome> holderSet = structure.biomes(); +- Predicate<Holder<Biome>> predicate = holderSet::contains; +- StructureStart structureStart = structure.generate( +- registryAccess, this, this.biomeSource, random, structureTemplateManager, seed, chunkPos, i, chunk, predicate +- ); +- if (structureStart.isValid()) { +- structureManager.setStartForStructure(sectionPos, structure, structureStart, chunk); ++ private boolean tryGenerateStructure(StructureSet.a structureSelectionEntry, StructureManager structureManager, RegistryAccess registryAccess, RandomState random, StructureTemplateManager structureTemplateManager, long seed, ChunkAccess ichunkaccess, ChunkPos chunk, SectionPos chunkPos) { ++ Structure structure = (Structure) structureSelectionEntry.structure().value(); ++ int j = fetchReferences(structureManager, ichunkaccess, chunkPos, structure); ++ HolderSet<Biome> holderset = structure.biomes(); ++ ++ Objects.requireNonNull(holderset); ++ Predicate<Holder<Biome>> predicate = holderset::contains; ++ StructureStart structurestart = structure.generate(registryAccess, this, this.biomeSource, random, structureTemplateManager, seed, chunk, j, ichunkaccess, predicate); ++ ++ if (structurestart.isValid()) { ++ // CraftBukkit start ++ BoundingBox box = structurestart.getBoundingBox(); ++ org.bukkit.event.world.AsyncStructureSpawnEvent event = new org.bukkit.event.world.AsyncStructureSpawnEvent(structureManager.level.getMinecraftWorld().getWorld(), org.bukkit.craftbukkit.generator.structure.CraftStructure.minecraftToBukkit(structure, registryAccess), new org.bukkit.util.BoundingBox(box.minX(), box.minY(), box.minZ(), box.maxX(), box.maxY(), box.maxZ()), chunk.x, chunk.z); ++ org.bukkit.Bukkit.getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ return true; ++ } ++ // CraftBukkit end ++ structureManager.setStartForStructure(chunkPos, structure, structurestart, ichunkaccess); + return true; + } else { + return false; diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java.patch new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java.patch @@ -0,0 +1 @@ + diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/ChunkStatus.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/ChunkStatus.java.patch new file mode 100644 index 0000000000..0127726c74 --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/ChunkStatus.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/world/level/chunk/ChunkStatus.java ++++ b/net/minecraft/world/level/chunk/ChunkStatus.java +@@ -31,14 +32,15 @@ + public class ChunkStatus { + public static final int MAX_STRUCTURE_DISTANCE = 8; + private static final EnumSet<Heightmap.Types> PRE_FEATURES = EnumSet.of(Heightmap.Types.OCEAN_FLOOR_WG, Heightmap.Types.WORLD_SURFACE_WG); +- public static final EnumSet<Heightmap.Types> POST_FEATURES = EnumSet.of( +- Heightmap.Types.OCEAN_FLOOR, Heightmap.Types.WORLD_SURFACE, Heightmap.Types.MOTION_BLOCKING, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES +- ); +- private static final ChunkStatus.LoadingTask PASSTHROUGH_LOAD_TASK = (status, level, structureTemplateManager, lightEngine, task, chunk) -> CompletableFuture.completedFuture( +- Either.left(chunk) +- ); +- public static final ChunkStatus EMPTY = registerSimple( +- "empty", null, -1, PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (status, level, chunkGenerator, neighboringChunks, loadingChunk) -> { ++ public static final EnumSet<Heightmap.Types> POST_FEATURES = EnumSet.of(Heightmap.Types.OCEAN_FLOOR, Heightmap.Types.WORLD_SURFACE, Heightmap.Types.MOTION_BLOCKING, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES); ++ private static final ChunkStatus.LoadingTask PASSTHROUGH_LOAD_TASK = (chunkstatus, worldserver, structuretemplatemanager, lightenginethreaded, function, ichunkaccess) -> { ++ return CompletableFuture.completedFuture(Either.left(ichunkaccess)); ++ }; ++ public static final ChunkStatus EMPTY = registerSimple("empty", (ChunkStatus) null, -1, ChunkStatus.PRE_FEATURES, ChunkStatus.Type.PROTOCHUNK, (chunkstatus, worldserver, chunkgenerator, list, ichunkaccess) -> { ++ }); ++ public static final ChunkStatus STRUCTURE_STARTS = register("structure_starts", ChunkStatus.EMPTY, 0, false, ChunkStatus.PRE_FEATURES, ChunkStatus.Type.PROTOCHUNK, (chunkstatus, executor, worldserver, chunkgenerator, structuretemplatemanager, lightenginethreaded, function, list, ichunkaccess) -> { ++ if (worldserver.serverLevelData.worldGenOptions().generateStructures()) { // CraftBukkit ++ chunkgenerator.createStructures(worldserver.registryAccess(), worldserver.getChunkSource().getGeneratorState(), worldserver.structureManager(), ichunkaccess, structuretemplatemanager); + } + ); + public static final ChunkStatus STRUCTURE_STARTS = register( diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/DataLayer.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/DataLayer.java.patch new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/DataLayer.java.patch @@ -0,0 +1 @@ + diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/LevelChunk.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/LevelChunk.java.patch new file mode 100644 index 0000000000..5cda59a305 --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/LevelChunk.java.patch @@ -0,0 +1,235 @@ +--- a/net/minecraft/world/level/chunk/LevelChunk.java ++++ b/net/minecraft/world/level/chunk/LevelChunk.java +@@ -70,9 +73,9 @@ + return "<null>"; + } + }; +- private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel = Maps.newHashMap(); +- private boolean loaded; +- final Level level; ++ private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel; ++ public boolean loaded; ++ public final ServerLevel level; // CraftBukkit - type + @Nullable + private Supplier<FullChunkStatus> fullStatus; + @Nullable +@@ -85,20 +88,13 @@ + this(level, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, null, null, null); + } + +- public LevelChunk( +- Level level, +- ChunkPos pos, +- UpgradeData data, +- LevelChunkTicks<Block> blockTicks, +- LevelChunkTicks<Fluid> fluidTicks, +- long inhabitedTime, +- @Nullable LevelChunkSection[] sections, +- @Nullable LevelChunk.PostLoadProcessor postLoad, +- @Nullable BlendingData blendingData +- ) { +- super(pos, data, level, level.registryAccess().registryOrThrow(Registries.BIOME), inhabitedTime, sections, blendingData); +- this.level = level; +- this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap<>(); ++ public LevelChunk(Level level, ChunkPos pos, UpgradeData data, LevelChunkTicks<Block> blockTicks, LevelChunkTicks<Fluid> fluidTicks, long inhabitedTime, @Nullable LevelChunkSection[] achunksection, @Nullable LevelChunk.PostLoadProcessor sections, @Nullable BlendingData postLoad) { ++ super(pos, data, level, level.registryAccess().registryOrThrow(Registries.BIOME), inhabitedTime, achunksection, postLoad); ++ this.tickersInLevel = Maps.newHashMap(); ++ this.level = (ServerLevel) level; // CraftBukkit - type ++ this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap(); ++ Heightmap.Types[] aheightmap_type = Heightmap.Types.values(); ++ int j = aheightmap_type.length; + + for (Heightmap.Types types : Heightmap.Types.values()) { + if (ChunkStatus.FULL.heightmapsAfter().contains(types)) { +@@ -111,6 +109,11 @@ + this.fluidTicks = fluidTicks; + } + ++ // CraftBukkit start ++ public boolean mustNotSave; ++ public boolean needsDecoration; ++ // CraftBukkit end ++ + public LevelChunk(ServerLevel level, ProtoChunk chunk, @Nullable LevelChunk.PostLoadProcessor postLoad) { + this( + level, +@@ -146,6 +145,10 @@ + this.skyLightSources = chunk.skyLightSources; + this.setLightCorrect(chunk.isLightCorrect()); + this.unsaved = true; ++ this.needsDecoration = true; // CraftBukkit ++ // CraftBukkit start ++ this.persistentDataContainer = chunk.persistentDataContainer; // SPIGOT-6814: copy PDC to account for 1.17 to 1.18 chunk upgrading. ++ // CraftBukkit end + } + + @Override +@@ -231,13 +253,21 @@ + } + } + ++ // CraftBukkit start + @Nullable + @Override +- public BlockState setBlockState(BlockPos pos, BlockState state, boolean isMoving) { +- int y = pos.getY(); +- LevelChunkSection section = this.getSection(this.getSectionIndex(y)); +- boolean hasOnlyAir = section.hasOnlyAir(); +- if (hasOnlyAir && state.isAir()) { ++ public IBlockData setBlockState(BlockPos pos, IBlockData state, boolean isMoving) { ++ return this.setBlockState(pos, state, isMoving, true); ++ } ++ ++ @Nullable ++ public IBlockData setBlockState(BlockPos blockposition, IBlockData iblockdata, boolean flag, boolean doPlace) { ++ // CraftBukkit end ++ int i = blockposition.getY(); ++ LevelChunkSection chunksection = this.getSection(this.getSectionIndex(i)); ++ boolean flag1 = chunksection.hasOnlyAir(); ++ ++ if (flag1 && iblockdata.isAir()) { + return null; + } else { + int i = pos.getX() & 15; +@@ -276,8 +311,9 @@ + if (!section.getBlockState(i, i1, i2).is(block)) { + return null; + } else { +- if (!this.level.isClientSide) { +- state.onPlace(this.level, pos, blockState, isMoving); ++ // CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer. Prevents blocks such as TNT from activating when cancelled. ++ if (!this.level.isClientSide && doPlace && (!this.level.captureBlockStates || block instanceof net.minecraft.world.level.block.BaseEntityBlock)) { ++ iblockdata.onPlace(this.level, blockposition, iblockdata1, flag); + } + + if (state.hasBlockEntity()) { +@@ -318,14 +356,22 @@ + } + + @Nullable +- public BlockEntity getBlockEntity(BlockPos pos, LevelChunk.EntityCreationType creationType) { +- BlockEntity blockEntity = this.blockEntities.get(pos); +- if (blockEntity == null) { +- CompoundTag compoundTag = this.pendingBlockEntities.remove(pos); +- if (compoundTag != null) { +- BlockEntity blockEntity1 = this.promotePendingBlockEntity(pos, compoundTag); +- if (blockEntity1 != null) { +- return blockEntity1; ++ public BlockEntity getBlockEntity(BlockPos pos, LevelChunk.EnumTileEntityState creationType) { ++ // CraftBukkit start ++ BlockEntity tileentity = level.capturedTileEntities.get(pos); ++ if (tileentity == null) { ++ tileentity = (BlockEntity) this.blockEntities.get(pos); ++ } ++ // CraftBukkit end ++ ++ if (tileentity == null) { ++ CompoundTag nbttagcompound = (CompoundTag) this.pendingBlockEntities.remove(pos); ++ ++ if (nbttagcompound != null) { ++ BlockEntity tileentity1 = this.promotePendingBlockEntity(pos, nbttagcompound); ++ ++ if (tileentity1 != null) { ++ return tileentity1; + } + } + } +@@ -378,6 +439,14 @@ + if (blockEntity1 != null && blockEntity1 != blockEntity) { + blockEntity1.setRemoved(); + } ++ ++ // CraftBukkit start ++ } else { ++ System.out.println("Attempted to place a tile entity (" + blockEntity + ") at " + blockEntity.getBlockPos().getX() + "," + blockEntity.getBlockPos().getY() + "," + blockEntity.getBlockPos().getZ() ++ + " (" + getBlockState(blockposition) + ") where there was no entity tile!"); ++ System.out.println("Chunk coordinates: " + (this.chunkPos.x * 16) + "," + (this.chunkPos.z * 16)); ++ new Exception().printStackTrace(); ++ // CraftBukkit end + } + } + +@@ -403,10 +474,21 @@ + @Override + public void removeBlockEntity(BlockPos pos) { + if (this.isInLevel()) { +- BlockEntity blockEntity = this.blockEntities.remove(pos); +- if (blockEntity != null) { +- if (this.level instanceof ServerLevel serverLevel) { +- this.removeGameEventListener(blockEntity, serverLevel); ++ BlockEntity tileentity = (BlockEntity) this.blockEntities.remove(pos); ++ ++ // CraftBukkit start - SPIGOT-5561: Also remove from pending map ++ if (!pendingBlockEntities.isEmpty()) { ++ pendingBlockEntities.remove(pos); ++ } ++ // CraftBukkit end ++ ++ if (tileentity != null) { ++ Level world = this.level; ++ ++ if (world instanceof ServerLevel) { ++ ServerLevel worldserver = (ServerLevel) world; ++ ++ this.removeGameEventListener(tileentity, worldserver); + } + + blockEntity.setRemoved(); +@@ -446,6 +535,57 @@ + } + } + ++ // CraftBukkit start ++ public void loadCallback() { ++ org.bukkit.Server server = this.level.getCraftServer(); ++ if (server != null) { ++ /* ++ * If it's a new world, the first few chunks are generated inside ++ * the World constructor. We can't reliably alter that, so we have ++ * no way of creating a CraftWorld/CraftServer at that point. ++ */ ++ org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); ++ server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(bukkitChunk, this.needsDecoration)); ++ ++ if (this.needsDecoration) { ++ this.needsDecoration = false; ++ java.util.Random random = new java.util.Random(); ++ random.setSeed(level.getSeed()); ++ long xRand = random.nextLong() / 2L * 2L + 1L; ++ long zRand = random.nextLong() / 2L * 2L + 1L; ++ random.setSeed((long) this.chunkPos.x * xRand + (long) this.chunkPos.z * zRand ^ level.getSeed()); ++ ++ org.bukkit.World world = this.level.getWorld(); ++ if (world != null) { ++ this.level.populating = true; ++ try { ++ for (org.bukkit.generator.BlockPopulator populator : world.getPopulators()) { ++ populator.populate(world, random, bukkitChunk); ++ } ++ } finally { ++ this.level.populating = false; ++ } ++ } ++ server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk)); ++ } ++ } ++ } ++ ++ public void unloadCallback() { ++ org.bukkit.Server server = this.level.getCraftServer(); ++ org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); ++ org.bukkit.event.world.ChunkUnloadEvent unloadEvent = new org.bukkit.event.world.ChunkUnloadEvent(bukkitChunk, this.isUnsaved()); ++ server.getPluginManager().callEvent(unloadEvent); ++ // note: saving can be prevented, but not forced if no saving is actually required ++ this.mustNotSave = !unloadEvent.isSaveChunk(); ++ } ++ ++ @Override ++ public boolean isUnsaved() { ++ return super.isUnsaved() && !this.mustNotSave; ++ } ++ // CraftBukkit end ++ + public boolean isEmpty() { + return false; + } diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/LevelChunkSection.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/LevelChunkSection.java.patch new file mode 100644 index 0000000000..704eb84a2a --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/LevelChunkSection.java.patch @@ -0,0 +1,35 @@ +--- a/net/minecraft/world/level/chunk/LevelChunkSection.java ++++ b/net/minecraft/world/level/chunk/LevelChunkSection.java +@@ -21,12 +22,14 @@ + private short nonEmptyBlockCount; + private short tickingBlockCount; + private short tickingFluidCount; +- private final PalettedContainer<BlockState> states; +- private PalettedContainerRO<Holder<Biome>> biomes; ++ private final PalettedContainer<IBlockData> states; ++ // CraftBukkit start - read/write ++ private PalettedContainer<Holder<Biome>> biomes; + +- public LevelChunkSection(PalettedContainer<BlockState> states, PalettedContainerRO<Holder<Biome>> biomes) { +- this.states = states; +- this.biomes = biomes; ++ public LevelChunkSection(PalettedContainer<IBlockData> datapaletteblock, PalettedContainer<Holder<Biome>> palettedcontainerro) { ++ // CraftBukkit end ++ this.states = datapaletteblock; ++ this.biomes = palettedcontainerro; + this.recalcBlockCounts(); + } + +@@ -180,6 +190,12 @@ + return this.biomes.get(x, y, z); + } + ++ // CraftBukkit start ++ public void setBiome(int i, int j, int k, Holder<Biome> biome) { ++ this.biomes.set(i, j, k, biome); ++ } ++ // CraftBukkit end ++ + public void fillBiomesFromNoise(BiomeResolver biomeResolver, Climate.Sampler climateSampler, int x, int y, int z) { + PalettedContainer<Holder<Biome>> palettedContainer = this.biomes.recreate(); + int i = 4; diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/storage/ChunkSerializer.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/storage/ChunkSerializer.java.patch new file mode 100644 index 0000000000..13e6943d3a --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/storage/ChunkSerializer.java.patch @@ -0,0 +1,117 @@ +--- a/net/minecraft/world/level/chunk/storage/ChunkSerializer.java ++++ b/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +@@ -86,17 +93,17 @@ + LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", pos, pos, chunkPos); + } + +- UpgradeData upgradeData = tag.contains("UpgradeData", 10) ? new UpgradeData(tag.getCompound("UpgradeData"), level) : UpgradeData.EMPTY; +- boolean _boolean = tag.getBoolean("isLightOn"); +- ListTag list = tag.getList("sections", 10); +- int sectionsCount = level.getSectionsCount(); +- LevelChunkSection[] levelChunkSections = new LevelChunkSection[sectionsCount]; +- boolean hasSkyLight = level.dimensionType().hasSkyLight(); +- ChunkSource chunkSource = level.getChunkSource(); +- LevelLightEngine lightEngine = chunkSource.getLightEngine(); +- Registry<Biome> registry = level.registryAccess().registryOrThrow(Registries.BIOME); +- Codec<PalettedContainerRO<Holder<Biome>>> codec = makeBiomeCodec(registry); +- boolean flag = false; ++ UpgradeData chunkconverter = tag.contains("UpgradeData", 10) ? new UpgradeData(tag.getCompound("UpgradeData"), level) : UpgradeData.EMPTY; ++ boolean flag = tag.getBoolean("isLightOn"); ++ ListTag nbttaglist = tag.getList("sections", 10); ++ int i = level.getSectionsCount(); ++ LevelChunkSection[] achunksection = new LevelChunkSection[i]; ++ boolean flag1 = level.dimensionType().hasSkyLight(); ++ ServerChunkCache chunkproviderserver = level.getChunkSource(); ++ LevelLightEngine levellightengine = chunkproviderserver.getLightEngine(); ++ Registry<Biome> iregistry = level.registryAccess().registryOrThrow(Registries.BIOME); ++ Codec<PalettedContainer<Holder<Biome>>> codec = makeBiomeCodecRW(iregistry); // CraftBukkit - read/write ++ boolean flag2 = false; + + for (int i = 0; i < list.size(); i++) { + CompoundTag compound = list.getCompound(i); +@@ -114,21 +127,27 @@ + ); + } + +- PalettedContainerRO<Holder<Biome>> palettedContainerRO; +- if (compound.contains("biomes", 10)) { +- palettedContainerRO = codec.parse(NbtOps.INSTANCE, compound.getCompound("biomes")) +- .promotePartial(errorMessage -> logErrors(pos, _byte, errorMessage)) +- .getOrThrow(false, LOGGER::error); ++ PalettedContainer object; // CraftBukkit - read/write ++ ++ if (nbttagcompound1.contains("biomes", 10)) { ++ dataresult = codec.parse(NbtOps.INSTANCE, nbttagcompound1.getCompound("biomes")).promotePartial((s) -> { ++ logErrors(pos, b0, s); ++ }); ++ logger = ChunkSerializer.LOGGER; ++ Objects.requireNonNull(logger); ++ object = ((DataResult<PalettedContainer<Holder<Biome>>>) dataresult).getOrThrow(false, logger::error); // CraftBukkit - decompile error + } else { + palettedContainerRO = new PalettedContainer<>( + registry.asHolderIdMap(), registry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES + ); + } + +- LevelChunkSection levelChunkSection = new LevelChunkSection(palettedContainer, palettedContainerRO); +- levelChunkSections[sectionIndexFromSectionY] = levelChunkSection; +- SectionPos sectionPos = SectionPos.of(pos, _byte); +- poiManager.checkConsistencyWithBlocks(sectionPos, levelChunkSection); ++ LevelChunkSection chunksection = new LevelChunkSection(datapaletteblock, (PalettedContainer) object); // CraftBukkit - read/write ++ ++ achunksection[k] = chunksection; ++ SectionPos sectionposition = SectionPos.of(pos, b0); ++ ++ poiManager.checkConsistencyWithBlocks(sectionposition, chunksection); + } + + boolean flag1 = compound.contains("BlockLight", 7); +@@ -196,9 +221,12 @@ + } + } + +- chunkAccess.setLightCorrect(_boolean); +- CompoundTag compound1 = tag.getCompound("Heightmaps"); +- EnumSet<Heightmap.Types> set = EnumSet.noneOf(Heightmap.Types.class); ++ // CraftBukkit start - load chunk persistent data from nbt - SPIGOT-6814: Already load PDC here to account for 1.17 to 1.18 chunk upgrading. ++ net.minecraft.nbt.Tag persistentBase = tag.get("ChunkBukkitValues"); ++ if (persistentBase instanceof CompoundTag) { ++ ((ChunkAccess) object1).persistentDataContainer.putAll((CompoundTag) persistentBase); ++ } ++ // CraftBukkit end + + for (Heightmap.Types types : chunkAccess.getStatus().heightmapsAfter()) { + String serializationKey = types.getSerializationKey(); +@@ -268,6 +307,12 @@ + ); + } + ++ // CraftBukkit start - read/write ++ private static Codec<PalettedContainer<Holder<Biome>>> makeBiomeCodecRW(Registry<Biome> iregistry) { ++ return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getHolderOrThrow(Biomes.PLAINS)); ++ } ++ // CraftBukkit end ++ + public static CompoundTag write(ServerLevel level, ChunkAccess chunk) { + ChunkPos pos = chunk.getPos(); + CompoundTag compoundTag = NbtUtils.addCurrentDataVersion(new CompoundTag()); +@@ -377,11 +452,14 @@ + } + } + +- compoundTag.put("Heightmaps", compoundTag2); +- compoundTag.put( +- "structures", packStructureData(StructurePieceSerializationContext.fromLevel(level), pos, chunk.getAllStarts(), chunk.getAllReferences()) +- ); +- return compoundTag; ++ nbttagcompound.put("Heightmaps", nbttagcompound3); ++ nbttagcompound.put("structures", packStructureData(StructurePieceSerializationContext.fromLevel(level), chunkcoordintpair, chunk.getAllStarts(), chunk.getAllReferences())); ++ // CraftBukkit start - store chunk persistent data in nbt ++ if (!chunk.persistentDataContainer.isEmpty()) { // SPIGOT-6814: Always save PDC to account for 1.17 to 1.18 chunk upgrading. ++ nbttagcompound.put("ChunkBukkitValues", chunk.persistentDataContainer.toTagCompound()); ++ } ++ // CraftBukkit end ++ return nbttagcompound; + } + + private static void saveTicks(ServerLevel level, CompoundTag tag, ChunkAccess.TicksToSave ticksToSave) { diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch new file mode 100644 index 0000000000..71479e6a9a --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch @@ -0,0 +1,110 @@ +--- a/net/minecraft/world/level/chunk/storage/ChunkStorage.java ++++ b/net/minecraft/world/level/chunk/storage/ChunkStorage.java +@@ -16,6 +18,10 @@ + import net.minecraft.world.level.ChunkPos; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.chunk.ChunkGenerator; ++// CraftBukkit start ++import java.util.concurrent.ExecutionException; ++import net.minecraft.world.level.chunk.ChunkStatus; ++import net.minecraft.world.level.dimension.LevelStem; + import net.minecraft.world.level.levelgen.structure.LegacyStructureDataHandler; + import net.minecraft.world.level.storage.DimensionDataStorage; + +@@ -35,18 +42,13 @@ + return this.worker.isOldChunkAround(pos, radius); + } + +- public CompoundTag upgradeChunkTag( +- ResourceKey<Level> levelKey, +- Supplier<DimensionDataStorage> storage, +- CompoundTag chunkData, +- Optional<ResourceKey<Codec<? extends ChunkGenerator>>> chunkGeneratorKey +- ) { +- int version = getVersion(chunkData); +- if (version < 1493) { +- chunkData = DataFixTypes.CHUNK.update(this.fixerUpper, chunkData, version, 1493); +- if (chunkData.getCompound("Level").getBoolean("hasLegacyStructureData")) { +- LegacyStructureDataHandler legacyStructureHandler = this.getLegacyStructureHandler(levelKey, storage); +- chunkData = legacyStructureHandler.updateFromLegacy(chunkData); ++ // CraftBukkit start ++ private boolean check(ServerChunkCache cps, int x, int z) { ++ ChunkPos pos = new ChunkPos(x, z); ++ if (cps != null) { ++ com.google.common.base.Preconditions.checkState(org.bukkit.Bukkit.isPrimaryThread(), "primary thread"); ++ if (cps.hasChunk(x, z)) { ++ return true; + } + } + +@@ -60,9 +73,45 @@ + return var7; + } + +- private LegacyStructureDataHandler getLegacyStructureHandler(ResourceKey<Level> level, Supplier<DimensionDataStorage> storage) { +- LegacyStructureDataHandler legacyStructureDataHandler = this.legacyStructureHandler; +- if (legacyStructureDataHandler == null) { ++ public CompoundTag upgradeChunkTag(ResourceKey<LevelStem> resourcekey, Supplier<DimensionDataStorage> supplier, CompoundTag nbttagcompound, Optional<ResourceKey<Codec<? extends ChunkGenerator>>> optional, ChunkPos pos, @Nullable LevelAccessor generatoraccess) { ++ // CraftBukkit end ++ int i = getVersion(nbttagcompound); ++ ++ // CraftBukkit start ++ if (i < 1466) { ++ CompoundTag level = nbttagcompound.getCompound("Level"); ++ if (level.getBoolean("TerrainPopulated") && !level.getBoolean("LightPopulated")) { ++ ServerChunkCache cps = (generatoraccess == null) ? null : ((ServerLevel) generatoraccess).getChunkSource(); ++ if (check(cps, pos.x - 1, pos.z) && check(cps, pos.x - 1, pos.z - 1) && check(cps, pos.x, pos.z - 1)) { ++ level.putBoolean("LightPopulated", true); ++ } ++ } ++ } ++ // CraftBukkit end ++ ++ if (i < 1493) { ++ nbttagcompound = DataFixTypes.CHUNK.update(this.fixerUpper, nbttagcompound, i, 1493); ++ if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) { ++ LegacyStructureDataHandler persistentstructurelegacy = this.getLegacyStructureHandler(resourcekey, supplier); ++ ++ nbttagcompound = persistentstructurelegacy.updateFromLegacy(nbttagcompound); ++ } ++ } ++ ++ injectDatafixingContext(nbttagcompound, resourcekey, optional); ++ nbttagcompound = DataFixTypes.CHUNK.updateToCurrentVersion(this.fixerUpper, nbttagcompound, Math.max(1493, i)); ++ if (i < SharedConstants.getCurrentVersion().getDataVersion().getVersion()) { ++ NbtUtils.addCurrentDataVersion(nbttagcompound); ++ } ++ ++ nbttagcompound.remove("__context"); ++ return nbttagcompound; ++ } ++ ++ private LegacyStructureDataHandler getLegacyStructureHandler(ResourceKey<LevelStem> level, Supplier<DimensionDataStorage> storage) { // CraftBukkit ++ LegacyStructureDataHandler persistentstructurelegacy = this.legacyStructureHandler; ++ ++ if (persistentstructurelegacy == null) { + synchronized (this) { + legacyStructureDataHandler = this.legacyStructureHandler; + if (legacyStructureDataHandler == null) { +@@ -74,13 +123,14 @@ + return legacyStructureDataHandler; + } + +- public static void injectDatafixingContext( +- CompoundTag chunkData, ResourceKey<Level> levelKey, Optional<ResourceKey<Codec<? extends ChunkGenerator>>> chunkGeneratorKey +- ) { +- CompoundTag compoundTag = new CompoundTag(); +- compoundTag.putString("dimension", levelKey.location().toString()); +- chunkGeneratorKey.ifPresent(generator -> compoundTag.putString("generator", generator.location().toString())); +- chunkData.put("__context", compoundTag); ++ public static void injectDatafixingContext(CompoundTag chunkData, ResourceKey<LevelStem> levelKey, Optional<ResourceKey<Codec<? extends ChunkGenerator>>> chunkGeneratorKey) { // CraftBukkit ++ CompoundTag nbttagcompound1 = new CompoundTag(); ++ ++ nbttagcompound1.putString("dimension", levelKey.location().toString()); ++ chunkGeneratorKey.ifPresent((resourcekey1) -> { ++ nbttagcompound1.putString("generator", resourcekey1.location().toString()); ++ }); ++ chunkData.put("__context", nbttagcompound1); + } + + public static int getVersion(CompoundTag chunkData) { diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/storage/RegionFile.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/storage/RegionFile.java.patch new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/storage/RegionFile.java.patch @@ -0,0 +1 @@ + diff --git a/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/storage/RegionFileStorage.java.patch b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/storage/RegionFileStorage.java.patch new file mode 100644 index 0000000000..637d17ecdc --- /dev/null +++ b/patch-remap/mache-vineflower-stripped/net/minecraft/world/level/chunk/storage/RegionFileStorage.java.patch @@ -0,0 +1,76 @@ +--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java ++++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java +@@ -26,27 +30,38 @@ + this.sync = sync; + } + +- private RegionFile getRegionFile(ChunkPos chunkPos) throws IOException { +- long _long = ChunkPos.asLong(chunkPos.getRegionX(), chunkPos.getRegionZ()); +- RegionFile regionFile = this.regionCache.getAndMoveToFirst(_long); +- if (regionFile != null) { +- return regionFile; ++ private RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit ++ long i = ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()); ++ RegionFile regionfile = (RegionFile) this.regionCache.getAndMoveToFirst(i); ++ ++ if (regionfile != null) { ++ return regionfile; + } else { + if (this.regionCache.size() >= 256) { + this.regionCache.removeLast().close(); + } + + FileUtil.createDirectoriesSafe(this.folder); +- Path path = this.folder.resolve("r." + chunkPos.getRegionX() + "." + chunkPos.getRegionZ() + ".mca"); +- RegionFile regionFile1 = new RegionFile(path, this.folder, this.sync); +- this.regionCache.putAndMoveToFirst(_long, regionFile1); +- return regionFile1; ++ Path path = this.folder; ++ int j = chunkcoordintpair.getRegionX(); ++ Path path1 = path.resolve("r." + j + "." + chunkcoordintpair.getRegionZ() + ".mca"); ++ if (existingOnly && !java.nio.file.Files.exists(path1)) return null; // CraftBukkit ++ RegionFile regionfile1 = new RegionFile(path1, this.folder, this.sync); ++ ++ this.regionCache.putAndMoveToFirst(i, regionfile1); ++ return regionfile1; + } + } + + @Nullable + public CompoundTag read(ChunkPos chunkPos) throws IOException { +- RegionFile regionFile = this.getRegionFile(chunkPos); ++ // CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing ++ RegionFile regionfile = this.getRegionFile(chunkPos, true); ++ if (regionfile == null) { ++ return null; ++ } ++ // CraftBukkit end ++ DataInputStream datainputstream = regionfile.getChunkDataInputStream(chunkPos); + + CompoundTag var4; + try (DataInputStream chunkDataInputStream = regionFile.getChunkDataInputStream(chunkPos)) { +@@ -61,7 +100,13 @@ + } + + public void scanChunk(ChunkPos chunkPos, StreamTagVisitor visitor) throws IOException { +- RegionFile regionFile = this.getRegionFile(chunkPos); ++ // CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing ++ RegionFile regionfile = this.getRegionFile(chunkPos, true); ++ if (regionfile == null) { ++ return; ++ } ++ // CraftBukkit end ++ DataInputStream datainputstream = regionfile.getChunkDataInputStream(chunkPos); + + try (DataInputStream chunkDataInputStream = regionFile.getChunkDataInputStream(chunkPos)) { + if (chunkDataInputStream != null) { +@@ -71,7 +131,8 @@ + } + + protected void write(ChunkPos chunkPos, @Nullable CompoundTag chunkData) throws IOException { +- RegionFile regionFile = this.getRegionFile(chunkPos); ++ RegionFile regionfile = this.getRegionFile(chunkPos, false); // CraftBukkit ++ + if (chunkData == null) { + regionFile.clear(chunkPos); + } else { |