From 12abd04b4ab92640451cda7d999a0f8ba1193e86 Mon Sep 17 00:00:00 2001 From: Anatoly Kopyl Date: Tue, 14 Jul 2026 15:25:53 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D1=82=D1=8C=D1=8E=20=D0=BF=D1=80=D0=BE=20?= =?UTF-8?q?=D0=BC=D0=B0=D0=B9=D0=BD=D0=BA=D1=80=D0=B0=D1=84=D1=82=20=D1=81?= =?UTF-8?q?=D0=B5=D1=80=D0=B2=D0=B5=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shikiHighlighter.js | 1 + src/routes/blog/+page.server.ts | 5 ++ src/routes/blog/minecraft-server/+page.svx | 89 ++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 src/routes/blog/minecraft-server/+page.svx diff --git a/shikiHighlighter.js b/shikiHighlighter.js index 1c9c3b4..9816b04 100644 --- a/shikiHighlighter.js +++ b/shikiHighlighter.js @@ -15,6 +15,7 @@ export const highlighter = await createHighlighter({ 'html', 'markdown', 'mdx', + 'nginx', 'bash', 'svelte', 'yaml', diff --git a/src/routes/blog/+page.server.ts b/src/routes/blog/+page.server.ts index f959f2b..cdf619a 100644 --- a/src/routes/blog/+page.server.ts +++ b/src/routes/blog/+page.server.ts @@ -1,8 +1,13 @@ import {metadata as htmlInCssMetadata} from "./html-in-css/+page.svx" import {metadata as thisBlogMetadata} from "./this-blog/+page.svx" import {metadata as shortsMetadata} from "./shorts/+page.svx" +import {metadata as minecraftServerMetadata} from "./minecraft-server/+page.svx" const posts = [ + { + href: '/blog/minecraft-server', + ...minecraftServerMetadata + }, { href: '/blog/shorts', ...shortsMetadata diff --git a/src/routes/blog/minecraft-server/+page.svx b/src/routes/blog/minecraft-server/+page.svx new file mode 100644 index 0000000..277ebd4 --- /dev/null +++ b/src/routes/blog/minecraft-server/+page.svx @@ -0,0 +1,89 @@ +--- +title: "Мой овердофига усложненный Майнкрафт сервер" +date: "2026-03-13" +--- + + + + + +Каждый год в моей компании друзей наступает «неделя Майнкрафта» — время, когда мы все собираемся вместе поиграть. И, как обычно, мне выпала участь поднять сервер для всей компашки. + +Идею поиграть с модами обсуждали давно, но модифицированный сервер всегда оказывался слишком большой морокой. В первую очередь из-за необходимости объяснять каждому участнику, как установить все нужные моды. Была и другая проблема — постоянный риск гриферства со стороны случайных игроков. Большинство моих друзей пираты, поэтому использовать белый список не было вариантом. + +К счастью, я наткнулся на [Drasl](https://github.com/unmojang/drasl)! Это открытие затянуло меня в кроличью нору и в итоге привело к той серверной инфраструктуре, которой мы пользуемся сейчас. + +Некоторые из вас возможно знают, что система аутентификации, которую Mojang использовала до перехода в Microsoft, называлась Yggdrasil. Drasl — это open-source реализация этого алгоритма на Go. Проще говоря, он позволяет поднять собственный сервер аутентификации, на котором мои друзья могут зарегистрироваться и через который будет происходить авторизация. + +Здесь стоит упомянуть, что я и так уже хощу несколько сервисов для своей компании друзей. В основном это VPN сервис, написанный на Go поверх [Pocketbase](https://pocketbase.io/). Поэтому все пользователи уже зарегистрированы в системе, с которой они знакомы и которой пользуются регулярно. + +### Синхронизация пользователей + +В Drasl есть административный API для управления пользователями. Я решил написать модуль для своего существующего Golang-монолита, который через этот API будет синхронизировать пользователей Minecraft с пользователями моей основной системы. Drasl я развернул во внутренней сети и сделал доступ к нему через Nginx с ограничением: + +- публично доступны только Yggdrasil-эндпоинты, +- административный API может вызывать только сервер с Pocketbase. + +Примерная конфигурация: + +```nginx +# /etc/nginx/conf.d/mc-auth.my-domain.conf + +location ^~ /drasl/ { + allow 192.168.1.0/24; + allow ; + 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](https://github.com/dscalzi/HeliosLauncher) (ранее известный как Electron Launcher). + +Я зарабатываю на хлеб фронтенд-разработкой, поэтому я обновил визуальный стиль лаунчера, привёл его к дизайну, который уже используется в веб-панели управления VPN и заменил модуль аутентификации в лаунчере на собственный. + +Теперь логин проходит через мой API, который выдаёт клиенту Yggdrasil-токен, используемый для входа на сервер. + +![Лаунчер](https://habrastorage.org/r/w1560/getpro/habr/upload_files/935/16f/8c1/93516f8c108692ed2e57803003e17a4c.webp) + +### Автоматическая установка модов + +У Helios Launcher есть ещё одна полезная возможность — он умеет автоматически скачивать и устанавливать необходимые для сервера моды, если в нем захардкодить ссылку на .json с определённой структурой. Но создание такого JSON-файла — довольно утомительный процесс, особенно если вы не используете готовый модпак с CurseForge. + +Поэтому я написал небольшой хелпер-скрипт get-nebula-obj, который генерирует нужный объект для любого .jar файла с модом. + +![get-nebula-obj в действии](https://habrastorage.org/r/w1560/getpro/habr/upload_files/8f9/466/2c8/8f94662c8cc0a751b8549db7e496c668.webp) + +После того как я перебрал примерно 200 модов и собрал модпак, который меня устраивает, проект можно было почти считать завершённым. + +### Панель управления Minecraft + +Поскольку у меня уже была веб-панель для сервисов, я решил докинуть туда страницу управления Minecraft-аккаунтом. Там игроки могут: менять скин, добавлять плащ и менять свой никнейм. + +![Панель управления в браузере](https://habrastorage.org/r/w1560/getpro/habr/upload_files/c61/59e/835/c6159e835101fdd80bd22c225cf08be0.webp) + +Теперь игроку нужно сделать всего одну вещь: скачать мой лаунчер. После этого всё настраивается автоматически: моды, сервер в списке multiplayer, голосовой чат, шейдеры, текстурпаки. + +Любой клиент, который попытается подключиться к серверу не через мой лаунчер, получит ошибку аутентификации. Судя по логам, это уже помогло отфильтровать большое количество ботов. + +На разработку ушло около месяца (действие происходило до всеобъемлющего перехода на вайбкодинг). Так что неделя Майнкрафта давно позади. Следующая задача — уговорить друзей поиграть с собой в Майнкрафт. -- 2.49.1