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
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
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
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
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