陰陽師業原火bug的原理是什麼?
希望從技術角度分析下,在bug復現過程中,客戶端與伺服器端是如何通信的?
個人猜測,僅供玩耍:
首先我們回想一下普通御魂本的時候,客戶端和伺服器是怎麼通信的:1.客戶端進入御魂界面,選擇御魂層數,進入:
這個時候客戶端和伺服器通信過程:客戶端告知伺服器:我要刷御魂了 御魂層數是幾層。
伺服器收到消息:哦,你要刷御魂啊,這一層啊,好的,你刷吧。然後告訴客戶端你可以開始刷了。
客戶端收到消息:我可以開始刷了啊,好的我進入了開打。進入遊戲後告訴伺服器,我已經進入了。我開打了。
伺服器收到消息:好的,我收到你的消息了,打吧,然後把體力也扣了。
2.客戶端開始刷御魂,這裡就是殺死御魂的過程。又分為兩種情況:
(1)成功殺死御魂怪:客戶端告知伺服器:伺服器阿爸,你看我打完了喲,快給我獎勵吧。
伺服器接受到消息:哦,對啊你打完了,好的,我給你發獎勵哈,然後根據之前告知的層數隨機計算出收益。發送給客戶端。
客戶端收到消息:啊,好多獎勵啊,哇塞,6號位破勢,媽的,生命加成。
(2)失敗:
客戶端告知伺服器:伺服器阿爸,我打完了喲,可是失敗了。
伺服器收到消息:失敗了,繼續努力吧。
客戶端收到消息:哦
估計以上就是正常的御魂通信過程。當然這中間各種網路的通信都給省略了,我也不是遊戲專業。
那麼這回bug是怎麼回事呢?
設想如下:1.客戶端進入業原火副本,選擇種類進入:
客戶端告知伺服器:我要刷御魂了,御魂層數是(這裡我估計網易就是直接將新的御魂設計為11,12,13層,然後改了名字)
伺服器收到消息:哦,你要刷御魂啊,這一層啊,你刷吧,然後告訴客戶端你可以開始刷了。然後伺服器就等待客戶端返回給他已經進入了業原火副本的請求,為扣除卷做準備。
客戶端收到消息:我可以開刷了啊,好的,我要進入了,這裡就需要注意了,客戶端在快要進入業原火的時候迅速切換到了御魂一。開打。
然後問題就來了,
伺服器發現客戶端半天都沒返回進入業原火副本的請求啊,他就不停問客戶端:進去了沒。最後客戶端進入了魂一就告訴他:我進入了啊。伺服器收到回復了哈,扣除開始:
這裡說一下,扣體力或者卷的原理:
伺服器在接到打御魂請求後會在客戶端進入御魂本後要求客戶端返回一個確認消息,從而扣除體力或者卷。但是這裡出了一個問題。本來伺服器以為你是要打業原火,所以要求你進入副本後返回開始打業原火的消息,我好扣除卷,結果你進入了御魂一,返回了御魂一的信息。那你之前不是要打業原火嗎?出錯了?然後伺服器就認為這個是一個異常,沒有處理。但是最神奇的是,它沒發現了這個異常就應該終止這次御魂副本任務了。但是御魂獎勵正常開出。這就有問題了。這裡我開發遊戲的朋友給了我一個思路:(1)為了用戶體驗,所有即使出錯了,客戶端也不會報錯。所以業原火切換到御魂一客戶端這邊沒報錯。(2)伺服器端對於御魂寫的判定過於簡單。出現了沒有覆蓋到的邏輯。程序不知道怎麼處理了。
例如:if(打正常御魂本幾)
體力-4if (打業原火)卷-1else{啥也不做,最後就是啥都沒扣除}這樣的邏輯有什麼問題大家應該都知道了吧?
只要出現if(打業原火又打御魂),程序就不知道怎麼辦了。
當然這的邏輯十分簡單,在具體的代碼中其實應該更加複雜。比如,朋友說伺服器應該是有一開始記錄好客戶端打的層數的。同時這個邏輯在之前的1到10層副本也是正常的。因為不會出現選擇了魂3進入魂1的情況。(3)最大的問題,伺服器並沒有在最後生成獎勵的時候寫嚴格的判定邏輯。
2.客戶端開始打御魂
(1)成功殺死御魂怪:客戶端告知伺服器:伺服器阿爸,我打完了呢,你快給我獎勵啊。伺服器收到消息:哦,對啊你打完了,好的,我給你發獎勵哈,然後根據之前告知的業原火層數隨機計算出收益,發送。客戶端收到消息:我的天....繼續刷啊啊啊啊、
(2)失敗:你他么說會失敗?以上僅供玩耍哈!
最後總結:
1.計算獎勵是根據第一次客戶端告知伺服器要進入的本計算的。2.扣除消耗是在伺服器確認你進入了本的時候做出的3.伺服器端的消耗扣除條件判斷寫得有問題4.伺服器最後計算獎勵沒有把3中的判斷作為決定性的因素。這鍋誰來背呢?怒答一發。
這麼大用戶體量的產品,服務端進程架構一定是分散式的。即發放副本獎勵道具的進程(叫它中央服好了)跟打副本的進程(叫副本服好了)不是同一個。
簡單來說,應該就是中央服依據它所記錄的副本id進行獎勵發放,而副本服處打的副本id是另一個(具體通信流程抓一下包可以復原)。副本服通知中央服副本通關之後,中央服未進行副本id的核對,就按原副本id發放了獎勵。
推薦閱讀:
※怎麼看待 iOS 版的萬智牌2015 ?
※如何評價《劍俠世界》請吳亦凡代言?
※有哪些手游產品在社會化營銷方面做的比較成功?
※App Store首頁包版推薦,《虛榮》都沒有過這種待遇,為什麼《皇室戰爭》拿到了?
※小孩子痴迷玩手機怎麼辦?