Skip to content

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.

java
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
	dispatcher.register(CommandManager.literal("argtater1")
			.then(CommandManager.argument("value", IntegerArgumentType.integer())
					.executes(context -> {
						int value = IntegerArgumentType.getInteger(context, "value");
						context.getSource()
								.sendFeedback(
										() -> Text.literal(
												"Called /argtater1 with value = %s".formatted(value)),
										false);
						return 1;
					})));
});

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:

java
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
	dispatcher.register(CommandManager.literal("argtater2")
			.then(CommandManager.argument("value1", IntegerArgumentType.integer())
					.executes(context -> {
						int value1 = IntegerArgumentType.getInteger(context, "value1");
						context.getSource()
								.sendFeedback(
										() -> Text.literal(
												"Called /argtater2 with value 1 = %s".formatted(value1)),
										false);
						return 1;
					})
					.then(CommandManager.argument("value2", IntegerArgumentType.integer())
							.executes(context -> {
								int value1 = IntegerArgumentType.getInteger(context, "value1");
								int value2 = IntegerArgumentType.getInteger(context, "value2");
								context.getSource()
										.sendFeedback(
												() -> Text.literal(
														"Called /argtater2 with value 1 = %s and value 2 = %s"
																.formatted(value1, value2)),
												false);
								return 1;
							}))));
});

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.

java
	CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
		dispatcher.register(CommandManager.literal("argtater3")
				.then(CommandManager.argument("value1", IntegerArgumentType.integer())
						.executes(context ->
								printValues(IntegerArgumentType.getInteger(context, "value1"), 0, context))
						.then(CommandManager.argument("value2", IntegerArgumentType.integer())
								.executes(context -> printValues(
										IntegerArgumentType.getInteger(context, "value1"),
										IntegerArgumentType.getInteger(context, "value2"),
										context)))));
	});

private static int printValues(int value1, int value2, CommandContext<ServerCommandSource> context) {
	context.getSource()
			.sendFeedback(
					() -> Text.literal(
							"Called /argtater3 with value 1 = %s and value 2 = %s".formatted(value1, value2)),
					false);
	return 1;
}

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}

java
	CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
		dispatcher.register(CommandManager.literal("argtater3")
				.then(CommandManager.argument("value1", IntegerArgumentType.integer())
						.executes(context ->
								printValues(IntegerArgumentType.getInteger(context, "value1"), 0, context))
						.then(CommandManager.argument("value2", IntegerArgumentType.integer())
								.executes(context -> printValues(
										IntegerArgumentType.getInteger(context, "value1"),
										IntegerArgumentType.getInteger(context, "value2"),
										context)))));
	});

private static int printValues(int value1, int value2, CommandContext<ServerCommandSource> context) {
	context.getSource()
			.sendFeedback(
					() -> Text.literal(
							"Called /argtater3 with value 1 = %s and value 2 = %s".formatted(value1, value2)),
					false);
	return 1;
}

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:

java
ArgumentTypeRegistry.registerArgumentType(
		new Identifier("fabric-docs", "block_pos"),
		BlockPosArgumentType.class,
		ConstantArgumentSerializer.of(BlockPosArgumentType::new)
);

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.

java
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
	dispatcher.register(CommandManager.literal("parse_pos").then(
			CommandManager.argument("pos", new BlockPosArgumentType())
					.executes(context -> {
						BlockPos arg = context.getArgument("pos", BlockPos.class);
						context.getSource().sendFeedback(
								() -> Text.literal("Called /parse_pos with BlockPos: ")
										.append(Text.of(arg.toString())),
								false);
						return 1;
					})
	));
});

Durch das Ausführen des Befehls, können wir testen, ob der Argumenttyp funktioniert oder nicht:

Ungültiges Argument.

Gültiges Argument.

Ergebnis des Befehls.