Commands

Overview

If you're familar with Spigot's CommandExecutor or @CommandHandler approaches, BulletMC offers a more flexible, lower level way of commands powered by Brigader, the same command parsing library used by vanilla minecraft.

BulletMC wraps Brigadier with custom tooling to handle tab suggestions, error codes, etc.


Registering commands

In this example we're going to make a sample /ping command. If your plugin ever needs to add custom commands, similarly to registering events, you'll override the registerCommands()function. Other than that, everything from brigadier is the same. The beauty with this system is almost all brigadier commands will be a drop in replacement for bullet commands. Here is an example for our /ping command.

override fun registerCommands() {
    dispatcher.register(
        literal<Player>("ping")
            .executes { ctx ->
                ctx.source.sendMessage(Component.text("pong!"))
                CommandCodes.SUCCESS.id
            }
    )
}

Now when a player executes /ping, the server will send the player a message of pong! BulletMC only supports sending messages in the form of components to allow for more modularity, it can also support mini message.

And thats it, you don't have to manually register the dispatcher or add anything in a .yml or .json file, BulletMC automatically loads commands from all enabled plugins during server startup.

How BulletMC commands work

Behind the scenes, BulletMC uses the full flexibility of Brigadier while maintaining client compatibility. At the core of the commands, lies a CommandManager. This command manager is responsible for the registration of commands, as well as tab suggestions. Tab complete for commands in BulletMC comes by default, read the chapter on tab complete for more information.

CommandManager.dispatcher: Main CommandDispatcher<Player> used across the server to register all of the commands

CommandManager.registerCommands(): Registers all built-in commands (eg, /say, /gamemode, etc). This probably should never be called unless you have a very specific use case.

CommandManager.buildCommandGraphFromDispatcher(): Generates a compressed representation of the command tree for clients when sending tab complete suggestions


Defining a command

Here's a simple example using the built in /say command as reference

class SayCommand {
    fun register(dispatcher: CommandDispatcher<Player>) {
        dispatcher.register(
            literal<Player>("say")
                .then(
                    argument<Player, String>("message", greedyString())
                        .executes { context ->
                            val message = StringArgumentType.getString(context, "message")
                            
                            if(message.isEmpty() || message.length > 255) {
                                context.source.sendMessage(Component.text("Invalid message").color(NamedTextColor.RED))
                                return@executes CommandCodes.ILLEGAL_ARGUMENT.id
                            }

                            Bullet.broadcast(message)
                            CommandCodes.SUCCESS.id
                        }
                )
        )
    }
}

Notice how for the return status, BulletMC uses CommandCodes instead of numbers, this is primarily the way you should return the codes, as it makes it a lot more clean.

Available Argument Types

Type
Kotlin Usage
Example

String

StringArgumentType.word() / greedyString()

"Hello", can also support player names and compare it with Bullet.players

Integer

IntegerArgumentType.integer(min, max)

42

Double

DoubleArgumentType.doubleArg(min, max)

3.14

Boolean

BooleanArgumentType.bool()

true/false

Tab completion

Tab suggestions are handled automatically if you register an ArgumentCommandNode with .suggests(...). BulletMC marks such nodes with the minecraft:ask_server suggestion provider, which the vanilla client understands.

Command Result Codes

Rather than returning 0 or 1, BulletMC uses meaningful CommandCodes Each code corresponds to a known integer and helps strucutre plugin command output consistently


Built-in commands

BulletMC includes a few built in commands you can learn from or use in your server in com.aznos.commands.commands . However it is intintial that not many built in commands are provided to keep the server as lightweight as possible.

Command
Arguments
Description

/say

String - message

Broadcasts a message to all clients connected, supports mini message

/settime

Integer - time

Sets the time of the world, 0-24000. 0 is 6AM

/help

(Optional) Integer - page

Displays all available commands on the server, maximum of 15 commands per page

/gamemode

String, Integer - gamemode

Sets your gamemode to either survival, creative, adventure, or spectator

/tp

String - location String - target String - location

Either optionally can teleport you or another player to a specific location or another player

/stop

Integer - time till shutdown

Shuts down the server and broadcasts a warning, by default the server will shut down after 60 seconds pass

/performance

N/A

Shows the overall performance of the server

/setweather

String - weather

0 -> Clear 1 -> Rain

/msg

String - player String - message

Sends a private message to a specific player

/difficulty

String - difficulty

Sets the difficulty of the server

/spawn

String - entity

Spawns in a non-living or living entity

/kick

String - player String - reason

Kicks a player from the server, they may rejoin later

/ban

String - player (Optional) String - reason (Optional) String - duration

Bans a player, if no duration is provided the ban will be permanent.

/unban

String - player

Unbans a banned player

Last updated