diff --git a/Spigot-API-Patches/0193-Expose-MinecraftServer-isRunning.patch b/Spigot-API-Patches/0194-Expose-MinecraftServer-isRunning.patch similarity index 83% rename from Spigot-API-Patches/0193-Expose-MinecraftServer-isRunning.patch rename to Spigot-API-Patches/0194-Expose-MinecraftServer-isRunning.patch index 6fbda7b505..7f75d592ad 100644 --- a/Spigot-API-Patches/0193-Expose-MinecraftServer-isRunning.patch +++ b/Spigot-API-Patches/0194-Expose-MinecraftServer-isRunning.patch @@ -1,4 +1,4 @@ -From 4cafe0ab6318dce5b1775e57728b433bf581267d Mon Sep 17 00:00:00 2001 +From a5bc4ab211dd7d61537cf330e7092ec28ba18733 Mon Sep 17 00:00:00 2001 From: JRoy Date: Fri, 10 Apr 2020 21:24:35 -0400 Subject: [PATCH] Expose MinecraftServer#isRunning @@ -6,10 +6,10 @@ Subject: [PATCH] Expose MinecraftServer#isRunning This allows for plugins to detect if the server is actually turning off in onDisable rather than just plugins reloading. diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index b9973406..dda12412 100644 +index c3c2d9c6b..ea3e5d6fa 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -1661,6 +1661,15 @@ public final class Bukkit { +@@ -1680,6 +1680,15 @@ public final class Bukkit { public static int getCurrentTick() { return server.getCurrentTick(); } @@ -26,10 +26,10 @@ index b9973406..dda12412 100644 @NotNull diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 80f9abdc..5758ae79 100644 +index bfa83c9bb..9ceaac0e8 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -1455,5 +1455,12 @@ public interface Server extends PluginMessageRecipient { +@@ -1470,5 +1470,12 @@ public interface Server extends PluginMessageRecipient { * @return Current tick */ int getCurrentTick(); @@ -43,5 +43,5 @@ index 80f9abdc..5758ae79 100644 // Paper end } -- -2.17.1 +2.25.1 diff --git a/Spigot-Server-Patches/0392-Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/0392-Asynchronous-chunk-IO-and-loading.patch index 572a60c9e0..97341983eb 100644 --- a/Spigot-Server-Patches/0392-Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/0392-Asynchronous-chunk-IO-and-loading.patch @@ -1,4 +1,4 @@ -From cbcdb57187511c075ce0b1f4ba3add4d57aad890 Mon Sep 17 00:00:00 2001 +From 79568d5d2ba10081b7b930c8b5b3012f22f4d39c 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 @@ -1053,10 +1053,10 @@ index 0000000000..4f10a8311e +} diff --git a/src/main/java/com/destroystokyo/paper/io/PrioritizedTaskQueue.java b/src/main/java/com/destroystokyo/paper/io/PrioritizedTaskQueue.java new file mode 100644 -index 0000000000..78bd238f4c +index 0000000000..97f2e433c4 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/PrioritizedTaskQueue.java -@@ -0,0 +1,276 @@ +@@ -0,0 +1,277 @@ +package com.destroystokyo.paper.io; + +import java.util.concurrent.ConcurrentLinkedQueue; @@ -1131,8 +1131,11 @@ index 0000000000..78bd238f4c + * This can also be thrown if the queue has shutdown. + */ + public void add(final T task) throws IllegalStateException { -+ task.onQueue(this); -+ this.queues[task.getPriority()].add(task); ++ int priority = task.getPriority(); ++ if (priority != COMPLETING_PRIORITY) { ++ task.setQueue(this); ++ this.queues[priority].add(task); ++ } + if (this.shutdown.get()) { + // note: we're not actually sure at this point if our task will go through + throw new IllegalStateException("Queue has shutdown, refusing to execute task " + IOUtil.genericToString(task)); @@ -1309,10 +1312,8 @@ index 0000000000..78bd238f4c + } + } + -+ void onQueue(final PrioritizedTaskQueue queue) { -+ if (this.queue.getAndSet(queue) != null) { -+ throw new IllegalStateException("Already queued!"); -+ } ++ void setQueue(final PrioritizedTaskQueue queue) { ++ this.queue.set(queue); + } + + /* priority */ @@ -1901,10 +1902,10 @@ index 0000000000..1dfa8abfd8 +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java new file mode 100644 -index 0000000000..715a2dd8d2 +index 0000000000..e8282e9781 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java -@@ -0,0 +1,455 @@ +@@ -0,0 +1,492 @@ +package com.destroystokyo.paper.io.chunk; + +import com.destroystokyo.paper.io.PaperFileIOThread; @@ -1941,7 +1942,9 @@ index 0000000000..715a2dd8d2 + private final PrioritizedTaskQueue chunkTasks = new PrioritizedTaskQueue<>(); // used if async chunks are disabled in config + + protected static QueueExecutorThread[] globalWorkers; ++ protected static QueueExecutorThread globalUrgentWorker; + protected static PrioritizedTaskQueue globalQueue; ++ protected static PrioritizedTaskQueue globalUrgentQueue; + + protected static final ConcurrentLinkedQueue CHUNK_WAIT_QUEUE = new ConcurrentLinkedQueue<>(); + @@ -2023,6 +2026,7 @@ index 0000000000..715a2dd8d2 + + globalWorkers = new QueueExecutorThread[threads]; + globalQueue = new PrioritizedTaskQueue<>(); ++ globalUrgentQueue = new PrioritizedTaskQueue<>(); + + for (int i = 0; i < threads; ++i) { + globalWorkers[i] = new QueueExecutorThread<>(globalQueue, (long)0.10e6); //0.1ms @@ -2034,6 +2038,15 @@ index 0000000000..715a2dd8d2 + + globalWorkers[i].start(); + } ++ ++ globalUrgentWorker = new QueueExecutorThread<>(globalUrgentQueue, (long)0.10e6); //0.1ms ++ globalUrgentWorker.setName("Paper Async Chunk Urgent Task Thread"); ++ globalUrgentWorker.setPriority(Thread.NORM_PRIORITY+1); ++ globalUrgentWorker.setUncaughtExceptionHandler((final Thread thread, final Throwable throwable) -> { ++ PaperFileIOThread.LOGGER.fatal("Thread '" + thread.getName() + "' threw an uncaught exception!", throwable); ++ }); ++ ++ globalUrgentWorker.start(); + } + + /** @@ -2284,6 +2297,7 @@ index 0000000000..715a2dd8d2 + worker.flush(); + } + } ++ globalUrgentWorker.flush(); + + // flush again since tasks we execute async saves + drainChunkWaitQueue(); @@ -2316,20 +2330,30 @@ index 0000000000..715a2dd8d2 + public void raisePriority(final int chunkX, final int chunkZ, final int priority) { + final Long chunkKey = Long.valueOf(IOUtil.getCoordinateKey(chunkX, chunkZ)); + -+ ChunkSaveTask chunkSaveTask = this.chunkSaveTasks.get(chunkKey); ++ ChunkTask chunkSaveTask = this.chunkSaveTasks.get(chunkKey); + if (chunkSaveTask != null) { -+ final boolean raised = chunkSaveTask.raisePriority(priority); -+ if (chunkSaveTask.isScheduled() && raised) { -+ // only notify if we're in queue to be executed -+ this.internalScheduleNotify(); -+ } ++ // don't bump save into urgent queue ++ raiseTaskPriority(chunkSaveTask, priority != PrioritizedTaskQueue.HIGHEST_PRIORITY ? priority : PrioritizedTaskQueue.HIGH_PRIORITY); + } + + ChunkLoadTask chunkLoadTask = this.chunkLoadTasks.get(chunkKey); + if (chunkLoadTask != null) { -+ final boolean raised = chunkLoadTask.raisePriority(priority); -+ if (chunkLoadTask.isScheduled() && raised) { -+ // only notify if we're in queue to be executed ++ raiseTaskPriority(chunkLoadTask, priority); ++ } ++ } ++ ++ private void raiseTaskPriority(ChunkTask task, int priority) { ++ final boolean raised = task.raisePriority(priority); ++ if (task.isScheduled() && raised) { ++ // only notify if we're in queue to be executed ++ if (priority == PrioritizedTaskQueue.HIGHEST_PRIORITY) { ++ // was in another queue but became urgent later, add to urgent queue and the previous ++ // queue will just have to ignore this task if it has already been started. ++ // Ultimately, we now have 2 potential queues that can pull it out whoever gets it first ++ // but the urgent queue has dedicated thread(s) so it's likely to win.... ++ globalUrgentQueue.add(task); ++ this.internalScheduleNotifyUrgent(); ++ } else { + this.internalScheduleNotify(); + } + } @@ -2343,8 +2367,14 @@ index 0000000000..715a2dd8d2 + + // It's important we order the task to be executed before notifying. Avoid a race condition where the worker thread + // wakes up and goes to sleep before we actually schedule (or it's just about to sleep) -+ this.queue.add(task); -+ this.internalScheduleNotify(); ++ if (task.getPriority() == PrioritizedTaskQueue.HIGHEST_PRIORITY) { ++ globalUrgentQueue.add(task); ++ this.internalScheduleNotifyUrgent(); ++ } else { ++ this.queue.add(task); ++ this.internalScheduleNotify(); ++ } ++ + } + + protected void internalScheduleNotify() { @@ -2359,6 +2389,14 @@ index 0000000000..715a2dd8d2 + } + } + ++ ++ protected void internalScheduleNotifyUrgent() { ++ if (globalUrgentWorker == null) { ++ return; ++ } ++ globalUrgentWorker.notifyTasks(); ++ } ++ +} diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java index b582171c51..03d7ce8294 100644 @@ -2800,7 +2838,7 @@ index a950ad801d..26f1a4b095 100644 nbttagcompound1.set("PostProcessing", a(ichunkaccess.l())); diff --git a/src/main/java/net/minecraft/server/ChunkStatus.java b/src/main/java/net/minecraft/server/ChunkStatus.java -index 134a4f0b7d..88f1674616 100644 +index 134a4f0b7d..40ce30cdc2 100644 --- a/src/main/java/net/minecraft/server/ChunkStatus.java +++ b/src/main/java/net/minecraft/server/ChunkStatus.java @@ -153,6 +153,7 @@ public class ChunkStatus { @@ -2811,6 +2849,30 @@ index 134a4f0b7d..88f1674616 100644 public static int a(ChunkStatus chunkstatus) { return ChunkStatus.r.getInt(chunkstatus.c()); } +@@ -168,6 +169,7 @@ public class ChunkStatus { + this.t = chunkstatus == null ? 0 : chunkstatus.c() + 1; + } + ++ public int getStatusIndex() { return c(); } // Paper - OBFHELPER + public int c() { + return this.t; + } +@@ -189,6 +191,7 @@ public class ChunkStatus { + return this.w.doWork(this, worldserver, definedstructuremanager, lightenginethreaded, function, ichunkaccess); + } + ++ public int getNeighborRadius() { return this.f(); } // Paper - OBFHELPER + public int f() { + return this.x; + } +@@ -216,6 +219,7 @@ public class ChunkStatus { + return this.z; + } + ++ public boolean isAtLeastStatus(ChunkStatus chunkstatus) { return b(chunkstatus); } // Paper - OBFHELPER + public boolean b(ChunkStatus chunkstatus) { + return this.c() >= chunkstatus.c(); + } diff --git a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java index 7e5ece9d50..cfe43e882e 100644 --- a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java @@ -3055,7 +3117,7 @@ index 50135446f7..b38bc67758 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 7dec34cb76..893c542f57 100644 +index b4c9d544fe..7e5fa016c7 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 { diff --git a/Spigot-Server-Patches/0460-Add-tick-times-API-and-mspt-command.patch b/Spigot-Server-Patches/0464-Add-tick-times-API-and-mspt-command.patch similarity index 94% rename from Spigot-Server-Patches/0460-Add-tick-times-API-and-mspt-command.patch rename to Spigot-Server-Patches/0464-Add-tick-times-API-and-mspt-command.patch index f218762545..c834ec9b41 100644 --- a/Spigot-Server-Patches/0460-Add-tick-times-API-and-mspt-command.patch +++ b/Spigot-Server-Patches/0464-Add-tick-times-API-and-mspt-command.patch @@ -1,4 +1,4 @@ -From b27e5e76fb9039e25e502f831badc083d73afbf7 Mon Sep 17 00:00:00 2001 +From cfb50538f4ae30ec9bef1c562944e001e795b106 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 5 Apr 2020 22:23:14 -0500 Subject: [PATCH] Add tick times API and /mspt command @@ -6,7 +6,7 @@ Subject: [PATCH] Add tick times API and /mspt command diff --git a/src/main/java/com/destroystokyo/paper/MSPTCommand.java b/src/main/java/com/destroystokyo/paper/MSPTCommand.java new file mode 100644 -index 000000000..d0211d4f3 +index 0000000000..d0211d4f39 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/MSPTCommand.java @@ -0,0 +1,64 @@ @@ -75,7 +75,7 @@ index 000000000..d0211d4f3 + } +} diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java -index 6916ed30c..1c4cd3635 100644 +index 6916ed30c4..1c4cd36351 100644 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java @@ -70,6 +70,7 @@ public class PaperConfig { @@ -87,7 +87,7 @@ index 6916ed30c..1c4cd3635 100644 version = getInt("config-version", 20); set("config-version", 20); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index c9deaffc4..9e5d569f7 100644 +index 936434110c..2686874f26 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -106,6 +106,11 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant Date: Fri, 10 Apr 2020 21:24:12 -0400 Subject: [PATCH] Expose MinecraftServer#isRunning @@ -6,10 +6,10 @@ Subject: [PATCH] Expose MinecraftServer#isRunning This allows for plugins to detect if the server is actually turning off in onDisable rather than just plugins reloading. diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index b9a398bc5..32121e87b 100644 +index 53b71b7915..1a3c6aae18 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -2207,5 +2207,10 @@ public final class CraftServer implements Server { +@@ -2217,5 +2217,10 @@ public final class CraftServer implements Server { public int getCurrentTick() { return net.minecraft.server.MinecraftServer.currentTick; } @@ -21,5 +21,5 @@ index b9a398bc5..32121e87b 100644 // Paper end } -- -2.17.1 +2.25.1