如何基于PaperMC的Brigadier为Minecraft give命令添加物品补全建议
解决PaperMC中为Give命令添加自定义物品Tab补全的问题
核心思路
你找到的items节点是give命令物品参数对应的ArgumentCommandNode,要实现自定义物品的Tab补全,只需替换该节点的SuggestionProvider,在原版补全逻辑基础上追加自定义物品的补全项即可。
具体实现步骤
1. 重写物品参数的补全逻辑
通过AsyncPlayerSendCommandsEvent拦截命令树发送事件,修改give命令的items节点补全器:
@EventHandler public void onSendCommands(AsyncPlayerSendCommandsEvent event) { CommandDispatcher<CommandSourceStack> dispatcher = event.getDispatcher(); CommandNode<CommandSourceStack> giveNode = dispatcher.getRoot().getChild("give"); if (giveNode == null) return; ArgumentCommandNode<CommandSourceStack, ?> itemsNode = (ArgumentCommandNode<CommandSourceStack, ?>) giveNode.getChild("items"); if (itemsNode == null) return; // 保留原版补全逻辑,避免丢失原版物品的补全 SuggestionProvider<CommandSourceStack> originalProvider = itemsNode.getCustomSuggestions(); SuggestionProvider<CommandSourceStack> customProvider = (context, builder) -> { CompletableFuture<Suggestions> originalSuggestions = originalProvider.getSuggestions(context, builder); // 追加自定义物品补全项,格式为「命名空间:物品ID」 return originalSuggestions.thenApply(suggestions -> { List<Suggestion> customItems = Arrays.asList( Suggestion.builder(builder, "myplugin:custom_sword").build(), Suggestion.builder(builder, "myplugin:magic_apple").build() ); List<Suggestion> merged = new ArrayList<>(suggestions.getList()); merged.addAll(customItems); return Suggestions.create(builder.getInput(), merged); }); }; // 构建新的物品参数节点并替换原节点 ArgumentCommandNode<CommandSourceStack, ?> newItemsNode = ArgumentCommandNode.builder(itemsNode.getName(), itemsNode.getType()) .withCustomSuggestions(customProvider) .withRequirement(itemsNode.getRequirement()) .withRedirect(itemsNode.getRedirect()) .withRedirectModifier(itemsNode.getRedirectModifier()) .build(); giveNode.getChildren().remove(itemsNode); giveNode.addChild(newItemsNode); }
2. 简洁替代方案(部分Paper版本适用)
直接通过命令调度器注册针对items参数的补全扩展,无需替换节点:
@Override public void onEnable() { CommandDispatcher<CommandSourceStack> dispatcher = Bukkit.getCommandMap().getDispatcher(); dispatcher.getCompletionSuggestions().registerCompletion( "items", (context, builder) -> { builder.suggest("myplugin:custom_axe"); builder.suggest("myplugin:enchanted_ring"); return CompletableFuture.completedFuture(builder.build()); } ); }
3. 关键注意事项
- 自定义物品ID必须遵循「插件ID:物品ID」的命名空间格式,确保和你注册物品时的ID一致
- 若自定义物品是动态生成的,可将补全列表改为从插件的物品注册表中动态遍历获取
- 第一种方案兼容性更强,适配多数Paper版本;第二种方案更简洁,但需测试对应版本的API支持情况
内容的提问来源于stack exchange,提问作者Senne
相关产品推荐
相关产品推荐

