Skip to content

AbstractCommand

Package: com.hypixel.hytale.server.core.command.system

Core abstract base class for all commands. Provides the builder API for declaring arguments, subcommands, usage variants, aliases, and permissions. Subclass this (or one of its convenience subclasses) and implement execute(CommandContext) to define a command.

public abstract class AbstractCommand
protected AbstractCommand(@Nullable String name, @Nullable String description, boolean requiresConfirmation)

Primary constructor. name is the command name (lowercased internally); pass null for usage variant commands. description is a translation key. If requiresConfirmation is true, a --confirm flag is auto-registered and required before execution.

protected AbstractCommand(@Nullable String name, @Nullable String description)

Delegates to the primary constructor with requiresConfirmation = false.

protected AbstractCommand(@Nullable String description)

Delegates with name = null — used for usage variant commands.

@Nullable
protected abstract CompletableFuture<Void> execute(@Nonnull CommandContext var1);

Called when the command is invoked and all arguments have been parsed and validated. Return null for synchronous commands, or a CompletableFuture for async commands.

These methods declare the command’s arguments. Call them in the constructor or setup(). Arguments are parsed in declaration order for required args, and by name prefix for optional args.

@Nonnull
public <D> RequiredArg<D> withRequiredArg(@Nonnull String name, @Nonnull String description, @Nonnull ArgumentType<D> argType)
public <W extends WrappedArg<D>, D> W withRequiredArg(@Nonnull String name, @Nonnull String description, @Nonnull ArgWrapper<W, D> wrapper)
@Nonnull
public <D> RequiredArg<List<D>> withListRequiredArg(@Nonnull String name, @Nonnull String description, @Nonnull ArgumentType<D> argType)
@Nonnull
public <D> OptionalArg<D> withOptionalArg(@Nonnull String name, @Nonnull String description, @Nonnull ArgumentType<D> argType)
public <W extends WrappedArg<D>, D> W withOptionalArg(@Nonnull String name, @Nonnull String description, @Nonnull ArgWrapper<W, D> wrapper)
@Nonnull
public <D> OptionalArg<List<D>> withListOptionalArg(@Nonnull String name, @Nonnull String description, @Nonnull ArgumentType<D> argType)

Optional arguments with a fallback value when not provided.

@Nonnull
public <D> DefaultArg<D> withDefaultArg(String name, String description, ArgumentType<D> argType, @Nullable D defaultValue, String defaultValueDescription)
public <W extends WrappedArg<D>, D> W withDefaultArg(@Nonnull String name, @Nonnull String description, @Nonnull ArgWrapper<W, D> wrapper, D defaultValue, @Nonnull String defaultValueDescription)
@Nonnull
public <D> DefaultArg<List<D>> withListDefaultArg(@Nonnull String name, @Nonnull String description, @Nonnull ArgumentType<D> argType, List<D> defaultValue, @Nonnull String defaultValueDescription)

Boolean flags prefixed with --.

@Nonnull
public FlagArg withFlagArg(@Nonnull String name, @Nonnull String description)
public void addSubCommand(@Nonnull AbstractCommand command)

Adds a named subcommand. The subcommand’s name becomes the first argument token that routes to it. Each subcommand can only have one parent. Throws IllegalStateException if the command has already been registered.

public void addUsageVariant(@Nonnull AbstractCommand command)

Adds a usage variant — an alternative argument pattern for the same command name. Variants are distinguished by their number of required parameters. The variant command must use the description-only constructor (no name). Example: /kill (self) vs /kill <player> (other).

public void addAliases(@Nonnull String... aliases)

Adds alternative names for this command. Aliases are lowercased. Cannot add aliases after registration or to unnamed commands.

public void requirePermission(@Nonnull String permission)

Sets an explicit permission string. If not called, permissions are auto-generated from the command hierarchy (see below).

protected void setPermissionGroups(@Nonnull String... groups)

Restricts the command to specific permission groups.

protected void setPermissionGroup(@Nullable GameMode gameMode)

Restricts the command to a specific game mode’s permission group.

public boolean hasPermission(@Nonnull CommandSender sender)

Checks whether the sender has permission to execute this command. Recurses up the parent command chain — all ancestors must also pass.

When a command’s owner is set (via setOwner()), permissions are auto-generated if not explicitly set:

  • Plugin commands: {plugin.getBasePermission()}.command.{commandName}
  • Built-in commands: hytale.system.command.{commandName}
  • Subcommands: {parentPermission}.{subcommandName}
public void setOwner(@Nonnull CommandOwner owner)

Sets the command owner (either a PluginBase or CommandManager). Propagates to all subcommands and variants. Triggers auto-permission generation.

protected void setUnavailableInSingleplayer(boolean unavailableInSingleplayer)

Marks the command as unavailable in singleplayer mode.

public void setAllowsExtraArguments(boolean allowsExtraArguments)

Allows extra tokens beyond declared arguments (useful for commands that accept freeform input).

@Nullable
public String getName()
@Nonnull
public Set<String> getAliases()
public String getDescription()
@Nullable
public String getPermission()
@Nullable
public String getFullyQualifiedName()

Returns the full command path (e.g., "entity clone" for a subcommand).

@Nonnull
public Map<String, AbstractCommand> getSubCommands()
@Nonnull
public List<RequiredArg<?>> getRequiredArguments()
public boolean isVariant()

Returns true if this command has no name (is a usage variant).

AbstractCommand
├── AbstractAsyncCommand (async base: executeAsync() -> CompletableFuture<Void>)
│ ├── AbstractPlayerCommand (player-only: resolves sender to PlayerRef, Ref, Store, World)
│ └── AbstractCommandCollection (subcommand group: shows usage listing)
├── CommandBase (sync base: executeSync() -> void)
└── (direct subclasses)
public class MyCommand extends CommandBase {
private final RequiredArg<String> nameArg;
private final DefaultArg<Integer> countArg;
public MyCommand() {
super("mycommand", "server.commands.mycommand.description");
this.nameArg = withRequiredArg("name", "server.commands.mycommand.name", ArgumentType.STRING);
this.countArg = withDefaultArg("count", "server.commands.mycommand.count", ArgumentType.INTEGER, 1, "1");
}
@Override
protected void executeSync(@Nonnull CommandContext context) {
String name = context.get(nameArg);
int count = context.get(countArg);
context.sendMessage(Message.raw("Hello " + name + " x" + count));
}
}