對戰平台原理分析

來源:互聯網
上載者:User

遊戲對戰平台,在沒有瞭解的情況下,總是給人一種很神秘的感覺,然而,當你對socket的理解到達一定程度之後,你就不會再覺得神秘。
       用一句話來總結這種技術:虛擬區域網路(VLAN)。

   實現這種平台,主要是用戶端,而用戶端有很多種方法,就我所瞭解,可以用面三種方法實現:
    1. 替換Windows socket DLL,然後,你想做什麼就做什麼吧。
    2. 進程注入,HOOK WinSock函數調用。
    3. 虛擬網卡驅動。

       其實,前兩種技術,也是許多木馬使用的方法。正所謂技術是一面雙刃劍,看你要用到什麼地方了。現在的對戰平台,就我瞭解,使用的是後兩種方法。大多數是第2中----畢竟,驅動在有些使用者權限下是無法安裝和使用的。
       浩方,QQ對戰平台,VS等,基本上都是採用第二中方法。第三種方法,見過一個。效果還可以。

    下面介紹一下我研究時寫的平台結構:
       整個平台包含兩個組成部分:服務端和用戶端。
       通訊方式:全部採用UDP通訊。

零、基礎知識:
     如果你有志與開發這樣一個類似平台,我建議你先瞭解以下內容:
     a. Windows協議棧的簡單瞭解。
     b. WinSock通訊。
     c. HOOK技術。
     d. 線程,進程之間的資料交換和通訊。
     e. 線程之間的同步。
     f. 線程注入。
     e. 其它的一些Windows開發的基礎知識,就不一一列舉了。

     這些都是基本功,基本功如何,決定了你能走到哪一步。

一、服務端:
      伺服器在邏輯上被分為了兩部分:
      a. 使用者服務器: 虛擬IP分配,使用者管理,訊息通知等。
      b. 轉寄伺服器: 進行必要的資料轉寄(無法進行P2P通訊的)

二、用戶端:
     用戶端也包含兩個部分,
     a. 用戶端EXE: 負責進行進程注入,與伺服器通訊。
     b. 用戶端DLL: 負責進行socket函數替換和處理。

    註:這裡,伺服器和用戶端都有KeepAlive的功能,如果在一定時間內未收到包,則認為使用者已經掉線。

三、主要工作流程:
     這裡主要對使用者登陸和登出,啟動和離開遊戲這連個主要環節進行總結。

    a. 使用者登陸過程
     +-------------------------------+
      | 輸入使用者名稱和密碼,登陸 |
     +-------------------------------+
                     |
     +-----------------------------+
     |   發送登陸包到伺服器    |
     +-----------------------------+
                    |
     +-----------------------------+
     |        處理反饋資訊        |
     +------------------------------+
                |
           <登陸成功>   ------------失敗-------------> [提示使用者]
                |
     +------------------------------+
     | 請求其他線上使用者資訊 |
     +-----------------------------+
   使用者登陸資訊用戶端處理流程

         +--------------------+
         | 收到使用者登陸包 |
         +--------------------+
                  |
             <資料解析>----------------> [丟棄不合法資料包]
                  |
         <驗證使用者登陸資訊> -----------失-敗-------+
                  |                                                    |
                  |                                                      |
    +----------------------------+        +---------------------------------+
    |      分配虛擬IP地址        |       |反饋登陸失敗資訊到用戶端|
    +----------------------------+       +-------------------------------+

                      |
    +--------------------------------------+
    |    添加使用者到線上使用者列表     |
    +--------------------------------------+
    |反饋使用者登陸成功,伺服器資訊|
    |                   到用戶端                | (* 這裡包含了轉寄伺服器資訊)
    +--------------------------------------+
                           |
       +------------------------------+
       |廣播資訊到所有登陸使用者|
       +-----------------------------+

           使用者登陸資訊服務端處理流程(由使用者服務器處理)

    b. 使用者登出過程
     
             +--------------------+
             | 收到使用者退出包 |
             +--------------------+
                       |
                   <資料解析>----------------> [丟棄不合法資料包]
                       |
             +----------------------+
             < 尋找將使用者資訊 >   ------------> 未找到,不處理
             +---------------------+
                       |
       +----------------------------------------+
       |   將使用者從線上使用者列表中刪除   |
       +---------------------------------------+
                       |
       +------------------------------------+
       |     回收虛擬IP給其他使用者       |
       +-----------------------------------+
                       |
       +-------------------------------------------+
       | 廣播使用者登出資訊到所有線上使用者 |
       +-------------------------------------------+

           伺服器處理過程

         <判斷使用者是否在遊戲中>   -----------是------------> 提示使用者
                  |
                否
                 |
       +-----------------------------+
       |   發送登出包到伺服器    |
       +-----------------------------+
                  |
       +-------------------------+
       |          退出                |
       +-------------------------+
            用戶端處理過程

c. 遊戲啟動過程

       +--------------------------+
       |      建立記憶體共用      |
       | (CreateFileMapping) |
       |   寫入遊戲當前配置   |
       | (包含線上使用者資訊和 |
       |    轉寄伺服器資訊)   |
       +--------------------------+
                 |
       +-----------------------------+
       | 根據使用者選擇啟動遊戲 |
       | (調用CreateProcess) |
       +----------------------------+
                 |
          <是否啟動成功> ------------否----------> [提示使用者失敗資訊]
                 |
       +-----------------------------+
       | 將遊戲DLL注入到遊戲 |
       +----------------------------+
                  |
    +--------------------------------+
    |     讀取遊戲的配置資訊     |
    +-------------------------------+
                  |
    +-----------------------------+
    |       串連轉寄伺服器       |
    +-----------------------------+
                  |
    +--------------------------------------+
    | 遊戲DLL HOOK所有網路函數 |
    |   (採用Inline Hook方式)          |
    +-------------------------------------+
                  |
    +----------------------------------+
    |   OK, now game start OK!   |
    +----------------------------------+

d. 遊戲退出過程

   +----------------------------------------------+
   | 遊戲DLL釋放所有已經HOOK的函數 |
   +---------------------------------------------+
                  |
   +-----------------------------------+
   |     關閉記憶體共用檔案            |
   +-----------------------------------+
                  |
   +--------------------------------------+
   |     發送退出包到轉寄伺服器      |
   +--------------------------------------+

四、遊戲DLL工作過程:

     整個平台運作過程中,最主要的部分恐怕就是這個部分了,所以,單獨將這部分的結構進行一下說明。
   
     在這裡,我將處理過程分成了三個層,每個層分別完成不同的功能:網路HOOK層,自訂協議棧,網路資料轉送層。
     首先,HOOK所有上層的網路函數調用,然後交給自訂協議棧進行處理,處理完成後,如果需要發送資料,則交由下層的網路發送層進行發送。

     +----------------------------------------------------------+
     |                                                                          |
     | 網路函數HOOK層: 主要負責網路函數的替換 |
     |                  並且交由下層處理                            |
     |    這裡,其實也就是對於WS2_32.dll中的          |
     | socket函數進行替換。                                      |
     |                                                                         |
     +---------------------------------------------------------+
     |                                                                         |
     | 資料處理層:主要負責將上層的各種網路       |
     |                    函數功能調用進行處理。              |
     |    舉個簡單的例子,當遊戲調用Socket函數   |
     | 準備建立一個socket時,我們根據它的參數, |
     | 內部虛擬出一個socket控制代碼給它。而實際的上 |
     | Windows本身並不知道這個調用過程。          |
     |                                                                      |
     +-------------------------------------------------------+
     |                                                                     |
     | 真實網路傳輸層:在這一層,才是真正的將數|
     |                 據包進行封裝和發送的過程            |
     |                                                                       |
     +-------------------------------------------------------+

       其實,整個用戶端只建立了兩個socket,一個用於和伺服器通訊的socket,另外一個就是在遊戲DLL中建立的一個和轉寄伺服器以及遊戲之間通訊所使用的socket。
       這裡重要的就是中間的那層,主要就是對於socket調用中的每個函數進行類比。這個就需要各位自己去瞭解了。我不可能也沒有能力把每個都描述出來。
        其實,這裡的第二層處理也可以不採用我的這種方法,可以採用協議替換法,比如,當遊戲調用socket函數要建立一個IPX socket時,你可以修改其中的參數,變成UDP,然後調用Windows真實的socket函數。

五、主要的技術痛點:
      a. 類比Windows Socket。

          這個技術點,說起來就比較多了。我們知道Windows有六中socket模型,我們必須類比出來大部分的模型(根據遊戲所使用的模型不同而需要類比的模型就不同)。
     根據我的跟蹤和測試,說說現在瞭解的幾個遊戲所使用的socket模型和協議類型:

     《紅色警戒》: 使用了簡單的WSAAsyncSelect模型。(IPX協議)
     《星際爭霸》: 使用了Select 模型。(IPX, UDP協議,根據使用者的參數)
     《暗    黑》: 使用Select模型。(使用TCP協議)
     《反恐精英》: 使用Select模型。(使用TCP, UDP協議)
     《冰封王座》: 似乎使用了IOCP Socket模型。這個還不是很清楚。(使用TCP,UDP兩種協議)

      b. 改進UDP資料通訊的可靠性。
         整個平台中,所有通訊全部使用的是UDP,所以,這點很重要。如果我們的遊戲中採用了TCP通訊,我們在類比的時候就的保證所有資料都能被對方收到。

   六、開發後記:
       去年的時候,我寫過一個英文的對戰平台研究,現在看看,那簡直是垃圾!可能是那是比較浮躁,對於什麼東西都沒有瞭解清楚。一年後,再回過頭來看我寫的那些代碼,真是慘不忍睹。現在,我覺得自己心靜了很多,技術上也成熟了許多。想說的就是Windows開發,我可以算是入門了吧!呵呵!
      整個平台,只是在我的機器上進行測試和開發,難度比較大。工程。現在,我也只對《紅色警戒》, 《星際爭霸》, 《暗黑》三個遊戲測試通過。感覺一個人開發實在太累了,而且,這些東西都是經過一次次的AV錯誤一步步調試出來的,想想那些歲月,真是不堪回首!暫時不想再繼續下去了。等什麼時候有精力和時間的時候再來處理吧。
      很多時候,為了能夠調試通過一個函數,我不知要經曆多少次的遊戲重啟過程。基本上MSDN上的大多數socket函數已經被我翻了個遍,每個函數的參數,傳回值等都的瞭解。
      為了瞭解Windows實現socket的原理,閱讀那份據說是Win2K的源碼(如果你想閱讀的話,到網上搜尋一下,解壓後大概有700M),關於socket的那部分代碼在/win2k/private/net/sockets/winsock2/wsock32目錄下(估計是WS2_32.dll的源碼),讀了很多內容,也瞭解了一些東西,也讓我知道以後怎麼去寫socket程式。現在我有時寫代碼寫累的時候,還會去看點Windows的源碼,挺有意思的。像gina的實現,CommCtrl的實現等。
      代碼大概已經寫的至少有一兩萬行了,基本上都是我在EditPlus/NotePad中一個字母一個字母敲出來的。暫時不想共用出來了,就分享一下原理篇給大家。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.