add hotfix
This commit is contained in:
parent
ff550d5d6a
commit
b7504ff7be
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,7 +7,6 @@ temp/
|
||||
local/
|
||||
build/
|
||||
android/
|
||||
hotupdate/
|
||||
keystore/
|
||||
node_modules/
|
||||
|
||||
|
373
assets/scripts/hotUpdate/HotUpdate.ts
Normal file
373
assets/scripts/hotUpdate/HotUpdate.ts
Normal file
@ -0,0 +1,373 @@
|
||||
import { isTest } from '../Config';
|
||||
import { GIFCache } from '../gif/GIF';
|
||||
import { getSwitch } from '../jcfw/service/jclogin';
|
||||
|
||||
const { ccclass, property } = cc._decorator;
|
||||
|
||||
const UpdateMsg = [
|
||||
'No use hot update!',
|
||||
'No local manifest file found, hot update skipped.',
|
||||
'Fail to download manifest file, hot update skipped.',
|
||||
'Fail to parse manifest file, hot update skipped.',
|
||||
'Asset update error.',
|
||||
'Compression package decoding failed.',
|
||||
'Already up to date with the latest remote version.',
|
||||
'New version found, please try to update.',
|
||||
'Update finished.',
|
||||
'Update failed.',
|
||||
];
|
||||
|
||||
enum State {
|
||||
NONE,
|
||||
ERROR_NO_LOCAL_MANIFEST,
|
||||
ERROR_DOWNLOAD_MANIFEST,
|
||||
ERROR_PARSE_MANIFEST,
|
||||
ERROR_UPDATING,
|
||||
ERROR_DECOMPRESS,
|
||||
ALREADY_UP_TO_DATE,
|
||||
NEW_VERSION_FOUND,
|
||||
UPDATE_FINISHED,
|
||||
UPDATE_FAILED,
|
||||
UPDATE_PROGRESSION,
|
||||
}
|
||||
|
||||
@ccclass
|
||||
export default class HotUpdate extends cc.Component {
|
||||
static State = State;
|
||||
|
||||
@property(cc.Node) loginNode: cc.Node = null;
|
||||
|
||||
@property({
|
||||
type: cc.Asset,
|
||||
tooltip: '当前版本资源记录的manifest文件',
|
||||
})
|
||||
manifestUrl: cc.Asset = null;
|
||||
|
||||
@property(cc.ProgressBar) bar: cc.ProgressBar = null;
|
||||
|
||||
@property(cc.Label) log: cc.Label = null;
|
||||
|
||||
@property(cc.Label) currentProcess: cc.Label = null; //当前进度
|
||||
|
||||
// @property(cc.Node) uiloading: cc.Node = null; // loading小人
|
||||
|
||||
state = State.NONE;
|
||||
|
||||
private _updating = false;
|
||||
private _canRetry = false;
|
||||
|
||||
private _am = null;
|
||||
|
||||
private _failCount = 0;
|
||||
private _totalFilesCount = 0;
|
||||
private _totalBytesCount = 0;
|
||||
|
||||
// use this for initialization
|
||||
init() {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Hot update is only available in Native build
|
||||
if (!cc.sys.isNative) {
|
||||
return;
|
||||
}
|
||||
let storagePath =
|
||||
(jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') +
|
||||
'blackjack-remote-asset';
|
||||
console.log('Storage path for remote asset : ' + 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.
|
||||
let versionCompareHandle = (versionA, versionB) => {
|
||||
console.log(
|
||||
'JS Custom Version Compare: version A is ' +
|
||||
versionA +
|
||||
', version B is ' +
|
||||
versionB
|
||||
);
|
||||
let vA = versionA.split('.');
|
||||
let vB = versionB.split('.');
|
||||
for (let i = 0; i < vA.length; ++i) {
|
||||
let a = parseInt(vA[i]);
|
||||
let 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(
|
||||
'',
|
||||
storagePath,
|
||||
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.
|
||||
let compressed = asset.compressed;
|
||||
// Retrieve the correct md5 value.
|
||||
let expectedMD5 = asset.md5;
|
||||
// asset.path is relative path and path is absolute.
|
||||
let relativePath = asset.path;
|
||||
// The size of asset file, but this value could be absent.
|
||||
let size = asset.size;
|
||||
if (compressed) {
|
||||
console.log('Verification passed : ' + relativePath);
|
||||
return true;
|
||||
} else {
|
||||
console.log(
|
||||
'Verification passed : ' +
|
||||
relativePath +
|
||||
' (' +
|
||||
expectedMD5 +
|
||||
')'
|
||||
);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// '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.
|
||||
// Max concurrent tasks count have been limited to 2
|
||||
this._am.setMaxConcurrentTask(2);
|
||||
}
|
||||
// this.checkUpdate();
|
||||
resolve(true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测线上与服务器的资源版本
|
||||
*/
|
||||
async checkUpdate() {
|
||||
this.log.string = 'checking...';
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!cc.sys.isNative) {
|
||||
return;
|
||||
}
|
||||
if (this._updating) {
|
||||
return;
|
||||
}
|
||||
if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
|
||||
// Resolve md5 url
|
||||
let 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()
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this._am.setEventCallback(this.checkUpdateCallback.bind(this));
|
||||
|
||||
this._am.checkUpdate();
|
||||
this._updating = true;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 将服务器资源更新到本地
|
||||
*/
|
||||
hotUpdate() {
|
||||
// this.uiloading.active = true;
|
||||
this.log.string = 'updating...';
|
||||
if (!cc.sys.isNative) {
|
||||
return;
|
||||
}
|
||||
if (this._am && !this._updating) {
|
||||
this._am.setEventCallback(this.hotUpdateCallback.bind(this));
|
||||
|
||||
if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
|
||||
// Resolve md5 url
|
||||
let 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新下载失败资源
|
||||
*/
|
||||
retry() {
|
||||
if (!cc.sys.isNative) {
|
||||
return;
|
||||
}
|
||||
if (!this._updating && this._canRetry) {
|
||||
this._canRetry = false;
|
||||
// 'Retry failed Assets...';
|
||||
this._am.downloadFailedAssets();
|
||||
}
|
||||
}
|
||||
|
||||
private checkUpdateCallback(event) {
|
||||
let logMsg = '';
|
||||
switch (event.getEventCode()) {
|
||||
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
|
||||
this.state = State.ERROR_NO_LOCAL_MANIFEST;
|
||||
break;
|
||||
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
|
||||
this.state = State.ERROR_DOWNLOAD_MANIFEST;
|
||||
break;
|
||||
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
|
||||
this.state = State.ERROR_PARSE_MANIFEST;
|
||||
break;
|
||||
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
|
||||
this.state = State.ALREADY_UP_TO_DATE;
|
||||
this.loginNode.active = true;
|
||||
this.node.destroy();
|
||||
// 进去游戏
|
||||
break;
|
||||
case jsb.EventAssetsManager.NEW_VERSION_FOUND:
|
||||
this.state = State.NEW_VERSION_FOUND;
|
||||
// update
|
||||
this.scheduleOnce(() => {
|
||||
this.hotUpdate();
|
||||
}, 1);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
this._am.setEventCallback(null);
|
||||
this._updating = false;
|
||||
|
||||
logMsg = UpdateMsg[this.state];
|
||||
}
|
||||
|
||||
private hotUpdateCallback(event) {
|
||||
let needRestart = false;
|
||||
let failed = false;
|
||||
|
||||
switch (event.getEventCode()) {
|
||||
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
|
||||
this.state = State.ERROR_NO_LOCAL_MANIFEST;
|
||||
failed = true;
|
||||
break;
|
||||
case jsb.EventAssetsManager.UPDATE_PROGRESSION:
|
||||
this.state = State.UPDATE_PROGRESSION;
|
||||
|
||||
this._totalFilesCount = event.getTotalFiles();
|
||||
this._totalBytesCount = event.getTotalBytes();
|
||||
|
||||
this.bar.progress = event.getPercent();
|
||||
|
||||
// 显示进度 33%
|
||||
this.currentProcess.string = `${Math.round(
|
||||
event.getPercent() * 100
|
||||
).toString()}%`;
|
||||
//
|
||||
break;
|
||||
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
|
||||
this.state = State.ERROR_DOWNLOAD_MANIFEST;
|
||||
break;
|
||||
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
|
||||
this.state = State.ERROR_PARSE_MANIFEST;
|
||||
failed = true;
|
||||
break;
|
||||
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
|
||||
this.state = State.ALREADY_UP_TO_DATE;
|
||||
failed = true;
|
||||
break;
|
||||
case jsb.EventAssetsManager.UPDATE_FINISHED:
|
||||
this.state = State.UPDATE_FINISHED;
|
||||
|
||||
needRestart = true;
|
||||
break;
|
||||
case jsb.EventAssetsManager.UPDATE_FAILED:
|
||||
this.state = State.UPDATE_FAILED;
|
||||
this._updating = false;
|
||||
this._canRetry = true;
|
||||
break;
|
||||
case jsb.EventAssetsManager.ERROR_UPDATING:
|
||||
this.state = State.ERROR_UPDATING;
|
||||
|
||||
this._failCount++;
|
||||
break;
|
||||
case jsb.EventAssetsManager.ERROR_DECOMPRESS:
|
||||
this.state = State.ERROR_DECOMPRESS;
|
||||
// logMsg = event.getMessage();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
this._am.setEventCallback(null);
|
||||
this._updating = false;
|
||||
}
|
||||
|
||||
if (needRestart) {
|
||||
this._am.setEventCallback(null);
|
||||
|
||||
// Prepend the manifest's search path
|
||||
let searchPaths = jsb.fileUtils.getSearchPaths();
|
||||
let newPaths = this._am.getLocalManifest().getSearchPaths();
|
||||
|
||||
console.log('new search path:', JSON.stringify(newPaths));
|
||||
|
||||
Array.prototype.unshift.apply(searchPaths, newPaths);
|
||||
// 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);
|
||||
|
||||
// 更新完成 重新开始游戏
|
||||
// this.uiloading.active = false;
|
||||
console.log('hotupdate done!');
|
||||
this.log.string = 'finish';
|
||||
// this.scheduleOnce(() => {
|
||||
// cc.game.restart();
|
||||
// }, 1);
|
||||
setTimeout(() => {
|
||||
cc.game.restart();
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
protected onLoad(): void {
|
||||
// GIFCache.getInstance();
|
||||
// 原生且不在审核
|
||||
getSwitch(() => {
|
||||
if (cc.sys.isNative && !isTest) {
|
||||
this.init().then(async () => {
|
||||
await this.checkUpdate();
|
||||
});
|
||||
} else {
|
||||
this.loginNode.active = true;
|
||||
this.node.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
if (cc.sys.isNative && this._am) {
|
||||
this._am.setEventCallback(null);
|
||||
}
|
||||
}
|
||||
}
|
9
assets/scripts/hotUpdate/HotUpdate.ts.meta
Normal file
9
assets/scripts/hotUpdate/HotUpdate.ts.meta
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.0.5",
|
||||
"uuid": "6f84f1f8-b5d9-456d-9f11-d0cd76b15f21",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
1
hotupdate/project.manifest
Normal file
1
hotupdate/project.manifest
Normal file
File diff suppressed because one or more lines are too long
1
hotupdate/version.manifest
Normal file
1
hotupdate/version.manifest
Normal file
@ -0,0 +1 @@
|
||||
{"packageUrl":"https://test.kingsome.cn/game2006/test/slim/","remoteManifestUrl":"https://test.kingsome.cn/game2006/test/slim/project.manifest","remoteVersionUrl":"https://test.kingsome.cn/game2006/test/slim/version.manifest","version":"0.1.0"}
|
Loading…
x
Reference in New Issue
Block a user