兼容层总览
事实基准:
harvestcraft-1.3.14-GTNH.jar(MC 1.7.10 / Forge 10.13.4.1614)CFR 0.152 反编译源码。
概览
本模组对外部模组的兼容全部通过 FML 的 IMC(FMLInterModComms) 与 Loader.isModLoaded 条件判断完成,没有 @Optional.Interface 之外的类加载技巧,没有 Class.forName 反射降级。目标模组没装时一律安全跳过。
| 目标模组 | modid | 注入方式 | 触发条件 | 条件是否来自配置 | 注入量 | 条目 |
|---|---|---|---|---|---|---|
| Thaumcraft | Thaumcraft |
IMC harvestStandardCrop |
Loader.isModLoaded("Thaumcraft") |
否(硬编码) | 95 条作物注册 | Thaumcraft |
| MineFactoryReloaded | MineFactoryReloaded |
FactoryRegistry.sendMessage |
Loader.isModLoaded("MineFactoryReloaded") |
否(硬编码) | 348 条工厂注册 | MFR |
| MrCrayfish’s Furniture Mod | cfm |
IMC register → 反射调用字符串 |
ItemRegistry.enablemrcrayfishcompatibility |
是(general 分类,默认 true) |
92 条配方 | Crayfish |
| NotEnoughItems | NotEnoughItems |
IMC registerHandlerInfo / registerCatalystInfo |
无 —— 无条件发送 | 否 | 4 个 handler + 2 个 catalyst | NEI |
| AppleCore | AppleCore |
源码内直接分支调用 | 静态字段 isLoadedAppleCore |
否 | 改写吃完蛋糕后的效果 | 见下 |
逐个条件的源码位置
| 位置 | 条件 | 结果 |
|---|---|---|
HarvestCraft.java:78-80 |
if (Loader.isModLoaded("Thaumcraft")) { PamThaumcraftAspectsList.getRegistry(); } |
有则注入 95 条 |
HarvestCraft.java:88-90 |
if (Loader.isModLoaded("MineFactoryReloaded")) { PamMFRCompatibility.getRegistry(); } |
有则注入 348 条 |
HarvestCraft.java:128-130 |
if (ItemRegistry.enablemrcrayfishcompatibility) { sendMessage("cfm", "register", "…CrayfishCompatibility.registerRecipes"); } |
由配置控制 |
HarvestCraft.java:131-142 |
无 if —— 4 次 sendNEIHandler + 2 次 registerCatalystInfo 无条件执行 |
永远发送 |
HarvestCraft.java:161 |
isLoadedAppleCore = Loader.isModLoaded("AppleCore")(静态初始化块) |
只赋值;唯一读取点是 BlockPamCake.java:80 |
未安装时是否安全
- Thaumcraft / MFR:包在
if (Loader.isModLoaded(...))内,未安装则整段不执行。安全。 - Crayfish:由配置布尔控制。但 IMC 的接收方是
"cfm";若 CfM 未安装,FML 会把这条消息丢弃(IMC 对不存在的目标 modid 不报错)。安全。 另注:HarvestCraft.java:129传的是方法名字符串"com.pam.harvestcraft.CrayfishCompatibility.registerRecipes",CfM 侧需自行反射调用——本模组不保证 CfM 存在时的调用成功。 - NEI:无条件发送 6 条 IMC 消息。若 NEI 未安装,消息被丢弃。安全,但这些消息永远不会在未装 NEI 的环境下生效,因此"无条件"等价于"有 NEI 时才生效"。
sendIMCMessages() 的调用时机
HarvestCraft.sendIMCMessages() 是 private static,在 init()(FMLInitializationEvent)第 116 行调用一次(HarvestCraft.java:116),而不是 preInit。而 Thaumcraft / MFR 的注入在 preInit 里(:78-90)。
因此跨模组注入分成两个阶段:
| 阶段 | 位置 | 内容 |
|---|---|---|
preInit |
HarvestCraft.java:78-90 |
Thaumcraft、MFR |
init |
HarvestCraft.java:116 |
Crayfish、NEI |
另一个常被误读的类名
PamThaumcraftAspectsList(类名含 “Aspects”)不注册任何 aspect。它只发 harvestStandardCrop 这一种 IMC 消息。Aspect 与 AspectList 仅出现在 import(PamThaumcraftAspectsList.java:11-12)里,没有任何使用点 —— 详见 Thaumcraft 兼容。
AppleCore:唯一一处非 IMC 的兼容
isLoadedAppleCore 在静态初始化块里取值(HarvestCraft.java:161),唯一读取点是 BlockPamCake.java:80:
if (HarvestCraft.isLoadedAppleCore) {
this.onEatenCompatibility(new ItemStack((Block)this), player);
} else {
player.func_71024_bL().func_75122_a(2, 0.1f);
}
- 装了 AppleCore:走
onEatenCompatibility(...)(本模组自己的兼容实现,位于BlockPamCake)。 - 没装:给玩家加
2点饥饿、0.1f饱和度(func_71024_bL()= 玩家饥饿属性容器,SRG → 未解析;func_75122_a(int, float)为addStats族方法,SRG → 未解析;语义佐证:第二参数是float饱和度、第一参数是int饥饿点)。 - 这是本模组唯一一处用布尔开关分支(而非 IMC)实现的兼容。
未使用的类路径
NEIHarvestcraftConfig 在源码中有两份:
| 路径 | 行数 | 作用 |
|---|---|---|
com/pam/harvestcraft/NEIHarvestcraftConfig.java |
33 | 注册 3 组 NEI 配方/用途 handler |
com/pam/harvestcraft/compat/NEIHarvestcraftConfig.java |
138 | 调 API.hideItem 隐藏大量内部方块 |
两者都没有 @Mod 注解或 NEI 的 @IConfigureNEI 注册点被本模组引用。NEI 侧要生效必须由外部按类名/包路径加载——本模组不主动注册这两个类。详见 NEI 兼容。