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:
@@ -36,6 +36,14 @@ d'initialisation côté plugin de jeu :
|
||||
templates. Un listener interne wire les 12 events natifs ; les game
|
||||
plugins peuvent broadcast leurs propres events. `/core reload` recharge
|
||||
les deux fichiers à chaud.
|
||||
- **Paramètres d'équipe** — `TeamConfigService` typé avec cascade
|
||||
per-team → global → default. 8 settings standards
|
||||
(`FRIENDLY_FIRE`, `MAX_SIZE`, etc.), étendable. Globaux dans
|
||||
`<plugin>-team-config.yml`, per-team en SQLite. GUI in-game via
|
||||
`/core team settings [team]`.
|
||||
- **Framework GUI** — `AbstractInventoryGui` + `GuiListener` réutilisable
|
||||
pour tout GUI custom. Détection par holder, clic toujours annulé,
|
||||
`GuiItems` builder fluide avec codes couleur `&`.
|
||||
- **Bootstrap unique** — `new CRCore(this).enable()` dans le `onEnable()`
|
||||
du plugin de jeu, et tout est branché.
|
||||
|
||||
@@ -62,6 +70,8 @@ d'initialisation côté plugin de jeu :
|
||||
| [database-diagram.puml](diagrams/database-diagram.puml) | Classe | Wrapper SQLite + table builder |
|
||||
| [messages-class-diagram.puml](diagrams/messages-class-diagram.puml) | Classe | Service de messages YAML |
|
||||
| [broadcasts-class-diagram.puml](diagrams/broadcasts-class-diagram.puml) | Classe | Service de broadcasts YAML + listener |
|
||||
| [team-config-class-diagram.puml](diagrams/team-config-class-diagram.puml) | Classe | Paramètres d'équipe (cascade + GUI) |
|
||||
| [gui-class-diagram.puml](diagrams/gui-class-diagram.puml) | Classe | Framework GUI réutilisable |
|
||||
| [bootstrap-sequence.puml](diagrams/bootstrap-sequence.puml) | Séquence | `CRCore.enable()` côté plugin de jeu |
|
||||
|
||||
## Conventions
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
@startuml gui-class-diagram
|
||||
title CR-Core — GUI framework (class diagram, réutilisable)
|
||||
|
||||
skinparam classAttributeIconSize 0
|
||||
hide empty members
|
||||
|
||||
package "fr.luc.crcore.gui" {
|
||||
|
||||
abstract class AbstractInventoryGui {
|
||||
- inventory: Inventory
|
||||
- handlers: Map<Integer, GuiClickHandler>
|
||||
--
|
||||
# setInventory(Inventory): void
|
||||
+ getInventory(): Inventory
|
||||
+ {abstract} rebuild(): void
|
||||
+ onClose(HumanEntity): void
|
||||
+ openTo(HumanEntity): void
|
||||
# setButton(slot, item, handler): void
|
||||
# setDecoration(slot, item): void
|
||||
# clearSlot(slot): void
|
||||
+ handleClick(event): void ' appelé par GuiListener
|
||||
+ handleClose(event): void
|
||||
}
|
||||
AbstractInventoryGui ..|> "org.bukkit.inventory.InventoryHolder"
|
||||
|
||||
interface GuiClickHandler <<FunctionalInterface>> {
|
||||
+ onClick(InventoryClickEvent): void
|
||||
}
|
||||
|
||||
class GuiListener {
|
||||
+ registerOn(JavaPlugin): void
|
||||
--
|
||||
@ onClick(InventoryClickEvent)
|
||||
@ onClose(InventoryCloseEvent)
|
||||
}
|
||||
GuiListener ..|> "org.bukkit.event.Listener"
|
||||
|
||||
class GuiItems <<utility>> {
|
||||
+ {static} named(material, name): Builder
|
||||
+ {static} of(material): Builder
|
||||
+ {static} filler(): ItemStack
|
||||
+ {static} item(builder): ItemStack
|
||||
}
|
||||
|
||||
class "GuiItems.Builder" as Builder {
|
||||
- stack: ItemStack
|
||||
- meta: ItemMeta
|
||||
+ name(text): Builder
|
||||
+ lore(lines...): Builder
|
||||
+ lore(List<String>): Builder
|
||||
+ amount(int): Builder
|
||||
+ build(): ItemStack
|
||||
+ asItem(): ItemStack
|
||||
}
|
||||
GuiItems +-- Builder
|
||||
|
||||
GuiListener ..> AbstractInventoryGui : dispatches via getHolder()
|
||||
AbstractInventoryGui --> GuiClickHandler : per-slot
|
||||
}
|
||||
|
||||
note right of GuiListener
|
||||
Détection par holder :
|
||||
if (e.getInventory().getHolder()
|
||||
instanceof AbstractInventoryGui gui) {
|
||||
e.setCancelled(true); // ← TOUJOURS, même slot vide
|
||||
gui.handleClick(e);
|
||||
}
|
||||
|
||||
Enregistré une fois dans CRCore.enable().
|
||||
end note
|
||||
|
||||
note right of AbstractInventoryGui
|
||||
Pattern :
|
||||
1. extends AbstractInventoryGui
|
||||
2. constructeur :
|
||||
Inventory inv = Bukkit.createInventory(this, 27, "&eTitre");
|
||||
setInventory(inv);
|
||||
3. override rebuild() pour peindre
|
||||
4. setButton(slot, GuiItems.named(...).build(), handler)
|
||||
end note
|
||||
|
||||
@enduml
|
||||
@@ -0,0 +1,119 @@
|
||||
@startuml team-config-class-diagram
|
||||
title CR-Core — Team config (class diagram, cascade per-team → global → default)
|
||||
|
||||
skinparam classAttributeIconSize 0
|
||||
hide empty members
|
||||
|
||||
package "fr.luc.crcore.team.config" {
|
||||
|
||||
class "TeamSetting<T>" as TeamSetting <<final>> {
|
||||
- key: String
|
||||
- type: Class<T>
|
||||
- defaultValue: T
|
||||
- kind: Kind
|
||||
- parser: Function<Object,T>
|
||||
- serializer: Function<T,Object>
|
||||
--
|
||||
+ {static} ofBoolean(key, default): TeamSetting<Boolean>
|
||||
+ {static} ofInt(key, default): TeamSetting<Integer>
|
||||
+ {static} ofString(key, default): TeamSetting<String>
|
||||
+ {static} ofEnum(key, default): TeamSetting<E>
|
||||
--
|
||||
+ parse(raw): T
|
||||
+ serialize(value): Object
|
||||
+ getKey() / getType() / getDefaultValue() / getKind()
|
||||
}
|
||||
|
||||
enum "TeamSetting.Kind" as Kind {
|
||||
BOOLEAN
|
||||
INTEGER
|
||||
STRING
|
||||
ENUM
|
||||
}
|
||||
TeamSetting +-- Kind
|
||||
|
||||
class TeamSettings <<utility>> {
|
||||
+ {static} FRIENDLY_FIRE: TeamSetting<Boolean>
|
||||
+ {static} PVP_PROTECTION_SECONDS: TeamSetting<Integer>
|
||||
+ {static} MAX_SIZE: TeamSetting<Integer>
|
||||
+ {static} MIN_SIZE: TeamSetting<Integer>
|
||||
+ {static} RESPAWN_AT_TEAM_SPAWN: TeamSetting<Boolean>
|
||||
+ {static} TEAM_CHAT_ENABLED: TeamSetting<Boolean>
|
||||
+ {static} SHOW_TAG_ABOVE_HEAD: TeamSetting<Boolean>
|
||||
+ {static} TEAM_COLOR_IN_NAME: TeamSetting<Boolean>
|
||||
--
|
||||
+ {static} register(setting): void
|
||||
+ {static} get(key): Optional<TeamSetting<?>>
|
||||
+ {static} all(): Collection<TeamSetting<?>>
|
||||
}
|
||||
TeamSettings ..> TeamSetting
|
||||
|
||||
interface TeamConfigService {
|
||||
+ get(team, setting): T
|
||||
+ getGlobal(setting): T
|
||||
+ setPerTeam(team, setting, value): void
|
||||
+ resetPerTeam(team, setting): void
|
||||
+ setGlobal(setting, value): void
|
||||
+ reload(): void
|
||||
+ hasPerTeamOverride(team, setting): boolean
|
||||
+ getGlobalSnapshot(): Map<TeamSetting<?>, Object>
|
||||
+ getGlobalFileName(): Optional<String>
|
||||
}
|
||||
|
||||
package "fr.luc.crcore.team.config.impl" {
|
||||
class YamlTeamConfigService {
|
||||
- plugin: JavaPlugin
|
||||
- teamRepository: TeamRepository
|
||||
- userFile: File
|
||||
- globalValues: Map<String, Object>
|
||||
--
|
||||
- ensureUserFile(): void
|
||||
- rebuildGlobalValues(): void
|
||||
- persistGlobals(): void
|
||||
}
|
||||
YamlTeamConfigService ..|> TeamConfigService
|
||||
}
|
||||
|
||||
TeamConfigService ..> TeamSetting : reads/writes
|
||||
}
|
||||
|
||||
package "fr.luc.crcore.team" {
|
||||
class Team {
|
||||
- settings: Map<String, Object>
|
||||
+ getSettings(): Map<String, Object>
|
||||
}
|
||||
}
|
||||
|
||||
package "fr.luc.crcore.team.config.gui" {
|
||||
abstract class AbstractSettingsGui {
|
||||
- rebuild() : peint la grille
|
||||
# {abstract} getCurrentValue(setting): T
|
||||
# {abstract} onChange(setting, newValue): void
|
||||
# isOverride(setting): boolean
|
||||
# renderFooter(): void
|
||||
}
|
||||
class GlobalSettingsGui
|
||||
class TeamSettingsGui
|
||||
GlobalSettingsGui --|> AbstractSettingsGui
|
||||
TeamSettingsGui --|> AbstractSettingsGui
|
||||
AbstractSettingsGui --|> "fr.luc.crcore.gui.AbstractInventoryGui"
|
||||
|
||||
GlobalSettingsGui --> TeamConfigService
|
||||
TeamSettingsGui --> TeamConfigService
|
||||
TeamSettingsGui --> Team
|
||||
}
|
||||
|
||||
YamlTeamConfigService --> "fr.luc.crcore.team.TeamRepository" : persists per-team via save()
|
||||
TeamConfigService ..> Team : reads/writes settings map
|
||||
|
||||
note bottom of YamlTeamConfigService
|
||||
Cascade de résolution :
|
||||
1. team.getSettings().get(key) ← override per-team (SQLite)
|
||||
2. globalValues.get(key) ← <plugin>-team-config.yml
|
||||
3. setting.getDefaultValue() ← constante Java
|
||||
|
||||
Le YAML global est ré-écrit à chaque setGlobal() (persistant à crash).
|
||||
Les per-team sont écrits via teamRepository.save(team).
|
||||
end note
|
||||
|
||||
@enduml
|
||||
+114
-1
@@ -807,7 +807,120 @@ depuis les fichiers user du dataFolder. Les defaults en jar ne bougent pas
|
||||
|
||||
---
|
||||
|
||||
## 10. Bootstrap `CRCore`
|
||||
## 10. Paramètres d'équipe (`fr.luc.crcore.team.config`)
|
||||
|
||||
**Statut** : implémenté. 8 settings standards + GUI in-game + cascade
|
||||
per-team → global → default.
|
||||
|
||||
### Modèle de résolution
|
||||
|
||||
```
|
||||
1. hard default défini en code dans TeamSettings (constantes)
|
||||
2. global config <plugin>-team-config.yml ← admin via GUI ou YAML
|
||||
3. per-team override table SQLite crcore_team_settings ← admin via GUI
|
||||
```
|
||||
|
||||
`config.get(team, setting)` cascade per-team → global → default.
|
||||
`config.getGlobal(setting)` cascade global → default (skip per-team).
|
||||
Toutes les valeurs retournées sont **non-null** grâce au default en bout
|
||||
de chaîne.
|
||||
|
||||
### Settings standards (`TeamSettings`)
|
||||
|
||||
| Constante | Clé YAML/SQL | Type | Défaut |
|
||||
|---|---|---|---|
|
||||
| `FRIENDLY_FIRE` | `friendly_fire` | bool | `false` |
|
||||
| `PVP_PROTECTION_SECONDS` | `pvp_protection_seconds` | int | `0` |
|
||||
| `MAX_SIZE` | `max_size` | int | `0` (illimité) |
|
||||
| `MIN_SIZE` | `min_size` | int | `0` |
|
||||
| `RESPAWN_AT_TEAM_SPAWN` | `respawn_at_team_spawn` | bool | `true` |
|
||||
| `TEAM_CHAT_ENABLED` | `team_chat_enabled` | bool | `true` |
|
||||
| `SHOW_TAG_ABOVE_HEAD` | `show_tag_above_head` | bool | `true` |
|
||||
| `TEAM_COLOR_IN_NAME` | `team_color_in_name` | bool | `true` |
|
||||
|
||||
CR-Core fournit les défauts ; **c'est au plugin de jeu d'appliquer ces
|
||||
settings** dans sa logique (ex. écouter `EntityDamageByEntityEvent` et
|
||||
checker `config.get(team, FRIENDLY_FIRE)` pour décider si le coup passe).
|
||||
|
||||
### API typée
|
||||
|
||||
```java
|
||||
boolean ff = core.teamConfig().get(team, TeamSettings.FRIENDLY_FIRE);
|
||||
int max = core.teamConfig().getGlobal(TeamSettings.MAX_SIZE);
|
||||
core.teamConfig().setPerTeam(team, TeamSettings.FRIENDLY_FIRE, true);
|
||||
core.teamConfig().resetPerTeam(team, TeamSettings.FRIENDLY_FIRE);
|
||||
core.teamConfig().setGlobal(TeamSettings.MAX_SIZE, 8); // persiste le YAML
|
||||
core.teamConfig().reload();
|
||||
```
|
||||
|
||||
### Settings custom (game plugin)
|
||||
|
||||
Un game plugin peut enregistrer ses propres settings :
|
||||
|
||||
```java
|
||||
public static final TeamSetting<Boolean> CITES_PVP_ROUND_END =
|
||||
TeamSetting.ofBoolean("cites_pvp_round_end", false);
|
||||
|
||||
@Override public void onEnable() {
|
||||
core = new CRCore(this).enable();
|
||||
TeamSettings.register(CITES_PVP_ROUND_END);
|
||||
}
|
||||
```
|
||||
|
||||
→ La clé apparaîtra automatiquement dans les GUI globaux et per-team, et
|
||||
sera persistée en SQLite + YAML comme les standards.
|
||||
|
||||
### Commande GUI
|
||||
|
||||
`/core team settings [team]` — player-only, ouvre l'interface graphique.
|
||||
|
||||
- Sans argument → **GUI globaux** (perm `crcore.team.settings.global`).
|
||||
Modif → écrit dans `<plugin>-team-config.yml`.
|
||||
- Avec argument → **GUI per-team** (perm `crcore.team.settings`). Modif →
|
||||
écrit en SQLite (overrides). Bouton "Reset tous les overrides" pour
|
||||
remettre toutes les valeurs au global.
|
||||
|
||||
### Mécaniques GUI
|
||||
|
||||
- **Inventaire 27 slots**, settings sur la ligne du milieu (slots 10..16).
|
||||
- **Booléens** : lampe verte (ON) / grise (OFF), clic = toggle.
|
||||
- **Entiers** : item livre.
|
||||
- Clic gauche = +1, shift = +10
|
||||
- Clic droit = -1, shift = -10
|
||||
- Clamp à 0 minimum
|
||||
- **Strings/Enums** : affichage seul (édition via YAML — pas dans la V1
|
||||
du GUI).
|
||||
- **Per-team** : indication visuelle "Override per-team actif" dans la
|
||||
lore quand une valeur est différente du global.
|
||||
- **Slot 22** : bouton Fermer.
|
||||
- **Slot 18** (per-team uniquement) : bouton "Reset tous les overrides".
|
||||
|
||||
### Framework GUI réutilisable
|
||||
|
||||
Le module `fr.luc.crcore.gui` est **générique** — réutilisable pour tout
|
||||
futur GUI CR-Core ou game plugin :
|
||||
|
||||
- `AbstractInventoryGui implements InventoryHolder` — base abstraite,
|
||||
`rebuild()`, `setButton(slot, item, handler)`, `setDecoration(...)`,
|
||||
`clearSlot(...)`, hook `onClose(...)`.
|
||||
- `GuiClickHandler` (FunctionalInterface) — handler de clic par slot.
|
||||
- `GuiListener` — un seul Listener Bukkit qui route les clics et les
|
||||
fermetures vers le bon GUI via `inventory.getHolder()`.
|
||||
- `GuiItems` — builder fluide `named(material, "&aTitre").lore(...).build()`,
|
||||
filler décoratif gris.
|
||||
|
||||
Pour faire un GUI custom : `extends AbstractInventoryGui`, créer
|
||||
l'inventaire dans le constructeur, override `rebuild()`. Le `GuiListener`
|
||||
est déjà enregistré par `CRCore.enable()`.
|
||||
|
||||
### Diagrammes
|
||||
|
||||
- [team-config-class-diagram.puml](diagrams/team-config-class-diagram.puml)
|
||||
- [gui-class-diagram.puml](diagrams/gui-class-diagram.puml)
|
||||
|
||||
---
|
||||
|
||||
## 11. Bootstrap `CRCore`
|
||||
|
||||
**Statut** : implémenté. Point d'entrée unique pour les plugins de jeu.
|
||||
|
||||
|
||||
+3
-1
@@ -267,12 +267,13 @@ CitesPlugin/ # dossier IntelliJ (renommer plus t
|
||||
|
||||
## Fichiers de config générés au premier `enable()`
|
||||
|
||||
Au premier démarrage, CR-Core crée DEUX fichiers dans le dataFolder :
|
||||
Au premier démarrage, CR-Core crée TROIS fichiers dans le dataFolder :
|
||||
|
||||
| Fichier | Rôle |
|
||||
|---|---|
|
||||
| `<plugin-name-lowercase>-messages.yml` | Templates de tous les messages (commandes + broadcasts) |
|
||||
| `<plugin-name-lowercase>-broadcasts.yml` | Routes : qui reçoit quel event |
|
||||
| `<plugin-name-lowercase>-team-config.yml` | Paramètres globaux d'équipe (defaults appliqués à toutes les teams) |
|
||||
|
||||
Les deux suivent le même pattern : si ton plugin de jeu bundle un fichier
|
||||
au même nom dans ses ressources, c'est lui qui sert de template initial à
|
||||
@@ -320,6 +321,7 @@ Au premier `enable()`, les tables suivantes sont créées (en `IF NOT EXISTS`) :
|
||||
visibility, spawn_world/x/y/z/yaw/pitch)
|
||||
- `crcore_team_members` — un membre = (team_id, player_id, role, joined_at)
|
||||
- `crcore_team_scores` — (team_id, score_name, value)
|
||||
- `crcore_team_settings` — (team_id, key, value, type) — overrides per-team
|
||||
- `crcore_player_profiles` — un profil = (id)
|
||||
- `crcore_player_scores` — (profile_id, score_name, value)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user