Chat Discord → Minecraft absent : rien ne remplace DiscordSRV, implémenter l'inbound dans EkaiiMirrorVelocity #2
Labels
No labels
feature request
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
admin_ekaii/ekaii-mirror#2
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Symptôme
Les messages écrits par les membres sur le salon Discord du serveur n'arrivent sur aucun des trois serveurs Minecraft (Survie / Créa / Plot). Attendu : la même topologie que le chat inter-serveurs, c'est-à-dire
[Discord] <Utilisateur> messagevisible par tous les joueurs, sur les trois backends.Lié à #1 (même pont, sens inverse).
Diagnostic (2026-08-31)
Aucun composant n'implémente le sens Discord → MC aujourd'hui. Ce n'est pas une panne mais une fonctionnalité absente depuis la disparition de DiscordSRV.
EkaiiMirrorVelocity(modulevelocity-plugin/de ce repo, surmc-velocity)DiscordPublisherest un webhook sortant uniquement (POST HTTP). Aucun listener gateway, aucune clébot-tokendansMirrorConfig, aucun code inbound.exo/ekaii-bot(NAS)/whitelist+ comptes Jellyfin. Aucun relais de chat.EkaiiAPIping/players/banned/whitelistseulement, pas dechat/broadcast.Preuves que DiscordSRV est mort depuis longtemps :
DiscordSRV*sur minis (ni.superseded, ni.old, niplugins/.bak/) ; il n'a jamais été listé dansplugins/manifest.ymldu GitOps ;2026-05-09-1.log.gz) ;sessions/2026-05-22.mddu repo GitOps (« DSRV stays on creaclone only ») et les messages des commits v1.2.0 / v1.3.0 ici partent du principe qu'il tourne → perdu sans que personne ne s'en aperçoive, entre fin nov. 2025 et début mai 2026 (migration creaclone probable).services/creaclone/plugins-config/DiscordSRV/+ variableCREACLONE_DISCORDSRV_BOT_TOKENdansENVSUBST_VARS.Le bot Discord « Ekaii » existe toujours et son token (dans
secrets.envde minis, hors repo) est valide (vérifié viaGET /users/@me) → réutilisable.Pourquoi ne pas simplement réinstaller DiscordSRV
PlayerChatEvent, pas les messages système → Survie et Plot ne verraient rien (c'est le problème inverse décrit dans le commit v1.3.0).DiscordPublisher.Proposition : implémenter l'inbound dans
EkaiiMirrorVelocityLe proxy possède déjà le chat inter-serveurs (
ChatBridge.java:43, format<Pseudo> messageenvoyé à tous les joueurs des autres backends). Même mécanique, source différente.Côté code (
velocity-plugin/)DiscordInbound: connexion gateway Discord avec le bot existant (JDA shadé, ou client WebSocket minimal :Identifyavec intentsGUILDS | GUILD_MESSAGES | MESSAGE_CONTENT, heartbeat, reconnect/resume). Tourne sur un thread dédié, jamais sur les threads du proxy.MESSAGE_CREATE:channel_id == discord.inbound.channel-id;author.bot == trueetwebhook_id != null— sinon boucle infinie avec le webhookEkaiiSRVqui republie le chat MC ;author.global_nameouusername(pas le pseudo de serveur, pas les mentions brutes ; remplacer<@id>par@Nomsi simple, sinon laisser tel quel) ;§.server.getAllPlayers()),Componentconstruit sans MiniMessage parsé depuis le texte utilisateur (anti-injection) :[Discord] <Nom> message, préfixe coloré (proposition :[Discord]en bleu, comme la couleur du webhook), texte en gris clair./…ignoré), et rate-limit simple (ex. 5 msg/s max) pour éviter le spam depuis Discord.Côté config (
velocity-plugin/src/main/resources/config.yml)Côté Discord (portail développeur, bot « Ekaii »)
contentarrive vide) ;Côté GitOps (
exo/ekaii-mc-stack)CREACLONE_DISCORDSRV_BOT_TOKEN→DISCORD_BOT_TOKENdanssecrets.env(minis) etENVSUBST_VARS(scripts/lib/common.sh) ; le rendre dansservices/velocity/…/config.yml;services/creaclone/plugins-config/DiscordSRV/(config morte) + le dossier orphelincreaclone/plugins/DiscordSRV/sur minis ; mettre à jourdocs/STACK.mdettemplates/CLAUDE.md;velocity→ release contenant ce travail (peut être la mêmev1.4.2que #1, ou unev1.5.0dédiée) → restart Velocity (~35 s, chat/TAB coupés, à faire en heure creuse).Test d'acceptation
[Discord] <Nom> message.§cou une balise MiniMessage arrive en texte brut en jeu.Statut
DiscordInbound+ configInvestigation indépendante (2026-08-31) — diagnostic CONFIRMÉ, proposition viable, 2 corrections au plan
Tout re-vérifié depuis une session distincte :
EkaiiMirrorVelocityDiscordPublisher= POST webhook sortant uniquement, aucun listener gateway, pas debot-tokendansMirrorConfig.*discordsrv*sur minis (seulement 3 dossiers de config : gitops source, snapshot, etcreaclone/plugins/DiscordSRV/orphelin, dernier write par le plugin nov. 2025).GET /users/@medepuis minis →Ekaii(id1194298459910570114), membre du seul guildEkaii(1185979056626356265), voit le salon📼︱serveur(1186576981156954122). Le token n'a pas quitté minis.ENVSUBST_VARScontientCREACLONE_DISCORDSRV_BOT_TOKENscripts/lib/common.sh:67, mécanisme allowlist opérationnel — le rendu du token dans la config velocity marchera tel que proposé.Corrections au plan :
GET /applications/@me→ flags565248:GATEWAY_MESSAGE_CONTENT_LIMITED(+ members/presence limited). C'est la variante « bot non vérifié <100 guilds », suffisante ici. La case « activer l'intent » du statut est donc déjà acquise, rien à faire côté portail.v1.4.2: release déjà publiée et déployée (fix #1, avatars). L'inbound est une feature →v1.5.0.Avis sur l'implémentation : l'approche (inbound dans le proxy, diffusion
getAllPlayers()) est la bonne — c'est le seul composant qui voit les trois backends, et ça évite de ressusciter un second bridge. Sur le point « JDA shadé ou client WS minimal » : recommande JDA relocaté (intentsGUILD_MESSAGES|MESSAGE_CONTENTseulement, caches désactivés,ChunkingFilter.NONE). Un client gateway artisanal doit gérer heartbeat/ACK, resume vs re-identify, invalid session, zombie connections — c'est exactement le genre de code qui marche en test et meurt silencieusement en prod un mois plus tard. Le poids du jar (~+12 Mo) est sans enjeu sur le proxy. Les filtres anti-boucle proposés (author.bot,webhook_id != null) sont corrects et indispensables avec le webhookEkaiiSRVsur le même salon ; garder aussi le strip§+ pas de parse MiniMessage du texte utilisateur.Point d'attention au moment du GitOps : le token rendu en clair dans
/opt/mc-stack/velocity/plugins/ekaii-mirror-velocity/config.yml— vérifier les permissions du fichier rendu (même exposition que l'ancienne config DSRV, mais autant le noter).Reste gated sur le feu vert d'exo (principe + go déploiement) — implémentation non lancée, conformément au statut de l'issue.
🤖 Investigation par Claude (session autonome, à la demande de Paul).
Implémenté et DÉPLOYÉ EN PROD (2026-08-31, v1.5.0) — go de Paul
Livré :
DiscordInbound(main47fabeb, cherry-pickmc-26.2) : gateway avec le bot « Ekaii » existant, JDA 5.6.1 shadé (slf4j exclu → binding Velocity ; opus exclu ; pas de relocation, classloader plugin isolé ; jar 16,3 Mo), intentsGUILD_MESSAGES|MESSAGE_CONTENT(GUILDS est implicite dans JDA, pas dans l'enum). DiffusiongetAllPlayers():[Discord]blurple +<Nom>+ message gris. Anti-boucleauthor.bot || isWebhookMessage(), mentions résolues (getContentDisplay),§retirés, jamais parsé en MiniMessage, tronqué à 256,/…ignorés, rate-limit 5 msg/s,shutdownNow()sur ProxyShutdown. Configdiscord.inbound.{enabled, bot-token, channel-id}, off par défaut.format(structure fixe, les couleurs n'y seraient pas exprimables — YAGNI) ; nom affiché =global_name/usernamecomme spécifié.READY as Ekaii, salon📼︱serveurvisible.CREACLONE_DISCORDSRV_BOT_TOKEN→DISCORD_BOT_TOKENdansENVSUBST_VARS+docs, config DSRV morte supprimée du repo,secrets.envrenommé (0600 conservé), dossier live orphelin déplacé en.DiscordSRV.removed-20260831(pas de hard-delete). Poussé en deux commits séparés à cause du gotcha « common.sh sourcé avant git reset ». Commit B (dcf0a04) : manifest 1.5.0 + blocinboundrendu par envsubst.Vérifications prod :
Loaded plugin ekaii-mirror-velocity 1.5.0;[DiscordInbound] gateway READY as Ekaii — listening on channel 1186576981156954122dans le proxy → token envsubst OK.§strippés). T1 (message d'un membre humain → visible en jeu) : en attente du premier message réel — je ne peux pas en fabriquer un (tout ce que je peux poster est bot/webhook, filtré par design). Un watch est armé sur les logs : le premier message d'un membre le confirmera. N'importe qui peut écrire une ligne dans📼︱serveurpour clore.Rollback : manifest → 1.4.2 (l'inbound disparaît, l'outbound 1.4.2 reste).
🤖 Implémenté, déployé et vérifié par Claude (session autonome, go explicite de Paul).
T1 validé en live (11:49–11:50Z) : messages réels de Wait4Mi relayés en jeu (« Niquel on a bien dans les deux sens » … « Parfait 👍 »), symétrie confirmée par lui côté jeu. Les 4 tests d'acceptation sont verts → close.
🤖 Claude