Một số game trên Steam chỉ phát hành server dành riêng cho Windows. Không có bản binary Linux nào trong depot, nên lời khuyên thường gặp là "chạy nó trên máy Windows." Bạn không cần phải làm vậy. Với Wine, bạn có thể chạy server Windows trên một máy Linux bình thường, và nó vẫn kết nối được với Steam và nhận người chơi thật. Đây chính xác là công thức đã hiệu quả với chúng tôi, lấy Alien Swarm: Reactive Drop (một game co-op Source miễn phí) làm ví dụ. Cách làm này cũng nên áp dụng được cho các server dành riêng Source chỉ có trên Windows khác.
Trước tiên, kiểm tra xem có thật sự không có server Linux không
Đừng giả định. Hãy hỏi thẳng Steam trước khi nghĩ đến Wine. Trỏ steamcmd vào app và đọc danh sách nền tảng của nó:
steamcmd +login anonymous +app_info_print <appid> +quit \
| grep -iE "oslist|name"Nếu app server dành riêng chỉ có "oslist windows", thì không có bản build Linux native nào để dựa vào. Bạn cũng có thể thử ép cài đặt bản Linux; khi thật sự không có depot Linux thì nó báo lỗi ngay:
steamcmd +@sSteamCmdForcePlatformType linux \
+login anonymous +app_update <appid> validate +quit
# ERROR! Failed to install app '<appid>' (Missing configuration)Lỗi đó, cùng với việc không có file ELF nào tải về, đã xác nhận điều này. Giờ thì Wine là con đường. Cài server VÀ app 1007 (Steamworks Common Redistributables) vào cùng một thư mục, với kiểu nền tảng windows. App 1007 cung cấp các DLL Steam mà server cần, và bạn sẽ hiểu lý do ở Bước 2:
steamcmd +@sSteamCmdForcePlatformType windows +login anonymous \
+force_install_dir /path/to/server \
+app_update <appid> validate \
+app_update 1007 validate \
+quitVì sao cách thử Wine ngây thơ lại thất bại
Chạy server thẳng từ Wine đâm vào hai bức tường liên tiếp:
- Không có console: server cần một terminal thật. Chuyển hướng từ /dev/null sẽ cho ra CTextConsoleWin32::GetLine: !GetNumberOfConsoleInputEvents và nó không bao giờ khởi động.
- Không nạp được thư viện Steam: kể cả khi đã khởi động, nó in ra "Unable to load Steam support library" và không bao giờ đăng ký với Steam, nên không ai tìm thấy hay vào được.
Cả hai đều khắc phục được. Đây là công thức đầy đủ.
Bước 1: cấp cho nó một terminal thật (PTY)
Máy headless không có terminal, và server console Windows từ chối chạy nếu thiếu nó. Bọc lệnh khởi chạy trong script, thứ cấp phát một pseudo-terminal, và dùng Xvfb làm màn hình giả:
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.logChỉ vậy thôi đã đủ để server nạp một map và bind cổng game của nó. Nhưng nó vẫn chưa nói chuyện được với Steam.
Bước 2: hai DLL Steam, hai nguồn khác nhau
Engine Source cần CẢ HAI, steamclient.dll và steam.dll, nằm cạnh file exe của server, và đây là cái bẫy khiến chúng tôi mất trọn một vòng gỡ lỗi nữa: chúng đến từ những NƠI KHÁC NHAU, và app 1007 chỉ cho bạn MỘT trong số đó.
- steamclient.dll: đến từ app 1007 (Steamworks Common Redistributables), thứ bạn đã cài ở Bước 1. Chuẩn, khớp phiên bản, do Valve duy trì.
- steam.dll: KHÔNG có trong app 1007. Nó là một phần của Steam CLIENT, và cách sạch sẽ duy nhất để có nó là chạy steamcmd.exe của Windows một lần dưới Wine, thứ tự cập nhật và đặt steam.dll (cùng steamclient.dll) vào thư mục riêng của nó.
Vậy nên hãy bootstrap steam.dll bằng steamcmd.exe dưới Wine, rồi copy cả hai DLL vào cạnh file exe của 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" .Bước 3: vì sao steam.dll mới là mảnh ghép quan trọng
Đây là phần gần như không ai ghi lại. Lỗi ghi "Unable to load Steam support library," và thư viện support mà nó nhắc đến không phải steamclient.dll, mà là steam.dll. Engine Source tìm steam.dll ngay cạnh file thực thi của chính nó để bootstrap toàn bộ chuỗi Steam. Nếu chỉ có steamclient.dll (mà đó là tất cả những gì app 1007 cho bạn) thì vẫn lỗi; ngay khi steam.dll nằm cạnh file .exe, log lật từ thất bại sang thành công:
Connection to Steam servers successful.
VAC secure mode is activated.VAC sẽ không kích hoạt trừ khi server là một gameserver đã đăng nhập đúng cách, nên dòng đó là bằng chứng nó đã đăng ký. Hầu hết server Source đăng nhập ẩn danh ở đây và không cần Game Server Login Token (GSLT). Chỉ vài game (như CS2) mới cần.
Cái bẫy: A2S im lặng nhưng server vẫn ổn
Đây là chỗ oái oăm ngốn của chúng tôi nhiều thời gian nhất, và là lý do chúng tôi suýt bỏ cuộc. Dưới Wine, server KHÔNG trả lời A2S_INFO, truy vấn UDP mà các công cụ dùng để đọc tên, map và số người chơi của một server. Truy vấn nó và mọi cổng đều timeout, ngay cả từ chính máy đó. Nếu bạn dùng A2S làm health check, server trông như đã chết hẳn.
Nó chưa chết. Việc A2S im lặng dưới Wine không ngăn người chơi thật vào được. Trình duyệt server trong game liệt kê server từ master list của Steam (mà server tự đẩy lên), và kết nối trực tiếp dùng giao thức của game, không phải A2S. Nên phép thử thật sự là một client kết nối được, chứ không phải một truy vấn có phản hồi. Khi cuối cùng chúng tôi thử, một người chơi thật đã kết nối và chơi ngay lần đầu:
Client "player" connected (10.0.0.5:27005).
1/ 8 on map <mapname>Bài học thực tế: với một server chạy trên Wine, đừng health check bằng A2S. Hãy kiểm tra thứ gì đó thật sự phản ánh việc server còn sống, như dòng "VAC secure mode is activated" trong log, dòng số người chơi, hoặc một phép kiểm tra đơn giản rằng cổng UDP của game đã được bind.
Cách này có hiệu quả với mọi game Windows không?
Hãy thành thật về phạm vi. Chúng tôi đã chứng minh nó trên một server engine Source, và cùng công thức đó (PTY, một runtime dựng bằng steamcmd, steam.dll nằm cạnh exe) nên hiệu quả với các server dành riêng Source chỉ có trên Windows khác. Các game trên engine khác tích hợp Steam theo cách khác, nên hãy coi chúng là những thử nghiệm riêng. Dù thế nào cũng có hai điều cần lường trước: khởi động chậm hơn Linux native (Wine cộng bước steamcmd cộng đăng nhập Steam), và hành vi A2S im lặng nói trên nhiều khả năng sẽ áp dụng cho tất cả.
Hoặc bỏ qua tất cả những thứ này
Đây là kiểu việc vặt lằng nhằng ngốn cả một buổi chiều. Nếu bạn chỉ muốn có server, chúng tôi vận hành cả dàn máy Linux và phần Wine giúp bạn, tính theo giờ, có IP công khai ngay từ phút đầu. Xem những gì chúng tôi host trên 2hours.gg.