2018.02.24 七米游戏 更新实现

cocos2dx lua 游戏热更

cocos2dx 提供了相应的示例 可参考 lua-tests 中的 AssetsManagerExTest.lua 

实现详解:

1. 客户端,配置相应的 project.manifest 文件,首次更新时会检测该文件,工程目录如下

2018.02.24 七米游戏 更新实现_第1张图片

    project.mainfest 内容如下:

{
	"packageUrl" : "http://192.168.1.8:8080/Download/Package/",
	"remoteManifestUrl" : "http://192.168.1.8:8080/Download/version/project.manifest",
	"remoteVersionUrl" : "http://192.168.1.8:8080/Download/version/version.manifest",
	"version" : "1.0.0",
	"engineVersion" : "3.0 beta",

	"assets" : {
		"Images/background1.jpg" : {
			"md5" : "..."
		}
	},
    
    "searchPaths" : [
    ]
}

2. 服务端, 服务端新建两个文件夹 version, Package

    version 用于存放更新检测配置文件 project.manifestversion.manifest 

    Package 用于存放更新下载文件 如 png 资源图,lua 文件等

    project.manifest 内容如下

{
    "packageUrl" : "http://192.168.1.8:8080/Download/Package/",
    "remoteManifestUrl" : "http://192.168.1.8:8080/Download/version/project.manifest",
    "remoteVersionUrl" : "http://192.168.1.8:8080/Download/version/version.manifest",
    "version" : "1.0.2",

    "assets" : {
        "blocks.png" : {
            "md5" : "....."
        },
        "abc.zip" : {
            "md5" : ".....",
            "compressed" : true
        },
        "ttt.png" : {
            "md5" : "....."
        }
    },

    "searchPaths" : [
    ]
}

    服务器 Download/Package 文件夹下存放 blocks.png, abc.zip 等文件  

    注:compressed  参数 true 表示下载完后直接对 zip 进行解压

    version.manifest 内容如下

{
    "packageUrl" : "http://192.168.1.8:8080/Download/Package/",
    "remoteManifestUrl" : "http://192.168.1.8:8080/Download/version/project.manifest",
    "remoteVersionUrl" : "http://192.168.1.8:8080/Download/version/version.manifest",
    "version" : "1.0.2",
}

说明:.manifest 文件中的内容说明

key 作用
packageUrl 更新包的url,更新时会从这个url 对应的地址下载更新文件
remoteManifestUrl project.manifest的url,更新时会根据这个文件进行检测要更新哪些文件
remoteVersionUrl 这个文件和project.manifest一个意思,但是比project.manifest更简洁,
version 游戏版本,本地版本号小与服务器版本号则进行更新
engineVersion 引擎版本,写不写无所谓
assets 所有的文件名和他的md5值,在更新的时候会比对本地和远程的md5值,不一致则会更新,否则不更新

    更新时会先从本地加载 project.manifest 文件,从中读取到 remoteManifestUrl 及 remoteVersionUrl 后,从对应的 url 下载 project.manifest 与 version.manifest 文件, 如果 本地 project.manifest 中的 版本号小于服务器的版本号,则进行更新

3. 客户端实现代码

function UILoading:updateCheck(layer)
    local ttfConfig = {}
    ttfConfig.fontFilePath = "fonts/FZY3JW.TTF"
    ttfConfig.fontSize = 40

    local  progress = cc.Label:createWithTTF(ttfConfig, "0%", cc.VERTICAL_TEXT_ALIGNMENT_CENTER)
    progress:setPosition(cc.p(960, 540 + 50))
    progress:setColor(cc.c3b(0, 255, 0 ))
    layer:addChild(progress)	
    local assetsManagerEx = cc.AssetsManagerEx:create(manifestPath, cc.FileUtils:getInstance():getWritablePath() .. storagePath)  
    assetsManagerEx:retain() 	 
    local localManifest = assetsManagerEx:getLocalManifest()
    print("当前版本:".. localManifest:getVersion())

    if not assetsManagerEx:getLocalManifest():isLoaded() then
        print("Fail to update assets, step skipped.")
        print("本地资源错误,请重新下载游戏。")
    else
        local function onUpdateEvent(event)
            local eventCode = event:getEventCode()
	    print("====== assetsmanagerex error code:", eventCode)  
            --[[ cc.EventAssetsManagerEx.EventCode = {  
                ERROR_NO_LOCAL_MANIFEST = 0,  
                ERROR_DOWNLOAD_MANIFEST = 1,  
                ERROR_PARSE_MANIFEST = 2,  
                NEW_VERSION_FOUND = 3,  
                ALREADY_UP_TO_DATE = 4,  
                UPDATE_PROGRESSION = 5,  
                ASSET_UPDATED = 6,  
                ERROR_UPDATING = 7,  
                UPDATE_FINISHED = 8,  
                UPDATE_FAILED = 9,  
                ERROR_DECOMPRESS = 10  
            } ]] 

            if eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_NO_LOCAL_MANIFEST then
		print("发生错误:本地找不到manifest文件", eventCode)
            elseif  eventCode == cc.EventAssetsManagerEx.EventCode.UPDATE_PROGRESSION then
		print("更新进度=" .. event:getPercent(), eventCode)
                local assetId = event:getAssetId()
                local percent = event:getPercent()
                local strInfo = ""

                if assetId == cc.AssetsManagerExStatic.VERSION_ID then
                    strInfo = string.format("Version file: %d%%", percent)
                elseif assetId == cc.AssetsManagerExStatic.MANIFEST_ID then
                    strInfo = string.format("Manifest file: %d%%", percent)
                else
                    strInfo = string.format("%d%%", percent)
                end
                progress:setString(strInfo)
            elseif eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_DOWNLOAD_MANIFEST then
                print("发生错误:下载 manifest文件失败", eventCode)
            elseif eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_PARSE_MANIFEST then
                print("发生错误:解析 manifest文件失败", eventCode)
            elseif eventCode == cc.EventAssetsManagerEx.EventCode.ALREADY_UP_TO_DATE then
                print("已经是最新版本了,进入游戏主界面", eventCode)
	    elseif eventCode == cc.EventAssetsManagerEx.EventCode.UPDATE_FINISHED then
		print("更新完毕,重新启动", eventCode)
		-- app:run()
            elseif eventCode == cc.EventAssetsManagerEx.EventCode.ERROR_UPDATING then
		print("发生错误:更新失败", eventCode)
            end
        end
        local listener = cc.EventListenerAssetsManagerEx:create(assetsManagerEx,onUpdateEvent)
        cc.Director:getInstance():getEventDispatcher():addEventListenerWithFixedPriority(listener, 1)
        -- 检查版本并升级
        assetsManagerEx:update()
    end
end

    只需要调用 updateCheck() 即可


----------------------------------------------------------------------------------------------------------------------------------

今日在查看更新相关底层代码时发现还有一个 groupVersions 参数 该参数是写在 version.manifest 文件中的

"groupVersions" : {

    "ver_niuniu" : "1.0.0"

}

感觉用处不大,但可做为游戏版本控制 比如大厅版本 本地与服务器都是 1.1.0 但是游戏版本 为1.1.1 此时还是会进行更新。 

你可能感兴趣的:(2018.02.24 七米游戏 更新实现)