DiscordSRV для SMP: продвинутая настройка, role-sync и автоматизация ивентов
Базовый чат-бридж DiscordSRV ставится за десять минут, и на этом большинство админов останавливается. В этом гайде идём дальше: синк ролей с LuckPerms, привязка аккаунтов через /link, отдельные каналы для смертей и достижений, консоль-канал, мост на голосовой чат и тюнинг под 200+ онлайна.
Что считаем уже сделанным
Перед продвинутой частью предполагаем рабочую базовую связку. Если её нет, коротко: создаёте Discord-приложение в Developer Portal, включаете три privileged intents (PRESENCE, SERVER MEMBERS, MESSAGE CONTENT), кидаете токен в plugins/DiscordSRV/config.yml в поле BotToken, добавляете бота на сервер с правами Administrator на этапе теста. После рестарта /discord в чате должен показать связь.
Дальше речь идёт про DiscordSRV 1.27.x под Paper 1.20-1.21, LuckPerms 5.4+ и Java 21. На Folia DiscordSRV пока не работает в полном объёме, об этом ниже в FAQ.
Group Sync: связка LuckPerms групп с Discord ролями
Цель: игрок донатит в Discord, бот сам добавляет его в группу vip на сервере. Или наоборот, админ выдаёт ранг в LuckPerms, и Discord автоматически вешает соответствующую роль.
Файл plugins/DiscordSRV/synchronization.yml:
GroupRoleSynchronizationGroupsAndRolesToSync:
"vip": "987654321098765432"
"donator": "987654321098765433"
"moderator": "987654321098765434"
"admin": "987654321098765435"
"default": "987654321098765436"
GroupRoleSynchronizationCycleTime: 5
GroupRoleSynchronizationOnLink: true
GroupRoleSynchronizationOneWay: false
GroupRoleSynchronizationMinecraftIsAuthoritative: true
GroupRoleSynchronizationPrimaryGroupOnly: false
GroupRoleSynchronizationEnableDenyPermission: true
Числовые ID ролей берутся через ПКМ по роли в Discord при включённом Developer Mode. Слева в кавычках имя группы LuckPerms ровно как в /lp group <name> info.
Ключевые поля разберём отдельно. GroupRoleSynchronizationCycleTime задаёт период автосинка в минутах, 5 это разумный баланс. GroupRoleSynchronizationOneWay: false включает двунаправленную синхронизацию: добавили роль в Discord, добавилась группа в LP, и наоборот. MinecraftIsAuthoritative решает кто главный при конфликте: если в LP группы нет, а роль в Discord стоит, бот её снимет (потому что Minecraft authoritative).
В сценарии донат-сервера обычно ставят OneWay: true и MinecraftIsAuthoritative: false, потому что покупка делается через Discord-бота вроде Tebex или MineStore, и оттуда роль приходит первой.
Чтобы синк работал, бот должен иметь permission Manage Roles в Discord, и его собственная роль должна быть в иерархии выше управляемых ролей. Это частая ошибка: бот не выдаёт @Admin именно потому, что роль @DiscordSRV ниже @Admin в списке ролей сервера.
Account linking: /link изнутри игры
Без привязки аккаунтов role-sync ничего не сделает, бот не знает кому какие роли давать. По умолчанию игрок пишет в чат /discord link, бот в DM присылает 6-значный код, игрок вставляет код в выделенный канал #verification или в DM боту.
Конфиг канала верификации в config.yml:
Channels:
global: "987654321111111111"
verification: "987654321222222222"
console: "987654321333333333"
deaths: "987654321444444444"
achievements: "987654321555555555"
Дальше в linking.yml подкрутить требования:
RequireLinkedAccountToPlay: true
RequireLinkedAccountToPlayMessage: "&cПривяжи Discord: /discord link"
DiscordRequiredRoleToJoin: "987654321666666666"
SendCodeAsDirectMessage: true
ConfirmCodeInPublicChannel: false
Если у вас донатный SMP или whitelist-only сервер, RequireLinkedAccountToPlay: true отрезает альты: каждый аккаунт должен быть привязан к Discord, на одном Discord-аккаунте обычно одна привязка. DiscordRequiredRoleToJoin идёт ещё дальше: подключается только тот, у кого в Discord есть указанная роль (например, прошёл правила и нажал реакцию на rules-канале).
Channel routing: разные миры в разные каналы
На SMP с парой миров типа world, world_resource, creative_plots зеркалить весь чат в один канал быстро превращается в кашу. DiscordSRV из коробки роутит весь общий чат в global, но в связке с VentureChat или ChatControl можно повесить каналы на конкретные миры или префиксы.
Пример с VentureChat. В plugins/VentureChat/channels.yml есть каналы Global, Local, Resources. Дальше в plugins/DiscordSRV/config.yml:
Channels:
global: "987654321111111111"
resources: "987654321777777777"
local: "987654321888888888"
DiscordChatChannelVentureChatNeedsToBeSetForChat: true
VentureChat транслирует сообщение с префиксом канала, DiscordSRV ловит его через хук и кладёт в нужный текстовый канал. То же работает с CarbonChat и CMI, нужны соответствующие хуки в DiscordSRV.
Альтернатива без сторонних чат-плагинов: повесить мир-роутинг через DiscordSRV Channel Linking и кастомный фильтр на формат сообщения, но это уже хак.
Death-канал и achievement-канал
Спам про смерти в общем чате надоедает уже через час. Выносим в отдельный канал.
В messages.yml редактируете формат:
MinecraftPlayerDeathMessage:
Channel: "deaths"
Embed:
Color: "#ef4444"
Author:
Name: "%player%"
ImageUrl: "https://crafatar.com/avatars/%uuid%?size=64"
Description: "%death_message%"
Footer:
Text: "%world%"
MinecraftPlayerAchievementMessage:
Channel: "achievements"
Embed:
Color: "#fbbf24"
Author:
Name: "%player%"
ImageUrl: "https://crafatar.com/avatars/%uuid%?size=64"
Description: ":trophy: получил **%achievement_name%**"
Crafatar отдаёт скин игрока по UUID в виде PNG, embed получает аватар-головой соответствующего игрока. Альтернатива - MineSkin (https://api.mineskin.org/render/head?uuid=...) или mc-heads.net (https://mc-heads.net/avatar/%uuid%/64).
Channel: ссылается на ключ из Channels: блока в config.yml. Если ключа нет, сообщение упадёт в global.
Console-канал: безопасный приватный лог
Зеркалирование консоли в Discord удобно, но это серьёзная дыра если канал не закрыт. Любой игрок с доступом увидит токены, IP, ошибки с путями к конфигам.
Базовая настройка в config.yml:
DiscordConsoleChannelId: "987654321333333333"
DiscordConsoleChannelUsable: true
DiscordConsoleChannelBlacklistActsAsWhitelist: false
DiscordConsoleChannelBlacklistedCommands:
- "?"
- "op"
- "deop"
- "whitelist"
- "stop"
- "save-all"
- "luckperms user * permission set *"
DiscordConsoleChannelDoNotSendCommandsList:
- "lp user * info"
DiscordConsoleChannelTruncateLength: 1900
Канал #server-console должен быть в категории Admin, видим только админ-роли, у @everyone снято всё, у бота есть View Channel, Send Messages, Read Message History.
DiscordConsoleChannelBlacklistedCommands блокирует команды которые нельзя выполнять из Discord: даже если кто-то получит доступ к каналу, /op или /stop не пройдут. Если хотите пускать только белый список, переключите BlacklistActsAsWhitelist: true и оставьте в списке ровно те команды что разрешены.
Я бы дополнительно ставил 2FA для Discord-аккаунтов всех админов, и снимал у бота Administrator после первоначальной настройки. Для функционала достаточно: View Channels, Manage Roles, Send Messages, Embed Links, Manage Webhooks, Read Message History, Mention @everyone (если используете broadcast в общий канал).
Custom commands: выполнение из Discord
Через мост можно выполнять команды на сервере из Discord-канала. Полезно для модераторов когда они не в игре: /tempban Player1 1d спам, /broadcast рестарт через 5 минут.
Через слэш-команды бота это надёжнее обычных текстовых, потому что Discord сам валидирует аргументы и видит права роли:
DiscordCommandsExecutableViaConsoleChannel: true
DiscordCommandRolesRequiredToExecute:
"tempban":
- "987654321moderator"
- "987654321admin"
"broadcast":
- "987654321admin"
"kick":
- "987654321moderator"
DiscordCommandConfirmation: true
DiscordCommandConfirmationTimeout: 10
DiscordCommandConfirmation добавляет реакцию-подтверждение, чтобы случайно не уронить сервер /stop. Для /op и подобного крайне рекомендую вообще не давать выполнения, держать в blacklist.
Webhooks: тизеры сезона и анонсы
DiscordSRV умеет слать кастомные сообщения через webhook URL. Полезно для скриптов которые публикуют апдейт сезона, ссылку на Patreon или превью карты.
Создайте webhook в настройках канала Discord (Edit Channel -> Integrations -> Webhooks -> New Webhook), сохраните URL.
Слать из плагина или внешним скриптом:
curl -H "Content-Type: application/json" \
-X POST \
-d '{
"username": "Season 4 Announcer",
"avatar_url": "https://i.imgur.com/your.png",
"embeds": [{
"title": "Сезон 4 стартует 1 мая",
"description": "Новый мир, новые ивенты, x2 опыт первую неделю",
"color": 1099334,
"image": {"url": "https://example.com/season4.png"}
}]
}' \
"https://discord.com/api/webhooks/123456789/abcdef..."
Удобно повесить такой curl на cron или на Laravel-задачу из админки сервера.
Mention parsing и форматирование
По умолчанию упоминания в Discord (@admin) приходят в Minecraft-чат сырым ID. Включаем красивую отрисовку:
DiscordChatChannelTranslateMentions: true
DiscordChatChannelMinecraftMentionFormat: "&9@%name%"
DiscordChatChannelEmojiBehavior: "name"
DiscordChatChannelDiscordToMinecraft:
- "&7&o[DISCORD] &r%name%&7: &f%message%"
TranslateMentions: true парсит <@123456> в @nickname. EmojiBehavior: name превращает :diamond: в [diamond] вместо мусора в чате (если на клиентах нет шрифта emoji). Есть значения unicode (как есть, ломается на старых клиентах) и hide (вырезать).
В обратную сторону, Minecraft to Discord, регулируйте через DiscordChatChannelMinecraftToDiscord шаблон.
DiscordSRV-Voice и proximity voice
Голосовой чат через Discord интегрируется через DiscordSRV-Voice аддон или связку с Plasmo Voice. Аддон создаёт временные voice-каналы привязанные к зонам в мире: подошёл ближе - слышишь, отошёл - перестал.
Установка коротко: в plugins/ кидаете DiscordSRV-Voice.jar, в Discord создаёте категорию Voice Proximity, бот сам создаёт каналы по мере необходимости. В конфиге указываете категорию:
Voice:
Enabled: true
CategoryId: "987654321999999999"
LobbyChannelId: "987654321aaaaaaaaa"
HorizontalRadius: 50
VerticalRadius: 30
AllowVoiceCrossWorlds: false
Альтернатива - Plasmo Voice с собственным сервером, без зависимости от Discord. Это когда нужен низкий пинг, поддержка radio-моделей, шифрование. DiscordSRV в этом сценарии остаётся для текстового чата и role-sync, голос идёт через Plasmo.
Производительность при 200+ онлайна
На больших SMP DiscordSRV начинает упираться в Discord rate limits: 5 сообщений в 5 секунд на канал, 50 запросов в секунду на бота. Базовая настройка под нагрузку:
ChatChannelHookTimeout: 1500
DiscordChatChannelMessageBatching: true
DiscordChatChannelMessageBatchSize: 8
DiscordChatChannelMessageBatchDelay: 1500
RestActionAsyncSubmit: true
MessageBatching: true склеивает несколько чат-сообщений в одно сообщение Discord за 1.5 секунды, что снижает RPS в 5-10 раз. Видно как небольшое отставание, но в общем потоке это незаметно.
RestActionAsyncSubmit: true обязательно: иначе синхронные запросы к Discord API блокируют main thread сервера и роняют TPS при сетевых задержках.
Метрики проверяйте через /discord debug: бот печатает текущий ping до Discord, длину очереди, количество задач JDA. Если ping регулярно выше 300 мс - стоит проверить сеть до европейских дата-центров Discord.
Бэкап конфига и привязок
Все привязки игроков к Discord хранятся в файле plugins/DiscordSRV/linkedaccounts.json (или в MySQL если включили). Это критичные данные: потеря означает что 200 игроков должны заново линковаться, role-sync сбрасывается.
Минимум - cron на ежедневный архив:
#!/bin/bash
DATE=$(date +%Y-%m-%d)
tar czf /backup/discordsrv-$DATE.tar.gz \
/opt/minecraft/plugins/DiscordSRV/linkedaccounts.json \
/opt/minecraft/plugins/DiscordSRV/config.yml \
/opt/minecraft/plugins/DiscordSRV/synchronization.yml \
/opt/minecraft/plugins/DiscordSRV/messages.yml
find /backup -name "discordsrv-*.tar.gz" -mtime +30 -delete
Если перешли на MySQL-хранилище привязок - добавьте дамп таблицы discordsrv_accountlinks в общий mysqldump-скрипт сервера. И не забудьте про BotToken: если выложите конфиг на github как пример, токен утечёт и кто-то получит контроль над ботом.
FAQ
DiscordSRV работает на Folia?
Частично. На текущий момент DiscordSRV не имеет официальной поддержки Folia, потому что многие хуки используют main thread API. Чат-бридж работает, но события вроде смертей и achievements ловятся нестабильно. Если у вас Folia - смотрите в сторону EssentialsXDiscord или DiscordIntegration как альтернативы, либо ждите официального патча.
Как защитить console-канал от утечки?
Канал в категории Admin, у @everyone снято View Channel, Read Message History отдельно проверьте. Включите 2FA у всех админов с доступом, иначе скомпрометированный аккаунт = доступ к консоли. В DiscordSRV держите BlacklistedCommands со списком опасных команд, чтобы даже при утечке нельзя было выполнить /op или /stop. Webhook URL никогда не светите в публичных репозиториях.
Можно ли несколько Minecraft серверов в один Discord?
Да, есть два подхода. Первый: ставите DiscordSRV на каждый сервер, выделяете под каждый отдельный канал (#smp-chat, #anarchy-chat, #creative-chat), один Discord-сервер. Второй: один прокси (BungeeCord/Velocity) с глобальным чатом, и DiscordSRV висит на прокси-плагине типа DiscordSRV-Bridge или используете Velocitab + общий чат-плагин. Для SMP-сети первый вариант чаще удобнее: каждый сервер изолирован, проще роутить.
Что делать если бот rate-limited?
Включите MessageBatching как описано выше, это решает 90% случаев. Если не помогло - смотрите в /discord debug какие именно запросы упираются. Часто виноват частый role-sync (CycleTime: 1 минута на 500 игроках = тысячи API-запросов). Поднимите до 10-15 минут. Для пиковых событий типа массового присоединения по линку - временно отключите автосинк на старте сервера, синхронизируйте порциями вручную через /discord resync.
Можно ли менять формат сообщений на лету без рестарта?
messages.yml и config.yml перечитываются командой /discord reload. Изменения в linking.yml и synchronization.yml обычно применяются после перезапуска плагина: /discord debug покажет текущие настройки, и если они не подхватились - перезагрузка сервера обязательна.
Бот не выдаёт роли несмотря на правильный конфиг
Девять из десяти случаев: иерархия ролей. Откройте Discord -> Server Settings -> Roles. Роль вашего бота должна быть выше всех ролей которыми он управляет. Перетащите её наверх, рестарт не нужен. Десятый случай: у бота нет permission Manage Roles на уровне сервера или конкретной категории/канала. Проверяйте в Server Settings -> Roles -> ваш бот -> Permissions.
Как сделать чтобы аватар в Discord был скином игрока?
В messages.yml для embed-сообщений ставьте ImageUrl: "https://crafatar.com/avatars/%uuid%?size=128&overlay". Параметр overlay накладывает второй слой шапки. Для full-body рендера - https://crafatar.com/renders/body/%uuid%?overlay. Сервис кэширует результаты, проблем с rate limit не будет.
Что дальше
Если только запускаетесь, делайте по шагам: сначала чат-бридж, потом account linking с RequireLinkedAccountToPlay, после этого role-sync. Не тащите всё сразу, отлаживайте по одной фиче. И обязательно прогоните бэкап скрипта на тестовом окружении перед продакшеном: восстановление линков из tar архива должно занимать секунды, иначе при инциденте потеряете больше времени чем сэкономили.
И сразу ограничьте права бота. Administrator нужен только в момент первой настройки, дальше держите минимально необходимый набор. Плюс 2FA на все Discord-аккаунты с доступом к админ-каналам. Это ровно тот случай когда дополнительные пять минут настройки экономят пол ночи восстановления после инцидента.
Protege tu servidor contra ataques DDoS
Protección gratuita con configuración en 5 minutos. 1 TB de tráfico incluido.
Probar gratisArtículos relacionados
Как сделать Minecraft сервер 24/7
Пошаговое руководство по запуску Minecraft сервера в режиме 24/7: выбор между домашним ПК и VPS, настройка screen/tmux, systemd-юниты, автоперезапуск при краше и защита от DDoS.
Тренды DDoS-атак на игровые серверы в 2026 году
Анализ ключевых тенденций DDoS-атак на игровую индустрию в 2026 году: рост объёмов до терабитных масштабов, эволюция Minecraft-специфичных атак, распространение IoT-ботнетов и новые технологии защиты на базе XDP/eBPF и машинного обучения.
Aternos vs платный хостинг: когда бесплатного хватит, а когда пора платить
Честный разбор Aternos в 2026: реальные лимиты, idle sleep, реклама, очередь запуска. И сравнение с Minehut, Exaroton, Falix и платными хостингами от 3 долларов.