关于协议:本文章的代码在“Creative Commons Zero v1.0”协议下共享,允许你在你自己的模组中使用本模组展示的代码示例。
命令建议
Brigadier 允许你为参数指定建议。在 Minecraft 中,这些建议会在玩家输入命令时发送至客户端。
建议提供器
“建议提供器”(SuggestionProvider
)用于制作将会发送至客户端的建议的列表。建议提供器是一个函数性接口,接收一个 CommandContext
和一个 SuggestionBuilder
并返回一些 Suggestions
。SuggestionProvider
返回一个 CompletableFuture,因为这些建议并不一定立即可用。
命令的建议是带有环境的,因为建议提供器给予你当前的命令环境。
示例建议提供器
假设你需要建议实体能够拥有的所有属性。
class AttributeSuggestionProvider implements SuggestionProvider<ServerCommandSource> { @Override public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> context, SuggestionsBuilder builder) throws CommandSyntaxException { Identifier entityTypeId = context.getArgument("type", Identifier.class); ...
因为我们有命令环境,我们可以此建议提供器所对应的参数之前的所有参数。
Next is a bunch of boilerplate code
class AttributeSuggestionProvider implements SuggestionProvider<ServerCommandSource> { @Override public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> 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<ServerCommandSource> { @Override public CompletableFuture<Suggestions> getSuggestions(CommandContext<ServerCommandSource> 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.