python调用cocos creator打包多个小游戏脚本
客户端打包脚本, 包括删除临时目录, git还原, 拉取, 改游戏host, 修改标题, 打包zip, 替换图片, 记录日记.
pub.py
import zipfile import os import shutil import subprocess import re import importlib.util # from my_logger import logger def import_variable_if_module_exists(module_name, variable_name): spec = importlib.util.find_spec(module_name) if spec is not None: module = importlib.import_module(module_name) variable = getattr(module, variable_name, None) if variable is not None: print(f"{module_name} 模块存在,并成功导入 {variable_name} 变量。") return variable else: print(f"{module_name} 模块存在,但 {variable_name} 变量不存在。") else: print(f"{module_name} 模块不存在。") return None logger = import_variable_if_module_exists("my_logger", "logger") def logDebug(msg): if logger is not None: logger.debug(msg) else: print(msg) def logError(msg): if logger is not None: logger.error(msg) else: print(msg) #删除文件夹 def deleteFolder(path): if not os.path.isdir(path): return try: shutil.rmtree(path) logDebug(f"成功删除文件夹 {path}") except OSError as e: logDebug(f"删除文件夹 {path} 失败: {e}") #列出文件夹 def listDir(curPath): list = [] # logDebug("当前路径:" + curPath) files = os.listdir(curPath) for path in files: fullPath = os.path.join(curPath, path) if not os.path.isfile(fullPath): # append是打元素加到尾部 list.append(fullPath) return list #运行程序, 并输出原来的控制台输出 def runCmd(command): """ 运行CMD命令并返回输出结果 参数: command (str): 要执行的CMD命令 返回:无 """ try: process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, text=True) # 循环读取并输出第三方程序的输出 for line in iter(process.stdout.readline, ""): logDebug(line.strip()) # 等待进程完成 process.wait() except Exception as e: logDebug(str(e)) def replaceInText(srcTxt, orginStr, replaceStr): destTxt = srcTxt.replace(orginStr, replaceStr) return destTxt def readAllTxt(filePath, encoding = "utf-8"): # 使用with语句打开文件,并确保文件在使用后自动关闭 with open(filePath, "r", encoding=encoding) as file: # 读取文件的全部内容 content = file.read() # 输出文件内容 return content def writeAllTxt(filePath, content, encoding = "utf-8"): # 使用with语句打开文件,并确保文件在使用后自动关闭 with open(filePath, "w", encoding=encoding) as file: # 写入文件 file.write(content) #替换GlobalVar.js中的域名 def replaceGlobalVar(rootDir, hostName): globalVarJsPath = os.path.join(rootDir, "assets\\BalootClient\\GlobalVar.js") if not os.path.exists(globalVarJsPath): logError("error, GlobalVar.js不存在:" + globalVarJsPath) return txt = readAllTxt(globalVarJsPath) pattern = re.compile(r'loginServerAddress.*') replacedText = pattern.sub("loginServerAddress: \"" + hostName + "\"," , txt) writeAllTxt(globalVarJsPath, replacedText) #替换index.html里面的标题 def replaceIndexHtml(htmlPath, title): if not os.path.exists(htmlPath): logError("error, index.html不存在:" + htmlPath) return txt = readAllTxt(htmlPath) pattern = re.compile(r'<title>.*</title>') replacedText = pattern.sub(f"<title>{title}</title>", txt) writeAllTxt(htmlPath, replacedText) # 是否是子游戏目录 def isSubGameFolder(folderName): if len(folderName) > 5: checkStr = folderName[0:4] for ch in checkStr: if not ch.isdigit(): return False if folderName[4] != "_": return False return True return False # zip压缩目录(带根目录) def zipCompress(folder_path, output_path): if os.path.exists(output_path): try: os.remove(output_path) except OSError: logDebug("文件删除失败:" + output_path) with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf: for root, dirs, files in os.walk(folder_path): for file in files: file_path = os.path.join(root, file) file_in_zip_path = os.path.relpath(file_path, os.path.dirname(folder_path)) zipf.write(file_path, file_in_zip_path) def publishWebMobile(): hostName = "game.mygame.com" creatorPath = r"C:\ProgramData\cocos\editors\Creator\2.4.13\CocosCreator.exe" defaultDir = os.path.dirname(__file__) # 取文件对应的目录 logDebug("所有子游戏根目录为:" + defaultDir) dirs = listDir(defaultDir) tmpsFolder = ["build", "library", "local", "packages", "temp"] for localDir in dirs: shortName = os.path.basename(localDir) if not isSubGameFolder(shortName): logDebug(shortName + "不是子游戏目录") continue logDebug(f"正在处理:{shortName}\n1.清理临时目录") # 删除临时文件夹 for tmp in tmpsFolder: deleteFolder(localDir + "\\" + tmp) # 切换目录 os.chdir(localDir) logDebug("2.git 还原, 当前目录:" + os.getcwd()) # git 还原 runCmd("git restore .") logDebug("3.git 更新, 当前目录:" + os.getcwd()) # git 更新 runCmd("git pull") logDebug(f"4.替换GlobalVar.js里面的域名替换为{hostName}") # 替换GlobalVar.js里面的服务器地址 replaceGlobalVar(localDir, hostName) logDebug("5. creator打包") # 调cocos creator cmdStr = f'\"{creatorPath}" --path \"' + localDir + "\" --build \"platform=web-mobile;debug=false\"" logDebug(cmdStr) runCmd(cmdStr) logDebug("6. 替换标题") # 替换index.html里面的标题 webDir = localDir + '\\build\\web-mobile\\' replaceIndexHtml(webDir + "index.html", shortName[5:]) # 替换icon与splash logDebug("7. 替换图片") shutil.copy2(os.path.join(defaultDir, r"pub\favicon.ico"), webDir + "favicon.ico") shutil.copy2(os.path.join(defaultDir, r"pub\splash.png"), webDir + "splash.png") # 压缩文件的输出路径 logDebug("8. 压缩成zip") zipFileOutput = os.path.join(defaultDir, shortName + '.zip') zipCompress(localDir + r'\build\web-mobile', zipFileOutput) publishWebMobile() logDebug("完成")
my_logger.py
import logging # 创建logger logger = logging.getLogger('my_logger') logger.setLevel(logging.DEBUG) # 设置日志级别 # 创建console handler并设置等级,将其添加到logger ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) logger.addHandler(ch) # 创建file handler并设置等级,将其添加到logger fh = logging.FileHandler('my_logger.log') fh.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) logger.addHandler(fh) # 测试日志输出 """ logger.debug('这是一个debug级别的日志信息') logger.info('这是一个info级别的日志信息') logger.warning('这是一个warning级别的日志信息') logger.error('这是一个error级别的日志信息') logger.critical('这是一个critical级别的日志信息') """
zip压缩, 不带根目录:
#不带根目录的压缩 def create_zip_file(source_dir, zip_file_path): with zipfile.ZipFile(zip_file_path, 'w', compression=zipfile.ZIP_DEFLATED) as zip_file: for root, dirs, files in os.walk(source_dir): for file in files: file_path = os.path.join(root, file) relative_path = os.path.relpath(file_path, source_dir) zip_file.write(file_path, relative_path)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
2013-07-17 MFC学习 修改窗口样式