aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNassim Jahnke <[email protected]>2024-12-17 13:32:46 +0100
committerNassim Jahnke <[email protected]>2024-12-17 13:32:46 +0100
commit2d83f05a6c5d6323d9b7962654ec21a644343086 (patch)
tree8fc3d33667711150d197c116889aad33975c10c6
parent7daedfcbc3e40875375a6b2b16e37134390c332e (diff)
downloadPaper-2d83f05a6c5d6323d9b7962654ec21a644343086.tar.gz
Paper-2d83f05a6c5d6323d9b7962654ec21a644343086.zip
Update watchdog patches
-rw-r--r--feature-patches/1061-Improved-Watchdog-Support.patch357
-rw-r--r--feature-patches/1062-Detail-more-information-in-watchdog-dumps.patch229
-rw-r--r--paper-server/patches/features/0007-Anti-Xray.patch11
-rw-r--r--paper-server/patches/features/0020-Rewrite-dataconverter-system.patch4
-rw-r--r--paper-server/patches/features/0022-Lag-compensation-ticks.patch6
-rw-r--r--paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch9
-rw-r--r--paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch6
-rw-r--r--paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch3
-rw-r--r--paper-server/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java18
-rw-r--r--paper-server/src/main/java/org/spigotmc/RestartCommand.java2
-rw-r--r--paper-server/src/main/java/org/spigotmc/WatchdogThread.java32
-rw-r--r--paper-server/src/main/resources/log4j2.xml2
12 files changed, 253 insertions, 426 deletions
diff --git a/feature-patches/1061-Improved-Watchdog-Support.patch b/feature-patches/1061-Improved-Watchdog-Support.patch
index 3ed20e43df..90799d6e60 100644
--- a/feature-patches/1061-Improved-Watchdog-Support.patch
+++ b/feature-patches/1061-Improved-Watchdog-Support.patch
@@ -40,25 +40,28 @@ This is to ensure that if main isn't truely stuck, it's not manipulating state w
This also moves all plugins who register "delayed init" tasks to occur just before "Done" so they
are properly accounted for and wont trip watchdog on init.
-diff --git a/src/main/java/io/papermc/paper/util/LogManagerShutdownThread.java b/src/main/java/io/papermc/paper/util/LogManagerShutdownThread.java
+diff --git a/io/papermc/paper/util/LogManagerShutdownThread.java b/io/papermc/paper/util/LogManagerShutdownThread.java
new file mode 100644
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+index 0000000000000000000000000000000000000000..3d7df554b89cff23f64da7ad48b5e4d26ac2baf7
--- /dev/null
-+++ b/src/main/java/io/papermc/paper/util/LogManagerShutdownThread.java
-@@ -0,0 +0,0 @@
++++ b/io/papermc/paper/util/LogManagerShutdownThread.java
+@@ -0,0 +1,29 @@
+package io.papermc.paper.util;
+
-+public class LogManagerShutdownThread extends Thread {
++import org.apache.logging.log4j.LogManager;
++
++public final class LogManagerShutdownThread extends Thread {
+
+ static LogManagerShutdownThread INSTANCE = new LogManagerShutdownThread();
-+ public static final void hook() {
++
++ public static void hook() {
+ if (INSTANCE == null) {
+ throw new IllegalStateException("Cannot re-hook after being unhooked");
+ }
+ Runtime.getRuntime().addShutdownHook(INSTANCE);
+ }
+
-+ public static final void unhook() {
++ public static void unhook() {
+ Runtime.getRuntime().removeShutdownHook(INSTANCE);
+ INSTANCE = null;
+ }
@@ -69,38 +72,38 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ @Override
+ public void run() {
-+ org.apache.logging.log4j.LogManager.shutdown();
++ LogManager.shutdown();
+ }
+}
-diff --git a/src/main/java/net/minecraft/CrashReport.java b/src/main/java/net/minecraft/CrashReport.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/CrashReport.java
-+++ b/src/main/java/net/minecraft/CrashReport.java
-@@ -0,0 +0,0 @@ public class CrashReport {
+diff --git a/net/minecraft/CrashReport.java b/net/minecraft/CrashReport.java
+index 3e0e88afcf010d9a3d46e48bca5cbdf98fe97544..8bd7999c17c8772451f873966f8c90969aee1482 100644
+--- a/net/minecraft/CrashReport.java
++++ b/net/minecraft/CrashReport.java
+@@ -205,6 +205,7 @@ public class CrashReport {
}
- public static CrashReport forThrowable(Throwable cause, String title) {
+ public static CrashReport forThrowable(Throwable cause, String description) {
+ if (cause instanceof ThreadDeath) com.destroystokyo.paper.util.SneakyThrow.sneaky(cause); // Paper
while (cause instanceof CompletionException && cause.getCause() != null) {
cause = cause.getCause();
}
-diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/Main.java
-+++ b/src/main/java/net/minecraft/server/Main.java
-@@ -0,0 +0,0 @@ public class Main {
- @SuppressForbidden(reason = "System.out needed before bootstrap") // CraftBukkit - decompile error
+diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java
+index 4437283a5d157eede121b98be0112c1067eded5e..fc9ec242743f755a1f0c9ec6bccd11c82375d655 100644
+--- a/net/minecraft/server/Main.java
++++ b/net/minecraft/server/Main.java
+@@ -68,6 +68,7 @@ public class Main {
+ )
@DontObfuscate
- public static void main(final OptionSet optionset) { // CraftBukkit - replaces main(String[] astring)
+ public static void main(final OptionSet optionSet) { // CraftBukkit - replaces main(String[] args)
+ io.papermc.paper.util.LogManagerShutdownThread.hook(); // Paper
SharedConstants.tryDetectVersion();
/* CraftBukkit start - Replace everything
- OptionParser optionparser = new OptionParser();
-diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/MinecraftServer.java
-+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ OptionParser optionParser = new OptionParser();
+diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
+index 8aa9ae2925ad44d57a27be3e520fcf20e30237d6..30b2bce976e3bf4c8e0b165cac527a685c02aeb1 100644
+--- a/net/minecraft/server/MinecraftServer.java
++++ b/net/minecraft/server/MinecraftServer.java
+@@ -287,7 +287,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
public int autosavePeriod;
// Paper - don't store the vanilla dispatcher
@@ -109,17 +112,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit end
// Spigot start
public static final int TPS = 20;
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -300,6 +300,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
-
+ public static final long SERVER_INIT = System.nanoTime(); // Paper - Lag compensation
+ public volatile Thread shutdownThread; // Paper
-+ public volatile boolean abnormalExit = false; // Paper
-+
- public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
++ public volatile boolean abnormalExit; // Paper
+
+ public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
- AtomicReference<S> atomicreference = new AtomicReference();
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -393,6 +395,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
*/
// Paper end
@@ -127,7 +129,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this));
// CraftBukkit end
this.paperConfigurations = services.paperConfigurations(); // Paper - add paper configuration files
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -877,6 +880,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// CraftBukkit start
private boolean hasStopped = false;
private boolean hasLoggedStop = false; // Paper - Debugging
@@ -135,7 +137,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private final Object stopLock = new Object();
public final boolean hasStopped() {
synchronized (this.stopLock) {
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -892,6 +896,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.hasStopped = true;
}
if (!hasLoggedStop && isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging
@@ -146,10 +148,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit end
if (this.metricsRecorder.isRecording()) {
this.cancelRecordingMetrics();
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- ca.spottedleaf.moonrise.common.util.MoonriseCommon.haltExecutors();
+@@ -964,6 +972,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ this.getProfileCache().save(false); // Paper - Perf: Async GameProfileCache saving
}
- // Paper end - rewrite chunk system
+ // Spigot end
+ // Paper start - Improved watchdog support - move final shutdown items here
+ Util.shutdownExecutors();
+ try {
@@ -162,7 +164,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public String getLocalIp() {
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1056,6 +1073,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
protected void runServer() {
try {
@@ -170,7 +172,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!this.initServer()) {
throw new IllegalStateException("Failed to initialize server");
}
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1066,6 +1084,17 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.server.spark.enableBeforePlugins(); // Paper - spark
// Spigot start
@@ -188,20 +190,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
org.spigotmc.WatchdogThread.hasStarted = true; // Paper
Arrays.fill( this.recentTps, 20 );
// Paper start - further improve server tick loop
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1155,6 +1184,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
JvmProfiler.INSTANCE.onServerTick(this.smoothedTickTimeMillis);
}
- } catch (Throwable throwable2) {
+ } catch (Throwable var69) {
+ // Paper start
-+ if (throwable2 instanceof ThreadDeath) {
-+ MinecraftServer.LOGGER.error("Main thread terminated by WatchDog due to hard crash", throwable2);
++ if (var69 instanceof ThreadDeath) {
++ MinecraftServer.LOGGER.error("Main thread terminated by WatchDog due to hard crash", var69);
+ return;
+ }
+ // Paper end
- MinecraftServer.LOGGER.error("Encountered an unexpected exception", throwable2);
- CrashReport crashreport = MinecraftServer.constructOrExtractCrashReport(throwable2);
-
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ LOGGER.error("Encountered an unexpected exception", var69);
+ CrashReport crashReport = constructOrExtractCrashReport(var69);
+ this.fillSystemReport(crashReport.getSystemReport());
+@@ -1177,15 +1212,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.services.profileCache().clearExecutor();
}
@@ -219,9 +221,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ //io.papermc.paper.log.CustomLogManager.forceReset(); // Paper - Reset loggers after shutdown
+ //this.onServerExit(); // Paper - moved into stop
}
-
}
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ }
+@@ -1289,6 +1324,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@Override
public TickTask wrapRunnable(Runnable runnable) {
@@ -234,37 +236,37 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return new TickTask(this.tickCount, runnable);
}
-@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
- this.resources.managers.updateStaticRegistryTags();
- this.resources.managers.getRecipeManager().finalizeRecipeLoading(this.worldData.enabledFeatures());
- this.potionBrewing = this.potionBrewing.reload(this.worldData.enabledFeatures()); // Paper - Custom Potion Mixes
-- this.getPlayerList().saveAll();
-+ // Paper start
-+ if (Thread.currentThread() != this.serverThread) {
-+ return;
-+ }
-+ // this.getPlayerList().saveAll(); // Paper - we don't need to save everything, just advancements // TODO Move this to a different patch
-+ for (ServerPlayer player : this.getPlayerList().getPlayers()) {
-+ player.getAdvancements().save();
-+ }
-+ // Paper end
- this.getPlayerList().reloadResources();
- this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary());
- this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager);
-diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
- long j = Util.getNanos() - i;
- String s = String.format(Locale.ROOT, "%.3fs", (double) j / 1.0E9D);
-
-- DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s);
-+ DedicatedServer.LOGGER.info("Done preparing level \"{}\" ({})", this.getLevelIdName(), s); // Paper - clarify startup log messages & add total time
- if (dedicatedserverproperties.announcePlayerAchievements != null) {
- ((GameRules.BooleanValue) this.getGameRules().getRule(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)).set(dedicatedserverproperties.announcePlayerAchievements, this.overworld()); // CraftBukkit - per-world
+@@ -2085,7 +2126,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+ this.resources.managers.updateStaticRegistryTags();
+ this.resources.managers.getRecipeManager().finalizeRecipeLoading(this.worldData.enabledFeatures());
+ this.potionBrewing = this.potionBrewing.reload(this.worldData.enabledFeatures()); // Paper - Custom Potion Mixes
+- this.getPlayerList().saveAll();
++ // Paper start
++ if (Thread.currentThread() != this.serverThread) {
++ return;
++ }
++ // this.getPlayerList().saveAll(); // Paper - we don't need to save everything, just advancements // TODO Move this to a different patch
++ for (ServerPlayer player : this.getPlayerList().getPlayers()) {
++ player.getAdvancements().save();
++ }
++ // Paper end
+ this.getPlayerList().reloadResources();
+ this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary());
+ this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager);
+diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
+index 1ad96b964cdcf10b9f81d32d07e03c1a0ab6fe0a..d51d0c56e0cb68556ad366d52312bdb81ed17e9e 100644
+--- a/net/minecraft/server/dedicated/DedicatedServer.java
++++ b/net/minecraft/server/dedicated/DedicatedServer.java
+@@ -322,7 +322,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+ this.loadLevel(this.storageSource.getLevelId()); // CraftBukkit
+ long l = Util.getNanos() - nanos;
+ String string = String.format(Locale.ROOT, "%.3fs", l / 1.0E9);
+- LOGGER.info("Done ({})! For help, type \"help\"", string);
++ LOGGER.info("Done preparing level \"{}\" ({})", this.getLevelIdName(), string); // Paper - clarify startup log messages & add total time
+ if (properties.announcePlayerAchievements != null) {
+ this.getGameRules().getRule(GameRules.RULE_ANNOUNCE_ADVANCEMENTS).set(properties.announcePlayerAchievements, this.overworld()); // CraftBukkit - per-world
}
-@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+@@ -418,7 +418,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
// this.remoteStatusListener.stop(); // Paper - don't wait for remote connections
}
@@ -274,7 +276,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
@Override
-@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
+@@ -726,7 +727,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@Override
public void stopServer() {
super.stopServer();
@@ -283,173 +285,52 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
SkullBlockEntity.clear();
}
-diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/players/PlayerList.java
-+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
-@@ -0,0 +0,0 @@ public abstract class PlayerList {
+diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
+index d227714de0fe13544779fae6cf0e9ff6af5469c7..393bd2ec0962d3870f5b4cb74200e5467b50cdb8 100644
+--- a/net/minecraft/server/players/PlayerList.java
++++ b/net/minecraft/server/players/PlayerList.java
+@@ -513,7 +513,7 @@ public abstract class PlayerList {
this.cserver.getPluginManager().callEvent(playerQuitEvent);
- entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
+ player.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
-- entityplayer.doTick(); // SPIGOT-924
-+ if (server.isSameThread()) entityplayer.doTick(); // SPIGOT-924 // Paper - don't tick during emergency shutdowns (Watchdog)
+- player.doTick(); // SPIGOT-924
++ if (this.server.isSameThread()) player.doTick(); // SPIGOT-924 // Paper - don't tick during emergency shutdowns (Watchdog)
// CraftBukkit end
// Paper start - Configurable player collision; Remove from collideRule team if needed
-diff --git a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java
-+++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java
-@@ -0,0 +0,0 @@ public abstract class BlockableEventLoop<R extends Runnable> implements Profiler
- public static boolean isNonRecoverable(Throwable exception) {
- return exception instanceof ReportedException reportedException
+diff --git a/net/minecraft/util/thread/BlockableEventLoop.java b/net/minecraft/util/thread/BlockableEventLoop.java
+index 186c1b2e3599770385150eb7acdcd890aa5835eb..bfea9a2ae5e0bd5dae2873f715d192dfcbe97ee5 100644
+--- a/net/minecraft/util/thread/BlockableEventLoop.java
++++ b/net/minecraft/util/thread/BlockableEventLoop.java
+@@ -169,6 +169,6 @@ public abstract class BlockableEventLoop<R extends Runnable> implements Profiler
+ public static boolean isNonRecoverable(Throwable error) {
+ return error instanceof ReportedException reportedException
? isNonRecoverable(reportedException.getCause())
-- : exception instanceof OutOfMemoryError || exception instanceof StackOverflowError;
-+ : exception instanceof OutOfMemoryError || exception instanceof StackOverflowError || exception instanceof ThreadDeath; // Paper
+- : error instanceof OutOfMemoryError || error instanceof StackOverflowError;
++ : error instanceof OutOfMemoryError || error instanceof StackOverflowError || error instanceof ThreadDeath; // Paper
}
}
-diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/Level.java
-+++ b/src/main/java/net/minecraft/world/level/Level.java
-@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
+diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
+index cb6ca60af3d3f90501e4693a78466b9f7462362d..127e25dab3a5e4df9cdf8eefd0485ea07b7696d9 100644
+--- a/net/minecraft/world/level/Level.java
++++ b/net/minecraft/world/level/Level.java
+@@ -863,6 +863,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
try {
- tickConsumer.accept(entity);
- } catch (Throwable throwable) {
-+ if (throwable instanceof ThreadDeath) throw throwable; // Paper
+ consumerEntity.accept(entity);
+ } catch (Throwable var6) {
++ if (var6 instanceof ThreadDeath) throw var6; // Paper
// Paper start - Prevent block entity and entity crashes
final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level().getWorld().getName(), entity.getX(), entity.getY(), entity.getZ());
- MinecraftServer.LOGGER.error(msg, throwable);
-diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
-@@ -0,0 +0,0 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
+ MinecraftServer.LOGGER.error(msg, var6);
+diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
+index d1d0dc13eecb0e0eb3a7839b570a5fe7f62f3fba..205f5a687eb685284a2e403f3eb6bdc694fc5423 100644
+--- a/net/minecraft/world/level/chunk/LevelChunk.java
++++ b/net/minecraft/world/level/chunk/LevelChunk.java
+@@ -855,6 +855,7 @@ public class LevelChunk extends ChunkAccess {
- gameprofilerfiller.pop();
- } catch (Throwable throwable) {
-+ if (throwable instanceof ThreadDeath) throw throwable; // Paper
+ profilerFiller.pop();
+ } catch (Throwable var5) {
++ if (var5 instanceof ThreadDeath) throw var5; // Paper
// Paper start - Prevent block entity and entity crashes
final String msg = String.format("BlockEntity threw exception at %s:%s,%s,%s", LevelChunk.this.getLevel().getWorld().getName(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
- net.minecraft.server.MinecraftServer.LOGGER.error(msg, throwable);
-diff --git a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
-+++ b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
-@@ -0,0 +0,0 @@ public class ServerShutdownThread extends Thread {
- @Override
- public void run() {
- try {
-+ // Paper start - try to shutdown on main
-+ server.safeShutdown(false, false);
-+ for (int i = 1000; i > 0 && !server.hasStopped(); i -= 100) {
-+ Thread.sleep(100);
-+ }
-+ if (server.hasStopped()) {
-+ while (!server.hasFullyShutdown) Thread.sleep(1000);
-+ return;
-+ }
-+ // Looks stalled, close async
- org.spigotmc.AsyncCatcher.enabled = false; // Spigot
-+ server.forceTicks = true;
- this.server.close();
-+ while (!server.hasFullyShutdown) Thread.sleep(1000);
-+ } catch (InterruptedException e) {
-+ e.printStackTrace();
-+ // Paper end
- } finally {
-+ org.apache.logging.log4j.LogManager.shutdown(); // Paper
- try {
-- net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender
-+ //net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Move into stop
- } catch (Exception e) {
- }
- }
-diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/spigotmc/RestartCommand.java
-+++ b/src/main/java/org/spigotmc/RestartCommand.java
-@@ -0,0 +0,0 @@ public class RestartCommand extends Command
- // Paper end
-
- // Paper start - copied from above and modified to return if the hook registered
-- private static boolean addShutdownHook(String restartScript)
-+ public static boolean addShutdownHook(String restartScript) // Paper
- {
- String[] split = restartScript.split( " " );
- if ( split.length > 0 && new File( split[0] ).isFile() )
-diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/spigotmc/WatchdogThread.java
-+++ b/src/main/java/org/spigotmc/WatchdogThread.java
-@@ -0,0 +0,0 @@ import org.bukkit.Bukkit;
- public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThread // Paper - rewrite chunk system
- {
-
-+ public static final boolean DISABLE_WATCHDOG = Boolean.getBoolean("disable.watchdog"); // Paper - Improved watchdog support
- private static WatchdogThread instance;
- private long timeoutTime;
- private boolean restart;
-@@ -0,0 +0,0 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre
- {
- if ( WatchdogThread.instance == null )
- {
-+ if (timeoutTime <= 0) timeoutTime = 300; // Paper
- WatchdogThread.instance = new WatchdogThread( timeoutTime * 1000L, restart );
- WatchdogThread.instance.start();
- } else
-@@ -0,0 +0,0 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre
- // Paper start
- Logger log = Bukkit.getServer().getLogger();
- long currentTime = WatchdogThread.monotonicMillis();
-- if ( this.lastTick != 0 && this.timeoutTime > 0 && currentTime > this.lastTick + this.earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
-+ MinecraftServer server = MinecraftServer.getServer();
-+ if ( this.lastTick != 0 && this.timeoutTime > 0 && WatchdogThread.hasStarted && (!server.isRunning() || (currentTime > this.lastTick + this.earlyWarningEvery && !DISABLE_WATCHDOG) )) // Paper - add property to disable
- {
-- boolean isLongTimeout = currentTime > lastTick + timeoutTime;
-+ boolean isLongTimeout = currentTime > lastTick + timeoutTime || (!server.isRunning() && !server.hasStopped() && currentTime > lastTick + 1000);
- // Don't spam early warning dumps
- if ( !isLongTimeout && (earlyWarningEvery <= 0 || !hasStarted || currentTime < lastEarlyWarning + earlyWarningEvery || currentTime < lastTick + earlyWarningDelay)) continue;
-- if ( !isLongTimeout && MinecraftServer.getServer().hasStopped()) continue; // Don't spam early watchdog warnings during shutdown, we'll come back to this...
-+ if ( !isLongTimeout && server.hasStopped()) continue; // Don't spam early watchdog warnings during shutdown, we'll come back to this...
- lastEarlyWarning = currentTime;
- if (isLongTimeout) {
- // Paper end
-@@ -0,0 +0,0 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre
-
- if ( isLongTimeout )
- {
-- if ( this.restart && !MinecraftServer.getServer().hasStopped() )
-+ if ( !server.hasStopped() )
- {
-- RestartCommand.restart();
-+ AsyncCatcher.enabled = false; // Disable async catcher incase it interferes with us
-+ server.forceTicks = true;
-+ if (restart) {
-+ RestartCommand.addShutdownHook( SpigotConfig.restartScript );
-+ }
-+ // try one last chance to safe shutdown on main incase it 'comes back'
-+ server.abnormalExit = true;
-+ server.safeShutdown(false, restart);
-+ try {
-+ Thread.sleep(1000);
-+ } catch (InterruptedException e) {
-+ e.printStackTrace();
-+ }
-+ if (!server.hasStopped()) {
-+ server.close();
-+ }
- }
- break;
- } // Paper end
-diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/resources/log4j2.xml
-+++ b/src/main/resources/log4j2.xml
-@@ -0,0 +0,0 @@
- <?xml version="1.0" encoding="UTF-8"?>
--<Configuration status="WARN">
-+<Configuration status="WARN" shutdownHook="disable">
- <Appenders>
- <Queue name="ServerGuiConsole">
- <PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg{nolookups}%n" />
+ net.minecraft.server.MinecraftServer.LOGGER.error(msg, var5);
diff --git a/feature-patches/1062-Detail-more-information-in-watchdog-dumps.patch b/feature-patches/1062-Detail-more-information-in-watchdog-dumps.patch
index 9d5a4deee3..20f825b57b 100644
--- a/feature-patches/1062-Detail-more-information-in-watchdog-dumps.patch
+++ b/feature-patches/1062-Detail-more-information-in-watchdog-dumps.patch
@@ -6,32 +6,55 @@ Subject: [PATCH] Detail more information in watchdog dumps
- Dump position, world, velocity, and uuid for currently ticking entities
- Dump player name, player uuid, position, and world for packet handling
-diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/network/Connection.java
-+++ b/src/main/java/net/minecraft/network/Connection.java
-@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
+diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
+index 8fe485c5bf79804bb4d1f774f95a92b14a576e80..0bcae6256d3b3fb6b2e0c2f23907d4659b236ef3 100644
+--- a/net/minecraft/network/Connection.java
++++ b/net/minecraft/network/Connection.java
+@@ -603,7 +603,13 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
if (!(this.packetListener instanceof net.minecraft.server.network.ServerLoginPacketListenerImpl loginPacketListener)
|| loginPacketListener.state != net.minecraft.server.network.ServerLoginPacketListenerImpl.State.VERIFYING
|| Connection.joinAttemptsThisTick++ < MAX_PER_TICK) {
+ // Paper start - detailed watchdog information
+ net.minecraft.network.protocol.PacketUtils.packetProcessing.push(this.packetListener);
+ try {
- tickablepacketlistener.tick();
+ tickablePacketListener.tick();
+ } finally {
+ net.minecraft.network.protocol.PacketUtils.packetProcessing.pop();
+ } // Paper end - detailed watchdog information
} // Paper end - Buffer joins to world
}
-diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java
-+++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java
-@@ -0,0 +0,0 @@ public class PacketUtils {
-
- private static final Logger LOGGER = LogUtils.getLogger();
+diff --git a/net/minecraft/network/protocol/PacketUtils.java b/net/minecraft/network/protocol/PacketUtils.java
+index e65c62dbe4c1560ae153e4c4344e9194c783a2f4..4535858701b2bb232b9d2feb2af6551526232ddc 100644
+--- a/net/minecraft/network/protocol/PacketUtils.java
++++ b/net/minecraft/network/protocol/PacketUtils.java
+@@ -21,6 +21,8 @@ public class PacketUtils {
+ public static <T extends PacketListener> void ensureRunningOnSameThread(Packet<T> packet, T processor, BlockableEventLoop<?> executor) throws RunningOnDifferentThreadException {
+ if (!executor.isSameThread()) {
+ executor.executeIfPossible(() -> {
++ packetProcessing.push(processor); // Paper - detailed watchdog information
++ try { // Paper - detailed watchdog information
+ if (processor instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // Paper - Don't handle sync packets for kicked players
+ if (processor.shouldHandleMessage(packet)) {
+ try {
+@@ -35,6 +37,12 @@ public class PacketUtils {
+ } else {
+ LOGGER.debug("Ignoring packet due to disconnection: {}", packet);
+ }
++ // Paper start - detailed watchdog information
++ } finally {
++ totalMainThreadPacketsProcessed.getAndIncrement();
++ packetProcessing.pop();
++ }
++ // Paper end - detailed watchdog information
+ });
+ throw RunningOnDifferentThreadException.RUNNING_ON_DIFFERENT_THREAD;
+ }
+@@ -61,4 +69,22 @@ public class PacketUtils {
+ packetListener.fillCrashReport(crashReport);
+ }
++
+ // Paper start - detailed watchdog information
+ public static final java.util.concurrent.ConcurrentLinkedDeque<PacketListener> packetProcessing = new java.util.concurrent.ConcurrentLinkedDeque<>();
+ static final java.util.concurrent.atomic.AtomicLong totalMainThreadPacketsProcessed = new java.util.concurrent.atomic.AtomicLong();
@@ -41,46 +64,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+
+ public static java.util.List<PacketListener> getCurrentPacketProcessors() {
-+ java.util.List<PacketListener> ret = new java.util.ArrayList<>(4);
++ java.util.List<PacketListener> listeners = new java.util.ArrayList<>(4);
+ for (PacketListener listener : packetProcessing) {
-+ ret.add(listener);
++ listeners.add(listener);
+ }
+
-+ return ret;
++ return listeners;
+ }
+ // Paper end - detailed watchdog information
-+
- public PacketUtils() {}
-
- public static <T extends PacketListener> void ensureRunningOnSameThread(Packet<T> packet, T listener, ServerLevel world) throws RunningOnDifferentThreadException {
-@@ -0,0 +0,0 @@ public class PacketUtils {
- public static <T extends PacketListener> void ensureRunningOnSameThread(Packet<T> packet, T listener, BlockableEventLoop<?> engine) throws RunningOnDifferentThreadException {
- if (!engine.isSameThread()) {
- engine.executeIfPossible(() -> {
-+ packetProcessing.push(listener); // Paper - detailed watchdog information
-+ try { // Paper - detailed watchdog information
- if (listener instanceof ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // CraftBukkit - Don't handle sync packets for kicked players
- if (listener.shouldHandleMessage(packet)) {
- try {
-@@ -0,0 +0,0 @@ public class PacketUtils {
- } else {
- PacketUtils.LOGGER.debug("Ignoring packet due to disconnection: {}", packet);
- }
-+ // Paper start - detailed watchdog information
-+ } finally {
-+ totalMainThreadPacketsProcessed.getAndIncrement();
-+ packetProcessing.pop();
-+ }
-+ // Paper end - detailed watchdog information
-
- });
- throw RunningOnDifferentThreadException.RUNNING_ON_DIFFERENT_THREAD;
-diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/server/level/ServerLevel.java
-+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
-
+ }
+diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
+index 9cc47bda7197ca3f63b0ede9905c9a13931f84ed..05f45b490e823a455b23b23b26a7da3b447059ea 100644
+--- a/net/minecraft/server/level/ServerLevel.java
++++ b/net/minecraft/server/level/ServerLevel.java
+@@ -956,7 +956,26 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ }
}
+ // Paper start - log detailed entity tick information
@@ -103,13 +101,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ currentlyTickingEntity.lazySet(entity);
+ }
+ // Paper end - log detailed entity tick information
- // Spigot start
- /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out EAR 2
- entity.tickCount++;
-@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ entity.setOldPosAndRot();
+ ProfilerFiller profilerFiller = Profiler.get();
+ entity.tickCount++;
+@@ -972,6 +991,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ for (Entity entity1 : entity.getPassengers()) {
this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
}
-
+ // Paper start - log detailed entity tick information
+ } finally {
+ if (currentlyTickingEntity.get() == entity) {
@@ -119,12 +117,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - log detailed entity tick information
}
- private void tickPassenger(Entity vehicle, Entity passenger, boolean isActive) { // Paper - EAR 2
-diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/entity/Entity.java
-+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ private void tickPassenger(Entity ridingEntity, Entity passengerEntity, final boolean isActive) { // Paper - EAR 2
+diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
+index 5a67aa9f1fe103e5622ed6fa93bc4bc25ddbb688..1ff09959aa95d9822ccb6724bbb3f441c768511a 100644
+--- a/net/minecraft/world/entity/Entity.java
++++ b/net/minecraft/world/entity/Entity.java
+@@ -956,8 +956,43 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return this.onGround;
}
@@ -168,8 +166,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (this.noPhysics) {
this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z);
} else {
-@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
- gameprofilerfiller.pop();
+@@ -1075,6 +1110,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ profilerFiller.pop();
}
}
+ // Paper start - detailed watchdog information
@@ -181,115 +179,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - detailed watchdog information
}
- private void applyMovementEmissionAndPlaySound(Entity.MovementEmission moveEffect, Vec3 movement, BlockPos landingPos, BlockState landingState) {
-@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) {
+@@ -4348,7 +4390,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
- public void setDeltaMovement(Vec3 velocity) {
+ public void setDeltaMovement(Vec3 deltaMovement) {
+ synchronized (this.posLock) { // Paper
- this.deltaMovement = velocity;
+ this.deltaMovement = deltaMovement;
+ } // Paper
}
- public void addDeltaMovement(Vec3 velocity) {
-@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ public void addDeltaMovement(Vec3 addend) {
+@@ -4445,7 +4489,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
// Paper end - Fix MC-4
if (this.position.x != x || this.position.y != y || this.position.z != z) {
+ synchronized (this.posLock) { // Paper
this.position = new Vec3(x, y, z);
+ } // Paper
- int i = Mth.floor(x);
- int j = Mth.floor(y);
- int k = Mth.floor(z);
-diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/org/spigotmc/WatchdogThread.java
-+++ b/src/main/java/org/spigotmc/WatchdogThread.java
-@@ -0,0 +0,0 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre
- private volatile long lastTick;
- private volatile boolean stopping;
-
-+ // Paper start - log detailed tick information
-+ private void dumpEntity(net.minecraft.world.entity.Entity entity) {
-+ Logger log = Bukkit.getServer().getLogger();
-+ double posX, posY, posZ;
-+ net.minecraft.world.phys.Vec3 mot;
-+ double moveStartX, moveStartY, moveStartZ;
-+ net.minecraft.world.phys.Vec3 moveVec;
-+ synchronized (entity.posLock) {
-+ posX = entity.getX();
-+ posY = entity.getY();
-+ posZ = entity.getZ();
-+ mot = entity.getDeltaMovement();
-+ moveStartX = entity.getMoveStartX();
-+ moveStartY = entity.getMoveStartY();
-+ moveStartZ = entity.getMoveStartZ();
-+ moveVec = entity.getMoveVector();
-+ }
-+
-+ String entityType = net.minecraft.world.entity.EntityType.getKey(entity.getType()).toString();
-+ java.util.UUID entityUUID = entity.getUUID();
-+ net.minecraft.world.level.Level world = entity.level();
-+
-+ log.log(Level.SEVERE, "Ticking entity: " + entityType + ", entity class: " + entity.getClass().getName());
-+ log.log(Level.SEVERE, "Entity status: removed: " + entity.isRemoved() + ", valid: " + entity.valid + ", alive: " + entity.isAlive() + ", is passenger: " + entity.isPassenger());
-+ log.log(Level.SEVERE, "Entity UUID: " + entityUUID);
-+ log.log(Level.SEVERE, "Position: world: '" + (world == null ? "unknown world?" : world.getWorld().getName()) + "' at location (" + posX + ", " + posY + ", " + posZ + ")");
-+ log.log(Level.SEVERE, "Velocity: " + (mot == null ? "unknown velocity" : mot.toString()) + " (in blocks per tick)");
-+ log.log(Level.SEVERE, "Entity AABB: " + entity.getBoundingBox());
-+ if (moveVec != null) {
-+ log.log(Level.SEVERE, "Move call information: ");
-+ log.log(Level.SEVERE, "Start position: (" + moveStartX + ", " + moveStartY + ", " + moveStartZ + ")");
-+ log.log(Level.SEVERE, "Move vector: " + moveVec.toString());
-+ }
-+ }
-+
-+ private void dumpTickingInfo() {
-+ Logger log = Bukkit.getServer().getLogger();
-+
-+ // ticking entities
-+ for (net.minecraft.world.entity.Entity entity : net.minecraft.server.level.ServerLevel.getCurrentlyTickingEntities()) {
-+ this.dumpEntity(entity);
-+ net.minecraft.world.entity.Entity vehicle = entity.getVehicle();
-+ if (vehicle != null) {
-+ log.log(Level.SEVERE, "Detailing vehicle for above entity:");
-+ this.dumpEntity(vehicle);
-+ }
-+ }
-+
-+ // packet processors
-+ for (net.minecraft.network.PacketListener packetListener : net.minecraft.network.protocol.PacketUtils.getCurrentPacketProcessors()) {
-+ if (packetListener instanceof net.minecraft.server.network.ServerGamePacketListenerImpl) {
-+ net.minecraft.server.level.ServerPlayer player = ((net.minecraft.server.network.ServerGamePacketListenerImpl)packetListener).player;
-+ long totalPackets = net.minecraft.network.protocol.PacketUtils.getTotalProcessedPackets();
-+ if (player == null) {
-+ log.log(Level.SEVERE, "Handling packet for player connection or ticking player connection (null player): " + packetListener);
-+ log.log(Level.SEVERE, "Total packets processed on the main thread for all players: " + totalPackets);
-+ } else {
-+ this.dumpEntity(player);
-+ net.minecraft.world.entity.Entity vehicle = player.getVehicle();
-+ if (vehicle != null) {
-+ log.log(Level.SEVERE, "Detailing vehicle for above entity:");
-+ this.dumpEntity(vehicle);
-+ }
-+ log.log(Level.SEVERE, "Total packets processed on the main thread for all players: " + totalPackets);
-+ }
-+ } else {
-+ log.log(Level.SEVERE, "Handling packet for connection: " + packetListener);
-+ }
-+ }
-+ }
-+ // Paper end - log detailed tick information
-+
- private WatchdogThread(long timeoutTime, boolean restart)
- {
- super( "Paper Watchdog Thread" );
-@@ -0,0 +0,0 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre
- log.log( Level.SEVERE, "------------------------------" );
- log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
- ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(MinecraftServer.getServer(), isLongTimeout); // Paper - rewrite chunk system
-+ this.dumpTickingInfo(); // Paper - log detailed tick information
- WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
- log.log( Level.SEVERE, "------------------------------" );
- //
+ int floor = Mth.floor(x);
+ int floor1 = Mth.floor(y);
+ int floor2 = Mth.floor(z);
diff --git a/paper-server/patches/features/0007-Anti-Xray.patch b/paper-server/patches/features/0007-Anti-Xray.patch
index b322872f20..8e51f5c6ae 100644
--- a/paper-server/patches/features/0007-Anti-Xray.patch
+++ b/paper-server/patches/features/0007-Anti-Xray.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Anti-Xray
diff --git a/io/papermc/paper/FeatureHooks.java b/io/papermc/paper/FeatureHooks.java
-index aad9d9687dffb872a12ba0ba39d674895b7474e7..764daee7cd619c56314bcea9a4c35702afcb262d 100644
+index 0eba4fce940b90e67f3746480c040178ba9f5525..3bdbd3d566dee767204d898e0bb4f82f0060d9ca 100644
--- a/io/papermc/paper/FeatureHooks.java
+++ b/io/papermc/paper/FeatureHooks.java
@@ -7,6 +7,7 @@ import it.unimi.dsi.fastutil.longs.LongSets;
@@ -16,7 +16,7 @@ index aad9d9687dffb872a12ba0ba39d674895b7474e7..764daee7cd619c56314bcea9a4c35702
import java.util.List;
import java.util.Map;
import java.util.Set;
-@@ -35,20 +36,25 @@ public final class FeatureHooks {
+@@ -36,20 +37,25 @@ public final class FeatureHooks {
}
public static LevelChunkSection createSection(final Registry<Biome> biomeRegistry, final Level level, final ChunkPos chunkPos, final int chunkSection) {
@@ -46,13 +46,6 @@ index aad9d9687dffb872a12ba0ba39d674895b7474e7..764daee7cd619c56314bcea9a4c35702
}
public static Set<Long> getSentChunkKeys(final ServerPlayer player) {
-@@ -74,4 +80,4 @@ public final class FeatureHooks {
- public static boolean isSpiderCollidingWithWorldBorder(final Spider spider) {
- return true; // ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isCollidingWithBorder(spider.level().getWorldBorder(), spider.getBoundingBox().inflate(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON))
- }
--}
-\ No newline at end of file
-+}
diff --git a/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java b/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java
index d4872b7f4e9591b3b1c67406312905851303f521..cb41460e94161675e2ab43f4b1b5286ee38e2e13 100644
--- a/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java
diff --git a/paper-server/patches/features/0020-Rewrite-dataconverter-system.patch b/paper-server/patches/features/0020-Rewrite-dataconverter-system.patch
index 844c0f9320..4e1356ce74 100644
--- a/paper-server/patches/features/0020-Rewrite-dataconverter-system.patch
+++ b/paper-server/patches/features/0020-Rewrite-dataconverter-system.patch
@@ -30621,10 +30621,10 @@ index 1110ca4075a1bbaa46b66686435dab91b275c945..c2218630c3074c8b3f82364e37503b12
return structureTemplate.save(new CompoundTag());
}
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
-index d450d4af96716caff4b29a84d1d83ec4010854f0..646c2f2b617ed706021c83c9fc4492860dfdd4e9 100644
+index 7b233bd4c5c373fe38585e0f8d3e6367dd357741..fd6fdb6d7e15633bd01d4f930ee3b15c0dd2ca06 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
-@@ -301,6 +301,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -303,6 +303,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
diff --git a/paper-server/patches/features/0022-Lag-compensation-ticks.patch b/paper-server/patches/features/0022-Lag-compensation-ticks.patch
index 1d692f7144..50c0323115 100644
--- a/paper-server/patches/features/0022-Lag-compensation-ticks.patch
+++ b/paper-server/patches/features/0022-Lag-compensation-ticks.patch
@@ -8,10 +8,10 @@ Areas affected by lag comepnsation:
- Eating food items
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
-index 646c2f2b617ed706021c83c9fc4492860dfdd4e9..8aa9ae2925ad44d57a27be3e520fcf20e30237d6 100644
+index fd6fdb6d7e15633bd01d4f930ee3b15c0dd2ca06..22dc6bec58702762e4a31415f9aed2df2b3ad0d6 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
-@@ -299,6 +299,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -301,6 +301,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public final io.papermc.paper.configuration.PaperConfigurations paperConfigurations; // Paper - add paper configuration files
public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
@@ -19,7 +19,7 @@ index 646c2f2b617ed706021c83c9fc4492860dfdd4e9..8aa9ae2925ad44d57a27be3e520fcf20
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
-@@ -1564,6 +1565,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
+@@ -1566,6 +1567,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
for (ServerLevel serverLevel : this.getAllLevels()) {
serverLevel.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent
serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent
diff --git a/paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch b/paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch
index 69bf0f769f..5c3b4d6856 100644
--- a/paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch
+++ b/paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch
@@ -1,6 +1,6 @@
--- /dev/null
+++ b/io/papermc/paper/FeatureHooks.java
-@@ -1,0 +_,77 @@
+@@ -1,0 +_,84 @@
+package io.papermc.paper;
+
+import io.papermc.paper.command.PaperSubcommand;
@@ -16,6 +16,7 @@
+import net.minecraft.core.Registry;
+import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
+import net.minecraft.server.level.ServerPlayer;
++import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.monster.Spider;
+import net.minecraft.world.level.ChunkPos;
+import net.minecraft.world.level.Level;
@@ -77,4 +78,10 @@
+ public static boolean isSpiderCollidingWithWorldBorder(final Spider spider) {
+ return true; // ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isCollidingWithBorder(spider.level().getWorldBorder(), spider.getBoundingBox().inflate(ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_EPSILON))
+ }
++
++ public static void dumpTickingInfo() {
++ }
++
++ private static void dumpEntity(final Entity entity) {
++ }
+}
diff --git a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch
index eb9c14d4a5..3aa38008fc 100644
--- a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch
+++ b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch
@@ -41,7 +41,7 @@
@Nullable
private KeyPair keyPair;
@Nullable
-@@ -271,10 +_,33 @@
+@@ -271,10 +_,35 @@
private final SuppressedExceptionCollector suppressedExceptions = new SuppressedExceptionCollector();
private final DiscontinuousFrame tickFrame;
@@ -54,7 +54,7 @@
+ public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
+ public int autosavePeriod;
+ // Paper - don't store the vanilla dispatcher
-+ private boolean forceTicks;
++ public boolean forceTicks;
+ // CraftBukkit end
+ // Spigot start
+ public static final int TPS = 20;
@@ -63,6 +63,8 @@
+ @Deprecated(forRemoval = true) // Paper
+ public final double[] recentTps = new double[ 3 ];
+ // Spigot end
++ public volatile boolean hasFullyShutdown; // Paper - Improved watchdog support
++ public volatile boolean abnormalExit; // Paper - Improved watchdog support
+ public final io.papermc.paper.configuration.PaperConfigurations paperConfigurations; // Paper - add paper configuration files
+ public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
+ private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
diff --git a/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch b/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch
index def9b71a6f..243d71c069 100644
--- a/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch
+++ b/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch
@@ -301,7 +301,7 @@
}
@Override
-@@ -271,12 +_,14 @@
+@@ -271,12 +_,15 @@
}
if (this.rconThread != null) {
@@ -314,6 +314,7 @@
+ // this.remoteStatusListener.stop(); // Paper - don't wait for remote connections
}
+
++ this.hasFullyShutdown = true; // Paper - Improved watchdog support
+ System.exit(0); // CraftBukkit
}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
index c6e8441e29..e8e93538df 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
@@ -12,11 +12,27 @@ public class ServerShutdownThread extends Thread {
@Override
public void run() {
try {
+ // Paper start - try to shutdown on main
+ server.safeShutdown(false, false);
+ for (int i = 1000; i > 0 && !server.hasStopped(); i -= 100) {
+ Thread.sleep(100);
+ }
+ if (server.hasStopped()) {
+ while (!server.hasFullyShutdown) Thread.sleep(1000);
+ return;
+ }
+ // Looks stalled, close async
org.spigotmc.AsyncCatcher.enabled = false; // Spigot
+ server.forceTicks = true;
this.server.close();
+ while (!server.hasFullyShutdown) Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ // Paper end
} finally {
+ org.apache.logging.log4j.LogManager.shutdown(); // Paper
try {
- net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender
+ //net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Move into stop
} catch (Exception e) {
}
}
diff --git a/paper-server/src/main/java/org/spigotmc/RestartCommand.java b/paper-server/src/main/java/org/spigotmc/RestartCommand.java
index b87f66ad04..3287d39951 100644
--- a/paper-server/src/main/java/org/spigotmc/RestartCommand.java
+++ b/paper-server/src/main/java/org/spigotmc/RestartCommand.java
@@ -105,7 +105,7 @@ public class RestartCommand extends Command {
// Paper end
// Paper start - copied from above and modified to return if the hook registered
- private static boolean addShutdownHook(String restartScript) {
+ public static boolean addShutdownHook(String restartScript) {
String[] split = restartScript.split(" ");
if (split.length > 0 && new File(split[0]).isFile()) {
Thread shutdownHook = new Thread(() -> {
diff --git a/paper-server/src/main/java/org/spigotmc/WatchdogThread.java b/paper-server/src/main/java/org/spigotmc/WatchdogThread.java
index 7fa7816014..0c67e3297e 100644
--- a/paper-server/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/paper-server/src/main/java/org/spigotmc/WatchdogThread.java
@@ -1,17 +1,19 @@
package org.spigotmc;
+import io.papermc.paper.FeatureHooks;
+import io.papermc.paper.configuration.GlobalConfiguration;
import java.lang.management.ManagementFactory;
import java.lang.management.MonitorInfo;
import java.lang.management.ThreadInfo;
import java.util.logging.Level;
import java.util.logging.Logger;
-import io.papermc.paper.configuration.GlobalConfiguration;
import net.minecraft.server.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.CraftServer;
public class WatchdogThread extends Thread {
+ public static final boolean DISABLE_WATCHDOG = Boolean.getBoolean("disable.watchdog"); // Paper - Improved watchdog support
private static WatchdogThread instance;
private long timeoutTime;
private boolean restart;
@@ -36,6 +38,7 @@ public class WatchdogThread extends Thread {
public static void doStart(int timeoutTime, boolean restart) {
if (WatchdogThread.instance == null) {
+ if (timeoutTime <= 0) timeoutTime = 300; // Paper
WatchdogThread.instance = new WatchdogThread(timeoutTime * 1000L, restart);
WatchdogThread.instance.start();
} else {
@@ -60,14 +63,15 @@ public class WatchdogThread extends Thread {
// Paper start
Logger logger = Bukkit.getServer().getLogger();
long currentTime = WatchdogThread.monotonicMillis();
- if (this.lastTick != 0 && this.timeoutTime > 0 && currentTime > this.lastTick + this.earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) { // Paper - Add property to disable
- boolean isLongTimeout = currentTime > this.lastTick + this.timeoutTime;
+ MinecraftServer server = MinecraftServer.getServer();
+ if (this.lastTick != 0 && this.timeoutTime > 0 && WatchdogThread.hasStarted && (!server.isRunning() || (currentTime > this.lastTick + this.earlyWarningEvery && !DISABLE_WATCHDOG))) { // Paper - add property to disable
+ boolean isLongTimeout = currentTime > this.lastTick + this.timeoutTime || (!server.isRunning() && !server.hasStopped() && currentTime > this.lastTick + 1000);
// Don't spam early warning dumps
if (!isLongTimeout && (this.earlyWarningEvery <= 0 ||
!hasStarted || currentTime < this.lastEarlyWarning + this.earlyWarningEvery ||
currentTime < this.lastTick + this.earlyWarningDelay))
continue;
- if (!isLongTimeout && MinecraftServer.getServer().hasStopped())
+ if (!isLongTimeout && server.hasStopped())
continue; // Don't spam early watchdog warnings during shutdown, we'll come back to this...
this.lastEarlyWarning = currentTime;
if (isLongTimeout) {
@@ -106,6 +110,7 @@ public class WatchdogThread extends Thread {
// Paper end - Different message for short timeout
logger.log(Level.SEVERE, "------------------------------");
logger.log(Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):"); // Paper
+ FeatureHooks.dumpTickingInfo(); // Paper - log detailed tick information
WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE), logger);
logger.log(Level.SEVERE, "------------------------------");
@@ -123,8 +128,23 @@ public class WatchdogThread extends Thread {
logger.log(Level.SEVERE, "------------------------------");
if (isLongTimeout) {
- if (this.restart && !MinecraftServer.getServer().hasStopped()) {
- RestartCommand.restart();
+ if (!server.hasStopped()) {
+ AsyncCatcher.enabled = false; // Disable async catcher incase it interferes with us
+ server.forceTicks = true;
+ if (this.restart) {
+ RestartCommand.addShutdownHook(SpigotConfig.restartScript);
+ }
+ // try one last chance to safe shutdown on main incase it 'comes back'
+ server.abnormalExit = true;
+ server.safeShutdown(false, this.restart);
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if (!server.hasStopped()) {
+ server.close();
+ }
}
break;
}
diff --git a/paper-server/src/main/resources/log4j2.xml b/paper-server/src/main/resources/log4j2.xml
index 637d64da99..d2a75850af 100644
--- a/paper-server/src/main/resources/log4j2.xml
+++ b/paper-server/src/main/resources/log4j2.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="WARN">
+<Configuration status="WARN" shutdownHook="disable">
<Appenders>
<Queue name="ServerGuiConsole">
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg{nolookups}%n" />