🇨🇳 中文 (Chinese - China)
🇨🇳 中文 (Chinese - China)
Appearance
🇨🇳 中文 (Chinese - China)
🇨🇳 中文 (Chinese - China)
Appearance
大多数的命令都有参数。 有些时候他们是可选的,这意味着如果你不提供这些参数命令照样可以工作 一个节点可能有多个参数类型导致用户感到困惑,请注意避免这个问题。
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;
})));
});
比如说,在命令文本/argtater
之后,您应该输入一个整型数字。 比如说,在命令文本/argtater
之后,您应该输入一个整型数字。 举个例子,如果您输入了/argtater 3
,您应该会收到一条反馈消息:Called /argtater with value = 3
。 如果您输入了 /argtataer
并且没有任何参数,那么这个命令将不会被正确解析。 如果您输入了 /argtataer
并且没有任何参数,那么这个命令将不会被正确解析。
接下来我们将添加第二个可选的参数:
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;
}))));
});
现在您可以输入一个或者两个整型数字了。 如果您提供了一个整型数字,那么会打印单个值的反馈文本。 现在您可以输入一个或者两个整型数字了。 如果您提供了一个整型数字,那么会打印单个值的反馈文本。 如果您提供了两个整型数字,那么会打印有两个值的反馈文本。
您可能会发现没有必要指定两次相似的执行。 因此,我们可以创建一个方法,用于两次执行。 因此,我们可以创建一个方法,用于两次执行。
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;
}
如果原版并没有提供您想要的命令参数类型,您可以创建您自己的类型。 为此,您需要创建一个继承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(
new Identifier("fabric-docs", "block_pos"),
BlockPosArgumentType.class,
ConstantArgumentSerializer.of(BlockPosArgumentType::new)
);
我们可以在命令中使用我们的自定义参数类型──通过传递实例到 .argument
方法到 command builder 中即可。
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;
})
));
});
运行命令,我们可以测试我们的参数类型是否可以正常工作: