|
楼主 |
发表于 2008-7-5 01:02:53
|
显示全部楼层
Section 4
===============================================================================
4.0 [解压出的数据]
===============================================================================
解压出来的数据是原来数据流中紧连数据单位的集合. 此类数据项的偏移由其大小确。
本小节的内容是录像数据流中起始记录的内容,其中记录有关于游戏设置与玩家的信息。游戏过程中的相关数据在第5节会讨论到
起始数据的格式如下::
# | 大小 | 名称
---+----------+--------------------------
1 | 4 byte | 未知 (0x00000110 - another record id?)
2 | 可变 |玩家记录 (见 4.1)
3 | 可变 | 游戏名称(0值结尾) (见 4.2)
4 | 1 byte | 空字节
5 | 可变 | 编码字符 (0值结尾) (见 4.3)
| | - 游戏设置 (见 4.4)
| | - 游戏创建或地图名 (见 4.5)
6 | 4 byte | 玩家数 (见 4.6)
7 | 4 byte | 游戏类型 (见 4.7)
8 | 4 byte | 语言 (见 4.8)
9 | 可变 | 玩家哦列表(见 4.9)
10 | 可变 | 游戏起始记录 (见 4.11)
下面几小节将详细分述
除去这些静态数据项(上面的) ,后面数据块携带的可变信息在第5节说明
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.1 [玩家记录]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
偏移 | 大小/类型 | 描述
-------+-----------+-----------------------------------------------------------
0x0000 | 1 byte | RecordID:
| | 0x00 游戏主机
| | 0x16 额外玩家 (参见 4.9)
0x0001 | 1 byte | 玩家id
0x0002 | n bytes | 玩家名字 (0值结尾)
n+2 | 1 byte | 额外数据大小:
| | 0x01 = 自定义游戏
| | 0x08 = ladder对战
游戏类型决定以下数据:
o 自定义游戏:
偏移 | 大小/类型 | 描述
-------+-----------+---------------------------------------------------------
0x0000 | 1 byte | null byte (1 byte)
o ladder上的对战:
偏移 | 大小/类型 | 描述
-------+-----------+---------------------------------------------------------
0x0000 | 4 bytes | 游戏记录的持续时间(以毫秒记)
0x0004 | 4 bytes | 玩家种族标记:
| | 0x01=人族
| | 0x02=兽人
| | 0x04=暗夜精灵
| | 0x08=天灾
| | (0x10=daemon 进程守护?)
| | 0x20=随机
| | 0x40=种族 可选/固定 (参见 4.11的注释)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.2 [游戏名称]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
游戏名的编码为0值结尾的纯文本(ASCII?)
只有在战网(battle.net)上的自定义游戏中能够自命名游戏, 其他情况下游戏名称是固定的(这类修改已做出来过了,比如可修改“本地局域网的游戏”)
o 战网的天梯对战(ladder)其名为”BNet”.
o 自定义局域网游戏则含有一个语言本地化的游戏创建者的名字.
例如: 玩家“Blue”所创建的游戏:
"Blue's game" :英文版的 Warcraft III
"Blue的游戏" 这是中文版的
o单人的自定义游戏则是固定的本地语言标识.
"local game" :英文版
中文版是“当地局域网内的游戏”(为啥?不过这是可以改的)
o 下面的是一些语言版本的字符串 (纯文本 ASCII 编码) ,取自魔兽1.06及以前版本,没有中文的(自己找去= =)。
顺便告诉你可以在哪里修改这类本地语言字符串
(see war3.mpq\\UI\\FrameDef\\GlobalStrings.fdf: GAMENAME, LOCAL_GAME):
English : "%s's Game" : "local game"
Czech (1029): "Hra %s" : "M韘tn?hra"
German (1031): "Spiel von %s" : "Lokales Spiel"
Spanish (1034): "Partida de %s" : "Partida local"
French (1036): "Partie de %s" : "Partie locale"
Italian (1040): "Partita di %s" : "Partita locale"
Polish (1045): "Gra (%s)" : "Gra lokalna"
%s 为游戏创建玩家名字.
o 1.07以后的一些变动,似乎只提到了德语的?还是原文不全?或者是统一格式
(local game+PlayerName)?
(see war3.mpq\\UI\\FrameDef\\GlobalStrings.fdf: GAMENAME, LOCAL_GAME):
German (1031): "Lokales Spiel (%s)" : "Lokales Spiel"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.3 [字符串的编码]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
游戏设置和3个0值结尾的字符串靠在一起编成单一0值结尾字符串,
(令人费解!)
每个字节值都加1. 所有编码字节为奇.
一个控制字节储存后7个字节的变化信息.
如此一来所有空字节变成1, 它们永不会出现在编码字符内. 而空字节的作用是标记编码字符串的结末.
编码字符串起始于一个控制字节.
控制字节以一位比特为后7个字节标记出位段. Bit 1 (not Bit 0) 指向控制字节之后的紧连字节, bit 2 为再下一个 , 如此.
只有Bit 1-7 分给编码字符的关连指向. Bit 0 不使用
解码方式如下:
如果关联位为 '1'则字符直接移动(不变).
如果关联位为 '0'则字符减1.
在一个控制字节和随后的7字节后又是一个控制字节,直到遇到一个空字符为止。
一段解码的代码举例( 用C):
[codes=c]char* EncodedString;
char* DecodedString;
char mask;
int pos=0;
int dpos=0;
while (EncodedString[pos] != 0)
{
if (pos%8 == 0) mask=EncodedString[pos];
else
{
if ((mask & (0x1 << (pos%8))) == 0)
DecodedString[dpos++] = EncodedString[pos] - 1;
else
DecodedString[dpos++] = EncodedString[pos];
}
pos++;
}[/codes]
编码方式可以变相解释为:
每个字符中的’0’位移至控制字节,然后设为1.
TODO:也许可以通过这点构造更简易的解码算法。.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.4 [游戏设置]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
首先你要解码游戏设置部分 (见 4.3).
游戏设置 (创建游戏时的扩展选项“高级选项”部分) 由总计13个字节的各种标志(flag)构成.
想了解详细设置的话看这里:
"support/Readme/(PC)UIMainMenus.html"
自己在你的魔兽安装目录下找.
下面列出的是已知的非空标志.
偏移 | 位值 | 描述
-------+-------+---------------------------------------------------------------
0x0000 | 0,1 | 游戏速度: 0 = 慢, 1 = 正常, 2 = 快, 3 = 未使用
-------+-------+---------------------------------------------------------------
0x0001 | 0 |可见度:隐藏地形
| 1 |可见度: 探索过的地图
| 2 |可见度: 总是可见(无战争烟雾)
| 3 |可见度: 默认
| 4,5 | 观察者 : 0 = 关闭或为裁判 (参见 0x0003 Bit6)
| | 1 = 未使用
| | 2 = 默认的观察者
| | 3 = 打开或为裁判
| 6 | 共同队伍 (队伍成员的起始点相邻)
-------+-------+---------------------------------------------------------------
0x0002 | 1,2 | 锁定队伍: 0 = 关, 1 = 未使用, 2 = 未使用, 3 = 开
-------+-------+---------------------------------------------------------------
0x0003 | 0 | 完全单位共享
| 1 | 随机英雄
| 2 | 随机种族
| 6 | 观察者为裁判 (另见观察者相关部分 0 or 3)
-------+-------+---------------------------------------------------------------
0x0004 | | 0
0x0005 | | 未知 (0 出现在战网ladder对战,自定义游戏中没有)
0x0006 | | 0
0x0007 | | 未知 (0 出现在战网ladder对战,自定义游戏中没有)
0x0008 | | 0
-------+-------+---------------------------------------------------------------
0x0009 | 4Byte | 地图效验 //TODO: 算法呢?
- 0C | |
-------+-------+---------------------------------------------------------------
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.5 [地图或游戏创建名]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
你需要先解码这部分内容 (见 4.3).
先是地图名, 然后是游戏创建者 (ladder对战中是"Battle.Net")再接下来是空值字符串.
编码的字符自此结束,接下来该不会有何未处理的解码字节 (了吧?).
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.6 [玩家数]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4 bytes – 玩家数目或可加入玩家槽数
战网对战中指玩家确切数目
自定义游戏中, 是加入游戏屏幕上显示的玩家槽数(最大,和是否关闭无关)
单人自定义游戏为12
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.7 [游戏类型]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
偏移 | 大小/类型 | 描述
-------+-----------+-----------------------------------------------------------
0x0000 | 1 byte | 游戏类型:
| | (0x00 = 未知,曾在1、03以前的一些版本里出现过)
| | 0x01 = Ladder对战 -> 1v1或 FFA混战
或者是Custom -> Scenario(指有暴雪签名的自定义地图) (不能完全确定)
| | 0x09 = 自定义游戏
| | 0x1D = 单人游戏
| | 0x20 = Ladder组队作战 (战友组队或随机队伍, 2v2、3v3、4v4等)
0x0001 | 1 byte | 自定义游戏的私有标志:
| | 0x00 - 当为公开的局域网/战网自定义游戏时
| | 0x08 - 当为战网自定义游戏设为私人游戏时
0x0002 | 1 word | 未知 (总为 0x0000 )
TODO:
1.07后的数值:
01 00 00 00 : ladder 1v1 / 暴雪签名的自定义地图
20 00 00 00 : ladder 组队
09 00 00 00 : 自定义游戏
09 A8 12 00 : 自定义游戏
09 A0 12 00 : 自定义游戏
09 A8 42 00 : 自定义游戏
09 A8 14 00 : 自定义游戏
09 A0 14 00 : 自定义游戏
01 40 13 00 : 自定义游戏
09 A0 42 00 : 自定义游戏
09 A8 44 00 : 自定义游戏
(是指后来版本的自定义游戏标志曾多次改变?)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.8 [语言id]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4 byte - (独立于地域(指语言区?),地图,游戏类型 !)
也许是别的效验码或经过编码的语言.
手中的一些录像文件中找到的数值: (ger=通用,eng=英文?)
C4 F0 12 00 - patch 1.10 ger
90 F1 12 00 - patch 1.06 ger
90 F1 12 00 - patch 1.05 ger
A0 F6 6D 00 - patch 1.04 ger
24 F8 12 00 - patch 1.04 eng(?)
A0 F6 6D 00 - patch 1.03 ger
C0 F6 6D 00 - patch 1.02 ger
//TODO: 这部分内容尚且不明确,也许你能找出答案.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.9 [玩家列表]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
这里的玩家列表是由所有加入游戏玩家的记录数组。
(除去游戏主机和电脑玩家).
这意味着如果只有一个人类玩家(难道不能全电脑么)的话这里啥都没有..
每个加入游戏的玩家以以下结构记录:
偏移 | 大小/类型 | 描述
-------+-----------+-----------------------------------------------------------
0x0000 | 4/11 byte | 玩家记录 (见 4.1)
0x000? | 4 byte | 未知
| | (总为 0x00000000 对于1.07以后说来;
| | 若是 0x00000001 是1.06及以前的)
当玩家记录标记为“加入玩家” (第一字节0x16 同见 4.1)时就以这份样式进行记录.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.10 [游戏起始记录]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
偏移 | 大小/类型 | 描述
-------+-----------+-----------------------------------------------------------
0x0000 | 1 byte | 记录ID - 总为 0x19
0x0001 | 1 word | 以下数据的编号
0x0003 | 1 byte | 录像记录的玩家数目 == 玩家槽数目(创建游戏时所见的)
0x0004 | n bytes | nr * SlotRecord (see 4.11) (这啥?)
n+4 | 1 dword | 随机种子 (见 4.12)
n+8 | 1 byte | 选择模式
| | 0x00 - 队伍和种族可自由选择 (常规的自定义对战)
| | 0x01 - 队伍锁定
| | (地图设置: 编辑器中锁定势力选项)
| | 0x03 - 队伍和种族不可选
| | (地图设置: 编辑器中固定玩家选项) (都自己找找吧:)
| | 0x04 - 固定的随机种族
| | (创建游戏时的高级选项: 随机种族)
| | 0xcc - 自动匹配比赛(ladder对战)
n+9 | 1 byte | 起始点数 (地图设置的起始点..没啥好说的)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.11 [玩家槽记录]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
偏移 | 大小/类型 | 描述
-------+-----------+-----------------------------------------------------------
0x0000 | 1 byte | 玩家 id (电脑玩家是0x00)
0x0001 | 1 byte | 地图下载类型: 0x64 自定义游戏, 0xff ladder对战
0x0002 | 1 byte | 玩家槽状态:
| | 0x00 空的
| | 0x01 关闭
| | 0x02 使用
0x0003 | 1 byte | 电脑玩家标志:
| | 0x00 人类的话..
| | 0x01 标识电脑
0x0004 | 1 byte | 队伍号:0 - 11
| | (队伍 12 是观察者或裁判)
0x0005 | 1 byte | 颜色 (0-11):
| | 其值+1 为WE里的玩家颜色(和bj一样..):
| | (red, blue, cyan, purple, yellow, orange, green,
| | pink, gray, light blue, dark green, brown,这些就是颜色..)
| | 第12号颜色 == 观察者和裁判的(白色对吧?)
0x0006 | 1 byte | 玩家种族标志 (如你在游戏中所选):
| | 0x01=人类
| | 0x02=兽人
| | 0x04=暗夜精灵
| | 0x08=亡灵天灾
| | 0x20=随机
| | 0x40=种族可选/固定 (见下面的注释)
0x0007 | 1 byte | 电脑ai等级: (1.03以上版本才有)
| | 0x00 for 简单级
| | 0x01 for 普通级
| | 0x02 for 疯狂级
| | 对非AI玩家来说这里是 0x01 (意思人类的水平就相当于普通级别的ai..)
0x0008 | 1 byte | 玩家设置的生命自虐障碍百分比 (如你在游戏中所见)
| | 可用数值: 0x32, 0x3C, 0x46, 0x50, 0x5A, 0x64 (50=100)
| | (当然在1.07以上版本才有)
注释:
o 1.03以前,这部分记录只有7字节.
最后两项是没有的.(谁还管1.03以前的版本啊,有么..)
o 1.07版本以前是8字节最后一项没有.(..同上)
o 是否锁定队伍和颜色部分(指加入游戏后是否可由玩家调整队伍和颜色)未能确定.
o 1.06以前版本的规则:
当玩家种族标志第6位为1 (0x40 added) 则认为是地图固定了种族 (参见 4.10).
o 1.07以后:
当玩家种族标志第6位为1 (0x40 added) 认为是可选择的(与以上相反)。否则为ladder对战或
地图固定了种族(同见4.10) (话说我怎么没见到什么..)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4.12 [随机种子]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
这部分可谓是魔兽3引擎初始化随机种子采取的最佳措施. 录像数据的运转需要这样一个设好的随机种子
(起始点和种族这些数据这时已经设置好).
队自定义游戏来说(无论战网还是局域网) 这个随机种子的双字看起来是游戏主机魔兽程序的运行时间(毫秒计).
ladder对战里要严格些 - 也许通过服务器传来一个“真”的随机种子 (至少不像游戏运行时间这样一下就被猜到)。
=============================================================================== |
|