Files
MrixsCraft/docs/server/Specification.md

11 KiB
Raw Permalink Blame History

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

-- Таблица пользователей
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-архив с обновлением модов/конфигов через панель управления:

 [Архив с модами] -> [Распаковка во временную папку] 
                           │
                           ▼
               [Обход каждого файла в цикле]
                           │
                           ▼
                  [Расчет SHA-1 хэша]
                           │
             ┌─────────────┴─────────────┐
             ▼                           ▼
    [Хэш ЕСТЬ в базе?]          [Хэша НЕТ в базе]
             │                           │
             │                    [Копирование в CAS]
             │                [/files/ab/abcdef12...]
             │                           │
             └─────────────┬─────────────┘
                           ▼
             [Добавление в manifest.json]

Итоговый формат генерируемого manifest.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 Релиза Лаунчера

[Коммит/Тег в 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).