COCOS2DX Lua hot update

Before I contacted the hot update, I was confused about the hot update. Later, I read some materials, tried it myself, and basically understood its process.
The so-called hot update is to update code and resources online.

The process of hot update

First, the client sends a request to the server, and the server tells the client that there is no update, and you are the latest, so just skip it. But if you are telling you that there is an update, then tell me what needs to be updated, right, you may need to update things, put them in a file, and send them to the client. The client will get this file and go one by one. The server wants, and finally downloads all the content to be updated to the local. But if the downloaded resource already exists before, will there be a problem?
Let’s take the win32 platform as an example


luagame4.png

This is the project directory

For the download directory, a Normally

C:\Users\user\AppData< span class="hljs-symbol" style="color:rgb(203,75,22)">\Local\LuaGame4

But there is another problem. Usually we call resources directly under the project directory. This will be downloaded to the c drive. How can you call it?
This involves a priority issue. For example, the path of an image is img/sample.png. In the project The full path under the directory is
E/LuaGame4/res/img/sample.png, then we usually call this in the code

local sp = cc.Sprite:create("img/sample.png")self:addChild( sp )

Going back to the previous question, now I’m going to update this picture, the above is downloading

C:\Users\user\AppData\ Local\LuaGame4

In this directory, we need to use the same The code can be adjusted To use new resources, as long as the resource path in this directory is consistent with our project, then set C:\Users\user\AppData\Local\LuaGame4 Join Search the path, and set its priority to the highest, then it can be called.

Specific implementation

know its rough The working process will be very clear after actual operation.
In cocos2dx, the class AssetsManagerEx is used. For AssetsManager this class is not recommended. There are many things in this class that we haven’t considered, so we won’t go into it.
Code first

local writablePath = cc.FileUtils:getInstance():getWritablePath() local storagePath = writablePath .. "new_version"--Set the src and res of the download directory as the search directory with the highest priority, so as to ensure that the downloaded file can cover the original code cc.FileUtils:getInstance():addSearchPath(storagePath..< span class="hljs-string" style="color:rgb(42,161,152)">"/src/",true) cc.FileUtils:getInstance():addSearchPath(storagePath.."/res/", true) - Create AssetsManagerEx object local as setsManagerEx = cc.AssetsManagerEx:create("src/version/project.manifest", storagePath) assetsManagerEx:retain()- -Set the download message listener local function handleAssetsManagerEx(event) if (cc.EventAssetsManagerEx.EventCode.ALREADY_UP_TO_DATE == event: getEventCode()) then print("is the latest version, enter the main interface of the game") - app:enterScene( "GameScene") end if (cc.EventAssetsManagerEx.EventCode.NEW_VERSION_FOUND == event:getEventCode()) then print("found a new version, Start upgrading") end if (cc.EventAssetsManagerEx.EventCode.UPDATE_PROGR ESSION == event:getEventCode()) then print("Update progress=" .. event:getPercent()) end if (cc.EventAssetsManagerEx.EventCode.UPDATE_FINISHED == event:getEventCode()) then print("Update complete, restart") app:run() end if (cc.EventAssetsManagerEx.EventCode.ERROR_NO_LOCAL_MANIFEST == event:getEventCode()) then print( "An error occurred: The manifest file cannot be found locally") end if (cc.EventAssetsManagerEx.EventCode .ERROR_DOWNLOAD_MANIFEST == event:getEventCode()) then print("An error occurred: Failed to download the manifest file") end if (cc.EventAssetsManagerEx.EventCode.ERROR_PARSE_MANIFEST == event:getEventCode()) then print("An error occurred: Failed to parse the manifest file") end if (cc.EventAssetsManagerEx.EventCode.ERROR_UPDATING == event:getEventCode()) then print("An error occurred: Update failed") end end local dispatcher = cc.Director:getInstance():getEventDispatcher() local eventListenerAssetsManagerEx = cc.EventListenerAssetsManagerEx:create(assetsManagerEx, handleAssetsManagerEx) dispatcher:addEventListenerWithFixedPriority(eventListenerAssetsManagerEx, 1) - check the version and Upgrade assetsManagerEx:update()

follow first

-- Create AssetsManagerEx objects local assetsManagerEx = cc. AssetsManagerEx:create("src /version/project.manifest", storagePath)

To start looking, first build a AssetsManagerEx:create object, which needs to be passed in two Parameters

  • project.manifest path< /li>
  • download path

The project.manifest path I passed in here is src/version/project.manifest

< br style="">

manifest.png

What kind of file is this, open it and see

{ "packageUrl": "http:// localhost:8080/examples/servlets/update/assets/", "remoteManifestUrl": "http://localhost:8080/examples/servlets/update/version/project.manifest", "remoteVersionUrl": "http://localhost:8080/examples/servlets/update/version/ /version.manifest", "version": "1.0.0", "engineVersion": "3.x dev", "assets": {"res/blocks.png": {"md5": "...."} }, "searchPaths": []}

< p style="margin-top:0px; margin-bottom:25px; word-break:break-word; col or:rgb(47,47,47); font-size:16px; line-height:27.2px"> This is a json format file, explain the meaning of each key

< /table>

Take a look at what version.manifest wrote

{ "packageUrl": "http://localhost:8080/examples/servlets/update/assets/",  "remoteManifestUrl": "http://localhost:8080/examples/servlets/update/version/project.manifest"< /span>, "remoteVersionUrl": "http:/ /localhost:8080/examples/servlets/update/version//version.manifest", "version": "1.0.2", "engineVersion": "3.x dev",}

Fuck, this is not a simplification of project.manifest Version?
Damn, how do you know!
Since it is a simplified version, why bother to get two files instead of using the more detailed project.manifest?

This is for the purpose of updating traffic. We will put a project.manifest manifest file about the entire project resource in the project directory. When updating, AssetsManagerEx will get the remoteVersionUrl, and first set the version.manifest and compare version to determine whether to update. If you want to update, download it again. The detailed project.manifest file, the advantage of this is that when your project is relatively large, the corresponding project.manifest will also be larger. If you download project.manifest every time, it will cause unnecessary concessions NS.

After creating the AssetsManagerEx object, it is necessary to register a monitoring event for it, so that we can grasp the update status, such as progress, such as whether there is an error, etc. For the corresponding event, it has been written very clearly in the code, so I won’t talk about it here.

Then call assetsManagerEx:update() to start the update.

Finished.
Huh? Finished?
Ah, it’s over
Your sister

Okay, I know you are still a little bit dazed. What about this TM my server? What am I going to get here. . Don’t worry, look down

Documents that need to be prepared

  • client
    For the client, it’s a copy The project.manifest file, which records the md5 of the first-level code of all resources, is convenient for comparison during the first update, and once it has been updated once , I won’t use this file in the future. Instead, use the project.manifest in the download directory. Otherwise, update it or update it in vain
  • Server
    On the server, three things are neededproject.manifest , version.manifest, and update package.

Make a simple tomcat

The http protocol used for hot update, and writing an http backend, the easier way is to build a tomcat, friends who don’t know how to build it, it’s not difficult, if you have a bit of java, you can know how to read two articles Used


tomcat.png

This is the directory of my tomcat, I created a update folder, there are two sub-folders below

  • version

version.png

  • assets

assets.png

The article puts a resource pathres/blocks.png, his url is packageUrl and res/blocks.png for splicing, that is, http://localhost:8080/examples/servlets/update/assets/res/blocks.png.

It feels a little bit after putting it like this? The directory on the server is exactly the same as your project directory. In this case, as long as the download directory is added to the search path, the same relative path can be found in the download directory.


luagame4.png

luagame4.png


manifest.png

manifest.png


tomcat.png

tomcat.png


version.png

version.png


assets.png

assets.png

Leave a Comment

Your email address will not be published.

key Role
packageUrl Update the url of the package
remoteManifestUrl project.manifest url
remoteVersionUrl this file and project.manifest A meaning, but more concise than project.manifest, I will say later
version version, whether it needs to be updated is up to him
engineVersion Engine version, it doesn’t matter whether it is written or not
assets All file names and their md5 values ​​will be compared with the local and remote md5 values ​​when they are updated. If they are inconsistent, they will be updated, otherwise they will not be updated.