Skip to content

Latest commit

 

History

History
79 lines (72 loc) · 5.73 KB

5.7.md

File metadata and controls

79 lines (72 loc) · 5.73 KB

扩展

Mixin提供了几个接口供模组使用,这些接口全部位于org.spongepowered.asm.mixin.extensibility包下

这个接口可以应用于运行时动态修改Mixin配置,以及有限地控制Mixin运作。
需要在json配置文件的plugin属性中指定实现类的全名才能生效。
实现这个接口的类不能调用Minecraft中的任何代码和其他本不应该在CoreMod阶段调用的代码。

这个接口提供了以下方法:

  • onLoad: 在插件所在的配置加载完成后调用,可以在这里做一些基本的模组初始化设置。
  • getRefMapperConfig: 只有当插件所在的配置文件中没有指定refmap属性时,这个方法才会被调用,允许运行时动态指定refmap文件;
    • 需要返回refmap.json文件的文件名,如果返回null,则会用默认的refmap。
  • 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");
}