import { native, sys } from 'cc' import { Logger } from './Logger' import EventManager from './EventManager' import VersionManager from './VersionManager' import ManifestConfig from '../config/ManifestConfig' import ResourcePreload from '../../game/utils/ResourcePreload' import CommonTips from '../uicomponent/CommonTips' export default class HotUpdate { public static Event_CheckUpdate: string = 'Event_CheckUpdate' public static Event_On_Progress: string = 'HotUpdate_Event_On_Progress' public static Event_On_NeedUpdate: string = 'HotUpdate_Event_On_NeedUpdate' public static Event_Finish_Update: string = 'HotUpdate_Event_Finish' public static Event_On_ALREADY_UP_TO_DATE: string = 'HotUpdate_Event_On_ALREADY_UP_TO_DATE' public static Event_On_Fail_Update: string = 'HotUpdate_Event_On_Fail_Update' private _am: any private _checkListener: null private storagePath: string private manifestUrl: string private localBigVersion: number private remoteBigVersion: number public needUpdate: boolean = false public isUpdating: boolean public isFinishUpdate: boolean public isCheck: boolean private key: string private hotupdateIndex: number constructor() { } public init( index: number, key: string = 'Code-remote-asset', manifestUrl: string ) { if (sys.isNative) { this.hotupdateIndex = index this.key = key this.manifestUrl = manifestUrl this.storagePath = '获取this.storagePath报错了' Logger.log(this, 'init removeDirectory=', this.storagePath + '_temp') } this.needUpdate = false this.isUpdating = false this.isFinishUpdate = false this.isCheck = false } private jumpToPack() { let url: string if (sys.isNative) { if (sys.os == sys.OS.ANDROID) { url = VersionManager.instance.apkStoreUrl } else if (sys.os == sys.OS.IOS) { url = VersionManager.instance.iosStoreUrl } } Logger.info( this, 'jumpToPack==androidurl===', VersionManager.instance.apkStoreUrl ) Logger.info( this, 'jumpToPack==iosStoreUrl===', VersionManager.instance.iosStoreUrl ) Logger.info(this, 'jumpToPack=====', url) sys.openURL(url) // cc.game.end(); } //显示强制更新,即更细包面板 private showPackUpdateDialog() { CommonTips.showMsg( '有新的版本需要更新,下载后请先卸载,以前的版本,再安装!' ) this.jumpToPack() this.showPackUpdateDialog() } private checkCb(event: any) { Logger.log(this, 'checkCb Code: =================' + event.getEventCode()) switch (event.getEventCode()) { case native.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST: Logger.info(this, 'No local manifest file found, hot update skipped.') this.failUpdate() break case native.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST: case native.EventAssetsManager.ERROR_PARSE_MANIFEST: Logger.info(this, 'Fail to download manifest file, hot update skipped.') this.failUpdate() break case native.EventAssetsManager.ALREADY_UP_TO_DATE: Logger.info(this, 'Already up to date with the latest remote version.') this.alreadyUpToDate() break case native.EventAssetsManager.NEW_VERSION_FOUND: Logger.info( this, 'new version found, please try to update.', this.localBigVersion, this.remoteBigVersion ) if ( this.key == VersionManager.Config_Key[0] && this.localBigVersion < this.remoteBigVersion ) { //更新大版本 Logger.info( this, 'new version found, please try to update======packupdate=', this.localBigVersion, this.remoteBigVersion ) this.showPackUpdateDialog() } else { Logger.info( this, 'new version found, please try to update======hotupdate=', this.localBigVersion, this.remoteBigVersion ) // this._am.update(); this.needUpdate = true EventManager.instance.dispatchEvent( HotUpdate.Event_On_NeedUpdate, this.key ) } break case native.EventAssetsManager.UPDATE_PROGRESSION: // var currentPercent = event.getPercent(); // var totalPercent = event.getPercentByFile(); // var fileprocess = event.getDownloadedFiles() + ' / ' + event.getTotalFiles(); // var byteprocess = event.getDownloadedBytes() + ' / ' + event.getTotalBytes(); Logger.info( this, 'UPDATE_PROGRESSION2222==========', this.key, event.getDownloadedBytes(), event.getTotalBytes() ) if (event.getTotalBytes() > 0) { EventManager.instance.dispatchEvent( HotUpdate.Event_On_Progress, event.getDownloadedBytes(), event.getTotalBytes(), this.key ) } break case native.EventAssetsManager.UPDATE_FINISHED: Logger.info(this, 'UPDATE_FINISHED==============') this.finishUpdate(true) break case native.EventAssetsManager.UPDATE_FAILED: Logger.warn(this, 'Update failed==========', event.getMessage()) this.failUpdate() break case native.EventAssetsManager.ERROR_UPDATING: let fullFilePath: string = this.storagePath + '/' + event.getAssetId() let tempFilePath: string = this.storagePath + '_temp/' + event.getAssetId() Logger.warn(this, 'fullFilePath====', fullFilePath) Logger.warn(this, 'tempFilePath====', tempFilePath) // jsb.fileUtils.removeFile(tempFilePath); Logger.warn( this, 'ERROR_UPDATING=============', event.getAssetId(), event.getMessage() ) this.failUpdate() break default: // this.failUpdate(); return } } public checkUpdate() { if (this.isUpdating || this.isCheck) { Logger.log(this, 'Checking or updating ...') return } let hotupdateUrlKey: string = VersionManager.Config_Url_Key[this.hotupdateIndex] Logger.log(this, 'checkoutUpdate=====', this.manifestUrl, hotupdateUrlKey) if (!this._am) { this._am = new native.AssetsManager( '', this.storagePath, this.versionCompareHandle.bind(this) ) } // this._am.setMaxConcurrentTask(1); let manifestStr: string = ManifestConfig.getManifestStr(hotupdateUrlKey) Logger.log(this, 'checkUpdate=======manifestStr=======', manifestStr) let manifest = new native.Manifest(manifestStr, this.storagePath) this._am.setVerifyCallback(function(filePath, asset) { return true // var md5 = calculateMD5(filePath); // if (md5 === asset.md5) // return true; // else // return false; }) this._am.setEventCallback(this.checkCb.bind(this)) // 设置事件回调 this.isCheck = true this._am.loadLocalManifest(manifest, this.storagePath) this._am.checkUpdate() } /** * @param versionA 本地版本 1.0.0 * @param versionB 服务器版本 1.0.1 */ private versionCompareHandle(versionA: string, versionB: string) { const vA = versionA.split('.') const vB = versionB.split('.') Logger.log( this, 'versionCompareHandle======', this.key, VersionManager.Config_Key[0] ) if (this.key == VersionManager.Config_Key[0]) { Logger.log(this, 'versionCompareHandle22===', versionA, versionB) VersionManager.instance.nowVersion = versionA VersionManager.instance.targetVersion = versionB } this.localBigVersion = parseInt(vA[0]) this.remoteBigVersion = parseInt(vB[0]) for (let i = 0; i < vA.length; ++i) { const a = parseInt(vA[i]) const b = parseInt(vB[i] || '0') if (a !== b) return a - b } if (vB.length > vA.length) { return -1 } else { return 0 } } public startUpdate() { if (this.isUpdating) return let localManifest = this._am.getLocalManifest() let remoteManifest = this._am.getRemoteManifest() Logger.log(this, 'startUpdate111===', localManifest.getVersionFileUrl()) Logger.log(this, 'startUpdate2222===', localManifest.getManifestFileUrl()) Logger.log(this, 'startUpdate3333===', remoteManifest.getVersionFileUrl()) Logger.log(this, 'startUpdate4444===', remoteManifest.getManifestFileUrl()) this.isUpdating = true EventManager.instance.dispatchEvent( HotUpdate.Event_On_Progress, 0, 100, this.key ) this._am.update() } public disposeUpdate() { if (this._am) { this._am.setVerifyCallback(null) this._am.setEventCallback(null) } this._am = null this._checkListener = null this.isUpdating = false this.needUpdate = false } private failUpdate() { this.disposeUpdate() this.isCheck = false EventManager.instance.dispatchEvent( HotUpdate.Event_On_Fail_Update, this.key ) } private alreadyUpToDate() { this.disposeUpdate() this.isFinishUpdate = true EventManager.instance.dispatchEvent( HotUpdate.Event_On_ALREADY_UP_TO_DATE, this.key ) } private finishUpdate(needRestart: boolean) { Logger.info(this, '更新完成=====', needRestart) this.disposeUpdate() this.isFinishUpdate = true EventManager.instance.dispatchEvent( HotUpdate.Event_Finish_Update, this.key, needRestart ) if (false && needRestart) { //暂时不想修 fileUtils 这个报错 var searchPaths = '' //jsb.fileUtils.getSearchPaths();暂时注释 Logger.info(this, '更新完成====searchPaths======', searchPaths) sys.localStorage.setItem( 'HotUpdateSearchPaths', JSON.stringify(searchPaths) ) //jsb.fileUtils.setSearchPaths(searchPaths);暂时注释 if (this.key == VersionManager.Config_Key[0]) { ResourcePreload.instance.restartGame() } } } }