Инструмент устанавливает выделенный сервер Counter-Strike 1.6 в отдельном каталоге и управляет им. Он компилирует тестовые плагины из репозитория, выполняет серверные проверки и формирует локальные отчеты. Игровой клиент разработчик запускает самостоятельно.
Панель инструментов разработчика содержит кнопки подготовки и управления сервером, создания отчетов и генерации флагов.
Порядок работы описан в руководстве ручных проверок. Девять сценариев и 22 варианта ролей и исходов приведены в перечне сценариев. Поддерживаемая конфигурация и ограничения описаны в документе о совместимости.
Требуются Python 3.12 или новее, доступ к Steam и HTTPS-архивам фиксированных версий, библиотеки для запуска x86-программ, а также обновленный репозиторий NextClientServerApi с готовым x86-модулем. Команды выполняются из корня репозитория. В Linux используется python3.
python tools/test_server/test_server.py prepare
Одна команда устанавливает сервер Valve, ReHLDS, ReGameDLL, Metamod, AMX Mod X и ReAPI; компилирует и подключает nextclient_testlab и nextclient_materials_test; устанавливает модуль и заголовочный файл NextClientServerApi; копирует пресет материалов и маску dissolve.
Сервер остается остановленным. По умолчанию он размещается в build/test-server/<platform>. Для запуска выполните python tools/test_server/test_server.py start --map cs_office, затем подключитесь из запущенного вручную клиента к 127.0.0.1:27020.
Инструмент ищет NextClientServerApi рядом с этим репозиторием и на один каталог выше. Например, для D:/projects/nextclient/NextClient будет найден D:/projects/NextClientServerApi.
В Windows модуль ищется в cmake-build-release-visual-studio-2026-x86 и cmake-build-release-visual-studio-2022-x86; в Linux проверяются cmake-build-release-wsl и cmake-build-release-linux. На обеих платформах также проверяются build/Release, build и addons/amxmodx/modules внутри репозитория API. Модуль должен иметь формат x86 PE/ELF для текущей платформы и содержать native ncl_mat_through_walls; заголовочный файл должен объявлять эту функцию.
Если репозиторий или готовый модуль находится в другом месте, укажите пути явно:
python tools/test_server/test_server.py prepare --server-api D:/projects/NextClientServerApi --server-api-module D:/build/api/nextclientapi_amxx.dll
Параметр --server-api-module не требуется, если инструмент находит сборку автоматически. После успешной подготовки явно переданные пути сохраняются в выбранном локальном JSON-конфиге; остальные настройки сохраняются. При отсутствии конфига prepare создает его. Если файлы API отсутствуют или устарели, команда возвращает ошибку с проверенными путями до скачивания архивов и установки сервера. При подготовке устанавливается полный набор плагинов. Готовый модуль API копируется без сборки его репозитория. Для переустановки базы Valve используйте prepare --repair-base.
Повторный prepare обновляет полный комплект. Команда build пересобирает установленный набор плагинов; в полном комплекте она также обновляет ресурсы материалов и модуль API. Обе операции требуют остановленного сервера.
Плагин проверки материалов компилируется до установки. Если компиляция завершается с ошибкой, установленные файлы материалов сохраняются. Файлы заменяются атомарно, а при ошибке копирования выполненные замены отменяются. Команда doctor проверяет дополнительный модуль и ресурсы; start проверяет, что оба плагина и модуль API работают.
Требуются Python 3.12 или новее, доступ к Steam и HTTPS-архивам фиксированных версий, а также библиотеки выбранной платформы для запуска x86-программ. Все команды инструмента в этом справочнике выполняются из корня репозитория. В Linux используется python3.
python tools/test_server/test_server.py init
python tools/test_server/test_server.py doctor
Если build/test-server/config.local.json отсутствует, init создает его. Команда устанавливает Steam app 90, мод cstrike, ветку steam_legacy, затем устанавливает поверх базы компоненты фиксированных версий и компилирует плагин. Такой выбор базы соответствует требованиям ReHLDS.
Версии компонентов и SHA-256 архивов заданы в server.lock.json. Хеши проверяются до распаковки. Заголовочные файлы ReAPI берутся из того же архива, что и модуль. SteamCMD и депо Valve могут обновляться независимо; состояние их установки фиксируется отдельно.
При повторном запуске init сохраняет локальную JSON-конфигурацию и применяет текущие конфиги сервера. Для переустановки базы Valve с последующей установкой всех компонентов выполните:
python tools/test_server/test_server.py init --repair-base
В Ubuntu 24.04 установите 32-битные библиотеки:
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install libc6:i386 libstdc++6:i386 libgcc-s1:i386Для Linux используется отдельный файл конфигурации. В WSL каталог сервера должен находиться в файловой системе Linux, например /var/tmp/nextclient-testlab. Сохраните следующий файл конфигурации как build/test-server/config.linux.local.json:
{"schema":1,"server":{"root":"/var/tmp/nextclient-testlab","port":27020}}Установите сервер:
python3 tools/test_server/test_server.py --config build/test-server/config.linux.local.json initБиблиотека Steamworks должна быть доступна по пути ~/.steam/sdk32/steamclient.so. Если путь уже существует, проверьте, куда он ведет, командой readlink -f ~/.steam/sdk32/steamclient.so. Если путь свободен, создайте ссылку из корня репозитория:
mkdir -p ~/.steam/sdk32
ln -s "$(pwd)/build/test-server/cache/steamcmd/linux-x86/linux32/steamclient.so" ~/.steam/sdk32/steamclient.soВ примере используется каталог кеша по умолчанию. Затем проверьте установку и запустите сервер:
python3 tools/test_server/test_server.py --config build/test-server/config.linux.local.json doctor
python3 tools/test_server/test_server.py --config build/test-server/config.linux.local.json start --map cs_officedoctor проверяет необходимые x86-файлы PE/ELF, 32-битные зависимости Linux и библиотеку Steamworks. Для компиляции используется временный каталог в файловой системе Linux, поскольку 32-битный компилятор AMXX несовместим с некоторыми особенностями inode/stat в DrvFs.
Для подключений с другой машины добавьте к start параметры --bind 0.0.0.0 --port 27020; в клиенте укажите доступный IP-адрес сервера. Одновременно запущенные серверы Windows и WSL должны использовать разные адреса или порты.
Глобальный параметр --config <path> указывается перед подкомандой:
python tools/test_server/test_server.py --config build/test-server/config.local.json status
Файл по умолчанию: build/test-server/config.local.json. Минимальный пример приведен в config.example.json. Для отсутствующих полей используются значения из таблицы. Относительные пути отсчитываются от корня репозитория.
| Поле | По умолчанию | Назначение |
|---|---|---|
schema |
1 |
Схема конфигурации |
server.root |
build/test-server/<platform> |
Каталог сервера; платформа windows-x86 или linux-x86 |
server.bind |
127.0.0.1 |
IPv4-адрес прослушивания |
server.port |
27020 |
Порт от 1 до 65535 |
server.maxplayers |
8 |
Максимум игроков, от 4 до 32 |
server.map |
cs_office |
Начальная карта |
server.lan |
true |
Настройка LAN-сервера |
paths.cache |
build/test-server/cache |
Каталог скачанных архивов |
paths.reports |
out/manual-tests |
Сессии, отчеты и результаты сборки |
paths.server_api |
auto |
Репозиторий API для полного набора плагинов |
paths.server_api_module |
auto |
Готовый x86-модуль API; относительный путь считается от корня этого репозитория |
timeouts.ready_seconds |
60 |
Тайм-аут ожидания готовности сервера |
timeouts.steamcmd_seconds |
3600 |
Тайм-аут SteamCMD |
timeouts.compile_seconds |
120 |
Тайм-аут компиляции плагина |
Тайм-ауты задаются положительными числами в секундах. Неизвестные поля и неверные типы значений отклоняются. Параметры --map, --bind и --port, где они поддерживаются, переопределяют параметры конфигурации для конкретного вызова.
Для каждой серверной сессии автоматически создается пароль RCON. Он хранится локально в файле сессии rcon.secret.
Формат вызова: python tools/test_server/test_server.py <command>. Допустимые параметры выводятся через <command> --help.
| Команда | Параметры | Назначение |
|---|---|---|
prepare |
--repair-base, --server-api, --server-api-module |
Установка сервера со всеми тестовыми плагинами, ресурсами и готовым модулем API |
init |
--repair-base |
Установка или восстановление сервера и сборка плагина |
doctor |
Нет | Проверка установленных файлов и библиотек для запуска |
build |
Нет | Пересборка установленного набора плагинов, обновление профилей и ресурсов материалов |
compile-only |
Нет | Компиляция с архивами фиксированных версий AMXX/ReAPI без установки сервера Valve |
start |
--map, --bind, --port |
Запуск выделенного сервера |
status |
Нет | Проверка процесса, запущенного инструментом, и состояния плагина |
stop |
Нет | Остановка сервера, запущенного инструментом, и архивирование журнала |
smoke |
--suite, --map, --port, --case, --repetitions |
Запуск сервера, выполнение проверок и остановка |
calibrate |
--map cs_office или --map de_dust2 |
Запуск сервера, получение заготовки координат и остановка |
report |
Обязательный --run <run_id> |
Создание JSON/HTML-отчета прогона и обновление индекса |
results |
Нет | Перестроение локальных HTML-страниц по сохраненным результатам |
После проверки карты, модулей и загруженных версий start возвращает session_id и connect. Адрес прослушивания 0.0.0.0 в клиентской команде connect заменяется доступным адресом сервера.
status сопоставляет ответ плагина с идентификатором запроса. Перед отправкой RCON-команды проверяется идентификатор сессии сервера по указанному адресу. Команды, изменяющие состояние, отправляются один раз.
Перед остановкой сервера stop проверяет PID, данные о создании процесса и исполняемый файл. Если подтверждено, что процесс запущен инструментом, команда запрашивает штатный выход или завершает процесс принудительно. Если завершение не подтверждено, запись процесса сохраняется и возвращается ошибка. Если PID уже принадлежит другому процессу, исходная сессия считается остановленной. Следующий start или stop архивирует ее журнал и удаляет устаревшую запись.
Все три команды выполняются с одним файлом конфигурации:
python tools/test_server/test_server.py stop
python tools/test_server/test_server.py build
python tools/test_server/test_server.py start --map cs_office
build не запускает сборку, пока сервер работает. Установленный .amxx заменяется только после успешной компиляции. Журнал компилятора: <paths.reports>/install/<platform>/compile.log.
Для того же BSP сборка сохраняет существующие откалиброванные секции профиля и добавляет недостающие. Изменения профиля загружаются при новой подготовке сцены. См. калибровку.
| Код | Значение |
|---|---|
0 |
Команда вернула ok=true |
1 |
Результат smoke-проверки содержит ok=false и код результата, заканчивающийся на smoke |
2 |
Неверные параметры, ошибка окружения или другая ошибка выполнения, включая сбой запуска сервера для smoke-проверки |
Причина указана в полях JSON code и details. Успешный код завершения инструмента не подтверждает результат визуальной проверки.
Команды smoke самостоятельно запускают и останавливают сервер. Перед их выполнением остановите сервер ручной проверки. Примеры для всех наборов:
python tools/test_server/test_server.py smoke --suite stack
python tools/test_server/test_server.py smoke --suite gameplay
python tools/test_server/test_server.py smoke --suite core
python tools/test_server/test_server.py smoke --suite review --map cs_office
python tools/test_server/test_server.py smoke --suite hostage --repetitions 5
python tools/test_server/test_server.py smoke --suite bomb --repetitions 5
python tools/test_server/test_server.py smoke --suite players --map cs_office --repetitions 5
python tools/test_server/test_server.py smoke --suite lifecycle --map de_dust2 --repetitions 5
| Набор | Что проверяется |
|---|---|
stack (по умолчанию) |
Загрузка компонентов и соответствие фиксированным версиям |
gameplay |
Операции с игроками, заложниками и бомбой на cs_office и de_dust2 |
core |
Сброс, смена карты и завершение отложенных запросов |
review |
Повтор после ошибки, сохранение активного профиля, выбор цели наблюдения с учетом задержки GameDLL и перенос исхода при смене карты; требуется cs_office |
hostage |
Восемь вариантов на cs_office |
bomb |
Девять вариантов на de_dust2 |
players |
Варианты CT и T на выбранной карте |
lifecycle |
Варианты CT, T и наблюдателя на выбранной карте |
Параметры --case и --repetitions применяются к четырем наборам сценариев. Число повторов: от 1 до 5, по умолчанию 5. Без --case выполняются все варианты набора.
| Набор | Индексы вариантов, начиная с нуля |
|---|---|
hostage |
0 static CT; 1 static T; 2 follow CT; 3 visibility CT; 4 visibility T; 5 visibility observer; 6 end kill; 7 end rescue |
bomb |
0 cycle T/defuse; 1 CT/defuse; 2 T/explosion; 3 CT/explosion; 4 visibility T/dropped; 5 CT/dropped; 6 T/planted; 7 CT/planted; 8 observer T |
players |
0 CT; 1 T |
lifecycle |
0 CT; 1 T; 2 observer |
Например:
python tools/test_server/test_server.py smoke --suite hostage --case 2 --repetitions 5
python tools/test_server/test_server.py smoke --suite bomb --case 6 --repetitions 1
Наборы сценариев используют игроков, управляемых сервером. operations=pass подтверждает выполненные игровые проверки. PVS клиента, визуальная оценка и общий результат server остаются not_run, если требуется настоящий клиент. В частности, сопровождение заложника проверяет Use, оба маршрута, периодические HostagePos и остановку; проверки PVS inside/outside/return требуют ручного прогона CT. Шаги смены карты и переподключения в radar_lifecycle требуют клиента разработчика; серверную очистку при смене карты отдельно проверяет core.
Ошибка остановки сохраняется в details.cleanup и устанавливает ok=false, не удаляя выполненные проверки. Итог smoke сохраняется в <paths.reports>/smoke/<suite>-<uuid>.json; HTML и индекс создаются автоматически. Диагностика конкретного набора, например review.json, также сохраняется в каталоге сессии.
Команды вводятся в консоли подключенного клиента после обычного выбора команды и класса. Текущий оператор определяется по userid до отключения или смены карты. Для управления из серверной консоли сначала назначьте оператором подключенного игрока командой nct_operator <userid>.
| Команда | Действие |
|---|---|
nct_menu |
Открыть меню роли, сценария, исхода, шага, повтора, сброса и вспомогательных действий |
nct_list |
Вывести имена сценариев, карты, маски ролей и число шагов |
nct_run <scenario> [ct|t|observer] |
Подготовить сценарий, при необходимости сменить карту |
nct_outcome defuse|explosion|kill|rescue|dropped|planted |
Выбрать исход для следующего действия или прогона |
nct_step |
Выполнить один шаг из состояния ready |
nct_repeat |
Сбросить и повторить выбранный сценарий с новым идентификатором прогона |
nct_reset round|map |
Сбросить раунд или перезагрузить текущую карту |
nct_map cs_office|de_dust2 |
Сменить карту с сохранением запроса на продолжение radar_lifecycle |
nct_resume |
Один раз использовать сохраненный запрос на продолжение сценария после смены карты |
nct_status |
Вывести краткое состояние и записать подробный снимок сцены в журнал |
nct_trace on|off |
Включить или отключить подробную запись сообщений и видимости |
nct_report |
Записать в журнал отчет по событиям, записанным к моменту запроса |
nct_result pass|fail|skip <note> |
Записать результат ручной визуальной проверки для текущего или последнего прогона |
nct_team ct|t|observer |
Изменить роль оператора |
nct_respawn |
Возродить оператора в команде CT или T |
nct_die |
Убить оператора через штатные обработчики damage/killed |
nct_observe <userid> |
Выбрать живого игрока для наблюдения от первого лица |
nct_goto <anchor> |
Перейти к точке профиля, если подготовка, сброс или стадия не выполняются |
nct_god on|off |
Включить или отключить неуязвимость |
nct_noclip on|off |
Включить или отключить перемещение сквозь геометрию |
nct_view open|occluded|outside |
Проверить текущий объект из текущей позиции по требованиям указанной позиции обзора |
nct_anchor <name> |
Вывести текущую позицию, направление взгляда и хеш карты для секции профиля |
Тайм-ауты, восстановление, снимки состояния и критерии успешной проверки описаны в руководстве оператора.
Идентификатор прогона имеет вид <session_id>.<map_epoch>.<counter>. Он берется из nct_status: run соответствует текущей сцене, а last_run сохраняет завершенный прогон после сброса раунда. При загрузке карты last_run очищается.
python tools/test_server/test_server.py report --run <run_id>
python tools/test_server/test_server.py results
report записывает report.json и report.html в <paths.reports>/<run_id>/, затем обновляет index.html. Инструмент возвращает html_path и index_path. Для активной сцены команда получает журнал на момент запроса. События, произошедшие позднее, попадут в следующий отчет. Для другой сцены или остановленного сервера используются сохраненные события с live_snapshot=false.
results читает сохраненные файлы без обращения к игровому серверу; установленный сервер не требуется. Страницы открываются как локальные файлы. Поврежденные JSON и неподдерживаемые схемы вызывают ошибки чтения. Корректные результаты остаются доступными. HTML показывает сохраненные данные; ручная оценка записывается через nct_result, после чего отчет собирается повторно.
Отчет разделяет результаты сборки, серверных проверок и визуальной оценки. Отсутствующие наблюдения сохраняют not_run. Отчет считается неполным, если в журнале есть поврежденная полная строка, незавершенная последняя строка или достигнут лимит в 10 000 событий. Проверьте issues и trace_truncated. Для широковещательной отправки указан состав получателей на момент отправки.
Метаданные сессии содержат загруженные версии, хеши плагина, компилятора, исходников и локальных профилей, а также сохраненные манифест установки Valve и хеши базы до установки компонентов. При отсутствии метаданных базы используется null. Версию и настройки клиента оператор записывает в примечание к ручной проверке.
Каталоги прогонов содержат очищенные события и, при наличии исходного журнала, server.clean.log. Передавайте только каталоги нужных прогонов, без каталогов сессий и общего каталога отчетов. Файлы *.secret, testlab-session.cfg, users.ini и server.raw.log оставьте локально. При передаче коллекции сохраните относительную структуру каталогов индекса, связанных результатов и очищенных журналов.
Эффекты рендеринга проверяются отдельным плагином nextclient_materials_test. Команда prepare устанавливает его вместе с TestLab, ресурсами и NextClientServerApi. Плагин содержит команды ncl_fx для dissolve, шумовой прозрачности, глитча, подкраски, обводки и передачи вне PVS. Команды, визуальные проверки и самостоятельная установка описаны в его инструкции.
Эти команды не запускают игру или выделенный сервер:
python -m unittest discover -s tools/test_server/tests -p "test_*.py"
python tools/test_server/test_server.py compile-only
compile-only загружает архивы фиксированных версий AMXX base, AMXX Counter-Strike и ReAPI. Для сборки используются заголовочные файлы из этих архивов. Плагин TestLab и build.json сохраняются в <paths.reports>/build/<platform>/. NextClientServerApi для этой команды не требуется.
Workflow тестового сервера выполняет модульные тесты и компиляцию в Windows и Ubuntu. Ручной запуск с server_smoke=true дополнительно устанавливает базу Valve и выполняет stack, gameplay и review.
Правила добавления сценариев находятся в инструкциях тестового плагина. Для нового сценария также опишите подготовку, действия и ожидаемые результаты в перечне ручных проверок.