Files
MrixsCraft/docs/server/Specification.md

200 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Спецификация серверной части Minecraft проекта (Backend & Infrastructure)
## 1. Стек технологий
* **Бэкенд-платформа:** Go (чистый net/http с роутером github.com/go-chi/chi, для максимальной прозрачности и контроля).
* **База данных:** PostgreSQL (реляционная СУБД для надежного хранения транзакций токенов, пользователей и связей файлов).
* **Фронтенд (Сайт и Админка):** SPA на Vue.js / React / Svelte, либо классический монолит на Go-шаблонах (html/template) для максимального упрощения деплоя (всё в одном исполняемом файле).
* **Статический веб-сервер (CDN):** Nginx (занимается отдачей тяжелых файлов и проксированием API-запросов к Go-бэкенду).
---
## 2. Архитектура хранилища файлов (Content-Addressable Storage - CAS)
Для экономии места на диске сервера и клиента, а также для сквозного кэширования, все файлы модов, библиотек и ассетов хранятся по их SHA-1 хэшам.
* **Путь на сервере:** `/var/www/cdn/files/[первые два символа хэша]/[полный хэш]`
* *Пример:* Файл с хэшем `a1b2c3d4e5...` будет лежать по пути `/var/www/cdn/files/a1/b2c3d4e5...` (это предотвращает замедление файловой системы при наличии десятков тысяч файлов в одной директории).
* **URL для скачивания:** `https://cdn.myserver.com/files/a1b2c3d4e5...`
---
## 3. Схема Базы Данных (PostgreSQL)
```sql
-- Таблица пользователей
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(32) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
uuid UUID UNIQUE NOT NULL,
role VARCHAR(16) DEFAULT 'user', -- 'user', 'admin'
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Таблица скинов и плащей (ссылки на файлы в CAS)
CREATE TABLE player_textures (
user_id INT PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
skin_hash VARCHAR(40), -- SHA-1 хэш файла скина в CAS
cape_hash VARCHAR(40), -- SHA-1 хэш файла плаща в CAS
is_slim BOOLEAN DEFAULT FALSE -- модель скина (Alex/Steve)
);
-- Сессии Yggdrasil (для авторизации лаунчера и игры)
CREATE TABLE yggdrasil_sessions (
client_token UUID NOT NULL,
access_token UUID PRIMARY KEY,
user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
expires_at TIMESTAMP NOT NULL
);
-- Таблица модпаков (игровых серверов)
CREATE TABLE modpacks (
id SERIAL PRIMARY KEY,
slug VARCHAR(32) UNIQUE NOT NULL, -- например: 'hitech', 'magic'
name VARCHAR(64) NOT NULL,
minecraft_version VARCHAR(16) NOT NULL,
java_version INT NOT NULL, -- 8, 17, 21
server_ip VARCHAR(255) NOT NULL, -- IP:Port для добавления в servers.dat
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Единый реестр уникальных файлов (CAS)
CREATE TABLE global_files (
sha1 VARCHAR(40) PRIMARY KEY,
size_bytes BIGINT NOT NULL,
file_name VARCHAR(255) NOT NULL -- оригинальное имя файла (для истории)
);
-- Релизы лаунчера (заполняются через CI/CD)
CREATE TABLE launcher_releases (
id SERIAL PRIMARY KEY,
version VARCHAR(32) NOT NULL, -- например: '1.2.0'
os VARCHAR(16) NOT NULL, -- 'windows', 'linux', 'darwin'
arch VARCHAR(16) NOT NULL, -- 'amd64', 'arm64'
sha256 VARCHAR(64) NOT NULL, -- SHA-256 для проверки бинарника лаунчера
file_path VARCHAR(255) NOT NULL,
is_active BOOLEAN DEFAULT TRUE,
is_mandatory BOOLEAN DEFAULT TRUE, -- принудительное обновление
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
---
## 4. Спецификация API Эндпоинтов
### 4.1. Автоматический деплой из CI/CD (Protected Route)
Эндпоинт, который вызывает твой пайплайн сборки после успешной компиляции лаунчера.
* **Маршрут:** `POST /api/admin/launcher/release`
* **Авторизация:** Заголовок `X-CI-Token: <секретный_токен_из_секретов_репозитория>`
* **Тело запроса (Multipart Form Data):**
* `version`: "1.2.0"
* `os`: "windows"
* `arch`: "amd64"
* `sha256`: "hash_of_binary..."
* `file`: (бинарный файл лаунчера)
### 4.2. Yggdrasil API (Mojang Emulation)
* `POST /authserver/authenticate` — Аутентификация по логину/паролю. Возвращает UUID и токены.
* `POST /authserver/refresh` — Обновление сессии лаунчера по `clientToken` и `accessToken`.
* `POST /authserver/validate` — Быстрая проверка токена при запуске лаунчера.
* `GET /sessionserver/session/minecraft/profile/{uuid}` — Эндпоинт, к которому обращается сам игровой клиент для загрузки скинов игроков на сервере.
### 4.3. Публичное API сайта и лаунчера
* `POST /api/web/register` — Регистрация игрока.
* `POST /api/web/login` — Логин в личный кабинет сайта.
* `POST /api/web/profile/skin` — Загрузка скина (принимает PNG, считает его SHA-1, сохраняет в `/files/` и привязывает к юзеру).
* `GET /api/launcher/latest` — Возвращает информацию о последней версии лаунчера и ссылки на скачивание для автообновления.
* `GET /api/servers.json` — Список активных модпаков для меню выбора в лаунчере.
---
## 5. Алгоритмы и Пайплайны работы
### 5.1. Пайплайн загрузки и сборки модпака (в Админ-панели)
Когда админ загружает ZIP-архив с обновлением модов/конфигов через панель управления:
```text
[Архив с модами] -> [Распаковка во временную папку]
[Обход каждого файла в цикле]
[Расчет SHA-1 хэша]
┌─────────────┴─────────────┐
▼ ▼
[Хэш ЕСТЬ в базе?] [Хэша НЕТ в базе]
│ │
│ [Копирование в CAS]
│ [/files/ab/abcdef12...]
│ │
└─────────────┬─────────────┘
[Добавление в manifest.json]
```
**Итоговый формат генерируемого `manifest.json` для лаунчера:**
```json
{
"minecraft_version": "1.21",
"java_version": 21,
"server_info": {
"name": "HiTech Server",
"ip": "play.myserver.com:25565"
},
"files": [
{
"path": "mods/jei-1.21.jar",
"hash": "a1b2c3d4e5f6...",
"size": 1048576,
"url": "https://cdn.myserver.com/files/a1b2c3d4e5f6..."
},
{
"path": "config/general.json",
"hash": "f7g8h9i0j1k2...",
"size": 1245,
"url": "https://cdn.myserver.com/files/f7g8h9i0j1k2..."
}
]
}
```
### 5.2. Автоматическое добавление сервера в игру (servers.dat)
Перед запуском игры лаунчер читает блок `server_info` из манифеста. Если в `instances/<slug>/servers.dat` отсутствует сервер с IP `server_info.ip`, лаунчер парсит этот NBT-файл и добавляет в него новую запись:
* **Имя:** `server_info.name`
* **IP:** `server_info.ip`
Это избавляет игроков от ручного ввода IP в клиенте.
### 5.3. Пайплайн CI/CD Релиза Лаунчера
```text
[Коммит/Тег в Git] -> [Сборка в CI (Windows/Linux/macOS)]
[Расчет SHA-256 для каждого]
[POST-запрос с секретным токеном]
[Go-Бэкенд сохраняет файлы]
[Обновляет версию лаунчера в БД]
[Игроки видят обновление при запуске]
```
---
## 6. Конфигурация Nginx (CDN & Static)
Для максимальной производительности Nginx настраивается на прямую отдачу файлов, минуя Go-бэкенд. Запросы к API проксируются.
* **Статика (`/files/`)**: Настраивается отдавать файлы с вечным кэшированием, так как они никогда не меняются (меняется только сам хэш в манифесте).
* **Скины (`/skins/`)**: Кэширование настраивается на меньший срок (например, 1 час), чтобы при смене скина игроки видели изменения без жесткого сброса кэша.
* **API (`/api/`, `/authserver/`)**: Все запросы перенаправляются на локальный порт Go-приложения (например, `127.0.0.1:8080`).