2hours.gg/

Serveurs de jeu à l'heure. Paie seulement quand tu joues.

Comment faire tourner un serveur de jeu Windows uniquement sur Linux

Certains jeux Steam ne fournissent qu'un serveur dédié Windows. Il n'y a pas de binaire Linux dans le dépôt, donc le conseil habituel est "lance-le sur une machine Windows." Ce n'est pas obligatoire. Avec Wine, tu peux faire tourner le serveur Windows sur une machine Linux normale, et il se connectera à Steam et acceptera de vrais joueurs. Voici la recette exacte qui a marché pour nous, avec Alien Swarm: Reactive Drop (un jeu co-op Source gratuit) comme exemple. La même approche devrait fonctionner pour d'autres serveurs dédiés Source disponibles uniquement sur Windows.

D'abord, vérifie qu'il n'existe vraiment pas de serveur Linux

Ne suppose rien. Demande directement à Steam avant de te tourner vers Wine. Pointe steamcmd sur l'app et lis sa liste de plateformes :

steamcmd +login anonymous +app_info_print <appid> +quit \
  | grep -iE "oslist|name"

Si l'app du serveur dédié est en "oslist windows" uniquement, il n'y a pas de build Linux natif de secours. Tu peux aussi essayer de forcer une installation Linux ; quand il n'y a vraiment aucun dépôt Linux, ça échoue tout de suite :

steamcmd +@sSteamCmdForcePlatformType linux \
  +login anonymous +app_update <appid> validate +quit
# ERROR! Failed to install app '<appid>' (Missing configuration)

Cette erreur, et l'absence de fichiers ELF, le confirment. Wine est donc la voie à suivre. Installe le serveur ET l'app 1007 (les Steamworks Common Redistributables) dans le même dossier, avec le type de plateforme windows. L'app 1007 fournit les DLL Steam dont le serveur a besoin, et tu verras pourquoi à l'étape 2 :

steamcmd +@sSteamCmdForcePlatformType windows +login anonymous \
  +force_install_dir /path/to/server \
  +app_update <appid> validate \
  +app_update 1007 validate \
  +quit

Pourquoi la tentative naïve avec Wine échoue

Lancer le serveur directement depuis Wine se heurte à deux murs coup sur coup :

  • Pas de console: le serveur attend un vrai terminal. Rediriger depuis /dev/null donne CTextConsoleWin32::GetLine: !GetNumberOfConsoleInputEvents et il ne démarre jamais.
  • Impossible de charger la bibliothèque Steam: même une fois démarré, il affiche "Unable to load Steam support library" et ne s'enregistre jamais auprès de Steam, donc personne ne peut le trouver ni le rejoindre.

Les deux se corrigent. Voici la recette complète.

Étape 1 : donne-lui un vrai terminal (PTY)

Une machine sans écran n'a pas de terminal, et le serveur console Windows refuse de tourner sans. Enveloppe le lancement dans script, qui alloue un pseudo-terminal, et utilise Xvfb pour un faux affichage :

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.log

Rien que ça permet au serveur de charger une map et de lier son port de jeu. Mais il ne peut toujours pas dialoguer avec Steam.

Étape 2 : deux DLL Steam, deux sources différentes

Le moteur Source a besoin des DEUX, steamclient.dll et steam.dll, à côté de l'exe du serveur, et voici le piège qui nous a coûté une manche de débogage supplémentaire : elles viennent d'endroits DIFFÉRENTS, et l'app 1007 ne t'en donne qu'UNE seule.

  • steamclient.dll: vient de l'app 1007 (Steamworks Common Redistributables), que tu as installée à l'étape 1. Canonique, de version cohérente, maintenue par Valve.
  • steam.dll: n'est PAS dans l'app 1007. Elle fait partie du CLIENT Steam, et la seule façon propre de l'obtenir est de lancer la steamcmd.exe Windows une fois sous Wine, qui se met à jour toute seule et dépose steam.dll (plus steamclient.dll) dans son propre dossier.

Amorce donc steam.dll avec steamcmd.exe sous Wine, puis copie les deux DLL à côté de l'exe du serveur :

# 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" .

Étape 3 : pourquoi steam.dll est la pièce qui compte

C'est la partie que presque personne ne note. L'erreur dit "Unable to load Steam support library," et la bibliothèque de support en question n'est pas steamclient.dll, c'est steam.dll. Le moteur Source cherche steam.dll à côté de son propre exécutable pour amorcer toute la chaîne Steam. Avec seulement steamclient.dll présent (et c'est tout ce que te donne l'app 1007), ça échoue toujours ; dès que steam.dll est à côté du .exe, le log bascule de l'échec au succès :

Connection to Steam servers successful.
VAC secure mode is activated.

VAC ne s'active que si le serveur est un gameserver correctement connecté, donc cette ligne est ta preuve qu'il s'est enregistré. La plupart des serveurs Source se connectent ici de façon anonyme et n'ont besoin d'aucun Game Server Login Token (GSLT). Seuls quelques jeux (comme CS2) en exigent un.

Le piège : A2S devient muet mais le serveur va bien

Voici le piège qui nous a coûté le plus de temps, et la raison pour laquelle on a failli abandonner. Sous Wine, le serveur ne répond PAS à A2S_INFO, la requête UDP que les outils utilisent pour lire le nom, la map et le nombre de joueurs d'un serveur. Interroge-le et chaque port arrive à expiration, même depuis la même machine. Si tu utilises A2S comme health check, le serveur a l'air complètement mort.

Il n'est pas mort. Le silence d'A2S sous Wine n'empêche pas les vrais joueurs de rejoindre. Le navigateur de serveurs en jeu liste les serveurs depuis la master list de Steam (que le serveur alimente de lui-même), et une connexion directe utilise le protocole du jeu, pas A2S. Le vrai test, c'est donc un client qui se connecte, pas une requête qui répond. Quand on a fini par essayer, un vrai joueur s'est connecté et a joué du premier coup :

Client "player" connected (10.0.0.5:27005).
1/ 8 on map <mapname>

La leçon pratique : pour un serveur hébergé sous Wine, ne fais pas de health check avec A2S. Vérifie quelque chose qui reflète vraiment l'activité, comme la ligne "VAC secure mode is activated" dans le log, la ligne du nombre de joueurs, ou un simple contrôle que le port UDP du jeu est bien lié.

Est-ce que ça marche pour tous les jeux Windows ?

Sois honnête sur la portée. On l'a prouvé sur un serveur moteur Source, et la même recette (PTY, un runtime construit par steamcmd, steam.dll à côté de l'exe) devrait marcher pour d'autres serveurs dédiés Source disponibles uniquement sur Windows. Les jeux sur d'autres moteurs intègrent Steam différemment, alors traite-les comme des expériences distinctes. Deux choses à prévoir dans tous les cas : les démarrages sont plus lents que sur Linux natif (Wine plus l'étape steamcmd plus la connexion Steam), et le comportement A2S muet ci-dessus s'appliquera probablement à tous.

Ou saute tout ça

C'est le genre de bricolage qui bouffe un après-midi. Si tu veux juste le serveur, on gère le parc Linux et la tuyauterie Wine pour toi, à l'heure, avec une IP publique dès la première minute. Regarde ce qu'on héberge sur 2hours.gg.

Voir aussi

← Retour à tous les guides