Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 881e06e5 PR-725: Add Item Unlimited Lifetime APIs CraftBukkit Changes: 74c08312 SPIGOT-6962: Call EntityChangeBlockEvent when when FallingBlockEntity starts to fall 64db5126 SPIGOT-6959: Make /loot command ignore empty items for spawn 2d760831 Increase outdated build delay 9ed7e4fb SPIGOT-6138, SPIGOT-6415: Don't call CreatureSpawnEvent after cross-dimensional travel fc4ad813 SPIGOT-6895: Trees grown with applyBoneMeal() don't fire the StructureGrowthEvent 59733a2e SPIGOT-6961: Actually return a copy of the ItemMeta Spigot Changes: ffceeae3 SPIGOT-6956: Drop unload queue patch as attempt at fixing stop issue e19ddabd PR-1011: Add Item Unlimited Lifetime APIs 34d40b0e SPIGOT-2942: give command fires PlayerDropItemEvent, cancelling it causes Item Duplication
315 lines
16 KiB
Diff
315 lines
16 KiB
Diff
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/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
|
index a0a3cec47c8f9e379a5bc1d43eeda5eb9d81f814..23d849872109e43d6e22a953d3a4298565d4621d 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
|
@@ -454,8 +454,10 @@ public class PaperConfig {
|
|
}
|
|
|
|
public static boolean deobfuscateStacktraces = true;
|
|
+ public static boolean useRgbForNamedTextColors = true;
|
|
private static void loggerSettings() {
|
|
deobfuscateStacktraces = getBoolean("settings.loggers.deobfuscate-stacktraces", deobfuscateStacktraces);
|
|
+ useRgbForNamedTextColors = getBoolean("settings.loggers.use-rgb-for-named-text-colors", useRgbForNamedTextColors);
|
|
}
|
|
|
|
public static boolean allowBlockPermanentBreakingExploits = false;
|
|
diff --git a/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java b/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java
|
|
index 685deaa0e5d1ddc13e3a7c0471b1cfcf1710c869..84243e10c115104cadfe84c4f152f53c1b5f7c6f 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java
|
|
@@ -1,5 +1,10 @@
|
|
package com.destroystokyo.paper.console;
|
|
|
|
+import io.papermc.paper.adventure.PaperAdventure;
|
|
+import io.papermc.paper.console.HexFormattingConverter;
|
|
+import net.kyori.adventure.audience.MessageType;
|
|
+import net.kyori.adventure.identity.Identity;
|
|
+import net.kyori.adventure.text.Component;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
import org.bukkit.craftbukkit.command.CraftConsoleCommandSender;
|
|
@@ -10,8 +15,13 @@ public class TerminalConsoleCommandSender extends CraftConsoleCommandSender {
|
|
|
|
@Override
|
|
public void sendRawMessage(String message) {
|
|
- // TerminalConsoleAppender supports color codes directly in log messages
|
|
- LOGGER.info(message);
|
|
+ final Component msg = PaperAdventure.LEGACY_SECTION_UXRC.deserialize(message);
|
|
+ this.sendMessage(Identity.nil(), msg, MessageType.SYSTEM);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void sendMessage(Identity identity, Component message, MessageType type) {
|
|
+ LOGGER.info(HexFormattingConverter.SERIALIZER.serialize(message));
|
|
}
|
|
|
|
}
|
|
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..ea83ee8762c126c449993a7497257b0bd8663452
|
|
--- /dev/null
|
|
+++ b/src/main/java/io/papermc/paper/console/HexFormattingConverter.java
|
|
@@ -0,0 +1,212 @@
|
|
+package io.papermc.paper.console;
|
|
+
|
|
+import com.destroystokyo.paper.PaperConfig;
|
|
+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 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[21m", // 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[]{
|
|
+ "\u001B[0;30m", // Black §0
|
|
+ "\u001B[0;34m", // Dark Blue §1
|
|
+ "\u001B[0;32m", // Dark Green §2
|
|
+ "\u001B[0;36m", // Dark Aqua §3
|
|
+ "\u001B[0;31m", // Dark Red §4
|
|
+ "\u001B[0;35m", // Dark Purple §5
|
|
+ "\u001B[0;33m", // Gold §6
|
|
+ "\u001B[0;37m", // Gray §7
|
|
+ "\u001B[0;30;1m", // Dark Gray §8
|
|
+ "\u001B[0;34;1m", // Blue §9
|
|
+ "\u001B[0;32;1m", // Green §a
|
|
+ "\u001B[0;36;1m", // Aqua §b
|
|
+ "\u001B[0;31;1m", // Red §c
|
|
+ "\u001B[0;35;1m", // Light Purple §d
|
|
+ "\u001B[0;33;1m", // Yellow §e
|
|
+ "\u001B[0;37;1m", // White §f
|
|
+ "\u001B[5m", // Obfuscated §k
|
|
+ "\u001B[21m", // 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(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 = PaperConfig.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 445efad6a35b819dcb845524a28055a90da6e7f6..2914355be3f6c45b2dbd7ceb0ea65c7f22255a6d 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -1712,7 +1712,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
|
|
@Override
|
|
public void sendMessage(Component message, UUID sender) {
|
|
- MinecraftServer.LOGGER.info(io.papermc.paper.adventure.PaperAdventure.LEGACY_SECTION_UXRC.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 1a05d23ff886b015fb9396f119822c678a47ec6f..2e421eaac80cf251b32e0bb504dd54a73edf4986 100644
|
|
--- a/src/main/resources/log4j2.xml
|
|
+++ b/src/main/resources/log4j2.xml
|
|
@@ -6,21 +6,21 @@
|
|
</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>
|