7.5 KiB
7.5 KiB
⚡ betterMcCommands
Une bibliothèque Java moderne, fluide et événementielle pour créer et gérer des commandes Minecraft de façon hautement dynamique sans aucune configuration dans plugin.yml.
🌟 Fonctionnalités Clés
- DSL Fluide & Déclaratif : Création chainable de commandes racines et sous-commandes imbriquées avec
BetterMcCommands.builder("ma-commande"). - Zéro
plugin.yml: Injection et dé-enregistrement à chaud à l'exécution dans laCommandMapdu serveur. - Arguments Typés & Auto-complétion :
- Types primitifs :
string,word,greedyString,integer,decimal,bool,enumOf. - Types Minecraft :
player,offlinePlayer,world,location,duration. - Arguments optionnels, valeurs par défaut et suggestions (Tab-Complete) dynamiques.
- Types primitifs :
- Moteur d'Événements & Lifecycle :
- Hooks par commande (
.onPreExecute(),.onPostExecute(),.onPermissionDenied(),.onSyntaxError(),.onCooldown(),.onTabComplete()). - Bus d'événements global supportant les lambdas ou les classes d'écoute avec
@CommandEventHandler. - Événements annulables (
PreExecuteEvent) pour vérifier des conditions de jeu (cooldowns, état de combat, économie).
- Hooks par commande (
- Temps de recharge (Cooldowns) natifs : Configuration directe avec permission de bypass optionnelle.
- Formatage Moderne : Support direct des composants Kyori Adventure et des balises MiniMessage (
<gradient>,<green>, etc.).
📦 Installation & Configuration Gradle
Ajoutez la dépendance dans votre build.gradle.kts :
dependencies {
implementation("fr.luc:betterMcCommands:1.0.0-SNAPSHOT")
}
🚀 Guide de Démarrage Rapide
1. Initialisation dans votre Plugin
public class MyPlugin extends JavaPlugin {
private BetterMcCommands commandsManager;
@Override
public void onEnable() {
// Initialisation du gestionnaire pour ce plugin
this.commandsManager = BetterMcCommands.create(this);
// Enregistrement de vos classes d'écouteurs d'événements
this.commandsManager.registerListeners(new MyCommandEventsListener());
// Enregistrement d'une commande
DemoBaseCommand.create().register();
}
@Override
public void onDisable() {
// Désenregistrement à chaud et nettoyage propre
if (commandsManager != null) {
commandsManager.unregisterAll();
}
}
}
💡 Exemples de Commandes
Déclaration d'une commande racine avec sous-commandes et arguments typés
BetterMcCommands.builder("commande-demo")
.description("Commande de démonstration")
.aliases("demo", "cdemo")
.permission("bettermc.demo")
// Événement exécuté avant la commande (annulable)
.onPreExecute(event -> {
if (event.isPlayer() && isInCombat(event.getPlayer())) {
event.setCancelled(true);
event.reply("<red>Impossible d'exécuter cette commande en combat !</red>");
}
})
// Exécution de la commande racine : /commande-demo
.executes(context -> {
context.reply("<gradient:#00d2ff:#3a7bd5><bold>=== Démo betterMcCommands ===</bold></gradient>");
context.reply("<gray>Utilisez <yellow>/demo give</yellow> pour donner des ressources.</gray>");
})
// Sous-commande : /demo give <cible> [quantite]
.subcommand(BetterMcCommands.subBuilder("give")
.description("Donne des ressources à un joueur")
.permission("bettermc.demo.give")
.argument(Arguments.player("cible").description("Joueur recevant les items"))
.argument(Arguments.integer("quantite", 1, 64).defaultValue(1))
.executes(context -> {
Player target = context.getTargetPlayer("cible");
int quantite = context.getInt("quantite");
context.replySuccess("Attribution de <gold>" + quantite + "</gold> items à <aqua>" + target.getName() + "</aqua> !");
})
)
// Sous-commande avec argument gourmand (greedy) : /demo broadcast <message...>
.subcommand(BetterMcCommands.subBuilder("broadcast")
.description("Diffuse une annonce")
.argument(Arguments.greedyString("message"))
.executes(context -> {
String msg = context.getString("message");
context.replySuccess("Diffusion : <yellow>" + msg + "</yellow>");
})
)
// Sous-commande avec Cooldown : /demo kit (recharge de 60 secondes)
.subcommand(BetterMcCommands.subBuilder("kit")
.cooldown(Duration.ofSeconds(60))
.cooldownBypass("bettermc.bypass.kit")
.playerOnly()
.executes(context -> {
context.replySuccess("Kit reçu !");
})
)
.register();
🎯 Système d'Événements & Lifecycle
Vous pouvez intercepter les événements du cycle de vie des commandes soit directement sur le builder (.onPreExecute(...), .onPostExecute(...)), soit dans une classe dédiée avec @CommandEventHandler :
public class MyCommandEventsListener {
@CommandEventHandler(priority = 10)
public void onPreExecute(CommandPreExecuteEvent event) {
System.out.println("Commande demandée : /" + event.getNode().getFullName() + " par " + event.getSender().getName());
}
@CommandEventHandler(command = "commande-demo")
public void onDemoPostExecute(CommandPostExecuteEvent event) {
System.out.println("Commande exécutée en " + event.getExecutionDuration().toMillis() + "ms.");
}
@CommandEventHandler
public void onPermissionDenied(CommandPermissionDeniedEvent event) {
event.setCustomErrorMessage("<dark_red>Accès refusé ! Permission requise : " + event.getRequiredPermission() + "</dark_red>");
}
@CommandEventHandler
public void onCooldown(CommandCooldownEvent event) {
event.setCustomMessage("<red>⏳ Patientez <gold>" + event.getRemainingCooldown().toSeconds() + "s</gold> avant de réutiliser cette commande.</red>");
}
}
📂 Architecture des Packages
fr.luc.bettermccommands/
├── BetterMcCommands.java (Manager principal & Façade)
├── api/ (Interfaces et modèles publics)
│ ├── Command.java
│ ├── CommandNode.java
│ ├── CommandContext.java
│ ├── CommandExecutor.java
│ ├── CommandSenderType.java
│ ├── CommandResult.java
│ └── suggestion/
├── builder/ (Fluent DSL Builder)
│ ├── AbstractCommandBuilder.java
│ ├── CommandBuilder.java
│ └── SubCommandBuilder.java
├── argument/ (Arguments typés & Auto-complétion)
│ ├── CommandArgument.java
│ ├── ArgumentType.java
│ ├── Arguments.java
│ └── type/
├── event/ (Bus d'événements & Lifecycle)
│ ├── CommandEvent.java
│ ├── CancellableCommandEvent.java
│ ├── CommandPreExecuteEvent.java
│ ├── CommandPostExecuteEvent.java
│ ├── CommandPermissionDeniedEvent.java
│ ├── CommandSyntaxErrorEvent.java
│ ├── CommandCooldownEvent.java
│ ├── CommandTabCompleteEvent.java
│ └── annotation/
├── cooldown/ (Gestion des cooldowns par joueur)
├── platform/ (Injection runtime CommandMap Paper/Spigot)
└── demo/ (Plugin de démonstration et exemples)