Paper/Spigot-Server-Patches/0395-Fix-some-generation-concurrency-issues.patch
Spottedleaf 2f782a6652 Updated Upstream (CraftBukkit)
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

CraftBukkit Changes:
17543ecf SPIGOT-5035: Error Using Virtual Merchant GUI
0fc6922b SPIGOT-5028: Villager#setVillagerExperience() doesn't work
bdbdbe44 SPIGOT-5024: Fox error - Unknown target reason
2019-06-06 16:56:51 +01:00

214 lines
9.1 KiB
Diff

From b055d60f929af546c7baa990929e26e2682096fc 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/DefinedStructureManager.java b/src/main/java/net/minecraft/server/DefinedStructureManager.java
index 6aa0ca3959..ed9b5c63f0 100644
--- a/src/main/java/net/minecraft/server/DefinedStructureManager.java
+++ b/src/main/java/net/minecraft/server/DefinedStructureManager.java
@@ -20,7 +20,7 @@ import org.apache.logging.log4j.Logger;
public class DefinedStructureManager implements IResourcePackListener {
private static final Logger LOGGER = LogManager.getLogger();
- private final Map<MinecraftKey, DefinedStructure> b = Maps.newHashMap();
+ private final Map<MinecraftKey, DefinedStructure> b = Maps.newConcurrentMap(); // Paper
private final DataFixer c;
private final MinecraftServer d;
private final java.nio.file.Path e;
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index a12964f904..7e01731f64 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 eca27e52e9..fb3463fcce 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 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.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.21.0