feat: configurable broadcasts + /core reload

New fr.luc.crcore.broadcast module:
- BroadcastAudience enum (NONE, LEADER, TEAM, ADMIN, ALL).
- BroadcastContext (fluent: team + involvedPlayerId + placeholders).
- BroadcastService interface + YamlBroadcastService impl.
- CRCoreBroadcastListener (Bukkit listener) wires the 12 native events
  (9 team + 3 player) to broadcasts.broadcast(eventKey, ctx).

Same single-per-plugin file pattern as messages:
<plugin-dataFolder>/<plugin-name-lowercase>-broadcasts.yml. Defaults
bundled at resources/crcore-broadcasts.yml, copied on first boot (game
plugin's own resource of the same name takes priority as the template).
In-memory fallback so new CR-Core keys work without admin edit.

Routes (who) vs templates (what) are separated: broadcasts.yml lists
audiences per eventKey, messages.yml contains the templates under keys
<eventKey>.broadcast. Admin can change either independently.

12 new *.broadcast keys added to crcore-messages.yml with sensible
French defaults and color codes. Listener injects standard placeholders
(name, team_name, tag, color, visibility, player, new_leader,
old/new_value, etc.).

ADMIN audience resolved via crcore.broadcast.admin permission. Multi-
audiences via YAML list (e.g., [TEAM, ADMIN]); union of resolved
players, no duplicate.

New /core reload subcommand (permission crcore.reload) hot-reloads
both messages and broadcasts from disk without restart.

CRCore: protected buildBroadcastService() override point, getter
broadcasts(), wire of CRCoreBroadcastListener at enable(). CoreCommand
constructor extended to take BroadcastService, registers the reload
subcommand.

Docs/features.md: new section 9 "Service de broadcasts". docs/setup.md:
updated to mention both YAML files. decisions.md logs the routes-vs-
templates split, the audience model, and the reload semantics.
New diagram broadcasts-class-diagram.puml. README updated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Antone Barbaud
2026-06-10 11:16:34 +02:00
parent 923f48ffc7
commit a94bc56a5b
15 changed files with 1060 additions and 22 deletions
+36
View File
@@ -367,6 +367,42 @@ 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-10 — Système de broadcasts configurables + `/core reload`
- **Choix** : nouveau module `fr.luc.crcore.broadcast` avec
`BroadcastService` + `BroadcastAudience` enum + `BroadcastContext` data
class + `YamlBroadcastService` impl. Un listener Bukkit interne
(`CRCoreBroadcastListener`) écoute les 12 events CR-Core et les traduit
en appels `broadcast(eventKey, ctx)`.
- **Modèle « un seul fichier par plugin »** identique à messages :
`<plugin-dataFolder>/<plugin-name-lowercase>-broadcasts.yml`. Defaults
bundlés dans le jar à `crcore-broadcasts.yml`, copiés au premier boot
(avec priorité au template du plugin de jeu sous le même nom s'il en
fournit un).
- **Séparation routes / templates** :
- **Routes** = qui reçoit quoi = `<plugin>-broadcasts.yml` (liste
d'audiences par event)
- **Templates** = quel texte = `<plugin>-messages.yml` (clés
`<eventKey>.broadcast`)
- L'admin peut modifier l'un sans toucher à l'autre. Modulaire.
- **5 audiences** : `NONE`, `LEADER`, `TEAM`, `ADMIN`, `ALL`.
Multi-cibles via liste, union sans doublon.
- **Permission ADMIN** : `crcore.broadcast.admin` (granular,
configurable côté LuckPerms).
- **Listener Bukkit interne** : `CRCoreBroadcastListener` est instancié
et enregistré dans `CRCore.enable()`. Les game plugins n'ont rien à
faire pour bénéficier du broadcast des events natifs CR-Core ; pour
leurs propres events, ils appellent `core.broadcasts().broadcast(...)`.
- **Pas de cancellation** : le broadcast est post-event ; si une route
est mal configurée, on ne casse pas la logique métier — au pire un
message non envoyé ou envoyé trop large.
- **Nouvelle commande `/core reload`** : permission `crcore.reload`,
recharge `messages` + `broadcasts` depuis les fichiers user. Les
defaults en jar restent fixes. Hot reload utile en dev / pour ajuster
les routes sans restart.
- **Override de l'impl** : `CRCore.buildBroadcastService(messages)` est
`protected` — comme pour les autres services.
## 2026-06-09 — Réorganisation packages : `impl/` et `exception/` séparés
- **Choix** : pour chaque domaine (`team`, `player`, `message`), les