From a2459e30fd85fc1b6ee0253afc76024a8bd01561 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Sun, 14 May 2017 14:49:56 +0100 Subject: [PATCH] Allow the watchdog to try sanely stopping the server --- .../0018-Add-exception-reporting-event.patch | 28 +-- .../0028-Access-items-by-EquipmentSlot.patch | 6 +- ...ent-to-allow-plugins-to-handle-clien.patch | 2 +- .../0044-Use-UserCache-for-player-heads.patch | 2 +- .../0045-Disable-spigot-tick-limiters.patch | 2 +- ...figurable-Chunk-IO-Thread-Base-Count.patch | 2 +- .../0047-Add-PlayerInitialSpawnEvent.patch | 4 +- .../0048-Disable-chest-cat-detection.patch | 4 +- ...49-Ensure-commands-are-not-ran-async.patch | 6 +- ...chunks-are-slime-spawn-chunks-toggle.patch | 4 +- .../0051-Optimize-Pathfinding.patch | 4 +- ...opper-searches-if-there-are-no-items.patch | 4 +- .../0053-Expose-server-CommandMap.patch | 4 +- ...e-informative-in-maxHealth-exception.patch | 2 +- ...le-async-calls-to-restart-the-server.patch | 228 ++++++++++++++++-- 15 files changed, 239 insertions(+), 63 deletions(-) diff --git a/Spigot-API-Patches/0018-Add-exception-reporting-event.patch b/Spigot-API-Patches/0018-Add-exception-reporting-event.patch index 9db0939737..ff5143c511 100644 --- a/Spigot-API-Patches/0018-Add-exception-reporting-event.patch +++ b/Spigot-API-Patches/0018-Add-exception-reporting-event.patch @@ -1,4 +1,4 @@ -From f3ef3ba155ffb8398e2f421fb0ccb0df8b857c4e Mon Sep 17 00:00:00 2001 +From 7155b06489e081b18b19b4f122dcd73cce84dffb Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 29 Feb 2016 20:24:35 -0600 Subject: [PATCH] Add exception reporting event @@ -6,7 +6,7 @@ Subject: [PATCH] Add exception reporting event diff --git a/src/main/java/com/destroystokyo/paper/event/server/ServerExceptionEvent.java b/src/main/java/com/destroystokyo/paper/event/server/ServerExceptionEvent.java new file mode 100644 -index 0000000..4109454 +index 00000000..4109454a --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/event/server/ServerExceptionEvent.java @@ -0,0 +1,37 @@ @@ -49,7 +49,7 @@ index 0000000..4109454 +} diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerCommandException.java b/src/main/java/com/destroystokyo/paper/exception/ServerCommandException.java new file mode 100644 -index 0000000..6fb39af +index 00000000..6fb39af0 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/exception/ServerCommandException.java @@ -0,0 +1,64 @@ @@ -119,7 +119,7 @@ index 0000000..6fb39af +} diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerEventException.java b/src/main/java/com/destroystokyo/paper/exception/ServerEventException.java new file mode 100644 -index 0000000..410b241 +index 00000000..410b2413 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/exception/ServerEventException.java @@ -0,0 +1,52 @@ @@ -177,7 +177,7 @@ index 0000000..410b241 +} diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerException.java b/src/main/java/com/destroystokyo/paper/exception/ServerException.java new file mode 100644 -index 0000000..c06ea39 +index 00000000..c06ea394 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/exception/ServerException.java @@ -0,0 +1,23 @@ @@ -206,7 +206,7 @@ index 0000000..c06ea39 +} diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerInternalException.java b/src/main/java/com/destroystokyo/paper/exception/ServerInternalException.java new file mode 100644 -index 0000000..e762ed0 +index 00000000..e762ed0d --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/exception/ServerInternalException.java @@ -0,0 +1,35 @@ @@ -247,7 +247,7 @@ index 0000000..e762ed0 +} diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerPluginEnableDisableException.java b/src/main/java/com/destroystokyo/paper/exception/ServerPluginEnableDisableException.java new file mode 100644 -index 0000000..f016ba3 +index 00000000..f016ba3b --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/exception/ServerPluginEnableDisableException.java @@ -0,0 +1,20 @@ @@ -274,7 +274,7 @@ index 0000000..f016ba3 \ No newline at end of file diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerPluginException.java b/src/main/java/com/destroystokyo/paper/exception/ServerPluginException.java new file mode 100644 -index 0000000..6defac2 +index 00000000..6defac28 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/exception/ServerPluginException.java @@ -0,0 +1,38 @@ @@ -318,7 +318,7 @@ index 0000000..6defac2 +} diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerPluginMessageException.java b/src/main/java/com/destroystokyo/paper/exception/ServerPluginMessageException.java new file mode 100644 -index 0000000..89e1325 +index 00000000..89e13252 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/exception/ServerPluginMessageException.java @@ -0,0 +1,64 @@ @@ -388,7 +388,7 @@ index 0000000..89e1325 +} diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerSchedulerException.java b/src/main/java/com/destroystokyo/paper/exception/ServerSchedulerException.java new file mode 100644 -index 0000000..2d0b2d4 +index 00000000..2d0b2d4a --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/exception/ServerSchedulerException.java @@ -0,0 +1,37 @@ @@ -431,7 +431,7 @@ index 0000000..2d0b2d4 +} diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerTabCompleteException.java b/src/main/java/com/destroystokyo/paper/exception/ServerTabCompleteException.java new file mode 100644 -index 0000000..5582999 +index 00000000..5582999f --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/exception/ServerTabCompleteException.java @@ -0,0 +1,22 @@ @@ -458,7 +458,7 @@ index 0000000..5582999 + } +} diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java -index 466757b..08976cd 100644 +index 466757b9..08976cd4 100644 --- a/src/main/java/org/bukkit/command/SimpleCommandMap.java +++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java @@ -10,6 +10,9 @@ import java.util.List; @@ -494,7 +494,7 @@ index 466757b..08976cd 100644 } diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java -index 4ee123e..1302773 100644 +index ffb68704..d1f7cdde 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -18,6 +18,9 @@ import java.util.logging.Level; @@ -587,5 +587,5 @@ index 4ee123e..1302773 100644 } } -- -2.9.2.windows.1 +2.12.2 diff --git a/Spigot-API-Patches/0028-Access-items-by-EquipmentSlot.patch b/Spigot-API-Patches/0028-Access-items-by-EquipmentSlot.patch index 85b929cdc2..ca3514dd90 100644 --- a/Spigot-API-Patches/0028-Access-items-by-EquipmentSlot.patch +++ b/Spigot-API-Patches/0028-Access-items-by-EquipmentSlot.patch @@ -1,11 +1,11 @@ -From 261076ee6c8f78815af83409d38da123ad3073c3 Mon Sep 17 00:00:00 2001 +From 26190b10232f54bf47faaa9280b87067cb355aa2 Mon Sep 17 00:00:00 2001 From: Jedediah Smith Date: Sun, 20 Mar 2016 06:44:49 -0400 Subject: [PATCH] Access items by EquipmentSlot diff --git a/src/main/java/org/bukkit/inventory/PlayerInventory.java b/src/main/java/org/bukkit/inventory/PlayerInventory.java -index 557cc04..799f150 100644 +index 557cc04d..799f1506 100644 --- a/src/main/java/org/bukkit/inventory/PlayerInventory.java +++ b/src/main/java/org/bukkit/inventory/PlayerInventory.java @@ -211,4 +211,22 @@ public interface PlayerInventory extends Inventory { @@ -32,5 +32,5 @@ index 557cc04..799f150 100644 + // Paper end } -- -2.9.2.windows.1 +2.12.2 diff --git a/Spigot-API-Patches/0034-Add-handshake-event-to-allow-plugins-to-handle-clien.patch b/Spigot-API-Patches/0034-Add-handshake-event-to-allow-plugins-to-handle-clien.patch index 880b57f1bd..cb2729053c 100644 --- a/Spigot-API-Patches/0034-Add-handshake-event-to-allow-plugins-to-handle-clien.patch +++ b/Spigot-API-Patches/0034-Add-handshake-event-to-allow-plugins-to-handle-clien.patch @@ -1,4 +1,4 @@ -From 15b47a774783a9db24c742bb1fde6bb7c6404638 Mon Sep 17 00:00:00 2001 +From 0c052b19800312a88135b490c5054f15de4c1745 Mon Sep 17 00:00:00 2001 From: kashike Date: Wed, 13 Apr 2016 20:20:18 -0700 Subject: [PATCH] Add handshake event to allow plugins to handle client diff --git a/Spigot-Server-Patches/0044-Use-UserCache-for-player-heads.patch b/Spigot-Server-Patches/0044-Use-UserCache-for-player-heads.patch index f066f3e7f5..8582f86cfc 100644 --- a/Spigot-Server-Patches/0044-Use-UserCache-for-player-heads.patch +++ b/Spigot-Server-Patches/0044-Use-UserCache-for-player-heads.patch @@ -1,4 +1,4 @@ -From bf24caf82339d24a9c4a6fd4ef31cdb3c7496d1b Mon Sep 17 00:00:00 2001 +From dec1d0f854ae03840844ad4e2694ee88c9fffae0 Mon Sep 17 00:00:00 2001 From: Techcable Date: Wed, 2 Mar 2016 23:42:37 -0600 Subject: [PATCH] Use UserCache for player heads diff --git a/Spigot-Server-Patches/0045-Disable-spigot-tick-limiters.patch b/Spigot-Server-Patches/0045-Disable-spigot-tick-limiters.patch index f2c6ede52b..8ecb7989e6 100644 --- a/Spigot-Server-Patches/0045-Disable-spigot-tick-limiters.patch +++ b/Spigot-Server-Patches/0045-Disable-spigot-tick-limiters.patch @@ -1,4 +1,4 @@ -From bf5743f31df9d1cd46c219f13808a0063a09e6b0 Mon Sep 17 00:00:00 2001 +From 665ac161d0b041435b72526bb71f61665d243981 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 2 Mar 2016 23:45:17 -0600 Subject: [PATCH] Disable spigot tick limiters diff --git a/Spigot-Server-Patches/0046-Configurable-Chunk-IO-Thread-Base-Count.patch b/Spigot-Server-Patches/0046-Configurable-Chunk-IO-Thread-Base-Count.patch index f56abd6ec7..73f07024cb 100644 --- a/Spigot-Server-Patches/0046-Configurable-Chunk-IO-Thread-Base-Count.patch +++ b/Spigot-Server-Patches/0046-Configurable-Chunk-IO-Thread-Base-Count.patch @@ -1,4 +1,4 @@ -From e576a2e6f75c9065ff77b0d808d9deb8828c2a2a Mon Sep 17 00:00:00 2001 +From 2779ccb7bac4216609527d97a4dfd10af2dd1161 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 2 Mar 2016 23:46:57 -0600 Subject: [PATCH] Configurable Chunk IO Thread Base Count diff --git a/Spigot-Server-Patches/0047-Add-PlayerInitialSpawnEvent.patch b/Spigot-Server-Patches/0047-Add-PlayerInitialSpawnEvent.patch index dd0cd845af..d710115319 100644 --- a/Spigot-Server-Patches/0047-Add-PlayerInitialSpawnEvent.patch +++ b/Spigot-Server-Patches/0047-Add-PlayerInitialSpawnEvent.patch @@ -1,4 +1,4 @@ -From 5f5ff59c74f2094741e3cf0f5c615d34d2231005 Mon Sep 17 00:00:00 2001 +From 7cac8ec6816a10e2fc0253343ae45abae07b6372 Mon Sep 17 00:00:00 2001 From: Steve Anton Date: Thu, 3 Mar 2016 00:09:38 -0600 Subject: [PATCH] Add PlayerInitialSpawnEvent @@ -32,5 +32,5 @@ index 80bf61164..59c7e78b8 100644 entityplayer.playerInteractManager.a((WorldServer) entityplayer.world); String s1 = "local"; -- -2.12.2.windows.2 +2.12.2 diff --git a/Spigot-Server-Patches/0048-Disable-chest-cat-detection.patch b/Spigot-Server-Patches/0048-Disable-chest-cat-detection.patch index 7636e780aa..dea08ac4c5 100644 --- a/Spigot-Server-Patches/0048-Disable-chest-cat-detection.patch +++ b/Spigot-Server-Patches/0048-Disable-chest-cat-detection.patch @@ -1,4 +1,4 @@ -From d76321993eecd60cc0a0410ff8b45a0303134b81 Mon Sep 17 00:00:00 2001 +From c498e6be94f4c593eddc5a0f928f42f30d74d4f4 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 3 Mar 2016 01:13:45 -0600 Subject: [PATCH] Disable chest cat detection @@ -35,5 +35,5 @@ index c75ed8a36..9c4d1c938 100644 EntityOcelot entityocelot; -- -2.12.2.windows.2 +2.12.2 diff --git a/Spigot-Server-Patches/0049-Ensure-commands-are-not-ran-async.patch b/Spigot-Server-Patches/0049-Ensure-commands-are-not-ran-async.patch index ed38f7e4b5..1bbcb64468 100644 --- a/Spigot-Server-Patches/0049-Ensure-commands-are-not-ran-async.patch +++ b/Spigot-Server-Patches/0049-Ensure-commands-are-not-ran-async.patch @@ -1,4 +1,4 @@ -From c121bda3726ac920a54e7d3462c86cc16e114a8c Mon Sep 17 00:00:00 2001 +From 8ce22be35e9a02aa376a84177cb4ee4ec7ba341d Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 3 Mar 2016 01:17:12 -0600 Subject: [PATCH] Ensure commands are not ran async @@ -14,7 +14,7 @@ big slowdown in execution but throwing an exception at same time to raise awaren that it is happening so that plugin authors can fix their code to stop executing commands async. diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 27283efad..57879c76d 100644 +index 0fe8525dc..d983ca5cd 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -1268,6 +1268,29 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { @@ -82,5 +82,5 @@ index 0f77d0674..5302bb283 100644 return true; } -- -2.12.2.windows.2 +2.12.2 diff --git a/Spigot-Server-Patches/0050-All-chunks-are-slime-spawn-chunks-toggle.patch b/Spigot-Server-Patches/0050-All-chunks-are-slime-spawn-chunks-toggle.patch index 1bb8773509..498ebe87a9 100644 --- a/Spigot-Server-Patches/0050-All-chunks-are-slime-spawn-chunks-toggle.patch +++ b/Spigot-Server-Patches/0050-All-chunks-are-slime-spawn-chunks-toggle.patch @@ -1,4 +1,4 @@ -From 6b81f8f28de16733bff9a2d833a2397f6af7fe9e Mon Sep 17 00:00:00 2001 +From 5b82630c76ec77f49dbb00cf894f200fe1fddd13 Mon Sep 17 00:00:00 2001 From: vemacs Date: Thu, 3 Mar 2016 01:19:22 -0600 Subject: [PATCH] All chunks are slime spawn chunks toggle @@ -33,5 +33,5 @@ index 8fb14d6b5..c68429fb1 100644 } } -- -2.12.2.windows.2 +2.12.2 diff --git a/Spigot-Server-Patches/0051-Optimize-Pathfinding.patch b/Spigot-Server-Patches/0051-Optimize-Pathfinding.patch index ddcf2d546f..13a9d0c8e0 100644 --- a/Spigot-Server-Patches/0051-Optimize-Pathfinding.patch +++ b/Spigot-Server-Patches/0051-Optimize-Pathfinding.patch @@ -1,4 +1,4 @@ -From 3cca34b5a315231f82eaf848a700b684e4263560 Mon Sep 17 00:00:00 2001 +From 678f86007ac1d9562ba47b223fa0d0ea7bc0b6d2 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 3 Mar 2016 02:02:07 -0600 Subject: [PATCH] Optimize Pathfinding @@ -47,5 +47,5 @@ index 4f28b8819..43b2be505 100644 } -- -2.12.2.windows.2 +2.12.2 diff --git a/Spigot-Server-Patches/0052-Avoid-hopper-searches-if-there-are-no-items.patch b/Spigot-Server-Patches/0052-Avoid-hopper-searches-if-there-are-no-items.patch index cfa611bb17..7e67522263 100644 --- a/Spigot-Server-Patches/0052-Avoid-hopper-searches-if-there-are-no-items.patch +++ b/Spigot-Server-Patches/0052-Avoid-hopper-searches-if-there-are-no-items.patch @@ -1,4 +1,4 @@ -From 0c1ce95af25b8c95b34c255e9c0a440d64a100d7 Mon Sep 17 00:00:00 2001 +From 0494ae25272ee63d7a9acdfbf988e56a2ec39fd2 Mon Sep 17 00:00:00 2001 From: CullanP Date: Thu, 3 Mar 2016 02:13:38 -0600 Subject: [PATCH] Avoid hopper searches if there are no items @@ -95,5 +95,5 @@ index b80f95159..e1fc4ea6c 100644 while (iterator.hasNext()) { -- -2.12.2.windows.2 +2.12.2 diff --git a/Spigot-Server-Patches/0053-Expose-server-CommandMap.patch b/Spigot-Server-Patches/0053-Expose-server-CommandMap.patch index d6b7155d96..7990fcffff 100644 --- a/Spigot-Server-Patches/0053-Expose-server-CommandMap.patch +++ b/Spigot-Server-Patches/0053-Expose-server-CommandMap.patch @@ -1,4 +1,4 @@ -From bf934f8ce2b8aed42e8412904cf5bd84f5163e3d Mon Sep 17 00:00:00 2001 +From f0e1e045895f33b09daee5f01a956ab63951f7f1 Mon Sep 17 00:00:00 2001 From: kashike Date: Thu, 3 Mar 2016 02:15:57 -0600 Subject: [PATCH] Expose server CommandMap @@ -17,5 +17,5 @@ index 5302bb283..cab671d68 100644 return commandMap; } -- -2.12.2.windows.2 +2.12.2 diff --git a/Spigot-Server-Patches/0054-Be-a-bit-more-informative-in-maxHealth-exception.patch b/Spigot-Server-Patches/0054-Be-a-bit-more-informative-in-maxHealth-exception.patch index f85ff0be80..2a4aa460c1 100644 --- a/Spigot-Server-Patches/0054-Be-a-bit-more-informative-in-maxHealth-exception.patch +++ b/Spigot-Server-Patches/0054-Be-a-bit-more-informative-in-maxHealth-exception.patch @@ -1,4 +1,4 @@ -From e38ec7282ebbcd915a447b0f169b44928de95196 Mon Sep 17 00:00:00 2001 +From fe12f8c9a8953da9282ad24eb1db64ec59b20fcb Mon Sep 17 00:00:00 2001 From: kashike Date: Thu, 3 Mar 2016 02:18:39 -0600 Subject: [PATCH] Be a bit more informative in maxHealth exception diff --git a/Spigot-Server-Patches/0211-Properly-handle-async-calls-to-restart-the-server.patch b/Spigot-Server-Patches/0211-Properly-handle-async-calls-to-restart-the-server.patch index 3f77fc3253..1aedccc7ab 100644 --- a/Spigot-Server-Patches/0211-Properly-handle-async-calls-to-restart-the-server.patch +++ b/Spigot-Server-Patches/0211-Properly-handle-async-calls-to-restart-the-server.patch @@ -1,4 +1,4 @@ -From 2aa53ac9f67c953bdeac7f66834cdf8fb343799d Mon Sep 17 00:00:00 2001 +From 554073bf2250350eccddf53021abab00aa749b5d Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 12 May 2017 23:34:11 -0500 Subject: [PATCH] Properly handle async calls to restart the server @@ -15,14 +15,61 @@ restart command, and adds separate handling for async calls, such as those from the watchdog thread. When calling from the watchdog thread, we cannot assume the main thread is in a -tickable state; it may be completely deadlocked. Therefore, we kill that thread -right then and there. +tickable state; it may be completely deadlocked. In order to handle this, we mark +the server as stopping, in order to account for situations where the server should +complete a tick reasonbly soon, i.e. 99% of cases. + +Should the server not enter a state where it is stopping within 10 seconds, We +will assume that the server has in fact deadlocked and will proceed to force +kill the server. + +This modification does not force restart the server should we actually enter a +deadlocked state where the server is stopping, whereas this will in most cases +exit within a reasonable amount of time, to put a fixed limit on a process that +will have plugins and worlds saving to the disk has a high potential to result +in corruption/dataloss. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 8df30e3d0..df3077c9d 100644 +index 8df30e3d0..9fdd61c7c 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1630,6 +1630,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs +@@ -70,6 +70,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs + public WorldServer[] worldServer; + private PlayerList v; + private boolean isRunning = true; ++ private boolean isRestarting = false; // Paper - flag to signify we're attempting to restart + private boolean isStopped; + private int ticks; + protected final Proxy e; +@@ -488,7 +489,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs + if (this.v != null) { + MinecraftServer.LOGGER.info("Saving players"); + this.v.savePlayers(); +- this.v.u(); ++ this.v.u(isRestarting); + try { Thread.sleep(100); } catch (InterruptedException ex) {} // CraftBukkit - SPIGOT-625 - give server at least a chance to send packets + } + +@@ -545,10 +546,18 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs + return this.isRunning; + } + ++ // Paper start - allow passing of the intent to restart + public void safeShutdown() { ++ safeShutdown(false); ++ } ++ ++ public void safeShutdown(boolean isRestarting) { + this.isRunning = false; ++ this.isRestarting = isRestarting; + } + ++ // Paper end ++ + // Paper start - Further improve server tick loop + private static final int TPS = 20; + private static final long SEC_IN_NANO = 1000000000; +@@ -1630,6 +1639,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs return this.ab; } @@ -30,13 +77,58 @@ index 8df30e3d0..df3077c9d 100644 public Thread aI() { return this.serverThread; } +diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java +index 034bdb7cf..34236c622 100644 +--- a/src/main/java/net/minecraft/server/PlayerList.java ++++ b/src/main/java/net/minecraft/server/PlayerList.java +@@ -1338,10 +1338,15 @@ public abstract class PlayerList { + entityplayer.playerInteractManager.b(world.getWorldData().getGameType()); + } + ++ // Paper start - Extract method to allow for restarting flag + public void u() { ++ u(false); ++ } ++ ++ public void u(boolean isRestarting) { + // CraftBukkit start - disconnect safely + for (EntityPlayer player : this.players) { +- player.playerConnection.disconnect(this.server.server.getShutdownMessage()); // CraftBukkit - add custom shutdown message ++ player.playerConnection.disconnect(!isRestarting ? this.server.server.getShutdownMessage() : org.spigotmc.SpigotConfig.restartMessage); // CraftBukkit - add custom shutdown message // Paper - add isRestarting flag + } + // CraftBukkit end + // Paper start - Remove collideRule team if it exists +@@ -1352,6 +1357,7 @@ public abstract class PlayerList { + } + // Paper end + } ++ // Paper end + + // CraftBukkit start + public void sendMessage(IChatBaseComponent[] iChatBaseComponents) { diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java -index 49768734d..35c828805 100644 +index 49768734d..e1bc3e64e 100644 --- a/src/main/java/org/spigotmc/RestartCommand.java +++ b/src/main/java/org/spigotmc/RestartCommand.java -@@ -52,36 +52,7 @@ public class RestartCommand extends Command - // Disable Watchdog - WatchdogThread.doStop(); +@@ -45,88 +45,119 @@ public class RestartCommand extends Command + AsyncCatcher.enabled = false; // Disable async catcher incase it interferes with us + try + { +- if ( script.isFile() ) +- { +- System.out.println( "Attempting to restart with " + SpigotConfig.restartScript ); ++ // Paper - extract method and cleanup ++ boolean isRestarting = addShutdownHook(script); ++ if (isRestarting) { ++ System.out.println("Attempting to restart with " + SpigotConfig.restartScript); ++ } else { ++ System.out.println( "Startup script '" + SpigotConfig.restartScript + "' does not exist! Stopping server." ); ++ } + +- // Disable Watchdog +- WatchdogThread.doStop(); ++ // Stop the watchdog ++ WatchdogThread.doStop(); - // Kick all players - for ( EntityPlayer p : (List< EntityPlayer>) MinecraftServer.getServer().getPlayerList().players ) @@ -60,7 +152,13 @@ index 49768734d..35c828805 100644 - } catch ( InterruptedException ex ) - { - } -- ++ shutdownServer(isRestarting); ++ } catch ( Exception ex ) ++ { ++ ex.printStackTrace(); ++ } ++ } + - // Actually shutdown - try - { @@ -68,17 +166,8 @@ index 49768734d..35c828805 100644 - } catch ( Throwable t ) - { - } -+ shutdownServer(); // Paper - Moved to function that will handle sync and async - - // This will be done AFTER the server has completely halted - Thread shutdownHook = new Thread() -@@ -129,4 +100,53 @@ public class RestartCommand extends Command - ex.printStackTrace(); - } - } -+ + // Paper start - sync copied from above with minor changes, async added -+ private static void shutdownServer() ++ private static void shutdownServer(boolean isRestarting) + { + if (MinecraftServer.getServer().isMainThread()) + { @@ -94,20 +183,75 @@ index 49768734d..35c828805 100644 + } catch ( InterruptedException ex ) + { + } -+ + +- // This will be done AFTER the server has completely halted +- Thread shutdownHook = new Thread() +- { +- @Override +- public void run() +- { +- try +- { +- String os = System.getProperty( "os.name" ).toLowerCase(java.util.Locale.ENGLISH); +- if ( os.contains( "win" ) ) +- { +- Runtime.getRuntime().exec( "cmd /c start " + script.getPath() ); +- } else +- { +- Runtime.getRuntime().exec( new String[] +- { +- "sh", script.getPath() +- } ); +- } +- } catch ( Exception e ) +- { +- e.printStackTrace(); +- } +- } +- }; + closeSocket(); -+ + +- shutdownHook.setDaemon( true ); +- Runtime.getRuntime().addShutdownHook( shutdownHook ); +- } else + // Actually shutdown + try -+ { + { +- System.out.println( "Startup script '" + SpigotConfig.restartScript + "' does not exist! Stopping server." ); + MinecraftServer.getServer().stop(); + } catch ( Throwable t ) + { + } + } else + { ++ // Mark the server to shutdown at the end of the tick ++ MinecraftServer.getServer().safeShutdown(isRestarting); + +- // Actually shutdown +- try +- { +- MinecraftServer.getServer().stop(); +- } catch ( Throwable t ) +- { +- } ++ ++ // wait 10 seconds to see if we're actually going to try shutdown ++ try ++ { ++ Thread.sleep(10000); ++ } ++ catch (InterruptedException ignored) ++ { + } ++ ++ // Check if we've actually hit a state where the server is going to safely shutdown ++ // if we have, let the server stop as usual ++ if (MinecraftServer.getServer().isStopped()) return; ++ ++ // If the server hasn't stopped by now, assume worse case and kill + closeSocket(); -+ MinecraftServer.getServer().getServerThread().stop(); + System.exit( 0 ); +- } catch ( Exception ex ) + } + } + @@ -118,14 +262,46 @@ index 49768734d..35c828805 100644 + + // Give time for it to kick in + try -+ { + { +- ex.printStackTrace(); + Thread.sleep( 100 ); + } catch ( InterruptedException ex ) + { + } + } + // Paper end ++ ++ // Paper - copied from above and modified to return if the hook registered ++ private static boolean addShutdownHook(final File script) { ++ ++ if (script.isFile()) { ++ Thread shutdownHook = new Thread() { ++ @Override ++ public void run() { ++ try { ++ String os = System.getProperty("os.name").toLowerCase(java.util.Locale.ENGLISH); ++ if (os.contains("win")) { ++ Runtime.getRuntime().exec("cmd /c start " + script.getPath()); ++ } else { ++ Runtime.getRuntime().exec(new String[] ++ { ++ "sh", script.getPath() ++ }); ++ } ++ } catch (Exception e) { ++ e.printStackTrace(); ++ } ++ } ++ }; ++ ++ shutdownHook.setDaemon(true); ++ Runtime.getRuntime().addShutdownHook(shutdownHook); ++ return true; ++ } else { ++ return false; + } + } } -- -2.13.0.windows.1 +2.12.2