-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3d1c9bc
commit 3b0e271
Showing
37 changed files
with
586 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
--- | ||
title: Befehlsargumente | ||
description: Lerne, wie man Befehle mit komplexen Parametern erstellt. | ||
--- | ||
|
||
# Befehlsargumente | ||
|
||
Parameter werden in den meisten Befehlen verwendet. Manchmal sind sie optional, das heißt, wenn du diesen Parameter nicht angibst, wird der Befehl dennoch ausgeführt. Ein Knoten kann mehrere Parametertypen haben, aber es ist zu beachten, dass die Möglichkeit einer | ||
Mehrdeutigkeit besteht, die vermieden werden sollte. | ||
|
||
@[code lang=java highlight={3} transcludeWith=:::4](@/reference/latest/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) | ||
|
||
In diesem Fall musst du nach dem Befehlstext `/argtater` eine ganze Zahl eingeben. Zum Beispiel, wenn du `/argtater 3` ausführst, erhaltest du die Rückmeldung `Called /argtater with value = 3`. Wenn du `/argtater` ohne Argumente eingibst, kann der Befehl nicht korrekt geparst werden. | ||
|
||
Dann fügen wir ein optionales zweites Argument hinzu: | ||
|
||
@[code lang=java highlight={3,13} transcludeWith=:::5](@/reference/latest/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) | ||
|
||
Jetzt kannst du eine oder zwei ganze Zahlen eingeben. Wenn du eine ganze Zahl eingibst, wird ein Feedback-Text mit einem einzigen Wert ausgegeben. Wenn du zwei Ganzzahlen angibst, wird ein Feedback-Text mit zwei Werten ausgegeben. | ||
|
||
Du kannst es unnötig finden, ähnliche Ausführungen zweimal anzugeben. Daher können wir eine Methode erstellen, die in beiden Ausführungen verwendet wird. | ||
|
||
@[code lang=java highlight={3,5,6,7} transcludeWith=:::6](@/reference/latest/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) | ||
|
||
## Benutzerdefinierte Argumenttypen | ||
|
||
Wenn Vanilla nicht den von dir benötigten Argumenttyp verfügt, kannst du deinen eigenen erstellen. Dazu musst du eine Klasse erstellen, die das Interface `ArgumentType<T>` erbt, wobei `T` der Typ des Arguments ist. | ||
|
||
Du musst die Methode "parse" implementieren, die die Eingabezeichenfolge zu dem gewünschten Typ parst. | ||
|
||
Du kannst zum Beispiel einen Argumenttyp erstellen, der eine `BlockPos` aus einer Zeichenkette mit dem folgenden Format parst: `{x, y, z}` | ||
|
||
@[code lang=java highlight={3,5,6,7} transcludeWith=:::6](@/reference/latest/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) | ||
|
||
### Benutzerdefinierte Argumenttypen registrieren | ||
|
||
:::warning | ||
Du musst den benutzerdefinierten Argumenttyp sowohl im Server als auch im Client registrieren, sonst wird der Befehl nicht funktionieren! | ||
::: | ||
|
||
Du kannst deinen benutzerdefinierten Argumenttyp in der Methode `onInitialize` deines Mod-Initialisierers mit der Klasse `ArgumentTypeRegistry` registrieren: | ||
|
||
@[code lang=java transcludeWith=:::11](@/reference/latest/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) | ||
|
||
### Benutzerdefinierte Argumenttypen verwenden | ||
|
||
Wir können unseren benutzerdefinierten Argumenttyp in einem Befehl verwenden, indem wir eine Instanz davon an die Methode `.argument` im Builder des Befehls übergeben. | ||
|
||
@[code lang=java transcludeWith=:::10 highlight={3}](@/reference/latest/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) | ||
|
||
Durch das Ausführen des Befehls, können wir testen, ob der Argumenttyp funktioniert oder nicht: | ||
|
||
![Ungültiges Argument.](/assets/develop/commands/custom-arguments_fail.png) | ||
|
||
![Gültiges Argument.](/assets/develop/commands/custom-arguments_valid.png) | ||
|
||
![Ergebnis des Befehls.](/assets/develop/commands/custom-arguments_result.png) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
--- | ||
title: Befehle erstellen | ||
description: Befehle mit komplexen Parametern und Aktionen erstellen. | ||
authors: | ||
- dicedpixels | ||
- i509VCB | ||
- pyrofab | ||
- natanfudge | ||
- Juuxel | ||
- solidblock | ||
- modmuss50 | ||
- technici4n | ||
- atakku | ||
- haykam | ||
- mschae23 | ||
- treeways | ||
- xpple | ||
--- | ||
|
||
# Befehle erstellen | ||
|
||
Durch das Erstellen von Befehlen kann ein Mod-Entwickler Funktionen hinzufügen, die durch einen Befehl verwendet werden können. Dieses Tutorial wird dir erklären, wie man Befehle registriert und die allgemeine Befehlsstruktur von Brigadier. | ||
|
||
:::info | ||
Brigadier ist ein Befehlsparser und Dispatcher, der von Mojang für Minecraft entwickelt wurde. Es ist eine baumbasierte Befehlsbibliothek, in der du einen Baum von Befehlen und Argumenten aufbaust. Brigadier ist Open Source: https\://github.com/Mojang/brigadier | ||
::: | ||
|
||
### Das Interface `Command` | ||
|
||
`com.mojang.brigadier.Command` ist ein funktionales Interface, das einen bestimmten Code ausführt und in bestimmten Fällen eine `CommandSyntaxException` auslöst. Er hat einen generischen Typ `S`, der den Typ der _Befehlsquelle_ definiert. | ||
Die Befehlsquelle liefert einen Kontext, in dem ein Befehl ausgeführt wurde. In Minecraft ist die Befehlsquelle normalerweise ein `ServerCommandSource`, die einen Server, einen Befehlsblock, eine Remote-Verbindung (RCON), einen Spieler oder eine Entität darstellen kann. | ||
|
||
Die einzige Methode in `Command`, `run(CommandContext<S>)` nimmt einen `CommandContext<S>` als einzigen Parameter und gibt eine ganze Zahl zurück. Der Befehlskontext enthält die Befehlsquelle von `S` und ermöglicht es dir, Argumente zu erhalten, die geparsten Befehlsknoten zu betrachten und die in diesem Befehl verwendete Eingabe zu sehen. | ||
|
||
Wie andere funktionale Interfaces wird es in der Regel als Lambda oder als Methodenreferenz verwendet: | ||
|
||
```java | ||
Command<ServerCommandSource> command = context -> { | ||
return 0; | ||
}; | ||
``` | ||
|
||
Die Ganzzahl kann als Ergebnis des Befehls betrachtet werden. Normalerweise bedeuten Werte kleiner oder gleich Null, dass ein Befehl fehlgeschlagen ist und nichts machen wird. Positive Werte bedeuten, dass der Befehl erfolgreich war und etwas gemacht hat. Brigadier bietet eine Konstante zur Anzeige von Erfolg; `Befehl#SINGLE_SUCCESS`. | ||
|
||
#### Was kann die `ServerCommandSource` machen? | ||
|
||
Eine "ServerCommandSource" liefert einen zusätzlichen implementierungsspezifischen Kontext, wenn ein Befehl ausgeführt wird. Dazu gehört die Möglichkeit, die Entität, die den Befehl ausgeführt hat, die Welt, in der der Befehl ausgeführt wurde, oder den Server, auf dem der Befehl ausgeführt wurde, zu ermitteln. | ||
|
||
Du kannst auf die Befehlsquelle von einem Befehlskontext aus zugreifen, indem du `getSource()` für die Instanz `CommandContext` aufrufst. | ||
|
||
```java | ||
Command<ServerCommandSource> command = context -> { | ||
ServerCommandSource source = context.getSource(); | ||
return 0; | ||
}; | ||
``` | ||
|
||
### Registrieren eines einfachen Befehls | ||
|
||
Befehle werden innerhalb des `CommandRegistrationCallback` registriert, der von der Fabric API bereitgestellt wird. | ||
|
||
:::info | ||
Informationen zur Registrierung von Callbacks findest du in der Anleitung [Events](../events.md). | ||
::: | ||
|
||
Das Event sollte im Initialisierer deines Mods registriert werden. | ||
|
||
Der Callback hat drei Parameter: | ||
|
||
- `CommandDispatcher<ServerCommandSource> dispatcher` - Dient zum Registrieren, Parsen und Ausführen von Befehlen. `S` ist der Typ | ||
der Befehlsquelle, die der Command Dispatcher unterstützt. | ||
- `CommandRegistryAccess registryAccess` - Bietet eine Abstraktion zu Registrys, die an bestimmte Befehlsargumente übergeben werden können | ||
Argument-Methoden | ||
- `CommandManager.RegistrationEnvironment environment` - Identifiziert den Typ des Servers, auf dem die Befehle registriert werden. | ||
|
||
Im Mod-Initialisierer registrieren wir nur einen einfachen Befehl: | ||
|
||
@[code lang=java transcludeWith=:::_1](@/reference/latest/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) | ||
|
||
In der Methode `sendFeedback()` ist der erste Parameter der zu sendende Text, der ein `Supplier<Text>` ist, um zu vermeiden, dass Text-Objekte instanziert werden, wenn sie nicht benötigt werden. | ||
|
||
Der zweite Parameter bestimmt, ob die Rückmeldung an andere Operatoren gesendet werden soll. Im Allgemeinen sollte der Befehl `false` sein, wenn er etwas abfragen soll, ohne die Welt tatsächlich zu beeinflussen, wie zum Beispiel die aktuelle Zeit oder den Punktestand eines Spielers. Wenn der Befehl etwas macht, wie z. B. die Zeit zu ändern oder den Spielstand einer Person zu ändern, sollte er `true` sein. | ||
|
||
Wenn der Befehl fehlschlägt, kannst du, anstatt `sendFeedback()` aufzurufen, direkt eine beliebige Ausnahme auslösen, die vom Server oder Client entsprechend behandelt wird. | ||
|
||
Die `CommandSyntaxException` wird im Allgemeinen ausgelöst, um Syntaxfehler in Befehlen oder Argumenten aufzuzeigen. Du kannst auch deine eigene Exception implementieren. | ||
|
||
Um diesen Befehl auszuführen, musst du `/foo` eingeben, wobei die Groß- und Kleinschreibung zu beachten ist. | ||
|
||
#### Umgebung der Registrierung | ||
|
||
Falls gewünscht, kannst du auch dafür sorgen, dass ein Befehl nur unter bestimmten Umständen registriert wird, zum Beispiel nur in der dedizierten Umgebung: | ||
|
||
@[code lang=java highlight={2} transcludeWith=:::2](@/reference/latest/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) | ||
|
||
#### Befehlsanforderungen | ||
|
||
Angenommen, du hast einen Befehl, den nur Operatoren ausführen können sollen. An dieser Stelle kommt die Methode `requires()` ins Spiel. Die Methode `requires()` hat ein Argument eines `Predicate<S>`, das eine `ServerCommandSource` liefert, mit der getestet werden kann, ob die `CommandSource` den Befehl ausführen kann. | ||
|
||
@[code lang=java highlight={3} transcludeWith=:::3](@/reference/latest/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) | ||
|
||
Dieser Befehl wird nur ausgeführt, wenn die Quelle des Befehls mindestens ein Operator der Ebene 2 ist, einschließlich Befehlsblöcke. Andernfalls ist der Befehl nicht registriert. | ||
|
||
Dies hat den Nebeneffekt, dass dieser Befehl in der Tab-Vervollständigung für alle, die nicht Level 2 Operator sind, nicht angezeigt wird. Das ist auch der Grund, warum du die meisten Befehle nicht mit der Tabulatortaste vervollständigen kannst, wenn du keine Cheats aktivierst. | ||
|
||
#### Unterbefehle | ||
|
||
Um einen Unterbefehl hinzuzufügen, registriere den ersten buchstäblichen Knoten des Befehls ganz normal. Um einen Unterbefehl zu haben, musst du den nächsten buchstäblichen Knoten an den bestehenden Knoten anhängen. | ||
|
||
@[code lang=java highlight={3} transcludeWith=:::7](@/reference/latest/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) | ||
|
||
Ähnlich wie die Argumente können auch die Unterbefehlsknoten auf optional gesetzt werden. Im folgenden Fall sind sowohl `/subtater` als auch `/subtater subcommand` gültig. | ||
|
||
@[code lang=java highlight={2,8} transcludeWith=:::8](@/reference/latest/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) | ||
|
||
### Client-Befehle | ||
|
||
Die Fabric API verfügt über einen `ClientCommandManager` im Paket `net.fabricmc.fabric.api.client.command.v2`, der zur Registrierung clientseitiger Befehle verwendet werden kann. Der Code sollte nur im clientseitigen Code vorhanden sein. | ||
|
||
@[code lang=java transcludeWith=:::1](@/reference/latest/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java) | ||
|
||
### Befehlsumleitungen | ||
|
||
Befehlsumleitungen - auch bekannt als Aliase - sind eine Möglichkeit, die Funktionalität eines Befehls auf einen anderen umzuleiten. Dies ist nützlich, wenn du den Namen eines Befehls ändern möchtest, aber den alten Namen beibehalten willst. | ||
|
||
@[code lang=java transcludeWith=:::12](@/reference/latest/src/client/java/com/example/docs/client/command/FabricDocsReferenceClientCommands.java) | ||
|
||
### FAQ | ||
|
||
<br> | ||
|
||
###### Warum lässt sich mein Code nicht kompilieren? | ||
|
||
- Abfangen oder Auslösen einer `CommandSyntaxException` - `CommandSyntaxException` ist keine `RuntimeException`. Wenn du sie auslöst, sollte sie in Methoden ausgelöst werden, die `CommandSyntaxException` in den Methodensignaturen auslösen, oder sie sollte abgefangen werden. | ||
Brigadier wird die checked Exceptions behandeln und die entsprechende Fehlermeldung im Spiel für dich weiterleiten. | ||
|
||
- Probleme mit generischen Typen - Es kann sein, dass du hin und wieder ein Problem mit generischen Typen hast. Wenn du Serverbefehle registrierst (was in den meisten Fällen der Fall ist), stelle sicher, dass du `CommandManager.literal` oder `CommandManager.argument` anstelle von `LiteralArgumentBuilder.literal` oder `RequiredArgumentBuilder.argument` benutzt. | ||
|
||
- Überprüfe die Methode `sendFeedback()` - Du hast vielleicht vergessen, einen booleschen Wert als zweites Argument anzugeben. Denke auch daran dass seit Minecraft 1.20 der erste Parameter `Supplier<Text>` anstelle von `Text` ist. | ||
|
||
- Ein Befehl sollte eine ganze Zahl zurückgeben - Bei der Registrierung von Befehlen akzeptiert die Methode `executes()` ein `Command` Objekt, das normalerweise ein Lambda ist. Das Lambda sollte eine ganze Zahl zurückgeben, anstelle anderen Typen. | ||
|
||
###### Kann ich Befehle zur Laufzeit registrieren? | ||
|
||
::: warning | ||
You can do this, but it is not recommended. You would get the `CommandManager` from the server and add anything commands | ||
you wish to its `CommandDispatcher`. | ||
|
||
Danach musst du den Befehlsbaum mit `CommandManager.sendCommandTree(ServerPlayerEntity)` erneut an jeden Spieler senden. | ||
|
||
Dies ist erforderlich, da der Client den Befehlsbaum, den er bei der Anmeldung (oder beim Senden von Operator-Paketen) erhält, lokal zwischenspeichert, um Fehlermeldungen zu vervollständigen. | ||
::: | ||
|
||
###### Kann ich die Registrierung von Befehlen während der Laufzeit aufheben? | ||
|
||
::: warning | ||
You can also do this, however, it is much less stable than registering commands at runtime and could cause unwanted side | ||
effects. | ||
|
||
Um die Dinge einfach zu halten, musst du Reflection auf Brigadier anwenden und Knoten entfernen. Danach musst du den Befehlsbaum erneut an jeden Spieler mit `sendCommandTree(ServerPlayerEntity)` senden. | ||
|
||
Wenn du den aktualisierten Befehlsbaum nicht sendest, kann es sein, dass der Client denkt, dass der Befehl noch existiert, obwohl die Ausführung am Server fehlschlägt. | ||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
--- | ||
title: Befehlsvorschläge | ||
description: Lerne, wie man Spielern Werte für Befehlsargumente vorschlagen kann. | ||
authors: | ||
- IMB11 | ||
--- | ||
|
||
# Befehlsvorschläge | ||
|
||
Minecraft hat ein mächtiges System für Befehlsvorschläge, das an vielen Stellen verwendet wird, wie zum Beispiel beim Befehl `/give`. Mit diesem System kannst du dem Spieler Werte für Befehlsargumente vorschlagen, aus denen er dann auswählen kann - eine großartige Möglichkeit, um deine Befehle benutzerfreundlicher und ergonomischer zu gestalten. | ||
|
||
## Vorschlaganbieter | ||
|
||
Ein `SuggestionProvider` wird verwendet, um eine Liste von Vorschlägen zu erstellen, die an den Spieler gesendet werden. Ein Vorschlaganbieter ist eine funktionales Interface, das einen `CommandContext` und einen `SuggestionBuilder` entgegennimmt und einige `Suggestions` zurückgibt. Der `SuggestionProvider` gibt ein `CompletableFuture` zurück, da die Vorschläge möglicherweise nicht sofort verfügbar sind. | ||
|
||
## Verwenden von Vorschlaganbietern | ||
|
||
Um einen Vorschlaganbieter zu verwenden, musst du die Methode `suggests` auf dem Argument Builder aufrufen. Diese Methode nimmt einen `SuggestionProvider` entgegen und gibt einen neuen Argument Builder mit dem angehängten Vorschlaganbieter zurück. | ||
|
||
@[code java transcludeWith=:::9 highlight={4}](@/reference/latest/src/main/java/com/example/docs/command/FabricDocsReferenceCommands.java) | ||
|
||
## Eingebaute Vorschlaganbieter | ||
|
||
Es gibt einige eingebaute Vorschlaganbieter, du verwenden kannst: | ||
|
||
| Vorschlaganbieter | Beschreibung | | ||
| ----------------------------------------- | --------------------------------------------------------- | | ||
| `SuggestionProviders.SUMMONABLE_ENTITIES` | Schläft alle Entitäten vor, die beschworen werden können. | | ||
| `SuggestionProviders.AVAILABLE_SOUNDS` | Schlägt alle Klänge vor, die abgespielt werden können. | | ||
| `LootCommand.SUGGESTION_PROVIDER` | Zeigt alle verfügbaren Loottabellen an. | | ||
| `SuggestionProviders.ALL_BIOMES` | Schlägt alle Biome vor, die verfügbar sind. | | ||
|
||
## Erstellen eines benutzerdefinierten Vorschlagsanbieters | ||
|
||
Wenn ein eingebauter Anbieter deine Anforderungen nicht erfüllt, kannst du einen eigenen Vorschlaganbieter erstellen. Zu diesem Zweck musst du eine Klasse erstellen, die das Interface `SuggestionProvider` implementiert und die Methode `getSuggestions` überschreibt. | ||
|
||
In diesem Beispiel erstellen wir einen Vorschlaganbieter, der alle Benutzernamen der Spieler auf dem Server vorschlägt. | ||
|
||
@[code java transcludeWith=:::1](@/reference/latest/src/main/java/com/example/docs/command/PlayerSuggestionProvider.java) | ||
|
||
Um diesen Vorschlaganbieter zu verwenden, übergebe einfach eine Instanz davon an die Methode `.suggests` im Argument Builder. | ||
|
||
Natürlich können die Anbieter von Vorschlägen komplexer sein, da sie auch den Befehlskontext lesen können, um Vorschläge zu machen, die auf dem Zustand des Befehls basieren - zum Beispiel auf den Argumenten, die bereits angegeben wurden. | ||
|
||
Dies könnte in Form von Lesen des Inventars des Spielers und Vorschlagen von Gegenständen oder Entitäten, die sich in der Nähe des Spielers befinden, geschehen. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.