SkillAgentSearch skills...

Arn

Only command manager you will need.

Install / Use

/learn @efekos/Arn

README

Arn

Discord Patreon Buy me a coffee

<!-- TOC --> <!-- TOC -->

Arn is an annotation-based command library inspired by Spring boot that helps Minecraft plugins with creating, handling and registering commands. This library uses Brigadier commands that Minecraft uses, so you can use most kinds of arguments you see in the commands of the original game. Plus, you can turn any enumerator to a custom argument, all it takes is two annotations.

Installation

Add this repository if you don't have it in your <repositories> or repositories.

<repository>
  <id>efekosdev</id>
  <url>https://efekos.dev/maven</url>
</repository>
maven { url 'https://efekos.dev/maven' }

| Artifact | Platform | Latest Version | |--------------|--------------|--------------------| | arn-paper | PaperMC | 0.4 | | arn-spigot | SpigotMC | 0.4 |

Add this dependency. Check the table above to make sure you use the latest version and the correct dependency.

<dependency>
  <groupId>dev.efekos.arn</groupId>
  <artifactId>arn-paper</artifactId>
  <version>0.4</version>
</dependency>
implementation 'dev.efekos.arn:arn-paper:0.4'

Usage

Arn uses Java Reflection API to scan through your plugin, detect needed classes and use them. Because of this, you have to add a Container annotation to every class that must be scanned by Arn.

Creating commands

Let's create a new class using the knowledge we know so far.

import dev.efekos.arn.common.annotation.Container;

@Container
public class CommandClass {

}

Normally, you need to either handle your command through events or create a Command class for it. But in Arn, all you have to do is add a method with such annotations.

import dev.efekos.arn.common.annotation.Command;
import org.bukkit.command.CommandSender;

@Command("ping") // command name
public int helloWorld(CommandSender sender /*get the sender*/) {
    sender.sendMessage("Pong!");
    return 0;
}

When scanned and registered, this method will be equivalent of command /helloworld, that takes no arguments and says "Pong!" back to the sender. Now you might be thinking about arguments. That is pretty easy.

import dev.efekos.arn.common.annotation.Command;
import dev.efekos.arn.common.annotation.CommandArgument;
import org.bukkit.command.CommandSender;

@Command("hello")
public int helloWorld(CommandSender sender, @CommandArgument String name /*string argument*/) {
    sender.sendMessage("Hello "+name+"!");
    return 0;
}

All we have to do is add a parameter with CommandArgument annotation. This method is now the equivalent of /helloworld <name>, <name> being a String that can have whitespaces using quoted strings. You can use following combinations of annotations and types by default (all of them requires CommandArgument.):

These don't require a CommandArgument annotation.

By default, name of an argument is same with name of the parameter. If you want, you can explicitly specify argument names like this.

public int method(@CommandArgument("name") String s);

Using parameter names as argument names

If you don't specify argument names and let Arn use parameter names instead, you'll probably face a problem. Maven does not compile applications with parameter names. In order to solve this problem, you can add small configuration to your maven-compiler-plugin. It is something like this:

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <parameters>true</parameters>
    </configuration>
    <!-- ... -->
</plugin>

I use Maven, so I don't know a solution for Gradle. It is probably something easy like it is in Maven, so you can fix it with a bit of research.

Advanced literals

I only showed you how to make base commands. There is more than base commands in Arn. If you want to use two or more literals, you can simply separate them with . in your CommandArgument annotation. But in this way, arguments will be placed after all the literals. If you want to place literals between arguments, you can follow this syntax: [ab]:[0-9]+:[a-z]+. First group of a letter determines will this literal be placed before or after the argument with the given index. Second group of a number is the index of an argument. Finally, last group of a lowercase word is the actual literal. Let me explain how it works more with this graph:

Advanced literal placement explained

As you can see, the last literal 'makefloor' is placed after 0th argument. This is because the first letter is 'a' and the index is 0. If the letter was 'b', the literal would be placed after second literal 'stuff'. If the index was 1, the literal would be placed after the 1st argument.

Custom arguments

If you want to make a custom argument, you can, using Enum classes! All you have to do is annotate an enum class with both Container and CustomArgument, and you'll be able to use that enum class as a command argument.

// Rating.java

import dev.efekos.arn.common.annotation.Command;
import dev.efekos.arn.common.annotation.CommandArgument;
import dev.efekos.arn.common.annotation.Container;
import dev.efekos.arn.common.annotation.CustomArgument;
import org.bukkit.entity.Player;

@Container
@CustomArgument()
public enum Rating {
    TRASH,
    BAD,
    MID,
    GREAT,
    GOAT
}

// Commands.java

@Co
View on GitHub
GitHub Stars6
CategoryDevelopment
Updated3mo ago
Forks0

Languages

Java

Security Score

87/100

Audited on Dec 13, 2025

No findings