13
0
geforkt von Mirrors/Paper

Update watchdog patches

Dieser Commit ist enthalten in:
Nassim Jahnke 2024-12-17 13:32:46 +01:00
Ursprung 7daedfcbc3
Commit 2d83f05a6c
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: EF6771C01F6EF02F
12 geänderte Dateien mit 253 neuen und 426 gelöschten Zeilen

Datei anzeigen

@ -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 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. 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 new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 index 0000000000000000000000000000000000000000..3d7df554b89cff23f64da7ad48b5e4d26ac2baf7
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/util/LogManagerShutdownThread.java +++ b/io/papermc/paper/util/LogManagerShutdownThread.java
@@ -0,0 +0,0 @@ @@ -0,0 +1,29 @@
+package io.papermc.paper.util; +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(); + static LogManagerShutdownThread INSTANCE = new LogManagerShutdownThread();
+ public static final void hook() { +
+ public static void hook() {
+ if (INSTANCE == null) { + if (INSTANCE == null) {
+ throw new IllegalStateException("Cannot re-hook after being unhooked"); + throw new IllegalStateException("Cannot re-hook after being unhooked");
+ } + }
+ Runtime.getRuntime().addShutdownHook(INSTANCE); + Runtime.getRuntime().addShutdownHook(INSTANCE);
+ } + }
+ +
+ public static final void unhook() { + public static void unhook() {
+ Runtime.getRuntime().removeShutdownHook(INSTANCE); + Runtime.getRuntime().removeShutdownHook(INSTANCE);
+ INSTANCE = null; + INSTANCE = null;
+ } + }
@ -69,38 +72,38 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ @Override + @Override
+ public void run() { + 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 diff --git a/net/minecraft/CrashReport.java b/net/minecraft/CrashReport.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 3e0e88afcf010d9a3d46e48bca5cbdf98fe97544..8bd7999c17c8772451f873966f8c90969aee1482 100644
--- a/src/main/java/net/minecraft/CrashReport.java --- a/net/minecraft/CrashReport.java
+++ b/src/main/java/net/minecraft/CrashReport.java +++ b/net/minecraft/CrashReport.java
@@ -0,0 +0,0 @@ public class CrashReport { @@ -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 + if (cause instanceof ThreadDeath) com.destroystokyo.paper.util.SneakyThrow.sneaky(cause); // Paper
while (cause instanceof CompletionException && cause.getCause() != null) { while (cause instanceof CompletionException && cause.getCause() != null) {
cause = cause.getCause(); cause = cause.getCause();
} }
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 4437283a5d157eede121b98be0112c1067eded5e..fc9ec242743f755a1f0c9ec6bccd11c82375d655 100644
--- a/src/main/java/net/minecraft/server/Main.java --- a/net/minecraft/server/Main.java
+++ b/src/main/java/net/minecraft/server/Main.java +++ b/net/minecraft/server/Main.java
@@ -0,0 +0,0 @@ public class Main { @@ -68,6 +68,7 @@ public class Main {
@SuppressForbidden(reason = "System.out needed before bootstrap") // CraftBukkit - decompile error )
@DontObfuscate @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 + io.papermc.paper.util.LogManagerShutdownThread.hook(); // Paper
SharedConstants.tryDetectVersion(); SharedConstants.tryDetectVersion();
/* CraftBukkit start - Replace everything /* CraftBukkit start - Replace everything
OptionParser optionparser = new OptionParser(); OptionParser optionParser = new OptionParser();
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 8aa9ae2925ad44d57a27be3e520fcf20e30237d6..30b2bce976e3bf4c8e0b165cac527a685c02aeb1 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -287,7 +287,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>(); public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
public int autosavePeriod; public int autosavePeriod;
// Paper - don't store the vanilla dispatcher // Paper - don't store the vanilla dispatcher
@ -109,17 +112,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit end // CraftBukkit end
// Spigot start // Spigot start
public static final int TPS = 20; 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 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 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 Thread shutdownThread; // Paper
+ public volatile boolean abnormalExit = false; // Paper + public volatile boolean abnormalExit; // Paper
+
public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) { public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
AtomicReference<S> atomicreference = new AtomicReference(); @@ -393,6 +395,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
} }
*/ */
// Paper end // Paper end
@ -127,7 +129,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this)); Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this));
// CraftBukkit end // CraftBukkit end
this.paperConfigurations = services.paperConfigurations(); // Paper - add paper configuration files 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 // CraftBukkit start
private boolean hasStopped = false; private boolean hasStopped = false;
private boolean hasLoggedStop = false; // Paper - Debugging private boolean hasLoggedStop = false; // Paper - Debugging
@ -135,7 +137,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private final Object stopLock = new Object(); private final Object stopLock = new Object();
public final boolean hasStopped() { public final boolean hasStopped() {
synchronized (this.stopLock) { 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; this.hasStopped = true;
} }
if (!hasLoggedStop && isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging if (!hasLoggedStop && isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging
@ -146,10 +148,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit end // CraftBukkit end
if (this.metricsRecorder.isRecording()) { if (this.metricsRecorder.isRecording()) {
this.cancelRecordingMetrics(); this.cancelRecordingMetrics();
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -964,6 +972,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
ca.spottedleaf.moonrise.common.util.MoonriseCommon.haltExecutors(); 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 + // Paper start - Improved watchdog support - move final shutdown items here
+ Util.shutdownExecutors(); + Util.shutdownExecutors();
+ try { + try {
@ -162,7 +164,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
public String getLocalIp() { 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() { protected void runServer() {
try { try {
@ -170,7 +172,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!this.initServer()) { if (!this.initServer()) {
throw new IllegalStateException("Failed to initialize server"); 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 this.server.spark.enableBeforePlugins(); // Paper - spark
// Spigot start // Spigot start
@ -188,20 +190,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
org.spigotmc.WatchdogThread.hasStarted = true; // Paper org.spigotmc.WatchdogThread.hasStarted = true; // Paper
Arrays.fill( this.recentTps, 20 ); Arrays.fill( this.recentTps, 20 );
// Paper start - further improve server tick loop // 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); JvmProfiler.INSTANCE.onServerTick(this.smoothedTickTimeMillis);
} }
} catch (Throwable throwable2) { } catch (Throwable var69) {
+ // Paper start + // Paper start
+ if (throwable2 instanceof ThreadDeath) { + if (var69 instanceof ThreadDeath) {
+ MinecraftServer.LOGGER.error("Main thread terminated by WatchDog due to hard crash", throwable2); + MinecraftServer.LOGGER.error("Main thread terminated by WatchDog due to hard crash", var69);
+ return; + return;
+ } + }
+ // Paper end + // Paper end
MinecraftServer.LOGGER.error("Encountered an unexpected exception", throwable2); LOGGER.error("Encountered an unexpected exception", var69);
CrashReport crashreport = MinecraftServer.constructOrExtractCrashReport(throwable2); CrashReport crashReport = constructOrExtractCrashReport(var69);
this.fillSystemReport(crashReport.getSystemReport());
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -1177,15 +1212,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.services.profileCache().clearExecutor(); this.services.profileCache().clearExecutor();
} }
@ -219,9 +221,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ //io.papermc.paper.log.CustomLogManager.forceReset(); // Paper - Reset loggers after shutdown + //io.papermc.paper.log.CustomLogManager.forceReset(); // Paper - Reset loggers after shutdown
+ //this.onServerExit(); // Paper - moved into stop + //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 @Override
public TickTask wrapRunnable(Runnable runnable) { public TickTask wrapRunnable(Runnable runnable) {
@ -234,37 +236,37 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return new TickTask(this.tickCount, runnable); return new TickTask(this.tickCount, runnable);
} }
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -2085,7 +2126,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.resources.managers.updateStaticRegistryTags(); this.resources.managers.updateStaticRegistryTags();
this.resources.managers.getRecipeManager().finalizeRecipeLoading(this.worldData.enabledFeatures()); this.resources.managers.getRecipeManager().finalizeRecipeLoading(this.worldData.enabledFeatures());
this.potionBrewing = this.potionBrewing.reload(this.worldData.enabledFeatures()); // Paper - Custom Potion Mixes this.potionBrewing = this.potionBrewing.reload(this.worldData.enabledFeatures()); // Paper - Custom Potion Mixes
- this.getPlayerList().saveAll(); - this.getPlayerList().saveAll();
+ // Paper start + // Paper start
+ if (Thread.currentThread() != this.serverThread) { + if (Thread.currentThread() != this.serverThread) {
+ return; + return;
+ } + }
+ // this.getPlayerList().saveAll(); // Paper - we don't need to save everything, just advancements // TODO Move this to a different patch + // 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()) { + for (ServerPlayer player : this.getPlayerList().getPlayers()) {
+ player.getAdvancements().save(); + player.getAdvancements().save();
+ } + }
+ // Paper end + // Paper end
this.getPlayerList().reloadResources(); this.getPlayerList().reloadResources();
this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary()); this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary());
this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager); 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 diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 1ad96b964cdcf10b9f81d32d07e03c1a0ab6fe0a..d51d0c56e0cb68556ad366d52312bdb81ed17e9e 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java --- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -322,7 +322,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
long j = Util.getNanos() - i; this.loadLevel(this.storageSource.getLevelId()); // CraftBukkit
String s = String.format(Locale.ROOT, "%.3fs", (double) j / 1.0E9D); long l = Util.getNanos() - nanos;
String string = String.format(Locale.ROOT, "%.3fs", l / 1.0E9);
- DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s); - LOGGER.info("Done ({})! For help, type \"help\"", string);
+ DedicatedServer.LOGGER.info("Done preparing level \"{}\" ({})", this.getLevelIdName(), s); // Paper - clarify startup log messages & add total time + LOGGER.info("Done preparing level \"{}\" ({})", this.getLevelIdName(), string); // Paper - clarify startup log messages & add total time
if (dedicatedserverproperties.announcePlayerAchievements != null) { if (properties.announcePlayerAchievements != null) {
((GameRules.BooleanValue) this.getGameRules().getRule(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)).set(dedicatedserverproperties.announcePlayerAchievements, this.overworld()); // CraftBukkit - per-world 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 // this.remoteStatusListener.stop(); // Paper - don't wait for remote connections
} }
@ -274,7 +276,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
@Override @Override
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -726,7 +727,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@Override @Override
public void stopServer() { public void stopServer() {
super.stopServer(); super.stopServer();
@ -283,173 +285,52 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
SkullBlockEntity.clear(); SkullBlockEntity.clear();
} }
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index d227714de0fe13544779fae6cf0e9ff6af5469c7..393bd2ec0962d3870f5b4cb74200e5467b50cdb8 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java --- a/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java
@@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -513,7 +513,7 @@ public abstract class PlayerList {
this.cserver.getPluginManager().callEvent(playerQuitEvent); this.cserver.getPluginManager().callEvent(playerQuitEvent);
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); player.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
- entityplayer.doTick(); // SPIGOT-924 - player.doTick(); // SPIGOT-924
+ if (server.isSameThread()) entityplayer.doTick(); // SPIGOT-924 // Paper - don't tick during emergency shutdowns (Watchdog) + if (this.server.isSameThread()) player.doTick(); // SPIGOT-924 // Paper - don't tick during emergency shutdowns (Watchdog)
// CraftBukkit end // CraftBukkit end
// Paper start - Configurable player collision; Remove from collideRule team if needed // 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 diff --git a/net/minecraft/util/thread/BlockableEventLoop.java b/net/minecraft/util/thread/BlockableEventLoop.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 186c1b2e3599770385150eb7acdcd890aa5835eb..bfea9a2ae5e0bd5dae2873f715d192dfcbe97ee5 100644
--- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java --- a/net/minecraft/util/thread/BlockableEventLoop.java
+++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java +++ b/net/minecraft/util/thread/BlockableEventLoop.java
@@ -0,0 +0,0 @@ public abstract class BlockableEventLoop<R extends Runnable> implements Profiler @@ -169,6 +169,6 @@ public abstract class BlockableEventLoop<R extends Runnable> implements Profiler
public static boolean isNonRecoverable(Throwable exception) { public static boolean isNonRecoverable(Throwable error) {
return exception instanceof ReportedException reportedException return error instanceof ReportedException reportedException
? isNonRecoverable(reportedException.getCause()) ? isNonRecoverable(reportedException.getCause())
- : exception instanceof OutOfMemoryError || exception instanceof StackOverflowError; - : error instanceof OutOfMemoryError || error instanceof StackOverflowError;
+ : exception instanceof OutOfMemoryError || exception instanceof StackOverflowError || exception instanceof ThreadDeath; // Paper + : 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 diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index cb6ca60af3d3f90501e4693a78466b9f7462362d..127e25dab3a5e4df9cdf8eefd0485ea07b7696d9 100644
--- a/src/main/java/net/minecraft/world/level/Level.java --- a/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl @@ -863,6 +863,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
try { try {
tickConsumer.accept(entity); consumerEntity.accept(entity);
} catch (Throwable throwable) { } catch (Throwable var6) {
+ if (throwable instanceof ThreadDeath) throw throwable; // Paper + if (var6 instanceof ThreadDeath) throw var6; // Paper
// Paper start - Prevent block entity and entity crashes // 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()); 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); MinecraftServer.LOGGER.error(msg, var6);
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index d1d0dc13eecb0e0eb3a7839b570a5fe7f62f3fba..205f5a687eb685284a2e403f3eb6bdc694fc5423 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java --- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -0,0 +0,0 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p @@ -855,6 +855,7 @@ public class LevelChunk extends ChunkAccess {
gameprofilerfiller.pop(); profilerFiller.pop();
} catch (Throwable throwable) { } catch (Throwable var5) {
+ if (throwable instanceof ThreadDeath) throw throwable; // Paper + if (var5 instanceof ThreadDeath) throw var5; // Paper
// Paper start - Prevent block entity and entity crashes // 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()); 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); net.minecraft.server.MinecraftServer.LOGGER.error(msg, var5);
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" />

Datei anzeigen

@ -6,32 +6,55 @@ Subject: [PATCH] Detail more information in watchdog dumps
- Dump position, world, velocity, and uuid for currently ticking entities - Dump position, world, velocity, and uuid for currently ticking entities
- Dump player name, player uuid, position, and world for packet handling - 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 diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 8fe485c5bf79804bb4d1f774f95a92b14a576e80..0bcae6256d3b3fb6b2e0c2f23907d4659b236ef3 100644
--- a/src/main/java/net/minecraft/network/Connection.java --- a/net/minecraft/network/Connection.java
+++ b/src/main/java/net/minecraft/network/Connection.java +++ b/net/minecraft/network/Connection.java
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> { @@ -603,7 +603,13 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
if (!(this.packetListener instanceof net.minecraft.server.network.ServerLoginPacketListenerImpl loginPacketListener) if (!(this.packetListener instanceof net.minecraft.server.network.ServerLoginPacketListenerImpl loginPacketListener)
|| loginPacketListener.state != net.minecraft.server.network.ServerLoginPacketListenerImpl.State.VERIFYING || loginPacketListener.state != net.minecraft.server.network.ServerLoginPacketListenerImpl.State.VERIFYING
|| Connection.joinAttemptsThisTick++ < MAX_PER_TICK) { || Connection.joinAttemptsThisTick++ < MAX_PER_TICK) {
+ // Paper start - detailed watchdog information + // Paper start - detailed watchdog information
+ net.minecraft.network.protocol.PacketUtils.packetProcessing.push(this.packetListener); + net.minecraft.network.protocol.PacketUtils.packetProcessing.push(this.packetListener);
+ try { + try {
tickablepacketlistener.tick(); tickablePacketListener.tick();
+ } finally { + } finally {
+ net.minecraft.network.protocol.PacketUtils.packetProcessing.pop(); + net.minecraft.network.protocol.PacketUtils.packetProcessing.pop();
+ } // Paper end - detailed watchdog information + } // Paper end - detailed watchdog information
} // Paper end - Buffer joins to world } // 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 diff --git a/net/minecraft/network/protocol/PacketUtils.java b/net/minecraft/network/protocol/PacketUtils.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index e65c62dbe4c1560ae153e4c4344e9194c783a2f4..4535858701b2bb232b9d2feb2af6551526232ddc 100644
--- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java --- a/net/minecraft/network/protocol/PacketUtils.java
+++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java +++ b/net/minecraft/network/protocol/PacketUtils.java
@@ -0,0 +0,0 @@ public class PacketUtils { @@ -21,6 +21,8 @@ public class PacketUtils {
public static <T extends PacketListener> void ensureRunningOnSameThread(Packet<T> packet, T processor, BlockableEventLoop<?> executor) throws RunningOnDifferentThreadException {
private static final Logger LOGGER = LogUtils.getLogger(); 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 + // Paper start - detailed watchdog information
+ public static final java.util.concurrent.ConcurrentLinkedDeque<PacketListener> packetProcessing = new java.util.concurrent.ConcurrentLinkedDeque<>(); + 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(); + 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() { + 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) { + for (PacketListener listener : packetProcessing) {
+ ret.add(listener); + listeners.add(listener);
+ } + }
+ +
+ return ret; + return listeners;
+ } + }
+ // Paper end - detailed watchdog information + // Paper end - detailed watchdog information
+ }
public PacketUtils() {} diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index 9cc47bda7197ca3f63b0ede9905c9a13931f84ed..05f45b490e823a455b23b23b26a7da3b447059ea 100644
public static <T extends PacketListener> void ensureRunningOnSameThread(Packet<T> packet, T listener, ServerLevel world) throws RunningOnDifferentThreadException { --- a/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class PacketUtils { +++ b/net/minecraft/server/level/ServerLevel.java
public static <T extends PacketListener> void ensureRunningOnSameThread(Packet<T> packet, T listener, BlockableEventLoop<?> engine) throws RunningOnDifferentThreadException { @@ -956,7 +956,26 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
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
} }
+ // Paper start - log detailed entity tick information + // Paper start - log detailed entity tick information
@ -103,13 +101,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ currentlyTickingEntity.lazySet(entity); + currentlyTickingEntity.lazySet(entity);
+ } + }
+ // Paper end - log detailed entity tick information + // Paper end - log detailed entity tick information
// Spigot start entity.setOldPosAndRot();
/*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out EAR 2 ProfilerFiller profilerFiller = Profiler.get();
entity.tickCount++; entity.tickCount++;
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -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 this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
} }
+ // Paper start - log detailed entity tick information + // Paper start - log detailed entity tick information
+ } finally { + } finally {
+ if (currentlyTickingEntity.get() == entity) { + if (currentlyTickingEntity.get() == entity) {
@ -119,12 +117,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - log detailed entity tick information + // Paper end - log detailed entity tick information
} }
private void tickPassenger(Entity vehicle, Entity passenger, boolean isActive) { // Paper - EAR 2 private void tickPassenger(Entity ridingEntity, Entity passengerEntity, final 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 diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 5a67aa9f1fe103e5622ed6fa93bc4bc25ddbb688..1ff09959aa95d9822ccb6724bbb3f441c768511a 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java --- a/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -956,8 +956,43 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return this.onGround; return this.onGround;
} }
@ -168,8 +166,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (this.noPhysics) { if (this.noPhysics) {
this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z);
} else { } else {
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -1075,6 +1110,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
gameprofilerfiller.pop(); profilerFiller.pop();
} }
} }
+ // Paper start - detailed watchdog information + // Paper start - detailed watchdog information
@ -181,115 +179,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - detailed watchdog information + // Paper end - detailed watchdog information
} }
private void applyMovementEmissionAndPlaySound(Entity.MovementEmission moveEffect, Vec3 movement, BlockPos landingPos, BlockState landingState) { private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) {
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -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 + synchronized (this.posLock) { // Paper
this.deltaMovement = velocity; this.deltaMovement = deltaMovement;
+ } // Paper + } // Paper
} }
public void addDeltaMovement(Vec3 velocity) { public void addDeltaMovement(Vec3 addend) {
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -4445,7 +4489,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
} }
// Paper end - Fix MC-4 // Paper end - Fix MC-4
if (this.position.x != x || this.position.y != y || this.position.z != z) { if (this.position.x != x || this.position.y != y || this.position.z != z) {
+ synchronized (this.posLock) { // Paper + synchronized (this.posLock) { // Paper
this.position = new Vec3(x, y, z); this.position = new Vec3(x, y, z);
+ } // Paper + } // Paper
int i = Mth.floor(x); int floor = Mth.floor(x);
int j = Mth.floor(y); int floor1 = Mth.floor(y);
int k = Mth.floor(z); int floor2 = 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, "------------------------------" );
//

Datei anzeigen

@ -5,7 +5,7 @@ Subject: [PATCH] Anti-Xray
diff --git a/io/papermc/paper/FeatureHooks.java b/io/papermc/paper/FeatureHooks.java 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 --- a/io/papermc/paper/FeatureHooks.java
+++ b/io/papermc/paper/FeatureHooks.java +++ b/io/papermc/paper/FeatureHooks.java
@@ -7,6 +7,7 @@ import it.unimi.dsi.fastutil.longs.LongSets; @@ -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.List;
import java.util.Map; import java.util.Map;
import java.util.Set; 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) { 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) { 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 diff --git a/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java b/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java
index d4872b7f4e9591b3b1c67406312905851303f521..cb41460e94161675e2ab43f4b1b5286ee38e2e13 100644 index d4872b7f4e9591b3b1c67406312905851303f521..cb41460e94161675e2ab43f4b1b5286ee38e2e13 100644
--- a/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java --- a/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java

Datei anzeigen

@ -30621,10 +30621,10 @@ index 1110ca4075a1bbaa46b66686435dab91b275c945..c2218630c3074c8b3f82364e37503b12
return structureTemplate.save(new CompoundTag()); return structureTemplate.save(new CompoundTag());
} }
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java 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 --- a/net/minecraft/server/MinecraftServer.java
+++ b/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 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) { public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {

Datei anzeigen

@ -8,10 +8,10 @@ Areas affected by lag comepnsation:
- Eating food items - Eating food items
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java 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 --- a/net/minecraft/server/MinecraftServer.java
+++ b/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 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 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 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) { public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system 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()) { for (ServerLevel serverLevel : this.getAllLevels()) {
serverLevel.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent 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 serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent

Datei anzeigen

@ -1,6 +1,6 @@
--- /dev/null --- /dev/null
+++ b/io/papermc/paper/FeatureHooks.java +++ b/io/papermc/paper/FeatureHooks.java
@@ -1,0 +_,77 @@ @@ -1,0 +_,84 @@
+package io.papermc.paper; +package io.papermc.paper;
+ +
+import io.papermc.paper.command.PaperSubcommand; +import io.papermc.paper.command.PaperSubcommand;
@ -16,6 +16,7 @@
+import net.minecraft.core.Registry; +import net.minecraft.core.Registry;
+import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; +import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
+import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.monster.Spider; +import net.minecraft.world.entity.monster.Spider;
+import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.ChunkPos;
+import net.minecraft.world.level.Level; +import net.minecraft.world.level.Level;
@ -77,4 +78,10 @@
+ public static boolean isSpiderCollidingWithWorldBorder(final Spider spider) { + 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)) + 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) {
+ }
+} +}

Datei anzeigen

@ -41,7 +41,7 @@
@Nullable @Nullable
private KeyPair keyPair; private KeyPair keyPair;
@Nullable @Nullable
@@ -271,10 +_,33 @@ @@ -271,10 +_,35 @@
private final SuppressedExceptionCollector suppressedExceptions = new SuppressedExceptionCollector(); private final SuppressedExceptionCollector suppressedExceptions = new SuppressedExceptionCollector();
private final DiscontinuousFrame tickFrame; private final DiscontinuousFrame tickFrame;
@ -54,7 +54,7 @@
+ public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>(); + public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
+ public int autosavePeriod; + public int autosavePeriod;
+ // Paper - don't store the vanilla dispatcher + // Paper - don't store the vanilla dispatcher
+ private boolean forceTicks; + public boolean forceTicks;
+ // CraftBukkit end + // CraftBukkit end
+ // Spigot start + // Spigot start
+ public static final int TPS = 20; + public static final int TPS = 20;
@ -63,6 +63,8 @@
+ @Deprecated(forRemoval = true) // Paper + @Deprecated(forRemoval = true) // Paper
+ public final double[] recentTps = new double[ 3 ]; + public final double[] recentTps = new double[ 3 ];
+ // Spigot end + // 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 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 + 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 + private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping

Datei anzeigen

@ -301,7 +301,7 @@
} }
@Override @Override
@@ -271,12 +_,14 @@ @@ -271,12 +_,15 @@
} }
if (this.rconThread != null) { if (this.rconThread != null) {
@ -314,6 +314,7 @@
+ // this.remoteStatusListener.stop(); // Paper - don't wait for remote connections + // this.remoteStatusListener.stop(); // Paper - don't wait for remote connections
} }
+ +
+ this.hasFullyShutdown = true; // Paper - Improved watchdog support
+ System.exit(0); // CraftBukkit + System.exit(0); // CraftBukkit
} }

Datei anzeigen

@ -12,11 +12,27 @@ public class ServerShutdownThread extends Thread {
@Override @Override
public void run() { public void run() {
try { 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 org.spigotmc.AsyncCatcher.enabled = false; // Spigot
server.forceTicks = true;
this.server.close(); this.server.close();
while (!server.hasFullyShutdown) Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
// Paper end
} finally { } finally {
org.apache.logging.log4j.LogManager.shutdown(); // Paper
try { try {
net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender //net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Move into stop
} catch (Exception e) { } catch (Exception e) {
} }
} }

Datei anzeigen

@ -105,7 +105,7 @@ public class RestartCommand extends Command {
// Paper end // Paper end
// Paper start - copied from above and modified to return if the hook registered // 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(" "); String[] split = restartScript.split(" ");
if (split.length > 0 && new File(split[0]).isFile()) { if (split.length > 0 && new File(split[0]).isFile()) {
Thread shutdownHook = new Thread(() -> { Thread shutdownHook = new Thread(() -> {

Datei anzeigen

@ -1,17 +1,19 @@
package org.spigotmc; package org.spigotmc;
import io.papermc.paper.FeatureHooks;
import io.papermc.paper.configuration.GlobalConfiguration;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.management.MonitorInfo; import java.lang.management.MonitorInfo;
import java.lang.management.ThreadInfo; import java.lang.management.ThreadInfo;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import io.papermc.paper.configuration.GlobalConfiguration;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftServer;
public class WatchdogThread extends Thread { public class WatchdogThread extends Thread {
public static final boolean DISABLE_WATCHDOG = Boolean.getBoolean("disable.watchdog"); // Paper - Improved watchdog support
private static WatchdogThread instance; private static WatchdogThread instance;
private long timeoutTime; private long timeoutTime;
private boolean restart; private boolean restart;
@ -36,6 +38,7 @@ public class WatchdogThread extends Thread {
public static void doStart(int timeoutTime, boolean restart) { public static void doStart(int timeoutTime, boolean restart) {
if (WatchdogThread.instance == null) { if (WatchdogThread.instance == null) {
if (timeoutTime <= 0) timeoutTime = 300; // Paper
WatchdogThread.instance = new WatchdogThread(timeoutTime * 1000L, restart); WatchdogThread.instance = new WatchdogThread(timeoutTime * 1000L, restart);
WatchdogThread.instance.start(); WatchdogThread.instance.start();
} else { } else {
@ -60,14 +63,15 @@ public class WatchdogThread extends Thread {
// Paper start // Paper start
Logger logger = Bukkit.getServer().getLogger(); Logger logger = Bukkit.getServer().getLogger();
long currentTime = WatchdogThread.monotonicMillis(); 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();
boolean isLongTimeout = currentTime > this.lastTick + this.timeoutTime; 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 // Don't spam early warning dumps
if (!isLongTimeout && (this.earlyWarningEvery <= 0 || if (!isLongTimeout && (this.earlyWarningEvery <= 0 ||
!hasStarted || currentTime < this.lastEarlyWarning + this.earlyWarningEvery || !hasStarted || currentTime < this.lastEarlyWarning + this.earlyWarningEvery ||
currentTime < this.lastTick + this.earlyWarningDelay)) currentTime < this.lastTick + this.earlyWarningDelay))
continue; 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... continue; // Don't spam early watchdog warnings during shutdown, we'll come back to this...
this.lastEarlyWarning = currentTime; this.lastEarlyWarning = currentTime;
if (isLongTimeout) { if (isLongTimeout) {
@ -106,6 +110,7 @@ public class WatchdogThread extends Thread {
// Paper end - Different message for short timeout // Paper end - Different message for short timeout
logger.log(Level.SEVERE, "------------------------------"); logger.log(Level.SEVERE, "------------------------------");
logger.log(Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):"); // Paper 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); WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE), logger);
logger.log(Level.SEVERE, "------------------------------"); logger.log(Level.SEVERE, "------------------------------");
@ -123,8 +128,23 @@ public class WatchdogThread extends Thread {
logger.log(Level.SEVERE, "------------------------------"); logger.log(Level.SEVERE, "------------------------------");
if (isLongTimeout) { 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 (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; break;
} }

Datei anzeigen

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN"> <Configuration status="WARN" shutdownHook="disable">
<Appenders> <Appenders>
<Queue name="ServerGuiConsole"> <Queue name="ServerGuiConsole">
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg{nolookups}%n" /> <PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg{nolookups}%n" />