Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23059,7 +23059,7 @@ index cda915fcb4822689f42b25280eb99aee082ddb74..094d2d528cb74b8f1d277cd780bba7f4
thread1 -> {
DedicatedServer dedicatedServer1 = new DedicatedServer(
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 330d1f751006e6a5acfec1a3ab390b1c2d482299..af7e9692a38f8278734e2f1ab51c1e03b123ef3c 100644
index de7264a1a4f267b99a5a1b7a29ef7c841a3463a6..5d044ca38543aeb24fe431e232afc3caeeb7078b 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -185,7 +185,7 @@ import net.minecraft.world.scores.ScoreboardSaveData;
Expand Down Expand Up @@ -23244,8 +23244,8 @@ index 330d1f751006e6a5acfec1a3ab390b1c2d482299..af7e9692a38f8278734e2f1ab51c1e03
+ // Paper end - rewrite chunk system
// Paper start - Improved watchdog support - move final shutdown items here
Util.shutdownExecutors();
try {
@@ -1081,16 +1177,31 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.onServerExit();
@@ -1076,16 +1172,31 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// execute small amounts of other tasks just in case the number of tasks we are
// draining is large - chunk system and packet processing may be latency sensitive

Expand Down Expand Up @@ -23280,15 +23280,15 @@ index 330d1f751006e6a5acfec1a3ab390b1c2d482299..af7e9692a38f8278734e2f1ab51c1e03
profiler.pop(); // moonrise:run_all_chunk
profiler.pop(); // moonrise:run_all_tasks

@@ -1396,6 +1507,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1391,6 +1502,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

private boolean pollTaskInternal() {
if (super.pollTask()) {
+ this.moonrise$executeMidTickTasks(); // Paper - rewrite chunk system
return true;
} else {
boolean ret = false; // Paper - force execution of all worlds, do not just bias the first
@@ -1537,6 +1649,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1532,6 +1644,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// Paper - improve tick loop - moved into runAllTasksAtTickStart
this.runAllTasksAtTickStart(); // Paper - improve tick loop
this.tickServer(sprinting ? () -> false : this::haveTime);
Expand All @@ -23302,7 +23302,7 @@ index 330d1f751006e6a5acfec1a3ab390b1c2d482299..af7e9692a38f8278734e2f1ab51c1e03
this.tickFrame.end();
this.recordEndOfTick(); // Paper - improve tick loop
profilerFiller.pop();
@@ -2562,6 +2681,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -2557,6 +2676,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
}

Expand Down Expand Up @@ -29136,7 +29136,7 @@ index 3d317880a257bf431f110048d305ddd2a06880d7..25f2e74e229fa12a2d7f1ff43c6cb12a

public ClipContext(Vec3 from, Vec3 to, ClipContext.Block block, ClipContext.Fluid fluid, Entity entity) {
diff --git a/net/minecraft/world/level/EntityGetter.java b/net/minecraft/world/level/EntityGetter.java
index d4c78c7f521b31ea9ce0cf7d62978b8e324b5d10..bcbe39eed2d254861689c95f7040f27b6ff2d438 100644
index b367eb61283c0cbf4ce9cda67089de2e22c95f4f..6ae3698e8e2c84fb21c0a4facbbf1568dbd45405 100644
--- a/net/minecraft/world/level/EntityGetter.java
+++ b/net/minecraft/world/level/EntityGetter.java
@@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.Shapes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Subject: [PATCH] Incremental chunk and player saving


diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 8dc6adb868ade00fdee6f3f53aff01fddf79926d..7e8715af6433ac3324ae7d79f5252a4550af6bb1 100644
index a9751f4bda862ef597ba39700b83c434f7a457d9..90e23b96ed3fc5a84f52e6f94ad40bdb028fedf7 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -972,7 +972,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
Expand All @@ -17,7 +17,7 @@ index 8dc6adb868ade00fdee6f3f53aff01fddf79926d..7e8715af6433ac3324ae7d79f5252a45
var4 = this.saveAllChunks(suppressLogs, flush, force);
} finally {
this.isSaving = false;
@@ -1620,9 +1620,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1615,9 +1615,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}

this.ticksUntilAutosave--;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ index 2bc436cdf5180a7943c45fabb9fbbedae6f7db56..f312a7f5b1b2a777ab36b94ce7cbf387

@Override
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 7e8715af6433ac3324ae7d79f5252a4550af6bb1..092ead4419f0a558f25b4baacf3343b05c872022 100644
index 90e23b96ed3fc5a84f52e6f94ad40bdb028fedf7..1885c0378a329ef24ee3ac7556ceff4b328db089 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1753,33 +1753,22 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1748,33 +1748,22 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
}

Expand Down
4 changes: 2 additions & 2 deletions paper-server/patches/features/0028-Optimize-Hoppers.patch
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ index 0000000000000000000000000000000000000000..24a2090e068ad3c0d08705050944abdf
+ }
+}
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 092ead4419f0a558f25b4baacf3343b05c872022..c2227d57ea2e2da537a313d4bfd2f8c7f776be64 100644
index 1885c0378a329ef24ee3ac7556ceff4b328db089..14103cf9ad602ee39aefaafe7e65dffc72880e2a 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1808,6 +1808,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@@ -1803,6 +1803,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
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.updateLagCompensationTick(); // Paper - lag compensation
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Mon, 9 Feb 2026 19:09:12 -0700
Subject: [PATCH] Add explicit flush support to Log4j AsyncAppender


diff --git a/org/apache/logging/log4j/core/appender/AsyncAppender.java b/org/apache/logging/log4j/core/appender/AsyncAppender.java
index f84870712345cd688a90ea53ad47eb33fe658863..126a5d1bc4239ba83565600a060877c22e39e06b 100644
--- a/org/apache/logging/log4j/core/appender/AsyncAppender.java
+++ b/org/apache/logging/log4j/core/appender/AsyncAppender.java
@@ -446,6 +446,23 @@ public final class AsyncAppender extends AbstractAppender {
return dispatcher.getAppenders();
}

+ // Paper start - add explicit flush method
+ public boolean flush(final long timeout, final TimeUnit timeUnit) {
+ if (!isStarted() || dispatcher == null) {
+ return true;
+ }
+
+ final long timeoutMillis = timeout <= 0L ? 0L : timeUnit.toMillis(timeout);
+ try {
+ return dispatcher.flush(timeoutMillis);
+ } catch (final InterruptedException ignored) {
+ Thread.currentThread().interrupt();
+ LOGGER.warn("Interrupted while flushing AsyncAppender {}", getName());
+ return false;
+ }
+ }
+ // Paper end - add explicit flush method
+
/**
* Returns the name of the appender that any errors are logged to or {@code null}.
*
diff --git a/org/apache/logging/log4j/core/appender/AsyncAppenderEventDispatcher.java b/org/apache/logging/log4j/core/appender/AsyncAppenderEventDispatcher.java
index ed962f5952c0861809d2558e709e8dd683751383..a12872c42a26d469e5b7004f7fe7ae535071a633 100644
--- a/org/apache/logging/log4j/core/appender/AsyncAppenderEventDispatcher.java
+++ b/org/apache/logging/log4j/core/appender/AsyncAppenderEventDispatcher.java
@@ -33,6 +33,25 @@ class AsyncAppenderEventDispatcher extends Log4jThread {

private static final LogEvent STOP_EVENT = new Log4jLogEvent();

+ // Paper start - add explicit flush method
+ private static final class FlushEvent extends Log4jLogEvent {
+
+ private final java.util.concurrent.CountDownLatch latch = new java.util.concurrent.CountDownLatch(1);
+
+ private void done() {
+ this.latch.countDown();
+ }
+
+ private boolean await(final long timeoutMillis) throws InterruptedException {
+ if (timeoutMillis <= 0L) {
+ this.latch.await();
+ return true;
+ }
+ return this.latch.await(timeoutMillis, java.util.concurrent.TimeUnit.MILLISECONDS);
+ }
+ }
+ // Paper end - add explicit flush method
+
private static final AtomicLong THREAD_COUNTER = new AtomicLong(0);

private static final Logger LOGGER = StatusLogger.getLogger();
@@ -87,6 +106,13 @@ class AsyncAppenderEventDispatcher extends Log4jThread {
if (event == STOP_EVENT) {
break;
}
+ // Paper start - add explicit flush method
+ if (event instanceof FlushEvent flushEvent) {
+ this.flushAppenderOutputStreams();
+ flushEvent.done();
+ continue;
+ }
+ // Paper end - add explicit flush method
event.setEndOfBatch(queue.isEmpty());
dispatch(event);
}
@@ -105,6 +131,13 @@ class AsyncAppenderEventDispatcher extends Log4jThread {
if (event == STOP_EVENT) {
continue;
}
+ // Paper start - add explicit flush method
+ if (event instanceof FlushEvent flushEvent) {
+ this.flushAppenderOutputStreams();
+ flushEvent.done();
+ continue;
+ }
+ // Paper end - add explicit flush method
event.setEndOfBatch(queue.isEmpty());
dispatch(event);
eventCount++;
@@ -112,6 +145,24 @@ class AsyncAppenderEventDispatcher extends Log4jThread {
LOGGER.trace("{} has processed the last {} remaining event(s).", getName(), eventCount);
}

+ // Paper start - add explicit flush method
+ private void flushAppenderOutputStreams() {
+ for (int appenderIndex = 0; appenderIndex < appenders.size(); appenderIndex++) {
+ flushAppender(appenders.get(appenderIndex));
+ }
+ if (errorAppender != null) {
+ flushAppender(errorAppender);
+ }
+ }
+
+ private void flushAppender(final AppenderControl appenderControl) {
+ final Appender appender = appenderControl.getAppender();
+ if (appender instanceof AbstractOutputStreamAppender<?> outputStreamAppender) {
+ outputStreamAppender.getManager().flush();
+ }
+ }
+ // Paper end - add explicit flush method
+
/**
* Dispatches the given {@code event} to the registered appenders <b>in the
* current thread</b>.
@@ -178,4 +229,44 @@ class AsyncAppenderEventDispatcher extends Log4jThread {
// Wait for the completion.
join(timeoutMillis);
}
+
+ // Paper start - add explicit flush method
+ boolean flush(final long timeoutMillis) throws InterruptedException {
+ if (stoppedRef.get()) {
+ flushAppenderOutputStreams();
+ return true;
+ }
+
+ // If the dispatcher thread has not started yet, fail fast
+ if (Thread.State.NEW.equals(getState())) {
+ return false;
+ }
+
+ final FlushEvent flushEvent = new FlushEvent();
+
+ final long startNanos = timeoutMillis > 0L ? System.nanoTime() : 0L;
+ final boolean enqueued;
+ if (timeoutMillis <= 0L) {
+ queue.put(flushEvent);
+ enqueued = true;
+ } else {
+ enqueued = queue.offer(flushEvent, timeoutMillis, java.util.concurrent.TimeUnit.MILLISECONDS);
+ }
+
+ if (!enqueued) {
+ return false;
+ }
+
+ if (timeoutMillis <= 0L) {
+ return flushEvent.await(0L);
+ }
+
+ final long elapsedMillis = java.util.concurrent.TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos);
+ final long remainingMillis = timeoutMillis - elapsedMillis;
+ if (remainingMillis <= 0L) {
+ return false;
+ }
+ return flushEvent.await(remainingMillis);
+ }
+ // Paper end - add explicit flush method
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
--- a/net/minecraft/CrashReport.java
+++ b/net/minecraft/CrashReport.java
@@ -32,8 +_,10 @@
private final SystemReport systemReport = new SystemReport();

@@ -34,6 +_,7 @@
public CrashReport(String title, Throwable exception) {
+ io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateThrowable(exception); // Paper
this.title = title;
this.exception = exception;
+ this.systemReport.setDetail("CraftBukkit Information", new org.bukkit.craftbukkit.CraftCrashReport()); // CraftBukkit
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
@DontObfuscate
- public static void main(String[] args) {
+ public static void main(final OptionSet optionSet) { // CraftBukkit - replaces main(String[] args)
+ io.papermc.paper.util.LogManagerShutdownThread.hook(); // Paper - Improved watchdog support
+ io.papermc.paper.log.LogManagerShutdownThread.hook(); // Paper - Improved watchdog support
SharedConstants.tryDetectVersion();
+ /* CraftBukkit start - Replace everything
OptionParser optionParser = new OptionParser();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@
+ }
+ */
+ // Paper end
+ io.papermc.paper.util.LogManagerShutdownThread.unhook(); // Paper - Improved watchdog support
+ io.papermc.paper.log.LogManagerShutdownThread.unhook(); // Paper - Improved watchdog support
+ Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this));
+ // CraftBukkit end
+ this.paperConfigurations = services.paper().configurations(); // Paper - add paper configuration files
Expand Down Expand Up @@ -597,7 +597,7 @@
}

LOGGER.info("Saving worlds");
@@ -707,6 +_,25 @@
@@ -707,6 +_,20 @@
} catch (IOException var4) {
LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), var4);
}
Expand All @@ -613,11 +613,6 @@
+ // Spigot end
+ // Paper start - Improved watchdog support - move final shutdown items here
+ Util.shutdownExecutors();
+ try {
+ net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender
+ } catch (final Exception ignored) {
+ }
+ io.papermc.paper.log.CustomLogManager.forceReset(); // Paper - Reset loggers after shutdown
+ this.onServerExit();
+ // Paper end - Improved watchdog support - move final shutdown items here
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
}
}

@@ -317,6 +_,37 @@
@@ -317,6 +_,35 @@
private void movePlayerFile(File file3, String oldFileName, String newFileName) {
File file4 = new File(worldPlayersDirectory, oldFileName + ".dat");
File file5 = new File(file3, newFileName + ".dat");
Expand All @@ -57,7 +57,6 @@
+ root = net.minecraft.nbt.NbtIo.readCompressed(new java.io.FileInputStream(file4), net.minecraft.nbt.NbtAccounter.unlimitedHeap());
+ } catch (Exception exception) {
+ // Paper start
+ io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateThrowable(exception);
+ exception.printStackTrace();
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception);
+ // Paper end
Expand All @@ -74,7 +73,6 @@
+ net.minecraft.nbt.NbtIo.writeCompressed(root, new java.io.FileOutputStream(file1));
+ } catch (Exception exception) {
+ // Paper start
+ io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateThrowable(exception);
+ exception.printStackTrace();
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception);
+ // Paper end
Expand Down
Loading
Loading