خوادم ألعاب بالساعة. ادفع فقط عندما تلعب.

كيف تشغّل خادم لعبة مخصص لـ Windows فقط على Linux

بعض ألعاب Steam توفّر خادمًا مخصصًا لـ Windows فقط. لا يوجد ملف Linux ثنائي في المستودع (depot)، لذا فالنصيحة المعتادة هي "شغّله على جهاز Windows." لست بحاجة إلى ذلك. مع Wine، يمكنك تشغيل خادم Windows على جهاز Linux عادي، وسيتصل بـ Steam ويقبل لاعبين حقيقيين. هذه هي الوصفة الدقيقة التي نجحت معنا، باستخدام Alien Swarm: Reactive Drop (لعبة Source تعاونية مجانية) كمثال. المقاربة نفسها ينبغي أن تصلح لخوادم Source المخصصة الأخرى المخصصة لـ Windows فقط.

أولًا، تأكد أنه لا يوجد فعلًا خادم 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 هو الطريق. ثبّت الخادم والتطبيق 1007 (وهو Steamworks Common Redistributables) في المجلد نفسه، بنوع المنصة windows. يجلب التطبيق 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 يرفض العمل بدونها. غلّف الإطلاق في سكربت يخصص طرفية زائفة (pseudo-terminal)، واستخدم 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 الخادم، وهنا الفخ الذي كلّفنا جولة تصحيح كاملة إضافية: إنهما يأتيان من مكانين مختلفين، والتطبيق 1007 يمنحك واحدة منهما فقط.

  • steamclient.dll: تأتي من التطبيق 1007 (Steamworks Common Redistributables)، الذي ثبّتّه في الخطوة 1. أصلية، بإصدار متوافق، وتصونها Valve.
  • steam.dll: ليست في التطبيق 1007. إنها جزء من عميل (CLIENT) Steam، والطريقة النظيفة الوحيدة للحصول عليها هي تشغيل steamcmd.exe الخاص بـ Windows مرة واحدة تحت 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 وحده (وهو كل ما يمنحه لك التطبيق 1007) يظل يفشل؛ وفي اللحظة التي تصبح فيها steam.dll بجانب ملف الـ .exe، يتحول السجل من الفشل إلى النجاح:

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

لا يُفعَّل VAC ما لم يكن الخادم gameserver مسجّل الدخول بشكل صحيح، لذا فإن هذا السطر هو دليلك على أنه سجّل نفسه. معظم خوادم 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) ينبغي أن تعمل مع خوادم Source المخصصة الأخرى المخصصة لـ Windows فقط. الألعاب على محركات أخرى تدمج Steam بشكل مختلف، لذا عاملها كتجارب منفصلة. أمران يجب توقعهما على أي حال: الإقلاع أبطأ منه في Linux الأصلي (Wine زائد خطوة steamcmd زائد تسجيل الدخول إلى Steam)، وسلوك صمت A2S أعلاه سيسري على الأرجح على الجميع.

أو تخطَّ كل هذا

هذا النوع من العناء يلتهم أمسية كاملة. إذا كنت تريد الخادم فقط، فنحن نتولى أسطول Linux وسباكة Wine بدلًا عنك، بالساعة، مع عنوان IP عام من الدقيقة الأولى. انظر ما نستضيفه على 2hours.gg.

انظر أيضًا

العودة إلى جميع الأدلة