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>
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
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
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 nonprovided) si le plugin de jeu shade CR-Core dans son propre jar (recommandé pour de la pure librairie). Pensez à utiliser un<relocation>dans lemaven-shade-plugindu 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 enCR-Core/, fermer IntelliJ, renommer, rouvrir. Lepom.xmlet les packages sont déjà à jour, le nom du dossier n'a aucun impact sur le build.