import file_utils import config_utils import sys import os.path import json def packageChannel(): if len(sys.argv) < 2: print('argument is missing') return 1 channelConfig = sys.argv[1] jsonText = file_utils.readFile(channelConfig) config = json.loads(jsonText) print('*************config*****************') print(jsonText) print('************************************') # 检查配置 if not checkConfig(config): return 1 # 检查文件 gameApk = config['package'] if not os.path.exists(gameApk): print('%s not exists' % gameApk) if supportSignV2(gameApk): packageChannelV2(gameApk, config) else: packageChannelV1(gameApk, config) def supportSignV2(gameApk): ''' 验证是否APK Signature Scheme v2 ''' apksigner = file_utils.getApksignerPath() ret = getJavaResult(apksigner, 'verify --verbose "%s"' % gameApk) if '(APK Signature Scheme v2): true' in ret: return True return False def packageChannelV2(gameApk, config): walle = file_utils.getWallePath() if not os.path.exists(config['outPath']): os.makedirs(config['outPath']) successCount = 0 failureCount = 0 channels = config['channel'] for channel in channels: signedApk = os.path.join(config['outPath'], channel['outName'] + '.apk') print('add channel package %s...' % signedApk) appid = '' appkey = '' version = config_utils.getDate() if 'appid' in channel: appid = channel['appid'] if 'appkey' in channel: appkey = channel['appkey'] if 'version' in channel: version = channel['version'] ret = file_utils.execJarCmd(walle, 'put -e version=%s,agent=%s,appid=%s,appkey=%s "%s" "%s"' % (version, channel['agent'], appid, appkey, gameApk, signedApk)) if ret: failureCount += 1 else: successCount += 1 print('success %d, failure %d' % (successCount, failureCount)) def packageChannelV1(gameApk, config): # 解包 decompliePath = os.path.join(file_utils.getCurrentPath(), 'gen', 'channel') if os.path.exists(decompliePath): print('delete decomplie folder...') file_utils.deleteFolder(decompliePath) print('decomplie apk...') apktoolPath = file_utils.getApkToolPath() ret = file_utils.execJarCmd(apktoolPath, 'd -f "%s" -o "%s"' % (gameApk, decompliePath)) if ret: return ret if not os.path.exists(config['outPath']): os.makedirs(config['outPath']) alignapkTool = file_utils.getAlignPath() apksigner = file_utils.getApksignerPath() path = os.path.join(file_utils.getCurrentPath(), 'keystore', 'key.json') jsonText = file_utils.readFile(path) signConfig = json.loads(jsonText) keystore = signConfig['default'] storeFile = os.path.join(file_utils.getCurrentPath(), 'keystore', keystore['storeFile']) successCount = 0 failureCount = 0 channels = config['channel'] for channel in channels: changeChannel(decompliePath, channel) temp = channel['agent'] backApk = os.path.join(decompliePath, temp + '.apk') alignApk = os.path.join(decompliePath, temp + '_align.apk') signedApk = os.path.join(config['outPath'], channel['outName'] + '.apk') print('add channel package %s...' % signedApk) print('recomplie apk...') ret = file_utils.execJarCmd(apktoolPath, 'b -f "%s" -o "%s"' % (decompliePath, backApk)) if ret: failureCount += 1 continue print('align apk...') ret = file_utils.execFormatCmd('"%s" -f -p 4 "%s" "%s"' % (alignapkTool, backApk, alignApk)) if ret: failureCount += 1 continue print('sign apk...') ret = file_utils.execJarCmd(apksigner, 'sign --v2-signing-enabled=false --ks "%s" --ks-key-alias %s --ks-pass pass:%s --key-pass pass:%s --out "%s" "%s"' % (storeFile, keystore['keyAlias'], keystore['storePassword'], keystore['keyPassword'], signedApk, alignApk)) if ret: failureCount += 1 else: successCount += 1 if os.path.exists(alignApk): os.remove(alignApk) if os.path.exists(backApk): os.remove(backApk) print('success %d, failure %d' % (successCount, failureCount)) def changeChannel(decompliePath, channel): ''' 修改渠道 ''' properties = os.path.join(decompliePath, 'assets', 'jmhy.properties') appid = '' appkey = '' version = config_utils.getDate() if 'appid' in channel: appid = channel['appid'] if 'appkey' in channel: appkey = channel['appkey'] if 'version' in channel: version = channel['version'] content = 'version=%s\nagent=%s\nappid=%s\nappkey=%s' % (version, channel['agent'], appid, appkey) file_utils.createFile(properties, content) def checkConfig(config): if 'package' not in config: print('package not exists in config') return False if 'outPath' not in config: print('outPath not exists in config') return False if 'channel' not in config: print('channel not exists in config') return False return True def getJavaResult(jar, cmd): return getCmdResult('java -jar "%s" %s' % (jar, cmd)) def getCmdResult(cmd): p = os.popen(cmd) content = p.read() return content packageChannel()