fix color

This commit is contained in:
loki5512344 2026-03-13 15:51:47 +01:00
parent 6b6605a2b0
commit 5088e3ad1c
20 changed files with 623 additions and 423 deletions

View file

@ -119,7 +119,6 @@ public final class LoChat extends JavaPlugin {
getCommand("announce").setExecutor(new AnnounceCommand(this));
getCommand("chatspy").setExecutor(new ChatSpyCommand(this));
getCommand("clearchat").setExecutor(new ClearChatCommand(this));
getCommand("hub").setExecutor(new HubCommand(this));
NickCommand nickCmd = new NickCommand(this);
getCommand("nick").setExecutor(nickCmd);
@ -151,10 +150,15 @@ public final class LoChat extends JavaPlugin {
getCommand("clearchatconfig").setExecutor(clearCfgCmd);
getCommand("clearchatconfig").setTabCompleter(clearCfgCmd);
// Discord команда
DiscordCommand discordCmd = new DiscordCommand(this, discordIntegration);
getCommand("discord").setExecutor(discordCmd);
getCommand("discord").setTabCompleter(discordCmd);
// Custom commands управление
CustomCommandsCommand customCommandsCmd = new CustomCommandsCommand(this, customCommandManager);
getCommand("customcommands").setExecutor(customCommandsCmd);
getCommand("customcommands").setTabCompleter(customCommandsCmd);
// Discord admin команда (отдельно от кастомной /discord)
DiscordCommand discordAdminCmd = new DiscordCommand(this, discordIntegration);
getCommand("discordadmin").setExecutor(discordAdminCmd);
getCommand("discordadmin").setTabCompleter(discordAdminCmd);
}
private void registerListeners() {

View file

@ -0,0 +1,128 @@
package com.loki.lochat.commands;
import com.loki.lochat.LoChat;
import com.loki.lochat.managers.CustomCommandManager;
import com.loki.lochat.utils.ChatFormatter;
import net.kyori.adventure.text.Component;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CustomCommandsCommand implements CommandExecutor, TabCompleter {
private final LoChat plugin;
private final CustomCommandManager commandManager;
public CustomCommandsCommand(LoChat plugin, CustomCommandManager commandManager) {
this.plugin = plugin;
this.commandManager = commandManager;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!sender.hasPermission("lochat.customcommands")) {
sender.sendMessage(ChatFormatter.parse("<#F44336>❌ У вас нет прав для использования этой команды!"));
return true;
}
if (args.length == 0) {
showHelp(sender);
return true;
}
switch (args[0].toLowerCase()) {
case "list" -> showCommandsList(sender);
case "reload" -> reloadCommands(sender);
case "enable" -> {
if (args.length < 2) {
sender.sendMessage(ChatFormatter.parse("<#FFA726>⚠️ Использование: /customcommands enable <команда>"));
return true;
}
toggleCommand(sender, args[1], true);
}
case "disable" -> {
if (args.length < 2) {
sender.sendMessage(ChatFormatter.parse("<#FFA726>⚠️ Использование: /customcommands disable <команда>"));
return true;
}
toggleCommand(sender, args[1], false);
}
default -> showHelp(sender);
}
return true;
}
private void showHelp(CommandSender sender) {
Component message = ChatFormatter.parse("""
<gradient:#FFD700:#FFA500><bold>▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬</bold></gradient>
<gradient:#87CEEB:#4169E1><bold>🛠️ Управление кастомными командами</bold></gradient>
<#FFEB3B>📋 Доступные команды:</color>
<#9E9E9E>• <#FFFFFF>/customcommands list</color> - список команд
<#9E9E9E>• <#FFFFFF>/customcommands reload</color> - перезагрузить команды
<#9E9E9E>• <#FFFFFF>/customcommands enable <команда></color> - включить команду
<#9E9E9E>• <#FFFFFF>/customcommands disable <команда></color> - выключить команду
<gradient:#FFD700:#FFA500><bold>▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬</bold></gradient>
""");
sender.sendMessage(message);
}
private void showCommandsList(CommandSender sender) {
net.kyori.adventure.text.TextComponent.Builder message = Component.text()
.append(ChatFormatter.parse("<gradient:#FFD700:#FFA500><bold>▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬</bold></gradient>\n"))
.append(ChatFormatter.parse("<gradient:#87CEEB:#4169E1><bold>📋 Кастомные команды</bold></gradient>\n\n"));
for (CustomCommandManager.CustomCommandData data : commandManager.getCommands().values()) {
String status = data.enabled() ? "<#4CAF50>✅ Включена" : "<#F44336>❌ Выключена";
String permission = data.permission() != null ? " <#9E9E9E>(Права: " + data.permission() + ")" : "";
message.append(ChatFormatter.parse(
"<#FFFFFF>/" + data.name() + "</color> " + status + permission + "\n"
));
}
message.append(ChatFormatter.parse("\n<gradient:#FFD700:#FFA500><bold>▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬</bold></gradient>"));
sender.sendMessage(message.build());
}
private void reloadCommands(CommandSender sender) {
try {
commandManager.reload();
sender.sendMessage(ChatFormatter.parse("<#4CAF50>✅ Кастомные команды успешно перезагружены!"));
} catch (Exception e) {
sender.sendMessage(ChatFormatter.parse("<#F44336>❌ Ошибка при перезагрузке команд: " + e.getMessage()));
plugin.getLogger().severe("Ошибка перезагрузки кастомных команд: " + e.getMessage());
}
}
private void toggleCommand(CommandSender sender, String commandName, boolean enable) {
sender.sendMessage(ChatFormatter.parse(
"<#FFA726>⚠️ Для изменения статуса команд отредактируйте файл custom-commands.yml и выполните /customcommands reload"
));
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if (!sender.hasPermission("lochat.customcommands")) {
return new ArrayList<>();
}
if (args.length == 1) {
return Arrays.asList("list", "reload", "enable", "disable");
}
if (args.length == 2 && (args[0].equalsIgnoreCase("enable") || args[0].equalsIgnoreCase("disable"))) {
return new ArrayList<>(commandManager.getCommands().keySet());
}
return new ArrayList<>();
}
}

View file

@ -90,17 +90,28 @@ public class DiscordCommand implements CommandExecutor, TabCompleter {
sender.sendMessage(ChatFormatter.parse("&e⏳ Отправка тестового сообщения..."));
// Отправляем тестовое сообщение
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
// Используем CompletableFuture для асинхронной отправки (Folia-совместимо)
java.util.concurrent.CompletableFuture.runAsync(() -> {
try {
discord.sendTestMessage(message, sender.getName());
plugin.getServer().getScheduler().runTask(plugin, () ->
sender.sendMessage(ChatFormatter.parse("&a✓ Тестовое сообщение отправлено в Discord"))
);
// Возвращаемся в главный поток для отправки сообщения
if (sender instanceof org.bukkit.entity.Player player) {
player.getScheduler().run(plugin, (task) ->
sender.sendMessage(ChatFormatter.parse("&a✓ Тестовое сообщение отправлено в Discord")), null
);
} else {
// Для консоли можно отправить сразу
sender.sendMessage(ChatFormatter.parse("&a✓ Тестовое сообщение отправлено в Discord"));
}
} catch (Exception e) {
plugin.getServer().getScheduler().runTask(plugin, () ->
sender.sendMessage(ChatFormatter.parse("&c✗ Ошибка отправки: " + e.getMessage()))
);
if (sender instanceof org.bukkit.entity.Player player) {
player.getScheduler().run(plugin, (task) ->
sender.sendMessage(ChatFormatter.parse("&c✗ Ошибка отправки: " + e.getMessage())), null
);
} else {
sender.sendMessage(ChatFormatter.parse("&c✗ Ошибка отправки: " + e.getMessage()));
}
plugin.getLogger().severe("Discord test error: " + e.getMessage());
}
});
}

View file

@ -30,36 +30,36 @@ public class LoChatCommand implements CommandExecutor, TabCompleter {
}
if (args.length == 0) {
sender.sendMessage(MM.deserialize("&#FFD700LoChat v" + plugin.getPluginMeta().getVersion()));
sender.sendMessage(MM.deserialize("&#808080Команды:"));
sender.sendMessage(MM.deserialize("&#FFFF00/lochat reload - Перезагрузить конфиги"));
sender.sendMessage(MM.deserialize("&#FFFF00/lochat commands - Список кастомных команд"));
sender.sendMessage(MM.deserialize("&#FFFF00/lochat commands reload - Перезагрузить кастомные команды"));
sender.sendMessage(MM.deserialize("<#FFD700>LoChat v" + plugin.getPluginMeta().getVersion()));
sender.sendMessage(MM.deserialize("<#808080>Команды:"));
sender.sendMessage(MM.deserialize("<#FFFF00>/lochat reload</color> <#808080>- Перезагрузить конфиги"));
sender.sendMessage(MM.deserialize("<#FFFF00>/lochat commands</color> <#808080>- Список кастомных команд"));
sender.sendMessage(MM.deserialize("<#FFFF00>/lochat commands reload</color> <#808080>- Перезагрузить кастомные команды"));
return true;
}
switch (args[0].toLowerCase()) {
case "reload" -> {
plugin.reload();
sender.sendMessage(MM.deserialize("&#00FF00Конфигурация перезагружена!"));
sender.sendMessage(MM.deserialize("<#00FF00>Конфигурация перезагружена!"));
}
case "commands" -> {
if (args.length > 1 && args[1].equalsIgnoreCase("reload")) {
plugin.getCustomCommandManager().reload();
sender.sendMessage(MM.deserialize("&#00FF00Кастомные команды перезагружены!"));
sender.sendMessage(MM.deserialize("<#00FF00>Кастомные команды перезагружены!"));
} else {
var commands = plugin.getCustomCommandManager().getCommands();
sender.sendMessage(MM.deserialize("&#FFD700Кастомные команды (" + commands.size() + "):"));
sender.sendMessage(MM.deserialize("<#FFD700>Кастомные команды (" + commands.size() + "):"));
for (var cmd : commands.values()) {
sender.sendMessage(MM.deserialize("&e/" + cmd.name() + " &#808080(" + cmd.type() + ")"));
sender.sendMessage(MM.deserialize("<#FFEB3B>/" + cmd.name() + "</color> <#808080>(" + cmd.type() + ")"));
if (!cmd.aliases().isEmpty()) {
sender.sendMessage(MM.deserialize("&#808080 Алиасы: " + String.join(", ", cmd.aliases())));
sender.sendMessage(MM.deserialize("<#808080> Алиасы: " + String.join(", ", cmd.aliases())));
}
}
}
}
default ->
sender.sendMessage(MM.deserialize("&#FF0000Неизвестная команда. Используйте /lochat для помощи."));
sender.sendMessage(MM.deserialize("<#FF0000>Неизвестная команда. Используйте /lochat для помощи."));
}
return true;

View file

@ -53,12 +53,19 @@ public class ChatServiceImpl implements ChatService {
// Используем тот же рендерер что и в ChatEventListener для единообразия
EnhancedChatRenderer renderer = new EnhancedChatRenderer(plugin, sender, messageComponent, false);
int recipientCount = 0;
for (Player player : Bukkit.getOnlinePlayers()) {
if (DistanceUtil.isInRange(sender, player, radius)) {
Component renderedMessage = renderer.render(sender, sender.displayName(), messageComponent, player);
player.sendMessage(renderedMessage);
recipientCount++;
}
}
// Если никто не услышал (только отправитель в радиусе)
if (recipientCount <= 1) {
sender.sendMessage(ChatFormatter.parse(plugin.getConfig().getString("messages.local.nobody-heard", "<#FFA726>Вас никто не услышал - рядом нет игроков")));
}
}
@Override

View file

@ -81,6 +81,11 @@ public class GradientConfig {
}
public String getPrefixFormat() {
// Сначала проверяем в formatting.prefix-format (из gradient-config.yml)
if (config.contains("formatting.prefix-format")) {
return config.getString("formatting.prefix-format", "[{prefix}] ");
}
// Затем проверяем в gradient.prefix-format (из config.yml)
return config.getString("gradient.prefix-format", "[{prefix}] ");
}

View file

@ -24,7 +24,11 @@ public class GradientPlayerListener implements Listener {
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
FoliaUtil.runAsync(module.getPlugin(), () -> {
module.getDataManager().getPlayerData(player.getUniqueId());
var data = module.getDataManager().getPlayerData(player.getUniqueId());
// Применяем градиент к displayName при входе
FoliaUtil.runEntityTask(module.getPlugin(), player, () -> {
com.loki.lochat.gradient.util.DisplayNameUtil.updateDisplayName(module, player, data);
});
});
}

View file

@ -16,7 +16,7 @@ import java.util.regex.Pattern;
public final class DisplayNameUtil {
private static final LegacyComponentSerializer SERIALIZER = LegacyComponentSerializer.builder()
.character('§')
.character('&')
.hexCharacter('#')
.hexColors()
.build();

View file

@ -59,6 +59,12 @@ public class DiscordIntegration {
int retryAttempts = config.getInt("performance.retry_attempts", 3);
long retryDelay = config.getLong("performance.retry_delay", 1000);
// Логируем информацию о URL для отладки
plugin.getLogger().info("Discord webhook URL length: " + webhookUrl.length());
if (webhookUrl.length() > 0) {
plugin.getLogger().info("Discord webhook URL starts with: " + webhookUrl.substring(0, Math.min(50, webhookUrl.length())));
}
webhook = new DiscordWebhook(plugin, webhookUrl, username, avatarUrl, timeout, retryAttempts, retryDelay);
if (!webhook.isValid()) {

View file

@ -28,7 +28,7 @@ public class DiscordWebhook {
public DiscordWebhook(JavaPlugin plugin, String webhookUrl, String username, String avatarUrl,
int timeout, int retryAttempts, long retryDelay) {
this.plugin = plugin;
this.webhookUrl = webhookUrl;
this.webhookUrl = webhookUrl != null ? webhookUrl.trim() : null; // Убираем пробелы
this.username = username;
this.avatarUrl = avatarUrl;
this.timeout = timeout * 1000; // конвертируем в миллисекунды
@ -142,7 +142,8 @@ public class DiscordWebhook {
* Синхронная отправка в вебхук
*/
private boolean sendWebhookSync(String jsonPayload) throws IOException {
URL url = URI.create(webhookUrl).toURL();
String cleanUrl = webhookUrl.trim();
URL url = URI.create(cleanUrl).toURL();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try {
@ -180,8 +181,32 @@ public class DiscordWebhook {
* Проверить валидность вебхука
*/
public boolean isValid() {
return webhookUrl != null &&
webhookUrl.startsWith("https://discord.com/api/webhooks/") &&
webhookUrl.length() > 50; // Минимальная длина валидного URL
if (webhookUrl == null || webhookUrl.trim().isEmpty()) {
plugin.getLogger().warning("Discord webhook URL is null or empty");
return false;
}
String cleanUrl = webhookUrl.trim();
if (!cleanUrl.startsWith("https://discord.com/api/webhooks/") &&
!cleanUrl.startsWith("https://discordapp.com/api/webhooks/")) {
plugin.getLogger().warning("Discord webhook URL has invalid format: " + cleanUrl);
return false;
}
if (cleanUrl.length() < 50) {
plugin.getLogger().warning("Discord webhook URL is too short: " + cleanUrl);
return false;
}
// Проверяем на недопустимые символы
try {
URI.create(cleanUrl);
} catch (IllegalArgumentException e) {
plugin.getLogger().warning("Discord webhook URL contains illegal characters: " + e.getMessage());
return false;
}
return true;
}
}

View file

@ -1,5 +1,6 @@
package com.loki.lochat.listener;
import com.loki.lochat.LoChat;
import com.loki.lochat.api.service.MessageService;
import com.loki.lochat.core.filter.AdvancedMessageFilter;
import com.loki.lochat.core.registry.ServiceRegistry;
@ -62,8 +63,25 @@ public class ChatEventListener implements Listener {
event.viewers().removeIf(viewer ->
viewer instanceof Player p && !com.loki.lochat.util.DistanceUtil.isInRange(sender, p, radius)
);
// Проверяем, есть ли получатели (кроме отправителя)
long recipientCount = event.viewers().stream()
.filter(viewer -> viewer instanceof Player p && !p.equals(sender))
.count();
if (recipientCount == 0) {
// Отправляем уведомление отправителю после обработки события (Folia-совместимо)
sender.getScheduler().run(plugin, (task) ->
sender.sendMessage(com.loki.lochat.utils.ChatFormatter.parse(plugin.getConfig().getString("messages.local.nobody-heard", "<#FFA726>Вас никто не услышал - рядом нет игроков"))), null
);
}
}
event.renderer(new EnhancedChatRenderer(plugin, sender, event.message(), isGlobal));
// Отправляем сообщение в Discord
if (plugin instanceof LoChat loChat) {
loChat.getDiscordIntegration().sendChatMessage(sender, filteredMessage, isGlobal);
}
}
}

View file

@ -10,6 +10,8 @@ import org.bukkit.command.CommandMap;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import java.io.File;
@ -57,7 +59,8 @@ public class CustomCommandManager {
section.getString("message", ""),
section.getStringList("aliases"),
section.getString("type", "chat"),
section.getString("target", "sender")
section.getString("target", "sender"),
section.getBoolean("enabled", true)
);
commands.put(commandName, data);
@ -75,17 +78,18 @@ public class CustomCommandManager {
CommandMap commandMap = Bukkit.getCommandMap();
// Создаем и регистрируем команду
CustomCommand command = new CustomCommand(data.name, this);
CustomCommand command = new CustomCommand(data.name(), this);
commandMap.register("lochat", command);
// Регистрируем алиасы
for (String alias : data.aliases) {
for (String alias : data.aliases()) {
CustomCommand aliasCommand = new CustomCommand(alias, this);
commandMap.register("lochat", aliasCommand);
}
} catch (Exception e) {
plugin.getLogger().severe("Ошибка регистрации команды " + data.name + ": " + e.getMessage());
plugin.getLogger().severe("Ошибка регистрации команды " + data.name() + ": " + e.getMessage());
e.printStackTrace();
}
}
@ -98,7 +102,7 @@ public class CustomCommandManager {
if (data == null) {
// Проверяем алиасы
for (CustomCommandData cmd : commands.values()) {
if (cmd.aliases.contains(commandName)) {
if (cmd.aliases().contains(commandName)) {
data = cmd;
break;
}
@ -107,21 +111,28 @@ public class CustomCommandManager {
if (data == null) return false;
// Проверяем включена ли команда
if (!data.enabled()) {
// Не показываем ошибку, просто игнорируем команду
return true;
}
// Проверяем права
if (data.permission != null && !player.hasPermission(data.permission)) {
if (data.permission() != null && !player.hasPermission(data.permission())) {
player.sendMessage(ChatFormatter.parse(plugin.getMessageConfig().getNoPermission()));
return true;
}
// Обрабатываем плейсхолдеры
String message = processPlaceholders(data.message, player, args);
String message = processPlaceholders(data.message(), player, args);
// Выполняем команду в зависимости от типа
switch (data.type.toLowerCase()) {
case "broadcast" -> sendBroadcast(data.target, message);
case "title" -> sendTitle(data.target, player, message);
case "actionbar" -> sendActionBar(data.target, player, message);
default -> sendChatMessage(data.target, player, message);
switch (data.type().toLowerCase()) {
case "broadcast" -> sendBroadcast(data.target(), message);
case "title" -> sendTitle(data.target(), player, message);
case "actionbar" -> sendActionBar(data.target(), player, message);
case "bungee" -> sendBungeeCommand(player, data);
default -> sendChatMessage(data.target(), player, message);
}
return true;
@ -136,6 +147,7 @@ public class CustomCommandManager {
result = result.replace("{y}", String.valueOf(player.getLocation().getBlockY()));
result = result.replace("{z}", String.valueOf(player.getLocation().getBlockZ()));
result = result.replace("{world}", player.getWorld().getName());
result = result.replace("{ping}", String.valueOf(player.getPing()));
// Аргументы команды
for (int i = 0; i < args.length; i++) {
@ -258,11 +270,52 @@ public class CustomCommandManager {
}
}
private void sendBungeeCommand(Player player, CustomCommandData data) {
// Отправляем сообщение игроку
if (!data.message().isEmpty()) {
Component component = ChatFormatter.parse(data.message());
player.sendMessage(component);
}
// Подключаем к серверу через BungeeCord
String serverName = getServerFromConfig(data);
if (serverName != null && !serverName.isEmpty()) {
connectToServer(player, serverName);
}
}
private String getServerFromConfig(CustomCommandData data) {
// Ищем параметр server в конфиге команды
try {
File commandsFile = new File(plugin.getDataFolder(), "custom-commands.yml");
FileConfiguration config = YamlConfiguration.loadConfiguration(commandsFile);
return config.getString(data.name() + ".server", "hub");
} catch (Exception e) {
plugin.getLogger().warning("Ошибка получения сервера для команды " + data.name() + ": " + e.getMessage());
return "hub";
}
}
private void connectToServer(Player player, String serverName) {
try {
java.io.ByteArrayOutputStream b = new java.io.ByteArrayOutputStream();
java.io.DataOutputStream out = new java.io.DataOutputStream(b);
out.writeUTF("Connect");
out.writeUTF(serverName);
player.sendPluginMessage(plugin, "BungeeCord", b.toByteArray());
} catch (Exception e) {
plugin.getLogger().severe("Ошибка подключения к серверу " + serverName + ": " + e.getMessage());
player.sendMessage(ChatFormatter.parse("<#F44336>❌ Ошибка подключения к серверу"));
}
}
public Map<String, CustomCommandData> getCommands() {
return commands;
}
public record CustomCommandData(String name, String permission, String message, List<String> aliases, String type,
String target) {
String target, boolean enabled) {
}
}

View file

@ -45,16 +45,16 @@ public class EnhancedChatRenderer implements ChatRenderer {
.append(Component.text("A").color(net.kyori.adventure.text.format.TextColor.fromHexString("#FF6347")))
.append(Component.text("L").color(net.kyori.adventure.text.format.TextColor.fromHexString("#FF4500")));
} else {
// 📍 LOCAL с градиентом от голубого к синему
prefixComponent = Component.text("📍 ")
.append(Component.text("L").color(net.kyori.adventure.text.format.TextColor.fromHexString("#87CEEB")))
// LOCAL с градиентом от голубого к синему (без эмодзи)
prefixComponent = Component.text("L").color(net.kyori.adventure.text.format.TextColor.fromHexString("#87CEEB"))
.append(Component.text("O").color(net.kyori.adventure.text.format.TextColor.fromHexString("#87CEFA")))
.append(Component.text("C").color(net.kyori.adventure.text.format.TextColor.fromHexString("#00BFFF")))
.append(Component.text("A").color(net.kyori.adventure.text.format.TextColor.fromHexString("#1E90FF")))
.append(Component.text("L").color(net.kyori.adventure.text.format.TextColor.fromHexString("#4169E1")));
}
Component playerComponent = createPlayerComponent(source, sourceDisplayName);
// Используем displayName игрока напрямую (он уже Component с градиентом)
Component playerComponent = createPlayerComponent(source, source.displayName());
Component processedMessage = message;
processedMessage = TextFormatter.formatMarkdown(processedMessage);
@ -67,13 +67,13 @@ public class EnhancedChatRenderer implements ChatRenderer {
// Красивое разделение с градиентными стрелками
Component separator = isGlobal ?
Component.text(" ▶ ").color(net.kyori.adventure.text.format.TextColor.fromHexString("#FFD700")) :
Component.text(" ▶ ").color(net.kyori.adventure.text.format.TextColor.fromHexString("#87CEEB"));
Component.text(" ▶ ", net.kyori.adventure.text.format.TextColor.fromHexString("#FFD700")) :
Component.text(" ▶ ", net.kyori.adventure.text.format.TextColor.fromHexString("#FFFFFF"));
return prefixComponent
.append(separator)
.append(playerComponent)
.append(Component.text(": ").color(net.kyori.adventure.text.format.NamedTextColor.DARK_GRAY))
.append(Component.text(": ", net.kyori.adventure.text.format.NamedTextColor.WHITE))
.append(processedMessage);
}