Fix a concurrency issue with legacy structure data loading

This code could get hit by many threads at once, causing multiple
chunk loads to convert legacy data, leading to all sorts of fun.

Additionally, go ahead and preload it async on world load.
This commit is contained in:
Aikar 2019-03-29 02:02:53 -04:00
parent e42b8d1c0c
commit b66154b26e
No known key found for this signature in database
GPG Key ID: 401ADFC9891FAAFE
4 changed files with 46 additions and 22 deletions

View File

@ -1,4 +1,4 @@
From 126fcc3b0e84e0ee1b2d356311d8f6b2a32625c4 Mon Sep 17 00:00:00 2001
From c9d95cbf8d5ef37223484c7ced54dad5a840e484 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 21 Jul 2018 16:55:04 -0400
Subject: [PATCH] Async Chunk Loading and Generation
@ -713,7 +713,7 @@ index 186cfda7e..781e06877 100644
}
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index d938eb374..51df075b4 100644
index d938eb374..7734712af 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -119,7 +119,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
@ -725,7 +725,22 @@ index d938eb374..51df075b4 100644
if (cps.isLoaded(x, z)) {
return true;
}
@@ -385,11 +385,12 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
@@ -204,10 +204,13 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
}
}
+ private final Object legacyStructureLock = new Object(); // Paper
+ public void getPersistentStructureLegacy(DimensionManager dimensionmanager, @Nullable PersistentCollection persistentcollection) { this.a(dimensionmanager, persistentcollection); } // Paper
public void a(DimensionManager dimensionmanager, @Nullable PersistentCollection persistentcollection) {
if (this.e == null) {
+ synchronized (legacyStructureLock){ if (this.e == null) { // Paper
this.e = PersistentStructureLegacy.a(dimensionmanager, persistentcollection);
- }
+ } } } // Paper
}
@@ -385,11 +388,12 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
}
};
} else {
@ -947,13 +962,14 @@ index be555f82d..3e81ebdb8 100644
this.aJ = Sets.newHashSet();
this.aL = new double[] { 0.0D, 0.0D, 0.0D};
diff --git a/src/main/java/net/minecraft/server/IChunkLoader.java b/src/main/java/net/minecraft/server/IChunkLoader.java
index 4698ee99f..dfb45cc4e 100644
index 4698ee99f..431f4ab18 100644
--- a/src/main/java/net/minecraft/server/IChunkLoader.java
+++ b/src/main/java/net/minecraft/server/IChunkLoader.java
@@ -6,6 +6,8 @@ import javax.annotation.Nullable;
@@ -6,6 +6,9 @@ import javax.annotation.Nullable;
public interface IChunkLoader {
+ void getPersistentStructureLegacy(DimensionManager dimensionmanager, @Nullable PersistentCollection persistentcollection); // Paper
+ void loadEntities(NBTTagCompound nbttagcompound, Chunk chunk); // Paper - Async Chunks
+ Object[] loadChunk(GeneratorAccess generatoraccess, int i, int j, Consumer<Chunk> consumer) throws IOException; // Paper - Async Chunks
@Nullable
@ -2056,7 +2072,7 @@ index 284e96710..8b08efe1f 100644
}
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index a7302b39c..739fbecac 100644
index 4c971ddfb..1c66c833b 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -41,7 +41,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
@ -2306,10 +2322,18 @@ index 69d8a25bd..d0eaa9e9f 100644
}
}
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 0ff3fe03d..9b5509dce 100644
index 0ff3fe03d..e71a40580 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -714,7 +714,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
@@ -80,6 +80,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
this.P();
this.Q();
this.getWorldBorder().a(minecraftserver.au());
+ MCUtil.scheduleAsyncTask(() -> this.getChunkProvider().chunkLoader.getPersistentStructureLegacy(dimensionmanager, worldMaps)); // Paper
}
public WorldServer i_() {
@@ -714,7 +715,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
gen = new org.bukkit.craftbukkit.generator.NormalChunkGenerator(this, this.getSeed());
}
@ -2347,7 +2371,7 @@ index fac42f8e5..59b1628e5 100644
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 95fe3a91b..b5a87cfaf 100644
index 0e4455d66..eacecccfd 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -163,6 +163,16 @@ public class CraftWorld implements World {
@ -2385,7 +2409,7 @@ index 95fe3a91b..b5a87cfaf 100644
if (isChunkLoaded(chunkCoordX + x, chunkCoordZ + z)) {
unloadChunk(chunkCoordX + x, chunkCoordZ + z);
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 054ebc82b..2e0b4de83 100644
index 68e30185a..7905420ca 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -82,6 +82,7 @@ public class CraftEventFactory {

View File

@ -1,11 +1,11 @@
From c42c13d5dbe4ecbfa968caf358f3fc38f352c92a Mon Sep 17 00:00:00 2001
From 9e37b3bf99fe441cef80a2aae6e2367eec74487e Mon Sep 17 00:00:00 2001
From: Trigary <trigary0@gmail.com>
Date: Fri, 14 Sep 2018 17:42:08 +0200
Subject: [PATCH] Limit lightning strike effect distance
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 0b54b7d78..d723868fc 100644
index e04204055..30985cdfc 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -237,6 +237,28 @@ public class PaperWorldConfig {
@ -69,10 +69,10 @@ index 7781babf5..50f620009 100644
--this.lifeTicks;
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 9b5509dce..409b50744 100644
index e71a40580..53e7834cc 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -1064,7 +1064,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
@@ -1065,7 +1065,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
// CraftBukkit end
if (super.strikeLightning(entity)) {

View File

@ -1,4 +1,4 @@
From fe18b0ba4dedd917601d2eb2ef3f534635b4c7f9 Mon Sep 17 00:00:00 2001
From 122ff2211ce676b485e6deb97917c3828d83e3fc Mon Sep 17 00:00:00 2001
From: BillyGalbreath <Blake.Galbreath@GMail.com>
Date: Thu, 4 Oct 2018 10:08:02 -0500
Subject: [PATCH] Use EntityTypes for living entities
@ -639,10 +639,10 @@ index 11010d8e1..4eb746ebb 100644
entityvindicator.setPositionRotation(blockposition, 0.0F, 0.0F);
entityvindicator.prepare(generatoraccess.getDamageScaler(new BlockPosition(entityvindicator)), (GroupDataEntity) null, (NBTTagCompound) null);
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 409b50744..a4fc1e5e2 100644
index 53e7834cc..5c2421ac3 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -494,7 +494,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
@@ -495,7 +495,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
boolean flag2 = this.getGameRules().getBoolean("doMobSpawning") && this.random.nextDouble() < (double) difficultydamagescaler.b() * paperConfig.skeleHorseSpawnChance; // Paper
if (flag2) {
@ -652,7 +652,7 @@ index 409b50744..a4fc1e5e2 100644
entityhorseskeleton.s(true);
entityhorseskeleton.setAgeRaw(0);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index e33135ada..6ed7c9355 100644
index 7c0a53053..40ee34675 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1181,153 +1181,153 @@ public class CraftWorld implements World {

View File

@ -1,4 +1,4 @@
From a186f2f777fab6c95fb2351c8c5cfa3937cf01fd Mon Sep 17 00:00:00 2001
From 1dbf386fc08f6efe1e5dcdea5c9df5bf427cd8b5 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 24 Mar 2019 00:24:52 -0400
Subject: [PATCH] Entity#getEntitySpawnReason
@ -10,10 +10,10 @@ persistenting Living Entity, SPAWNER for spawners,
or DEFAULT since data was not stored.
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index 51df075b4..53ae5d509 100644
index 7734712af..dce52ac0f 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -1131,7 +1131,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
@@ -1134,7 +1134,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
while (iterator.hasNext()) {
Entity entity1 = (Entity) iterator.next();
@ -98,7 +98,7 @@ index b1630137e..df416e3b5 100644
if (entity != null) {
UUID uuid = nbttagcompound1.a("Attach");
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0624848cc..9faed9303 100644
index 5b4bce464..2d436feab 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1084,6 +1084,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc