Лаунчсервер Laminara
Аккаунты, скины, доступ к сборкам и новости через UnicoreProviderLaminara
Laminara — лаунчсервер, который умеет брать данные из сайта через модуль UnicoreProviderLaminara. Игрок входит в лаунчер логином и паролем от сайта, а сборки, скины и лента новостей подтягиваются оттуда же.
В отличие от GravitLauncher, сессии Laminara держит у себя: сама выпускает токены, крутит ротацию, обслуживает yggdrasil и узнаёт машину игрока. От сайта ей нужен только ответ «эта пара логин-пароль верна, и вот кто это» плюс справка об игроке. Поэтому контракт здесь короче — четыре ручки под /auth/laminara вместо одиннадцати у Gravit.
Что берётся с сайта
| Провайдер | Что делает | Где включается в config.json |
|---|---|---|
| Аутентификация | Вход по нику или почте с паролем и кодом 2FA | auth.provider |
| Скины | Скин и плащ из кабинета — в лаунчере и в игре через yggdrasil | yggdrasil.skinProvider |
| Доступ | Сборки по правам, ролям и донат-группам сайта | access.sources.<имя>.type |
| Новости | Лента новостей сайта в окне лаунчера | news.source.type |
Все четыре включаются по имени unicore и работают независимо: можно взять с сайта только вход, а новости оставить свои.
Подключение
Выпустить ключ
Утилиты → API-ключи → Создать, право kernel.laminara.provider, в доверенные адреса — IP машины с лаунчсервером.
Право отдельное от kernel.provider: ключ лаунчсервера можно отозвать, не трогая интеграцию с GravitLauncher.
Поставить модуль
Бинарь из релизов модуля кладётся в каталог модулей лаунчсервера под именем unicore:
curl -L -o unicore https://github.com/MCXTeam/UnicoreProviderLaminara/releases/latest/download/unicore-linux-amd64
install -m 755 unicore /var/lib/laminara/modules/unicoreИмя файла — это ключ, по которому лаунчсервер найдёт настройки модуля, поэтому переименовать обязательно. Для arm-серверов рядом лежит unicore-linux-arm64 и checksums.txt.
Прописать адрес и ключ
Адрес сайта и ключ задаются один раз в modules.config.unicore, дальше провайдеры только выбираются по имени:
{
"modules": {
"dir": "/var/lib/laminara/modules",
"config": {
"unicore": {
"url": "https://api.example.com",
"apiKey": "ваш-ключ",
"timeout": "5s",
"cacheTTL": "1m"
}
}
},
"auth": { "provider": "unicore" },
"yggdrasil": { "enabled": true, "skinProvider": "unicore" },
"news": { "source": { "type": "unicore", "config": { "limit": 10 } } },
"access": {
"sources": { "site": { "type": "unicore" } },
"rules": [{ "builds": ["*"], "source": "site", "message": "Сборка открыта по привилегии на сайте" }]
}
}После правки конфига перезапустите laminara-server.
Проверить
laminara-server exec "unicore"Модуль покажет адрес сайта, наличие связи, название проекта и версию CMS. То же самое напрямую:
curl https://api.example.com/auth/laminara/ping \
-H 'Authorization: Api-Key ваш-ключ'Ключ без доверенных адресов не работает
Пустой список адресов означает отказ во всех запросах — так задумано для всех ключей, не только для этого. Подробности на странице API-ключи.
Настройки модуля
| Поле | По умолчанию | Что значит |
|---|---|---|
url | — | Адрес API сайта, без завершающего слэша |
apiKey | — | Ключ с правом kernel.laminara.provider |
timeout | 5s | Таймаут запроса к сайту |
cacheTTL | 1m | Сколько держать профиль игрока в памяти модуля |
Профили кэшируются, потому что за ними модуль ходит часто: скины отдаются в том числе игровому серверу через yggdrasil, и на каждую проверку доступа к сборке тоже нужен профиль.
Доступ к сборкам
Отдельной ручки для сборок нет: список сборок живёт в лаунчсервере, а сайт только отвечает, что есть у игрока. Решение принимает модуль по профилю.
По правам
Основное → Настройки → «Сборки лаунчера Laminara» — перечислите идентификаторы сборок через запятую:
survival, skyblock, anarchyНа каждую сборку появится право laminara.build.<id> — его видно в конструкторе прав в группе «Лаунчер». Выдали право игроку, роли или донат-группе — сборка открылась в лаунчере.
Без этой настройки прав не будет
Права сборок заводятся динамически именно из этого списка. Пока сборка в нём не перечислена, права laminara.build.<id> в каталоге нет, и выдать его некому.
Шаблон права меняется в конфиге источника доступа, а пустая строка выключает проверку по правам совсем:
{
"type": "unicore",
"config": {
"permission": "laminara.build.%build%",
"groups": { "creative": ["vip", "premium"] },
"failOpen": false
}
}| Поле | По умолчанию | Что значит |
|---|---|---|
permission | laminara.build.%build% | Шаблон права; пустая строка выключает проверку по правам |
groups | — | Сборка и роли или донат-группы, которым она открыта |
failOpen | false | Пускать ли всех, пока сайт недоступен |
По ролям и группам
Если заводить права не хочется, соответствие сборок и групп пишется прямо в конфиге — блок groups выше. Модуль сверит его с ролями и донат-группами из профиля. Со стороны сайта для этого ничего настраивать не нужно.
Игрок проходит, если у него есть право по шаблону либо одна из перечисленных групп. Забаненный на сайте не проходит никогда, даже при failOpen.
Ручки
Все под ключом с правом kernel.laminara.provider.
| Метод | Путь | Что делает |
|---|---|---|
GET | /auth/laminara/ping | Название проекта и версия CMS |
POST | /auth/laminara/authenticate | Проверка логина, пароля и кода 2FA |
GET | /auth/laminara/user?username= или ?uuid= | Профиль без пароля |
GET | /auth/laminara/news?limit=20 | Новости для окна лаунчера |
Профиль у authenticate и user одинаковый:
{
"uuid": "d1b0f4a2-0000-4000-8000-000000000001",
"username": "Steve",
"roles": ["player", "moderator"],
"groups": ["vip"],
"permissions": ["laminara.build.survival"],
"banned": false,
"banReason": "",
"textures": {
"skin": { "url": "https://api.example.com/skin/Steve.png", "slim": false },
"cape": { "url": "https://api.example.com/cape/Steve.png" }
}
}username — канонический ник, даже если вошли по почте: именно он попадёт в игру. В permissions приходят права игрока вместе с правами его ролей и активных донат-привилегий. У user поле banned заполняется по-настоящему — забаненный отдаётся профилем, а не ошибкой, потому что модуль отличает бан от «игрока нет».
Тексты новостей приходят без HTML: заголовок и тело прогоняются в простой текст, потому что лаунчер разметку не рендерит. limit по умолчанию — 20.
Ошибки входа
Тело ответа — { "error": "<код>" }, у блокировки добавляется reason.
| Код HTTP | error | Когда |
|---|---|---|
| 404 | auth.usernotfound | Игрока с таким ником или почтой нет |
| 401 | auth.wrongpassword | Пароль не подошёл |
| 401 | auth.require2fa | 2FA включена, код не передан |
| 401 | auth.wrong2fa | Код 2FA не подошёл |
| 403 | auth.usernotactivated | Почта не подтверждена |
| 403 | auth.userblocked | Аккаунт забанен |
| 403 | auth.passwordchangerequired | Администратор потребовал сменить пароль |
Получив auth.require2fa, лаунчер показывает поле для кода и повторяет запрос. Неверный логин, пароль и код игрок видит одинаково — «неверный логин или пароль», чтобы перебором нельзя было узнать список ников.
Смена пароля по требованию
Код auth.passwordchangerequired модуль пока показывает игроку как есть, без человеческого текста. Если вы включили принудительную смену пароля, предупредите игрока отдельно: сменить его можно только в кабинете на сайте.
Ограничения частоты
Ручки Laminara не троттлятся: лаунчсервер считает попытки входа сам, до обращения к сайту. Но неудачные входы сайт всё равно копит — после десяти промахов по одной учётке за 15 минут включается растущая пауза, до пяти минут. С подключённой каптчей порог поднимается до 25. Это та же защита, что и у входа на сайте, и она работает по учётной записи, а не по адресу лаунчсервера.
Команды в консоли
Модуль добавляет в консоль лаунчсервера команду unicore (алиас cms):
$ laminara-server exec "unicore user Steve"
Ник Steve
UUID d1b0f4a2-0000-4000-8000-000000000001
Роли Player, Moderator
Группы VIP
Права laminara.build.survival
Бан нет
Скин https://api.example.com/skin/Steve.png
Плащ —
$ laminara-server exec "unicore forget"
кэш профилей очищенunicore forget сбрасывает кэш профилей — пригодится, когда право выдано только что, а лаунчер ещё показывает старое состояние.