Der Schalter, der auf dem Zielserver stehen muss
Der Serverwechsel funktionierte für Bedrock-Spieler und nicht für Java-Spieler. Die Sendeseite sah dabei völlig gesund aus — die Ursache lag am anderen Ende.
1008 Wörter · 5 Min. Lesezeit
- minecraft
- plugin
- fehlersuche
Nachdem der Serverwechsel gebaut war, gab es ein Fehlerbild, das mich einen halben Tag gekostet hat: Bedrock-Spieler wurden weitergeleitet, Java-Spieler nicht.
Für Java-Spieler passierte scheinbar nichts. Kein Fehler im Protokoll des sendenden Servers, keine Meldung im Chat, kein Verbindungsabbruch. Der Befehl lief durch, und der Spieler blieb, wo er war.
Warum die Fehlersuche in die falsche Richtung lief
Alles, was ich prüfen konnte, war auf der Sendeseite. Und dort war alles in Ordnung:
- Das Plugin rief die Weiterleitung auf.
- Die Zieladresse in der Konfiguration war richtig.
- Der Zielport war von außen erreichbar.
- Die Erweiterung für die Bedrock-Seite funktionierte — sichtbar daran, dass Bedrock-Spieler ankamen.
Genau dieser letzte Punkt hat die Suche verlängert. Wenn ein Weg funktioniert und ein anderer nicht, sucht man den Unterschied auf der Seite, die man kennt. Der Unterschied lag aber woanders.
Die Ursache
Ein Server nimmt weitergeleitete Verbindungen nur an, wenn er das ausdrücklich erlaubt. Es gibt dafür eine Einstellung in der Serverkonfiguration, und sie steht standardmäßig auf nein.
Der Server, zu dem geschickt wurde, hat die ankommenden Spieler also abgewiesen. Ohne Fehlermeldung auf der Sendeseite, weil dort alles korrekt gelaufen ist — die Weiterleitung wurde erfolgreich ausgesprochen.
Warum Bedrock funktionierte: Bei Bedrock-Clients läuft die Weiterleitung über die Übersetzungsschicht, und die baut die Verbindung anders auf. Für sie greift diese Einstellung nicht.
Die Falle beim Beheben
Die Einstellung zu ändern ist eine Zeile in einer Konfigurationsdatei. Und hier lauert die zweite Falle des Tages:
Minecraft schreibt seine Serverkonfiguration beim Herunterfahren neu. Wer sie im laufenden Betrieb ändert, verliert die Änderung beim nächsten Stopp — der Server schreibt seinen eigenen Stand aus dem Speicher zurück.
Die richtige Reihenfolge ist also: erst stoppen, dann bearbeiten, dann starten. Ich habe das beim ersten Versuch falsch herum gemacht, mich gewundert, warum es weiterhin nicht ging, und noch einmal von vorne angefangen.
Infobox
Solche Dateien gibt es in vielen Systemen: Konfigurationen, die eine Anwendung nicht nur liest, sondern auch schreibt. Der Erkennungstest ist einfach — ändert sich der Zeitstempel der Datei beim Herunterfahren? Wenn ja, ist Bearbeiten im laufenden Betrieb sinnlos. Ich prüfe das inzwischen bei jeder Konfigurationsdatei, die ich zum ersten Mal anfasse.
Was ich daraus gelernt habe
Bei einer Weiterleitung gibt es zwei Seiten, und die Fehlermeldung erscheint auf der falschen. Das Muster ist allgemeiner: Immer, wenn zwei Systeme beteiligt sind, gehört das Protokoll beider Seiten in die Fehlersuche. Ich hatte eine Stunde lang nur auf eine Seite geschaut, weil dort der Befehl abgesetzt wurde.
Wenn ein Weg funktioniert und ein anderer nicht, ist der Unterschied selten dort, wo man ihn vermutet. Bedrock ging, Java nicht — mein Reflex war, den Unterschied in meinem Code zu suchen. Der Unterschied lag in einem Schalter auf einem anderen Rechner.
Standardwerte sind Entscheidungen. Dass diese Einstellung standardmäßig auf „nein" steht, ist sinnvoll: Ein Server soll nicht ohne Weiteres Spieler von beliebigen anderen Servern annehmen. Für mich war es ein Hindernis, für die Allgemeinheit ist es Schutz.
Warum Konfigurationsdateien, die zurückgeschrieben werden, so tückisch sind
Der Nebenfund dieses Tages hat mich mehr beschäftigt als das eigentliche Problem: Eine Datei, die eine Anwendung beim Beenden neu schreibt, kann man im laufenden Betrieb nicht ändern.
Das Muster ist verbreiteter, als man denkt. Anwendungen, die ihre Konfiguration beim Start einlesen, im Speicher halten und beim Beenden zurückschreiben, gibt es in jedem Ökosystem — teils, um fehlende Werte zu ergänzen, teils, um Kommentare zu aktualisieren.
Die Erkennung ist einfach: Ändert sich der Zeitstempel der Datei beim Herunterfahren? Wenn ja, ist Bearbeiten im Betrieb sinnlos.
Der Nebeneffekt ist noch unangenehmer: Solche Anwendungen überschreiben auch Kommentare und Formatierung. Wer eine Konfiguration sorgfältig kommentiert hat, findet nach dem nächsten Neustart die generierte Fassung vor.
Der Prüfweg, der daraus entstanden ist
Nach diesem Tag habe ich mir ein kleines Werkzeug gebaut, das für jeden Spielserver den tatsächlichen Zustand abfragt statt den konfigurierten.
Es macht eine echte Serverlisten-Abfrage — dieselbe, die ein Spielclient macht, bevor er sich verbindet. Die Antwort enthält Version, Spielerzahl, Beschreibung und das Serverbild.
Der Wert liegt darin, dass es keine Datei liest. Es fragt den laufenden Server, und was der antwortet, ist die Wahrheit — unabhängig davon, was in einer Konfiguration steht, welche Datei zuletzt geschrieben wurde und ob ein Neustart die Änderung übernommen hat.
Dieses Prinzip — von außen prüfen, was tatsächlich passiert, statt innen zu lesen, was gemeint war — ist eine der wenigen Regeln, die ich bei jedem System anwende, unabhängig von der Technik. Bei Webdiensten ist es ein Aufruf von außen. Bei Datenbanken eine Abfrage. Bei Spielservern eine Serverlisten-Abfrage.
Die Fehlerbilder, an denen ich das heute erkenne
Nach diesem Tag habe ich mir aufgeschrieben, welche Symptome auf welche Seite zeigen. Bei einer Weiterleitung zwischen zwei Servern gibt es drei typische Bilder.
Der Spieler bleibt, wo er ist, ohne Meldung. Die Sendeseite hat die Weiterleitung ausgesprochen, die Zielseite hat abgelehnt. Ursache liegt am Ziel.
Der Spieler fliegt raus, kommt nirgends an. Die Weiterleitung wurde ausgesprochen, aber ohne gültiges Ziel für diesen Clienttyp. Ursache liegt auf der Sendeseite.
Der Spieler kommt an, wird aber sofort wieder getrennt. Ziel erreicht, aber die Identitätsprüfung schlägt fehl — typisch, wenn ein Server hinter einem Proxy stehen soll und die Einstellungen dafür nicht passen.
Diese drei Fälle zu unterscheiden, spart bei jeder Fehlersuche den größten Teil der Zeit. Und alle drei erkennt man an der Frage: Was steht im Protokoll des Zielservers?
Genau dort hatte ich beim ersten Mal nicht nachgesehen, weil der Befehl auf der anderen Seite abgesetzt wurde.
Der Prüfweg, den ich mir gebaut habe
Nach diesem Tag habe ich ein kleines Skript, das für jeden meiner Server prüft, ob die Grundeinstellungen so sind, wie ich denke — nicht durch Lesen der Datei, sondern durch tatsächliche Abfrage: Antwortet der Port? Meldet der Server die erwartete Version? Steht der Schalter für weitergeleitete Verbindungen?
Der Punkt dabei ist die Formulierung: Nicht was in der Konfiguration steht, sondern was der laufende Server tatsächlich tut. Diese Unterscheidung hat mir seitdem mehrfach Zeit gespart, und sie ist derselbe Gedanke wie „am ausgelieferten Stand messen, nicht am lokal gebauten".