记录一下这一路热更新与加密的爱恨情仇

记录一下这一路热更新与加密的爱恨情仇

年少时不懂事,拿着原理就敢往里干,最初使用了一个rpgmaker做的玩具,emmm当时是只会发布html相关,它本身的安卓打出来也是个网页,后来选择cocos也是发现他网页属性比较高,因此网页套壳成了首选,基于网页加载的相关原理总结如图。

一个程序,是由各种文件组成,代码构建的产物本身也就是另外一种形式的代码,只要能够更改或者替换某个产物,其内部行为就会出现变化。

要让产物稳定变化,那么肯定就是基于源码的稳定变化了。—这句话也就是加密与热更新的核心。

于是webview套壳网页游戏热更新v1就此发布

此版本基于对整个网页部署的流程进行了安卓化部署,andServer就相当于一个nginx,一个web容器,用于在客户端本地部署一个网页服务器,这样,通过改造构建容器时的handler,就能把assets的文件和通过安卓热更新下载到本地的应用私有目录的补丁文件混在一起,优先通过私有目录构建,没有的文件从assets目录拿。再通过对应用的布局进行锁定。这样,一个本地web服务器就构建好了,通过webView直接加载本地网页地址,并且可以通过热更的方式更新内容。-----或许你有个疑问,都套壳了,怎么不直接套个远端服务器的网页地址,不是更方便吗。emmm,这你就不懂了,流量不是钱嘛,加载速度也慢,游戏大了加载受限,但是这样的话就靠玩家自己的手机就行了。不过这也有一个很大的问题。那就是性能,webView+andServer的双重压力,导致游戏在一些关键场景会出现性能瓶颈。于是这个方案作为游戏热更新的方案就此报废,迎来了第一次改造。

热更新v1.1

既然andServer太重,那么就不要andServer,至于file://这个协议emmm在安卓反正是早就不让用实际也用不了。但是通过一些特殊的文件处理类,直接改造webView的本地取用逻辑确实没什么问题的,具体点就是换了一个handler去重写,前面写的是andServer的现在写的是webView要加载的相关的。具体叫啥忘了,大致是这样的,就是webView的一个资源相关的。这个时候基本的性能不怎么影响了,作为一个rpg类型的回合制游戏来讲,流畅度足够了,----emmm其实这个时候是感觉流畅度和电脑上差不多,实则是没吃过细糠。这个时候感觉也够用了。但是却有个很致命的问题----闪退,尤其是套壳网页,玩家玩了几个小时说越来越卡,最后有的时候直接闪退。好家伙,这时套壳就要背锅了,误上断头台了说是,刚开始写了一大堆asset load,这玩意刚开始也没有给人说有这么大的风险,oom啊。其实后来我感觉web套壳的分配显存是比cocos自己原生的要大的,因为他虽然卡,但是他一般不会闪退,卡得动不了他都不轻易闪退。反而是cocos原生安卓,虽然极其流畅,但是动不动没预料的就闪退了。

这里也就是cocos最大的一个坑,脱离节点树自行加载的asset不会自行释放,会一直占住显存,并且cocos提供了一系列的销毁,什么destroy,什么release,每次,我以为释放成功,我以为取得重大突破时都会给我当头一棒,并且这个东西并没有写在cocos的官方文档里面——(也或许是我没发现,反正真正用到cocos并不算特别九)

当年也大概就是2年左右吧最终找到这个解决问题的是在csdn的某个小帖子上零星记录着几句引用计数,引用归零自动释放显存。def,adef,等相关。

至此真相大白,我的套壳背大锅了属于是,误上断头台。

热更新v1.2

上局说到,web套壳热更新由于显存引起的闪退问题被当作根因被直接砍掉,用原生进行替代,于是v1.2就此诞生

emmm,你问我为什么不用官方提供的热更新方案,呜呜呜,我也想啊,奈何当时看了半天,这玩意就一个。。。啊我丢,刚又去准备截个图,结果(upload://kctaCypwTw385ZFAzVqcKTjTS2Y.png)

呜呜呜呜~~~~~这什么时候更新的,当年我记得就


这么一句话加一个范例工程,

image-7 好吧确实是新增了一页,这个老的还在。

2年前ai不发达,又是小白的我只能苦哈哈的用自己能控制的方式做成一个又一个优化版热更新了。好吧扯远了,好吧,看了下只是对以前那种模式做了一个详细说明和补充,事实上直接拿来用还是不太好。这里就要引出第二个核心问题, 加密 了。cocos提供的这种MD5的方式对于密钥不变noce可变的这种原文不变,密文可变的加密来说就会是一种灾难,热更新就变成全量更新了。因此简单的方式就是对其进行改造。这方面各有各的奇葩路子。我也没用这种。因为长期的热更新底层积累,我更加倾向于链式补丁的方案,可回退可更新。可发布,更容易管理。

这里就需要搞清楚热更新与加密的本质了。

热更新与加密

这两者本质上来说是不矛盾的,甚至可以互相没啥关系。

传统补丁我们很容易想到md5,摘要算法,能快速确认文件变没变,但是文件一旦加密,例如AES相关加密,那么哪怕密钥一样,密文也会不一样,如何让热更新只更新真正变化的呢,那么就得明白真正要更新的变化是什么,真正需要更新的变化其实只是原文变化而导致的变化,而不是加密的随机性引起的变化,因此。我们不再是对比产物md5而是转而把产物还原,对比原文的md5变化,这样就能最大程度的复用原文未变化的密文。

链式版本发布与更新管理

解决加密和热更新关系的问题后可以清楚的发现,加密是不会影响热更新的,这两者虽然影响不大,但是细节处理却比较复杂,cocos虽然给了热更新和加密等相关方案,但是就版本发布与管理,二者的结合支持却很弱。或者是我没发现好用的。于是虽然官方文档说的区别与链式补丁,但是我就钟爱链式补丁,管你对比不对比,对比我也要链式的,自己写个对比

单纯的md5已经是不足以承受加密和热更的混合,此时再来个壮士断腕,直接上版本管理,全部钉死在构建信息里面。通过清单机制,以及补丁清单等一系列细节信息,只需要在需要构建热更新时先发布基础版本,构建出产物后发布基础版本,选择基础版本后进行链式发布,将一切需要手动操作进行脚本的聚合到cocos扩展进行自动处理。最终只关注产物发布与部署即可。此时在原有的热更新机制就变为了私有目录下是一个个版本id为目录名的私有目录,通过搜索优先级调控的链式版本,通过发布与回滚版本号实现目录优先级的启动范围调控和发布下载。

热更v1.3

emmm上述的两大核心神器一出,我还是用在了心心念念的web套壳

这里仅仅是因为之前某个网页游戏不支持安卓发布,并且没有热更新方案。

热更v2.0

经历之前的种种坎坷,最终热更新长成了链式的模样

好吧。我也不卖扩展,只是ai越来越快,人还是要慢下来坚持一下老手艺

中间也做了一个godot的热更新,全自动构建发布,分布式节点下载,其实也是出于无奈,资源有限时就会想方设法。哈哈,点个赞,有机会下次再讲godot之我的链式热更新之路。

我进来其实就是想看看热更新相关的,或者说 官方的热更新方案,你是说很复杂?不太实用?或者有什么问题? 没看出你想表达什么是?官方的 很简单的把 也很成熟 至少我没找到不用官方方案的理由还

上面有说到,在以前大概两年前,那会文档描述确实比较少,因此基于当时的理解走上自定义方案,并不是说官方的不实用或者复杂,适合自己的才是最好的,文章只是记录,以及阐述相关热更新原理和结合实际的相关个人应用

固定加密算法产出的密文稳定直接套用官方的当然没问题,但是如果说你要自定义加密算法,在c++层改写。套用的加密算法分级,以及算法密钥相同时产出的密文随机时,直接套用就会失效,上面也有说到,你觉得好用只是没有涉及到你用不了的场景,明白了加密与热更新的关系才知道如何处理

emmm,基本上用开源引擎就会涉及到加密保护的问题,用自带的加密相关是很容易被通用破解器给干掉的,改写后的加密就会涉及到密文变化相关问题,以及性能问题,重要数据加密等级就需要提高,资产类大头就需要放轻,高等级的AES就会涉及到原文不变,密钥不变,但是密文会随机,此时对于热更新的底层理解就远比你用哪一个更加重要,如果要看官方的直接去官网文档看就好了,文中吐槽纯属当时文档太简陋,现在我去看了已经补了很多说明了。就不再过多阐述了,本文属于记录型和实干型,实用的可以划走了。