Mixin提供了几个接口供模组使用,这些接口全部位于org.spongepowered.asm.mixin.extensibility
包下
这个接口可以应用于运行时动态修改Mixin配置,以及有限地控制Mixin运作。
需要在json配置文件的plugin
属性中指定实现类的全名才能生效。
实现这个接口的类不能调用Minecraft中的任何代码和其他本不应该在CoreMod阶段调用的代码。
这个接口提供了以下方法:
onLoad
: 在插件所在的配置加载完成后调用,可以在这里做一些基本的模组初始化设置。getRefMapperConfig
: 只有当插件所在的配置文件中没有指定refmap
属性时,这个方法才会被调用,允许运行时动态指定refmap文件;- 需要返回refmap.json文件的文件名,如果返回
null
,则会用默认的refmap。
- 需要返回refmap.json文件的文件名,如果返回
shouldApplyMixin
: 在Mixin注入类即将合并到目标类前调用,传入两个参数:targetClassName
: 目标类全名;mixinClassName
: 注入类全名;- 需要返回一个布尔值,用于指示是否执行合并。
acceptTargets
: 在所有配置文件载入完成后调用,传入两个Set
,允许模组移除这两个Set
中的内容,但是往这两个Set
中添加任何内容都是无效的:myTargets
: 插件所在的配置文件中的所有目标类全名;otherTargets
: 其他配置文件中的所有目标类全名。
getMixins
: 这个方法允许模组动态添加注入类:- 需要返回一个
List
,其中存放要添加的注入类的全名,如果返回null
,则表示不添加任何内容。
- 需要返回一个
preApply
: 在注入类应用到目标类之前调用,传入四个参数:targetClassName
: 目标类全名;targetClass
: 目标类合并前的ClassNode
(注意类全名是org.spongepowered.asm.lib.tree.ClassNode
,而不是org.objectweb.asm.tree.ClassNode
,Mixin中包含了一个近乎完整的ASM库);mixinClassName
: 注入类全名;mixinInfo
: 传入一个IMixinInfo
类型的对象,目前只有一个类实现了这个接口:org.spongepowered.asm.mixin.transformer.MixinInfo
(这个类没有Javadoc)。
postApply
: 在注入类应用到目标类之后调用,传入四个参数:targetClassName
: 同上;targetClass
: 目标类合并后的ClassNode
;mixinClassName
: 同上;mixinInfo
: 同上。
之前介绍的用于注入的注解中有一个没有提到的属性:constraints
,为了避免出现兼容性等问题,这个属性的值会进行验证,只有验证通过才能成功注入到目标中去。
constraints
的值的格式是<token>(<constraint>)
:
<token>
: 必须是一串大写的字符串,而且必须有实现这个接口的类定义过这个字符串;getToken
: 接口中的这个方法正是定义处理这个<token>
的,方法传入两个参数:token
: 在constraints
中写的<token>
部分的字符串;env
: 表明当前的运行环境;- 要求返回一个
Integer
,这个值会和<constraint>
中写的进行比较,如果返回null
,则表示传入的token
未被定义,如果所有的IEnvironmentTokenProvider
实现类都对这个token
返回null
,那么就会抛出异常,游戏退出。
<constraint>
: 写一个和整型数字比较的规则:(1234)
: 表示要求getToken
必须返回1234;(>1234)
: 表示要求getToken
返回值必须大于1234;(1234+)
、(1234-)
、(1234>)
、(>=1234)
: 都表示要求getToken
返回值必须大于等于1234;(<1234)
: 表示要求getToken
返回值必须小于1234;(1234<)
、(<=1234)
: 都表示要求getToken
返回值必须小于等于1234;(1234-1300)
: 表示要求getToken
返回值在[1234, 1300]区间内;(1234+10)
: 表示要求getToken
返回值在[1234, 1244]区间内;
实现这个接口的类需要在引导Mixin时添加:
public void injectIntoClassLoader(LaunchClassLoader classLoader) {
MixinBootstrap.init();
Mixins.addConfiguration("mixins.example.json");
MixinEnvironment.getCurrentEnvironment().registerTokenProviderClass("com.example.ExampleTokenProvider"); // 也可以传入这个类的实例,主要用于当这个类没有无参构造方法时
}
这个接口可以用于当mixin运行出现异常时修改异常信息。
onPrepareError
: 当Mixin配置文件初始化出现异常时调用:config
: 出现异常的配置;th
: 引发的异常,此时允许修改异常的内容;mixin
: 传入一个负责处理这个配置文件的IMixinInfo
类型的对象;action
: 传入一个默认的异常等级;- 要求返回一个新的异常等级,如果返回
IMixinErrorHandler.ErrorAction.ERROR
,则表示要求抛出异常并退出游戏,如果返回null
,则表示使用默认的异常等级。
onApplyError
: 在应用Mixin注入出现异常时调用:targetClassName
: 引发异常的目标类全名;- 其余同上。
实现这个接口的类也需要在引导Mixin时添加:
public void injectIntoClassLoader(LaunchClassLoader classLoader) {
MixinBootstrap.init();
Mixins.addConfiguration("mixins.example.json");
Mixins.registerErrorHandlerClass("com.example.ExampleErrorHandler");
}