diff --git a/src/main/java/com/loki/lochat/gradient/util/GradientUtil.java b/src/main/java/com/loki/lochat/gradient/util/GradientUtil.java index 2453478..3450088 100644 --- a/src/main/java/com/loki/lochat/gradient/util/GradientUtil.java +++ b/src/main/java/com/loki/lochat/gradient/util/GradientUtil.java @@ -88,7 +88,12 @@ public final class GradientUtil { private static String formatHex(String hex, boolean useLegacyFormat) { hex = hex.replace("#", "").toLowerCase(); if (useLegacyFormat) { - return "&#" + hex; + // Формат §x§R§R§G§G§B§B для TAB и других плагинов + StringBuilder sb = new StringBuilder("§x"); + for (char c : hex.toCharArray()) { + sb.append("§").append(c); + } + return sb.toString(); } else { return "<#" + hex + ">"; } diff --git a/src/main/java/com/loki/lochat/utils/ChatFormatter.java b/src/main/java/com/loki/lochat/utils/ChatFormatter.java index e6bdf9a..ecb3e17 100644 --- a/src/main/java/com/loki/lochat/utils/ChatFormatter.java +++ b/src/main/java/com/loki/lochat/utils/ChatFormatter.java @@ -18,31 +18,52 @@ public class ChatFormatter { private static final Pattern HEX_PATTERN = Pattern.compile("&#([A-Fa-f0-9]{6})"); private static final Pattern LEGACY_COLOR_PATTERN = Pattern.compile("&([0-9a-fk-orA-FK-OR])"); private static final Pattern SECTION_COLOR_PATTERN = Pattern.compile("§([0-9a-fk-orA-FK-OR])"); + private static final Pattern SECTION_HEX_PATTERN = Pattern.compile("§x(§[0-9A-Fa-f]){6}"); private static final Pattern MINIMESSAGE_HEX_PATTERN = Pattern.compile("<#([A-Fa-f0-9]{6})>"); private ChatFormatter() {} /** * Конвертирует все форматы цветов в MiniMessage - * Поддерживает: &коды, §коды, &#HEX, MiniMessage теги + * Поддерживает: &коды, §коды, &#HEX, §x§...HEX, MiniMessage теги */ public static String convertAllColors(String message) { if (message == null) return ""; String result = message; - // 1. Конвертируем §коды -> &коды (для унификации) + // 1. Конвертируем §x§R§R§G§G§B§B -> <#RRGGBB> + result = convertSectionHexColors(result); + + // 2. Конвертируем §коды -> &коды (для унификации) result = convertSectionToAmpersand(result); - // 2. Конвертируем &#RRGGBB -> <#RRGGBB> (только если еще не в MiniMessage формате) + // 3. Конвертируем &#RRGGBB -> <#RRGGBB> (только если еще не в MiniMessage формате) result = convertHexColors(result); - // 3. Конвертируем &коды -> MiniMessage теги + // 4. Конвертируем &коды -> MiniMessage теги result = convertLegacyColors(result); return result; } + /** + * Конвертирует §x§R§R§G§G§B§B в <#RRGGBB> + */ + public static String convertSectionHexColors(String message) { + if (message == null) return ""; + Matcher matcher = SECTION_HEX_PATTERN.matcher(message); + StringBuilder result = new StringBuilder(); + while (matcher.find()) { + String match = matcher.group(); + // §x§R§R§G§G§B§B -> RRGGBB + String hex = match.replace("§x", "").replace("§", ""); + matcher.appendReplacement(result, "<#" + hex + ">"); + } + matcher.appendTail(result); + return result.toString(); + } + /** * Конвертирует §коды в &коды */ @@ -251,7 +272,9 @@ public class ChatFormatter { private static String getPlayerDisplay(Player player) { LoChat plugin = LoChat.getInstance(); if (plugin != null && plugin.getGradientModule() != null && plugin.getGradientModule().isEnabled()) { - return plugin.getGradientModule().getFormattedName(player); + String name = plugin.getGradientModule().getFormattedName(player); + // Конвертируем §x§... формат в MiniMessage + return convertAllColors(name); } return player.getName(); } diff --git a/src/test/java/com/loki/lochat/gradient/util/GradientUtilTest.java b/src/test/java/com/loki/lochat/gradient/util/GradientUtilTest.java index 18be21c..e81b136 100644 --- a/src/test/java/com/loki/lochat/gradient/util/GradientUtilTest.java +++ b/src/test/java/com/loki/lochat/gradient/util/GradientUtilTest.java @@ -35,8 +35,8 @@ class GradientUtilTest { void applyGradient_singleColor_legacy() { String result = GradientUtil.applyGradient("Hi", List.of("#FF0000"), true); assertNotNull(result); - assertTrue(result.contains("&#ff0000")); - assertEquals("&#ff0000H&#ff0000i", result); + // Формат §x§f§f§0§0§0§0 + assertTrue(result.contains("§x§f§f§0§0§0§0")); } @Test @@ -51,8 +51,8 @@ class GradientUtilTest { String result = GradientUtil.applyGradient("AB", List.of("#FF0000", "#0000FF"), true); assertNotNull(result); // Первый символ должен быть красным, последний синим - assertTrue(result.startsWith("&#ff0000A")); - assertTrue(result.contains("�ffB")); + assertTrue(result.contains("§x§f§f§0§0§0§0")); // красный + assertTrue(result.contains("§x§0§0§0§0§f§f")); // синий } @Test @@ -105,7 +105,7 @@ class GradientUtilTest { void buildDisplayName_noPrefix_withColors() { String result = GradientUtil.buildDisplayName(null, "AB", List.of("#FF0000", "#0000FF"), true, true, "[{prefix}] ", true); assertNotNull(result); - assertTrue(result.contains("&#")); + assertTrue(result.contains("§x")); } @Test @@ -113,7 +113,7 @@ class GradientUtilTest { String result = GradientUtil.buildDisplayName("V", "AB", List.of("#FF0000", "#0000FF"), true, true, "[{prefix}] ", true); assertNotNull(result); // Единый градиент на всё - assertTrue(result.contains("&#")); + assertTrue(result.contains("§x")); } @Test @@ -121,7 +121,7 @@ class GradientUtilTest { String result = GradientUtil.buildDisplayName("V", "AB", List.of("#FF0000", "#0000FF"), true, false, "[{prefix}] ", true); assertNotNull(result); // Отдельные градиенты - assertTrue(result.contains("&#")); + assertTrue(result.contains("§x")); } @Test