diff --git a/Spigot-API-Patches/Timings-v2.patch b/Spigot-API-Patches/Timings-v2.patch index 50cb9c1109..f172613449 100644 --- a/Spigot-API-Patches/Timings-v2.patch +++ b/Spigot-API-Patches/Timings-v2.patch @@ -14,6 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + +import static co.aikar.timings.TimingsManager.*; + ++import org.bukkit.Bukkit; +import org.jetbrains.annotations.NotNull; + +public class FullServerTickHandler extends TimingHandler { @@ -42,7 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override + public void stopTiming() { + super.stopTiming(); -+ if (!isEnabled()) { ++ if (!isEnabled() || Bukkit.isStopping()) { + return; + } + if (TimingHistory.timedTicks % 20 == 0) { diff --git a/Spigot-Server-Patches/Improved-Watchdog-Support.patch b/Spigot-Server-Patches/Improved-Watchdog-Support.patch index 0f8895a7e8..c1b8161a66 100644 --- a/Spigot-Server-Patches/Improved-Watchdog-Support.patch +++ b/Spigot-Server-Patches/Improved-Watchdog-Support.patch @@ -40,6 +40,20 @@ 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/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/com/destroystokyo/paper/Metrics.java ++++ b/src/main/java/com/destroystokyo/paper/Metrics.java +@@ -0,0 +0,0 @@ public class Metrics { + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { ++ if (MinecraftServer.getServer().hasStopped()) { ++ return; ++ } + submitData(); + } + }, 1000 * 60 * 5, 1000 * 60 * 30); diff --git a/src/main/java/net/minecraft/server/CrashReport.java b/src/main/java/net/minecraft/server/CrashReport.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/CrashReport.java @@ -210,6 +224,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return new TickTask(this.ticks, runnable); } +diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java ++++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + MutableBoolean mutableboolean = new MutableBoolean(); + + do { ++ boolean isShuttingDown = world.getMinecraftServer().hasStopped(); // Paper + mutableboolean.setFalse(); + list.stream().map((playerchunk) -> { + CompletableFuture completablefuture; +@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + return (IChunkAccess) completablefuture.join(); + }).filter((ichunkaccess) -> { + return ichunkaccess instanceof ProtoChunkExtension || ichunkaccess instanceof Chunk; +- }).filter(this::saveChunk).forEach((ichunkaccess) -> { ++ }).filter(ichunkaccess1 -> saveChunk(ichunkaccess1, !isShuttingDown)).forEach((ichunkaccess) -> { // Paper - dont save async during shutdown + mutableboolean.setTrue(); + }); + } while (mutableboolean.isTrue()); diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java @@ -268,6 +303,108 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } @Override +diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/Main.java ++++ b/src/main/java/org/bukkit/craftbukkit/Main.java +@@ -0,0 +0,0 @@ public class Main { + + OptionSet options = null; + ++ // Paper start - preload logger classes to avoid plugins mixing versions ++ tryPreloadClass("com.destroystokyo.paper.log.LogFullPolicy"); ++ tryPreloadClass("org.apache.logging.log4j.core.Core"); ++ tryPreloadClass("org.apache.logging.log4j.core.Appender"); ++ tryPreloadClass("org.apache.logging.log4j.core.ContextDataInjector"); ++ tryPreloadClass("org.apache.logging.log4j.core.Filter"); ++ tryPreloadClass("org.apache.logging.log4j.core.ErrorHandler"); ++ tryPreloadClass("org.apache.logging.log4j.core.LogEvent"); ++ tryPreloadClass("org.apache.logging.log4j.core.Logger"); ++ tryPreloadClass("org.apache.logging.log4j.core.LoggerContext"); ++ tryPreloadClass("org.apache.logging.log4j.core.LogEventListener"); ++ tryPreloadClass("org.apache.logging.log4j.core.AbstractLogEvent"); ++ tryPreloadClass("org.apache.logging.log4j.message.AsynchronouslyFormattable"); ++ tryPreloadClass("org.apache.logging.log4j.message.FormattedMessage"); ++ tryPreloadClass("org.apache.logging.log4j.message.ParameterizedMessage"); ++ tryPreloadClass("org.apache.logging.log4j.message.Message"); ++ tryPreloadClass("org.apache.logging.log4j.message.MessageFactory"); ++ tryPreloadClass("org.apache.logging.log4j.message.TimestampMessage"); ++ tryPreloadClass("org.apache.logging.log4j.message.SimpleMessage"); ++ tryPreloadClass("org.apache.logging.log4j.core.async.AsyncLogger"); ++ tryPreloadClass("org.apache.logging.log4j.core.async.AsyncLoggerContext"); ++ tryPreloadClass("org.apache.logging.log4j.core.async.AsyncQueueFullPolicy"); ++ tryPreloadClass("org.apache.logging.log4j.core.async.AsyncLoggerDisruptor"); ++ tryPreloadClass("org.apache.logging.log4j.core.async.RingBufferLogEvent"); ++ tryPreloadClass("org.apache.logging.log4j.core.async.DisruptorUtil"); ++ tryPreloadClass("org.apache.logging.log4j.core.async.RingBufferLogEventHandler"); ++ tryPreloadClass("org.apache.logging.log4j.core.impl.ThrowableProxy"); ++ tryPreloadClass("org.apache.logging.log4j.core.impl.ThrowableProxy$CacheEntry"); ++ tryPreloadClass("org.apache.logging.log4j.core.impl.ExtendedClassInfo"); ++ tryPreloadClass("org.apache.logging.log4j.core.impl.ExtendedStackTraceElement"); ++ // Paper end + try { + options = parser.parse(args); + } catch (joptsimple.OptionException ex) { +@@ -0,0 +0,0 @@ public class Main { + } catch (Throwable t) { + t.printStackTrace(); + } ++ // Paper start ++ // load some required classes to avoid errors during shutdown if jar is replaced ++ // also to guarantee our version loads over plugins ++ tryPreloadClass("com.destroystokyo.paper.util.SneakyThrow"); ++ tryPreloadClass("com.google.common.collect.Iterators$PeekingImpl"); ++ tryPreloadClass("com.google.common.collect.MapMakerInternalMap$Values"); ++ tryPreloadClass("com.google.common.collect.MapMakerInternalMap$ValueIterator"); ++ tryPreloadClass("com.google.common.collect.Iterables"); ++ for (int i = 1; i <= 15; i++) { ++ tryPreloadClass("com.google.common.collect.Iterables$" + i, false); ++ } ++ tryPreloadClass("org.apache.commons.lang3.mutable.MutableBoolean"); ++ tryPreloadClass("org.apache.commons.lang3.mutable.MutableInt"); ++ tryPreloadClass("org.jline.terminal.impl.MouseSupport"); ++ tryPreloadClass("org.jline.terminal.impl.MouseSupport$1"); ++ tryPreloadClass("org.jline.terminal.Terminal$MouseTracking"); ++ tryPreloadClass("co.aikar.timings.TimingHistory"); ++ tryPreloadClass("co.aikar.timings.TimingHistory$MinuteReport"); ++ tryPreloadClass("io.netty.channel.AbstractChannelHandlerContext"); ++ tryPreloadClass("io.netty.channel.AbstractChannelHandlerContext$11"); ++ tryPreloadClass("io.netty.channel.AbstractChannel$AbstractUnsafe$8"); ++ tryPreloadClass("io.netty.util.concurrent.DefaultPromise"); ++ tryPreloadClass("io.netty.util.concurrent.DefaultPromise$1"); ++ tryPreloadClass("io.netty.util.internal.PromiseNotificationUtil"); ++ tryPreloadClass("io.netty.util.internal.SystemPropertyUtil"); ++ tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler"); ++ tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler$1"); ++ tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler$2"); ++ tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler$3"); ++ tryPreloadClass("org.bukkit.craftbukkit.scheduler.CraftScheduler$4"); ++ tryPreloadClass("org.slf4j.helpers.MessageFormatter"); ++ tryPreloadClass("org.slf4j.helpers.FormattingTuple"); ++ tryPreloadClass("org.slf4j.helpers.BasicMarker"); ++ tryPreloadClass("org.slf4j.helpers.Util"); ++ // Minecraft, seen during saving ++ tryPreloadClass("net.minecraft.server.LightEngineLayerEventListener$Void"); ++ tryPreloadClass("net.minecraft.server.LightEngineLayerEventListener"); ++ // Paper end ++ } ++ } ++ ++ // Paper start ++ private static void tryPreloadClass(String className) { ++ tryPreloadClass(className, true); ++ } ++ private static void tryPreloadClass(String className, boolean printError) { ++ try { ++ Class.forName(className); ++ } catch (ClassNotFoundException e) { ++ if (printError) System.err.println("An expected class " + className + " was not found for preloading: " + e.getMessage()); + } + } ++ // Paper end + + private static List asList(String... params) { + return Arrays.asList(params); 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 diff --git a/Spigot-Server-Patches/MC-Dev-fixes.patch b/Spigot-Server-Patches/MC-Dev-fixes.patch index 9586d21752..10621de25c 100644 --- a/Spigot-Server-Patches/MC-Dev-fixes.patch +++ b/Spigot-Server-Patches/MC-Dev-fixes.patch @@ -393,6 +393,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 j = SectionPosition.a(j, EnumDirection.UP); ++k; if (k >= l) { +diff --git a/src/main/java/net/minecraft/server/LightEngineThreaded.java b/src/main/java/net/minecraft/server/LightEngineThreaded.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/LightEngineThreaded.java ++++ b/src/main/java/net/minecraft/server/LightEngineThreaded.java +@@ -0,0 +0,0 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { + } + + private void a(int i, int j, IntSupplier intsupplier, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable) { +- this.e.a((Object) ChunkTaskQueueSorter.a(() -> { ++ this.e.a(ChunkTaskQueueSorter.a(() -> { // Paper - decompile error + this.c.add(Pair.of(lightenginethreaded_update, runnable)); + if (this.c.size() >= this.f) { + this.b(); +@@ -0,0 +0,0 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable { + + public void queueUpdate() { + if ((!this.c.isEmpty() || super.a()) && this.g.compareAndSet(false, true)) { +- this.b.a((Object) (() -> { ++ this.b.a((() -> { // Paper - decompile error + this.b(); + this.g.set(false); + })); diff --git a/src/main/java/net/minecraft/server/LootSelectorEntry.java b/src/main/java/net/minecraft/server/LootSelectorEntry.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/LootSelectorEntry.java diff --git a/scripts/testServer.sh b/scripts/testServer.sh index 502e7a8e3f..1ce78a3328 100755 --- a/scripts/testServer.sh +++ b/scripts/testServer.sh @@ -87,6 +87,7 @@ fi # JVM FLAGS # +cp "$jar" paper.jar baseargs="-server -Xms${PAPER_MIN_TEST_MEMORY:-512M} -Xmx${PAPER_TEST_MEMORY:-2G} -Dfile.encoding=UTF-8 -XX:MaxGCPauseMillis=150 -XX:+UseG1GC " baseargs="$baseargs -DIReallyKnowWhatIAmDoingISwear=1 " baseargs="$baseargs -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=60 " @@ -94,7 +95,7 @@ baseargs="$baseargs -XX:InitiatingHeapOccupancyPercent=10 -XX:G1MixedGCLiveThres baseargs="$baseargs -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5100" -cmd="java ${PAPER_TEST_BASE_JVM_ARGS:-$baseargs} ${PAPER_TEST_EXTRA_JVM_ARGS} -jar $jar ${PAPER_TEST_APP_ARGS:-} nogui" +cmd="java ${PAPER_TEST_BASE_JVM_ARGS:-$baseargs} ${PAPER_TEST_EXTRA_JVM_ARGS} -jar paper.jar ${PAPER_TEST_APP_ARGS:-} nogui" screen_command="screen -DURS papertest $cmd" tmux_command="tmux new-session -A -s Paper -n 'Paper Test' -c '$(pwd)' '$cmd'"