不用对战平台玩魔兽

1月9日

不用浩方互联网打魔兽争霸全攻略

昨天和hewei晚上做了全面测试,总结出如下方法。

魔兽建立连接分析

1 udp获得游戏列表(A是主,B是客户机)
B进入游戏,进入局域网,会向局域网发出udp广播,udp目标端口是6112,A收到这个广播后返回一个udp包给B,B才会在魔兽的游戏列表里看到A建的游戏。 

2 看到A建的游戏后,B双击进入游戏会建立一个到A的tcp连接,端口也是6112 。


游戏方案

1利用使用ddwrt的路由器的pptp转发功能实现。

我之前没有测试成功,可能是版本的问题,现在测试的ddwrt是DD-WRT v24-sp2 (01/01/09) mini-usb-ftp (用std 还是mini 都可以)  (SVN revision 11296M VINT Eko)。

进入ddwrt 管理界面,service > vpn 打开pptp服务设置用户密码,打开 Broadcast support(这个是启用bcrelay模块,负责转发广播包) 选项。

客户端拨号到路由器连接vpn,到此就和在同一网段的局域网打游戏一样了。(魔兽争霸已经测试成功)

其他局域网的游戏应该也可以比如cs,大家可以测试一下。不过基于ipx协议的局域网游戏可能不行。

2 普通vpn + battleLan

对于没有广播转发功能的vpn可以采用下面小程序。

battlelan(一个夸网段玩局域网游戏的程序) 下载 http://home.comcast.net/~sonicsmart/battlelan.html

(魔兽争霸已经测试成功)

3 只用battleLan

对于俩个adsl拨号的玩家,只使用battlelan填入主机adsl分配的公网ip就可以连接,而在宽带路由器后面的用户可以在路由器设置udp和tcp 6112端口的转发到你的机器。(魔兽争霸已经测试成功)

以上只是描述关键部分,至于ddsn的设置,vpn的设置,路由器的设置,battlelan的设置没有详细说明。



下面是在一个论坛看的BattleLAN工作原理:

--------------------------------------------------------

冰封抓包结果如下:

1》开游戏,点“局域网”发出消息:
172.16.28.16——>255.255.255.255  udp LEN=udp 24B      端口:6112——>6112 
发送的数据:   
f7 2f 10 00 50 58 33 57 14 00 00 00 00 00 00 00

2》开BattleLAN不发送消息
3》开BattleLAN点“局域网”发出消息172.16.28.16——>255.255.255.255  udp LEN=24      端口:6112——>6112
172.16.28.16——>BattleLAN中地址  udp LEN=24      端口:6112——>6112
其中发往172.16.30.35的消息为::(172.16.30.35是BattleLAN.ini中IP之一)
f7 2f 10 00 50 58 33 57 14 00 00 00 00 00 00 00

4》用BattleLAN正常非同子网联机过程:

172.16.30.30创建游戏,172.16.28.14进行正常连接过程:(172.16.28.14开BattleLAN)
172.16.28.14——>172.16.30.30   udp LEN=24   端口:6112——>6112
内容:f7 2f 10 00 50 58 33 57 14 00 00 00 00 00 00 00
172.16.30.30——>172.16.28.14   udp LEN=159  端口:6112——>6112
内 容:f7 30 97 00 50 58 33 57 14 00 00 00 01 00 00 00 d7 ca ab 02 e5 bd 93 e5 9c b0 e5 b1 80 e5 9f 9f e7 bd 91 e5 86 85 e7 9a 84 e6 b8 b8 e6 88 8f 20 28 79 6c 00 00 01 03 49 07 01 01 75 01 a1 75 01 db e9 23 03 4d cb 61 71 73 5d 45 6f 77 19 6f 6d 6f 61 65 5d 45 2b 6f 75 41 21 41 6d 6d 2b 73 75 61 73 73 21 77 d9 37 2f 35 31 21 41 49 65 21 43 4f 2f 77 33 79 35 01 79 6d 77 71 75 79 01 01 01 00 0a 00 00 00 01 00 00 00 01 00 00 00 0a 00 00 00 72 08 00 00 e0 17

(到此172.16.28.14看到172.16.30.30建的组,双击建的组进入到游戏中)
172.16.28.14——>172.16.30.30  tcp  LEN=0  端口:3704——>6112
172.16.30.30——>172.16.28.14  tcp  LEN=0  端口:6112——>3704
...

结论:

1》BattleLAN只做两件工作:1截本地到广播的包2将截到的包发往BattleLAN.ini中记录的IP

2》冰封联机原理:A建游戏,B去联,B只需向A发送一个LEN=24,源和目的端口为6112的特定UDP包就可以了。

 

这样我们可以通过原始套接字完成以上功能,利用此原理,我写了一个功能类似BattleLAN的软件(SendWar)可以正常连冰封。以下是其核心代码和步骤:

               构造要发的包

   char buffer[4096]="\x17\xe0\x17\xe0\x00\x18\x00\x00\xf7\x2f\x10\x00\x50\x58\x33\x57\x14\x00\x00\x00\x00\x00\x00\x00";//1.20版本
    char buffer1[4096]="\x17\xe0\x17\xe0\x00\x18\x00\x00\xf7\x2f\x10\x00\x50\x58 \x33\x57\x15\x00\x00\x00\x00\x00\x00\x00";//1.21版本

               初始化原始套接字

  SendSocket = socket(PF_INET,SOCK_RAW,IPPROTO_UDP);

               获取目的主机名(建游戏的主机名)
     if(atoi(allIPstr[j]))  //allIPstr[j]中记录的是目的主机字符串之一
    {
      u_long ip = inet_addr(allIPstr[j]);
      hostdata = gethostbyaddr((char*)&ip,sizeof(ip),PF_INET);
    }
     else
    {
      hostdata = gethostbyname(allIPstr[j]);
    }
     if(!hostdata)
    {
      fflush(0);
      continue;
    }
    sockaddr_in dest;
    dest.sin_family = PF_INET;
    dest.sin_addr = *(in_addr*)(hostdata->h_addr_list[0]);

  //发包

     sendto(SendSocket,buffer,24,0,(sockaddr *)&dest,sizeof(sockaddr_in));

   sendto(SendSocket,buffer1,24,0,(sockaddr *)&dest,sizeof(sockaddr_in));

  如目的主机确实有建游戏则发完包后可以看到所建的游戏,这样双击就可以进行游戏了

 

注意冰封1.21与1.20版本所发送的LEN=24UDP消息有稍微不同,所以上面发了两个包(BattleLAN与此不同,它是截获消息发送出 去,当然你也可认像BattleLAN一样,另外我没有计算较验码(不影响连游戏),我写的SendWar可以像BattleLAN一样工作(一直开着也 不会卡,当然没必要一直开)。

懂得了原理你也可以写出自己的BattleLAN了哦! 

posted @ 2010-05-13 00:03  elite_lcf  阅读(4423)  评论(0编辑  收藏  举报
知识共享许可协议
本博客采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。