Параметри виділеного сервера Source під Linux, частина 2

  • Запису
    • Налаштування веб-сервера
    • Налаштування ігрового сервера

    • Включення
    • Обслуговування
  • SourceTV
  • Прискорення скачування контенту (Fast Download)
    • Налаштування веб-сервера
    • Налаштування ігрового сервера

  • Боти
    • Поддержваемая карта
    • Пользовательсякая карта
Запису
Записи (Replays) в Team Fortress 2 — це можливість, на стороні сервера — створення запису останньої життя гравця, а на стороні клієнта — її перегляду, редагування, збереження і публікації. Є розширенням SourceTV.
Записи повинні бути явно дозволені в командному рядку сервера, включені і налаштовані в конфігураційному файлі, виконуваному до завантаження карти. Крім того, повинен бути попередньо настроєний веб-сервер для віддачі записів гравцям.
Налаштування веб-сервера
Для наочності ми заведемо в DNS окремий піддомен replay.example.org створимо каталог /var/www/replay.example.org, і для зручності винесемо запис логів в окремі файли і надамо можливість користувачеві game читати їх.
З-під root створюємо каталоги, встановлюємо власника (game:game) і права — користувачеві game на запис, іншим веб-серверу) — на читання. Можна заодно зробити символьні посилання для зручності. Даний веб-сервер буде спільним для обох ігрових серверів, але кожен з них буде використовувати окремі каталоги для викладання записів.
# mkdir -p /var/www/replay.example.org/{htdocs/server1,htdocs/server2,log}
# chown -R game:game /var/www/replay.example.org
# chmod -R 755 /var/www/replay.example.org
# ln -s /var/www/replay.example.org/log /home/game/log/www-replay

В нашій конфігурації за замовчуванням усі журналів веб-сервера мають власника nginx:adm і права 640, тобто вони недоступні звичайним користувачам. Коректуємо це для даного випадку:
# touch /var/www/replay.example.org/log/{access,error}.log
# chmod 644 /var/www/replay.example.org/log/*.log

Таким чином користувачеві game наші логи стануть доступні для читання. Але тільки до першої їх ротації. Виправляємо і це. В каталозі /etc/logrotate.d копіюємо файл nginx в srcds-nginx, в ньому прописуємо шлях до логів і в рядку
create 640 nginx adm
виправляємо маску прав доступу з 640 на 644:
srcds-nginx
#/etc/logrotate.d/srcds-nginx

/var/www/stat.example.org/log/*.log
/var/www/fastdl.example.org/log/*.log
/var/www/replay.example.org/log/*.log
{
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 644 nginx adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}

Тут ми шляхах для ротації вказали заодно каталоги з логами від сервера статистики HLstatsX і від сервера Fast Download.
З-під root створюємо файл конфігурації веб-сервера, /etc/nginx/conf.d/replay.example.org.conf:
replay.example.org.conf
# /etc/nginx/conf.d/replay.example.org.conf

server
{
server_name replay.example.org;
listen 80;
root /var/www/replay.example.org/htdocs;
disable_symlinks on;
autoindex off;
access_log /var/www/replay.example.org/log/access.log main;
error_log /var/www/replay.example.org/log/error.log warn;
}

Це, звичайно, дещо спрощений варіант. Так як в нашому випадку веб-сервер знаходиться на тому ж комп'ютері, що і ігрові сервера і ділить з ними один канал в інтернет, то має сенс прописати додаткові обмеження по ширині каналу для віддачі записів. Але, на відміну від налаштувань Fast Download, встановлювати додаткові перевірки по referer немає необхідності.
Прописуємо виклик replay.example.org.conf в основний файл /etc/nginx/nginx.conf якщо ще не, потім тестуємо конфігурацію і перезапускаємо nginx.
# nginx -t
# systemctl reload nginx

Далі продовжуємо як користувач game.
Налаштування ігрового сервера
За замовчуванням, при вирішенні записів, сервера при запуску будуть намагатися виконати файл конфігурації ~/tf2/tf/cfg/replay.cfg. Так як ми запису включаємо на обох серверах, окремі параметри яких обов'язково повинні бути різні, то як і в попередніх випадках, ми готуємо індивідуальні файли для кожного сервера.
У каталозі ~/tf2/tf/cfg є файл replay_example.cfg, вивчаємо його і створюємо свій власний. Для першого сервера, ~/cfg/replay1.cfg:
replay1.cfg
echo "*** ~/cfg/replay1.cfg"

replay_name "Бот для записів"

replay_local_fileserver_path /var/www/replay.example.org/htdocs/server1

replay_fileserver_offload_enable 0

replay_fileserver_host replay.example.org

replay_fileserver_path /server1

replay_enable 1

Тут:
replay_name

ім'я спеціального бота для запису, як він буде видний у списку спостерігачів (spectators).
replay_local_fileserver_path

каталог, куди будуть поміщатися готові файли із записами. Повинен бути індивідуальним для кожного ігрового сервера і доступний для читання веб-сервером.
replay_fileserver_offload_enable

якщо 1 — то записи вивантажуються по ftp на інший сервер, який вже сам їх роздає по http. Не наш випадок.
якщо 0 — то роздачею займається веб-сервер на нашій машині.
replay_fileserver_host

ім'я або ip веб-сервера
replay_fileserver_path

частина url — шлях до записів, як відображається веб-сервером.
replay_enable

власне, включає запису на сервері.
Таким чином змінних replay_local_fileserver_path, replay_fileserver_host, replay_fileserver_path і не згаданих тут replay_fileserver_protocol (="http") і replay_fileserver_port (="80") формується url виду "http://replay.example.org:80/server1", який передається клієнту для скачування записів. А мінлива replay_local_fileserver_path задає фактичне розташування каталогу файлової системи і дорівнює root з файлу конфігурації nginx + replay_fileserver_path.
Копіюємо файл в replay2.cfg, виправляємо шляху server1 -> server2
replay2.cfg
echo "*** ~/cfg/replay2.cfg"

replay_name "My replay bot"

replay_local_fileserver_path /var/www/replay.example.org/htdocs/server2

replay_fileserver_offload_enable 0

replay_fileserver_host replay.example.org

replay_fileserver_path /server2

replay_enable 1

Робимо посилання в ~/tf2/tf/cfg:
$ ln -s -v ~/cfg/replay{1,2}.cfg ~/tf2/tf/cfg/

Варто мати на увазі, що ці файли конфігурації виконуються лише при початковому запуску сервера, після autoexec.cfg. При зміні карт вони не використовуються.
Ще з більш-менш корисних консольних змінних:
replay_dopublishtest

проводить тест готовності сервера (ігрового та веб) до записів — перевірять доступність шляхів у файловій системі, ім'я веб-сервера і так далі.
replay_data_lifespan

задає кількість днів (за замовчуванням 1 добу), по закінченні яких запису на сервері позначатимуться як "несвіжі", що дозволить ручного або автоматичного очищення їх видалити.
replay_docleanup

видаляє "несвіжі" записи. З параметром 'force' видаляє взагалі всі записи.
replay_fileserver_autocleanup

за замовчуванням 0 — викл, запускає автоматичне очищення "несвіжих" записів між раундами.
replay_dofileserver_cleanup_on_start

за промовчанням 1 — вкл, при старті сервера запускає автоматичне очищення "несвіжих" записів, як в ~/tf2/tf/replay/server{1,2}, так і в каталозі веб-сервера /var/www/replay.example.org/htdocs/server{1,2}.
replay_record_voice

за промовчанням 1 — вкл, записувати голосовий чат гравців.
Список актуальних, в даній версії движка Steam, змінних можна подивитися, ввівши в консолі сервера
find replay_
.
Включення
У скрипти запуску серверів start{1,2}.sh, в командний рядок ми дописуємо:
Для першого сервера:
start1.sh
CMDLINE="...
-replay reply1.cfg -replayserverdir server1 \
...

Для другого:
start2.sh
CMDLINE="...
-replay reply2.cfg -replayserverdir server2 \
...

Тут команда "-replay" включає функції запису і при запуску сервера виконує зазначений файл конфігурації. Друга команда, "-replayserverdir" у якості параметра приймає ім'я каталогу (від шляху ~/tf2/tf/replay/), в якому кожен сервер буде накопичувати запису.
Все, можна запускати сервера і пробувати. В ігровому клієнта, в браузере серверів близько імені нашого сервера, поруч з щитком VAC з'явиться характерна іконка Записів.
При включенні записів, на сервері з'являється бот в режимі спостерігача, який, власне, і веде записи і при цьому займає один ігровий слот. Тому встановлене при запуску сервера максимальна кількість гравців "+maxplayers 24" збільшується на одного, тобто в нашому випадку стає рівним двадцяти п'яти (а при включенні SteamTV — двадцяти шести).
У старих посібниках по налаштуванню записів зазвичай вказується параметр командного рядка сервера "-replay_port", але ми про нього і не згадуємо, так як він був скасований ще в далекому 2011 році — store.steampowered.com/news/6282/
При використанні плагінів, що полегшують масові дії над гравцями (у тому числі йдуть в комплекті з SourceMod), слід обережно ставитися до боту записів. У всякому разі, не варто ненароком кикать його з сервера :)
Обслуговування
Файли записів, хоча і невеликі за розміром, але все ж займають місце на диску, як в каталозі replay, так і в /var/www/. Та буває, що, незважаючи на встановлену дату старіння в одну добу (replay_data_lifespan 1) і включену автоочистку цих каталогів (replay_dofileserver_cleanup_on_start 1), старі файли автоматично не видаляються. Навіть при ручному запуску replay_docleanup. Тому для підстраховки додамо примусову очищення старих записів, запустивши
crontab -e
і дописавши в кінець:
crontab
0 3 * * * /usr/bin/find ~/tf2/tf/replay/server{1,2}/* -type f -mtime +10 -delete
0 3 * * * /usr/bin/find /var/www/replay.example.org/htdocs/server{1,2}/* -type f -mtime +10 -delete

Попередньо непогано було б переконатися, що cron використовує шелл, що підтримує розширення дужок — "{1,2}"
Читання access.log показує, що часом гравці, а точніше їх ігрові клієнти при підключенні до нашого сервера намагаються сказати записи ігор, в які вони грали і три тижні тому.
Ще мить — слід враховувати, що Записи їдять процесорний час. Приклад завантаження наведено в кінці розділу "Боти"
SourceTV
Тепер налаштуємо SourceTV. Це стане в нагоді для онлайн трансляцій світових чемпіонатів, коли ми будемо їх проводити.
SourceTV дозволяє глядачам, за допомогою своїх клієнтів Team Fortress 2 спостерігати за ходом гри на сервері. При використанні ланцюжків проксі серверів, розмір аудиторії практично не обмежений, але в даному випадку, коли трансляція гри буде здійснюватися лише силами нашого ігрового сервера, кількість глядачів має сенс лімітувати, так як кожен з них споживає і ресурси процесора і канал в інтернет.
Так як при первинній настройці запуску ігрових серверів ми вже вказали в командному рядку "+tv_port" зі своїм номером порту для кожного сервера, то можна відразу перейти до файлів конфігурації.
Так само як і для налаштування записів, SourceTV повинен бути активований до завантаження карти, тобто команда "tv_enable 1" повинна бути виконана в командному рядку запуску сервера або в файл autoexec.cfg. До того ж, досвідченим шляхом було встановлено, що аналогічна вимога і у команди "tv_name".
Оскільки налаштування SourceTV наших серверів фіксовані і при кожній зміні карти змінюватися не плануються, то всі спільні ми включимо в autoexec.cfg, індивідуальні — в autoexec{1,2}.cfg.
~/cfg/autoexec.cfg додаємо загальні параметри:
autoexec.cfg
//...

// SourceTV
// Заголовок у вікні у глядача
tv_title "Хліба і видовищ!"

// Пароль на підключення
// tv_password ""

// Максимальну кількість глядачів
tv_maxclients 5

// Ширина каналу для кожного глядача
tv_maxrate 0

// Транслювати всі (1) або тільки POV оператора (0)
tv_transmitall 1

// Затримка у мовленні
tv_delay 20

// Дозволити людини-оператора
tv_allow_camera_man 0

// Початок запису в файл
//tv_record <filename>

// Зупинка запису
//tv_stoprecord

// Автоматичний запис
tv_autorecord 1

Тут:
tv_title

заголовок у вікні у глядача при перегляді трансляції.
tv_password

пароль на підключення до трансляції.
tv_maxclients

максимальна кількість глядачів, від 0 до 255, за замовчуванням 128. Якщо потрібна не онлайн трансляція, а лише запис гри (tv_record, tv_autorecord), то можна виставити на нуль.
tv_maxrate

максимальна ширина каналу на кожного гравця, за замовчуванням — 8000 біт/сек, при установці в 0 — без обмежень. Параметр тісно пов'язаний з попереднім параметром, особливо якщо планується повністю заповнений глядачами сервер.
tv_transmitall

за замовчуванням ("0"), глядачам передається лише те, що показує оператор SourceTV (ІІ або спеціально навчена людина). При установці в "1", глядачам передається вся інформація про грі, і вони можуть перемикатися між POV від різних гравців, або взагалі парити над/під картою. При включенні параметра в два-три рази збільшується необхідна ширина каналу для кожного глядача.
tv_delay

затримка глядачам трансляції в секундах, за замовчуванням 30. Служить для зменшення чітерства, коли глядач може давати підказки гравцеві.
tv_delaymapchange

затримувати ("1") чи ні ("0" — за замовчуванням) зміну карти, до тих пір, поки не закінчиться трансляція (з-за затримки tv_delay).
tv_delaymapchange_protect

захищає ("1" — за замовчуванням) або ні ("0") від зміни карти вручну до тих пір, поки не закінчиться раунд.
tv_allow_camera_man

дозволяти ("1" — за замовчуванням) або ні ("0") гравцям-спостерігачам ставати операторами SourceTV. Якщо "0" — то тільки автоматичне керування камерою.
tv_autorecord

при включенні ("1") автоматично починаються записуватися всі ігри в файли з іменами виду
auto-<YYYYMMDD><hhmm><ім'я карти>.dem
в каталог ~/tf2/tf, наприклад "auto-20160630-2208-koth_sawmill.dem".
При установці пароля ("tv_password <пароль>"), глядачі не зможуть підключитися з браузера серверів — їм постійно буде відмовлено з повідомленням: "Disconnect: Bad spectator password", а в консолі сервера буде написано "Dropped <гравець> from server (Bad spectator password)". Для підключення, глядачам треба буде в консолі (
~
) ігри ввести
password <пароль>
, закрити консоль, а потім спробувати підключитися. Або відразу в консолі ввести
connect 192.0.2.0:27020; password <пароль>
.
~/cfg/autoexec1.cfg дописуємо в кінець:
autoexec1.cfg
//...

// Включаємо SourceTV
tv_enable 1

// Ім'я серверу у браузері
tv_name "SourceTV at Public Server No 1"

Тут:
tv_name

ім'я SourceTV сервера, як воно буде відображатися в браузері серверів, в закладці "Спостереження".
tv_enable

включає ("1") чи ні ("0", за замовчуванням) SourceTV на сервері.
Аналогічно коригуємо ~/cfg/autoexec2.cfg
autoexec2.cfg
//...

tv_enable 1

tv_name "SoutceTV at Private Server No 2"

tv_autorecord 0

А от для другого сервера ми autoexec2.cfg відключили автоматичне записування. Існує проблема при включенні автоматичного запису ("tv_autorecord 1") на картах, підключених з Steam Workshop, у яких ім'я виглядає як "workshop/", або "workshop/.ugc" — то є в будь-якому випадку містить слеш "/", що призводить до корявому формування імені файла у tv_autorecord в схемі
auto-<YYYYMMDD><hhmm><ім'я карти>.dem
і лайки в логах виду:
Failed to write file /home/game/tf2/tf/replay/server2/sessions/20160702-074150-workshop/cp_orange_x3.ugc454299390.dmx
Failed to write file /home/game/tf2/tf/replay/server2/blocks/20160702-074150-workshop/cp_orange_x3.ugc454299390_part_0.dmx

********************************************************************************
*
* Replay recording shutting down due to publishing error! Recording will begin
* at the beginning of the next round, but may fail again.
*
********************************************************************************

ERROR: Publish timed out after 60 seconds.

і, як наслідок, відключення записів. Як варіант, можна продумати схему з використанням "tv_record", що дозволяє ручне вказівку імені файлу для запису.
При включенні SourceTV на сервері з'являється бот в режимі спостерігача, який займається трансляцією гри і при цьому займає один ігровий слот. Тому встановлене при запуску сервера максимальна кількість гравців "+maxplayers 24" збільшується на одного, тобто в нашому випадку стає рівним двадцяти п'яти (а при включенні Replay — двадцяти шести).
Отже, команди прописані, перезапускаємо сервер і дивимося, що виходить. Так як у нас так само включені записи, які теж займають свій ігровий слот, то ми бачимо:
*** ~/cfg/autoexec.cfg (global)
--------------------------------------------------------
sv_pure set to 2.
--------------------------------------------------------
maxplayers set to 25
*** ~/cfg/autoexec1.cfg
Server logging enabled.
Server data logging to file /home/game/log/server1/L1008000.log
maxplayers set to 26 (extra slot was added for SourceTV)
...
Cannot verify load for invalid steam ID [A:1:0:1]
Cannot verify load for invalid steam ID [A:1:1:1]
Recording SourceTV demo to auto-20161008-1155-cp_granary.dem...
Connection to game coordinator established.
*** ~/cfg/server1.cfg
...
SourceTV broadcast active.
Connection to Steam servers successful.
Public IP is 192.0.2.0.

Отже, на початку максимальна кількість гравців на сервері було збільшено з 24 до 25 — це відпрацював параметр командного рядка "-replay", включилися запису. Потім ще один додатковий слот був доданий для SourceTV — це спрацював "tv_enable 1" з autoexec1.cfg. На лайку про invalid steam ID [A:1:0:1] не звертаємо увагу — це наші боти запису і трансляції, заради яких сервер додав ігрові слоти. Далі почалася запис демки в файл ~/tf2/tf/auto-20161008-1155-cp_granary.dem — спрацював параметр "tv_autorecord 1" з autoexec.cfg. І нарешті нам констатували, що SourceTV broadcast active.
Запрацювало. Можна заселити якусь мапу ботами, підключитися глядачем і подивитися, як виглядає трансляція при різних режимах tv_transmitall, tv_allow_camera_man.
Може статися так, що слоти додані, а про "SourceTV broadcast active." ні слова, так і при введенні в консолі сервера команда
tv_status
воно лається "SourceTV not active.", хоча введена тут же
tv_enable
повідомляє що все ок — "tv_enable = 1 ( def. 0 )". В такому випадку треба спробувати змінити карту —
changelevel <ім'я карти>
. Якщо після зміни все запрацювало — то значить все ж SourceTV спочатку так не активувався до завантаження першої карти — треба дивитися налаштування.
Команди, які можуть стати в нагоді:
tv_record <ім'я файлу>

починає запис, що зберігається в файл < ім'я файлу>. Записуються всі події незалежно від того, що бачить оператор.
tv_stoprecord

зупиняє запис.
tv_clients

показує інформацію про підключених глядачах.
tv_msg

надіслати повідомлення всім глядачам (з'явиться посеред екрану).
tv_status

виводить коротку інформацію про статус сервера — час онлайн, FPS, кількість глядачів, використовувану смугу каналу тощо.
Список актуальних, в даній версії ігрового сервера, змінних можна подивитися, ввівши в консолі сервера
find tv_
.
Прискорення скачування контенту (Fast Download)
Якщо ми будемо використовувати на своїх серверах карти, моделі, звуки, що не входять в стандартну поставку Team Fortress 2 і відсутні в Steam Workshop, то при підключенні нового гравця йому необхідно завантажити до себе на ігровий комп'ютер наші ігрові матеріали (якщо їх у нього ще немає). За замовчуванням вони будуть викачуватися з нашого ігрового сервера — цей режим називається Slow Download. Але так як ігровий сервер це все ж не спеціалізований веб-сервер, то при частій встановленні нових користувальницьких карт і високої навантаженні, розумно було б покласти функції по віддачі карт (а також звуків, моделей і так далі) на спеціально навчений веб-сервер. Який, за щасливим збігом обставин у нас вже є. Цей функціонал і називається Fast Download.
Налаштування веб-сервера
Для використання Fast Download необхідно вказати веб-сервера використання каталогу зі структурою підкаталогів виду
dir/maps
dir/materials
dir/sound
...

де "dir" — кореневий каталог для Fast Download. Створити його в /home/game ми не можемо — домашній каталог у нас з правами rwx------, що не дозволяє веб-сервера бачити ці файли. Тому ми створимо ці каталоги де-небудь поза межами домашньої директорії користувача game.
Для спрощення налаштування, пропишемо у себе в DNS окремий піддомен fastdl.example.org створимо каталог /var/www/fastdl.example.org, і для зручності винесемо запис логів в окремі файли і надамо можливість користувачеві game читати їх.
З-під root створюємо каталоги, встановлюємо власника (game:game) і права — користувачеві game на запис, іншим веб-серверу) — на читання. Можна заодно зробити символьні посилання для зручності. Каталог Fast Download буде спільним для обох ігрових серверів.
# mkdir -p /var/www/fastdl.example.org/htdocs/{maps,materials,sound}
# mkdir /var/www/fastdl.example.org/log
# chown -R game:game /var/www/fastdl.example.org
# chmod -R 755 /var/www/fastdl.example.org
# ln -s /var/www/fastdl.example.org/htdocs /home/game/fastdl
# ln -s /var/www/fastdl.example.org/log /home/game/log/www-fastdl

В нашій конфігурації за замовчуванням усі журналів веб-сервера мають власника nginx:adm і права 640, тобто вони недоступні звичайним користувачам. Коректуємо це для даного випадку:
# touch /var/www/fastdl.example.org/log/{access,error}.log
# chmod 644 /var/www/fastdl.example.org/log/*.log

Таким чином користувачеві game наші логи стануть доступні для читання. Але тільки до першої їх ротації. Виправляємо і це. В каталозі /etc/logrotate.d копіюємо файл nginx в srcds-nginx, в ньому прописуємо шлях до логів і в рядку
create 640 nginx adm
виправляємо маску прав доступу з 640 на 644:
srcds-nginx
#/etc/logrotate.d/srcds-nginx

/var/www/stat.example.org/log/*.log
/var/www/fastdl.example.org/log/*.log
/var/www/replay.example.org/log/*.log
{
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 644 nginx adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}

Тут ми шляхах для ротації вказали заодно каталоги з логами від сервера статистики HLstatsX і від сервера з записами.
Є ще один цікавий момент, який варто врахувати. Для більшості серверів він навряд чи стане актуальним, але все ж. Ніщо не заважає власникові якогось ігрового сервера з такими ж як у нас користувацькими картами, не зі злості, а для економії свого трафіку, у своїх налаштуваннях Fast Download вказати адресу нашого веб-сервера (дізнатися його просто — достатньо ввести
sv_downloadurl
в консолі ігрового клієнта, під'єднавшись до сервера).
Виявити таких паразитів можна за referer, з яким від нас викачуються карти. Так, при завантаженні карти ігровим клієнтом, з подачі нашого ігрового сервера в балці веб-сервера з'являється запис виду:
198.51.100.0 http://fastdl.example.org - [16/Jun/2016:20:08:28 +0600] "GET /maps/cp_orange_x5.bsp.bz2 HTTP/1.1" 200 2685506 "hl2://192.0.2.0:27015" "Half-Life 2" 0.453 "-"

Звертаємо увагу на referer. Врахуємо це при налаштуванні.
Отже, беремося за налаштування веб-сервера. Спочатку зробимо визначення, з правильним referer скачують нашу карту. У головному файлі /etc/nginx/nginx.conf, в секції http {}, перед включенням файлу конфігурації для нашого віртуального хоста fastdl.example.org, вписуємо:
nginx.conf
# /etc/nginx/nginx.conf

http {
# <...>
map $http_referer $bad_client {
default 1;
"hl2://192.0.2.0:27015" 0;
"hl2://192.0.2.0:27016" 0;
}

include /etc/nginx/conf.d/fastdl.example.org.conf;
}

Тут все просто. Якщо заголовок $http_referer відповідає одному з наших серверів, то змінна $bad_client (зі значенням за замовчуванням 1) приймає значення 0.
Тепер створюємо файл конфігурації нашого віртуального сервера /etc/nginx/conf.d/fastdl.example.org.conf.
fastdl.example.org.conf
#/etc/nginx/conf.d/fastdl.example.org.conf

server
{
server_name fastdl.example.org;
listen 80;
root /var/www/fastdl.example.org/htdocs;
disable_symlinks on;
default_type application/octet-stream;

if ($bad_client) {
# Бажаючі можуть познущатися в стилі https://habrahabr.ru/post/272261/ з урахуванням місцевої специфіки
return 403;
}

access_log /var/www/fastdl.example.org/log/access.log main;
error_log /var/www/fastdl.example.org/log/error.log warn;
}

Тут ще простіше — перевіряємо ту змінну $bad_client, і до порушників застосовуємо санкції.
Взагалі, у nginx є директива valid_referers, але для нашого нестандартного $http_referer, з його типовою схемою, так і номером порту її не дуже зручно застосовувати. З map наочніше.
Прописуємо виклик fastdl.example.org.conf в основний файл nginx.conf якщо ще не, потім тестуємо конфігурацію і перезапускаємо nginx.
# nginx -t
# systemctl reload nginx

Далі продовжуємо як користувач game.
Налаштування ігрового сервера
Користувальницькі карти досить добре стискаються, тому їх можна віддавати гравцям в архівному вигляді (у форматі bzip2), але при цьому необхідно мати несжатую карту.bsp) у відповідному каталозі ігрового сервера. Наприклад, якщо ми де-небудь розжилися сподобалася нам картою cp_orange_x5 (дана карта наведено тільки для прикладу — вона існує в природі, але на момент написання матеріалу її не було в Steam Workshop), то робимо наступне:
$ mv cp_orange_x5.bsp ~/fastdl/maps
$ ln -s ~/fastdl/maps/cp_orange_x5.bsp ~/tf2/tf/maps
$ bzip2 --compress --keep --verbose --best ~/fastdl/maps/cp_orange_x5.bsp

тобто нестандартні карти ми будемо зберігати у каталозі ~/fastdl/maps, поруч із стисненими і символьним посиланням підключати в каталог до стандартних. Варіант, звичайно, обговорюється, але не краще і не гірше інших. Файли конфігурацій для карт виду <ім'я карти>.cfg необхідно створювати в ~/tf2/tf/cfg (ну або просто в ~/cfg, а туди вказувати посиланням).
Тепер прописуємо налаштування ігрового сервера в ~/cfg/autoexec.cfg:
autoexec.cfg
//...

// Fast Download

// Адресу веб-сервера, звідки гравцям буде віддаватися користувальницький контент
// Для відключення Fast Download вказуємо sv_downloadurl ""
sv_downloadurl "http://fastdl.example.org"

// Дозволяє гравцеві завантажувати файли на сервер (наприклад, спреї). Нєфіг.
sv_allowupload 0

// Дозволяє гравцеві завантажувати файли з сервера
// впливає лише на Slow Download. Тут наводимо просто для демонстрації.
sv_allowdownload 1

Перевіримо як все працює. Якщо сервер не працює, то запускаємо. Якщо він вже працює, то перезапускаємо, щоб змусити його перечитати autoexec.cfg з нашими новими налаштуваннями Fast Download.
Взагалі-то цілком собі допускається виклик одних файлів конфігурації з інших —
exec <configfile>
або з консолі. Тоді можна ті ж команди Fast Download винести в окремий файл конфігурації, включити виклик його в autoexec.cfg, а при необхідності "освіжити" налаштування запускати його ручками в консолі, або викликати з того ж server.cfg. Може бути зручно при налагодженні налаштувань, щоб кожен раз не перевантажувати ігровий сервер. Хоча його перезавантаження дозволить відпрацювати зміни, внесені але забуті в той же autoexec.cfg :-)
У себе в ігровому комп'ютері в каталозі SteamApps\common\Team Fortress 2\tf\download\maps\ шукаємо cp_orange_x5.bsp, якщо є — видаляємо (нам треба щоб вона скачати заново).
Запускаємо у себе гру, підключаємося до нашого сервера, дивимося, скачується карта з Fast Download (у віконці повинно бути написано саме "Downloading maps/cp_orange_x5.bsp.bz2" — з .bz2 розширенням):
Fast Download working
(На картинці карта _x3, але суть та ж).
Природно, передбачається, що у гравців в налаштуваннях клієнта дозволена завантаження контенту з сервера, як мінімум "Завантажувати карти" (cl_downloadfilter mapsonly), інакше буде видано повідомлення "Map is missing".
Allow maps downloading
Можемо спробувати браузером завантажити мапу http://fastdl.example.org/maps/cp_orange_x5.bsp.bz2якщо бачимо "403 Forbidden" — так і повинно бути, referer не
hl2://192.0.2.0
, радіємо.
Один момент:
Раз ми заявили можливість Fast Download (вказавши не порожній параметр sv_downloadurl), то при завантаженні файлів з веб-сервера, що добре видно в його логах, у гравців клієнти спочатку намагаються завантажити <ім'я карти>.bsp.bz2, у разі помилки 404 намагаються завантажити несжатую карту, без розширення .bz2 <ім'я карти>.bsp. У разі облому і в цій спробі, гравцеві НЕ надається можливості скачать карту з самого ігрового сервера з ~/tf2/tf/maps через Slow Download, а повідомляється, що карта не знайдено.
Map missing
Боти
У Team Fortress 2 є два типи роботів з штучним інтелектом і без. Боти з ІІ активно діють у грі, їх можна активувати без використання читерских команд (тобто при sv_cheats 0), на них можна заробляти багато досягнення. Боти без ІІ — "ляльки", активуються з використанням читерских команд (sv_cheats 1).
Офіційна TF wiki каже, що боти з ІІ коректно працюють на більшості карт King of the Hill (
koth_*
), деяких Payload картах (
pl_*
), Dustbowl і Gorge, картах Capture the Flag (
ctf_*
) і Mann Manor (
cp_manor_event
). Можливе використання ботів на інших картах, але з деякою попередньою підготовкою. І при цьому вони не будуть настільки ж гарні як живі гравці. Втім, ті ж медики підлікувати зуміють. Спробуємо обидва варіанти.
Поддержваемая карта
Спробуємо додати ботів на карту koth_sawmill, яка їх підтримує by design. У нас обидва сервера на 24 гравця. Точніше, на 24 ігрових слоти, але в даному прикладі цю різницю в нюансах не враховуємо. Зробимо так, що якщо гравців менше 24, то інші ігрові слоти сервера будуть зайняті ботами. Новий гравець увійшов у гру — бот зник. Гравець вийшов — бот додався. Експериментувати будемо на другому, піддослідному сервері. Щоб кожен раз не набирати команди в консолі сервера, вкажемо їх у файлі конфігурації для даної карти ~/cfg/koth_sawmill.cfg:
koth_sawmill.cfg
echo "*** ~/cfg/koth_sawmill.cfg"

// Рівень гри ботів
tf_bot_difficulty 3

// Режим додавання ботів в гру
tf_bot_join_after_player 0

// Відродження ботів
tf_bot_keep_class_after_death 0

// Тип застосування квоти на ботів
tf_bot_quota_mode fill

// Розмір квоти ботів в грі
tf_bot_quota 24

Тут ми зробили:
tf_bot_difficulty 3

Рівень гри ботів. 0=easy, 1=normal, 2=hard, 3=expert.
tf_bot_join_after_player 0

Боти будуть додані в гру при старті сервера (0), або при вході першого гравця (1), а до його входу карта буде без ботів.
tf_bot_keep_class_after_death 0

Після смерті, боти завжди будуть відроджуватися тим же класом (скаут, солдатів, ...), який отримали при створенні (1) або іншим (0), на розсуд ШІ.
tf_bot_quota 24

Спільно з наступним параметром, що визначає квоту ботів в грі. Використовується, якщо наступний параметр tf_bot_quota_mode встановлено "fill" або "match", але не більше кількості ігрових слотів, заданих +maxplayers в командному рядку запуску сервера.
tf_bot_quota_mode fill

Тип застосування квоти на ботів:
"normal" — сервер не буде додавати/прибирати ботів без прямої команди (tf_bot_add / tf_bot_kick)
"fill" — сервер буде підтримувати загальна кількість (ботів + живих гравців) у розмірі, заданого параметром tf_bot_quota
"match" — сервер буде підтримувати співвідношення живих гравців до ботам як 1:N, де N задано параметром tf_bot_quota.
tf_bot_add [кількість] [клас] [команда] [рівень] [ім'я]

Додавання ботів, при цьому вони не піддаються автоматичному регулюванню квотою (але, в будь-якому випадку, не більше maxplayers)
[Клас] — Demoman, Engineer, HeavyWeapons, Medic, Pyro, Scout, Soldier, Sniper, Spy
[Команда] — red або blue
[Рівень] — аналогічний tf_bot_difficulty, тільки для цього бота. 0=easy, 1=normal, 2=hard, 3=expert.
По нашій політиці, всі файли конфігурації намагаємося тримати в ~/cfg, тому робимо посилання в ~/tf2/tf/cfg:
$ ln -s ~/cfg/koth_sawmill.cfg ~/tf2/tf/cfg

Запускаємо сервер, якщо не запущений раніше, вводимо в консолі команду зміни карти:
changelevel koth_sawmill
. Входимо в гру, швидко огребаем від дванадцяти expert-lvl ботів і йдемо виправляти tf_bot_difficulty на 1 :-)
Пользовательсякая карта
Тепер додамо ботів на довільну карту. В даному випадку cp_orange_x3.
Копіюємо koth_sawmill.cfg в cp_orange_x3.cfg, враховуючи що ця карта підключена Steam Workshop:
$ mkdir ~/tf2/tf/cfg/workshop
$ cp ~/cfg/koth_sawmill.cfg ~/tf2/tf/cfg/workshop/cp_orange_x3.ugc454299390.cfg

І бажано в cp_orange_x3.ugc454299390.cfg виправити echo ім'я файлу, щоб уникнути непорозумінь.
Змінюємо карту. В консолі сервера вводимо
changelevel workshop/cp_orange_x3.ugc454299390
. Входимо в гру і бачимо сумну картину — хлопці стоять, нудьгують:
Нерухомі боти
Не впадаємо у відчай. В консолі ігрового сервера, вводимо команди:
sv_cheats 1
— дозволяє використання чит-команд і слідом
nav_generate
— створює навігаційну сітку (зберігається у файлі <ім'я карти>.nav), використовуючи яку боти можуть рухатися. Чекаємо деякий час...
Generating Navigation Mesh...
Sampling walkable space...
Sampling walkable space...
Sampling walkable space...
Creating navigation areas from sampled data...
Connecting navigation areas...
Merging navigation areas...
Created new fencetop area 1781(fc537be) between 3(1f542dcf) and 49(274fa843)
Finding hiding spots...DONE
Finding encounter spots...DONE
Finding sniper spots...DONE
Computing mesh visibility...
Computing mesh visibility... 0%
Computing mesh visibility... 1%
Computing mesh visibility... 5%
Computing mesh visibility... 17%
Can't compute incursion distances from the Red spawn room(s). <...>
Can't compute incursion distances from the Blue spawn room(s). <...>
Computing mesh visibility... 84%
Optimizing mesh visibility...
NavMesh Visibility List Lengths: min = 12, avg = 104, max = 280
Computing mesh visibility...DONE
Finding earliest occupy times...DONE
Start custom...
Post custom...
Custom game-specific analysis...DONE
Generation complete! 77.8 seconds elapsed.
Navigation map '/home/game/tf2/tf\maps\workshop/cp_orange_x3.ugc454299390.nav' saved.
[TF Workshop] Preparing map ID 454299390
[TF Workshop] Successfully prepared client map from workshop [ workshop/cp_orange_x3.ugc454299390 ]
---- Host_Changelevel ----
і так далі.

Після чого сервер перевантажує рівень. До речі ось тут і проявилася користь від прозорливо зазначеного параметра "sv_cheats 0" в server2.cfg. При зміні карти, що сталася вище, вручну включений sv_cheats скинувся 0, і можна не замислюватися — а чи не забули ми вимкнути те, що включили.
Входимо в гру — і все в порядку, боти ожили і на цій карті. Точки захоплюються, вороги вбивають, медики лікують. Хоча інженери і шпигуни не залишають точку респауна.
Але на мало-мальськи складних картах маршрути руху ботів можуть бути дуже неоптимальними, для виправлення цього є можливість коригування навігаційної сітки. Перелік навігаційних команд приведено в Navigation Mesh Commands, скачати вже готові і оптимізовані файли можна на Steam Users Forum.
Ще є "лялькові" боти (Puppet bots). Вони обділені ІІ і можуть або стояти на місці, або рухатися, підкоряючись командам гравця. Тут ми їх не розглядаємо. Детальніше про них можна прочитати в TF Wiki, з посиланням на початку глави. А заодно і подивитися вражаючий ролик https://youtu.be/Dn9970dxQ2g
Слід мати на увазі, що боти, як не дивно, їдять процесорний час. Як демонстраційного прикладу, ось висновок програми top для трьох запущених ігрових серверів на хиленьком Atom N2800:
Завантаження серверів
На першому сервері 24 бота з активною життєвою позицією (і сервер перевантажений і відчутно лагает, грати неможливо), на другому 12, на третьому ботів немає. Ах так, ще на першому і третьому сервері включені Записи. Якщо на тому ж третьому їх вимкнути, то його завантаження буде вдвічі нижче, менше 7%. Ну і tf_bot_join_after_player 1 знизить навантаження на серверах без гравців.
І, логічний, але не завжди очевидний момент — налаштування ботів (та й не тільки їх), задані у файлі конфігурації карт (koth_sawmill.cfg і cp_orange_x3.ugc454299390.cfg в нашому прикладі) не скидаються при зміні карти, а продовжують діяти і на наступних картах, при їх ротації. Інша справа, що поведінка ботів буде залежати від типу картки — як було продемонстровано в прикладах вище, на якихось картах боти можуть бути активні "з коробки", на інших картах, без згенерованих .nav файлів вони будуть стояти на точках респауна. Тому, якщо потрібно включати ботів тільки на деяких картах, то має сенс прописати tf_bot_quota 0 server{1,2}.cfg — при зміні карти кількість ботів буде дорівнює нулю, а вже у файлах конфігурації для конкретної карти їх можна включати цілеспрямовано.
Джерело: Хабрахабр
  • avatar
  • 0

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.