Как устроено
Всё держится на одном разделении: сервер готовит сборку, лаунчер её синхронизирует и запускает. Лаунчер никогда не собирает игру сам — он получает готовый список файлов с хешами и подписью и приводит своё состояние к нему.
Подготовка на сервере
Когда вы вызываете install, сервер проходит цепочку:
-
Метаданные версии
Берёт описание версии Minecraft из официальных метаданных Mojang — какие библиотеки, ассеты и какая Java нужны.
-
Загрузчик
Для Fabric и Quilt добавляет их библиотеки к ванильным. Для Forge и NeoForge скачивает установщик и прогоняет его процессоры — они патчат ванильный
client.jarв клиент загрузчика. Подробнее — в разделе Загрузчики. -
Скачивание
Тянет клиент, библиотеки, нативы, ассеты и Java. Загрузка идёт в несколько потоков с ограничением, уже скачанное с совпадающим хешем пропускается.
-
Профиль
Складывает всё в папку профиля с файлом
laminara.profile.json— там главный класс, classpath, аргументы запуска и путь к клиенту. Файлы можно править руками до публикации.
Публикация и подпись
publish превращает папку профиля в манифест — список файлов с их хешами. Манифест сериализуется в канонический (детерминированный) вид и подписывается ключом Ed25519.
Подпись накладывается ровно на те байты, которые получит лаунчер, и проверяется по ним же — без повторной сериализации. Поэтому лаунчер доверяет содержимому по подписи, а не по источнику. Байты можно раздавать откуда угодно: с самого сервера, с зеркала, с CDN. Скомпрометированное зеркало подсунуть чужой файл не сможет — хеш не сойдётся с подписанным манифестом.
Хранилище по содержимому
Файлы адресуются по хешу их содержимого (content-addressed storage). Отсюда два следствия:
- Одинаковые файлы в разных сборках лежат на диске один раз.
- Обновление сборки скачивает только реально изменившиеся файлы; всё, что не поменялось, у игрока уже есть.
Хранилище — адаптер: локальная файловая система или любое S3-совместимое хранилище. Выбор и рекомендации — в разделе Хранилище.
Что отдаёт сервер наружу
Публичный слушатель (адрес задаётся в api.addr) обслуживает три вещи на одном порту:
LauncherService— вход, обновление токена, список сборок, выдача манифеста. Это Connect поверх HTTP/1.1, так что дёргается обычнымcurl./objects/<хеш>— байты файлов. Для S3 сервер отдаёт редирект на presigned-ссылку, для файловой системы — отдаёт сам или черезX-Accel-Redirectсилами nginx./yggdrasil/— вход в игре по протоколу authlib-injector и выдача скинов.
Перед этим слушателем в продакшене стоит nginx: он держит TLS и раздаёт файлы. Как это собрать — в разделе Продакшен.
Адаптеры вместо хардкода
Там, где вариантов больше одного, Laminara не выбирает за вас, а даёт точку расширения: аутентификация, хранилище, скины, загрузчики. Каждый вариант — самостоятельный модуль, который сам себя регистрирует. Добавить свой источник учёток или новое хранилище значит дописать один файл, а не менять существующий код.