人妻少妇乱子伦精品_日韩人妻潮喷视频网站_日本最新最全无码不卡免费_日韩AV无码中文

當(dāng)前位置: 首頁 > 科技新聞 >

騰訊正式開源面向 Unity 項目的 Bug 修復(fù)神器 Inj

時間:2019-11-13 00:42來源:網(wǎng)絡(luò)整理 瀏覽:
InjectFix是騰訊最新對外開源的Unity代碼邏輯熱修復(fù)方案,可實現(xiàn)在Unity線上客戶端內(nèi),不用迭代新版本,就能快速修復(fù)游戲的線上b

InjectFix是騰訊最新對外開源的Unity代碼邏輯熱修復(fù)方案,可實現(xiàn)在Unity線上客戶端內(nèi),不用迭代新版本,就能快速修復(fù)游戲的線上bug。

騰訊正式開源面向 Unity 項目的 Bug 修復(fù)神器 InjectFix

先說幾個亮點:

InjectFix經(jīng)騰訊內(nèi)部多個項目應(yīng)用反饋十分良好,不僅能解決線上bug,還可以有效的提高日常開發(fā)效率,下面我們聊下這項目的前世今生。

熱更方案大亂斗

所有支持iOS的熱更方案都有個共同點:更新后代碼都是解析執(zhí)行。如果按其更新前是否解析執(zhí)行,可以分為兩大類:

一類是某些模塊甚至整個游戲,都一直解析執(zhí)行。這是最傳統(tǒng)的方式,目前市面上所有主流方案(xLua,slua,tolua,ILRuntime,jsb等等)都支持這種方式。這種方式的特點:

ps:也有一種思路是通過一個C#轉(zhuǎn)XX腳本工具來實現(xiàn)C#編碼,解析執(zhí)行,但如果你是一個已有項目想這么轉(zhuǎn)一下,大概率是失敗的,除非你一開始就在用這方式在開發(fā),碰到坑就避開,因為這類方案往往不是完整支持全部語法,支持的語法也不一定能完全一致。

另外一類是以原生方式跑,如果有bug,把邏輯重定向到新的,解析執(zhí)行的邏輯。這種方式的特點:

第二種方式是接下來討論的重點,方便起見,我們稱之為“熱修復(fù)”,熱修復(fù)最早的成熟方案是xLua提供,經(jīng)過兩年來的使用已經(jīng)逐漸被接受,tolua#后來也加入了這功能,也有一些網(wǎng)友基于ILRuntime做了熱修復(fù)功能。

InjectFix是什么?

InjectFix就是一個熱修復(fù)的實現(xiàn)。那它和其它熱修復(fù)方案又有什么不同呢?

設(shè)想這么個場景,我們有一個一千行代碼的函數(shù),其中有一行有問題,我們需要修復(fù)它。

如果用xLua,需要用lua去重新實現(xiàn)一遍這個函數(shù),工作量大。而基于ILRuntime的熱修復(fù),由于其補丁是另一個程序集,它無法直接訪問原類的私有成員,所以那999行正常代碼一般也不能直接使用,需要做較多修改。

而InjectFix不需要用lua,也不需要像ILRuntime熱修復(fù)那樣另外建一個工程把那一千行邏輯重實現(xiàn)。只需要在Unity原工程直接改掉這行代碼,然后標(biāo)注這函數(shù)要更新即可。

不僅如此,InjectFix還有其它優(yōu)勢:

  • 運行時非常小巧,僅100K左右,比各lua方案,ILRuntime都要小很多,而且不依賴第三方庫,純C#實現(xiàn)。
  • 支持每個游戲生成一份自己私有的補丁格式,私有的指令定義。這樣相比通用的lua原代碼,lua字節(jié)碼,clr程序集都更安全些。
  • 支持Assembly-CSharp.dll之外的dll的修復(fù)。
  • 免代碼生成,更干凈。

它也有缺點,不支持新增類,也不支持在已有類新增字段,修bug還是夠用的,但難以通過熱更為游戲增加新功能。InjectFix就一個純粹的修bug工具而已。

黑科技

由于InjectFix支持重復(fù)加載補丁,新加載補丁會自動覆蓋上一個,這特性可以用來實現(xiàn)真機代碼邏輯實時修改。

騰訊正式開源面向 Unity 項目的 Bug 修復(fù)神器 InjectFix

(視頻地址:https://v.qq.com/x/page/v09240mo6ai.html?&ptag=4_7.2.5.22206_copy)

蘋果政策合規(guī)性

各熱更方案群的問的頻率最高的問題之一:這方案會不會導(dǎo)致我游戲蘋果審核不通過。

讓我們看看蘋果的熱更新條款:

騰訊正式開源面向 Unity 項目的 Bug 修復(fù)神器 InjectFix

可以看到最新條款允許下載代碼解析執(zhí)行,但前提是不能通過新增特性和功能來把程序改得(和審核時相比)面目全非。再看看通常被拒時的理由中的Guideline2.5.2里的一句:

Yourapp,extension,orlinkedframeworkappearstocontaincodedesignedexplicitlywiththecapabilitytochangeyourapp’sbehaviororfunctionalityafterAppReviewapproval。

有“新增特性和功能”能力的熱更新方案的尷尬之處在于有“改得面目全非”的能力。而InjectFix從它提供的能力(只能修改已有函數(shù))來看,并不具備“新增特性和功能”的能力,這本來是弱點,放在這里卻成為合規(guī)性的保證了。

基本原理

InjectFix項目的研發(fā)挺曲折的。InjectFix和xLua是同一個作者,也是本文筆者,當(dāng)時xLua開源后,不斷有人提希望提供個C#轉(zhuǎn)lua的工具,而深入研究覺得實現(xiàn)個il虛擬機工作量還更小,這樣還能避免lua的一些gc問題。

決定要做il虛擬機后,也曾想過直接使用ILRuntime,評估后覺得不太符合我們的使用場景:ILRuntime并不能實現(xiàn)和原生代碼的函數(shù)級別配合,這是我們能實現(xiàn)原工程直接改Bug的關(guān)鍵;ILRuntime運行時部分依賴cecil,除了資源占用大之外,還容易和unity自帶或者某些插件的cecil沖突;加載的是標(biāo)準(zhǔn)的程序集在安全性方面也比較堪憂。雖說這些都可以改,但修改的工作量也挺大的,還不如自己寫一個。

InjectFix實現(xiàn)bug修復(fù)主要靠這兩部分:虛擬機負(fù)責(zé)新邏輯的解析執(zhí)行;注入代碼負(fù)責(zé)把調(diào)用重定向到虛擬機;下面我們結(jié)合最簡單的例子介紹下這兩部分。

虛擬機

關(guān)鍵部分用幾行偽碼就可以描述清楚:

騰訊正式開源面向 Unity 項目的 Bug 修復(fù)神器 InjectFix

導(dǎo)讀

argumentBase指向的是求值棧該函數(shù)的棧幀,棧幀是這么安排的:

騰訊正式開源面向 Unity 項目的 Bug 修復(fù)神器 InjectFix

先放參數(shù)(如果有的話),再放本地變量(如果有的話),接著是臨時區(qū)域,當(dāng)函數(shù)返回時彈掉所有東西,如果有返回值就放到棧頂(函數(shù)執(zhí)行前參數(shù)0的位置)。

用如下一個靜態(tài)方法來演示下虛擬機怎么運行:

 

這函數(shù)編譯后是這四條指令

騰訊正式開源面向 Unity 項目的 Bug 修復(fù)神器 InjectFix

Add函數(shù)的執(zhí)行過程

代碼注入

上面的Add函數(shù)注入后是這樣的

 

比較簡單,發(fā)現(xiàn)這函數(shù)有patch的話,就重定向到虛擬機。

而__Gen_Wrap_25是個適配器函數(shù),賦值把參數(shù)壓棧,調(diào)用虛擬機的Execute函數(shù),并把結(jié)果返回。__Gen_Wrap_25的實現(xiàn)如下:

 

PS:我們的例子僅有三種指令,和這幾條指令無關(guān)的代碼全部簡化了,真正復(fù)雜得多,有興趣可以看源碼了解。

總結(jié)

InjectFix使用簡單,小巧,合規(guī)且安全。即使你不打算用它來更新線上版本,只要你程序有原生部分,接入也能一定程度上提高開發(fā)效率,沒什么拒絕它的理由,是吧?

【責(zé)任編輯:張燕妮 TEL:(010)68476606】
推薦內(nèi)容