跳到主要内容

Adventure 库参数

这些参数返回来自 net.kyori 包的类。虽然它们在技术上不是 Minecraft 或 Bukkit 原生的,但由于 Paper 包含了 Adventure 库,它们在 Paper 生态系统中被广泛使用。

Component 参数

备注

这个参数非常技术性。它遵循与 /tellraw <player> <component> 命令第二个参数相同的格式,需要文本组件的 JSON 表示形式,这使得它不适合一般用户输入。

结果以 Adventure component 的形式返回以供使用。

使用示例

public static LiteralCommandNode<CommandSourceStack> componentArgument() {
return Commands.literal("componentargument")
.then(Commands.argument("arg", ArgumentTypes.component())
.executes(ctx -> {
final Component component = ctx.getArgument("arg", Component.class);

ctx.getSource().getSender().sendRichMessage(
"你的消息: <input>",
Placeholder.component("input", component)
);
return Command.SINGLE_SUCCESS;
}))
.build();
}

游戏内预览

Key 参数

Key 参数允许用户输入任何人工(命名空间)键,并确保其有效性。这将返回一个 Key, 可以在 Paper API 的其他地方使用。

使用示例

public static LiteralCommandNode<CommandSourceStack> keyArgument() {
return Commands.literal("key")
.then(Commands.argument("key_input", ArgumentTypes.key())
.executes(ctx -> {
final Key key = ctx.getArgument("key_input", Key.class);

ctx.getSource().getSender().sendRichMessage("你输入了 <aqua><key></aqua>!",
Placeholder.unparsed("key", key.asString())
);

return Command.SINGLE_SUCCESS;
}))
.build();
}

游戏内预览

Named color 参数

此参数提供用户选择 16 种内置"命名"文本颜色的能力。此参数返回一个 NamedTextColor, 你可以用它来为组件应用颜色。

使用示例

public static LiteralCommandNode<CommandSourceStack> namedColorArgument() {
return Commands.literal("namedcolor")
.then(Commands.argument("color", ArgumentTypes.namedColor())
.then(Commands.argument("message", StringArgumentType.greedyString())
.executes(ctx -> {
final NamedTextColor color = ctx.getArgument("color", NamedTextColor.class);
final String msg = StringArgumentType.getString(ctx, "message");

ctx.getSource().getSender().sendMessage(
Component.text(msg).color(color)
);
return Command.SINGLE_SUCCESS;
})))
.build();
}

游戏内预览

Adventure style 参数

备注

与 component 参数类似,此参数不太适合一般用户输入,因为它也遵循显示组件的 JSON 格式。大多数用户 不知道如何使用该格式,因此不建议一般使用。

style 参数以 Style 对象的形式返回其值。 这可以使用 Component#style(Style) 应用于任何组件。虽然 JSON 输入允许 text 字段,但其内容会被完全忽略。

使用示例

public static LiteralCommandNode<CommandSourceStack> styleArgument() {
return Commands.literal("style")
.then(Commands.argument("style", ArgumentTypes.style())
.then(Commands.argument("message", StringArgumentType.greedyString())
.executes(ctx -> {
final Style style = ctx.getArgument("style", Style.class);
final String msg = StringArgumentType.getString(ctx, "message");

ctx.getSource().getSender().sendRichMessage("你的输入: <input>",
Placeholder.component("input", Component.text(message).style(style))
);
return Command.SINGLE_SUCCESS;
})))
.build();
}

游戏内预览

Signed message 参数

signed message 参数允许玩家以已签名消息的形式向服务器发送参数。这种已签名消息是一种特殊类型 - 它 允许服务器在不能直接修改的情况下将该消息发送给任何玩家。可见的区别是未签名消息在左侧有白色条, 而已签名消息没有。

signed message 参数返回一个 SignedMessageResolver。为了调用其 #resolve 方法,你必须传入两个参数:

  • 参数名称
  • CommandContext<CommandSourceStack> 对象

解析后的值是一个 CompletableFuture<SignedMessage>,你可以使用 thenAccept(Consumer<T>) 处理其 SignedMessage 值。在消费者内部,你可以将已签名消息发送给玩家或以其他方式使用它。

注意

默认情况下,传入 thenAccept 的消费者不在主线程上执行,这使得在其中使用大多数 Paper API 是不安全的。 如果你需要使用 API,你可以安排一个任务在下一个可用的 tick 上运行。为此,你可以使用 主线程执行器。 你可以在这里了解更多信息。

备注

非玩家发送者无法发送已签名消息,这意味着解析的 CompletableFuture 永远不会完成。 你应该通过在 SignedArgument 上使用 .requires(ctx -> ctx.getSender() instanceof Player) 确保只有玩家可以使用你的参数。如果你希望 无论是否签名都能执行参数,你可以为非玩家发送者添加一个后备的贪婪字符串参数。

使用示例

MinecraftArguments.java
public static LiteralCommandNode<CommandSourceStack> signedMessageArgument() {
return Commands.literal("signedmessage")
.then(Commands.argument("target", ArgumentTypes.player())
.then(Commands.argument("message", ArgumentTypes.signedMessage())
.executes(MinecraftArguments::executeSignedMessageCommand)))
.build();
}

private static int executeSignedMessageCommand(final CommandContext<CommandSourceStack> ctx) throws CommandSyntaxException {
final Player target = ctx.getArgument("target", PlayerSelectorArgumentResolver.class).resolve(ctx.getSource()).getFirst();
final SignedMessageResolver messageResolver = ctx.getArgument("message", SignedMessageResolver.class);

messageResolver.resolveSignedMessage("message", ctx).thenAccept(msg -> {
target.sendMessage(msg, ChatType.CHAT.bind(ctx.getSource().getSender().name()));
});


return Command.SINGLE_SUCCESS;
}

游戏内预览