From 7193100047eaf722745dbc5d0b7231b48531b12f Mon Sep 17 00:00:00 2001 From: Vankka Date: Thu, 7 Sep 2023 21:27:21 +0300 Subject: [PATCH] Fix a bug in appending, add ansi and color 'handling' --- .../common/config/main/ConsoleConfig.java | 1 + .../common/console/ConsoleModule.java | 1 - .../common/console/SingleConsoleHandler.java | 54 ++++++++++++++++++- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/com/discordsrv/common/config/main/ConsoleConfig.java b/common/src/main/java/com/discordsrv/common/config/main/ConsoleConfig.java index adebaf6d..fcc6e587 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/ConsoleConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/ConsoleConfig.java @@ -64,6 +64,7 @@ public class ConsoleConfig { ANSI("```ansi\n", "```"), LOG("```accesslog\n", "```"), DIFF("```diff\n", "```"), + MARKDOWN("", ""), PLAIN("```\n", "```"), PLAIN_CONTENT("", ""); diff --git a/common/src/main/java/com/discordsrv/common/console/ConsoleModule.java b/common/src/main/java/com/discordsrv/common/console/ConsoleModule.java index bcde03a7..fbaf9afd 100644 --- a/common/src/main/java/com/discordsrv/common/console/ConsoleModule.java +++ b/common/src/main/java/com/discordsrv/common/console/ConsoleModule.java @@ -31,7 +31,6 @@ public class ConsoleModule extends AbstractModule implements LogAppe backend.addAppender(this); } - @Override public void reload(Consumer resultConsumer) { for (SingleConsoleHandler handler : handlers) { diff --git a/common/src/main/java/com/discordsrv/common/console/SingleConsoleHandler.java b/common/src/main/java/com/discordsrv/common/console/SingleConsoleHandler.java index f8f0d4d7..73d093aa 100644 --- a/common/src/main/java/com/discordsrv/common/console/SingleConsoleHandler.java +++ b/common/src/main/java/com/discordsrv/common/console/SingleConsoleHandler.java @@ -11,15 +11,33 @@ import net.dv8tion.jda.api.entities.Message; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class SingleConsoleHandler { private static final int MESSAGE_MAX_LENGTH = Message.MAX_CONTENT_LENGTH; + private static final String ESCAPE = "\u001B"; + private static final Pattern ANSI_PATTERN = Pattern.compile( + ESCAPE + + "\\[" + + "(\\d{1,3}" + + "(;\\d{1,3}" + + "(;\\d{1,3}" + + "(?:(?:;\\d{1,3}){2})?" + + ")?" + + ")?" + + ")" + + "m" + ); + private static final Pattern COLOR_CODE_PATTERN = Pattern.compile("\\u007F[0-9a-fk-orx]"); private final DiscordSRV discordSRV; private final ConsoleConfig config; @@ -93,6 +111,10 @@ public class SingleConsoleHandler { } private void clearBuffer(Queue currentBuffer, ConsoleConfig.OutputMode outputMode) { + if (currentBuffer.isEmpty()) { + return; + } + int blockLength = outputMode.blockLength(); StringBuilder builder = new StringBuilder(); @@ -165,12 +187,42 @@ public class SingleConsoleHandler { } } + private String getAnsiEscapeSequence(String codePart) { + String[] split = codePart.split(";"); + int[] numbers = new int[split.length]; + for (int i = 0; i < split.length; i++) { + numbers[i] = Integer.parseInt(split[i]); + } + if (numbers.length == 1) { + return String.valueOf(numbers[0]); + } else if (numbers.length == 2) { + return numbers[0] + ";" + numbers[1]; + } else { + // longer than supported by Discord, so drop the ansi here + return null; + } + } + private List formatEntry(LogEntry entry, ConsoleConfig.OutputMode outputMode) { int blockLength = outputMode.blockLength(); int maximumPart = MESSAGE_MAX_LENGTH - blockLength - "\n".length(); String message = discordSRV.placeholderService().replacePlaceholders(config.appender.lineFormat, entry) + "\n"; + // TODO: make a parser for ANSI + color codes that makes a intermediary format that can be converted to + // TODO: either 16 color ansi (ANSI mode) or just bold/italics/underline/strikethrough markdown (MARKDOWN mode) + Matcher matcher = ANSI_PATTERN.matcher(message); + while (matcher.find()) { + String codes = matcher.group(1); + String escapeSequence = getAnsiEscapeSequence(codes); + if (escapeSequence != null && outputMode == ConsoleConfig.OutputMode.ANSI) { + message = matcher.replaceAll(ESCAPE + escapeSequence + "m"); + } else { + message = matcher.replaceAll(""); + } + } + message = message.replaceAll(COLOR_CODE_PATTERN.pattern(), ""); + if (outputMode == ConsoleConfig.OutputMode.DIFF) { message = getLogLevelDiffCharacter(entry.level()) + message; // TODO: also format throwable?