시간 단위 게임 서버. 플레이할 때만 결제하세요.

Windows 전용 게임 서버를 Linux에서 돌리는 법

일부 Steam 게임은 Windows용 전용 서버만 제공합니다. depot에 Linux 바이너리가 없으니 늘 나오는 조언은 "Windows 머신에서 돌려라"입니다. 그럴 필요 없습니다. Wine을 쓰면 Windows 서버를 일반 Linux 머신에서 돌릴 수 있고, Steam에 접속해 실제 플레이어를 받아들입니다. 이것은 예로 Alien Swarm: Reactive Drop(무료 co-op Source 게임)을 사용해 우리가 실제로 성공한 바로 그 레시피입니다. 같은 접근법이 Windows 전용의 다른 Source 전용 서버에도 통할 것입니다.

먼저, 정말로 Linux 서버가 없는지 확인하기

넘겨짚지 마세요. Wine에 의존하기 전에 Steam에 직접 물어보세요. steamcmd를 해당 앱으로 향하게 하고 그 플랫폼 목록을 읽으세요:

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

서버의 전용 서버 앱이 "oslist windows"뿐이라면, 기댈 네이티브 Linux 빌드가 없습니다. Linux 설치를 강제로 시도해볼 수도 있습니다. 정말로 Linux depot이 없으면 그 자리에서 실패합니다:

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은 서버가 필요로 하는 Steam DLL을 가져다주며, 그 이유는 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)을 줘라

헤드리스 머신에는 터미널이 없고, Windows의 콘솔 서버는 터미널 없이는 돌기를 거부합니다. 실행을 스크립트로 감싸 의사 터미널을 할당하고, 가짜 디스플레이용으로 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단계: 두 개의 Steam DLL, 두 개의 서로 다른 출처

Source 엔진은 steamclient.dll과 steam.dll 둘 다를 서버 exe 옆에 필요로 하며, 여기 디버깅을 한 바퀴 통째로 더 쓰게 만든 함정이 있습니다: 그것들은 서로 다른 곳에서 오고, app 1007은 그중 하나만 줍니다.

  • steamclient.dll: 은 1단계에서 설치한 app 1007(Steamworks Common Redistributables)에서 옵니다. 정식이고, 호환되는 버전이며, Valve가 관리합니다.
  • steam.dll: 은 app 1007에 없습니다. 이것은 Steam 클라이언트의 일부이며, 그것을 깔끔하게 얻는 유일한 방법은 Windows용 steamcmd.exe를 Wine 아래에서 한 번 실행하는 것입니다. 그러면 자동 업데이트되어 steam.dll(과 steamclient.dll)을 자기 폴더에 놓습니다.

그러니 Wine 아래에서 steamcmd.exe로 steam.dll을 부트스트랩한 뒤, 두 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 체인 전체를 부트스트랩하기 위해 실행 파일 옆에서 steam.dll을 찾습니다. 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를 헬스 체크로 쓴다면 서버가 완전히 죽은 것처럼 보입니다.

죽은 게 아닙니다. Wine 아래에서 A2S가 침묵해도 실제 플레이어가 들어오는 것을 막지 않습니다. 게임 내 서버 브라우저는 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로 빌드한 런타임, exe 옆의 steam.dll)는 Windows 전용의 다른 Source 전용 서버에도 통할 것입니다. 다른 엔진의 게임은 Steam을 다르게 통합하므로 별개의 실험으로 취급하세요. 어쨌든 예상할 것 두 가지: 부팅이 네이티브 Linux보다 느립니다(Wine에 steamcmd 단계와 Steam 로그인이 더해집니다). 그리고 위의 A2S 침묵 동작은 아마 전부에 해당할 것입니다.

아니면 이 모든 걸 건너뛰기

이건 오후 하나를 통째로 잡아먹는 종류의 번거로움입니다. 서버만 원한다면, Linux 플릿과 Wine 배관은 우리가 맡습니다. 시간 단위로, 첫 1분부터 공개 IP와 함께요. 우리가2hours.gg에서 호스팅하는 것을 보세요.

함께 보기

← 모든 가이드로 돌아가기