cocos2dx中有一个热更新类AssetsManagerEx,用这个类实现热更功能时需要有两个文件,project.manifest以及version.manifest。这里主要是project.manifest文件,里面需要存有资源文件和代码文件的md5值,通过md5的不同得出差异文件然后下载。
这里通过python来实现这两个文件。
创建一个python文件generateManifest.py。
#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/')
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()
在我项目的路径下,自己创建一个json文件,里面包含有版本信息等,通过修改这个文件内容然后执行文件generateManifest.py就会生成所需要的文件project.manifest以及version.manifest。
我项目下的version_info.json文件如下
{
"packageUrl" : "http://ip:port/update/MyProj/assets/",
"remoteManifestUrl" : "http://ip:port/update/MyProj/version/project.manifest",
"remoteVersionUrl" : "http://ip:port/update/MyProj/version/version.manifest",
"engineVersion" : "Quick-cocos2dx-3.3",
"version" : "1.1.0"
}
生成version.manifest如下
{
"packageUrl": "http://ip:port/update/MyProj/assets/",
"engineVersion": "Quick-cocos2dx-3.3",
"version": "1.1.0",
"remoteVersionUrl": "http://ip:port/update/MyProj/version/version.manifest",
"remoteManifestUrl": "http://ip:port/update/MyProj/version/project.manifest"
}
生成project.manifest如下
{
"assets": {
"src/packages/mvc/init.lua": {
"md5": "6b9173481a1300c5e737ad5885ebef00"
},
"src/protobuf.lua": {
"md5": "f790fe35eb179a4341ff41d94e488a5d"
}
...
},
"packageUrl": "http://ip:port/update/MyProj/assets/",
"engineVersion": "Quick-cocos2dx-3.3",
"version": "1.1.0",
"remoteVersionUrl": "http://ip:port/update/MyProj/version/version.manifest",
"remoteManifestUrl": "http://ip:port/update/MyProj/version/project.manifest"
}
参考:http://blog.csdn.net/u011488256/article/details/52274826