0011 - One /admin Dispatcher, Contributed Subcommands, Optional Shortcuts¶
Status¶
Accepted (1.0.0)
Context¶
Until 1.0 the root command knew a handful of subcommands by name and had to
mirror action ids of modules it was not allowed to import. Every module
needed commands, and so would every extension. Admins also expect the short
forms they know from other plugins (/kick, /ban, /vanish).
Decision¶
AdminCommand(API) is one/adminsubcommand; modules and extensions register them inCommandRegistrythroughModuleContext#registerCommand. The root dispatcher (UniversalAdminCommand) knows no command by name;/admin helpand tab completion are generated from the registry and filtered by permission.- A command is a frontend: it parses arguments and runs an action through
CommandInvocation#run, which also renders failures uniformly. The action re-checks permissions; the command's permission only controls visibility. AdminCommand#shortcuts()declares top-level labels. They are registered through Paper'sCOMMANDSlifecycle event asBasicCommands delegating to the same dispatcher, controlled bycommands.shortcuts.enabledandcommands.shortcuts.disabled. Player-facing commands (/report,/staffchat) setalwaysRegisterShortcuts.- Usage synopses are plain text passed as (escaped) message arguments, so
<player>is never mistaken for a MiniMessage tag.
Consequences¶
- Extensions get first-class commands, help entries and shortcuts with no extra code in the core.
- Shortcut clashes with other plugins are solvable by configuration;
/universaladmin:<label>always reaches ours. plugin.ymlonly declares/admin; everything else is dynamic.
Alternatives¶
- Brigadier trees for every command. Richer client-side validation, but
far more code per command and an API that changes with Minecraft
versions; the string-based
AdminCommandkeeps extension code simple. - Static shortcut list in
plugin.yml. Cannot be switched off or extended by extensions.