aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches/0387-Fix-some-generation-concurrency-issues.patch
blob: 3b44f6f0cfb7191cacbbdbdd999d09fcce5b1c1f (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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
From b5f68bce15b03752bc7ceca98de47efcb5fe6468 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Fri, 24 May 2019 07:53:16 +0100
Subject: [PATCH] Fix some generation concurrency issues


diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index e3b4e30e6..10c149fae 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -101,6 +101,23 @@ public abstract class World implements IIBlockAccess, GeneratorAccess, AutoClose
     private int tileTickPosition;
     public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
     public java.util.ArrayDeque<BlockRedstoneTorch.RedstoneUpdateInfo> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
+    // Paper start - yes this is hacky as shit
+    RegionLimitedWorldAccess regionLimited;
+    World originalWorld;
+    public World regionLimited(RegionLimitedWorldAccess limitedWorldAccess) {
+        try {
+            World clone = (World) super.clone();
+            clone.regionLimited = limitedWorldAccess;
+            clone.originalWorld = this;
+            return clone;
+        } catch (CloneNotSupportedException e1) {
+        }
+        return null;
+    }
+    ChunkCoordIntPair[] strongholdCoords;
+    List<StructureStart> strongholdStuctures = Lists.newArrayList();
+    final java.lang.Object stuctureLock = new Object();
+    // Paper end
 
     public CraftWorld getWorld() {
         return this.world;
diff --git a/src/main/java/net/minecraft/server/WorldGenStronghold.java b/src/main/java/net/minecraft/server/WorldGenStronghold.java
index ddf726867..c2188ceef 100644
--- a/src/main/java/net/minecraft/server/WorldGenStronghold.java
+++ b/src/main/java/net/minecraft/server/WorldGenStronghold.java
@@ -10,10 +10,12 @@ import javax.annotation.Nullable;
 
 public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyConfiguration> {
 
+    /* // Paper start - no shared state
     private boolean a;
     private ChunkCoordIntPair[] aS;
     private final List<StructureStart> aT = Lists.newArrayList();
     private long aU;
+     */
 
     public WorldGenStronghold(Function<Dynamic<?>, ? extends WorldGenFeatureEmptyConfiguration> function) {
         super(function);
@@ -21,16 +23,22 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
 
     @Override
     public boolean a(ChunkGenerator<?> chunkgenerator, Random random, int i, int j) {
+        // Paper start
+        /*
         if (this.aU != chunkgenerator.getSeed()) {
             this.d();
         }
+        */
+        final World world = chunkgenerator.getWorld();
 
-        if (!this.a) {
+        synchronized (world.stuctureLock) {
+        if ( world.strongholdCoords == null) {
             this.a(chunkgenerator);
-            this.a = true;
-        }
+          // this.a = true;
+        }}
+        // Paper end
 
-        ChunkCoordIntPair[] achunkcoordintpair = this.aS;
+        ChunkCoordIntPair[] achunkcoordintpair = world.strongholdCoords; // Paper
         int k = achunkcoordintpair.length;
 
         for (int l = 0; l < k; ++l) {
@@ -45,9 +53,11 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
     }
 
     private void d() {
+        /* // Paper
         this.a = false;
         this.aS = null;
         this.aT.clear();
+         */ // Paper
     }
 
     @Override
@@ -65,25 +75,32 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
         return 8;
     }
 
+
     @Nullable
     @Override
     public synchronized BlockPosition getNearestGeneratedFeature(World world, ChunkGenerator<? extends GeneratorSettingsDefault> chunkgenerator, BlockPosition blockposition, int i, boolean flag) { // CraftBukkit - synchronized
         if (!chunkgenerator.getWorldChunkManager().a(this)) {
             return null;
         } else {
+            // Paper start - no shared state
+            /*
             if (this.aU != world.getSeed()) {
                 this.d();
             }
+             */
 
-            if (!this.a) {
-                this.a(chunkgenerator);
-                this.a = true;
+            synchronized (world.stuctureLock) {
+                if ( world.strongholdCoords == null) {
+                    this.a(chunkgenerator);
+                    //this.a = true;
+                }
             }
+            // Paper end
 
             BlockPosition blockposition1 = null;
             BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
             double d0 = Double.MAX_VALUE;
-            ChunkCoordIntPair[] achunkcoordintpair = this.aS;
+            ChunkCoordIntPair[] achunkcoordintpair = world.strongholdCoords; // Paper
             int j = achunkcoordintpair.length;
 
             for (int k = 0; k < j; ++k) {
@@ -106,7 +123,7 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
     }
 
     private void a(ChunkGenerator<?> chunkgenerator) {
-        this.aU = chunkgenerator.getSeed();
+        //this.aU = chunkgenerator.getSeed(); // Paper
         List<BiomeBase> list = Lists.newArrayList();
         Iterator iterator = IRegistry.BIOME.iterator();
 
@@ -122,15 +139,15 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
         int j = chunkgenerator.getSettings().f();
         int k = chunkgenerator.getSettings().g();
 
-        this.aS = new ChunkCoordIntPair[j];
+        ChunkCoordIntPair[] strongholdCoords = chunkgenerator.getWorld().strongholdCoords = new ChunkCoordIntPair[j]; // Paper
         int l = 0;
-        Iterator iterator1 = this.aT.iterator();
+        Iterator iterator1 = chunkgenerator.getWorld().strongholdStuctures.iterator(); // Paper
 
         while (iterator1.hasNext()) {
             StructureStart structurestart = (StructureStart) iterator1.next();
 
-            if (l < this.aS.length) {
-                this.aS[l++] = new ChunkCoordIntPair(structurestart.f(), structurestart.g());
+            if (l < strongholdCoords.length) { // Paper
+                strongholdCoords[l++] = new ChunkCoordIntPair(structurestart.f(), structurestart.g()); // Paper
             }
         }
 
@@ -140,11 +157,11 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
         double d0 = random.nextDouble() * 3.141592653589793D * 2.0D;
         int i1 = l;
 
-        if (l < this.aS.length) {
+        if (l < strongholdCoords.length) { // Paper
             int j1 = 0;
             int k1 = 0;
 
-            for (int l1 = 0; l1 < this.aS.length; ++l1) {
+            for (int l1 = 0; l1 < strongholdCoords.length; ++l1) { // Paper
                 double d1 = (double) (4 * i + i * k1 * 6) + (random.nextDouble() - 0.5D) * (double) i * 2.5D;
                 int i2 = (int) Math.round(Math.cos(d0) * d1);
                 int j2 = (int) Math.round(Math.sin(d0) * d1);
@@ -156,7 +173,7 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
                 }
 
                 if (l1 >= i1) {
-                    this.aS[l1] = new ChunkCoordIntPair(i2, j2);
+                    strongholdCoords[l1] = new ChunkCoordIntPair(i2, j2); // Paper
                 }
 
                 d0 += 6.283185307179586D / (double) k;
@@ -165,7 +182,7 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
                     ++k1;
                     j1 = 0;
                     k += 2 * k / (k1 + 1);
-                    k = Math.min(k, this.aS.length - l1);
+                    k = Math.min(k, strongholdCoords.length - l1);
                     d0 += random.nextDouble() * 3.141592653589793D * 2.0D;
                 }
             }
@@ -207,7 +224,7 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
                 this.a(chunkgenerator.getSeaLevel(), this.d, 10);
             } while (this.b.isEmpty() || worldgenstrongholdpieces_worldgenstrongholdstart.b == null);
 
-            ((WorldGenStronghold) this.k()).aT.add(this);
+            chunkgenerator.getWorld().strongholdStuctures.add(this); // Paper - this worries me, this is never cleared, even in vanilla (world seed never changes "world", and that appears to be the only relevant world)
         }
     }
 }
-- 
2.23.0