Sueta

NexDiscordLink - Advanced Discord Link Plugin

1.0.5

Secure Minecraft ↔ Discord linking, sync, 2FA, rewards, chat bridge and automated health checks.

·Plugin

NexDiscordLink
Secure Minecraft ↔ Discord account linking, synchronization, 2FA, rewards, chat and network automation.

Spigot/Paper 1.16.5+ • Java 17+ • English & Turkish

Download latest release • Source & documentation • Türkçe dokümantasyon

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

More than a chat bridge
NexDiscordLink connects Discord to the complete Minecraft account lifecycle. It combines secure account linking, authentication, role and nickname synchronization, configurable rewards, rich event messages, auditing and proxy-network support in one production-oriented plugin.

Account Linking & Security

  • Discord DM, interactive button/modal panel and bilingual slash-command linking.
  • Expiring, single-use, rate-limited codes and one-account-per-platform enforcement.
  • TOTP 2FA with an in-game QR map and private Discord verification after network changes.
  • Secure unlinking using TOTP or a short-lived, account-bound Discord approval.
  • AES-GCM TOTP encryption, keyed IP fingerprints, verification rate limits and redacted audit logs.
  • Guarded Discord console command, disabled by default with an explicit allowlist.

Synchronization & Rewards

  • Linked role, Vault group ↔ Discord role, nickname and ban synchronization.
  • Minecraft → Discord, Discord → Minecraft and bidirectional role-sync modes.
  • Synchronization on join, on a schedule or immediately through an admin command.
  • First-link, relink, Discord-role, recurring salary and server-boost rewards.
  • Rewards run configurable console commands for economy, items, XP and other plugins.

Discord Messages & Chat

  • Two-way Minecraft ↔ Discord chat with optional webhook avatars.
  • Join, quit, death, advancement, linking, profile, security and audit messages.
  • Per-event channel and toggle, title, description, color, author, thumbnail, image, footer, timestamp and buttons.
  • English and Turkish message files with safe bundled fallbacks.
  • Discord mention parsing disabled by default for bridged player messages.

Automatic Config Doctor & Lang Doctor
Every startup and plugin reload checks the active configuration and language files automatically—no doctor command is needed.

  • Detects unreadable YAML, missing or unknown keys, wrong types and invalid ranges.
  • Validates Discord IDs, HTTP/HTTPS URLs, embed colors, button styles and feature dependencies.
  • Checks proxy/MySQL compatibility and chat destinations.
  • Detects missing translations, English fallback gaps and placeholder mismatches such as {player}.
  • Never prints tokens, passwords or encryption keys and never rewrites your files.

Storage & Network Support

  • SQLite for a single server and MySQL for production deployments.
  • Shared-MySQL Velocity/Bungee backends with one designated bot node.
  • Asynchronous PlaceholderAPI cache for scoreboards and TAB integrations.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Commands
Minecraft

/link        /eşle /hesapeşle /esle /hesapesle
/unlink      /eşlemesil /eslemesil /hesapayır /hesapayir
/linkstatus  /eşledurum /esledurum /hesabım /hesabim
/linkreward  /eşleödül /esleodul /ödül /odul
/2fa setup|login|disable
/nexdiscord reload|status|sync|resetreward

Discord

/link or /eşle
/profile or /hesap
/unlink or /eşlemeyi-kaldır
/help or /yardım
/setup-link
/console (optional; disabled by default)

Requirements

  • Java 17 or newer
  • Spigot or Paper 1.16.5 or newer
  • Discord bot with Server Members Intent and Message Content Intent enabled
  • Optional: Vault and a compatible permissions plugin
  • Optional: PlaceholderAPI
  • MySQL reachable by every backend when proxy mode is enabled

Quick Installation

  1. Download the shaded fat JAR from GitHub Releases.
  2. Place it in the server's plugins folder and start once.
  3. Stop the server and configure the bot token, channels and role IDs in plugins/NexDiscordLink/config.yml.
  4. Enable the required Discord intents and permissions.
  5. Start the server, review the automatic Doctor report and run /nexdiscord status.
  6. If modal linking is enabled, run /setup-link on Discord.

Upgrade safely
Stop the server completely and back up the old JAR, configuration, database and secret.key before replacing the plugin. Do not use a global /reload for JAR updates.

Security notice
Never publish a live bot token, database password, webhook URL, secret.key or production configuration. Losing the encryption key makes existing encrypted TOTP secrets unreadable.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Configuration & Language Files
The following files are the bundled defaults for NexDiscordLink 1.0.5. Expand a section to view or copy it. Never paste production tokens, passwords, webhooks or secret keys into public posts.

config.yml
# _____                                             _____
#( ___ )                                           ( ___ )
# |   |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|   |
# |   |                      _          __          |   |
# |   |    _______  ______  (_)  ______/ /__ _   __ |   |
# |   |   / ___/ / / / __ \/ / |/_/ __  / _ \ | / / |   |
# |   |  / /  / /_/ / / / / />  </ /_/ /  __/ |/ /  |   |
# |   | /_/   \__, /_/ /_/_/_/|_|\__,_/\___/|___/   |   |
# |   |      /____/                                 |   |
# |___|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|___|
#(_____)                                           (_____)

# NexDiscordLink Configuration File

bot-token: "YOUR_BOT_TOKEN_HERE" # Replace with your Discord Bot Token

settings:
  language: "en" # Options: en, tr
  update-checker: true

proxy:
  enabled: false
  server-id: "survival-1" # Must be unique for each backend
  bot-enabled: true # Enable on one backend; shared MySQL codes work across all backends
  link-check-interval-ticks: 40 # Worker notification/reward polling interval (2 seconds)

database-settings:
  type: "sqlite" # Options: sqlite, mysql
  host: "localhost"
  port: 3306
  database: "nexdiscordlink"
  username: "root"
  password: ""

channels:
  log-channel-id: "123456789012345678"
  console-channel-id: "" # Optional fallback when console-webhook-url is empty
  console-webhook-url: "" # Optional: Use Webhook for console logs (Faster & Works during startup)

audit-log:
  enabled: true
  channel-id: "" # Empty uses channels.log-channel-id
  console: false

rewards:
  salary-interval: 60 # In minutes
  commands:
    - "eco give {player} 1000"
  boost-commands:
    - "eco give {player} 5000"
    - "give {player} diamond 5"
  link-rewards:
    enabled: true
    limit: 1 # How many times a player can receive link rewards (0 = unlimited)
    commands:
      - "eco give {player} 2000"
      - "give {player} golden_apple 2"
    first-link-commands:
      - "experience add {player} 250 points"
    relink-commands: []
    discord-role-commands:
      "YOUR_SUPPORTER_ROLE_ID":
        - "eco give {player} 1000"
    preview:
      - "&8&m--------------------------------"
      - "&b&lDiscord Eşleme Ödülleri"
      - "&7• &f2.000 oyun parası"
      - "&7• &f2 altın elma"
      - "&7• &fİlk eşlemede 250 XP"
      - "&8&m--------------------------------"

link-system:
  type: "BOTH" # Options: DM, MODAL, BOTH
  account-policy: "ONE_TO_ONE" # One Minecraft account per Discord account and vice versa
  code-length: 6
  code-expiry-minutes: 5
  modal:
    channel-id: "YOUR_LINK_CHANNEL_ID"
    button-label: "Link Account"
    button-style: "PRIMARY" # PRIMARY (blue), SECONDARY (grey), SUCCESS (green), DANGER (red)
    modal-title: "Link Your Account"
    input-label: "Link Code"
    input-placeholder: "Enter your link code"

unlink-security:
  require-confirmation: true # Uses 2FA when enabled, otherwise sends a Discord DM approval

security-settings:
  enabled: true

console-command:
  enabled: false # Enable /console slash command on Discord (DANGEROUS - allows full server access!)
  # Only root commands listed here can be executed. An empty list denies every command.
  whitelist:
    - "say"
    - "list"
    - "tps"

sync:
  nickname:
    enabled: true
    format: "%name%"
  ban:
    enabled: false
  linked-role:
    enabled: true
    role-id: "YOUR_LINKED_ROLE_ID"
  role-sync:
    enabled: true
    direction: "MINECRAFT_TO_DISCORD" # MINECRAFT_TO_DISCORD, DISCORD_TO_MINECRAFT, BIDIRECTIONAL
    interval-minutes: 5
    vault-groups:
      vip: "123456789012345678"
      mvp: "123456789012345678"

chat-bridge:
  enabled: true
  channel-id: "YOUR_CHAT_CHANNEL_ID"
  webhook-url: "" # Optional: If set, uses webhook for Game -> Discord (Better visuals)
  discord-to-game-format: "&8[&bDiscord&8] &f{user}: &7{message}"

# Discord embed and Game -> Discord message customization.
# Empty title/description values use the active language file.
# Colors accept names, #RRGGBB, or "R, G, B". Image URLs must use http/https.
# Supported common placeholders: {player}, {uuid}. Event-specific placeholders are shown below.
discord-messages:
  defaults:
    color: "" # Empty keeps each message's built-in color
    timestamp: true
    author:
      enabled: false
      text: "{player}"
      url: ""
      icon-url: "https://mc-heads.net/avatar/{player}"
    thumbnail:
      enabled: false
      url: "https://mc-heads.net/avatar/{player}"
    image:
      enabled: false
      url: ""
    footer:
      enabled: false
      text: "NexDiscordLink"
      icon-url: ""

  events:
    join:
      enabled: true
      channel-id: "" # Empty uses channels.log-channel-id
      title: ""
      description: "" # {player}, {uuid}
      color: "#2ECC71"
      author:
        enabled: true
      thumbnail:
        enabled: true
    quit:
      enabled: true
      channel-id: ""
      title: ""
      description: "" # {player}, {uuid}
      color: "#E74C3C"
      author:
        enabled: true
      thumbnail:
        enabled: true
    death:
      enabled: true
      channel-id: ""
      title: ""
      description: "" # {player}, {uuid}, {death_message}
      color: "#000000"
      author:
        enabled: true
      thumbnail:
        enabled: true
    advancement:
      enabled: true
      channel-id: ""
      title: ""
      description: "" # {player}, {uuid}, {advancement}
      color: "#F1C40F"
      author:
        enabled: true
      thumbnail:
        enabled: true

  link-panel:
    enabled: true
    channel-id: "" # Empty uses link-system.modal.channel-id
    title: ""
    description: ""
    button-label: "" # Empty uses link-system.modal.button-label
    button-style: "" # Empty uses link-system.modal.button-style
    color: "#2ECC71"
    timestamp: false
    footer:
      enabled: true
      text: "" # Empty uses discord.modal.embed.footer from the active language file
      icon-url: ""

  security-login:
    title: ""
    description: "" # {player}, {uuid}, {ip}
    button-label: ""
    button-style: "SUCCESS" # PRIMARY, SECONDARY, SUCCESS, DANGER
    color: "#E74C3C"
    author:
      enabled: true
    thumbnail:
      enabled: true

  unlink-confirmation:
    content: "" # {player}, {uuid}; empty uses the active language file
    button-label: ""
    button-style: "DANGER" # PRIMARY, SECONDARY, SUCCESS, DANGER

  profile:
    title: ""
    color: "#00FFFF"
    field-player: ""
    field-uuid: ""
    field-status: ""
    author:
      enabled: true
    thumbnail:
      enabled: true

  audit:
    enabled: true
    channel-id: "" # Empty uses audit-log.channel-id, then channels.log-channel-id
    title: ""
    field-event: ""
    field-actor: ""
    field-detail: ""
    event-colors:
      account_linked: "#2ECC71"
      account_unlinked: "#F1C40F"
      two_factor_enabled: "#3498DB"
      two_factor_disabled: "#E67E22"
      two_factor_verified: "#2ECC71"
      verification_failed: "#E74C3C"
      ip_challenge: "#E74C3C"
      ip_verified: "#2ECC71"
      role_sync: "#9B59B6"
      admin_action: "#34495E"

  chat:
    minecraft-to-discord-format: "**{player}**: {message}"
    webhook-username: "{player}"
    webhook-avatar-url: "https://mc-heads.net/avatar/{player}"

Similar projects

Plugin →