aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0770-Allow-delegation-to-vanilla-chunk-gen.patch
blob: fc9c73e9338b4672bf16e2d183c2539105788c36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MiniDigger <admin@benndorf.dev>
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 2f793169ee3b8265059f75c5a3cc13a86acedc83..bf747c7584733014aac771ba4ca039c588582f25 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2329,6 +2329,90 @@ public final class CraftServer implements Server {
         return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(net.minecraft.core.Registry.BIOME_REGISTRY), world); // Paper - Anti-Xray - Add parameters
     }
 
+    // Paper start
+    private static final List<net.minecraft.world.level.chunk.ChunkStatus> 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
+    );
+
+    @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 net.minecraft.core.Registry<net.minecraft.world.level.biome.Biome> biomeRegistry = serverLevel.getServer().registryAccess().registryOrThrow(net.minecraft.core.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<Runnable> 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<net.minecraft.world.level.chunk.ChunkAccess> 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.core.Holder<net.minecraft.world.level.biome.Biome> biomeHolder = serverLevel.registryAccess().registryOrThrow(net.minecraft.core.Registry.BIOME_REGISTRY).getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
+                        final net.minecraft.world.level.chunk.ChunkAccess chunk = new net.minecraft.world.level.chunk.EmptyLevelChunk(serverLevel, new net.minecraft.world.level.ChunkPos(xx, zz), biomeHolder);
+                        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 4a23d03757e1735b9ebb8c003adcc0374a7d672d..ce006e1d6c38e5b0bdb336c480fb9d291292f75c 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<net.minecraft.world.level.biome.Biome> biomes;
     private Set<BlockPos> tiles;
     private final Set<BlockPos> lights = new HashSet<>();
@@ -194,7 +194,13 @@ public final class OldCraftChunkData implements ChunkGenerator.ChunkData {
         return this.tiles;
     }
 
-    Set<BlockPos> getLights() {
+    public Set<BlockPos> getLights() { // Paper
         return this.lights;
     }
+
+    // Paper start
+    public void setRawChunkData(LevelChunkSection[] sections) {
+        this.sections = sections;
+    }
+    // Paper end
 }