Init
This commit is contained in:
224
content/core-concepts/commands/subcommands.fr.md
Normal file
224
content/core-concepts/commands/subcommands.fr.md
Normal file
@@ -0,0 +1,224 @@
|
||||
---
|
||||
title: Subcommands
|
||||
type: docs
|
||||
weight: 3
|
||||
---
|
||||
|
||||
Subcommands allow you to create hierarchical command structures, organizing related functionality under a single parent command.
|
||||
|
||||
## Creating Subcommands
|
||||
|
||||
### Basic Structure
|
||||
|
||||
```java
|
||||
public class AdminCommand extends AbstractCommand {
|
||||
|
||||
public AdminCommand() {
|
||||
super("admin", "Administration commands");
|
||||
|
||||
// Add subcommands
|
||||
addSubCommand(new KickSubCommand());
|
||||
addSubCommand(new BanSubCommand());
|
||||
addSubCommand(new MuteSubCommand());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Void> execute(CommandContext context) {
|
||||
// This runs when no subcommand is specified
|
||||
context.sender().sendMessage(Message.raw("Usage: /admin <kick|ban|mute>"));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Subcommand Implementation
|
||||
|
||||
```java
|
||||
public class KickSubCommand extends AbstractCommand {
|
||||
|
||||
private final RequiredArg<PlayerRef> playerArg;
|
||||
private final OptionalArg<String> reasonArg;
|
||||
|
||||
public KickSubCommand() {
|
||||
super("kick", "Kick a player from the server");
|
||||
|
||||
playerArg = withRequiredArg("player", "Player to kick", ArgTypes.PLAYER_REF);
|
||||
reasonArg = withOptionalArg("reason", "Kick reason", ArgTypes.STRING);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Void> execute(CommandContext context) {
|
||||
PlayerRef target = context.get(playerArg);
|
||||
String reason = context.get(reasonArg);
|
||||
|
||||
// Check if player is online via ECS reference
|
||||
Ref<EntityStore> ref = target.getReference();
|
||||
if (ref != null && ref.isValid()) {
|
||||
// Disconnect via PacketHandler
|
||||
String kickReason = reason != null ? reason : "Kicked by admin";
|
||||
target.getPacketHandler().disconnect(kickReason);
|
||||
context.sendMessage(Message.raw("Kicked " + target.getUsername()));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Usage: `/admin kick player123 --reason "Breaking rules"`
|
||||
|
||||
## Command Collections
|
||||
|
||||
For commands that only contain subcommands (no direct execution), extend `AbstractCommandCollection`:
|
||||
|
||||
```java
|
||||
public class ManageCommand extends AbstractCommandCollection {
|
||||
|
||||
public ManageCommand() {
|
||||
super("manage", "Management commands");
|
||||
|
||||
addSubCommand(new ManageUsersCommand());
|
||||
addSubCommand(new ManageWorldsCommand());
|
||||
addSubCommand(new ManagePluginsCommand());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
With `AbstractCommandCollection`, running `/manage` without a subcommand will show available subcommands automatically.
|
||||
|
||||
## Nested Subcommands
|
||||
|
||||
Subcommands can have their own subcommands:
|
||||
|
||||
```java
|
||||
public class ManageUsersCommand extends AbstractCommand {
|
||||
|
||||
public ManageUsersCommand() {
|
||||
super("users", "User management");
|
||||
|
||||
addSubCommand(new ListUsersCommand()); // /manage users list
|
||||
addSubCommand(new AddUserCommand()); // /manage users add
|
||||
addSubCommand(new RemoveUserCommand()); // /manage users remove
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Void> execute(CommandContext context) {
|
||||
// Show usage for /manage users
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Subcommand Aliases
|
||||
|
||||
Subcommands can have aliases just like regular commands:
|
||||
|
||||
```java
|
||||
public class TeleportCommand extends AbstractCommand {
|
||||
|
||||
public TeleportCommand() {
|
||||
super("teleport", "Teleport commands");
|
||||
addAliases("tp");
|
||||
|
||||
addSubCommand(new TeleportHereCommand());
|
||||
addSubCommand(new TeleportAllCommand());
|
||||
}
|
||||
}
|
||||
|
||||
public class TeleportHereCommand extends AbstractCommand {
|
||||
|
||||
public TeleportHereCommand() {
|
||||
super("here", "Teleport player to you");
|
||||
addAliases("h", "tome");
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Now players can use:
|
||||
- `/teleport here player1`
|
||||
- `/tp here player1`
|
||||
- `/tp h player1`
|
||||
- `/tp tome player1`
|
||||
|
||||
## Command Variants
|
||||
|
||||
Variants allow the same command to accept different argument patterns:
|
||||
|
||||
```java
|
||||
public class TpCommand extends AbstractCommand {
|
||||
|
||||
private final RequiredArg<PlayerRef> targetArg;
|
||||
|
||||
public TpCommand() {
|
||||
super("tp", "Teleport command");
|
||||
|
||||
// Main variant: /tp <player>
|
||||
targetArg = withRequiredArg("target", "Player to teleport to", ArgTypes.PLAYER_REF);
|
||||
|
||||
// Add variant: /tp <player> <destination>
|
||||
addUsageVariant(new TpToPlayerVariant());
|
||||
|
||||
// Add variant: /tp <x> <y> <z>
|
||||
addUsageVariant(new TpToPositionVariant());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Void> execute(CommandContext context) {
|
||||
// Teleport sender to target player
|
||||
PlayerRef target = context.get(targetArg);
|
||||
// ...
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Variant Implementation
|
||||
|
||||
```java
|
||||
public class TpToPlayerVariant extends AbstractCommand {
|
||||
|
||||
private final RequiredArg<PlayerRef> playerArg;
|
||||
private final RequiredArg<PlayerRef> destinationArg;
|
||||
|
||||
public TpToPlayerVariant() {
|
||||
// No name for variants - use description only
|
||||
super("Teleport one player to another");
|
||||
|
||||
playerArg = withRequiredArg("player", "Player to teleport", ArgTypes.PLAYER_REF);
|
||||
destinationArg = withRequiredArg("destination", "Destination player", ArgTypes.PLAYER_REF);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Void> execute(CommandContext context) {
|
||||
PlayerRef player = context.get(playerArg);
|
||||
PlayerRef destination = context.get(destinationArg);
|
||||
// Teleport player to destination
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{< callout type="info" >}}
|
||||
Variants are distinguished by the number of required parameters. Each variant must have a different number of required arguments.
|
||||
{{< /callout >}}
|
||||
|
||||
## Permission Inheritance
|
||||
|
||||
Subcommand permissions are automatically built from the parent:
|
||||
|
||||
```
|
||||
/admin -> myplugin.command.admin
|
||||
/admin kick -> myplugin.command.admin.kick
|
||||
/admin ban -> myplugin.command.admin.ban
|
||||
```
|
||||
|
||||
You can also set custom permissions:
|
||||
|
||||
```java
|
||||
public KickSubCommand() {
|
||||
super("kick", "Kick a player");
|
||||
requirePermission("myplugin.admin.kick");
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user