feat: typed team settings (cascade per-team → global → default) + in-game GUI
New fr.luc.crcore.team.config module: - TeamSetting<T> (typed, with key/type/default/parser/serializer; factories ofBoolean/ofInt/ofString/ofEnum). - TeamSettings registry: 8 standard settings (FRIENDLY_FIRE, PVP_PROTECTION_SECONDS, MAX_SIZE, MIN_SIZE, RESPAWN_AT_TEAM_SPAWN, TEAM_CHAT_ENABLED, SHOW_TAG_ABOVE_HEAD, TEAM_COLOR_IN_NAME), extensible via register() for game plugins. - TeamConfigService interface with cascade get(team, setting) → per-team override (SQLite) → global YAML → hard default. Persists per- team via TeamRepository.save(), global via YamlConfiguration.save(). - YamlTeamConfigService default impl with bundled crcore-team-config.yml. Storage: - Team.getSettings() Map<String, Object> for per-team overrides. - New SQLite table crcore_team_settings (team_id, key, value, type) with load + write-through persist in SqliteTeamRepository. - Global YAML <plugin>-team-config.yml in dataFolder, auto-created at first boot (template from game plugin's resource of the same name takes priority). New reusable GUI framework fr.luc.crcore.gui: - AbstractInventoryGui (implements InventoryHolder, rebuild() abstract, setButton/setDecoration/clearSlot helpers, onClose hook, openTo()). - GuiClickHandler FunctionalInterface. - GuiListener (single Bukkit listener, detects via getHolder(), ALWAYS cancels clicks even on slots without handlers). - GuiItems builder (named/of/filler + lore/amount/build, '&' color codes translated). Concrete settings GUIs (fr.luc.crcore.team.config.gui): - AbstractSettingsGui base renderer: 27 slots, settings in row 2, booleans = LIME_DYE / GRAY_DYE toggle, integers = BOOK with left +1 / right -1 (shift × 10), strings/enums display-only. - GlobalSettingsGui: writes to YAML on each change. - TeamSettingsGui: writes to per-team overrides, "override active" flag in lore when value differs from global, "Reset all overrides" footer button. New /core team settings [team] subcommand: - No arg → GlobalSettingsGui (perm crcore.team.settings.global). - With arg → TeamSettingsGui (perm crcore.team.settings). - Player-only (Bukkit needs HumanEntity to open inventory). - Lives under /core team to stay modular (objective: split into modules later; everything team-related under /core team). CRCore: buildTeamConfigService() override point, teamConfig()/getTeamConfig() getters, GuiListener.registerOn(plugin) at enable(). CoreCommand, TeamGroupSubCommand and CoreReloadSubCommand extended to receive TeamConfigService. /core reload now reloads messages + broadcasts + team-config. Docs: new section 10 "Paramètres d'équipe", new decisions logged, setup.md tree updated, two new diagrams (team-config + gui). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -367,6 +367,69 @@ 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 — Settings d'équipe : cascade per-team → global → default + GUI
|
||||
|
||||
- **Choix** : nouveau module `fr.luc.crcore.team.config` avec :
|
||||
- `TeamSetting<T>` typé (factories `ofBoolean`, `ofInt`, `ofString`,
|
||||
`ofEnum`) — chaque setting porte sa clé, son type, son default et sa
|
||||
sérialisation YAML/SQL.
|
||||
- `TeamSettings` registry des 8 settings standards
|
||||
(`FRIENDLY_FIRE`, `PVP_PROTECTION_SECONDS`, `MAX_SIZE`, `MIN_SIZE`,
|
||||
`RESPAWN_AT_TEAM_SPAWN`, `TEAM_CHAT_ENABLED`, `SHOW_TAG_ABOVE_HEAD`,
|
||||
`TEAM_COLOR_IN_NAME`), extensible via `TeamSettings.register(...)`
|
||||
pour les game plugins.
|
||||
- `TeamConfigService` (interface) + `YamlTeamConfigService` (impl).
|
||||
- **Cascade de résolution** : per-team → global → hard default. Garantie
|
||||
non-null grâce au default. La couche per-team est stockée dans
|
||||
{@code Team.getSettings()} (Map<String, Object>) persistée en SQLite ;
|
||||
la couche globale dans `<plugin>-team-config.yml` ; les defaults sont
|
||||
des constantes Java.
|
||||
- **Stockage per-team SQLite** : nouvelle table `crcore_team_settings`
|
||||
(team_id, key, value, type). Le type tag (bool/int/str) permet de
|
||||
reconstruire le type Java au load sans réflexion.
|
||||
- **Settings custom (game plugin)** : le game plugin peut faire
|
||||
`TeamSettings.register(MON_SETTING)` dans son onEnable() pour
|
||||
l'enregistrer ; il apparaîtra automatiquement dans les GUI globaux et
|
||||
per-team, et sera persisté comme les standards.
|
||||
- **Pas d'application automatique** : CR-Core ne fait que stocker /
|
||||
exposer les settings. C'est au game plugin d'écouter les events Bukkit
|
||||
pertinents (ex. `EntityDamageByEntityEvent`) et de consulter
|
||||
`config.get(team, FRIENDLY_FIRE)` pour appliquer la règle. CR-Core ne
|
||||
veut pas hardcoder des semantics gameplay.
|
||||
|
||||
## 2026-06-10 — Framework GUI réutilisable (`fr.luc.crcore.gui`)
|
||||
|
||||
- **Choix** : module GUI générique avec
|
||||
`AbstractInventoryGui implements InventoryHolder` (base abstraite),
|
||||
`GuiClickHandler` (FunctionalInterface), `GuiListener` (un seul
|
||||
Listener Bukkit pour TOUS les GUI CR-Core), `GuiItems` (builder fluide
|
||||
d'`ItemStack` avec codes couleur).
|
||||
- **Détection par holder** : `event.getInventory().getHolder() instanceof
|
||||
AbstractInventoryGui` — propre, sans titre/UUID custom, marche même
|
||||
après un translate.
|
||||
- **Click toujours annulé** : le `GuiListener` cancel TOUT clic dans un
|
||||
GUI CR-Core (avant invocation du handler) — l'utilisateur ne peut
|
||||
jamais déplacer un item du GUI, même sur un slot sans handler.
|
||||
- **Réutilisable** : c'est un framework, pas un GUI métier. Tout futur
|
||||
GUI (settings, kits, classements interactifs, etc.) hérite
|
||||
d'`AbstractInventoryGui`.
|
||||
|
||||
## 2026-06-10 — `/core team settings` (global = sans arg, per-team = avec arg)
|
||||
|
||||
- **Choix** : commande unique `/core team settings [team]` qui multiplexe :
|
||||
- Sans arg → ouvre `GlobalSettingsGui` (perm
|
||||
`crcore.team.settings.global`).
|
||||
- Avec arg `team` → ouvre `TeamSettingsGui` (perm `crcore.team.settings`).
|
||||
- **Pas `/core settings`** au top-level — l'objectif est de séparer
|
||||
plus tard en modules (team, score, kits, …). Tout ce qui touche les
|
||||
teams reste sous `/core team`.
|
||||
- **Player-only** : Bukkit a besoin d'un `HumanEntity` pour ouvrir un
|
||||
inventaire. Pas de fallback console.
|
||||
- **Mécaniques** : booléens → toggle, entiers → clic gauche +1/right -1
|
||||
(shift = ×10), strings/enums → édition différée au YAML (V1).
|
||||
- **GUI per-team** : un bouton "Reset tous les overrides" qui efface
|
||||
tous les per-team de l'équipe pour les faire retomber sur le global.
|
||||
|
||||
## 2026-06-10 — Système de broadcasts configurables + `/core reload`
|
||||
|
||||
- **Choix** : nouveau module `fr.luc.crcore.broadcast` avec
|
||||
|
||||
Reference in New Issue
Block a user