简介
在早期游戏过程中,玩家可以通过替换Database.tdb文件来修改其掌控的数据,例如关卡全开tdb文件,其一度流传广泛。
后来,在BallanceRecordChanger出现后,直接复制替换Database.tdb变得不再是最佳方法,使用BallanceRecordChanger可以精确修改Database.tdb文件中的每一个数据,而并不像替换Database.tdb文件一样,“眉毛胡子一把抓”。
Database.tdb是由游戏内部脚本自行创建修改的,且附带加密。有一段时间有一些人曾以高分榜的成绩作为竞速依据[来源请求],但在Database.tdb真正可以被定制修改之前很久,此方法就已经因证据不够确凿而被废弃(例如可以修改地图或使用球补丁等达到更高分数),取而代之的是视频验证。
文件结构
此处介绍的是针对1.13版本,即具有13关补丁的Database.tdb的文件格式进行介绍。因为通过文件结构分析怀疑非1.13版本的Database.tdb文件格式与1.13版本的有所不同,故作此声明。
后文叙述中,比特之间左为高位,字节之间右为高位。(与HxD排布一致)
后文中有关字符串的序列化指的是以ASCII进行序列化。
加密解开
数据库是具有一定加密的,需要通过特定方法解开加密,才能得到可以被阅读的数据,解密的方法为加密的逆向。
交换比特
首先,加密是以字节为单位进行的。每个字节有8个比特,解密的第一步是还原比特顺序,将这8个比特的高位3比特和低位5比特交换位置,完成解密的第一步。如下图:
BIT_1 BIT_2 BIT_3 BIT_4 BIT_5 BIT_6 BIT_7 BIT_8
经过变换后得到BIT_4 BIT_5 BIT_6 BIT_7 BIT_8 BIT_1 BIT_2 BIT_3
可通过代码(C#)实现:j = (byte)(j << 3 | j >> 5);
异或补码变换
此后需要进行异或补码变换,首先将交换比特结束后的字节与0xAF
做异或(XOR)运算,然后对得到的字节再取补码,即最高位取反,其余位取反后+1。此时,文件的加密已解开。
可通过代码(C#)实现:j = (byte)(-(j ^ 0xAF));
文件结构
加密解开后,文件内部的结构将可以被人类勉强阅读,下面将介绍文件中各部分的结构。橙色字表示此处并不确定。
助记符 | 长度 | 类型 | 注释 |
---|---|---|---|
Highscore_01 | 可变 | HIGHSCORE | 第1关高分榜 |
Highscore_02 | 可变 | HIGHSCORE | 第2关高分榜 |
Highscore_03 | 可变 | HIGHSCORE | 第3关高分榜 |
Highscore_04 | 可变 | HIGHSCORE | 第4关高分榜 |
Highscore_05 | 可变 | HIGHSCORE | 第5关高分榜 |
Highscore_06 | 可变 | HIGHSCORE | 第6关高分榜 |
Highscore_07 | 可变 | HIGHSCORE | 第7关高分榜 |
Highscore_08 | 可变 | HIGHSCORE | 第8关高分榜 |
Highscore_09 | 可变 | HIGHSCORE | 第9关高分榜 |
Highscore_10 | 可变 | HIGHSCORE | 第10关高分榜 |
Highscore_11 | 可变 | HIGHSCORE | 第11关高分榜 |
Highscore_12 | 可变 | HIGHSCORE | 第12关高分榜 |
Freischaltung | 定值 | FREISCHALTUNG | 各个关卡是否被开启的描述区块 |
Options | 定值 | OPTIONS | 游戏部分设置的存储区块 |
Highscore_13 | 可变 | HIGHSCORE | 第13关高分榜 |
Highscore_14 | 可变 | HIGHSCORE | 第14关高分榜(无用处) |
Highscore_15 | 可变 | HIGHSCORE | 第15关高分榜(无用处) |
Highscore_16 | 可变 | HIGHSCORE | 第16关高分榜(无用处) |
Highscore_17 | 可变 | HIGHSCORE | 第17关高分榜(无用处) |
Highscore_18 | 可变 | HIGHSCORE | 第18关高分榜(无用处) |
Highscore_19 | 可变 | HIGHSCORE | 第19关高分榜(无用处) |
Highscore_20 | 可变 | HIGHSCORE | 第20关高分榜(无用处) |
HIGHSCORE
HIGHSCORE是高分榜结构,每个HIGHSCORE结构负责存储一关的高分榜数据,共记录十组用户名与成绩数据。
FREISCHALTUNG
FREISCHALTUNG(德语:激活)记录了每一关的激活情况。
助记符 | 长度 | 类型 | 注释 |
---|---|---|---|
Head | 16字节 | 字节数组 | 表头,默认为DB_Levelfreischaltung 序列化后再附加一个0x00 组成
|
Unknow_1 | 20字节 | 字节数组 | 未知,疑似为描述字符以及一些偏移量记录,恒为0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x46, 0x72, 0x65, 0x69, 0x67, 0x65, 0x73, 0x63, 0x68, 0x61, 0x6C, 0x74, 0x65, 0x74, 0x3F, 0x00
|
Active_01 | 4字节 | 布尔 | 标明第1关是否解锁,true(即1)为解锁,false(即0)为不解锁 |
Active_02 | 4字节 | 布尔 | 标明第2关是否解锁 |
Active_03 | 4字节 | 布尔 | 标明第3关是否解锁 |
Active_04 | 4字节 | 布尔 | 标明第4关是否解锁 |
Active_05 | 4字节 | 布尔 | 标明第5关是否解锁 |
Active_06 | 4字节 | 布尔 | 标明第6关是否解锁 |
Active_07 | 4字节 | 布尔 | 标明第7关是否解锁 |
Active_08 | 4字节 | 布尔 | 标明第8关是否解锁 |
Active_09 | 4字节 | 布尔 | 标明第9关是否解锁 |
Active_10 | 4字节 | 布尔 | 标明第10关是否解锁 |
Active_11 | 4字节 | 布尔 | 标明第11关是否解锁 |
Active_12 | 4字节 | 布尔 | 标明第12关是否解锁 |
Active_13 | 4字节 | 布尔 | 标明第13关是否解锁 |
OPTIONS
OPTIONS记录了游戏中部分设置。