From 43eac55d18e248e27eeadf9e898b917b0d255d8f Mon Sep 17 00:00:00 2001 From: gongxh Date: Thu, 24 Apr 2025 18:37:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=91=E5=B8=831.0.29=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E7=83=AD=E6=9B=B4=E6=96=B0=E8=AF=B4=E6=98=8E=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 +- docs/HotUpdate.md | 161 ++++++++++++++++++++++++++++++ package.json | 2 +- src/hotupdate/HotUpdate.ts | 22 ++-- src/hotupdate/HotUpdateManager.ts | 11 +- src/interface/PromiseResult.ts | 2 - 6 files changed, 183 insertions(+), 19 deletions(-) create mode 100644 docs/HotUpdate.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 4000484..a50f965 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,4 +4,6 @@ ## 1.0.27 - 添加socket网络模块,支持所有平台,抹平微信、支付宝、抖音小游戏和web以及原生平台的使用差异; ## 1.0.28 -- 添加小游戏激励视频、支付、和通用信息获取接口 (支付宝小游戏、抖音小游戏、微信小游戏) \ No newline at end of file +- 添加小游戏激励视频、支付、和通用信息获取接口 (支付宝小游戏、抖音小游戏、微信小游戏) +## 1.0.29 +- 添加原生平台热更新支持 \ No newline at end of file diff --git a/docs/HotUpdate.md b/docs/HotUpdate.md new file mode 100644 index 0000000..5c32305 --- /dev/null +++ b/docs/HotUpdate.md @@ -0,0 +1,161 @@ +## 热更新 + +* 完全使用creator官方的热更新方案 + +* 重新封装,使用更简单 + +* **支持动态变更资源路径** + +* cdn上资源结构 + + ![image_hotupdate1](https://gitee.com/gongxinhai/public-image/raw/master/image_hotupdate1.jpeg#pic_left) + +### 规则 + +* 和版本号绑定,版本更新后之前的热更新资源失效,(版本号指的是初始化函数中传入的版本号 推荐使用游戏版本号) + +* 在构建完成之后的main.js中添加以下内容,可以使用构建模版,或者用脚本修改 + + ```javascript + (function () { + if (typeof window.jsb === 'object') { + let saveVersion = localStorage.getItem('hotupdate::version'); + let searchPaths = localStorage.getItem('hotupdate::searchpaths'); + //TODO::版本号 这里需要根据自己的项目修改 + let version = "0.0.2"; + if (!saveVersion || saveVersion != version ) { + localStorage.setItem('hotupdate::searchpaths', null); + searchPaths = null; + } + if (searchPaths) { + let paths = JSON.parse(searchPaths); + jsb.fileUtils.setSearchPaths(paths); + + let fileList = []; + let storagePath = paths[0] || ''; + let tempPath = storagePath + '_temp/'; + let baseOffset = tempPath.length; + + if (jsb.fileUtils.isDirectoryExist(tempPath) && !jsb.fileUtils.isFileExist(tempPath + 'project.manifest.temp')) { + jsb.fileUtils.listFilesRecursively(tempPath, fileList); + fileList.forEach(srcPath => { + let relativePath = srcPath.substr(baseOffset); + let dstPath = storagePath + relativePath; + + if (srcPath[srcPath.length] == '/') { + jsb.fileUtils.createDirectory(dstPath); + } else { + if (jsb.fileUtils.isFileExist(dstPath)) { + jsb.fileUtils.removeFile(dstPath); + } + jsb.fileUtils.renameFile(srcPath, dstPath); + } + }) + jsb.fileUtils.removeDirectory(tempPath); + } + } + } + })(); + ``` + +### 使用 + +一些枚举类型 + +```typescript +export enum HotUpdateCode { + /** 成功 */ + Succeed = 0, + /** 平台不支持 不需要热更新 */ + PlatformNotSupported = -1000, + /** 未初始化 */ + NotInitialized = -1001, + /** 是最新版本 */ + LatestVersion = -1002, + /** 更新中 */ + Updating = -1003, + /** 加载本地manifest失败 */ + LoadManifestFailed = -1004, + /** 下载manifest文件失败 */ + ParseManifestFailed = -1005, + + /** 下载version.manifest失败 */ + LoadVersionFailed = -1006, + /** 解析version.manifest失败 */ + ParseVersionFailed = -1007, + + + /** 更新失败 需要重试 */ + UpdateFailed = -1008, + /** 更新错误 */ + UpdateError = -1009, + /** 解压错误 */ + DecompressError = -1010, +} +``` + +* 初始化 【必须】 + + ```typescript + /** + * 初始化热更新管理器 + * @param manifestUrl 传入本地manifest文件地址 creator资源Asset下的属性nativeUrl + * @param version 游戏版本号 eg: 1.0.0 + */ + kunpocc.HotUpdateManager.getInstance().init(manifestUrl: string, version: string) + ``` + +* 检查更新 + + ```typescript + interface ICheckResult { + /** 0:成功 其他:失败 */ + code: number; + /** 失败信息 */ + message: string;; + /** 需要更新的资源大小 (KB) */ + size?: number; + } + + kunpo.HotUpdateManager.getInstance().checkUpdate().then((res: ICheckResult) => { + console.log(`发现更新 资源大小:${res.size}kb`); + // 直接更新 + // this.startUpdate(true); + }).catch((err: any) => { + log("检查热更新出错了", JSON.stringify(err)); + if (res.code == HotUpdateCode.LatestVersion) { + console.log(`已经是最新版本了`); + } else { + console.log(`出错了 code:${res.code} message:${res.message}`); + // 根据 HotUpdateCode 中的错误码, 做后续处理,或提示,或跳过本次更新等 + } + }); + ``` + +* 直接尝试更新 + + ```typescript + kunpo.HotUpdateManager.getInstance().startUpdate({ + skipCheck: skipCheck, // 是否跳过检查更新,如果没有提前使用 + progress: (kb: number, total: number) => { + kunpo.log("热更新进度", kb, total); + }, + complete: (code: HotUpdateCode, message: string) => { + kunpo.log("热更新成功或者失败了", code, message); + if (code == HotUpdateCode.LatestVersion) { + console.log(`已经是最新版了`); + } else if (code == HotUpdateCode.UpdateFailed) { + console.log(`更新失败了 code:${code} message:${message}`); + // 可以在这里重试失败的资源 + // kunpo.HotUpdateManager.getInstance().retryUpdate(); + } else if (code == HotUpdateCode.LoadVersionFailed || code == HotUpdateCode.ParseVersionFailed) { + console.log(`更新失败了 可以选择跳过热更新 code:${code} message:${message}`); + } else { + console.log(`其他的失败 code:${code} message:${message}`); + } + } + }); + ``` + + + diff --git a/package.json b/package.json index b56b88f..9f780e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kunpocc", - "version": "1.0.28", + "version": "1.0.29", "description": "基于creator3.0+的kunpocc库", "main": "./dist/kunpocc.cjs", "module": "./dist/kunpocc.mjs", diff --git a/src/hotupdate/HotUpdate.ts b/src/hotupdate/HotUpdate.ts index b8d8b6b..affb7d1 100644 --- a/src/hotupdate/HotUpdate.ts +++ b/src/hotupdate/HotUpdate.ts @@ -118,9 +118,9 @@ export class HotUpdate { } }).then(res => { log(`${TAG} 检查更新结果:${JSON.stringify(res)}`); - resolve(res); + res.code === HotUpdateCode.Succeed ? resolve(res) : reject(res); }).catch(res => { - resolve(res); + reject(res); }); }); } @@ -138,12 +138,10 @@ export class HotUpdate { if (res.skipCheck) { this.startUpdateTask(); } else { - this.checkUpdate().then((res) => { - if (res.code === HotUpdateCode.Succeed) { - this.startUpdateTask(); - } else { - this._complete(res.code, res.message); - } + this.checkUpdate().then(res => { + this.startUpdateTask(); + }).catch((res: ICheckUpdatePromiseResult) => { + this._complete(res.code, res.message); }); } } @@ -299,20 +297,20 @@ export class HotUpdate { switch (eventCode) { case native.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST: this._am.setEventCallback(null); - resolve({ code: HotUpdateCode.LoadManifestFailed, message: "检查更新时下载manifest文件失败", needUpdate: false, size: 0 }); + resolve({ code: HotUpdateCode.LoadManifestFailed, message: "检查更新时下载manifest文件失败", size: 0 }); return; case native.EventAssetsManager.ERROR_PARSE_MANIFEST: this._am.setEventCallback(null); - resolve({ code: HotUpdateCode.ParseManifestFailed, message: "检查更新时解析manifest文件失败", needUpdate: false, size: 0 }); + resolve({ code: HotUpdateCode.ParseManifestFailed, message: "检查更新时解析manifest文件失败", size: 0 }); return; case native.EventAssetsManager.ALREADY_UP_TO_DATE: this._am.setEventCallback(null); - resolve({ code: HotUpdateCode.LatestVersion, message: "已是最新版本", needUpdate: false, size: 0 }); + resolve({ code: HotUpdateCode.LatestVersion, message: "已是最新版本", size: 0 }); return; case native.EventAssetsManager.NEW_VERSION_FOUND: // 发现新版本 this._am.setEventCallback(null); - resolve({ code: HotUpdateCode.Succeed, message: "发现新版本", needUpdate: true, size: this._am.getTotalBytes() / 1024 }); + resolve({ code: HotUpdateCode.Succeed, message: "发现新版本", size: this._am.getTotalBytes() / 1024 }); return; } }); diff --git a/src/hotupdate/HotUpdateManager.ts b/src/hotupdate/HotUpdateManager.ts index b7ffa13..ebbab23 100644 --- a/src/hotupdate/HotUpdateManager.ts +++ b/src/hotupdate/HotUpdateManager.ts @@ -105,22 +105,27 @@ export class HotUpdateManager { public checkUpdate(): Promise { return new Promise((resolve, reject) => { if (!Platform.isNativeMobile) { - resolve({ code: HotUpdateCode.PlatformNotSupported, message: "当前平台不需要热更新" }); + reject({ code: HotUpdateCode.PlatformNotSupported, message: "当前平台不需要热更新" }); return; } if (!this._isInitialized) { - resolve({ code: HotUpdateCode.NotInitialized, message: "未初始化, 需要先调用init方法" }); + reject({ code: HotUpdateCode.NotInitialized, message: "未初始化, 需要先调用init方法" }); return; } if (this._updating) { - resolve({ code: HotUpdateCode.Updating, message: "正在更新或者正在检查更新中" }); + reject({ code: HotUpdateCode.Updating, message: "正在更新或者正在检查更新中" }); return; } this._updating = true; this._hotUpdate = new HotUpdate(); this._hotUpdate.checkUpdate().then((res) => { this._updating = false; + // 有更新 resolve(res); + }).catch((res: ICheckUpdatePromiseResult) => { + this._updating = false; + // 无更新 + reject(res); }); }); } diff --git a/src/interface/PromiseResult.ts b/src/interface/PromiseResult.ts index 241cffe..30ab8be 100644 --- a/src/interface/PromiseResult.ts +++ b/src/interface/PromiseResult.ts @@ -12,8 +12,6 @@ export interface IPromiseResult { } export interface ICheckUpdatePromiseResult extends IPromiseResult { - /** 是否需要更新 */ - needUpdate?: boolean; /** 需要更新的资源大小 (KB) */ size?: number; } \ No newline at end of file