下载客户端

IL钩子入门

2026-04-03 22:00:14
发布在雨世界
转载

AI智能总结导读

这是一篇面向《雨世界》新模组制作者的IL钩子入门指南,介绍了IL钩子是可将代码注入游戏、修改已编译的通用中间语言的钩子类型,对比了On钩子与IL钩子的区别,还讲解了IL指令阅读、IL钩子编写方法及注意事项,帮助新手掌握IL钩子的使用。

我经常看到新的模组制作者对IL钩子感到完全困惑,这也难怪。IL钩子一开始确实非常令人费解,对于刚接触它们的人来说没什么意义。本指南旨在对IL钩子进行一个非常简单的介绍,一旦你知道要寻找什么,就会发现它们其实相当简单。 什么是IL钩子 从最基本的层面来说,IL钩子允许你将自己的代码注入游戏中。 当使用《雨世界》内置的模组工具时,我们通常有四种不同类型的钩子可以使用:“On钩子”、“IL钩子”、运行时重定向和HarmonyX补丁。 On钩子使用起来非常简单,你只需钩住函数,然后在其之前或之后插入自己的代码。 举个例子,这个例子可以将五卵石的长袍变成红色。

但如果我们需要更改代码本身中的某些内容,而在其前后运行代码都无法解决问题时该怎么办?这就是中间语言钩子(IL Hooks)的用武之地。本指南将尽力简化中间语言钩子的概念,让新的模组制作者不再对其感到畏惧。 你应该具备一些模组制作和编程的基础知识,但也不必过于担心,即使你对此一无所知,也可以尝试一下,说不定会有惊喜。 首先,让我们来了解它的实际作用。 什么是通用中间语言 中间语言钩子通过直接修改已编译的通用中间语言(简称CIL)来工作。 C#应用程序的工作方式是,它们首先被编译成CIL语言。这种语言是代码的简化版本,读起来有点像汇编语言,由特定平台的解释器将其转换为兼容的机器码。这为开发者提供了一个巨大优势,他们只需编写一次代码,就能在任何平台上运行(当然还需要一些调试)。 以下是一个简化图表

CIL语言非常易于阅读和修改,这也是像DNSpy这类工具能很好工作并允许直接编辑代码的原因。对于模组制作来说,它也非常出色,因为你可以直接对代码进行清晰的修改,而无需触及游戏的程序集。 了解了这些之后,现在是时候讨论如何实际编写IL钩子了。 如何阅读IL指令 在开始之前,先介绍如何查看游戏的CIL。当你在DNSpy中打开一个程序集并找到想要查看的函数时,右键点击该函数并选择【编辑IL指令】。 打开后,你会看到大量文本,但我们真正需要关注的是高亮显示的部分。 让我们一步步分析一个超级简单的函数。

首先你会看到操作码(OpCodes)和操作数(Operands)。操作码告知编译器要执行何种操作,操作数则在需要时告知如何执行该操作。并非所有操作码都需要操作数。索引是指令从0开始执行的顺序。 操作码解释 Ldarg.0:我们首先看到的是Ldarg.0,它将第一个参数加载到栈上。Ldarg.0相当于“this”,是你最常使用的操作码。C#中所有非静态函数都以这种方式工作。 Ldarg.1:将第二个参数加载到栈上,也就是我们函数接收的布尔值。除了其类型无关紧要、编号方式相同外,没有太多其他需要说明的。 call:call的作用就是调用一个函数。在匹配函数时,你会经常用到这个,但在插入自己的代码时会使用其他方法,这能让流程变得简单很多。 ret:完成后返回函数。由于此函数没有返回值,所以不会返回任何内容,但如果有的话,在返回前栈上需要有一个有效的返回变量。 你将使用的最常见操作码:其中许多是不言自明的。 Ldarg:索引0在函数为非静态时表示this,否则表示第一个参数。末尾的数字对应参数的序号。 Ldloc:将局部变量加载到栈上。格式与Ldarg相同。 Ldfld:将类中的字段加载到栈上。 BrTrue / BrFalse:如果为真则分支或如果为假则分支。 call/callvirt:调用函数。 ret:返回…… 现在让我们尝试自己编写一个。 我该如何编写它们。让我们拔掉所有米洛斯秃鹫的羽毛。要实现这一点,我们需要挂钩VultureGraphics构造函数,并在它有机会生成翅膀之前将feathersPerWing设置为零。首先创建你的IL钩子。

ILCursor将用于在函数中移动并进行修改。 接下来,我们需要选择一个插入代码的位置。必须选择在秃鹫羽毛生成之前,且在feathersPerWing变量被设置之后的位置,以确保我们能将该变量设为零并保持这一状态。在本指南中,我会选择colorWaves方法正下方的位置,因为这个位置大小合适,且远离任何分支。 重要提示:如果在分支附近修改代码,需要确保分支不会跳过你的代码。你可以查看BrTrue/BrFalse/Br操作码的操作数,了解它们的分支目标。建议目前先避开这些分支,直到你能熟练编写基本的IL钩子为止。那么我们开始匹配吧。我们会匹配一个相当完整的方法,让你能轻松上手。这些方法的长度会有很大差异,但这个方法是个不错的起点,因为它非常容易理解。

IL指令

最终结果

匹配本质上就是像搜索指令一样重写指令。通常,你应该匹配DNSpy高亮显示的所有内容,以防止冲突并保持堆栈平衡。如果要匹配的代码出现多次,可以匹配代码周围的其他内容,或者重新运行Goto函数,直到确定位于正确的代码处。慢慢来,确保理解每个操作数的作用。 匹配模式 通常我们有4组匹配。 参数:单个数字/值 类型:仅对象类型 变量/调用:类型+全名 分支:输出标签 让我们按每组逐步讲解。 MoveType.Before 我们希望在匹配到的所有内容之前插入代码。 MatchCallOrCallvirt 这是一个调用,因此它需要一个类型和一个名称。对于第一个,我们使用UnityEngine.Random类型,由于我们要获取一个属性,所以按照IL指令中的写法调用“get_value”。 MatchLdcR4/MatchStloc这些是我们的参数,它们只需获取IL指令中的任意数字,一点也不复杂。 MatchBlt/MatchBr我们的分支更容易编写,因为你可以直接忽略输出。 最后是那些没有显示出来的类型,你只需像处理调用时那样使用该类型,只是不需要名称。一步步完成所有步骤,你就能得到最终结果。

这是另一个不同函数的示例,它更容易阅读。之前提到的所有一般思路都适用。

现在我们已经匹配了函数,接下来要插入自己的代码。由于我们要调用一个函数,所以需要保持栈平衡,即只在栈上加载所需内容,并在继续执行前调用一次函数。这很简单,只需两行代码。

c.Emit(OpCodes.Ldarg_0);将Ldarg.0插入到我们的堆栈中。和之前一样,这就等同于“this”(双关语)。 c.EmitDelegateNow这就是我们的秘密武器。c.EmitDelegate允许你调用一个匿名函数。这对我们意味着,我们只需将VultureGraphics加载到堆栈上,然后像对待任何普通函数一样对其进行操作。原本需要多条指令和一个分支的操作现在简化为两步。 整合所有内容

就这样,米洛斯秃鹫(Miros Vultures)掉光了所有羽毛(它们就该这样)

注意事项 恭喜!你已经完成了你的第一个IL钩子,未来还会有更多。IL钩子看起来可能有些吓人,但一旦你知道如何分解问题,就会发现它们其实比看起来容易得多。希望你能从本指南中学到一些东西。以下是一些需要记住的注意事项,之后就去制作你一直想做的那个模组吧。 保持简洁 最好的IL钩子是那些与其他模组兼容性最高,且不会因游戏更新而失效的钩子,这类钩子通常都简洁明了。尽量不要让代码过于复杂,保持简洁就好。 花时间阅读源代码并寻求帮助 这是提升IL钩子编写能力以及整体模组制作水平的两个最佳方法。你可以在GitHub上搜索Monomod使用的函数名,并将编程语言设置为C#,就能找到很多示例。 如果实在行不通,就休息一下再回来。这个建议让我的很多项目免于彻底失败。通常当我们感到沮丧时,会变得情绪化,无法更逻辑地思考问题。当你冷静下来,带着全新的心态回来时,就能更清晰地看到解决方案。

评论

共0条评论
face
inputImg
最新更新

IL钩子入门

我经常看到新的模组制作者对IL钩子感到完全困惑,这也难怪。IL钩子一开始确实非常令人费解,对于刚接触它们的人来说没什么意义。本指南旨在对IL钩子进行一个非常简单…

2026-04-03 22:000赞 · 0评论

开启你的首个战役

### 《雨世界》模组创建简易指南 本指南旨在帮助想要制作slugcat(蛞蝓猫)或战役但不知如何入手的玩家。 #### 模组设置 ##### 模组文件夹 1.…

2026-04-02 13:000赞 · 0评论

《雨世界》1.11.7版本更新内容

《雨世界》更新内容 1. Safari模式现已支持观测者篇章的区域和生物(无需收集新代币,观测者篇章中的橙色代币将同时解锁竞技场地图和Safari区域) 2. …

2026-03-31 19:490赞 · 0评论

如何指向(移动手部)+额外动作!

一份快速基础指南来帮助你!我找了很久都没找到相关资料,所以决定详细制作这份指南。希望它能帮到你! 简介 首先,只有在启用欢乐合作模式时才能使用此功能,而这需要【…

2026-02-18 01:002赞 · 0评论

全蛞蝓猫指南

《雨中冒险》各slugcat(本体及DLC“倾盆大雨”“观察者”)的战役简介,略带幽默。包含剧透、精美图片及彩蛋。 基本信息

2026-02-18 01:002赞 · 0评论

如何在不剧透的情况下帮助新玩家

trying to get someone into rain world? look no further than THIS guide on how to…

2026-02-18 01:000赞 · 0评论

RW新手指南

给那些陷入困境、感到害怕或完全无法理解游戏的玩家指南。我会尽量用简洁明了的语言解释基本机制,让你的游戏体验更轻松,并激励你通关这款精彩的游戏。 引言 我在哪里,…

2026-02-18 01:001赞 · 0评论

如何羞辱蜥蜴 3.0

这是“进阶蜥蜴战斗”指南的第三版,如今我拥有三倍时长的游戏经验和至少两倍的古怪想法,因此内容更加可靠。战斗或许看起来极为复杂且困难,但本指南有望帮助你理解它。 …

2026-02-17 22:000赞 · 0评论

The Watcher 1.5 成就

《观察者》1.5版本更新不仅带来了一些“无关紧要”的内容,还新增了一些没有描述的成就,很多玩家肯定会问“如何获取这些成就?”。本指南将详细介绍它们的获取方法! …

2026-02-17 22:000赞 · 0评论

Within Time成就指南 - 猎人战役简易通关方法

猎人流程最轻松快速通关详细攻略 简介 (我知道这篇攻略文字量很大。如果不想看长篇大论,可以参考每个章节末尾的【简而言之】部分,或者直接跳过文字内容观看视频攻略)…

2026-02-17 19:001赞 · 0评论
暂无更多