The command system - GameModsBR/MineCity GitHub Wiki

The commands system were created to be easily customizable by the server owners, to achieve that we've split the system in 3 parts:

  1. Command Groups: Can hold commands, can also hold and be parent of other groups.
  2. Command Definition: Defines the command description, aliases and the parent groups.
  3. Command Function: The java code that actually execute the command, it also describes the arguments used by the command through annotation.

Groups and command definitions are defined in commands.xml and can be rearranged or modified as desired, the only thing that should not change is the command definition id as it's used to link the command definition to command function and functions are not changeable.

Contents

  1. Customizing the commands.xml
  2. <minecity-commands> parameters
  3. <group> definition 1. id parameter 2. cmd parameter 3. parent parameter
  4. <desc> definition
  5. <command> definition 1. id parameter 2. parent parameter 3. cmd parameter
  6. <syntax> definition
  7. Creating a command function

Customizing the commands.xml

This is the basic file structured, the file must look like this:

<?xml version="1.0" encoding="utf-8" ?>
<minecity-commands modified="false" add-missing="true">
    <groups>
       <!-- Group tags goes here -->
    </groups>
    <commands>
       <!-- Command tags goes here -->
    </commands>
</minecity-commands>

<minecity-commands> parameters

If you are modify the file, change the modified="false" to modified="true" otherwise the file can be completely overridden at anytime.

If you want to completely remove a command, you need to change add-missing="true" to add-missing="true" otherwise the removed command will be added back at anytime. It will also stop new commands implemented on future versions to be added to the file automatically.

<group> definition

An example of fully defined group tag:

<group id="mcid" cmd="minecity,mc">
    <desc>All MineCity commands</desc>
</group>
<group id="city" parent=",mcid" cmd="city,town,c,t">
    <desc>All city related commands</desc>
</group>

id parameter

Defines the internal group id, it will not be visible to players, it's used merely to build the parental relationship with commands and other groups. Use only simple characters to avoid issues, never use comma or spaces.

cmd parameter

Defines how the group will be exposed, this is what the players will have to type to access the group, do not use spaces. You can define as many names as you want by separating them with comma but the first value will be the primary name, other values will be considered aliases and will be visible only when the player attempts to auto-complete them.

The commands will be added linked to subgroups, so the city group in this example can be accessed by:

  • /city
  • /town
  • /c
  • /t
  • /minecity city
  • /minecity town
  • /minecity c
  • /minecity t
  • /mc city
  • /mc town
  • /mc c
  • /mc t

parent parameter

It's optional, empty or omitted values means that the group does not have parent and will be registered as a root command (/city and /minecity in this example). You can specify as many parents you want by separating them with comma. Take a note that they city's parent's parameter begins with comma, that defines the city group parent of none and mcid. Also note that the values are group ids and not command ids nor the values defined on cmd parameter. Do not create parental loops! It's wrong and will crash the server!, an example of parental loop: GroupA is child of GroupA. An other: GroupA is child of GroupB which is child of GroupA.

<desc> definition

A simple informative text that will be displayed on help commands.

<command> definition

An example of fully defined command tag:

<command id="city.spawn" parent="city" cmd="go,spawn">
    <desc>Teleport you to the city</desc>
    <syntax>[city name]</syntax>
</command>

id parameter

It differs from group id definition, a command id is the internal name to identify the function that will execute the command, if you use an invalid id the command will be unusable, you can define multiple <command> tags with the same id and different descriptions for example as long as they does not have the same parent, you can't do that with groups.

parent parameter

Exactly the same as the group's parent parameter.

cmd parameter

Exactly the same as the group's cmd parameter.

<syntax> definition

A simple informative text that defines the command syntax, will be displayed on help commands. Note: This is planned to be removed in future in favor of the automatic syntax resolution generated by @Arg annotations on command functions.

Creating a command function

This section is for developers who wants to create completely new commands.

A command function is basically a public java method that receives CommandEvent as argument, the method can have any modifier as long as it's public, it can also have any return type but CommandResult is recommended. The method must also be annotated with @Command annotation.

The command execution will be considered failed if:

  • the method returns a CommandResult with a failure state
  • the method returns a Message object
  • the method returns false
  • the method throws an exception
  • the method returns null and is not declared to return void or Message

The command execution will be considered successful if:

  • the method returns a CommandResult with a successful state
  • the method returns null and is declared to return Message or void
  • none of the conditions above matches what is returned

Some examples:

public class Example
{
   public MineCity mineCity;

   @Command("example.1")
   public static CommandResult<Void> staticMethod(CommandEvent ev)
   {
      ev.sender.send(new Message("example.1", "Example 1"));
      return CommandResult.success();
   }

   @Command(value = "example.2", args = @Arg(name = "opt", type=Arg.Type.PREDEFINED, options = {"a","b","c"}, optional=true))
   public CommandResult<String> instanceMethod(CommandEvent ev)
   {
      if(ev.args.length != 0)
          return new CommandResult<>(new Message("example.2.bad-args-size", "This function receives only one argument"));

      List<String> validValues = Arrays.asList("a","b","c","d");

      if(!validValues.contains(ev.args[0]))
          return new CommandResult<>(new Message("example.2.bad-value",
                  "The value ${val} is invalid, valid values are ${valid}", new Object[][]{
                      {"val",ev.args[0]},  {"valid",validValues}
                  }
          ));

      return new CommandResult<>(new Message("example.2.success",
                  "Valid value: ${val}",
                  new Object[]{"val",ev.args[0]}
      ), ev.args[0]);
   }

   @Command(value = "example.3", console = false,
       args = { @Arg(name="player", type=Arg.Type.PLAYER), @Arg(name="city", type=Arg.Type.CITY, sticky=true) }
   )
   public Message returnsMessage(CommandEvent ev)
       throws DataSourceException
   {
       if(ev.args.length < 2)
           return new Message("example.3.invalid-args", "Please type the player name and a city name");
       
       String playerName = ev.args[0];
       String cityName = String.join(" ", Arrays.asList(ev.args).subList(1, ev.args.length));

       City city = mineCity.dataSource.getCityByName(cityName).orElse(null);
       if(city == null)
           return new Message("example.3.city-not-found", "The city ${name} was not found", new Object[]{"name",cityName});

       PlayerID player = mineCity.dataSource.getPlayer(playerName).orElse(null);
       if(player == null)
           return new Message("example.3.player-not-found", "The player ${name} was not found", new Object[]{"name",playerName});

       city.setOwner(player);
       return null;
   }
}
⚠️ **GitHub.com Fallback** ⚠️