feat: Custom guild chat format and NametagManager for above-head & tablist guild tags
This commit is contained in:
@@ -33,6 +33,7 @@ public final class Main extends JavaPlugin {
|
|||||||
private EconomyManager economyManager;
|
private EconomyManager economyManager;
|
||||||
private fr.luc.gamingcore.worldguard.WorldGuardManager worldGuardManager;
|
private fr.luc.gamingcore.worldguard.WorldGuardManager worldGuardManager;
|
||||||
private GuildManager guildManager;
|
private GuildManager guildManager;
|
||||||
|
private fr.luc.gamingcore.manager.NametagManager nametagManager;
|
||||||
private BetterMcCommands betterMcCommands;
|
private BetterMcCommands betterMcCommands;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,6 +65,8 @@ public final class Main extends JavaPlugin {
|
|||||||
|
|
||||||
// 6. Initialiser le service métier GuildManager et charger les données
|
// 6. Initialiser le service métier GuildManager et charger les données
|
||||||
this.guildManager = new GuildManager(this, guildRepository, economyManager, worldGuardManager);
|
this.guildManager = new GuildManager(this, guildRepository, economyManager, worldGuardManager);
|
||||||
|
this.nametagManager = new fr.luc.gamingcore.manager.NametagManager(this, guildManager);
|
||||||
|
this.guildManager.setNametagManager(nametagManager);
|
||||||
loadConfigSettings();
|
loadConfigSettings();
|
||||||
this.guildManager.loadData();
|
this.guildManager.loadData();
|
||||||
|
|
||||||
@@ -75,6 +78,7 @@ public final class Main extends JavaPlugin {
|
|||||||
PluginManager pm = getServer().getPluginManager();
|
PluginManager pm = getServer().getPluginManager();
|
||||||
pm.registerEvents(new TerritoryProtectionListener(this), this);
|
pm.registerEvents(new TerritoryProtectionListener(this), this);
|
||||||
pm.registerEvents(new fr.luc.gamingcore.listener.GuildChatListener(this), this);
|
pm.registerEvents(new fr.luc.gamingcore.listener.GuildChatListener(this), this);
|
||||||
|
pm.registerEvents(new fr.luc.gamingcore.listener.NametagListener(this), this);
|
||||||
|
|
||||||
getLogger().info("GamingCore (Système de Guilde - Cœur Métier & Commandes) a ete active avec succes !");
|
getLogger().info("GamingCore (Système de Guilde - Cœur Métier & Commandes) a ete active avec succes !");
|
||||||
}
|
}
|
||||||
@@ -265,4 +269,13 @@ public final class Main extends JavaPlugin {
|
|||||||
public BetterMcCommands getBetterMcCommands() {
|
public BetterMcCommands getBetterMcCommands() {
|
||||||
return betterMcCommands;
|
return betterMcCommands;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtient le gestionnaire de Nametags et TabList.
|
||||||
|
*
|
||||||
|
* @return L'instance NametagManager.
|
||||||
|
*/
|
||||||
|
public fr.luc.gamingcore.manager.NametagManager getNametagManager() {
|
||||||
|
return nametagManager;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package fr.luc.gamingcore.listener;
|
||||||
|
|
||||||
|
import fr.luc.gamingcore.Main;
|
||||||
|
import fr.luc.gamingcore.manager.NametagManager;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Écouteur gérant l'assignation automatique des Nametags et noms TabList à la connexion/déconnexion des joueurs.
|
||||||
|
*/
|
||||||
|
public class NametagListener implements Listener {
|
||||||
|
|
||||||
|
private final Main plugin;
|
||||||
|
private final NametagManager nametagManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructeur de l'écouteur de Nametags.
|
||||||
|
*
|
||||||
|
* @param plugin Instance principale du plugin.
|
||||||
|
*/
|
||||||
|
public NametagListener(Main plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.nametagManager = plugin.getNametagManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Met à jour le tag au-dessus de la tête et dans la TabList lors de la connexion.
|
||||||
|
*
|
||||||
|
* @param event L'événement PlayerJoinEvent.
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
// Léger délai d'un tick pour laisser le client charger le scoreboard
|
||||||
|
plugin.getServer().getScheduler().runTask(plugin, () -> {
|
||||||
|
if (player.isOnline()) {
|
||||||
|
nametagManager.updatePlayer(player);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nettoie les entrées de scoreboard à la déconnexion.
|
||||||
|
*
|
||||||
|
* @param event L'événement PlayerQuitEvent.
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
nametagManager.removePlayer(event.getPlayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ public class GuildManager {
|
|||||||
private final ChunkPriceCalculator priceCalculator;
|
private final ChunkPriceCalculator priceCalculator;
|
||||||
private final InviteManager inviteManager;
|
private final InviteManager inviteManager;
|
||||||
private final MessageManager messageManager;
|
private final MessageManager messageManager;
|
||||||
|
private NametagManager nametagManager;
|
||||||
|
|
||||||
// Indexations en mémoire pour des lookups O(1)
|
// Indexations en mémoire pour des lookups O(1)
|
||||||
private final Map<UUID, Guild> guildsById = new ConcurrentHashMap<>();
|
private final Map<UUID, Guild> guildsById = new ConcurrentHashMap<>();
|
||||||
@@ -55,6 +56,10 @@ public class GuildManager {
|
|||||||
this.messageManager = plugin.getMessageManager();
|
this.messageManager = plugin.getMessageManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setNametagManager(NametagManager nametagManager) {
|
||||||
|
this.nametagManager = nametagManager;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Charge toutes les données depuis la base de données SQLite en mémoire.
|
* Charge toutes les données depuis la base de données SQLite en mémoire.
|
||||||
*/
|
*/
|
||||||
@@ -80,6 +85,10 @@ public class GuildManager {
|
|||||||
if (worldGuardManager != null && worldGuardManager.isEnabled()) {
|
if (worldGuardManager != null && worldGuardManager.isEnabled()) {
|
||||||
worldGuardManager.syncAllGuilds(new ArrayList<>(loadedGuilds));
|
worldGuardManager.syncAllGuilds(new ArrayList<>(loadedGuilds));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nametagManager != null) {
|
||||||
|
nametagManager.updateAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -214,6 +223,10 @@ public class GuildManager {
|
|||||||
worldGuardManager.createOrUpdateRegion(guild, loc.getWorld(), chunkX, chunkZ);
|
worldGuardManager.createOrUpdateRegion(guild, loc.getWorld(), chunkX, chunkZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nametagManager != null) {
|
||||||
|
nametagManager.updatePlayer(founder);
|
||||||
|
}
|
||||||
|
|
||||||
logAction(guild, founder, "CREATION", "Création de la guilde avec le chunk initial (" + chunkX + ", " + chunkZ + ")");
|
logAction(guild, founder, "CREATION", "Création de la guilde avec le chunk initial (" + chunkX + ", " + chunkZ + ")");
|
||||||
|
|
||||||
return GuildResult.success("La guilde " + guild.getFormattedName() + " a été créée avec succès !");
|
return GuildResult.success("La guilde " + guild.getFormattedName() + " a été créée avec succès !");
|
||||||
@@ -244,6 +257,18 @@ public class GuildManager {
|
|||||||
worldGuardManager.removeGuildRegions(guild);
|
worldGuardManager.removeGuildRegions(guild);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nametagManager != null) {
|
||||||
|
for (GuildMember m : guild.getMembers()) {
|
||||||
|
if (m.getOfflinePlayer() != null && m.getOfflinePlayer().isOnline()) {
|
||||||
|
Player p = m.getOfflinePlayer().getPlayer();
|
||||||
|
if (p != null) {
|
||||||
|
nametagManager.updatePlayer(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nametagManager.removeGuildTeam(guild.getId());
|
||||||
|
}
|
||||||
|
|
||||||
unindexGuild(guild);
|
unindexGuild(guild);
|
||||||
repository.deleteGuildAsync(guild.getId());
|
repository.deleteGuildAsync(guild.getId());
|
||||||
|
|
||||||
@@ -280,6 +305,10 @@ public class GuildManager {
|
|||||||
worldGuardManager.syncGuildMembers(guild);
|
worldGuardManager.syncGuildMembers(guild);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nametagManager != null) {
|
||||||
|
nametagManager.updatePlayer(player);
|
||||||
|
}
|
||||||
|
|
||||||
logAction(guild, player, "JOIN", player.getName() + " a rejoint la guilde (" + defaultRank.getName() + ")");
|
logAction(guild, player, "JOIN", player.getName() + " a rejoint la guilde (" + defaultRank.getName() + ")");
|
||||||
broadcastToGuild(guild, "guild.broadcast.member_joined", "{player}", player.getName());
|
broadcastToGuild(guild, "guild.broadcast.member_joined", "{player}", player.getName());
|
||||||
|
|
||||||
@@ -325,6 +354,13 @@ public class GuildManager {
|
|||||||
worldGuardManager.syncGuildMembers(guild);
|
worldGuardManager.syncGuildMembers(guild);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nametagManager != null) {
|
||||||
|
Player targetPlayer = org.bukkit.Bukkit.getPlayer(targetUuid);
|
||||||
|
if (targetPlayer != null) {
|
||||||
|
nametagManager.updatePlayer(targetPlayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logAction(guild, actor, "KICK", targetName + " a été expulsé par " + actor.getName());
|
logAction(guild, actor, "KICK", targetName + " a été expulsé par " + actor.getName());
|
||||||
broadcastToGuild(guild, "guild.broadcast.member_kicked", "{player}", targetName, "{actor}", actor.getName());
|
broadcastToGuild(guild, "guild.broadcast.member_kicked", "{player}", targetName, "{actor}", actor.getName());
|
||||||
|
|
||||||
@@ -357,6 +393,10 @@ public class GuildManager {
|
|||||||
worldGuardManager.syncGuildMembers(guild);
|
worldGuardManager.syncGuildMembers(guild);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nametagManager != null) {
|
||||||
|
nametagManager.updatePlayer(player);
|
||||||
|
}
|
||||||
|
|
||||||
logAction(guild, player, "LEAVE", player.getName() + " a quitté la guilde.");
|
logAction(guild, player, "LEAVE", player.getName() + " a quitté la guilde.");
|
||||||
broadcastToGuild(guild, "guild.broadcast.member_left", "{player}", player.getName());
|
broadcastToGuild(guild, "guild.broadcast.member_left", "{player}", player.getName());
|
||||||
|
|
||||||
@@ -557,6 +597,10 @@ public class GuildManager {
|
|||||||
repository.saveGuildAsync(guild);
|
repository.saveGuildAsync(guild);
|
||||||
logAction(guild, actor, "COLOR", "Couleur modifiée vers " + hexColor);
|
logAction(guild, actor, "COLOR", "Couleur modifiée vers " + hexColor);
|
||||||
|
|
||||||
|
if (nametagManager != null) {
|
||||||
|
nametagManager.updateGuild(guild);
|
||||||
|
}
|
||||||
|
|
||||||
return GuildResult.success("La couleur de la guilde a été changée pour <color:" + hexColor + ">" + hexColor + "</color> !");
|
return GuildResult.success("La couleur de la guilde a été changée pour <color:" + hexColor + ">" + hexColor + "</color> !");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,6 +621,10 @@ public class GuildManager {
|
|||||||
repository.saveGuildAsync(guild);
|
repository.saveGuildAsync(guild);
|
||||||
logAction(guild, actor, "TAG", "Tag modifié vers [" + newTag.toUpperCase() + "]");
|
logAction(guild, actor, "TAG", "Tag modifié vers [" + newTag.toUpperCase() + "]");
|
||||||
|
|
||||||
|
if (nametagManager != null) {
|
||||||
|
nametagManager.updateGuild(guild);
|
||||||
|
}
|
||||||
|
|
||||||
return GuildResult.success("Le tag de la guilde a été changé pour " + guild.getFormattedTag() + " !");
|
return GuildResult.success("Le tag de la guilde a été changé pour " + guild.getFormattedTag() + " !");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
package fr.luc.gamingcore.manager;
|
||||||
|
|
||||||
|
import fr.luc.gamingcore.Main;
|
||||||
|
import fr.luc.gamingcore.model.Guild;
|
||||||
|
import fr.luc.gamingcore.model.GuildMember;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scoreboard.Scoreboard;
|
||||||
|
import org.bukkit.scoreboard.Team;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gestionnaire responsable de l'affichage des tags et couleurs de guilde
|
||||||
|
* au-dessus de la tête des joueurs (Nametag / Scoreboard Team) et dans la liste des joueurs (TabList).
|
||||||
|
*/
|
||||||
|
public class NametagManager {
|
||||||
|
|
||||||
|
private final Main plugin;
|
||||||
|
private final GuildManager guildManager;
|
||||||
|
private final Scoreboard scoreboard;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructeur du gestionnaire de Nametags.
|
||||||
|
*
|
||||||
|
* @param plugin Instance principale du plugin.
|
||||||
|
* @param guildManager Gestionnaire métier des guildes.
|
||||||
|
*/
|
||||||
|
public NametagManager(Main plugin, GuildManager guildManager) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.guildManager = guildManager;
|
||||||
|
this.scoreboard = Bukkit.getScoreboardManager().getMainScoreboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Met à jour le nametag et le nom dans le TabList pour un joueur spécifique.
|
||||||
|
*
|
||||||
|
* @param player Le joueur à mettre à jour.
|
||||||
|
*/
|
||||||
|
public void updatePlayer(Player player) {
|
||||||
|
if (player == null || !player.isOnline()) return;
|
||||||
|
|
||||||
|
Guild guild = guildManager.getGuildByPlayer(player.getUniqueId());
|
||||||
|
|
||||||
|
if (guild != null) {
|
||||||
|
String teamName = getTeamName(guild.getId());
|
||||||
|
Team team = scoreboard.getTeam(teamName);
|
||||||
|
if (team == null) {
|
||||||
|
team = scoreboard.registerNewTeam(teamName);
|
||||||
|
}
|
||||||
|
|
||||||
|
String tagText = "<color:" + guild.getColor() + ">[" + guild.getTag() + "] </color>";
|
||||||
|
Component prefixComponent = MiniMessage.miniMessage().deserialize(tagText);
|
||||||
|
team.prefix(prefixComponent);
|
||||||
|
|
||||||
|
if (!team.hasEntry(player.getName())) {
|
||||||
|
// Retirer d'une ancienne équipe de guilde si nécessaire
|
||||||
|
Team oldTeam = scoreboard.getEntryTeam(player.getName());
|
||||||
|
if (oldTeam != null && oldTeam.getName().startsWith("g_") && !oldTeam.getName().equals(teamName)) {
|
||||||
|
oldTeam.removeEntry(player.getName());
|
||||||
|
}
|
||||||
|
team.addEntry(player.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TabList Name
|
||||||
|
Component tabName = MiniMessage.miniMessage().deserialize(tagText + "<white>" + player.getName() + "</white>");
|
||||||
|
player.playerListName(tabName);
|
||||||
|
} else {
|
||||||
|
// Joueur sans guilde
|
||||||
|
Team currentTeam = scoreboard.getEntryTeam(player.getName());
|
||||||
|
if (currentTeam != null && currentTeam.getName().startsWith("g_")) {
|
||||||
|
currentTeam.removeEntry(player.getName());
|
||||||
|
}
|
||||||
|
player.playerListName(Component.text(player.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Met à jour l'affichage de tous les membres d'une guilde donnée.
|
||||||
|
*
|
||||||
|
* @param guild La guilde dont les membres doivent être actualisés.
|
||||||
|
*/
|
||||||
|
public void updateGuild(Guild guild) {
|
||||||
|
if (guild == null) return;
|
||||||
|
for (GuildMember member : guild.getMembers()) {
|
||||||
|
if (member.getOfflinePlayer() != null && member.getOfflinePlayer().isOnline()) {
|
||||||
|
Player p = member.getOfflinePlayer().getPlayer();
|
||||||
|
if (p != null) {
|
||||||
|
updatePlayer(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supprime l'équipe Scoreboard associée à une guilde lors de sa dissolution.
|
||||||
|
*
|
||||||
|
* @param guildId L'UUID de la guilde dissoute.
|
||||||
|
*/
|
||||||
|
public void removeGuildTeam(UUID guildId) {
|
||||||
|
if (guildId == null) return;
|
||||||
|
String teamName = getTeamName(guildId);
|
||||||
|
Team team = scoreboard.getTeam(teamName);
|
||||||
|
if (team != null) {
|
||||||
|
team.unregister();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Met à jour tous les joueurs actuellement connectés sur le serveur.
|
||||||
|
*/
|
||||||
|
public void updateAll() {
|
||||||
|
for (Player online : Bukkit.getOnlinePlayers()) {
|
||||||
|
updatePlayer(online);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nettoie les équipes lors de la déconnexion d'un joueur.
|
||||||
|
*
|
||||||
|
* @param player Le joueur déconnecté.
|
||||||
|
*/
|
||||||
|
public void removePlayer(Player player) {
|
||||||
|
if (player == null) return;
|
||||||
|
Team team = scoreboard.getEntryTeam(player.getName());
|
||||||
|
if (team != null && team.getName().startsWith("g_")) {
|
||||||
|
team.removeEntry(player.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTeamName(UUID guildId) {
|
||||||
|
// Le nom d'équipe est préfixé par "g_" suivi des 12 premiers caractères de l'UUID pour rester sous les 16 car.
|
||||||
|
String raw = guildId.toString().replace("-", "");
|
||||||
|
return "g_" + (raw.length() > 12 ? raw.substring(0, 12) : raw);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -93,7 +93,7 @@ guild:
|
|||||||
pagination: "<click:run_command:'/guild list {prev_page}'><hover:show_text:'<yellow>Page précédente</yellow>'><aqua>[◀ Précédent]</aqua></hover></click> <dark_gray>---</dark_gray> <click:run_command:'/guild list {next_page}'><hover:show_text:'<yellow>Page suivante</yellow>'><aqua>[Suivant ▶]</aqua></hover></click>"
|
pagination: "<click:run_command:'/guild list {prev_page}'><hover:show_text:'<yellow>Page précédente</yellow>'><aqua>[◀ Précédent]</aqua></hover></click> <dark_gray>---</dark_gray> <click:run_command:'/guild list {next_page}'><hover:show_text:'<yellow>Page suivante</yellow>'><aqua>[Suivant ▶]</aqua></hover></click>"
|
||||||
|
|
||||||
chat:
|
chat:
|
||||||
format: "<color:{color}>[Chat Guilde] <gold>{rank}</gold> <white>{player}</white> <dark_gray>»</dark_gray> <white>{message}</white></color>"
|
format: "<color:{color}>[Guild Chat]</color> {guild} <dark_gray>-</dark_gray> <gold>{rank}</gold> <dark_gray>-</dark_gray> <white>{player}</white> <dark_gray>=></dark_gray> <white>{message}</white>"
|
||||||
|
|
||||||
broadcast:
|
broadcast:
|
||||||
member_joined: "<green><white>{player}</white> a rejoint la guilde !</green>"
|
member_joined: "<green><white>{player}</white> a rejoint la guilde !</green>"
|
||||||
|
|||||||
Reference in New Issue
Block a user