Skip to content
OrePlugins

StaffTools

Moderation with a punishment record you can read.

Product pagev1.0.01.21 through 1.26 · Java 21+

Installation

  1. 1Drop the jar into plugins/ and restart. There are no dependencies — Paper fetches sqlite-jdbc itself on first boot and shares one copy with any other plugin on the same version. A server with no outbound network that day will see StaffTools refuse to enable with an instruction rather than a stack trace; it will not run without a working ban list.
  2. 2Run /stafftools commands. This is the one check worth doing on day one, because the failure it catches is completely silent — see Who owns /ban below.
  3. 3Give your moderators stafftools.staff, then edit plugins/StaffTools/config.yml and run /stafftools reload.

Who owns /ban

/ban and /kick are vanilla command names, and EssentialsX, LiteBans and AdvancedBan all want them too. Bukkit will not overwrite a name that is already taken: the loser silently gets only its namespaced form, and nothing anywhere says so.

That is the most expensive thing that can go wrong here, because it looks like nothing at all. A ban that reaches the wrong plugin records no reason, cannot be scoped to a world, never shows up in /history and cannot be lifted with /unban. The first symptom is noticing weeks later that the record looks thin.

StaffTools takes /ban and /kick back from vanilla and says so in the console at startup; vanilla’s versions remain as /minecraft:ban and /minecraft:kick. Against another plugin, whoever loads first wins and the server decides that — so if you are keeping another punishment plugin, hand it the names in commands.disabled rather than relying on load order. /stafftools commands is the authoritative answer for your server.

The punish panel

Each button is one line of config: label, kind, duration, icon, and an optional fifth field naming a world. kind is ban, mute, kick or warn; duration is 30m, 2h, 7d or perm.

The label goes on the record as the reason, so write it as one. Spam reads correctly in /history; Button 1 does not.

A preset with an unreadable duration or an unknown kind is skipped and named in the log. A preset with an unknown icon still works and falls back to paper — a cosmetic typo should not silently remove a moderation action.

World bans

/banworld (player) (world) (duration|perm) [reason]. The player keeps their access to the server and is stopped from entering that world, on login and on every world change.

They are moved to world-ban-fallback, or to the first loaded world if you leave that blank, and told why. The teleport is deferred one tick on purpose: issued from inside a world-change handler, an immediate teleport is overridden by the one already in flight and silently does nothing.

A punish preset can carry a world too, so griefing in the minigame world can be a single button that costs somebody the minigame world and nothing else.

Mutes

A mute covers chat and the commands that are chat by another name. The default list is /msg /tell /r /reply /me /say /w /whisper; add whatever your chat plugins provide under muted-commands. Namespaced forms are handled for you, so blocking /me also blocks /minecraft:me.

Mutes are resolved once when a player logs in and kept in memory, so an ordinary chat message never touches the database — which matters, because that handler runs for every line typed on the server.

The cache is authoritative rather than merely fast: issuing or lifting a mute updates it in the same breath as the database, so it takes effect on the player’s very next message rather than whenever something happens to re-read.

Permissions

stafftools.staff is the one to hand a moderator. It grants the everyday set and deliberately withholds two: stafftools.invsee, because that view is editable and anything moved in it is real, and stafftools.reload, which is an operator action.

stafftools.report defaults to everyone. Everything else defaults to op.

Commands are not declared in plugin.yml, and that is deliberate. A permission on a plugin.yml command makes Paper hide it from anyone lacking the node, so a staff member without the permission gets unknown command and cannot tell a missing permission from a broken plugin. Here the command stays visible and refuses by name.

Staff notes

/note (player) (text). Most of what staff need to remember about somebody is not a punishment — argues with everyone but has never actually broken a rule, or says it was their brother on the account.

With nowhere to put that, it either becomes a punishment that did not happen, or it lives in one moderator’s head and leaves when they do.

Notes appear under /history alongside the punishment record.

Commands

StaffTools commands and permissions
CommandWhat it doesPermission
/punish (player)The panel. Pick an offence; the reason and the length come with it.stafftools.punish
/ban (player) [reason] · /tempban (player) (time) [reason]Permanent and timed bans. Takes the name back from vanilla.stafftools.ban
/banworld (player) (world) (time|perm) [reason]Ban from one world only. The player stays on the server.stafftools.ban
/mute · /tempmute · /unmuteThe same for chat, covering /msg and the other commands that are chat by another name.stafftools.mute
/history (player)The record: every punishment including lifted ones, plus staff notes.stafftools.history
/note (player) (text)Something worth remembering that is not a punishment.stafftools.note
/staffmode · /vanish · /freeze (player) · /invsee (player)The staff toolkit. Inventories are held and handed back.stafftools.mode, and one node each
/report (player) (reason) · /reports [close (id)]Anyone can file one; staff are told immediately rather than waiting for somebody to look.stafftools.report (everyone)
/stafftools commandsWhich command names this plugin actually owns on your server.stafftools.reload

Still stuck?

Post in Discord with your server version and the relevant part of the log. That is almost always enough to get a straight answer the same day.

Get help