🇨🇳 中文 (Chinese - China)
🇨🇳 中文 (Chinese - China)
外观
🇨🇳 中文 (Chinese - China)
🇨🇳 中文 (Chinese - China)
外观
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 其中 value = 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
这个方法,这个方法会把输入的字符串解析为期望的类型。
举个例子,您可以创建一个可以把格式形如 {x, y, z}
的字符串解析为一个 BlockPos
参数类型。
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)
);
我们可以在命令中使用我们的自定义参数类型──通过在 command builder 中传递实例到 .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;
}
运行命令,我们可以测试参数类型是否生效: