This commit is contained in:
2026-01-20 20:33:59 +01:00
commit b16a40e431
583 changed files with 87339 additions and 0 deletions

View File

@@ -0,0 +1,272 @@
---
title: Command Context
type: docs
weight: 4
---
The `CommandContext` provides access to command execution information, including the sender, parsed arguments, and the original input string.
## Accessing the Context
The context is passed to your `execute()` method:
```java
@Override
protected CompletableFuture<Void> execute(CommandContext context) {
// Use context here
return null;
}
```
## Command Sender
Get the entity or console that executed the command:
```java
CommandSender sender = context.sender();
// Send messages (must use Message class)
sender.sendMessage(Message.raw("Hello!"));
sender.sendMessage(Message.translation("my.translation.key"));
// Check permissions
if (sender.hasPermission("myplugin.admin")) {
// ...
}
```
### Checking Sender Type
```java
if (context.sender() instanceof Player) {
Player player = (Player) context.sender();
// Player-specific logic
} else {
// Console or other sender
context.sender().sendMessage("This command requires a player!");
}
```
## Getting Arguments
### Required Arguments
```java
private final RequiredArg<PlayerRef> playerArg;
private final RequiredArg<Integer> countArg;
// In execute():
PlayerRef player = context.get(playerArg); // Never null for required args
int count = context.get(countArg); // Never null for required args
```
### Optional Arguments
```java
private final OptionalArg<String> reasonArg;
// Get value (may be null if not provided)
String reason = context.get(reasonArg);
// Check if provided before using
if (context.provided(reasonArg)) {
String reason = context.get(reasonArg);
}
```
### Default Arguments
```java
private final DefaultArg<Integer> countArg; // Default: 1
// Always returns a value (never null)
int count = context.get(countArg); // Returns default if not specified
```
### Flag Arguments
```java
private final FlagArg silentFlag;
// Check if flag was provided
boolean isSilent = context.provided(silentFlag);
```
## Input String
Access the original command input:
```java
String input = context.getInputString();
// For "/give player123 sword 5" -> "give player123 sword 5"
```
## The Command
Access the command being executed:
```java
AbstractCommand command = context.getCalledCommand();
String commandName = command.getName();
String fullName = command.getFullyQualifiedName(); // e.g., "admin kick"
```
## Argument Type Fallback Behavior
Some argument types have special processing with fallback behavior. This is handled by the argument type's `processedGet()` method:
### PLAYER_REF Fallback
When using `PLAYER_REF` with optional arguments:
- If argument is not provided and sender is a player, the argument type can return the sender's PlayerRef
```java
// Note: This fallback behavior is in the argument type, not CommandContext
private final OptionalArg<PlayerRef> targetArg;
@Override
protected CompletableFuture<Void> execute(CommandContext context) {
PlayerRef target = context.get(targetArg);
// Manual fallback if null
if (target == null && context.sender() instanceof Player player) {
target = player.getPlayerRef();
}
// ...
}
```
### World Argument Fallback
When using `WORLD` with optional arguments:
- If not specified and sender is player, returns player's world
- If only one world exists, returns that world
```java
private final OptionalArg<World> worldArg;
@Override
protected CompletableFuture<Void> execute(CommandContext context) {
World world = context.get(worldArg);
// Manual fallback if null
if (world == null && context.sender() instanceof Player player) {
world = player.getWorld();
}
// ...
}
```
## Error Handling
Commands can throw exceptions for error cases:
```java
@Override
protected CompletableFuture<Void> execute(CommandContext context) {
PlayerRef playerRef = context.get(playerArg);
// Check if player is online via ECS reference
Ref<EntityStore> ref = playerRef.getReference();
if (ref == null || !ref.isValid()) {
throw new GeneralCommandException(
Message.translation("error.player.offline")
.param("player", playerRef.getUsername())
);
}
// Continue execution with valid reference
return null;
}
```
## Asynchronous Commands
Return a `CompletableFuture` for async operations:
```java
@Override
protected CompletableFuture<Void> execute(CommandContext context) {
if (!(context.sender() instanceof Player player)) {
return null;
}
PlayerRef playerRef = player.getPlayerRef(); // Note: deprecated
World world = player.getWorld();
return CompletableFuture.runAsync(() -> {
// Async operation (e.g., database query)
// PlayerData data = database.loadData(playerRef.getUuid());
// Return to world thread for game logic
world.execute(() -> {
Ref<EntityStore> ref = playerRef.getReference();
if (ref != null && ref.isValid()) {
// applyData(ref, data);
playerRef.sendMessage(Message.raw("Data loaded!"));
}
});
});
}
```
## Complete Example
```java
public class GiveCommand extends AbstractCommand {
private final RequiredArg<Item> itemArg;
private final OptionalArg<PlayerRef> targetArg;
private final DefaultArg<Integer> countArg;
private final FlagArg silentFlag;
public GiveCommand() {
super("give", "Give items to a player");
itemArg = withRequiredArg("item", "Item to give", ArgTypes.ITEM_ASSET);
targetArg = withOptionalArg("target", "Target player", ArgTypes.PLAYER_REF);
countArg = withDefaultArg("count", "Amount", ArgTypes.INTEGER, 1, "1");
silentFlag = withFlagArg("silent", "Don't broadcast");
}
@Override
protected CompletableFuture<Void> execute(CommandContext context) {
// Get arguments
Item item = context.get(itemArg);
int count = context.get(countArg); // Uses default if not specified
boolean silent = context.provided(silentFlag);
// Get target with fallback to sender
PlayerRef targetRef = context.get(targetArg);
if (targetRef == null && context.sender() instanceof Player senderPlayer) {
targetRef = senderPlayer.getPlayerRef(); // Note: deprecated
}
if (targetRef == null) {
throw new GeneralCommandException(
Message.raw("Must specify a target player!")
);
}
// Validate target is online via ECS reference
Ref<EntityStore> ref = targetRef.getReference();
if (ref == null || !ref.isValid()) {
throw new GeneralCommandException(
Message.raw("Player is not online!")
);
}
// Execute - give item to player via ECS
// ...
// Feedback
if (!silent) {
context.sendMessage(Message.raw(
"Gave " + count + "x " + item.getId() + " to " + targetRef.getUsername()
));
}
return null;
}
}
```