Skip to content

1. Project Overview ​

What is AppelTools? ​

AppelTools is a coordinated Paper + Velocity plugin suite for the AppelCraft Minecraft server network. It provides moderation, economy, social (friends/parties), and utility features across a multi-server network.

The suite consists of three Gradle modules that build to two deployable plugins plus one shared library:

  • common (AppelTools-Common.jar) — pure-Java shared library, no Bukkit/Velocity types. Defines the database, configs, types, permissions, plugin updater, chat filter, Discord embeds, and platform abstractions.
  • paper (AppelTools-Paper.jar) — runs on each Paper 26.3 backend server. Handles gameplay commands (teleport, gamemode, speed, fly, homes, economy, freeze, notes GUI), per-server player economy (Vault), staff mode (vanish + tool kit + invsee), and a plugin-messaging listener for chat/command moderation and staff-mode sync.
  • velocity (AppelTools-Velocity.jar) — runs on the Velocity 4.2 proxy. Cross-server moderation (ban/mute/kick, IP-targeted variants, history, undo), friend system, party system, private messaging, chat filter, staff-chat broadcasting, reports, maintenance mode, server restart scheduler, server registration, and Discord logging of all significant events.

Paper and Velocity share the same MySQL database but do not share a JVM. They synchronize via Velocity plugin-message channels (see 08-messaging.md).

┌──────────────┐  plugin messages   ┌──────────────────────┐
│   Velocity   │ ─────────────────▶ │   Paper (each node)  │
│   Proxy      │ ◀───────────────── │                      │
└──────┬───────┘                    └──────────┬───────────┘
       │                                      │
       └─────────────► MySQL ◄────────────────┘

Feature Catalogue ​

Moderation (Velocity-side) ​

  • ban, tempban, unban — permanent, temporary (with Duration), and undo.
  • ipban, tempipban, ipunban — IP-targeted variants; kick all currently connected players with that IP.
  • kick, ipkick — single and IP-kick.
  • mute, tempmute, unmute — chat mute.
  • ipmute, tempipmute, ipunmute — IP-targeted mute, notifies all players with that IP.
  • history — list all punishments for a player (perm + temp + undone).

Economy (Paper-side) ​

  • balance (alias bal, money) — show your per-server balance.
  • pay — pay another player; respects their PaymentsToggled flag, 2-decimal rounding via BigDecimal, requires positive amount.
  • togglepay — enable/disable receiving payments.
  • economy (alias eco) — admin: add|remove|set|reset <target> [amount].
  • baltop (alias balancetop) — paginated top 1000 balances, 10 per page, 60-second cached.
  • Vault hook (VaultEconomyProvider) — name AppelEconomy, currency $, format #,###.00, no bank support.

Teleport (Paper-side) ​

  • teleport (tp) — /tp <target> or /tp <target> <dest>.
  • teleporthere (tphere) — pull target to you.
  • teleportpos (tppos) — /tppos <x> <y> <z> [yaw] [pitch] [world] with ~ and 0 shortcuts.
  • back (return) — return to your last teleport-from location.
  • teleporttoggle (tptoggle) — block/unblock incoming teleport requests.
  • teleportauto (tpauto) — auto-accept all incoming teleport requests.
  • teleportask (tpask, tpa) — send a TO teleport request, clickable accept/deny.
  • teleportahere (tpahere) — send a HERE teleport request.
  • teleportaccept (tpaccept) — accept a pending request.
  • teleportdeny (tpdeny) — deny a pending request.
  • teleportacancel (tpacancel) — cancel all or a specific pending request.

Homes (Paper-side, per-server via getServerUUID()) ​

  • home (homes) — list homes; teleport to one by name; admin: /home <player>:<name>.
  • sethome — set a home, optionally for another player.
  • delhome — send a clickable /delhomeconfirm <name> confirmation.
  • delhomeconfirm — actually delete.
  • renamehome — rename an existing home.

Speed & Flight (Paper-side) ​

  • speed — set walking or flying speed 1-10 depending on whether you're currently flying.
  • walkingspeed (walkspeed) — walking speed 1-10.
  • flyingspeed (flyspeed) — flying speed 1-10.
  • fly (togglefly) — toggle allowFlight; turns flying on when enabling.

Gamemode (Paper-side) ​

  • gamemode (gm) — set a player's gamemode.
  • creative (gmc), survival (gms), adventure (gma), spectator (gmsp) — direct shortcuts.

Friends (Velocity-side, cross-server) ​

  • friends (friend, f) — add, accept, deny, remove, list (10/page), requests (sent), pending (received), notifications (toggle), toggle (toggle incoming requests).

Parties (Velocity-side, cross-server) ​

  • party (p) — invite, leave, list, promote, demote, transfer, remove (alias kick), warp, accept, disband, chat, mute, allinvite, admin join, admin list, admin disband.
  • pchat (pc) — party chat.

Private Messaging (Velocity-side, cross-server) ​

  • message (many aliases) — private message; stores lastMessaged, respects ignore lists, applies chat filter, notifies staff of curse words, spy broadcasts.
  • reply — reply to the last messaged player or console.
  • ignore / unignore — manage ignored list.
  • messagetoggle — toggle receiving private messages.

Chat (Velocity-side, cross-server) ​

  • Per-player ChatChannel enum: GLOBAL, PARTY, MESSAGE, STAFF. Switch with chat <channel>.
  • rules — print the configured rules.
  • chat-filter — enabled by default; configurable curse words and IP/URL blocking.

Reports (Velocity-side) ​

  • report — report <player> <reason>. Rejects self-report and report cooldown. Adds to the player's report list, broadcasts to staff, posts a Discord embed, fires StaffNotificationService.sendReport.
  • reports — list and remove <index>.

Staff (Velocity-side) ​

  • staffchat (sc) — @Join <message> to all staff with chat toggled.
  • staffchattoggle (sctoggle) — toggle persistent staff-chat channel.
  • staffmodetoggle (smtoggle, staffmode, sm, h) — toggle staff mode.
  • staffnotificationstoggle (sntoggle, staffnotifications) — toggle staff notification broadcast.
  • staffspytoggle (sstoggle, staffspy) — toggle PM-spy broadcasts.
  • stafflist (slist) — online staff grouped by server.
  • versionlist (vlist) — online players grouped by Minecraft protocol version.
  • broadcast (a, alert, bc) — global alert.
  • notes (sn, snotes, staffnotes) — add|remove|list notes; sends Discord embed to watchlist channel.

Staff Tools (Paper-side) ​

  • freeze — toggle a player's frozen flag. Enforcement happens in StaffFreezeListener (cancels movement, inventory, interact, place, break, command).
  • notesgui — opens a 54-slot chest GUI of a target player's notes; requires staff mode.
  • Staff tool kit (while in staff mode, given by StaffInventoryManager): vanish (FEATHER), freeze (BLAZE_ROD), invsee (CHEST), notes (PAPER), next-player (ENDER_EYE). Inventory is serialized to staffInventory table on entry and restored on exit.
  • /atp debug staffmode give <DebugStaffModeItem> — admin: hand out a specific staff item.

Maintenance (Velocity-side) ​

  • maintenance (mt) — toggle proxy-wide maintenance; kicks non-bypass players, posts Discord.
  • While maintenance is on, ProxyPingListener overrides MOTD, server-icon, version-name, and player-list-hover.
  • Admin.MAINTENANCE_BYPASS — permission to ignore the maintenance kick.

Server Management (Velocity-side) ​

  • servers — register <name> <ip> <port>, unregister <name>, list. Registers a backend in the servers table.

Restart (Velocity-side) ​

  • restartserver (rs) — restartserver <duration|cancel>. Schedules broadcasts at 60/30/10/1 minutes and 5/4/3/2/1 seconds, then shuts the proxy down. cancel aborts a scheduled restart.

Plugin Updater ​

  • updater list / get <plugin> / update <plugin> (under both atp and atv).
  • Six providers supported: Jenkins, SpigotMC, Modrinth, Hangar, GitHub, Geyser.
  • Configured in config.yml under the plugins: block.
  • updatePlugin downloads to .tmp, validates ZIP magic 0x50 0x4B, deletes the old file, renames if Spigot.

Discord (JDA) ​

  • Paper bot: loads if Modules.Discord.ROOT is enabled and token is non-empty. Hosts the /search slash command.
  • Velocity bot: builds LiteCommands-for-JDA; hosts StaffNotificationService for outbound embeds and the /search slash command.
  • Embeds: green logs, yellow missing-plugins, red report/error, yellow watch-list staff note, custom curse embed.
  • Staff notification embeds: 📋 report, 👤 staff join/leave, ⚖️ punishment, 🔧 maintenance, 🔄 restart.

Plugin Checker ​

  • Config.Other.REQUIRED_PLUGINS lists plugins that must be present on each Paper node.
  • If any are missing on startup, setWhitelisted(true) and post Embeds.createMissingPluginsEmbed into the Discord log channel, pinging MOD_ROLES. Retries until the bot is connected.

Whitelist ​

  • setWhitelisted(boolean) — when true, PlayerJoinListener kicks any joining player who lacks Permissions.Command.Staff.ROOT, with "You are not whitelisted!".

Staff Inventory Persistence ​

  • On staff-mode entry, the player's current inventory is Base64-serialized via ItemStack.serializeItemsAsBytes and saved to staffInventory(Server, Uuid, Inventory).
  • On staff-mode exit, the inventory is restored and the row deleted.

Per-server Player UUID ​

  • On first start, each Paper node generates a serverUuid (random) and persists it to data.yml. Used as the ServerUUID foreign key in playerServerData and homes.
  • This is what makes per-server balance and per-server homes work.

Concurrency and Lifecycle Notes ​

  • Paper auto-save: ATPPlayerManager.startAutoSaveTask() runs every 5 minutes; on shutdown the bootstrap awaits saveAllPlayers().
  • Velocity auto-save: PunishmentManager.startAutoSaveTask() runs every 5 minutes (checkAllTempPunishments); expires temp punishments and deactivates them.
  • Velocity announcements: AnnouncementManager.start() runs at the configured interval.
  • All DB writes use CompletableFuture.supplyAsync; the Database.runUpdate retries on MySQL deadlock (SQLState == "40001") with a 1-second backoff.
  • The chat queue (SignedQueue / QueuedData) auto-resolves any pending future after 50 ms with SignedResult.ALLOWED to keep the pipeline moving.

Built with VitePress.