Commands - noobmobile/GroovyBukkitAPI GitHub Wiki
Include the suffix Command on your class and the @Inject annotation. Every closure in the class will be considerated a command and it must have the first parameter as Context. The name of the variable will be registered in the main as the name of the command. You still need to register the command in the plugin.yml (maybe won't be necessary in the future)
@Inject
class TestCommand {
Terminal main
ItemService itemService // an example service, it'll automatically injected and registered on our main
// our command will be registered as /give
def give = { Context context ->
// when we call the Context#player() method, an exception will be throwed if it's not a player that it's executing the command
// but don't worry, the exception it's treated and a nice message it's sent to the Console saying it's only for players
def player = context.player()
if (!context.hasArgs(2)){ // if there's two or more arguments
return "§cPlease, use /give <player> <item> <amount>" // we can also use context.returning(String... messages)
}
def target = context.parsePlayer(0) // parse the player on args[0]
def material = context.parseEnum(1, Material) // parse an enum on args[1]
def amount = context.hasArg(2) ? context.parseInt(2) : 1
target.getInventory(new ItemComposer(material, amount).build())
return "§aItem given with success to $target.name"
}
}The Context class it's where happens all the command logic.
It's throwed whenever a "good exception" happens. A good exception it's when it's a exception we expect it to happen, like players inputing numbers, something not being found etc. If it is a good exception, we just send a message to the player saying what's wrong ("you typed a String instead of a Number" or "the player you typed is not online"). Any other exceptions will just be throwed if you don't catch them.
At any place of your command code, you can just return a String, and it will be sent to the player
def give = { Context context ->
// handle some logic
if (someBoolean){
return "someBoolean is true"
}
// rest of the logic
}You can also use Context.returning(String... messages) to return multiple messages
def give = { Context context ->
// handle some logic
if (someBoolean){
context.returning("I'm sorry but you don't have the permission to continue this code", "See you later!")
}
// rest of the logic
}Returns the CommandSender who executed the command
Cast the CommandSender to Player. If wasn't a player who executed the command (like the Console or Command Block), it'll be throwed a ContextException
Accept as parameter the index of the argument (like args[0], args[1]). parsePlayer() uses Bukkit.getPlayer(). If there's a problem parsing or if no player is found, it'll be throwed a ContextException
Returns the passed index argument casted as the passed enum
def material = context.parseEnum(0, Material)
def sound = context.parseEnum(1, Sound)Well, this is can be really tricky, but it's a powerful method.
collection - the collection to be searched
predicate - the function that extracts what we are searching for (for instance: we are searcing for machines by name, so extract Machine::name)
filter - our filter object, usually a String
type - the type name, just for our exception message if we don't find anything.
MachineService machineService
def give = { Context context ->
// lets suppose that this MachineService has a getAllMachines() method, but there's not a findByName() method
def machine = context.parseT(machineService.getAllMachines(), {machine -> machine.type.name}, context.getArg(0), "Machine")
// we are searching for all machines inside the provided collection, by its type name, with our args[0]
// if nothing is found, we throw a ContextException saying to the player "Machine (see why we pass the name of the type?) args[0] not found"
}Returns if the CommandSender has the passed permission. If he doesn't have the permission, it'll be throwed a ContextException
Returns if the CommandSender has the passed permission. Doesn't throw any exception.
What's the difference?
def give = { Context context ->
context.permission("give.permission")
// dont execute the rest of the code, just says to the CommandSender that he doesn't have the permission
}
def give = { Context context ->
def type = context.parseEnum(0, Material)
if (type == Material.DIAMOND && !context.hasPermission("give.diamonds")){
return "Sorry, only vips can give diamonds"
}
context.player().getInventory().addItem(new ItemStack(type))
}Returns a String joined with ", " of the enum
def give = { Context context ->
if (context.argsLenght() == 0){
context.returning("Use /give <material type>", "Valid types: " + context.validTypes(Material))
// prints "Valid types: STONE, DIRT, GRASS..."
}
}Same for the enum, but it's passed a collection a function that extracts the names
MachineService machineService
def give = { Context context ->
if (context.argsLenght() == 0){
context.returning("Use /give <machine type>", "Valid types: " + context.validTypes(machineService.getAllMachines(), {machine -> machine.name}))
// prints "Valid types: machinetype1, machinetype2, machinetype3..."
}
}Returns the argument in the passed index.
Returns if the passed arg exists
Returns if there's at least the passed number of arguments.
Returns the size of the arguments array.