papermc/Spigot-Server-Patches/0374-Fix-some-generation-concurrency-issues.patch

227 lines
9.8 KiB
Diff
Raw Normal View History

From d2a98726d1f84c4bdd9e8657f802d5a6a321c824 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 983bc1c7d9c..8cf3c10274b 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 22e14fe1e98..e2af6d43b2e 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 fc4348b6024..44be7169ffd 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.26.2