以Offset进行分段。仅为暂时成果,随时可能变动。
这些分段和内容同样适用于绯想天replay,萃梦想未测试。
0x0000-0x0001:非想天则版本号标记位。非想天则1.10的取值为D2 00,其它版本待测试。修改此值会造成rep在1.10版本非想天则选择页面上直接变灰,无法选择。
0x0002-0x0005:不明。目前观测到的所有rep,此部分取值固定为00 00 00 00,修改此值未见影响。(2024-05-13更新:0x0004似乎是一个随机数种子,与铃仙/幽幽子等机体的弹幕发射有关?具体待探究,感谢三回提供的信息。)
0x0006-0x0007:不明,取值未发现规律。也许与rep模式标记有关。
0x0008:rep模式标记位。取值有02(vs com), 03(vs player), 04(vs network 1p), 05(vs network 2p)。修改后仅在sokurep软件中观察到区别,在游戏中未见影响,也不会修改键位读取模式,怀疑有其它值参与了rep模式标记。
0x0009-0x000D:不明。目前观察到的为定值00 00 01 03 00 。
0x000E-0x006F:双方角色信息部分。其中0x000C-0x003E部分为1p角色信息,0x003F-0x006F部分为2p角色信息,猜想两部分结构完全一致,下述内容以1p角色信息为准。
0x000E:角色决定位,取值范围为00-13,具体取值表见下文。填写13以上的值会导致游戏崩溃。根据过往资料,猜测有大鲇鱼角色存在的可能,但未得到证明。
0x000F: 配色决定位,取值范围为00-07,按顺序对应原版的八种配色。实际取08,09,0A也可能有特殊配色出现,不同机体特殊配色数量不同,具体见角色取值表。这些特殊配色中,编码非最大的颜色是黄昏制作的未使用方案,编码最大的可能是程序错误读取了其它人的色表。最大编码配色在非想天则第一次打开rep/非第一次打开rep时展示的颜色不同,其中非第一次打开rep的颜色在某种条件下可能变化。如果取范围外的值,配色按最大编码配色展示。文末相关链接中有特殊配色机制的演示视频。
0x0010-0x0013:某种特殊标记位,取值固定为14 00 00 00。修改此值会导致游戏卡死且无法正常关闭。开始怀疑是卡组开头标记,进一步的测试证明不一定与卡组有关。(2024-05-13更新:此部分用于记录卡组中卡片的数量。由于默认卡组为20张,在正常对局中固定表现为小端序0x14。感谢Hagb提供的信息。)
0x0014-0x003B:卡组部分,卡组取值范围和取值对应表可以和profile文件对应。该部分每两字节代表一张符卡,为小端序数据。卡组编辑为不符合规范的模式(如四张以上相同卡)会导致rep中不出现任何卡片。将卡片值改为范围外的值不会导致游戏异常,但当该符卡出现(符力满,出现下一张卡)时,会立刻消失。卡组的详细取值表可见文末相关链接。
0x003C:p侧标记位,具体作用不明,似乎与角色判定有关。在1p位置(0x003C)取值固定为00,在2p位置(0x006E)取值固定为01。00改为01或01改为00,会导致角色血条上的头像消失,同时发射的弹幕可能命中自己,似乎是弹幕错误响应了自己的受击框,需要进一步研究。改为00或01以外的值会导致游戏在第一本开始后崩溃。
0x003D:不明,据目前观察,取值固定为01,修改此值未见影响。
0x003E:不明,取值范围为00和01(常见),修改此值未见影响。
0x0070:不明,据目前观察,取值固定为03,修改此值未见影响。
0x0071:游戏场景决定位,取值表见下文。填写超出范围的值会展示场景00(倒塌的博丽神社),该值过大会导致游戏崩溃。机体(蝙蝠)不会使场景改变。
0x0072:游戏BGM决定位,取值表见文末相关链接。填写无对应bgm的值就什么都不播放。
0x0073-0x0076:本局游戏随机数种子,无取值范围,未见规律,在vs network中这四个字节在对战开始前传输。修改此值导致了符卡和天气顺序变化。
0x0077-0x0078:本局rep记录的键位数量,读取多长的按键记录由此数值决定。由于按键记录规则是固定的,可由此数值推算对战时长。如果按键记录长度小于此数值,后续由00填充,角色保持不动至对战时间结束。如果按键记录长度大于此数值,在对战时间到时强制停止播放,忽略后续的按键记录。
0x0079- :暂定为对战按键记录部分。该部分每两字节代表一个按键值,小端序。暂时认为每帧记录两个值,分别为1p和2p的按键,1p按键在前还是2p按键在前是不确定的(由目前未知的机制确定)。
特殊的,当rep在vs com模式下生成时,每帧只记录玩家按键值,不记录ai按键值。猜测rep播放时,ai行动依据玩家当前状态和rep中记录的随机数种子生成。其原因可能是ai行动无法用简单键盘操作复现(不符合正常操作逻辑,存在虚空跳跃,虚空必杀等现象)。
按键取值表见下文。由于每个键位对应一个bit位,按键值可以有效记录多键位同时按键。
角色取值表(以及对应的配色信息)
角色编码 | 对应角色 | 隐藏配色数量 | 变异种子色表来源 |
00 | 红白 | 1 | |
01 | 黑白 | 1 | |
02 | 16 | 1 | |
03 | 小爱 | 1 | |
04 | 图书 | 1 | |
05 | 妖梦 | 1 | |
06 | 蝙蝠 | 2 | |
07 | uu | 1 | |
08 | 紫 | 1 | null(纯黑) |
09 | 西瓜 | 1 | |
0A | 兔子 | 1 | null(纯黑) |
0B | 文 | 1 | 文 色表00 |
0C | 小町 | 1 | |
0D | 19 | 2 | |
0E | 天子 | 2 | 文 色表00 |
0F | 早苗 | 1 | |
10 | 9 | 2 | null(纯黑) |
11 | 中国 | 3 | |
12 | 高达 | 1 | |
13 | 青蛙 | 1 |
按键取值表
按键对应的bit位 | 按键对应的hex值 | 按键名称 |
1 | 01 00 | up(方向上键) |
2 | 02 00 | down(方向下键) |
3 | 04 00 | left(方向左键) |
4 | 08 00 | right(方向右键) |
5 | 10 00 | a(体术/确认键) |
6 | 20 00 | b(轻弹幕/取消键) |
7 | 40 00 | c(重弹幕键) |
8 | 80 00 | d(擦弹键) |
9 | 00 01 | 切换符卡 |
10 | 00 02 | 使用符卡 |
11 | 00 04 | F7(vs com切换预报) |
12 | 00 08 | F6(vs com切至上个天气) |
13 | 00 10 | F5(vs com切至下个天气) |
14 | 00 20 | F3(vs com重置卡组) |
15 | 00 40 | F2(vs com卡槽全满) |
16 | 00 80 | F1(vs com锁血) |
场景取值表
场景编码 | 场景名称 |
00 | 倒塌的博丽神社 |
01 | 魔法森林 |
02 | 玄武之泽 |
03 | 妖怪之山 |
04 | 玄云海 |
05 | 有顶天 |
0A | 博丽神社 |
0B | 雾雨魔法店 |
0C | 红魔馆钟楼 |
0D | 人偶森林 |
0E | 红魔馆地下图书馆 |
0F | 冥界 |
10 | 红魔馆大堂 |
11 | 白玉楼雪庭 |
12 | 迷途竹林 |
1E | 雾之湖湖畔 |
1F | 守矢神社 |
20 | 间歇泉入口 |
21 | 间歇泉地下通道 |
22 | 聚变反应炉核心 |
相关资料
非想天则对战数据包解析(英文):https://github.com/delthas/touhou-protocol-docs/blob/master/protocol_123.md
非想天则卡组、角色、场景、BGM详细取值表(英文):https://hisouten.koumakan.jp/wiki/Deck_Extracting
配色机制的说明和异常配色演示视频:https://www.bilibili.com/video/BV1Mr4y1i7QU
通过Replay编辑实现特定动作:https://rinkastone.com/2022/01/19/archives/205
[…] 本文仅总结操作思路,具体的Replay字段解析和编码表请转http://rinkastone.com/2022/01/10/archives/109查看。 […]
太强了,前排支持,感觉是能够玩的很花的技术
@lzusa 目前来说用处不是很大,主要是对着字节码直接改比较反直觉反人类。
但是基于这些资料开发罗曼连/CMV生成器是有很大的想象空间的。
感谢作者的信息,帮大忙了。在逆向过程中发现 0x0010-0x0013 是卡组部分卡的个数,所以其值固定为小端序 0x14,读取完这个部分后游戏会依据读取出的数值来接着读取相应数量的卡。(我没有研究非 0x14 的行为。)
存储输入数量的 0x0077-0x007a 是一个 4 字节而不是 2 字节整数,之后(如果是 vs com 或者 network 模式的 pvp rep)是 p1输入 p2输入 p1输入 p2输入 … 这样的序列。
正常结束(正常决着、过了战后人物对话的)的 pvp rep 的输入数是一个奇数,其中最后一个“输入”其实是小端序的对局总帧数(关于 0xffff 取余数),但是在 replay 模式被读取时似乎和其他按键没有区别而不会有特殊用途。(对于 65535 帧以内的 pvp rep)这个数会略大于 0x0077~0x007a 处的输入数 / 2(开始前、拿本后、拿决后无法作出动作时的输入不会存下)