Игры админов — часть 2, Quake2 + Quake3

Posted: 2014-11-29 in IT
Метки:

Я продолжаю писать цикл статей, касающихся поднятия игровых серверов.
В прошлой заметке я рассказал, как поднять свой сервер игры Doom2, а в этой заметке мы поднимём ещё парочку игрушек, созданных той же компанией id software.

Итак, мы будем поднимать сервера для пары квейков, мультиплеер которых стал классикой — Quake2 и Quake3. Поскольку сервера эти по современным меркам очень легковесны, а такие шутеры не несут на себе никаких ценных и приватных данных, то не возбраняется запустить их в той же виртуалке, где крутятся другие сервера такого типа. Запускать мы их будет от других пользователей, чтобы в случае нахождения уязвимости в игровом сервере ущерб всё равно был бы по возможности минимизирован.
Содаем пользователей заранее:

# adduser quake2
# adduser quake3

И создадим помимо домашних каталогов каталоги с основными файлами игры:

# mkdir /usr/games/quake2
# mkdir /usr/games/quake3

Переделаем немного скрипты запуска:
Сперва для Quake2:
$ cat /home/quake2/start_q2_serv.sh
#!/bin/bash

runprefix='screen -dmS ';

echo "Stop Quake 2 Server...";
echo " pkill quake2...";
pkill quake2
echo " wait 5 sec ...";
sleep 5

echo "Start Quake 2 Server...";
cd /usr/games/quake2;

$runprefix quake2_dm ./quake2 +set port 27910 +set dedicated 1 +map q2dm1
$runprefix quake2_ctf ./quake2 +set port 27911 +set game ctf +set dedicated 1 +map q2ctf1

И для Quake3:

$ cat start_q3_serv.sh
#!/bin/bash

runprefix='screen -dmS ';

echo "Stop Quake 3 Server...";
echo " pkill q3ded...";
pkill q3ded

echo " wait 5 sec ...";
sleep 5

echo "Start Quake 3 Server...";
cd /usr/games/quake3;

# dedicated 1-local-only, 2-advert on master-server

$runprefix quake3_dm ./q3ded +set net_port 27960 +set sv_fps 120 +set dedicated 2 +exec dm.cfg
$runprefix quake3_ctf ./q3ded +set net_port 27961 +set sv_fps 120 +set dedicated 2 +exec ctf.cfg

Скрипты по сути в основе своей одинаковы, меняются только параметры запуска.

Quake 2

Сервер Quake2 делается очень просто. Качаем с оф-сайта дистриб под линукс (ftp://ftp.idsoftware.com/idstuff/quake2/unix, я использовал quake2-3.20-glibc-i386-unknown-linux2.0.tar.gz), распаковываем в /usr/games/quake2.
Настройка:
В конфиг quake2.conf пишем путь к игре — /usr/games/quake2
В ./baseq2/config.cfg пишем параметры deathmatch-сервера:

set deathmatch 1
set maxclients 16
set fraglimit 50
set timelimit 20

set hostname "Quake2 DM"
set website "http://q2.your-domain.local/" s
set Admin "your@mail.address" s
set public 1
set stdlogfile 1
set rcon_password "CHANGE PASSWORD HERE"
set allow_download 1
set allow_download_maps 1
setmaster q2master.planetquake.com
map q2dm1

а в ./baseq2/maps.lst — список карт:

q2dm1 "The Edge"
q2dm2 "Tokay's Towers"
q2dm3 "The Frag Pipe"
q2dm4 "Lost Hallways"
q2dm5 "The Pits"
q2dm6 "Lava Tomb"
q2dm7 "The Slimy Place"
q2dm8 "WareHouse"

Для CTF — параметр fraglimit меняется на capturelimit, можно задать timelimit, ну и карту прописать q2ctf1, мап-лист поправить.
Осттальные моды прикручиваются к Quake2 аналогично — в /usr/games/quake2 создается каталог для мода, и он прописывается в скрипт запуска, параметр +set game «имя каталога с модом». Внутри каталога — главный конфиг config.cfg, мап-лист, pak-файлы.
Добавление карт тоже несложно — помещаем файлы карт (*.bsp) в /usr/games/quake2/baseq2 (или каталога мода)/maps, прописываем их в мап-лист, рестартим сервер. Ну и сразу подготовим фильтр для апача, чтобы пароль от RCON не подсмотрели:
# cat .htaccess
### Manage access to Q2-files from internet

# Deny by file-extensions for configs/logs
<Files ~ "\.(cfg|CFG|conf|so|sh|log|LOG|txt|out)$">
Deny from all
</Files>

# Allow by file-extensions for wad/pk3 for anyone
<Files ~ "\.(pk3|PK3|pk7|PK7|pak|PAK)$">
Allow from all
</Files>

# Get access to certain files only from trusted-network
<Files ~ "^(pak0.pak|pak1.pak)$">
Order deny,allow
deny from all
Allow from 10.2.0.0/16
</Files>

# Get access to certain files only from admins
<Files ~ "^(gamei386.so)$">
Order deny,allow
deny from all
Allow from 10.44.26.59
</Files>

Осталось положить pak0.pak и pak1.pak в baseq2, и можно запускать.

Quake 3

Делается не сильно сложнее. Скачиваем установщик ftp://ftp.idsoftware.com/idstuff/quake3/linux/linuxq3apoint-1.32b-3.x86.run, запускаем, говорим, что игру надо поставить в /usr/games/quake3, потом туда надо скопировать главный архив — pak0.pk3.
Тут есть одна засада. Этот файл, будучи по своей внутренней структуре обычным ZIP-архивом, во многих сборках часто перепаковывался, в результате чего не каждая сборка подходит. На сервер лучше всего положить оригинальный файл размером 479493658 байт с вот такими хэшами:
md5sum 1197ca3df1e65f3c380f8abc10ca43bf
sha1sum 9d588ea65e92944d3e23eeb6ec08f1dd666f4658
sha256sum 7ce8b3910620cd50a09e4f1100f426e8c6180f68895d589f80e6bd95af54bcae

Каждая карта или набор карт упакована в один pk3-архив, для прикручивания — поместить в ./baseq3 и рестартнуть сервер. Файл .htaccess почти такой же, как и дял quake2.
Больше в /usr/games/quake3 ничего менять не надо. Конфиги сервера ищутся в домашнем каталоге, куда мы их и поместим.
Идём в /home/quake3/.q3a/baseq3, и правим там следующие кофниги:
— q3config.cfg — общий конфиг с парамтерами по-умолчанию для всех типов серверов q3, котрые мы настраиваем.

# cat q3config.cfg 
seta sv_hostname "Default server"
seta server_maxpacketsmax "100"
seta sv_minPing "0"
seta sv_maxPing "0"
seta sv_floodProtect "1"
seta sv_master2 "master0.gamespy.com"
seta sv_master3 "q3master.barrysworld.com"
seta sv_master4 ""
seta sv_master5 ""
seta sv_maxrate "10000"
seta sv_snaps "40"
seta sv_maxpakets "300"
seta sv_packetdup "0"
seta sv_lanForceRate "1"
seta sv_punkbuster "0"
seta sv_strictAuth "0"
seta vm_ui "2"
seta vm_cgame "2"
seta vm_game "2"
seta com_hunkmegs "32"
seta dmflags "0"
seta fraglimit "30"
seta timelimit "20"
seta sv_maxclients "20"
seta cm_playerCurveClip "1"
seta g_maxGameClients "0"
seta capturelimit "5"
seta g_friendlyFire "0"
seta g_teamAutoJoin "1"
seta g_teamForceBalance "1"
seta g_warmup "180"
seta g_log "dm.log"
seta g_logSync "0"
seta g_banIPs ""
seta g_filterBan "1"
seta g_allowVote "1"
seta sv_allowdownload "1"
seta g_doWarmup "1"
seta map_rotate "1"
seta com_maxfps "85"
seta com_blood "1"
seta com_introplayed "0"
seta sv_fps "120"
seta com_zoneMegs "16"

— dm.cfg — конфиг дефматч-сервера:

# cat dm.cfg 
g_gametype 0                                    # 0-deadmatch 1-1v1 3-teamplay и т.д.
fraglimit 50                                    # кол-во фрагов
timelimit 20                                    # лимит времени
sv_maxclients 20                                # на сколько клиентов
sv_hostname "Q3-DM"                   # название игры (сессии)
g_motd "q3."             # стартовое приветствие
sv_privateClients 0
sv_privatePassword ""                           # пароль для закрытых серверов
rconpassword ""                 # админский пас на консоль (rcon)
                                                # это для управления сервером проги-
sv_maxRate 10000                                # Server Watch, The-All-Seeing Eye.

set server_motd1 "Welcome to Server"
set server_motd2 " Quake 3 Deathmatch "
set server_motd3 " Use \callvote map q3dm1 \maplist "

seta g_doWarmup 1
seta g_warmup 180

exec maps_dm.cfg
exec bots_dm.cfg

g_allowvote 1
set vote_allow_kick 1
set vote_allow_map 1

g_quadfactor 3
g_syncronousClients 1
g_weaponrespawn 20
g_log dm.log

Конфиг смены карт maps_dm.cfg:

#Map Смена карт (сами выбираете карты и последовательность запуска)
seta map_rotate "1"
set map_random "1"
set map_queue "1"
set map_cfgdir "cfg-maps"

set d1 "map q3dm1 ; set nextmap vstr d2"
set d2 "map q3dm2 ; set nextmap vstr d3"
set d3 "map q3dm3 ; set nextmap vstr d4"
set d4 "map q3dm4 ; set nextmap vstr d5"
set d5 "map q3dm5 ; set nextmap vstr d6"
set d6 "map q3dm6 ; set nextmap vstr d7"
set d7 "map q3dm7 ; set nextmap vstr d8"
set d8 "map q3dm8 ; set nextmap vstr d9"
set d9 "map q3dm9 ; set nextmap vstr d10"
set d10 "map q3dm10 ; set nextmap vstr d11"
set d11 "map q3dm11 ; set nextmap vstr d12"
set d12 "map q3dm12 ; set nextmap vstr d13"
set d13 "map q3dm13 ; set nextmap vstr d14"
set d14 "map q3dm14 ; set nextmap vstr d15"
set d15 "map q3dm15 ; set nextmap vstr d16"
set d16 "map q3dm16 ; set nextmap vstr d17"
set d17 "map q3dm17 ; set nextmap vstr d18"
set d18 "map q3dm18 ; set nextmap vstr d19"
set d19 "map q3dm19 ; set nextmap vstr d1"

set ead1 "map eadm1 ; set nextmap vstr ead2"
set ead2 "map eadm2 ; set nextmap vstr ead3"
set ead3 "map eadm3 ; set nextmap vstr ead4"
set ead4 "map eadm4 ; set nextmap vstr ead5"
set ead5 "map eadm5 ; set nextmap vstr ead6"
set ead6 "map eadm6 ; set nextmap vstr ead7"
set ead7 "map eadm7 ; set nextmap vstr ead8"
set ead8 "map eadm8 ; set nextmap vstr ead9"
set ead9 "map eadm9 ; set nextmap vstr ead10"
set ead10 "map eadm10 ; set nextmap vstr ead11"
set ead11 "map eadm11 ; set nextmap vstr ead12"
set ead12 "map eadm12 ; set nextmap vstr q3t1"

set q3t1 "map q3tourney1 ; set nextmap vstr q3t2"
set q3t2 "map q3tourney2 ; set nextmap vstr q3t3"
set q3t3 "map q3tourney3 ; set nextmap vstr q3t4"
set q3t4 "map q3tourney4 ; set nextmap vstr q3t5"
set q3t5 "map q3tourney5 ; set nextmap vstr q3t6"
set q3t6 "map q3tourney6 ; set nextmap vstr z3d1"

set z3d1 "map ztn3dm1 ; set nextmap vstr z3d2"
set z3d2 "map ztn3dm2 ; set nextmap vstr z3d3"
set z3d3 "map ztn3dm1-ho ; set nextmap vstr am1"

set am1 "map W_Garden ; set nextmap vstr am2"
set am2 "map Cemetery ; set nextmap vstr am3"
set am3 "map Desktop ; set nextmap vstr am4"
set am4 "map Ferrocen ; set nextmap vstr ex1"

set ex1 "map addict ; set nextmap vstr ex2"
set ex2 "map Bal3dm2 ; set nextmap vstr ex3"
set ex3 "map lloydmdm2 ; set nextmap vstr ex4"
set ex4 "map nedmaj ; set nextmap vstr ex5"
set ex5 "map nedsword ; set nextmap vstr ex6"
set ex6 "map nemesis ; set nextmap vstr ex7"
set ex7 "map overkill ; set nextmap vstr ex8"
set ex8 "map pqarena ; set nextmap vstr ex9"
set ex9 "map q3mexx1 ; set nextmap vstr ex10"
set ex10 "map q3tbdm4 ; set nextmap vstr ex11"
set ex11 "map q3zdm1 ; set nextmap vstr ex12"
set ex12 "map satan ; set nextmap vstr ex13"
set ex13 "map senndm1 ; set nextmap vstr ex14"
set ex14 "map senndm2 ; set nextmap vstr ex15"
set ex15 "map tig_den ; set nextmap vstr d1"

vstr d1

Конфиг управления ботами bots_dm.cfg:

#Bots
set bot_enable 1                        # Включаем ботов
addbot uriel 3 100                      # Добавляем бота + его хар-ки
addbot slash 2 100
addbot anarki 3 100
addbot bones 2 100
addbot klesk 3 100
addbot orbb 2 100
addbot sorlag 3 100
addbot doom 2 100
addbot xaero 3 100
addbot hossman 3 100
bot_minplayers 3        # Заменяет бота клиентом когда тот подключится
                        # Здесь поддерживатся 3 бота автоматом. При двойке кол-во ботов 
                        # будет уменьшатся (кикатся) до 1го.

Из важного — есть встроенные боты (для их корректной работы требуется наличие *.aas-файла рядом с *.bsp-файлом), свой скрипт ротации карт, голосовалка за кик читеров / смену карты, и ещё ряд параметров.
— ctf.cfg — конфиг для Capture the flag.

# cat ctf.cfg 
g_gametype 4                                    # 0-deadmatch 1-1v1 3-teamplay и т.д.
capturelimit 5                                  # кол-во фрагов
timelimit 40                                    # лимит времени
sv_maxclients 30                                # на сколько клиентов
sv_hostname "Q3-CTF"                  # название игры (сессии)
g_motd "q3.ctf"             # стартовое приветствие
sv_privateClients 0
sv_privatePassword ""                           # пароль для закрытых серверов
rconpassword ""                 # админский пас на консоль (rcon)
                                                # это для управления сервером проги-
sv_maxRate 10000                                # Server Watch, The-All-Seeing Eye.
g_teamForceBalance 1
g_teamAutoJoin 1

set server_motd1 "Welcome to Server"
set server_motd2 " Quake 3 Capture The Flag "
set server_motd3 " Use \callvote map q3ctf1 \maplist "

seta g_doWarmup 1
seta g_warmup 300

#Admin
set Administrator" "Amin"
set "Email" "amin[]domain"
set "URL" "http://q3.domain/"
set "Location" "Hell"

#Map Смена карт (сами выбираете карты и последовательность запуска)
seta map_rotate "1"
set map_random "1"
set map_queue "1"
set map_cfgdir "cfg-maps"

set c1 "map q3ctf1 ; set nextmap vstr c2"
set c2 "map q3ctf2 ; set nextmap vstr c3"
set c3 "map q3ctf3 ; set nextmap vstr c4"
set c4 "map q3ctf4 ; set nextmap vstr c5"
set c5 "map eactf1 ; set nextmap vstr c6"
set c6 "map q3tourney6_ctf ; set nextmap vstr c1"

vstr c1

#Bots
set bot_enable 1                        # Включаем ботов
addbot uriel 3 100                      # Добавляем бота + его хар-ки
addbot slash 2 100
addbot anarki 3 100
addbot bones 2 100
addbot klesk 3 100
addbot orbb 2 100
addbot sorlag 3 100
addbot doom 2 100
addbot xaero 3 100
addbot hossman 3 100
bot_minplayers 3        # Заменяет бота клиентом когда тот подключится
                        # Сдесь потдерживатся 9 ботов автоматом. При двойке кол-во ботов 
                        # будет уменьшатся (кикатся) до 1го.

g_allowvote 1
set vote_allow_kick 1
set vote_allow_map 1

g_quadfactor 3
g_syncronousClients 1
g_weaponrespawn 20
g_log ctf.log

Всё, можно запускать. Если при запуске налбладаются ошибки об отсутствии библиотек — ставим их с помощью пакетного менеджера, но мне вроде этого делать не пришлось.
Веб-сервер настраивается полностью аналогично, как мы это делали для Doom2 — отдельная запись в DNS, для неё свой виртуал-хост, в каталоге виртуал-хоста — симлинк в каталог с игрой. Не забыть проверить, что апач корреткно обработал htaccess.

Также можно прикрутить автоматическую очистку логов. Quake3 пишет логи в ~/.q3a/baseq3, имена логов заданы в окнфигах. Quake2 логов по умолчанию не пишет.

В /etc/rc.local прописываем вызовы наших скриптов, естественно, под своими пользователями:

# cat /etc/rc.d/rc.local 
#!/bin/sh

su - quake3 -c "/home/quake3/start_q3_serv.sh"
su - quake2 -c "/home/quake2/start_q2_serv.sh

После их запуска мы должны увидеть в списке процессов примерно такое:
# ps au | grep quake
quake3 769 11.1 0.6 56360 27220 pts/17 Ss+ ноя26 378:38 ./q3ded +set net_port 27960 +set sv_fps 120 +set dedicated 2 +exec dm.cfg
quake3 770 11.2 0.8 56360 37688 pts/18 Ss+ ноя26 381:48 ./q3ded +set net_port 27961 +set sv_fps 120 +set dedicated 2 +exec ctf.cfg
quake2 804 0.8 0.0 13420 1124 pts/19 Ss+ ноя26 30:27 ./quake2 +set port 27910 +set dedicated 1 +map q2dm1
quake2 805 0.8 0.0 13424 1380 pts/20 Ss+ ноя26 30:25 ./quake2 +set port 27911 +set game ctf +set dedicated 1 +map q2ctf1
root 12983 0.0 0.0 6160 920 pts/24 S+ 02:13 0:00 grep --color=auto quake

Серверы подняты, каждой игре выделен свой пользователь, можно погамать.

Теперь прикрутим автоматическое скачивание карт дял Quake3.
Изначально для этих игр скачивание идёт по их собственному внутри-игровому протоколу (основанному на UDP), что очень медленно и непрямо. Для Дума-2 юыстрое скачивание сделано сторонней тулзой, а вот нативный Q2/Q3 прямую закачку по HTTP не умеют. Зато её умеет такой порт, как ioquake3. Чтобы это работало — создаем виртуалхост в нашем апаче для мини-сайта (туда можно навесить баннеров с мониторингами), делаем симлинк такого типа:
# ls -l /var/www/html_q3/
pk3 -> /usr/games/quake3/baseq3

В файл q3config.cfg на сервере прописываем такие опции:

seta sv_dlURL "http://your-domain.local/pk3"
seta net_clientDownload "1"
seta sv_allowDownload "1"

Конфиг виртуалхоста:

# cat /etc/httpd/conf.d/games-web-servers.conf 

<Directory /var/www/html_q3>
 Options Indexes FollowSymLinks
 AllowOverride All
</Directory>

<Directory /var/www/html_q2>
 Options Indexes FollowSymLinks
 AllowOverride All
</Directory>


<VirtualHost *:80>
 DocumentRoot /var/www/html_q3
 ServerName q3.your-domain.local
</VirtualHost>

<VirtualHost *:80>
 DocumentRoot /var/www/html_q2
 ServerName q2.your-domain.local
</VirtualHost>

При такой настройке клиенты, умеющие HTTP-скачивание (ioquake3), будут скачивать недостающие карты прямо с веб-сервера полностью автоамтически, а обычные клиенты — через гораздо более медленный внутренний протокол. Работать будут оба варианта.

Также можно на сервере вместо классического сервера q3ded использовать ioquake3 — в этом случае меняется только имя бинарника, запускающего сервер, а всё остальное остаётся таким же, как и раньше.

RCON

Для управления уже запущенным сервером есть два варианта.
Первый — зайти по SSH пользователем quake3, присоединиться к screen-сессии (screen -Rx quake3_dm) и начать вводить команды.
Этот способ более безопасен против перехвата паролей из траффика и не требует никакого доп-софта, кроме ссш-клиента. Но при этом предоставляется полный доступ ко всем конфигам и файлам сервера. Тут всё понятно.
Второй — использовать rcon. Пароль тут передается совсем несекурно — он отображается при вводе в игре и идёт по сети открытым текстом, но и доступ к серверу предоставляется лишь частичный. Из плюсов — можно управлять прямо из игры.
Запустив Quake3, мы можем войти в игру, открыть консоль (кнопка [~] по умолчанию) и ввести команду \rconpassword [Пароль из конфига]
После этого мы может вводить rcon-команды типа таких:
\rcon kick CheaterName
\rcon map q2dm7
\rcon fraglimit 50
\rcon timelimit 10

и прочих. Если сервер заполнен — есть возможность послать rcon-команды из клиента, не заходя в игру, для этого сперва надо задать в консоли \rconaddress [АдресСервера:Порт], потом кинуть \rconpassword [НашПароль], а потом уже — команды.
Плюсы — сменить карту или фраглимит админ может прямо из игры, никуда не переключаясь.
Вообще через RCON управляются очень многие игровые серверы. Для стрелялок и прочих игр, не хранящих ничего ценного внутри, это отличный протокол. Самое деструктивное, что можно сделать с сервером кваки через rcon — выключить сервер. SSH-доступ более надёжен, но и возможности предоставляет более полные, в том числе и возможности что-нибудь сломать.
Пароль rcon давать кому попало не следует, иначе вам испортят игру на вашем же сервере.

P.S. На фтп-шнике ftp://ftp.idsoftware.com/idstuff/ есть ещё много чего занятного, типа вульфа-3д под айФонЪ и исходники первого Quake. А следующий выпуск на игровую тему скорее всего будет посвящен поднятию сервера моей любимой игрушки — Unreal Tournament 2004.

Ну и на заминку советую посмотреть, как классно обстебали игры современные (серия видео Call of Dooty):




Это к вопросу, почему «хорошая графика» != «хорошая игра».

- комментарии
  1. Karman:

    Будет ли про установку CS 1.6?

  2. Counter-Strike — сильно не моё. Если руки дойдут — может, напишу и про его настройку.
    Но когда — вопрос открытый.