Alcuni giochi Steam distribuiscono solo un server dedicato per Windows. Non c'è nessun binario Linux nel depot, quindi il consiglio classico è "fallo girare su una macchina Windows." Non è obbligatorio. Con Wine puoi far girare il server Windows su una normale macchina Linux, e questo si connetterà a Steam e accetterà giocatori reali. Questa è la ricetta esatta che ha funzionato per noi, usando Alien Swarm: Reactive Drop (un gioco co-op gratuito su motore Source) come esempio. Lo stesso approccio dovrebbe funzionare anche per altri server dedicati Source disponibili solo per Windows.
Prima di tutto, verifica che non esista davvero un server Linux
Non dare nulla per scontato. Chiedi direttamente a Steam prima di ricorrere a Wine. Punta steamcmd sull'app e leggi l'elenco delle piattaforme supportate:
steamcmd +login anonymous +app_info_print <appid> +quit \
| grep -iE "oslist|name"Se l'app del server dedicato è solo "oslist windows", non esiste una build Linux nativa a cui appoggiarsi. Puoi anche provare a forzare un'installazione Linux; quando davvero non esiste un depot Linux, fallisce subito:
steamcmd +@sSteamCmdForcePlatformType linux \
+login anonymous +app_update <appid> validate +quit
# ERROR! Failed to install app '<appid>' (Missing configuration)Quell'errore, unito al fatto che non arriva nessun file ELF, lo conferma. A questo punto Wine è la strada da seguire. Installa il server E l'app 1007 (le Steamworks Common Redistributables) nella stessa cartella, con il tipo di piattaforma windows. L'app 1007 fornisce le DLL di Steam di cui il server ha bisogno, e vedrai perché nel Passo 2:
steamcmd +@sSteamCmdForcePlatformType windows +login anonymous \
+force_install_dir /path/to/server \
+app_update <appid> validate \
+app_update 1007 validate \
+quitIl server richiede anche il runtime Microsoft Visual C++ 2019 dentro il prefisso Wine. Installalo una volta con winetricks (serve un display, quindi avvolgilo in xvfb-run):
WINEPREFIX=/wine xvfb-run -a winetricks -q vcrun2019
wineserver -wPerché il primo tentativo ingenuo con Wine fallisce
Avviare il server direttamente da Wine fa scontrare subito con due ostacoli, uno dopo l'altro:
- Nessuna console: il server richiede un vero terminale. Fare il piping da /dev/null restituisce CTextConsoleWin32::GetLine: !GetNumberOfConsoleInputEvents e non parte mai.
- Impossibile caricare la libreria Steam: anche una volta avviato, stampa "Unable to load Steam support library" e non si registra mai con Steam, quindi nessuno riesce a trovarlo o unirsi.
Entrambi si possono risolvere. Ecco la ricetta completa.
Passo 1: dagli un vero terminale (PTY)
Una macchina headless non ha terminale, e il server console di Windows si rifiuta di girare senza. Gli serve un pseudo-terminale (PTY) il cui lato di input resta aperto, che è ciò che ti dà docker run -it. Il consiglio comune è avvolgere l'avvio in script. Su una macchina senza terminale è proprio quello il bug: l'input di script arriva a fine file, anche la lettura della console del server lo vede, e il suo ciclo principale si blocca. La mappa può caricarsi, ma il server non risponde mai sui suoi socket. Avvialo invece da un piccolo wrapper Python che apre un PTY e non lo chiude mai, e usa Xvfb come display finto:
Xvfb :99 -screen 0 1024x768x24 &
export DISPLAY=:99 WINEPREFIX=/wine
cat > launch_pty.py <<'EOF'
import os, sys
cmd = ["wine", "srcds_console.exe", "-console", "-condebug",
"-game", "<gamedir>", "+map", "<map>", "-port", "27015"]
pid, master = os.forkpty()
if pid == 0:
os.execvp(cmd[0], cmd)
# Parent: never close master, so the server's input stays open.
# Copy the server output to our own stdout.
while True:
try:
data = os.read(master, 4096)
except OSError:
break
if not data:
break
sys.stdout.buffer.write(data)
sys.stdout.flush()
_, status = os.waitpid(pid, 0)
sys.exit(os.waitstatus_to_exitcode(status))
EOF
python3 launch_pty.pyQuesto da solo basta a far caricare una mappa al server e a far aprire la sua porta di gioco. Ma il server ancora non riesce a parlare con Steam.
Passo 2: due DLL di Steam, due fonti diverse
Il motore Source ha bisogno SIA di steamclient.dll SIA di steam.dll accanto all'exe del server, ed ecco la trappola che ci è costata un intero giro extra di debug: le due DLL arrivano da fonti DIVERSE, e l'app 1007 te ne dà solo UNA.
- steamclient.dll: viene dall'app 1007 (Steamworks Common Redistributables), che hai installato al passaggio 1. Ufficiale, con la versione corretta, mantenuta da Valve.
- steam.dll: NON fa parte dell'app 1007. È parte del CLIENT Steam, e l'unico modo pulito per ottenerlo è eseguire una volta lo steamcmd.exe per Windows sotto Wine, che si autoaggiorna e crea steam.dll (oltre a steamclient.dll) nella sua cartella.
Quindi genera steam.dll con steamcmd.exe sotto Wine, poi copia entrambe le DLL accanto all'eseguibile del server:
# 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" .Passo 3: perché steam.dll è il pezzo che conta davvero
Questa è la parte che quasi nessuno scrive da nessuna parte. L'errore dice "Unable to load Steam support library," e la libreria di supporto in questione non è steamclient.dll, è steam.dll. Il motore Source cerca steam.dll accanto al proprio eseguibile per avviare l'intera catena Steam. Con la sola steamclient.dll presente (che è tutto ciò che ti dà l'app 1007) continua a fallire; nel momento in cui steam.dll è accanto al .exe, il log passa dal fallimento al successo:
Connection to Steam servers successful.
VAC secure mode is activated.VAC non si attiva a meno che il server non abbia effettuato un login corretto come gameserver, quindi quella riga è la prova che si è registrato. La maggior parte dei server Source qui accede in modo anonimo e non ha bisogno di un Game Server Login Token (GSLT). Solo pochi giochi (come CS2) ne richiedono uno.
La trappola: A2S tace
Ecco il problema che ci è costato più tempo. Con il wrapper script, il server NON rispondeva ad A2S_INFO, la query UDP che gli strumenti usano per leggere nome, mappa e numero di giocatori di un server. Ogni query andava in timeout, anche dalla stessa macchina, quindi il server sembrava del tutto morto. All'inizio abbiamo dato la colpa a Wine. Era il ciclo principale bloccato del Passo 1: il server non leggeva affatto i suoi socket.
Con il PTY tenuto aperto, il server risponde normalmente ad A2S e giocatori reali possono entrare. La prova finale resta un client che si connette, non una query che risponde. Una volta sistemato il PTY, un giocatore reale si è connesso e ha giocato:
Client "player" connected (10.0.0.5:27005).
1/ 8 on map <mapname>La lezione pratica: se un server ospitato con Wine carica la mappa ma A2S tace, non dare subito la colpa a Wine. Controlla come è collegata la console. Una porta UDP occupata non prova che il server sia vivo, perché un server bloccato tiene la porta occupata mentre i pacchetti si accumulano senza essere letti.
Funziona con ogni gioco per Windows?
Siamo onesti sulla portata. L'abbiamo provato su un server con motore Source, e la stessa ricetta (PTY, un runtime costruito con steamcmd, steam.dll accanto all'exe) dovrebbe funzionare per altri server dedicati Source solo Windows. I giochi su altri motori integrano Steam in modo diverso, quindi trattali come esperimenti separati. Una cosa da aspettarsi in ogni caso: gli avvii sono più lenti che su Linux nativo (Wine più il passo steamcmd più il login Steam).
Oppure salta tutto questo
È il tipo di lavoro infinito che si mangia un pomeriggio. Se vuoi solo il server, gestiamo noi la flotta Linux e l'impianto Wine, a ore, con un IP pubblico dal primo minuto. Alien Swarm: Reactive Drop non è ancora nelle nostre pagine di deploy pubbliche, ma altri server solo Windows sì, come Wreckfest e rFactor 2. Vedi tutto ciò che ospitiamo su 2hours.gg.