Каждый год в моей компании друзей наступает «неделя Майнкрафта» — время, когда мы все собираемся вместе поиграть. И, как обычно, мне выпала участь поднять сервер для всей компашки.

Идею поиграть с модами обсуждали давно, но модифицированный сервер всегда оказывался слишком большой морокой. В первую очередь из-за необходимости объяснять каждому участнику, как установить все нужные моды. Была и другая проблема — постоянный риск гриферства со стороны случайных игроков. Большинство моих друзей пираты, поэтому использовать белый список не было вариантом.

К счастью, я наткнулся на Drasl! Это открытие затянуло меня в кроличью нору и в итоге привело к той серверной инфраструктуре, которой мы пользуемся сейчас.

Некоторые из вас возможно знают, что система аутентификации, которую Mojang использовала до перехода в Microsoft, называлась Yggdrasil. Drasl — это open-source реализация этого алгоритма на Go. Проще говоря, он позволяет поднять собственный сервер аутентификации, на котором мои друзья могут зарегистрироваться и через который будет происходить авторизация.

Здесь стоит упомянуть, что я и так уже хощу несколько сервисов для своей компании друзей. В основном это VPN сервис, написанный на Go поверх Pocketbase. Поэтому все пользователи уже зарегистрированы в системе, с которой они знакомы и которой пользуются регулярно.

Синхронизация пользователей

В Drasl есть административный API для управления пользователями. Я решил написать модуль для своего существующего Golang-монолита, который через этот API будет синхронизировать пользователей Minecraft с пользователями моей основной системы. Drasl я развернул во внутренней сети и сделал доступ к нему через Nginx с ограничением:

  • публично доступны только Yggdrasil-эндпоинты,

  • административный API может вызывать только сервер с Pocketbase.

Примерная конфигурация:

# /etc/nginx/conf.d/mc-auth.my-domain.conf

location ^~ /drasl/ {
  allow 192.168.1.0/24;
  allow <pocketbase-ip>;
  deny all;
  
  proxy_pass http://192.168.1.132:25585;
  proxy_http_version 1.1;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
}

location / {
  proxy_pass http://192.168.1.132:25585;
  
  proxy_http_version 1.1;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
}

Впоследствии, домен, на котором размещён этот сервис, можно указать как параметр запуска для сервера и клиента Minecraft — тогда вместо официального сервера аутентификации Mojang будет использоваться кастомный.

Что делать с клиентом?

С сервером всё просто передали параметр и ладно, но возникает вопрос: как заставить клиента использовать мой auth-сервер? Если установка модов уже была проблемой для пользователей, то эта часть выглядит ещё сложнее. Поэтому я решил форкнуть Helios Launcher (ранее известный как Electron Launcher).

Я зарабатываю на хлеб фронтенд-разработкой, поэтому я обновил визуальный стиль лаунчера, привёл его к дизайну, который уже используется в веб-панели управления VPN и заменил модуль аутентификации в лаунчере на собственный.

Теперь логин проходит через мой API, который выдаёт клиенту Yggdrasil-токен, используемый для входа на сервер.

Лаунчер
Лаунчер

Автоматическая установка модов

У Helios Launcher есть ещё одна полезная возможность — он умеет автоматически скачивать и устанавливать необходимые для сервера моды, если в нем захардкодить ссылку на .json с определённой структурой. Но создание такого JSON-файла — довольно утомительный процесс, особенно если вы не используете готовый модпак с CurseForge.

Поэтому я написал небольшой хелпер-скрипт get-nebula-obj, который генерирует нужный объект для любого .jar файла с модом.

get-nebula-obj в действии
get-nebula-obj в действии

После того как я перебрал примерно 200 модов и собрал модпак, который меня устраивает, проект можно было почти считать завершённым.

Панель управления Minecraft

Поскольку у меня уже была веб-панель для сервисов, я решил докинуть туда страницу управления Minecraft-аккаунтом. Там игроки могут: менять скин, добавлять плащ и менять свой никнейм.

Панель управления в браузере
Панель управления в браузере

Теперь игроку нужно сделать всего одну вещь: скачать мой лаунчер. После этого всё настраивается автоматически: моды, сервер в списке multiplayer, голосовой чат, шейдеры, текстурпаки.

Любой клиент, который попытается подключиться к серверу не через мой лаунчер, получит ошибку аутентификации. Судя по логам, это уже помогло отфильтровать большое количество ботов.

На разработку ушло около месяца (действие происходило до всеобъемлющего перехода на вайбкодинг). Так что неделя Майнкрафта давно позади. Следующая задача — уговорить друзей поиграть с собой в Майнкрафт.