Перейти к содержимому

Конфигурация

Все модули адаптера читают ключи из одной цепочки источников, отдельно для каждого ключа:

  1. Файл из системного свойства JVM -Dl2nx.config-file=<path>; если оно не задано — l2nx.properties в рабочей директории JVM.
  2. Системные свойства JVM -Dl2nx.<key>=<value> — только для ключей, которых нет в файле.

Переменные окружения не поддерживаются. Подробности поиска файла — в быстром старте.

Правила для значений:

  • Файл читается в UTF-8. Значения обрезаются по краям; пустое значение считается незаданным, и действует значение по умолчанию.
  • Ключи читаются один раз при старте. Изменение вступает в силу после перезапуска сервера. Единственное исключение — отдельный файл настроек приложения, который перечитывается на работающем сервере.
  • Неверное значение (не число, вне диапазона, неизвестный вариант) никогда не заменяется значением по умолчанию: адаптер пишет в лог ошибку с именем ключа, и часть, которая его читает, не стартует. Для ключей core адаптер переходит в FAILED.
  • Булевы значения — true или false, перечисления не зависят от регистра.
  • cores в значениях по умолчанию ниже — число процессоров, доступных JVM.
Ключ Тип По умолчанию Обязателен Смысл
l2nx.config-file путь не задан нет Путь к файлу свойств. Читается только как системное свойство JVM. Задан, но не читается — адаптер падает при старте.
l2nx.enabled boolean false нет Главный выключатель. При false адаптер переходит в DISABLED: нет подключения, heartbeat и синхронизации.
l2nx.platform-url URL — да Базовый URL вашего тенанта на платформе, например https://<tenant>.api.l2nx.app. Должен быть https, с хостом, без query и fragment; завершающий слэш отбрасывается.
l2nx.host-type gs/ls gs нет Где работает адаптер: gs — игровой сервер, ls — логин-сервер. Определяет, какой из ключей ниже читается.
l2nx.gs-key строка — для gs Ключ игрового сервера: начинается с nx_sk_, всего 38 символов. Нельзя задавать вместе с l2nx.ls-key.
l2nx.ls-key строка — для ls Ключ логин-сервера, тот же формат, что у l2nx.gs-key. Нельзя задавать вместе с l2nx.gs-key.
Ключ Тип По умолчанию Обязателен Смысл
l2nx.io.workers int max(2, cores/2) нет Размер пула адаптера для блокирующей работы модулей и обработчиков команд (JDBC, HTTP). Потоки называются nx-io-N. ≥ 1.

Адаптер публикует через Kafka producer, настройки подключения и безопасности которого приходят с платформы. Настраиваются три параметра:

Ключ Тип По умолчанию Обязателен Смысл
l2nx.kafka.producer.batch.size байты 16384 нет Размер батча producer. Больше — меньше round trip и быстрее массовая синхронизация, меньше — ниже задержка.
l2nx.kafka.producer.linger.ms мс 10 нет Сколько producer ждёт заполнения батча. Большие значения сокращают round trip на больших первичных синхронизациях, 0 даёт минимальную задержку.
l2nx.kafka.producer.compression.type строка gzip нет Сжатие батчей: none, gzip, lz4, snappy или zstd. gzip не требует ничего дополнительно; для lz4, snappy и zstd нужен JAR библиотеки в classpath.

События, которые публикует хост, идут через одну ограниченную очередь, которую разбирает один поток.

Ключ Тип По умолчанию Обязателен Смысл
l2nx.events.queue-capacity int 10000 нет Максимум событий в очереди. Меньше — меньше heap, но больше потерь на всплесках. ≥ 1.
l2nx.events.drop-policy newest/oldest newest нет Что происходит при полной очереди. newest отбрасывает входящее событие и сохраняет порядок очереди (рекомендуется); oldest вытесняет самое старое событие — когда свежесть важнее полноты.
l2nx.events.shutdown-drain-timeout-ms мс 5000 нет Сколько адаптер продолжает доставлять события из очереди после начала остановки; остаток отбрасывается и учитывается. Увеличьте, если события теряются при остановке. ≥ 0.

Команды с платформы передаются обработчикам, которые зарегистрировал хост. Offsets коммитятся батчами, поэтому незакоммиченный батч доставляется повторно после перезапуска: обработчики должны быть идемпотентными.

Ключ Тип По умолчанию Обязателен Смысл
l2nx.commands.poll-timeout-ms мс 100 нет Сколько блокируется каждый опрос новых команд. Меньше — быстрее остановка и больше холостых пробуждений. ≥ 1.
l2nx.commands.shutdown-timeout-ms мс 5000 нет Сколько остановка ждёт работающие обработчики. Команды, не переданные к этому моменту, доставляются повторно при следующем старте. ≥ 0.
l2nx.commands.host-sync-timeout-ms мс 30000 нет Лимит на синхронный вызов обработчика в игровую сторону через host executor. По истечении команда завершается с UNAVAILABLE. Не даёт перегруженному игровому пулу остановить consumer команд. ≥ 1.
l2nx.commands.deferred-reply-max-ms мс 300000 нет Лимит на отложенный ответ: обработчик, который отложил ответ и не завершил его, получает INTERNAL_ERROR. Должен превышать самую долгую легитимную отложенную команду на сервере. ≥ 1.
l2nx.commands.kafka.<property> строка — нет Передаётся как есть в Kafka consumer команд как <property>. Значения по умолчанию max.poll.records=50 и auto.offset.reset=earliest так можно переопределить; bootstrap.servers, client.id, group.id, enable.auto.commit, security.protocol и sasl.* адаптер фиксирует — их нельзя.

Движок синхронизации БД (l2nx.cdc-engine.*). Значения по умолчанию рассчитаны на таблицу предметов примерно в 12 миллионов строк.

Ключ Тип По умолчанию Обязателен Смысл
l2nx.cdc-engine.tick-interval-seconds с 60 нет Период между циклами синхронизации каждой сущности. Меньше — свежее данные и выше нагрузка на БД. ≥ 1.
l2nx.cdc-engine.rows-per-window int 500000 нет Строк за одно окно запроса; большие сущности читаются в несколько окон. Больше — быстрее первичная синхронизация, но дольше чтение и больше heap. От 1 до 10000000.
l2nx.cdc-engine.query-timeout-seconds с 10 нет JDBC-таймаут каждого запроса. Окно, превысившее таймаут, прерывается и повторяется в следующем цикле. Увеличьте для больших таблиц на медленных дисках. ≥ 1.
l2nx.cdc-engine.publish-flush-seconds с 5 нет Сколько конец цикла ждёт подтверждений публикации. Неподтверждённые строки публикуются снова в следующем цикле. Увеличьте при предупреждениях publishes still pending. ≥ 1.
l2nx.cdc-engine.workers int max(2, min(entities, cores/2)) нет Размер общего пула движка. 0 — формула по умолчанию.
l2nx.cdc-engine.fetch-size int 10000 нет Подсказка JDBC fetch size. На MySQL Connector/J игнорируется (адаптер читает строки потоком); MariaDB использует её как батч курсора только с useCursorFetch=true в URL; другие драйверы — как размер батча курсора. ≥ 1.
l2nx.cdc-engine.persist.dir путь nx-cdc-snapshot нет Директория кэша снапшотов на диске; относительный путь — от рабочей директории JVM. См. ниже.
l2nx.cdc-engine.persist.checkpoint-min-interval-seconds с 300 нет Минимальный интервал между перезаписями файла снапшота одной сущности. ≥ 0.

Кэш снапшотов включён всегда. Он хранится как <persist.dir>/<schema>/<entity>.snap и загружается при старте, поэтому первый цикл после перезапуска сообщает и о строках, удалённых из базы, пока сервер был выключен. Lock-файл в директории не даёт второму адаптеру с той же схемой её использовать: каждому серверу с общей рабочей директорией задайте свой l2nx.cdc-engine.persist.dir. Запись снапшотов идёт на пуле движка; на медленном хранилище увеличьте l2nx.cdc-engine.workers.

Движок синхронизации состояния из памяти (l2nx.runtime-sync.*). Его ключи не зависят от l2nx.cdc-engine.*.

Ключ Тип По умолчанию Обязателен Смысл
l2nx.runtime-sync.tick-interval-seconds с 10 нет Период между чтениями состояния из памяти; каждое сравнивается с предыдущим. ≥ 1.
l2nx.runtime-sync.publish-flush-seconds с 5 нет То же, что l2nx.cdc-engine.publish-flush-seconds, на каждый тик. ≥ 1.
l2nx.runtime-sync.workers int max(2, min(entities, cores/2)) нет Размер общего пула движка. Если задан — ≥ 1.
Ключ Тип По умолчанию Обязателен Смысл
l2nx.gd-sync.resync-interval-hours часы 0 нет Период плановой полной переотправки каталогов игровых данных. 0 выключает расписание. ≥ 0.

Игровые данные переотправляются и тогда, когда хост запрашивает это после перезагрузки датапака, и когда это запрашивает платформа, поэтому расписание — лишь страховка.

l2nx-app.properties задаёт поведение сервера для того, что персонаж делает в игре по команде из приложения, пока игрок вне клиента. l2nx.properties подключает сервер к платформе, а этот файл — продуктовое поведение сервера, его правит гейм-дизайнер. nx-gs-adapter-core читает его только на игровом сервере (логин-сервер его игнорирует).

  • Расположение. Рядом с l2nx.properties: в рабочей директории JVM или, если -Dl2nx.config-file указывает в другое место, в директории этого файла. Нет файла — действуют все значения по умолчанию. Системные свойства JVM эти ключи не переопределяют.
  • Эталонный файл. l2nx-app.properties перечисляет все ключи со значениями по умолчанию и комментариями. Скопируйте его и измените нужное.
  • Значения по умолчанию. Отсутствующий ключ принимает значение по умолчанию. Все типы сессий и чат с приложением по умолчанию выключены; возрождение включено.
  • Значения. Обрезаются по краям; true / false и имена перечислений точные (регистр важен). Файл в UTF-8; метка порядка байтов (BOM) в начале файла игнорируется.
  • Проверка. Сначала проверяется весь файл. Одно неверное значение или неизвестный ключ (в том числе опечатка) не применяет ничего: прежние значения остаются, а в логе по одной строке app settings not applied, previous values stay: <key>: <reason> на каждую проблему. В отличие от ключей l2nx.*, неверное значение никогда не останавливает сервер.
  • Перезагрузка. Адаптер проверяет файл примерно раз в 5 секунд и применяет изменение без перезапуска; в логе app settings updated: <key>: <old> -> <new>.
  • Идущие сессии. Новые значения действуют на новые старты. Сессия сохраняет порог возврата, с которым начата; отключённый тип сессии даёт идущим сессиям завершиться и отклоняет новые старты.

Хост читает актуальные значения через типизированный NxAppRules (NxAdapter.appRules(), ConnectContext.appRules(), CommandContext.appRules()); current() возвращает неизменяемый снимок AppRules.

Ключ Тип По умолчанию Смысл
app.phantom.title.text строка l2nx.app Титул над персонажем, которого приложение поставило в мир, вместо его собственного; только отображение, не сохраняется. 1-16 символов; пусто — без подмены.
app.phantom.title.color 6 hex-цифр RGB FFFF00 Цвет этого титула. Используется, только когда задан текст титула.
app.session.recent-logout-minutes минуты 2 Нет старта из приложения в течение этого времени после выхода персонажа из игры с клиентом. 0 отключает правило. 0-60.
app.session.restart-window-minutes минуты 15 Нет старта из приложения, если плановый рестарт ближе этого времени. 0-120.
app.session.return-threshold-minutes минуты 30 Сессия, завершившаяся с меньшим временем в мире, возвращает персонажа туда, откуда он начал; при равном или большем времени персонаж остаётся на месте. Один порог для всех типов сессий. ≥ 0.
app.private-store.enabled boolean false Частный магазин из приложения на этом сервере. false: старт отклоняется как отключённый.
app.private-store.start-cooldown-minutes минуты 5 Нет нового старта частного магазина (продажа или покупка) персонажа в течение этого времени после фактического старта предыдущего магазина этого персонажа из приложения; не даёт сбивать цены перезапуском магазина. Другие персонажи того же игрока не ждут; закрытие магазина не ограничено. 0 отключает правило. 0-1440.
app.fishing.enabled boolean false Офлайн-рыбалка на этом сервере. false: старт отклоняется как отключённый. true требует app.fishing.spot-pool.
app.fishing.start-cooldown-minutes минуты 15 Нет нового старта рыбалки ни для одного персонажа мастер-аккаунта в течение этого времени после фактического старта предыдущей рыбалки этого мастер-аккаунта из приложения. 0-1440.
app.fishing.min-duration-minutes минуты 30 Самая короткая рыбалка, которую может запросить старт. ≥ 1.
app.fishing.max-duration-minutes минуты 1440 Самая долгая рыбалка, которую может запросить старт; не меньше app.fishing.min-duration-minutes. Собственный суточный лимит сервера может завершить сессию раньше.
app.fishing.float-distance игровые единицы 170 Расстояние от рыбака до поплавка по направлению точки. 90-250.
app.fishing.spot-order RANDOM/FIRST_FREE RANDOM Как выбирается свободная точка пула: любая свободная или свободная с наименьшим id.
app.fishing.spot-pool строка пусто Имя пула точек, которым рыбалка пользуется на сервере; сам пул (id точек, координаты, направление) — данные игрового сервера. 1-32 символа a-z, 0-9 и _; пусто — пула нет. Изменённый пул действует только на новые старты.
app.revive.enabled boolean true Возрождение мёртвого персонажа в точке возрождения из приложения, с ещё подключённым или уже закрытым клиентом. false: возрождение отклоняется как отключённое. С NATIVE других ключей не требует.
app.revive.town.mode NATIVE/SPOT_POOL NATIVE Куда возрождение «в город» ставит персонажа: как сама игра при «В деревню» или на точку из пулов app.revive.town.spot-pool, которую не занимает ни одна идущая сессия приложения (любую из них, если свободных нет). Персонаж с кармой всегда получает место NATIVE.
app.revive.town.spot-pool список имён пулов пусто Пулы точек, из которых выбирает возрождение SPOT_POOL, через запятую; каждое имя — 1-32 символа a-z, 0-9 и _, без повторов; можно указать пул из app.fishing.spot-pool. Сами пулы — данные игрового сервера. SPOT_POOL с пустым списком — ошибка.
app.chat.enabled boolean false Игровой чат в приложении и отправка в него из приложения. false: игровой чат не публикуется на платформу, любая отправка от персонажа из приложения отклоняется как отключённая (объявления и строки от имени стаффа уходят как раньше), а шёпот из игры на Name* (персонажу не в игре) получает ответ как на неизвестное имя.
app.chat.online-send-channels список каналов CLAN,ALLIANCE,PARTY,WHISPER Каналы, в которые приложение может писать, пока персонаж в игре: CLAN, ALLIANCE, PARTY, WHISPER через запятую, без повторов. Пусто — в этом состоянии приложение только читает чат. Отправка в канал вне списка отклоняется.
app.chat.offline-send-channels список каналов CLAN,ALLIANCE,WHISPER Каналы, в которые приложение может писать, пока персонаж не в игре, так же; PARTY здесь недопустим (вне игры группы нет). Пусто — в этом состоянии приложение только читает чат.
app.restore.batch-size int 10 Сколько сессий восстанавливается за пачку после рестарта. Ограничено половиной l2nx.io.workers. ≥ 1.
app.restore.batch-pause-millis мс 1000 Пауза между пачками восстановления. ≥ 0.
app.shutdown.result-millis-per-session мс 20 Сколько добавляется на открытую сессию к 5 с, которые штатная остановка ждёт результаты сессий. ≥ 1.
app.history.retention-days дни 90 Закрытые сессии старше этого срока удаляются из таблицы адаптера при старте сервера. ≥ 7.

У nx-gs-adapter-api, nx-gs-kafka, nx-gs-commons, nx-gs-db-migrations и nx-gs-db-migrator-liquibase5 своих ключей нет. Мигратор использует тот же JdbcConnectionSource, что и остальной адаптер.