# Спецификация серверной части 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//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`).