21 changed files with 414 additions and 0 deletions
Binary file not shown.
Binary file not shown.
@ -0,0 +1,3 @@ |
|||
cd . |
|||
python main.py |
|||
pause |
@ -0,0 +1 @@ |
|||
{"10001": "1.0.0"} |
File diff suppressed because one or more lines are too long
@ -0,0 +1,14 @@ |
|||
[ |
|||
{ |
|||
"platform":"android", |
|||
"version":"1.0.0", |
|||
"buildDir":"build\\{#}\\data\\assets\\", |
|||
"filters":["frame","internal","main"], |
|||
"only":["10001"], |
|||
"fileName":"assets", |
|||
"disName":"game_hot", |
|||
"suffix":"zip", |
|||
"maxFileSize":2.5, |
|||
"pkgName":"game" |
|||
} |
|||
] |
@ -0,0 +1,60 @@ |
|||
import hashlib |
|||
import json |
|||
import os |
|||
|
|||
#获取目录下的全部文件列表 |
|||
def get_all_filenames(parentPath,folder_path,isRootPath): |
|||
filenames = [] |
|||
contents = os.listdir(folder_path) |
|||
for content in contents: |
|||
path = os.path.join(folder_path, content) |
|||
if isRootPath == True: |
|||
path=path.replace("/","\\") |
|||
filenames.append(path) |
|||
else: |
|||
if os.path.isfile(path): |
|||
filePath=os.path.join(folder_path,content) |
|||
filePath=filePath.replace(parentPath+"\\","") |
|||
filePath=filePath.replace("/","\\") |
|||
filenames.append(filePath) |
|||
else: |
|||
subfolder_filenames = get_all_filenames(parentPath,path,isRootPath) |
|||
filenames.extend(subfolder_filenames) |
|||
return filenames |
|||
|
|||
#验证某个文件路径是否在文件list列表中 |
|||
def hasInList(fn,list): |
|||
for f in list: |
|||
if f in fn: |
|||
return True |
|||
return False |
|||
|
|||
#获取某个文件的MD5码 |
|||
def getHas(filePath): |
|||
pathArr = filePath.split(".") |
|||
if len(pathArr) > 2 and pathArr[2] != "json": |
|||
return pathArr[2] |
|||
return None |
|||
|
|||
# 根据路径创建一个md5字符串 |
|||
def create_md5(input_str): |
|||
md5 = hashlib.md5() # 创建一个md5对象 |
|||
md5.update(input_str.encode('utf-8')) # 使用utf-8编码 |
|||
return md5.hexdigest() # 返回十六进制的哈希值 |
|||
|
|||
#检查文件路径是否存在,如果不存在就创建一个目录 |
|||
def existsDir(path): |
|||
if not os.path.exists(path): |
|||
os.makedirs(path, exist_ok=True) |
|||
# 读取json文件 |
|||
def readJson(path): |
|||
if os.path.exists(path): |
|||
f=open(path,encoding="utf-8") |
|||
jsonobj = json.load(f) |
|||
f.close(); |
|||
return jsonobj |
|||
# 写json数据到本地 |
|||
def writeJson(path,content): |
|||
f=open(path,"w") |
|||
json.dump(content,f) |
|||
f.close() |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@ |
|||
{"gameId": "10001", "version": "1a47b", "list": ["10001.1", "10001.2", "10001.3", "10001.4", "10001.5"]} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@ |
|||
{"gameId": "10001", "version": "1a47b", "list": ["10001.1", "10001.2", "10001.3", "10001.4", "10001.5"]} |
@ -0,0 +1,297 @@ |
|||
import json |
|||
import os |
|||
import zipfile |
|||
import fileTools |
|||
from zipTools import create_split_zip |
|||
|
|||
#加载配置 |
|||
config = fileTools.readJson("config.json") |
|||
#本地文件缓存 |
|||
local_version_list=[] |
|||
|
|||
def getPathItem(path,list): |
|||
if len(list) <= 0:return None |
|||
for file in list: |
|||
if file["path"] == path: |
|||
return file |
|||
return None |
|||
#文件是否别改变 |
|||
def isChanged(file): |
|||
path=targetDir+file["path"] |
|||
current_time = os.stat(path).st_mtime |
|||
return current_time > float(file["st"]) |
|||
#获取版本 |
|||
def getVer(ver): |
|||
verArr = ver.split(".") |
|||
index=len(verArr) -1 |
|||
verArr[index]=int(verArr[index]) + 1 |
|||
if verArr[index] >= 100 : |
|||
verArr[index]=0; |
|||
verArr[index-1]=int(verArr[index-1])+1 |
|||
if verArr[index-1] >= 100 : |
|||
verArr[index-1]=0; |
|||
verArr[index-2]=int(verArr[index-2])+1 |
|||
return f'{verArr[0]}.{verArr[1]}.{verArr[2]}' |
|||
|
|||
def getVerCode(ver): |
|||
verArr = ver.split(".") |
|||
count=0 |
|||
for i in range(0,len(verArr)): |
|||
count +=int(verArr[i]) |
|||
return count |
|||
|
|||
#处理配置对象 |
|||
def handleConfigObject(obj,dirpath): |
|||
cachePath=currentPath+"\\cache_files\\";#缓存当前版本变化量 |
|||
fileTools.existsDir(cachePath) |
|||
local_ver_path=cachePath+"files.json" |
|||
local_version={} |
|||
local_version["list"]=[] |
|||
local_version["version"]=obj["version"] |
|||
#加载本地版本缓存 |
|||
if os.path.exists(local_ver_path): |
|||
local_version = fileTools.readJson(local_ver_path) |
|||
else: |
|||
fileTools.writeJson(local_ver_path,local_version["list"]) |
|||
files = fileTools.get_all_filenames(dirpath,dirpath,False) |
|||
filters = obj["filters"] |
|||
versionList=[] |
|||
base_ver_list=[] |
|||
fversion=local_version["version"] |
|||
for file_path in files: |
|||
if not fileTools.hasInList(file_path,filters): |
|||
md5 = fileTools.getHas(file_path) |
|||
cur_file_path = file_path.replace(dirpath, "") |
|||
if md5 == None: |
|||
md5 = fileTools.create_md5(cur_file_path) |
|||
file_item=getPathItem(cur_file_path,local_version["list"]) |
|||
fileArr=cur_file_path.split("\\") |
|||
newFileObj={} |
|||
newFileObj["bundleName"]= fileArr[0] |
|||
newFileObj["path"]=cur_file_path |
|||
newFileObj["st"]=os.stat(file_path).st_mtime |
|||
base_ver_list.append(newFileObj) |
|||
def addObj(ver): |
|||
if file_item!= None: |
|||
file_item["st"]=os.stat(file_path).st_mtime |
|||
if ver == local_version["version"]: |
|||
ver=getVer(local_version["version"]) |
|||
local_version["version"]=ver |
|||
else: |
|||
local_version["list"].append(newFileObj) |
|||
#版本路径数据 |
|||
versionList.append(newFileObj) |
|||
if file_item == None or isChanged(file_item): |
|||
if len(obj["only"]) > 0: |
|||
if fileTools.hasInList(fileArr[0],obj["only"]): |
|||
addObj(fversion) |
|||
else: |
|||
addObj(fversion) |
|||
if len(versionList) <= 0 : |
|||
print("=======================暂无热更资源发布================================") |
|||
return |
|||
print("=======================开始发布资源================================") |
|||
verConfigPath=cur_version_path+local_version["version"] |
|||
zipFileHotPathDir=verConfigPath+"\\hot\\assets\\" |
|||
fileTools.existsDir(zipFileHotPathDir) |
|||
zipFileHotPath=zipFileHotPathDir+"\\"+obj["fileName"]+"."+obj["suffix"] |
|||
if os.path.exists(zipFileHotPath): |
|||
os.remove(zipFileHotPath) |
|||
zf = zipfile.ZipFile(zipFileHotPath, "w", zipfile.zlib.DEFLATED) |
|||
for tar in versionList: |
|||
print("bundleName-> "+tar["bundleName"]+"\t\t开始写入文件 --- > "+tar["path"]) |
|||
fullpath=targetDir+"\\"+tar["path"] |
|||
zf.write(fullpath,tar["path"]) |
|||
zf.close() |
|||
print("=======================开始对资源进行分包处理================================") |
|||
print(f'当前资源版本 -> {local_version["version"]}') |
|||
list = create_split_zip(zipFileHotPath,zipFileHotPathDir,1000 * 1000 * obj["maxFileSize"],obj["suffix"]) |
|||
new_config_list=[] |
|||
for fi in list: |
|||
newob={} |
|||
newob["name"]=obj["pkgName"] |
|||
newob["resName"]=fi |
|||
#newob["version"]=local_version["version"] |
|||
new_config_list.append(newob) |
|||
configPath=zipFileHotPathDir[:zipFileHotPathDir.find("\\assets")]+"\\config.json" |
|||
fileTools.writeJson(configPath,new_config_list) |
|||
#删除原有包 |
|||
if os.path.exists(zipFileHotPath): |
|||
os.remove(zipFileHotPath) |
|||
print("-------------------------分包完成-----------------------------------------") |
|||
zipFileBasePathDir=verConfigPath+"\\base\\assets\\" |
|||
fileTools.existsDir(zipFileBasePathDir) |
|||
zipFileBasePath=zipFileBasePathDir+"\\"+obj["fileName"]+"."+obj["suffix"] |
|||
if os.path.exists(zipFileBasePath): |
|||
os.remove(zipFileBasePath) |
|||
zf = zipfile.ZipFile(zipFileBasePath, "w", zipfile.zlib.DEFLATED) |
|||
for tar in base_ver_list: |
|||
print("bundleName-> "+tar["bundleName"]+"\t\t开始写入文件 --- > "+tar["path"]) |
|||
fullpath=targetDir+"\\"+tar["path"] |
|||
zf.write(fullpath,tar["path"]) |
|||
zf.close() |
|||
print("=======================开始对资源进行分包处理================================") |
|||
list = create_split_zip(zipFileBasePath,zipFileBasePathDir,1000 * 1000 * obj["maxFileSize"],obj["suffix"]) |
|||
new_config_list=[] |
|||
for fi in list: |
|||
newob={} |
|||
newob["name"]=obj["pkgName"] |
|||
newob["resName"]=fi |
|||
#newob["version"]=local_version["version"] |
|||
new_config_list.append(newob) |
|||
configPath=zipFileBasePathDir[:zipFileBasePathDir.find("\\assets")]+"\\config.json" |
|||
fileTools.writeJson(configPath,new_config_list) |
|||
#删除原有包 |
|||
if os.path.exists(zipFileBasePath): |
|||
os.remove(zipFileBasePath) |
|||
print("-------------------------开始写入分包配置----------------------------------") |
|||
print(f'当前资源版本 -> {local_version["version"]}') |
|||
#写入数据缓存 |
|||
fileTools.writeJson(local_ver_path,local_version) |
|||
|
|||
def handleGameObject(obj,dirpath): |
|||
cachePath=currentPath+"\\cache_files\\";#缓存当前版本变化量 |
|||
fileTools.existsDir(cachePath) |
|||
game_local_version_list=[] |
|||
game_bundle_ver_list={} |
|||
for gn in obj["only"]: |
|||
local_ver_path_dir=f'{cachePath}{gn}' |
|||
local_ver_path=f'{local_ver_path_dir}\\files.json' |
|||
local_bundle_ver_path=f'{local_ver_path_dir}\\bundle.ver.json' |
|||
fileTools.existsDir(local_ver_path_dir) |
|||
gameObj={} |
|||
gameObj["name"]=gn |
|||
gameObj["local_ver_path"]=local_ver_path |
|||
gameObj["cache_list"]=[] |
|||
gameObj["list"]=[] |
|||
gameObj["ver_list"]=[] |
|||
if os.path.exists(local_ver_path): |
|||
gameObj["cache_list"] = fileTools.readJson(local_ver_path) |
|||
else: |
|||
fileTools.writeJson(local_ver_path,gameObj["cache_list"]) |
|||
game_local_version_list.append(gameObj) |
|||
#bundle list |
|||
if os.path.exists(local_bundle_ver_path): |
|||
game_bundle_ver_list= fileTools.readJson(local_bundle_ver_path) |
|||
else: |
|||
fileTools.writeJson(local_bundle_ver_path,game_bundle_ver_list) |
|||
|
|||
def getGameItem(gn): |
|||
for fn in game_local_version_list: |
|||
if fn["name"] == gn : |
|||
return fn |
|||
return None |
|||
files = fileTools.get_all_filenames(dirpath,dirpath,False) |
|||
filters = obj["filters"] |
|||
gameVer={} |
|||
for file_path in files: |
|||
if not fileTools.hasInList(file_path,filters): |
|||
md5 = fileTools.getHas(file_path) |
|||
cur_file_path = file_path.replace(dirpath, "") |
|||
fileArr=cur_file_path.split("\\") |
|||
if fileTools.hasInList(fileArr[0],obj["only"]): |
|||
subGameObj=getGameItem(fileArr[0]) |
|||
if subGameObj != None: |
|||
file_item=getPathItem(cur_file_path,subGameObj["cache_list"]) |
|||
|
|||
newFileObj={} |
|||
newFileObj["bundleName"]= fileArr[0] |
|||
newFileObj["path"]=cur_file_path |
|||
newFileObj["st"]=os.stat(file_path).st_mtime |
|||
subGameObj["ver_list"].append(newFileObj) |
|||
if "config" in cur_file_path : |
|||
subGameObj["md5"]=md5 |
|||
if not fileArr[0] in game_bundle_ver_list: |
|||
game_bundle_ver_list[fileArr[0]]=obj["version"] |
|||
if file_item == None or isChanged(file_item): |
|||
def addObj(): |
|||
if file_item != None: |
|||
file_item["st"]=os.stat(file_path).st_mtime |
|||
if not fileArr[0] in gameVer: |
|||
gameVer[fileArr[0]]=game_bundle_ver_list[fileArr[0]] |
|||
game_bundle_ver_list[fileArr[0]]=getVer(gameVer[fileArr[0]]) |
|||
else: |
|||
gameObj["cache_list"].append(newFileObj) |
|||
|
|||
subGameObj["list"].append(newFileObj) |
|||
if len(obj["only"]) > 0: |
|||
if fileTools.hasInList(fileArr[0],obj["only"]): |
|||
addObj() |
|||
else: |
|||
addObj() |
|||
print("=======================开始发布资源================================") |
|||
for fn in game_local_version_list: |
|||
id=fn["name"] |
|||
verConfigPath=cur_version_path+id+"\\"+game_bundle_ver_list[id]+"\\" |
|||
if len(fn["list"]) <=0 : |
|||
print(f'======================={id}暂无资源发布============================') |
|||
continue; |
|||
zipFileHotPathDir=verConfigPath+"\\hot\\assets\\" |
|||
fileTools.existsDir(zipFileHotPathDir) |
|||
zipFileHotPath=zipFileHotPathDir+"\\"+id+"."+"."+obj["suffix"] |
|||
if os.path.exists(zipFileHotPath): |
|||
os.remove(zipFileHotPath) |
|||
zf = zipfile.ZipFile(zipFileHotPath, "w", zipfile.zlib.DEFLATED) |
|||
for tar in fn["list"]: |
|||
print("bundleName-> "+tar["bundleName"]+"\t\t开始写入文件 --- > "+tar["path"]) |
|||
fullpath=targetDir+"\\"+tar["path"] |
|||
zf.write(fullpath,tar["path"]) |
|||
zf.close() |
|||
print(f'=======================开始对资源【{id}】进行分包处理================================') |
|||
list = create_split_zip(zipFileHotPath,zipFileHotPathDir,1000 * 1000 * obj["maxFileSize"],obj["suffix"]) |
|||
configPath=zipFileHotPathDir[:zipFileHotPathDir.find("\\assets")]+"\\config.json" |
|||
configObj={} |
|||
configObj["gameId"]=id |
|||
configObj["version"]=fn["md5"] |
|||
configObj["list"]=list |
|||
fileTools.writeJson(configPath,configObj) |
|||
#删除原有包 |
|||
if os.path.exists(zipFileHotPath): |
|||
os.remove(zipFileHotPath) |
|||
#基础版本 |
|||
zipFileHotPathDir=verConfigPath+"\\base\\assets\\" |
|||
fileTools.existsDir(zipFileHotPathDir) |
|||
zipFileHotPath=zipFileHotPathDir+"\\"+id+"."+"."+obj["suffix"] |
|||
if os.path.exists(zipFileHotPath): |
|||
os.remove(zipFileHotPath) |
|||
zf = zipfile.ZipFile(zipFileHotPath, "w", zipfile.zlib.DEFLATED) |
|||
for tar in fn["ver_list"]: |
|||
print("bundleName-> "+tar["bundleName"]+"\t\t开始写入文件 --- > "+tar["path"]) |
|||
fullpath=targetDir+"\\"+tar["path"] |
|||
zf.write(fullpath,tar["path"]) |
|||
zf.close() |
|||
print(f'=======================开始对资源【{id}】进行分包处理================================') |
|||
|
|||
list = create_split_zip(zipFileHotPath,zipFileHotPathDir,1000 * 1000 * obj["maxFileSize"],obj["suffix"]) |
|||
configPath=zipFileHotPathDir[:zipFileHotPathDir.find("\\assets")]+"\\config.json" |
|||
configObj={} |
|||
configObj["gameId"]=id |
|||
configObj["version"]=fn["md5"] |
|||
configObj["list"]=list |
|||
fileTools.writeJson(configPath,configObj) |
|||
#删除原有包 |
|||
if os.path.exists(zipFileHotPath): |
|||
os.remove(zipFileHotPath) |
|||
#写入数据缓存 |
|||
fileTools.writeJson(fn["local_ver_path"],fn["cache_list"]) |
|||
#写入版本 |
|||
fileTools.writeJson(local_bundle_ver_path,game_bundle_ver_list) |
|||
print(f'当前资源版本 -> {game_bundle_ver_list[id]}') |
|||
|
|||
if __name__ == '__main__': |
|||
currentPath = os.getcwd().replace('\\', '\\') # 获取当前程序运行路径 |
|||
parentPath = os.path.dirname(currentPath) # 获取上一级目录 |
|||
for itemObj in config: |
|||
#处理打包文件目标目录 |
|||
targetDir = parentPath +"\\"+itemObj["buildDir"] |
|||
targetDir=targetDir.replace("{#}",itemObj["platform"]) |
|||
cur_version_path=currentPath+"\\"+itemObj["disName"]+"\\" |
|||
fileTools.existsDir(cur_version_path) |
|||
if itemObj["pkgName"] == "base": |
|||
handleConfigObject(itemObj,targetDir) |
|||
elif itemObj["pkgName"] == "game": |
|||
handleGameObject(itemObj,targetDir) |
|||
else: |
|||
print("没有找到处理handler") |
|||
|
|||
|
@ -0,0 +1,36 @@ |
|||
|
|||
import os |
|||
import zipfile |
|||
|
|||
|
|||
def get_file_name(path): |
|||
return os.path.splitext(os.path.basename(path))[0] |
|||
#将zip文件拆分成多个zip字文件 |
|||
def create_split_zip(src_zip_path, dst_dir, max_size,suffix="zip"): |
|||
cur_file_Name=get_file_name(src_zip_path) |
|||
files=[] |
|||
with zipfile.ZipFile(src_zip_path, 'r') as z: |
|||
file_list = z.infolist() |
|||
chunk_number = 1 |
|||
dst_zip = None |
|||
file_size=0 |
|||
for file_info in file_list: |
|||
file_data = z.read(file_info.filename) |
|||
file_size += file_info.compress_size |
|||
if file_size >= max_size : |
|||
if dst_zip: |
|||
dst_zip.close() |
|||
dst_zip=None |
|||
chunk_number+=1 |
|||
file_size=0 |
|||
if dst_zip == None : |
|||
fileName=f'{cur_file_Name}{chunk_number}' |
|||
files.append(fileName) |
|||
dst_zip_name = os.path.join(dst_dir, f'{fileName}.{suffix}') |
|||
if os.path.exists(dst_zip_name): |
|||
os.remove(dst_zip_name) |
|||
dst_zip = zipfile.ZipFile(dst_zip_name, 'w', zipfile.ZIP_DEFLATED) |
|||
dst_zip.writestr(file_info.filename, file_data) |
|||
if dst_zip != None : |
|||
dst_zip.close() |
|||
return files |
Loading…
Reference in new issue