我正在尝试向 Minecraft 源文件添加一个方法,但我必须弄清楚如何在不实际编辑源文件的情况下执行此操作,因为重新分发必须包含在我正在创建的 mod 中的源文件是非法的. 我需要将该方法添加setInPortalZub()
到位于 中的“EntityPlayer”文件中net.minecraft.entity.player
。我正在使用 MCP / Minecraft Forge API。我已尝试创建 的实例EntityPlayer
,但我不确定它是如何工作的。
1 回答
您即将进入美妙而令人沮丧的 coremods 世界!FML (Forge ModLoader) 中的 Coremods 是将任意代码注入原始 Minecraft 类的“最简单”方式,而无需分发这些类文件的修改版本。
这是通过利用Object
Web 发布的 ASM 字节码操作框架来实现的。该框架允许您编写可以在加载时读取和操作类的字节码的 java 代码。
我不可能解释完成这一壮举所必须采取的每一步,因此我将发布指向我自己的 coremod 注入类的链接,并尝试对每一个进行解释。
该类CorePlugin
告诉 Forge ModLoader 在哪里可以找到执行实际代码注入的转换器类。
FML 根据您的.jar
文件清单找到此类:
Manifest-Version: 1.0
FMLCorePlugin: bspkrs.treecapitator.fml.asm.TreeCapitatorCorePlugin
FMLCorePluginContainsFMLMod: bspkrs.treecapitator.fml.TreeCapitatorMod
Created-By: 1.7.0 (Oracle Corporation)
FMLCorePlugin
指定 CorePlugin 类的完全限定路径。如果您的.jar
文件也包含常规@Mod
样式的 Forge ModLoader mod 类,您还需要指定FMLCorePluginContainsFMLMod
(尽管预期值未知;我认为您在其中放置的值实际上并不重要,但键必须是那里)。
现在是有趣的部分......实际的字节码转换器。这是 Treecapitator 的变压器的链接
在不涉及太多细节的情况下,我编写了这个类以便能够在 Eclipse 和“生产”中处理执行。这就是为什么有两个HashMap
s;一种用于 MCP 执行,另一种用于混淆执行。每个被加载的类首先被传递到transform()
方法中。代码检查它是否是我们要转换的类,如果是则转换它。
实现这一切的最终结果是,每当ItemInWorldManager
创建一个实例时,转换器都会运行并将单行添加到removeBlock()
方法中的特定位置。这条单行作为一个廉价的块中断钩子,允许在玩家打破块时执行代码。
提示:
- 获取 Eclipse 的 ByteCode Outline 插件。您可以在 Object Web 网站上找到它。
- 有时 Eclipse/MCP 中的类结构与混淆环境中的类结构不同
- 这些不是容易理解的概念。使用 Bytecode Outline 插件来查看您正在转换的类,无论是否包含您希望它包含的代码。这应该可以帮助您弄清楚要寻找哪些“地标”以及您需要插入哪些 ASM 节点。
我希望这会有所帮助!
编辑:修复了断开的链接以引用仍然包含类的旧分支。