From d68d5105ce6e1c653657e50661c4e98ff13f3d25 Mon Sep 17 00:00:00 2001 From: Bukkit/Spigot Date: Fri, 17 Mar 2023 07:38:07 +1100 Subject: [PATCH] SPIGOT-5916: getLastColors does not work with the rgb colors By: DerFrZocker --- .../src/main/java/org/bukkit/ChatColor.java | 51 +++++++++++++++++++ .../test/java/org/bukkit/ChatColorTest.java | 10 ---- .../java/org/bukkit/LastChatColorTest.java | 40 +++++++++++++++ 3 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 paper-api/src/test/java/org/bukkit/LastChatColorTest.java diff --git a/paper-api/src/main/java/org/bukkit/ChatColor.java b/paper-api/src/main/java/org/bukkit/ChatColor.java index 623bba2e9d..6149c77df6 100644 --- a/paper-api/src/main/java/org/bukkit/ChatColor.java +++ b/paper-api/src/main/java/org/bukkit/ChatColor.java @@ -243,6 +243,15 @@ public enum ChatColor { for (int index = length - 1; index > -1; index--) { char section = input.charAt(index); if (section == COLOR_CHAR && index < length - 1) { + + String hexColor = getHexColor(input, index); + if (hexColor != null) { + // We got a hex color + result = hexColor + result; + break; + } + + // It is not a hex color, check normal color char c = input.charAt(index + 1); ChatColor color = getByChar(c); @@ -260,6 +269,48 @@ public enum ChatColor { return result; } + @Nullable + private static String getHexColor(@NotNull String input, int index) { + // Check for hex color with the format '§x§1§2§3§4§5§6' + // Our index is currently on the last '§' which means to have a potential hex color + // The index - 11 must be an 'x' and index - 12 must be a '§' + // But first check if the string is long enough + if (index < 12) { + return null; + } + + if (input.charAt(index - 11) != 'x' || input.charAt(index - 12) != COLOR_CHAR) { + return null; + } + + // We got a potential hex color + // Now check if every the chars switches between '§' and a hex number + // First check '§' + for (int i = index - 10; i <= index; i += 2) { + if (input.charAt(i) != COLOR_CHAR) { + return null; + } + } + + for (int i = index - 9; i <= (index + 1); i += 2) { + char toCheck = input.charAt(i); + if (toCheck < '0' || toCheck > 'f') { + return null; + } + + if (toCheck > '9' && toCheck < 'A') { + return null; + } + + if (toCheck > 'F' && toCheck < 'a') { + return null; + } + } + + // We got a hex color return it + return input.substring(index - 12, index + 2); + } + static { for (ChatColor color : values()) { BY_ID.put(color.intCode, color); diff --git a/paper-api/src/test/java/org/bukkit/ChatColorTest.java b/paper-api/src/test/java/org/bukkit/ChatColorTest.java index 2a8c8c7298..fc4e808537 100644 --- a/paper-api/src/test/java/org/bukkit/ChatColorTest.java +++ b/paper-api/src/test/java/org/bukkit/ChatColorTest.java @@ -68,14 +68,4 @@ public class ChatColorTest { String u = ChatColor.BLACK.toString() + ChatColor.DARK_BLUE + ChatColor.DARK_GREEN + ChatColor.DARK_AQUA + ChatColor.DARK_RED + ChatColor.DARK_PURPLE + ChatColor.GOLD + ChatColor.GRAY + ChatColor.DARK_GRAY + ChatColor.BLUE + ChatColor.GREEN + ChatColor.GREEN + ChatColor.AQUA + ChatColor.AQUA + ChatColor.RED + ChatColor.RED + ChatColor.LIGHT_PURPLE + ChatColor.LIGHT_PURPLE + ChatColor.YELLOW + ChatColor.YELLOW + ChatColor.WHITE + ChatColor.WHITE + ChatColor.MAGIC + ChatColor.MAGIC + " & more"; assertThat(t, is(u)); } - - @Test - public void getChatColors() { - String s = String.format("%c%ctest%c%ctest%c", ChatColor.COLOR_CHAR, ChatColor.RED.getChar(), ChatColor.COLOR_CHAR, ChatColor.ITALIC.getChar(), ChatColor.COLOR_CHAR); - String expected = ChatColor.RED.toString() + ChatColor.ITALIC; - assertThat(ChatColor.getLastColors(s), is(expected)); - - s = String.format("%c%ctest%c%ctest", ChatColor.COLOR_CHAR, ChatColor.RED.getChar(), ChatColor.COLOR_CHAR, ChatColor.BLUE.getChar()); - assertThat(ChatColor.getLastColors(s), is(ChatColor.BLUE.toString())); - } } diff --git a/paper-api/src/test/java/org/bukkit/LastChatColorTest.java b/paper-api/src/test/java/org/bukkit/LastChatColorTest.java new file mode 100644 index 0000000000..0a4fe1cced --- /dev/null +++ b/paper-api/src/test/java/org/bukkit/LastChatColorTest.java @@ -0,0 +1,40 @@ +package org.bukkit; + +import static org.junit.Assert.assertEquals; +import java.util.Arrays; +import java.util.Collection; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class LastChatColorTest { + + @Parameterized.Parameters + public static Collection data() { + return Arrays.asList(new Object[][]{ + {String.format("%c%ctest%c%ctest%c", ChatColor.COLOR_CHAR, ChatColor.RED.getChar(), ChatColor.COLOR_CHAR, ChatColor.ITALIC.getChar(), ChatColor.COLOR_CHAR), ChatColor.RED.toString() + ChatColor.ITALIC}, + {String.format("%c%ctest%c%ctest", ChatColor.COLOR_CHAR, ChatColor.RED.getChar(), ChatColor.COLOR_CHAR, ChatColor.BLUE.getChar()), ChatColor.BLUE.toString()}, + {"§x§1§2§3§4§5§6", "§x§1§2§3§4§5§6"}, + {"§y§1§2§3§4§5§6", "§6"}, + {"§3§4§5§6", "§6"}, + {"Test2§x§1§f§3§4§F§6test§l", "§x§1§f§3§4§F§6§l"}, + {"Test2§x§P§f§3§4§F§6test§l", "§6§l"}, + {"Test2§x§fxf§3§4§F§6test§l", "§6§l"}, + {"Test2§x§1§4§F§6test§l", "§6§l"} + }); + } + + private final String input; + private final String expected; + + public LastChatColorTest(String input, String expected) { + this.input = input; + this.expected = expected; + } + + @Test + public void testGetLastColors() { + assertEquals(expected, ChatColor.getLastColors(input)); + } +}