Warcraft局域网内数据格式

发布时间 : 星期日 文章Warcraft局域网内数据格式更新完毕开始阅读

魔兽争霸III数据包规范

v0.3 by Soar Qin

(麦德三世 译)

1. 本文涉及的数据包种类

a) 魔兽争霸III拥有以下类型的数据包

i. 局域网UDP数据包。

这类数据包都用于在游戏准备阶段广播/检测游戏信息。 ii. 游戏中TCP数据包。

这类数据包在游戏准备阶段和实际游戏阶段都会被用到。 我会分两部分来介绍这类数据包。 iii. Battle.net TCP/UDP 数据包。

有时间的话,我会用一份单独的doc文档来介绍这部分。 目前可暂且参考 http://www.bnetdocs.org.

b) 本规范中仅讨论前二类数据包。

2. 数据包头

魔兽争霸III中使用的所有数据包都拥有四字节的包头,具体如下表:

字节 / 类型 1 / uint8 用途 魔数标志位。 0xF7 – 局域网UDP或游戏中TCP数据包(本文中所有数据包都采用这个标志) 0xFF -- Battle.net战网数据包 1 / uint8 2 / uint16

操作码。详情参考第3、4、5部分。 数据包长度(包括4字节的包头部分)。 3. 局域网UDP数据包

a) 操作码0x2F

这种数据包用于查询局域网游戏,它可用于两种场合:1.应答0x31或0x32数据包以查询指定游戏的信息。2.玩家进入局域网游戏界面时发送。向255.255.255.255广播以查询所有可加入的游戏。

字节 / 类型 4 / uint32 用途 以低位在前的方式表示游戏类型。 'W3XP' = TFT 'WAR3' = ROC 4 / uint32 游戏版本。 比如War3 1.24,这里就填24。 4 / uint32

b) 操作码0x30

游戏ID, 广播时置零。 用于应答UDP 0x2F数据包,该数据包包含完整的游戏信息。 字节 / 类型 4 / uint32 用途 以低位在前的方式表示操作系统信息。 'IX86' = Windows 'XMAC' = Mac OS X 4 / uint32 4 / uint32 4 / uint32 以低位在前的方式表示游戏类型。 游戏ID。 系统时钟(比如Windows就用GetTickCount()来获得)。 N/以'\\0'结束的这是一个经过编码的字符串,包含着大量重要的游字符串 4 / uint32 4 / uint32 戏信息。参考附注。 玩家位置数。 游戏标志。据我所知 0x01 = 剧情游戏;0x09 = 自定义游戏。 4 / uint32 4 / uint32 游戏内玩家数。 非电脑玩家位置数。 综上所述,我们可以得出这样的公式:显示的游戏内玩家数=游戏内玩家数+(位置数-非电脑位置数) 4 / uint32 2 / uint16 未知。通常是0-0x80 以低位在前方式表示用于侦听连接的TCP游戏端口。

附注(编码字符串):

所有值为偶数的字节都+1。因此所有编码后的字节都是奇数。并用一个控制字节来保存接下去7字节的转换方式。

因为所有空字节都会变成1,因此编码字符串内不会包含空字节。但空字节用于表征字符串的结束。

编码字符串以一个控制字节开头。

控制字节中第1-7位(不包括第0位)分别依次对应控制字节后的7个字节。

第0位无作用,永远设为1。 解码方式如下:

如果对应位为'1',那么该字符不作修改。 如果对应位为'0',那么该字符的值要减去1。

解码完一个控制字节其后的七个字节后,接下去的字节又是一个新的控制字节。

重复操作直到数据流中出现NULL字符。

用C语言解码的样例:

char* EncodedString; char* DecodedString; char mask;

int pos=0, dpos=0;

while (EncodedString[pos] != 0) {

if (pos%8 == 0) mask=EncodedString[pos]; else {

if ((mask & (0x1 << (pos%8))) == 0)

联系合同范文客服:xxxxx#qq.com(#替换为@)