From b66154b26ec7b0d12d246d5769e77c5067beab72 Mon Sep 17 00:00:00 2001 From: Aikar Date: Fri, 29 Mar 2019 02:02:53 -0400 Subject: [PATCH] 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. --- ...2-Async-Chunk-Loading-and-Generation.patch | 44 ++++++++++++++----- ...mit-lightning-strike-effect-distance.patch | 8 ++-- ...-Use-EntityTypes-for-living-entities.patch | 8 ++-- .../0423-Entity-getEntitySpawnReason.patch | 8 ++-- 4 files changed, 46 insertions(+), 22 deletions(-) diff --git a/Spigot-Server-Patches/0362-Async-Chunk-Loading-and-Generation.patch b/Spigot-Server-Patches/0362-Async-Chunk-Loading-and-Generation.patch index 3402e0e3d1..34e1fb089b 100644 --- a/Spigot-Server-Patches/0362-Async-Chunk-Loading-and-Generation.patch +++ b/Spigot-Server-Patches/0362-Async-Chunk-Loading-and-Generation.patch @@ -1,4 +1,4 @@ -From 126fcc3b0e84e0ee1b2d356311d8f6b2a32625c4 Mon Sep 17 00:00:00 2001 +From c9d95cbf8d5ef37223484c7ced54dad5a840e484 Mon Sep 17 00:00:00 2001 From: Aikar 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 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 { diff --git a/Spigot-Server-Patches/0377-Limit-lightning-strike-effect-distance.patch b/Spigot-Server-Patches/0377-Limit-lightning-strike-effect-distance.patch index a6c613c998..3676f837fa 100644 --- a/Spigot-Server-Patches/0377-Limit-lightning-strike-effect-distance.patch +++ b/Spigot-Server-Patches/0377-Limit-lightning-strike-effect-distance.patch @@ -1,11 +1,11 @@ -From c42c13d5dbe4ecbfa968caf358f3fc38f352c92a Mon Sep 17 00:00:00 2001 +From 9e37b3bf99fe441cef80a2aae6e2367eec74487e Mon Sep 17 00:00:00 2001 From: Trigary 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)) { diff --git a/Spigot-Server-Patches/0389-Use-EntityTypes-for-living-entities.patch b/Spigot-Server-Patches/0389-Use-EntityTypes-for-living-entities.patch index 0ea2d8cbdc..86d75d3f16 100644 --- a/Spigot-Server-Patches/0389-Use-EntityTypes-for-living-entities.patch +++ b/Spigot-Server-Patches/0389-Use-EntityTypes-for-living-entities.patch @@ -1,4 +1,4 @@ -From fe18b0ba4dedd917601d2eb2ef3f534635b4c7f9 Mon Sep 17 00:00:00 2001 +From 122ff2211ce676b485e6deb97917c3828d83e3fc Mon Sep 17 00:00:00 2001 From: BillyGalbreath 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 { diff --git a/Spigot-Server-Patches/0423-Entity-getEntitySpawnReason.patch b/Spigot-Server-Patches/0423-Entity-getEntitySpawnReason.patch index 067ea74c18..b19910bfa0 100644 --- a/Spigot-Server-Patches/0423-Entity-getEntitySpawnReason.patch +++ b/Spigot-Server-Patches/0423-Entity-getEntitySpawnReason.patch @@ -1,4 +1,4 @@ -From a186f2f777fab6c95fb2351c8c5cfa3937cf01fd Mon Sep 17 00:00:00 2001 +From 1dbf386fc08f6efe1e5dcdea5c9df5bf427cd8b5 Mon Sep 17 00:00:00 2001 From: Aikar 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