Skip to content

Paramètres de Commandes

La notion de paramètres est utilisée dans la plupart des commandes. Des fois, ces paramètres peuvent être optionnels, ce qui veut dire que si vous ne donnez pas ce paramètre, la commande va quand même s'exécuter. Un nœud peut avoir plusieurs types de paramètres, mais n'oubliez pas qu'il y a une possibilité d'ambiguïté, qui devrait toujours être évitée.

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;
					})));
});

Dans ce cas d'exemple, après la commande textuelle /argtater, vous devez donner un nombre. Par exemple, si vous exécutez /argtater 3, vous allez avoir en retour le message Called /argtater with value = 3. Si vous tapez /argater sans arguments, la commande ne pourra pas être correctement analysée.

Nous ajoutons ensuite un second paramètre optionnel :

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;
							}))));
});

Maintenant, vous pouvez donner un ou deux arguments de type nombre à la commande. Si vous donnez un seul nombre, vous allez avoir en retour un texte avec une seule valeur d'affichée. Si vous donnez deux nombres, vous allez avoir en retour un texte avec deux valeurs d'affichées.

Vous pouvez penser qu'il n'est pas nécessaire de spécifier plusieurs fois des exécutions similaires. Donc, nous allons créer une méthode qui va être utilisée pour les deux cas d'exécution.

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;
}

Paramètres de Commande Personnalisés

Si le type de paramètre de commande dont vous avez besoin n'existe pas en vanilla, vous pouvez toujours le créer par vous-même. Pour le faire, vous avez besoin de créer une nouvelle classe qui hérite l'interface ArgumentType<T>T est le type du paramètre.

Vous devrez implémenter la méthode parse, qui va donc analyser la saisie de chaine de caractères afin de la transformer en le type désiré.

Par exemple, vous pouvez créer un type de paramètre qui transforme une chaine de caractères en BlockPos avec le format suivant : {x, y, z}

java
public class BlockPosArgumentType implements ArgumentType<BlockPos> {
	/**
	 * Parse the BlockPos from the reader in the {x, y, z} format.
	 */
	@Override
	public BlockPos parse(StringReader reader) throws CommandSyntaxException {
		try {
			// This requires the argument to be surrounded by quotation marks.
			// eg: "{1, 2, 3}"
			String string = reader.readString();

			// Remove the { and } from the string using regex.
			string = string.replace("{", "").replace("}", "");

			// Split the string into the x, y, and z values.
			String[] split = string.split(",");

			// Parse the x, y, and z values from the split string.
			int x = Integer.parseInt(split[0].trim());
			int y = Integer.parseInt(split[1].trim());
			int z = Integer.parseInt(split[2].trim());

			// Return the BlockPos.
			return new BlockPos(x, y, z);
		} catch (Exception e) {
			// Throw an exception if anything fails inside the try block.
			throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherParseException().create("Invalid BlockPos format. Expected {x, y, z}");
		}
	}
}

Enregistrer les Paramètres de Commande Personnalisés

WARNING

Vous devez enregistrer votre paramètre de commande personnalisée à la fois sur le serveur et sur le client, sinon dans le cas contraire cette commande ne fonctionnera pas !

Vous pouvez enregistrer votre paramètre de commande personnalisé dans la méthode onInitialize de l'initialiseur de votre mod en utilisant la classe ArgumentTypeRegistry :

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

Utiliser les Paramètres de Commande Personnalisés

Nous pouvons utiliser notre paramètre de commande personnalisé dans une commande, en passant une instance de ce dernier dans la méthode .argument du constructeur de commande.

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;
					})
	));
});

En exécutant la commande, on peut vérifier si le paramètre de commande fonctionne ou pas :

Argument invalide.

Argument valide.

Résultat de commande.