production setup
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
.git
|
||||
.github
|
||||
build
|
||||
data
|
||||
docker/db-dumps
|
||||
*.log
|
||||
*.pid
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
DB_ROOT_PASSWORD=change-me
|
||||
DB_USER=sylvania
|
||||
DB_PASSWORD=sylvania
|
||||
EXTERNAL_ADDRESS=127.0.0.1
|
||||
REALM_NAME=Sylvania Solo
|
||||
REALM_ADDRESS=127.0.0.1
|
||||
REALM_PORT=8086
|
||||
BUILD_JOBS=2
|
||||
BUILD_TYPE=Release
|
||||
IMAGE_TAG=local
|
||||
@@ -0,0 +1,13 @@
|
||||
# Copy to .env.production and replace both passwords before deployment.
|
||||
DB_ROOT_PASSWORD=GENERATE_A_LONG_RANDOM_ROOT_PASSWORD
|
||||
DB_USER=sylvania
|
||||
DB_PASSWORD=GENERATE_A_DIFFERENT_LONG_RANDOM_DB_PASSWORD
|
||||
|
||||
REALM_NAME=FelWell
|
||||
REALM_ADDRESS=legion.moon-well.online
|
||||
REALM_PORT=8085
|
||||
EXTERNAL_ADDRESS=legion.moon-well.online
|
||||
|
||||
BUILD_JOBS=8
|
||||
BUILD_TYPE=Release
|
||||
IMAGE_TAG=production
|
||||
@@ -9,6 +9,12 @@ build*/
|
||||
*.kdev*
|
||||
.DS_Store
|
||||
CMakeLists.txt.user
|
||||
.env
|
||||
.env.production
|
||||
/data/
|
||||
/docker/db-dumps/*.rar
|
||||
/docker/db-dumps/*.sql
|
||||
/docker/db-dumps/*.sql.gz
|
||||
*.bak
|
||||
*.patch
|
||||
*.diff
|
||||
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
FROM ubuntu:24.04 AS builder
|
||||
|
||||
ARG BUILD_TYPE=Release
|
||||
ARG BUILD_JOBS=2
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
|
||||
apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
cmake \
|
||||
git \
|
||||
libboost-filesystem-dev \
|
||||
libboost-iostreams-dev \
|
||||
libboost-locale-dev \
|
||||
libboost-program-options-dev \
|
||||
libboost-regex-dev \
|
||||
libboost-system-dev \
|
||||
libboost-thread-dev \
|
||||
libbz2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libmariadb-dev \
|
||||
libmariadb-dev-compat \
|
||||
libncurses-dev \
|
||||
libreadline-dev \
|
||||
libssl-dev \
|
||||
zlib1g-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
|
||||
RUN cmake -S . -B /build \
|
||||
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
||||
-DCMAKE_INSTALL_PREFIX=/opt/sylvania \
|
||||
-DTOOLS=OFF \
|
||||
&& cmake --build /build --parallel "${BUILD_JOBS}" \
|
||||
&& cmake --install /build
|
||||
|
||||
FROM ubuntu:24.04 AS runtime
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
|
||||
apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
libboost-filesystem1.83.0 \
|
||||
libboost-iostreams1.83.0 \
|
||||
libboost-locale1.83.0 \
|
||||
libboost-program-options1.83.0 \
|
||||
libboost-regex1.83.0 \
|
||||
libboost-system1.83.0 \
|
||||
libboost-thread1.83.0 \
|
||||
libbz2-1.0 \
|
||||
libcurl4t64 \
|
||||
libmariadb3 \
|
||||
libncurses6 \
|
||||
libreadline8t64 \
|
||||
libssl3t64 \
|
||||
mariadb-client \
|
||||
zlib1g \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& useradd --system --uid 10001 --home /opt/sylvania --shell /usr/sbin/nologin sylvania
|
||||
|
||||
COPY --from=builder /opt/sylvania /opt/sylvania
|
||||
COPY docker/entrypoint.sh /usr/local/bin/sylvania-entrypoint
|
||||
|
||||
RUN chmod +x /usr/local/bin/sylvania-entrypoint \
|
||||
&& mkdir -p /opt/sylvania/data /opt/sylvania/logs \
|
||||
&& chown -R sylvania:sylvania /opt/sylvania
|
||||
|
||||
USER sylvania
|
||||
WORKDIR /opt/sylvania
|
||||
|
||||
EXPOSE 1119 8081 8085
|
||||
ENTRYPOINT ["sylvania-entrypoint"]
|
||||
CMD ["worldserver"]
|
||||
@@ -0,0 +1,58 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
FROM ubuntu:24.04 AS builder
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
|
||||
apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
cmake \
|
||||
git \
|
||||
libboost-filesystem-dev \
|
||||
libboost-iostreams-dev \
|
||||
libboost-locale-dev \
|
||||
libboost-program-options-dev \
|
||||
libboost-regex-dev \
|
||||
libboost-system-dev \
|
||||
libboost-thread-dev \
|
||||
libbz2-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libmariadb-dev \
|
||||
libmariadb-dev-compat \
|
||||
libncurses-dev \
|
||||
libreadline-dev \
|
||||
libssl-dev \
|
||||
zlib1g-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
|
||||
RUN cmake -S . -B /build \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=/opt/sylvania \
|
||||
-DSERVERS=OFF \
|
||||
-DTOOLS=ON \
|
||||
&& cmake --build /build --parallel 2 \
|
||||
&& cmake --install /build
|
||||
|
||||
FROM ubuntu:24.04
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
libboost-filesystem1.83.0 \
|
||||
libboost-iostreams1.83.0 \
|
||||
libboost-program-options1.83.0 \
|
||||
libboost-regex1.83.0 \
|
||||
libboost-system1.83.0 \
|
||||
libbz2-1.0 \
|
||||
libssl3t64 \
|
||||
zlib1g \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY --from=builder /opt/sylvania/bin /opt/sylvania/bin
|
||||
WORKDIR /client
|
||||
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
# FelWell — Legion 7.3.5
|
||||
|
||||
Production-сборка SylvaniaCore для realm **FelWell**. Сервер рассчитан на
|
||||
клиент World of Warcraft Legion **7.3.5 build 26972** и публикуется по адресу
|
||||
`legion.moon-well.online`.
|
||||
|
||||
## Что входит в сборку
|
||||
|
||||
- SylvaniaCore: `worldserver` и `bnetserver`;
|
||||
- MariaDB 11.4 с базами `auth`, `characters`, `world`, `hotfixes` и `shop`;
|
||||
- Docker Compose для сборки и запуска всего стека;
|
||||
- автоматическая настройка `auth.realmlist` из переменных окружения;
|
||||
- русская локализация дополнительных `broadcast_text`;
|
||||
- постоянные Docker volumes для базы данных и журналов.
|
||||
|
||||
## Требования к VPS
|
||||
|
||||
- Ubuntu 24.04;
|
||||
- Docker Engine с Compose plugin;
|
||||
- DNS-запись `legion.moon-well.online`, направленная на публичный IP VPS;
|
||||
- открытые входящие TCP-порты `1119`, `8081` и `8085`;
|
||||
- игровой порт MariaDB `3306` не должен быть открыт в Интернет.
|
||||
|
||||
В каталоге `data/` должны находиться данные, извлечённые из клиента
|
||||
7.3.5.26972: `dbc`, `maps`, `vmaps`, `mmaps`, `cameras` и `gt`.
|
||||
|
||||
## Первый запуск
|
||||
|
||||
Создайте production-конфигурацию:
|
||||
|
||||
```bash
|
||||
cp .env.production.example .env.production
|
||||
nano .env.production
|
||||
```
|
||||
|
||||
Обязательно замените `DB_ROOT_PASSWORD` и `DB_PASSWORD` на разные длинные
|
||||
случайные пароли. Затем положите полные дампы `world` и `hotfixes` в
|
||||
`docker/db-dumps/` и запустите сервер:
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env.production up --build -d
|
||||
docker compose --env-file .env.production ps
|
||||
docker compose --env-file .env.production logs -f bnetserver worldserver
|
||||
```
|
||||
|
||||
При запуске запись realm автоматически получает следующие значения:
|
||||
|
||||
```text
|
||||
name = FelWell
|
||||
address = legion.moon-well.online
|
||||
port = 8085
|
||||
gamebuild = 26972
|
||||
```
|
||||
|
||||
## Русские переводы
|
||||
|
||||
Дополнительные переводы находятся в `sql/translations/ruRU/`. Их можно
|
||||
импортировать после инициализации базы:
|
||||
|
||||
```bash
|
||||
set -a
|
||||
. ./.env.production
|
||||
set +a
|
||||
|
||||
for file in sql/translations/ruRU/broadcast_text_locale_ruRU_part_*.sql; do
|
||||
docker compose --env-file .env.production exec -T database \
|
||||
mariadb --binary-mode -uroot "-p${DB_ROOT_PASSWORD}" hotfixes < "$file"
|
||||
done
|
||||
|
||||
docker compose --env-file .env.production restart worldserver
|
||||
```
|
||||
|
||||
Импорт идемпотентный: существующие строки не перезаписываются.
|
||||
|
||||
## Свой Git-сервер и обновления GitHub
|
||||
|
||||
Используется стандартная схема с двумя remote:
|
||||
|
||||
- `origin` — ваш собственный Git-сервер, основное место хранения;
|
||||
- `upstream` — публичный GitHub-репозиторий SylvaniaCore, только источник
|
||||
обновлений.
|
||||
|
||||
GitHub уже настроен как `upstream`. Добавьте свой сервер, подставив настоящий
|
||||
SSH URL:
|
||||
|
||||
```bash
|
||||
git remote add origin git@YOUR_GIT_SERVER:YOUR_GROUP/SylvaniaCore.git
|
||||
git push -u origin master
|
||||
git remote -v
|
||||
```
|
||||
|
||||
Рабочие изменения сначала коммитятся и отправляются только в ваш `origin`:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Configure FelWell production deployment"
|
||||
git push origin master
|
||||
```
|
||||
|
||||
Для получения очередных обновлений GitHub:
|
||||
|
||||
```bash
|
||||
git status
|
||||
git fetch upstream --prune
|
||||
git switch master
|
||||
git branch "backup/before-upstream-$(date +%F-%H%M)"
|
||||
git merge upstream/sylvaniacore
|
||||
```
|
||||
|
||||
Если возникли конфликты, разрешите их, сохраняя FelWell-настройки в
|
||||
`compose.yaml`, `docker/`, `.env.production.example` и SQL-миграциях. После
|
||||
сборки и проверки отправьте результат на собственный сервер:
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env.production build
|
||||
docker compose --env-file .env.production up -d
|
||||
docker compose --env-file .env.production logs --tail=200 worldserver bnetserver
|
||||
git push origin master
|
||||
```
|
||||
|
||||
Не выполняйте обновление при незакоммиченных изменениях. Файлы `.env`,
|
||||
`.env.production`, игровые данные и полные дампы БД исключены из Git.
|
||||
|
||||
## Резервное копирование базы
|
||||
|
||||
Перед обновлением создайте дамп всех игровых баз:
|
||||
|
||||
```bash
|
||||
set -a
|
||||
. ./.env.production
|
||||
set +a
|
||||
|
||||
docker compose --env-file .env.production exec -T database \
|
||||
mariadb-dump -uroot "-p${DB_ROOT_PASSWORD}" \
|
||||
--single-transaction --routines --events \
|
||||
--databases auth characters world hotfixes shop \
|
||||
| gzip > "felwell-$(date +%F-%H%M).sql.gz"
|
||||
```
|
||||
|
||||
Храните резервные копии вне VPS. Docker volume защищает данные при пересоздании
|
||||
контейнеров, но не заменяет внешнюю резервную копию.
|
||||
|
||||
## Полезные команды
|
||||
|
||||
```bash
|
||||
# Состояние контейнеров
|
||||
docker compose --env-file .env.production ps
|
||||
|
||||
# Последние журналы
|
||||
docker compose --env-file .env.production logs --tail=200 worldserver bnetserver
|
||||
|
||||
# Перезапуск серверов без удаления БД
|
||||
docker compose --env-file .env.production restart bnetserver worldserver
|
||||
|
||||
# Остановка стека с сохранением volumes
|
||||
docker compose --env-file .env.production down
|
||||
```
|
||||
|
||||
Не запускайте `docker compose down -v` на production: ключ `-v` удаляет volume
|
||||
MariaDB вместе с игровыми аккаунтами и персонажами.
|
||||
+309
@@ -0,0 +1,309 @@
|
||||
<div align="center">
|
||||
|
||||
<img src=".github/assets/sylvaniacore-logo.png" alt="SylvaniaCore" width="360">
|
||||
|
||||
# SylvaniaCore
|
||||
|
||||
**C++-ядро игрового мира [La Légion de Sylvania](https://legendesylvania.com)**<br>
|
||||
Эмулятор сервера *World of Warcraft®* — Legion 7.3.5
|
||||
|
||||
[](https://discord.gg/qmQBXbuXkx)
|
||||
[](./LICENSE)
|
||||
[](https://github.com/BlaMacfly/SylvaniaCore/stargazers)
|
||||
[](https://github.com/BlaMacfly/SylvaniaCore/network/members)
|
||||
[](https://github.com/slash-design/DestinyCore)
|
||||
|
||||
</div>
|
||||
|
||||
> Практическая инструкция по Docker, production-развёртыванию FelWell и
|
||||
> синхронизации с собственным Git-сервером: [README.ru.md](./README.ru.md).
|
||||
|
||||
---
|
||||
|
||||
## 📖 О проекте
|
||||
|
||||
**SylvaniaCore** — ядро франкоязычного игрового мира **La Légion de Sylvania**
|
||||
для *World of Warcraft® Legion 7.3.5*. Это форк
|
||||
[DestinyCore](https://github.com/slash-design/DestinyCore), который, в свою
|
||||
очередь, происходит из семейства TrinityCore. Проект постоянно развивается и
|
||||
поддерживается для нужд игрового мира.
|
||||
|
||||
Репозиторий одновременно служит **актуальной кодовой базой** и **резервной
|
||||
копией** production-сервера.
|
||||
|
||||
### Философия: «адаптивный blizzlike»
|
||||
|
||||
Это не *fun*-сервер и не сервер с *rates x∞*. Оригинальные значения Blizzard
|
||||
(урон, баланс и экономика) **сохраняются**. Основная работа направлена на
|
||||
**исправление отклонений от blizzlike**, а не на упрощение игры. Каждая
|
||||
обнаруженная ошибка исправляется в источнике — в данных или в ядре, — а не
|
||||
обходится командами игрового мастера.
|
||||
|
||||
---
|
||||
|
||||
## ✨ Дополнения SylvaniaCore
|
||||
|
||||
Помимо возможностей upstream-ядра, проект содержит собственные системы:
|
||||
|
||||
| Модуль | Описание |
|
||||
| --- | --- |
|
||||
| 🤖 **PlayerBots** | Управляемые боты-игроки (`src/server/game/PlayerBot`): групповые команды, роли танка и лекаря, управление экипировкой и автоматическое заполнение полей боя |
|
||||
| ⚔️ **Осада столиц** | Ежедневные нападения отрядов ботов на столицы с назначенным командиром и PvP-флагом игроков (`src/server/game/CapitalSiege`) |
|
||||
| 💰 **Наёмники** | Нанимаемые NPC-компаньоны: одиночный игрок может заключить с ними контракт за игровое золото (`src/server/game/Mercenary`) |
|
||||
| 🇫🇷 **Локализация frFR** | Восстановление официальных французских текстов из клиента 7.3.5 — заданий, диалогов и broadcast-текстов — и перевод отсутствующего сценарного контента |
|
||||
| 🐛 **Исправления контента** | Последовательное восстановление кампаний, подземелий и заданий по отдельным зонам: Мардум, Скитающийся остров, Вершина Смерча и другие |
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Требования
|
||||
|
||||
- **CMake 3.31+**
|
||||
- **Boost 1.84.0**
|
||||
- **MySQL 8.0** или **MariaDB 10.6+** — игровой мир использует MariaDB 11.4
|
||||
- **OpenSSL 3.x**
|
||||
- **GCC / Clang / MSVC** — рекомендуется Visual Studio 2022
|
||||
|
||||
Поддерживаемые платформы: **Linux, Windows и macOS**.
|
||||
|
||||
---
|
||||
|
||||
## 📦 Сборка
|
||||
|
||||
1. Клонируйте репозиторий:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/BlaMacfly/SylvaniaCore.git
|
||||
cd SylvaniaCore
|
||||
```
|
||||
|
||||
2. Настройте и соберите проект:
|
||||
|
||||
```bash
|
||||
cmake -S . -B build -DTOOLS=ON
|
||||
cmake --build build -j$(nproc)
|
||||
```
|
||||
|
||||
3. Установите базы данных согласно разделу
|
||||
[Установка базы данных](#-установка-базы-данных).
|
||||
|
||||
4. Запустите серверы:
|
||||
|
||||
```bash
|
||||
./bin/worldserver
|
||||
./bin/bnetserver
|
||||
```
|
||||
|
||||
> ℹ️ В исходном коде намеренно сохранены внутренние имена upstream-проекта:
|
||||
> `DestinyCore`, названия целей CMake и пути конфигурации. Это обеспечивает
|
||||
> совместимость с upstream-обновлениями и существующими сценариями
|
||||
> развёртывания.
|
||||
|
||||
### Docker Compose
|
||||
|
||||
Ядро, сервер Battle.net и MariaDB 11.4 можно собрать и запустить вместе:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Поместите DB_world_*.sql и DB_hotfixes_*.sql (или .sql.gz) в docker/db-dumps/
|
||||
# Поместите dbc/, maps/, vmaps/, mmaps/, cameras/ и gt/ клиента 7.3.5 в data/
|
||||
docker compose up --build -d
|
||||
docker compose logs -f worldserver
|
||||
```
|
||||
|
||||
Схемы `auth`, `characters` и `shop` импортируются автоматически при первом
|
||||
запуске MariaDB. Полные дампы `world` и `hotfixes` также импортируются из
|
||||
`docker/db-dumps/`. Перед публикацией сервера обязательно замените пароли в
|
||||
`.env`. Объявляемый клиентам адрес задаётся переменной `EXTERNAL_ADDRESS`.
|
||||
|
||||
### Production-развёртывание FelWell
|
||||
|
||||
Production-шаблон настраивает игровой мир `FelWell` по адресу
|
||||
`legion.moon-well.online:8085`:
|
||||
|
||||
```bash
|
||||
cp .env.production.example .env.production
|
||||
# Обязательно замените оба пароля в .env.production
|
||||
docker compose --env-file .env.production up --build -d
|
||||
docker compose --env-file .env.production logs -f bnetserver worldserver
|
||||
```
|
||||
|
||||
При запуске запись `auth.realmlist` автоматически синхронизируется с
|
||||
`REALM_NAME`, `REALM_ADDRESS` и `REALM_PORT`. DNS-запись `A/AAAA` должна
|
||||
указывать на VPS, а брандмауэр должен разрешать TCP-порты `1119`, `8081` и
|
||||
`8085`. MariaDB должна оставаться только во внутренней сети Docker и не должна
|
||||
публиковаться в Интернет.
|
||||
|
||||
Volumes `database-data` и `sylvania-logs` сохраняют базу данных и журналы
|
||||
соответственно. Изменения в `docker/db-dumps/` не импортируются повторно, если
|
||||
база уже была инициализирована.
|
||||
|
||||
---
|
||||
|
||||
## 💾 Установка базы данных
|
||||
|
||||
Репозиторий содержит **только схемы** `auth`, `characters` и `shop`. Базы
|
||||
`world` и `hotfixes` слишком велики для хранения в Git; их необходимо загрузить
|
||||
из **релизов upstream-репозитория DestinyCore**.
|
||||
|
||||
> ⚠️ **Никогда не импортируйте файлы из `sql/base/dev/`.** Это **пустые**
|
||||
> структуры таблиц без игровых данных, предназначенные для разработчиков
|
||||
> upstream-проекта. После такого импорта `worldserver` может запуститься, но
|
||||
> клиент останется на экране загрузки из-за пустой базы `world`.
|
||||
|
||||
### 1. Загрузка upstream-базы
|
||||
|
||||
Загрузите последний релиз базы на странице
|
||||
[slash-design/DestinyCore/releases](https://github.com/slash-design/DestinyCore/releases).
|
||||
На момент написания это `DB735.02.rar` размером около 84 МБ. Архив содержит два
|
||||
дампа:
|
||||
|
||||
| Файл | База | Размер после распаковки |
|
||||
| --- | --- | --- |
|
||||
| `DB_world_735.02.sql` | `world` | около 375 МБ |
|
||||
| `DB_hotfixes_735.02.sql` | `hotfixes` | около 127 МБ |
|
||||
|
||||
Оба дампа самостоятельно выполняют `CREATE DATABASE`, а затем `USE` для баз
|
||||
`world` и `hotfixes`. Если нужны другие имена баз, измените эти две строки в
|
||||
начале соответствующего файла.
|
||||
|
||||
### 2. Создание и импорт баз
|
||||
|
||||
```bash
|
||||
# Базы auth / characters / world / hotfixes
|
||||
mysql -u root -p < sql/create/create_mysql.sql
|
||||
|
||||
# База shop не создаётся upstream-скриптом
|
||||
mysql -u root -p -e "CREATE DATABASE shop DEFAULT CHARACTER SET utf8;"
|
||||
|
||||
# Схемы из репозитория
|
||||
mysql -u trinity -p auth < sql/base/auth_database.sql
|
||||
mysql -u trinity -p characters < sql/base/characters_database.sql
|
||||
mysql -u trinity -p shop < sql/base/shop_database.sql
|
||||
|
||||
# Полные базы из upstream-релиза
|
||||
mysql -u trinity -p < DB_world_735.02.sql
|
||||
mysql -u trinity -p < DB_hotfixes_735.02.sql
|
||||
```
|
||||
|
||||
### 3. Автоматическое применение обновлений ядром
|
||||
|
||||
Не импортируйте файлы из `sql/updates/` вручную. В `worldserver.conf` должно
|
||||
быть указано:
|
||||
|
||||
```ini
|
||||
Updates.EnableDatabases = 31 # auth + characters + world + hotfixes + shop
|
||||
Updates.AutoSetup = 1
|
||||
```
|
||||
|
||||
При первом запуске `worldserver` самостоятельно применит около 330 файлов из
|
||||
`sql/updates/world`, а также обновления для `characters` и `hotfixes`. Таблица
|
||||
`updates` в upstream-дампах изначально пуста — это нормально: история
|
||||
обновлений будет применена целиком. Процесс может занять несколько минут.
|
||||
|
||||
### 4. Исправления контента игрового мира (необязательно)
|
||||
|
||||
В `sql/sylvania/` хранится версионируемая история исправлений игровых данных:
|
||||
артефактов, кампаний, подземелий, модулей «Наёмники» и «Осада столиц». Они не
|
||||
относятся к механизму автоматических обновлений и импортируются вручную в
|
||||
хронологическом порядке после завершения предыдущих этапов. Production-база
|
||||
`world` игрового мира не распространяется.
|
||||
|
||||
### 🩺 Клиент завис на экране загрузки?
|
||||
|
||||
Следующие два сообщения появляются при каждом подключении на **всех** серверах
|
||||
этого семейства и **не являются ошибками**:
|
||||
|
||||
```text
|
||||
Client tried to call not implemented method ResourceService.GetContentHandle
|
||||
Received not handled opcode [CMSG_GET_ACCOUNT_CHARACTER_LIST ...]
|
||||
```
|
||||
|
||||
`ResourceService` — незавершённая upstream-реализация сервиса Battle.net, а
|
||||
`CMSG_GET_ACCOUNT_CHARACTER_LIST`, то есть межсерверный список персонажей,
|
||||
намеренно объявлен как `STATUS_UNHANDLED` в
|
||||
`src/server/game/Server/Protocol/Opcodes.cpp`. Если клиент не проходит экран
|
||||
загрузки, проверьте:
|
||||
|
||||
- правильность импорта `world` и `hotfixes`, учитывая предупреждение о
|
||||
`sql/base/dev/`;
|
||||
- кеш клиента — очистите каталог `Cache`;
|
||||
- извлечённые данные: `dbc/`, `maps/`, `vmaps/`, `mmaps/`, `cameras/` и `gt/`
|
||||
должны происходить из клиента **7.3.5 build 26972**, а `DataDir` должен
|
||||
указывать на содержащий их каталог;
|
||||
- `DBErrors.log` и начальные строки журнала `worldserver`, где будет указана
|
||||
проблемная таблица.
|
||||
|
||||
---
|
||||
|
||||
## 🌍 Подключение к игровому миру
|
||||
|
||||
Игровой сервер открыт, а инструкции по подключению опубликованы на официальном
|
||||
сайте: **[legendesylvania.com](https://legendesylvania.com)**.
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Участие в разработке
|
||||
|
||||
Мы приветствуем исправления ошибок, улучшения документации и новые возможности:
|
||||
|
||||
1. Создайте форк репозитория.
|
||||
2. Создайте отдельную ветку для изменения.
|
||||
3. Откройте pull request.
|
||||
|
||||
Discord открыт **для разработчиков и всех желающих участвовать в развитии
|
||||
ядра**. Там можно обсудить исправление до начала работы, задать вопросы по
|
||||
архитектуре или попросить проверить pull request. Это не Discord игрового мира.
|
||||
|
||||
<a href="https://discord.gg/qmQBXbuXkx"><img src="https://img.shields.io/badge/Discord-Для%20разработчиков-5865F2?style=for-the-badge&logo=discord&logoColor=white" alt="Присоединиться к Discord разработчиков"></a>
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Сообщение об ошибке
|
||||
|
||||
Создайте обращение в [трекере задач](https://github.com/BlaMacfly/SylvaniaCore/issues).
|
||||
Перед этим убедитесь, что аналогичная проблема ещё не зарегистрирована.
|
||||
|
||||
---
|
||||
|
||||
## 🙏 Благодарности
|
||||
|
||||
SylvaniaCore не существовал бы без проектов, на основе которых он создан:
|
||||
|
||||
- [DestinyCore](https://github.com/slash-design/DestinyCore) — upstream-ядро,
|
||||
форком которого является этот репозиторий;
|
||||
- [TrinityCore](https://github.com/TrinityCore/TrinityCore) — исходное семейство
|
||||
проекта;
|
||||
- [**ArgusCore**](https://github.com/Trion-Control-Panel/ArgusCore), проект
|
||||
[FlyingPhoenix](https://github.com/fIyingPhoenix), — один из важнейших
|
||||
ориентиров для SylvaniaCore. В нём проделана огромная работа над движком,
|
||||
сетевым уровнем и механиками классов версии 7.3.5. Мы регулярно используем
|
||||
его как источник решений при восстановлении крупных частей ядра. Спасибо за
|
||||
открыто опубликованные наработки;
|
||||
- [mod-playerbots](https://github.com/liyunfan1223/mod-playerbots) — источник
|
||||
решений для логики ботов-игроков.
|
||||
|
||||
Состояние CI upstream-репозитория:
|
||||
[](https://github.com/slash-design/DestinyCore/actions/workflows/win-x64-build.yml)
|
||||
[](https://github.com/slash-design/DestinyCore/actions/workflows/gcc-build.yml)
|
||||
[](https://github.com/slash-design/DestinyCore/actions/workflows/clang-build.yml)
|
||||
|
||||
---
|
||||
|
||||
## 📜 Лицензия
|
||||
|
||||
Проект распространяется по лицензии **GPL v2.0**. См. файл
|
||||
[LICENSE](./LICENSE).
|
||||
|
||||
*World of Warcraft® и Blizzard Entertainment® являются зарегистрированными
|
||||
товарными знаками Blizzard Entertainment, Inc. Проект не связан с Blizzard
|
||||
Entertainment и не одобрен этой компанией.*
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
|
||||
<img src=".github/assets/sylvaniacore-logo.png" alt="SylvaniaCore" width="90">
|
||||
|
||||
⭐ Если вам нравится SylvaniaCore, поставьте проекту звезду!
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,71 @@
|
||||
name: sylvania-core
|
||||
|
||||
x-core: &core
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
BUILD_JOBS: ${BUILD_JOBS:-2}
|
||||
BUILD_TYPE: ${BUILD_TYPE:-Release}
|
||||
image: sylvania-core:${IMAGE_TAG:-local}
|
||||
working_dir: /opt/sylvania/bin
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
database:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
DB_HOST: database
|
||||
DB_PORT: 3306
|
||||
DB_USER: ${DB_USER:-sylvania}
|
||||
DB_PASSWORD: ${DB_PASSWORD:-sylvania}
|
||||
REALM_NAME: ${REALM_NAME:-Sylvania Solo}
|
||||
REALM_ADDRESS: ${REALM_ADDRESS:-127.0.0.1}
|
||||
REALM_PORT: ${REALM_PORT:-8086}
|
||||
volumes:
|
||||
- ./data:/opt/sylvania/data:ro
|
||||
- ./sql:/src/sql:ro
|
||||
- sylvania-logs:/opt/sylvania/logs
|
||||
|
||||
services:
|
||||
database:
|
||||
image: mariadb:11.4
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-change-me}
|
||||
DB_USER: ${DB_USER:-sylvania}
|
||||
DB_PASSWORD: ${DB_PASSWORD:-sylvania}
|
||||
volumes:
|
||||
- database-data:/var/lib/mysql
|
||||
- ./docker/database/init.sh:/docker-entrypoint-initdb.d/00-sylvania-init.sh:ro
|
||||
- ./sql/base:/sylvania/base:ro
|
||||
- ./docker/db-dumps:/sylvania/dumps:ro
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "healthcheck.sh --connect --innodb_initialized"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 30
|
||||
start_period: 30s
|
||||
|
||||
bnetserver:
|
||||
<<: *core
|
||||
command: ["bnetserver"]
|
||||
environment:
|
||||
DB_HOST: database
|
||||
DB_PORT: 3306
|
||||
DB_USER: ${DB_USER:-sylvania}
|
||||
DB_PASSWORD: ${DB_PASSWORD:-sylvania}
|
||||
EXTERNAL_ADDRESS: ${EXTERNAL_ADDRESS:-127.0.0.1}
|
||||
ports:
|
||||
- "1119:1119"
|
||||
- "8081:8081"
|
||||
|
||||
worldserver:
|
||||
<<: *core
|
||||
command: ["worldserver"]
|
||||
stdin_open: true
|
||||
tty: true
|
||||
ports:
|
||||
- "${REALM_PORT:-8086}:8085"
|
||||
|
||||
volumes:
|
||||
database-data:
|
||||
sylvania-logs:
|
||||
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
db_user="${DB_USER:-sylvania}"
|
||||
db_password="${DB_PASSWORD:-sylvania}"
|
||||
|
||||
# Identifiers are deliberately fixed; only the application login is configurable.
|
||||
mariadb --protocol=socket -uroot -p"${MARIADB_ROOT_PASSWORD}" <<SQL
|
||||
CREATE DATABASE IF NOT EXISTS auth CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||
CREATE DATABASE IF NOT EXISTS characters CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||
CREATE DATABASE IF NOT EXISTS world CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||
CREATE DATABASE IF NOT EXISTS hotfixes CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||
CREATE DATABASE IF NOT EXISTS shop CHARACTER SET utf8 COLLATE utf8_general_ci;
|
||||
CREATE USER IF NOT EXISTS '${db_user}'@'%' IDENTIFIED BY '${db_password}';
|
||||
GRANT ALL PRIVILEGES ON auth.* TO '${db_user}'@'%';
|
||||
GRANT ALL PRIVILEGES ON characters.* TO '${db_user}'@'%';
|
||||
GRANT ALL PRIVILEGES ON world.* TO '${db_user}'@'%';
|
||||
GRANT ALL PRIVILEGES ON hotfixes.* TO '${db_user}'@'%';
|
||||
GRANT ALL PRIVILEGES ON shop.* TO '${db_user}'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
SQL
|
||||
|
||||
mariadb --protocol=socket -uroot -p"${MARIADB_ROOT_PASSWORD}" auth < /sylvania/base/auth_database.sql
|
||||
mariadb --protocol=socket -uroot -p"${MARIADB_ROOT_PASSWORD}" characters < /sylvania/base/characters_database.sql
|
||||
mariadb --protocol=socket -uroot -p"${MARIADB_ROOT_PASSWORD}" shop < /sylvania/base/shop_database.sql
|
||||
|
||||
shopt -s nullglob
|
||||
for dump in /sylvania/dumps/*.sql /sylvania/dumps/*.sql.gz; do
|
||||
echo "Importing game database dump: ${dump}"
|
||||
if [[ "${dump}" == *.gz ]]; then
|
||||
gzip -dc "${dump}" | mariadb --protocol=socket -uroot -p"${MARIADB_ROOT_PASSWORD}"
|
||||
else
|
||||
mariadb --protocol=socket -uroot -p"${MARIADB_ROOT_PASSWORD}" < "${dump}"
|
||||
fi
|
||||
done
|
||||
|
||||
# The published 7.3.5 dump uses a lowercase name, while the core queries this
|
||||
# one legacy table with its historical mixed-case identifier on Linux.
|
||||
mariadb --protocol=socket -uroot -p"${MARIADB_ROOT_PASSWORD}" \
|
||||
-e 'RENAME TABLE hotfixes.questv2clitask TO hotfixes.QuestV2CliTask;'
|
||||
@@ -0,0 +1,13 @@
|
||||
# Full game database dumps
|
||||
|
||||
Put the upstream `world` and `hotfixes` dumps here before the first
|
||||
`docker compose up`. Both plain `.sql` and `.sql.gz` files are imported.
|
||||
|
||||
The repository intentionally does not ship those datasets. Do not use
|
||||
`sql/base/dev`: those files contain empty developer schemas and are not a
|
||||
playable game database.
|
||||
|
||||
If the database volume has already been initialized, add the dumps manually or
|
||||
recreate the volume explicitly with `docker compose down -v` (this deletes all
|
||||
database data).
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
server="${1:-worldserver}"
|
||||
case "${server}" in
|
||||
worldserver|bnetserver) ;;
|
||||
*) exec "$@" ;;
|
||||
esac
|
||||
|
||||
db_host="${DB_HOST:-database}"
|
||||
db_port="${DB_PORT:-3306}"
|
||||
db_user="${DB_USER:-sylvania}"
|
||||
db_password="${DB_PASSWORD:-sylvania}"
|
||||
external_address="${EXTERNAL_ADDRESS:-127.0.0.1}"
|
||||
realm_name="${REALM_NAME:-Sylvania Solo}"
|
||||
realm_address="${REALM_ADDRESS:-127.0.0.1}"
|
||||
realm_port="${REALM_PORT:-8086}"
|
||||
|
||||
if [[ ! "${realm_name}" =~ ^[[:alnum:]А-Яа-яЁё._[:space:]-]{1,32}$ ]]; then
|
||||
echo "REALM_NAME contains unsupported characters or is longer than 32 characters" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! "${realm_address}" =~ ^[A-Za-z0-9.-]+$ ]]; then
|
||||
echo "REALM_ADDRESS must be an IPv4 address or a DNS name" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! "${realm_port}" =~ ^[0-9]+$ ]] || (( realm_port < 1 || realm_port > 65535 )); then
|
||||
echo "REALM_PORT must be an integer between 1 and 65535" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
config_dir=/opt/sylvania/etc
|
||||
template="${config_dir}/${server}.conf.dist"
|
||||
config="${config_dir}/${server}.conf"
|
||||
|
||||
cp "${template}" "${config}"
|
||||
sed -i -E \
|
||||
-e "s#^(LoginDatabaseInfo[[:space:]]*=).*#\\1 \"${db_host};${db_port};${db_user};${db_password};auth\"#" \
|
||||
"${config}"
|
||||
|
||||
# Keep the client-facing realm record in sync after restores and migrations.
|
||||
# Values are validated above before being interpolated into SQL.
|
||||
mariadb --protocol=tcp \
|
||||
-h "${db_host}" -P "${db_port}" -u "${db_user}" "-p${db_password}" auth <<SQL
|
||||
INSERT INTO realmlist
|
||||
(id, name, address, localAddress, localSubnetMask, port, icon, flag,
|
||||
timezone, allowedSecurityLevel, population, gamebuild, Region, Battlegroup)
|
||||
VALUES
|
||||
(1, '${realm_name}', '${realm_address}', '${realm_address}',
|
||||
'255.255.255.0', ${realm_port}, 0, 0, 1, 0, 0, 26972, 1, 1)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
address = VALUES(address),
|
||||
localAddress = VALUES(localAddress),
|
||||
port = VALUES(port),
|
||||
gamebuild = VALUES(gamebuild);
|
||||
SQL
|
||||
|
||||
if [[ "${server}" == worldserver ]]; then
|
||||
sed -i -E \
|
||||
-e "s#^(WorldDatabaseInfo[[:space:]]*=).*#\\1 \"${db_host};${db_port};${db_user};${db_password};world\"#" \
|
||||
-e "s#^(CharacterDatabaseInfo[[:space:]]*=).*#\\1 \"${db_host};${db_port};${db_user};${db_password};characters\"#" \
|
||||
-e "s#^(HotfixDatabaseInfo[[:space:]]*=).*#\\1 \"${db_host};${db_port};${db_user};${db_password};hotfixes\"#" \
|
||||
-e "s#^(ShopDatabaseInfo[[:space:]]*=).*#\\1 \"${db_host};${db_port};${db_user};${db_password};shop\"#" \
|
||||
-e 's#^DataDir[[:space:]]*=.*#DataDir = "/opt/sylvania/data"#' \
|
||||
-e 's#^LogsDir[[:space:]]*=.*#LogsDir = "/opt/sylvania/logs"#' \
|
||||
"${config}"
|
||||
else
|
||||
sed -i -E \
|
||||
-e "s#^LoginREST.ExternalAddress=.*#LoginREST.ExternalAddress=${external_address}#" \
|
||||
-e "s#^LoginREST.LocalAddress=.*#LoginREST.LocalAddress=${external_address}#" \
|
||||
-e 's#^LogsDir[[:space:]]*=.*#LogsDir = "/opt/sylvania/logs"#' \
|
||||
"${config}"
|
||||
fi
|
||||
|
||||
exec "/opt/sylvania/bin/${server}" -c "${config}"
|
||||
@@ -0,0 +1,34 @@
|
||||
# Русская локализация Legion 7.3.5
|
||||
|
||||
Пакет добавляет 37 773 отсутствующие строки `ruRU` в таблицу
|
||||
`broadcast_text_locale`. Переводы взяты из ветки `legion` проекта
|
||||
AshamaneCore и адаптированы к текущей схеме SylvaniaCore:
|
||||
|
||||
- `MaleText_lang` → `Text_lang`
|
||||
- `FemaleText_lang` → `Text1_lang`
|
||||
|
||||
Файлы используют `INSERT IGNORE`: уже существующие строки не изменяются.
|
||||
Импортировать их нужно по порядку в базу `hotfixes`:
|
||||
|
||||
```bash
|
||||
set -a
|
||||
. ./.env
|
||||
set +a
|
||||
|
||||
for file in sql/translations/ruRU/broadcast_text_locale_ruRU_part_*.sql; do
|
||||
docker compose exec -T database \
|
||||
mariadb --binary-mode -uroot "-p${DB_ROOT_PASSWORD}" hotfixes < "$file"
|
||||
done
|
||||
```
|
||||
|
||||
После импорта перезапустите игровой сервер:
|
||||
|
||||
```bash
|
||||
docker compose restart worldserver
|
||||
```
|
||||
|
||||
Перед установкой на рабочий сервер рекомендуется сделать резервную копию БД.
|
||||
|
||||
Таблицы `creature_template_locale`, `quest_template_locale` и
|
||||
`quest_objectives_locale` уже содержат все русские строки из указанного
|
||||
источника, поэтому для них SQL-дельта не требуется.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
||||
-- Production realm defaults. Docker startup keeps these values synchronized
|
||||
-- from REALM_NAME, REALM_ADDRESS and REALM_PORT after this migration runs.
|
||||
UPDATE `realmlist`
|
||||
SET `name` = 'FelWell',
|
||||
`address` = 'legion.moon-well.online',
|
||||
`localAddress` = 'legion.moon-well.online',
|
||||
`port` = 8085,
|
||||
`gamebuild` = 26972
|
||||
WHERE `id` = 1;
|
||||
Reference in New Issue
Block a user