cocos creator 快速生成apk

#!/usr/bin/python
#coding:utf8

import os
import sys
import re
import execjs, time

curFilepath = os.path.realpath(__file__)
storeFile = os.path.join(os.path.split(curFilepath)[0], 'xxx.keystore')
samsung = 'samsung'
MTPProjectPath = os.path.abspath(os.path.join(curFilepath, "../../.."))
MTPProjectBuild = os.path.join(MTPProjectPath, 'build/jsb-default')
MTPProjectBuild2 = os.path.join(MTPProjectPath, 'build/apkCache')
SRC_APKTEMP = os.path.join(os.path.split(curFilepath)[0], samsung)
DST_APKTEMP = os.path.join(MTPProjectBuild2, samsung)
apktool = os.path.join(os.path.split(curFilepath)[0], 'apktool_2.7.0.jar')

bundleNames = {
}

SUB_GAMES = {
}

BUNDLE_IDS = {
}

def readConfig(gameName):
    packageName = BUNDLE_IDS[gameName].replace("com", "co")
    cfgPath = 'assets/resources/xxx.ts'
    filename = os.path.join(MTPProjectPath, cfgPath)

    with open(filename, 'r', encoding='UTF-8') as file:
        result = file.read()
        result = result.replace("export class xxx","class xxxxx")

    context = execjs.compile(result)

    return context.call('xxxxxxx.readConfig', packageName)

CONFIG = None


# 替换成对应的游戏
def replaceJSGame(gameName):
    new_s = ''
    jsPath = os.path.join(DST_APKTEMP, "assets/assets/resources/index.js")
    with open(jsPath, 'r') as f:
        con = f.read()
        new_s = re.sub(r"(exports.xxxxxxxxxxx\.)\w+;", r"\1{};".format(gameName), con)
        f.close()

    with open(jsPath, 'w') as f:
        f.write(new_s)

# 修改安装名
def replaceAppName(gameName):
    new_s = ''
    jsPath = os.path.join(DST_APKTEMP, "res/values/strings.xml")
    with open(jsPath, 'r') as f:
        con = f.read()
        new_s = con.replace('GameName', 'Fast-{}'.format(gameName))
        new_s = new_s.replace("172594591747244", CONFIG['facebook_app_id'])
        f.close()

    with open(jsPath, 'w') as f:
        f.write(new_s)

#  修改androidmanifest.xml
def replaceAndroidManifest(gameName):
    new_s = ''
    jsPath = os.path.join(DST_APKTEMP, "AndroidManifest.xml")
    with open(jsPath, 'r') as f:
        con = f.read()
        new_s = con.replace("xxxxxxx.samsung", BUNDLE_IDS[gameName])
        new_s = new_s.replace("172594591747244", CONFIG['facebook_app_id'])
        f.close()

    with open(jsPath, 'w') as f:
        f.write(new_s)

def replaceVersion(gameName):
    new_s = ''
    jsPath = os.path.join(DST_APKTEMP, "assets/manifest/project.manifest")
    pattern = r'"version":".*?"'
    with open(jsPath, 'r') as f:
        con = f.read()
        new_s = re.sub(pattern, r'"version":"3.1.1.1"', con)
        f.close()

    with open(jsPath, 'w') as f:
        f.write(new_s)

def replaceBuildConfig(gameName):
    new_s = ''
    jsPath = os.path.join(DST_APKTEMP, "smali_classes3/co/xxxx/xxx/BuildConfig.smali")
    with open(jsPath, 'r') as f:
        con = f.read()
        new_s = con.replace("bundle.samsung", BUNDLE_IDS[gameName])
        f.close()

    with open(jsPath, 'w') as f:
        f.write(new_s)

# 签名apk
def sign(unSignApkFile, signApkFile):
    password='avia123'
    keyAlias='avia'
    fmtCmd = 'jarsigner -keystore {storeFile} -signedjar  {signApkFile}  {unSignApkFile} {keyAlias} -keypass {password} -storepass {password}'
    cmd = fmtCmd.format(storeFile=storeFile, password=password, signApkFile=signApkFile, unSignApkFile=unSignApkFile, keyAlias=keyAlias)
    return os.system(cmd)

# 检查游戏是否存在, 以及是否有index.js, 非加密的构建
def checkGameName(gameName):
    path = os.path.join(MTPProjectBuild, "assets", bundleNames[gameName]) 
    pathJs = os.path.join(MTPProjectBuild, "assets/main/index.js")
    return os.path.exists(path) and os.path.exists(pathJs) 

# 生成apk
def installApk(gameName):
    global CONFIG
    CONFIG = readConfig(gameName)
    assert CONFIG, "读取配置失败"
    start_time = time.time()
    if os.path.exists(DST_APKTEMP):
        os.system('rm -rf {}'.format(DST_APKTEMP))

    if not os.path.exists(MTPProjectBuild2):
        os.makedirs(MTPProjectBuild2)

    print("开始构建安装包: {}".format(gameName))
    assert checkGameName(gameName), "游戏 {} 不存在或者非Debug构建".format(gameName)
    cmd = 'cp -r {} {}'.format(SRC_APKTEMP, DST_APKTEMP)
    os.system(cmd)

    copys = [
        "assets/main",
        "assets/internal",
        "assets/resources",
        "main.js",
        "src",
        "jsb-adapter",
        "manifest",
    ]
    for bundleNameId in SUB_GAMES[gameName].split(','):
        bundleName = "bundleName_{}".format(bundleNameId)
        copys.append("assets/{}".format(bundleName))

    # copy scirpt
    for copy in copys:
        target = DST_APKTEMP
        if copy.startswith('assets'):
            target = os.path.join(DST_APKTEMP, 'assets')
        cmd = 'cp -r {}/{} {}/assets'.format(MTPProjectBuild, copy, target)
        print('copy: {}'.format(copy))
        assert os.system(cmd)==0, "copy {} 失败".format(copy)

    # 修改对应包的内容
    replaceJSGame(gameName)
    replaceVersion(gameName)
    replaceAppName(gameName)
    replaceAndroidManifest(gameName)
    replaceBuildConfig(gameName)

    apkPath = os.path.join(MTPProjectBuild2, 'temp.apk')
    print('正在生成apk')
    cmd = 'java -jar {} b {} -o {}'.format(apktool, DST_APKTEMP, apkPath)
    assert os.system(cmd)==0, "生成apk失败"

    print('正在签名apk')
    signApkFile = apkPath.replace('.apk', '-S.apk')
    assert sign(apkPath, signApkFile)==0, "签名apk失败"

    print('正在安装apk')
    cmd = 'rm -rf {} && adb install -r {}'.format(apkPath, signApkFile)
    assert os.system(cmd)==0, "安装apk失败"

    print('正在启动游戏')
    cmd = 'adb shell am start -n {}/org.cocos2dx.javascript.AppActivity'.format(BUNDLE_IDS[gameName])
    assert os.system(cmd)==0, "启动游戏失败"

    end_time = time.time()
    print('cost time: {}s'.format(round(end_time-start_time)))

def reInstallApk(gameName):
    start_time = time.time()
    apkPath = os.path.join(MTPProjectBuild2, 'temp.apk')
    print('正在生成apk')
    cmd = 'java -jar {} b {} -o {}'.format(apktool, DST_APKTEMP, apkPath)
    assert os.system(cmd)==0, "生成apk失败"

    print('正在签名apk')
    signApkFile = apkPath.replace('.apk', '-S.apk')
    assert sign(apkPath, signApkFile)==0, "签名apk失败"

    print('正在安装apk')
    cmd = 'rm -rf {} && adb install -r {}'.format(apkPath, signApkFile)
    assert os.system(cmd)==0, "安装apk失败"

    print('正在启动游戏')
    cmd = 'adb shell am start -n {}/org.cocos2dx.javascript.AppActivity'.format(BUNDLE_IDS[gameName])
    assert os.system(cmd)==0, "启动游戏失败"

    end_time = time.time()
    print('cost time: {}s'.format(round(end_time-start_time)))

# reInstallApk("BBS")

installApk("BBS")

因为有保密协议,对部分数据进行了和谐, 因为咱们的项目比较多,用这个可以提高工作效率

posted @ 2023-05-06 21:11  Please Call me 小强  阅读(101)  评论(0编辑  收藏  举报