第三方兼容钩子
基本信息
| 属性 | 值 |
|---|---|
| 目标模组枚举 | me.eigenraven.lwjgl3ify.mixins.TargetedMod |
| 枚举项数 | 6 |
| 兼容钩子入口 | CommonProxy.runCompatHooks() / ClientProxy.runCompatHooks() |
| 由 mixin 门控的兼容条目 | 3(见 第三方模组兼容 Mixin) |
| 声明式依赖 | 无(@Mod 无 dependencies 参数) |
LWJGL3ify 不在 @Mod 注解中声明任何硬依赖。它与第三方模组的关系全部是"检测到就打补丁 / 没检测到就跳过",因此可以安全地出现在任何整合包里。
功能
TargetedMod 枚举的 6 个判定目标
TargetedMod.java:11 定义 6 项,各有独立的判定方式:
| 枚举项 | 判定方式 | 行 | 用途 |
|---|---|---|---|
FASTCRAFT_1_25 |
字节码常量扫描:在 fastcraft.a 的方法指令中查找连续的 LDC "fcVersion" + LDC "1.25" |
:13-26 |
STB_TEXTURE_STITCHING_FOR_FASCRAFT |
FASTCRAFT_ANY |
setCoreModClass("fastcraft.Tweaker") |
:27 |
STB_TEXTURE_STITCHING 的排除 / _FORCE 的必需 |
OPTIFINE |
setCoreModClass("optifine.OptiFineForgeTweaker") |
:28 |
STB_TEXTURE_STITCHING_FOR_FASCRAFT 的必需 |
XAEROS_MINIMAP |
setModId("XaeroMinimap") |
:29 |
XAEROS_MINIMAP_SCROLL |
XAEROS_WORLDMAP |
setModId("XaeroWorldMap") |
:30 |
XAEROS_WORLDMAP_SCROLL |
OPENCOMPUTERS |
setCoreModClass("li.cil.oc.client.launch.TransformerLoader") + setModId("OpenComputers") 双重 |
:32-33 |
OPENCOMPUTERS_KEYBOARD_INPUT_FIX |
FASTCRAFT_1_25 的判定尤其特殊:它不按 modId 或 coremod 类,而是打开 fastcraft.a 的 ASM 树,在每个方法的指令序列中找 "fcVersion" 后紧跟 "1.25" 的两个 LdcInsnNode(:17-24)。源码注释写明理由:“we look for the strings in the call”(:15),对应 FastCraft 自身的 Launch.blackboard.put("fcVersion", "1.25")。
OPENCOMPUTERS 的双重判定带注释"Support both the NH fork and upstream"(TargetedMod.java:31)——因为 NH 分支与上游 OpenComputers 的 TransformerLoader 位置不同。
CoFH AccessTransformer 修补
CommonProxy.runCompatHooks()(CommonProxy.java:11-24)是唯一的通用兼容钩子。它反射操作 COFHCore 的访问转换器:
Class.forName("cofh.asm.CoFHAccessTransformer")(:14)。- 取其静态字段
superClasses并setAccessible(true)(:15-16)。 - 往
HashMap里塞两条映射(:18-19):org/lwjgl/openal/OpenALException→java/lang/RuntimeExceptionorg/lwjglx/openal/OpenALException→java/lang/RuntimeException
- 打 INFO 日志
"Installed CoFH AT compatibility"(:20)。
触发动机见 :12 注释:“Fix crash with OpenComputers/COFHCore due to a class extending OpenALException”。
这是刻意的静默降级:catch (ReflectiveOperationException e) 的 catch 块体只有一行注释 // ignore - cofh not present(:21-23),既不打日志也不重抛。装了 COFHCore 却修补失败时不会有任何提示。
该钩子在 preInit 最开始被调用——Lwjgl3ify.java:42 的 PROXY.runCompatHooks()。
ClientProxy 追加的客户端行为
ClientProxy.runCompatHooks()(ClientProxy.java:45-56)在 super.runCompatHooks() 之后:
Config.DEBUG_REGISTER_OPENGL_LOGGER为真时调GLDebugLog.setupDebugMessageCallback()(:47-49)。Keyboard.populateKeyLookupTables()—— 填充依赖键盘布局的查表(:51)。registerKeybindHandler()—— 向InputEvents注册一个内部McKeybindHandler(:52、:69-71)。该处理器onKeyEvent是空实现,onTextEvent转发给TextFieldHandler.onTextInput(:58-67)。FMLCommonHandler.instance().bus().register(this)(:53-55)。
声明依赖的真相
@Mod 注解(Lwjgl3ify.java:21-27)没有 dependencies 参数,acceptableRemoteVersions = "*"、acceptedMinecraftVersions = "[1.7.10]"。mcmod.info 的 requiredMods / dependencies / dependants 三个数组全为空(mcmod.info:15-17)。
实际依赖由 README 文字声明而非 FML 元数据表达:必须使用 UniMixins 0.1.23+ 的 GTNHMixins 模块;Hodgepodge 强烈推荐(README 说明它含 LWJGL3ify 无法在 GTNH 分支中直接修复的 Biomes’o’Plenty / Witchery / JourneyMap 等 mod 的 Java 17+ 兼容补丁)。
Hodgepodge 之所以不写成 FML 依赖,从源码可反推:两个 Xaeros mixin 明确用 expect = -1 容忍 Hodgepodge 的重复补丁(XaerosMinimapScrolling.java:19 的注释"Optional because an old hodgepodge patch might also do the same")。写成硬依赖反而会破坏这种可共存设计。
ModularUI2 的 API 消费
ModularUI2 通过 compileOnlyApi 依赖本模组的 :api 产物:
- 依赖声明:
com.github.GTNewHorizons:lwjgl3ify:3.0.34:api+transitive = false(ModularUI2/dependencies.gradle:33) - 使用的类型:
me.eigenraven.lwjgl3ify.api.InputEvents(ModularPanel.java:39、ModularScreen.java:25、ModernInteractable.java:7、IMuiScreen.java:18、OverlayInputHandler.java:8、BaseTextFieldWidget.java:23) - 软绑定方式:
@Optional.Interface(modid = "lwjgl3ify", iface = "me.eigenraven.lwjgl3ify.api.InputEvents$KeyboardListener")(IMuiScreen.java:36、OverlayInputHandler.java:13) - 实现接口:
IMuiScreen extends InputEvents.KeyboardListener(IMuiScreen.java:39)、OverlayInputHandler implements InputEvents.KeyboardListener(OverlayInputHandler.java:14)
注意:这是
compileOnlyApi——编译期可见、运行期不强制。ModularUI2 用@Optional.Interface做软绑定,因此不装 lwjgl3ify 也能运行,只是收不到原始按键事件。这是本 mod 被其他 mod 依赖的典型形态,与硬依赖不同。
数值
| 数值 | 值 |
|---|---|
TargetedMod 枚举项 |
6 |
| 按 modId 判定 | 3(XaeroMinimap、XaeroWorldMap、OpenComputers 之一) |
| 按 coremod 类判定 | 3(FastCraft、OptiFine、OpenComputers 之一) |
| 按字节码常量判定 | 1(FASTCRAFT_1_25) |
mcmod.info 声明的依赖数 |
0(三个依赖数组均为空) |
@Mod(dependencies = ...) |
未声明 |
| README 声明的必需前置 | UniMixins 0.1.23+(GTNHMixins 模块) |
| README 声明的强烈推荐 | Hodgepodge |
| 已知外部 API 消费者 | 1(ModularUI2) |
已知静默失败点
| 位置 | 行为 | 后果 |
|---|---|---|
CommonProxy.java:21-23 |
catch (ReflectiveOperationException e) 块体仅有一行注释 |
装了 COFHCore 但修补失败时完全无日志 |
LwjglRedirectTransformer.java:106-108 |
catch (Exception e) 打 WARN 后 return false |
该类以未转换状态继续加载 |
Lwjgl3ifyCoremod.java:31-36 |
catch (ClassCastException e) 打 warn |
非 LaunchWrapper 启动时排除包失败 |
Lwjgl3ify.java:83-85 |
catch (ReflectiveOperationException e) 打 LOG.warn |
排除项清单打印失败不影响启动 |
其中第一条是本条目内最值得注意的:它是唯一一条完全不留日志的兼容钩子失败路径。
交互
| 触发 | 行为 |
|---|---|
| 装有 CoFHCore | preInit 时修补 OpenALException 继承关系(成功打 INFO) |
| 未装 CoFHCore | Class.forName 抛 ClassNotFoundException,静默跳过 |
| 装有 XaeroMinimap / XaeroWorldMap | 启用对应滚轮归一化 mixin |
| 装有 OpenComputers | 启用 InputBuffer 键盘输入修复 mixin |
| 装有 FastCraft(任意版本) | 禁用 MixinStitcher,除非开 stbiIgnoreFastcraft |
| 装了 Hodgepodge | 重复补丁被 expect = -1 静默跳过 |
| 装了 ModularUI2 | ModularUI2 获得 InputEvents.KeyboardListener 回调 |
| 未装 lwjgl3ify | ModularUI2 仍可运行(软绑定) |
相关条目
- 第三方模组兼容 Mixin - 3 个受
TargetedMod门控的条目 - 纹理加载与拼接 Mixin - FastCraft / OptiFine 门控的条目
- 输入与显示事件 API - ModularUI2 消费的
InputEvents - LWJGL2→LWJGL3 兼容层 -
OpenALException修补的包路径 - FML 加载插件 -
runCompatHooks()的调用点