From ccabae4fb6156f88aa7cfdd82ae948d1ab0d076f Mon Sep 17 00:00:00 2001 From: Jason <11360596+jpenilla@users.noreply.github.com> Date: Sun, 5 Dec 2021 02:27:20 -0800 Subject: [PATCH] Update and deprecate Allow delegation to vanilla chunk gen (#7031) --- build-data/paper.at | 1 - ...low-delegation-to-vanilla-chunk-gen.patch} | 24 +-- ...llow-delegation-to-vanilla-chunk-gen.patch | 67 -------- ...llow-delegation-to-vanilla-chunk-gen.patch | 146 ++++++++++++++++++ 4 files changed, 160 insertions(+), 78 deletions(-) rename patches/{removed/1.18/0215-Allow-delegation-to-vanilla-chunk-gen.patch => api/0345-Allow-delegation-to-vanilla-chunk-gen.patch} (76%) delete mode 100644 patches/removed/1.18/0464-Allow-delegation-to-vanilla-chunk-gen.patch create mode 100644 patches/server/0824-Allow-delegation-to-vanilla-chunk-gen.patch diff --git a/build-data/paper.at b/build-data/paper.at index 3bd1667cc3..f18d4fd87a 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -143,7 +143,6 @@ public net.minecraft.world.entity.Entity isInBubbleColumn()Z # Allow delegation to vanilla chunk gen public org.bukkit.craftbukkit.generator.CustomChunkGenerator delegate -private-f org.bukkit.craftbukkit.generator.CraftChunkData sections # Optimize redstone algorithm public net.minecraft.world.level.block.RedStoneWireBlock shouldSignal diff --git a/patches/removed/1.18/0215-Allow-delegation-to-vanilla-chunk-gen.patch b/patches/api/0345-Allow-delegation-to-vanilla-chunk-gen.patch similarity index 76% rename from patches/removed/1.18/0215-Allow-delegation-to-vanilla-chunk-gen.patch rename to patches/api/0345-Allow-delegation-to-vanilla-chunk-gen.patch index accb0d324e..3929720576 100644 --- a/patches/removed/1.18/0215-Allow-delegation-to-vanilla-chunk-gen.patch +++ b/patches/api/0345-Allow-delegation-to-vanilla-chunk-gen.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Allow delegation to vanilla chunk gen diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 338f0938fbae7eec6cecaf3f1cd30d3e27ad40d6..dc0ceb725aebcce9d048b53e06d4fa84bb3afbe1 100644 +index eb0aa2a2a9def0270341ee15d8a7a0629a67a823..b7c45aa5d5f79fd16e59401acfa9c2bed0a5d78c 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -1634,6 +1634,22 @@ public final class Bukkit { +@@ -1697,6 +1697,24 @@ public final class Bukkit { return server.createChunkData(world); } - + + // Paper start + /** + * Create a ChunkData for use in a generator, that is populated by the vanilla generator for that world @@ -20,9 +20,11 @@ index 338f0938fbae7eec6cecaf3f1cd30d3e27ad40d6..dc0ceb725aebcce9d048b53e06d4fa84 + * @param x the x coordinate of the chunk + * @param z the z coordinate of the chunk + * @return a new ChunkData for the world -+ * ++ * @deprecated The new multi-stage worldgen API allows a similar effect by overriding all of the "shouldGenerate..." methods to ++ * return true, and then modifying the chunkdata in a later stage such as surface or bedrock generation. + */ + @NotNull ++ @Deprecated(forRemoval = true) + public static ChunkGenerator.ChunkData createVanillaChunkData(@NotNull World world, int x, int z) { + return server.createVanillaChunkData(world, x, z); + } @@ -32,24 +34,26 @@ index 338f0938fbae7eec6cecaf3f1cd30d3e27ad40d6..dc0ceb725aebcce9d048b53e06d4fa84 * Creates a boss bar instance to display to players. The progress * defaults to 1.0 diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 5a98eaeafafc11a7f925701187fc96eb5c675efe..b47eb644b35d27eb5ff65a2ff62e451d23e8026b 100644 +index 395b0706bfbf03741df6ca1ff084618b91140acc..6996a61534bbdd34729f1dcd988ae2666bfad2c4 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -1383,6 +1383,20 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -1422,6 +1422,22 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi @NotNull public ChunkGenerator.ChunkData createChunkData(@NotNull World world); - + + // Paper start + /** -+ * Create a ChunkData for use in a generator, that is populated by the vanilla generator for that world ++ * Create a ChunkData for use in a generator, that is populated by the vanilla generator for that world. + * + * @param world the world to create the ChunkData for + * @param x the x coordinate of the chunk + * @param z the z coordinate of the chunk + * @return a new ChunkData for the world -+ * ++ * @deprecated The new multi-stage worldgen API allows a similar effect by overriding all of the "shouldGenerate..." methods to ++ * return true, and then modifying the chunkdata in a later stage such as surface or bedrock generation. + */ + @NotNull ++ @Deprecated(forRemoval = true) + ChunkGenerator.ChunkData createVanillaChunkData(@NotNull World world, int x, int z); + // Paper end + @@ -63,7 +67,7 @@ index 80fcd02e9cb5f432f21b1f68fd8266f296becaa0..0667315e2bd10254aef59c2a6bcceee9 @@ -454,6 +454,22 @@ public abstract class ChunkGenerator { return false; } - + + // Paper start + /** + * Create a ChunkData for use in a generator, that is populated by the vanilla generator for that world diff --git a/patches/removed/1.18/0464-Allow-delegation-to-vanilla-chunk-gen.patch b/patches/removed/1.18/0464-Allow-delegation-to-vanilla-chunk-gen.patch deleted file mode 100644 index 4fb384e93e..0000000000 --- a/patches/removed/1.18/0464-Allow-delegation-to-vanilla-chunk-gen.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MiniDigger -Date: Wed, 29 Apr 2020 02:10:32 +0200 -Subject: [PATCH] Allow delegation to vanilla chunk gen - - -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index b1dfd1b13652807882e057ae4fb55f9a045d1a16..926ecc79744142c1361399afa61719db435638fa 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2244,6 +2244,32 @@ public final class CraftServer implements Server { - return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY)); - } - -+ // Paper start -+ @Override -+ public ChunkGenerator.ChunkData createVanillaChunkData(World world, int x, int z) { -+ // get empty object -+ OldCraftChunkData data = (OldCraftChunkData) createChunkData(world); -+ // do bunch of vanilla shit -+ net.minecraft.server.level.ServerLevel nmsWorld = ((CraftWorld) world).getHandle(); -+ net.minecraft.world.level.chunk.ProtoChunk protoChunk = new net.minecraft.world.level.chunk.ProtoChunk(new net.minecraft.world.level.ChunkPos(x, z), null, nmsWorld, nmsWorld); -+ List list = new ArrayList<>(); -+ list.add(protoChunk); -+ net.minecraft.server.level.WorldGenRegion genRegion = new net.minecraft.server.level.WorldGenRegion(nmsWorld, list, net.minecraft.world.level.chunk.ChunkStatus.EMPTY, -1); -+ // call vanilla generator, one feature after another. Order here is important! -+ net.minecraft.world.level.chunk.ChunkGenerator chunkGenerator = nmsWorld.getChunkSource().generator; -+ if (chunkGenerator instanceof org.bukkit.craftbukkit.generator.CustomChunkGenerator) { -+ chunkGenerator = ((org.bukkit.craftbukkit.generator.CustomChunkGenerator) chunkGenerator).delegate; -+ } -+ chunkGenerator.createBiomes(nmsWorld.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), protoChunk); -+ chunkGenerator.fillFromNoise((runnable) -> {}, nmsWorld.structureFeatureManager(), protoChunk); -+ chunkGenerator.buildSurfaceAndBedrock(genRegion, protoChunk); -+ // copy over generated sections -+ data.setRawChunkData(protoChunk.getSections()); -+ // hooray! -+ return data; -+ } -+ // Paper end -+ - @Override - public BossBar createBossBar(String title, BarColor color, BarStyle style, BarFlag... flags) { - return new CraftBossBar(title, color, style, flags); -diff --git a/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java b/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java -index 960405935e395a31c0300773c41413801cf0d290..f86a8619862c752ca5d47a2ce4c2d0fab6f0810d 100644 ---- a/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java -+++ b/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java -@@ -23,7 +23,7 @@ import org.bukkit.material.MaterialData; - public final class OldCraftChunkData implements ChunkGenerator.ChunkData { - private final int minHeight; - private final int maxHeight; -- private final LevelChunkSection[] sections; -+ private LevelChunkSection[] sections; - private final Registry biomes; - private Set tiles; - private final Set lights = new HashSet<>(); -@@ -192,4 +192,10 @@ public final class OldCraftChunkData implements ChunkGenerator.ChunkData { - Set getLights() { - return this.lights; - } -+ -+ // Paper start -+ public void setRawChunkData(LevelChunkSection[] sections) { -+ this.sections = sections; -+ } -+ // Paper end - } diff --git a/patches/server/0824-Allow-delegation-to-vanilla-chunk-gen.patch b/patches/server/0824-Allow-delegation-to-vanilla-chunk-gen.patch new file mode 100644 index 0000000000..b3d9977a49 --- /dev/null +++ b/patches/server/0824-Allow-delegation-to-vanilla-chunk-gen.patch @@ -0,0 +1,146 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MiniDigger +Date: Wed, 29 Apr 2020 02:10:32 +0200 +Subject: [PATCH] Allow delegation to vanilla chunk gen + + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 02e25451737841001363f4697fd05b1e2c6240cd..d91abf93f2a06f73d3124f4fcff2491fe8d36655 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -2287,6 +2287,107 @@ public final class CraftServer implements Server { + return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), world); // Paper - Anti-Xray - Add parameters + } + ++ // Paper start ++ private static final List VANILLA_GEN_STATUSES = List.of( ++ net.minecraft.world.level.chunk.ChunkStatus.EMPTY, ++ net.minecraft.world.level.chunk.ChunkStatus.STRUCTURE_STARTS, ++ net.minecraft.world.level.chunk.ChunkStatus.STRUCTURE_REFERENCES, ++ net.minecraft.world.level.chunk.ChunkStatus.BIOMES, ++ net.minecraft.world.level.chunk.ChunkStatus.NOISE, ++ net.minecraft.world.level.chunk.ChunkStatus.SURFACE, ++ net.minecraft.world.level.chunk.ChunkStatus.CARVERS, ++ net.minecraft.world.level.chunk.ChunkStatus.LIQUID_CARVERS, ++ net.minecraft.world.level.chunk.ChunkStatus.FEATURES, ++ net.minecraft.world.level.chunk.ChunkStatus.LIGHT ++ ); ++ ++ @net.minecraft.MethodsReturnNonnullByDefault ++ private static final class PaperEmptyLevelChunk extends net.minecraft.world.level.chunk.EmptyLevelChunk { ++ private final net.minecraft.world.level.biome.Biome biome; ++ ++ public PaperEmptyLevelChunk(net.minecraft.world.level.Level world, net.minecraft.world.level.ChunkPos pos) { ++ super(world, pos); ++ this.biome = this.level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); ++ } ++ ++ @Override ++ public net.minecraft.world.level.biome.Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ) { ++ return this.biome; ++ } ++ ++ @Override ++ public void markPosForPostprocessing(BlockPos pos) {} ++ } ++ ++ @Override ++ @Deprecated(forRemoval = true) ++ public ChunkGenerator.ChunkData createVanillaChunkData(World world, int x, int z) { ++ // do bunch of vanilla shit ++ final net.minecraft.server.level.ServerLevel serverLevel = ((CraftWorld) world).getHandle(); ++ final Registry biomeRegistry = serverLevel.getServer().registryAccess().registryOrThrow(Registry.BIOME_REGISTRY); ++ final net.minecraft.world.level.chunk.ProtoChunk protoChunk = new net.minecraft.world.level.chunk.ProtoChunk( ++ new net.minecraft.world.level.ChunkPos(x, z), ++ net.minecraft.world.level.chunk.UpgradeData.EMPTY, ++ serverLevel, ++ biomeRegistry, ++ null ++ ); ++ ++ final net.minecraft.world.level.chunk.ChunkGenerator chunkGenerator; ++ if (serverLevel.chunkSource.getGenerator() instanceof org.bukkit.craftbukkit.generator.CustomChunkGenerator bukkit) { ++ chunkGenerator = bukkit.delegate; ++ } else { ++ chunkGenerator = serverLevel.chunkSource.getGenerator(); ++ } ++ ++ final net.minecraft.world.level.ChunkPos chunkPos = new net.minecraft.world.level.ChunkPos(x, z); ++ final net.minecraft.util.thread.ProcessorMailbox mailbox = net.minecraft.util.thread.ProcessorMailbox.create( ++ net.minecraft.Util.backgroundExecutor(), ++ "CraftServer#createVanillaChunkData(worldName='" + world.getName() + "', x='" + x + "', z='" + z + "')" ++ ); ++ for (final net.minecraft.world.level.chunk.ChunkStatus chunkStatus : VANILLA_GEN_STATUSES) { ++ final List chunks = Lists.newArrayList(); ++ final int statusRange = Math.max(1, chunkStatus.getRange()); ++ ++ for (int zz = chunkPos.z - statusRange; zz <= chunkPos.z + statusRange; ++zz) { ++ for (int xx = chunkPos.x - statusRange; xx <= chunkPos.x + statusRange; ++xx) { ++ if (xx == chunkPos.x && zz == chunkPos.z) { ++ chunks.add(protoChunk); ++ } else { ++ final net.minecraft.world.level.chunk.ChunkAccess chunk = new PaperEmptyLevelChunk(serverLevel, new net.minecraft.world.level.ChunkPos(xx, zz)); ++ chunks.add(chunk); ++ } ++ } ++ } ++ ++ chunkStatus.generate( ++ mailbox::tell, ++ serverLevel, ++ chunkGenerator, ++ serverLevel.getStructureManager(), ++ serverLevel.chunkSource.getLightEngine(), ++ chunk -> { ++ throw new UnsupportedOperationException("Not creating full chunks here"); ++ }, ++ chunks, ++ true ++ ).thenAccept(either -> { ++ if (chunkStatus == net.minecraft.world.level.chunk.ChunkStatus.NOISE) { ++ either.left().ifPresent(chunk -> net.minecraft.world.level.levelgen.Heightmap.primeHeightmaps(chunk, net.minecraft.world.level.chunk.ChunkStatus.POST_FEATURES)); ++ } ++ }).join(); ++ } ++ ++ // get empty object ++ OldCraftChunkData data = (OldCraftChunkData) this.createChunkData(world); ++ // copy over generated sections ++ data.getLights().addAll(protoChunk.getLights().toList()); ++ data.setRawChunkData(protoChunk.getSections()); ++ // hooray! ++ return data; ++ } ++ // Paper end ++ + @Override + public BossBar createBossBar(String title, BarColor color, BarStyle style, BarFlag... flags) { + return new CraftBossBar(title, color, style, flags); +diff --git a/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java b/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java +index 6f6bf950cd15b34031618782c82824cf0b191ff8..8d8c7d84a76b11e14ee252e93349d495eec77957 100644 +--- a/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java ++++ b/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java +@@ -23,7 +23,7 @@ import org.bukkit.material.MaterialData; + public final class OldCraftChunkData implements ChunkGenerator.ChunkData { + private final int minHeight; + private final int maxHeight; +- private final LevelChunkSection[] sections; ++ private LevelChunkSection[] sections; // Paper + private final Registry biomes; + private Set tiles; + private final Set lights = new HashSet<>(); +@@ -194,7 +194,13 @@ public final class OldCraftChunkData implements ChunkGenerator.ChunkData { + return this.tiles; + } + +- Set getLights() { ++ public Set getLights() { // Paper + return this.lights; + } ++ ++ // Paper start ++ public void setRawChunkData(LevelChunkSection[] sections) { ++ this.sections = sections; ++ } ++ // Paper end + }