ffc77c4213
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>
207 lines
7.2 KiB
Markdown
207 lines
7.2 KiB
Markdown
# 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
|
|
<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 :
|
|
|
|
```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.
|