Manche Steam-Spiele liefern nur einen Windows-Dedicated-Server aus. Es gibt kein Linux-Binary im Depot, also lautet der übliche Rat "lass es auf einer Windows-Kiste laufen." Das musst du nicht. Mit Wine kannst du den Windows-Server auf einer normalen Linux-Maschine laufen lassen, und er verbindet sich mit Steam und nimmt echte Spieler an. Das ist genau das Rezept, das bei uns funktioniert hat, mit Alien Swarm: Reactive Drop (einem kostenlosen Source-Koop-Spiel) als Beispiel. Der gleiche Ansatz sollte auch auf andere reine Windows-Source-Dedicated-Server übertragbar sein.
Prüfe zuerst, ob es wirklich keinen Linux-Server gibt
Nimm nichts an. Frag Steam direkt, bevor du zu Wine greifst. Richte steamcmd auf die App und lies ihre Plattformliste:
steamcmd +login anonymous +app_info_print <appid> +quit \
| grep -iE "oslist|name"Wenn die Dedicated-Server-App nur "oslist windows" hat, gibt es keinen nativen Linux-Build als Rückfallebene. Du kannst auch versuchen, eine Linux-Installation zu erzwingen; wenn es wirklich kein Linux-Depot gibt, scheitert das sofort:
steamcmd +@sSteamCmdForcePlatformType linux \
+login anonymous +app_update <appid> validate +quit
# ERROR! Failed to install app '<appid>' (Missing configuration)Dieser Fehler, und dass keine ELF-Dateien ankommen, bestätigt es. Jetzt ist Wine der Weg. Installiere den Server UND App 1007 (die Steamworks Common Redistributables) in denselben Ordner, mit dem Plattformtyp windows. App 1007 liefert die Steam-DLLs, die der Server braucht, und in Schritt 2 siehst du, warum:
steamcmd +@sSteamCmdForcePlatformType windows +login anonymous \
+force_install_dir /path/to/server \
+app_update <appid> validate \
+app_update 1007 validate \
+quitWarum der naive Wine-Versuch scheitert
Den Server direkt aus Wine zu starten läuft nacheinander gegen zwei Wände:
- Keine Konsole: der Server erwartet ein echtes Terminal. Umleiten von /dev/null ergibt CTextConsoleWin32::GetLine: !GetNumberOfConsoleInputEvents und er startet nie.
- Steam-Bibliothek kann nicht geladen werden: selbst wenn er hochfährt, gibt er "Unable to load Steam support library" aus und registriert sich nie bei Steam, sodass ihn niemand finden oder betreten kann.
Beides ist behebbar. Hier das vollständige Rezept.
Schritt 1: gib ihm ein echtes Terminal (PTY)
Eine Headless-Kiste hat kein Terminal, und der Windows-Konsolen-Server weigert sich, ohne eins zu laufen. Verpacke den Start in script, das ein Pseudo-Terminal zuweist, und nutze Xvfb für ein Fake-Display:
Xvfb :99 -screen 0 1024x768x24 &
export DISPLAY=:99 WINEPREFIX=/wine
script -qfc "wine srcds_console.exe -console -condebug \
-game <gamedir> +map <map> -port 27015" /tmp/server.logDas allein bringt den Server dazu, eine Map zu laden und seinen Spielport zu binden. Aber er kann immer noch nicht mit Steam reden.
Schritt 2: zwei Steam-DLLs, zwei verschiedene Quellen
Die Source-Engine braucht BEIDE, steamclient.dll und steam.dll, neben der Server-.exe, und hier ist die Falle, die uns eine ganze zusätzliche Debugging-Runde gekostet hat: sie kommen von UNTERSCHIEDLICHEN Stellen, und App 1007 gibt dir nur EINE davon.
- steamclient.dll: kommt aus App 1007 (Steamworks Common Redistributables), die du in Schritt 1 installiert hast. Kanonisch, versionsgleich, von Valve gepflegt.
- steam.dll: ist NICHT in App 1007. Sie gehört zum Steam-CLIENT, und der einzige saubere Weg, sie zu bekommen, ist, die Windows-steamcmd.exe einmal unter Wine auszuführen, die sich selbst aktualisiert und steam.dll (plus steamclient.dll) in ihrem eigenen Ordner ablegt.
Bootstrappe steam.dll also mit steamcmd.exe unter Wine und kopiere dann beide DLLs neben die Server-.exe:
# steam.dll: run Windows steamcmd once under Wine (needs Xvfb for a display)
cd "$WINEPREFIX/drive_c/steamcmd"
curl -fsSLO https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip
unzip -o steamcmd.zip
DISPLAY=:99 wine steamcmd.exe +quit # lays down steam.dll + steamclient.dll
# place both next to the server exe
cd /path/to/server
cp "$WINEPREFIX/drive_c/steamcmd/steam.dll" .
[ -f steamclient.dll ] || cp "$WINEPREFIX/drive_c/steamcmd/steamclient.dll" .Schritt 3: warum steam.dll das entscheidende Teil ist
Das ist der Teil, den fast niemand aufschreibt. Der Fehler sagt "Unable to load Steam support library," und die gemeinte Support-Bibliothek ist nicht steamclient.dll, es ist steam.dll. Die Source-Engine sucht steam.dll neben ihrer eigenen ausführbaren Datei, um die ganze Steam-Kette zu bootstrappen. Ist nur steamclient.dll vorhanden (und mehr gibt dir App 1007 nicht), scheitert es weiterhin; sobald steam.dll neben der .exe liegt, kippt das Log von Fehlschlag zu Erfolg:
Connection to Steam servers successful.
VAC secure mode is activated.VAC aktiviert sich nur, wenn der Server ein korrekt eingeloggter Gameserver ist, also ist diese Zeile dein Beweis, dass er sich registriert hat. Die meisten Source-Server loggen sich hier anonym ein und brauchen kein Game Server Login Token (GSLT). Nur wenige Spiele (wie CS2) verlangen eins.
Die Falle: A2S verstummt, aber der Server ist okay
Hier der Haken, der uns die meiste Zeit gekostet hat, und der Grund, warum wir fast aufgegeben hätten. Unter Wine beantwortet der Server A2S_INFO NICHT, die UDP-Abfrage, mit der Tools Name, Map und Spielerzahl eines Servers auslesen. Frag ihn ab, und jeder Port läuft in einen Timeout, sogar von derselben Maschine. Wenn du A2S als Health Check nutzt, sieht der Server völlig tot aus.
Er ist nicht tot. Dass A2S unter Wine verstummt, hindert echte Spieler nicht am Beitreten. Der In-Game-Server-Browser listet Server aus Steams Master List (an die der Server von sich aus meldet), und ein Direct Connect nutzt das Spielprotokoll, nicht A2S. Der wahre Test ist also ein Client, der sich verbindet, nicht eine Abfrage, die antwortet. Als wir es endlich probiert haben, verband sich ein echter Spieler und spielte beim ersten Versuch:
Client "player" connected (10.0.0.5:27005).
1/ 8 on map <mapname>Die praktische Lektion: für einen Wine-gehosteten Server keinen Health Check mit A2S machen. Prüfe etwas, das die Lebendigkeit wirklich abbildet, etwa die Zeile "VAC secure mode is activated" im Log, die Zeile mit der Spielerzahl, oder einen simplen Check, dass der Spiel-UDP-Port gebunden ist.
Funktioniert das für jedes Windows-Spiel?
Sei ehrlich, was den Rahmen angeht. Wir haben es an einem Source-Engine-Server bewiesen, und das gleiche Rezept (PTY, eine per steamcmd gebaute Laufzeit, steam.dll neben der exe) sollte für andere reine Windows-Source-Dedicated-Server funktionieren. Spiele auf anderen Engines binden Steam anders ein, also behandle sie als eigene Experimente. Zwei Dinge sind in jedem Fall zu erwarten: Starts sind langsamer als natives Linux (Wine plus der steamcmd-Schritt plus der Steam-Login), und das oben beschriebene A2S-Verstummen wird wahrscheinlich für alle gelten.
Oder lass das alles sein
Das ist die Art Bastelei, die einen Nachmittag frisst. Wenn du einfach nur den Server willst, betreiben wir die Linux-Flotte und die Wine-Verkabelung für dich, stundenweise, mit einer öffentlichen IP ab der ersten Minute. Sieh dir an, was wir auf 2hours.gg hosten.