# proxy Velocity-Plugin des CraftAttack-Netzwerks (craftattack, arena, Limbo, Event, Weltmuseum). Aufgebaut wie spawn auf den Backends: Ein kleiner Kern lädt **Appliances**, jede ist ein Teil-Plugin mit eigenen Listenern, Befehlen und eigenem Config-Abschnitt. Braucht LuckPerms auf Velocity. | Appliance | Was | Braucht | |---|---|---| | `mute` | `/mute`, `/unmute`, LuckPerms-Permission `chatbridge.muted` | – | | `chat` | öffentlicher Chat, `/msg`, `/r`, `/adminchat`, Join/Leave, Chat-Einstellungen | `mute` | | `tablist` | Spieler anderer Server in der Tabliste | `chat` | | `signup` | erster Server beim Join: Login-Server oder CraftAttack, je nach Anmeldung auf der Website | – | ## Aufbau ``` src/main/java/eu/mhsl/craftattack/proxy/ core/ Main (Velocity-Plugin), Config, Servers core/appliance/ Appliance, ApplianceCommand, PlayerCommand appliances// eine Appliance je Package ``` **Neue Appliance** (z. B. der Anmeldecheck, der zwischen Login-Server und echtem Server entscheidet): 1. Package `appliances//` mit einer Klasse `extends Appliance`. 2. `onEnable()` für den Aufbau, `listeners()` für Objekte mit `@Subscribe`, `commands()` für Befehle (`ApplianceCommand.of("name", command, "alias")`), `onDisable()` beim Herunterfahren. 3. In `Main.APPLIANCES` eintragen. Die Reihenfolge ist die Startreihenfolge: `queryAppliance(X.class)` geht nur für Appliances, die davor stehen. 4. Einstellungen als `.` in `src/main/resources/config.properties`, lesen mit `config().string(…)`, `integer`, `bool`, `list`, `pairs`. Daten in `dataDirectory()` (`plugins/proxy//`). Der Name einer Appliance ist der Klassenname mit kleinem Anfangsbuchstaben (`Mute` → `mute`), änderbar über `name()`. Schlägt `onEnable()` fehl, fällt nur diese Appliance aus und der Fehler steht im Log; Velocity und die anderen Appliances laufen weiter. Eine Appliance, die Spieler blockieren soll, muss deshalb selbst dafür sorgen, dass sie bei einem Fehler nicht stillschweigend alle durchlässt. Globale Schlüssel: `disabled-appliances`, `admin-permission`, `server-symbols`, `server-where` (letztere über `servers()` in jeder Appliance). ## Chat (`chat`, `mute`, `tablist`) Chat und Tabliste gelten im ganzen Netzwerk. Velocity verteilt jede Zeile als Systemnachricht an alle Spieler; die Backends verwerfen den Chat selbst („Silencer“), sonst stünde er dort doppelt. Warum so herum: Velocity kann eine signierte Chat-Nachricht (ab 1.19.1) weder ändern noch abbrechen, ohne den Spieler zu trennen. Der Proxy lässt sie deshalb zum Backend durch, schaut nur zu und verteilt sie selbst. - **Öffentlicher Chat:** Spieler auf einem anderen Server als man selbst bekommen ein dunkelgraues Symbol vor den Namen (⛏ CraftAttack, ◎ Arena, ⌛ Warteraum, ⚄ Event, ♜ Weltmuseum; Hover: „… ist gerade in der Arena“), Spieler vom eigenen Server keins. Gilt auch für /msg, Join/Leave und die Tabliste. Einfache Zeichen ohne Klammern, damit sie nicht mit Rängen ([🌟], 👑, 🗡 …) verwechselt werden. Namen von Spielern im Netzwerk werden golden als `@Name` hervorgehoben und hören einen Ton. - **Name:** Rang-Prefixe schickt spawn (`DisplayName` → Kanal `craftattack:chat`, gilt nur solange der Spieler auf diesem Server ist), blau mit Permission `adminmarker`, 🎮 für Bedrock. - **/msg** (`tell`, `w`, `whisper`), **/r**, **/adminchat** (Permission `admin`). - **/mute `` ``**, **/unmute ``** (Permission `admin`): temporäre LuckPerms-Permission `chatbridge.muted` in der gemeinsamen MariaDB, läuft von selbst ab. Gestummte dürfen weder öffentlich noch per /msg schreiben, außer an Admins. - **Join/Leave** nur beim Ein- und Ausloggen ins Netzwerk, nicht beim Serverwechsel. - **Einstellungen** in `/settings` auf spawn (Join/Leave anzeigen, Erwähnungen hervorheben, Erwähnungston): Velocity speichert sie in `plugins/proxy/chat/settings.properties` und gibt sie beim Join an spawn zurück, damit die Arena dieselben Werte zeigt. Unbekannte Spieler übernimmt Velocity nur vom `chat.settings-server` (craftattack), damit die Defaults der Arena keine echten Werte verdrängen. - **Tabliste:** Spieler anderer Server stehen unten, mit Symbol, grau und als Spectator (kursiv). Die Einträge vom eigenen Server schickt weiter das Backend (Skins, Spielmodus, Prefixe). Abgleich alle 2 s und kurz nach Join, Wechsel und Quit. - **Log:** Chat, /msg, Adminchat und Mutes stehen im Velocity-Log (`[chat]`, `[msg]`, `[adminchat]`, `[mute]`). Silencer auf den Backends: | Server | Wo | |---|---| | craftattack, arena | spawn, Appliance `NetworkChat` (verwirft Chat und `/me`, `/teammsg`, `minecraft:msg`) | | limbo | EndlessJumper | | event | Minigames (ab `develop` 8dc1659), `velocity.chat-via-proxy: true` in `resources/config.yml` | Server ohne Silencer stehen in `chat.unsilenced-servers`: Deren Spieler bekommen den Chat vom eigenen Server nicht noch einmal, dort greift der Mute aber nur für die anderen Server. Einstellungen: `plugins/proxy/config.properties` (wird beim ersten Start angelegt, kommentiert). ## Bauen und Deploy Java 25, Gradle-Wrapper. ```bash ./gradlew build # inkl. Tests ./gradlew uploadPlugin # nach ~/velocity/plugins/proxy.jar, danach: sudo systemctl restart velocity ``` ### Umstellung von chat-bridge (einmalig) Plugin-ID und Datenordner haben sich geändert (`chat-bridge` → `proxy`). Auf dem Proxy (10.20.9.3), bei gestopptem Velocity: ```bash cd ~/velocity/plugins mkdir -p proxy/chat mv chat-bridge/settings.properties proxy/chat/settings.properties mv chat-bridge.jar ~/backup/ # sonst laufen beide Plugins und jede Zeile kommt doppelt mv chat-bridge ~/backup/chat-bridge-config ``` `proxy/config.properties` legt das Plugin beim ersten Start aus der Vorlage an. Eigene Änderungen aus der alten `config.properties` übernehmen: `unsilenced-servers`, `settings-server` und `marker-permission` heißen jetzt `chat.…`, die übrigen Schlüssel bleiben gleich. Kanal `craftattack:chat` und die Permission `chatbridge.muted` bleiben gleich, an spawn und an laufenden Mutes ändert sich nichts.