NEI 配方树处理器

基本信息

属性 值
处理器类 hellfirepvp.beebetteratbees.client.gui.BBABGuiRecipeTreeHandler
基类 AbstractTreeGUIHandler(同时 implements ICraftingHandler, IUsageHandler)
注册位置 ClientProxy#registerNEIGUIs(ClientProxy.java:23-27)
面板贴图 beebetteratbees:textures/gui/neiBlank.png
面板标题 bbab.gui.breedtree = Bee Breeding Tree
每页配方数 1(recipiesPerPage() 硬编码返回 1)
注册方块 / 物品 / 实体 0 / 0 / 0

这是一个纯客户端 NEI 附属

仓库中没有任何 GameRegistry.registerBlock / registerItem / registerTileEntity 之类调用。@Mod 注解(BeeBetterAtBees.java:17-21)声明依赖:

required-after:NotEnoughItems;required-after:Forestry

gradle.properties 里 usesMixins = false,无 coremod、无 AccessTransformer 之外的补丁。 CommonProxy#registerNEIGUIs() 是空方法(CommonProxy.java:11), 所有实际逻辑只在客户端代理里。

注册方式

同一个 handler 实例被同时注册成两类处理器(ClientProxy.java:24-26):

BBABGuiRecipeTreeHandler handler = new BBABGuiRecipeTreeHandler();
API.registerRecipeHandler(handler);
API.registerUsageHandler(handler);

AbstractTreeGUIHandler#getRecipeHandler / getUsageHandler 每次都用 newInstance() 反射无参构造出一个新 handler 承载本次查询的结果, 实例字段 arecipes 承载当前页的配方列表。

蜜蜂物种根的加载

speciesRoot 是处理器唯一的静态状态(BBABGuiRecipeTreeHandler.java:37), 唯一的赋值点是 loadBeeRoot()(:208-215):

speciesRoot = (IBeeRoot) AlleleManager.alleleRegistry.getSpeciesRoot("rootBees");

rootBees 是 Forestry 的蜜蜂物种根 UID。找不到时只打一条 warn 日志, 不抛异常、不阻断加载。

因为加载可能失败或根本没被调用,loadCraftingRecipes / loadUsageRecipes 的每个入口都先判 speciesRoot == null 直接 return(:66、:74、:135、:143)。 rootBees 为空时这个 mod 静默失效——这是设计上的容错,不是崩溃路径。

合成侧与用途侧的匹配规则不同

侧 匹配字段 条件
合成 loadCraftingRecipes mutation.getTemplate()[0] 模板主位等于查询物种
用途 loadUsageRecipes getAllele0() 或 getAllele1() 父代任一等位等于查询物种

两侧都遵守 !mutation.isSecret() || shouldShowSecretRecipes, 并在末尾调用 cleanupDuplicateRecipes()。

源码缺陷

NEIBBABConfig 在仓库内没有任何引用点。 全仓库 grep -rn "NEIBBABConfig" src/ 只命中该文件自身的类声明与 javadoc,没有 new NEIBBABConfig(),也没有注册代码。 它 implements IConfigureNEI,其 loadConfig()(NEIBBABConfig.java:17) 是唯一调用 loadBeeRoot() 的地方,因此 speciesRoot 的填充依赖 NEI 侧的 附属加载机制而非本 mod 自己的生命周期。IConfigureNEI 还实现了 getName() / getVersion(),同样只用于 NEI 的显示。

cleanupDuplicateRecipes() 边遍历边删除。(:177-196) 它对 arecipes 做增强 for,同时又用 iterator.remove() 修改同一个列表, 命中重复后 break 并递归重入。逻辑上靠 break 规避了 ConcurrentModificationException,但递归 + O(n²) 的组合在大型 mod 组合(大量 secret 变异开启时)会很脆弱。

相关条目

  • 变异树布局与渲染 - CachedBeeMutationTree 如何由 mutation 构造出可看的树
  • 配置项 - shouldShowSecretRecipes / showDuplicateTrees
  • 依赖的 Forestry 与 NotEnoughItems 不在本 wiki 收录范围(relation.md 中无对应行), 此处不复述其内容。