# Setup technique ## Stack - **Type** : librairie Java (`jar`) — pas un plugin Bukkit - **artifactId Maven** : `CR-Core` - **Build** : Maven - **Java** : 16 - **API serveur (provided)** : Paper 1.16.5 (`com.destroystokyo.paper:paper-api:1.16.5-R0.1-SNAPSHOT`) - **Package racine** : `fr.luc.crcore` ## Dépôts Maven - `papermc` — https://repo.papermc.io/repository/maven-public/ - `spigot-repo` — https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - `sonatype` — https://oss.sonatype.org/content/groups/public/ ## Build & install local ```bash mvn clean install ``` Cela publie `fr.luc:CR-Core:1.0-SNAPSHOT` dans le repo Maven local `~/.m2/`, prêt à être consommé par les plugins de jeu. ## Utilisation depuis un plugin de jeu Dans le `pom.xml` du plugin de jeu : ```xml fr.luc CR-Core 1.0-SNAPSHOT compile ``` > Scope `compile` (et non `provided`) **si** le plugin de jeu shade CR-Core dans > son propre jar (recommandé pour de la pure librairie). Pensez à utiliser un > `` dans le `maven-shade-plugin` du plugin de jeu pour éviter les > conflits si plusieurs plugins shadent CR-Core sur le même serveur. Côté code du plugin de jeu : ```java public final class MyGamePlugin extends JavaPlugin { private TeamService teamService; @Override public void onEnable() { // Instancie le service team (chaque plugin a son propre registre) this.teamService = new TeamServiceImpl(new InMemoryTeamRepository()); // Enregistre une commande basée sur le framework de CR-Core getCommand("team").setExecutor(new TeamCommand(teamService)); getCommand("team").setTabCompleter(new TeamCommand(teamService)); } } ``` Exemple minimal de commande : ```java public class TeamCommand extends BaseCommand { public TeamCommand(TeamService service) { super("team", "teams", "t"); description("Manage teams"); addSubCommand(new TeamCreateSub(service)); addSubCommand(new TeamInfoSub(service)); } } public class TeamCreateSub extends SubCommand { private final TeamService service; public TeamCreateSub(TeamService service) { super("create", "c", "new"); this.service = service; description("Create a new team"); permission("mygame.team.create"); playerOnly(); argument("name", ArgumentTypes.STRING); argument("tag", ArgumentTypes.STRING); argument("color", ArgumentTypes.enumOf(TeamColor.class)); } @Override public CommandResult execute(CommandContext ctx) { Player player = ctx.requirePlayer(); String name = ctx.get("name"); String tag = ctx.get("tag"); TeamColor color = ctx.get("color"); try { Team team = service.createTeam(name, tag, color, player.getUniqueId()); return CommandResult.success("Équipe " + team.getName() + " créée !"); } catch (TeamException ex) { return CommandResult.failure(ex.getMessage()); } } } ``` Et dans le `plugin.yml` du plugin de jeu : ```yaml name: MyGame main: fr.luc.mygame.MyGamePlugin version: 1.0 api-version: 1.16 commands: team: description: Manage teams aliases: [teams, t] ``` ## Override Toute classe du noyau peut être étendue : ```java public class LoggingTeamService extends TeamServiceImpl { public LoggingTeamService(TeamRepository repo) { super(repo); } @Override protected void onAfterCreate(Team team) { getPlugin().getLogger().info("Team created: " + team.getName()); } @Override protected Team newTeam(UUID id, String name, String tag, TeamColor color, UUID leaderId) { return new MyCustomTeam(id, name, tag, color, leaderId); } } ``` ## Arborescence du projet ``` CitesPlugin/ # dossier IntelliJ (renommer plus tard si voulu) ├── pom.xml ├── GEMINI.md ├── docs/ # source de vérité │ ├── README.md │ ├── setup.md │ ├── features.md │ ├── decisions.md │ └── diagrams/ │ ├── team-class-diagram.puml │ ├── team-create-sequence.puml │ ├── team-create-activity.puml │ └── command-class-diagram.puml └── src/main/java/fr/luc/crcore/ ├── common/ # abstractions partagées │ ├── Identifiable.java # interface │ ├── Named.java # interface │ ├── ScoreHolder.java # interface (impl. par Team et PlayerProfile) │ ├── AbstractEntity.java # abstract class │ └── Repository.java # interface ├── command/ # framework de commandes │ ├── Command.java # interface │ ├── AbstractCommand.java # base partagée │ ├── BaseCommand.java # commande top-level (Bukkit-aware) │ ├── SubCommand.java # sous-commande │ ├── CommandContext.java │ ├── CommandResult.java │ ├── CommandException.java │ ├── ArgumentType.java │ ├── ArgumentTypes.java # STRING, INTEGER, BOOLEAN, ONLINE_PLAYER, enumOf, choice │ └── ArgumentDef.java # package-private ├── team/ # domaine team │ ├── Team.java │ ├── TeamMember.java │ ├── TeamRole.java # enum │ ├── TeamColor.java # enum │ ├── TeamVisibility.java # enum (PUBLIC / PRIVATE) │ ├── TeamRanking.java # record (rank, team, score) │ ├── TeamRepository.java # interface │ ├── InMemoryTeamRepository.java # impl │ ├── TeamService.java # interface │ ├── TeamServiceImpl.java # impl avec hooks overridables │ ├── TeamException.java │ ├── TeamAlreadyExistsException.java │ ├── TeamNotFoundException.java │ └── TeamAccessException.java # auto-join refusé └── player/ # domaine player ├── PlayerProfile.java # entité, scores par joueur ├── PlayerRanking.java # record (rank, profile, score) ├── PlayerProfileRepository.java # interface ├── InMemoryPlayerProfileRepository.java ├── PlayerProfileService.java # interface ├── PlayerProfileServiceImpl.java # impl avec hooks overridables ├── PlayerException.java └── PlayerProfileNotFoundException.java ``` > **Note IntelliJ** : le dossier physique s'appelle encore `CitesPlugin/`. Pour > le renommer en `CR-Core/`, fermer IntelliJ, renommer, rouvrir. Le `pom.xml` > et les packages sont déjà à jour, le nom du dossier n'a aucun impact sur le > build.