Exemple #1
0
def recompileApk(workDir, decompileDir, game, channel, destApkName):

    targetApk = workDir + "/output.apk"
    log_utils.debug("now to recompileApk for %s", destApkName)
    ret = apk_utils.recompileApk(decompileDir, targetApk)
    if ret:
        return 1

    apk_utils.copyRootResFiles(targetApk, decompileDir)

    if 'signApk' not in channel or channel['signApk'] != '0':
        ret = apk_utils.signApk(workDir, game, channel, targetApk)
        if ret:
            return 1
    else:
        log_utils.debug("the apk is set to unsigned.")

    channelNameStr = channel["name"].replace(' ', '')

    # if isPublic:
    #     #destApkName = channelNameStr + '-' + time.strftime('%Y%m%d%H') + '.apk'
    #     destApkName = apk_utils.getOutputApkName(game, channel, newPackageName, decompileDir)
    # else:
    #     destApkName = channelNameStr + '-' + time.strftime('%Y%m%d%H') + '-debug.apk'

    destApkPath = file_utils.getFullOutputPath(game["appName"],
                                               channel["name"])
    destApkPath = os.path.join(destApkPath, destApkName)
    ret = apk_utils.alignApk(targetApk, destApkPath)
    if ret:
        return 1

    log_utils.info("channel %s package success to %s.", channel["name"],
                   destApkName)
    return 0
Exemple #2
0
def pack(game, channel, sourcepath, isPublic):

    sourcepath = sourcepath.replace('\\', '/')
    if not os.path.exists(sourcepath):
        return 1

    appID = game['appID']
    appKey = game['appKey']
    appName = game['appName']

    channelId = channel["id"]
    channelName = channel["name"]
    sdkName = channel["sdk"]

    log_utils.info("now to package %s...", channelName)

    workDir = 'workspace/' + appName + '/' + channelName
    workDir = file_utils.getFullPath(workDir)

    file_utils.del_file_folder(workDir)
    tempApkSource = workDir + "/temp.apk"
    file_utils.copy_file(sourcepath, tempApkSource)
    decompileDir = workDir + "/decompile"
    ret = apk_utils.decompileApk(tempApkSource, decompileDir)

    if ret:
        return 1

    #检查母包接入是否正确
    # ret = apk_utils.checkApkForU8SDK(workDir, decompileDir)
    # if ret:
    #     return 1

    #检查multidex那个jar包
    apk_utils.checkMultiDexJar(workDir, decompileDir)

    #change xml config and so on
    newPackageName = apk_utils.renamePackageName(channel, decompileDir,
                                                 channel['suffix'], isPublic)

    #copy third-plugins resources. note:The third plugins must be operated before the main sdk.
    ret = apk_utils.handleThirdPlugins(workDir, decompileDir, game, channel,
                                       newPackageName)

    if ret:
        return 1

    #copy sdk code to decompileDir
    sdkSourceDir = file_utils.getFullPath('config/sdk/' + sdkName)
    smaliDir = decompileDir + "/smali"
    sdkDestDir = workDir + "/sdk/" + sdkName
    file_utils.copy_files(sdkSourceDir, sdkDestDir)

    if (not os.path.exists(sdkSourceDir + "/classes.dex")):
        ret = apk_utils.jar2dex(sdkSourceDir, sdkDestDir)
        if ret:
            return 1

    ret = apk_utils.dexes2smali(sdkDestDir, smaliDir, "baksmali.jar")
    if ret:
        return 1

    #copy main sdk resources.
    ret = apk_utils.copyResource(game, channel, newPackageName, sdkDestDir,
                                 decompileDir, channel['operations'],
                                 channelName)
    if ret:
        return 1

    #auto handle icon
    apk_utils.appendChannelIconMark(game, channel, decompileDir)

    #copy channel special resources
    ret = apk_utils.copyChannelResources(game, channel, decompileDir)
    if ret:
        return 1

    #copy game root resources and res resources
    apk_utils.copyAppResources(game, decompileDir)
    apk_utils.copyAppRootResources(game, decompileDir)

    #generate config files for apk to run.
    apk_utils.writeDevelopInfo(game, channel, decompileDir)
    apk_utils.writePluginInfo(channel, decompileDir)
    apk_utils.writeManifestMetaInfo(channel, decompileDir)
    apk_utils.writeLogConfig(game, decompileDir)

    #if the main sdk has special logic. execute the special logic script.
    ret = apk_utils.doSDKScript(channel, decompileDir, newPackageName,
                                sdkDestDir)
    if ret:
        return 1

    #if the game has some special logic. execute the special logic script.called post_script.py
    ret = apk_utils.doGamePostScript(game, channel, decompileDir,
                                     newPackageName)
    if ret:
        return 1

    #here to config the splash screen.
    ret = apk_utils.addSplashScreen(workDir, channel, decompileDir)
    if ret:
        return 1

    #check cpu supports
    apk_utils.checkCpuSupport(game, decompileDir)

    #modify game name if channel specified.
    apk_utils.modifyGameName(channel, decompileDir)

    #modify yml
    apk_utils.modifyYml(game, newPackageName, decompileDir)

    #generate new R.java
    ret = apk_utils.generateNewRFile(newPackageName, decompileDir, channel)
    if ret:
        return 1

    #check to split dex
    apk_utils.splitDex(workDir, decompileDir)

    targetApk = workDir + "/output.apk"
    log_utils.debug("now to recompileApk....")
    ret = apk_utils.recompileApk(decompileDir, targetApk)
    if ret:
        return 1

    apk_utils.copyRootResFiles(targetApk, decompileDir)

    if 'signApk' not in channel or channel['signApk'] != '0':
        ret = apk_utils.signApk(workDir, game, channel, targetApk)
        if ret:
            return 1
    else:
        log_utils.debug("the apk is set to unsigned.")

    #destApkName = channelName + '.apk'
    channelNameStr = channelName.replace(' ', '')

    if isPublic:
        #destApkName = channelNameStr + '-' + time.strftime('%Y%m%d%H') + '.apk'
        destApkName = apk_utils.getOutputApkName(game, channel, newPackageName,
                                                 decompileDir)
    else:
        destApkName = channelNameStr + '-' + time.strftime(
            '%Y%m%d%H') + '-debug.apk'

    destApkPath = file_utils.getFullOutputPath(appName, channelName)
    destApkPath = os.path.join(destApkPath, destApkName)
    ret = apk_utils.alignApk(targetApk, destApkPath)

    if ret:
        return 1

    #clear workspace
    #file_utils.del_file_folder(workDir)

    log_utils.info("channel %s package success.", channelName)
    return 0
Exemple #3
0
def doPack(package_info):
    channelConfig, logger, logfilepath = getChannelConfig(package_info)
    workDirCls = dir_utils.WorkDirCls(
        rootDir, channelConfig['game_info']['game_id'],
        channelConfig['game_info']['game_bundle_id'],
        channelConfig['game_info']['channel_flag'],
        channelConfig['game_info']['channel_version'])
    logger.info(channelConfig)
    workDir = workDirCls.workRootDir
    if not os.path.exists(workDir):
        os.makedirs(workDir)
    # 反编译apk
    logger.info('clean workdir')
    file_utils.del_file_folder(workDir)
    logger.info("copy sourceapk to workdir")
    apkSource = os.path.join(workDir, 'temp.apk')
    file_utils.copy_file(channelConfig['game_info']['source_apk'], apkSource)
    logger.info("decompile apk")
    ret, cmd, result = apk_utils.decompileApk(apkSource,
                                              workDirCls.workDecompileDir,
                                              apktoolPath)  ###反编译
    logger.info(cmd)
    logger.info(str(ret) + "======" + result)
    #删除原SDK相关内容
    logger.info("delete default sdk info")
    ret, result = apk_utils.removeDefaultSDKInfo(workDirCls.workDecompileDir,
                                                 defaultSDKInfoConfigFile)
    logger.info(str(ret) + "======" + result)
    # 对资源进行特殊处理(删除layout-v26/abc_screen_toolbar.xml中的android:keyboardNavigationCluster、删除drawable-v24/ic_launcher_foreground.xml中的android:fillType)
    logger.info("handle special resource")
    ret, result = apk_utils.handleSpecialResource(workDirCls.workDecompileDir)
    logger.info(str(ret) + "======" + result)
    #拷贝sdk插件到工作目录
    logger.info("copy sdk plugin to workdir")

    #拷贝渠道SDK到工作目录
    channelSdk = os.path.join(channelSdkPath,
                              channelConfig['game_info']['channel_flag'],
                              channelConfig['game_info']['channel_version'])
    file_utils.copy_files(channelSdk, workDirCls.workSDKDir)

    #拷贝媒体SDK到工作目录
    if channelConfig['ad_sdk'].has_key(
            'media_flag') and channelConfig['ad_sdk']['media_flag'] > 0:
        madiaSdk = os.path.join(mediaSdkPath,
                                channelConfig['ad_sdk']['media_flag'],
                                channelConfig['game_info']['media_version'])
        file_utils.copy_files(madiaSdk, workDirCls.workSDKDir)

    #copy头条aar
    #logger.info("if has toutiao, copy toutiao plugin to workdir")
    #if channelConfig['ad_sdk'].has_key('tt_id') and len(channelConfig['ad_sdk']['tt_id']) > 0:
    #    toutiaoPluginDir = os.path.join(workDirCls.channelsDir, 'toutiao')
    #    file_utils.copy_files(toutiaoPluginDir, workDirCls.workSDKDir)
    #copy广点通aar
    #logger.info("if has gdt, copy gdt plugin to workdir")
    #if channelConfig['ad_sdk'].has_key('gdt_id') and channelConfig['ad_sdk'].has_key('gdt_secret_key') and len(channelConfig['ad_sdk']['gdt_id']) > 0 and len(channelConfig['ad_sdk']['gdt_secret_key']) > 0:
    #    gdtPluginDir = os.path.join(workDirCls.channelsDir, 'gdt')
    #    file_utils.copy_files(gdtPluginDir, workDirCls.workSDKDir)
    #copy快手aar
    #logger.info("if has kuaishou, copy kuaishou plugin to workdir")
    #if channelConfig['ad_sdk'].has_key('ks_id') and len(channelConfig['ad_sdk']['ks_id']) > 0 and channelConfig['ad_sdk'].has_key('ks_name') and len(channelConfig['ad_sdk']['ks_name']) > 0:
    #    kuaishouPluginDir = os.path.join(workDirCls.channelsDir, 'kuaishou')
    #    file_utils.copy_files(kuaishouPluginDir, workDirCls.workSDKDir)
    #copy独代aar
    #logger.info("if has dudai, copy dudai plugin to workdir")
    #if channelConfig['game_info'].has_key('is_dudai') and channelConfig['game_info']['is_dudai'] == 'true':
    #    dudaiPluginDir = os.path.join(workDirCls.channelsDir, 'dudai')
    #    file_utils.copy_files(dudaiPluginDir, workDirCls.workSDKDir)

    #aar模式需进行解压和资源合并
    logger.info("in workdir, unzip aar and zip, then merge")
    if apk_utils.isAarMode(workDirCls.workSDKDir):
        apk_utils.unzipAarFiles(workDirCls.workSDKDir)
        apk_utils.mergeAarFiles(workDirCls.workSDKDir)
    # copy libs(.jar除外)
    logger.info("copy sdk libs(except jar) to decompile dir")
    ret, result = apk_utils.copyLibs(
        os.path.join(workDirCls.workSDKDir, 'libs'),
        os.path.join(workDirCls.workDecompileDir, 'lib'))
    logger.info(str(ret) + "======" + result)
    # 处理lib文件夹,仅保留一个,防止不一致导致部分机型崩溃
    logger.info("handle lib dir(cpu type)")
    ret, result = apk_utils.deleteOtherLibDir(
        os.path.join(workDirCls.workDecompileDir, 'lib'),
        channelConfig['game_info']['partner_id'])
    logger.info(str(ret) + "======" + result)
    #copy 渠道res
    logger.info("copy sdk res to decompile res dir")
    ret, result = apk_utils.copyResToApk(
        os.path.join(workDirCls.workSDKDir, 'res'),
        os.path.join(workDirCls.workDecompileDir, 'res'))
    logger.info(str(ret) + "======" + result)
    #copy 渠道assets
    logger.info("copy sdk assets to decompile assets dir")
    ret, result = apk_utils.copyResToApk(
        os.path.join(workDirCls.workSDKDir, 'assets'),
        os.path.join(workDirCls.workDecompileDir, 'assets'))
    logger.info(str(ret) + "======" + result)
    #copy 其他资源
    logger.info("copy sdk other res to decompile dir")
    ret, result = apk_utils.copyOtherResToApk(workDirCls.workSDKDir,
                                              workDirCls.workDecompileDir)
    logger.info(str(ret) + "======" + result)
    #配置写入 独代配置暂时写死,没有更新
    logger.info("update conf file()")
    apk_utils.updateConfFile(channelConfig, workDirCls.workDecompileDir)
    #修改apktool.yml 版本号 targetSdkVersion
    logger.info(
        "update apktool.yml, include targetSdkVersion, version_code etc.")
    apk_utils.updateApktoolYmlFile(channelConfig, workDirCls.workDecompileDir)
    #修改包名,合并manifest 2019-08-01新增:应用宝渠道,在主activity里面添加url scheme 格式:scheme://host/path(path为分包名)
    logger.info("merge manifest")
    ret, result, oldPackageName = apk_utils.mergeManifest(
        os.path.join(workDirCls.workDecompileDir, 'AndroidManifest.xml'),
        os.path.join(workDirCls.workSDKDir, 'sdkmanifest.xml'), channelConfig)
    logger.info(str(ret) + "======" + result)
    #替换AndroidManifest里面的占位符
    logger.info("replace placeholder in manifest")
    apk_utils.replaceSpecialString(
        os.path.join(workDirCls.workDecompileDir, 'AndroidManifest.xml'),
        channelConfig, oldPackageName)
    #修改应用名称
    logger.info("update app display name")
    ret, result = apk_utils.updateAppDisplayName(
        workDirCls.workDecompileDir, channelConfig['game_info']['game_name'])
    logger.info(str(ret) + "======" + result)

    apk_utils.handle_drawable_v4(workDirCls.workDecompileDir)
    #修改icon
    if channelConfig['game_info'].has_key(
            'icon_file') and channelConfig['game_info'].has_key('icon_name'):
        logger.info("handle app icon")
        ret, result = apk_utils.handlePackageIcon(
            channelConfig['game_info']['icon_file'],
            workDirCls.workDecompileDir,
            channelConfig['game_info']['icon_name'])
        logger.info(str(ret) + "======" + result)

    #替换游戏素材(闪屏、loading、登录背景图)
    logger.info("replace app resource")
    if channelConfig['game_info'].has_key('game_resources') and len(
            channelConfig['game_info']['game_resources']
    ) > 0 and channelConfig['game_info'].has_key('resource_path') and len(
            channelConfig['game_info']['resource_path']) > 0:
        oldGameResourcePath = os.path.join(
            workDirCls.workDecompileDir,
            channelConfig['game_info']['resource_path'].replace('/', os.sep))
        for newGameResourcePath in channelConfig['game_info'][
                'game_resources']:
            file_utils.copy_file(
                newGameResourcePath,
                os.path.join(oldGameResourcePath,
                             os.path.basename(newGameResourcePath)))
    #重新生成R文件,编译,然后生成jar包搭配渠道的libs目录下
    logger.info("generate R file")
    ret, cmd, result = apk_utils.generateNewRFile(
        oldPackageName, channelConfig['game_info']['game_bundle_id'],
        workDirCls.workDecompileDir, toolsDir, channelConfig)
    logger.info(cmd)
    logger.info(str(ret) + "======" + result)
    #jar to dex
    logger.info("convert jar to dex")
    if not os.path.exists(
            os.path.join(workDirCls.currentChannelDir, "classes.dex")):
        ret, cmd, result = apk_utils.jar2dex(workDirCls.workSDKDir,
                                             workDirCls.workSDKDir,
                                             channelConfig)
        logger.info(cmd)
        logger.info(str(ret) + "======" + result)
    #dex to smali
    logger.info("convert dex to smali")
    sdkDexFile = os.path.join(workDirCls.workSDKDir, "classes.dex")
    ret, cmd, result = apk_utils.dex2smali(sdkDexFile,
                                           workDirCls.workDecompileSmaliDir,
                                           baksmaliJarPath)
    logger.info(cmd)
    logger.info(str(ret) + "======" + result)
    #应用宝/小米 多Dex处理
    if channelConfig['game_info']['partner_id'] == '3' or channelConfig[
            'game_info']['partner_id'] == '9':
        logger.info("handle multi dex")
        apk_utils.splitDex(workDirCls.workDecompileDir)

    # 处理需要特殊处理的smali文件
    apk_utils.handleSmali(channelConfig, workDirCls.workDecompileDir)

    #重新编译
    logger.info("compile new apk")
    targetApkFile = os.path.join(workDirCls.workTempDir, "output.apk")
    ret, cmd, result = apk_utils.recompileApk(workDirCls.workTempDir,
                                              workDirCls.workDecompileDir,
                                              targetApkFile, apktoolPath)
    logger.info(cmd)
    logger.info(str(ret) + "======" + result)
    #签名
    logger.info("sign apk")
    signInfo = {
        "keystore": os.path.join(commonConfigDir, '7yol_default.keystore'),
        "password": "******",
        "aliaskey": "7yol_default",
        "aliaspwd": "Aa314159"
    }
    ret, cmd, result = apk_utils.signApk(targetApkFile, signInfo)
    logger.info(cmd)
    logger.info(str(ret) + "======" + result)
    #对齐
    logger.info("align apk")
    targetZApk = os.path.join(workDirCls.workTempDir, "outputZ.apk")
    ret, cmd, result = apk_utils.alignApk(zipalignToolPath, targetApkFile,
                                          targetZApk)
    logger.info(cmd)
    logger.info(str(ret) + "======" + result)
    #copy到target目录
    logger.info("copy apk to target dir")
    targetApkFileName = os.path.splitext(os.path.basename(logfilepath))[0]
    targetApkFilePath = os.path.join(
        channelConfig['game_info']['target_apk'],
        channelConfig['game_info']['game_id'],
        channelConfig['game_info']['channel_flag'],
        channelConfig['game_info']['game_bundle_id'],
        targetApkFileName + '.apk')
    file_utils.copy_file(targetZApk, targetApkFilePath)
    if os.path.exists(targetApkFilePath):
        logger.info("pack success!!!===target apk is: %s" % targetApkFilePath)
        print '{"status":1, "apkPath":"%s", "logPath": "%s"}' % (
            targetApkFilePath, logfilepath)
    else:
        logger.info("pack fail")
        print '{"status":0, "logPath": "%s"}' % (logfilepath)
def pack(game, channel, sourcepath, isPublic):

    sourcepath = sourcepath.replace("\\", "/")
    if not os.path.exists(sourcepath):
        return 1

    appID = game["appID"]
    appKey = game["appKey"]
    appName = game["appName"]

    channelId = channel["id"]
    channelName = channel["name"]
    sdkName = channel["sdk"]

    log_utils.info("now to package %s...", channelName)

    workDir = "workspace/" + appName + "/" + channelName
    workDir = file_utils.getFullPath(workDir)

    file_utils.del_file_folder(workDir)
    tempApkSource = workDir + "/temp.apk"
    file_utils.copy_file(sourcepath, tempApkSource)
    decompileDir = workDir + "/decompile"
    ret = apk_utils.decompileApk(tempApkSource, decompileDir)

    if ret:
        return 1

    # 检查母包接入是否正确
    # ret = apk_utils.checkApkForU8SDK(workDir, decompileDir)
    # if ret:
    #     return 1

    # copy sdk code to decompileDir
    sdkSourceDir = file_utils.getFullPath("config/sdk/" + sdkName)
    smaliDir = decompileDir + "/smali"
    sdkDestDir = workDir + "/sdk/" + sdkName
    file_utils.copy_files(sdkSourceDir, sdkDestDir)

    if not os.path.exists(sdkSourceDir + "/classes.dex"):
        apk_utils.jar2dex(sdkSourceDir, sdkDestDir)

    sdkDexFile = sdkDestDir + "/classes.dex"
    ret = apk_utils.dex2smali(sdkDexFile, smaliDir, "baksmali.jar")
    if ret:
        return 1

    # change xml config and so on
    newPackageName = apk_utils.renamePackageName(channel, decompileDir, channel["suffix"], isPublic)

    # copy third-plugins resources. note:The third plugins must be operated before the main sdk.
    ret = apk_utils.handleThirdPlugins(workDir, decompileDir, game, channel, newPackageName)

    if ret:
        return 1

    # copy main sdk resources.
    ret = apk_utils.copyResource(
        game, channel, newPackageName, sdkDestDir, decompileDir, channel["operations"], channelName
    )
    if ret:
        return 1

    # copy channel special resources
    ret = apk_utils.copyChannelResources(game, channel, decompileDir)
    if ret:
        return 1

    # copy game root resources and res resources
    apk_utils.copyAppResources(game, decompileDir)
    apk_utils.copyAppRootResources(game, decompileDir)
    apk_utils.appendChannelIconMark(game, channel, decompileDir)

    # generate config files for apk to run.
    apk_utils.writeDevelopInfo(appID, appKey, channel, decompileDir)
    apk_utils.writePluginInfo(channel, decompileDir)
    apk_utils.writeManifestMetaInfo(channel, decompileDir)

    # if the main sdk has special logic. execute the special logic script.
    ret = apk_utils.doSDKScript(channel, decompileDir, newPackageName, sdkDestDir)
    if ret:
        return 1

    # if the game has some special logic. execute the special logic script.called post_script.py
    ret = apk_utils.doGamePostScript(game, channel, decompileDir, newPackageName)
    if ret:
        return 1

    # here to config the splash screen.
    ret = apk_utils.addSplashScreen(workDir, channel, decompileDir)
    if ret:
        return 1

    # check cpu supports
    apk_utils.checkCpuSupport(game, decompileDir)

    # modify game name if channel specified.
    apk_utils.modifyGameName(channel, decompileDir)

    # generate new R.java
    ret = apk_utils.generateNewRFile(newPackageName, decompileDir)
    if ret:
        return 1

    targetApk = workDir + "/output.apk"
    ret = apk_utils.recompileApk(decompileDir, targetApk)
    if ret:
        return 1

    apk_utils.copyRootResFiles(targetApk, decompileDir)

    ret = apk_utils.signApk(appName, channelId, targetApk)
    if ret:
        return 1

    # destApkName = channelName + '.apk'
    channelNameStr = channelName.replace(" ", "")

    if isPublic:
        destApkName = channelNameStr + "-" + time.strftime("%Y%m%d%H") + ".apk"
    else:
        destApkName = channelNameStr + "-" + time.strftime("%Y%m%d%H") + "-debug.apk"

    destApkPath = file_utils.getFullOutputPath(appName, channelName)
    destApkPath = os.path.join(destApkPath, destApkName)
    ret = apk_utils.alignApk(targetApk, destApkPath)

    if ret:
        return 1

    # clear workspace
    # file_utils.del_file_folder(workDir)

    log_utils.info("channel %s package success.", channelName)
    return 0
Exemple #5
0
def pack(game, channel, sourcepath, isPublic):

    sourcepath = sourcepath.replace('\\', '/')
    if not os.path.exists(sourcepath):
        return 1

    appID = game['appID']
    appKey = game['appKey']
    appName = game['appName']

    channelId = channel["id"]
    channelName = channel["name"]
    sdkName = channel["sdk"]

    log_utils.info("now to package %s...", channelName)

    workDir = 'workspace/' + appName + '/' + channelName
    workDir = file_utils.getFullPath(workDir)

    file_utils.del_file_folder(workDir)
    tempApkSource = workDir + "/temp.apk"
    file_utils.copy_file(sourcepath, tempApkSource)
    decompileDir = workDir + "/decompile"
    ret = apk_utils.decompileApk(tempApkSource, decompileDir)

    if ret:
        return 2

    #检查母包接入是否正确
    # ret = apk_utils.checkApkForU8SDK(workDir, decompileDir)
    # if ret:
    #     return 1

    #检查multidex那个jar包
    apk_utils.checkMultiDexJar(workDir, decompileDir)

    #更改XML配置等
    newPackageName = apk_utils.renamePackageName(channel, decompileDir,
                                                 channel['suffix'], isPublic)

    #复制第三插件资源。注意:这第三个插件必须在主SDK之前运行。
    ret = apk_utils.handleThirdPlugins(workDir, decompileDir, game, channel,
                                       newPackageName)

    if ret:
        return 3

    #将SDK代码复制到反编译程序
    sdkSourceDir = file_utils.getFullPath('config/sdk/' + sdkName)
    smaliDir = decompileDir + "/smali"
    sdkDestDir = workDir + "/sdk/" + sdkName
    file_utils.copy_files(sdkSourceDir, sdkDestDir)

    if (not os.path.exists(sdkSourceDir + "/classes.dex")):
        ret = apk_utils.jar2dex(sdkSourceDir, sdkDestDir)
        if ret:
            return 4

    ret = apk_utils.dexes2smali(sdkDestDir, smaliDir, "baksmali.jar")
    if ret:
        return 5

    #复制主SDK资源。
    ret = apk_utils.copyResource(game, channel, newPackageName, sdkDestDir,
                                 decompileDir, channel['operations'],
                                 channelName)
    if ret:
        return 6

    #自动处理图标
    apk_utils.appendChannelIconMark(game, channel, decompileDir)

    #复制渠道专用资源
    ret = apk_utils.copyChannelResources(game, channel, decompileDir)
    if ret:
        return 7

    #复制游戏根资源和资源
    apk_utils.copyAppResources(game, decompileDir)
    apk_utils.copyAppRootResources(game, decompileDir)

    #生成APK运行的配置文件。
    apk_utils.writeDevelopInfo(game, channel, decompileDir)
    apk_utils.writePluginInfo(channel, decompileDir)
    apk_utils.writeManifestMetaInfo(channel, decompileDir)
    apk_utils.writeLogConfig(game, decompileDir)

    #如果主SDK具有特殊逻辑。执行特殊的逻辑脚本。
    ret = apk_utils.doSDKScript(channel, decompileDir, newPackageName,
                                sdkDestDir)
    if ret:
        return 8

    #如果游戏有一些特殊的逻辑。执行特殊的逻辑脚本。 post_script.py
    ret = apk_utils.doGamePostScript(game, channel, decompileDir,
                                     newPackageName)
    if ret:
        return 9

    #here to config the splash screen.
    ret = apk_utils.addSplashScreen(workDir, channel, decompileDir)
    if ret:
        return 10

    #检查CPU支持
    apk_utils.checkCpuSupport(game, decompileDir)

    #如果指定频道,修改游戏名称。
    apk_utils.modifyGameName(channel, decompileDir)

    #修改YML
    apk_utils.modifyYml(game, newPackageName, decompileDir)
    #到达复制sdk到临时目录

    #生成新的R.java
    print('生成新的R.java')
    print(newPackageName)
    print(decompileDir)
    print(channel)
    print('===================================')
    ret = apk_utils.generateNewRFile(newPackageName, decompileDir, channel)
    if ret:
        return 11

    #检查分离DEX
    apk_utils.splitDex(workDir, decompileDir)

    targetApk = workDir + "/output.apk"
    log_utils.debug("现在重新编译APK....")
    ret = apk_utils.recompileApk(decompileDir, targetApk)
    if ret:
        return 12

    apk_utils.copyRootResFiles(targetApk, decompileDir)  #复制根目录

    ###

    #destApkName = channelName + '.apk'
    channelNameStr = channelName.replace(' ', '')

    if isPublic:  # 获取最终apk包名
        #destApkName = channelNameStr + '-' + time.strftime('%Y%m%d%H') + '.apk'
        destApkName = apk_utils.getOutputApkName(game, channel, newPackageName,
                                                 decompileDir)
    else:
        destApkName = channelNameStr + '-' + time.strftime(
            '%Y%m%d%H') + '-debug.apk'

    destApkPath = file_utils.getFullOutputPath(appName, channelName)
    destApkPath = os.path.join(destApkPath, destApkName)
    ret = apk_utils.alignApk(targetApk, destApkPath)

    if ret:
        return 13

    if 'signApk' not in channel or channel['signApk'] != '0':
        ret = apk_utils.signApk(workDir, game, channel,
                                destApkPath)  #对已经输出的安装包进行签名
        if ret:
            return 14
    else:
        log_utils.debug("APK设置为未签名。")

    #clear workspace
    #file_utils.del_file_folder(workDir)

    log_utils.info("游戏 %s 渠道 %s 打包成功.", appName, channelName)
    return 0
Exemple #6
0
def pack(game, channel, sourcepath, isPublic):

    sourcepath = sourcepath.replace('\\', '/')
    if not os.path.exists(sourcepath):
        return 1

    appID = game['appID']
    appKey = game['appKey']
    appName = game['appName']

    channelId = channel["id"]
    channelName = channel["name"]
    sdkName = channel["sdk"]

    log_utils.info("now to package %s...", channelName)

    workDir = 'workspace/' + appName + '/' + channelName
    workDir = file_utils.getFullPath(workDir)

    file_utils.del_file_folder(workDir)
    tempApkSource = workDir + "/temp.apk"
    file_utils.copy_file(sourcepath, tempApkSource)
    decompileDir = workDir + "/decompile"
    smaliDir = decompileDir + "/smali"

    #反编译APK
    ret = apk_utils.decompileApk(tempApkSource, decompileDir)
    if ret:
        return 1

    #检查母包接入是否正确
    ret = apk_utils.checkApkForU8SDK(workDir, decompileDir)
    if ret:
        return 1

    #change xml config and so on
    newPackageName = apk_utils.renamePackageName(channel, decompileDir, channel['suffix'], isPublic)

    #copy third-plugins resources. note:The third plugins must be operated before the main sdk.
    ret = apk_utils.handleThirdPlugins(workDir, decompileDir, game, channel, newPackageName)
    if ret:
        return 1

    #copy sdk code to decompileDir
    sdkSourceDir = 'config/sdk/' + sdkName
    sdkSourceDir = file_utils.getFullPath(sdkSourceDir)
    sdkDestDir = workDir + "/sdk/" + sdkName
    file_utils.copy_files(sdkSourceDir, sdkDestDir)

    #将公共库复制到临时目录,除了moyoihw渠道
    if sdkName != 'moyoihw':
        promptDir = 'config/local/common-release.aar'
        promptDestDir = sdkDestDir + '/libs/common-release.aar';
        file_utils.copy_files(promptDir, promptDestDir)

    
    #处理需要Gradle自动下载的库
    if 'dependencies' in channel and channel['dependencies'] != None and len(channel['dependencies']) > 0:      
        #将build.gradle复制到临时目录
        localSourceDir = 'config/local/build.gradle'
        file_utils.copy_files(localSourceDir, sdkDestDir + '/build.gradle')

        #修改build.gradle
        config_utils.writeGradleDependencies(channel['dependencies'], sdkDestDir)
        
    #将SDK中所有aar文件解压,然后将里面各个类型的资源文件合并到SDK对应目录
    file_utils.decomAAR(sdkDestDir)

    ret = apk_utils.jar2dex(sdkDestDir, sdkDestDir)
    if ret:
        return 1

    ret = apk_utils.dexes2smali(sdkDestDir, smaliDir, "baksmali.jar")
    if ret:
        return 1

    #copy main sdk resources.
    ret = apk_utils.copyResource(game, channel, newPackageName, sdkDestDir, decompileDir, channel['operations'], channelName)
    if ret:
        return 1

    #auto handle icon
    apk_utils.appendChannelIconMark(game, channel, decompileDir)

    #copy channel special resources
    ret = apk_utils.copyChannelResources(game, channel, decompileDir)
    if ret:
        return 1

    #copy game root resources and res resources
    apk_utils.copyAppResources(game, decompileDir)
    apk_utils.copyAppRootResources(game, decompileDir)
    

    #generate config files for apk to run.
    apk_utils.writeDevelopInfo(game, channel, decompileDir)
    apk_utils.writePluginInfo(channel, decompileDir)
    apk_utils.writeManifestMetaInfo(channel, decompileDir)
    apk_utils.writeLogConfig(game, decompileDir)

    #if the main sdk has special logic. execute the special logic script.
    ret = apk_utils.doSDKScript(channel, decompileDir, newPackageName, sdkDestDir)
    if ret:
        return 1

    #if the game has some special logic. execute the special logic script.called post_script.py
    ret = apk_utils.doGamePostScript(game, channel, decompileDir, newPackageName)
    if ret:
        return 1

    #here to config the splash screen.
    ret = apk_utils.addSplashScreen(workDir, channel, decompileDir)
    if ret:
        return 1

    #check cpu supports
    apk_utils.checkCpuSupport(game, decompileDir)

    #modify game name if channel specified.
    apk_utils.modifyGameName(channel, decompileDir)

    #modify yml
    apk_utils.modifyYml(game, newPackageName, decompileDir)

    #generate new R.java
    ret = apk_utils.generateNewRFile(newPackageName, decompileDir, channel)
    if ret:
        return 1

    #check to split dex
    apk_utils.splitDex(workDir, decompileDir)

    targetApk = workDir + "/output.apk"
    log_utils.debug("now to recompileApk....")
    ret = apk_utils.recompileApk(decompileDir, targetApk)
    if ret:
        return 1

    apk_utils.copyRootResFiles(targetApk, decompileDir)

    if 'signApk' not in channel or channel['signApk'] != '0':
        apk_utils.xsigncode(workDir, game, channel, targetApk)
  
        apk_utils.signApk(workDir, game, channel, targetApk)
    else:
        log_utils.debug("the apk is set to unsigned.")
    
    channelNameStr = channelName.replace(' ', '')

    if isPublic:
        destApkName = apk_utils.getOutputApkName(game, channel, newPackageName, decompileDir)
    else:
        destApkName = channelNameStr + '-' + time.strftime('%Y%m%d%H') + '-debug.apk'

    destApkPath = file_utils.getFullOutputPath(appName, channelName)
    destApkPath = os.path.join(destApkPath, destApkName)
    ret = apk_utils.alignApk(targetApk, destApkPath)
    if ret:
        return 1

    log_utils.info("channel %s package success.", channelName)
    return 0