Files
ShbDiscordBot/AGENTS.md
2026-08-07 13:41:43 +03:00

3.5 KiB

ShbDiscordBot contributor guide

Purpose and invariants

This repository builds one Paper plugin which embeds a JDA Discord bot. Discord is the entry point for issuing short-lived link codes, Minecraft is the only place where a code can be consumed, and ShbUtils Core API is the source of truth for persistent Discord-to-Minecraft links.

  • /auth is a global Discord slash command intended for bot DMs.
  • /link <six-digit-code> is a player-only Paper command.
  • /sdb reload is the operator-only full runtime/config reload command. Do not override Paper's built-in /reload command.
  • Link codes are process-local, single-use, active for ten minutes by default, and must never be logged.
  • Existing Discord or Minecraft links must not be overwritten.
  • Discord roles only grant LuckPerms nodes. This project deliberately does not revoke them.

Build and verification

  • Use Java 25 and the checked-in Gradle wrapper.
  • ./gradlew test runs the automated test suite.
  • ./gradlew shadowJar creates the deployable plugin JAR; the plain JAR does not include JDA/Jackson.
  • ./gradlew build must pass before handing work off.
  • LuckPerms and Paper are compile-only/server-provided dependencies. Do not shade either of them.

Architecture rules

  • Keep configuration parsing, Discord/JDA integration, ShbUtils HTTP transport, link orchestration, Paper commands, and LuckPerms synchronization in separate classes.
  • Do not perform network requests, JDA waits, or LuckPerms user loads on the Paper main thread.
  • Only touch Bukkit player/server state on the Paper main thread. Capture UUIDs and immutable values before crossing thread boundaries.
  • Make scheduled role scans non-overlapping and bound API concurrency.
  • Treat API 401 and validation/conflict responses as permanent failures; treat I/O, timeouts, 429, and 5xx as retryable.
  • On disable, cancel tasks and close JDA plus plugin-owned executors.
  • A runtime reload must validate the new config before stopping the current runtime, invalidate pending codes, await JDA shutdown off the Paper thread, recreate all config-bound services, and immediately run role synchronization.

Security and configuration

  • Never commit real Discord tokens or X-Internal-Secret values. The resource config.yml contains empty placeholders only.
  • Never include secrets, bearer tokens, full HTTP headers, or active link codes in logs or exceptions shown to players.
  • Parse Discord snowflakes as strings/unsigned IDs and Minecraft identifiers as UUIDs.
  • Generate codes with SecureRandom; preserve leading zeroes and enforce rate limiting when consuming invalid codes.

API contract and documentation

  • The local API reference is docs/API.md, based on https://api.shlakoblock.com/api.json.
  • Runtime code uses only internal status and Discord-link endpoints. Do not use the API verification-code endpoints for the Discord-to-Minecraft flow: those endpoints implement the reverse direction.
  • When the upstream OpenAPI version changes, compare every path/schema and update docs/API.md, DTOs, tests, and the recorded snapshot date together.

Testing expectations

  • Cover code uniqueness, expiry, replacement, rate limiting, reservation/release, and concurrent single-use behavior.
  • Test HTTP paths, JSON fields, internal-secret headers, status handling, and timeout/error classification without contacting production.
  • Test role-to-permission union, idempotent grants, unlinked users, and grant-only behavior.
  • A feature is incomplete if it can block the Paper main thread or leak a secret/code to logs.