Files
lineage2-h5-server/README.md
T

14 KiB
Raw Blame History

L2J Mobius High Five — Docker

L2J Mobius (хроники High Five, L2J_Mobius_CT_2.6_HighFive) в Docker Compose. Три контейнера: mysql, loginserver, gameserver. Исходники сервера лежат прямо в этом репозитории (src/) и собираются локально через Ant — без внешних зависимостей от GitLab при каждой пересборке.

Структура проекта

l2j-docker/
├── src/                    # Исходники L2J Mobius (java/, build.xml, dist/, launcher/) — редактируешь напрямую
├── Dockerfile.build        # Собирает src/ через Ant, кладёт результат в /out
├── scripts/
│   ├── collect-dist.sh     # Нормализует результат сборки в /out/login, /out/game, /out/sql
│   └── extract-reference.sh # Выгружает /out на хост в reference/ для просмотра
├── login/
│   ├── Dockerfile          # Runtime-образ login-сервера (JRE)
│   └── entrypoint.sh       # Ждёт mysql, применяет config_override, стартует jar
├── game/
│   ├── Dockerfile          # Runtime-образ game-сервера (JDK — нужен для скриптового движка)
│   └── entrypoint.sh       # Ждёт mysql+login, применяет config_override, стартует jar
├── mysql/
│   ├── Dockerfile          # MySQL 8.0 + автоимпорт SQL-схем при первом старте
│   └── init/
├── config/
│   ├── login/config/       # Override-конфиги login (применяются при каждом старте контейнера)
│   └── game/config/        # Override-конфиги game
├── reference/              # Сгенерированный полный дефолтный дистрибутив (не в git, см. ниже)
├── geodata/                # .l2j файлы геодаты (не входят в репозиторий, кладутся руками)
├── docker-compose.yml
├── .env                    # Пароли, порты — реальные значения, не в git
└── .env.example            # Шаблон .env с плейсхолдерами

Как это работает

  1. Dockerfile.build копирует src/ в builder-образ и собирает его через ant -f build.xml. Результат — LoginServer.jar, GameServer.jar и SQL-схемы.
  2. scripts/collect-dist.sh раскладывает собранный архив в /out/login, /out/game, /out/sql — единую структуру для runtime-образов.
  3. login/Dockerfile и game/Dockerfile берут готовый /out/* из builder-образа и кладут в финальный контейнер с JRE/JDK.
  4. config/login/config/ и config/game/config/ — это единственное место, где нужно редактировать конфиги. При каждом старте контейнера entrypoint.sh копирует всё из этой папки поверх дефолтных файлов внутри контейнера. Правки здесь переживают любой docker compose build / --force-recreate. Редактировать конфиги внутри уже запущенного контейнера (docker exec) — не сохранится после пересборки.

Запуск с нуля

1. Собрать builder-образ

docker build -f Dockerfile.build -t l2j-build:latest .

2. Геодата

Скачай геодату для High Five отдельно. (Можно тут) Распакуй все .l2j файлы (и geo_index.txt) прямо в ./geodata/, без вложенных подпапок.

3. Настроить .env

cp .env.example .env   # если только клонировал репозиторий
nano .env

Задай MYSQL_ROOT_PASSWORD и остальные значения. Важно: пароль здесь должен совпадать с паролем в config/login/config/Database.ini и config/game/config/Database.ini (см. ниже).

⚠️ Обязательно смени перед первым запуском

Репозиторий содержит рабочие сетевые настройки (mysql, loginserver вместо localhost), но пароль и IP — от конкретной машины, на которой это разворачивалось изначально. Смени их в трёх местах, иначе: подключение к БД будет использовать чужой пароль, а клиенты будут пытаться попасть на чужой IP.

  1. config/login/config/Database.ini и config/game/config/Database.ini — строка Password = .... Должна совпадать с MYSQL_ROOT_PASSWORD в .env.
  2. config/game/config/ipconfig.xml — атрибут address="..." в корневом теге <gameserver>. Это IP/домен, который сервер сообщает клиенту после выбора сервера в списке (свой локальный/публичный IP, не 192.168.1.207 — это чужая машина).

Всё остальное (mysql, loginserver, 0.0.0.0 в Server.ini) — универсальные значения, менять не нужно, они завязаны на имена сервисов в docker-compose.yml, а не на конкретный хост.

4. Настроить сетевые конфиги

Login и game сервера по умолчанию слушают/подключаются на localhost — внутри Docker-сети это не работает, контейнеры видят друг друга по именам сервисов (mysql, loginserver, gameserver). Уже настроено в config/*/config/Database.ini и config/login/config/Server.ini:

  • Database.ini (оба сервера): URL = jdbc:mysql://mysql/l2jmobiush5?...
  • login/config/Server.ini: LoginHostname = 0.0.0.0, LoginHostname для приёма game-сервера — LoginHost = 0.0.0.0 (не 127.0.0.1, иначе gameserver не сможет подключиться из своего контейнера)
  • game/config/Server.ini: LoginHost = loginserver (имя сервиса, не IP)

5. ipconfig.xml — адрес для клиентов

config/game/config/ipconfig.xml определяет, какой IP-адрес game-сервер сообщает клиенту после выбора сервера в списке. Если клиент подключается:

  • с этого же сервера — оставь 127.0.0.1
  • из локальной сети — укажи локальный IP сервера (например, 192.168.1.207)
  • из интернета — укажи публичный IP или домен

Пример минимального конфига:

<?xml version="1.0" encoding="UTF-8"?>
<gameserver address="192.168.1.207" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../data/xsd/ipconfig.xsd">
</gameserver>

6. Собрать и запустить

docker compose build
docker compose up -d
docker compose logs -f mysql loginserver gameserver

Ожидаемая последовательность в логах:

  1. mysql — выполняет SQL-схемы, проходит healthcheck
  2. loginserver — LoginServer: Login client listener started on 0.0.0.0:2106
  3. gameserver — LoginServerThread: Registered on login as Server N: <Name>

Если видишь Registered on login as Server — стек полностью поднят.

Просмотр полного дистрибутива сервера (reference)

/out внутри builder-образа (login/, game/, sql/ с jar-файлами, конфигами и data/) существует только как промежуточный слой между стадиями Docker-сборки — на хосте его не видно напрямую. Чтобы удобно читать дефолтные файлы сервера (посмотреть, что там есть, прежде чем что-то копировать в override), используй скрипт scripts/extract-reference.sh:

./scripts/extract-reference.sh

Это выгружает полный /out из свежего l2j-build:latest образа в ./reference/ — обычную папку на диске:

reference/login/config/...
reference/game/config/...
reference/game/data/...
reference/login/libs/...

Дальше — смотришь нужный файл и копируешь только его в override:

cat reference/game/config/Rates.ini
cp reference/game/config/Rates.ini config/game/config/Rates.ini
nano config/game/config/Rates.ini
docker compose up -d --force-recreate gameserver

reference/ — сгенерированные файлы, не нужно коммитить их в git (см. .gitignore). После пересборки Java-кода (docker build -f Dockerfile.build ...) перезапусти скрипт, чтобы reference/ отражал актуальную сборку:

docker build -f Dockerfile.build -t l2j-build:latest . && ./scripts/extract-reference.sh

Редактирование конфигов

Все дефолтные конфиги обоих серверов уже скопированы в config/login/config/ и config/game/config/. Правь их прямо здесь:

nano config/game/config/Rates.ini    # рейты экспы/дропа
nano config/game/config/NPC.ini      # агрессия, respawn
nano config/game/config/Player.ini   # лимиты персонажей

После правки — пересоздать нужный контейнер (без пересборки образа, если менялся только конфиг, а не код):

docker compose up -d --force-recreate gameserver

Важно — не копируй reference/ в config/ массово поверх уже настроенных файлов. config/login/config/Database.ini, config/game/config/Database.ini, config/game/config/Server.ini и config/game/config/ipconfig.xml содержат критичные сетевые правки (mysql/loginserver вместо localhost/127.0.0.1) — если их затереть дефолтными значениями из reference/, game-сервер перестанет находить MySQL или login-сервер (Connection refused, LoginServer not available). Копируй в override только конкретные файлы, которые собираешься менять, не весь каталог целиком.

Изменение кода сервера

Исходники лежат в src/java/. После правки:

docker build -f Dockerfile.build -t l2j-build:latest .
docker compose build
docker compose up -d

Первая команда пересобирает Java-код через Ant, вторая — пересобирает runtime-образы login/game с новыми jar-файлами, третья — перезапускает стек.

Память JVM

Размер кучи для game-сервера задан в game/entrypoint.sh:

exec java -Xms1g -Xmx4g -Dfile.encoding=UTF-8 -cp "$CLASSPATH" -jar libs/GameServer.jar

Полная геодата High Five (203 региона) требует заметного объёма памяти при загрузке — при OutOfMemoryError на этапе [ Geodata ] увеличь -Xmx. После правки:

docker compose build gameserver
docker compose up -d --force-recreate gameserver

Резервное копирование

Образы и контейнеры полностью воспроизводимы из этого репозитория — бэкапить нужно только:

  1. Сам репозиторий (src/, конфиги, override) — обычный git.
  2. Данные MySQL (аккаунты, персонажи) — они живут в Docker-volume mysql_data, не в файлах проекта. Дамп:
docker exec l2j-mysql mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" l2jmobiush5 > backup_$(date +%Y%m%d_%H%M%S).sql

Восстановление:

docker exec -i l2j-mysql mysql -u root -p"$MYSQL_ROOT_PASSWORD" l2jmobiush5 < backup_ФАЙЛ.sql

Порты

Сервис Порт Назначение
loginserver 2106 Подключение клиента (экран логина)
gameserver 7777 Подключение клиента (после выбора сервера)
gameserver → loginserver 9014 Внутренний auth-обмен между серверами
mysql 3306 БД (не публикуется наружу по умолчанию)

Меняются в .env.