fix: TAB hex format and chat color codes support
This commit is contained in:
parent
ed796a4264
commit
5c1230bc16
3 changed files with 41 additions and 13 deletions
|
|
@ -88,7 +88,12 @@ public final class GradientUtil {
|
||||||
private static String formatHex(String hex, boolean useLegacyFormat) {
|
private static String formatHex(String hex, boolean useLegacyFormat) {
|
||||||
hex = hex.replace("#", "").toLowerCase();
|
hex = hex.replace("#", "").toLowerCase();
|
||||||
if (useLegacyFormat) {
|
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 {
|
} else {
|
||||||
return "<#" + hex + ">";
|
return "<#" + hex + ">";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,31 +18,52 @@ public class ChatFormatter {
|
||||||
private static final Pattern HEX_PATTERN = Pattern.compile("&#([A-Fa-f0-9]{6})");
|
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 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_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 static final Pattern MINIMESSAGE_HEX_PATTERN = Pattern.compile("<#([A-Fa-f0-9]{6})>");
|
||||||
|
|
||||||
private ChatFormatter() {}
|
private ChatFormatter() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Конвертирует все форматы цветов в MiniMessage
|
* Конвертирует все форматы цветов в MiniMessage
|
||||||
* Поддерживает: &коды, §коды, &#HEX, MiniMessage теги
|
* Поддерживает: &коды, §коды, &#HEX, §x§...HEX, MiniMessage теги
|
||||||
*/
|
*/
|
||||||
public static String convertAllColors(String message) {
|
public static String convertAllColors(String message) {
|
||||||
if (message == null) return "";
|
if (message == null) return "";
|
||||||
|
|
||||||
String result = message;
|
String result = message;
|
||||||
|
|
||||||
// 1. Конвертируем §коды -> &коды (для унификации)
|
// 1. Конвертируем §x§R§R§G§G§B§B -> <#RRGGBB>
|
||||||
|
result = convertSectionHexColors(result);
|
||||||
|
|
||||||
|
// 2. Конвертируем §коды -> &коды (для унификации)
|
||||||
result = convertSectionToAmpersand(result);
|
result = convertSectionToAmpersand(result);
|
||||||
|
|
||||||
// 2. Конвертируем &#RRGGBB -> <#RRGGBB> (только если еще не в MiniMessage формате)
|
// 3. Конвертируем &#RRGGBB -> <#RRGGBB> (только если еще не в MiniMessage формате)
|
||||||
result = convertHexColors(result);
|
result = convertHexColors(result);
|
||||||
|
|
||||||
// 3. Конвертируем &коды -> MiniMessage теги
|
// 4. Конвертируем &коды -> MiniMessage теги
|
||||||
result = convertLegacyColors(result);
|
result = convertLegacyColors(result);
|
||||||
|
|
||||||
return 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) {
|
private static String getPlayerDisplay(Player player) {
|
||||||
LoChat plugin = LoChat.getInstance();
|
LoChat plugin = LoChat.getInstance();
|
||||||
if (plugin != null && plugin.getGradientModule() != null && plugin.getGradientModule().isEnabled()) {
|
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();
|
return player.getName();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ class GradientUtilTest {
|
||||||
void applyGradient_singleColor_legacy() {
|
void applyGradient_singleColor_legacy() {
|
||||||
String result = GradientUtil.applyGradient("Hi", List.of("#FF0000"), true);
|
String result = GradientUtil.applyGradient("Hi", List.of("#FF0000"), true);
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertTrue(result.contains("&#ff0000"));
|
// Формат §x§f§f§0§0§0§0
|
||||||
assertEquals("&#ff0000H&#ff0000i", result);
|
assertTrue(result.contains("§x§f§f§0§0§0§0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -51,8 +51,8 @@ class GradientUtilTest {
|
||||||
String result = GradientUtil.applyGradient("AB", List.of("#FF0000", "#0000FF"), true);
|
String result = GradientUtil.applyGradient("AB", List.of("#FF0000", "#0000FF"), true);
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
// Первый символ должен быть красным, последний синим
|
// Первый символ должен быть красным, последний синим
|
||||||
assertTrue(result.startsWith("&#ff0000A"));
|
assertTrue(result.contains("§x§f§f§0§0§0§0")); // красный
|
||||||
assertTrue(result.contains("�ffB"));
|
assertTrue(result.contains("§x§0§0§0§0§f§f")); // синий
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -105,7 +105,7 @@ class GradientUtilTest {
|
||||||
void buildDisplayName_noPrefix_withColors() {
|
void buildDisplayName_noPrefix_withColors() {
|
||||||
String result = GradientUtil.buildDisplayName(null, "AB", List.of("#FF0000", "#0000FF"), true, true, "[{prefix}] ", true);
|
String result = GradientUtil.buildDisplayName(null, "AB", List.of("#FF0000", "#0000FF"), true, true, "[{prefix}] ", true);
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertTrue(result.contains("&#"));
|
assertTrue(result.contains("§x"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -113,7 +113,7 @@ class GradientUtilTest {
|
||||||
String result = GradientUtil.buildDisplayName("V", "AB", List.of("#FF0000", "#0000FF"), true, true, "[{prefix}] ", true);
|
String result = GradientUtil.buildDisplayName("V", "AB", List.of("#FF0000", "#0000FF"), true, true, "[{prefix}] ", true);
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
// Единый градиент на всё
|
// Единый градиент на всё
|
||||||
assertTrue(result.contains("&#"));
|
assertTrue(result.contains("§x"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -121,7 +121,7 @@ class GradientUtilTest {
|
||||||
String result = GradientUtil.buildDisplayName("V", "AB", List.of("#FF0000", "#0000FF"), true, false, "[{prefix}] ", true);
|
String result = GradientUtil.buildDisplayName("V", "AB", List.of("#FF0000", "#0000FF"), true, false, "[{prefix}] ", true);
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
// Отдельные градиенты
|
// Отдельные градиенты
|
||||||
assertTrue(result.contains("&#"));
|
assertTrue(result.contains("§x"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue