diff options
Diffstat (limited to 'patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk')
11 files changed, 673 insertions, 0 deletions
diff --git a/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/ChunkAccess.java.patch b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/ChunkAccess.java.patch new file mode 100644 index 0000000000..ecc6a59334 --- /dev/null +++ b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/ChunkAccess.java.patch @@ -0,0 +1,102 @@ +--- a/net/minecraft/world/level/chunk/ChunkAccess.java ++++ b/net/minecraft/world/level/chunk/ChunkAccess.java +@@ -82,25 +82,34 @@ + protected final LevelHeightAccessor levelHeightAccessor; + protected final LevelChunkSection[] sections; + +- public ChunkAccess(ChunkPos chunkpos, UpgradeData upgradedata, LevelHeightAccessor levelheightaccessor, Registry<Biome> registry, long i, @Nullable LevelChunkSection[] alevelchunksection, @Nullable BlendingData blendingdata) { +- this.chunkPos = chunkpos; +- this.upgradeData = upgradedata; +- this.levelHeightAccessor = levelheightaccessor; +- this.sections = new LevelChunkSection[levelheightaccessor.getSectionsCount()]; +- this.inhabitedTime = i; +- this.postProcessing = new ShortList[levelheightaccessor.getSectionsCount()]; +- this.blendingData = blendingdata; +- this.skyLightSources = new ChunkSkyLightSources(levelheightaccessor); +- if (alevelchunksection != null) { +- if (this.sections.length == alevelchunksection.length) { +- System.arraycopy(alevelchunksection, 0, this.sections, 0, this.sections.length); ++ // 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; ++ this.sections = new LevelChunkSection[levelHeightAccessor.getSectionsCount()]; ++ this.inhabitedTime = inhabitedTime; ++ this.postProcessing = new ShortList[levelHeightAccessor.getSectionsCount()]; ++ this.blendingData = sections; ++ this.skyLightSources = new ChunkSkyLightSources(levelHeightAccessor); ++ if (achunksection != null) { ++ if (this.sections.length == achunksection.length) { ++ System.arraycopy(achunksection, 0, this.sections, 0, this.sections.length); + } else { + ChunkAccess.LOGGER.warn("Could not set level chunk sections, array length is {} instead of {}", alevelchunksection.length, this.sections.length); + } + } + +- replaceMissingSections(registry, this.sections); ++ replaceMissingSections(biomeRegistry, this.sections); ++ // CraftBukkit start ++ this.biomeRegistry = biomeRegistry; + } ++ public final Registry<Biome> biomeRegistry; ++ // CraftBukkit end + + private static void replaceMissingSections(Registry<Biome> registry, LevelChunkSection[] alevelchunksection) { + for (int i = 0; i < alevelchunksection.length; ++i) { +@@ -267,12 +270,13 @@ + return true; + } + +- public void setUnsaved(boolean flag) { +- this.unsaved = flag; ++ 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(); +@@ -445,12 +445,33 @@ + CrashReport crashreport = CrashReport.forThrowable(throwable, "Getting biome"); + CrashReportCategory crashreportcategory = crashreport.addCategory("Biome being got"); + +- crashreportcategory.setDetail("Location", () -> { ++ crashreportsystemdetails.setDetail("Location", () -> { ++ return CrashReportCategory.formatLocation(this, x, y, z); ++ }); ++ throw new ReportedException(crashreport); ++ } ++ } ++ ++ // 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 biomeresolver, Climate.Sampler climate_sampler) { + ChunkPos chunkpos = this.getPos(); diff --git a/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/ChunkGenerator.java.patch b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/ChunkGenerator.java.patch new file mode 100644 index 0000000000..5e896beacf --- /dev/null +++ b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/ChunkGenerator.java.patch @@ -0,0 +1,74 @@ +--- a/net/minecraft/world/level/chunk/ChunkGenerator.java ++++ b/net/minecraft/world/level/chunk/ChunkGenerator.java +@@ -307,8 +306,8 @@ + } + } + +- public void applyBiomeDecoration(WorldGenLevel worldgenlevel, ChunkAccess chunkaccess, StructureManager structuremanager) { +- ChunkPos chunkpos = chunkaccess.getPos(); ++ public void addVanillaDecorations(WorldGenLevel generatoraccessseed, ChunkAccess ichunkaccess, StructureManager structuremanager) { // CraftBukkit ++ ChunkPos chunkcoordintpair = ichunkaccess.getPos(); + + if (!SharedConstants.debugVoidTerrain(chunkpos)) { + SectionPos sectionpos = SectionPos.of(chunkpos, worldgenlevel.getMinSection()); +@@ -440,11 +439,38 @@ + } + } + +- private static BoundingBox getWritableArea(ChunkAccess chunkaccess) { +- ChunkPos chunkpos = chunkaccess.getPos(); +- int i = chunkpos.getMinBlockX(); +- int j = chunkpos.getMinBlockZ(); +- LevelHeightAccessor levelheightaccessor = chunkaccess.getHeightAccessorForGeneration(); ++ // 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 chunkcoordintpair = chunk.getPos(); ++ int i = chunkcoordintpair.getMinBlockX(); ++ int j = chunkcoordintpair.getMinBlockZ(); ++ LevelHeightAccessor levelheightaccessor = chunk.getHeightAccessorForGeneration(); + int k = levelheightaccessor.getMinBuildHeight() + 1; + int l = levelheightaccessor.getMaxBuildHeight() - 1; + +@@ -577,7 +603,15 @@ + StructureStart structurestart = structure.generate(registryaccess, this, this.biomeSource, randomstate, structuretemplatemanager, i, chunkpos, j, chunkaccess, predicate); + + if (structurestart.isValid()) { +- structuremanager.setStartForStructure(sectionpos, structure, structurestart, chunkaccess); ++ // 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-spigotflower-stripped/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java.patch b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java.patch new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java.patch @@ -0,0 +1 @@ + diff --git a/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/ChunkStatus.java.patch b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/ChunkStatus.java.patch new file mode 100644 index 0000000000..2e317e64ea --- /dev/null +++ b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/ChunkStatus.java.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/world/level/chunk/ChunkStatus.java ++++ b/net/minecraft/world/level/chunk/ChunkStatus.java +@@ -38,9 +38,9 @@ + }; + public static final ChunkStatus EMPTY = registerSimple("empty", (ChunkStatus) null, -1, ChunkStatus.PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, serverlevel, chunkgenerator, list, chunkaccess) -> { + }); +- public static final ChunkStatus STRUCTURE_STARTS = register("structure_starts", ChunkStatus.EMPTY, 0, false, ChunkStatus.PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, executor, serverlevel, chunkgenerator, structuretemplatemanager, threadedlevellightengine, function, list, chunkaccess) -> { +- if (serverlevel.getServer().getWorldData().worldGenOptions().generateStructures()) { +- chunkgenerator.createStructures(serverlevel.registryAccess(), serverlevel.getChunkSource().getGeneratorState(), serverlevel.structureManager(), chunkaccess, structuretemplatemanager); ++ 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); + } + + serverlevel.onStructureStartsAvailable(chunkaccess); diff --git a/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/DataLayer.java.patch b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/DataLayer.java.patch new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/DataLayer.java.patch @@ -0,0 +1 @@ + diff --git a/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/LevelChunk.java.patch b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/LevelChunk.java.patch new file mode 100644 index 0000000000..dc92d39044 --- /dev/null +++ b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/LevelChunk.java.patch @@ -0,0 +1,185 @@ +--- a/net/minecraft/world/level/chunk/LevelChunk.java ++++ b/net/minecraft/world/level/chunk/LevelChunk.java +@@ -78,8 +74,8 @@ + } + }; + private final Map<BlockPos, LevelChunk.RebindableTickingBlockEntityWrapper> tickersInLevel; +- private boolean loaded; +- final Level level; ++ public boolean loaded; ++ public final ServerLevel level; // CraftBukkit - type + @Nullable + private Supplier<FullChunkStatus> fullStatus; + @Nullable +@@ -95,7 +91,7 @@ + public LevelChunk(Level level, ChunkPos chunkpos, UpgradeData upgradedata, LevelChunkTicks<Block> levelchunkticks, LevelChunkTicks<Fluid> levelchunkticks1, long i, @Nullable LevelChunkSection[] alevelchunksection, @Nullable LevelChunk.PostLoadProcessor levelchunk_postloadprocessor, @Nullable BlendingData blendingdata) { + super(chunkpos, upgradedata, level, level.registryAccess().registryOrThrow(Registries.BIOME), i, alevelchunksection, blendingdata); + this.tickersInLevel = Maps.newHashMap(); +- this.level = level; ++ this.level = (ServerLevel) level; // CraftBukkit - type + this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap(); + Heightmap.Types[] aheightmap_types = Heightmap.Types.values(); + int j = aheightmap_types.length; +@@ -113,9 +109,10 @@ + this.fluidTicks = levelchunkticks1; + } + +- public LevelChunk(ServerLevel serverlevel, ProtoChunk protochunk, @Nullable LevelChunk.PostLoadProcessor levelchunk_postloadprocessor) { +- this(serverlevel, protochunk.getPos(), protochunk.getUpgradeData(), protochunk.unpackBlockTicks(), protochunk.unpackFluidTicks(), protochunk.getInhabitedTime(), protochunk.getSections(), levelchunk_postloadprocessor, protochunk.getBlendingData()); +- Iterator iterator = protochunk.getBlockEntities().values().iterator(); ++ // CraftBukkit start ++ public boolean mustNotSave; ++ public boolean needsDecoration; ++ // CraftBukkit end + + while (iterator.hasNext()) { + BlockEntity blockentity = (BlockEntity) iterator.next(); +@@ -144,6 +145,10 @@ + this.skyLightSources = protochunk.skyLightSources; + this.setLightCorrect(protochunk.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 +@@ -254,6 +253,7 @@ + } + } + ++ // CraftBukkit start + @Nullable + @Override + @Override +@@ -262,7 +260,14 @@ + LevelChunkSection levelchunksection = this.getSection(this.getSectionIndex(i)); + boolean flag1 = levelchunksection.hasOnlyAir(); + +- if (flag1 && blockstate.isAir()) { ++ @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 j = blockpos.getX() & 15; +@@ -306,8 +311,9 @@ + if (!levelchunksection.getBlockState(j, k, l).is(block)) { + return null; + } else { +- if (!this.level.isClientSide) { +- blockstate.onPlace(this.level, blockpos, blockstate1, flag); ++ // 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 (blockstate.hasBlockEntity()) { +@@ -352,8 +356,13 @@ + } + + @Nullable +- public BlockEntity getBlockEntity(BlockPos blockpos, LevelChunk.EntityCreationType levelchunk_entitycreationtype) { +- BlockEntity blockentity = (BlockEntity) this.blockEntities.get(blockpos); ++ 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 (blockentity == null) { + CompoundTag compoundtag = (CompoundTag) this.pendingBlockEntities.remove(blockpos); +@@ -432,6 +440,13 @@ + 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 + } + } + +@@ -463,8 +476,11 @@ + if (this.isInLevel()) { + BlockEntity blockentity = (BlockEntity) this.blockEntities.remove(blockpos); + +- if (blockentity != null) { +- Level level = this.level; ++ // CraftBukkit start - SPIGOT-5561: Also remove from pending map ++ if (!pendingBlockEntities.isEmpty()) { ++ pendingBlockEntities.remove(pos); ++ } ++ // CraftBukkit end + + if (level instanceof ServerLevel) { + ServerLevel serverlevel = (ServerLevel) level; +@@ -516,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-spigotflower-stripped/net/minecraft/world/level/chunk/LevelChunkSection.java.patch b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/LevelChunkSection.java.patch new file mode 100644 index 0000000000..87bf8fcc9d --- /dev/null +++ b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/LevelChunkSection.java.patch @@ -0,0 +1,37 @@ +--- a/net/minecraft/world/level/chunk/LevelChunkSection.java ++++ b/net/minecraft/world/level/chunk/LevelChunkSection.java +@@ -22,11 +22,13 @@ + 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> palettedcontainer, PalettedContainerRO<Holder<Biome>> palettedcontainerro) { +- this.states = palettedcontainer; ++ public LevelChunkSection(PalettedContainer<IBlockData> datapaletteblock, PalettedContainer<Holder<Biome>> palettedcontainerro) { ++ // CraftBukkit end ++ this.states = datapaletteblock; + this.biomes = palettedcontainerro; + this.recalcBlockCounts(); + } +@@ -189,8 +190,14 @@ + return (Holder) this.biomes.get(i, j, k); + } + +- public void fillBiomesFromNoise(BiomeResolver biomeresolver, Climate.Sampler climate_sampler, int i, int j, int k) { +- PalettedContainer<Holder<Biome>> palettedcontainer = this.biomes.recreate(); ++ // 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>> datapaletteblock = this.biomes.recreate(); + boolean flag = true; + + for (int l = 0; l < 4; ++l) { diff --git a/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/storage/ChunkSerializer.java.patch b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/storage/ChunkSerializer.java.patch new file mode 100644 index 0000000000..1f6ebd7010 --- /dev/null +++ b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/storage/ChunkSerializer.java.patch @@ -0,0 +1,94 @@ +--- a/net/minecraft/world/level/chunk/storage/ChunkSerializer.java ++++ b/net/minecraft/world/level/chunk/storage/ChunkSerializer.java +@@ -93,16 +93,16 @@ + ChunkSerializer.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", new Object[]{chunkpos, chunkpos, chunkpos1}); + } + +- UpgradeData upgradedata = compoundtag.contains("UpgradeData", 10) ? new UpgradeData(compoundtag.getCompound("UpgradeData"), serverlevel) : UpgradeData.EMPTY; +- boolean flag = compoundtag.getBoolean("isLightOn"); +- ListTag listtag = compoundtag.getList("sections", 10); +- int i = serverlevel.getSectionsCount(); +- LevelChunkSection[] alevelchunksection = new LevelChunkSection[i]; +- boolean flag1 = serverlevel.dimensionType().hasSkyLight(); +- ServerChunkCache serverchunkcache = serverlevel.getChunkSource(); +- LevelLightEngine levellightengine = serverchunkcache.getLightEngine(); +- Registry<Biome> registry = serverlevel.registryAccess().registryOrThrow(Registries.BIOME); +- Codec<PalettedContainerRO<Holder<Biome>>> codec = makeBiomeCodec(registry); ++ 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; + + DataResult dataresult; +@@ -127,7 +127,7 @@ + palettedcontainer = new PalettedContainer<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES); + } + +- Object object; ++ PalettedContainer object; // CraftBukkit - read/write + + if (compoundtag1.contains("biomes", 10)) { + dataresult = codec.parse(NbtOps.INSTANCE, compoundtag1.getCompound("biomes")).promotePartial((s) -> { +@@ -140,7 +140,7 @@ + object = new PalettedContainer<>(registry.asHolderIdMap(), registry.getHolderOrThrow(Biomes.PLAINS), PalettedContainer.Strategy.SECTION_BIOMES); + } + +- LevelChunkSection levelchunksection = new LevelChunkSection(palettedcontainer, (PalettedContainerRO) object); ++ LevelChunkSection chunksection = new LevelChunkSection(datapaletteblock, (PalettedContainer) object); // CraftBukkit - read/write + + alevelchunksection[k] = levelchunksection; + SectionPos sectionpos = SectionPos.of(chunkpos, b0); +@@ -221,6 +221,13 @@ + } + } + ++ // 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 ++ + ((ChunkAccess) object1).setLightCorrect(flag); + CompoundTag compoundtag2 = compoundtag.getCompound("Heightmaps"); + EnumSet<Heightmap.Types> enumset = EnumSet.noneOf(Heightmap.Types.class); +@@ -300,9 +307,11 @@ + return PalettedContainer.codecRO(registry.asHolderIdMap(), registry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, registry.getHolderOrThrow(Biomes.PLAINS)); + } + +- public static CompoundTag write(ServerLevel serverlevel, ChunkAccess chunkaccess) { +- ChunkPos chunkpos = chunkaccess.getPos(); +- CompoundTag compoundtag = NbtUtils.addCurrentDataVersion(new CompoundTag()); ++ // 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 + + compoundtag.putInt("xPos", chunkpos.x); + compoundtag.putInt("yPos", chunkaccess.getMinSection()); +@@ -439,9 +452,14 @@ + } + } + +- compoundtag.put("Heightmaps", compoundtag3); +- compoundtag.put("structures", packStructureData(StructurePieceSerializationContext.fromLevel(serverlevel), chunkpos, chunkaccess.getAllStarts(), chunkaccess.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 serverlevel, CompoundTag compoundtag, ChunkAccess.TicksToSave chunkaccess_tickstosave) { diff --git a/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch new file mode 100644 index 0000000000..b8f6e2e997 --- /dev/null +++ b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch @@ -0,0 +1,91 @@ +--- 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; + +@@ -36,9 +42,53 @@ + return this.worker.isOldChunkAround(chunkpos, i); + } + +- public CompoundTag upgradeChunkTag(ResourceKey<Level> resourcekey, Supplier<DimensionDataStorage> supplier, CompoundTag compoundtag, Optional<ResourceKey<Codec<? extends ChunkGenerator>>> optional) { +- int i = getVersion(compoundtag); ++ // 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; ++ } ++ } + ++ CompoundTag nbt; ++ try { ++ nbt = read(pos).get().orElse(null); ++ } catch (InterruptedException | ExecutionException ex) { ++ throw new RuntimeException(ex); ++ } ++ if (nbt != null) { ++ CompoundTag level = nbt.getCompound("Level"); ++ if (level.getBoolean("TerrainPopulated")) { ++ return true; ++ } ++ ++ ChunkStatus status = ChunkStatus.byName(level.getString("Status")); ++ if (status != null && status.isOrAfter(ChunkStatus.FEATURES)) { ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ ++ 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) { + compoundtag = DataFixTypes.CHUNK.update(this.fixerUpper, compoundtag, i, 1493); + if (compoundtag.getCompound("Level").getBoolean("hasLegacyStructureData")) { +@@ -58,8 +108,8 @@ + return compoundtag; + } + +- private LegacyStructureDataHandler getLegacyStructureHandler(ResourceKey<Level> resourcekey, Supplier<DimensionDataStorage> supplier) { +- LegacyStructureDataHandler legacystructuredatahandler = this.legacyStructureHandler; ++ private LegacyStructureDataHandler getLegacyStructureHandler(ResourceKey<LevelStem> level, Supplier<DimensionDataStorage> storage) { // CraftBukkit ++ LegacyStructureDataHandler persistentstructurelegacy = this.legacyStructureHandler; + + if (legacystructuredatahandler == null) { + synchronized (this) { +@@ -73,8 +123,8 @@ + return legacystructuredatahandler; + } + +- public static void injectDatafixingContext(CompoundTag compoundtag, ResourceKey<Level> resourcekey, Optional<ResourceKey<Codec<? extends ChunkGenerator>>> optional) { +- CompoundTag compoundtag1 = new CompoundTag(); ++ public static void injectDatafixingContext(CompoundTag chunkData, ResourceKey<LevelStem> levelKey, Optional<ResourceKey<Codec<? extends ChunkGenerator>>> chunkGeneratorKey) { // CraftBukkit ++ CompoundTag nbttagcompound1 = new CompoundTag(); + + compoundtag1.putString("dimension", resourcekey.location().toString()); + optional.ifPresent((resourcekey1) -> { diff --git a/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/storage/RegionFile.java.patch b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/storage/RegionFile.java.patch new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/storage/RegionFile.java.patch @@ -0,0 +1 @@ + diff --git a/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/storage/RegionFileStorage.java.patch b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/storage/RegionFileStorage.java.patch new file mode 100644 index 0000000000..ce9acb3765 --- /dev/null +++ b/patch-remap/mache-spigotflower-stripped/net/minecraft/world/level/chunk/storage/RegionFileStorage.java.patch @@ -0,0 +1,72 @@ +--- a/net/minecraft/world/level/chunk/storage/RegionFileStorage.java ++++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java +@@ -30,8 +30,8 @@ + this.sync = flag; + } + +- private RegionFile getRegionFile(ChunkPos chunkpos) throws IOException { +- long i = ChunkPos.asLong(chunkpos.getRegionX(), chunkpos.getRegionZ()); ++ 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) { +@@ -43,8 +43,9 @@ + + FileUtil.createDirectoriesSafe(this.folder); + Path path = this.folder; +- int j = chunkpos.getRegionX(); +- Path path1 = path.resolve("r." + j + "." + chunkpos.getRegionZ() + ".mca"); ++ 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); +@@ -53,9 +54,14 @@ + } + + @Nullable +- public CompoundTag read(ChunkPos chunkpos) throws IOException { +- RegionFile regionfile = this.getRegionFile(chunkpos); +- DataInputStream datainputstream = regionfile.getChunkDataInputStream(chunkpos); ++ public CompoundTag read(ChunkPos chunkPos) throws IOException { ++ // 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 compoundtag; + label43: +@@ -93,9 +99,14 @@ + return compoundtag; + } + +- public void scanChunk(ChunkPos chunkpos, StreamTagVisitor streamtagvisitor) throws IOException { +- RegionFile regionfile = this.getRegionFile(chunkpos); +- DataInputStream datainputstream = regionfile.getChunkDataInputStream(chunkpos); ++ public void scanChunk(ChunkPos chunkPos, StreamTagVisitor visitor) throws IOException { ++ // 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 { + if (datainputstream != null) { +@@ -119,8 +130,8 @@ + + } + +- protected void write(ChunkPos chunkpos, @Nullable CompoundTag compoundtag) throws IOException { +- RegionFile regionfile = this.getRegionFile(chunkpos); ++ protected void write(ChunkPos chunkPos, @Nullable CompoundTag chunkData) throws IOException { ++ RegionFile regionfile = this.getRegionFile(chunkPos, false); // CraftBukkit + + if (compoundtag == null) { + regionfile.clear(chunkpos); |