Skip to content

Creating a simple ban command

Ali edited this page Nov 21, 2023 · 1 revision

In the previous tutorial, we created a basic /hello command to make sure everything works fine.

In this tutorial, we will create a /ban <target> <reason> command.

First, we will remove our /hello command, as it is not part of our plugin!

public final class SunBans extends JavaPlugin {

    @Override
    public void onEnable() {
        BukkitCommandHandler handler = BukkitCommandHandler.create(this);
-        handler.register(this);
    }

    @Override
    public void onDisable() {
    }
    
-    @Command("hello")
-    public void sayHello(BukkitCommandActor actor) {
-        actor.reply("Why, hello there!");
-    }
}

It's better to put our commands in their own classes. This will make it easier to refactor in the future, and will keep our main class clean as it should only be responsible for registering our commands and not the actual command logic.

For this, we will create a new BanCommand class, which will contain our newly created command.

New class

We want our command to be structured as follows: /ban <target> <reason>. Our command will simply ban the target player with the reason provided.

One of the most convenient features of Lamp is the ability to easily add as many aliases as we want to our command, with minimal effort.

We will make our command also /sunbans ban <target> <reason>

public class BansCommand {

    @Command({"ban", "sunbans ban"})
    public void ban(
            BukkitCommandActor actor,
            OfflinePlayer target,
            String reason
    ) {
    }

}

As you can see, Lamp will automatically handle our aliases without us having to repeat our code.

Also, our method signature parameters (OfflinePlayer target, String reason) reflects the command parameters. We don't have to parse the player name, make sure it's valid, or send errors. Everything is handled automatically by Lamp!

Note: String arguments that come at the end of the command will automatically consume the rest of the input. If you run the command as /bans Bob You aren't wearing a hat!, the reason argument will be You aren't wearing a hat!. If this behavior is not desired, you can add @Single to the argument, in which it would only be the first word (You).

Let's add code for our ban command:

@Command({"ban", "sunbans ban"})
public void ban(BukkitCommandActor actor, OfflinePlayer target, String reason) {
+    Bukkit.getBanList(BanList.Type.NAME)
+            .addBan(
+                    /* target = */ target.getName(),
+                    /* reason = */ reason,
+                    /* expires = */ null,
+                    /* source = */ actor.getName()
+            );
+    actor.reply("&aSuccessfully banned &e" + target.getName() + "&a!");
}

Fantastic! Our command is ready. What's left is to register it in our command handler.

@Override
public void onEnable() {
    BukkitCommandHandler handler = BukkitCommandHandler.create(this);
+   handler.register(new BansCommand());
}

It may seem that the way OfflinePlayer works is magic, but this is because Lamp supports many of the common types out of the box:

  • Java types
    • Primitive types and their wrappers
      • int, java.lang.Integer
      • double, java.lang.Double
      • long, java.lang.Long
      • ...
    • java.lang.String
    • java.util.UUID
    • java.net.URL and java.net.URI
  • Bukkit types:
    • Player for online players
    • OfflinePlayer for any player that ever played on the server
    • World for a Bukkit world
    • EntityType for Bukkit's entity types
    • A Lamp-provided EntitySelector<...> class for Minecraft selectors (such as @p, @a, @e[type=horse])

This makes building commands significantly easier, as we only have to focus on the actual command logic, and not the parsing and validating of the input

Banning a non-existent player

Banning a player

We also get auto-completions for the target parameter out of the box. How convenient!

Tab-completions

Fantastic! In the next tutorial, we will make our command more robust by adding a description, a permission, and colorful completions.

Clone this wiki locally