本文介绍热更新有关的基础概念,流程和知识点,以及需要注意的事项(独家经验,倾囊相授),项目类型为cocos-lua,非quick
A.通过重新下载来更新,可称之为整包更新 ,整包更新会造成用户流失(给玩家思考要不要重新下载的机会),以及有appstore审核被拒绝的可能性,因此能热更新则热更新,除非改动C++代码才整包更新。
B.通过下载最新代码和资源来更新,叫做热更新。
首先要说明的是存放代码的src和资源的res目录是非可读写目录。因此热更新的资源是无法下载到之前目录的,那么就得建立一个手机上可读写的目录假设称之为hot目录,hot目录下也建立src和res目录,更新的资源全都存放到hot下的src和res。假设访问file.lua时,优先访问hot/src下的file.lua,当hot/src下不存在file.lua时去src下访问。这里hot/src叫做搜索路径,通过cc.FileUtils:getInstance():addSearchPath("hot/src/", true)设置, 参数true代表把当前路径优先级设为最高。设置搜索路径之后,文件的全路径=搜索路径+相对路径,因而实现了先hot/src后src的访问顺序。
A.启动游戏后下载资源服务器游戏版本号
B.对比本地版本号和服务器版本号差异,判断整包更新/热更新/不用更新
C.如果是热更新的话下载更新文件
D.边下载边检测是否完成,显示进度条(通过帧调度器实现,每帧检测)
E.检测到下载完成后,将服务器下载的版本文件放到hot或其子目录下(这里如果你下载文件保存的目录就是hot则所有文件下载完成再保存版本文件,如果你下载的目录不是在hot下,则完成时把所有文件包括版本文件拷贝到hot目录下)
F.下载完成后删除不需要的文件,清理各类缓( cc.FileUtils:getInstance():purgeCachedEntries() ),否则本次更新的文件不会生效,重启游戏(基于E,本次对比时和服务器版本一定会一致,直接进入游戏)
假设 线上发布了版本1.0,现在需要进行版本1.1的热更新
概述:先用python生成两个版本文件(python脚本和操作步骤请见下一篇https://blog.csdn.net/ellis1970/article/details/122046905),假设名为version.json和asset.json,version.json里记录游戏版本号假设为100.100,左边用来判断整包更新,右边用来判断热更新,每次更新时让版本号+1。asset.json里记录src和res下所有文件的信息(路径,大小,MD5){"assets": {"res/assets/bg.png": ["11c6793a636950dc74f0124b71605564", 38661],...},这里文件分成两个的原因是当游戏较大之后asset.json可能有几MB的大小,下载时需要2秒以上,避免不需要更新时下载asset.json。也就是说先下载version.json判断要不要热更新,要热更新则再下载asset.json,然后将下载下来的asset.json本地的asset.json对比(用一个循环判断md5值是否相等)生成差异文件列表(随着文件增多,生成差异列表时间会越来越长,可多达3秒以上),最后遍历差异文件列表依次下载服务器上的最新文件,下载完成后删除不需要的文件。
优点:开发者出新版本较快,资源服务器只有一套最新版本的资源,不用考虑跨版本更新的问题,进度条可以较准确反应实际进度。
缺点:因为没有压缩,下载时流量较多。
概述:和md5更新相比,差异包更新当请求下载时直接下载当前版本到最新版本的压缩包,然后解压完成更新。需要注意,假如1.2发布,因为线上同时存在1.0、1.1版本,所以需要生成差量包 1.0-1.2.zip,以及 1.1-1.2.zip。同理,假如一款产品经历了更新:1.1、1.2、1.3...1.9,那么当进行2.0热更新的时候,那么需要生成的差量包是 1.0-2.0.zip、1.1-2.0.zip...1.9-2.0.zip。
优点:玩家下载流量小。
缺点:维护成本高,开发人员发新版本较慢,进度条不好做,较难准确反应实际进度。
Cocos其实自带了热更新功能,AssetsManager对应差异包更新, AssetsManagerEx对应md5更新,不过成熟项目似乎很少用自带的,都是自己做一套热更新
举例来说,检测需要下载20MB,下载了5MB然后退出游戏,下次重新进入时提示需要下载15MB,继续下载。可通过生成下载列表时判断文件是否已经存在来实现,cc.FileUtils:getInstance():isFileExist(path)
由于下载的文件受网络不稳定,作弊,劫持等情况影响,可能出现下载保存到客户端后的文件和版本服务器上的文件不一致的情况,最后保存后调用一个函数生成md5吗和服务器的md5对比校验是否一致,不一致则重新下载,这样可确保进入游戏时没有错误的文件而导致报错和bug。
lua版下载地址:md5.lua/md5.lua at master · kikito/md5.lua · GitHub
实测lua版生成效率上不稳定,在安卓模拟器上有时很慢,因此最好用C++接口,且需要在真机上测试验证其效率。
保存到另一个目录假设称之为down目录,这种情况直接保存服务器版本文件asset.json,version.json,下载完成后把down目录的所有文件拷贝到hot目录,这里注意必须保证拷贝函数的写法和拷贝结果正确,验证方法是观察文本文件内容,和非文本的二进制文件(csb,mp3,png等)他们的大小从原位置到新位置后是否一致,换言之可能出现文本文件内容不一致,二进制文件大小不一致的情况。
直接保存到hot目录,这种情况完成下载后再保存版本文件asset.json,version.json,且必须做文件完整性校验,因为下载中断重进下载时,无法判断hot目录下的文件是上次下载的还是上次下载之前已经存在的。