cocoscreator热更新

本文介绍了CocosCreator的热更新流程,强调了官方文档的重要性,并指出官方示例中计算MD5的问题,提供了修复方案。同时,分享了一个自写的热更新组件的demo供下载参考。
摘要由CSDN通过智能技术生成
首先要看一下官方文档

官方热更新范例
官方热更新文档
官方热更新API
官方 version_generator.js 文件
首先我们要熟悉一下官方的热更新文档,了解热更新机制。其次自己要去通过实践来熟悉一下。


官方实例几处需要注意的,会导致热更新出问题
参考这篇博客

  1. 热更新目录的储存

    /**
     * 这里需要注意的是,不要将相同的路径重复添加。所以这里加了判断
     */
    // 在下载资源完毕后,加入资源搜索路径
    var searchPaths = jsb.fileUtils.getSearchPaths();
    var newPaths = this._assetsMng.getLocalManifest().getSearchPaths();
    for(let i = 0; i < newPaths.length; i++){
         
        if(searchPaths.indexOf(newPaths[i]) == -1){
         
        	Array.prototype.unshift.apply(searchPaths, newPaths[i]);
        }
    }
    cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));
    jsb.fileUtils.setSearchPaths(searchPaths);
    
  2. 在main.js 中 main.js 开头 添加读取热更新路径(HotUpdateSearchPaths),并且这是searchPaths

    // 在 main.js 的开头添加如下代码
    if (jsb) {
         
        var hotUpdateSearchPaths = localStorage.getItem('HotUpdateSearchPaths');
    	if (hotUpdateSearchPaths) {
         
       	 jsb.fileUtils.setSearchPaths(JSON.parse(hotUpdateSearchPaths));
    	}
    }
    
  3. 热更新MD5校验问题
    在官方的校验函数中,当一个文件下载完成的时候,要对资源进行验证,验证成功返回true,该文件标识更新成功。
    但是官方范例没有提到如何在js里计算文件md5。并且官方的version_generator.js 在计算的时候有一处问题。

    md5 = crypto.createHash('md5').update(fs.readFileSync(subpath,"binary")).digest('hex');
    

    这里fs.readFileSycn(subpath,“binary”)返回的并非二进制类型,而是String。这会导致非文本文件md5计算错误。如果写入到manifest的文件md5是错误的,你下载文件后,计算md5作比较当然就很难匹配上了。除此之外,我们在jsb里只能使用:

    jsb.fileUtils.getStringFromFile(filePath);
    jsb.fileUtils.getDataFromFile(filePath);
    

    来获取文件内容,但是getStringFromFile()无法获取非文本内容。所以我们只能使用getStringFromFile()来获取二进制数据,它在js层面的师徒类型是Uint8Array 和 nodejs readFileSync()一致。
    现在我们来修改一下官方的version_generator.js
    md5 = crypto.createHash('md5').update(fs.readFileSync(subpath,"binary")).digest('hex');
    改为:md5 = crypto.createHash('md5').update(fs.readFileSync(subpath)).digest('hex');
    修改后的version_generator.js

    接下来我们实现 byteArray md5的计算, jsb_md5.js
    下面直接上代码

    /**
    * from jsb_runtime_md5.js
    * @param {} data
    */
    module.exports = function(data){
         
       // for test/debug
       function fflog(msg) {
         
           try {
         
               console.log(msg);
           } catch(e) {
         }
       }
    
       // convert number to (unsigned) 32 bit hex, zero filled string
       function to_zerofilled_hex(n) {
         
           var t1 = (n >>> 24).toString(16);
           var t2 = (n & 0x00FFFFFF).toString(16);
           return "00".substr(0, 2 - t1.length) + t1 +
               "000000".substr(0, 6 - t2.length) + t2;
       }
    
       // convert a 64 bit unsigned number to array of bytes. Little endian
       function int64_to_bytes(num) {
         
           var retval = [];
           for (var i = 0; i < 8; i++) {
         
               retval.push(num & 0xFF);
               num = num >>> 8;
           }
           return retval;
       }
    
       //  32 bit left-rotation
       function rol(num, places) {
         
           return ((num << places) & 0xFFFFFFFF) | (num >>> (32 - places));
       }
    
       // The 4 MD5 functions
       function fF(b, c, d) {
         
           return (b & c) | (~b & d);
       }
    
       function fG(b, c, d) {
         
           return (d & b) | (~d & c);
       }
    
       function fH(b, c, d) {
         
           return b ^ c ^ d;
       }
    
       function fI(b, c, d) {
         
           return c ^ (b | ~d);
       }
    
       // pick 4 bytes at specified offset. Little-endian is assumed
       function bytes_to_int32(arr, off) {
         
           return (arr[off + 3] << 24) | (arr[off + 2] << 16) | (arr[off + 1] << 8) | (arr[off]);
       }
       // convert the 4 32-bit buffers to a 128 bit hex string. (Little-endian is assumed)
       function int128le_to_hex(a, b, c, d) {
         
           var ra = "";
           var t = 0;
           var ta = 0;
           for (var i = 3; i >= 0; i--) {
         
               ta = arguments[i];
               t = (ta & 0xFF);
               ta = ta >>> 8;
               t = t << 8;
               t = t | (ta & 0xFF);
               ta = ta >>> 8;
               t = t << 8;
               t = t | (ta & 0xFF);
               ta = ta >>> 8;
               t = t << 8;
               t = t | ta;
               ra = ra + to_zerofilled_hex(t);
           }
           return ra;
       }
    
       // check input data type and perform conversions if needed
       
       if (!data instanceof Uint8Array){
         
           fflog("input data type mismatch only support Uint8Array");
           return null;
       }
       var databytes = [];
       for(var i = 0; i < data.byteLength;i++){
         
           databytes.push(data[i]);
       }
    
       // save original length
       var org_len = databytes.length;
    
       // first append the "1" + 7x "0"
       databytes.push(0x80);
    
       // determine required amount of padding
       var tail = databytes.length % 64;
       // no room for msg length?
       if (tail > 56) {
         
           // pad to next 512 bit block
           for (var i = 0; i < (64 - tail); i++) {
         
               databytes.push(0x0);
           }
           tail = databytes.length % 64;
       }
       for (i = 0; i < (56 - tail); i++) {
         
           databytes.push(0x0);
       }
       // message length in bits mod 512 should now be 448
       // append 64 bit, little-endian original msg length (in *bits*!)
       databytes = databytes.concat(int64_to_bytes(org_len * 8));
    
       // initialize 4x32 bit state
       var h0 = 0x67452301;
       var h1 = 0xEFCDAB89;
       var h2 = 0x98BADCFE;
       var h3 = 0x10325476;
    
       // temp buffers
       var a = 0,
           b = 0,
           c 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值