本帖最后由 SkyDynamic 于 2025-8-5 17:25 编辑
用于修复SDED HDD无法读取maimai的opt资源文件
原因分析
通过逆向Assembly-CSharp.dll可知, 游戏初始化的时候会执行CardMaker.MAI.MaiContext#Awake, 然后执行AssetBundleDB#initialize进行AssetsBundleDB初始化, 但是CardMaker.Common.AssetBundleDB#initialize方法有两种传参方式:
- void initialize(AssetBundleDB.Title title)
- void initialize(AssetBundleDB.Title title, List optionDirectories)
第一个则是只初始化StreamingAssets\assets_mai内的资源
第二个则是传入opt的Path, 在完成StreamingAssets\assets_mai初始化后进行添加opt的AssetsBundle
但是CardMaker.MAI.MaiContext#Awake使用的是前者, 而在后续也没有进行任何的资源添加, 导致后续获取资源的时候一直为null
修复方法
将资源文件重新进行索引
如果对与assets_mai文件夹进行过研究, 就会发现除了ui_cardxxxx_xxxx之外, 还有会有个assets_mai.bytes
而这个bytes文件则为索引了资源文件的文件
通过Hxd HexEditor可以知道这个文件是一个以@.......为文件头的文件并不是任何的传统意义上的文本, 也不是什么数据库, 现有的工具无法正常读取
在逆向CM之后, 可以知道这个实际上是一个CM自己维护的结构文件, 那么我们就可以进行读取和修改了.
本贴会提供两个py脚本进行参考
使用方法:
copy_assets.py: 放到option目录下进行执行, 会自动读取Mai的资源文件并且复制到StreamingAssets\assets_mai中
cardmaker_mai_assets_builder.py: 放到StreamingAssets\assets_mai下执行, 会自动读取该目录下的所有资源文件, 然后会生成一个新的assets_mai_modify.bytes文件, 该文件就是重新索引资源后的资源结构文件, 将原本的备份后, 将该文件命名为assets_mai.bytes就可以正常使用CM
脚本源码: https://gist.github.com/SkyDynamic/8715376f0a984c52f3638e9655ecabf6
使用mod
我基于上述编写了一个BepInEX Mod进行修复
在CardMaker.MAI.MaiContext#Awake执行之后, 使用AssetBundleDB#appendAssetsBundleSet方法将opt的资源重新进行正确的添加, 游戏就能正常读取资源文件了
mod源码仓库: https://github.com/SkyDynamic/cm-mai-resource-fix