Некоторые игры Steam поставляют только выделенный сервер под Windows. В депо нет Linux-бинарника, поэтому обычный совет - "запусти его на Windows-машине". Это необязательно. С Wine вы можете запустить Windows-сервер на обычной Linux-машине, и он подключится к Steam и будет принимать живых игроков. Это точный рецепт, который сработал у нас, на примере Alien Swarm: Reactive Drop (бесплатной кооп-игры на движке Source). Тот же подход должен подойти и для других Windows-only выделенных серверов на Source.
Сначала убедитесь, что Linux-сервера действительно нет
Не гадайте. Спросите Steam напрямую, прежде чем браться за Wine. Наведите steamcmd на приложение и прочитайте его список платформ:
steamcmd +login anonymous +app_info_print <appid> +quit \
| grep -iE "oslist|name"Если у приложения выделенного сервера только "oslist windows", нативной Linux-сборки, на которую можно опереться, нет. Можно также попробовать форсировать установку под Linux; когда Linux-депо действительно нет, это быстро проваливается:
steamcmd +@sSteamCmdForcePlatformType linux \
+login anonymous +app_update <appid> validate +quit
# ERROR! Failed to install app '<appid>' (Missing configuration)Эта ошибка и отсутствие появившихся ELF-файлов подтверждают это. Теперь путь - через Wine. Установите сервер И app 1007 (Steamworks Common Redistributables) в одну папку, с типом платформы windows. App 1007 поставляет DLL Steam, которые нужны серверу, и почему - вы увидите на Шаге 2:
steamcmd +@sSteamCmdForcePlatformType windows +login anonymous \
+force_install_dir /path/to/server \
+app_update <appid> validate \
+app_update 1007 validate \
+quitПочему наивная попытка с Wine проваливается
Запуск сервера напрямую из Wine упирается в две стены подряд:
- Нет консоли: сервер ожидает настоящий терминал. Перенаправление из /dev/null даёт CTextConsoleWin32::GetLine: !GetNumberOfConsoleInputEvents, и он так и не запускается.
- Не удаётся загрузить библиотеку Steam: даже запустившись, он выводит "Unable to load Steam support library" и не регистрируется в Steam, поэтому его никто не может найти или зайти на него.
Обе исправимы. Вот полный рецепт.
Шаг 1: дайте ему настоящий терминал (PTY)
У headless-машины нет терминала, а Windows-сервер с консолью отказывается работать без него. Оберните запуск в script, который выделяет псевдотерминал, и используйте Xvfb для фиктивного дисплея:
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Уже одно это заставляет сервер загрузить карту и занять свой игровой порт. Но с Steam он по-прежнему говорить не может.
Шаг 2: две DLL Steam, два разных источника
Движку Source нужны ОБЕ, steamclient.dll и steam.dll, рядом с exe сервера, и вот ловушка, которая стоила нам целого лишнего круга отладки: они берутся из РАЗНЫХ мест, а app 1007 даёт вам только ОДНУ из них.
- steamclient.dll: берётся из app 1007 (Steamworks Common Redistributables), которую вы установили на Шаге 1. Каноническая, совпадающая по версии, поддерживаемая Valve.
- steam.dll: её НЕТ в app 1007. Она часть КЛИЕНТА Steam, и единственный чистый способ её получить, это один раз запустить Windows-steamcmd.exe под Wine, который сам обновляется и кладёт steam.dll (плюс steamclient.dll) в собственную папку.
Поэтому поднимите steam.dll через steamcmd.exe под Wine, а затем скопируйте обе DLL рядом с 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" .Шаг 3: почему именно steam.dll - решающая деталь
Это та часть, которую почти никто не записывает. Ошибка гласит "Unable to load Steam support library", и библиотека поддержки, о которой речь, - это не steamclient.dll, а steam.dll. Движок Source ищет steam.dll рядом со своим исполняемым файлом, чтобы поднять всю цепочку Steam. Если есть только steamclient.dll (а больше app 1007 вам ничего и не даёт), всё равно не работает; как только steam.dll оказывается рядом с .exe, лог переворачивается с провала на успех:
Connection to Steam servers successful.
VAC secure mode is activated.VAC не активируется, пока сервер не станет корректно залогиненным геймсервером, поэтому эта строка - ваше доказательство, что он зарегистрировался. Большинство серверов Source логинятся здесь анонимно и не требуют Game Server Login Token (GSLT). Только немногим играм (вроде CS2) он нужен.
Ловушка: A2S молчит, но сервер в порядке
Вот подвох, который стоил нам больше всего времени, и причина, по которой мы едва не сдались. Под Wine сервер НЕ отвечает на A2S_INFO, UDP-запрос, которым инструменты читают имя сервера, карту и число игроков. Запросите его, и каждый порт уходит в таймаут, даже с той же машины. Если вы используете A2S как проверку здоровья, сервер выглядит совершенно мёртвым.
Он не мёртв. То, что A2S молчит под Wine, не мешает живым игрокам заходить. Игровой браузер серверов берёт серверы из мастер-листа Steam (куда сервер сам себя добавляет), а прямое подключение использует игровой протокол, а не A2S. Так что настоящая проверка - это подключающийся клиент, а не отвечающий запрос. Когда мы наконец попробовали, живой игрок подключился и играл с первой попытки:
Client "player" connected (10.0.0.5:27005).
1/ 8 on map <mapname>Практический вывод: для сервера на Wine не проверяйте здоровье через A2S. Проверяйте то, что действительно отражает жизнеспособность, например строку "VAC secure mode is activated" в логе, строку с числом игроков или простую проверку, что игровой UDP-порт занят.
Работает ли это для любой игры на Windows?
Будьте честны насчёт охвата. Мы доказали это на сервере движка Source, и тот же рецепт (PTY, рантайм, собранный через steamcmd, steam.dll рядом с exe) должен работать для других Windows-only выделенных серверов на Source. Игры на других движках интегрируют Steam иначе, поэтому относитесь к ним как к отдельным экспериментам. В любом случае ожидайте двух вещей: запуски медленнее, чем на нативном Linux (Wine плюс шаг steamcmd плюс вход в Steam), и описанное выше молчание A2S, скорее всего, будет касаться всех.
Или пропустите всё это
Это та возня, что съедает целый день. Если вам нужен просто сервер, мы держим парк Linux и всю обвязку Wine за вас, по часам, с публичным IP с первой минуты. Посмотрите, что мы хостим на 2hours.gg.