lua热更md5加密

预先创建一个res/config/version_info.json文件
创建这个文件的目的是为了生成project.manifest和version.manifest做数据准备
配置好包的地址
配置好版本号
配置好project和version远程文件的地址

{
    "packageUrl" : "http://10.225.14.23:8081/wwwCYH/update/LuaTest009/assets/",
    "remoteManifestUrl" : "http://10.225.14.23:8081/wwwCYH//update/LuaTest009/version/project.manifest",
    "remoteVersionUrl" : "http://10.225.14.23:8081/wwwCYH//update/LuaTest009/version/version.manifest",
    "version" : "1.0.0",
    "engineVersion" : "cocos2dx3.10"
}

加密脚本和资源的python代码
此处的加密是依靠路径和资源内容作为加密对象,这样可以保证资源的唯一性

#coding:utf-8

import os
import sys
import json
import hashlib
import subprocess
import getpass

username = getpass.getuser()
# 改变当前工作目录
# os.chdir('/Users/' + username + '/Documents/client/MyProj/')
os.chdir("F:/cocosWork/LuaTest002/")

assetsDir = {
    #MyProj文件夹下需要进行热跟的文件夹
    "searchDir" : ["src", "res"],
    #需要忽略的文件夹
    "ignorDir" : ["cocos", "framework", ".svn"],
    #需要忽略的文件
    "ignorFile":[".DS_Store"],
}

versionConfigFile   = "res/config/version_info.json"  #版本信息的配置文件路径
versionManifestPath = "res/version/version.manifest"    #由此脚本生成的version.manifest文件路径
projectManifestPath = "res/version/project.manifest"    #由此脚本生成的project.manifest文件路径
# projectManifestPath = "/Users/ximi/Documents/client/MyProj/res/version/project.manifest"    #由此脚本生成的project.manifest文件路径(mac机)

class SearchFile:
    def __init__(self):
        self.fileList = []

        for k in assetsDir:
            if (k == "searchDir"):
                for searchdire in assetsDir[k]:                 
                    self.recursiveDir(searchdire)

    def recursiveDir(self, srcPath):
        ''' 递归指定目录下的所有文件'''
        dirList = []    #所有文件夹  

        files = os.listdir(srcPath) #返回指定目录下的所有文件,及目录(不含子目录)

        for f in files:         
            #目录的处理
            if (os.path.isdir(srcPath + '/' + f)):              
                if (f[0] == '.' or (f in assetsDir["ignorDir"])):
                    #排除隐藏文件夹和忽略的目录
                    pass
                else:
                    #添加非需要的文件夹                                  
                    dirList.append(f)

            #文件的处理
            elif (os.path.isfile(srcPath + '/' + f)) and (f not in assetsDir["ignorFile"]):               
                self.fileList.append(srcPath + '/' + f) #添加文件

        #遍历所有子目录,并递归
        for dire in dirList:        
            #递归目录下的文件
            self.recursiveDir(srcPath + '/' + dire)

    def getAllFile(self):
        ''' get all file path'''
        return tuple(self.fileList)


def CalcMD5(filepath):
    """generate a md5 code by a file path"""
    with open(filepath,'rb') as f:
        md5obj = hashlib.md5()
        md5obj.update(f.read())
        return md5obj.hexdigest()


def getVersionInfo():
    '''get version config data'''
    configFile = open(versionConfigFile,"r")
    json_data = json.load(configFile)

    configFile.close()
    # json_data["version"] = json_data["version"] + '.' + str(GetSvnCurrentVersion())
    json_data["version"] = json_data["version"]
    return json_data


def GenerateVersionManifestFile():
    ''' 生成大版本的version.manifest'''
    json_str = json.dumps(getVersionInfo(), indent = 2)
    fo = open(versionManifestPath,"w")  
    fo.write(json_str)  
    fo.close()


def GenerateProjectManifestFile():
    searchfile = SearchFile()
    fileList = list(searchfile.getAllFile())
    project_str = {}
    project_str.update(getVersionInfo())
    dataDic = {}
    for f in fileList:      
        dataDic[f] = {"md5" : CalcMD5(f)}
        print f

    project_str.update({"assets":dataDic})
    json_str = json.dumps(project_str, sort_keys = True, indent = 2)

    fo = open(projectManifestPath,"w")  
    fo.write(json_str)  
    fo.close()

if __name__ == "__main__":
    GenerateVersionManifestFile()
    GenerateProjectManifestFile()

实现热更的代码:

local function assetsUpdate()
	local writablePath = cc.FileUtils:getInstance():getWritablePath()
    local storagePath = writablePath .. "new_version"
	--将下载目录的src和res作为优先级最高的搜索目录,这样才能保证下载的能覆盖原来的代码
	cc.FileUtils:getInstance():addSearchPath(storagePath.."/src/",true)
    cc.FileUtils:getInstance():addSearchPath(storagePath.."/res/",true)
    
    print("下载的文件地址--"..storagePath)
    -- 创建AssetsManagerEx对象
    local assetsManagerEx = cc.AssetsManagerEx:create("src/version/project.manifest", storagePath)
    assetsManagerEx:retain()
    -- 设置下载消息listener
    local function handleAssetsManagerEx(event)
        if (cc.EventAssetsManagerEx.EventCode.ALREADY_UP_TO_DATE == event:getEventCode()) then
            print("已经是最新版本了,进入游戏主界面")
            require("app.MyApp"):create():run()
        end
        if (cc.EventAssetsManagerEx.EventCode.NEW_VERSION_FOUND == event:getEventCode()) then
            print("发现新版本,开始升级")
        end
        if (cc.EventAssetsManagerEx.EventCode.UPDATE_PROGRESSION == event:getEventCode()) then
            print("更新进度=" .. event:getPercent())
        end
        if (cc.EventAssetsManagerEx.EventCode.UPDATE_FINISHED == event:getEventCode()) then
            print("更新完毕,重新启动")
            require("app.MyApp"):create():run()
        end
        if (cc.EventAssetsManagerEx.EventCode.ERROR_NO_LOCAL_MANIFEST == event:getEventCode()) then
            print("发生错误:本地找不到manifest文件")
        end
        if (cc.EventAssetsManagerEx.EventCode.ERROR_DOWNLOAD_MANIFEST == event:getEventCode()) then
            print("发生错误:下载manifest文件失败")
        end
        if (cc.EventAssetsManagerEx.EventCode.ERROR_PARSE_MANIFEST == event:getEventCode()) then
            print("发生错误:解析manifest文件失败")
        end
        if (cc.EventAssetsManagerEx.EventCode.ERROR_UPDATING == event:getEventCode()) then
            print("发生错误:更新失败")
        end
    end
    local dispatcher = cc.Director:getInstance():getEventDispatcher()
    local eventListenerAssetsManagerEx = cc.EventListenerAssetsManagerEx:create(assetsManagerEx, handleAssetsManagerEx)
    dispatcher:addEventListenerWithFixedPriority(eventListenerAssetsManagerEx, 1)
    -- 检查版本并升级
    assetsManagerEx:update()
end

对于热更源码的解读:
AssetsManagerEx:在创建它的时候需要给他一个本地的project.manifest,至于路径可以自己定义,我这里存放的是src/version/project.manifest,该类利用这个数据做一个原版的比较对象,当你第一次热更以后,这个路径下的project.manifest就没用了,因为下载目下也有一个更新版本的project.manifest,之后都以下载目录下作为比较对象,至于为啥没有用是因为我们修改了require文件路径的优先级
AssetsManagerEx:update();当调用这个函数的时候,就开始下载资源服务器version.manifest,比较版本号,如果发现本地的版本号小于资源服的版本,则下载资源服的project.manifest,然后那本地的资源(名字,MD5)和刚下载下来的资源(名字,MD5)进行比较,此处有三个结果,删除,修改,添加,最后将这些差异放在一个数组里去处理(删除或者下载资源),特别注意当发现资源服上没有,本地有的话,这里的删除只能删下载目录中的资源,游戏包中的资源是你所无法删除的

远程部署:
每一次版本更新 都要执行对本地全部资源的MD5加密,然后将本地资源全部考到资源服
在这里插入图片描述
总结:
当要做版本更新的时候,要在本地关闭热更功能,用本地资源跑最新游戏,然后对本地资源进行MD5加密,最后修改版本号,把本地全部资源上传资源服

本地开发最新客户端-----------------------------------------------------------------------------》玩家手中的旧版本客户端
上传 下载
资源服 -----------------------------------------------------------------------------》android缓存

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值