# 🎯 Système d'Événements & Cycle de Vie - betterMcCommands `betterMcCommands` intègre un système d'événements complet permettant d'intercepter, modifier, auditer ou bloquer chaque étape de l'exécution d'une commande. --- ## 📑 Sommaire - [1. Vue d'Ensemble du Cycle de Vie](#1-vue-densemble-du-cycle-de-vie) - [2. Les Deux Méthodes d'Écoute](#2-les-deux-méthodes-découte) - [Méthode A : Hooks Fluides sur le Builder](#méthode-a--hooks-fluides-sur-le-builder) - [Méthode B : Classes d'Écouteurs avec `@CommandEventHandler`](#méthode-b--classes-découteurs-avec-commandeventhandler) - [3. Référence Exhaustive des Événements](#3-référence-exhaustive-des-événements) - [4. Exemples Pratiques](#4-exemples-pratiques) --- ## 1. Vue d'Ensemble du Cycle de Vie Lorsqu'un joueur ou la console exécute une commande : 1. **Vérification d'émetteur et permission** -> `CommandPermissionDeniedEvent` (si refus). 2. **Vérification du Cooldown** -> `CommandCooldownEvent` (si cooldown actif). 3. **Parsing des arguments** -> `CommandSyntaxErrorEvent` (si syntaxe invalide). 4. **Demande de Confirmation** -> `CommandConfirmationRequiredEvent` (si confirmation requise). 5. **Pré-exécution** -> `CommandPreExecuteEvent` (**annulable**). 6. **Exécution métier** -> Appel du `CommandExecutor`. 7. **Post-exécution** -> `CommandPostExecuteEvent` (durée d'exécution, statut de réussite/échec, logs). --- ## 2. Les Deux Méthodes d'Écoute ### Méthode A : Hooks Fluides sur le Builder Permet d'attacher un comportement spécifique directement à une commande : ```java BetterMcCommands.builder("trade") .onPreExecute(event -> { if (event.isPlayer() && isInCombat(event.getPlayer())) { event.setCancelled(true); event.reply("Vous ne pouvez pas échanger en combat !"); } }) .onPostExecute(event -> { System.out.println("Trade exécuté en " + event.getExecutionDuration().toMillis() + "ms."); }) .executes(context -> { context.replySuccess("Échange ouvert !"); }) .register(); ``` --- ### Méthode B : Classes d'Écouteurs avec `@CommandEventHandler` Idéal pour centraliser la sécurité, l'audit et les métriques globales : ```java package fr.luc.monplugin.listener; import fr.luc.bettermccommands.event.*; import fr.luc.bettermccommands.event.annotation.CommandEventHandler; public class CommandAuditListener { // Écoute TOUTES les commandes avant leur exécution @CommandEventHandler(priority = 10) public void onAnyPreExecute(CommandPreExecuteEvent event) { System.out.println("[Audit] Demande d'exécution : /" + event.getNode().getFullName() + " par " + event.getSender().getName()); } // Écoute UNIQUEMENT la commande racine 'admin' @CommandEventHandler(command = "admin") public void onAdminPostExecute(CommandPostExecuteEvent event) { if (!event.isSuccessful()) { System.err.println("[Alerte Sécurité] Échec sur commande admin : " + event.getNode().getFullName()); } } // Personnalise les messages de refus de permission @CommandEventHandler public void onPermissionDenied(CommandPermissionDeniedEvent event) { if (event.getRequiredPermission() != null) { event.setCustomErrorMessage("Accès Refusé : Permission requise [" + event.getRequiredPermission() + "]."); } } // Personnalise l'avertissement de cooldown @CommandEventHandler public void onCooldown(CommandCooldownEvent event) { event.setCustomMessage("⏳ Patientez " + event.getRemainingCooldown().toSeconds() + "s avant de réutiliser cette commande."); } } ``` Pour enregistrer cette classe : ```java commandsManager.registerListeners(new CommandAuditListener()); ``` --- ## 3. Référence Exhaustive des Événements | Classe d'Événement | Description | Données Disponibles | Annulable ? | |---|---|---|:---:| | `CommandPreExecuteEvent` | Déclenché immédiatement avant l'exécution métier. | `getNode()`, `getSender()`, `getContext()` | ✅ **Oui** | | `CommandPostExecuteEvent` | Déclenché après la fin de l'exécution. | `getResult()`, `getExecutionDuration()`, `getException()`, `isSuccessful()` | ❌ Non | | `CommandPermissionDeniedEvent` | Déclenché lors d'un échec de permission ou restriction console/joueur. | `getRequiredPermission()`, `getRequiredSenderType()`, `setCustomErrorMessage(...)` | ✅ **Oui** | | `CommandSyntaxErrorEvent` | Déclenché lors d'un argument manquant ou format incorrect. | `getErrorReason()`, `getUsage()`, `setCustomMessage(...)` | ✅ **Oui** | | `CommandCooldownEvent` | Déclenché lorsqu'un joueur tente d'exécuter une commande sous cooldown. | `getRemainingCooldown()`, `setCustomMessage(...)` | ✅ **Oui** | | `CommandConfirmationRequiredEvent` | Déclenché lorsqu'une commande requiert une confirmation préalable. | `getTimeout()`, `setCustomPromptMessage(...)` | ✅ **Oui** | | `CommandTabCompleteEvent` | Déclenché lors du calcul des suggestions d'auto-complétion. | `getSuggestions()`, `addSuggestion(...)`, `getCurrentInput()` | ✅ **Oui** | --- > 📖 **Étape suivante** : Découvrez la validation et la confirmation dans [05_VALIDATION_AND_CONFIRMATION.md](05_VALIDATION_AND_CONFIRMATION.md).