java 實現魔獸搜尋器 魔獸對戰平台

來源:互聯網
上載者:User

主要UDP包:
收索包:
內容:F7 2F 10 00 50 58 33 57 15 00 00 00 00 00 00 00
功能:向主機提出收索資訊。問別人“你建什麼主機?”
在開啟魔獸進入區域網路的時候,會向當前網段(255.255.255.255)廣播這個包。只要條件符合,收到這個包的主機都會返回一個地圖資訊給他(他:這個收索包的IP連接埠)
主機包:
內容:F7 32 10 00 00 00 00 00 01 00 00 00 00 00 00 00
功能:告訴別人:“我建主機了,要不要看看。”
建立主機的時候開始,向當前網段廣播這個包,每5秒鐘一次。收到這包的客戶機會發送搜尋包。
地圖包:
內容: 
F7 30 8C 00 50 58 33 57  14 00 00 00 01 00 00 00 
39 69 C2 00 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 76 73 00 00 01 03 49  07 01 01 77 01 B9 79 01  
99 D5 B9 31 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 B1 37 2F  37 31 63 2F 77 23 33 79  
01 77 73 01 01 00 0A 00  00 00 01 00 00 00 01 00
00 00 0A 00 00 00 1B 00  00 00 E0 17             
功能:“這就是我所建的圖,你好好看。”
主機收到搜尋包之後就把這個包返回給他,包括所有有用資訊。
 

魔獸的工作流程

魔獸進入區域網路的時候會廣播一個搜尋包,只發送一次。只發送當前網段(255.255.255.255),所以我們的魔獸只能看到本寢室,或者少數幾個寢室的幾個主機。

建立了了主機的魔獸收到之後就會發送一個包給他,這個包就是地圖資訊,包括地圖資訊,主機名稱,加入了多少人,剩下多少位置,還有一個重要的資料就是遊戲的連接埠。一般魔獸的連接埠是6112.

建立主機的魔獸會向本地發送一個包,“我建立主機了”

搜到這條訊息的魔獸會發送一個搜尋包給主機。

主機就發送 地圖資訊。

收到之後就解析地圖,這時候大家就看到了有人建主了                   點擊加入· ~  建立tcp串連 一直到推出主機的遊戲

 

ps: 一場遊戲下來,和主機發送的包 大概25MB(半小時) 主機收發的包就是 9*25 MB/30 min ;//按照dota計算 一個主+9個用戶端的10人遊戲。 這樣粗略的估計主機的網速要求就是 9*25*1024/30*60=128>100 kb/s 加上一點點別的程式所要的通訊包。要想不卡,主機的網速需要保證這個數吧。

 


關鍵技術

1,監聽主機(建立了魔獸地圖的機器)的地圖資訊。
     
      有兩種方法能獲得地圖資訊,一種是抓包,把所有的和6112連接埠有關的包都抓過來分析。(個人覺得這樣電腦的負擔太大了)。現在的多數搜尋器都是這樣實現的。
      但是Java要實現抓包不是很容易。c++能實現這個功能,可以考慮用c++編譯一個dll。Java調用。或者用開源項目。搜搜就能找到。
     
      我用的方法是建立一個線程。每5秒鐘發送一個包收索本機是否建立主機。如果自己建立了主機,則會返回一個地圖資訊包。收到之後告訴其他ip“我建主了”;
      這樣用戶端就不需要一直發送搜尋包了。
      找到了主機,一切都好辦了。
 2,告訴別人我建主機了
      如何告訴別人我建立了主機。很簡單,建立了主機的魔獸會每5秒鐘發送一個包給當前網段,告訴別人我建主機了。
      我們只要把這個包發送到其他ip的6112連接埠就ok了。就是告訴別人“我建主了”,收到的人就會發送一個包:“看看什麼圖”,然後主機就會回複一個包,沒錯這就    是地圖資訊!
     
 3,解析地圖
      不解析地圖不會對遊戲產生任何影響。因為魔獸接受地圖包,自己解析,它很明白這圖是什麼。但是解析地圖,你可以知道主機建立的這個地圖是什麼,主機叫什麼    名字,有幾個人加入,有幾個電腦。還有幾個空位置。主機是什麼版本。這些很有用的資訊在軟體上顯示出來時很有用的!
      關於UDP包的解說有好多的文章。大家可以去google上搜尋一下,關鍵字 魔獸 UDP
      我這裡就幾點補充。

這個是網上的:

02 00 00 00:遊戲總共允許玩家。
01 00 00 00:未知,似乎是電腦數。
01 00 00 00:未知,似乎是玩家數。
01 00 00 00:剩餘空位。
08 00 00 00:未知。似乎是定值。

E0 17=0x17E0=6112,遊戲連接埠。

 

 

02 00 00 00:遊戲總共允許玩家。
01 00 00 00:未知,這似乎是定值。
01 00 00 00:已知,這就是是玩家數。
01 00 00 00:已知,除電腦外的所有空位。
08 00 00 00:未知。不斷變化著……。

E0 17=0x17E0=6112,遊戲連接埠。

all = map[map.length - 22];<br /> unknown = map[map.length - 18];<br /> people = map[map.length - 14];<br /> besidescp= map[map.length - 10];// 這個數是這樣計算的:除電腦外的所有位置,包括已經有人的位置,例如總數是10個,加了3個電腦,則這個數就是7,不關那7個位置是否有無人。<br />

// 這個數是這樣計算的:除電腦外的所有位置,包括已經有人的位置,例如總數是10個,加了3個電腦,則這個數就是7,不關那7個位置是否有無人。

 

這裡把地圖的解析代碼貼出來。

/**<br /> * 魔獸的主機節點(遊戲中的“建主”了,也就是建立了什麼地圖)<br /> * 解析主機資訊<br /> * 產生一個主機節點,包括地圖資訊,版本,人數,等等<br /> *參數:byte[] 地圖資訊包,InetAddress 包的ip地址,int 延時<br /> */<br />package xinyu126.common;<br />import java.io.UnsupportedEncodingException;<br />import java.net.InetAddress;<br />import java.util.Arrays;<br />import java.util.Vector;<br />/**<br /> * @author xinyu126<br /> *<br /> */<br />public class WarNode {<br />String serverName;<br />String serverInfo;<br />String mapStr;<br />int all;<br />int besidescp;<br />int people;<br />int unknow;<br />int version;<br />int timeDelay;<br />public InetAddress IP = null;<br />public boolean checked = true;<br />public WarNode(byte[] map, InetAddress IP, int delay) {<br />int i = 0;<br />if (map[0] != (byte) 0xf7 || map[1] != (byte) 0x30) {<br />// 這個不是地圖資訊!<br />return;<br />}<br />this.IP = IP;<br />this.timeDelay = delay;<br />// 第八個是版本,1.20(20) 1.21(21)什麼的<br />version = map[8];<br />// 從第二十個開始<br />// 遊戲資訊,大部分是:“當地區域網路內遊戲(X……”<br />byte[] t = new byte[32];<br />for (i = 0; i < 32; i++) {<br />t[i] = map[i + 20];<br />}<br />try {<br />serverInfo = new String(t, "UTF-8");<br />} catch (UnsupportedEncodingException e) {<br />e.printStackTrace();<br />}</p><p>// 現在開始解析地圖路徑和主機的名字<br />i = 69;<br />byte[] mapStr = new byte[64];<br />t = new byte[32];<br />int v = 0;<br />int n = 0;<br />boolean flag = true;<br />do {<br />String mm = "00000000" + Integer.toBinaryString(~map[i]);<br />// System.out.println(mm);<br />for (int j = 1; j < 8; j++) {<br />int c = map[i + j];<br />if (c == 0) {<br />// 如果遇到0x00表示已經結束了<br />break;<br />}<br />int k = '1' == mm.charAt(mm.length() - j - 1) ? 1 : 0;<br />// System.out.println(k);</p><p>if (c == 1) {<br />// 當遇到第一個 0x01的時候表示地圖路徑完事了,開始解析主機的名字<br />flag = false;<br />}<br />if (flag) {<br />// 加到地圖上<br />mapStr[v] = (byte) (c - k);<br />v++;<br />} else {<br />// 加到名字上<br />// 注意這裡:如果名字不夠長,這8個位元組中不能放下01 01 00這三個位元組,則會在後面添上“爭霸”這個兩個中文“d5<br />// f9 b1 d5”,然後另起8個位元組,放下01 01 00.這個時候要注意去掉這個“爭霸”。防止亂碼<br />//<br />// TODO 暫時這樣處理。知道還有很多問題<br />if (c != (byte) 0xd5 && c != (byte) 0xf9 && c != (byte) 0xb1) {<br />t[n] = (byte) (c - k);<br />n++;<br />}<br />}<br />}<br />i += 8;<br />} while (map[i] != 1 && i < map.length - 25);<br />this.mapStr = "M" + new String(Arrays.copyOf(mapStr, v));<br />serverName = new String(Arrays.copyOf(t, n));<br />all = map[map.length - 22];<br />unknow = map[map.length - 18];<br />people = map[map.length - 14];//<br />besidescp = map[map.length - 10];// 這個數是這樣計算的:除電腦外的所有位置,包括已經有人的位置,例如總數是10個,加了3個電腦,則這個數就是7,不關那7個位置是否有無人。<br />// System.out.println(serverInfo + " " + serverName + " " + this.mapStr<br />// + all + " " + computer);<br />}<br />public Vector<String> getInfo() {<br />Vector<String> vv=new Vector<String>();<br />vv.add("1." + version);<br />vv.add(IP.getHostAddress());<br />vv.add(serverName);<br />vv.add(serverInfo);<br />vv.add(mapStr);<br />vv.add("" + (all - besidescp + people) + "|" + all);<br />vv.add(String.valueOf(all - besidescp));<br />vv.add("" + timeDelay);<br />return vv;<br />}<br />public void setTimeDelay(int delay) {<br />this.timeDelay = delay;<br />}<br />}<br />

 

 

完整的程式碼在開源 http://code.google.com/p/warpuber

歡迎加入 開發

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.