简体   繁体   English

如何在不编辑源文件的情况下将方法添加到源文件?

[英]How do I add a method to a source file without editing the source file?

I am trying to add a method to a Minecraft source file, but I have to figure out how to do it without actually editing the source files, since it is illegal to redistribute source files which would have to be included in the mod I am creating. 我正在尝试向Minecraft源文件添加一个方法,但我必须弄清楚如何在不实际编辑源文件的情况下进行,因为重新分发源文件是非法的,这些源文件必须包含在我正在创建的mod中。 I need to add the method setInPortalZub() to the file "EntityPlayer located in net.minecraft.entity.player . I am using the MCP / Minecraft Forge API. I have tried creating an instance of EntityPlayer , but I'm not exactly sure how that would work. 我需要将方法setInPortalZub()添加到位于net.minecraft.entity.player的文件“EntityPlayer。我正在使用MCP / Minecraft Forge API。我尝试创建EntityPlayer的实例,但我不确定怎么会这样。

You are about to enter the wonderful and frustrating world of coremods! 你即将进入coremods奇妙而令人沮丧的世界! Coremods in FML (Forge ModLoader) are the "easiest" way to inject arbitrary code into vanilla Minecraft classes without having to distribute modified versions of those class files. FML中的Coremod(Forge ModLoader)是将任意代码注入vanilla Minecraft类的“最简单”方法,而不必分发这些类文件的修改版本。

This is accomplished by utilizing the ASM Bytecode manipulation framework released by Object Web. 这是通过利用Object Web发布的ASM Bytecode操作框架来实现的。 This framework allows you to write java code that can read and manipulate the bytecode of a class at load time. 此框架允许您编写可在加载时读取和操作类的字节码的Java代码。

It is impossible for me to explain every step you must take to accomplish this feat, so instead I will post links to my own coremod injection classes and attempt to give an explanation of each. 我不可能解释你必须采取的每一步来完成这一壮举,所以我会发布链接到我自己的coremod注入类,并试图解释每一个。

Here is the CorePlugin class. 这是CorePlugin类。

The CorePlugin class tells Forge ModLoader where to find your transformer class that does the actual code injection. CorePlugin类告诉Forge ModLoader在哪里找到执行代码注入的转换器类。

This class is found by FML based on your .jar file manifest: 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 specifies the fully qualified path to your CorePlugin class. FMLCorePlugin指定CorePlugin类的完全限定路径。 If your .jar file is to contain a regular @Mod style Forge ModLoader mod class as well you will also need to specify FMLCorePluginContainsFMLMod (although the expected value is unknown; I don't think it actually matters what you put for the value there, but the key must be there). 如果您的.jar文件要包含常规的@Mod样式Forge ModLoader mod类,那么您还需要指定FMLCorePluginContainsFMLMod (虽然期望的值是未知的;我认为它实际上并不重要你为那里的值,但关键必须在那里)。

Now for the fun part... the actual bytecode transformer. 现在为有趣的部分......实际的字节码转换器。 Here is a link to the transformer for Treecapitator 这是Treecapitator变换器的链接

Without going into too much detail, I wrote this class to be able to handle execution both in Eclipse as well as in "production". 在没有详细介绍的情况下,我编写了这个类,以便能够在Eclipse和“生产”中处理执行。 That's why there are two HashMap s; 这就是为什么有两个HashMap ; one for MCP execution and one for obfuscated execution. 一个用于MCP执行,另一个用于混淆执行。 Every class that gets loaded is first passed into the transform() method. 每个加载的类首先传递给transform()方法。 The code checks to see if it's a class we want to transform and transforms it if it is. 代码检查它是否是我们想要转换的类,如果是,则转换它。

The end result of implementing all this is that whenever an instance of ItemInWorldManager is created the transformer runs and adds a single line to a specific location within the removeBlock() method. 实现所有这一切的最终结果是,无论何时创建ItemInWorldManager的实例,变换器都会运行,并将一行添加到removeBlock()方法中的特定位置。 This single line serves as a cheap block break hook to allow for code to execute when a player breaks a block. 这一行作为一个廉价的块中断钩子,允许代码在玩家打破一个块时执行。


Tips: 提示:

  • Get the ByteCode Outline plugin for Eclipse. 获取Eclipse的ByteCode Outline插件。 You can find it on the Object Web website. 您可以在Object Web网站上找到它。
  • Sometimes the class structure isn't the same in Eclipse/MCP as it is in an obfuscated environment 有时,Eclipse / MCP中的类结构与混淆环境中的类结构不同
  • These are not easy concepts to wrap your head around. 这些都不是简单的概念。 Use the Bytecode Outline plugin to view the class you are transforming both with and without the code you want it to contain. 使用Bytecode Outline插件查看要转换的类,无论是否包含要包含的代码。 That should help you figure out what "landmarks" to look for and what ASM nodes you'll need to insert. 这应该可以帮助您找出要查找的“标记”以及您需要插入的ASM节点。

I hope that helps! 我希望有所帮助!

EDIT: fixed the broken links to reference an old branch that still contains the classes. 编辑:修复损坏的链接以引用仍包含类的旧分支。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM