DiscordSRV dla SMP: zaawansowana konfiguracja, role sync i automatyzacja eventow

DiscordSRV dla SMP: zaawansowana konfiguracja, role sync i automatyzacja eventow

Podstawowy chat bridge w DiscordSRV stawia sie w dziesiec minut i wielu adminow na tym poprzestaje. W tym poradniku idziemy dalej: synchronizacja rol z LuckPerms, linkowanie kont przez /link, osobne kanaly na smierci i osiagniecia, kanal konsoli, integracja glosowa i tuning pod 200+ graczy online.

Co zakladamy jako gotowe

Przed czescia zaawansowana zakladamy dzialajacy podstawowy bridge. Jezeli go nie ma, krotko: tworzysz Discord Application w Developer Portal, wlaczasz trzy privileged intenty (PRESENCE, SERVER MEMBERS, MESSAGE CONTENT), wrzucasz token do plugins/DiscordSRV/config.yml w pole BotToken, dodajesz bota z uprawnieniami Administrator na czas testow. Po restarcie /discord w czacie powinno potwierdzic polaczenie.

Wszystko co dalej dotyczy DiscordSRV 1.27.x na Paper 1.20-1.21, LuckPerms 5.4+ i Java 21. Folia jest wspierana tylko czesciowo, wiecej w sekcji FAQ.

Group Sync: laczenie grup LuckPerms z rolami Discord

Cel: gracz wplaca donate przez Discord, bot sam dodaje go do grupy vip na serwerze. Albo odwrotnie, admin nadaje range w LuckPerms i Discord automatycznie zaklada odpowiednia role.

Plik 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

Numeryczne ID rol bierzesz przez prawy klik w role na Discordzie z wlaczonym Developer Mode. Nazwa po lewej w cudzyslowach musi sie zgadzac dokladnie z grupa LuckPerms wedlug /lp group <name> info.

Kluczowe pola. GroupRoleSynchronizationCycleTime to interwal auto-sync w minutach, 5 to rozsadny default. OneWay: false wlacza synchronizacje dwukierunkowa: dodanie roli na Discordzie skutkuje grupa w LP, i odwrotnie. MinecraftIsAuthoritative decyduje przy konflikcie: jezeli w LP nie ma grupy, a rola na Discordzie jest, bot ja zdejmie (bo Minecraft jest autorytatywny).

Na donate-serwerze zwykle stawia sie OneWay: true i MinecraftIsAuthoritative: false, bo zakup leci przez bota Discord typu Tebex albo MineStore i to stamtad rola przychodzi pierwsza.

Aby sync dzialal, bot musi miec uprawnienie Manage Roles, a jego wlasna rola musi byc w hierarchii wyzej niz role, ktorymi zarzadza. To jeden z najczestszych bledow: bot nie nadaje @Admin wlasnie dlatego, ze @DiscordSRV jest pod @Admin na liscie rol serwera.

Linkowanie kont: /link z poziomu gry

Bez linkowania kont role sync nic nie zrobi, bot nie wie ktory gracz odpowiada ktoremu uzytkownikowi Discord. Domyslnie gracz wpisuje /discord link w czacie, bot wysyla DM z 6-cyfrowym kodem, gracz wkleja kod na osobnym kanale #verification lub do DM bota.

Blok kanalow w config.yml:

Channels:
  global: "987654321111111111"
  verification: "987654321222222222"
  console: "987654321333333333"
  deaths: "987654321444444444"
  achievements: "987654321555555555"

Potem w linking.yml ustawiasz wymagania:

RequireLinkedAccountToPlay: true
RequireLinkedAccountToPlayMessage: "&cZlinkuj Discord: /discord link"
DiscordRequiredRoleToJoin: "987654321666666666"
SendCodeAsDirectMessage: true
ConfirmCodeInPublicChannel: false

Na donate-SMP lub serwerze whitelist-only RequireLinkedAccountToPlay: true skutecznie odcina alty: kazde konto Minecraft musi byc powiazane z kontem Discord, zwykle jeden Discord to jeden link. DiscordRequiredRoleToJoin idzie dalej: na serwer wejdzie tylko ten, kto ma na Discordzie konkretna role (np. zaakceptowal regulamin reakcja w kanale rules).

Channel routing: rozne swiaty na rozne kanaly

Na SMP z paroma swiatami w stylu world, world_resource, creative_plots lustrzany czat w jednym kanale szybko zmienia sie w bagno. Domyslnie DiscordSRV routuje wszystko do global, ale w polaczeniu z VentureChat lub ChatControl mozna podpiac kanaly do konkretnych swiatow albo prefixow.

Przyklad z VentureChat. W plugins/VentureChat/channels.yml masz kanaly Global, Local, Resources. W plugins/DiscordSRV/config.yml:

Channels:
  global: "987654321111111111"
  resources: "987654321777777777"
  local: "987654321888888888"

DiscordChatChannelVentureChatNeedsToBeSetForChat: true

VentureChat wysyla wiadomosc z prefixem kanalu, DiscordSRV lapie hak i kladzie ja w odpowiedni kanal tekstowy. Tak samo dziala z CarbonChat i CMI przez ich haki.

Bez zewnetrznego pluginu czatu mozna powiesic routing przez DiscordSRV channel linking plus wlasny filtr formatu, ale to juz hack.

Kanal smierci i kanal osiagniec

Spam o smierciach na glownym kanale meczy juz po godzinie. Wynosimy do osobnego kanalu.

W messages.yml edytujemy format:

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: zdobyl **%achievement_name%**"

Crafatar wystawia skin gracza po UUID jako PNG, embed dostaje awatar-glowe wlasciwego gracza. Alternatywy to MineSkin (https://api.mineskin.org/render/head?uuid=...) lub mc-heads.net (https://mc-heads.net/avatar/%uuid%/64).

Channel: odwoluje sie do klucza w bloku Channels: w config.yml. Jezeli klucza nie ma, wiadomosc spadnie do global.

Kanal konsoli: bezpieczny prywatny log

Lustrowanie konsoli w Discordzie jest wygodne, ale to powazna dziura jezeli kanal nie jest zamkniety. Kazdy gracz z dostepem zobaczy tokeny, IP, stacktrace ze sciezkami konfigow.

Bazowy setup w 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

Kanal #server-console musi byc w kategorii Admin, widoczny tylko dla rol adminskich, u @everyone zdjete wszystko, bot ma View Channel, Send Messages, Read Message History.

DiscordConsoleChannelBlacklistedCommands blokuje komendy, ktorych nie wolno wykonac z Discordu: nawet jezeli ktos dostanie sie do kanalu, /op ani /stop nie pojda. Jezeli wolisz scisla whiteliste, przelacz BlacklistActsAsWhitelist: true i wpisz tylko dozwolone komendy.

Dodatkowo wlaczylbym 2FA na kontach Discord wszystkich adminow i zdjal botowi Administrator po pierwszej konfiguracji. Funkcjonalnie wystarczy: View Channels, Manage Roles, Send Messages, Embed Links, Manage Webhooks, Read Message History, Mention @everyone (jezeli uzywasz broadcastow w globalnym kanale).

Custom commands: wykonywanie z Discordu

Przez bridge mozna odpalac komendy serwera z kanalu Discord. Przydatne dla moderacji gdy nie sa w grze: /tempban Player1 1d spam, /broadcast restart za 5 minut.

Slash-komendy bota sa pewniejsze niz zwykly tekst, bo Discord sam waliduje argumenty i widzi prawa roli:

DiscordCommandsExecutableViaConsoleChannel: true

DiscordCommandRolesRequiredToExecute:
  "tempban":
    - "987654321moderator"
    - "987654321admin"
  "broadcast":
    - "987654321admin"
  "kick":
    - "987654321moderator"

DiscordCommandConfirmation: true
DiscordCommandConfirmationTimeout: 10

DiscordCommandConfirmation dodaje reakcje-potwierdzenie, zeby ktos przypadkiem nie polozyl serwera komenda /stop. Dla /op i podobnych mocno odradzam wlaczanie wykonywania, trzymaj je w blacklist.

Webhooki: zapowiedzi sezonu i ogloszenia

DiscordSRV potrafi wysylac wlasne wiadomosci przez URL webhooka. Przydatne do skryptow publikujacych aktualizacje sezonu, link do Patreona albo podglad mapy.

Tworzysz webhook w ustawieniach kanalu (Edit Channel -> Integrations -> Webhooks -> New Webhook), zapisujesz URL.

Wysylanie z pluginu albo zewnetrznego skryptu:

curl -H "Content-Type: application/json" \
  -X POST \
  -d '{
    "username": "Season 4 Announcer",
    "avatar_url": "https://i.imgur.com/your.png",
    "embeds": [{
      "title": "Sezon 4 startuje 1 maja",
      "description": "Nowy swiat, nowe eventy, x2 XP w pierwszym tygodniu",
      "color": 1099334,
      "image": {"url": "https://example.com/season4.png"}
    }]
  }' \
  "https://discord.com/api/webhooks/123456789/abcdef..."

Wygodnie powiesic taki curl na cron lub na zadanie Laravel z panelu admina.

Mention parsing i formatowanie

Domyslnie wzmianki z Discordu (@admin) leca na czat Minecraft jako surowe ID. Wlaczamy ladne formatowanie:

DiscordChatChannelTranslateMentions: true
DiscordChatChannelMinecraftMentionFormat: "&9@%name%"
DiscordChatChannelEmojiBehavior: "name"
DiscordChatChannelDiscordToMinecraft:
  - "&7&o[DISCORD] &r%name%&7: &f%message%"

TranslateMentions: true parsuje <@123456> na @nickname. EmojiBehavior: name zamienia :diamond: na [diamond], zamiast smiecia w czacie (jezeli klient nie ma fontu emoji). Inne wartosci to unicode (jak jest, lamie sie na starych klientach) i hide (wytnij).

W druga strone, Minecraft do Discord, regulujesz przez szablon DiscordChatChannelMinecraftToDiscord.

DiscordSRV-Voice i proximity voice

Czat glosowy przez Discord integruje sie albo dodatkiem DiscordSRV-Voice, albo polaczeniem z Plasmo Voice. Dodatek tworzy tymczasowe kanaly glosowe powiazane ze strefami w swiecie: podejdziesz blizej, slyszysz, odejdziesz, przestajesz.

Krotki setup. Wrzucasz DiscordSRV-Voice.jar do plugins/, w Discordzie tworzysz kategorie Voice Proximity, bot sam tworzy kanaly w razie potrzeby. W konfigu wskazujesz kategorie:

Voice:
  Enabled: true
  CategoryId: "987654321999999999"
  LobbyChannelId: "987654321aaaaaaaaa"
  HorizontalRadius: 50
  VerticalRadius: 30
  AllowVoiceCrossWorlds: false

Alternatywa to Plasmo Voice z wlasnym serwerem, bez zaleznosci od Discord. To wybor gdy potrzebujesz niskiego pingu, modeli radia albo szyfrowania end-to-end. DiscordSRV w tym scenariuszu zostaje do czatu tekstowego i role sync, glos leci przez Plasmo.

Wydajnosc przy 200+ online

Na duzych SMP DiscordSRV zaczyna obijac sie o limity Discord: 5 wiadomosci na 5 sekund na kanal, 50 zapytan na sekunde na bota. Bazowy tuning:

ChatChannelHookTimeout: 1500
DiscordChatChannelMessageBatching: true
DiscordChatChannelMessageBatchSize: 8
DiscordChatChannelMessageBatchDelay: 1500
RestActionAsyncSubmit: true

MessageBatching: true skleja kilka linii czatu w jedna wiadomosc Discord co 1.5 sekundy, co tnie RPS 5-10 razy. Widac to jako lekkie opoznienie, ale w ogolnym ruchu nie razi.

RestActionAsyncSubmit: true jest wymagane: w przeciwnym razie synchroniczne calle do API Discord blokuja main thread serwera i zabija TPS przy wahaniach sieci.

Metryki sprawdzasz przez /discord debug: bot wypisuje aktualny ping do Discord, dlugosc kolejki, liczbe taskow JDA. Jezeli ping ciagle wyzej niz 300 ms, sprawdz routing do europejskich centrow Discord.

Backup configa i powiazan

Wszystkie powiazania graczy z Discordem leza w pliku plugins/DiscordSRV/linkedaccounts.json (lub w MySQL jezeli wlaczyles). To dane krytyczne: utrata oznacza ze 200 graczy musi linkowac sie na nowo, role sync resetuje sie do zera.

Minimum to cron z dziennym archiwum:

#!/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

Jezeli przeszedles na MySQL, dodaj dump tabeli discordsrv_accountlinks do glownego skryptu mysqldump. I nie zapomnij o BotToken: jezeli wystawisz konfig na GitHub jako przyklad, token wycieknie i ktos przejmie kontrole nad botem.

FAQ

Czy DiscordSRV dziala na Folii?

Czesciowo. Aktualnie DiscordSRV nie ma oficjalnego wsparcia dla Folii, bo wiele hookow korzysta z API main threada. Bridge czatu dziala, ale eventy typu smierci i osiagniecia lapane sa niepewnie. Jezeli stoisz na Folii, popatrz na EssentialsXDiscord albo DiscordIntegration jako alternatywy, albo poczekaj na oficjalny patch.

Jak zabezpieczyc kanal konsoli przed wyciekiem?

Kanal w kategorii Admin, u @everyone zdjete View Channel i Read Message History. Wymus 2FA u kazdego admina z dostepem, bo skompromitowane konto = dostep do konsoli. W DiscordSRV trzymaj BlacklistedCommands z lista niebezpiecznych komend, zeby nawet przy wycieku nie szlo wykonac /op ani /stop. URL webhooka nigdy nie pchaj do publicznych repo.

Czy mozna miec kilka serwerow Minecraft w jednym Discordzie?

Tak, dwa podejscia. Pierwsze: DiscordSRV na kazdym serwerze, dla kazdego osobny kanal (#smp-chat, #anarchy-chat, #creative-chat), jeden serwer Discord. Drugie: jeden proxy (BungeeCord/Velocity) z globalnym czatem i DiscordSRV jako plugin proxy w stylu DiscordSRV-Bridge albo Velocitab plus jeden plugin czatu. Dla siatki SMP zwykle wygodniejsze jest podejscie pierwsze: kazdy serwer izolowany, latwiej routowac.

Co zrobic gdy bot dostaje rate-limit?

Wlacz MessageBatching jak opisano powyzej, to rozwiazuje 90% przypadkow. Jezeli nie pomoglo, zobacz w /discord debug ktore zapytania sie zatykaja. Czesto winny jest zbyt czesty role sync (CycleTime: 1 minuta na 500 graczach to tysiace zapytan API). Podnies do 10-15 minut. Przy masowych eventach linkowania na starcie serwera tymczasowo wylacz autosync i synchronizuj porcjami przez /discord resync recznie.

Czy mozna zmieniac format wiadomosci bez restartu?

messages.yml i config.yml reladuje sie komenda /discord reload. Zmiany w linking.yml i synchronization.yml zwykle wymagaja restartu pluginu. /discord debug pokaze aktualne ustawienia, jezeli twoja zmiana nie wskoczyla, restart serwera jest konieczny.

Bot nie nadaje rol mimo poprawnej konfiguracji

Dziewiec na dziesiec przypadkow: hierarchia rol. Discord -> Server Settings -> Roles. Rola twojego bota musi byc wyzej niz wszystkie role, ktorymi zarzadza. Przeciagnij na gore, restart nie jest potrzebny. Dziesiaty przypadek: bot nie ma uprawnienia Manage Roles na poziomie serwera albo kanalu/kategorii. Sprawdzasz w Server Settings -> Roles -> twoj bot -> Permissions.

Jak ustawic, zeby awatar w Discordzie byl skinem gracza?

W messages.yml przy embedach ustaw ImageUrl: "https://crafatar.com/avatars/%uuid%?size=128&overlay". Parametr overlay nakkdada druga warstwe nakrycia glowy. Dla pelnego renderu sylwetki https://crafatar.com/renders/body/%uuid%?overlay. Crafatar cachuje wyniki, problemow z rate limitem nie bedzie.

Co dalej

Jezeli dopiero startujesz, idz etapami: najpierw chat bridge, potem account linking z RequireLinkedAccountToPlay, na koncu role sync. Nie pakuj wszystkiego naraz, debuguj jedna funkcje na raz. I koniecznie przetrenuj skrypt backupu na srodowisku staging zanim wjedzie produkcja: odtworzenie linkow z tar archiwum powinno trwac sekundy, w przeciwnym razie po incydencie stracisz wiecej czasu niz zaoszczedziles.

Od razu ogranicz uprawnienia bota. Administrator jest potrzebny tylko w momencie pierwszej konfiguracji, dalej zostaw absolutne minimum. Plus 2FA na wszystkich kontach Discord z dostepem do kanalow admina. To dokladnie ten przypadek, w ktorym dodatkowe piec minut konfiguracji oszczedza pol nocy odtwarzania po incydencie.


Chroń swój serwer przed atakami DDoS

Darmowa ochrona z konfiguracją w 5 minut. 1 TB ruchu w zestawie.

Wypróbuj za darmo


Powiązane artykuły