🇷🇺 Русский (Russian)
🇷🇺 Русский (Russian)
Внешний вид
🇷🇺 Русский (Russian)
🇷🇺 Русский (Russian)
Внешний вид
This page is written for:
1.21
This page is written for:
1.21
Большинство команд используют аргументы. Иногда они могут быть необязательными, что означает, что команда выполнится, даже если вы не предоставите этот аргумент. Один узел может иметь несколько типов аргументов, но будьте внимательны, чтобы избежать неоднозначности.
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("command_with_arg")
.then(CommandManager.argument("value", IntegerArgumentType.integer())
.executes(FabricDocsReferenceCommands::executeCommandWithArg)));
});
private static int executeCommandWithArg(CommandContext<ServerCommandSource> context) {
int value = IntegerArgumentType.getInteger(context, "value");
context.getSource().sendFeedback(() -> Text.literal("Called /command_with_arg with value = %s".formatted(value)), false);
return 1;
}
В этом случае после текста команды /command_with_arg
следует ввести целое число. Например, если вы запустите /command_with_arg 3
, вы получите сообщение:
Вызывается /command_with_arg со значением = 3
Если ввести /command_with_arg без аргументов, команду не удастся правильно обработать.
Далее мы добавим необязательный второй аргумент:
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("command_with_two_args")
.then(CommandManager.argument("value_one", IntegerArgumentType.integer())
.executes(FabricDocsReferenceCommands::executeWithOneAre)
.then(CommandManager.argument("value_two", IntegerArgumentType.integer())
.executes(FabricDocsReferenceCommands::executeWithTwoArgs))));
});
private static int executeWithOneAre(CommandContext<ServerCommandSource> context) {
int value1 = IntegerArgumentType.getInteger(context, "value_one");
context.getSource().sendFeedback(() -> Text.literal("Called /command_with_two_args with value one = %s".formatted(value1)), false);
return 1;
}
private static int executeWithTwoArgs(CommandContext<ServerCommandSource> context) {
int value1 = IntegerArgumentType.getInteger(context, "value_one");
int value2 = IntegerArgumentType.getInteger(context, "value_two");
context.getSource().sendFeedback(() -> Text.literal("Called /argtater2 with value one = %s and value two = %s".formatted(value1, value2)),
false);
return 1;
}
Теперь вы можете указать одно или два целых числа. Если вы укажете одно число, будет выведено сообщение с одним значением. Если вы укажете два числа, будет выведено сообщение с двумя значениями.
Возможно, вам покажется излишним дважды указывать схожие исполнения. Поэтому мы можем создать метод, который будет использоваться в обоих случаях.
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("command_with_common_exec")
.then(CommandManager.argument("value_one", IntegerArgumentType.integer())
.executes(context -> executeCommon(IntegerArgumentType.getInteger(context, "value_one"), 0, context))
.then(CommandManager.argument("value_two", IntegerArgumentType.integer())
.executes(context -> executeCommon(
IntegerArgumentType.getInteger(context, "value_one"),
IntegerArgumentType.getInteger(context, "value_two"),
context)))));
});
private static int executeCommon(int value1, int value2, CommandContext<ServerCommandSource> context) {
context.getSource().sendFeedback(() -> Text.literal("Called /command_with_common_exec with value 1 = %s and value 2 = %s".formatted(value1, value2)), false);
return 1;
}
Если в стандартной библиотеке нет нужного вам типа аргументов, вы можете создать свой. Для этого нужно создать класс, который наследуется от интерфейса ArgumentType<T>
, где T
— это тип аргумента.
Вам нужно будет реализовать метод parse
, который преобразует входную строку в нужный тип.
Например, вы можете создать тип аргумента, который преобразует строку в BlockPos
с форматом: {x, y, z}
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}");
}
}
}
WARNING
Необходимо зарегистрировать свой тип аргументов как на сервере, так и на клиенте, иначе команда не будет работать!
Вы можете зарегистрировать свой тип аргументов в методе onInitialize
вашего инициализатора мода, используя класс ArgumentTypeRegistry
:
ArgumentTypeRegistry.registerArgumentType(
Identifier.of("fabric-docs", "block_pos"),
BlockPosArgumentType.class,
ConstantArgumentSerializer.of(BlockPosArgumentType::new)
);
Мы можем использовать наш собственный тип аргумента в команде, передав его экземпляр в метод .argument
при создании команды.
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("command_with_custom_arg").then(
CommandManager.argument("block_pos", new BlockPosArgumentType())
.executes(FabricDocsReferenceCommands::executeCustomArgCommand)
));
});
private static int executeCustomArgCommand(CommandContext<ServerCommandSource> context) {
BlockPos arg = context.getArgument("block_pos", BlockPos.class);
context.getSource().sendFeedback(() -> Text.literal("Called /command_with_custom_arg with block pos = %s".formatted(arg)), false);
return 1;
}
Выполнив команду, мы можем проверить, работает ли наш тип аргумента: