1. 程式人生 > >手遊熱更新方案--Unity3D下的CsToLua技術

手遊熱更新方案--Unity3D下的CsToLua技術

con 我們 如何 研發 效率 並且 dll文件 play 表示

WeTest 導讀

CsToLua工具將客戶端 C#源碼自動轉換為Lua,實現熱更新,本文以麻將項目為例介紹客戶端技術細節。


麻將項目架構

技術分享圖片

其中ChinaMahjong-CSLua為C#工程,實現麻將項目的主要業務流程。翻譯工程的輸入是C#項目生成的dll文件。其中Cecil負責分析類型 類成員關系 ,比如類字段函數結構,引用關系、類之間的繼承關系等,ILSpy負責反編譯函數體裏的語句,比如條件語句,函數調用,算數運算等。下面逐個介紹具體的實現。

Mono.Cecil

Mono.Cecil:一個可加載並瀏覽現有程序集並進行動態修改並保存的.NET框架。可以靜態註入程序集(註入後生成新的程序集)和動態註入程序集(註入後不改變目標程序集,只在運行時改變程序集行為。麻將項目入口:

技術分享圖片

舉一個Mono.Cecil例子,這是原始的Unity C#代碼:

技術分享圖片

我們采用Cecil工具對生成的Dll進行代碼嵌入,具體的嵌入邏輯如下:

技術分享圖片

技術分享圖片

OpCodes.Ldstr 字段推送對元數據中存儲的字符串的新對象引用。指令將一個對象引用推送 (類型 O) 到一個新的字符串對象,表示存儲的元數據中的特定字符串文字;

OpCodes.Call 字段調用由傳遞的方法說明符指示的方法。

反編譯嵌入自定義邏輯代碼,實現了原生代碼功能的更新。也就是說在沒有源代碼的前提下,Mono.Ceil可以動態嵌入指定代碼至可執行文件。(這也是一些外掛的套路,也有加殼和加密技術來提升反編譯的難度了,此處省去一萬字)上面的代碼等價於如下:

技術分享圖片

Mono.Cecil底層是如何處理的呢,再舉一個例子,這是原始的C#代碼:

技術分享圖片

上面是C#邏輯打包成dll後,采用Cecil反編譯得到的內容如下,具體邏輯見註釋:

技術分享圖片

用Mono.Cecil得到了二進制文件的中間代碼,中間代碼是一種基於操作棧的虛擬機語言,指令間借助棧傳遞數據。

ILSpy

ILSpy是一個開源.Net的反編譯器,能把C#生成二進制文件轉換為MSIL或者C#任選一種。因為項目C#程序集是團隊開發,因此不需要破解加密算法和去殼等操作。相關的反編譯軟件有:ilasm、.Net Reflector和Just Decompile等。

ILspy的主要功能:從Mono.Cecil拿到具體類型,類型定義的方法,以及各自的MethodBody。然後對MethodBody中的IL Instructions(指令代碼)做數據流分析和控制流分析。如下為ILSpy的輸人內容:

技術分享圖片

舉個例子,說明一下ILSpy具體的實現流程,如下為C#源碼:

技術分享圖片

通過Mono.Ceil和ILSpy分析後的輸出:

技術分享圖片

ILSpy對IL Instructions以跳轉指令為界限,劃分了基本的block,block間構成樹形結構:

技術分享圖片

TK_CSLua

TK_CSLua根據不同的語句塊實現具體的翻譯邏輯,比如將C#中的while循環,生成Lua裏面的while-end邏輯等。翻譯過程是一個遞歸的過程,如圖為不同類型的語句塊處理邏輯:

技術分享圖片

while循環的處理邏輯為:

技術分享圖片

最終自動生成了Lua代碼,如下所示:

技術分享圖片

ToLua

ToLua基於LuaInterface,LuaInterface是一個實現Lua和微軟.Net平臺的CLR混合編程的開源庫,使得Lua腳本可以實例化CLR對象,訪問屬性,調用方法甚至使用Lua函數來處理事件。提供了一套中間層導出工具,對於需要訪問的CLR、Unity及自定義類預生成Wrap文件,Lua訪問時只訪問Wrap文件,Wrap文件接收Lua傳遞來的參數,進行類型(值、對象、委托)轉換,再調用真正工作的CLR對象和函數,最後將返回值返回給Lua ,有效地提高了效率。

Lua虛擬機啟動主流程:

技術分享圖片

Unity C#與Lua交互,麻將項目主要采用了Wrap文件這種非反射的方式實現。以下為生成綁定的具體流程:

技術分享圖片

生成後的WrapperConfig文件如下所示:

技術分享圖片

舉個例子說明綁定的具體實現,C#代碼如下:

技術分享圖片

ToLua綁定後生成的代碼:

技術分享圖片

C#中的對象在傳給Lua時並不是直接把對象暴露給了Lua,而是在這個OjbectTranslator裏面註冊並返回一個索引,並把這個索引包裝成一個userdata傳遞給Lua,並且設置元表:

技術分享圖片

數據包裝如下:

技術分享圖片

遊戲啟動

麻將項目啟動入口為Init.Lua:

技術分享圖片

加載配置,進入登錄場景。

技術分享圖片


UPA—— 一款針對Unity遊戲/產品的深度性能分析工具,由騰訊WeTest和unity官方共同研發打造,可以幫助遊戲開發者快速定位性能問題。旨在為遊戲開發者提供更完善的手遊性能解決方案,同時與開發環節形成閉環,保障遊戲品質。

點擊鏈接:http://wetest.qq.com/cube/ ,下載WeTest助手APP ,立即使用UPA,

手遊熱更新方案--Unity3D下的CsToLua技術