https://github.com/tbluef/bluecommands
Generic but powerful annotation based CommandAPI
https://github.com/tbluef/bluecommands
annotations commands
Last synced: 3 months ago
JSON representation
Generic but powerful annotation based CommandAPI
- Host: GitHub
- URL: https://github.com/tbluef/bluecommands
- Owner: TBlueF
- License: mit
- Created: 2023-09-03T11:47:59.000Z (almost 3 years ago)
- Default Branch: master
- Last Pushed: 2025-02-26T13:48:43.000Z (over 1 year ago)
- Last Synced: 2025-10-29T01:48:59.658Z (8 months ago)
- Topics: annotations, commands
- Language: Java
- Homepage:
- Size: 168 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
## Usage
### Adding to project
```kotlin
repositories {
maven ( "https://repo.bluecolored.de/releases" )
}
dependencies {
implementation("de.bluecolored:bluecommands-core:1.2.0")
implementation("de.bluecolored:bluecommands-brigadier:1.2.0") // Optional
}
```
### Creating and executing Commands
```java
class MyCommands {
private Command commands;
public MyCommands() {
BlueCommands commandFactory = new BlueCommands<>();
this.commands = commandFactory.createCommand(this);
}
public void runCommand(CommandSender sender, String input) {
// parse the command
ParseResult parseResult = this.commands.parse(sender, new InputReader(input));
// get the match with the highest priority
ParseMatch match = parseResult.getMatches().stream()
.max(Comparator.comparing(ParseMatch::getPriority))
.orElse(null);
if (match == null) {
// handle no command found
return;
}
// execute the command (the result is whatever the command-method returns)
Object executionResult = match.execute();
}
@Command("foo [optionalArg2]")
public void fooCommand(
CommandSender sender,
@Argument("arg1") String stringArgument,
@Argument("optionalArg2") Double optionalDoubleArgument
) {
// do something
}
}
```
### Creating custom argument-parsers
Example here for creating an argument parser which accepts online Bukkit-Players:
```java
public class PlayerArgument extends SimpleArgumentParser {
public PlayerArgument() {
super(false, false);
}
@Override
public Player parse(S context, String name) throws CommandParseException {
Player player = Bukkit.getPlayerExact(name);
if (player == null) {
throw new CommandParseException("'" + name + "' is not an online player!");
}
return player;
}
@Override
public List suggest(S context, InputReader input) {
return Bukkit.getOnlinePlayers().stream()
.map(player -> (Suggestion) new SimpleSuggestion(player.getName()))
.toList();
}
}
```
Then register the new Parser before creating your commands:
```java
BlueCommands commandFactory = new BlueCommands<>();
// register the custom argument-parser
commandFactory.setArgumentParserForArgumentType(Player.class, new PlayerArgument<>());
this.commands = commandFactory.createCommand(this);
```
### Context-Resolver
With context-resolvers you can add other parameters to your command-method that should be resolved from the context.
```java
BlueCommands commandFactory = new BlueCommands<>();
commandFactory.setContextResolverForType(Server.class, CommandSender::getServer);
```
Then in a command you can add a `Server` parameter which will be filled based on the current command-context:
```java
@Command("foo [optionalArg2]")
public void fooCommand(
Server server,
@Argument("arg1") String stringArgument,
@Argument("optionalArg2") Double optionalDoubleArgument
) {
// ...
}
```
### Context-Predicates (e.g. Permissions)
Here an example to create a Permission annotation and use it to validate commands for a context.
Create the new Annotation:
```java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Permission {
String value();
}
```
Label your commands with this new annotation:
```java
@Command("foo [optionalArg2]")
@Permission("foo.bar.bazz")
public void fooCommand(
CommandSender sender,
@Argument("arg1") String stringArgument,
@Argument("optionalArg2") Double optionalDoubleArgument
) {
// ...
}
```
Register a context-predicate for this Annotation:
```java
BlueCommands commandFactory = new BlueCommands<>();
commandFactory.setAnnotationContextPredicate(Permission.class, (permission, commandSender) -> {
return commandSender.hasPermission(permission.value());
});
```
When the annotation is present, the command will now only be available if the registered predicate returns `true`.
### Merging commands
You can merge multiple commands into one. E.g. if you have multiple objects that hold command-methods:
```java
BlueCommands commandFactory = new BlueCommands<>();
Command root = new Command<>();
root.tryMerge(commandFactory.createCommand(object1));
root.tryMerge(commandFactory.createCommand(object2));
root.tryMerge(commandFactory.createCommand(object3));
```