A simple Velocity proxy plugin that requires players to link a Discord account before they can join the rest of the network.
- A player joins the proxy.
- If they are not linked, the plugin intercepts the initial backend connection before Velocity sends them to a backend server.
- The player is disconnected with a message containing a short-lived verification code.
- The player goes to your Discord server and runs
/link code:<their code>. - The bot verifies their Discord roles.
- If the user has at least one allowed role, the plugin stores the Discord ↔ Minecraft link.
- The player rejoins and can now access the network.
After linking, players do not re-run code verification. The plugin reuses the stored Discord ID + Minecraft UUID and checks current Discord roles on join.
The plugin blocks unlinked players before they are connected to any backend server by using Velocity's pre-connect events.
On first startup, the plugin creates:
plugins/velocitydiscord/config.propertiesplugins/velocitydiscord/links.json
Example config.properties values:
bot.token=YOUR_DISCORD_BOT_TOKEN
discord.guild.id=YOUR_DISCORD_GUILD_ID
allowed.discord.role.ids=[123456789012345678,234567890123456789]
special.discord.role.id=345678901234567890
special.enabled=false
debug=false
enforce.linking=true
code.length=6
code.expiry.minutes=10allowed.discord.role.idssupports multiple Discord role IDs.- If the list is empty (
[]), any Discord member may link. - If the list contains one or more role IDs, the Discord user must have at least one of them.
Using Discord role IDs is strongly recommended over role names.
special.discord.role.idsets a Discord role to automatically grant after successful/link.- The role is only granted when special mode is enabled.
special.enabledcontrols the startup state (runtime toggles do not rewrite config).
You can toggle special mode at runtime from the Velocity console:
vdspecial status
vdspecial on
vdspecial off
Alias: velocitydiscordspecial
- Set
debug=trueto enable detailed[VelocityDiscord]join/access diagnostics in console logs. - Keep
debug=false(default) for normal operation with minimal log noise.
The generated config also includes these message settings:
messages.kickmessages.successmessages.invalid-codemessages.no-required-rolemessages.discord-server-onlymessages.wrong-discord-servermessages.bot-offlinemessages.usage
Messages are parsed with MiniMessage, so you can use colors and clickable links.
The kick message supports {code} (and {genCode} for compatibility) as the generated Minecraft verification code placeholder.
Example clickable kick message:
messages.kick=<gold>Welcome</gold>\n\n<gray>Verify in Discord #bot-cmds and run:</gray>\n<yellow>/link code:{code}</yellow>\ndiscord.gg/your-invite- Create a Discord application and bot in the Discord developer portal.
- Enable the bot for your server.
- Invite it with the
applications.commandsscope and normal bot access. - Put the bot token into
plugins/velocitydiscord/config.properties. - Set
discord.guild.idto your server ID. - Optionally set
allowed.discord.role.idsto the role IDs that should be accepted. - Restart Velocity.
The plugin registers a global slash command named /link when the bot becomes ready. The command expects a required code option.
cd /VelocityDiscord
./gradlew build- Link enforcement stays disabled until a real Discord bot token is configured, which avoids locking everyone out with the default placeholder token.
- If
allowed.discord.role.idsis empty, role checks are skipped. code.expiry.minutesonly controls pending pre-link codes, not already linked accounts.