Paper/Spigot-Server-Patches/0376-Fix-some-generation-concurrency-issues.patch
Shane Freeder b16fd5c3a3
Updated Upstream (Bukkit/CraftBukkit/Spigot)
Upstream has released updates that appears to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
6148fca7 SPIGOT-5484: Add more spawn tick settings

CraftBukkit Changes:
fc249340 SPIGOT-5484: Add more spawn tick settings

Spigot Changes:
6de3d4be Rebuild patches
2020-03-10 11:01:21 +00:00

227 lines
9.7 KiB
Diff

From 40a6743af3f62cee194013e598512f7237ce95fc 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 20d9dd839..18e0ca2c7 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -86,6 +86,23 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
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/WorldGenFeatureStateProviderWeighted.java b/src/main/java/net/minecraft/server/WorldGenFeatureStateProviderWeighted.java
index 22e14fe1e..e2af6d43b 100644
--- a/src/main/java/net/minecraft/server/WorldGenFeatureStateProviderWeighted.java
+++ b/src/main/java/net/minecraft/server/WorldGenFeatureStateProviderWeighted.java
@@ -23,18 +23,18 @@ public class WorldGenFeatureStateProviderWeighted extends WorldGenFeatureStatePr
this(new WeightedList<>(dynamic.get("entries").orElseEmptyList(), IBlockData::a));
}
- public WorldGenFeatureStateProviderWeighted a(IBlockData iblockdata, int i) {
+ public synchronized WorldGenFeatureStateProviderWeighted a(IBlockData iblockdata, int i) { // Paper
this.b.a(iblockdata, i);
return this;
}
@Override
- public IBlockData a(Random random, BlockPosition blockposition) {
+ public synchronized IBlockData a(Random random, BlockPosition blockposition) { // Paper
return (IBlockData) this.b.b(random);
}
@Override
- public <T> T a(DynamicOps<T> dynamicops) {
+ public synchronized <T> T a(DynamicOps<T> dynamicops) { // Paper
Builder<T, T> builder = ImmutableMap.builder();
builder.put(dynamicops.createString("type"), dynamicops.createString(IRegistry.t.getKey(this.a).toString())).put(dynamicops.createString("entries"), this.b.a(dynamicops, (iblockdata) -> {
diff --git a/src/main/java/net/minecraft/server/WorldGenStronghold.java b/src/main/java/net/minecraft/server/WorldGenStronghold.java
index fc4348b60..44be7169f 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[] aq;
private final List<StructureStart> ar = Lists.newArrayList();
private long as;
+ */
public WorldGenStronghold(Function<Dynamic<?>, ? extends WorldGenFeatureEmptyConfiguration> function) {
super(function);
@@ -21,16 +23,22 @@ public class WorldGenStronghold extends StructureGenerator<WorldGenFeatureEmptyC
@Override
public boolean a(BiomeManager biomemanager, ChunkGenerator<?> chunkgenerator, Random random, int i, int j, BiomeBase biomebase) {
+ // Paper start
+ /*
if (this.as != 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.aq;
+ 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.aq = null;
this.ar.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) {
if (!chunkgenerator.getWorldChunkManager().a(this)) {
return null;
} else {
+ // Paper start - no shared state
+ /*
if (this.as != 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.aq;
+ 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.as = chunkgenerator.getSeed();
+ //this.as = 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.aq = new ChunkCoordIntPair[j];
+ ChunkCoordIntPair[] strongholdCoords = chunkgenerator.getWorld().strongholdCoords = new ChunkCoordIntPair[j]; // Paper
int l = 0;
- Iterator iterator1 = this.ar.iterator();
+ Iterator iterator1 = chunkgenerator.getWorld().strongholdStuctures.iterator(); // Paper
while (iterator1.hasNext()) {
StructureStart structurestart = (StructureStart) iterator1.next();
- if (l < this.aq.length) {
- this.aq[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.aq.length) {
+ if (l < strongholdCoords.length) { // Paper
int j1 = 0;
int k1 = 0;
- for (int l1 = 0; l1 < this.aq.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.aq[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.aq.length - l1);
+ k = Math.min(k, strongholdCoords.length - l1); // Paper
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.l()).ar.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.25.0