2018年6月27日星期三

unity 安卓热更新代码的最新方法: 通过Mono加载新的重新编译的dll

 unity代码热更新方法有很多,但实用的目前就是lua,但我不喜欢lua,一直想用c#进行热更新。
     在2012年,就有人提出既然Mono是开源的,那么完全可以通过修改mono源代码实现重新加载dll实现热更新。可惜这个楼主只提出了设想,并没有具体实现细节。
     今年,也就是2016年,我在一个技术群里得知,其实绝大部分大公司,目前用的都是这种方法实现热更新,其中一个游戏就是超级地城之光。既然知道已经有人在做了,那么我就可以尝试一下。自己捣鼓前,我还百度了一下,果然,已经有人有教程了:
     http://blog.csdn.net/qq_27772057/article/details/51945700
     我觉得这个人的博客已经很详细了,不过由于整体看上去比较复杂,所以可能细节上不好处理。
     我自己重新去实现了一下整个流程,已经测试通过。
     目前的策略是,通过修改mono源代码,编译出新的libmono.so
     启动游戏时候,下载Assembly-CSharp.dll,这样进入游戏就会使用更新后的代码。
     为了让大家方便一些,我自己编译好了4.6版本的libmono.so, 除了热更新,其实还有加密的功能,加密算法也很简单:
     char* ch;
    char* ch2 = "This is jiamed";
    char ch3[15];
    int i = 0;

    ch = data;
    for(i = 0; i < 14; i++)
    {
        ch3[i] = ch[i];
    }
    ch3[14] = 0;
    if(strcmp(ch3, ch2) == 0)
    {
        data = ch + sizeof(char) * 14;
        data_len -= 14;
        ch = data;
        for(i = 0; i < 10000; i++)
        {
            ch[i] = ch[i] ^ 0xab;
        }
        
    }

当然你可以无视,我已经兼容了非加密文件就不处理的情况。
有了这个so,你就可以省去绝大部分工作,剩下的就是打开游戏下载dll,下载的目录是:
string path1 = "/data/data/" + packname + "/files/";
packname就是你们的包名。

另外你需要将我的so替换你们自己的so,可以直接覆盖unity安装文件夹里的,也可以打包完毕后手动替换,手动替换的话要重新签名,建议写一个打包工具。

当然我目前使用的是4.6,所以其他版本的unity大家就要自己去编译了。
其实还有更好的方法,就是hook技术,这样就可以无视所有版本,只要是unity就可以用,可惜我不会安卓开发,所以hook希望有人补充吧。

需要更详细的细节可以在此帖下面询问。毕竟很多游戏都用了这个方法热更新,却没有人出来说下具体细节,也是醉了。

最后是文件地址:
http://pan.baidu.com/s/1c10hhxI

没有评论:

发表评论