aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0755-Allow-delegation-to-vanilla-chunk-gen.patch
blob: 7710b03f6d64b8ff049f4343f6ad77a5ed37f5d2 (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 95015ceeb458d44229d7a23bbcb092c07f5d322e..53a58b6988cd11d37d6cdff6f2699710e3229745 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2336,6 +2336,90 @@ public final class CraftServer implements Server {
         return new OldCraftChunkData(world.getMinHeight(), world.getMaxHeight(), handle.registryAccess().registryOrThrow(Registries.BIOME), 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.registries.Registries.BIOME);
+        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.getDelegate();
+        } 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.registries.Registries.BIOME).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
 }