Creator热更新方案,弃用官方方案,采用增量zip方式

有需要 期待

https://store.cocos.com/app/detail/3838

借个位置楼主, android 交流群

现在是打包热更资源,不是打包bundle,想什么呢

补充一个细节,资源打zip的时候,注意用重新构建的文件信息打,例如统一文件时间戳,统一外部属性等。否则打出的zip的md5,每次都会变化。文件列表也要先排序再打。
用代码比较方便,python就是 zipf.writestr(info, f.read()),info要自己构建

我是先用cocos构建命令打,构建好了文件,在对构建文件进行压缩,你说的文件时间系统统一具体是怎么个意思,另外就是我用的是js的jszip工具来压缩的,会有什么区别吗

就是相同的文件内容,但是列表顺序,文件创建和修改时间不一样的话,zip包的md5是不一样的。
你可以试试看你打出来的相同内容zip的md5是否一样,如果一样,那就没问题了。

我让AI 给一段python代码,说明一下应该怎么压缩,相同的文件内容打出的zip包,md5才一致:

被你这么提醒,发现对文件生成两次构建,在所有文件都没有被修改过的情况下去构建,这两次构建出来的文件中,有一个manifest永远不相同
zip就更离谱了每次都变,后来我像你一样加了个固定时间戳也不行
这里边涉及有两个问题,一个是对相同内容两次构建有一个manifest文件永远不同,
另外一个是zip包加了固定时间构建的后,对相同的两个内容出来的zip包所有md5都不同
:rofl:

你的问题很常见 因为大家都是被虐过来的 这个时候就应该是官方站出来 给个例程 至少是个能用的例程 如果有更高的要求 你自己可以再去扩展 ,因为ZIP方式是官方提出来的 但很遗憾 类似这种情况时候 官方总是消失的无影无踪

可以构建相同的md5的,我这边每次构建都可以一样,你可能忘记排序加入zip的文件列表,或者文件的一些属性没设置。你问问chatgpt ai让他出jszip的代码。我自己用的python,手动构建文件info就好了。

对相同内容两次构建有一个manifest文件永远不同

manifest 我构建出来都一样的,不过不同也没事,版本号和md5对就可以了。

我给你问了chatgpt :

const JSZip = require('jszip');
const fs = require('fs');
const path = require('path');

function setFixedDate(zipObj) {
    const fixedDate = new Date('2024-01-01T00:00:00Z');
    for (let filename in zipObj.files) {
        if (zipObj.files.hasOwnProperty(filename)) {
            zipObj.files[filename].date = fixedDate;
        }
    }
}

function addFilesToZip(zip, dir, baseDir) {
    const files = fs.readdirSync(dir).sort();
    files.forEach(file => {
        const filePath = path.join(dir, file);
        const relativePath = path.relative(baseDir, filePath);
        const stats = fs.statSync(filePath);

        if (stats.isDirectory()) {
            addFilesToZip(zip.folder(file), filePath, baseDir);
        } else {
            const data = fs.readFileSync(filePath);
            zip.file(relativePath, data, {
                date: new Date('2024-01-01T00:00:00Z'),
                unixPermissions: parseInt('0600', 8) // Set file permissions to rw-------
            });
        }
    });
}

function createDeterministicZip(zipPath, folderPath) {
    const zip = new JSZip();
    addFilesToZip(zip, folderPath, folderPath);

    setFixedDate(zip);

    zip.generateAsync({ type: 'nodebuffer', compression: 'DEFLATE' })
        .then(content => {
            fs.writeFileSync(zipPath, content);
        });
}

// Usage
createDeterministicZip('archive.zip', 'folder');

关键点是一个是对文件列表sort,另外一个把文件的读写权限也统一,你试试看。

有用,但不全有用,经过测试,setFixedDate这个方法起实际作用,对于两次相同内容构建出来的zip大部分相同唯独resources这个文件夹构建的zip不行,
另外也单独对unixPermissions参数和sort分别测试,并没有效果,在不运行setFixedDate前提下依旧是所有zip包不同,另外补充:setFixedDate里边语法错误,zipObj.files不存在hasOwnProperty方法,我修正为别的写法了
Object.keys(zipObj.files).forEach(filename => {

    zipObj.files[filename].date = fixedDate;

});

因此问题转化为了,为什么对resources无效果

我用的python里面有个zipfile.writestr,可以保证存进去的文件额外信息完全由手工构建的,传入的info和文件本身读取的内容,都是固定的。所以一般没问题。
jszip的file还是会去拿文件本身进行处理,保不准有哪些文件属性不一样的。

你可以对比一下打出来zip的差异,看差异在哪里,是什么信息,就知道是什么属性有问题了。

不是这样说的,是这几个因素缺一不可,都加上才比较保险,不是哪个起实际作用的问题,都是为了保证内容一致。
sort的作用,是保证加入zip的文件顺序一定要一样。readdirSync出来的文件列表要排序。他本身接口是不会排序的,在不同电脑上,可能就不一样。
权限也是一样的,假如拿linux系统做打包机,这个权限如果被另外的脚本随机修改,就不一样了。

奇怪了,我用BeyoneCompare软件全方位对比两次构建出来的resources,无论是文件,文件夹,修改时间,读写属性都一致,就这个文件夹构建zip很特殊,其他的AB包加了你说的时间校验,包括读写属性等等后确实md5一致了,就这个很特别