Learn · frameworks
Mixin 是什么?字节码注入详解
Mixin 是一个字节码注入库,它允许模组在加载时修改 Minecraft 的编译后的类。以下是如何进行注入以及为什么每个现代模组都需要它的说明.
什么是 Minecraft 中的 Mixin?
Mixin 是一个字节码注入库,它允许模组在游戏加载时修改 Minecraft 的编译后的类,而无需触及原始源代码。一个模组会编写一个小类,指示“将此代码插入到此游戏方法中的此位置”,Mixin 会在 JVM 加载目标类的那一刻,将该代码编织到字节码中。Fabric 将其用作其核心模组机制。
简而言之:Minecraft 以编译后的 Java 代码形式发布。Mixin 将这些编译后的类视为构建的基础,并在游戏运行任何帧之前在内存中编辑它们。
Mixin 的字节码注入是如何工作的?
Mixin 在编译和执行之间工作。游戏类已经编译,但 JVM 尚未加载它。这就是 Mixin 利用的窗口。一个模组将带有注释的 Mixin 类交给加载器,当该游戏类被加载时,Mixin 会实时重写其字节码,将模组的代码融入其中。
这些注释是整个诀窍所在。它们不描述游戏文件的每一行代码,而是描述您想要到达的位置:方法的顶部、返回值、其中的特定调用、局部变量。Mixin 会在字节码中找到该位置,并在其周围缝合您的指令.
这必要是因为 Minecraft 从未被设计成可以扩展的。对于模组想要修改的大部分内容,官方都没有提供插件 API。Mixin 就是答案:如果游戏不给你提供钩子,你就自己将钩子刻入编译后的代码中。
为什么模组选择 Mixin 而不是直接编辑游戏?
两个理由支撑着整个论点:兼容性和更新生存。
直接编辑游戏源代码,你就必须分发 Minecraft 的完整修改副本。其他人无法在你基础上构建,而且一旦游戏更新,它就会崩溃。Mixin 补丁是小而精准的,这意味着数十个模组可以同时修改同一款游戏,而无需分发完整的克隆版本。
| 方法 | 是否能与其他模组共存 | 是否能承受游戏更新 | 以什么形式发布 |
|---|---|---|---|
| 手动编辑编译后的游戏 | 否,只有一个分支获胜 | 否,任何更改都会导致崩溃 | 一个完整的修改后的 jar 文件 |
| Mixin 注入 | 是,补丁可以叠加 | 通常,如果方法仍然存在 | 少量的小类 |
第二个柱子是安静的超能力。因为 Mixin 说的是“在这里注入”,而不是“文件必须完全是这样”,许多 Mixin 可以在零修改的情况下跨版本继续工作。这就像描述一个目的地,而不是记住一张地图的区别。
Mixin 如何融入 Fabric??
Fabric 的构建依赖于 Mixin,句点。加载器读取每个模组的 Mixin 配置文件,收集配置文件中列出的 Mixin 类,并将它们交给 Mixin,以便在类加载时应用。您无需手动配置任何内容;在配置文件中声明您的 Mixin 便是完整的集成。
一个典型的 Fabric 模组主要由其自身的常规类组成,外加少量用于钩住其真正需要修改的几个游戏方法的 Mixin。模组的实际逻辑存在于常规代码中。Mixin 仅仅是控制权在正确时机被获取的薄层.
常见的 Mixin 注入点有哪些?
你选择的注入类型决定了补丁的侵入性以及它与其他模组的兼容性。轻微的修改更安全且不易受更新影响。更重的修改可以让你获得更多控制权,但会牺牲稳定性。
| 注释 | 它做什么 | 何时使用 |
|---|---|---|
@Inject | 在目标方法中选定的点运行你的代码 | 默认选项;侵入性最小,更新兼容性最好 |
@Redirect | 替换目标方法内部的一个特定方法调用 | 替换单个调用,无需重写方法 |
@ModifyArg | 更改传递给目标方法调用中的参数 | 调整进入调用的一个值 |
@ModifyVariable | 在方法中间重写局部变量 | 调整方法已经计算的状态 |
@Overwrite | 替换整个方法 | 最后的选择;与其他任何修改该方法的内容冲突 |
@Inject 是主力军,因为它精确且得体。它在精确的位置插入代码,而不影响方法中的其他部分,这正因如此,它往往能经受住更新的考验,并且很少与其他模组发生冲突。@Overwrite 则位于另一端:它会摧毁整个方法,因此任何其他模组也想修改该方法都会失败。优秀的 Mixin 故意保持其影响范围小.
干净的注入点也是移除模组瞬间完成的原因。没有任何东西被写入你的文件,所以移除模组会连同所有更改一起移除.
为什么 Mixin 对严肃客户至关重要
这是 Terminus 构建的基础。一款优质的实用型客户端的生死取决于它如何干净利落地融入游戏,而 Mixin 正是使这成为可能的方式,无需分发一个被破坏的 Minecraft 副本。狭窄的注入点可确保客户端与您已安装的模组兼容,并且在游戏更新时也能保持稳定,而不是在补丁发布时崩溃。理解 Mixin 是最快的方式,可以让你看到一个构建良好的客户端如何感觉像是游戏的一部分,而不是一个脆弱的附加组件。
常见问题解答
Mixin 并不是一个独立的下载库,而是模组构建所用的工具。像 Fabric 这样的加载器会内置 Mixin,并在游戏加载时应用模组声明的混入.
不,所有补丁都发生在类加载时内存中。磁盘上的jar文件从不改变,这就是删除模组可以完全移除其行为,并且没有任何残留的原因.
当两个补丁以冲突的方式打补丁时,一个可以覆盖另一个。罪魁祸首通常是 @Overwrite。使用窄注入点的 Mixins,例如 @Inject,能更可靠地共存.
Mixin 是一个通用的 Java 字节码框架. Minecraft modding 往往是在最需要使用的场合才会大显身手,而且 Fabric 标准化它使其成为生态系统默认的工具.
获取Terminus
Built on clean Mixin hooks, not a hacked-up jar.