Commands
Commands help user or administrator to interact with the proxy and plugins.
Defining a command
Section titled “Defining a command”Inject ICommandService
service to begin working with commands.
Commands are registered with Register
method in Mojang Brigadier-like style.
class MyService(ICommandService commands){ public void RegisterCommands() { commands.Register(builder => builder .Literal("hello") .Executes(HelloAsync)); }
private async ValueTask<int> HelloAsync(CommandContext context, CancellationToken cancellationToken) { // Commands are triggered by console, plugins, players, or anything if (context.Source is IPlayer player) { await player.SendChatMessageAsync("Hello, World!", cancellationToken); } else { logger.LogInformation("Hello, World!"); }
return 0; }}
Manually triggering a command
Section titled “Manually triggering a command”You can trigger a command execution manually with ExecuteAsync
method.
class MyService(ICommandService commands) : ICommandSource{ public async ValueTask TriggerCommandAsync(CancellationToken cancellationToken) { ICommandSource commandSource = this; string command = "hello";
await commands.ExecuteAsync(commandSource, command, cancellationToken); }}
Command suggestions
Section titled “Command suggestions”You can request suggestions for a command with CompleteAsync method.
class MyService(ICommandService commands) : ICommandSource{ public async ValueTask SuggestCommandAsync(CancellationToken cancellationToken) { ICommandSource commandSource = this; string command = "hel";
var variants = await commands.CompleteAsync(command, commandSource, cancellationToken); // variants value is string[] { "hello" } }}
Command arguments
Section titled “Command arguments”You can define optional command arguments with Argument
method.
class MyService(ICommandService commands){ public void RegisterCommands() { commands.Register(builder => builder .Literal("hello") .Then(builder => builder .Argument("name", Arguments.String()) .Executes(HelloAsync))); }
private async ValueTask<int> HelloAsync(CommandContext context, CancellationToken cancellationToken) { // Arguments are optional if (!context.TryGetArgument<string>("name", out var name)) name = "World";
if (context.Source is IPlayer player) { await player.SendChatMessageAsync($"Hello, {name}!", cancellationToken); } else { logger.LogInformation($"Hello, {name}!"); }
return 0; }}
Complex Command Example
Section titled “Complex Command Example”class MyService(ICommandService commands){ // Register a `slot` command to change player held item slot public void RegisterCommands() { commands.Register(builder => builder .Literal("slot") .Executes(SlotCommandAsync) .Then(builder => builder .Argument("index", Arguments.Integer()) .Executes(SlotCommandAsync))); }
private async ValueTask<int> SlotCommandAsync(CommandContext context, CancellationToken cancellationToken) { if (context.Source is not IPlayer player) { logger.LogInformation("This command can be executed only by player"); return 1; }
if (!context.TryGetArgument<int>("index", out var slot)) { // If slot argument is not provided, we will use random one slot = Random.Shared.Next(0, 9); }
await player.SendChatMessageAsync($"Your held item slot is changed to {slot}", cancellationToken); await player.SendPacketAsync(new SetHeldItemClientboundPacket { Slot = slot }, cancellationToken); return 0; }}