对maimaiDX素材文件的研究
文件结构
已知:构成一首乐曲的要素有:音频、封面、BGA、谱面
alls的更新基于虚拟磁盘,每个opt都是挂载在父磁盘后的差分磁盘。因此,根据每次更新内容的不同,opt所包含的文件类型均有所不同,如果将素材范围限定在维持谱面运行的最低标准时,所需文件结构大致如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Axxx(xxx代表三位数字)
├─AssetBundleImages(以AB包形式存在的图形)
│ ├─jacket(分辨率400x400的封面)
│ │ ├─ui_jacket_xxxxxx.ab(AB包文件)
│ │ └─ui_jacket_xxxxxx.ab.manifest(AB包声明文件)
│ └─jacket_s(分辨率200x200的封面)
│ ├─ui_jacket_xxxxxx.ab
│ └─ui_jacket_xxxxxx.ab.manifest
├─MovieData(BGA)
│ └─xxxxxx.dat(加密的视频文件)
├─music(谱面文件)
│ ├─GenreSort.xml(乐曲种类注册表,仅A000)
│ ├─MusicSort.xml(乐曲注册表)
│ ├─MusicRanking.xml(排位乐曲注册表)
│ ├─MusicGenreSort.xml(Tab种类注册表,仅A000)
│ └─musicxxxxxx
│ ├─xxxxxx_00.ma2(Basic谱面)
│ ├─xxxxxx_01.ma2(Advanced谱面)
│ ├─xxxxxx_02.ma2(Expert谱面)
│ ├─xxxxxx_03.ma2(Master谱面)
│ ├─xxxxxx_04.ma2(Re:Master谱面)
│ └─Music.xml(包含了歌曲及谱面的基本信息)
└─SoundData(音频)
│ ├─Mai2.acf
│ ├─musicxxxxxx.acb
│ └─musicxxxxxx.awb
└─DataConfig.xml(opt版本信息)
游戏中对乐曲的索引依赖于6位id,但并不是所有位均有实际意义。其中,BGA、音频和封面所使用的id,低4位代表乐曲id,高位补0,实际有效位仅为4位;在谱面文件中,第5位被用于区分标准谱面与DX谱面,低4位和高2位分别高位补0,如Oshama Scramble!的标准谱面id为000363,DX谱面id为010363,实际有效位为5位。
封面
sinmai所有的png素材均以AssetBundle的形式存在,本身不存在加密,其存在的意义在于可以让游戏动态加载和卸载资源,模块化的设计也便于更新维护。AB包有两种,一种是序列化文件,资源被拆解并以单个文件的形式存在(*.ab文件);另一种是资源文件(*.assets文件),资源以二进制数据块的形式存在。乐曲封面使用的形式是前者,有两种分辨率,位于不同的文件夹,分别是400x400(jacket)和200x200(jacket_s)。
*.manifest文件是同名*.ab文件的声明文件,包含CRC、哈希等信息。
Unity的解包工具非常多,推荐AssetStudio(已停止维护)、Unity Assets Bundle Extractor(UABE)或UnityPy(基于AssetStudio,好处是可以跨平台运行,我在很久之前写过一个基于这个的py脚本)。但是如果想要repack,目前已知的只有UABE支持这个功能,通过替换ab包里的字节流完成。
音频与BGA
之所以放在一起写是因为他们本质上是同源的,都使用了criware的中间件,因此也使用了相同的key进行加密。
sinmai的音频使用了CRI ADX2进行加密,每个音频对应相同名称的*.awb和*.acb文件,前者是音频流,后者是音频目录。awb本质是在hca外套了一层壳,前者可以通过VGMToolbox脱壳,得到hca文件后可以通过HCADecoder解密。
sinmai的视频文件后缀为*.dat,不过直接读取字节流可以看出其加密使用的是CRI Movie 2(即USM文件):
USM文件可以通过CRID-usm-Decrypter解密。
sinmai使用的hca key为7F4551499DF55E68,前8位为B,后8位为A
谱面
sinmai的谱面依赖于谱面本体、谱面信息和谱面索引三部分完成。
谱面索引依赖于music文件夹下的MusicSort.xml
,游戏在运行时会根据这个文件中的曲目列表生成索引,再依次遍历各个谱面文件夹下的文件。谱面信息由musicxxxxxx
文件夹下的Music.xml
来记录,里面包含的歌曲的绝大部分信息。
sinmai的谱面本体为*.ma2文件,文件名形如 xxxxxx_xx.ma2
,前6位为素材id,后2位为难度标定,从00到04分别代表BSC、ADV、EXP、MAS和ReM,每个难度的谱面各占据一个文件。*.ma2文件本质上是一个文本文件,以瀑布流的形式记录note信息,其与Simai的双向转换可以借助MaichartConverter进行。