265 lines
6.7 KiB
Markdown
265 lines
6.7 KiB
Markdown
---
|
|
title: Creating Commands
|
|
type: docs
|
|
weight: 1
|
|
---
|
|
|
|
Commands in Hytale are created by extending the `AbstractCommand` class. This page covers the basics of creating and registering commands.
|
|
|
|
## Basic Command Structure
|
|
|
|
```java
|
|
import com.hypixel.hytale.server.core.command.system.AbstractCommand;
|
|
import com.hypixel.hytale.server.core.command.system.CommandContext;
|
|
import com.hypixel.hytale.server.core.Message;
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
public class HelloCommand extends AbstractCommand {
|
|
|
|
public HelloCommand() {
|
|
super("hello", "Sends a greeting message");
|
|
}
|
|
|
|
@Override
|
|
protected CompletableFuture<Void> execute(CommandContext context) {
|
|
context.sendMessage(Message.raw("Hello, World!"));
|
|
return null;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Constructors
|
|
|
|
`AbstractCommand` provides several constructors:
|
|
|
|
```java
|
|
// Name and description
|
|
protected AbstractCommand(String name, String description)
|
|
|
|
// Name, description, and requires confirmation flag
|
|
protected AbstractCommand(String name, String description, boolean requiresConfirmation)
|
|
|
|
// Description only (for variant commands)
|
|
protected AbstractCommand(String description)
|
|
```
|
|
|
|
## Registering Commands
|
|
|
|
Register commands in your plugin's `start()` method:
|
|
|
|
```java
|
|
@Override
|
|
public void start() {
|
|
getCommandRegistry().registerCommand(new HelloCommand());
|
|
}
|
|
```
|
|
|
|
## Adding Aliases
|
|
|
|
Commands can have multiple names:
|
|
|
|
```java
|
|
public class TeleportCommand extends AbstractCommand {
|
|
|
|
public TeleportCommand() {
|
|
super("teleport", "Teleport to a location");
|
|
addAliases("tp", "warp");
|
|
}
|
|
|
|
// ...
|
|
}
|
|
```
|
|
|
|
Players can now use `/teleport`, `/tp`, or `/warp`.
|
|
|
|
## Command with Arguments
|
|
|
|
Add required arguments using `withRequiredArg`:
|
|
|
|
```java
|
|
import com.hypixel.hytale.server.core.command.system.AbstractCommand;
|
|
import com.hypixel.hytale.server.core.command.system.CommandContext;
|
|
import com.hypixel.hytale.server.core.command.system.arguments.system.RequiredArg;
|
|
import com.hypixel.hytale.server.core.command.system.arguments.types.ArgTypes;
|
|
// For ECS operations: import com.hypixel.hytale.component.Ref;
|
|
// For ECS operations: import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
|
import com.hypixel.hytale.server.core.universe.PlayerRef;
|
|
import com.hypixel.hytale.server.core.asset.type.item.config.Item;
|
|
import com.hypixel.hytale.server.core.Message;
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
public class GiveCommand extends AbstractCommand {
|
|
|
|
private final RequiredArg<PlayerRef> targetArg;
|
|
private final RequiredArg<Item> itemArg;
|
|
|
|
public GiveCommand() {
|
|
super("give", "Give an item to a player");
|
|
|
|
targetArg = withRequiredArg("player", "Target player", ArgTypes.PLAYER_REF);
|
|
itemArg = withRequiredArg("item", "Item to give", ArgTypes.ITEM_ASSET);
|
|
}
|
|
|
|
@Override
|
|
protected CompletableFuture<Void> execute(CommandContext context) {
|
|
PlayerRef targetRef = context.get(targetArg);
|
|
Item item = context.get(itemArg);
|
|
|
|
// PlayerRef provides direct access to player info
|
|
String username = targetRef.getUsername();
|
|
|
|
// For ECS operations, use getReference() to access the EntityStore
|
|
// Ref<EntityStore> entityRef = targetRef.getReference();
|
|
|
|
// Give item to player...
|
|
context.sendMessage(Message.raw("Gave item to " + username));
|
|
|
|
return null;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Optional Arguments
|
|
|
|
Add optional arguments that don't need to be specified:
|
|
|
|
```java
|
|
private final OptionalArg<Integer> countArg;
|
|
|
|
public GiveCommand() {
|
|
super("give", "Give items to a player");
|
|
|
|
targetArg = withRequiredArg("player", "Target player", ArgTypes.PLAYER_REF);
|
|
itemArg = withRequiredArg("item", "Item to give", ArgTypes.ITEM_ASSET);
|
|
countArg = withOptionalArg("count", "Number of items", ArgTypes.INTEGER);
|
|
}
|
|
|
|
@Override
|
|
protected CompletableFuture<Void> execute(CommandContext context) {
|
|
PlayerRef targetRef = context.get(targetArg);
|
|
Item item = context.get(itemArg);
|
|
Integer count = context.get(countArg); // May be null
|
|
|
|
int amount = count != null ? count : 1;
|
|
// Give items to player...
|
|
|
|
return null;
|
|
}
|
|
```
|
|
|
|
Usage: `/give player123 iron_sword` or `/give player123 iron_sword --count 5`
|
|
|
|
## Default Arguments
|
|
|
|
Arguments with default values:
|
|
|
|
```java
|
|
private final DefaultArg<Integer> countArg;
|
|
|
|
public GiveCommand() {
|
|
super("give", "Give items to a player");
|
|
|
|
countArg = withDefaultArg("count", "Number of items",
|
|
ArgTypes.INTEGER, 1, "defaults to 1");
|
|
}
|
|
|
|
@Override
|
|
protected CompletableFuture<Void> execute(CommandContext context) {
|
|
int count = context.get(countArg); // Never null, uses default
|
|
// ...
|
|
}
|
|
```
|
|
|
|
## Flag Arguments
|
|
|
|
Boolean flags that can be toggled:
|
|
|
|
```java
|
|
private final FlagArg silentFlag;
|
|
|
|
public BroadcastCommand() {
|
|
super("broadcast", "Send a message to all players");
|
|
|
|
silentFlag = withFlagArg("silent", "Don't show sender name");
|
|
}
|
|
|
|
@Override
|
|
protected CompletableFuture<Void> execute(CommandContext context) {
|
|
boolean silent = context.provided(silentFlag);
|
|
// ...
|
|
}
|
|
```
|
|
|
|
Usage: `/broadcast Hello everyone! --silent`
|
|
|
|
## List Arguments
|
|
|
|
For arguments that accept multiple values:
|
|
|
|
```java
|
|
private final RequiredArg<List<String>> playersArg;
|
|
|
|
public KickAllCommand() {
|
|
super("kickall", "Kick multiple players");
|
|
|
|
playersArg = withListRequiredArg("players", "Players to kick", ArgTypes.STRING);
|
|
}
|
|
|
|
@Override
|
|
protected CompletableFuture<Void> execute(CommandContext context) {
|
|
List<String> players = context.get(playersArg);
|
|
for (String player : players) {
|
|
// Kick each player
|
|
}
|
|
return null;
|
|
}
|
|
```
|
|
|
|
Usage: `/kickall player1 player2 player3`
|
|
|
|
Available list argument methods:
|
|
- `withListRequiredArg(name, description, argType)` - Required list
|
|
- `withListOptionalArg(name, description, argType)` - Optional list
|
|
- `withListDefaultArg(name, description, argType, defaultValue, defaultDesc)` - List with default
|
|
|
|
## Requiring Confirmation
|
|
|
|
For dangerous commands, require explicit confirmation:
|
|
|
|
```java
|
|
public class ResetCommand extends AbstractCommand {
|
|
|
|
public ResetCommand() {
|
|
super("reset", "Reset all player data", true); // requiresConfirmation = true
|
|
}
|
|
|
|
@Override
|
|
protected CompletableFuture<Void> execute(CommandContext context) {
|
|
// This only runs if --confirm was provided
|
|
resetAllData();
|
|
return null;
|
|
}
|
|
}
|
|
```
|
|
|
|
Usage: `/reset --confirm`
|
|
|
|
## Permissions
|
|
|
|
Commands automatically generate permissions based on your plugin name:
|
|
|
|
```
|
|
{group}.{plugin}.command.{commandname}
|
|
```
|
|
|
|
For example: `com.example.myplugin.command.give`
|
|
|
|
You can also set a custom permission:
|
|
|
|
```java
|
|
public GiveCommand() {
|
|
super("give", "Give items");
|
|
requirePermission("myplugin.admin.give");
|
|
}
|
|
```
|