Diese Datei beschreibt den aktuellen technischen Aufbau des Farmwelt-Plugins. Sie ersetzt die frühere Entwicklungsspezifikation und soll bei Wartung, Debugging und Erweiterungen als Orientierung dienen.
Farmwelt ist ein Paper/Folia-Plugin mit drei Hauptbereichen:
/farmwelt-GUI für Farmwelt-Teleports.- Ressourcenmonitor für normale Welten.
- Administrations- und Debug-Befehle für Betrieb und Diagnose.
Das Plugin implementiert keine eigene Random-Teleport-Logik. Teleports werden über konfigurierbare Befehle ausgeführt, typischerweise BetterRTP. Claims werden optional über GriefPrevention erkannt, damit Ressourcenabbau innerhalb von Grundstücken ignoriert werden kann.
src/main/java/de/minecraftgilde/farmwelt/
+-- FarmweltPlugin.java
+-- command/
| +-- FarmweltCommand.java
+-- config/
| +-- ConfigManager.java
+-- gui/
| +-- FarmweltMenu.java
| +-- FarmweltMenuHolder.java
| +-- FarmweltMenuItem.java
| +-- TeleportAction.java
+-- listener/
| +-- FarmweltGuiListener.java
| +-- ResourceBreakListener.java
+-- claim/
| +-- ClaimProtectionProvider.java
| +-- GriefPreventionClaimProtectionProvider.java
| +-- NoopClaimProtectionProvider.java
+-- model/
| +-- ResourceMatch.java
| +-- ResourceWorldRule.java
| +-- ResourceWorldType.java
| +-- ViolationAction.java
| +-- ViolationRecord.java
| +-- ViolationResult.java
| +-- ViolationSnapshot.java
+-- service/
+-- ClaimProtectionService.java
+-- FarmweltTeleportService.java
+-- JailActionService.java
+-- MessageService.java
+-- ResourceDetectionService.java
+-- ViolationService.java
Die Hauptklasse ist FarmweltPlugin.
Beim Start:
saveDefaultConfig()erzeugt die Standardconfig, falls noch keine existiert.ConfigManagerlädt Farmwelt-GUI-Einträge.ConfigManagerlädt Ressourcenmonitor-Konfiguration, Weltregeln und Action-Schwellen.- GUI, Services und Listener werden erstellt.
- Der Befehl
/farmweltwird registriert. FarmweltCommandwird zusätzlich als Listener registriert, weil der Monitor-Debug auf Rechtsklicks reagiert.FarmweltGuiListenerverarbeitet GUI-Klicks.ResourceBreakListenerverarbeitet Blockabbau- und Explosions-Events.
Beim Reload über /farmwelt reload:
- Bukkit/Paper lädt die Config neu.
- Farmwelt-GUI-Einträge werden neu gelesen.
- Ressourcenmonitor-Konfiguration wird neu gelesen.
- Claim-Hook wird neu initialisiert.
- Violation-Schwellen und Zeitfenster werden neu geladen.
Bestehende Violation-Datensätze bleiben im Speicher, werden aber nach dem neuen Zeitfenster bewertet. Persistenz gibt es aktuell nicht.
ConfigManager ist die zentrale Übersetzung von config.yml in laufzeitfreundliche Strukturen.
Wichtige Aufgaben:
- Farmwelt-GUI-Einträge aus
farmworldslesen. - Icons als Bukkit-
Materialvalidieren. - GUI-Slots validieren.
- Teleport-Aktionen validieren.
- Ressourcenmonitor-Grundwerte lesen.
monitored-worldsundignored-worldsin Sets vorbereiten.- Permission-Namen für Bypass und Notify lesen.
- Audit-Optionen lesen.
- Action-Schwellen und Cooldowns lesen.
- Jail-Konfiguration lesen.
- Weltregeln vorbereiten.
- Materialnamen beim Laden in
EnumSet<Material>übersetzen.
Die Materiallisten werden dadurch nicht bei jedem Blockabbau aus der Config gelesen. Ungültige Materialien werden beim Laden geloggt und ignoriert.
Die ausgelieferte Standardconfig verwendet bewusst breite Ressourcenlisten auf Basis der Paper-API 26.1.2. Sie decken typische natürliche Farmressourcen wie Holz, Erze, Amethyst, Sand/Gravel/Clay/Mud, Terracotta, Eis, Nether- und End-Blöcke ab. Serverbetreiber können diese Listen enger ziehen, wenn einzelne Materialien in Hauptwelten erlaubt bleiben sollen.
FarmweltCommand implementiert den zentralen Befehl /farmwelt.
Vorhandene Befehle:
/farmwelt
/farmwelt info
/farmwelt reload
/farmwelt debug claim
/farmwelt debug monitor
/farmwelt debug violations [spieler]
Permissions:
/farmwelt:farmwelt.use- Alle Admin-Subcommands:
farmwelt.admin
/farmwelt info und /farmwelt reload können auch von der Konsole genutzt werden. Debug-Befehle benötigen einen Spieler, weil sie mit Spielerpositionen, Rechtsklicks oder online Spielern arbeiten.
Klassen:
FarmweltMenuFarmweltMenuHolderFarmweltMenuItemFarmweltGuiListener
Ablauf:
- Spieler führt
/farmweltaus. FarmweltCommandprüftfarmwelt.use.FarmweltMenu.open(player)erstellt ein Inventory mit 45 Slots.- Farmwelt-Einträge aus der Config werden in den Inhaltsbereich gelegt.
- Statische Items wie Info- und Schließen-Item werden ergänzt.
FarmweltGuiListenerbricht Klicks und Drags in der GUI ab, damit Items nicht entnommen werden können.- Klick auf einen Farmwelt-Eintrag ruft
FarmweltTeleportService.teleport(...)auf.
Die Config-Slots der Farmwelt-Einträge beziehen sich auf den internen Inhaltsbereich mit 27 Slots. Im Inventory wird ein Offset verwendet, damit die Einträge optisch im mittleren Bereich liegen.
Klasse:
FarmweltTeleportService
Unterstützt wird aktuell:
teleport:
type: command
sender: player
command: "betterrtp:rtp world Farmwelt"Unterstützte Sender:
player: Befehl wird überplayer.performCommand(...)ausgeführt.console: Befehl wird überserver.dispatchCommand(...)als Konsole ausgeführt.
Folia-relevanter Ablauf:
- Der GUI-Klick löst den Teleport-Service aus.
- Der Service plant die Befehlsausführung über
player.getScheduler().execute(...). - Im Spieler-Kontext wird das Inventory geschlossen.
- Platzhalter werden ersetzt.
- Der Befehl wird ohne führenden Slash ausgeführt.
Unterstützte Platzhalter:
{player}{world}{id}{display-name}
{world} und {display-name} verwenden aktuell den Anzeigenamen des GUI-Eintrags. Für technische Weltnamen sollte der BetterRTP-Befehl direkt in der Config fest eingetragen werden.
Klasse:
ResourceBreakListener
Der Ressourcenmonitor reagiert auf BlockBreakEvent, EntityDamageByEntityEvent, HangingBreakEvent, BlockExplodeEvent und EntityExplodeEvent mit ignoreCancelled = true. Bereits von anderen Plugins abgebrochene Events werden nicht verarbeitet. EntityDamageByEntityEvent deckt geschützte Item-Frame-Loots wie Elytren in End-City-Schiffen ab; HangingBreakEvent verhindert im enforce-Modus, dass geschützte Item Frames indirekt zerstört werden.
Entscheidungsreihenfolge:
- Ressourcenmonitor muss aktiviert sein.
- Modus muss
audit,warnoderenforcesein. - Claim-Fail-Mode darf den Monitor nicht deaktivieren.
- Spieler darf keine Bypass-Permission haben.
- Welt muss in
monitored-worldsstehen. - Welt darf nicht in
ignored-worldsstehen. - Für die Welt muss eine
world-rules-Regel existieren. - Blockmaterial muss zur Weltregel passen, oder Item-Loot muss in
protected-itemsstehen. - Wenn Claim-Ausnahmen aktiv sind, darf die Block- bzw. Item-Frame-Position nicht in einem Claim liegen.
- Danach wird je nach Modus Audit, Warnung, Staff-Notify oder Blockabbruch verarbeitet.
Diese Reihenfolge ist wichtig: Teurere Prüfungen wie Claims passieren erst, nachdem einfache Ausschlussgründe erledigt sind.
Im enforce-Modus schützt der Listener zusätzlich Ressourcenblöcke vor indirekter Zerstörung durch Explosionen. Dafür wird die blockList() des Explosions-Events gefiltert: erkannte Ressourcenblöcke werden entfernt, die Explosion selbst wird aber nicht komplett abgebrochen. Der Explosionsschutz ist aktiv, wenn der Ressourcenmonitor im enforce-Modus läuft und actions.cancel-break.enabled aktiv ist. Geschützte Item-Frame-Loots werden in enforce sofort blockiert, da sie einzelne hochwertige Loot-Aktionen statt fortlaufenden Blockabbaus sind.
Klasse:
ResourceDetectionService
Weltregeln werden über ResourceWorldRule abgebildet. Unterstützte Typen:
overworldnetherend
Overworld:
- Prüft ausschließlich
resources. - Es gibt keine Höhenprüfung.
- Treffer erhalten die Kategorie
overworld.
Nether:
- Prüft ausschließlich
resources. - Treffer erhalten die Kategorie
nether.
End:
- Prüft ausschließlich
resources. - Treffer erhalten die Kategorie
end. protected-itemsschützt Item-Frame-Loot wieELYTRA; Treffer erhalten die Kategorieend-loot.
Wenn keine Regel existiert oder das Material weder in resources noch als passender Item-Loot in protected-items steht, wird kein Ressourcen-Treffer erzeugt.
Klassen:
ClaimProtectionServiceClaimProtectionProviderGriefPreventionClaimProtectionProviderNoopClaimProtectionProvider
ClaimProtectionService entscheidet anhand der Config, welcher Provider genutzt wird.
Aktuell unterstützter Provider:
provider: GriefPreventionGriefPrevention wird optional angebunden. Der Provider nutzt Reflection, um die GriefPrevention-Datenstruktur und getClaimAt(Location, boolean, Claim) vorzubereiten. Dadurch bleibt Farmwelt ohne harte Compile-Abhängigkeit zu GriefPrevention lauffähig.
Wichtige Config-Werte:
enabled: Schaltet Claim-Prüfung ein.skip-inside-claims: Ignoriert Ressourcenabbau in Claims.fail-mode: disable-monitor: Deaktiviert den Ressourcenmonitor, wenn der aktivierte Claim-Provider nicht verfügbar ist.ignore-height: Wird an GriefPrevention weitergereicht.
Beim Ressourcenmonitor wird die Position des abgebauten Blocks geprüft. /farmwelt debug claim prüft dagegen die aktuelle Spielerposition, weil der Befehl für schnelle Admin-Diagnose gedacht ist.
Klasse:
ViolationService
Der ViolationService hält pro Spieler einen Datensatz im Speicher. Er arbeitet thread-sicher mit ConcurrentHashMap und aktualisiert Einträge atomar über compute.
Gespeichert werden unter anderem:
- Spieler-UUID.
- Aktuelle Verstöße im Zeitfenster.
- Blockierte Versuche.
- Startzeit des Fensters.
- Letzter erkannter Block.
- Letzte Position.
- Letzte Kategorie.
- Zeitpunkte der letzten Actions.
- Status, ob Jail im aktuellen Fenster bereits ausgelöst wurde.
Zeitfenster:
resource-monitor:
violation-window-seconds: 600Wenn das Zeitfenster abgelaufen ist, startet der nächste relevante Treffer wieder mit einem neuen Datensatz. Es gibt keine Datenbank und keine Persistenz über Serverneustarts.
Action-Entscheidung:
warning: Wird abafter-blocksund nach Cooldown ausgelöst.notify-staff: Wird abafter-blocksund nach Cooldown ausgelöst.cancel-break: Wird inenforceabafter-blocksund nach Cooldown als Nachricht ausgelöst.jail: Nutzt nicht den normalen Violation-Zähler, sondern die Anzahl blockierter Versuche.
Wichtig: Der eigentliche Blockabbruch im enforce-Modus hängt an der aktuellen Count-Schwelle von cancel-break. Der Cooldown steuert die Nachricht, nicht die Tatsache, ob nach erreichter Schwelle weiter blockiert wird.
Klasse:
MessageService
Der MessageService ist für Spieler-, Staff- und Console-Meldungen zuständig.
Aufgaben:
- Audit-Logs in die Konsole schreiben.
- Audit-Meldungen an Spieler mit Notify-Permission senden.
- Violation-Warnungen an Spieler senden.
- Staff-Benachrichtigungen senden.
- Cancel-Break-Nachrichten und Actionbar senden.
- Jail-Meldungen senden.
- Platzhalter ersetzen.
Nachrichten verwenden aktuell Legacy-Farbcodes mit & und werden über Adventure-Komponenten ausgegeben.
Wichtige Platzhalter:
{player}{uuid}{world}{x}{y}{z}{block}{category}{count}{blocked-count}{window-seconds}
Enforce wird nur bei resource-monitor.mode: enforce aktiv.
Ablauf bei einem relevanten Blockabbau:
- Violation wird registriert.
- Warn- und Staff-Actions werden geprüft.
- Wenn
cancel-break.enabledaktiv ist und die Schwelle erreicht ist, wirdevent.setCancelled(true)gesetzt. - Spieler erhält je nach Cooldown Chat- und/oder Actionbar-Nachricht.
- Der blockierte Versuch wird separat registriert.
- Wenn die Jail-Schwelle für blockierte Versuche erreicht ist, wird
JailActionService.execute(...)aufgerufen.
Ablauf bei einer relevanten Explosion:
BlockExplodeEventoderEntityExplodeEventliefert die betroffenen Blöcke.- Der Listener prüft Monitorstatus,
enforce-Modus undcancel-break. - Für jeden Block werden Weltregel, Ressourcenmaterial und Claim-Ausnahme geprüft.
- Erkannte Ressourcenblöcke werden aus der Explosionsliste entfernt.
- Alle übrigen Blöcke bleiben in der Explosionsliste.
Jail ist standardmäßig deaktiviert:
actions:
jail:
enabled: false
mode: notify-onlyUnterstützte Jail-Modi:
disabled: keine Aktion.notify-only: nur Staff informieren.execute-command: konfigurierten Befehl als Konsole ausführen.
Folia-relevanter Ablauf bei execute-command:
- Staff-Meldung wird direkt über den MessageService gesendet.
- Der Konsolenbefehl wird über
getGlobalRegionScheduler().execute(...)geplant. - Die optionale Spielernachricht nach erfolgreichem Befehl wird über
player.getScheduler().execute(...)geplant.
/farmwelt info zeigt:
- Plugin-Version.
- Anzahl geladener Farmwelt-Einträge.
- Ressourcenmonitor-Status und Modus.
- Claim-Provider.
- Claim-Hook-Status.
- BetterRTP-Status.
- GriefPrevention-Status.
- Jail-Modus.
/farmwelt debug claim zeigt:
- Claim-Provider.
- Claim-Schutz-Status.
- Ob die Spielerposition in einem Claim liegt.
/farmwelt debug monitor:
- Schaltet pro Spieler einen Rechtsklick-Debugmodus um.
- Rechtsklick auf einen Block zeigt Welt-, Regel-, Claim-, Bypass-, Ressourcen- und Blockierinformationen.
- Der Modus wird beim erneuten Befehl oder beim Quit entfernt.
/farmwelt debug violations [spieler]:
- Zeigt aktuellen Violation-Zähler.
- Zeigt blockierte Versuche.
- Zeigt Restzeit des Fensters.
- Zeigt Schwellen und Jail-Status.
- Optional kann ein anderer online Spieler geprüft werden.
Das Plugin ist in paper-plugin.yml mit folia-supported: true markiert.
Aktuelle Folia-relevante Punkte:
- Teleportbefehle aus der GUI werden über den Entity-Scheduler des Spielers geplant.
- Jail-Konsolenbefehle werden über den Global-Region-Scheduler geplant.
- Spielernachrichten nach Jail-Befehl werden wieder über den Entity-Scheduler geplant.
- Violation-Daten liegen in thread-sicheren Strukturen.
- Der Ressourcenmonitor arbeitet eventgetrieben und speichert nur kleine In-Memory-Datensätze.
Bei neuen Features sollten Welt-, Block- oder Spielerzugriffe weiterhin im passenden Kontext passieren. Besonders kritisch sind zeitversetzte Aktionen, Teleports, Inventarzugriffe und direkte Weltmanipulationen.
paper-plugin.yml:
dependencies:
server:
BetterRTP:
load: BEFORE
required: false
join-classpath: false
GriefPrevention:
load: BEFORE
required: false
join-classpath: trueBetterRTP:
- Wird nicht direkt per API genutzt.
- Farmwelt führt nur konfigurierte Befehle aus.
- Ohne BetterRTP startet Farmwelt, aber die Standardbefehle funktionieren nicht.
GriefPrevention:
- Wird optional für Claim-Erkennung genutzt.
- Der Hook wird über Reflection vorbereitet.
- Bei aktivem
fail-mode: disable-monitordeaktiviert ein fehlender Hook den Ressourcenmonitor.
Farmwelt nutzt aktuell keine Datenbank und keine Dateien außer der Config.
In-Memory-Daten:
- Geladene Farmwelt-Menüeinträge.
- Geladene Ressourcenregeln.
- Violation-Datensätze pro Spieler.
- Audit-Cooldown-Zeitpunkte pro Spieler, Material und Kategorie. Wiederholte Audit-Treffer setzen den Zeitpunkt auch dann neu, wenn keine Meldung ausgegeben wird.
- Aktive Monitor-Debug-Spieler.
Diese Daten gehen bei Serverneustart verloren. Das ist für die aktuelle Funktion beabsichtigt.
Bei neuen Features zuerst prüfen:
- Gehört die Änderung in Config, Command, Listener oder Service?
- Muss sie Folia-Kontext beachten?
- Muss sie in
/farmwelt infooder Debug-Ausgaben sichtbar werden? - Braucht sie eine neue Permission?
- Muss die Admin-Doku angepasst werden?
- Muss die README nur kurz oder ausführlich aktualisiert werden?
Leitlinien:
- Keine neuen harten Runtime-Abhängigkeiten ohne guten Grund.
- Config-Werte beim Laden validieren und vorbereiten.
- Event-Listener früh verlassen, wenn ein Fall nicht relevant ist.
- Ressourcenmonitor-Regeln nicht pro Event aus YAML lesen.
- Spieler- und Weltzugriffe bei asynchronen oder geplanten Aktionen Folia-sicher ausführen.
- Harte Sanktionen standardmäßig deaktiviert oder sehr konservativ halten.
README.md: Überblick, Installation, Commands, Permissions und Betriebsgrundlagen.docs/ADMIN_GUIDE.md: Einrichtung, Testplan, Rollout und Wartung.docs/ARCHITECTURE.md: Technischer Aufbau und Wartungshinweise für Entwickler.