手游热更新方案--Unity3D下的CsToLua技术
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技术的更多相关文章
- 【腾讯Bugly干货分享】手游热更新方案xLua开源:Unity3D下Lua编程解决方案
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/2bY7A6ihK9IMcA0bOFyB-Q 导语 xL ...
- 腾讯开源手游热更新方案,Unity3D下的Lua编程
原文:http://www.sohu.com/a/123334175_355140 作者|车雄生 编辑|木环 腾讯最近在开源方面的动作不断:先是微信跨平台基础组件Mars宣布开源,腾讯手游又于近期开源 ...
- 手游热更新方案xLua开源:Unity3D下Lua编程解决方案
C#下Lua编程支持 xLua为Unity. .Net. Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用. xLua的突破 xLua在功能.性能.易用 ...
- Unity3D 热更新方案总结
如何评价腾讯在Unity下的xLua(开源)热更方案? Unity 游戏用XLua的HotFix实现热更原理揭秘 腾讯开源手游热更新方案,Unity3D下的Lua编程 [Unity]基于IL代码注入的 ...
- Unity3D 热更新方案(集合各位专家的汇总)
http://blog.csdn.net/guofeng526/article/details/52662994 热更新”这个词,在Unity3D的应用下,是有些语义错误的,但是作为大家都熟知的一项技 ...
- Unity3D热更新方案网摘总结
参考:http://blog.csdn.net/guofeng526/article/details/52662994 http://blog.csdn.net/u010019717/article/ ...
- 移动端热更新方案(iOS+Android)
PPT资源包含iOS+Android 各种方案分析:https://github.com/qiyer/Share/blob/master/%E7%83%AD%E6%9B%B4%E6%96%B0%E5% ...
- Unity官方发布热更新方案性能对照
孙广东 2016.3.11 Unity应用的iOS热更新 作者:丁治宇 Unity TechnologiesChina Agenda • 什么是热更新 • 为何要热更新 • 怎样在iOS 上对 ...
- unity热更新方案对比
Unity应用的iOS热更新 • 什么是热更新 • 为何要热更新 • 怎样在iOS 上对Unity 应用进行热更新 • 支持Unity iOS 热更新的各种Lua 插件的对照 什么是热更新 • ...
随机推荐
- 详解Lambda
定义好委托: public delegate int FirDelegate(int a); public delegate int SecDelegate(int a,int b); public ...
- Word中去除/删除/删掉Equation Chapter (Next) Section 1
实际问题如图显示 Equation Chapter (Next) Section 1 . 具体操作步骤如下: 1.Word的"格式"菜单--"样式和格式",出现 ...
- Python import this : The Zen of Python
>>> import thisThe Zen of Python, by Tim Peters Beautiful is better than ugly.Explicit is b ...
- Angularjs $http服务的两个request安全问题
今天为了hybrid app和后端restful服务的安全认证问题,又翻了一下$http的文档,$http服务文档页面两个安全问题是json和XSRF,JSON那个比较好理解,就不补充什么了,说说XS ...
- jtds驱动更新对一个老问题的解决
07年年末的一篇blog: 以前网站做初期开发时,有一个问题:hibernate下text大字符串读取时出这个异常:JDBCExceptionReporter - The amount of data ...
- Android Third Party Libraries and SDK's
http://javatechig.com/Android/android-third-party-libraries-sdks Over past few years, the age of mob ...
- Jmeter(二十六)_数据驱动测试
花了一点时间做了一个通用的执行引擎,好处就是我不用再关注测试脚本的内容,而是用测试用例的数据去驱动我们执行的方向.(这个只适合单个接口的测试,具体运用到接口自动化时,还是要靠手动去编写脚本!) 首先我 ...
- Junit-4.1.2 @Test 使用
学习使用Junit-4.1.2 @Test来做单元测试 1.下载jar包 下载junit-4.12.jar 下载hamcrest-core-1.3.jar 2.在External Libraries中 ...
- 浅谈java中的"=="和eqals区别
在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str2 = new String(&qu ...
- PAT1129:Recommendation System
1129. Recommendation System (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...