Néhány Steames játékhoz csak Windows dedikált szerver érhető el. A depóban nincs Linux bináris, ezért a szokásos tanács az, hogy „futtasd egy Windows gépen”. De nem kötelező. Wine segítségével a Windows szervert egy sima Linux gépen is futtathatod, és az képes lesz csatlakozni a Steamhez, valamint valódi játékosokat fogadni. Ez pontosan az a recept, ami nálunk bevált, az Alien Swarm: Reactive Drop (egy ingyenes Source co-op játék) példáján bemutatva. Ugyanez a módszer más, csak Windowsra elérhető Source dedikált szervereknél is működhet.
Először ellenőrizd, hogy tényleg nincs Linux szerver
Ne feltételezz semmit. Kérdezd meg közvetlenül a Steamet, mielőtt a Wine-hoz nyúlnál. Irányítsd a steamcmd-t az alkalmazásra, és olvasd ki a platformlistáját:
steamcmd +login anonymous +app_info_print <appid> +quit \
| grep -iE "oslist|name"Ha a dedikált szerver alkalmazás „oslist windows” értékű, akkor nincs natív Linux build, amire visszaválthatnál. Megpróbálhatod erőltetni a Linux telepítést is; ha valóban nincs Linux depó, ez gyorsan hibával leáll:
steamcmd +@sSteamCmdForcePlatformType linux \
+login anonymous +app_update <appid> validate +quit
# ERROR! Failed to install app '<appid>' (Missing configuration)Ez a hiba, és hogy egyetlen ELF fájl sem kerül a helyére, megerősíti ezt. Innentől a Wine az út. Telepítsd a szervert ÉS az app 1007-et (a Steamworks Common Redistributables csomagot) ugyanabba a mappába, windows platformtípussal. Az app 1007 tartalmazza a szervernek szükséges Steam DLL-eket, és a 2. lépésben ki fog derülni, miért:
steamcmd +@sSteamCmdForcePlatformType windows +login anonymous \
+force_install_dir /path/to/server \
+app_update <appid> validate \
+app_update 1007 validate \
+quitMiért bukik el a naiv Wine-próbálkozás
Ha a szervert egyből Wine-ból futtatod, két akadályba is beleütközöl egymás után:
- Nincs konzol: a szerver valódi terminált vár. Ha /dev/null-ból pipe-olod, a CTextConsoleWin32::GetLine: !GetNumberOfConsoleInputEvents hibát kapod, és sosem indul el.
- Nem tölthető be a Steam-könyvtár: még ha el is indul, kiírja, hogy „Unable to load Steam support library”, és sosem regisztrál a Steamnél, így senki sem találja meg vagy csatlakozik hozzá.
Mindkettő megoldható. Íme a teljes recept.
1. lépés: adj neki egy valódi terminált (PTY)
Egy headless gépnek nincs terminálja, a Windows konzolos szerver pedig nem hajlandó elindulni terminál nélkül. Csomagold be az indítást a script parancsba, ami pszeudo-terminált allokál, és használj Xvfb-t egy hamis kijelzőhöz:
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.logEz önmagában elég ahhoz, hogy a szerver betöltsön egy pályát, és lefoglalja a játékportját. De a Steammel még mindig nem tud kommunikálni.
2. lépés: két Steam DLL, két különböző forrás
A Source engine-nek MIND a steamclient.dll, MIND a steam.dll fájlra szüksége van a szerver exe mellett, és itt jön a csapda, ami egy teljes plusz hibakeresési kört emésztett fel: ezek KÜLÖNBÖZŐ helyekről származnak, az app 1007 pedig csak az EGYIKET adja meg.
- steamclient.dll: az app 1007-ből (Steamworks Common Redistributables) származik, amit az 1. lépésben telepítettél. Hivatalos, verzióhelyes, a Valve tartja karban.
- steam.dll: NEM része az app 1007-nek. A Steam KLIENS része, és az egyetlen tiszta módja a megszerzésének, ha egyszer lefuttatod a Windows steamcmd.exe-t Wine alatt, ami frissíti magát, és lerakja a steam.dll-t (plusz a steamclient.dll-t) a saját mappájába.
Szóval indítsd el a steam.dll-t a steamcmd.exe-vel Wine alatt, majd másold mindkét DLL-t a szerver exe mellé:
# 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" .3. lépés: miért a steam.dll a lényeg
Ezt a részt szinte senki nem írja le sehol. A hibaüzenet szerint „Unable to load Steam support library”, és az érintett támogató könyvtár nem a steamclient.dll, hanem a steam.dll. A Source engine a saját futtatható fájlja mellett keresi a steam.dll-t, hogy elindítsa a teljes Steam-láncot. Ha csak a steamclient.dll van jelen (amit az app 1007 önmagában ad), a betöltés még mindig elbukik; amint a steam.dll is ott van az .exe mellett, a naplóban a hiba sikerre vált át:
Connection to Steam servers successful.
VAC secure mode is activated.A VAC csak akkor aktiválódik, ha a szerver megfelelően bejelentkezett gameserverként, tehát ez a sor a bizonyíték arra, hogy sikeresen regisztrált. A legtöbb Source szerver itt anonim módon jelentkezik be, és nincs szüksége Game Server Login Tokenre (GSLT). Csak néhány játék (például a CS2) igényel ilyet.
A csapda: az A2S elhallgat, de a szerver rendben van
Itt jön a csapda, ami a legtöbb időnket vitte el, és amiért majdnem feladtuk. Wine alatt a szerver NEM válaszol az A2S_INFO lekérdezésre, arra az UDP lekérdezésre, amivel az eszközök kiolvassák egy szerver nevét, pályáját és a játékosszámot. Ha lekérdezed, minden port időtúllépést jelez, még ugyanarról a gépről is. Ha az A2S-t használod állapotellenőrzésre, a szerver teljesen halottnak tűnik.
Nem halott. Az, hogy az A2S néma marad Wine alatt, nem akadályozza meg, hogy valódi játékosok csatlakozzanak. A játékon belüli szerverböngésző a Steam mesterlistájából listázza a szervereket (amelyre a szerver magától küld adatot), a közvetlen csatlakozás pedig a játék saját protokollját használja, nem az A2S-t. Az igazi teszt tehát az, hogy egy kliens csatlakozik-e, nem az, hogy egy lekérdezés válaszol-e. Amikor végre kipróbáltuk, egy valódi játékos elsőre sikeresen csatlakozott és játszott:
Client "player" connected (10.0.0.5:27005).
1/ 8 on map <mapname>A gyakorlati tanulság: egy Wine alatt futó szervernél ne az A2S-szel ellenőrizd az állapotot. Olyasmit vizsgálj, ami valóban tükrözi az élő állapotot, például a naplóban megjelenő „VAC secure mode is activated” sort, a játékosszám-sort, vagy egy egyszerű ellenőrzést arra, hogy a játék UDP portja foglalt-e.
Ez minden Windows-os játéknál működik?
Legyünk őszinték a hatókörrel kapcsolatban. Ezt egy Source engine-es szerveren bizonyítottuk, és ugyanez a recept (PTY, steamcmd-vel épített futtatókörnyezet, steam.dll az exe mellett) más, csak Windowsra elérhető Source dedikált szervereknél is működhet. A más motorokon futó játékok másképp integrálják a Steamet, ezért ezeket kezeld külön kísérletként. Két dologra mindenképp számíthatsz: az indulás lassabb, mint natív Linuxon (a Wine, a steamcmd lépés és a Steam bejelentkezés miatt), és a fenti A2S-csend valószínűleg ezeknél is jelentkezik.
Vagy hagyd ki az egészet
Ez pont az a fajta időrabló mellékvágány, ami simán elviszi a délutánodat. Ha egyszerűen csak szervert szeretnél, mi visszük a Linux-flottát és a Wine-beállítást helyetted, óradíjas alapon, nyilvános IP-vel már az első perctől. Nézd meg, mit kínálunk a 2hours.gg oldalon.