199 lines
7.5 KiB
Markdown
199 lines
7.5 KiB
Markdown
# ⚡ 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 la `CommandMap` du 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.
|
|
- **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).
|
|
- **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` :
|
|
|
|
```kotlin
|
|
dependencies {
|
|
implementation("fr.luc:betterMcCommands:1.0.0-SNAPSHOT")
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🚀 Guide de Démarrage Rapide
|
|
|
|
### 1. Initialisation dans votre Plugin
|
|
|
|
```java
|
|
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
|
|
|
|
```java
|
|
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` :
|
|
|
|
```java
|
|
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)
|
|
```
|