feat: Real-time custom name color, chat color, and permission support via LuckPerms meta without server restarts

This commit is contained in:
2026-08-20 22:21:56 +02:00
parent b5caa905d6
commit 1df5c7020d
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
/**
* Écouteur gérant à la fois le chat privé de guilde (#message) et le formatage du chat global avec :
* [Grade] [TagGuilde] Pseudo: Message.
* [Grade] [TagGuilde] Pseudo: Message (avec couleurs dynamiques de pseudo et de message par grade).
*/
public class GuildChatListener implements Listener {
@@ -77,12 +77,13 @@ public class GuildChatListener implements Listener {
event.renderer(new ChatRenderer() {
@Override
public @NotNull Component render(@NotNull Player source, @NotNull Component sourceDisplayName, @NotNull Component message, @NotNull Audience viewer) {
boolean hasPapi = Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null;
// A. Préfixe de Grade (LuckPerms via PlaceholderAPI avec support des dégradés TAB & MiniMessage)
Component prefixComponent = Component.empty();
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
if (hasPapi) {
String lpPrefix = me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(source, "%luckperms_prefix%");
if (lpPrefix != null && !lpPrefix.trim().isEmpty()) {
// Conversion du format dégradé TAB {#HEX1>}texte{#HEX2<} vers MiniMessage <gradient:#HEX1:#HEX2>texte</gradient>
if (lpPrefix != null && !lpPrefix.trim().isEmpty() && !lpPrefix.startsWith("%")) {
if (lpPrefix.contains("{#") && lpPrefix.contains(">}")) {
lpPrefix = lpPrefix.replaceAll("\\{#([0-9a-fA-F]{6})>\\}(.*?)\\{#([0-9a-fA-F]{6})<\\}", "<gradient:#$1:#$3>$2</gradient>");
}
@@ -111,12 +112,48 @@ public class GuildChatListener implements Listener {
}
}
// C. Couleur du Pseudo (via Suffixe LuckPerms ou meta name-color)
Component nameComponent = sourceDisplayName.color(NamedTextColor.WHITE);
if (hasPapi) {
String lpSuffix = me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(source, "%luckperms_suffix%");
if (lpSuffix != null && !lpSuffix.trim().isEmpty() && !lpSuffix.startsWith("%")) {
if (lpSuffix.contains("{#") && lpSuffix.contains(">}")) {
lpSuffix = lpSuffix.replaceAll("\\{#([0-9a-fA-F]{6})>\\}(.*?)\\{#([0-9a-fA-F]{6})<\\}", "<gradient:#$1:#$3>$2</gradient>");
}
if (lpSuffix.contains("<") && lpSuffix.contains(">")) {
nameComponent = MiniMessage.miniMessage().deserialize(lpSuffix + source.getName());
} else {
nameComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(lpSuffix + source.getName());
}
}
}
// D. Couleur et Formatage du Message
Component messageComponent;
String rawMsg = PlainTextComponentSerializer.plainText().serialize(message);
if (source.hasPermission("gamingcore.chat.color") || source.isOp()) {
if (rawMsg.contains("<") && rawMsg.contains(">")) {
messageComponent = MiniMessage.miniMessage().deserialize(rawMsg);
} else {
messageComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(rawMsg);
}
} else if (hasPapi) {
String chatColor = me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(source, "%luckperms_meta_chat-color%");
if (chatColor != null && !chatColor.trim().isEmpty() && !chatColor.startsWith("%")) {
messageComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(chatColor + rawMsg);
} else {
messageComponent = message.color(NamedTextColor.WHITE);
}
} else {
messageComponent = message.color(NamedTextColor.WHITE);
}
// Assemblage final : [Grade] [TagGuilde] Pseudo: Message
return prefixComponent
.append(tagComponent)
.append(sourceDisplayName.color(NamedTextColor.WHITE))
.append(nameComponent)
.append(Component.text(": ", NamedTextColor.DARK_GRAY))
.append(message.color(NamedTextColor.WHITE));
.append(messageComponent);
}
});
}