Files
Cites_Plugins/docs/setup.md
T
Antone Barbaud ffc77c4213 feat: initial CR-Core library (team + player + command framework)
Pure Maven library for CR Minecraft game plugins, targeting Paper 1.16.5.

Common abstractions (fr.luc.crcore.common): Identifiable, Named, ScoreHolder,
AbstractEntity, Repository<T>.

Team domain (fr.luc.crcore.team): Team entity with name/tag/color/leader/
visibility (PUBLIC|PRIVATE)/members/scores/spawn point, TeamMember,
TeamRole/TeamColor/TeamVisibility enums, TeamRanking record, TeamService with
overridable hooks (factories, validations, lifecycle events), in-memory
repository, dedicated exception hierarchy.

Player domain (fr.luc.crcore.player): PlayerProfile with named scores per
player, PlayerProfileService with auto-creation, individual rankings,
exception hierarchy. Both Team and PlayerProfile implement ScoreHolder.

Command framework (fr.luc.crcore.command): Command interface,
AbstractCommand base, BaseCommand (CommandExecutor + TabCompleter), SubCommand,
CommandContext, CommandResult, ArgumentType<T> + ArgumentTypes catalogue
(STRING, INTEGER, DOUBLE, BOOLEAN, ONLINE_PLAYER, enumOf, choice).

Docs (docs/) is the single source of truth: README, setup, features,
decisions log, and 6 PlantUML diagrams (team class/sequence/activity/join,
player class, command class).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-08 17:17:56 +02:00

7.2 KiB

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

Build & install local

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 :

<dependency>
    <groupId>fr.luc</groupId>
    <artifactId>CR-Core</artifactId>
    <version>1.0-SNAPSHOT</version>
    <scope>compile</scope>
</dependency>

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 <relocation> 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 :

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 :

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 :

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 :

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.