def get_paths_for_provider(filePath): if not os.path.exists(filePath): return list() ET.register_namespace('android', androidNS) tree = ET.parse(filePath) root = tree.getroot() pathNode = root if pathNode.tag != 'paths': nodes = list(pathNode) pathNode = nodes[0] if pathNode.tag != 'paths': log_utils.error("file provider file not valid ? :" + filePath) return list() nodes = list(pathNode) result = list() for node in nodes: item = dict() item['tag'] = node.tag item['name'] = node.get('name') item['path'] = node.get('path') result.append(item) return result
def generate_rindex_v2(workDir, genPath, resPath, manifestPath): """ generate R.java with appt2 """ androidPath = file_utils.getFullToolPath("android.jar") if platform.system() == 'Windows': aapt2Path = file_utils.getFullToolPath("aapt2.exe") else: aapt2Path = file_utils.getFullToolPath("aapt2") if not os.path.exists(aapt2Path): log_utils.error("aapt2 is not exists in tool") return False #compile res first... resFlatPath = workDir + "/res_flat.zip" cmd = '"%s" compile -o "%s" --dir "%s" -v' % (aapt2Path, resFlatPath, resPath) ret = file_utils.exec_cmd(cmd) if not ret: return False #link res to generate R.java resTempPath = workDir + "/res.apk" cmd = '"%s" link -o "%s" --manifest "%s" -I "%s" --java "%s" "%s" -v' % ( aapt2Path, resTempPath, manifestPath, androidPath, genPath, resFlatPath) ret = file_utils.exec_cmd(cmd) return ret
def signApkInternal(apkfile, keystore, password, alias, aliaspwd, sigalg): apkfile = file_utils.getFullPath(apkfile) keystore = file_utils.getFullPath(keystore) aapt = file_utils.getFullToolPath("aapt") if not os.path.exists(keystore): log_utils.error("the keystore file is not exists. %s", keystore) return 1 listcmd = '%s list %s' % (aapt, apkfile) output = os.popen(listcmd).read() for filename in output.split('\n'): if filename.find('META_INF') == 0: rmcmd = '"%s" remove "%s" "%s"' % (aapt, apkfile, filename) file_utils.execFormatCmd(rmcmd) if sigalg is None: sigalg = "SHA1withRSA" signcmd = '"%sjarsigner" -digestalg SHA1 -sigalg %s -keystore "%s" -storepass "%s" -keypass "%s" "%s" "%s" ' % ( file_utils.getJavaBinDir(), sigalg, keystore, password, aliaspwd, apkfile, alias) ret = file_utils.execFormatCmd(signcmd) return ret
def copySplashToUnityResFolder(workDir, channel, decompileDir): splashPath = file_utils.getSplashPath() resPath = workDir + "/sdk/" + channel['name'] + "/splash/" + channel['splash'] + "/%s/u8_splash.png" resTargetPath = decompileDir + "/assets/bin/Data/splash.png" paths = ['drawable', 'drawable-hdpi', 'drawable-ldpi', 'drawable-mdpi', 'drawable-xhdpi'] bFound = False for path in paths: imgPath = resPath % path if os.path.exists(imgPath): resPath = imgPath bFound = True break if not bFound: log_utils.error("the u8_splash is not found.path:%s", resPath) return 1 if not os.path.exists(resTargetPath): log_utils.error("the unity splash is not exists. path:%s", resTargetPath) return 1 file_utils.copy_file(resPath, resTargetPath) return 0
def modify_gradle_dependencies(projPath, dependencyList): dependencyStr = "" for d in dependencyList: name = d['name'] excludes = None if 'excludes' in d: excludes = d['excludes'] name = name.strip() if excludes == None: dependencyStr += "scm '" + name + "'\n\t" else: dependencyStr += "scm('" + name + "'){\n\t" + parse_excludes( excludes) dependencyStr += "\n\t}\n\t" buildPath = os.path.join(projPath, 'app/build.gradle') if not os.path.exists(buildPath): log_utils.error("build.gradle is not exists: %s", buildPath) return False file_utils.modifyFileContent(buildPath, "${U8_DEPENDENCIES_PLACEHOLDER}", dependencyStr) return True
def test(self, dataset, remaining_time_budget=None): """Test method of domain-specific model.""" # Convert test dataset to necessary format and # store as self.domain_dataset_test # Make predictions if self.done_training is True or self.has_exception is True: return self.y_pred_last try: Y_pred = self.domain_model.test(dataset, remaining_time_budget=remaining_time_budget) self.y_pred_last = Y_pred # Update self.done_training self.done_training = self.domain_model.done_training except MemoryError as mem_error: self.has_exception = True self.done_training = True error("Error, model_test OutOfMemoryError={}, done_traning={}".format(mem_error, self.done_training)) except Exception as exp: self.has_exception = True self.done_training = True error("Error, model_test exp={}, done_traning={}".format(exp, self.done_training)) # return Y_pred return self.y_pred_last
def merge(manifestFiles): if manifestFiles == None or len(manifestFiles) == 0: return True manifests = list() for manifest in manifestFiles: if os.path.exists(manifest): m = ManifestFile.create(manifest) manifests.append(m) else: log_utils.warning("manifest file not exists. just igore. " + manifest) if len(manifests) <= 1: log_utils.debug("manifest file no need to merge") return True baseManifest = manifests.pop(len(manifests) - 1) for manifest in manifests: if not manifest.can_merge_to(baseManifest): log_utils.error("manifest merge failed. %s and %s has same node.", manifest.path(), baseManifest.path()) return False ret = baseManifest.merge_with(manifest) if not ret: return False return True
def getAllGames(): """ get all games """ configFile = file_utils.getFullPath("games/games.xml") try: tree = ET.parse(configFile) root = tree.getroot() except Exception as e: log_utils.error("can not parse games.xml.path:%s", configFile) return None gamesNode = root.find('games') if gamesNode == None: return None games = gamesNode.findall('game') if games == None or len(games) <= 0: return None lstGames = [] for cNode in games: game = {} params = cNode.findall('param') if params != None and len(params) > 0: for cParam in params: key = cParam.get("name") val = cParam.get("value") game[key] = val lstGames.append(game) return lstGames
def get_file_provider_res_file_name(self, component): key = '{' + androidNS + '}name' resourceKey = '{' + androidNS + '}resource' metaNodes = component.node.findall('meta-data') if metaNodes == None or len(metaNodes) == 0: log_utils.error( "merge android.support.v4.content.FileProvider failed. no meta-data info" ) return None for node in metaNodes: name = node.get(key) if name == 'android.support.FILE_PROVIDER_PATHS': resFile = node.get(resourceKey) if (not resFile.startswith('@xml/')): log_utils.error( "merge android.support.v4.content.FileProvider failed. android.support.FILE_PROVIDER_PATHS error:" + resFile) return False resFile = resFile[ 5:] + ".xml" #remove @xml/ and append .xml file ext return resFile return None
def merge_jni(self, targetLibs): if not os.path.exists(self.aarDir): log_utils.warning("the aar is not unarchived:" + self.aarFile) return False jniPath = os.path.join(self.aarDir, "jni") if not os.path.exists(jniPath): log_utils.debug( "aar jni merge completed. there is no jni folder in " + self.aarFile) return True for f in os.listdir(jniPath): cpuPath = os.path.join(jniPath, f) for c in os.listdir(cpuPath): cpuTargetPath = os.path.join(targetLibs, f, c) if os.path.exists(cpuTargetPath): log_utils.error("jni in aar " + self.aarFile + " merge failed. " + c + " already exists in " + targetLibs) return False file_utils.copy_file(os.path.join(cpuPath, c), cpuTargetPath) log_utils.debug(f + "/" + c + " in aar " + self.aarFile + " copied to " + targetLibs) return True
def addOrUpdateMetaData(decompileDir, metaDataKey, metaDataVal): manifestFile = decompileDir + "/AndroidManifest.xml" ET.register_namespace('android', androidNS) key = '{' + androidNS + '}name' valKey = '{' + androidNS + '}value' tree = ET.parse(manifestFile) root = tree.getroot() applicationNode = root.find('application') if applicationNode is None: log_utils.error("application node is not exists in AndroidManifest.xml") return '' bFound = False metadataNodes = applicationNode.findall('meta-data') if metadataNodes != None: for mnode in metadataNodes: keyName = mnode.get(key) if keyName == metaDataKey: bFound = True mnode.set(valKey, metaDataVal) break if not bFound: metaNode = SubElement(applicationNode, 'meta-data') metaNode.set(key, metaDataKey) metaNode.set(valKey, metaDataVal) tree.write(manifestFile, 'UTF-8')
def parse_method_default(className, line): if not line.startswith(".method"): log_utils.error("the line parse error in parse_method_default:"+line) return None blocks = line.split() return blocks[len(blocks)-1]
def dump_sdk_config(sdkDir, sdkObj): configFile = os.path.join(sdkDir, 'config.xml') if not os.path.exists(configFile): log_utils.error("the config.xml is not exists of sdk %s.path:%s", sdkObj['sdk'], configFile) return False try: tree = ET.parse(configFile) configNode = tree.getroot() except Exception as e: log_utils.error("can not parse config.xml.path:%s", configFile) log_utils.exception(e) return False dependencyNodes = configNode.find('dependencies') if dependencyNodes != None: configNode.remove(dependencyNodes) extraRNodes = configNode.find("extraR") if extraRNodes != None and len(extraRNodes) > 0: configNode.remove(extraRNodes) if 'extraRList' in sdkObj and len(sdkObj['extraRList']) > 0: extraRNodes = SubElement(configNode, 'extraR') for r in sdkObj['extraRList']: pNode = SubElement(extraRNodes, 'package') pNode.set('name', r) pretty_xml(configNode, '\t', '\n') # 执行美化方法 tree.write(configFile, 'UTF-8') return sdkObj
def parse_proxy_application(channel, sdkManifest): """ parse proxy application in SDKManifest.xml """ if not os.path.exists(sdkManifest): log_utils.error("the manifest file is not exists.sdkManifest:%s", sdkManifest) return False ET.register_namespace('android', androidNS) sdkTree = ET.parse(sdkManifest) sdkRoot = sdkTree.getroot() appConfigNode = sdkRoot.find('applicationConfig') if appConfigNode != None: proxyApplicationName = appConfigNode.get('proxyApplication') if proxyApplicationName != None and len(proxyApplicationName) > 0: if 'U8_APPLICATION_PROXY_NAME' in channel: channel['U8_APPLICATION_PROXY_NAME'] = channel['U8_APPLICATION_PROXY_NAME'] + ',' + proxyApplicationName else: channel['U8_APPLICATION_PROXY_NAME'] = proxyApplicationName return True
def unzip_file(zipfilename, unziptodir): if not os.path.exists(unziptodir): os.makedirs(unziptodir) zfobj = zipfile.ZipFile(zipfilename) for name in zfobj.namelist(): try: name = name.replace('\\', '/') ext_filename = formatPath(os.path.join(unziptodir, name)) if name.endswith('/'): os.makedirs(ext_filename) else: ext_dir = os.path.dirname(ext_filename) if not os.path.exists(ext_dir): os.makedirs(ext_dir) log_utils.debug("unzip_file:" + ext_filename) ext_filename = win_expand_path(ext_filename) with open(ext_filename, 'wb') as outfile: outfile.write(zfobj.read(name)) except Exception as e: log_utils.error("unzip_file cause an exception:%s", repr(e))
def getAllKeystores(appName): fileName = "games/" + appName + "/keystore.xml" configFile = file_utils.getFullPath(fileName) try: tree = ET.parse(configFile) root = tree.getroot() except Exception as e: log_utils.error("can not parse keystore.xml.path:%s", configFile) return None channels = root.find("keystores").findall("channel") lstKeystores = [] for cNode in channels: channel = {} params = cNode.findall("param") for cParam in params: key = cParam.get('name') val = cParam.get('value') channel[key] = val lstKeystores.append(channel) return lstKeystores
def getStartActivity(decompileDir): manifestFile = decompileDir + "/AndroidManifest.xml" ET.register_namespace('android', androidNS) key = '{' + androidNS + '}name' valKey = '{' + androidNS + '}value' tree = ET.parse(manifestFile) root = tree.getroot() applicationNode = root.find('application') if applicationNode is None: log_utils.error("application node is not exists in AndroidManifest.xml") return '' activityNodeLst = applicationNode.findall('activity') if activityNodeLst is None: log_utils.error("activity node is not exists in AndroidManifest.xml") return '' activityName = '' for activityNode in activityNodeLst: activityName = activityNode.get(key) bMain = False intentNodeLst = activityNode.findall('intent-filter') if intentNodeLst is None: break for intentNode in intentNodeLst: bFindAction = False bFindCategory = False actionNodeLst = intentNode.findall('action') if actionNodeLst is None: break for actionNode in actionNodeLst: if actionNode.attrib[key] == 'android.intent.action.MAIN': bFindAction = True break categoryNodeLst = intentNode.findall('category') if categoryNodeLst is None: break for categoryNode in categoryNodeLst: if categoryNode.attrib[key] == 'android.intent.category.LAUNCHER': bFindCategory = True break if bFindAction and bFindCategory: bMain = True break if bMain: activityName = activityNode.attrib[key] return activityName return None
def dex2smali(dexFile, targetdir, dextool="baksmali.jar"): """ Transfer the dex to smali. """ if not os.path.exists(dexFile): log_utils.error("the dexfile is not exists. path:%s", dexFile) return 1 if not os.path.exists(targetdir): os.makedirs(targetdir) smaliTool = file_utils.getFullToolPath(dextool) dexPath = os.path.dirname(dexFile) dexName = os.path.basename(dexFile) (dexBaseName, ext) = os.path.splitext(dexName) dexIndex = 2 dexFilePath = os.path.join(dexPath, dexName) while os.path.exists(dexFilePath): cmd = '"%s" -jar "%s" -o "%s" "%s"' % (file_utils.getJavaCMD(), smaliTool, targetdir, dexFilePath) ret = file_utils.execFormatCmd(cmd) if ret: return 1 dexFilePath = os.path.join(dexPath, dexBaseName + str(dexIndex) + ext) dexIndex = dexIndex + 1 # for k in range(1, 10): # baseName = dexBaseName # if k > 1: # baseName = baseName + str(k) # baseName = baseName + ext # dexFilePath = os.path.join(dexPath, baseName) # cmd = '"%s" -jar "%s" -o "%s" "%s"' % (file_utils.getJavaCMD(), smaliTool, targetdir, dexFilePath) # ret = file_utils.execFormatCmd(cmd) # if ret: # return 1 # if os.path.exists(dexFilePath): # if platform.system() == 'Darwin' or platform.system() == 'Linux': # cmd = '"%s" -jar "%s" -o "%s" "%s"' % (file_utils.getJavaCMD(), smaliTool, targetdir, dexFilePath) # ret = file_utils.execFormatCmd(cmd) # if ret: # return 1 # else: # cmd = '"%s" -jar "%s" disassemble -o "%s" "%s"' % (file_utils.getJavaCMD(), smaliTool, targetdir, dexFilePath) # ret = file_utils.execFormatCmd(cmd) # if ret: # return 1 return 0
def parse_class(line): if not line.startswith(".class"): log_utils.error("line parse error. not startswith .class : "+line) return None blocks = line.split() return blocks[len(blocks)-1]
def modify_gradle_dependencies_path(projPath, path): buildPath = os.path.join(projPath, 'app/build.gradle') if not os.path.exists(buildPath): log_utils.error("build.gradle is not exists: %s", buildPath) return False file_utils.modifyFileContent(buildPath, "${U8_SDK_LIBS_FOLDER}", path) return True
def modifyRootApplicationExtends(decompileDir, applicationClassName): applicationSmali = findRootApplicationSmali(decompileDir) if applicationSmali is None: log_utils.error("the applicationSmali get failed.") return log_utils.debug("modifyRootApplicationExtends: root application smali:%s", applicationSmali) modifyApplicationExtends(decompileDir, applicationSmali, applicationClassName)
def get_test_numpy(self): if self.test_tfds is None: error("Error: test_tfds is None.") return self.accum_test_x, self.accum_test_y if len(self.accum_test_x) == 0: time_test_np_start = time.time() tfds_test_os_iterator = self.test_tfds.make_one_shot_iterator() as_timer("tfds_test_ositer") tfds_test_iter_next = tfds_test_os_iterator.get_next() time_test_os_iterator_end = time.time() info( "note: now take time_test_os_iterator_end cost_time={}s".format( round(time_test_os_iterator_end - time_test_np_start, 3) ) ) with tf.Session(config=tf.ConfigProto(log_device_placement=False)) as sess: if self.domain == "text": while True: try: example, labels = sess.run(tfds_test_iter_next) example = np.squeeze(example, (2, 3)) example = np.squeeze(example, axis=-1) example = example.astype(np.int) self.accum_test_x.extend(example) self.accum_test_y.extend(labels) self.accm_test_cnt += example.shape[0] # X.append(example) # Y.append(labels) except tf.errors.OutOfRangeError: break else: while True: try: example, labels = sess.run(tfds_test_iter_next) # output: Note:time example shape=(86401, 1, 1, 1) # logger.info("Note:time example shape={}".format(example.shape)) self.accum_test_x.append(example) self.accum_test_y.append(labels) self.accm_test_cnt += 1 except tf.errors.OutOfRangeError: as_timer("tfds_test_run_OOR_{}".format(self.accm_test_cnt)) break time_test_np_end = time.time() info( "note: now take test accm_test_cnt={}, cost_time={}s".format( self.accm_test_cnt, round(time_test_np_end - time_test_np_start, 3) ) ) self.accum_test_y = np.array(self.accum_test_y) return self.accum_test_x
def connect(self): try: self.connection = sqlite3.connect(self.db) self.connection.row_factory = self.dict_factory self.cursor = self.connection.cursor() except Exception as e: print(e) log_utils.error("connect db failed.") return False return True
def merge_styleable_blocks(cls, blocks): if blocks == None or len(blocks) <= 1: return mainBlock = blocks[0] tree = ET.parse(mainBlock.path()) root = tree.getroot() mainNode = None for node in list(root): resType = node.tag resName = node.attrib.get('name') if resType == mainBlock.get_res_type( ) and resName == mainBlock.get_name(): mainNode = node break if mainNode == None: log_utils.error( "merge styleable node failed. main node %s not exists in file:%s", mainBlock.get_name(), mainBlock.path()) return for k in range(1, len(blocks)): mtree = ET.parse(blocks[k].path()) mroot = mtree.getroot() mergeNode = None for mnode in list(mroot): mtype = mnode.tag mname = mnode.attrib.get('name') if mtype == mainBlock.get_res_type( ) and mname == mainBlock.get_name(): mergeNode = mnode break if mergeNode != None: mergeChildren = mergeNode.findall('attr') if mergeChildren != None and len(mergeChildren) > 0: for node in list(mergeChildren): log_utils.debug( "merge styleable attr %s from %s to %s", mainBlock.get_name(), blocks[k].path(), mainBlock.path()) mainNode.append(node) tree.write(mainBlock.path(), "UTF-8")
def parse_method_invoke(line): if not line.startswith("invoke-"): log_utils.error("the line parse error in parse_method_invoke:"+line) blocks = line.split("->") method = blocks[len(blocks)-1] preblocks = blocks[0].split(",") className = preblocks[len(preblocks)-1] className = className.strip() return className,method
def addSplashScreen(workDir, channel, decompileDir): """ if the splash attrib is not zero ,then set the splash activity if the splash_copy_to_unity attrib is set, then copy the splash img to unity res fold ,replace the default splash.png. """ if channel['splash'] =='0': return 0 if channel['splash_copy_to_unity'] == '1': return copySplashToUnityResFolder(workDir, channel, decompileDir) splashPath = file_utils.getSplashPath() smaliPath = splashPath + "/smali" smaliTargetPath = decompileDir + "/smali" copyResToApk(smaliPath, smaliTargetPath) splashLayoutPath = splashPath + "/u8_splash.xml" splashTargetPath = decompileDir + "/res/layout/u8_splash.xml" file_utils.copy_file(splashLayoutPath, splashTargetPath) resPath = workDir + "/sdk/" + channel['name'] + "/splash/" + channel['splash'] resTargetPath = decompileDir + "/res" copyResToApk(resPath, resTargetPath) #remove original launcher activity of the game activityName = removeStartActivity(decompileDir) #append the launcher activity with the splash activity appendSplashActivity(decompileDir, channel['splash']) splashActivityPath = smaliTargetPath + "/com/u8/sdk/SplashActivity.smali" f = open(splashActivityPath, 'r+') content = str(f.read()) f.close() replaceTxt = '{U8SDK_Game_Activity}' idx = content.find(replaceTxt) if idx == -1: log_utils.error("modify splash file failed.the {U8SDK_Game_Activity} not found in SplashActivity.smali") return 1 content = content[:idx] + activityName + content[(idx + len(replaceTxt)):] f2 = open(splashActivityPath, 'w') f2.write(content) f2.close() log_utils.info("modify splash file success.") return 0
def unarchive(self): if not os.path.exists(self.aarFile): log_utils.error("the aar file not exists:" + self.aarFile) return False if os.path.exists(self.aarDir): file_utils.del_file_folder(self.aarDir) file_utils.unzip_file(self.aarFile, self.aarDir) return True
def copy_scripts(clientPath, outputPath): log_utils.debug("begin copy scripts folder:") sourcePath = os.path.join(clientPath, 'scripts') if not os.path.exists(sourcePath): log_utils.error("the scripts path not exists:" + sourcePath) return False targetPath = os.path.join(outputPath, 'scripts') file_utils.del_file_folder(targetPath) file_utils.copy_files(sourcePath, targetPath)
def copy_local(clientPath, outputPath): log_utils.debug("begin copy local folder:") sourcePath = os.path.join(clientPath, 'config/local') targetPath = os.path.join(outputPath, 'config/local') if not os.path.exists(sourcePath): log_utils.error("the local path not exists:" + sourcePath) return False file_utils.del_file_folder(targetPath) file_utils.copy_files(sourcePath, targetPath)
def merge_sdk_aar(channel, aarPath, targetManifest, targetAssets, targetRes, targetLibs): merger = AARMerger(aarPath) ret = merger.merge(targetManifest, targetAssets, targetRes, targetLibs) if not ret: log_utils.error("aar handle failed. " + aarPath) return False if merger.is_need_R(): add_extraR(aarPath, channel, merger.get_package_name()) return True
def mergeJar(workDir, decompileDir): u8sdkJarPath = file_utils.getFullPath('config/local/u8sdkanelib.jar') if not os.path.exists(u8sdkJarPath): log_utils.error("the file is not exists:"+u8sdkJarPath) return 1 targetPath = file_utils.getFullPath(workDir + "/ane") if not os.path.exists(targetPath): os.makedirs(targetPath) file_utils.copy_file(u8sdkJarPath, targetPath+"/u8sdkanelib.jar") jar2dex(targetPath, targetPath) smaliPath = file_utils.getFullPath(decompileDir + "/smali") return dex2smali(targetPath + '/classes.dex', smaliPath)
def getDefaultKeystore(appName): fileName = "games/" + appName + "/keystore.xml" configFile = file_utils.getFullPath(fileName) try: tree = ET.parse(configFile) root = tree.getroot() except Exception as e: log_utils.error("can not parse keystore.xml.path:%s", configFile) return None params = root.find("default").findall("param") channel = {} for cParam in params: key = cParam.get('name') val = cParam.get('value') channel[key] = val return channel
def main(game, isPublic, target): appName = game['appName'] channels = config_utils.getAllChannels(appName, isPublic) if channels is None or len(channels) == 0: print("没有任何可以打包的渠道") return 3 selected = [] if target == '*': selected = channels else: for t in target.split(','): t = t.strip() matchChannels = [c for c in channels if c['name'].lower() == t.lower()] if len(matchChannels) > 0: selected.append(matchChannels[0]) clen = len(selected) log_utils.info("now hava %s channels to package...", clen) baseApkPath = file_utils.getFullPath('games/'+game['appName']+'/u8.apk') log_utils.info("the base apk file is : %s", baseApkPath) if not os.path.exists(baseApkPath): log_utils.error('the base apk file is not exists, must named with u8.apk') return 2 sucNum = 0 failNum = 0 for channel in selected: ret = core.pack(game, channel, baseApkPath, isPublic) if ret: exit(1) failNum = failNum + 1 else: sucNum = sucNum + 1 log_utils.info("<< success num:%s; failed num:%s >>", sucNum, failNum) if failNum > 0: log_utils.error("<< all done with error >>") else: log_utils.info("<< all nice done >>") return 0
def getAppKey(): configFile = file_utils.getFullPath("config/config.xml") try: tree = ET.parse(configFile) root = tree.getroot() except Exception as e: log_utils.error("can not parse config.xml.path:%s", configFile) return None gameNode = root.find("game") if gameNode == None: return None appID = gameNode.get('appKey') return appID
def writeDeveloperProperties(appID, appKey, channel, targetFilePath): targetFilePath = file_utils.getFullPath(targetFilePath) proStr = "" if channel['params'] != None and len(channel['params']) > 0: for param in channel['params']: if param['bWriteInClient'] == '1': proStr = proStr + param['name'] + "=" + param['value'] + "\n" if "sdkLogicVersionCode" in channel: proStr = proStr + "U8_SDK_VERSION_CODE=" + channel["sdkLogicVersionCode"] + "\n" proStr = proStr + "U8_Channel=" + channel['id'] + "\n" proStr = proStr + "U8_APPID=" + appID + "\n" proStr = proStr + "U8_APPKEY=" + appKey + "\n" #append u8 local config local_config = getLocalConfig() if "use_u8_auth" not in local_config or "u8_auth_url" not in local_config: log_utils.error("the use_u8_auth or u8_auth_url is not exists in local.properties. don't use u8 auth.") return if local_config['use_u8_auth'] == "1": proStr = proStr + "U8_AUTH_URL=" + local_config['u8_auth_url'] + "\n" #write third plugin info: plugins = channel.get('third-plugins') if plugins != None and len(plugins) > 0: for plugin in plugins: if 'params' in plugin and plugin['params'] != None and len(plugin['params']) > 0: for param in plugin['params']: if param['bWriteInClient'] == '1': proStr = proStr + param['name'] + "=" + param['value'] + "\n" log_utils.debug("the develop info is %s", proStr) targetFile = open(targetFilePath, 'wb') proStr = proStr.encode('UTF-8') targetFile.write(proStr) targetFile.close()
def doScript(channel, pluginInfo, decompileDir, packageName, sdkTempDir, scriptName): if scriptName != 'script.py': log_utils.error("the script file name must be script.py") return 1 sdkScript = os.path.join(sdkTempDir, scriptName) if not os.path.exists(sdkScript): return 0 sys.path.append(sdkTempDir) import script ret = script.execute(channel, pluginInfo, decompileDir, packageName) del sys.modules['script'] sys.path.remove(sdkTempDir) return ret
def packAllChannels(game, isPublic, threadNum): basePath = file_utils.getCurrDir() log_utils.info("Curr Work Dir::%s", basePath) appName = game['appName'] channels = config_utils.getAllChannels(appName, isPublic) if channels != None and len(channels) > 0: clen = len(channels) log_utils.info("Now Have %s channels to package ", clen) packagePath = file_utils.getFullPath("u8.apk") log_utils.info("The base apk file is : %s", packagePath) if not os.path.exists(packagePath): log_utils.error("The apk file name must be 'u8.apk'") return que = queue.Queue() for channel in channels: que.put(channel, True, None) # start threads to pack if threadNum <= 0: threadNum = 1 log_utils.info("Now start %s threads to pack", threadNum) for i in range(threadNum): thread = PackerThread(que, packagePath, isPublic, game, i+1) thread.start() que.join() log_utils.info("<< all nice done >>") else: log_utils.info("<< no channels to pack >>")
def dex2smali(dexFile, targetdir, dextool = "baksmali.jar"): """ Transfer the dex to smali. """ if not os.path.exists(dexFile): log_utils.error("the dexfile is not exists. path:%s", dexFile) return 1 if not os.path.exists(targetdir): os.makedirs(targetdir) dexFile = file_utils.getFullPath(dexFile) smaliTool = file_utils.getFullToolPath(dextool) targetdir = file_utils.getFullPath(targetdir) cmd = '"%s" -jar "%s" -o "%s" "%s"' % (file_utils.getJavaCMD(), smaliTool, targetdir, dexFile) ret = file_utils.execFormatCmd(cmd) return ret
def signApkInternal(apkfile, keystore, password, alias, aliaspwd): apkfile = file_utils.getFullPath(apkfile) keystore = file_utils.getFullPath(keystore) aapt = file_utils.getFullToolPath("aapt") if not os.path.exists(keystore): log_utils.error("the keystore file is not exists. %s", keystore) return 1 listcmd = '%s list %s' % (aapt, apkfile) output = os.popen(listcmd).read() for filename in output.split('\n'): if filename.find('META_INF') == 0: rmcmd = '"%s" remove "%s" "%s"' % (aapt, apkfile, filename) file_utils.execFormatCmd(rmcmd) signcmd = '"%sjarsigner" -digestalg SHA1 -sigalg SHA1withRSA -keystore "%s" -storepass "%s" -keypass "%s" "%s" "%s" ' % (file_utils.getJavaBinDir(), keystore, password, aliaspwd, apkfile, alias) ret = file_utils.execFormatCmd(signcmd) return ret
def copyResToApk(copyFrom, copyTo): """ Copy two resource folders """ if not os.path.exists(copyFrom): log_utils.error("the copyFrom %s is not exists.", copyFrom) return if not os.path.exists(copyTo): os.makedirs(copyTo) if os.path.isfile(copyFrom) and not mergeResXml(copyFrom, copyTo): file_utils.copyFile(copyFrom, copyTo) return for f in os.listdir(copyFrom): sourcefile = os.path.join(copyFrom, f) targetfile = os.path.join(copyTo, f) if os.path.isfile(sourcefile): if not os.path.exists(copyTo): os.makedirs(copyTo) if mergeResXml(sourcefile, targetfile): continue if not os.path.exists(targetfile) or os.path.getsize(targetfile) != os.path.getsize(sourcefile): destfilestream = open(targetfile, 'wb') sourcefilestream = open(sourcefile, 'rb') destfilestream.write(sourcefilestream.read()) destfilestream.close() sourcefilestream.close() if os.path.isdir(sourcefile): copyResToApk(sourcefile, targetfile)
def execFormatCmd(cmd): cmd = cmd.replace('\\', '/') cmd = re.sub('/+', '/', cmd) ret = 0 try: reload(sys) sys.setdefaultencoding('utf-8') if platform.system() == 'Windows': st = subprocess.STARTUPINFO st.dwFlags = subprocess.STARTF_USESHOWWINDOW st.wShowWindow = subprocess.SW_HIDE # cmd = str(cmd).encode('gbk') s = subprocess.Popen(cmd, shell=True) ret = s.wait() if ret: s = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) stdoutput, erroutput = s.communicate() log_utils.error("*******ERROR*******") log_utils.error(stdoutput) log_utils.error(erroutput) log_utils.error("*******************") cmd = 'error::' + cmd + ' !!!exec Fail!!! ' else: s = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) stdoutput, erroutput = s.communicate() log_utils.info(stdoutput) log_utils.info(erroutput) cmd = cmd + ' !!!exec success!!! ' log_utils.info(cmd) except Exception as e: print(e) return return ret
def checkApkForU8SDK(workDir, decompileDir): """ 检查母包中接入U8SDK抽象层是否正确 不正确,则自动修正 """ ret = 0 log_utils.info("now to check the u8.apk is correct?") manifestFile = decompileDir + "/AndroidManifest.xml" manifestFile = file_utils.getFullPath(manifestFile) ET.register_namespace('android', androidNS) tree = ET.parse(manifestFile) root = tree.getroot() key = '{'+androidNS+'}name' applicationNode = root.find('application') name = applicationNode.get(key) if not name or name != "com.u8.sdk.U8Application": log_utils.error("the android:name in application element must be 'com.u8.sdk.U8Application'. now change it to com.u8.sdk.U8Application, but maybe something will be wrong .") applicationNode.set(key, 'com.u8.sdk.U8Application') tree.write(manifestFile, 'UTF-8') smaliName = file_utils.getFullPath(decompileDir + "/smali/com/u8/sdk/U8SDK.smali") if not os.path.exists(smaliName): log_utils.error("the u8sdk2.jar is not packaged to the u8.apk. now merge it. but maybe something will be wrong .") u8sdkJarPath = file_utils.getFullPath('config/local/u8sdk2.jar') if not os.path.exists(u8sdkJarPath): log_utils.error("the u8sdk2.jar is not in config/local path. correct failed") return 1 targetPath = file_utils.getFullPath(workDir + "/local") if not os.path.exists(targetPath): os.makedirs(targetPath) file_utils.copy_file(u8sdkJarPath, targetPath+"/u8sdk2.jar") jar2dex(targetPath, targetPath) smaliPath = file_utils.getFullPath(decompileDir + "/smali") ret = dex2smali(targetPath + '/classes.dex', smaliPath) # if not ret: # ret = mergeJar(workDir, decompileDir) log_utils.info("check u8.apk successfully") return ret
def appendChannelIconMark(game, channel, decompileDir): """ 自动给游戏图标加上渠道SDK的角标 没有角标,生成没有角标的ICON """ gameIconPath = 'games/' + game['appName'] + '/icon/icon.png' gameIconPath = file_utils.getFullPath(gameIconPath) if not os.path.exists(gameIconPath): log_utils.error("the game %s icon is not exists:%s",game['appName'], gameIconPath) return 1 useMark = True if 'icon' not in channel: log_utils.warning("the channel %s of game %s do not config icon in config.xml,no icon mark.", channel['name'], game['appName']) useMark = False rlImg = Image.open(gameIconPath) if useMark: #如果有角标,则添加角标 markType = channel['icon'] markName = 'right-bottom' if markType == 'rb': markName = 'right-bottom' elif markType == 'rt': markName = 'right-top' elif markType == 'lt': markName = 'left-top' elif markType == 'lb': markName = 'left-bottom' markPath = 'config/sdk/' + channel['name'] + '/icon_marks/' + markName + '.png' if not os.path.exists(markPath): log_utils.warning("the icon mark %s is not exists of sdk %s.no icon mark.", markPath, channel['name']) else: markIcon = Image.open(markPath) rlImg = image_utils.appendIconMark(rlImg, markIcon, (0, 0)) ldpiSize = (36, 36) mdpiSize = (48, 48) hdpiSize = (72, 72) xhdpiSize = (96, 96) xxhdpiSize = (144,144) xxxhdpiSize = (192, 192) ldpiIcon = rlImg.resize(ldpiSize, Image.ANTIALIAS) mdpiIcon = rlImg.resize(mdpiSize, Image.ANTIALIAS) hdpiIcon = rlImg.resize(hdpiSize, Image.ANTIALIAS) xhdpiIcon = rlImg.resize(xhdpiSize, Image.ANTIALIAS) xxhdpiIcon = rlImg.resize(xxhdpiSize, Image.ANTIALIAS) xxxhdpiIcon = rlImg.resize(xxxhdpiSize, Image.ANTIALIAS) ldpiPath = file_utils.getFullPath(decompileDir + '/res/drawable-ldpi') mdpiPath = file_utils.getFullPath(decompileDir + '/res/drawable-mdpi') hdpiPath = file_utils.getFullPath(decompileDir + '/res/drawable-hdpi') xhdpiPath = file_utils.getFullPath(decompileDir + '/res/drawable-xhdpi') xxhdpiPath = file_utils.getFullPath(decompileDir + '/res/drawable-xxhdpi') xxxhdpiPath = file_utils.getFullPath(decompileDir + '/res/drawable-xxxhdpi') if not os.path.exists(ldpiPath): os.makedirs(ldpiPath) if not os.path.exists(mdpiPath): os.makedirs(mdpiPath) if not os.path.exists(hdpiPath): os.makedirs(hdpiPath) if not os.path.exists(xhdpiPath): os.makedirs(xhdpiPath) if not os.path.exists(xxhdpiPath): os.makedirs(xxhdpiPath) if not os.path.exists(xxxhdpiPath): os.makedirs(xxxhdpiPath) gameIconName = getAppIconName(decompileDir) + '.png' ldpiIcon.save(os.path.join(ldpiPath, gameIconName), 'PNG') mdpiIcon.save(os.path.join(mdpiPath, gameIconName), 'PNG') hdpiIcon.save(os.path.join(hdpiPath, gameIconName), 'PNG') xhdpiIcon.save(os.path.join(xhdpiPath, gameIconName), 'PNG') xxhdpiIcon.save(os.path.join(xxhdpiPath, gameIconName), 'PNG') xxxhdpiIcon.save(os.path.join(xxxhdpiPath, gameIconName), 'PNG') return 0
def copyResource(game, channel, packageName, sdkDir, decompileDir , operations, name, pluginInfo = None): """ Copy sdk resources to the apk decompile dir Merge manifest.xml Merge all res xml if the xml already exists in target apk. copy all others resources """ if operations != None: for child in operations: if child['type'] == 'mergeManifest': manifestFrom = file_utils.getFullPath(os.path.join(sdkDir, child['from'])) manifestFromTemp = manifestFrom manifestTo = file_utils.getFullPath(os.path.join(decompileDir, child['to'])) if 'orientation' in game: if game['orientation'] == 'portrait': manifestFrom = manifestFrom[:-4] + "_portrait.xml" else: manifestFrom = manifestFrom[:-4] + "_landscape.xml" if not os.path.exists(manifestFrom): manifestFrom = manifestFromTemp log_utils.info("The sdk manifest file is %s", manifestFrom) #merge into xml bRet = mergeManifest(channel, manifestTo, manifestFrom) if bRet: log_utils.info("merge manifest file success.") else: log_utils.error("merge manifest file failed.") return 1 elif child['type'] == 'copyRes': if child['from'] == None or child['to'] == None: log_utils.error("the sdk config file error. 'copyRes' need 'from' and 'to'.sdk name:%s", name) return 1 copyFrom = file_utils.getFullPath(os.path.join(sdkDir, child['from'])) copyTo = file_utils.getFullPath(os.path.join(decompileDir, child['to'])) if child['to'] == 'lib': copyLibs(game, copyFrom, copyTo) else: copyResToApk(copyFrom, copyTo) elif child['type'] == 'script' and pluginInfo != None: #now only third-plugin support script if child['from'] == None: log_utils.error("the sdk config file is error. 'script' need 'from' attrib to specify script.py") return 1 scriptName = child['from'] log_utils.info("now to execute plugin script. name:%s", scriptName) doScript(channel, pluginInfo, decompileDir, packageName, sdkDir, scriptName) return 0
def mergeManifest(channel, targetManifest, sdkManifest): """ Merge sdk SdkManifest.xml to the apk AndroidManifest.xml """ if not os.path.exists(targetManifest) or not os.path.exists(sdkManifest): log_utils.error("the manifest file is not exists.targetManifest:%s;sdkManifest:%s", targetManifest, sdkManifest) return False ET.register_namespace('android', androidNS) targetTree = ET.parse(targetManifest) targetRoot = targetTree.getroot() ET.register_namespace('android', androidNS) sdkTree = ET.parse(sdkManifest) sdkRoot = sdkTree.getroot() f = open(targetManifest) targetContent = f.read() f.close() permissionConfigNode = sdkRoot.find('permissionConfig') if permissionConfigNode != None and len(permissionConfigNode) > 0: for child in list(permissionConfigNode): key = '{' + androidNS + '}name' val = child.get(key) if val != None and len(val) > 0: attrIndex = targetContent.find(val) if -1 == attrIndex: targetRoot.append(child) appConfigNode = sdkRoot.find('applicationConfig') appNode = targetRoot.find('application') if appConfigNode != None: proxyApplicationName = appConfigNode.get('proxyApplication') if proxyApplicationName != None and len(proxyApplicationName) > 0: if 'U8_APPLICATION_PROXY_NAME' in channel: channel['U8_APPLICATION_PROXY_NAME'] = channel['U8_APPLICATION_PROXY_NAME'] + ',' + proxyApplicationName else: channel['U8_APPLICATION_PROXY_NAME'] = proxyApplicationName appKeyWord = appConfigNode.get('keyword') # exists = appKeyWord != None and len(appKeyWord.strip()) > 0 and targetContent.find(appKeyWord) != -1 # if not exists: #remove keyword check... for child in list(appConfigNode): targetRoot.find('application').append(child) targetTree.write(targetManifest, 'UTF-8') return True
def main(game, isPublic, isFullRes = False): print(u"**********当前配置的渠道号**********") print(u"\t渠道名 \t\t 渠道号 \t\t 渠道 \n") appName = game['appName'] channels = config_utils.getAllChannels(appName, isPublic) if channels is None or len(channels) == 0: print("没有任何可以打包的渠道") return for ch in channels: name = ch['name'] if len(name) <= 6: chStr = u"\t%s \t\t\t %s \t\t %s " % (ch['name'], ch['id'], ch['desc']) elif len(name) > 6 and len(name) <= 13: chStr = u"\t%s \t\t %s \t\t %s " % (ch['name'], ch['id'], ch['desc']) else: chStr = u"\t%s \t %s \t\t %s " % (ch['name'], ch['id'], ch['desc']) print(chStr) selected = [] while(True): sys.stdout.write(u"请选择需要打包的渠道(渠道名),全部输入*,多个用逗号分割:") sys.stdout.flush() target = raw_input() if target == '*': selected = channels else: for t in target.split(','): t = t.strip() matchChannels = [c for c in channels if c['name'].lower() == t.lower()] if len(matchChannels) > 0: selected.append(matchChannels[0]) if len(selected) == 0: print(u"\n无效的渠道名,请重新输入!!\n") else: break clen = len(selected) log_utils.info("now hava %s channels to package...", clen) baseApkPath = file_utils.getFullPath('games/'+game['appName']+'/u8.apk') log_utils.info("the base apk file is : %s", baseApkPath) if not os.path.exists(baseApkPath): log_utils.error('the base apk file is not exists, must named with u8.apk') return sucNum = 0 failNum = 0 for channel in selected: ret = core.pack(game, channel, baseApkPath, isPublic) if ret: failNum = failNum + 1 else: sucNum = sucNum + 1 log_utils.info("<< success num:%s; failed num:%s >>", sucNum, failNum) if failNum > 0: log_utils.error("<< all done with error >>") else: log_utils.info("<< all nice done >>")
def loadThirdPluginUserConfig(appName, plugin, pluginName): #configFile = file_utils.getFullPath("config/plugin/" + pluginName + "/config.xml") configFile = file_utils.getFullPath("games/"+appName+"/plugin/"+pluginName+"/config.xml") if not os.path.exists(configFile): log_utils.error("the plugin %s config.xml file is not exists.path:%s", pluginName, configFile) return 0 try: tree = ET.parse(configFile) root = tree.getroot() except: log_utils.error("can not parse config.xml.path:%s", configFile) return 0 configNode = root subpluginNodes = configNode.find("subplugins") if subpluginNodes != None and len(subpluginNodes) > 0: plugin['subplugins'] = [] for subNode in subpluginNodes: subplugin = {} subplugin['name'] = subNode.get('name') subplugin['desc'] = subNode.get('desc') subParamNodes = subNode.findall('param') subplugin['params'] = [] if subParamNodes != None and len(subParamNodes) > 0: for subParamNode in subParamNodes: param = {} param['name'] = subParamNode.get('name') param['value'] = subParamNode.get('value') param['required'] = subParamNode.get('required') param['showName'] = subParamNode.get('showName') param['bWriteInManifest'] = subParamNode.get('bWriteInManifest') param['bWriteInClient'] = subParamNode.get('bWriteInClient') subplugin['params'].append(param) plugin['subplugins'].append(subplugin) paramNodes = configNode.find("params") plugin['params'] = [] if paramNodes != None and len(paramNodes) > 0: for paramNode in paramNodes: param = {} param['name'] = paramNode.get('name') param['value'] = paramNode.get('value') param['required'] = paramNode.get('required') param['showName'] = paramNode.get('showName') param['bWriteInManifest'] = paramNode.get('bWriteInManifest') param['bWriteInClient'] = paramNode.get('bWriteInClient') plugin['params'].append(param) operationNodes = configNode.find("operations") plugin['operations'] = [] if operationNodes != None and len(operationNodes) > 0: for opNode in operationNodes: op = {} op['type'] = opNode.get('type') op['from'] = opNode.get('from') op['to'] = opNode.get('to') plugin['operations'].append(op) pluginNodes = configNode.find("plugins") if pluginNodes != None and len(pluginNodes) > 0: plugin['plugins'] = [] for pNode in pluginNodes: p = {} p['name'] = pNode.get('name') p['type'] = pNode.get('type') plugin['plugins'].append(p) return 1
def getAllChannels(appName, isPublic): fileName = "games/" + appName + "/config.xml" configFile = file_utils.getFullPath(fileName) try: tree = ET.parse(configFile) root = tree.getroot() except Exception as e: log_utils.error("can not parse config.xml.path:%s",configFile) return None lstGPlugins = [] globalPluginsNode = root.find("global-plugins") if globalPluginsNode is not None: globalPlugins = globalPluginsNode.findall("plugin") if globalPlugins is not None and len(globalPlugins) > 0: for pluginNode in globalPlugins: plugin = {} plugin['name'] = pluginNode.get("name") plugin['desc'] = pluginNode.get("desc") loadThirdPluginUserConfig(appName, plugin, plugin['name']) lstGPlugins.append(plugin) channels = root.find("channels").findall("channel") lstChannels = [] for cNode in channels: channel = {} params = cNode.findall("param") for cParam in params: key = cParam.get('name') val = cParam.get('value') channel[key] = val sdkVersionNode = cNode.find('sdk-version') if sdkVersionNode != None and len(sdkVersionNode) > 0: versionCodeNode = sdkVersionNode.find('versionCode') versionNameNode = sdkVersionNode.find('versionName') if versionCodeNode != None and versionNameNode != None: # u8server use the logic version code to decide which sdk version to use channel['sdkLogicVersionCode'] = versionCodeNode.text channel['sdkLogicVersionName'] = versionNameNode.text sdkParams = cNode.find("sdk-params") tblSDKParams = {} if sdkParams != None: sdkParamNodes = sdkParams.findall('param') if sdkParamNodes != None and len(sdkParamNodes) > 0: for cParam in sdkParamNodes: key = cParam.get('name') val = cParam.get('value') tblSDKParams[key] = val channel['sdkParams'] = tblSDKParams ret = loadChannelUserConfig(appName, channel) if ret: lstPlugins = [] + lstGPlugins pluginsNode = cNode.find("plugins") if pluginsNode != None: pluginNodeLst = pluginsNode.findall("plugin") if pluginNodeLst != None and len(pluginNodeLst) > 0: for cPlugin in pluginNodeLst: plugin = {} plugin['name'] = cPlugin.get('name') exists = False for p in lstPlugins: if p['name'] == plugin['name']: exists = True break if not exists: plugin['desc'] = cPlugin.get('desc') loadThirdPluginUserConfig(appName, plugin, plugin['name']) lstPlugins.append(plugin) channel['third-plugins'] = lstPlugins lstChannels.append(channel) return lstChannels
def loadChannelUserConfig(appName, channel): configFile = file_utils.getFullPath("config/sdk/" + channel['sdk'] + "/config.xml") if not os.path.exists(configFile): log_utils.error("the config.xml is not exists of sdk %s.path:%s", channel['name'], configFile) return 0 try: tree = ET.parse(configFile) root = tree.getroot() except: log_utils.error("can not parse config.xml.path:%s", configFile) return 0 configNode = root paramNodes = configNode.find("params") channel['params'] = [] if paramNodes != None and len(paramNodes) > 0: for paramNode in paramNodes: param = {} param['name'] = paramNode.get('name') param['required'] = paramNode.get('required') if param['required'] == '1': key = param['name'] if key in channel['sdkParams'] and channel['sdkParams'][key] != None: param['value'] = channel['sdkParams'][key] else: log_utils.error("the sdk %s 'sdkParam's is not all configed in the config.xml.path:%s", channel['name'], configFile) return 0 else: param['value'] = paramNode.get('value') param['showName'] = paramNode.get('showName') param['bWriteInManifest'] = paramNode.get('bWriteInManifest') param['bWriteInClient'] = paramNode.get('bWriteInClient') channel['params'].append(param) operationNodes = configNode.find("operations") channel['operations'] = [] if operationNodes != None and len(operationNodes) > 0: for opNode in operationNodes: op = {} op['type'] = opNode.get('type') op['from'] = opNode.get('from') op['to'] = opNode.get('to') channel['operations'].append(op) pluginNodes = configNode.find("plugins") if pluginNodes != None and len(pluginNodes) > 0: channel['plugins'] = [] for pNode in pluginNodes: p = {} p['name'] = pNode.get('name') p['type'] = pNode.get('type') channel['plugins'].append(p) versionNode = configNode.find("version") if versionNode != None and len(versionNode) > 0: versionCodeNode = versionNode.find("versionCode") versionNameNode = versionNode.find("versionName") # the sdk version code is used to check version update for the sdk. if versionCodeNode != None and versionNameNode != None: channel['sdkVersionCode'] = versionCodeNode.text channel['sdkVersionName'] = versionNameNode.text return 1