KenCommandAPI/README.md
2026-08-02 21:23:36 +02:00

81 lines
No EOL
2.7 KiB
Markdown

## Limitations & Bugs
- argument's can't require specific permissions.
- errors are always formatted using the RootLiteral's MessageStyle
## Design
Commands are trees of Literals.
Literals can have arguments.
Literals can also have Executors.
arguments can be optional by giving them a default value.
arguments can have suggestions.
`/feed <user>`:
- feed is the root literal
- `<user>` is an argument: it's value is a User Object
To allow the use of `/feed` without giving a user's name, i.e. to make the argument optional, we need to assign the
user-argument a default value.
## An example command
Let's say we want to make a command that allows seeing how many coins another User has.
If we don't specify a user, it should instead show the coins the sender has.
## As a tree
Visualized as a tree, we have a Node/Literal `coins` with an alias `balance` with an optional argument called `user`.
To make an argument optional, it must have a default value.
```text
literal:coins/balance
- has argument:user
- has executor:getCoins
```
## As code
```java
/**
* Show the amount coins a user has.
* If no user is given, it should show the amount the sender of the command has.
*/
@NoArgsConstructor(access = AccessLevel.NONE)
public class CoinsCommand {
@Getter
private final Literal<User> rootLiteral;
private final CommandArgumentSpec<User, User> userArg;
public CoinsCommand() {
userArg = CommandArgumentSpec.builder("user", new UserArgumentType<User>())
.withRequirement(p -> !p.hasPermission("economy.immune.getcoins"),
"you can't see that player's balance")
.withDefaultValue(CommandContext::getSender)
.build();
rootLiteral = Literal.<User>builder("coins", "balance")
.withStyle(MessageStyle.PLAIN)
.withPermission("economy.command.coins")
.withArgument(userArg)
.withSyncExecutor(this::getCoins)
.build();
}
private Result<Object, String> getCoins(CommandContext<User> ctx) {
var player = ctx.getArg(userArg);
ctx.getSender().sendMessage(player.getName() + " has " + player.getCoins() + " coins");
return Results.success(new Object());
}
}
```
If we wanted to report an error, we could do for example `return Results.failure("That user doesn't exist")`.
However, if we have a smart UserArgumentType, it automatically makes sure that the user exists.
Additionally, we can also a Requirement in the CommandArgumentSpec.
The registration of the command is platform-dependant. Typically, a class called CommandAPI can be used.
```java
CommandAPI api = new CommandAPI();
register(new CoinsCommand().getRootLiteral());
```