@startuml broadcasts-class-diagram title CR-Core — Broadcast service (class diagram) skinparam classAttributeIconSize 0 hide empty members package "fr.luc.crcore.util.broadcast" { enum BroadcastAudience { NONE LEADER TEAM ADMIN ALL } class BroadcastContext { - team: Team - involvedPlayerId: UUID - placeholders: Map -- + {static} of(team): BroadcastContext + {static} empty(): BroadcastContext + involving(playerId): BroadcastContext + with(key, value): BroadcastContext + getTeam(): Optional + getInvolvedPlayerId(): Optional + getPlaceholders(): Map + toPlaceholderPairs(): Object[] } interface BroadcastService { + broadcast(eventKey, context): void + getAudiences(eventKey): List + reload(): void } class CRCoreBroadcastListener { - broadcasts: BroadcastService + registerOn(plugin: JavaPlugin): void -- @ onTeamCreate(TeamCreateEvent) @ onTeamDissolve(TeamDissolveEvent) @ onTeamMemberAdd(TeamMemberAddEvent) @ onTeamMemberRemove(TeamMemberRemoveEvent) @ onPlayerJoinTeam(PlayerJoinTeamEvent) @ onLeadershipTransfer(TeamLeadershipTransferEvent) @ onVisibilityChange(TeamVisibilityChangeEvent) @ onTeamScoreChange(TeamScoreChangeEvent) @ onTeamSpawnChange(TeamSpawnPointChangeEvent) @ onProfileCreate(PlayerProfileCreateEvent) @ onProfileDelete(PlayerProfileDeleteEvent) @ onPlayerScoreChange(PlayerScoreChangeEvent) } CRCoreBroadcastListener ..|> "org.bukkit.event.Listener" package "fr.luc.crcore.util.broadcast.impl" { class YamlBroadcastService { - plugin: JavaPlugin - messages: MessagesService - defaults: Map> - audiences: Map> - userFile: File -- + YamlBroadcastService(plugin, messages) - loadDefaultsFromResource(): void - ensureUserFile(): void - rebuildEffectiveAudiences(): void - resolveRecipients(list, ctx): Set } YamlBroadcastService ..|> BroadcastService } BroadcastService ..> BroadcastContext : consumes BroadcastContext --> BroadcastAudience YamlBroadcastService --> "fr.luc.crcore.util.message.MessagesService" : reads templates CRCoreBroadcastListener --> BroadcastService : delegates CRCoreBroadcastListener ..> BroadcastContext : builds } package "fr.luc.crcore" { class CRCore { + broadcasts(): BroadcastService # buildBroadcastService(messages): BroadcastService } CRCore "1" *-- "1" BroadcastService : owns CRCore ..> CRCoreBroadcastListener : registers } note bottom of YamlBroadcastService Modèle "un seul fichier par plugin" : Sources en mémoire : 1. crcore-broadcasts.yml ← jar (fallback) 2. -broadcasts.yml ← dataFolder (édité par l'admin) Séparation routes / templates : - Routes = ce fichier (qui reçoit quoi) - Templates = MessagesService (clés .broadcast) end note @enduml