魔兽搜索器的反过程--魔兽发布器,java版

想必玩魔兽的人都玩过浩方。玩魔兽的同学都用过魔兽搜索器。浩方的就复杂了,魔兽搜索器的原理就简单多了。这里我不多讲搜索器。就简单说说原理。

魔兽端口:6112

有必要介绍一下魔兽的数据包:(UDP包)
1,[color=red]搜索包[/color]。交流的信息是“喂:你建图了吗??”
当建立了地图的主机收到这个包的时候就会把自己的地图返回给他,这个包我叫他地图包。

2,[color=red]地图包[/color]。交流的信息是“这是我建立的图,好好看看吧”。
这个包里面有地图信息,人数,电脑数等。都是有用的信息。
收到这个包的魔兽就能看到熟悉的“本地局域网游戏……”

3,[color=red]主机发布包[/color]。交流的信息是“我建图了,大家快来看呀!!”
这个是主机广播的。收到这个包的魔兽都会回答一个包。就是那个搜索包。

为什么魔兽就能在一个局域网中能看到呢??
因为这些包都是以255.255.255.255这个地址广播的。
所以只要把这些包突破这个255就能实现和外网联机。

[color=darkred]搜索器:[/color]
搜索器的原理就是向其他的ip地址发送 [color=red]搜索包[/color]。这样把主机的地图包骗过来。抛砖引玉的效果。
骗到了[color=red]地图包[/color],也就知道了主机在哪。可以和主机建立tcp连接。然后就是骗自己的魔兽。
把收到的[color=red]地图包[/color]发送给自己,魔兽就乖乖的把它显示在熟悉的“本地局域网游戏……”
加入游戏的时候就是和自己建立tcp连接。

这时候的tcp连接时 自己---搜索器---主机 。如果游戏中关闭收索器。那么就over了。断开连接。

搜索器就分析到这。

[color=darkred]发布器:[/color]
原理:
主机向各IP发布[color=red]主机发布包[/color]。
客户机收到之后自然就会回复一个[color=red]搜索包[/color]。注意这个[color=red]搜索包[/color]是魔兽自己回复的,当然是回复给发布器。
发布器把[color=red]地图包[/color]返回给他。
客服看到游戏。
建立tcp联机。
这时候的tcp连接是:魔兽-魔兽。没有中间的发布器。

如何获取地图包?
给自己主机发送搜索包。

为什么不要客户机能直接和魔兽建立tcp?
因为在[color=red]地图包[/color]里面包含有魔兽的端口信息(6112)。魔兽会连接到主机ip+6112端口的。这就和魔兽发布器无关的原因。发布器只是引导一下udp包。

这个中间少了很多东西。不需要每个人都在发搜索包收索谁建立主机。只要主机一个人发。游戏中也不需要别人转接什么tcp了·~

java实现很容易了,在加入聊天功能。

实现魔兽千人房也不是问题。(因为根本不存在房间的概念,所有的人都在这个房间)

开源地址:http://code.google.com/p/warpuber/
代码发布密码:ZZ7Kr3qd7zq3

目前基本功能实现,开发不是很全。希望有人关注,和我一起完善。


感谢关注的人。用这个方法实现魔兽联机确实是一条捷径。要用收索器有个很大的难题。
就是 魔兽--搜索器--魔兽 这个中间代理很不好做。
需要抓包分析,网络底层……
java是很难实现的,c++用spi能实现,我现在就想把搜索和发布的功能都实现。


还是有好多人没看明白。编程人就用程序说话吧。临时写一个测试文件,自己研究研究吧!

/**
* 运行这个你就知道什么原理了。
*1.打开魔兽1.20
*2.建立地图。任意。
*3.运行这个
*4.取消地图。
*/
package test;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import xinyu126.common.DataContainer;

/**
* @author xinyu126
*
*/
public class TestWar {
public static byte[] warSearch = { (byte) 0xf7, 0x2f, 0x10, 0x00, 0x50, 0x58, 0x33, 0x57, 0x14, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
public static byte[] warPublish = { (byte) 0xF7, 0x32, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00 };
class Server implements Runnable{
public void run(){
while (p == null) {
//2 监听包
//获取地图包
//因为我给我自己发了搜索包。所以我自己的魔兽会乖乖的给我地图包。
try {
server.receive(packet);

byte[] data = packet.getData();
//这里是换地图的显示信息
byte[] mm = "test play dota".getBytes();
mm = new String(mm).getBytes("utf-8");
int len = mm.length > 31 ? 31 : mm.length;
for (int i = 0; i < len; i++) {
data[20 + i] = mm[i];
}
//换完了
p = new DatagramPacket(data, packet.getLength(), ip, 6112);
System.out.println("shoudao" + new String(data));
} catch (IOException e) {
}

}
while (p != null) {
//3收到了后。发送给自己
//这就能看到自己建的地图了。但是不能加入,因为是假的!
//要是不发送给自己,那么就换个ip地址发送吧。那么别人会看到1-2个你。为甚呢??自己想去
//
try {
Thread.sleep(3000);
server.send(pub);
// server.receive(packet);
Thread.sleep(1000);
server.send(p);

} catch (InterruptedException e) {
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("发送!!");
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
new TestWar();

}

DatagramSocket server;
DatagramPacket packet, pub, p;
byte[] data;
InetAddress ip;
TestWar() {
try {
//6113 随便开的端口
//6112 魔兽端口。不能随便呀!
server = new DatagramSocket(6113);
ip = InetAddress.getLocalHost();
packet = new DatagramPacket(warSearch, 16, ip, 6112);
pub = new DatagramPacket(warPublish, 16, ip, 6112);
//1-----发送搜索包。这里就开始骗人了!~~哈哈
server.send(packet);
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


data = new byte[1024];
packet = new DatagramPacket(data, data.length);
p = null;
new Thread(new Server()).start();
}

}



运行效果
[img]http://dl.iteye.com/upload/attachment/162610/8a6bc6e4-4fba-3871-822b-29e4362d4f1a.jpg[/img]

10.31 回答c-j的问题(第三页最后一楼)
这里在作为一个说明:
我想很多人都没有发现的一个捷径。这也是为什么我这个方法不用抓包的原因。
[color=red]
因为地图包的最后两个字节包含端口信息!
所以无论什么端口发给魔兽。魔兽都能正确判断游戏主机的端口!!
我用6113端口为例吧。我做的程序也是6113端口。
例如我是用6113端口给魔兽6112端口发送地图包。
但是魔兽tcp会连接到6112端口去。而不是6113。这点是关键所在!
在UDP包的收发中魔兽收到6113的UDP包后,会把回复发送给6113端口。
但是魔兽解析地图的时候会忽略6113端口。而采用地图包里面的信息6112.
[/color]

另外魔兽的6112端口是可以自己设置的。刚进魔兽的时候可以修改。这一点,也就必须让魔兽把端口号放在地图包里面。

所以只要能让魔兽收到 ip+地图包。就能保证联机。tcp就可以不用管。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值