字节 / 类型
|
用途
|
1 / uint8
|
魔数标志位。
0xF7 – 局域网
UDP或游戏中TCP数据包(本文中所有数据包都采用这个标志)
0xFF -- Battle.net战网数据包
|
1 / uint8
|
操作码。详情参考第
3、4、5部分。
|
2 / uint16
|
数据包长度(包括
4字节的包头部分)。
|
字节 / 类型
|
用途
|
4 / uint32
|
以低位在前的方式表示游戏类型。
'W3XP' = TFT
'WAR3' = ROC
|
4 / uint32
|
游戏版本。
比如
War3 1.24,这里就填24。
|
4 / uint32
|
游戏
ID, 广播时置零。
|
字节 / 类型
|
用途
|
4 / uint32
|
以低位在前的方式表示操作系统信息。
'IX86' = Windows
'XMAC' = Mac OS X
|
4 / uint32
|
以低位在前的方式表示游戏类型。
|
4 / uint32
|
游戏
ID。
|
4 / uint32
|
系统时钟
(比如Windows就用GetTickCount()来获得)。
|
N/以
'\0'结束的字符串
|
这是一个经过编码的字符串,包含着大量重要的游戏信息。参考附注。
|
4 / uint32
|
玩家位置数。
|
4 / uint32
|
游戏标志。据我所知
0x01 = 剧情游戏;0x09 = 自定义游戏。
|
4 / uint32
|
游戏内玩家数。
|
4 / uint32
|
非电脑玩家位置数。
综上所述,我们可以得出这样的公式:显示的游戏内玩家数
=游戏内玩家数+(位置数-非电脑位置数)
|
4 / uint32
|
未知。通常是
0-0x80
|
2 / uint16
|
以低位在前方式表示用于侦听连接的
TCP游戏端口。
|
字节 / 类型
|
用途
|
4 / uint32
|
游戏设置。
|
1 / uint8
|
永远为
0。
|
2 / uint16
|
地图宽度。
|
2 / uint16
|
地图高度。
|
4 / uint32
|
地图本地校验码。
|
N/以
'\0'结束的字符串
|
地图名。
|
N/以
'\0'结束的字符串
|
主机用户名。
|
1 / uint8
|
永远为
0(也算个以'\0'结束的字符串?)
|
20 / uint8[20]
|
地图本地
SHA-1哈希值,这一段是1.23版后添加的,以防止地图互通。
|
字节 / 类型
|
用途
|
4 / uint32
|
以低位在前的方式表示游戏类型。
|
4 / uint32
|
游戏版本。
|
4 / uint32
|
游戏
ID(初始为1,随着逐个游戏的创建而自增)。
|
字节 / 类型
|
用途
|
4 / uint32
|
游戏
ID。
|
4 / uint32
|
显示的游戏内玩家数。
|
4 / uint32
|
玩家位置总数。
|
字节 / 类型
|
用途
|
4 / uint32
|
游戏
ID
|
字节 / 类型
|
用途
|
4 / uint32
|
系统时钟
(比如Windows就用GetTickCount()来获得)。
|
字节 / 类型
|
用途
|
2 / uint16
|
接下去
5段信息的总长度(到“开始位置数”为止,不包括本段的2个字节。)
|
1 / uint8
|
玩家位记录的条数,这里记为
RN。
|
9 * RN / 玩家位记录
* RN
|
每条玩家位记录代表每个玩家位的详细信息。每条记录的结构如下:
uint8
玩家
ID。0为电脑,0xFF为空。
uint8
地图下载进度。
0-100,0xFF代表'?'。
uint8
玩家位状态。
0-空,1-关闭,2-已有玩家。
uint8
是否电脑。
0-活人,1-电脑。
uint8
队伍。
0-11,12代表ob/裁判。
uint8
颜色。
0-11,12代表ob/裁判。
uint8
种族。
0x01-人类,
0x02-兽人,
0x04-暗夜精灵,
0x08-亡灵,
0x20-随机,
0x40-地图未指定。
uint8 AI等级。
0-简单,1-普通,2-疯狂
uint8
生命百分比。
通常为
50,60,70,80,90,100。用GHost++可设为其他值。
|
4 / uint32
|
游戏的初始随机种子。
|
1 / uint8
|
队伍和种族锁定标记:
0x01 – 队伍已锁定
0x02 – 种族已锁定
0x04 – 种族为随机(无法与
0x02共用)
|
1 / uint8
|
地图开始位置数。
|
1 / uint8
|
为新加入玩家分配的玩家位。
|
16 / sockaddr_in
|
主机用
getpeername()获得的目标玩家地址。
|
字节 / 类型
|
用途
|
4 / uint32
|
始终为
0x02,可能是sockaddr_in的结尾数字?
|
1 / uint8
|
在玩家位信息中显示的玩家
ID。
|
N/以
'\0'结束的字符串
|
玩家名。最长
16字节(包括结尾的'\0')。
|
1 / uint8
|
后续的额外字节数。局域网游戏中总是
1。
|
N / uint8[N]
|
额外字节。局域网游戏中总是一个
\0字节。
|
16 / sockaddr_in
|
从
getpeername()获得的该玩家地址。
|
16 / sockaddr_in
|
从
NAT路由(如果有)获得的该玩家地址(似乎只用于Battle.net战网)。
|
字节 / 类型
|
用途
|
1 / uint8
|
玩家
ID。
|
4 / uint32
|
离开原因标志。这部分还需进一步研究。
|
字节 / 类型
|
用途
|
1 / uint8
|
玩家
ID。
|
字节 / 类型
|
用途
|
2 / uint16
|
接下去
5段信息的总长度(到“开始位置数”为止,不包括本段的2个字节。)
|
1 / uint8
|
玩家位记录的条数,这里记为
RN。
|
9 * RN / 玩家位记录
* RN
|
每条玩家位记录代表每个玩家位的详细信息。每条记录的结构如下:
uint8
玩家
ID。0为电脑,0xFF为空。
uint8
地图下载进度。
0-100,0xFF代表'?'。
uint8
玩家位状态。
0-空,1-关闭,2-已有玩家。
uint8
是否电脑。
0-活人,1-电脑。
uint8
队伍。
0-11,12代表ob/裁判。
uint8
颜色。
0-11,12代表ob/裁判。
uint8
种族。
0x01-人类,
0x02-兽人,
0x04-暗夜精灵,
0x08-亡灵,
0x20-随机,
0x40-地图未指定。
uint8 AI等级。
0-简单,1-普通,2-疯狂
uint8
生命百分比。
通常为
50,60,70,80,90,100。用GHost++可设为其他值。
|
4 / uint32
|
游戏的初始随机种子。
|
1 / uint8
|
队伍和种族锁定标记:
0x01 – 队伍已锁定
0x02 – 种族已锁定
0x04 – 种族为随机(无法与
0x02共用)
|
1 / uint8
|
地图开始位置数。
|
字节 / 类型
|
用途
|
1 / uint8
|
需发送聊天信息的目标玩家数,这里记为
PN
|
PN / uint8 * PN
|
每个
uint8保存一个目标玩家ID。
|
1 / uint8
|
聊天信息发送者的玩家
ID
|
1 / uint8
|
聊天信息标志。
0x10-准备阶段,
0x20-游戏阶段
|
4 / uint32
|
发送目标标志。
0x00 – 向所有玩家发送
0x01 – 向盟友发送
0x02 – 向
OB/裁判发送
0x03-0x0E – 向特定玩家发送(玩家
ID=值-2)
当聊天信息标志为
0x10(即游戏准备阶段)时,这段信息将被排除。
|
N/以
'\0'结束的字符串
|
聊天字符串。
|
字节 / 类型
|
用途
|
4 / uint32
|
游戏
ID。
|
4 / uint32
|
游戏开始后经过的毫秒数。
|
1 / uint8
|
始终为
0。
|
2 / uint16
|
客户端的游戏端口。用于地图信息交换、直接私聊、主机变更等等。
|
4 / uint32
|
客户端会话计数器。初始值为
1,每加入一个游戏都会自增。
|
N/以
'\0'结束的字符串
|
用户名。
|
2 / uint16
|
可用的公共端口。这里记为
P。
|
16 * P / sockaddr_in * P
|
每个公共端口都有一个套接字
sockaddr_in结构。
|
字节 / 类型
|
用途
|
4 / uint32
|
理由标志。还需进一步研究。
|
字节 / 类型
|
用途
|
1 / uint8
|
需要发送聊天信息的玩家总数,这里记为
PN
|
PN / uint8 * PN
|
每个
uint8保存一个需发送聊天信息的玩家ID。
|
1 / uint8
|
聊天信息发送者的玩家
ID。
|
1 / uint8
|
聊天信息标志。
0x10 – 游戏准备阶段的聊天
0x11 – 变更小队
0x12 – 变更颜色
0x13 – 变更种族
0x14 – 变更生命百分比
0x20 – 游戏进行阶段的聊天
|
字节 / 类型
|
用途
|
4 / uint32
|
发送目标标志。
0x00 – 向所有玩家发送
0x01 – 向盟友发送
0x02 – 向
OB/裁判发送
0x03-0x0E – 向特定玩家发送(玩家
ID=值-2)
当聊天信息标志为
0x10(即游戏准备阶段)时,这段信息将被排除。
|
N/以
'\0'结束的字符串
|
聊天字符串。
|
字节 / 类型
|
用途
|
1 / uint8
|
数据。
聊天信息标志
= 0x11: 小队
聊天信息标志
= 0x12: 颜色
聊天信息标志
= 0x13: 种族
聊天信息标志
= 0x14: 生命百分比
参考
0x04/0x09玩家位信息部分。
|
字节 / 类型
|
用途
|
4 / uint32
|
地图
ID(?)
|
N/以
'\0'结束的字符串
|
地图路径
|
4 / uint32
|
地图大小(单位为字节)。
|
4 / uint32
|
整个地图文件的
CRC32。
|
4 / uint32
|
地图本地校验码。
|
20 / uint8[20]
|
地图本地
SHA-1哈希值,这一段是1.23版后添加的,以防止地图互通。
|
字节 / 类型
|
用途
|
4 / uint32
|
地图
ID(?)
|
1 / uint8
|
玩家
ID
|
字节 / 类型
|
用途
|
4 / uint32
|
地图
ID(?)
|
1 / uint8
|
下载源玩家
ID或主机ID
|
4 / uint32
|
可用地图尺寸(下载进度)
|
字节 / 类型
|
用途
|
1 / uint8
|
目标玩家
ID
|
1 / uint8
|
源玩家
ID
|
4 / uint32
|
地图
ID(?)
|
4 / uint32
|
地图文件偏移,用于写入数据。
|
4 / uint32
|
后面这段数据的
CRC32。
|
N / uint8[N]
|
地图数据。
|
字节 / 类型
|
用途
|
1 / uint8
|
目标玩家
ID
|
1 / uint8
|
源玩家
ID
|
4 / uint32
|
地图
ID(?)
|
4 / uint32
|
已下载的地图尺寸。
|
字节 / 类型
|
用途
|
1 / uint8
|
目标玩家
ID
|
1 / uint8
|
源玩家
ID
|
4 / uint32
|
地图
ID(?)
|
字节 / 类型
|
用途
|
4 / uint32
|
与
0x01数据包的值相同。
|
字节
/ 类型
|
用途
|
2 / uint16
|
游戏已用时间,单位是毫秒。
|
2 / uint16
|
下一段数据的
CRC32的低16位。
注意:如果游戏数据为空,这段数据本身也会被排除,这样整个包就只有
6字节。
|
N / uint8[N]
|
游戏数据。
|
字节 / 类型
|
用途
|
1 / uint8
|
玩家
ID
|
字节 / 类型
|
用途
|
2 / uint16
|
游戏已用时间,单位是毫秒。这里始终是
0。
|
2 / uint16
|
下一段数据的
CRC32的低16位。
注意:如果游戏数据为空,这段数据本身也会被排除,这样整个包就只有
6字节。
|
N / uint8[N]
|
游戏数据。
|
字节 / 类型
|
用途
|
N / uint8[N]
|
玩家操作数据,参考
0x0C以获得更多信息。
|
字节 / 类型
|
用途
|
4 / uint32
|
同步哈希值。
|