feat: moderation feature skeleton (/core admin + mod mode + tools)
New feature fr.luc.crcore.features.moderation, opt-in via CRCoreConfig.setupModeration() (also enabled by setupAll()). Core abstractions: - ModerationState: full player snapshot (inv + armor + offhand, XP, health, food, location, gamemode, allowFlight/flying, walk/fly speed). Immutable, restoreTo(player) restores everything. - ModerationService interface + ModerationServiceImpl (with protected onAfterEnter/onAfterExit hooks) + BukkitEventFiringModerationServiceImpl (fires ModerationEnterEvent / ModerationExitEvent). - ModerationRepository interface + InMemoryModerationRepository (skeleton — SQLite impl with BukkitObjectOutputStream serialization planned). - ModeratorTool interface: getKey/getSlot(0..8)/buildIcon + onLeftClick/onRightClick/onInteractEntity. ModeratorToolRegistry preserves registration order, slot collision = replace. - Exceptions: ModerationException base + AlreadyActive + NotActive. - Events: ModerationEvent base + Enter + Exit. 5 skeleton tools in the hotbar: - slot 0: TeleportRandomPlayerTool (compass, right-click → tp random) - slot 1: InventorySpyTool (chest, right-click on player → open inv) - slot 2: FreezeTool (ice, right-click on player → toggle freeze) - slot 7: VanishToggleTool (ender eye, click → toggle vanish) - slot 8: ExitTool (barrier, click → exit mod mode) Slots 3-6 free for custom tools. ModerationListener routes interactions and locks hotbar: - PlayerInteractEvent → tool.onLeftClick / onRightClick (with cancel). - PlayerInteractEntityEvent → tool.onInteractEntity (with cancel). - PlayerDropItemEvent / PlayerSwapHandItemsEvent: cancel for mods. - InventoryClickEvent: cancel only when top inv is the mod's own inv (preserves InventorySpyTool's ability to manipulate target's inv). - PlayerJoinEvent: re-applies vanish for already-vanished mods. - PlayerQuitEvent: cleanup freeze state. - PlayerMoveEvent: cancel block-position changes for frozen players, keeping head rotation free. Mod mode lifecycle: - enter: snapshot + clear inv + populate hotbar + CREATIVE + allowFlight + vanish + ModerationEnterEvent. - exit: state.restoreTo(player) + unvanish + unfreeze + repo delete + ModerationExitEvent. /core admin (perm crcore.admin, player-only): toggle on/off. Messages moderation.enter.success / moderation.exit.success added to crcore-messages.yml. CRCoreConfig.setupModeration() + isModerationEnabled() flag. CRCore: buildModerationService() and registerDefaultModeratorTools() override points, moderation() / getModerationService() getters with IllegalStateException guard. Builds + registers ModerationListener at enable() when feature on. CoreCommand extended to take ModerationService; registers AdminToggleSubCommand only when service non-null. Skeleton limitations documented in features.md: - In-memory repo only (server crash = lost inv) — SQLite planned. - InventorySpyTool opens real inv (no read-only wrapping yet). - TeleportRandomPlayerTool is a placeholder for a future player-picker GUI. - No moderation.*.broadcast keys yet. - No /core admin <player> (self-toggle only). Docs: section 11 in features.md, decision logged in decisions.md (skeleton scope + rationale), setup.md snippet updated, new moderation-class-diagram.puml, README.md updated. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+8
-2
@@ -44,8 +44,13 @@ d'initialisation côté plugin de jeu :
|
||||
- **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é.
|
||||
- **Modération (skeleton)** — `/core admin` toggle pour passer en
|
||||
mod mode : snapshot complet du joueur (inv, XP, location, gamemode),
|
||||
vanish, hotbar dotée d'outils (tp joueur, inv spy, freeze, vanish
|
||||
toggle, exit). `ModeratorTool` + registry extensibles. Persistance
|
||||
SQLite à venir.
|
||||
- **Bootstrap unique** — `new CRCore(this, new CRCoreConfig().setupAll()).enable()`
|
||||
dans le `onEnable()` du plugin de jeu, et tout est branché.
|
||||
|
||||
## Structure de la documentation
|
||||
|
||||
@@ -72,6 +77,7 @@ d'initialisation côté plugin de jeu :
|
||||
| [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 |
|
||||
| [moderation-class-diagram.puml](diagrams/moderation-class-diagram.puml) | Classe | Feature modération (skeleton) |
|
||||
| [bootstrap-sequence.puml](diagrams/bootstrap-sequence.puml) | Séquence | `CRCore.enable()` côté plugin de jeu |
|
||||
|
||||
## Conventions
|
||||
|
||||
Reference in New Issue
Block a user