diff --git a/sources/src/main/java/io/akarin/api/internal/mixin/IMixinWorldServer.java b/sources/src/main/java/io/akarin/api/internal/mixin/IMixinWorldServer.java index 16e431d86..db7c0ac07 100644 --- a/sources/src/main/java/io/akarin/api/internal/mixin/IMixinWorldServer.java +++ b/sources/src/main/java/io/akarin/api/internal/mixin/IMixinWorldServer.java @@ -1,6 +1,8 @@ package io.akarin.api.internal.mixin; +import java.util.Random; + public interface IMixinWorldServer { public Object lock(); - public Object rand(); + public Random rand(); } \ No newline at end of file diff --git a/sources/src/main/java/io/akarin/server/mixin/bootstrap/Watchcat.java b/sources/src/main/java/io/akarin/server/mixin/bootstrap/Watchcat.java index 6c6fb6ac6..2bf9a0e27 100644 --- a/sources/src/main/java/io/akarin/server/mixin/bootstrap/Watchcat.java +++ b/sources/src/main/java/io/akarin/server/mixin/bootstrap/Watchcat.java @@ -6,7 +6,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.CraftServer; import org.spigotmc.RestartCommand; import org.spigotmc.WatchdogThread; import org.spongepowered.asm.mixin.Final; @@ -23,6 +22,8 @@ import net.minecraft.server.MinecraftServer; public abstract class Watchcat extends Thread { @Shadow private static WatchdogThread instance; @Shadow private @Final long timeoutTime; + @Shadow private @Final long shortTimeout; // Paper - Timeout time for just printing a dump but not restarting + @Shadow private long lastShortDump; // Paper - Keep track of short dump times to avoid spamming console with short dumps @Shadow private @Final boolean restart; @Shadow private volatile long lastTick; @Shadow private volatile boolean stopping; @@ -39,47 +40,67 @@ public abstract class Watchcat extends Thread { public void run() { while (!stopping) { // - if (lastTick != 0 && System.currentTimeMillis() > lastTick + timeoutTime && !Boolean.getBoolean("disable.watchdog")) { // Paper - Add property to disable - Logger log = Bukkit.getServer().getLogger(); - log.log(Level.SEVERE, "Server has stopped responding!"); - log.log(Level.SEVERE, "Please report this to https://github.com/Akarin-project/Akarin/issues"); - log.log(Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports"); - log.log(Level.SEVERE, "Akarin version: " + Bukkit.getServer().getVersion()); - // - if (net.minecraft.server.World.haveWeSilencedAPhysicsCrash) { - log.log(Level.SEVERE, "------------------------------"); - log.log(Level.SEVERE, "During the run of the server, a physics stackoverflow was supressed"); - log.log(Level.SEVERE, "near " + net.minecraft.server.World.blockLocation); - } - // Paper start - Warn in watchdog if an excessive velocity was ever set - if (CraftServer.excessiveVelEx != null) { - log.log(Level.SEVERE, "------------------------------"); - log.log(Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity"); - log.log(Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated"); - log.log(Level.SEVERE, CraftServer.excessiveVelEx.getMessage()); - for (StackTraceElement stack : CraftServer.excessiveVelEx.getStackTrace()) { - log.log(Level.SEVERE, "\t\t" + stack); - } - } + long currentTime = System.currentTimeMillis(); // Paper - do we REALLY need to call this method multiple times? + if (lastTick != 0 && currentTime > lastTick + shortTimeout && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable and short timeout + { + // Paper start + boolean isLongTimeout = currentTime > lastTick + timeoutTime; + // Don't spam short dumps + if (!isLongTimeout && currentTime < lastShortDump + shortTimeout) + continue; + lastShortDump = currentTime; // Paper end + Logger log = Bukkit.getServer().getLogger(); + // Paper start - Different message when it's a short timeout + if (isLongTimeout) { + log.log(Level.SEVERE, "The server has stopped responding!"); + log.log(Level.SEVERE, "Please report this to https://github.com/Akarin-project/Akarin/issues"); + log.log(Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports"); + log.log(Level.SEVERE, "Paper version: " + Bukkit.getServer().getVersion()); + // + if (net.minecraft.server.World.haveWeSilencedAPhysicsCrash) { + log.log(Level.SEVERE, "------------------------------"); + log.log(Level.SEVERE, "During the run of the server, a physics stackoverflow was supressed"); + log.log(Level.SEVERE, "near " + net.minecraft.server.World.blockLocation); + } + // Paper start - Warn in watchdog if an excessive velocity was ever set + if (org.bukkit.craftbukkit.CraftServer.excessiveVelEx != null) { + log.log(Level.SEVERE, "------------------------------"); + log.log(Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity"); + log.log(Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated"); + log.log(Level.SEVERE, org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getMessage()); + for (StackTraceElement stack : org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace()) { + log.log(Level.SEVERE, "\t\t" + stack); + } + } + // Paper end + } else { + log.log(Level.SEVERE, "The server has not responded for " + shortTimeout / 1000 + " seconds! Creating thread dump"); + } + // Paper end - Different message for short timeout log.log(Level.SEVERE, "------------------------------"); log.log(Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Akarin!):"); dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(MinecraftServer.getServer().primaryThread.getId(), Integer.MAX_VALUE), log); log.log(Level.SEVERE, "------------------------------"); // - log.log(Level.SEVERE, "Entire Thread Dump:"); - ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true); - for (ThreadInfo thread : threads) { - dumpThread(thread, log); - } - log.log(Level.SEVERE, "------------------------------"); - - if (restart) RestartCommand.restart(); // GC Inlined - break; + // Paper start - Only print full dump on long timeouts + if (isLongTimeout) { + log.log(Level.SEVERE, "Entire Thread Dump:"); + ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true); + for (ThreadInfo thread : threads) { + dumpThread(thread, log); + } + log.log(Level.SEVERE, "------------------------------"); + + if (restart) { + RestartCommand.restart(); + } + break; + } // Paper end } try { - sleep(9000); // Akarin + sleep(1000); // Paper - Reduce check time to every second instead of every ten seconds, more consistent and allows for short timeout } catch (InterruptedException ex) { interrupt(); } diff --git a/sources/src/main/java/io/akarin/server/mixin/core/MixinMinecraftServer.java b/sources/src/main/java/io/akarin/server/mixin/core/MixinMinecraftServer.java index 61f89d2b6..f5daa7e2a 100644 --- a/sources/src/main/java/io/akarin/server/mixin/core/MixinMinecraftServer.java +++ b/sources/src/main/java/io/akarin/server/mixin/core/MixinMinecraftServer.java @@ -24,7 +24,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import co.aikar.timings.MinecraftTimings; -import co.aikar.timings.TimingHandler; import io.akarin.api.internal.Akari; import io.akarin.api.internal.Akari.AssignableFactory; import io.akarin.api.internal.mixin.IMixinWorldServer; diff --git a/sources/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/sources/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 71583c422..4ee22cde0 100644 --- a/sources/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/sources/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1922,17 +1922,20 @@ public final class CraftServer implements Server { @Override public void reloadPermissions() { - ((SimplePluginManager) pluginManager).clearPermissions(); - loadCustomPermissions(); + pluginManager.clearPermissions(); + if (com.destroystokyo.paper.PaperConfig.loadPermsBeforePlugins) loadCustomPermissions(); for (Plugin plugin : pluginManager.getPlugins()) { - plugin.getDescription().getPermissions().forEach((perm) -> { + for (Permission perm : plugin.getDescription().getPermissions()) { try { pluginManager.addPermission(perm); } catch (IllegalArgumentException ex) { getLogger().log(Level.WARNING, "Plugin " + plugin.getDescription().getFullName() + " tried to register permission '" + perm.getName() + "' but it's already registered", ex); } - }); + } } + if (!com.destroystokyo.paper.PaperConfig.loadPermsBeforePlugins) loadCustomPermissions(); + DefaultPermissions.registerCorePermissions(); + CraftDefaultPermissions.registerCorePermissions(); } @Override diff --git a/work/Paper b/work/Paper index a1d7a5d79..f7358c5cf 160000 --- a/work/Paper +++ b/work/Paper @@ -1 +1 @@ -Subproject commit a1d7a5d791f08c2818c101c6737b6cf862961bf4 +Subproject commit f7358c5cf7ace8b781a12c1f7f1a6f62675460d5