從技術的角度分析為什麼 GTA5 的反外掛機制如此之差
這兩天玩了一下 GTA5 線上模式,一開始挺好玩的,但是加入了一些人比較多的公開戰局以後,就遇到了很多「俠盜科學家」,也就是咱們常說的神仙,開外掛作弊的人。
首先是什麼刷車的,刷飛機的都有,隨意召喚 X80 超跑,坦克,飛機,原地一鍵改滿配的,這都是很常見的。接著是各種鎖血的,自瞄爆頭的,還帶預判位置,無論你跑到哪都能一槍打死。最後是各種傳送的,明明看到對方的飛機還離你兩個山頭遠,下一秒就出現在你頭頂了,並不是網路延遲,就算是延遲,也不可能一秒瞬移幾公里吧。
打了幾局下來,遊戲體驗極差,當然我也承認我自己作弊了,但是只是刷了一點錢,不至於像那些神仙那麼變態。。所以我現在看到這些神仙都繞著走,要是被盯上了就開被動模式,但是還有的神仙連被動模式都能秒你,這種就只有退戰局了。
話題說回來,為什麼 GTA5 的反外掛機制這麼爛,導致遍地外掛?目前我玩公開戰局,十個戰局有五六個都有掛。到底是 RockStar 放任外掛還是科學家們太強大?今天我們就從技術角度來分析 GTA5 的外掛。
一、網路架構
我們比較熟悉的傳統網路遊戲,例如英雄聯盟、穿越火線、反恐精英等等,都是基於 C/S 架構的,即客戶端(Clients)/ 伺服器(Server)。
而 GTA5 的線上模式使用的架構是 P2P + C/S,什麼是 P2P 呢?P2P 是一種去中心化的網路技術,你可以把傳統的 C/S 架構理解為學校老師上課,老師就是 Server,它說什麼你們就聽什麼,當你有什麼事情需要舉手報告給老師。而 P2P 大概就相當於學生自由討論,你可以和其他同學交流你自己的東西,每個人都能成為「老師」。
大部分遊戲的連接協議都是基於 TCP 協議,GTA5 遊戲連接協議的底層是基於 UDP 協議。TCP 和 UDP 有什麼區別呢?我們來舉個例子,首先 TCP 協議有一個「三次握手」過程,假設你想要連接到伺服器並發送信息,步驟是這樣的:
- 客戶端嘗試向伺服器發起連接,告知伺服器「我是客戶端 XXX」
- 伺服器收到連接請求後,返回給客戶端「我是服務端,我已經收到你的連接請求了」
- 客戶端再告訴伺服器「我是客戶端,我已經收到服務端返回給我的信息,現在可以建立連接了」
- 客戶端與伺服器的連接就建立成功了,開始發送數據。
而 UDP 是一種無連接的協議,用 UDP 協議想要發送數據的話,步驟是這樣的:
- 客戶端直接把一大坨數據發給伺服器「我是客戶端 XXX,這些就是數據,不管你收沒收到,我已經發了」
- 伺服器收到數據後,再告訴客戶端「我收到了,這句話不管你收沒收到,我已經發了」
這裡可以很明顯地看出,TCP 是一種可靠的傳輸數據方式,而 UDP 相對於前者來說是相對不可靠的,TCP 會對數據進行校驗,這樣可以避免傳輸過程產生的數據丟失和損壞,而 UDP 因為是無連接的協議,數據完整性是無法保證的。
二、數據傳輸
看完上面的介紹,你可能會問,為什麼 GTA5 不用 TCP 協議傳輸數據呢?這樣不就可以保證數據完整了嗎?
沒錯,TCP 協議是可以保證數據完整,但是帶來的負面影響是非常大的,如果使用 TCP 協議,那麼就會:
- 遊戲會很容易掉線,各種卡,開車會一卡一頓,走路也是,開槍會很難打中敵人。
- 伺服器會承受不了大量的連接而崩潰
而如果使用的是 UDP 協議,卡頓的問題就會好很多了,首先,因為無需建立連接,只需要發送數據,客戶端只要把數據發出去就行了,不用管收不收得到,這樣的話你在本地玩起來就會感覺很流暢,但是別人看你可能會各種瞬移(在網路不好的情況下),如果使用 TCP,遇到網路不好的情況,你和所有人都會覺得很卡,還可能頻繁掉線。
第二,GTA5 使用的 P2P 技術,P2P 是一種「點對點」的數據傳輸技術,因為 P2P 無需伺服器,而是由各個客戶端來互相傳輸數據,即每個人都可以成為「伺服器」來為其他客戶端提供數據,大大節省了中央伺服器的性能開銷,這樣有什麼好處呢?就是客戶端不會再因為和伺服器的延遲過高而感覺卡頓,因為提供數據的並不是伺服器,而是和你在一個戰局的其他玩家。
如果你和朋友一起在線上玩過飆車,你可能會見到這種情況:
- 你和你的朋友一起在玩漂移,過一個彎的時候你發現對方的車用一種很不自然的姿態漂過去了
- 你和你的朋友一起開車在山路行駛,過一個彎的時候你發現對方的車突然撞出路面了,過一會你發現他人不見了,而是出現在了另一個位置,車子一點事都沒有,好好地在開著。
先來解釋第一種情況,當你的朋友開著車在漂移的時候,因為是 P2P 網路,此時是由他的電腦在「告訴」你的電腦,他當前的車輛速度、輪子的角度,以及車子的其他信息,你的電腦收到了以後,在本地模擬進行計算,最終演算出了這個效果,在他電腦上看來他可能做了一個很漂亮的甩尾,而你這邊看到就像整輛車橫著飛了過去一樣。
然後是第二種情況,這種情況通常是網路卡頓,有可能是你的網路卡了,或者他的網路卡了,在遊戲的過程中,對方是不斷在向你的電腦發送數據的,然後你的電腦再在本地進行計算,而如果發著發著突然網路嗝屁了,你的電腦沒有收到對方打了轉向的消息,你的電腦就會「認為」對方的車以之前的速度直線撞出去了,但是過了一會,對方的數據包又傳過來了,你的電腦就會重新進行計算,然後你就會看到對方的車子又重新出現在了道路上。
三、數據安全
由於沒有中央伺服器的介入,所有數據都由客戶端之間互相發送,這就存在了一定(或者說很大)的安全隱患。
舉個例子,你和一個敵對玩家在對槍,你對著他開了一槍,此時你的電腦會發送數據告訴對方的電腦「我朝你開了一槍,方向是 XXX,角度是 XXX」,正常來說,對方的電腦在收到你的數據後,會在本地進行計算,你是不是打中了我,如果打中了,我再返回數據給你。
而如果他開了外掛,外掛通過修改數據包,一直就返回給你「你沒打中,你沒打中,略略略」這就變成了無敵外掛,你怎麼也打不死對方。
還有就是帖子開頭提到的刷載具,外掛通過改數據,在本地先刷一輛車出來,接著再「告訴」其他客戶端,我這裡出現了一輛車,其他客戶端收到以後,就會把這輛車顯示出來,這樣所有人都看得到這輛車了。
刷錢也是一個原理,通常情況你不可能直接修改你的金錢數量(要是能改那豈不是逆天了),因為數據掌握在中央伺服器上,你想要獲得錢,必須要通過正常的手段或者事件,例如殺了一個 NCP 掉了錢,撿起來就可以獲得,或者做任務得到錢。
刷錢的原理,就是在你面前創建一大堆錢袋(GTA5 裡面有這麼個東西叫錢袋,是一種物品,走過去就可以撿起來,然後就能獲得錢)因為創建實體是不會把數據提交給中央伺服器的,因此外掛可以在本地創建一堆錢袋,然後走過去撿起來,這時候客戶端就可以告訴中央伺服器「我撿到了好多錢袋,我現在有 XXXXX 的錢了」。
讀到這裡可能有人會問,既然需要上報給中央伺服器,那中央伺服器做個判斷不就行了?
沒錯,是可以通過這樣來判斷玩家獲得的錢是否合法,但是因為 GTA5 的玩家數量實在是太多了,如果每次獲得錢後都要進行一次驗證,那伺服器會炸的,設想一下,你在做一個任務,一陣激烈的槍戰後,地上倒了一堆 NPC,你走過去撿他們掉的錢,結果你撿一下就要上報給中央伺服器一次數據,那豈不是一卡一卡的?
所以,R 星並沒有這麼做,其實大部分時候,你的金錢數據都是在你本地儲存的,同時通過 P2P 網路與其他玩家同步,本地存一份,中央伺服器上存一份,然後定期同步,大概就是這樣的。
一個很明顯的地方,你在改車、買槍的時候,留意右下角,你會看到一個轉圈圈的圖標,旁邊寫著「交易處理中」,這時候其實客戶端就在和中央伺服器通訊,進行物品購買的操作,此時伺服器就會判斷你的錢夠不夠,但是不會判斷你的錢來源合不合法,因為無法追溯你獲得錢的來源,這就導致了可以刷錢。
四、網路卡頓的原因
在玩 GTAOL 的時候,你可能會發現,和有些玩家玩的時候就很流暢,和另一些玩家玩的時候就看到他們各種瞬移,各種車子撞樹撞電線杆,其實這都是和 P2P 有關。
前面已經說了,P2P 是將每個客戶端都變成了一台伺服器,既能接收數據也能發送數據,如果你和某個玩家比較近(物理上的),你和他的延遲低,那麼你們兩個一起玩的時候就會很流暢。而如果你和某個玩家距離幾千上萬公里,不同國家的,那麼你們之間的延遲就會很大,玩起來的時候就會感覺很卡。
因此 GTA5 有一個匹配機制,即自動將你附近的玩家(或者和你同一個國家的玩家)匹配到同一個戰局。例如我之前掛了一個日本的 SSR 作為加速器來連接遊戲,我匹配到的就全是日本玩家。
那麼如何避免或者降低卡頓呢?首先你需要確定你和某個玩家之間延遲大不大,例如和他一起飈車,如果他不停瞬移或者各種奇 ♂ 怪的姿勢瞎漂、撞車,那麼就說明延遲應該不小。
確定了延遲以後,你就應該盡量和這個玩家保持距離,最好是在視野範圍之外,這樣你的電腦就不會載入來自對方電腦的數據,這也是 B 站玩漂移的大佬 老基 說的,打輪轂的時候盡量找沒人的地方打,不然容易把車胎打爆。原因就是遊戲數據在由其他玩家發送給你,這中間可能就存在延遲或者其他問題,本來你打的是輪轂,可能就因為網路問題打到輪胎了。
五、心跳機制
前面說了,GTA5 的聯機是基於 UDP 協議的,既然 UDP 是一種無狀態的協議,為什麼偶爾還是能看到遊戲提示「連接超時」?答案就是心跳機制。為了確認客戶端在線,每個客戶端之間都會互相發送一個心跳數據包(heartbeat),時間可以是 5 秒一次,或者 10 秒一次都可以,如果超過指定時間還沒收到某個客戶端的心跳數據包,那麼就認為這個客戶端「死了」(連接超時)。
各位可以看看我的論壇,https://www.zerobbs.net/,打開後按下 F12,轉到 Console,你會看到很多的「WebSocket heartbeat received」,這個論壇的評論區是使用 WebSocket 實現評論內容實時更新的,雖然是基於 TCP,但是為了保證客戶端在線,還是使用了心跳數據包的機制,每間隔 5 秒發送一個心跳數據包。
TCP 協議雖然是一種有狀態的連接,但是並不是代表客戶端與伺服器的連接中斷後,伺服器就能「知道」的。
如果你是通過正常方式斷開連接,例如關閉程序、手動中斷連接,那麼伺服器是可以「知道」這一事件的,而如果你通過拔網線、禁用網卡的方式強行斷開連接,伺服器是無法「知道」的,並且會繼續嘗試給你發送數據,然後發送失敗,再判定你的客戶端已經離線。六、題外話
其實完全使用伺服器同步數據的遊戲也有,例如坦克世界,在坦克世界這個遊戲中,你的任何操作都需要與伺服器同步,例如車子前進後退,左轉右轉,開炮等。在 GTA5 里,你開一炮以後,是由你的電腦告訴其他玩家的電腦,我打了哪裡,方向,角度等。而坦克世界裡,你開了一炮以後,是由伺服器來計算,你的炮彈打到了哪裡,打中了沒有。
因此坦克世界是我目前見過外掛最少的遊戲,雖然也有,不過都是一些純本地自慰用的掛,比如什麼去草叢,無限視野縮放之類的。去草叢其實沒啥用,只是讓你看的清楚一點,伺服器告訴你看不見你就看不見,坦克世界玩家常說的「點亮了」就是指伺服器告訴你,你「看見」了對方的坦克。而如果伺服器就是不告訴你敵人在哪,你就算把山都變成透明的,你也看不到敵方的坦克。
很早以前見過一個比較牛逼的外掛,可以垂直開上山,卡進別人車裡,那個是利用了遊戲的 bug,現在早就已經修復了。
感謝閱讀此文章,本文章由 Akkariin 原創,轉載請註明文章地址。
原文鏈接:https://www.zerobbs.net/thread/107
推薦閱讀:
TAG:技術 | 俠盜獵車手5(遊戲GTA5) | 外掛 |