diff --git a/Spigot-Server-Patches/0009-Timings-v2.patch b/Spigot-Server-Patches/0009-Timings-v2.patch index b8808d2286..a518972edc 100644 --- a/Spigot-Server-Patches/0009-Timings-v2.patch +++ b/Spigot-Server-Patches/0009-Timings-v2.patch @@ -1,4 +1,4 @@ -From 983b67ed126cac183574f9d8832b247327386df4 Mon Sep 17 00:00:00 2001 +From 91be85953d10fb5df264b2673005a2744f9140b3 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 3 Mar 2016 04:00:11 -0600 Subject: [PATCH] Timings v2 @@ -153,10 +153,10 @@ index 0000000000..223d3b1125 +} diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java new file mode 100644 -index 0000000000..27ce4a828e +index 0000000000..fa1c920ea6 --- /dev/null +++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -@@ -0,0 +1,126 @@ +@@ -0,0 +1,118 @@ +package co.aikar.timings; + +import net.minecraft.server.World; @@ -202,16 +202,12 @@ index 0000000000..27ce4a828e + public final Timing broadcastChunkUpdates; + public final Timing countNaturalMobs; + -+ public final Timing syncChunkLoadTimer; -+ public final Timing syncChunkLoadDataTimer; -+ public final Timing syncChunkLoadStructuresTimer; -+ public final Timing syncChunkLoadPostTimer; -+ public final Timing syncChunkLoadPopulateTimer; -+ public final Timing chunkAwait; ++ public final Timing chunkLoad; ++ public final Timing chunkLoadPopulate; ++ public final Timing syncChunkLoad; + public final Timing chunkLoadLevelTimer; -+ public final Timing chunkGeneration; -+ public final Timing chunkIOStage1; -+ public final Timing chunkIOStage2; ++ public final Timing chunkIO; ++ public final Timing chunkPostLoad; + public final Timing worldSave; + public final Timing worldSaveChunks; + public final Timing worldSaveLevel; @@ -248,16 +244,12 @@ index 0000000000..27ce4a828e + tileEntityTick = Timings.ofSafe(name + "tileEntityTick"); + tileEntityPending = Timings.ofSafe(name + "tileEntityPending"); + -+ syncChunkLoadTimer = Timings.ofSafe(name + "syncChunkLoad"); -+ syncChunkLoadDataTimer = Timings.ofSafe(name + "syncChunkLoad - Data"); -+ syncChunkLoadStructuresTimer = Timings.ofSafe(name + "chunkLoad - recreateStructures"); -+ syncChunkLoadPostTimer = Timings.ofSafe(name + "chunkLoad - Post"); -+ syncChunkLoadPopulateTimer = Timings.ofSafe(name + "chunkLoad - Populate"); -+ chunkAwait = Timings.ofSafe(name + "chunkAwait"); -+ chunkLoadLevelTimer = Timings.ofSafe(name + "chunkLoad - Load Level"); -+ chunkGeneration = Timings.ofSafe(name + "chunkGeneration"); -+ chunkIOStage1 = Timings.ofSafe(name + "ChunkIO Stage 1 - DiskIO"); -+ chunkIOStage2 = Timings.ofSafe(name + "ChunkIO Stage 2 - Post Load"); ++ chunkLoad = Timings.ofSafe(name + "Chunk Load"); ++ chunkLoadPopulate = Timings.ofSafe(name + "Chunk Load - Populate"); ++ syncChunkLoad = Timings.ofSafe(name + "Sync Chunk Load"); ++ chunkLoadLevelTimer = Timings.ofSafe(name + "Chunk Load - Load Level"); ++ chunkIO = Timings.ofSafe(name + "Chunk Load - DiskIO"); ++ chunkPostLoad = Timings.ofSafe(name + "Chunk Load - Post Load"); + worldSave = Timings.ofSafe(name + "World Save"); + worldSaveLevel = Timings.ofSafe(name + "World Save - Level"); + worldSaveChunks = Timings.ofSafe(name + "World Save - Chunks"); @@ -351,14 +343,14 @@ index cd72a9c845..5de881371a 100644 private final float frictionFactor; private final float f; diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 2b6fe2e01d..87c5e09a59 100644 +index 2b6fe2e01d..4cd353b253 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -675,6 +675,7 @@ public class Chunk implements IChunkAccess { server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(this.bukkitChunk, this.needsDecoration)); if (this.needsDecoration) { -+ try (co.aikar.timings.Timing ignored = this.world.timings.syncChunkLoadPopulateTimer.startTiming()) { // Paper ++ try (co.aikar.timings.Timing ignored = this.world.timings.chunkLoadPopulate.startTiming()) { // Paper this.needsDecoration = false; java.util.Random random = new java.util.Random(); random.setSeed(world.getSeed()); @@ -371,7 +363,7 @@ index 2b6fe2e01d..87c5e09a59 100644 } } diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index ba2af2abe2..a653ce4ce5 100644 +index ba2af2abe2..875f353dc3 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -308,11 +308,13 @@ public class ChunkProviderServer extends IChunkProvider { @@ -382,10 +374,10 @@ index ba2af2abe2..a653ce4ce5 100644 CompletableFuture> completablefuture = this.getChunkFutureMainThread(i, j, chunkstatus, flag); + if (!completablefuture.isDone()) { // Paper -+ this.world.timings.chunkAwait.startTiming(); // Paper ++ this.world.timings.syncChunkLoad.startTiming(); // Paper this.serverThreadQueue.awaitTasks(completablefuture::isDone); - world.timings.syncChunkLoadTimer.stopTiming(); // Spigot -+ this.world.timings.chunkAwait.stopTiming(); // Paper ++ this.world.timings.syncChunkLoad.stopTiming(); // Paper + } // Paper ichunkaccess = (IChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { return ichunkaccess1; @@ -468,7 +460,7 @@ index ba2af2abe2..a653ce4ce5 100644 @Override diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -index e16d30f2ca..4af5a230ba 100644 +index e16d30f2ca..13d99de2cd 100644 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java @@ -1,5 +1,6 @@ @@ -478,16 +470,15 @@ index e16d30f2ca..4af5a230ba 100644 import com.google.common.collect.Maps; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongSet; -@@ -388,7 +389,7 @@ public class ChunkRegionLoader { +@@ -388,7 +389,6 @@ public class ChunkRegionLoader { private static void loadEntities(NBTTagCompound nbttagcompound, Chunk chunk) { NBTTagList nbttaglist = nbttagcompound.getList("Entities", 10); World world = chunk.getWorld(); - world.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot -+ world.timings.chunkLoadLevelTimer.startTiming(); // Spigot for (int i = 0; i < nbttaglist.size(); ++i) { NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i); -@@ -400,8 +401,6 @@ public class ChunkRegionLoader { +@@ -400,8 +400,6 @@ public class ChunkRegionLoader { chunk.d(true); } @@ -496,15 +487,15 @@ index e16d30f2ca..4af5a230ba 100644 NBTTagList nbttaglist1 = nbttagcompound.getList("TileEntities", 10); for (int j = 0; j < nbttaglist1.size(); ++j) { -@@ -418,7 +417,7 @@ public class ChunkRegionLoader { +@@ -418,8 +416,6 @@ public class ChunkRegionLoader { } } } - world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot -+ world.timings.chunkLoadLevelTimer.stopTiming(); // Paper - +- } + private static NBTTagCompound a(ChunkCoordIntPair chunkcoordintpair, Map map, Map map1) { diff --git a/src/main/java/net/minecraft/server/CustomFunction.java b/src/main/java/net/minecraft/server/CustomFunction.java index 8d7a6d2403..707bd2600d 100644 --- a/src/main/java/net/minecraft/server/CustomFunction.java @@ -943,7 +934,7 @@ index b4a0bd7951..67bdd57747 100644 this.methodProfiler.exit(); } diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 93d838ec2d..2a6955f855 100644 +index 93d838ec2d..5e31b65e16 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -1,7 +1,9 @@ @@ -956,21 +947,33 @@ index 93d838ec2d..2a6955f855 100644 import com.google.common.collect.Lists; import com.google.common.collect.Queues; import com.google.common.collect.Sets; -@@ -506,9 +508,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -506,11 +508,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { private CompletableFuture> f(ChunkCoordIntPair chunkcoordintpair) { return CompletableFuture.supplyAsync(() -> { - try { -+ try (Timing ignored = this.world.timings.syncChunkLoadTimer.startTimingIfSync()) { // Paper ++ try (Timing ignored = this.world.timings.chunkLoad.startTimingIfSync()) { // Paper this.world.getMethodProfiler().c("chunkLoad"); - NBTTagCompound nbttagcompound = this.readChunkData(chunkcoordintpair); + NBTTagCompound nbttagcompound; // Paper -+ try (Timing ignored2 = this.world.timings.chunkIOStage1.startTimingIfSync()) { // Paper start - timings ++ try (Timing ignored2 = this.world.timings.chunkIO.startTimingIfSync()) { // Paper start - timings + nbttagcompound = this.readChunkData(chunkcoordintpair); + } // Paper end - if (nbttagcompound != null) { +- if (nbttagcompound != null) { ++ if (nbttagcompound != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings boolean flag = nbttagcompound.hasKeyOfType("Level", 10) && nbttagcompound.getCompound("Level").hasKeyOfType("Status", 8); + + if (flag) { +@@ -521,7 +526,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + } + + PlayerChunkMap.LOGGER.error("Chunk file at {} is missing level data, skipping", chunkcoordintpair); +- } ++ }} // Paper + } catch (ReportedException reportedexception) { + Throwable throwable = reportedexception.getCause(); + @@ -548,7 +553,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { return "chunkGenerate " + chunkstatus.d(); }); @@ -984,7 +987,7 @@ index 93d838ec2d..2a6955f855 100644 ChunkStatus chunkstatus = PlayerChunk.getChunkStatus(playerchunk.getTicketLevel()); return !chunkstatus.b(ChunkStatus.FULL) ? PlayerChunk.UNLOADED_CHUNK_ACCESS : either.mapLeft((ichunkaccess) -> { -+ try (Timing ignored = world.timings.chunkIOStage2.startTimingIfSync()) { // Paper ++ try (Timing ignored = world.timings.chunkPostLoad.startTimingIfSync()) { // Paper ChunkCoordIntPair chunkcoordintpair = playerchunk.i(); Chunk chunk; diff --git a/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch index 7995edb9e3..34d28638a7 100644 --- a/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch @@ -1,4 +1,4 @@ -From 90a9b4ac3b0535d33c1f632104a5334f8e9ce64f Mon Sep 17 00:00:00 2001 +From 35ab84aa1f38c79f543ac56e8745919fb3b2bc87 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 13 Jul 2019 09:23:10 -0700 Subject: [PATCH] Asynchronous chunk IO and loading @@ -121,10 +121,10 @@ tasks required to be executed by the chunk load task (i.e lighting and some poi tasks). diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -index 27ce4a828e..30bafb214b 100644 +index fa1c920ea6..98acbfa44d 100644 --- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java +++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -@@ -61,6 +61,17 @@ public class WorldTimingsHandler { +@@ -57,6 +57,17 @@ public class WorldTimingsHandler { public final Timing miscMobSpawning; @@ -142,7 +142,7 @@ index 27ce4a828e..30bafb214b 100644 public WorldTimingsHandler(World server) { String name = server.worldData.getName() +" - "; -@@ -118,6 +129,17 @@ public class WorldTimingsHandler { +@@ -110,6 +121,17 @@ public class WorldTimingsHandler { miscMobSpawning = Timings.ofSafe(name + "Mob spawning - Misc"); @@ -161,7 +161,7 @@ index 27ce4a828e..30bafb214b 100644 public static Timing getTickList(WorldServer worldserver, String timingsType) { diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java -index dbd1439970..6916ed30c4 100644 +index dbd1439970..f4836e2da1 100644 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java @@ -1,5 +1,6 @@ @@ -171,68 +171,54 @@ index dbd1439970..6916ed30c4 100644 import com.google.common.base.Strings; import com.google.common.base.Throwables; -@@ -367,4 +368,64 @@ public class PaperConfig { +@@ -367,4 +368,50 @@ public class PaperConfig { maxBookPageSize = getInt("settings.book-size.page-max", maxBookPageSize); maxBookTotalSizeMultiplier = getDouble("settings.book-size.total-multiplier", maxBookTotalSizeMultiplier); } + + public static boolean asyncChunks = false; -+ //public static boolean asyncChunkGeneration = true; // Leave out for now until we can control this -+ //public static boolean asyncChunkGenThreadPerWorld = true; // Leave out for now until we can control this -+ public static int asyncChunkLoadThreads = -1; + private static void asyncChunks() { ++ ConfigurationSection section; + if (version < 15) { + boolean enabled = config.getBoolean("settings.async-chunks", true); -+ ConfigurationSection section = config.createSection("settings.async-chunks"); ++ section = config.createSection("settings.async-chunks"); + section.set("enable", enabled); -+ section.set("load-threads", -1); -+ section.set("generation", true); -+ section.set("thread-per-world-generation", true); ++ section.set("threads", -1); ++ } else { ++ section = config.getConfigurationSection("settings.async-chunks"); ++ if (section == null) { ++ section = config.createSection("settings.async-chunks"); ++ } + } -+ -+ // TODO load threads now control async chunk save for unloading chunks, look into renaming this? ++ // Clean up old configs ++ if (section.contains("load-threads")) { ++ if (!section.contains("threads")) { ++ section.set("threads", section.get("load-threads")); ++ } ++ section.set("load-threads", null); ++ } ++ section.set("generation", null); ++ section.set("thread-per-world-generation", null); + + asyncChunks = getBoolean("settings.async-chunks.enable", true); -+ //asyncChunkGeneration = getBoolean("settings.async-chunks.generation", true); // Leave out for now until we can control this -+ //asyncChunkGenThreadPerWorld = getBoolean("settings.async-chunks.thread-per-world-generation", true); // Leave out for now until we can control this -+ asyncChunkLoadThreads = getInt("settings.async-chunks.load-threads", -1); -+ if (asyncChunkLoadThreads <= 0) { -+ asyncChunkLoadThreads = (int) Math.min(Integer.getInteger("paper.maxChunkThreads", 8), Math.max(1, Runtime.getRuntime().availableProcessors() - 1)); ++ int threads = getInt("settings.async-chunks.threads", -1); ++ if (threads <= 0) { ++ threads = (int) Math.min(Integer.getInteger("paper.maxChunkThreads", 8), Math.max(1, Runtime.getRuntime().availableProcessors() - 1)); + } + + // Let Shared Host set some limits -+ String sharedHostEnvGen = System.getenv("PAPER_ASYNC_CHUNKS_SHARED_HOST_GEN"); -+ String sharedHostEnvLoad = System.getenv("PAPER_ASYNC_CHUNKS_SHARED_HOST_LOAD"); -+ /* Ignore temporarily - we cannot control the gen threads (for now) -+ if ("1".equals(sharedHostEnvGen)) { -+ log("Async Chunks - Generation: Your host has requested to use a single thread world generation"); -+ asyncChunkGenThreadPerWorld = false; -+ } else if ("2".equals(sharedHostEnvGen)) { -+ log("Async Chunks - Generation: Your host has disabled async world generation - You will experience lag from world generation"); -+ asyncChunkGeneration = false; -+ } -+ */ -+ -+ if (sharedHostEnvLoad != null) { ++ String sharedHostThreads = System.getenv("PAPER_ASYNC_CHUNKS_SHARED_HOST_THREADS"); ++ if (sharedHostThreads != null) { + try { -+ asyncChunkLoadThreads = Math.max(1, Math.min(asyncChunkLoadThreads, Integer.parseInt(sharedHostEnvLoad))); ++ threads = Math.max(1, Math.min(threads, Integer.parseInt(sharedHostThreads))); + } catch (NumberFormatException ignored) {} + } + + if (!asyncChunks) { + log("Async Chunks: Disabled - Chunks will be managed synchronosuly, and will cause tremendous lag."); + } else { -+ ChunkTaskManager.initGlobalLoadThreads(asyncChunkLoadThreads); ++ ChunkTaskManager.initGlobalLoadThreads(threads); + log("Async Chunks: Enabled - Chunks will be loaded much faster, without lag."); -+ /* Ignore temporarily - we cannot control the gen threads (for now) -+ if (!asyncChunkGeneration) { -+ log("Async Chunks - Generation: Disabled - Chunks will be generated synchronosuly, and will cause tremendous lag."); -+ } else if (asyncChunkGenThreadPerWorld) { -+ log("Async Chunks - Generation: Enabled - Chunks will be generated much faster, without lag."); -+ } else { -+ log("Async Chunks - Generation: Enabled (Single Thread) - Chunks will be generated much faster, without lag."); -+ } -+ */ + } + } } @@ -1583,7 +1569,7 @@ index 0000000000..ee906b594b +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java new file mode 100644 -index 0000000000..305da47868 +index 0000000000..ac9bc3e231 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java @@ -0,0 +1,149 @@ @@ -1675,7 +1661,7 @@ index 0000000000..305da47868 + + final PlayerChunkMap chunkManager = this.world.getChunkProvider().playerChunkMap; + -+ try (Timing ignored = this.world.timings.chunkIOStage1.startTimingIfSync()) { ++ try (Timing ignored = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { + final ChunkRegionLoader.InProgressChunkHolder chunkHolder; + + // apply fixes @@ -2399,7 +2385,7 @@ index 0000000000..2b20c159f6 + +} diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 5e4f3612ba..5b10562369 100644 +index 4c9c8e4839..259af7095c 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -299,11 +299,137 @@ public class ChunkProviderServer extends IChunkProvider { @@ -2548,10 +2534,10 @@ index 5e4f3612ba..5b10562369 100644 + this.world.asyncChunkTaskManager.raisePriority(x, z, com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHEST_PRIORITY); + com.destroystokyo.paper.io.chunk.ChunkTaskManager.pushChunkWait(this.world, x, z); + // Paper end - this.world.timings.chunkAwait.startTiming(); // Paper + this.world.timings.syncChunkLoad.startTiming(); // Paper this.serverThreadQueue.awaitTasks(completablefuture::isDone); + com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug - this.world.timings.chunkAwait.stopTiming(); // Paper + this.world.timings.syncChunkLoad.stopTiming(); // Paper } // Paper ichunkaccess = (IChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> { @@ -835,11 +966,12 @@ public class ChunkProviderServer extends IChunkProvider { @@ -2569,7 +2555,7 @@ index 5e4f3612ba..5b10562369 100644 } finally { playerChunkMap.callbackExecutor.run(); diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -index 8816c90e2d..1298a07dc7 100644 +index 79e85520f3..7389aba1a4 100644 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java @@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.longs.LongOpenHashSet; @@ -3113,7 +3099,7 @@ index f1620ba80e..74e6b8b973 100644 completablefuture = (CompletableFuture) this.statusFutures.get(i); if (completablefuture != null) { diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index b4c9d544fe..c4fb0c68dd 100644 +index 9c627bf3b4..19603343b2 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -63,7 +63,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -3284,36 +3270,37 @@ index b4c9d544fe..c4fb0c68dd 100644 - return CompletableFuture.supplyAsync(() -> { + // Paper start - Async chunk io + final java.util.function.BiFunction> syncLoadComplete = (chunkHolder, ioThrowable) -> { - try (Timing ignored = this.world.timings.syncChunkLoadTimer.startTimingIfSync()) { // Paper + try (Timing ignored = this.world.timings.chunkLoad.startTimingIfSync()) { // Paper this.world.getMethodProfiler().c("chunkLoad"); - NBTTagCompound nbttagcompound; // Paper -- try (Timing ignored2 = this.world.timings.chunkIOStage1.startTimingIfSync()) { // Paper start - timings +- try (Timing ignored2 = this.world.timings.chunkIO.startTimingIfSync()) { // Paper start - timings - nbttagcompound = this.readChunkData(chunkcoordintpair); - } // Paper end - -- if (nbttagcompound != null) { +- if (nbttagcompound != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings - boolean flag = nbttagcompound.hasKeyOfType("Level", 10) && nbttagcompound.getCompound("Level").hasKeyOfType("Status", 8); +- +- if (flag) { +- ProtoChunk protochunk = ChunkRegionLoader.loadChunk(this.world, this.definedStructureManager, this.m, chunkcoordintpair, nbttagcompound); + if (ioThrowable != null) { + com.destroystokyo.paper.io.IOUtil.rethrow(ioThrowable); + } -- if (flag) { -- ProtoChunk protochunk = ChunkRegionLoader.loadChunk(this.world, this.definedStructureManager, this.m, chunkcoordintpair, nbttagcompound); +- protochunk.setLastSaved(this.world.getTime()); +- return Either.left(protochunk); +- } + this.getVillagePlace().loadInData(chunkcoordintpair, chunkHolder.poiData); + chunkHolder.tasks.forEach(Runnable::run); + // Paper - async load completes this + // Paper end -- protochunk.setLastSaved(this.world.getTime()); -- return Either.left(protochunk); -- } -- - PlayerChunkMap.LOGGER.error("Chunk file at {} is missing level data, skipping", chunkcoordintpair); +- }} // Paper + // Paper start - This is done async + if (chunkHolder.protoChunk != null) { + chunkHolder.protoChunk.setLastSaved(this.world.getTime()); + return Either.left(chunkHolder.protoChunk); - } ++ } + // Paper end } catch (ReportedException reportedexception) { Throwable throwable = reportedexception.getCause(); diff --git a/Spigot-Server-Patches/0392-Reduce-sync-loads.patch b/Spigot-Server-Patches/0392-Reduce-sync-loads.patch index 2f3668be60..ea0af7a70c 100644 --- a/Spigot-Server-Patches/0392-Reduce-sync-loads.patch +++ b/Spigot-Server-Patches/0392-Reduce-sync-loads.patch @@ -1,4 +1,4 @@ -From 6e8a1f19c69babcf1acc2a75c5e01d98065e0dbe Mon Sep 17 00:00:00 2001 +From 1f3e0ea68603b51962d92e370949407a4b0e1f6f Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 19 Jul 2019 03:29:14 -0700 Subject: [PATCH] Reduce sync loads @@ -268,7 +268,7 @@ index 0000000000..59aec10329 + } +} diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 5b10562369..db0925f993 100644 +index 259af7095c..ea1117dc86 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -459,6 +459,7 @@ public class ChunkProviderServer extends IChunkProvider { @@ -276,7 +276,7 @@ index 5b10562369..db0925f993 100644 com.destroystokyo.paper.io.chunk.ChunkTaskManager.pushChunkWait(this.world, x, z); // Paper end + com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.world, x, z); // Paper - sync load info - this.world.timings.chunkAwait.startTiming(); // Paper + this.world.timings.syncChunkLoad.startTiming(); // Paper this.serverThreadQueue.awaitTasks(completablefuture::isDone); com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java @@ -328,5 +328,5 @@ index 3db0ad0a46..5f2c425129 100644 // Add env and gen to constructor public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { -- -2.25.1 +2.26.2 diff --git a/Spigot-Server-Patches/0396-implement-optional-per-player-mob-spawns.patch b/Spigot-Server-Patches/0396-implement-optional-per-player-mob-spawns.patch index 251d630f6a..de3b1c9588 100644 --- a/Spigot-Server-Patches/0396-implement-optional-per-player-mob-spawns.patch +++ b/Spigot-Server-Patches/0396-implement-optional-per-player-mob-spawns.patch @@ -1,14 +1,14 @@ -From 76b94acd550514b6c4c6ae226cd9dc63effca302 Mon Sep 17 00:00:00 2001 +From 26d8d9ebbb97baf05b31891140dcee94e88e4619 Mon Sep 17 00:00:00 2001 From: kickash32 Date: Mon, 19 Aug 2019 01:27:58 +0500 Subject: [PATCH] implement optional per player mob spawns diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -index 30bafb214b..c9a3ba4bfb 100644 +index 98acbfa44d..a94ebf7c76 100644 --- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java +++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -@@ -60,6 +60,7 @@ public class WorldTimingsHandler { +@@ -56,6 +56,7 @@ public class WorldTimingsHandler { public final Timing miscMobSpawning; @@ -16,7 +16,7 @@ index 30bafb214b..c9a3ba4bfb 100644 public final Timing poiUnload; public final Timing chunkUnload; -@@ -129,6 +130,7 @@ public class WorldTimingsHandler { +@@ -121,6 +122,7 @@ public class WorldTimingsHandler { miscMobSpawning = Timings.ofSafe(name + "Mob spawning - Misc"); @@ -545,7 +545,7 @@ index 0000000000..4f13d3ff83 + } +} diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index db0925f993..29197d6c8d 100644 +index ea1117dc86..fe894a68bc 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -741,7 +741,22 @@ public class ChunkProviderServer extends IChunkProvider { @@ -643,7 +643,7 @@ index 8427ee2ee8..0f04bcc8b7 100644 return this.bb; } diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 7e5fa016c7..f564502f81 100644 +index 19603343b2..a7b981f299 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -78,7 +78,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -800,5 +800,5 @@ index f9aed78188..fd8ca2a510 100644 @Override -- -2.25.1 +2.26.2 diff --git a/Spigot-Server-Patches/0460-Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch b/Spigot-Server-Patches/0460-Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch index 4014836586..0a3ba2294c 100644 --- a/Spigot-Server-Patches/0460-Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch +++ b/Spigot-Server-Patches/0460-Mid-Tick-Chunk-Tasks-Speed-up-processing-of-chunk-lo.patch @@ -1,4 +1,4 @@ -From fb41ea17cc836804549b69cb7112416be1b156c0 Mon Sep 17 00:00:00 2001 +From 815a77a6e4431669b2b8bc9d1fefd5735403d6c5 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 9 Apr 2020 00:09:26 -0400 Subject: [PATCH] Mid Tick Chunk Tasks - Speed up processing of chunk loads and @@ -42,11 +42,11 @@ index 223d3b1125..37341d2d2e 100644 public static final Timing commandFunctionsTimer = Timings.ofSafe("Command Functions"); public static final Timing connectionTimer = Timings.ofSafe("Connection Handler"); diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java -index 6916ed30c4..1e186f149c 100644 +index f4836e2da1..a6107ba016 100644 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java -@@ -428,4 +428,9 @@ public class PaperConfig { - */ +@@ -414,4 +414,9 @@ public class PaperConfig { + log("Async Chunks: Enabled - Chunks will be loaded much faster, without lag."); } } + @@ -56,7 +56,7 @@ index 6916ed30c4..1e186f149c 100644 + } } diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 3d79e756d9..98ce805a64 100644 +index c457e3b772..747305619b 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -683,6 +683,7 @@ public class ChunkProviderServer extends IChunkProvider { diff --git a/Spigot-Server-Patches/0464-Implement-Chunk-Priority-Urgency-System-for-World-Ge.patch b/Spigot-Server-Patches/0464-Implement-Chunk-Priority-Urgency-System-for-World-Ge.patch index 4de94524b6..cc3eb08863 100644 --- a/Spigot-Server-Patches/0464-Implement-Chunk-Priority-Urgency-System-for-World-Ge.patch +++ b/Spigot-Server-Patches/0464-Implement-Chunk-Priority-Urgency-System-for-World-Ge.patch @@ -1,4 +1,4 @@ -From 3bdf52eb971e76f98beef7dd5bc361e55fce2232 Mon Sep 17 00:00:00 2001 +From 2d591a6ae7d57ecdb73e3af88181f7636c415f7c Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 11 Apr 2020 03:56:07 -0400 Subject: [PATCH] Implement Chunk Priority / Urgency System for World Gen @@ -16,7 +16,7 @@ lots of chunks already. This massively reduces the lag spikes from sync chunk gens. diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index 98ce805a64..640265c3bd 100644 +index 747305619b..746b5b5589 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -308,6 +308,7 @@ public class ChunkProviderServer extends IChunkProvider { @@ -48,7 +48,7 @@ index 98ce805a64..640265c3bd 100644 // Paper end @@ -478,6 +487,11 @@ public class ChunkProviderServer extends IChunkProvider { com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug - this.world.timings.chunkAwait.stopTiming(); // Paper + this.world.timings.syncChunkLoad.stopTiming(); // Paper } // Paper + PlayerChunk playerChunk = this.getChunk(ChunkCoordIntPair.pair(x, z)); + if (playerChunk != null) { @@ -197,7 +197,7 @@ index 04b97cec29..568fbbd5f2 100644 private void d(int i) { diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java -index 90e4811157..0de3f6029c 100644 +index 63969e16aa..377676b94b 100644 --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -324,6 +324,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {