Venusanticheat docs

Subcommand class

The abstract class a plugin extends. Two constructors, two abstract methods, three getters — nothing else.

package xyz.kaosmc.anticheat.api.command
SignatureDescription
protected Subcommand(String label)Visible, no permission requirement.
protected Subcommand(String label, boolean hidden, String permission)Full form. A null permission means anyone may run it; hidden keeps it out of tab completion.
final String label()The label, as registered. Matching is case-insensitive but the label is reported exactly as given.
final boolean hidden()True when the command is excluded from tab completion and help output.
final String permission()The permission node checked before execution, or null.
abstract void execute(Player, String label, String[] args)label is the subcommand label, args the arguments after it (no label included).
abstract List<String> onTabComplete(Player, String[] args)Return the completions for the current argument list; return an empty list for none.
a subcommand with permission and completions
public final class BrandSubcommand extends Subcommand {

    private static final List<String> ARGUMENTS = List.of("alerts", "verbose", "brands");

    public BrandSubcommand() {
        super("stafftool", false, "myplugin.staff");
    }

    @Override
    public void execute(Player player, String label, String[] args) {
        if (args.length == 0) {
            player.sendMessage("Usage: /venus " + label + " <" + String.join("|", ARGUMENTS) + ">");
            return;
        }
        switch (args[0].toLowerCase(Locale.ROOT)) {
            case "alerts" -> toggle(player, AlertService.Channel.DETECTIONS);
            case "verbose" -> toggle(player, AlertService.Channel.VERBOSE);
            case "brands" -> toggle(player, AlertService.Channel.BRANDS);
            default -> player.sendMessage("Unknown option: " + args[0]);
        }
    }

    private static void toggle(Player player, AlertService.Channel channel) {
        VenusApi api = VenusAPIProvider.get();
        api.users().queryUserByUuid(player.getUniqueId()).ifPresent(user -> {
            AlertSettings settings = api.alerts().settings(user, channel);
            settings.setEnabled(!settings.enabled());
            player.sendMessage(channel + " is now " + (settings.enabled() ? "on" : "off"));
        });
    }

    @Override
    public List<String> onTabComplete(Player player, String[] args) {
        if (args.length != 1) return List.of();
        String prefix = args[0].toLowerCase(Locale.ROOT);
        return ARGUMENTS.stream().filter(option -> option.startsWith(prefix)).toList();
    }
}

Arguments

The args array never contains the subcommand label. For /venus stafftool verbose you receive args = ["verbose"] and label = "stafftool". Length checks are part of your job; the dispatcher does not validate arity.

Errors

An exception thrown from execute is caught by the dispatcher and reported to the sender as a generic failure, so a bug in your subcommand cannot break /venus for everyone else. Log the detail yourself if you need it.

Registration is covered on the subcommands interface.