Table of Contents

命令重定向

重定向是 Brigadier 的一种别称和子命令的形式。redirect 方法接收一个命令节点和一个可选的环境修饰。命令节点可以是在派发器注册后的一个特定的节点,或者就是根节点。

别称

在原版的 Minecraft 中,/tell/w 会重定向到 /msg,可以在 MessageCommand 中看到。

这个例子显示了如何将 /foo2 重定向到 /foo

  1. public class ExampleMod implements ModInitializer {
  2. @Override
  3. public void onInitialize() {
  4. CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
  5. final LiteralCommandNode<ServerCommandSource> fooNode = dispatcher.register(literal("foo")
  6. .executes(context -> {
  7. // 对于 1.19 以下的版本,请将“Text.literal”替换为“new LiteralText”。
  8. context.getSource().sendMessage(Text.literal("调用了 /foo,不带参数"));
  9.  
  10. return 1;
  11. }));
  12. dispatcher.register(literal("foo2").redirect(fooNode));
  13. });
  14. }
  15. }

redirect 会告诉 birgadier,在另一个命令节点之后解析命令。

可串联的命令

/execute as @e[type=player] in the_end run tp ~ ~ ~ 这样的命令形式也是可行的,因为也使用了重定向。

首先考虑原版的 /execute 命令。这是 literal("execute") 后的一个节点。在分发子命令之后,分发器会重定向到那个节点(并带有一些修饰),让你能够在输入完子命令的参数之后,输入可以在 /execute 之后输入的任何内容。在子命令 run 中,分发器会重定向到根节点(dispatcher.getRoot()),允许你在输入完 run 后输入另一个完整的命令。

下面是一个可串联的命令的例子:

  1. LiteralCommandNode<ServerCommandSource> rootNode = dispatcher.register(literal("fabric_test"));
  2. LiteralCommandNode<ServerCommandSource> root1 = dispatcher.register(literal("fabric_test")
  3. // 你可以注册同一个纯文本节点,会注册分支的多个部分。
  4. // 就像可耐这样,注册重复的分支时,控制台会报错,提示命令冲突,但是仍能生效。
  5. .then(literal("extra")
  6. .then(literal("long")
  7. .redirect(rootNode, this::lengthen)) // 返回串联的根节点
  8. .then(literal("short")
  9. .redirect(rootNode, this::shorten))) // 返回串联的根节点
  10. .then(literal("command")
  11. .executes(ctx -> {
  12. ctx.getSource().sendFeedback(Text.literal("可串联的命令"), false);
  13. return Command.SINGLE_SUCCESS;
  14. })));

redirect 方法还可以修改 CommandSource,方法就是使用“redirect modifier”(SingleRedirectModifier<S>),它是一个 lambda。

  1. .redirect(rootNode, context -> {
  2. // 重定向时,修改命令源的视线方向。
  3. return ((ServerCommandSource) context.getSource()).withLookingAt(Vec3ArgumentType.getVec3(context, "pos"));
  4. })

:!: 在 redirect modifier 中,只有被重定向节点之后的参数会被使用。也就是说,重定向修饰之前的参数无法用于后续重定向(如有)或者最终执行。