Einen Befehl erstellen

Der erste Schritt ist einen neuen CommandSpec-Builder zu holen. Er stellt Methoden zu Modifikation der Befehlshilfe, Argumente, und Logik bereit. Diese Methoden können beliebig miteinander verkettet werden.

Um schließlich den Befehl zu erstellen, musst du die CommandSpec.Builder#build() Methode aufrufen.

Danach kann der Befehl registriert werden.

Beispiel: Einen einfachen Befehl erstellen

import org.spongepowered.api.Sponge;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.command.spec.CommandSpec;

CommandSpec myCommandSpec = CommandSpec.builder()
    .description(Text.of("Hello World Command"))
    .permission("myplugin.command.helloworld")
    .executor(new HelloWorldCommand())
    .build();

Sponge.getCommandManager().register(plugin, myCommandSpec, "helloworld", "hello", "test");

Überblick über die Methoden des CommansSpec-Builders

Methode

Beschreibung

executor

Definiert die Befehlslogik (siehe Einen CommandExecutor schreiben).

Das Festlegen des Executors ist erforderlich, wenn keine Kinder-Befehle festgelegt sind.

arguments

Legt die Argument-Spezifikation für diesen Befehl fest (siehe Paramenterverarbeitung).

permission

Legt die Berechtigung fest, die überprüft wird, bevor diese Kommando genutzt wird.

Beschreibung

Eine kurze, einzeilige Beschreibung des Zweckes dieses Befehls, der vom Hilfesystem angezeigt wird.

extendedDescription

Legt eine erweiterte Beschreibung fest, die in der längeren Hilfe genutzt wird. Wird an die kurze Beschreibung angehängt.

child

Fügt die Kinder Befehle dieses Befehls mit ihren Aliasen hinzu (siehe Untergeordnete Befehle).

children

Legt die Kinder Befehle dieses Befehls mit ihren Aliasen fest (siehe Untergeordnete Befehle).

inputTokenizer

Definiert, wie die Argumente geparst werden sollen. Standardmäßig teilt der Parser die Befehlseingabe durch Leerzeichen. Zitate zählen als ein eigenes Argument.

Beispiel: /tpworld Notch "My World" ergibt zwei Argumente: Notch und My World.

build

Erstellt den Befehl. Danach musst du den Befehl noch registrieren.

Einen CommandExecutor schreiben

Die einzige benötigte Komponente, einen einfachen Befehl zu erstellen, ist die CommandExecutor Klasse, welche die Logik des Befehls enthält.

Die Klasse muss das CommandExecutor Interface implementieren, welches die CommandExecutor#execute(CommandSource, CommandContext) Methode definiert. Die Methode wird beim Aufruf des Befehls aufgerufen und hat zwei Argumente:

  • Die Quelle des Befehlsaufrufes (z.B. die Konsole, ein Befehlsblock oder ein Spieler)

  • Den Befehlskontext, welche die ausgewerteten Argumente enthält (Siehe Paramenterverarbeitung)

Beispiel: Ein einfacher CommandExecutor

import org.spongepowered.api.command.CommandException;
import org.spongepowered.api.command.CommandResult;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.command.args.CommandContext;
import org.spongepowered.api.command.spec.CommandExecutor;

public class HelloWorldCommand implements CommandExecutor {

    @Override
    public CommandResult execute(CommandSource src, CommandContext args) throws CommandException {
        src.sendMessage(Text.of("Hello World!"));
        return CommandResult.success();
    }
}

Tipp

Du kannst anonyme Klassen verwenden, um den CommandExecutor im Befehlserstellungsprozess zu definieren (Siehe auch das Beispiel auf der Paramenterverarbeitung Seite).

Befehle nur für Spieler

Manchmal ist es notwendig, dass nur ein Spieler einen Befehl (z.B. den /suicide Befehl) ausführen kann.

Führe eine instanceof Überprüfung durch, um den Typ der CommandSource herauszufinden:

import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.command.source.CommandBlockSource;
import org.spongepowered.api.command.source.ConsoleSource;

if(src instanceof Player) {
    Player player = (Player) src;
    player.sendMessage(Text.of("Hello " + player.getName() + "!"));
}
else if(src instanceof ConsoleSource) {
    src.sendMessage(Text.of("Hello GLaDOS!"));
    // The Cake Is a Lie
}
else if(src instanceof CommandBlockSource) {
    src.sendMessage(Text.of("Hello Companion Cube!"));
    // <3
}

Bemerkung

Wir empfehlen dir, dass du ein optionales [player] Argument hinzufügst, um deinen Befehl Konsolen-freundlich zu machen (z.B. /suicide [player]).

Die einfachste Lösung hierfür ist es, ein playerOrSource Befehlselement (Siehe Paramenterverarbeitung) hinzuzufügen.

Befehlsergebnisse

Die CommandExecutor#execute() Methode muss immer ein CommandResult zurückgeben. In den meisten Fällen ist es ausreichend CommandResult#success() zurückzugeben, wenn der Befehl erfolgreich war, oder CommandResult#empty(), wenn es das nicht war. In den Fällen, wo mehr Informationen übertragen werden müssen, sollte der CommandResult#builder() benutzt werden. Der Builder bietet verschiedene Methoden an, die Integers akzeptieren und das gleichnamige Attribut setzen. Alle Attribute, die nicht von Builder gesetzt werden, bleiben leer.

Befehlsblocke können diese Werte verwenden um die Scoreboard Statistiken anzupassen, die dann wiederum für sorgfältig ausgearbeitete Konstruktionen aus mehreren Befehlsblöcken verwendet werden können. Ein Tutorial, wie auf Daten zugegriffen werden kann hier gefunden werden.

Beispiel: Ein CommandResult erstellen

CommandResult result = CommandResult.builder()
    .affectedEntities(42)
    .successCount(1)
    .build();

Dieses Beispiel zeigt, wie man einen Builder verwendet, um ein CommandResult für einen Befehl zu erstellen, der 42 Entitäten betroffen hat und erfolgreich durchgelaufen ist.

Fehlerbehandlung

Die execute() Methode kann auch eine CommandException werfen, die angibt, dass während der Ausführung des Befehls ein Fehler aufgetreten ist. Wenn ein solcher Fehler geworfen wurde, wird dessen Nachricht der Befehlsquelle wie ein Fehler formatiert angezegt. Außerdem wird die Befehls-Verwendungs-Nachricht angezeigt. Eine ArgumentParseException, welche ein Unterart von CommandException ist, wird automatisch geworfen, wenn die Befehls-Argumente nicht gelesen werden konnten.