原地址:https://github.com/tModLoader/tModLoader/wiki/Expert-IL-Editing
介绍
本教程探讨了IL的编写方法。IL编辑是一种非常强大的技术,通过IL编辑,你可以让自己的mod更改Terraria原游戏的任何一处代码,而无需依赖TModLoader的钩子。IL编辑的意思是中间语言(Intermediate Language)编辑,其实就是说我们正在按照需要编辑已经编译好的代码,这对于一些不需要TModLoader方法的晦涩难懂的方法非常有用。在进行IL编辑时,请确保您的代码已经兼容了其他mod可能修改的同一处内容。IL编辑的功能非常强大,但是如果可能的话,请尽量尝试使用TModLoader的钩子,因为他们可以比IL编辑更好地兼容多个mod。如果以上的顾虑您都考虑清楚了,就请继续往下看吧。
限制
请注意,CLR(Common Language Runtime,通用语言运行平台)将在运行的时候内嵌短方法(short method),IL技术不能用于编辑这些方法,但是什么算是短方法还没有明确的定义,不过Properties这样的东西可能算是。
准备工作
·dnSpy - 我们在设计IL补丁的时候需要用到dnSpy的反编译功能
·IDE 如 Visual Studio 或其他
·泰拉瑞亚源代码 - 在源码里面找到你想要的内容是非常有帮助的
补丁位置
你可以吧补丁放在你mod的任何一个位置,但是Mod类的Load方法或者是任何一种AutoLoad方法应该是你的首选。

示例 - 蜂巢背包的升级
目标
本教程将要实现的目标是让玩家装备蜂巢背包时,各种蜜蜂武器更加强大。原版中当玩家装备蜂巢背包时,player类的strongBees字段将会被赋值true,并且生成的蜜蜂将可能变为大蜜蜂。为了实现我们的蜂巢背包升级,我们将要修改代码引用player类的strongBees字段,让它有一定的几率生成蜜蜂手雷。

原版方法
首先我们先来看看原版中的方法是怎么写的,并构思一下我们要对IL代码进行哪些更改。用dnSpy打开Terraria.exe,依次在右侧的列表里面打开Terraria,Terraria.exe,Terraria和Player的选项卡,然后向下寻找并选中beeType()方法。这里有一点要说一下,我们在修改的时候怎么才能找到自己想要的方法呢?答案是经验,首先我们知道,目标是修改蜂巢背包使得蜜蜂武器射出蜜蜂手雷,那么关于饰品的效果代码开发者会放在哪里?当然是人物代码里面。所以我们便锁定了Player类,然后源码肯定不是一个人写出来的,如果想要让其他程序员看懂代码,要么这位编写者添加了注释,要么他便是直接起了关于蜜蜂的方法名,因此我们试着寻找bee这个单词,发现有beeType()这个方法,那么我们便可以开始细读这个方法的内容。在确定他就是原版执行蜂巢背包功能的方法后我们便成功了——找到了原版的方法。在需要修改其他的内容时也是如此,通过英文猜测大概的方法,之后细细读它的意思。
然后我们将看到如下画面


这就是原版方法的C#代码,如果你去查projectileID的话,你会发现566是大蜜蜂,181是蜜蜂,我们的计划是添加进去蜜蜂手雷的可能性,并返回183也就是蜜蜂手雷的projectileID,如下图所示。

这就满足了我们的需求,但是应该怎么改呢?首先我们来利用dnSpy查看这个方法的IL代码。在菜单栏里面单击下拉组合框并切换到IL语言,我们会看到这样的东西。

啊,这是一堆什么破玩意啊,压根看不懂
爷——不——写——了!!!!(不是)
别着急,我们先来看一眼OpCode文档:

翻译版本:

(如果还是看不懂我之后试着发一篇解读的文章,或者你可以自己上网学习堆栈的相关知识)
现在我们已经了解了原始的方法,让我们用dnSpy来看看更改后的样子,首先我们右键beeType()方法并单击Edit Method(C#)...

在弹出的窗口中我们来更改原方法,然后单击编译

如果您缺少程序集引用或者代码有错误,那么您将看到一些错误提示。如何解决呢?首先我们需要将using Terraria.ID; 和 using ExampleMod;添加到代码中(ExampleMod改成你自己的mod名)。然后我们为ReLogic和ExamplePlayer添加缺失的引用,在 \Documents\My Games\Terraria\ModLoader\references目录下你可以找到ReLogic.dll。然后如果你已经编译了你的mod,你可以在 \Documents\My Games\Terraria\ModLoader\references\mods\ 目录下找到你的mod.dll。然后通过添加程序集引用将这两个dll添加到dnSpy

现在修复了错误,单击编译按钮便可以回到IL代码窗口。然后切换回C#视图,您可能会发现,您的更改并没有完全保留在C#代码中。但是实际上逻辑是相同的,只是布局不太一样。

然后我们切换回IL视图看看。发现代码已经增加了一部分,我们来注释一下。

翻译一下:

补丁就写完辣!
由于这个IL编辑肥肠滴简单啊,下一节我们将介绍把补丁打到游戏上的三种方法。