diff --git a/src/main/java/com/loki/lochat/commands/ChatColorCommand.java b/src/main/java/com/loki/lochat/commands/ChatColorCommand.java index 4c43009..da9ca32 100644 --- a/src/main/java/com/loki/lochat/commands/ChatColorCommand.java +++ b/src/main/java/com/loki/lochat/commands/ChatColorCommand.java @@ -11,12 +11,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +import java.util.regex.Pattern; public class ChatColorCommand implements CommandExecutor, TabCompleter { private final LoChat plugin; + private static final Pattern LEGACY_COLOR_PATTERN = Pattern.compile("^&([0-9a-fk-orA-FK-OR])$"); public ChatColorCommand(LoChat plugin) { this.plugin = plugin; @@ -36,51 +37,51 @@ public class ChatColorCommand implements CommandExecutor, TabCompleter { if (args.length == 0) { player.sendMessage(ChatFormatter.parse(plugin.getMessageConfig().getInvalidUsage("/chatcolor <цвет>"))); - player.sendMessage(ChatFormatter.parse("Доступные цвета: red, blue, green, yellow, gold, aqua, light_purple, white, gray, dark_gray")); + player.sendMessage(ChatFormatter.parse("Используйте Minecraft color codes: &a, &b, &c, &d, &e, &f, &0-&9, &k, &l, &m, &n, &o, &r")); + player.sendMessage(ChatFormatter.parse("Пример: /chatcolor &b")); return true; } - String color = args[0].toLowerCase(); + String color = args[0]; - // Проверяем валидность цвета + // Проверяем валидность цвета (формат &X где X - это цветовой код) if (!isValidColor(color)) { - player.sendMessage(ChatFormatter.parse("Неверный цвет! Используйте один из доступных цветов.")); + player.sendMessage(ChatFormatter.parse("Неверный формат цвета! Используйте формат &X, например: &b, &a, &c")); return true; } // Сохраняем цвет чата игрока plugin.getChatColorManager().setChatColor(player.getUniqueId(), color); - player.sendMessage(ChatFormatter.parse("Цвет чата установлен на <" + color + ">" + color + "!")); + + // Показываем пример с примененным цветом + String preview = ChatFormatter.convertAllColors(color + "Пример текста"); + player.sendMessage(ChatFormatter.parse("Цвет чата установлен! Пример: " + preview)); return true; } private boolean isValidColor(String color) { - List validColors = Arrays.asList( - "red", "blue", "green", "yellow", "gold", "aqua", - "light_purple", "white", "gray", "dark_gray", "black", - "dark_red", "dark_green", "dark_blue", "dark_aqua", "dark_purple" - ); - return validColors.contains(color); + if (color == null || color.length() != 2) { + return false; + } + if (!color.startsWith("&")) { + return false; + } + char code = color.charAt(1); + return (code >= '0' && code <= '9') || + (code >= 'a' && code <= 'f') || + (code >= 'A' && code <= 'F') || + code == 'k' || code == 'K' || + code == 'l' || code == 'L' || + code == 'm' || code == 'M' || + code == 'n' || code == 'N' || + code == 'o' || code == 'O' || + code == 'r' || code == 'R'; } @Override public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { - if (args.length == 1) { - List colors = Arrays.asList( - "red", "blue", "green", "yellow", "gold", "aqua", - "light_purple", "white", "gray", "dark_gray" - ); - List completions = new ArrayList<>(); - String input = args[0].toLowerCase(); - - for (String color : colors) { - if (color.startsWith(input)) { - completions.add(color); - } - } - return completions; - } + // Убираем автодополнение, так как теперь пользователь сам вводит цвет return new ArrayList<>(); } } \ No newline at end of file diff --git a/src/main/java/com/loki/lochat/managers/ChatColorManager.java b/src/main/java/com/loki/lochat/managers/ChatColorManager.java index 191ff4c..8891bb2 100644 --- a/src/main/java/com/loki/lochat/managers/ChatColorManager.java +++ b/src/main/java/com/loki/lochat/managers/ChatColorManager.java @@ -82,12 +82,59 @@ public class ChatColorManager { /** * Применяет цвет чата к сообщению + * Поддерживает формат &X (Minecraft color codes) */ public String applyChatColor(UUID playerId, String message) { String color = getChatColor(playerId); if (color != null) { + // Если цвет в формате &X, конвертируем его в MiniMessage + if (color.startsWith("&") && color.length() == 2) { + String miniMessageColor = convertLegacyColorToMiniMessage(color); + if (!miniMessageColor.isEmpty()) { + // Извлекаем имя тега из для закрывающего тега + String tagName = miniMessageColor.substring(1, miniMessageColor.length() - 1); + return miniMessageColor + message + ""; + } + } + // Если уже в формате MiniMessage, используем как есть return "<" + color + ">" + message + ""; } return message; } + + /** + * Конвертирует &X код в MiniMessage формат + */ + private String convertLegacyColorToMiniMessage(String legacyColor) { + if (legacyColor == null || legacyColor.length() != 2 || !legacyColor.startsWith("&")) { + return ""; + } + + char code = legacyColor.charAt(1); + return switch (Character.toLowerCase(code)) { + case '0' -> ""; + case '1' -> ""; + case '2' -> ""; + case '3' -> ""; + case '4' -> ""; + case '5' -> ""; + case '6' -> ""; + case '7' -> ""; + case '8' -> ""; + case '9' -> ""; + case 'a' -> ""; + case 'b' -> ""; + case 'c' -> ""; + case 'd' -> ""; + case 'e' -> ""; + case 'f' -> ""; + case 'k' -> ""; + case 'l' -> ""; + case 'm' -> ""; + case 'n' -> ""; + case 'o' -> ""; + case 'r' -> ""; + default -> ""; + }; + } } \ No newline at end of file diff --git a/src/main/java/com/loki/lochat/utils/ChatFormatter.java b/src/main/java/com/loki/lochat/utils/ChatFormatter.java index 84fd958..2b7f431 100644 --- a/src/main/java/com/loki/lochat/utils/ChatFormatter.java +++ b/src/main/java/com/loki/lochat/utils/ChatFormatter.java @@ -16,6 +16,7 @@ public class ChatFormatter { // Паттерны для цветов private static final Pattern HEX_PATTERN = Pattern.compile("&#([A-Fa-f0-9]{6})"); + private static final Pattern HEX_PATTERN_NO_AMPERSAND = Pattern.compile("(? + * Конвертирует &#RRGGBB и #RRGGBB в MiniMessage формат <#RRGGBB> */ public static String convertHexColors(String message) { - Matcher matcher = HEX_PATTERN.matcher(message); - StringBuilder result = new StringBuilder(); + String result = message; + + // Конвертируем &#RRGGBB + Matcher matcher = HEX_PATTERN.matcher(result); + StringBuilder sb = new StringBuilder(); while (matcher.find()) { - matcher.appendReplacement(result, "<#" + matcher.group(1) + ">"); + matcher.appendReplacement(sb, "<#" + matcher.group(1) + ">"); } - matcher.appendTail(result); - return result.toString(); + matcher.appendTail(sb); + result = sb.toString(); + + // Конвертируем #RRGGBB (без &, но не если это часть &#RRGGBB) + matcher = HEX_PATTERN_NO_AMPERSAND.matcher(result); + sb = new StringBuilder(); + while (matcher.find()) { + matcher.appendReplacement(sb, "<#" + matcher.group(1) + ">"); + } + matcher.appendTail(sb); + return sb.toString(); } /** @@ -171,6 +184,7 @@ public class ChatFormatter { boolean hasColorCodes = LEGACY_COLOR_PATTERN.matcher(result).find() || SECTION_COLOR_PATTERN.matcher(result).find() || HEX_PATTERN.matcher(result).find() + || HEX_PATTERN_NO_AMPERSAND.matcher(result).find() || MINIMESSAGE_HEX_PATTERN.matcher(result).find(); // Если есть право на цвета И есть цветовые коды - конвертируем @@ -239,6 +253,9 @@ public class ChatFormatter { // Убираем &#RRGGBB result = HEX_PATTERN.matcher(result).replaceAll(""); + // Убираем #RRGGBB (без &) + result = HEX_PATTERN_NO_AMPERSAND.matcher(result).replaceAll(""); + // Убираем &коды result = stripLegacyColors(result); diff --git a/src/main/resources/automessages.yml b/src/main/resources/automessages.yml index e99aefe..bef3d02 100644 --- a/src/main/resources/automessages.yml +++ b/src/main/resources/automessages.yml @@ -47,7 +47,7 @@ messages: # Донат donate: - - "&#FFD700&l:gem: ДОНАТ :gem:" + - "#FFD700&l:gem: ДОНАТ :gem:" - "&7Поддержи сервер и получи" - "&7крутые привилегии!" - "&eПодробнее: &a/donate"