Back to Plugins
Network PluginVelocity & BungeeCordv1.6.0

Report System

Velocity and BungeeCord reports powered by Discord and MariaDB.

ReportSystem 1.6.0 brings network-wide reporting to Velocity and BungeeCord in one JAR. Create dedicated Discord channels for reports, review stored chat and command history, archive transcripts and attachments, and optionally manage reports through a live web portal.

Features

Discord Integration

Automatically creates a unique text channel in your Discord server for every new report.

Web Transcripts

Generate and host professional chat transcripts (including media) when a report is closed.

Staff Protection

Optional settings to prevent players from maliciously reporting administrators.

Rate Limiting

Prevent spam with an advanced 'Greedy Token' system to rate limit report creation.

Cross-Server Sync

One JAR runs on Velocity or BungeeCord and handles reports across your entire network.

Stored Chat History

Review persistent player chat and command history in Discord with paginated chat logs.

Live Web Portal

Optionally synchronize reports with the web portal through a live WebSocket connection.

Same-Player Limits

Limit repeat reports against the same player in addition to the global report rate limit.

MariaDB Storage

Persistent, high-performance data storage for all report logs and statuses.

Compatibility

Velocity
BungeeCord
1.19.4 – 1.20.6 – 1.21.11 – 26.1.2 – 26.2 – 26.3Java 21+MariaDB / MySQLDiscord Bot Token

Commands & Permissions

CommandDescriptionPermission
/report <player> <reason>Submit a new reportreports.report (when require-permission is enabled)
/reportsView your own open reports—
/reports view-open [page]View your own open reports—
/reports view-closed [page]View your own closed reports—
/reports verShow the plugin version—
/reports demoCreate a demo report for portal testingreports.demo
/reports reloadReload config and language filesreports.reload
/reports info <id>View detailed report datareports.info
/reports close <id> [reason]Close an active reportreports.close
/reports delete <id>Remove report from databasereports.delete
/reports admin view-open [page]View all open reports on the networkreports.admin.view
/reports admin view-closed [page]View all closed reports on the networkreports.admin.view
/reports admin view-player sent <p> [open] [page]View reports a specific player has sentreports.admin.view
/reports admin view-player received <p> [open] [page]View reports filed against a specific playerreports.admin.view
/reports admin ban-session <p>Block a player from using /reportreports.admin.ban
/reports admin unban-session <p>Restore a player's ability to reportreports.admin.ban

Documentation & Setup

1Pre-requisites

You must have a MariaDB database for persistent data storage. You also need to register a new application on the Discord Developer Portal to obtain a Bot Token and Application ID. Ensure your Discord server has a specific Category prepared where the bot can spawn the report channels.

2Bot Configuration

Place the same ReportSystem 1.6.0 JAR in your Velocity or BungeeCord plugins folder and start the server once to generate the config.yml. Use Java 21 or newer and install the matching Protocolize build (required on BungeeCord). Install ReportSystem on the proxy only. Fill in your MariaDB credentials, and populate the discord-bot section with your Bot Token, Guild ID, Category ID, and Audit Log Channel ID.

3Transcripts Setup

To enable web-based transcripts when reports are closed, generate an API key at space.xap3y.eu. In your config, set discord-bot.transcripts.enabled to true and paste your generated key. Enable discord-bot.transcripts.save-attachments to archive Discord attachments before their links expire.

4. Live Portal & Migration

To connect the live portal, enable portal.enabled and request a Reports API key from xap3y on Discord. The portal uses a separate key from transcripts. When migrating between proxies, copy config.yml and retain the same database settings. Run one Discord bot and portal connection per network.

Version History

69 total downloads
1.6.0LatestOct 2, 20262

Report System 1.6.0

BungeeCord support

1.5.0Oct 1, 20264

Report System 1.5.0

1.2Mar 24, 202663

Report System [Velocity] 1.2

Default Config

config.yml255 lines
prefix: "&7[&cReports&7] &r"

enabled: true

require-permission: false # Permission: reports.report

notify-sound: "entity.experience_orb.pickup"
notify-sound-source: "MASTER"
notify-on-join: true
notify-delay-seconds: 5
announce-solved: true # Reply to reporter when their report is closed
max-open-reports: 10 # Max open reports per player, set to 0 for unlimited
reports-per-page: 5 # Number of reports to show per page in the /reports
protect-staff: true # Prevent players from reporting staff members
protect-permission: "reports.protect" # Permission to bypass staff protection

# Live website control portal. The API key falls back to discord-bot.transcripts.key when blank.
# This key is different from transcripts key!!!
portal:
    enabled: false
    debug: false # Keep disabled in normal use
    websocket-url: "wss://call.xap3y.eu/ws/mc-reports"
    user-agent: "ReportSystem/{version}"
    api-key: "" # Message me on discord for key: xap3y
    reconnect-seconds: 60

close-comment-required: false # Require a comment when closing a report
min-close-comment-length: 10 # Minimum length for close comment

# Rate limit /report command?
rate-limit: # refillGreedy
    enabled: true
    time-seconds: 180 # Time to refill in seconds
    tokens: 5 # Max reports allowed in the time above
    refill-tokens: 5 # Number of tokens to refill after each time
    can-bypass: true
    bypass-permission: "reports.bypassratelimit"

# Limit how often one reporter can report the same player.
same-player-rate-limit:
    enabled: true
    max-reports: 1
    time-seconds: 600 # 10 minutes

discord-bot:
    log-startup: true # Log startup to discord audit log channel
    token: "EXAMPLE_TOKEN"
    guild-id: 1111111111111111111 # Discord server ID
    channel-id: 1111111111111111111 # Audit log channel
    app-id: 1111111111111111111 # Discord app ID
    category-id: 1111111111111111111 # Category for report channels
    use-topic: false
    channel-topic: "topic" # {open} | {closed} | {total}
    activity: "ReportSystem v{version}" # Discord presence
    channel-template: "report-{reporter}" # {reporter}, {target}, {id}
    channel-message: "|| <@&ROLE_ID> ||" # Message to be sent in the report channel
    suppress-notifications: false # Send with @silent
    send-chat-history: true
    chat-history-messages-per-page: 20

    admin-role-ids:
        - 1111111111111111111
        - 2222222222222222222

    transcripts:
        enabled: false
        url: "https://call.xap3y.eu/v1/discord/transcript/upload"
        url-get: "https://space.xap3y.eu/mc/report/"
        url-get-ending: "?ref=test"
        key: "example_key" # Generate here: https://space.xap3y.eu/mc/report/get-key
        media-save-api-key: "example_key" # Same key as above
        file-save: false # Save a local copy of the transcript file
        save-attachments: true # Save all Discord attachments before their CDN links expire
        media-save-api: "https://call.xap3y.eu/v1/image/upload/url"
        user-agent: "ReportSystem/1.6.0"
        media-timeout: 10 # HTTP timeout in seconds for attachment upload
        res-json-template: "/message/urlSet/rawUrl" # Json template to extract url from space api, dont change

database:
    host: "localhost"
    port: 3306
    database: "reports_db"
    username: "reports_user"
    password: "securepassword"
    max-pool-size: 10
    minIdle: 2

    pool-refresh: true # Refresh the connection pool every 30 minutes
    refresh-interval: 600000 # milliseconds (10 minutes) - how often to refresh current open reports from the database

lang:
    only-player: "&cThis command can only be executed by a player."
    no-permission: "&cYou do not have permission to execute this command."
    reload: "&aConfiguration reloaded successfully."
    plugin-disabled: "&cReportSystem is currently disabled."
    fail: "&cAn error occurred while processing your request."
    report-usage: "&cUsage: /report <player> <reason>"
    report-success: "&aYou have successfully reported &c{target}."
    report-yourself: "&cYou cannot report yourself."
    report-cooldown: "&cYou are on cooldown. Please wait and try again later."
    report-rate-limit: "&cYou're doing that too fast. Try again in {sec} seconds."
    report-same-player-rate-limit: "&cYou have reported this player too many times recently. Try again in {minutes} minutes."
    report-announce: "&c{reporter} &ahas reported &c{target} &afor &c{reason}&a."
    report-join-notify: "&cThere are &e&l{count} &r&copened reports!"
    report-max-reports: "&cYou cannot have more than &f{max} &copen reports at the same time."
    report-no-reason: "&cWrong usage! &f/report <player> <reason>"
    report-no-player: "&cWrong usage! &f/report <player> <reason>"
    player-not-found: "&cPlayer &cnot found."
    report-close-no-id: "&cWrong usage! &f/reports close <id> [reason]"
    report-close-no-reason: "&cYou must provide a reason for closing the report. &f/reports close <id> <reason>"
    report-delete-no-id: "&cWrong usage! &f/reports delete <id>"
    report-info-no-id: "&cWrong usage! &f/reports info <id>"
    report-not-found: "&cReport with ID &f{id} &cnot found."

    report-already-closed: "&cReport with ID &f{id} &cis already closed."
    report-closed: "&aYou have successfully closed report ID &c{id}"
    report-close-discord-error: "&cAn error occurred while closing the report in Discord."
    report-deleted: "&aYou have successfully deleted report ID &c{id}"
    report-delete-discord-error: "&cAn error occurred while deleting the report in Discord."
    report-already-deleted: "&cReport with ID &f{id} &cis already deleted."
    no-reports-found: "&cNo reports found."
    closed-reports-header: "&cClosed Reports"
    report-ban: "&cYou cannot submit a report."
    report-ban-already: "&cYou are already banned &f{player}&c from submitting reports."
    report-unban-already: "&cPlayer &f{player}&c is not banned from submitting reports."
    report-ban-success: "&aYou have successfully banned &f{player}&a from submitting reports."
    report-unban-success: "&aYou have successfully unbanned &f{player}&a from submitting reports."
    report-close-reason-too-short: "&cThe close reason must be at least &f{min} &ccharacters long."
    open-reports-header: "&aOpen Reports"
    new-report: "New Report"
    page: "Page"
    time: "Time"
    reason: "Reason"
    reported-player: "Reported Player"
    reported-by: "Reported By"
    closed-by: "Closed By"
    deleted-by: "Deleted By"
    report-is-closed: "Report Closed"
    report-is-deleted: "Report Deleted"
    closed-at: "Closed At"
    comment: "Comment"
    view: "View"
    prev: "Prev"
    next: "Next"
    close-report: "Close Report"
    close-reason: "Close Reason"
    close-reason-lore: "Reason for closing the report (optional)"
    close-report-lore: "Click to close this report."
    report-solved-announce: "&aYour report with ID &c{id} &ahas been closed."
    report-solved-details-button: "view"
    report-solved-details-hover: "&7Close reason: &e{reason}\n&7Closed by: &e{closer}\n&7Closed at: &e{time}"
    report-solved-no-reason: "No reason provided"
    report-solved-unknown-closer: "Unknown"
    report-solved-unknown-time: "Unknown"
    page-out-of-range: "&4Internal error: Page number out of range."
    report-protected: "&cYou cannot report this player."

    # Discord Locale
    no-permission-button: "You do not have permission to interact with this button."
    no-permission-modal: "You do not have permission to submit this form."
    no-permission-command: "You do not have permission to execute this command."
    close-button: "Close"
    delete-button: "Delete"
    chatlog-title: "Chat Log"
    chatlog-empty: "No chat history is available for this report."
    delete-btn-save-no-reason: "Save Transcript (No Reason)"
    delete-btn-save-reason: "Save Transcript (With Reason)"
    delete-btn-no-save-no-reason: "Delete Only (No Reason)"
    delete-btn-no-save-reason: "Delete Only (With Reason)"
    delete-btn-cancel: "Cancel"
    delete-prompt: "Are you sure you want to delete report #{id}?\nPlease select an option below:"
    delete-cancelled: "Cancelled deletion."
    delete-reason-lore: "Reason for deleting the report"
    delete-report: "Delete Report"
    delete-reason: "Delete Reason"

cz-lang: # Czech translation
    only-player: "&cTento příkaz může použít pouze hráč."
    no-permission: "&cNemáte oprávnění k použití tohoto příkazu."
    reload: "&aKonfigurace byla úspěšně znovu načtena."
    fail: "&cPři zpracování požadavku došlo k chybě."
    report-usage: "&cPoužití: /report <hráč> <důvod>"
    report-success: "&aÚspěšně jste nahlásili hráče &c{target}."
    report-yourself: "&cNemůžeš nahlásit sám sebe."
    report-cooldown: "&cJste v cooldownu. Počkejte prosím a zkuste to znovu později."
    report-announce: "&c{reporter} &anahlásil hráče &c{target} &az důvodu &c{reason}&a."
    report-join-notify: "&cJe zde &e&l{count} &r&cotevřených reportů!"
    report-max-reports: "&cNemůžeš mít více než &f{max} &cotevřených reportů současně."
    report-no-reason: "&cŠpatné použití! &f/report <hráč> <důvod>"
    report-no-player: "&cŠpatné použití! &f/report <hráč> <důvod>"
    player-not-found: "&cHráč nebyl nalezen."
    report-close-no-id: "&cŠpatné použití! &f/reports close <id> [důvod]"
    report-close-no-reason: "&cMusíte uvést důvod uzavření reportu. &f/reports close <id> <důvod>"
    report-delete-no-id: "&cŠpatné použití! &f/reports delete <id>"
    report-info-no-id: "&cŠpatné použití! &f/reports info <id>"
    report-not-found: "&cReport s ID &f{id} &cnebylo nalezeno."
    report-already-closed: "&cReport s ID &f{id} &cuž je uzavřeno."
    report-closed: "&aÚspěšně jste uzavřeli report ID &c{id}"
    report-close-discord-error: "&cPři uzavírání report na Discordu došlo k chybě."
    report-deleted: "&aÚspěšně jste smazali report ID &c{id}"
    report-delete-discord-error: "&cPři mazání report na Discordu došlo k chybě."
    report-already-deleted: "&cNahlášení s ID &f{id} &cuž je smazáno."
    no-reports-found: "&cNebyla nalezena žádná nahlášení."
    closed-reports-header: "&cUzavřené reporty"
    report-ban: "&cNemůžeš odesílat reporty."
    report-ban-already: "&cHráč &f{player}&c už má zákaz odesílání reporty."
    report-unban-already: "&cHráč &f{player}&c nemá zákaz odesílání reporty."
    report-ban-success: "&aHráči &f{player}&a byl úspěšně udělen zákaz odesílání reportů."
    report-unban-success: "&aHráči &f{player}&a byl úspěšně zrušen zákaz odesílání reportů."
    report-close-reason-too-short: "&cDůvod uzavření musí mít alespoň &f{min} &cznaků."
    open-reports-header: "&aOtevřené reporty"
    new-report: "Nový report"
    page: "Strana"
    time: "Čas"
    reason: "Důvod"
    reported-player: "Nahlášený hráč"
    reported-by: "Nahlásil"
    closed-by: "Uzavřel"
    deleted-by: "Smazal"
    report-is-closed: "Report uzavřen"
    report-is-deleted: "Report smazán"
    closed-at: "Uzavřeno dne"
    comment: "Komentář"
    view: "Zobrazit"
    prev: "Předchozí"
    next: "Další"
    close-report: "Uzavřít report"
    close-reason: "Důvod uzavření"
    close-reason-lore: "Důvod uzavření reportu (volitelné)"
    close-report-lore: "Klikněte pro uzavření tohoto reportu."
    report-solved-announce: "&aVáš report s ID &c{id} &abylo uzavřeno."
    report-solved-details-button: "zobrazit"
    report-solved-details-hover: "&7Důvod uzavření: &e{reason}\n&7Uzavřel: &e{closer}\n&7Čas uzavření: &e{time}"
    report-solved-no-reason: "Důvod nebyl uveden"
    report-solved-unknown-closer: "Neznámý"
    report-solved-unknown-time: "Neznámý"
    page-out-of-range: "&4Interní chyba: Číslo stránky je mimo rozsah."
    report-protected: "&cNemůžeš nahlásit tohoto hráče."

    # Discord Locale
    no-permission-button: "Nemáte oprávnění použít toto tlačítko."
    no-permission-modal: "Nemáte oprávnění odeslat tento formulář."
    no-permission-command: "Nemáte oprávnění použít tento příkaz."
    close-button: "Uzavřít"
    delete-button: "Smazat"
    delete-btn-save-no-reason: "Uložit přepis (bez důvodu)"
    delete-btn-save-reason: "Uložit přepis (s důvodem)"
    delete-btn-no-save-no-reason: "Pouze smazat (bez důvodu)"
    delete-btn-no-save-reason: "Pouze smazat (s důvodem)"
    delete-btn-cancel: "Zrušit"
    delete-prompt: "Opravdu chcete smazat nahlášení #{id}?\nVyberte možnost níže:"
    delete-cancelled: "Mazání zrušeno."
    delete-reason-lore: "Důvod smazání nahlášení"
    delete-report: "Smazat nahlášení"
    delete-reason: "Důvod smazání"