cocoscreator hot update

The first is the official document

http://docs.cocos.com/creator/manual/zh/advanced-topics/hot-update.html
http://docs.cocos.com/creator/manual/zh/advanced-topics/assets-manager.html

Hot update of principle

There is a client project.manifest file that contains several information:

  • PACKAGEURL : URL, the server root directory update packet;
  • remoteManifestUrl : url, [Options] on the server project.manifest url files,
  • remoteVersionUrl : url, the server version.mainifest url file;
  • Version : xxx, project version;
  • Assets : {}, resource list;
    Key : relative path resources (resources with respect to root)
    MD5 : MD5 value represents version information resource file
    Compressed : [Optional] If true, then the file is downloaded automatically decompressed currently only supports zip compression format
    size : [options] byte size files for quick access to schedule information
  • SearchPaths : "", the search path

The client through the local project.manifest in the url, you can get the server project.manifest , both file comparisons version attribute, if the client version is lower than the server, start the update.
Updated content: assets is a file list, which lists the full resource projects, each resource has md5 said, according to the local client project.manifest the assets list and server assets list comparing different resources to download temporary folder, and finally if all resources are normal, put the contents of the temporary folder to replace the local cache folder, and modify the first search path for the folder. Therefore, the use of resources to restart the game after the first search from the cache folder.

Needs of the environment

  • nodejs
  • cocoscreator

Official Case

  • Download the official example , extract. The case has put the client and the server's resources are packaged well, the update packages in remote-assets folder.

     
    image.png

     

  • Server - I am using nodejs.

1. Create a new folder nodejs, New hotUpdate folder nodejs, the official copy remote-assets case to hotUpdate folder.


 
image.png

2. Create a new nodejs js script, the script reads as follows

var express = require('express');
var path = require('path'); var app = express(); app.use(express.static(path.join(__dirname, 'hotUpdate'))); app.listen(80); 

3. Run nodejs folder node app.js command to start the server, you can access http://127.0.0.1/remote-assets/project.manifest , if successfully access the server started successfully.

 
image.png

 

Next, modify the manifest file inside the url, there are three files need to be modified, two suffixes manifest file server remote-assets in the official project assets folder project.manifest

 
image.png

 
image.png

Modify only three url
 
image.png

After modifications are complete, open the project to see results with the simulator run.
Click the Check for Updates button
 
image.png

Click the Update Now button
 
image.png

 

For some reason, the emulator update is complete, restart the update can not use the resources, so needs to be compiled into native, my computer can not compile windows, not on the map. Apk packaged into a self-test can be updated successfully.

Scratch

  • Create a new version
    of the project has two scenes, as is the new version, resources stored on the server. To delete a scene as the older version, compiled and installed on the phone. The goal is to use the old version of the hot update to the new version, and successfully switch scenes.
    Create a new project, two new scenes, helloworld test scenario is more hot-line success of the scene (the old version does not exist helloworld, you can jump to the scene by updating). hotUpdate scenario, the scenario add two progress bar, and the number of bytes corresponding to two kinds of files progress, three label, and corresponding to two kinds of progress prompt information, three buttons, namely, check for updates, the update, handover scenario.

     
    image.png

     

  • Script --copy official example of
    a new hotUpdate script, added on Canvas. Five additional script variables, dragging up the scene in the corresponding node. Increased three callback method, to bind him on the button.

     
    image.png

     

    cc.Class({
    extends: cc.Component,

    properties: {
        byteLabel: cc.Label,
        fileLabel: cc.Label,
        byteProgress: cc.ProgressBar, fileProgress: cc.ProgressBar, label: cc.Label, manifestUrl: cc.RawAsset, }, onLoad() { var self = this; this._storagePath = jsb.fileUtils.getWritablePath(); this._am = new jsb.AssetsManager('', this._storagePath, this.versionCompareHandle); if (!cc.sys.ENABLE_GC_FOR_NATIVE_OBJECTS) { this._am.retain(); } this._am.setVerifyCallback(function (path, asset) { var compressed = asset.compressed; var expectedMD5 = asset.md5; var relativePath = asset.path; var size = asset.size; if (compressed) { self .label.string = "Verification passed : " + relativePath; return true; } else { self .label.string = "Verification passed : " + relativePath + ' (' + expectedMD5 + ')'; return true; } }); this.byteProgress.progress = 0; this.fileProgress.progress = 0; }, hotUpdate() { if (this._am && !this._updating) { this._updateListener = new jsb.EventListenerAssetsManager(this._am, this.updateCb.bind(this)); cc.eventManager.addListener(this._updateListener, 1); if (this._am.getState() === jsb.AssetsManager.State.UNINITED) { this._am.loadLocalManifest(this.manifestUrl); } this._am.update(); this._updating = true; } }, checkUpdata() { if (this._updating) { this.label.string = 'Checking or updating ...'; return; } if (this._am.getState() === jsb.AssetsManager.State.UNINITED) { this._am.loadLocalManifest(this.manifestUrl); } if (!this._am.getLocalManifest() || !this._am.getLocalManifest().isLoaded()) { this.label.string = 'Failed to load local manifest ...'; return; } this._checkListener = new jsb.EventListenerAssetsManager(this._am, this.checkCb.bind(this)); cc.eventManager.addListener(this._checkListener, 1); this._am.checkUpdate(); this._updating = true; }, changeScene() { cc.director.loadScene('helloworld'); }, checkCb: function (event) { switch (event.getEventCode()) { case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST: this.label.string = "No local manifest file found, hot update skipped."; break; case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST: case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST: this.label.string = "Fail to download manifest file, hot update skipped."; break; case jsb.EventAssetsManager.ALREADY_UP_TO_DATE: this.label.string = "Already up to date with the latest remote version."; break; case jsb.EventAssetsManager.NEW_VERSION_FOUND: this.label.string = 'New version found, please try to update.'; this.fileProgress.progress = 0; this.byteProgress.progress = 0; break; default: return; } cc.eventManager.removeListener(this._checkListener); this._checkListener = null; this._updating = false; }, updateCb: function (event) { var needRestart = false; var failed = false; switch (event.getEventCode()) { case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST: this.label.string = 'No local manifest file found, hot update skipped.'; failed = true; break; case jsb.EventAssetsManager.UPDATE_PROGRESSION: this.byteProgress.progress = event.getPercent(); this.fileProgress.progress = event.getPercentByFile(); this.fileLabel.string = event.getDownloadedFiles() + ' / ' + event.getTotalFiles(); this.byteLabel.string = event.getDownloadedBytes() + ' / ' + event.getTotalBytes(); var msg = event.getMessage(); if (msg) { this.label.string = 'Updated file: ' + msg; } break; case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST: case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST: this.label.string = 'Fail to download manifest file, hot update skipped.'; failed = true; break; case jsb.EventAssetsManager.ALREADY_UP_TO_DATE: this.label.string = 'Already up to date with the latest remote version.'; failed = true; break; case jsb.EventAssetsManager.UPDATE_FINISHED: this.label.string = 'Update finished. ' + event.getMessage(); needRestart = true; break; case jsb.EventAssetsManager.UPDATE_FAILED: this.label.string = 'Update failed. ' + event.getMessage(); this._updating = false; this._canRetry = true; break; case jsb.EventAssetsManager.ERROR_UPDATING: this.label.string = 'Asset update error: ' + event.getAssetId() + ', ' + event.getMessage(); break; case jsb.EventAssetsManager.ERROR_DECOMPRESS: this.label.string = event.getMessage(); break; default: break; } if (failed) { cc.eventManager.removeListener(this._updateListener); this._updateListener = null; this._updating = false; } if (needRestart) { cc.eventManager.removeListener(this._updateListener); this._updateListener = null; var searchPaths = jsb.fileUtils.getSearchPaths(); var newPaths = this._am.getLocalManifest().getSearchPaths(); Array.prototype.unshift(searchPaths, newPaths); cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths)); jsb.fileUtils.setSearchPaths(searchPaths); cc.game.restart(); } }, }); 
  • 打包资源
    首先构建原生
     
    image.png

    构建完成在项目中会生成原生项目,热更新需要的资源是res,src两个文件夹以及里面的内容。
    把nodejs--hotUpdate--remote-assets文件夹下所有东西都删除,把res,src复制到nodejs--hotUpdate--remote-assets文件夹下。
     
    image.png

构建完原生项目,打开官方项目文件夹,拷贝出 version_generator.js 文件到helloworld项目的根目录(如下图),并在helloworld根目录打开命令窗口,执行命令,node version_generator.js -v 1.7.0 -u http://127.0.0.1/remote-assets/ -s build/jsb-default/ -d assets/

 
image.png

在assets文件夹下会多出两个文件,把他们复制到nodejs--hotUpdate--remote-assets文件夹下。


 
image.png

最终远程资源如图


 
image.png

在nodejs文件夹下执行node app.js命令,启动服务器,可以访问http://127.0.0.1/remote-assets/project.manifest,如果成功访问则服务器启动成功。

  • 制作旧版本

删除helloworld场景,脚本,texture文件夹,以及之前生成的manifest文件。保存之后构建项目,构建选项不要变动

 
image.png

Helloworld open the root directory of the command window, execute the command, the Node version_generator.js -u -v 1.0.0 http://127.0.0.1/remote-assets/ -s Build / JSB-default / -d Assets / attention here - v 1.0.0, 1.7.0 before is the old version number is less than the new version

 

Two manifest files generated in assets. Project.manifest onto the above property inspector.


 
image.png

Rebuild the native platform, main.js add the following code, and then compile

if (cc.sys.isNative) {
   var hotUpdateSearchPaths = cc.sys.localStorage.getItem('HotUpdateSearchPaths');
    if (hotUpdateSearchPaths) {
         jsb.fileUtils.setSearchPaths(JSON.parse(hotUpdateSearchPaths)); } } 
 
image.png

Now we completed the old version of the production. This is my performance on Android phones.


 
image.png

 
image.png


Author: Ott rain
link: https: //www.jianshu.com/p/cec263b6b9ac
Source: Jane book
Jane book copyright reserved by the authors, are reproduced in any form, please contact the author to obtain authorization and indicate the source.

Guess you like

Origin www.cnblogs.com/suneil/p/11267647.html