commit 2c0d264d2f0a41329ea280e4b2a98845604e20d5 Author: poison-flower Date: Fri Sep 11 14:50:33 2026 +0300 Загрузить файлы в «/» diff --git a/README.md b/README.md new file mode 100644 index 00000000..0a1ee75f --- /dev/null +++ b/README.md @@ -0,0 +1,267 @@ +# 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-образ + +```bash +docker build -f Dockerfile.build -t l2j-build:latest . +``` + +### 2. Геодата + +Скачай геодату для High Five отдельно (она не входит в репозиторий Mobius и +не входит в этот проект — файлы `*.l2j`, обычно раздаются на форумах/трекерах). +Распакуй все `.l2j` файлы (и `geo_index.txt`) прямо в `./geodata/`, без +вложенных подпапок. + +### 3. Настроить `.env` + +```bash +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="..."` в + корневом теге ``. Это 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 + + + +``` + +### 6. Собрать и запустить + +```bash +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: ` + +Если видишь `Registered on login as Server` — стек полностью поднят. + +## Просмотр полного дистрибутива сервера (reference) + +`/out` внутри builder-образа (`login/`, `game/`, `sql/` с jar-файлами, +конфигами и data/) существует только как промежуточный слой между стадиями +Docker-сборки — на хосте его не видно напрямую. Чтобы удобно читать +дефолтные файлы сервера (посмотреть, что там есть, прежде чем что-то +копировать в override), используй скрипт `scripts/extract-reference.sh`: + +```bash +./scripts/extract-reference.sh +``` + +Это выгружает полный `/out` из свежего `l2j-build:latest` образа в +`./reference/` — обычную папку на диске: + +``` +reference/login/config/... +reference/game/config/... +reference/game/data/... +reference/login/libs/... +``` + +Дальше — смотришь нужный файл и копируешь **только его** в override: + +```bash +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/` отражал актуальную сборку: + +```bash +docker build -f Dockerfile.build -t l2j-build:latest . && ./scripts/extract-reference.sh +``` + +## Редактирование конфигов + +Все дефолтные конфиги обоих серверов уже скопированы в +`config/login/config/` и `config/game/config/`. Правь их прямо здесь: + +```bash +nano config/game/config/Rates.ini # рейты экспы/дропа +nano config/game/config/NPC.ini # агрессия, respawn +nano config/game/config/Player.ini # лимиты персонажей +``` + +После правки — пересоздать нужный контейнер (без пересборки образа, если +менялся только конфиг, а не код): + +```bash +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/`. После правки: + +```bash +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`: + +```bash +exec java -Xms1g -Xmx4g -Dfile.encoding=UTF-8 -cp "$CLASSPATH" -jar libs/GameServer.jar +``` + +Полная геодата High Five (203 региона) требует заметного объёма памяти при +загрузке — при `OutOfMemoryError` на этапе `[ Geodata ]` увеличь `-Xmx`. +После правки: + +```bash +docker compose build gameserver +docker compose up -d --force-recreate gameserver +``` + +## Резервное копирование + +Образы и контейнеры полностью воспроизводимы из этого репозитория — бэкапить +нужно только: + +1. **Сам репозиторий** (`src/`, конфиги, override) — обычный git. +2. **Данные MySQL** (аккаунты, персонажи) — они живут в Docker-volume + `mysql_data`, не в файлах проекта. Дамп: + +```bash +docker exec l2j-mysql mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" l2jmobiush5 > backup_$(date +%Y%m%d_%H%M%S).sql +``` + +Восстановление: + +```bash +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`.