-
Creator 版本:2.0.9
-
目标平台: Android / 模拟器 -->
-
详细报错信息,包含调用堆栈:
-
有所代码就下面那些,用插件生成相关东西,把project.manifest给manifestUrl。给服务器拷一份(res,src,project.manifest,version.manifest)
-
文件服务器网页可以正常访问
-
检查更新一直提示 code 2
提示信息:
Enable batch GL commands optimization!
src/cocos2d-jsb.js:7383 Cocos Creator v2.0.9
assets/scripts/updata.js:183 热更新部分
assets/scripts/updata.js:185 Storage path for remote asset : D:\CocosCreator\resources\cocos2d-x\simulator\win32\remote-asset
assets/scripts/updata.js:186 Local manifest URL : d:/Documents/NewProject_29/library/imports/8c/8cc9d7c8-8151-4f86-855c-a42d1b1fd130.manifest
assets/scripts/updata.js:190 搜索路径 (9) ["C:/Users/Administrator/AppData/Local/Simulator/debugruntime/", "D:\CocosCreator\resources\cocos2d-x\simulator\win32\/", "D:/CocosCreator/resources/cocos2d-x/simulator/", "D:/CocosCreator/resources/cocos2d-x/simulator/", "D:\CocosCreator\resources\cocos2d-x\simulator\win32\/", "D:/CocosCreator/resources/cocos2d-x/simulator/win32/", "D:/CocosCreator/resources/cocos2d-x/simulator/win32/", "D:/CocosCreator/resources/cocos2d-x/simulator/win32/", "D:\CocosCreator\resources\cocos2d-x\simulator\win32\/"]
assets/scripts/updata.js:25 Code: 2
assets/scripts/updata.js:36 Fail to download manifest file, hot update skipped.ERROR_PARSE_MANIFEST,下载manifest文件失败,跳过更新
代码:
插件
var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var manifest = {
packageUrl: 'http://192.168.100.100:80/',
remoteManifestUrl: 'http://192.168.100.100:80/project.manifest',
remoteVersionUrl: 'http://192.168.100.100:80/version.manifest',
version: '1.0.1',
assets: {},
searchPaths: []
};
var dest = 'assets/';
var src = 'build/jsb-default/';
// Parse arguments
var i = 2;
while ( i < process.argv.length) {
var arg = process.argv[i];
switch (arg) {
case '--url' :
case '-u' :
var url = process.argv[i+1];
manifest.packageUrl = url;
manifest.remoteManifestUrl = url + 'project.manifest';
manifest.remoteVersionUrl = url + 'version.manifest';
i += 2;
break;
case '--version' :
case '-v' :
manifest.version = process.argv[i+1];
i += 2;
break;
case '--src' :
case '-s' :
src = process.argv[i+1];
i += 2;
break;
case '--dest' :
case '-d' :
dest = process.argv[i+1];
i += 2;
break;
default :
i++;
break;
}
}
function readDir (dir, obj) {
var stat = fs.statSync(dir);
if (!stat.isDirectory()) {
return;
}
var subpaths = fs.readdirSync(dir), subpath, size, md5, compressed, relative;
for (var i = 0; i < subpaths.length; ++i) {
if (subpaths[i][0] === '.') {
continue;
}
subpath = path.join(dir, subpaths[i]);
stat = fs.statSync(subpath);
if (stat.isDirectory()) {
readDir(subpath, obj);
}
else if (stat.isFile()) {
// Size in Bytes
size = stat['size'];
md5 = crypto.createHash('md5').update(fs.readFileSync(subpath, 'binary')).digest('hex');
compressed = path.extname(subpath).toLowerCase() === '.zip';
relative = path.relative(src, subpath);
relative = relative.replace(/\\/g, '/');
relative = encodeURI(relative);
obj[relative] = {
'size' : size,
'md5' : md5
};
if (compressed) {
obj[relative].compressed = true;
}
}
}
}
var mkdirSync = function (path) {
try {
fs.mkdirSync(path);
} catch(e) {
if ( e.code != 'EEXIST' ) throw e;
}
}
// Iterate res and src folder
readDir(path.join(src, 'src'), manifest.assets);
readDir(path.join(src, 'res'), manifest.assets);
var destManifest = path.join(dest, 'project.manifest');
var destVersion = path.join(dest, 'version.manifest');
mkdirSync(dest);
fs.writeFile(destManifest, JSON.stringify(manifest), (err) => {
if (err) throw err;
console.log('Manifest successfully generated');
});
delete manifest.assets;
delete manifest.searchPaths;
fs.writeFile(destVersion, JSON.stringify(manifest), (err) => {
if (err) throw err;
console.log('Version successfully generated');
});
脚本
cc.Class({
extends: cc.Component,
properties: {
//这里指向生成的project.manifest文件
manifestUrl: {
type: cc.Asset,
default: null,
},
//这个没用的
str:{
type:cc.Label,
default:null,
}
},
// 检擦更新
checkCb: function (event) {
cc.log('Code: ' + event.getEventCode());
this.str.string = event.getEventCode()+"code";
switch (event.getEventCode())
{
//监听更新过程中的事件
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
cc.log ("No local manifest file found, hot update skipped.没有本地manifest文件,跳过更新");
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
cc.log ("Fail to download manifest file, hot update skipped.ERROR_DOWNLOAD_MANIFEST,下载manifest文件失败,跳过更新");
break;
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
cc.log ("Fail to download manifest file, hot update skipped.ERROR_PARSE_MANIFEST,下载manifest文件失败,跳过更新");
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
cc.log("Already up to date with the latest remote version.已经是最新版本,无需更新");
break;
case jsb.EventAssetsManager.NEW_VERSION_FOUND:
cc.log('New version found, please try to update.发现新版本准备更新');
this._needUpdate = true;
break;
default:
return;
}
this._am.setEventCallback(null); //注销监听
this.hotUpdate();
},
updateCb: function (event) {
var needRestart = false;
var failed = false;
this.str.string = event.getEventCode()+"updateCb";
switch (event.getEventCode())
{
case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
cc.log('No local manifest file found, hot update skipped.');
failed = true;
break;
case jsb.EventAssetsManager.UPDATE_PROGRESSION:
//this.tip.getComponent(cc.Label).string = "正在更新";
cc.log( event.getDownloadedFiles() + ' / ' + event.getTotalFiles());
cc.log( event.getDownloadedBytes() + ' / ' + event.getTotalBytes());
var percent = event.getPercent();
var percentByFile = event.getPercentByFile();
//this.file.getComponent(cc.Label).string = "下载文件数: " + event.getDownloadedFiles() + ' / ' + event.getTotalFiles();
var msg = event.getMessage();
if (msg) {
cc.log(msg);
}
//this.progress.getComponent(cc.Label).string = "文件进度:" + percent.toFixed(2) * 100 + "%"
cc.log(percent.toFixed(2)* 100 + '%');
break;
case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
cc.log('Fail to download manifest file, hot update skipped.');
//this.tip.getComponent(cc.Label).string = "下载失败";
failed = true;
break;
case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
cc.log('Already up to date with the latest remote version.');
//this.tip.getComponent(cc.Label).string = "已经是最新版本";
failed = true;
break;
case jsb.EventAssetsManager.UPDATE_FINISHED:
cc.log('Update finished. ' + event.getMessage());
//this.tip.getComponent(cc.Label).string = "更新完成:正在重启游戏";
needRestart = true;
break;
case jsb.EventAssetsManager.UPDATE_FAILED:
cc.log('Update failed. ' + event.getMessage());
this._failCount ++;
if (this._failCount < 5)
{
this._am.downloadFailedAssets();
}
else
{
cc.log('Reach maximum fail count, exit update process');
this._failCount = 0;
failed = true;
}
break;
case jsb.EventAssetsManager.ERROR_UPDATING:
cc.log('Asset update error: ' + event.getAssetId() + ', ' + event.getMessage());
break;
case jsb.EventAssetsManager.ERROR_DECOMPRESS:
cc.log(event.getMessage());
break;
default:
break;
}
if (failed) {
//cc.eventManager.removeListener(this._updateListener);
this._am.setEventCallback(null);
}
if (needRestart) { //重新启动游戏
//cc.eventManager.removeListener(this._updateListener);
this._am.setEventCallback(null);
// Prepend the manifest's search path
var searchPaths = jsb.fileUtils.getSearchPaths();
var newPaths = this._am.getLocalManifest().getSearchPaths();
Array.prototype.unshift(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));
console.log("测试===getPath",searchPaths);
jsb.fileUtils.setSearchPaths(searchPaths);
cc.game.restart();
}
},
hotUpdate: function () {
if (this._am && this._needUpdate) {
this._updateListener = new jsb.EventListenerAssetsManager(this._am, this.updateCb.bind(this));
//cc.eventManager.addListener(this._updateListener, 1);
this._am.setEventCallback(this._updateListener, 1);
this._failCount = 0;
this._am.update();
}
},
//初始AssetsManager
onLoad: function () {
if (!cc.sys.isNative) {
return;
}
console.log("热更新部分");
var storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'remote-asset');
cc.log('Storage path for remote asset : ' + storagePath);
cc.log('Local manifest URL : ' + this.manifestUrl);
this._am = new jsb.AssetsManager(this.manifestUrl, storagePath);
var searchPaths = jsb.fileUtils.getSearchPaths();
cc.log("搜索路径",searchPaths);
//this._am.retain();
this._needUpdate = false;
if (this._am.getLocalManifest().isLoaded())
{
this._checkListener = new jsb.EventListenerAssetsManager(this._am, this.checkCb.bind(this));
//cc.eventManager.addListener(this._checkListener, 1);
this._am.setEventCallback(this._checkListener, 1);
this._am.checkUpdate();
}
},
onDestroy: function () {
this._am && this._am.release();
}
});