Defines a command or subcommand.
- On a class: Main command entry point.
- On a method/nested class: Subcommand.
| Attribute | Type | Default | Description |
|---|---|---|---|
value |
String |
required | Command name |
aliases |
String[] |
{} |
Alternative names |
description |
String |
"" |
Description; prefix with i18n: for a message key |
@Command("teleport")
@Command(value = "here", aliases = {"h"}) // on method = subcommandDual-purpose: marks default method or optional parameter.
- On methods: Executes when no subcommand matches.
value()must be empty. - On parameters: Marks optional with a default value string.
@Default
public void execute(Player sender, double x, double y, double z) { ...}
public void heal(Player sender, @Default("10") int amount) { ...}Binds a parameter to a local resolver method.
- On methods: Declares it as a resolver for its return type.
- On parameters: Binds to a resolver by name.
@Resolve
public Location resolveLocation(Player sender, double x, double y, double z) { ...}
public void tp(Player sender, @Resolve("resolveLocation") Location loc) { ...}Resolver methods can have any sender type (same as command, different supported type, or base type). The framework automatically casts and passes the correct sender.
Overrides parameter name in usage/error messages.
public void heal(Player sender, @Name("amount") int health) { ...}
// Usage: <amount>Parameter consumes all remaining arguments. Must be last.
public void msg(Player sender, @Greedy String message) { ...}Enum parameters are handled natively: the argument is parsed with Enum.valueOf and suggestions are the enum
constants. No ArgumentResolver registration is required.
public enum Mode { FAST, SLOW }
public void setMode(Player sender, Mode mode) { ...}Binds parameter to a suggestion provider for tab-completion.
Can reference a field (returns List<String>) or a method. A provider method may take no parameters,
(String[] current), (sender), (sender, String[] current), (String[] current, String[] context), or
(sender, String[] current, String[] context).
// Field-based suggestions
public final List<String> modes = Arrays.asList("normal", "silent", "instant");
public void setMode(Player sender, @Suggest("modes") String mode) { ...}
// Method-based suggestions
public List<String> getNearPlayers(Player sender, String[] current, String[] context) { ...}
public void tpNear(Player sender, @Suggest("getNearPlayers") Player target) { ...}Sets command permission. Works on classes and methods.
| Attribute | Type | Default | Description |
|---|---|---|---|
value |
String |
required | Permission node |
message |
String |
"" |
Denied message; plain text is its own key/fallback, or use i18n:key |
@Command("admin")
@Permission("myplugin.admin")
public class AdminCommands { ...
}
@Command("secret")
@Permission(value = "myplugin.secret", message = "Access denied!")
public void secret(Player sender) { ...}
@Command("admin")
@Permission(value = "myplugin.admin", message = "i18n:permission.admin")
public void admin(Player sender) { ...}Every denied-permission message is sent through CommandManager.sendMessage. The default message uses the
permission key; a custom plain message is passed as both key and fallback. Override
CommandManager.formatMessage(key, defaultMessage, args) to translate keys.
Validates numeric parameters against bounds.
| Attribute | Type | Default | Description |
|---|---|---|---|
value |
double |
required | Min/max value |
message |
String |
"" |
Custom error message |
public void setLevel(Player sender, @Min(0) @Max(100) @Default("50") int level) { ...}Custom validation method. The method must accept the parameter type and throw IllegalArgumentException on failure.
| Attribute | Type | Default | Description |
|---|---|---|---|
value |
String |
required | Validation method name |
message |
String |
"" |
Custom error message |
public void validateCoordinate(double coord) {
if (Math.abs(coord) > 30000000) {
throw new IllegalArgumentException("Coordinate cannot exceed 30,000,000!");
}
}
public void tp(Player sender, @ValidateWith("validateCoordinate") double x, double y, double z) { ...}Annotations can be stacked on the same parameter:
// @Default + @Min + @Max + @ValidateWith (quadruple stack)
public void setLevel(Player sender, @Min(0) @Max(100) @ValidateWith("validateEven") @Default("50") int level) { ...}
// @Greedy + @Name + @Suggest + @Default (quadruple stack)
public void chat(Player sender, @Name("text") @Greedy @Suggest("colors") @Default("red") String message) { ...}
// @Resolve + @Suggest (on different params)
public void build(Player sender, @Resolve("resolvePoint") Point pt, @Suggest("blocks") String block) { ...}