Tutorial: Dein erstes eigenes Modul

Zielgruppe: Modul-Entwickler mit Zugriff auf das Nexus-Monorepo (SDK-Partner). Als Server-Betreiber installierst du fertige Module einfach im ACP.

Module sind eigenständige Pakete, die der Core entdeckt und über das SDK anbindet. Sie kommunizieren nur über Event-Bus, registrierte Permissions und SPI-Schnittstellen — nie direkt mit Daten anderer Module. Blaupause ist das BanSystem (modules/bansystem/).

1. Maven-Modul anlegen

Im Root-pom.xml das Modul eintragen (<module>modules/greeter</module>) und eine pom.xml wie beim BanSystem anlegen (SDK + Spring-Bibliotheken, Versionen über die Spring-Boot-BOM des Parents).

2. Modulklasse

package net.jubyte.nexus.modules.greeter;

import net.jubyte.nexus.sdk.*;
import org.springframework.stereotype.Component;

@Component
@NexusModule(id = "greeter", name = "Greeter", version = "0.1.0",
        description = "Begrüßt Spieler beim Join")
public class GreeterModule implements NexusModuleLifecycle {

    @Override
    public void onEnable(NexusModuleContext ctx) {
        ctx.registerPermission("greeter.manage", "Begrüßungen verwalten");
        ctx.subscribe("player.join", event ->
                ctx.logger().log(System.Logger.Level.INFO,
                        "Willkommen, {0}!", event.data().get("name")));
    }
}

Alternativ deklarativ mit @Subscribe("player.join") auf einer public Methode mit NexusEvent-Parameter — die Module Registry verdrahtet sie automatisch und räumt sie beim Deaktivieren wieder ab.

3. Eigene API-Routen

Ein normaler @RestController unter /api/v1/modules/greeter/... mit @RequiresPermission("greeter.manage") (aus dem SDK) — Permission == API-Scope, Durchsetzung übernimmt der Core serverseitig.

4. Eigene Daten

Eigenes Schema mod_greeter per Flyway-Migration in src/main/resources/db/migration/greeter/ (Nummernkreis mit dem Core abstimmen), Location in core/src/main/resources/application.yml ergänzen. Entities mit @Table(schema = "mod_greeter").

5. Konfiguration

ctx.config("greeting.text", "Willkommen!") liest aus dem zentralen Config-Store (Tabelle module_config) — mit Default, damit ein leeres Setup sofort funktioniert („alles einstellbar, nichts einstellen müssen“).

6. Testen ohne Core

FakeModuleContext ctx = new FakeModuleContext().withConfig("greeting.text", "Hi");
new GreeterModule().onEnable(ctx);
assertThat(ctx.registeredPermissions()).containsKey("greeter.manage");

FakeModuleContext (SDK) ist der gefakte Core: synchroner Event-Bus, In-Memory-Config, aufgezeichnete Permissions.

7. Aktivieren

Core neu starten → das Modul erscheint im ACP unter Module und lässt sich dort (oder per POST /api/v1/modules/greeter/enable) schalten. Der Zustand ist persistent, das Aktivieren wird auditiert, module.enabled geht über den Event-Bus.