Unele jocuri de pe Steam oferă doar un server dedicat pentru Windows. Nu există niciun binar pentru Linux în depot, așa că sfatul obișnuit e „rulează-l pe o mașină Windows”. Nu ești obligat. Cu Wine poți rula serverul Windows pe o mașină Linux obișnuită, iar el se va conecta la Steam și va accepta jucători reali. Aceasta este exact rețeta care a funcționat pentru noi, folosind Alien Swarm: Reactive Drop (un joc co-op gratuit pe Source) ca exemplu. Aceeași abordare ar trebui să funcționeze și pentru alte servere dedicate Windows-only pe Source.
Mai întâi, verifică dacă chiar nu există un server pentru Linux
Nu presupune nimic. Întreabă direct Steam înainte să apelezi la Wine. Îndreaptă steamcmd către aplicație și citește lista ei de platforme:
steamcmd +login anonymous +app_info_print <appid> +quit \
| grep -iE "oslist|name"Dacă aplicația serverului dedicat are doar „oslist windows”, nu există niciun build nativ pentru Linux la care să apelezi. Poți încerca și să forțezi o instalare pentru Linux; când chiar nu există un depot Linux, eșuează rapid:
steamcmd +@sSteamCmdForcePlatformType linux \
+login anonymous +app_update <appid> validate +quit
# ERROR! Failed to install app '<appid>' (Missing configuration)Eroarea asta, plus faptul că nu apare niciun fișier ELF, confirmă situația. Acum Wine e calea de urmat. Instalează serverul ȘI app 1007 (Steamworks Common Redistributables) în același folder, cu tipul de platformă windows. App 1007 aduce DLL-urile Steam de care are nevoie serverul, iar de ce, vei vedea la Pasul 2:
steamcmd +@sSteamCmdForcePlatformType windows +login anonymous \
+force_install_dir /path/to/server \
+app_update <appid> validate \
+app_update 1007 validate \
+quitDe ce eșuează încercarea naivă cu Wine
Rularea serverului direct din Wine se lovește de două probleme la rând:
- Fără consolă: serverul are nevoie de un terminal real. Dacă redirecționezi intrarea din /dev/null, primești CTextConsoleWin32::GetLine: !GetNumberOfConsoleInputEvents și nu pornește niciodată.
- Nu se poate încărca biblioteca Steam: chiar și după ce pornește, afișează "Unable to load Steam support library" și nu se înregistrează niciodată la Steam, așa că nimeni nu îl poate găsi sau i se poate alătura.
Ambele se pot rezolva. Iată rețeta completă.
Pasul 1: oferă-i un terminal real (PTY)
O mașină headless nu are terminal, iar serverul Windows cu consolă refuză să pornească fără unul. Împachetează lansarea în script, care alocă un pseudo-terminal, și folosește Xvfb pentru un display fals:
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.logDoar atât e suficient ca serverul să încarce o hartă și să lege portul de joc. Dar tot nu poate comunica cu Steam.
Pasul 2: două DLL-uri Steam, din două surse diferite
Motorul Source are nevoie de AMBELE, steamclient.dll și steam.dll, lângă exe-ul serverului, iar aici e capcana care ne-a costat o rundă întreagă de debugging în plus: ele vin din locuri DIFERITE, iar app 1007 îți dă doar UNA dintre ele.
- steamclient.dll: provine din app 1007 (Steamworks Common Redistributables), pe care l-ai instalat la Pasul 1. Este varianta canonică, cu versiunea potrivită, întreținută de Valve.
- steam.dll: NU se află în app 1007. Face parte din CLIENTUL Steam, iar singura metodă curată de a-l obține este să rulezi o dată steamcmd.exe pentru Windows sub Wine, care se auto-actualizează și pune steam.dll (plus steamclient.dll) în propriul folder.
Așadar, inițializează steam.dll cu steamcmd.exe sub Wine, apoi copiază ambele DLL-uri lângă executabilul serverului:
# 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" .Pasul 3: de ce steam.dll este piesa care contează
Asta e partea pe care aproape nimeni n-o scrie nicăieri. Eroarea spune „Unable to load Steam support library”, iar biblioteca la care se referă nu e steamclient.dll, ci steam.dll. Motorul Source caută steam.dll lângă propriul executabil ca să pornească întregul lanț Steam. Cu doar steamclient.dll prezent (care e tot ce îți oferă app 1007), tot eșuează; în momentul în care steam.dll ajunge lângă .exe, jurnalul trece de la eșec la succes:
Connection to Steam servers successful.
VAC secure mode is activated.VAC nu se activează decât dacă serverul e autentificat corect ca gameserver, deci acea linie e dovada că s-a înregistrat. Majoritatea serverelor Source se autentifică aici anonim și nu au nevoie de un Game Server Login Token (GSLT). Doar câteva jocuri (precum CS2) necesită unul.
Capcana: A2S nu mai răspunde, dar serverul funcționează normal
Iată capcana care ne-a consumat cel mai mult timp și motivul pentru care aproape am renunțat. Sub Wine, serverul NU răspunde la A2S_INFO, interogarea UDP pe care uneltele o folosesc ca să citească numele serverului, harta și numărul de jucători. Interoghează-l și fiecare port dă timeout, chiar și de pe aceeași mașină. Dacă folosești A2S ca health check, serverul pare complet mort.
Nu e mort. Faptul că A2S tace sub Wine nu împiedică jucătorii reali să se conecteze. Browserul de servere din joc afișează serverele din lista master a Steam (în care serverul se înscrie singur), iar o conectare directă folosește protocolul jocului, nu A2S. Deci testul real e un client care se conectează, nu o interogare care primește răspuns. Când în sfârșit am încercat, un jucător real s-a conectat și a jucat din prima încercare:
Client "player" connected (10.0.0.5:27005).
1/ 8 on map <mapname>Lecția practică: pentru un server găzduit prin Wine, nu face health check cu A2S. Verifică ceva care reflectă cu adevărat dacă e activ, cum ar fi linia „VAC secure mode is activated” din jurnal, linia cu numărul de jucători sau o simplă verificare că portul UDP al jocului e deschis.
Funcționează asta pentru orice joc Windows?
Să fim sinceri în privința limitelor. Am demonstrat asta pe un server cu motorul Source, iar aceeași rețetă (PTY, un runtime construit cu steamcmd, steam.dll lângă exe) ar trebui să funcționeze și pentru alte servere dedicate Windows-only pe Source. Jocurile pe alte motoare integrează Steam altfel, așa că tratează-le ca experimente separate. Două lucruri de așteptat oricum: pornirile sunt mai lente decât pe Linux nativ (Wine plus pasul steamcmd plus autentificarea Steam), iar comportamentul de A2S tăcut descris mai sus probabil se va aplica tuturor.
Sau evită tot procesul
Genul ăsta de bătaie de cap care îți mănâncă o după-amiază întreagă. Dacă vrei doar serverul, noi rulăm flota de Linux și toată instalația Wine pentru tine, la oră, cu IP public din primul minut. Vezi ce găzduim pe 2hours.gg.