From cdd8e09ac0223f8fb2f1e6c02b842ee1ccb5967b Mon Sep 17 00:00:00 2001 From: CraftBukkit/Spigot Date: Sun, 3 Jan 2021 17:24:43 +1100 Subject: [PATCH] SPIGOT-6304: Removed the detection of legacy text based on color codes Apparently there are items and plugins out there that still use legacy color codes within text components, and which thereby break this heuristic. Our remaining approach to differentiate between legacy (plain) and modern (JSON-based) text is to check if a particular text can be parsed as JSON-based text. This approach is not perfect either as there are ambiguous cases that it cannot resolve correctly. However, these cases are hopefully rare enough in practice that this approach remains suitable. By: blablubbabc --- .../craftbukkit/util/CraftChatMessage.java | 54 +++++++------------ 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java index 712ea5ecd0..1582a799e4 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java @@ -24,7 +24,6 @@ public final class CraftChatMessage { private static final Pattern LINK_PATTERN = Pattern.compile("((?:(?:https?):\\/\\/)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + " \\n]|$))))"); private static final Map formatMap; - private static final String COLOR_CHAR_STRING = String.valueOf(ChatColor.COLOR_CHAR); static { Builder builder = ImmutableMap.builder(); @@ -216,15 +215,11 @@ public final class CraftChatMessage { private static IChatBaseComponent fromJSONOrString(String message, boolean nullable, boolean keepNewlines) { if (message == null) message = ""; if (nullable && message.isEmpty()) return null; - if (isLegacy(message)) { - return fromString(message, keepNewlines)[0]; + IChatBaseComponent component = fromJSONOrNull(message); + if (component != null) { + return component; } else { - IChatBaseComponent component = fromJSONOrNull(message); - if (component != null) { - return component; - } else { - return fromString(message, keepNewlines)[0]; - } + return fromString(message, keepNewlines)[0]; } } @@ -247,27 +242,22 @@ public final class CraftChatMessage { public static String fromJSONOrStringToJSON(String message, boolean nullable, boolean keepNewlines, int maxLength, boolean checkJsonContentLength) { if (message == null) message = ""; if (nullable && message.isEmpty()) return null; - if (isLegacy(message)) { + // If the input can be parsed as JSON, we use that: + IChatBaseComponent component = fromJSONOrNull(message); + if (component != null) { + if (checkJsonContentLength) { + String content = fromComponent(component); + String trimmedContent = trimMessage(content, maxLength); + if (content != trimmedContent) { // identity comparison is fine here + // Note: The resulting text has all non-plain text features stripped. + return fromStringToJSON(trimmedContent, keepNewlines); + } + } + return message; + } else { + // Else we interpret the input as legacy text: message = trimMessage(message, maxLength); return fromStringToJSON(message, keepNewlines); - } else { - // If the input can be parsed as JSON, we use that: - IChatBaseComponent component = fromJSONOrNull(message); - if (component != null) { - if (checkJsonContentLength) { - String content = fromComponent(component); - String trimmedContent = trimMessage(content, maxLength); - if (content != trimmedContent) { // identity comparison is fine here - // Note: The resulting text has all non-plain text features stripped. - return fromStringToJSON(trimmedContent, keepNewlines); - } - } - return message; - } else { - // Else we interpret the input as legacy text: - message = trimMessage(message, maxLength); - return fromStringToJSON(message, keepNewlines); - } } } @@ -279,14 +269,6 @@ public final class CraftChatMessage { } } - // Heuristic detection of legacy (plain) text. - // May produce false-negatives: I.e. a return value of false does not imply that the text represents modern (JSON-based) text. - // We also consider empty Strings as legacy. The component deserializer cannot parse them (produces null). - private static boolean isLegacy(String message) { - // assert: message != null - return message.trim().isEmpty() || message.contains(COLOR_CHAR_STRING); - } - public static String fromStringToJSON(String message) { return fromStringToJSON(message, false); }