MineFactoryReloaded 兼容
事实基准:
harvestcraft-1.3.14-GTNH.jar(MC 1.7.10 / Forge 10.13.4.1614)CFR 0.152 反编译源码。
触发条件与安全性
| 属性 | 值 | 来源 |
|---|---|---|
| 依赖 modid | MineFactoryReloaded |
HarvestCraft.java:88 |
| 判定方式 | Loader.isModLoaded("MineFactoryReloaded") |
HarvestCraft.java:88 |
| 调用位置 | preInit |
HarvestCraft.java:88-90 |
| 入口 | PamMFRCompatibility.getRegistry() |
HarvestCraft.java:89 |
| 未安装时 | 整段被 if 跳过,安全 |
— |
| 注入通道 | powercrystals.minefactoryreloaded.api.FactoryRegistry.sendMessage |
PamMFRCompatibility.java:49 等 |
注入总量:348 条
PamMFRCompatibility.getRegistry()(PamMFRCompatibility.java:34-69)用 4 个循环完成注册:
| 循环 | 上界 | 每次迭代的 sendMessage 条数 |
有效注册条数 | 行 |
|---|---|---|---|---|
i < 60 |
60 | 4 | 240 | :48-53 |
i < 9 |
9 | 3 | 27 | :54-58 |
i < 24 |
24 | 3 | 72 | :59-63 |
i < 3 |
3 | 3 | 9 | :64-68 |
| 13 个字面调用点 | 348 |
字面
FactoryRegistry.sendMessage(...)在文件里只有 13 处(都在循环体内)。若只数调用点会严重少算(13 ≠ 348)。这里的 348 是按循环上界算出的有效注入条数。
每个循环注册的工厂类型
| 循环 | registerPlantable |
registerHarvestable |
registerFertilizable |
registerPickableFruit |
|---|---|---|---|---|
i < 60(作物) |
2(作物产物、种子各一) | 1 | 1(作物方块) | — |
i < 9(温带) |
— | — | 2(树苗 + 果实方块) | 1 |
i < 24(热带) |
— | — | 2 | 1 |
i < 3(原木类) |
— | — | 2 | 1 |
12 个静态数组(并行数组,按下标对齐)
PamMFRCompatibility.java:21-32 声明 12 个 public static 数组,在 getRegistry() 里赋值(:36-47)。数组长度与循环上界逐一核对,全部相等:
| 数组 | 元素类型 | 长度 | 对应循环上界 | 一致 |
|---|---|---|---|---|
PamCrops |
Block[] |
60 | 60 | ✔ |
PamCropItems |
Item[] |
60 | 60 | ✔ |
PamCropSeeds |
Item[] |
60 | 60 | ✔ |
PamTemperateSaplings |
Block[] |
9 | 9 | ✔ |
PamTemperateFruits |
Block[] |
9 | 9 | ✔ |
PamTemperateFruitItems |
Item[] |
9 | 9 | ✔ |
PamWarmSaplings |
Block[] |
24 | 24 | ✔ |
PamWarmFruits |
Block[] |
24 | 24 | ✔ |
PamWarmFruitItems |
Item[] |
24 | 24 | ✔ |
PamLogSaplings |
Block[] |
3 | 3 | ✔ |
PamLogFruits |
Block[] |
3 | 3 | ✔ |
PamLogFruitItems |
Item[] |
3 | 3 | ✔ |
没有 ArrayIndexOutOfBoundsException 风险——这一点是逐一计数核对的,不是看循环上界猜的。
7 个适配器类
| 类 | 实现的 MFR 接口 | 注入的工厂 | 关键行为 |
|---|---|---|---|
PlantableMFRCrop |
IFactoryPlantable |
registerPlantable |
把 Item(作物产物 / 种子)种成 Block(作物) |
HarvestableMFRCrop |
IFactoryHarvestable |
registerHarvestable |
canBeHarvested 要求 meta == 7(成熟);getDrops 转发 Block.getDrops;breakBlock() 返回 true |
FertilizableMFRCrop |
IFactoryFertilizable |
registerFertilizable |
canFertilize 要求 GrowPlant 且 meta < 7;fertilize 把 meta 设为 7 |
FertilizableMFRSapling |
IFactoryFertilizable |
registerFertilizable |
同上,针对树苗方块 |
FertilizableMFRFruit |
IFactoryFertilizable |
registerFertilizable |
同上,针对果实方块 |
PickableMFRFruit |
IFactoryFruit |
registerPickableFruit |
breakBlock() 返回 false(采摘不破坏);getReplacementBlock 返回同一方块、meta 0 |
PlantableMFRSapling |
—— | 无 | 仅 8 行,无接口实现 —— 见下 |
HarvestType.Normal 被用于全部 60 个作物的 registerHarvestable(PamMFRCompatibility.java:51)。
源码缺陷
| 位置 | 问题 | 有无运行时影响 |
|---|---|---|
PickableMFRFruit.java(构造器) |
构造器签名是 PickableMFRFruit(Block block, Item item, int meta),但方法体只赋值 _blockID 与 _itemID,meta 参数被完全丢弃。而 getReplacementBlock 硬编码 setMeta(0)。 |
无实际差异 —— 全部 36 个调用点(PamMFRCompatibility.java:56,61,66)传的 meta 都是 0。但参数本身是死参数。 |
PlantableMFRSapling.java |
文件仅 8 行,不实现任何 MFR 接口,全模组无任何引用。 | 无 —— 死代码。名字与 PlantableMFRCrop 极易混淆。 |
PamMFRCompatibility.java:45 |
PamTemperateFruitItems 的第一项是 Items.field_151034_e(原版苹果),不是 ItemRegistry.appleItem。 |
有语义影响 —— 温带苹果的"采摘产物"是原版苹果,而 pamApple 方块对应的是本模组的 appleItem。二者被有意配对(PamTemperateFruits[0] 是 BlockRegistry.pamApple,产物却是原版苹果)。SRG 名 field_151034_e 未解析;语义佐证:它在 PresserRecipes.java:22 同样作为"被压榨出 applejuiceItem 的输入"出现,而本模组另有 ItemRegistry.appleItem。 |
PamMFRCompatibility.java:47 |
PamLogFruitItems 三项是 ItemRegistry.cinnamonItem、ItemRegistry.maplesyrupItem、Items.field_151121_aF。 |
前两项本模组物品;第三项 field_151121_aF 为 SRG 名未解析,语义佐证:它是 pamPaperbark(纸皮树)的采摘产物,而 PamTreeGenerator.java:194 用 pamPaperbark 生成"原木树",说明该方块代表纸皮树皮。 |
未解析的 SRG 名
| SRG 名 | 出现 | 语义佐证 |
|---|---|---|
Items.field_151034_e |
PamMFRCompatibility.java:45 |
作为苹果的采摘产物 / 压榨输入 |
Items.field_151121_aF |
PamMFRCompatibility.java:47 |
作为纸皮树的采摘产物 |
world.func_72805_g |
FertilizableMFRCrop、HarvestableMFRCrop |
三参 (int,int,int) 取整数,与 meta 比较(== 7)→ World.getBlockMetadata |
world.func_72921_c |
FertilizableMFRCrop.java |
四参 (x,y,z,int) 写整数 → World.setBlockMetadata |
this.sourceId.getDrops |
HarvestableMFRCrop.java |
5 参返回 List<ItemStack> → Block.getDrops |