关于协议:本文章的代码在“Creative Commons Zero v1.0”协议下共享,允许你在你自己的模组中使用本模组展示的代码示例。 ====== 命令建议 ====== Brigadier 允许你为参数指定建议。在 Minecraft 中,这些建议会在玩家输入命令时发送至客户端。 ===== 建议提供器 ===== “建议提供器”(''SuggestionProvider'')用于制作将会发送至客户端的建议的列表。建议提供器是一个函数性接口,接收一个 ''CommandContext'' 和一个 ''SuggestionBuilder'' 并返回一些 ''Suggestions''。''SuggestionProvider'' 返回一个 [[https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/concurrent/CompletableFuture.html|CompletableFuture]],因为这些建议并不一定立即可用。 命令的建议是带有环境的,因为建议提供器给予你当前的命令环境。 ===== 示例建议提供器 ===== 假设你需要建议实体能够拥有的所有属性。 class AttributeSuggestionProvider implements SuggestionProvider { @Override public CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) throws CommandSyntaxException { Identifier entityTypeId = context.getArgument("type", Identifier.class); ... 因为我们有命令环境,我们可以此建议提供器所对应的参数之前的所有参数。 Next is a bunch of boilerplate code class AttributeSuggestionProvider implements SuggestionProvider { @Override public CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) { Identifier entityTypeId = context.getArgument("type", Identifier.class); EntityType entityType = Registries.ENTITY_TYPE.getOrEmpty(entityTypeId).orElse(null); // 对于 1.19.3 之前的版本,请使用 ''Registry.ENTITY_TYPE''。 if (!DefaultAttributeContainer.hasDefinitionFor(entityType)) { // TODO: 失败时 } DefaultAttributeContainer attributeContainer = DefaultAttributeRegistry.get(entityType); // 你会需要 mixin 来得到这个“instance map”。在本教程中,假设我们可以访问它。 for (EntityAttribute attribute : attributeContainer.instances().keySet()) { Identifier attributeId = Registries.ATTRIBUTE.getId(attribute); if (attributeId != null) { ... 为了让建议出现在客户端上,你必须给 builder 添加建议,方法就是使用其 ''suggest'' 方法。有些会处理数字,有些则显示一个提示。 for (EntityAttribute attribute : attributeContainer.instances().keySet()) { Identifier attributeId = Registries.ATTRIBUTE.getId(attribute); if (attributeId != null) { builder.suggest(attributeId.toString()); } } 你还可以使用 ''add(SuggestionBuilder)'' 方法让结果与另一个 suggestion builder 结合起来。 最后,你需要将需要返回的建议 build 了,方法就是使用 ''buildFuture'' 方法。 return builder.buildFuture(); 最终的结果: class AttributeSuggestionProvider implements SuggestionProvider { @Override public CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) { Identifier entityTypeId = context.getArgument("type", Identifier.class); EntityType entityType = Registries.ENTITY_TYPE.getOrEmpty(entityTypeId).orElse(null); if (!DefaultAttributeContainer.hasDefinitionFor(entityType)) { // TODO: 失败时 } DefaultAttributeContainer attributeContainer = DefaultAttributeRegistry.get(entityType); // 你会需要 mixin 来得到这个“instance map”。在本教程中,假设我们可以访问它。 for (EntityAttribute attribute : attributeContainer.instances().keySet()) { Identifier attributeId = Registries.ATTRIBUTE.getId(attribute); if (attributeId != null) { builder.suggest(attributeId.toString()); } } return builder.buildFuture(); } } ===== 使用建议提供器 ===== 现在你有了建议提供器,是时候使用这个提供,注意这个提供器对纯文本参数(literal)不适用。 注册参数时,你可以使用 ''suggests(SuggestionProvider)'' 方法可设置建议提供器。这会应用到 ''RequiredArgumentBuilder'',就像下面这样: argument(argumentName, word()) .suggests(CompletionProviders.suggestedStrings()) .then(/* 剩余的命令 */)); ===== 内置的建议提供器 ===== Minecraft 包括了几个内置的建议提供器,包括: ^ 类型 ^ 字段/方法 ^ | 可召唤的实体 | ''SuggestionProviders.SUMMONABLE_ENTITIES'' | | 可用的声音 | ''SuggestionProviders.AVAILABLE_SOUNDS'' | | 战利品表 | ''LootCommand.SUGGESTION_PROVIDER'' | | 生物群系 | ''SuggestionProviders.ALL_BIOMES'' | ===== CommandSource 中的工具 ===== ''CommandSource'' contains a few utility methods to help remove boilerplate when making the suggestions. Many of the utility methods involve returning completed suggestions from a ''Stream'' or ''Set'' of Identifiers, positions or matching strings. ===== 其他命令教程 ===== [[commands#高级概念|点击此处查看其他命令教程]]。