3DMGAME 3DM首页 新闻中心 前瞻 | 评测 游戏库 热门 | 最新 攻略中心 攻略 | 秘籍 下载中心 游戏 | 汉化 购买正版 论坛

注册 登录

QQ登录

只需一步,快速开始

查看: 1733|回复: 14
打印 上一主题 下一主题

[MOD] 关于此游戏制作mod时 BepInex框架和MelonLoder框架全部无法使用的建议

[复制链接]

1

主题

63

帖子

219

积分

中级玩家

Rank: 3Rank: 3

贡献度
12
金元
1605
积分
219
精华
1
注册时间
2017-6-17
跳转到指定楼层
主题
发表于 2026-5-16 05:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今古群侠传 Mod 技术分析报告零、快速总结TL;DR: 经过大量测试,该游戏 Unity 2021.3.15f1 的 Mono 运行时做了高强度托管代码裁剪,导致 BepInEx、MelonLoader、Harmony、MonoMod 等所有主流动态 Mod 框架全部无法使用。最终方案为自建静态 IL 注入框架(JinguMod),利用 Assembly.Load + Mono.Cecil 在游戏启动前修改 Assembly-CSharp.dll,已验证可成功修改游戏数值。

一、游戏基本信息项值
游戏名今古群侠传 / JinGu
开发商金十四工作室
平台Steam
Unity 版本2021.3.15f1c1
运行时Mono (MonoBleedingEdge) 6.12
架构x64 (64-bit)
C# 后端Mono(非 IL2CPP),存在 Assembly-CSharp.dll
二、主流 Mod 框架实验结论BepInEx — 全部失败版本代理 DLL结果
5.3.0 / 5.4.19 / 5.4.20 / 5.4.21 / 5.4.23winhttp.dll游戏正常启动,BepInEx 完全不加载,无 LogOutput.log
同上全部版本version.dll同上,完全不加载
所有版本x86 变体不兼容(游戏为 x64)失败原因: 该游戏的 UnityPlayer.dll 对 winhttp.dll 和 version.dll 使用了延迟加载(delay-load),实际运行时从不调用这些 DLL 的函数,导致 Windows 不会加载本地拷贝。Doorstop 代理 DLL 根本没有执行机会。
⚠️ 此问题在其他 Unity 2021 游戏中未复现,系该游戏特有的构建配置。

MelonLoader — 各版本表现不一版本结果
0.4.3闪退:MissingMethodException: AmbiguousMatchException..ctor
0.5.4闪退:MissingMethodException: ServicePointManager.set_Expect100Continue
0.5.7闪退:MissingMethodException: ServicePointManager.get_ServerCertificateValidationCallback
0.6.5安装器失败:Internal Failure: Failed to find MelonLoader Bootstrap
0.6.6手动安装报错找不到 dobby.dll;闪退但生成了 Mods/ 目录
0.7.3代理注入成功,但 Bootstrap 初始化失败:CustomAttributeFormatException: Could not find a field with name CharSet关键发现: MelonLoader 0.7.x 的 version.dll 代理确实能成功注入(与 BepInEx 不同),说明注入通道存在。失败发生在注入后的托管代码初始化阶段,被 Unity Mono 的 API 缺失所阻断。

尝试修复 MelonLoader 的过程针对 MelonLoader 0.7.3,尝试用 Mono.Cecil 修补其 DLL 来绕过 CharSet 报错:
  • 清空 NativeLibrary<T>..ctor(导致后续 ldfld 空引用)→ 失败
  • 在 BootstrapInterop.Initialize 的 catch 块中返回 null(跳过错误)→ 游戏能进主菜单,但 Core.Initialize 未被调用 → Mods 不加载
  • 插入 br 指令直接跳到 Core.Initialize → 闪退(方法元数据损坏)
  • 将所有 NativeLibrary 的 newobj 替换为 ldnull → 空引用异常
针对 MelonLoader 0.5.4 和 0.4.3,同样遇到一连串缺失 API:
  • ServicePointManager.set_Expect100Continue — 清空 ServerCertificateValidation.Install 方法
  • Directory.SetCurrentDirectory — 清空 MelonUtils.SetCurrentDomainBaseDirectory
  • AmbiguousMatchException..ctor(string, Exception) — 清空 InvariantCurrentCulture.Install
  • FileSystemWatcher..ctor(string, string) — 清空后仍旧失败,链式报错无止境
结论: 每一处补丁修完都会暴露下一个缺失的 API,属于系统性不兼容,无法通过逐个修补解决。

三、深层原因:Mono 托管代码裁剪Unity 在打包游戏时会分析哪些 .NET 类型被实际使用,未引用的都会被自动裁剪以减小包体。该游戏设置了高等级裁剪(High),导致以下关键 API 全部缺失:
缺失 API影响
System.Threading.ReaderWriterLockSlimHarmony / HarmonyX 类型初始化失败
RuntimeHelpers.PrepareMethodMonoMod 动态 Detour 无法执行 JIT 方法准备
ServicePointManager 方法MelonLoader 0.4.x / 0.5.x 网络层崩溃
DllImportAttribute.CharSet 字段MelonLoader 0.7.x 原生方法扫描失败
Directory.SetCurrentDirectoryMelonLoader 0.5.x 工作目录设置失败
AmbiguousMatchException..ctor(string,Exception)MelonLoader 0.4.x 异常处理失败
FileSystemWatcher..ctor(string,string)MelonLoader 0.4.x 配置文件监视失败
⚠️ 这些 API 属于 .NET 运行时的内部实现或底层同步原语,无法通过简单的 DLL 文件替换来补齐。PrepareMethod 更是 JIT 编译器层面的功能,仅存在于 C++ 编写的 Mono 运行时引擎中。

四、为何其他方案也不可行?修改 ScriptingAssemblies.jsonScriptingAssemblies.json 仅用于 Unity Editor 构建,游戏运行时忽略此文件。在其中添加 DLL 名称不会导致该 DLL 被加载。
Unity Subsystems游戏日志虽然打印了 Discovering subsystems at path .../UnitySubsystems,但该目录实际不存在,无法利用。
IL2CPP 转换游戏是 Mono 后端而非 IL2CPP,不存在 GameAssembly.dll。Mono 后端的优势是托管代码以原始 IL 字节码存储,可以用 Mono.Cecil 直接读写。

五、最终方案:静态 IL 注入框架核心思路放弃运行时动态 Hook,改为启动前用 Mono.Cecil 直接修改 Assembly-CSharp.dll 的 IL 字节码。Mono.Cecil 是纯 .NET 字节码读写库,不依赖任何游戏运行时 API。
实现架构Mods/YourPatch.dll          ← 你写的补丁(C# 代码,命名约定)        │JinguPatcher.exe             ← IL 注入工具(启动前运行一次)        │Assembly-CSharp.dll          ← 游戏代码被直接修改        │JinguMod.dll (Bootstrap)     ← 运行时引导器(Unity 通过 GameEntry 自动加载)        │游戏正常运行,补丁生效工作流程
  • GameEntry 静态构造函数(自动注入,无需用户操作)
    static GameEntry(){   var asm = Assembly.Load("JinguMod");   var type = asm.GetType("JinguMod.Bootstrap");   type.GetField("Loaded").GetValue(null);  // 触发 Bootstrap 初始化}
  • Bootstrap 初始化:扫描 Mods/ 目录,加载补丁 DLL
  • JinguPatcher.exe:扫描 Mods 补丁,生成 IL 注入到 Assembly-CSharp.dll
  • 补丁编写:使用命名约定 Prefix_类名_方法名 或 Postfix_类名_方法名

补丁编写示例namespace JinguModPatch;public static class PatchEntry{    // 拦截 ChangeItem,阻止扣钱    public static void Prefix_SaveData_ChangeItem(int itemId, ref int changeNum)    {        if (itemId == 10001 && changeNum < 0)            changeNum = 0;    }}核心代码Bootstrap 加载器(JinguMod/Bootstrap.cs):
public static class Bootstrap{    public static readonly bool Loaded;    public static readonly string Status;    static Bootstrap()    {        try        {            var modsDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Mods");            if (Directory.Exists(modsDir))            {                foreach (var dllPath in Directory.GetFiles(modsDir, "*.dll"))                {                    var patchAsm = Assembly.LoadFrom(dllPath);                    var entryType = patchAsm.GetType("JinguModPatch.PatchEntry");                    if (entryType != null)                    {                        var loadedField = entryType.GetField("Loaded");                        if (loadedField != null)                            loadedField.GetValue(null); // 触发补丁静态构造函数                    }                }            }            Status = "OK";        }        catch (Exception ex)        {            Status = ex.GetType().Name + ": " + ex.Message;        }        finally { Loaded = true; }    }}IL 注入工具(JinguPatcher/Program.cs):
  • 使用 Mono.Cecil 读取 Assembly-CSharp.dll
  • 扫描 Mods/ 中的补丁 DLL
  • 解析 Prefix_类名_方法名 命名约定
  • 将补丁方法的 call 指令注入目标方法开头
完整源码见项目仓库。

六、优缺点对比BepInEx / MelonLoader本方案(静态 IL 注入)
安装方式解压到游戏目录解压到游戏目录
是否依赖运行时 API是(被裁剪后失效)否
补丁语法[HarmonyPatch] 特性Prefix_类名_方法名 约定
入参修改支持支持(ref 参数)
返回值修改支持(__result)实验性支持(ref 返回值参数)
动态热重载支持不支持(需重启 + 重新注入)
兼容性取决于 Mono 裁剪等级任意 Mono 游戏通用
需要 dnSpy否仅查找方法签名时需要
玩家使用门槛极低(解压即用)极低(解压即用)
七、对未来的建议如果有开发者想从根本上解决此问题,可以考虑以下方向:
  • Unity 重新打包:在用 Unity 2021.3.15f1导出项目时,把 Managed Stripping Level 改为 Disabled,重新 Build 后提取完整的 System 类 DLL(mscorlib.dll、System.Core.dll 等),覆盖到原游戏中。这样做可以补齐所有缺失的 .NET API,使 BepInEx/MelonLoader 全部恢复可用。这是唯一可能让动态框架重回战场的方法。但没有原始项目文件难以复现
  • Assembly Publicizing:使用工具将游戏所有程序集的 internal 成员公开化,为 mod 提供最大灵活性。
  • Mono Runtime 注入:深入 mono-2.0-bdwgc.dll 层面,通过 C++ 直接向 Mono 注册缺失类型——但这是极其复杂且风险很高的方案。


本报告编写于 2026 年 5 月15日,基于对游戏版本构建号 080beb55ecda(Unity 2021.3.15f1c1) 【v1.0.0】的实际测试。——酸菜鱼真菜

评分

7

查看全部评分

回复

使用道具 举报

20

主题

3442

帖子

3633

积分

游戏精英

Rank: 8Rank: 8

贡献度
8
金元
36013
积分
3633
精华
0
注册时间
2011-7-26
舒服的沙发
发表于 2026-5-16 08:10 | 只看该作者
大佬牛皮!!!!支持!!!
回复 支持 反对

使用道具 举报

19

主题

2084

帖子

3026

积分

游戏达人

Rank: 7Rank: 7Rank: 7

贡献度
59
金元
27904
积分
3026
精华
0
注册时间
2018-6-17
硬硬的板凳
发表于 2026-5-16 09:06 | 只看该作者
开源地址在哪?学习一下
回复 支持 反对

使用道具 举报

19

主题

2084

帖子

3026

积分

游戏达人

Rank: 7Rank: 7Rank: 7

贡献度
59
金元
27904
积分
3026
精华
0
注册时间
2018-6-17
冰凉的地板
发表于 2026-5-16 09:22 | 只看该作者
请问开源地址是??
回复 支持 反对

使用道具 举报

1

主题

127

帖子

254

积分

高级玩家

Rank: 4

贡献度
6
金元
2298
积分
254
精华
0
注册时间
2023-12-23
5#
发表于 2026-5-16 10:53 | 只看该作者
6666666666666666666666
回复 支持 反对

使用道具 举报

32

主题

1734

帖子

5373

积分

游戏精英

真蛋疼无双

Rank: 8Rank: 8

贡献度
129
金元
48573
积分
5373
精华
0
注册时间
2010-3-13

2025国庆铭牌庆国庆迎中秋

6#
发表于 2026-5-16 15:18 | 只看该作者
厉害
回复 支持 反对

使用道具 举报

14

主题

1340

帖子

1642

积分

游戏狂人

Rank: 6Rank: 6

贡献度
1
金元
16376
积分
1642
精华
0
注册时间
2012-4-9
7#
发表于 2026-5-16 15:19 | 只看该作者
太强了大佬!!!!!
回复 支持 反对

使用道具 举报

1

主题

63

帖子

219

积分

中级玩家

Rank: 3Rank: 3

贡献度
12
金元
1605
积分
219
精华
1
注册时间
2017-6-17
8#
 楼主| 发表于 2026-5-16 16:24 | 只看该作者
fenghao630 发表于 2026-5-16 09:06
开源地址在哪?学习一下

我忘记传上来了 不过核心思路我都写在文章里了 可以用这个思路直接实现 我想等官方更新后 在重置下我现在做的框架再发上来
回复 支持 1 反对 0

使用道具 举报

7

主题

1612

帖子

2273

积分

游戏达人

Rank: 7Rank: 7Rank: 7

贡献度
66
金元
20091
积分
2273
精华
0
注册时间
2013-1-16
9#
发表于 2026-5-17 02:27 | 只看该作者
绅士小丑 发表于 2026-5-16 16:24
我忘记传上来了 不过核心思路我都写在文章里了 可以用这个思路直接实现 我想等官方更新后 在重置下我现在 ...

官方啥时候更新哦
回复 支持 反对

使用道具 举报

11

主题

878

帖子

3597

积分

游戏精英

Rank: 8Rank: 8

贡献度
134
金元
30607
积分
3597
精华
0
注册时间
2012-8-26

水神五一劳动节猫耳党量子Doro筒隐月子(特别版)3DMer(永久)龙年勋章

10#
发表于 2026-5-18 11:17 | 只看该作者
优秀
回复 支持 反对

使用道具 举报

0

主题

29

帖子

50

积分

初级玩家

Rank: 2

贡献度
0
金元
504
积分
50
精华
0
注册时间
2025-8-4
11#
发表于 2026-5-18 17:22 | 只看该作者
fenghao630 发表于 2026-5-16 09:06
开源地址在哪?学习一下

在他给的github仓库

回复 支持 反对

使用道具 举报

100

主题

764

帖子

9626

积分

匠心精神 CE

Rank: 12Rank: 12Rank: 12

贡献度
94
金元
92497
积分
9626
精华
0
注册时间
2020-4-8

神秘会员【紫】特殊组你开心就好[永久版]智力-1[永久版]

12#
发表于 2026-5-19 08:13 | 只看该作者
ScriptingAssemblies.json 在 JinGu_Data/ 里,并且正在被 Unity 运行时使用 这文件就是用来告诉 Mono 运行时"启动后该加载哪些托管 DLL"的。该文件仅用于 Editor"的判断直接被推翻   
回复 支持 反对

使用道具 举报

19

主题

2084

帖子

3026

积分

游戏达人

Rank: 7Rank: 7Rank: 7

贡献度
59
金元
27904
积分
3026
精华
0
注册时间
2018-6-17
13#
发表于 2026-5-20 10:16 | 只看该作者

“我忘记传上来了”
回复 支持 反对

使用道具 举报

0

主题

10

帖子

20

积分

新手玩家

Rank: 1

贡献度
0
金元
200
积分
20
精华
0
注册时间
2022-9-21
14#
发表于 2026-5-21 20:09 | 只看该作者
没毛病,大佬66666
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|3DMGAME ( 京ICP备14006952号-1  沪公网安备 31011202006753号

GMT+8, 2026-6-5 16:24 , Processed in 0.032703 second(s), 18 queries , Memcached On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表