From 668a1642a4da1eb226778303144593329f666f15 Mon Sep 17 00:00:00 2001 From: "BT (calcastor/mame)" <43831917+calcastor@users.noreply.github.com> Date: Thu, 3 Jul 2025 20:43:23 -0700 Subject: [PATCH] Improve console and logging --- ...oleAppender-for-console-improvements.patch | 560 ++++++++++++++++++ ...ams-to-redirect-System.out-err-to-lo.patch | 78 +++ ...r-to-keep-logging-IO-off-main-thread.patch | 51 ++ 3 files changed, 689 insertions(+) create mode 100644 patches/server/0229-Use-TerminalConsoleAppender-for-console-improvements.patch create mode 100644 patches/server/0230-Use-Log4j-IOStreams-to-redirect-System.out-err-to-lo.patch create mode 100644 patches/server/0231-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch diff --git a/patches/server/0229-Use-TerminalConsoleAppender-for-console-improvements.patch b/patches/server/0229-Use-TerminalConsoleAppender-for-console-improvements.patch new file mode 100644 index 00000000..eb2024e2 --- /dev/null +++ b/patches/server/0229-Use-TerminalConsoleAppender-for-console-improvements.patch @@ -0,0 +1,560 @@ +From 6a592314698c8dce978b3db2acf681b59d06a817 Mon Sep 17 00:00:00 2001 +From: Minecrell +Date: Fri, 9 Jun 2017 19:03:43 +0200 +Subject: [PATCH] Use TerminalConsoleAppender for console improvements + +Rewrite console improvements (console colors, tab completion, +persistent input line, ...) using JLine 3.x and TerminalConsoleAppender. + +New features: + - Support console colors for Vanilla commands + - Add console colors for warnings and errors + - Server can now be turned off safely using CTRL + C. JLine catches + the signal and the implementation shuts down the server cleanly. + - Support console colors and persistent input line when running in + IntelliJ IDEA + +Other changes: + - Server starts 1-2 seconds faster thanks to optimizations in Log4j + configuration + +diff --git a/pom.xml b/pom.xml +index c31fc87a..38d8bf98 100644 +--- a/pom.xml ++++ b/pom.xml +@@ -49,12 +49,20 @@ + jar + compile + ++ + + org.apache.logging.log4j + log4j-core +- 2.17.0 ++ 2.25.0 + compile + ++ ++ org.apache.logging.log4j ++ log4j-api ++ 2.25.0 ++ compile ++ ++ + + org.spigotmc + minecraft-server +@@ -69,13 +77,20 @@ + jar + compile + ++ + +- jline +- jline +- 2.12.1 +- jar ++ org.jline ++ jline-terminal-jni ++ 3.30.4 + compile + ++ ++ net.minecrell ++ terminalconsoleappender ++ 1.3.0 ++ compile ++ ++ + + org.xerial + sqlite-jdbc +@@ -187,7 +202,6 @@ + Bukkit + ${api.version} + Bukkit Team +- true + + + +@@ -215,7 +229,16 @@ + + org.apache.maven.plugins + maven-shade-plugin +- 3.5.0 ++ ++ 3.5.0 ++ ++ ++ org.apache.logging.log4j ++ log4j-transform-maven-shade-plugin-extensions ++ 0.2.0 ++ ++ ++ + + + package +@@ -239,10 +262,6 @@ + joptsimple + org.bukkit.craftbukkit.libs.joptsimple + +- +- jline +- org.bukkit.craftbukkit.libs.jline +- + + org.ibex + org.bukkit.craftbukkit.libs.org.ibex +@@ -263,6 +282,17 @@ + net.minecraft.server.v${minecraft_version} + + ++ ++ ++ ++ ++ ++ ++ true ++ ++ ++ ++ + + + +diff --git a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java +new file mode 100644 +index 00000000..5e2c4998 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java +@@ -0,0 +1,41 @@ ++package com.destroystokyo.paper.console; ++ ++import net.minecraft.server.DedicatedServer; ++import net.minecrell.terminalconsole.SimpleTerminalConsole; ++import org.bukkit.craftbukkit.command.ConsoleCommandCompleter; ++import org.jline.reader.LineReader; ++import org.jline.reader.LineReaderBuilder; ++ ++public final class PaperConsole extends SimpleTerminalConsole { ++ ++ private final DedicatedServer server; ++ ++ public PaperConsole(DedicatedServer server) { ++ this.server = server; ++ } ++ ++ @Override ++ protected LineReader buildReader(LineReaderBuilder builder) { ++ return super.buildReader(builder ++ .appName("Paper") ++ .variable(LineReader.HISTORY_FILE, java.nio.file.Paths.get(".console_history")) ++ .completer(new ConsoleCommandCompleter(this.server)) ++ ); ++ } ++ ++ @Override ++ protected boolean isRunning() { ++ return !this.server.isStopped() && this.server.isRunning(); ++ } ++ ++ @Override ++ protected void runCommand(String command) { ++ this.server.issueCommand(command, this.server); ++ } ++ ++ @Override ++ protected void shutdown() { ++ this.server.safeShutdown(); ++ } ++ ++} +\ No newline at end of file +diff --git a/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java b/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java +new file mode 100644 +index 00000000..61f9446b +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java +@@ -0,0 +1,17 @@ ++package com.destroystokyo.paper.console; ++ ++import org.apache.logging.log4j.LogManager; ++import org.apache.logging.log4j.Logger; ++import org.bukkit.craftbukkit.command.CraftConsoleCommandSender; ++ ++public class TerminalConsoleCommandSender extends CraftConsoleCommandSender { ++ ++ private static final Logger LOGGER = LogManager.getRootLogger(); ++ ++ @Override ++ public void sendRawMessage(String message) { ++ // TerminalConsoleAppender supports color codes directly in log messages ++ LOGGER.info(message); ++ } ++ ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java +index 79a53cc4..194609e7 100644 +--- a/src/main/java/net/minecraft/server/DedicatedServer.java ++++ b/src/main/java/net/minecraft/server/DedicatedServer.java +@@ -69,7 +69,9 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer + return; + } + // CraftBukkit end +- ++ // SportPaper start - Use TerminalConsoleAppender ++ new com.destroystokyo.paper.console.PaperConsole(DedicatedServer.this).start(); ++ /* + jline.console.ConsoleReader bufferedreader = reader; // CraftBukkit + String s; + +@@ -90,6 +92,8 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer + DedicatedServer.LOGGER.error("Exception handling console input", ioexception); + } + ++ */ ++ // SportPaper end + } + }; + +@@ -101,6 +105,9 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer + } + global.addHandler(new org.bukkit.craftbukkit.util.ForwardLogHandler()); + ++ // SportPaper start - Not needed with TerminalConsoleAppender ++ final org.apache.logging.log4j.Logger logger = LogManager.getRootLogger(); ++ /* + final org.apache.logging.log4j.core.Logger logger = ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()); + for (org.apache.logging.log4j.core.Appender appender : logger.getAppenders().values()) { + if (appender instanceof org.apache.logging.log4j.core.appender.ConsoleAppender) { +@@ -109,6 +116,8 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer + } + + new Thread(new org.bukkit.craftbukkit.util.TerminalConsoleWriterThread(System.out, this.reader)).start(); ++ */ ++ // SportPaper end + + System.setOut(new PrintStream(new LoggerOutputStream(logger, Level.INFO), true)); + System.setErr(new PrintStream(new LoggerOutputStream(logger, Level.WARN), true)); +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 53bcd950..3aaa9be6 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -47,7 +47,7 @@ import org.apache.logging.log4j.Logger; + import java.io.IOException; + import java.util.concurrent.atomic.AtomicBoolean; + +-import jline.console.ConsoleReader; ++// import jline.console.ConsoleReader; + import joptsimple.OptionSet; + + import org.bukkit.craftbukkit.Main; +@@ -124,7 +124,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs + public OptionSet options; + public org.bukkit.command.ConsoleCommandSender console; + public org.bukkit.command.RemoteConsoleCommandSender remoteConsole; +- public ConsoleReader reader; ++ // public ConsoleReader reader; // SportPaper - Use TerminalConsoleAppender + public static int currentTick = 0; // PaperSpigot - Further improve tick loop + public final Thread primaryThread; + //public java.util.Queue processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); SportBukkit - use Mojang's task queue +@@ -154,7 +154,9 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs + this.Y = this.V.createProfileRepository(); + // CraftBukkit start + this.options = options; ++ // SportPaper start - Handled by TerminalConsoleAppender + // Try to see if we're actually running in a terminal, disable jline if not ++ /* + if (System.console() == null && System.getProperty("jline.terminal") == null) { + System.setProperty("jline.terminal", "jline.UnsupportedTerminal"); + Main.useJline = false; +@@ -175,6 +177,8 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs + LOGGER.warn((String) null, ex); + } + } ++ */ ++ // SportPaper end + Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this)); + + this.serverThread = primaryThread = new Thread(this, "Server thread"); // Moved from main +@@ -765,7 +769,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs + } finally { + // CraftBukkit start - Restore terminal to original settings + try { +- reader.getTerminal().restore(); ++ net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // SportPaper - Use TerminalConsoleAppender + } catch (Exception ignored) { + } + // CraftBukkit end +@@ -1294,7 +1298,8 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs + } + + public void sendMessage(IChatBaseComponent ichatbasecomponent) { +- this.console.sendMessage(ichatbasecomponent.c()); // CraftBukkit - we want coloured and pretty messages too! ++ // SportPaper - Log message with colors ++ MinecraftServer.LOGGER.info(org.bukkit.craftbukkit.util.CraftChatMessage.fromComponent(ichatbasecomponent, EnumChatFormat.RESET)); + } + + public boolean a(int i, String s) { +diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java +index cb6a3be0..39d24de7 100644 +--- a/src/main/java/net/minecraft/server/PlayerList.java ++++ b/src/main/java/net/minecraft/server/PlayerList.java +@@ -72,8 +72,7 @@ public abstract class PlayerList { + + public PlayerList(MinecraftServer minecraftserver) { + this.cserver = minecraftserver.server = new CraftServer(minecraftserver, this); +- minecraftserver.console = org.bukkit.craftbukkit.command.ColouredConsoleSender.getInstance(); +- minecraftserver.reader.addCompleter(new org.bukkit.craftbukkit.command.ConsoleCommandCompleter(minecraftserver.server)); ++ minecraftserver.console = new com.destroystokyo.paper.console.TerminalConsoleCommandSender(); // SportPaper + // CraftBukkit end + + this.k = new GameProfileBanList(PlayerList.a); +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +index 52b2d106..e5343791 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +@@ -120,7 +120,7 @@ import io.netty.buffer.ByteBuf; + import io.netty.buffer.ByteBufOutputStream; + import io.netty.buffer.Unpooled; + import io.netty.handler.codec.base64.Base64; +-import jline.console.ConsoleReader; ++// import jline.console.ConsoleReader; + import net.md_5.bungee.api.chat.BaseComponent; + + public final class CraftServer implements Server { +@@ -986,9 +986,13 @@ public final class CraftServer implements Server { + return logger; + } + ++ // SportPaper start - JLine update ++ /* + public ConsoleReader getReader() { + return console.reader; + } ++ */ ++ // SportPaper end + + @Override + public PluginCommand getPluginCommand(String name) { +diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java +index 737904d4..4f2ae747 100644 +--- a/src/main/java/org/bukkit/craftbukkit/Main.java ++++ b/src/main/java/org/bukkit/craftbukkit/Main.java +@@ -10,7 +10,7 @@ import java.util.logging.Logger; + import joptsimple.OptionParser; + import joptsimple.OptionSet; + import net.minecraft.server.MinecraftServer; +-import org.fusesource.jansi.AnsiConsole; ++// import org.fusesource.jansi.AnsiConsole; + + public class Main { + public static boolean useJline = true; +@@ -193,6 +193,8 @@ public class Main { + } + + try { ++ // SportPaper start - Handled by TerminalConsoleAppender ++ /* + // This trick bypasses Maven Shade's clever rewriting of our getProperty call when using String literals + String jline_UnsupportedTerminal = new String(new char[] {'j','l','i','n','e','.','U','n','s','u','p','p','o','r','t','e','d','T','e','r','m','i','n','a','l'}); + String jline_terminal = new String(new char[] {'j','l','i','n','e','.','t','e','r','m','i','n','a','l'}); +@@ -210,10 +212,18 @@ public class Main { + // This ensures the terminal literal will always match the jline implementation + System.setProperty(jline.TerminalFactory.JLINE_TERMINAL, jline.UnsupportedTerminal.class.getName()); + } ++ */ + ++ if (options.has("nojline")) { ++ System.setProperty(net.minecrell.terminalconsole.TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); ++ useJline = false; ++ } ++ // SportPaper end + + if (options.has("noconsole")) { + useConsole = false; ++ useJline = false; // SportPaper ++ System.setProperty(net.minecrell.terminalconsole.TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // SportPaper + } + + // Spigot Start +diff --git a/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java b/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java +index 26a2fb89..d2c8a827 100644 +--- a/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java ++++ b/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java +@@ -3,16 +3,18 @@ package org.bukkit.craftbukkit.command; + import java.util.EnumMap; + import java.util.Map; + ++/* + import org.fusesource.jansi.Ansi; + import org.fusesource.jansi.Ansi.Attribute; + import jline.Terminal; ++*/ + + import org.bukkit.Bukkit; + import org.bukkit.ChatColor; + import org.bukkit.command.ConsoleCommandSender; + import org.bukkit.craftbukkit.CraftServer; + +-public class ColouredConsoleSender extends CraftConsoleCommandSender { ++public class ColouredConsoleSender /* extends CraftConsoleCommandSender */ {/* // SportPaper - comment out whole class + private final Terminal terminal; + private final Map replacements = new EnumMap(ChatColor.class); + private final ChatColor[] colors = ChatColor.values(); +@@ -71,4 +73,5 @@ public class ColouredConsoleSender extends CraftConsoleCommandSender { + return new ColouredConsoleSender(); + } + } ++ */ // SportPaper end - comment out whole class + } +diff --git a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java +index 7dc9f53c..7324a5c4 100644 +--- a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java ++++ b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java +@@ -7,41 +7,63 @@ import java.util.logging.Level; + import org.bukkit.craftbukkit.CraftServer; + import org.bukkit.craftbukkit.util.Waitable; + +-import jline.console.completer.Completer; ++// SportPaper start - JLine update ++import net.minecraft.server.DedicatedServer; // Paper ++import org.jline.reader.Candidate; ++import org.jline.reader.Completer; ++import org.jline.reader.LineReader; ++import org.jline.reader.ParsedLine; ++// SportPaper end + + public class ConsoleCommandCompleter implements Completer { +- private final CraftServer server; ++ private final DedicatedServer server; // SportPaper - CraftServer -> DedicatedServer + +- public ConsoleCommandCompleter(CraftServer server) { ++ public ConsoleCommandCompleter(DedicatedServer server) { // SportPaper - CraftServer -> DedicatedServer + this.server = server; + } + +- public int complete(final String buffer, final int cursor, final List candidates) { ++ // SportPaper start - Change method signature for JLine update ++ public void complete(LineReader reader, ParsedLine line, List candidates) { ++ final CraftServer server = this.server.server; ++ final String buffer = line.line(); ++ // SportPaper end + Waitable> waitable = new Waitable>() { + @Override + protected List evaluate() { + return server.getCommandMap().tabComplete(server.getConsoleSender(), buffer); + } + }; +- this.server.getServer().addMainThreadTask(waitable); ++ server.getServer().addMainThreadTask(waitable); // SportPaper - remove "this." + try { + List offers = waitable.get(); + if (offers == null) { +- return cursor; ++ return; // SportPaper - method returns void + } +- candidates.addAll(offers); + ++ // SportPaper start - JLine update ++ for (String completion : offers) { ++ if (completion.isEmpty()) { ++ continue; ++ } ++ ++ candidates.add(new Candidate(completion)); ++ } ++ // SportPaper end ++ ++ // SportPaper start - JLine handles cursor now ++ /* + final int lastSpace = buffer.lastIndexOf(' '); + if (lastSpace == -1) { + return cursor - buffer.length(); + } else { + return cursor - (buffer.length() - lastSpace - 1); + } ++ */ ++ // SportPaper end + } catch (ExecutionException e) { +- this.server.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e); ++ server.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e); // SportPaper - remove "this." + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } +- return cursor; + } + } +diff --git a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java +index ae3481ba..35ec02a0 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java +@@ -18,7 +18,7 @@ public class ServerShutdownThread extends Thread { + ex.printStackTrace(); + } finally { + try { +- server.reader.getTerminal().restore(); ++ net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // SportPaper - Use TerminalConsoleAppender + } catch (Exception e) { + } + } +diff --git a/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java b/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java +index 772f730f..15a806d1 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java +@@ -4,11 +4,11 @@ import java.io.IOException; + import java.io.OutputStream; + import java.util.logging.Level; + import java.util.logging.Logger; +-import jline.console.ConsoleReader; ++// import jline.console.ConsoleReader; + import com.mojang.util.QueueLogAppender; + import org.bukkit.craftbukkit.Main; + +-public class TerminalConsoleWriterThread implements Runnable { ++public class TerminalConsoleWriterThread /* implements Runnable */ { /* SportPaper - comment out whole class + final private ConsoleReader reader; + final private OutputStream output; + +@@ -49,4 +49,5 @@ public class TerminalConsoleWriterThread implements Runnable { + } + } + } ++ */ // SportPaper end - comment out whole class + } +diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml +index 63cb069f..a3fcd871 100644 +--- a/src/main/resources/log4j2.xml ++++ b/src/main/resources/log4j2.xml +@@ -1,12 +1,11 @@ + +- ++ + +- +- +- +- ++ ++ ++ + +- ++ + + + +@@ -18,7 +17,6 @@ + + + +- + + + +-- +2.50.0 + diff --git a/patches/server/0230-Use-Log4j-IOStreams-to-redirect-System.out-err-to-lo.patch b/patches/server/0230-Use-Log4j-IOStreams-to-redirect-System.out-err-to-lo.patch new file mode 100644 index 00000000..85f89bc4 --- /dev/null +++ b/patches/server/0230-Use-Log4j-IOStreams-to-redirect-System.out-err-to-lo.patch @@ -0,0 +1,78 @@ +From 3f289a88c1f05aeab139a92ef1b182ee31aa05ea Mon Sep 17 00:00:00 2001 +From: Minecrell +Date: Mon, 18 Sep 2017 12:00:03 +0200 +Subject: [PATCH] Use Log4j IOStreams to redirect System.out/err to logger + +Log4j2 provides an optimized implementation of PrintStream that +redirects its output to a logger. Use it instead of a custom +implementation for minor performance improvements and some fixes. + +With the old implementation, each call to System.print() +results in a separate line, even though it should not result in +a line break. Log4j's implementation handles it correctly. + +diff --git a/pom.xml b/pom.xml +index 38d8bf98..72385638 100644 +--- a/pom.xml ++++ b/pom.xml +@@ -62,6 +62,12 @@ + 2.25.0 + compile + ++ ++ org.apache.logging.log4j ++ log4j-iostreams ++ 2.25.0 ++ compile ++ + + + org.spigotmc +diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java +index 194609e7..a833297e 100644 +--- a/src/main/java/net/minecraft/server/DedicatedServer.java ++++ b/src/main/java/net/minecraft/server/DedicatedServer.java +@@ -19,7 +19,7 @@ import org.apache.logging.log4j.Logger; + import java.io.PrintStream; + import org.apache.logging.log4j.Level; + +-import org.bukkit.craftbukkit.LoggerOutputStream; ++// import org.bukkit.craftbukkit.LoggerOutputStream; // SportPaper - Use Log4j IOStreams + import co.aikar.timings.SpigotTimings; // Spigot + import org.bukkit.event.server.ServerCommandEvent; + import org.bukkit.craftbukkit.util.Waitable; +@@ -119,8 +119,10 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer + */ + // SportPaper end + +- System.setOut(new PrintStream(new LoggerOutputStream(logger, Level.INFO), true)); +- System.setErr(new PrintStream(new LoggerOutputStream(logger, Level.WARN), true)); ++ // SportPaper start - Use Log4j IOStreams ++ System.setOut(org.apache.logging.log4j.io.IoBuilder.forLogger(logger).setLevel(Level.INFO).buildPrintStream()); ++ System.setErr(org.apache.logging.log4j.io.IoBuilder.forLogger(logger).setLevel(Level.WARN).buildPrintStream()); ++ // SportPaper end + // CraftBukkit end + + thread.setDaemon(true); +diff --git a/src/main/java/org/bukkit/craftbukkit/LoggerOutputStream.java b/src/main/java/org/bukkit/craftbukkit/LoggerOutputStream.java +index 93526ab6..7dd83f9b 100644 +--- a/src/main/java/org/bukkit/craftbukkit/LoggerOutputStream.java ++++ b/src/main/java/org/bukkit/craftbukkit/LoggerOutputStream.java +@@ -5,7 +5,7 @@ import java.io.IOException; + import org.apache.logging.log4j.Level; + import org.apache.logging.log4j.Logger; + +-public class LoggerOutputStream extends ByteArrayOutputStream { ++public class LoggerOutputStream extends ByteArrayOutputStream { /* SportPaper - comment out whole class + private final String separator = System.getProperty("line.separator"); + private final Logger logger; + private final Level level; +@@ -28,4 +28,5 @@ public class LoggerOutputStream extends ByteArrayOutputStream { + } + } + } ++ */ + } +-- +2.50.0 + diff --git a/patches/server/0231-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch b/patches/server/0231-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch new file mode 100644 index 00000000..5fbfda28 --- /dev/null +++ b/patches/server/0231-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch @@ -0,0 +1,51 @@ +From 6c14dadfed2162e493010629fa6c58cfe6920147 Mon Sep 17 00:00:00 2001 +From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> +Date: Thu, 12 Aug 2021 04:46:41 -0700 +Subject: [PATCH] Use AsyncAppender to keep logging IO off main thread + + +diff --git a/pom.xml b/pom.xml +index 72385638..798bcd4b 100644 +--- a/pom.xml ++++ b/pom.xml +@@ -111,6 +111,13 @@ + jar + compile + ++ ++ ++ com.lmax ++ disruptor ++ 3.4.4 ++ runtime ++ + + + junit +diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml +index a3fcd871..128f6ece 100644 +--- a/src/main/resources/log4j2.xml ++++ b/src/main/resources/log4j2.xml +@@ -11,14 +11,17 @@ + + + ++ ++ ++ ++ + + + + + + +- +- ++ + + + +-- +2.50.0 +