Adding commands

Unturned Plugin Development #5

MCrow • one month ago

There are two ways to implement commands in Rocket plugins for Unturned. The traditional way is to implement the IRocketCommand interface and the newer way is to use the RocketCommandAttribute. In this episode, we will learn both ways.

Implementing IRocketCommand

When you want to add a command to your plugin you should create a new class in the Commands folder inside your plugin project. The class should be public and implement the IRocketCommand interface. To use IRocketCommand you need to add using Rocket.API directive to your class.

Once you do that, press Ctrl + . to add the missing interface members. You will see that the interface requires you to implement the Name, Help, Syntax, Callback, and Permissions properties.

  1. First you need to specify AllowedCaller. There are 3 options:
  • AllowedCaller.Both
  • AllowedCaller.Player
  • AllowedCaller.Console

When you specify AllowedCaller.Console for example then the command will only be called from the console.

  1. Name is the name of the command. It is the word that the player will type in the chat to execute the command. For example, maxskills or heal then the player will type /maxskills or /heal in the chat.

  2. Help is the description of the command. It is not displayed anywhere, but you should write a brief description of what the command does for documentation purposes.

  3. Syntax is the command syntax. It is also not used anywhere, but you can write it for the same reason as the help. It can be <player> or [player] for example. If the parameter is required then use <player>, if it is optional then use [player].

  4. Aliases is a list of strings that contains alternative names for the command. For example, if you set to new List<string> { "ms" } then the player can type /ms instead of /maxskills. If you don't want to have any aliases, you can set it to an empty list.

  5. Permissions is the permission required to execute the command. You can set it to new List<string> { "maxskills" } for example. It is not necessary, because by default every command has a permission with the same name as the command. Then you can set it to empty list.

  6. Execute is the method that is called when the command is executed. It has 2 parameters:

  • IRocketPlayer caller - the player who executed the command. It can be either a ConsolePlayer or UnturnedPlayer. If you set the command AllowedCaller to Player then you can cast caller to UnturnedPlayer and use it to get the player's position, health, etc.
  • string[] command - the command arguments. For example, if the player types /maxskills mcrow 30 then the command array will contain 2 elements: mcrow and 30.

Here is an example of a command that sets the player's skills to the maximum level:

using Rocket.API;
using Rocket.Unturned.Chat;
using Rocket.Unturned.Player;
using System.Collections.Generic;

namespace RestoreMonarchy.Example.Commands
{
    public class MaxskillsCommand : IRocketCommand
    {
        public AllowedCaller AllowedCaller => AllowedCaller.Both;

        public string Name => "maxskills";

        public string Help => "Gives maxskills to the specified or calling player.";

        public string Syntax => "[player]";

        public List<string> Aliases => new();

        public List<string> Permissions => new();

        public void Execute(IRocketPlayer caller, string[] command)
        {
            UnturnedPlayer player;
            if (command.Length > 0)
            {
                player = UnturnedPlayer.FromName(command[0]);
                if (player == null)
                {
                    UnturnedChat.Say(caller, "Player not found!");
                    return;
                }
            }
            else
            {
                if (caller is ConsolePlayer) 
                {
                    UnturnedChat.Say(caller, "You must specify a player!");
                    return;
                }

                player = (UnturnedPlayer)caller;
            }

            player.MaxSkills();
            if (caller != player)
            {
                UnturnedChat.Say(caller, $"Maxskills given to {player.DisplayName}.");
            } else
            {
                UnturnedChat.Say(caller, "Maxskills given to you.");
            }
        }
    }
}

This command sets the player's skills to the maximum level. If the player is not specified then it sets the caller's skills. It also sends a message to the caller that the command was executed successfully.

Using RocketCommandAttribute

Another way to add commands to your plugin is to use [RocketCommand] attribute. You can add it to any public method in your plugin class. The method should have 2 parameters: IRocketPlayer caller and string[] command.

Here is an example of a command that sets the player's health to 100. If the player is not specified then it sets the caller's health. It also sends a message to the caller that the command was executed successfully.

[RocketCommand("heal", "Heals the specified player.", "<player>", AllowedCaller.Both)]
public void HealCommand(IRocketPlayer caller, string[] command)
{
    UnturnedPlayer player;
    if (command.Length == 0)
    {
        if (caller is ConsolePlayer)
        {
            UnturnedChat.Say(caller, "You must specify a player!");
            return;
        }

        player = (UnturnedPlayer)caller;
    }
    else
    {
        player = UnturnedPlayer.FromName(command[0]);
        if (player == null)
        {
            UnturnedChat.Say(caller, "Player not found!");
            return;
        }
    }

    player.Heal(100, false, false);
}

Accessing plugin instance

With [RocketCommand] attribute it's easy to access the plugin instance, because you can use it for a method inside the plugin class.
However when you use IRocketCommand you first have to make a singleton of the plugin class and then you can access the plugin instance.

To do that you have to add a public static property to the plugin class that returns the instance of the plugin. The instance should be set in the Load method of the plugin.

Then you can access the plugin instance in the command class like this, allowing you to for example access translations and configuration.

In the next episode we will learn how to add translations and why is it important to use them.

Summary

Both implementing IRocketCommand and using [RocketCommand] attribute are valid ways to add commands to your Rocket plugin for Unturned. The first way is more traditional and gives you more control over the command, while the second way is easier and allows you to access the plugin instance directly.
However, I personally recommend using the first way, because it helps keep project better organized, especially when you want to have multiple commands in your plugin.