diff --git a/docs/decisions.md b/docs/decisions.md index 387ecef..ffefcfb 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -367,6 +367,52 @@ Format léger : une décision = un titre + contexte + choix + raison. bases existantes, ALTER TABLE manuel ou suppression du fichier (les bases d'event sont jetables). +## 2026-06-09 — Toutes les commandes "chef" deviennent admin (révision) + +- **Révision** de la décision "Refonte permissions + modèle admin/chef/joueur" + prise plus tôt aujourd'hui. +- **Choix** : le rôle chef n'apporte plus aucun privilège de commande pour + l'instant. Toutes les opérations de gestion d'équipe (`add`, `remove`, + `transfer`, `visibility`, `setspawn`) deviennent **admin** : + - Signature avec `` en argument (au lieu d'implicite "ma team"). + - Permission `crcore.team.` requise. + - Plus de check `isLeader(...)` dans `execute()`. +- **Raison** : le user a explicitement décidé que pour l'instant le chef + n'a pas plus de privilèges qu'un joueur lambda côté commandes. Le rôle + `LEADER` reste dans le modèle de données (utile pour les game plugins qui + pourraient l'exploiter via l'API, ou pour de futures commandes), mais il + ne gate plus rien au niveau du framework de commandes. +- **Conséquences** : + - `TeamRemoveSubCommand` : refuse de retirer le chef (l'admin doit + `setleader` d'abord). Pas un check chef, juste une garde de cohérence. + - `TeamTransferSubCommand` : devient l'équivalent admin "strict" de + `setleader` (membre existant uniquement). Les deux cohabitent ; doc dit + quand préférer l'un ou l'autre. + - `TeamSetSpawnSubCommand` : reste `playerOnly` car nécessite la + `Location` de l'exécutant — mais c'est désormais l'admin qui se place + à l'endroit voulu et tape `/core team setspawn `. + +## 2026-06-09 — Intégration PlaceholderAPI (optionnelle, auto-détectée) + +- **Choix** : `CRCore.enable()` détecte la présence du plugin PlaceholderAPI + via `pluginManager.getPlugin("PlaceholderAPI")` et enregistre + automatiquement `CRCorePlaceholderExpansion` si présent. Aucune action + requise côté plugin de jeu. +- **Dépendance Maven** : `me.clip:placeholderapi:2.11.6` en scope + `provided` (depuis `https://repo.extendedclip.com/...`). Le jar PAPI + n'est PAS embarqué — c'est un plugin runtime indépendant. +- **Indirection de chargement** : la méthode privée + `doRegisterPlaceholderHook()` isole la référence à + `CRCorePlaceholderExpansion`. Si PAPI est absent, la méthode n'est jamais + appelée et le bytecode référençant `me.clip.placeholderapi.*` n'est pas + vérifié → pas de `NoClassDefFoundError`. +- **Placeholders exposés** : + - Team : `%crcore_team%`, `%crcore_team_name/tag/color/color_chat/size/` + `visibility/leader_name/total_score%`, `%crcore_team_score_%` + - Player : `%crcore_player_score_%`, `%crcore_player_score_total%` +- **Override** : `CRCore.registerPlaceholderHook()` est `protected` — une + sous-classe peut ajouter des placeholders ou skipper la hook. + ## 2026-06-09 — Nouvelle commande `/core team setleader` - **Choix** : ajout de `TeamSetLeaderSubCommand` (`/core team setleader diff --git a/docs/diagrams/builtin-commands-diagram.puml b/docs/diagrams/builtin-commands-diagram.puml index 249dacc..4d83dec 100644 --- a/docs/diagrams/builtin-commands-diagram.puml +++ b/docs/diagrams/builtin-commands-diagram.puml @@ -1,5 +1,5 @@ @startuml builtin-commands-diagram -title CR-Core — Default /core team commands (admin / chef / joueur) +title CR-Core — Default /core team commands (admin / joueur) skinparam classAttributeIconSize 0 hide empty members @@ -11,16 +11,13 @@ package "fr.luc.crcore.command" { package "fr.luc.crcore.command.builtin" { - class CoreCommand { - + CoreCommand(teamSvc, playerSvc) - } + class CoreCommand CoreCommand --|> BaseCommand package "fr.luc.crcore.command.builtin.team" { class TeamGroupSubCommand { + TeamGroupSubCommand(service) - # registerDefaults(): void } TeamGroupSubCommand --|> SubCommand @@ -28,7 +25,7 @@ package "fr.luc.crcore.command.builtin" { + {static} teamByName(service): ArgumentType } - ' === ADMIN commands (permission seule) === + ' ─── ADMIN commands (permission seule, team par argument) ─── package "admin" <> { class TeamCreateSubCommand { perm: crcore.team.create @@ -46,32 +43,30 @@ package "fr.luc.crcore.command.builtin" { perm: crcore.team.score args: } - } - - ' === CHEF commands (permission + check chef) === - package "chef" <> { class TeamAddSubCommand { perm: crcore.team.add - args: + args: } class TeamRemoveSubCommand { perm: crcore.team.remove - args: + args: } class TeamTransferSubCommand { perm: crcore.team.transfer - args: + args: } class TeamVisibilitySubCommand { perm: crcore.team.visibility - args: + args: } class TeamSetSpawnSubCommand { perm: crcore.team.setspawn + args: + playerOnly } } - ' === PLAYER commands === + ' ─── PLAYER commands ─── package "player" <> { class TeamJoinSubCommand { perm: crcore.team.join @@ -114,6 +109,11 @@ package "fr.luc.crcore.command.builtin" { } note bottom of TeamGroupSubCommand + Le rôle LEADER reste dans le modèle Team + (utilisable par les game plugins via l'API) + mais n'accorde aucun privilège de commande + dans le set par défaut. + Override d'une feuille : core.getCoreCommand() .findSubCommand("team") diff --git a/docs/features.md b/docs/features.md index 8512cee..d835d8a 100644 --- a/docs/features.md +++ b/docs/features.md @@ -335,8 +335,14 @@ Voir [setup.md](setup.md#utilisation-depuis-un-plugin-de-jeu). sous-classe ou via `replaceSubCommand`. **Pas d'aliases courts** : les commandes ont leur nom long uniquement -(`/core team create` et pas `/core team c`). Les aliases ont été retirés -pour réduire la friction de découverte et la confusion. +(`/core team create` et pas `/core team c`). + +**Modèle simplifié à 2 rôles** : toutes les opérations de gestion d'équipe +sont **admin** (perm requise + team passée en argument). Les opérations +joueur (`join`, `leave`, `info`, `list`, `top`) sont gated par permission +mais ne nécessitent pas le rôle chef. Le rôle `LEADER` reste présent dans +le modèle de données (utilisable par les game plugins via l'API) mais +n'accorde aucun privilège de commande pour l'instant. ### Arborescence @@ -347,12 +353,12 @@ pour réduire la friction de découverte et la confusion. ├── delete [admin] dissoudre une équipe ├── setleader [admin] (re)assigner le chef ├── score [admin] modifier un score - ├── add [chef] ajouter à son équipe - ├── remove [chef] retirer de son équipe - ├── transfer [chef] transférer leadership - ├── visibility [chef] changer visibilité - ├── setspawn [chef] définir le spawn - ├── join [joueur] rejoindre PUBLIC + ├── add [admin] ajouter un joueur + ├── remove [admin] retirer un joueur + ├── transfer [admin] transfert chef→membre existant + ├── visibility [admin] changer visibilité + ├── setspawn [admin] spawn à la position de l'admin + ├── join [joueur] rejoindre une PUBLIC ├── leave [joueur] quitter son équipe ├── info [team] [joueur] infos ├── list [joueur] toutes les équipes @@ -361,13 +367,12 @@ pour réduire la friction de découverte et la confusion. ### Permissions -Chaque sous-commande a une permission `crcore.team.`. Modèle à 3 niveaux : +Chaque sous-commande a une permission `crcore.team.` : -| Niveau | Commandes | Comportement | -|---|---|---| -| **Admin** | `create`, `delete`, `setleader`, `score` | Permission seule (pas de check chef). Cible une team via argument. | -| **Chef** | `add`, `remove`, `transfer`, `visibility`, `setspawn` | Permission **ET** check chef de sa propre équipe en plus. Cible la team de l'exécutant. | -| **Joueur** | `join`, `leave`, `info`, `list`, `top` | Permission seule (à granter par défaut côté LuckPerms si on veut que tout le monde y ait accès). | +| Niveau | Commandes | +|---|---| +| **Admin** | `create`, `delete`, `setleader`, `score`, `add`, `remove`, `transfer`, `visibility`, `setspawn` | +| **Joueur** | `join`, `leave`, `info`, `list`, `top` | | Sous-commande | Permission | |---|---| @@ -512,7 +517,60 @@ db.table("my_kills") --- -## 7. Bootstrap `CRCore` +## 7. Intégration PlaceholderAPI (optionnelle) + +**Statut** : implémentée. Auto-détectée par `CRCore.enable()` — si le plugin +**PlaceholderAPI** est installé sur le serveur, les placeholders `%crcore_*%` +sont enregistrés automatiquement. Si PAPI est absent, la lib reste +fonctionnelle, juste sans placeholders. + +### Placeholders Team + +Renvoient vides si le joueur n'est dans aucune équipe. + +| Placeholder | Renvoie | Exemple | +|---|---|---| +| `%crcore_team%` | récap formaté coloré | `§c[#WOLF] Wolves` | +| `%crcore_team_name%` | nom de l'équipe | `Wolves` | +| `%crcore_team_tag%` | tag court | `WOLF` | +| `%crcore_team_color%` | nom de la couleur | `Red` | +| `%crcore_team_color_chat%` | code couleur ChatColor | `§c` | +| `%crcore_team_size%` | nombre de membres | `5` | +| `%crcore_team_visibility%` | `PUBLIC` ou `PRIVATE` | `PRIVATE` | +| `%crcore_team_leader_name%` | nom du chef (vide si leaderless) | `Alice` | +| `%crcore_team_total_score%` | somme des scores de l'équipe | `42` | +| `%crcore_team_score_%` | score nommé de l'équipe | `%crcore_team_score_kills%` → `12` | + +### Placeholders Player + +| Placeholder | Renvoie | +|---|---| +| `%crcore_player_score_%` | score nommé du joueur (0 si pas set) | +| `%crcore_player_score_total%` | somme de tous les scores du joueur | + +### Usage côté plugin de jeu / config + +Pas d'action à faire côté plugin de jeu — la hook s'enregistre toute seule. +Les placeholders sont disponibles partout où PAPI les résout (scoreboard, +tablist, chat, hologrammes via DecentHolograms, etc.) : + +```yaml +# Exemple de scoreboard config (FeatherBoard / Scoreboard plugin) +lines: + - "&aÉquipe : %crcore_team%" + - "&aChef : %crcore_team_leader_name%" + - "&aKills : %crcore_player_score_kills% (total équipe %crcore_team_score_kills%)" +``` + +### Override + +`CRCore.registerPlaceholderHook()` est `protected`. Override dans une +sous-classe de `CRCore` pour ajouter ses propres placeholders ou désactiver +la hook. + +--- + +## 8. Bootstrap `CRCore` **Statut** : implémenté. Point d'entrée unique pour les plugins de jeu. diff --git a/docs/setup.md b/docs/setup.md index ef2a023..6692898 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -5,6 +5,7 @@ - **Type** : librairie Java (`jar`) — pas un plugin Bukkit - **artifactId Maven** : `CR-Core` - **Build** : Maven, Java 11 +- **Intégrations optionnelles** : PlaceholderAPI (auto-détectée si installée) - **API serveur (provided)** : Paper 1.16.5 - **SQLite (compile)** : `org.xerial:sqlite-jdbc:3.45.3.0` - **Package racine** : `fr.luc.crcore` diff --git a/pom.xml b/pom.xml index 81b9cb5..8d3c336 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,10 @@ sonatype https://oss.sonatype.org/content/groups/public/ + + placeholderapi + https://repo.extendedclip.com/content/repositories/placeholderapi/ + @@ -58,6 +62,18 @@ ${sqlite.version} compile + + + me.clip + placeholderapi + 2.11.6 + provided +