123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- const { ccclass, property } = cc._decorator;
- @ccclass
- export default class HotUpdate extends cc.Component {
- @property({ type: cc.Node })
- public txtProgress: cc.Node = null;
- @property({ type: cc.Node })
- public txtProgressTips: cc.Node = null;
- @property({ type: cc.Node })
- public gProgress: cc.Node = null;
- @property({ type: cc.Node })
- public imgRole: cc.Node = null;
- @property({ type: cc.Node })
- public progress: cc.Node = null;
- @property({ type: cc.Sprite })
- public progressBar: cc.Sprite = null;
- @property({ type: cc.Asset })
- public manifestUrl: cc.Asset = null;
- _am: any;
- _checkListener: null;
- _updating: boolean;
- _updateListener: null;
- _canRetry: boolean;
- _failCount: number;
- _storagePath: string;
- versionCompareHandle: (versionA: any, versionB: any) => number;
- private _canEnterGame: boolean;
- public checkCb(event: any) {
- // cc.log('Code: ' + event.getEventCode());
- let isNewVersion = false;
- switch (event.getEventCode()) {
- case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
- console.log("No local manifest file found, hot update skipped.");
- break;
- case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
- case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
- console.log("Fail to download manifest file, hot update skipped.");
- break;
- case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
- console.log("Already up to date with the latest remote version.");
- this.EnterGame();
- break;
- case jsb.EventAssetsManager.NEW_VERSION_FOUND:
- console.log("New version found, please try to update.(" + this._am.getTotalBytes() + ')');
- isNewVersion = true;
- break;
- default:
- return;
- }
- this._am.setEventCallback(null);
- this._checkListener = null;
- this._updating = false;
- if (isNewVersion) {
- //有新版本,显示进度
- this.setProgress(0)
- this.hotUpdate();
- //5秒后判断是否开始下载,如果进度为0.直接进游戏,防止卡死
- this.scheduleOnce(() => {
- if (this.progressBar.fillRange == 0) {
- this.EnterGame()
- }
- }, 10)
- }
- }
- setProgress(val: number) {
- this.gProgress.active = true
- this.progressBar.fillRange = val
- this.imgRole.x = -this.progress.width / 2 + val * this.progress.width
- this.txtProgress.getComponent(cc.Label).string = Math.floor(val * 100) + "%"
- this.txtProgressTips.getComponent(cc.Label).string = "资源更新中"
- }
- public updateCb(event: any) {
- var needRestart = false;
- var failed = false;
- // console.log("updateCb event:"+JSON.stringify(event));
- switch (event.getEventCode()) {
- case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
- // console.log('No local manifest file found, hot update skipped.');
- failed = true;
- break;
- case jsb.EventAssetsManager.UPDATE_PROGRESSION:
- // this.panel.byteProgress.progress = event.getPercent();
- // this.panel.fileProgress.progress = event.getPercentByFile();
- // this.panel.fileLabel.string = event.getDownloadedFiles() + ' / ' + event.getTotalFiles();
- // this.panel.byteLabel.string = event.getDownloadedBytes() + ' / ' + event.getTotalBytes();
- // this.pb_hotUpdate.progress = event.getPercent();
- // this.lb_progress.string = Math.floor(event.getPercent()*100).toFixed(2) + '%';
- this.setProgress(event.getPercent())
- // var msg = event.getMessage();
- // if (msg) {
- // cc.log(event.getPercent()/100 + '% : ' + msg);
- // }
- break;
- case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
- case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
- // console.log('Fail to download manifest file, hot update skipped.');
- failed = true;
- break;
- case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
- // console.log('Already up to date with the latest remote version.');
- failed = true;
- break;
- case jsb.EventAssetsManager.UPDATE_FINISHED:
- // console.log('Update finished. ' + event.getMessage());
- needRestart = true;
- break;
- case jsb.EventAssetsManager.UPDATE_FAILED:
- // console.log('Update failed. ' + event.getMessage());
- break;
- case jsb.EventAssetsManager.ERROR_UPDATING:
- // console.log('Asset update error: ' + event.getAssetId() + ', ' + event.getMessage());
- break;
- case jsb.EventAssetsManager.ERROR_DECOMPRESS:
- // console.log("ERROR_DECOMPRESS:"+event.getMessage());
- break;
- default:
- break;
- }
- if (failed) {
- this._am.setEventCallback(null);
- this._updateListener = null;
- this._updating = false;
- this.EnterGame();
- }
- if (needRestart) {
- this._am.setEventCallback(null);
- this._updateListener = null;
- // Prepend the manifest's search path
- var searchPaths = jsb.fileUtils.getSearchPaths();
- var newPaths = this._am.getLocalManifest().getSearchPaths();
- // console.log(JSON.stringify(newPaths));
- for (var i = 0; i < newPaths.length; i++) {
- if (searchPaths.indexOf(newPaths[i]) == -1) {
- Array.prototype.unshift.apply(searchPaths, [newPaths[i]]);
- }
- }
- // This value will be retrieved and appended to the default search path during game startup,
- // please refer to samples/js-tests/main.js for detailed usage.
- // !!! Re-add the search paths in main.js is very important, otherwise, new scripts won't take effect.
- cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));
- jsb.fileUtils.setSearchPaths(searchPaths);
- cc.audioEngine.stopAll();
- cc.game.restart();
- }
- }
- public retry() {
- if (!this._updating && this._canRetry) {
- this._canRetry = false;
- // console.log('Retry failed Assets...');
- this._am.downloadFailedAssets();
- }
- }
- public checkUpdate() {
- if (this._updating) {
- // console.log('Checking or updating ...');
- return;
- }
- if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
- // Resolve md5 url
- var url = this.manifestUrl.nativeUrl;
- if (cc.loader.md5Pipe) {
- url = cc.loader.md5Pipe.transformURL(url);
- }
- this._am.loadLocalManifest(url);
- }
- if (!this._am.getLocalManifest() || !this._am.getLocalManifest().isLoaded()) {
- console.log('Failed to load local manifest ...');
- this.EnterGame();
- return;
- }
- this.getLocalVersion()
- this._am.setEventCallback(this.checkCb.bind(this));
- this._am.checkUpdate();
- this._updating = true;
- }
- public hotUpdate() {
- if (this._am && !this._updating) {
- this._am.setEventCallback(this.updateCb.bind(this));
- if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
- // Resolve md5 url
- var url = this.manifestUrl.nativeUrl;
- if (cc.loader.md5Pipe) {
- url = cc.loader.md5Pipe.transformURL(url);
- }
- this._am.loadLocalManifest(url);
- }
- this._failCount = 0;
- this._am.update();
- this._updating = true;
- }
- }
- // use this for initialization
- onLoad() {
- // Hot update is only available in Native build
- if (!cc.sys.isNative) {
- // this.EnterGame();
- return;
- }
- this._storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'blackjack-remote-asset');
- cc.log('Storage path for remote asset : ' + this._storagePath);
- // Setup your own version compare handler, versionA and B is versions in string
- // if the return value greater than 0, versionA is greater than B,
- // if the return value equals 0, versionA equals to B,
- // if the return value smaller than 0, versionA is smaller than B.
- this.versionCompareHandle = function (versionA, versionB) {
- cc.log("JS Custom Version Compare: version A is " + versionA + ', version B is ' + versionB);
- var vA = versionA.split('.');
- var vB = versionB.split('.');
- for (var i = 0; i < vA.length; ++i) {
- var a = parseInt(vA[i]);
- var b = parseInt(vB[i] || 0);
- if (a === b) {
- continue;
- }
- else {
- return a - b;
- }
- }
- if (vB.length > vA.length) {
- return -1;
- }
- else {
- return 0;
- }
- };
- // Init with empty manifest url for testing custom manifest
- this._am = new jsb.AssetsManager('', this._storagePath, this.versionCompareHandle);
- // Setup the verification callback, but we don't have md5 check function yet, so only print some message
- // Return true if the verification passed, otherwise return false
- this._am.setVerifyCallback(function (path, asset) {
- // When asset is compressed, we don't need to check its md5, because zip file have been deleted.
- var compressed = asset.compressed;
- // Retrieve the correct md5 value.
- var expectedMD5 = asset.md5;
- // asset.path is relative path and path is absolute.
- var relativePath = asset.path;
- // The size of asset file, but this value could be absent.
- var size = asset.size;
- if (compressed) {
- // console.log("Verification passed : " + relativePath);
- return true;
- }
- else {
- // console.log("Verification passed : " + relativePath + ' (' + expectedMD5 + ')');
- return true;
- }
- });
- // // console.log('Hot update is ready, please check or directly update.');
- if (cc.sys.os === cc.sys.OS_ANDROID) {
- // Some Android device may slow down the download process when concurrent tasks is too much.
- // The value may not be accurate, please do more test and find what's most suitable for your game.
- this._am.setMaxConcurrentTask(2);
- // console.log("Max concurrent tasks count have been limited to 2");
- }
- // cc.loader.loadRes('/project.manifest',(err,obj)=>{
- // if (!err) {
- // // let customManifestStr = JSON.stringify(obj);
- // let _nativeAsset = JSON.parse(obj._nativeAsset);
- // var customManifestStr = JSON.stringify({
- // 'packageUrl': _nativeAsset.packageUrl,
- // 'remoteManifestUrl': _nativeAsset.remoteManifestUrl,
- // 'remoteVersionUrl': _nativeAsset.remoteManifestUrl,
- // 'version': _nativeAsset.version,
- // 'assets': _nativeAsset.assert,
- // 'searchPaths': _nativeAsset.searchPaths
- // });
- // if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
- // var manifest = new jsb.Manifest(customManifestStr, this._storagePath);
- // this._am.loadLocalManifest(manifest, this._storagePath);
- // }
- // }
- // });
- //开始检测更新
- // this.checkUpdate();
- }
- public EnterGame() {
- // 游戏初始化
- this.getLocalVersion();
- this.scheduleOnce(() => {
- cc.director.loadScene("loading")
- }, 4)
- this._canEnterGame = true
- }
- //获取本地版本
- public getLocalVersion() {
- let localVersion = '';
- if (this._am && this._am.getLocalManifest() && !this._updating) {
- localVersion = this._am.getLocalManifest().getVersion();
- console.log("curVersion1:" + localVersion);
- import("Config" as any).then((cfgParam) => {
- let config = cfgParam.default
- config.appVersion = localVersion
- console.log("curVersion2:" + localVersion);
- })
- // console.log("curVersion:"+localVersion);
- }
- //return localVersion;
- }
- onDestroy() {
- if (this._updateListener) {
- this._am.setEventCallback(null);
- this._updateListener = null;
- }
- }
- };
|