mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-30 16:19:03 +01:00
Use net.kyori.ansi for console logging (#9313)
Uses the new ANSIComponentSerializer introduced in Adventure 4.14.0 to serialize components when logging them via the ComponentLogger, or when sending messages to the console. This replaces the old solution which uses legacy jank and custom color conversions, with a new library that handles the conversion and config
This commit is contained in:
parent
bc6e534738
commit
6925d11945
6 changed files with 156 additions and 358 deletions
|
@ -1,327 +0,0 @@
|
||||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Josh Roy <10731363+JRoy@users.noreply.github.com>
|
|
||||||
Date: Sat, 20 Feb 2021 13:09:59 -0500
|
|
||||||
Subject: [PATCH] Add support for hex color codes in console
|
|
||||||
|
|
||||||
Converts upstream's hex color code legacy format into actual hex color codes in the console.
|
|
||||||
|
|
||||||
diff --git a/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java b/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java
|
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
||||||
--- a/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java
|
|
||||||
+++ b/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java
|
|
||||||
@@ -0,0 +0,0 @@
|
|
||||||
package com.destroystokyo.paper.console;
|
|
||||||
|
|
||||||
+import net.kyori.adventure.audience.MessageType;
|
|
||||||
+import net.kyori.adventure.identity.Identity;
|
|
||||||
+import net.kyori.adventure.text.Component;
|
|
||||||
+import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
|
||||||
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
||||||
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();
|
|
||||||
+ private static final ComponentLogger LOGGER = ComponentLogger.logger(LogManager.getRootLogger().getName());
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendRawMessage(String message) {
|
|
||||||
- // TerminalConsoleAppender supports color codes directly in log messages
|
|
||||||
+ final Component msg = LegacyComponentSerializer.legacySection().deserialize(message);
|
|
||||||
+ this.sendMessage(Identity.nil(), msg, MessageType.SYSTEM);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ @Override
|
|
||||||
+ public void sendMessage(Identity identity, Component message, MessageType type) {
|
|
||||||
LOGGER.info(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/src/main/java/io/papermc/paper/adventure/providers/ComponentLoggerProviderImpl.java b/src/main/java/io/papermc/paper/adventure/providers/ComponentLoggerProviderImpl.java
|
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
||||||
--- a/src/main/java/io/papermc/paper/adventure/providers/ComponentLoggerProviderImpl.java
|
|
||||||
+++ b/src/main/java/io/papermc/paper/adventure/providers/ComponentLoggerProviderImpl.java
|
|
||||||
@@ -0,0 +0,0 @@
|
|
||||||
package io.papermc.paper.adventure.providers;
|
|
||||||
|
|
||||||
-import io.papermc.paper.adventure.PaperAdventure;
|
|
||||||
+import io.papermc.paper.console.HexFormattingConverter;
|
|
||||||
+import java.util.Locale;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
|
||||||
import net.kyori.adventure.text.logger.slf4j.ComponentLoggerProvider;
|
|
||||||
+import net.kyori.adventure.translation.GlobalTranslator;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
@@ -0,0 +0,0 @@ public class ComponentLoggerProviderImpl implements ComponentLoggerProvider {
|
|
||||||
}
|
|
||||||
|
|
||||||
private String serialize(final Component message) {
|
|
||||||
- return PaperAdventure.asPlain(message, null);
|
|
||||||
+ return HexFormattingConverter.SERIALIZER.serialize(GlobalTranslator.render(message, Locale.getDefault()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/src/main/java/io/papermc/paper/console/HexFormattingConverter.java b/src/main/java/io/papermc/paper/console/HexFormattingConverter.java
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/src/main/java/io/papermc/paper/console/HexFormattingConverter.java
|
|
||||||
@@ -0,0 +0,0 @@
|
|
||||||
+package io.papermc.paper.console;
|
|
||||||
+
|
|
||||||
+import io.papermc.paper.configuration.GlobalConfiguration;
|
|
||||||
+import io.papermc.paper.adventure.PaperAdventure;
|
|
||||||
+import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
+import net.kyori.adventure.text.format.TextColor;
|
|
||||||
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
||||||
+import net.minecrell.terminalconsole.TerminalConsoleAppender;
|
|
||||||
+import org.apache.logging.log4j.core.LogEvent;
|
|
||||||
+import org.apache.logging.log4j.core.config.Configuration;
|
|
||||||
+import org.apache.logging.log4j.core.config.plugins.Plugin;
|
|
||||||
+import org.apache.logging.log4j.core.layout.PatternLayout;
|
|
||||||
+import org.apache.logging.log4j.core.pattern.ConverterKeys;
|
|
||||||
+import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
|
|
||||||
+import org.apache.logging.log4j.core.pattern.PatternConverter;
|
|
||||||
+import org.apache.logging.log4j.core.pattern.PatternFormatter;
|
|
||||||
+import org.apache.logging.log4j.core.pattern.PatternParser;
|
|
||||||
+import org.apache.logging.log4j.util.PerformanceSensitive;
|
|
||||||
+import org.apache.logging.log4j.util.PropertiesUtil;
|
|
||||||
+
|
|
||||||
+import java.util.List;
|
|
||||||
+import java.util.regex.Matcher;
|
|
||||||
+import java.util.regex.Pattern;
|
|
||||||
+
|
|
||||||
+import static net.minecrell.terminalconsole.MinecraftFormattingConverter.KEEP_FORMATTING_PROPERTY;
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * Modified version of <a href="https://github.com/Minecrell/TerminalConsoleAppender/blob/master/src/main/java/net/minecrell/terminalconsole/MinecraftFormattingConverter.java">
|
|
||||||
+ * TerminalConsoleAppender's MinecraftFormattingConverter</a> to support hex color codes using the Adventure [char]#rrggbb format.
|
|
||||||
+ */
|
|
||||||
+@Plugin(name = "paperMinecraftFormatting", category = PatternConverter.CATEGORY)
|
|
||||||
+@ConverterKeys({"paperMinecraftFormatting"})
|
|
||||||
+@PerformanceSensitive("allocation")
|
|
||||||
+public final class HexFormattingConverter extends LogEventPatternConverter {
|
|
||||||
+
|
|
||||||
+ private static final boolean KEEP_FORMATTING = PropertiesUtil.getProperties().getBooleanProperty(KEEP_FORMATTING_PROPERTY);
|
|
||||||
+
|
|
||||||
+ private static final String ANSI_RESET = "\u001B[m";
|
|
||||||
+
|
|
||||||
+ private static final char COLOR_CHAR = 0x7f;
|
|
||||||
+ public static final LegacyComponentSerializer SERIALIZER = LegacyComponentSerializer.builder()
|
|
||||||
+ .hexColors()
|
|
||||||
+ .flattener(PaperAdventure.FLATTENER)
|
|
||||||
+ .character(HexFormattingConverter.COLOR_CHAR)
|
|
||||||
+ .build();
|
|
||||||
+ private static final String LOOKUP = "0123456789abcdefklmnor";
|
|
||||||
+
|
|
||||||
+ private static final String RGB_ANSI = "\u001B[38;2;%d;%d;%dm";
|
|
||||||
+ private static final String RESET_RGB_ANSI = ANSI_RESET + RGB_ANSI;
|
|
||||||
+ private static final Pattern NAMED_PATTERN = Pattern.compile(COLOR_CHAR + "[0-9a-fk-orA-FK-OR]");
|
|
||||||
+ private static final Pattern RGB_PATTERN = Pattern.compile(COLOR_CHAR + "#([0-9a-fA-F]){6}");
|
|
||||||
+
|
|
||||||
+ private static final String[] RGB_ANSI_CODES = new String[]{
|
|
||||||
+ formatHexAnsi(NamedTextColor.BLACK), // Black §0
|
|
||||||
+ formatHexAnsi(NamedTextColor.DARK_BLUE), // Dark Blue §1
|
|
||||||
+ formatHexAnsi(NamedTextColor.DARK_GREEN), // Dark Green §2
|
|
||||||
+ formatHexAnsi(NamedTextColor.DARK_AQUA), // Dark Aqua §3
|
|
||||||
+ formatHexAnsi(NamedTextColor.DARK_RED), // Dark Red §4
|
|
||||||
+ formatHexAnsi(NamedTextColor.DARK_PURPLE), // Dark Purple §5
|
|
||||||
+ formatHexAnsi(NamedTextColor.GOLD), // Gold §6
|
|
||||||
+ formatHexAnsi(NamedTextColor.GRAY), // Gray §7
|
|
||||||
+ formatHexAnsi(NamedTextColor.DARK_GRAY), // Dark Gray §8
|
|
||||||
+ formatHexAnsi(NamedTextColor.BLUE), // Blue §9
|
|
||||||
+ formatHexAnsi(NamedTextColor.GREEN), // Green §a
|
|
||||||
+ formatHexAnsi(NamedTextColor.AQUA), // Aqua §b
|
|
||||||
+ formatHexAnsi(NamedTextColor.RED), // Red §c
|
|
||||||
+ formatHexAnsi(NamedTextColor.LIGHT_PURPLE), // Light Purple §d
|
|
||||||
+ formatHexAnsi(NamedTextColor.YELLOW), // Yellow §e
|
|
||||||
+ formatHexAnsi(NamedTextColor.WHITE), // White §f
|
|
||||||
+ "\u001B[5m", // Obfuscated §k
|
|
||||||
+ "\u001B[1m", // Bold §l
|
|
||||||
+ "\u001B[9m", // Strikethrough §m
|
|
||||||
+ "\u001B[4m", // Underline §n
|
|
||||||
+ "\u001B[3m", // Italic §o
|
|
||||||
+ ANSI_RESET, // Reset §r
|
|
||||||
+ };
|
|
||||||
+ private static final String[] ANSI_ANSI_CODES = new String[]{
|
|
||||||
+ ANSI_RESET + "\u001B[0;30m", // Black §0
|
|
||||||
+ ANSI_RESET + "\u001B[0;34m", // Dark Blue §1
|
|
||||||
+ ANSI_RESET + "\u001B[0;32m", // Dark Green §2
|
|
||||||
+ ANSI_RESET + "\u001B[0;36m", // Dark Aqua §3
|
|
||||||
+ ANSI_RESET + "\u001B[0;31m", // Dark Red §4
|
|
||||||
+ ANSI_RESET + "\u001B[0;35m", // Dark Purple §5
|
|
||||||
+ ANSI_RESET + "\u001B[0;33m", // Gold §6
|
|
||||||
+ ANSI_RESET + "\u001B[0;37m", // Gray §7
|
|
||||||
+ ANSI_RESET + "\u001B[0;30;1m", // Dark Gray §8
|
|
||||||
+ ANSI_RESET + "\u001B[0;34;1m", // Blue §9
|
|
||||||
+ ANSI_RESET + "\u001B[0;32;1m", // Green §a
|
|
||||||
+ ANSI_RESET + "\u001B[0;36;1m", // Aqua §b
|
|
||||||
+ ANSI_RESET + "\u001B[0;31;1m", // Red §c
|
|
||||||
+ ANSI_RESET + "\u001B[0;35;1m", // Light Purple §d
|
|
||||||
+ ANSI_RESET + "\u001B[0;33;1m", // Yellow §e
|
|
||||||
+ ANSI_RESET + "\u001B[0;37;1m", // White §f
|
|
||||||
+ "\u001B[5m", // Obfuscated §k
|
|
||||||
+ "\u001B[1m", // Bold §l
|
|
||||||
+ "\u001B[9m", // Strikethrough §m
|
|
||||||
+ "\u001B[4m", // Underline §n
|
|
||||||
+ "\u001B[3m", // Italic §o
|
|
||||||
+ ANSI_RESET, // Reset §r
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ private final boolean ansi;
|
|
||||||
+ private final List<PatternFormatter> formatters;
|
|
||||||
+
|
|
||||||
+ /**
|
|
||||||
+ * Construct the converter.
|
|
||||||
+ *
|
|
||||||
+ * @param formatters The pattern formatters to generate the text to manipulate
|
|
||||||
+ * @param strip If true, the converter will strip all formatting codes
|
|
||||||
+ */
|
|
||||||
+ protected HexFormattingConverter(List<PatternFormatter> formatters, boolean strip) {
|
|
||||||
+ super("paperMinecraftFormatting", null);
|
|
||||||
+ this.formatters = formatters;
|
|
||||||
+ this.ansi = !strip;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ @Override
|
|
||||||
+ public void format(LogEvent event, StringBuilder toAppendTo) {
|
|
||||||
+ int start = toAppendTo.length();
|
|
||||||
+ //noinspection ForLoopReplaceableByForEach
|
|
||||||
+ for (int i = 0, size = formatters.size(); i < size; i++) {
|
|
||||||
+ formatters.get(i).format(event, toAppendTo);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (KEEP_FORMATTING || toAppendTo.length() == start) {
|
|
||||||
+ // Skip replacement if disabled or if the content is empty
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ boolean useAnsi = ansi && TerminalConsoleAppender.isAnsiSupported();
|
|
||||||
+ String content = toAppendTo.substring(start);
|
|
||||||
+ content = useAnsi ? convertRGBColors(content) : stripRGBColors(content);
|
|
||||||
+ format(content, toAppendTo, start, useAnsi);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static String convertRGBColors(final String input) {
|
|
||||||
+ return RGB_PATTERN.matcher(input).replaceAll(result -> {
|
|
||||||
+ final int hex = Integer.decode(result.group().substring(1));
|
|
||||||
+ return formatHexAnsi(hex);
|
|
||||||
+ });
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static String formatHexAnsi(final TextColor color) {
|
|
||||||
+ return formatHexAnsi(color.value());
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static String formatHexAnsi(final int color) {
|
|
||||||
+ final int red = color >> 16 & 0xFF;
|
|
||||||
+ final int green = color >> 8 & 0xFF;
|
|
||||||
+ final int blue = color & 0xFF;
|
|
||||||
+ return String.format(RESET_RGB_ANSI, red, green, blue);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private static String stripRGBColors(final String input) {
|
|
||||||
+ return RGB_PATTERN.matcher(input).replaceAll("");
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ static void format(String content, StringBuilder result, int start, boolean ansi) {
|
|
||||||
+ int next = content.indexOf(COLOR_CHAR);
|
|
||||||
+ int last = content.length() - 1;
|
|
||||||
+ if (next == -1 || next == last) {
|
|
||||||
+ result.setLength(start);
|
|
||||||
+ result.append(content);
|
|
||||||
+ if (ansi) {
|
|
||||||
+ result.append(ANSI_RESET);
|
|
||||||
+ }
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ Matcher matcher = NAMED_PATTERN.matcher(content);
|
|
||||||
+ StringBuilder buffer = new StringBuilder();
|
|
||||||
+ final String[] ansiCodes = GlobalConfiguration.get().logging.useRgbForNamedTextColors ? RGB_ANSI_CODES : ANSI_ANSI_CODES;
|
|
||||||
+ while (matcher.find()) {
|
|
||||||
+ int format = LOOKUP.indexOf(Character.toLowerCase(matcher.group().charAt(1)));
|
|
||||||
+ if (format != -1) {
|
|
||||||
+ matcher.appendReplacement(buffer, ansi ? ansiCodes[format] : "");
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ matcher.appendTail(buffer);
|
|
||||||
+
|
|
||||||
+ result.setLength(start);
|
|
||||||
+ result.append(buffer);
|
|
||||||
+ if (ansi) {
|
|
||||||
+ result.append(ANSI_RESET);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /**
|
|
||||||
+ * Gets a new instance of the {@link HexFormattingConverter} with the
|
|
||||||
+ * specified options.
|
|
||||||
+ *
|
|
||||||
+ * @param config The current configuration
|
|
||||||
+ * @param options The pattern options
|
|
||||||
+ * @return The new instance
|
|
||||||
+ * @see HexFormattingConverter
|
|
||||||
+ */
|
|
||||||
+ public static HexFormattingConverter newInstance(Configuration config, String[] options) {
|
|
||||||
+ if (options.length < 1 || options.length > 2) {
|
|
||||||
+ LOGGER.error("Incorrect number of options on paperMinecraftFormatting. Expected at least 1, max 2 received " + options.length);
|
|
||||||
+ return null;
|
|
||||||
+ }
|
|
||||||
+ if (options[0] == null) {
|
|
||||||
+ LOGGER.error("No pattern supplied on paperMinecraftFormatting");
|
|
||||||
+ return null;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ PatternParser parser = PatternLayout.createPatternParser(config);
|
|
||||||
+ List<PatternFormatter> formatters = parser.parse(options[0]);
|
|
||||||
+ boolean strip = options.length > 1 && "strip".equals(options[1]);
|
|
||||||
+ return new HexFormattingConverter(formatters, strip);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+}
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
||||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
||||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
||||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendSystemMessage(Component message) {
|
|
||||||
- MinecraftServer.LOGGER.info(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(io.papermc.paper.adventure.PaperAdventure.asAdventure(message))); // Paper - Log message with colors
|
|
||||||
+ MinecraftServer.LOGGER.info(io.papermc.paper.console.HexFormattingConverter.SERIALIZER.serialize(io.papermc.paper.adventure.PaperAdventure.asAdventure(message))); // Paper - Log message with colors
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyPair getKeyPair() {
|
|
||||||
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 @@
|
|
||||||
</Queue>
|
|
||||||
<TerminalConsole name="TerminalConsole">
|
|
||||||
<PatternLayout>
|
|
||||||
- <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %minecraftFormatting{%msg}%n%xEx{full}}">
|
|
||||||
+ <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %paperMinecraftFormatting{%msg}%n%xEx{full}}">
|
|
||||||
<!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
|
||||||
<!-- Disable prefix for various plugins that bypass the plugin logger -->
|
|
||||||
<PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
|
|
||||||
- pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx{full}}" />
|
|
||||||
+ pattern="%highlightError{[%d{HH:mm:ss} %level]: %paperMinecraftFormatting{%msg}%n%xEx{full}}" />
|
|
||||||
</LoggerNamePatternSelector>
|
|
||||||
</PatternLayout>
|
|
||||||
</TerminalConsole>
|
|
||||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
|
||||||
<PatternLayout>
|
|
||||||
- <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %minecraftFormatting{%msg}{strip}%n%xEx{full}">
|
|
||||||
+ <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %paperMinecraftFormatting{%msg}{strip}%n%xEx{full}">
|
|
||||||
<!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
|
||||||
<!-- Disable prefix for various plugins that bypass the plugin logger -->
|
|
||||||
<PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
|
|
||||||
- pattern="[%d{HH:mm:ss}] [%t/%level]: %minecraftFormatting{%msg}{strip}%n%xEx{full}" />
|
|
||||||
+ pattern="[%d{HH:mm:ss}] [%t/%level]: %paperMinecraftFormatting{%msg}{strip}%n%xEx{full}" />
|
|
||||||
</LoggerNamePatternSelector>
|
|
||||||
</PatternLayout>
|
|
||||||
<Policies>
|
|
|
@ -9,14 +9,6 @@ diff --git a/build.gradle.kts b/build.gradle.kts
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/build.gradle.kts
|
--- a/build.gradle.kts
|
||||||
+++ b/build.gradle.kts
|
+++ b/build.gradle.kts
|
||||||
@@ -0,0 +0,0 @@ dependencies {
|
|
||||||
Scanning takes about 1-2 seconds so adding this speeds up the server start.
|
|
||||||
*/
|
|
||||||
implementation("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - implementation
|
|
||||||
+ annotationProcessor("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - Needed to generate meta for our Log4j plugins
|
|
||||||
// Paper end
|
|
||||||
implementation("org.apache.logging.log4j:log4j-iostreams:2.19.0") // Paper - remove exclusion
|
|
||||||
implementation("org.ow2.asm:asm:9.4")
|
|
||||||
@@ -0,0 +0,0 @@ dependencies {
|
@@ -0,0 +0,0 @@ dependencies {
|
||||||
testImplementation("org.mockito:mockito-core:4.9.0") // Paper - switch to mockito
|
testImplementation("org.mockito:mockito-core:4.9.0") // Paper - switch to mockito
|
||||||
implementation("org.spongepowered:configurate-yaml:4.1.2") // Paper - config files
|
implementation("org.spongepowered:configurate-yaml:4.1.2") // Paper - config files
|
||||||
|
|
|
@ -24,9 +24,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
*/
|
*/
|
||||||
- runtimeOnly("org.apache.logging.log4j:log4j-core:2.14.1")
|
- runtimeOnly("org.apache.logging.log4j:log4j-core:2.14.1")
|
||||||
+ implementation("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - implementation
|
+ implementation("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - implementation
|
||||||
|
annotationProcessor("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - Needed to generate meta for our Log4j plugins
|
||||||
// Paper end
|
// Paper end
|
||||||
implementation("org.apache.logging.log4j:log4j-iostreams:2.19.0") // Paper - remove exclusion
|
implementation("org.apache.logging.log4j:log4j-iostreams:2.19.0") // Paper - remove exclusion
|
||||||
implementation("org.ow2.asm:asm:9.4")
|
|
||||||
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
|
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/src/main/java/org/spigotmc/SpigotConfig.java
|
--- a/src/main/java/org/spigotmc/SpigotConfig.java
|
||||||
|
@ -48,22 +48,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg%n" />
|
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg%n" />
|
||||||
</Queue>
|
</Queue>
|
||||||
<TerminalConsole name="TerminalConsole">
|
<TerminalConsole name="TerminalConsole">
|
||||||
- <PatternLayout pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx}" />
|
- <PatternLayout pattern="%highlightError{[%d{HH:mm:ss} %level]: %msg%n%xEx}" />
|
||||||
+ <PatternLayout>
|
+ <PatternLayout>
|
||||||
+ <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %minecraftFormatting{%msg}%n%xEx}">
|
+ <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %msg%n%xEx}">
|
||||||
+ <!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
+ <!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
||||||
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
||||||
+ pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx}" />
|
+ pattern="%highlightError{[%d{HH:mm:ss} %level]: %msg%n%xEx}" />
|
||||||
+ </LoggerNamePatternSelector>
|
+ </LoggerNamePatternSelector>
|
||||||
+ </PatternLayout>
|
+ </PatternLayout>
|
||||||
</TerminalConsole>
|
</TerminalConsole>
|
||||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||||
- <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %minecraftFormatting{%msg}{strip}%n" />
|
- <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %stripAnsi{%msg}%n" />
|
||||||
+ <PatternLayout>
|
+ <PatternLayout>
|
||||||
+ <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %minecraftFormatting{%msg}{strip}%n">
|
+ <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %stripAnsi{%msg}%n">
|
||||||
+ <!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
+ <!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
||||||
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
||||||
+ pattern="[%d{HH:mm:ss}] [%t/%level]: %minecraftFormatting{%msg}{strip}%n" />
|
+ pattern="[%d{HH:mm:ss}] [%t/%level]: %stripAnsi{%msg}%n" />
|
||||||
+ </LoggerNamePatternSelector>
|
+ </LoggerNamePatternSelector>
|
||||||
+ </PatternLayout>
|
+ </PatternLayout>
|
||||||
<Policies>
|
<Policies>
|
||||||
|
|
|
@ -21,27 +21,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
</Queue>
|
</Queue>
|
||||||
<TerminalConsole name="TerminalConsole">
|
<TerminalConsole name="TerminalConsole">
|
||||||
<PatternLayout>
|
<PatternLayout>
|
||||||
- <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %minecraftFormatting{%msg}%n%xEx}">
|
- <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %msg%n%xEx}">
|
||||||
+ <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %minecraftFormatting{%msg}%n%xEx{full}}">
|
+ <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %msg%n%xEx{full}}">
|
||||||
<!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
<!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
||||||
- <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
- <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
||||||
- pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx}" />
|
- pattern="%highlightError{[%d{HH:mm:ss} %level]: %msg%n%xEx}" />
|
||||||
+ <!-- Disable prefix for various plugins that bypass the plugin logger -->
|
+ <!-- Disable prefix for various plugins that bypass the plugin logger -->
|
||||||
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
|
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
|
||||||
+ pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx{full}}" />
|
+ pattern="%highlightError{[%d{HH:mm:ss} %level]: %msg%n%xEx{full}}" />
|
||||||
</LoggerNamePatternSelector>
|
</LoggerNamePatternSelector>
|
||||||
</PatternLayout>
|
</PatternLayout>
|
||||||
</TerminalConsole>
|
</TerminalConsole>
|
||||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||||
<PatternLayout>
|
<PatternLayout>
|
||||||
- <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %minecraftFormatting{%msg}{strip}%n">
|
- <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %stripAnsi{%msg}%n">
|
||||||
+ <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %minecraftFormatting{%msg}{strip}%n%xEx{full}">
|
+ <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %stripAnsi{%msg}%n%xEx{full}">
|
||||||
<!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
<!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
||||||
- <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
- <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
||||||
- pattern="[%d{HH:mm:ss}] [%t/%level]: %minecraftFormatting{%msg}{strip}%n" />
|
- pattern="[%d{HH:mm:ss}] [%t/%level]: %stripAnsi{%msg}%n" />
|
||||||
+ <!-- Disable prefix for various plugins that bypass the plugin logger -->
|
+ <!-- Disable prefix for various plugins that bypass the plugin logger -->
|
||||||
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
|
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
|
||||||
+ pattern="[%d{HH:mm:ss}] [%t/%level]: %minecraftFormatting{%msg}{strip}%n%xEx{full}" />
|
+ pattern="[%d{HH:mm:ss}] [%t/%level]: %stripAnsi{%msg}%n%xEx{full}" />
|
||||||
</LoggerNamePatternSelector>
|
</LoggerNamePatternSelector>
|
||||||
</PatternLayout>
|
</PatternLayout>
|
||||||
<Policies>
|
<Policies>
|
||||||
|
|
|
@ -604,7 +604,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+ public class Logging extends ConfigurationPart {
|
+ public class Logging extends ConfigurationPart {
|
||||||
+ public boolean logPlayerIpAddresses = true;
|
+ public boolean logPlayerIpAddresses = true;
|
||||||
+ public boolean deobfuscateStacktraces = true;
|
+ public boolean deobfuscateStacktraces = true;
|
||||||
+ public boolean useRgbForNamedTextColors = true;
|
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ public Scoreboards scoreboards;
|
+ public Scoreboards scoreboards;
|
||||||
|
@ -1442,7 +1441,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+ path("commandErrorMessage"),
|
+ path("commandErrorMessage"),
|
||||||
+ path("baby-zombie-movement-speed"),
|
+ path("baby-zombie-movement-speed"),
|
||||||
+ path("limit-player-interactions"),
|
+ path("limit-player-interactions"),
|
||||||
+ path("warnWhenSettingExcessiveVelocity")
|
+ path("warnWhenSettingExcessiveVelocity"),
|
||||||
|
+ path("logging", "use-rgb-for-named-text-colors")
|
||||||
+ };
|
+ };
|
||||||
+
|
+
|
||||||
+}
|
+}
|
||||||
|
|
|
@ -6,6 +6,10 @@ Subject: [PATCH] Use TerminalConsoleAppender for console improvements
|
||||||
Rewrite console improvements (console colors, tab completion,
|
Rewrite console improvements (console colors, tab completion,
|
||||||
persistent input line, ...) using JLine 3.x and TerminalConsoleAppender.
|
persistent input line, ...) using JLine 3.x and TerminalConsoleAppender.
|
||||||
|
|
||||||
|
Also uses the new ANSIComponentSerializer to serialize components when
|
||||||
|
logging them via the ComponentLogger, or when sending messages to the
|
||||||
|
console, for hex color support.
|
||||||
|
|
||||||
New features:
|
New features:
|
||||||
- Support console colors for Vanilla commands
|
- Support console colors for Vanilla commands
|
||||||
- Add console colors for warnings and errors
|
- Add console colors for warnings and errors
|
||||||
|
@ -18,6 +22,8 @@ Other changes:
|
||||||
- Server starts 1-2 seconds faster thanks to optimizations in Log4j
|
- Server starts 1-2 seconds faster thanks to optimizations in Log4j
|
||||||
configuration
|
configuration
|
||||||
|
|
||||||
|
Co-Authored-By: Emilia Kond <emilia@rymiel.space>
|
||||||
|
|
||||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/build.gradle.kts
|
--- a/build.gradle.kts
|
||||||
|
@ -30,6 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+ // Paper start
|
+ // Paper start
|
||||||
+ implementation("org.jline:jline-terminal-jansi:3.21.0")
|
+ implementation("org.jline:jline-terminal-jansi:3.21.0")
|
||||||
+ implementation("net.minecrell:terminalconsoleappender:1.3.0")
|
+ implementation("net.minecrell:terminalconsoleappender:1.3.0")
|
||||||
|
+ implementation("net.kyori:adventure-text-serializer-ansi")
|
||||||
+ /*
|
+ /*
|
||||||
+ Required to add the missing Log4j2Plugins.dat file from log4j-core
|
+ Required to add the missing Log4j2Plugins.dat file from log4j-core
|
||||||
+ which has been removed by Mojang. Without it, log4j has to classload
|
+ which has been removed by Mojang. Without it, log4j has to classload
|
||||||
|
@ -37,6 +44,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+ Scanning takes about 1-2 seconds so adding this speeds up the server start.
|
+ Scanning takes about 1-2 seconds so adding this speeds up the server start.
|
||||||
+ */
|
+ */
|
||||||
+ runtimeOnly("org.apache.logging.log4j:log4j-core:2.14.1")
|
+ runtimeOnly("org.apache.logging.log4j:log4j-core:2.14.1")
|
||||||
|
+ annotationProcessor("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - Needed to generate meta for our Log4j plugins
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
implementation("org.apache.logging.log4j:log4j-iostreams:2.19.0") // Paper - remove exclusion
|
implementation("org.apache.logging.log4j:log4j-iostreams:2.19.0") // Paper - remove exclusion
|
||||||
implementation("org.ow2.asm:asm:9.4")
|
implementation("org.ow2.asm:asm:9.4")
|
||||||
|
@ -96,21 +104,133 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
@@ -0,0 +0,0 @@
|
@@ -0,0 +0,0 @@
|
||||||
+package com.destroystokyo.paper.console;
|
+package com.destroystokyo.paper.console;
|
||||||
+
|
+
|
||||||
|
+import net.kyori.adventure.audience.MessageType;
|
||||||
|
+import net.kyori.adventure.identity.Identity;
|
||||||
|
+import net.kyori.adventure.text.Component;
|
||||||
|
+import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||||
|
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
+import org.apache.logging.log4j.LogManager;
|
+import org.apache.logging.log4j.LogManager;
|
||||||
+import org.apache.logging.log4j.Logger;
|
|
||||||
+import org.bukkit.craftbukkit.command.CraftConsoleCommandSender;
|
+import org.bukkit.craftbukkit.command.CraftConsoleCommandSender;
|
||||||
+
|
+
|
||||||
+public class TerminalConsoleCommandSender extends CraftConsoleCommandSender {
|
+public class TerminalConsoleCommandSender extends CraftConsoleCommandSender {
|
||||||
+
|
+
|
||||||
+ private static final Logger LOGGER = LogManager.getRootLogger();
|
+ private static final ComponentLogger LOGGER = ComponentLogger.logger(LogManager.getRootLogger().getName());
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public void sendRawMessage(String message) {
|
+ public void sendRawMessage(String message) {
|
||||||
+ // TerminalConsoleAppender supports color codes directly in log messages
|
+ final Component msg = LegacyComponentSerializer.legacySection().deserialize(message);
|
||||||
|
+ this.sendMessage(Identity.nil(), msg, MessageType.SYSTEM);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void sendMessage(Identity identity, Component message, MessageType type) {
|
||||||
+ LOGGER.info(message);
|
+ LOGGER.info(message);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+}
|
+}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java
|
||||||
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
|
--- a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java
|
||||||
|
+++ b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java
|
||||||
|
@@ -0,0 +0,0 @@ import net.kyori.adventure.text.TranslatableComponent;
|
||||||
|
import net.kyori.adventure.text.flattener.ComponentFlattener;
|
||||||
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
|
import net.kyori.adventure.text.serializer.ComponentSerializer;
|
||||||
|
+import net.kyori.adventure.text.serializer.ansi.ANSIComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
|
@@ -0,0 +0,0 @@ public final class PaperAdventure {
|
||||||
|
public static final AttributeKey<Locale> LOCALE_ATTRIBUTE = AttributeKey.valueOf("adventure:locale"); // init after FLATTENER because classloading triggered here might create a logger
|
||||||
|
@Deprecated
|
||||||
|
public static final PlainComponentSerializer PLAIN = PlainComponentSerializer.builder().flattener(FLATTENER).build();
|
||||||
|
+
|
||||||
|
+ public static final ANSIComponentSerializer ANSI_SERIALIZER = ANSIComponentSerializer.builder().flattener(FLATTENER).build();
|
||||||
|
+
|
||||||
|
private static final Codec<CompoundTag, String, IOException, IOException> NBT_CODEC = new Codec<CompoundTag, String, IOException, IOException>() {
|
||||||
|
@Override
|
||||||
|
public @NotNull CompoundTag decode(final @NotNull String encoded) throws IOException {
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/adventure/providers/ComponentLoggerProviderImpl.java b/src/main/java/io/papermc/paper/adventure/providers/ComponentLoggerProviderImpl.java
|
||||||
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
|
--- a/src/main/java/io/papermc/paper/adventure/providers/ComponentLoggerProviderImpl.java
|
||||||
|
+++ b/src/main/java/io/papermc/paper/adventure/providers/ComponentLoggerProviderImpl.java
|
||||||
|
@@ -0,0 +0,0 @@
|
||||||
|
package io.papermc.paper.adventure.providers;
|
||||||
|
|
||||||
|
import io.papermc.paper.adventure.PaperAdventure;
|
||||||
|
+import java.util.Locale;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||||
|
import net.kyori.adventure.text.logger.slf4j.ComponentLoggerProvider;
|
||||||
|
+import net.kyori.adventure.translation.GlobalTranslator;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@@ -0,0 +0,0 @@ public class ComponentLoggerProviderImpl implements ComponentLoggerProvider {
|
||||||
|
}
|
||||||
|
|
||||||
|
private String serialize(final Component message) {
|
||||||
|
- return PaperAdventure.asPlain(message, null);
|
||||||
|
+ return PaperAdventure.ANSI_SERIALIZER.serialize(GlobalTranslator.render(message, Locale.getDefault()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/console/StripANSIConverter.java b/src/main/java/io/papermc/paper/console/StripANSIConverter.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/console/StripANSIConverter.java
|
||||||
|
@@ -0,0 +0,0 @@
|
||||||
|
+package io.papermc.paper.console;
|
||||||
|
+
|
||||||
|
+import org.apache.logging.log4j.core.LogEvent;
|
||||||
|
+import org.apache.logging.log4j.core.config.Configuration;
|
||||||
|
+import org.apache.logging.log4j.core.config.plugins.Plugin;
|
||||||
|
+import org.apache.logging.log4j.core.layout.PatternLayout;
|
||||||
|
+import org.apache.logging.log4j.core.pattern.ConverterKeys;
|
||||||
|
+import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
|
||||||
|
+import org.apache.logging.log4j.core.pattern.PatternConverter;
|
||||||
|
+import org.apache.logging.log4j.core.pattern.PatternFormatter;
|
||||||
|
+import org.apache.logging.log4j.core.pattern.PatternParser;
|
||||||
|
+
|
||||||
|
+import java.util.List;
|
||||||
|
+import java.util.regex.Pattern;
|
||||||
|
+
|
||||||
|
+@Plugin(name = "stripAnsi", category = PatternConverter.CATEGORY)
|
||||||
|
+@ConverterKeys({"stripAnsi"})
|
||||||
|
+public final class StripANSIConverter extends LogEventPatternConverter {
|
||||||
|
+ final private Pattern ANSI_PATTERN = Pattern.compile("\\e\\[[\\d;]*[^\\d;]");
|
||||||
|
+
|
||||||
|
+ private final List<PatternFormatter> formatters;
|
||||||
|
+
|
||||||
|
+ private StripANSIConverter(List<PatternFormatter> formatters) {
|
||||||
|
+ super("stripAnsi", null);
|
||||||
|
+ this.formatters = formatters;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void format(LogEvent event, StringBuilder toAppendTo) {
|
||||||
|
+ int start = toAppendTo.length();
|
||||||
|
+ for (PatternFormatter formatter : formatters) {
|
||||||
|
+ formatter.format(event, toAppendTo);
|
||||||
|
+ }
|
||||||
|
+ String content = toAppendTo.substring(start);
|
||||||
|
+ content = ANSI_PATTERN.matcher(content).replaceAll("");
|
||||||
|
+
|
||||||
|
+ toAppendTo.setLength(start);
|
||||||
|
+ toAppendTo.append(content);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static StripANSIConverter newInstance(Configuration config, String[] options) {
|
||||||
|
+ if (options.length != 1) {
|
||||||
|
+ LOGGER.error("Incorrect number of options on stripAnsi. Expected exactly 1, received " + options.length);
|
||||||
|
+ return null;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ PatternParser parser = PatternLayout.createPatternParser(config);
|
||||||
|
+ List<PatternFormatter> formatters = parser.parse(options[0]);
|
||||||
|
+ return new StripANSIConverter(formatters);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||||
|
@ -166,7 +286,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
@Override
|
@Override
|
||||||
public void sendSystemMessage(Component message) {
|
public void sendSystemMessage(Component message) {
|
||||||
- MinecraftServer.LOGGER.info(message.getString());
|
- MinecraftServer.LOGGER.info(message.getString());
|
||||||
+ MinecraftServer.LOGGER.info(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(io.papermc.paper.adventure.PaperAdventure.asAdventure(message))); // Paper - Log message with colors
|
+ MinecraftServer.LOGGER.info(io.papermc.paper.adventure.PaperAdventure.ANSI_SERIALIZER.serialize(io.papermc.paper.adventure.PaperAdventure.asAdventure(message))); // Paper - Log message with colors
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyPair getKeyPair() {
|
public KeyPair getKeyPair() {
|
||||||
|
@ -221,6 +341,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
|
|
||||||
System.setOut(IoBuilder.forLogger(logger).setLevel(Level.INFO).buildPrintStream());
|
System.setOut(IoBuilder.forLogger(logger).setLevel(Level.INFO).buildPrintStream());
|
||||||
System.setErr(IoBuilder.forLogger(logger).setLevel(Level.WARN).buildPrintStream());
|
System.setErr(IoBuilder.forLogger(logger).setLevel(Level.WARN).buildPrintStream());
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
|
||||||
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
|
||||||
|
@@ -0,0 +0,0 @@ public class MinecraftServerGui extends JComponent {
|
||||||
|
this.finalizers.forEach(Runnable::run);
|
||||||
|
}
|
||||||
|
|
||||||
|
- private static final java.util.regex.Pattern ANSI = java.util.regex.Pattern.compile("\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})*)?[m|K]"); // CraftBukkit
|
||||||
|
+ private static final java.util.regex.Pattern ANSI = java.util.regex.Pattern.compile("\\e\\[[\\d;]*[^\\d;]"); // CraftBukkit // Paper
|
||||||
|
public void print(JTextArea textArea, JScrollPane scrollPane, String message) {
|
||||||
|
if (!SwingUtilities.isEventDispatchThread()) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
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/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||||
|
@ -495,11 +628,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
- <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
- <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
||||||
- </Queue>
|
- </Queue>
|
||||||
+ <TerminalConsole name="TerminalConsole">
|
+ <TerminalConsole name="TerminalConsole">
|
||||||
+ <PatternLayout pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx}" />
|
+ <PatternLayout pattern="%highlightError{[%d{HH:mm:ss} %level]: %msg%n%xEx}" />
|
||||||
+ </TerminalConsole>
|
+ </TerminalConsole>
|
||||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||||
- <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
- <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
||||||
+ <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %minecraftFormatting{%msg}{strip}%n" />
|
+ <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %stripAnsi{%msg}%n" />
|
||||||
<Policies>
|
<Policies>
|
||||||
<TimeBasedTriggeringPolicy />
|
<TimeBasedTriggeringPolicy />
|
||||||
<OnStartupTriggeringPolicy />
|
<OnStartupTriggeringPolicy />
|
||||||
|
|
Loading…
Reference in a new issue