aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0820-Allow-delegation-to-vanilla-chunk-gen.patch
blob: e5618d5f7887a43b3fba4750ecd6dc4da051c2c4 (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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 5f35c3714ac4e0e7afaa81c1ebe8d9601202bbb2..ba7023e7ca5d29375ff53c2951892138d155f69f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2301,6 +2301,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<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
+    );
+
+    @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<net.minecraft.world.level.biome.Biome> 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<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.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<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
 }