专栏首页WeTest质量开放平台团队的专栏手游热更新方案--Unity3D下的CsToLua技术
原创

手游热更新方案--Unity3D下的CsToLua技术

作者:王攀峰, 腾讯游戏客户端开发 工程师

商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处。

原文链接:http://wetest.qq.com/lab/view/387.html

WeTest 导读

=========

CsToLua工具将客户端 C#源码自动转换为Lua,实现热更新,本文以麻将项目为例介绍客户端技术细节。


麻将项目架构

======

1.png

其中ChinaMahjong-CSLua为C#工程,实现麻将项目的主要业务流程。翻译工程的输入是C#项目生成的dll文件。其中Cecil负责分析类型 类成员关系 ,比如类字段函数结构,引用关系、类之间的继承关系等,ILSpy负责反编译函数体里的语句,比如条件语句,函数调用,算数运算等。下面逐个介绍具体的实现。

Mono.Cecil

==========

Mono.Cecil:一个可加载并浏览现有程序集并进行动态修改并保存的.NET框架。可以静态注入程序集(注入后生成新的程序集)和动态注入程序集(注入后不改变目标程序集,只在运行时改变程序集行为。麻将项目入口:

2.png

举一个Mono.Cecil例子,这是原始的Unity C#代码:

3.png

我们采用Cecil工具对生成的Dll进行代码嵌入,具体的嵌入逻辑如下:

4.png
5.png

OpCodes.Ldstr 字段:推送对元数据中存储的字符串的新对象引用。指令将一个对象引用推送 (类型 O) 到一个新的字符串对象,表示存储的元数据中的特定字符串文字;

OpCodes.Call 字段:调用由传递的方法说明符指示的方法。

反编译嵌入自定义逻辑代码,实现了原生代码功能的更新。也就是说在没有源代码的前提下,Mono.Ceil可以动态嵌入指定代码至可执行文件。(这也是一些外挂的套路,也有加壳和加密技术来提升反编译的难度了,此处省去一万字)上面的代码等价于如下:

6.png

Mono.Cecil底层是如何处理的呢,再举一个例子,这是原始的C#代码:

7.png

上面是C#逻辑打包成dll后,采用Cecil反编译得到的内容如下,具体逻辑见注释:

8.png

用Mono.Cecil得到了二进制文件的中间代码,中间代码是一种基于操作栈的虚拟机语言,指令间借助栈传递数据。

ILSpy

=====

ILSpy是一个开源.Net的反编译器,能把C#生成二进制文件转换为MSIL或者C#任选一种。因为项目C#程序集是团队开发,因此不需要破解加密算法和去壳等操作。相关的反编译软件有:ilasm、.Net Reflector和Just Decompile等。

ILspy的主要功能:从Mono.Cecil拿到具体类型,类型定义的方法,以及各自的MethodBody。然后对MethodBody中的IL Instructions(指令代码)做数据流分析和控制流分析。如下为ILSpy的输人内容:

9.png

举个例子,说明一下ILSpy具体的实现流程,如下为C#源码:

10.png

通过Mono.Ceil和ILSpy分析后的输出:

11.png

ILSpy对IL Instructions以跳转指令为界限,划分了基本的block,block间构成树形结构:

12.png

TK_CSLua

========

TK_CSLua根据不同的语句块实现具体的翻译逻辑,比如将C#中的while循环,生成Lua里面的while-end逻辑等。翻译过程是一个递归的过程,如图为不同类型的语句块处理逻辑:

13.png

while循环的处理逻辑为:

14.png

最终自动生成了Lua代码,如下所示:

15.png

ToLua

=====

ToLua基于LuaInterface,LuaInterface是一个实现Lua和微软.Net平台的CLR混合编程的开源库,使得Lua脚本可以实例化CLR对象,访问属性,调用方法甚至使用Lua函数来处理事件。提供了一套中间层导出工具,对于需要访问的CLR、Unity及自定义类预生成Wrap文件,Lua访问时只访问Wrap文件,Wrap文件接收Lua传递来的参数,进行类型(值、对象、委托)转换,再调用真正工作的CLR对象和函数,最后将返回值返回给Lua ,有效地提高了效率。

Lua虚拟机启动主流程:

16.png

Unity C#与Lua交互,麻将项目主要采用了Wrap文件这种非反射的方式实现。以下为生成绑定的具体流程:

17.png

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

18.png

举个例子说明绑定的具体实现,C#代码如下:

19.png

ToLua绑定后生成的代码:

20.png

C#中的对象在传给Lua时并不是直接把对象暴露给了Lua,而是在这个OjbectTranslator里面注册并返回一个索引,并把这个索引包装成一个userdata传递给Lua,并且设置元表:

21.png

数据包装如下:

22.png

游戏启动

====

麻将项目启动入口为Init.Lua:

23.png

加载配置,进入登录场景。

24.png

UPA—— 一款针对Unity游戏/产品的深度性能分析工具,由腾讯WeTest和unity官方共同研发打造,可以帮助游戏开发者快速定位性能问题。旨在为游戏开发者提供更完善的手游性能解决方案,同时与开发环节形成闭环,保障游戏品质。

点击链接:http://wetest.qq.com/cube/ ,下载WeTest助手APP ,立即使用UPA,


腾讯WeTest有奖征文活动进行中,欢迎投稿!了解详情:

http://wetest.qq.com/lab/view/379.html

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 机器学习在启动耗时测试中的应用及模型调优(一)

    启动耗时自动化方案在关键帧识别时,常规的图像对比准确率很低。本文详细介绍了采用scikit-learn图片分类算法在启动耗时应用下的模型调优过程。

    WeTest质量开放平台团队
  • 揭密微信跳一跳小游戏那些外挂

    本着钻研技术的学习态度,我对目前几款比较火的外挂进行了源码分析,总结出了它们的一些破解思路。

    WeTest质量开放平台团队
  • 一分钟读懂兼容测试报告(一):概况篇

    原文链接:https://wetest.qq.com/lab/view/425.html

    WeTest质量开放平台团队
  • 企业微信+微盛SCRM小程序的应用与发展

    公域流量如何转化成商家私域流量?商家如何精准洞察用户心理与喜好?企业商家如何才能唤醒沉睡会员?

    微盛网络
  • 靶机渗透DC-9

    无论输入什么,点击之后都是返回到results.php的界面。直接SQLMap跑一下。

    HipHip
  • jenkins+eclipse+ant+蒲公英 实现Android自动打包全攻略(MAC版)

    搭建机器:一台Mac Book Pro 开发工具:Android Developer Tools Build: v22.6.2-1085508(mac版本) ...

    专注APP开发
  • 2017 年 Q3 季度 VR 行业全景热度观察

    截止 2017 年 9 月,VR在国内的搜索热度基本稳定,但各种硬件的热度抖动却异常剧烈。一方面,Oculus Rift 在暑促活动结束后反而出现了一波冲高回落...

    腾讯研究院
  • 【技术分享】机器学习之回归原理详述(一)

    导语:本文用了从数学层面和代码层面,再结合一些通俗易懂的例子,详细地描述了回归主要涉及的原理和知识,希望对于机器学习的初学者或者有兴趣研究模型具体实现的同学带来...

    腾讯智能钛AI开发者
  • 机器学习之回归原理详述(一)

    本文用了从数学层面和代码层面,再结合一些通俗易懂的例子,详细地描述了回归主要涉及的原理和知识,希望对于机器学习的初学者或者有兴趣研究模型具体实现的同学带来一点帮...

    汪毅雄
  • ESP32刷入Ruff Lite固件

    2)介绍:Ruff 是一个支持 JavaScript 开发应用的物联网操作系统,为软件开发者提供开放、高效、敏捷的物联网应用开发平台,让 IoT 应用开发更简单...

    治电小白菜

扫码关注云+社区

领取腾讯云代金券