Coremod 与 ASM 变换器
[!INFO] 实现类:
makamys.coretweaks.CoreTweaksPlugin(@MCVersion("1.7.10")) 声明:gradle.properties的coreModClass = CoreTweaksPlugin
基本信息
CoreTweaks 是双重身份 mod:既是 @Mod 普通模组,也是
IFMLLoadingPlugin coremod。二者由 Gradle 分别声明:
| 机制 | 声明位置 | 值 |
|---|---|---|
| coremod | gradle.properties coreModClass |
CoreTweaksPlugin |
| 访问变换器 | gradle.properties accessTransformersFile |
coretweaks_at.cfg |
| Mixin | gradle.properties usesMixins |
true |
⚠️ CoreTweaksPlugin.getAccessTransformerClass() 返回 null,
尽管 META-INF/coretweaks_at.cfg 确实存在。AT 生效靠的是
ForgeGradle 把该文件打进 jar 并由 FML 扫描 META-INF,
不是靠 coremod 回调。
构造即执行
CoreTweaksPlugin 的构造函数就调用了重逻辑:
public CoreTweaksPlugin() {
LOGGER.info("Instantiating CoreTweaksPlugin");
Config.reload();
CoreTweaks.init();
}
CoreTweaks.init() 负责构造纹理加载器、变换器缓存、
jar 发现器缓存等跨越整个类加载生命周期的长生命周期对象 ——
它们必须在任何类被转换之前就位,故只能放在 coremod 构造期。
3 个 ASM 变换器
getASMTransformerClass() 按配置动态返回类名数组:
| 变换器类 | 门控配置 | 默认 | 额外条件 |
|---|---|---|---|
asm.ModDiscovererTransformer |
forgeModDiscovererSkipKnownLibraries |
true | — |
asm.FMLFastSplashTransformer |
forgeFastProgressBar |
true | !isForgeSplashEnabled() |
asm.FMLLogTransformer |
forgeFixLoggerClassLoadingError |
true | — |
@Override public String[] getASMTransformerClass() {
List<String> transformerClasses = new ArrayList<>();
if (Config.forgeModDiscovererSkipKnownLibraries.isActive())
transformerClasses.add("makamys.coretweaks.asm.ModDiscovererTransformer");
if (!MixinConfigPlugin.isForgeSplashEnabled()) {
if (Config.forgeFastProgressBar.isActive())
transformerClasses.add("makamys.coretweaks.asm.FMLFastSplashTransformer");
}
if (Config.forgeFixLoggerClassLoadingError.isActive())
transformerClasses.add("makamys.coretweaks.asm.FMLLogTransformer");
return transformerClasses.toArray(new String[] {});
}
三者互相独立:数组可能为空、含 1、2 或 3 个元素。
⚠️ isForgeSplashEnabled() 定义在
MixinConfigPlugin(Mixin 侧)却被 coremod 侧调用 ——
同一份逻辑在 ASM 与 Mixin 两条路径间共享。
其余 IFMLLoadingPlugin 回调
| 回调 | 返回 | 说明 |
|---|---|---|
getASMTransformerClass |
动态数组 | 见上 |
getModContainerClass |
null |
不提供自定义 mod 容器 |
getSetupClass |
null |
不提供 setup 类 |
injectData |
空实现 | 不读 data map |
getAccessTransformerClass |
null |
⚠️ 见上文 AT 说明 |
后三项源码里均带 // TODO Auto-generated method stub 注释,
即从未实现过,是 FML 接口的占位空实现。
访问变换器 META-INF/coretweaks_at.cfg
全文仅 1 行:
public net.minecraft.entity.player.EntityPlayer field_71074_e #itemInUse
把 EntityPlayer 的私有字段 itemInUse(玩家正在使用的物品,
即进食/喝瓶/举盾的计数)由 private 放宽为 public。
用途:供 bugfix/DoubleEatFixer 读取该字段以修复
「额外食物被静默吞掉」(MC-849),该修复在 CoreTweaks 中
不经 Mixin,而是普通事件监听器
(CoreTweaksMod.init() 中 Config.fixDoubleEat.isActive() 时
FMLCommonHandler.instance().bus().register(new DoubleEatFixer()))。
三条变换路径的关系
| 路径 | 阶段 | 用途 |
|---|---|---|
| ASM coremod | 最早期 | 3 个 FML/Forge 自身类变换(发现器、启动画面、日志) |
| Mixin | PREINIT / INIT / DEFAULT | 37 个,见 动态 Mixin 注册 |
| AT | 类加载期 | 1 个字段可见性放宽 |
注意 fixDoubleEat 是唯一走 AT + 事件监听器的 bugfix,
不走 Mixin —— 其余 11 个 bugfix Mixin 均不需要 AT。
日志记录
CoreTweaks 持有静态 logger LogManager.getLogger("coretweaks"),
并额外提供 CoreTweaks.logger() 工厂方法,注释说明用途:
Attempts to create a new logger every time it’s called. This should be used in shutdown hooks, since the LOGGER reference becomes invalid.
coremod 侧的 LOGGER 来自 import static ...CoreTweaks.LOGGER。
相关条目
- 动态 Mixin 注册 - 37 个 Mixin 的注册入口
- CoreTweaks 配置 - 3 个 ASM 门控开关
- Bugfix Mixin -
fixDoubleEat走 AT 而非 Mixin