悉野小楼

导航

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)

 

posted on 2024-07-17 09:55  悉野  阅读(2)  评论(0编辑  收藏  举报