在跳一跳這樣一個小的遊戲裡面,如果一個使用者看到裡面有一堆外挂得了很高的分,對其他一些每天在練習,試圖把自己的水準提高,而打一個高分的人就很不公平,他可能就沒有動力繼續去練習,繼續超越自己個人的最高分數。是以這樣一個行為,外挂行為其實會破壞整個系統的規則,并且讓規則立即變得失效。
歡迎大家前往雲+社群,擷取更多騰訊海量技術實踐幹貨哦~
作者:Hahn, 騰訊進階UI工程師
由 WeTest品質開放平台團隊 釋出于雲+社群
WeTest 導讀
張小龍:這個遊戲釋出以後,其實它的效果有點超出我們的預期,我們自己開玩笑說,這個遊戲突然變成了有史以來可能使用者規模最大的一個遊戲,因為它的DAU大概到了1點幾億,但同時出現了很多外挂,我沒有想到這麼小的一款遊戲也會有那麼多外挂,我朋友圈的朋友也打出了特别高的分,但是我相信不是他自己打出來的。
1 月 15 日微信在廣州召開 2018 年的微信公開課 Pro,張小龍不僅當場玩了一把跳一跳遊戲并取得了900多的高分,還特别提到了跳一跳小遊戲的外挂:
是以,我們這個小遊戲釋出以後,我們就開始花了很多很多時間來打擊外挂。
本着鑽研技術的學習态度,我對目前幾款比較火的外挂進行了源碼分析,總結出了它們的一些破解思路,其實這些作者都并非惡意,作為一個程式員,還有什麼比用技術挑戰規則,突破極限要有成就感呢?
一、梳理
跳一跳的遊戲可以細分為兩步驟:距離判斷 + 按壓模拟,這兩步都有下面這些解決方案:
1、距離判斷:
● 簡單方案:像素點判斷
● 進階方案:OpenCV 圖像分析
2、按壓模拟:
● 簡單方案:adb/wda 指令
● 進階方案:機械臂模拟手指點選(原創)
下面逐一介紹這裡的實作方法,非常有意思。
二、距離判斷
1. 像素點判斷
該方法采用自目前最火的跳一跳小遊戲「輔助程式」:wechat_jump_game。
如上圖所示,我們先定義了「棋子」和「棋盤」,需要找到的兩個目标點用橙色點标注,首先針對棋子的目标點的判斷,可以這麼做:
相關代碼:
而針對棋盤中心點的确認的思路則是這樣的:
當然還有一些其他方法來盡量縮小棋盤中心點的檢測區域,這裡簡單介紹下:
當然,如果恰好跳到中心點,下一個棋盤中間會有白色點,則可以直接比對中心點的色值,得到棋盤中心點,這種情況基本百發百中:
但棋盤種類比較多,形狀也各異,而且棋盤表面并非純色,還有其他顔色,是以即使像素判斷的代碼裡增加了很多特殊 case,依舊不能做到非常完美:
總結一下,目前這個方案基本沒有太大問題,但如果跳一跳遊戲把背景改成了非線性漸變,或随機飄落一些物體,或棋盤表面更加複雜,那這裡的算法就基本不可用了。
2. OpenCV 圖像分析
基于像素點的判斷低效而且不夠健壯,而利用 OpenCV 計算機視覺庫則可以從圖像分析層面進一步簡化判斷邏輯提升效率,首先采用該方法的跳一跳小遊戲「輔助程式」來自 wechat_jump_jump。它是這麼得到棋子的位置的:
接下來找棋盤的中心點,假如下一個棋盤存在白色的示意點,同樣采用上面的模闆比對方法進行比對,若比對不上(比對值小于某門檻值,也許下個棋盤本身就是白色,是以灰階圖分辨不出),則采用第二種方案:
這裡是否準确的精髓就在于高斯濾波去除圖像噪音的臨界點以及 Canny 函數中門檻值的設定,需要不斷調整參數到最優狀态。
三、按壓模拟
1. adb/wda 指令
這兩個分别是針對 Android 和 iOS 的指令行工具,可以将手機和電腦連接配接起來,并通過指令行發送指令,指令中就包含了螢幕的截圖和按壓模拟。不過 iOS 配置起來稍微麻煩一點,具體操作指引可以參考 這裡。其核心的指令有:
當然,如果嫌配置麻煩,還可以通過 Android 的 AirDrop App 或 iOS 的 QuickTime 把手機螢幕投到電腦中,然後通過 Python 的 Pillow 庫來截取投屏的内容,再做進一步的圖像識别工作。
還有一點值得一提,按壓時間這部分還是有優化的空間,前面提到了跳躍距離和按壓時間基本是線性關系,但越到後面可以越發現,距離并非和按壓時間絕對成線性比例,因為遊戲本身不是一個純 2D 的平面場景(2.5D),是以我們測量到的直線距離在 2.5D 場景中是有變化的,雖然影響不大,但在遊戲後期棋盤越來越小,距離越來越大時,容易凸現出問題來,是以關于距離的計算有幾種不同的解決:
拟合函數的細節可以參考:
1)https://github.com/metowolf/JumpJumpHelper
2)https://github.com/wangshub/wechat_jump_game/issues/744
3)https://github.com/wangshub/wechat_jump_game/pull/841
2. 機械臂模拟手指點選
本着學術探究的态度,結合之前折騰開源硬體的經曆,是以也鬥膽想給跳一跳小遊戲增加一點動手環節,把觸摸模拟這一操作通過機械臂來實體完成,于是在萬能淘寶裡淘了一個一百多快錢的機械臂和部配置設定件,自己編寫了控制代碼,把按壓時間傳輸作為機械臂按下的停留時間,想法确定後便開始購置物品:
到貨後折騰一兩個晚上,最後成功搭建好了,大家看看效果(電容筆偶爾還是會觸碰不良)
視訊連結:https://v.qq.com/x/page/s05329u9gun.html
四、最後
反對一切使用外挂行為!
通過對外挂程式源碼的研讀,學習到了非常多創新的思維,這也算是外挂留給代碼世界的果實。
關于騰訊WeTest手遊安全測試團隊
騰訊WeTest手遊安全測試團隊從2011年初開始對手遊安全領域進行探索和技術積累,旨在通過提前發現遊戲版本的安全漏洞,預警風險,打造出業界領先的手遊安全測試技術方案,在工具上已經支援所有騰訊在研和營運的手遊項目。團隊通過使用與正式服同樣的遊戲用戶端和伺服器,模拟外挂工作室制作外挂的過程,依靠自身的技術積累來提高專業程度,持續保持漏洞的發現率。
目前提供了專家測試服務,希望通過提前發現遊戲版本的安全漏洞,預警風險,幫助提高騰訊遊戲的品牌和口碑。
服務目前已經對外開放,點選http://wetest.qq.com/product/sr 即可使用。
相關閱讀
張小龍釋出 2018 微信全新計劃(内附演講全文)
微信+WeTest:小程式雲端測試系統上線
微信小程式之提高應用速度小技巧
此文已由作者授權雲加社群釋出,轉載請注明原文出處
海量技術實踐經驗,盡在雲加社群!
https://cloud.tencent.com/developer