def generateNewRFile(newPackageName, decompileDir): """ Use all new resources to generate the new R.java, and compile it ,then copy it to the target smali dir """ ret = checkValueResources(decompileDir) if ret: return 1 decompileDir = file_utils.getFullPath(decompileDir) tempPath = os.path.dirname(decompileDir) tempPath = tempPath + "/temp" log_utils.debug("generate R:the temp path is %s", tempPath) if os.path.exists(tempPath): file_utils.del_file_folder(tempPath) if not os.path.exists(tempPath): os.makedirs(tempPath) resPath = os.path.join(decompileDir, "res") targetResPath = os.path.join(tempPath, "res") file_utils.copy_files(resPath, targetResPath) genPath = os.path.join(tempPath, "gen") if not os.path.exists(genPath): os.makedirs(genPath) aaptPath = file_utils.getFullToolPath("aapt") androidPath = file_utils.getFullToolPath("android.jar") manifestPath = os.path.join(decompileDir, "AndroidManifest.xml") cmd = '"%s" p -f -m -J "%s" -S "%s" -I "%s" -M "%s"' % (aaptPath, genPath, targetResPath, androidPath, manifestPath) ret = file_utils.execFormatCmd(cmd) if ret: return 1 rPath = newPackageName.replace('.', '/') rPath = os.path.join(genPath, rPath) rPath = os.path.join(rPath, "R.java") cmd = '"%sjavac" -source 1.7 -target 1.7 -encoding UTF-8 "%s"' % (file_utils.getJavaBinDir(), rPath) ret = file_utils.execFormatCmd(cmd) if ret: return 1 targetDexPath = os.path.join(tempPath, "classes.dex") dexToolPath = file_utils.getFullToolPath("/lib/dx.jar") cmd = file_utils.getJavaCMD() + ' -jar -Xmx512m -Xms512m "%s" --dex --output="%s" "%s"' % (dexToolPath, targetDexPath, genPath) ret = file_utils.execFormatCmd(cmd) if ret: return 1 smaliPath = os.path.join(decompileDir, "smali") ret = dex2smali(targetDexPath, smaliPath, "baksmali.jar") return ret
def doAppendIcon(): #复制icons中的图片到game_icon中 if os.path.exists(os.path.dirname(file_utils.curDir) + '/icons'): file_utils.copy_files(os.path.dirname(file_utils.curDir) + '/icons', file_utils.getFullPath('_icon/game_icon')) configFile = file_utils.getFullPath("channels_config.xml") dom = xml.dom.minidom.parse(configFile) root = dom.documentElement channellist = root.getElementsByTagName('channel') #icon处理 for channel in channellist: #获取sdk_name和fs_app_id params = channel.getElementsByTagName("param") sdk_name = "" fs_app_id = "" for param in params: if "sdk_name" == param.getAttribute("name"): sdk_name = param.getAttribute("value") if "fs_app_id" == param.getAttribute("name"): fs_app_id = param.getAttribute("value") #判断是否有sdk对应的game icon if os.path.exists(file_utils.getFullPath("_icon/game_icon/" + fs_app_id + ".png")): #获取demo的res的path sdkDemoPath = channel.getAttribute('path') resDir = os.path.dirname(file_utils.curDir) + "/" + sdkDemoPath #合并icon并存到res中 if os.path.exists( resDir ): file_utils.printF("icon fusion : channel_icon:%s, game_icon:%s \r\n", fs_app_id, sdk_name) appendChannelIconMark(fs_app_id, sdk_name, resDir)
def handleThirdPlugins(workDir, decompileDir, game, channel, packageName): pluginsFolder = file_utils.getFullPath('config/plugin') gamePluginFolder = file_utils.getFullPath('games/'+game['appName']+'/plugin') plugins = channel.get('third-plugins') if plugins == None or len(plugins) <= 0: log_utils.info("the channel %s has no supported plugins.", channel['name']) return 0 #copy all resources to temp folder. for plugin in plugins: pluginName = plugin['name'] pluginSourceFolder = os.path.join(pluginsFolder, pluginName) if not os.path.exists(pluginSourceFolder): log_utils.warning("the plugin %s config folder is not exists", pluginName) continue pluginTargetFolder = workDir + "/plugins/" + pluginName file_utils.copy_files(pluginSourceFolder, pluginTargetFolder) gamePluginSourceFolder = os.path.join(gamePluginFolder, pluginName) if not os.path.exists(gamePluginSourceFolder): log_utils.warning("the plugin %s is not configed in the game %s", pluginName, game['appName']) continue file_utils.copy_files(gamePluginSourceFolder, pluginTargetFolder) if not os.path.exists(pluginSourceFolder + "/classes.dex"): jar2dex(pluginSourceFolder, pluginTargetFolder) #handle plugins smaliDir = os.path.join(decompileDir, "smali") pluginNum = 0 for plugin in plugins: pluginName = plugin['name'] pluginFolder = workDir + "/plugins/" + pluginName if not os.path.exists(pluginFolder): log_utils.warning("the plugin %s temp folder is not exists", pluginName) continue pluginDexFile = os.path.join(pluginFolder, "classes.dex") ret = dex2smali(pluginDexFile, smaliDir, "baksmali.jar") if ret: return 1 ret = copyResource(game, channel, packageName, pluginFolder, decompileDir, plugin['operations'], pluginName, plugin) if ret: return 1 pluginNum += 1 log_utils.info("Total plugin num:%s;success handle num:%s", str(len(plugins)), str(pluginNum))
def flush(self): """flush all the blocks to files""" for k in self.folders: self.folders[k].flush() for k in self.folders: localFolder = os.path.join(self.filePath, self.folders[k].get_name()) if not os.path.exists(localFolder): file_utils.copy_files(self.folders[k].path(), localFolder)
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 installPIL(): # 检查PIL安装了没 pyScriptPath = file_utils.pythonDir + '/Scripts' if not os.path.exists(file_utils.pythonDir + '/Lib/site-packages/PIL'): file_utils.copy_files( file_utils.curDir + '/scripts/Lib_Pillow', pyScriptPath) #安装 Pillow os.chdir(pyScriptPath) os.system('pip install ' + pyScriptPath + '/Pillow-3.0.0-cp27-none-win32.whl') #检查环境变量 pathV = os.environ["PATH"] if not pyScriptPath in pathV: os.environ["PATH"]= pyScriptPath + ';' + os.environ["PATH"]
def compile_code(self, user_answer, file_paths, test_case): self.files = [] if self.compiled_user_answer and self.compiled_test_code: return None else: ref_code_path = test_case clean_ref_code_path, clean_test_case_path = \ self._set_test_code_file_path(ref_code_path) if file_paths: self.files = copy_files(file_paths) if not isfile(clean_ref_code_path): msg = "No file at %s or Incorrect path" % clean_ref_code_path return False, msg if not isfile(self.submit_code_path): msg = "No file at %s or Incorrect path" % self.submit_code_path return False, msg self.write_to_submit_code_file(self.submit_code_path, user_answer) self.user_output_path, self.ref_output_path = self.set_file_paths() self.compile_command, self.compile_main = self.get_commands( clean_ref_code_path, self.user_output_path, self.ref_output_path) self.compiled_user_answer = self._run_command( self.compile_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.compiled_test_code = self._run_command(self.compile_main, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) return self.compiled_user_answer, self.compiled_test_code
def copy_tool(clientPath, outputPath): log_utils.debug("begin copy tool folder:") sourcePath = os.path.join(clientPath, 'tool') if not os.path.exists(sourcePath): log_utils.error("the tool path not exists:" + sourcePath) return False targetPath = os.path.join(outputPath, 'tool') file_utils.del_file_folder(targetPath) subs = ['win', 'mac'] for sub in subs: file_utils.copy_files(os.path.join(sourcePath, sub), os.path.join(targetPath, sub))
def compile_code(self, user_answer, file_paths, expected_input, expected_output): self.files = [] if file_paths: self.files = copy_files(file_paths) if not isfile(self.submit_code_path): msg = "No file at %s or Incorrect path" % self.submit_code_path return False, msg user_code_directory = os.getcwd() + '/' user_answer = user_answer.replace("\r", "") self.write_to_submit_code_file(self.submit_code_path, user_answer)
def compile_code(self, user_answer, file_paths, test_case): self.files = [] if file_paths: self.files = copy_files(file_paths) if self.exec_scope: return None else: submitted = compile(user_answer, '<string>', mode='exec') self.exec_scope = {} exec submitted in self.exec_scope return self.exec_scope
def compile_code(self, user_answer, file_paths, expected_output): self.files = [] if file_paths: self.files = copy_files(file_paths) if hasattr(self, 'output_value'): return None else: submitted = compile(user_answer, '<string>', mode='exec') with redirect_stdout() as output_buffer: exec_scope = {} exec submitted in exec_scope self.output_value = output_buffer.getvalue() return self.output_value
def compile_code(self, user_answer, file_paths, test_case): self.files = [] if self.compiled_user_answer and self.compiled_test_code: return None else: ref_code_path = test_case clean_ref_code_path, clean_test_case_path = \ self._set_test_code_file_path(ref_code_path) if file_paths: self.files = copy_files(file_paths) if not isfile(clean_ref_code_path): msg = "No file at %s or Incorrect path" % clean_ref_code_path return False, msg if not isfile(self.submit_code_path): msg = "No file at %s or Incorrect path" % self.submit_code_path return False, msg user_code_directory = os.getcwd() + '/' self.write_to_submit_code_file(self.submit_code_path, user_answer ) ref_file_name = (clean_ref_code_path.split('/')[-1]).split('.')[0] self.user_output_path = self.set_file_paths(user_code_directory, 'Test' ) self.ref_output_path = self.set_file_paths(user_code_directory, ref_file_name ) compile_command, self.compile_main = self.get_commands( clean_ref_code_path, user_code_directory ) self.run_command_args = "java -cp {0} {1}".format( user_code_directory, ref_file_name ) self.compiled_user_answer = self._run_command(compile_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) self.compiled_test_code = self._run_command(self.compile_main, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) return self.compiled_user_answer, self.compiled_test_code
def create_proj(projPath, targetName, classPrefix): if not os.path.exists(projPath): log_utils.debug("the U8SDK_Projects dir is not exists." + projPath) return templatePath = os.path.join(projPath, "U8SDK_Template") if not os.path.exists(templatePath): log_utils.debug("the template project is not exists." + templatePath) return if not targetName.startswith("U8SDK_"): targetName = "U8SDK_" + targetName targetPath = os.path.join(projPath, targetName) if os.path.exists(targetPath): log_utils.debug("the target project is already exists." + targetPath) return file_utils.copy_files(templatePath, targetPath) srcPath = os.path.join(targetPath, "src/com/u8/sdk") for f in os.listdir(srcPath): fname = os.path.join(srcPath, f) file_utils.modifyFileContent(fname, "Temp", classPrefix) ftarget = f.replace("Temp", classPrefix) os.rename(fname, os.path.join(srcPath, ftarget)) configPath = os.path.join(targetPath, "config.xml") file_utils.modifyFileContent(configPath, "Temp", classPrefix) projFilePath = os.path.join(targetPath, ".project") file_utils.modifyFileContent(projFilePath, "U8SDK_Template", targetName)
def compile_code(self, user_answer, file_paths, expected_input, expected_output): self.files = [] if file_paths: self.files = copy_files(file_paths) submitted = compile(user_answer, '<string>', mode='exec') if expected_input: input_buffer = StringIO() input_buffer.write(expected_input) input_buffer.seek(0) sys.stdin = input_buffer with redirect_stdout() as output_buffer: exec_scope = {} exec submitted in exec_scope self.output_value = output_buffer.getvalue().rstrip("\n") return self.output_value
def compile_code(self, user_answer, file_paths, expected_input, expected_output): self.files = [] if not isfile(self.submit_code_path): msg = "No file at %s or Incorrect path" % self.submit_code_path return False, msg if file_paths: self.files = copy_files(file_paths) user_code_directory = os.getcwd() + '/' self.write_to_submit_code_file(self.submit_code_path, user_answer) self.user_output_path = self.set_file_paths(user_code_directory, 'Test' ) self.compile_command = self.get_commands() self.compiled_user_answer = self._run_command(self.compile_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) return self.compiled_user_answer
def check_code(self, user_answer, file_paths, test_case): self.files = [] if file_paths: self.files = copy_files(file_paths) ref_code_path = test_case clean_ref_path, clean_test_case_path = \ self._set_test_code_file_path(ref_code_path) user_answer, terminate_commands = \ self._remove_scilab_exit(user_answer.lstrip()) success = False self.write_to_submit_code_file(self.submit_code_path, user_answer) # Throw message if there are commmands that terminates scilab add_err = "" if terminate_commands: add_err = "Please do not use exit, quit and abort commands in your\ code.\n Otherwise your code will not be evaluated\ correctly.\n" cmd = 'printf "lines(0)\nexec(\'{0}\',2);\nquit();"'.format( clean_ref_path ) cmd += ' | timeout 8 scilab-cli -nb' ret = self._run_command(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) proc, stdout, stderr = ret # Get only the error. stderr = self._get_error(stdout) if stderr is None: # Clean output stdout = self._strip_output(stdout) if proc.returncode == 5: success, err = True, "Correct answer" else: err = add_err + stdout else: err = add_err + stderr return success, err
def compile_code(self, user_answer, file_paths, test_case): self.files = [] if self.compiled_user_answer and self.compiled_test_code: return None else: ref_code_path = test_case clean_ref_code_path, clean_test_case_path = \ self._set_test_code_file_path(ref_code_path) if file_paths: self.files = copy_files(file_paths) if not isfile(clean_ref_code_path): msg = "No file at %s or Incorrect path" % clean_ref_code_path return False, msg if not isfile(self.submit_code_path): msg = "No file at %s or Incorrect path" % self.submit_code_path return False, msg user_code_directory = os.getcwd() + '/' self.write_to_submit_code_file(self.submit_code_path, user_answer) ref_file_name = (clean_ref_code_path.split('/')[-1]).split('.')[0] self.user_output_path = self.set_file_paths( user_code_directory, 'Test') self.ref_output_path = self.set_file_paths(user_code_directory, ref_file_name) compile_command, self.compile_main = self.get_commands( clean_ref_code_path, user_code_directory) self.run_command_args = "java -cp {0} {1}".format( user_code_directory, ref_file_name) self.compiled_user_answer = self._run_command( compile_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.compiled_test_code = self._run_command(self.compile_main, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) return self.compiled_user_answer, self.compiled_test_code
def compile_code(self, user_answer, file_paths, test_case): self.files = [] if self.compiled_user_answer and self.compiled_test_code: return None else: ref_code_path = test_case clean_ref_code_path, clean_test_case_path = \ self._set_test_code_file_path(ref_code_path) if file_paths: self.files = copy_files(file_paths) if not isfile(clean_ref_code_path): msg = "No file at %s or Incorrect path" % clean_ref_code_path return False, msg if not isfile(self.submit_code_path): msg = "No file at %s or Incorrect path" % self.submit_code_path return False, msg self.write_to_submit_code_file(self.submit_code_path, user_answer) self.user_output_path, self.ref_output_path = self.set_file_paths() self.compile_command, self.compile_main = self.get_commands( clean_ref_code_path, self.user_output_path, self.ref_output_path ) self.compiled_user_answer = self._run_command( self.compile_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) self.compiled_test_code = self._run_command( self.compile_main, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) return self.compiled_user_answer, self.compiled_test_code
def compile_code(self, user_answer, file_paths, expected_input, expected_output): self.files = [] if file_paths: self.files = copy_files(file_paths) if not isfile(self.submit_code_path): msg = "No file at %s or Incorrect path" % self.submit_code_path return False, msg self.write_to_submit_code_file(self.submit_code_path, user_answer) self.user_output_path, self.ref_output_path = self.set_file_paths() self.compile_command, self.compile_main = self.get_commands( self.user_output_path, self.ref_output_path) self.compiled_user_answer = self._run_command(self.compile_command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.compiled_test_code = self._run_command(self.compile_main, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) return self.compiled_user_answer, self.compiled_test_code
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
def check_code(self, user_answer, file_paths, test_case): """ Function validates student script using instructor script as reference. Test cases can optionally be provided. The first argument ref_path, is the path to instructor script, it is assumed to have executable permission. The second argument submit_path, is the path to the student script, it is assumed to have executable permission. The Third optional argument is the path to test the scripts. Each line in this file is a test case and each test case is passed to the script as standard arguments. Returns -------- returns (True, "Correct answer") : If the student script passes all test cases/have same output, when compared to the instructor script returns (False, error_msg): If the student script fails a single test/have dissimilar output, when compared to the instructor script. Returns (False, error_msg): If mandatory arguments are not files or if the required permissions are not given to the file(s). """ ref_code_path = test_case get_ref_path, get_test_case_path = ref_code_path.strip().split(',') get_ref_path = get_ref_path.strip() get_test_case_path = get_test_case_path.strip() clean_ref_code_path, clean_test_case_path = \ self._set_test_code_file_path(get_ref_path, get_test_case_path) self.files = [] if file_paths: self.files = copy_files(file_paths) if not isfile(clean_ref_code_path): msg = "No file at %s or Incorrect path" % clean_ref_code_path return False, msg if not isfile(self.submit_code_path): msg = "No file at %s or Incorrect path" % self.submit_code_path return False, msg if not os.access(clean_ref_code_path, os.X_OK): msg = "Script %s is not executable" % clean_ref_code_path return False, msg if not os.access(self.submit_code_path, os.X_OK): msg = "Script %s is not executable" % self.submit_code_path return False, msg success = False user_answer = user_answer.replace("\r", "") self.write_to_submit_code_file(self.submit_code_path, user_answer) if clean_test_case_path is None or "": ret = self._run_command(clean_ref_code_path, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) proc, inst_stdout, inst_stderr = ret ret = self._run_command(self.submit_code_path, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) proc, stdnt_stdout, stdnt_stderr = ret if inst_stdout == stdnt_stdout: return True, "Correct answer" else: err = "Error: expected %s, got %s" % (inst_stderr, stdnt_stderr ) return False, err else: if not isfile(clean_test_case_path): msg = "No test case at %s" % clean_test_case_path return False, msg if not os.access(clean_ref_code_path, os.R_OK): msg = "Test script %s, not readable" % clean_test_case_path return False, msg # valid_answer is True, so that we can stop once a test case fails valid_answer = True # loop_count has to be greater than or equal to one. # Useful for caching things like empty test files,etc. loop_count = 0 test_cases = open(clean_test_case_path).readlines() num_lines = len(test_cases) for test_case in test_cases: loop_count += 1 if valid_answer: args = [clean_ref_code_path] + \ [x for x in test_case.split()] ret = self._run_command(args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) proc, inst_stdout, inst_stderr = ret if file_paths: self.files = copy_files(file_paths) args = [self.submit_code_path] + \ [x for x in test_case.split()] ret = self._run_command(args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc, stdnt_stdout, stdnt_stderr = ret valid_answer = inst_stdout == stdnt_stdout if valid_answer and (num_lines == loop_count): return True, "Correct answer" else: err = ("Error:expected" " {0}, got {1}").format(inst_stdout+inst_stderr, stdnt_stdout+stdnt_stderr ) return False, err
def check_code(self, user_answer, file_paths, test_case): """ Function validates student script using instructor script as reference. Test cases can optionally be provided. The first argument ref_path, is the path to instructor script, it is assumed to have executable permission. The second argument submit_path, is the path to the student script, it is assumed to have executable permission. The Third optional argument is the path to test the scripts. Each line in this file is a test case and each test case is passed to the script as standard arguments. Returns -------- returns (True, "Correct answer") : If the student script passes all test cases/have same output, when compared to the instructor script returns (False, error_msg): If the student script fails a single test/have dissimilar output, when compared to the instructor script. Returns (False, error_msg): If mandatory arguments are not files or if the required permissions are not given to the file(s). """ ref_code_path = test_case get_ref_path, get_test_case_path = ref_code_path.strip().split(',') get_ref_path = get_ref_path.strip() get_test_case_path = get_test_case_path.strip() clean_ref_code_path, clean_test_case_path = \ self._set_test_code_file_path(get_ref_path, get_test_case_path) self.files = [] if file_paths: self.files = copy_files(file_paths) if not isfile(clean_ref_code_path): msg = "No file at %s or Incorrect path" % clean_ref_code_path return False, msg if not isfile(self.submit_code_path): msg = "No file at %s or Incorrect path" % self.submit_code_path return False, msg if not os.access(clean_ref_code_path, os.X_OK): msg = "Script %s is not executable" % clean_ref_code_path return False, msg if not os.access(self.submit_code_path, os.X_OK): msg = "Script %s is not executable" % self.submit_code_path return False, msg success = False user_answer = user_answer.replace("\r", "") self.write_to_submit_code_file(self.submit_code_path, user_answer) if clean_test_case_path is None or "": ret = self._run_command(clean_ref_code_path, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc, inst_stdout, inst_stderr = ret ret = self._run_command(self.submit_code_path, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc, stdnt_stdout, stdnt_stderr = ret if inst_stdout == stdnt_stdout: return True, "Correct answer" else: err = "Error: expected %s, got %s" % (inst_stderr, stdnt_stderr) return False, err else: if not isfile(clean_test_case_path): msg = "No test case at %s" % clean_test_case_path return False, msg if not os.access(clean_ref_code_path, os.R_OK): msg = "Test script %s, not readable" % clean_test_case_path return False, msg # valid_answer is True, so that we can stop once a test case fails valid_answer = True # loop_count has to be greater than or equal to one. # Useful for caching things like empty test files,etc. loop_count = 0 test_cases = open(clean_test_case_path).readlines() num_lines = len(test_cases) for test_case in test_cases: loop_count += 1 if valid_answer: args = [clean_ref_code_path] + \ [x for x in test_case.split()] ret = self._run_command(args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc, inst_stdout, inst_stderr = ret if file_paths: self.files = copy_files(file_paths) args = [self.submit_code_path] + \ [x for x in test_case.split()] ret = self._run_command(args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc, stdnt_stdout, stdnt_stderr = ret valid_answer = inst_stdout == stdnt_stdout if valid_answer and (num_lines == loop_count): return True, "Correct answer" else: err = ("Error:expected" " {0}, got {1}").format(inst_stdout + inst_stderr, stdnt_stdout + stdnt_stderr) return False, err
def create_proj(projPath, toolPath, u8serverPath, targetName, classPrefix, selectType): # if not targetName.startswith("U8SDK_"): # targetName = "U8SDK_" + targetName print("selectType:" + selectType) selectType = int(selectType) if selectType == 1 or selectType == 2: print("generate client...........") if not os.path.exists(projPath): log_utils.debug("the U8SDK_Projects dir is not exists." + projPath) return if not os.path.exists(toolPath): log_utils.debug("the U8SDKTool-Win-P34 dir is not exists." + toolPath) return templatePath = os.path.join(projPath, "U8SDK_Template") if not os.path.exists(templatePath): log_utils.debug("the template project is not exists." + templatePath) return sdkConfigPath = os.path.join(toolPath, "config/sdk/" + targetName.lower()) if os.path.exists(sdkConfigPath): log_utils.error( "sdk with same name is already exists. please change the name." + targetName) return projTargetName = "U8SDK_" + targetName targetPath = os.path.join(projPath, projTargetName) if os.path.exists(targetPath): log_utils.debug("the target project is already exists." + targetPath) return file_utils.copy_files(templatePath, targetPath) srcPath = os.path.join(targetPath, "src/com/u8/sdk") for f in os.listdir(srcPath): fname = os.path.join(srcPath, f) file_utils.modifyFileContent(fname, "Temp", classPrefix) ftarget = f.replace("Temp", classPrefix) os.rename(fname, os.path.join(srcPath, ftarget)) configPath = os.path.join(targetPath, "config.xml") file_utils.modifyFileContent(configPath, "Temp", classPrefix) projFilePath = os.path.join(targetPath, ".project") file_utils.modifyFileContent(projFilePath, "U8SDK_Template", projTargetName) os.makedirs(sdkConfigPath) if selectType == 1 or selectType == 3: u8serverSDKPath = os.path.join( u8serverPath, "src/main/java/com/u8/server/sdk/" + targetName.lower()) if os.path.exists(u8serverSDKPath): log_utils.error( "sdk with same name is already exists in server. please change the name." + targetName) return u8serverPayPath = os.path.join( u8serverPath, "src/main/java/com/u8/server/web/pay/sdk/" + targetName + "PayCallbackAction.java") if os.path.exists(u8serverPayPath): log_utils.error( "sdk with same name is already exists in server callback. please change the name." + targetName) return serverDemoSDKPath = os.path.join( u8serverPath, "src/main/java/com/u8/server/sdk/demo") file_utils.copy_files(serverDemoSDKPath, u8serverSDKPath) sdkName = os.path.join(u8serverSDKPath, 'DemoSDK.java') targetSDKName = sdkName.replace("Demo", targetName) os.rename(sdkName, targetSDKName) file_utils.modifyFileContent(targetSDKName, "Demo", targetName) file_utils.modifyFileContent(targetSDKName, "demo", targetName.lower()) serverDemoPayPath = os.path.join( u8serverPath, 'src/main/java/com/u8/server/web/pay/sdk/DemoPayCallbackAction.java' ) file_utils.copy_file(serverDemoPayPath, u8serverPayPath) file_utils.modifyFileContent(u8serverPayPath, "demo", targetName.lower()) file_utils.modifyFileContent(u8serverPayPath, "Demo", targetName)
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 copy_sdk(clientPath, outputPath, sdk, isPlugin=False): sdkFolder = 'sdk' if isPlugin: sdkFolder = 'plugin' sourcePath = os.path.join(clientPath, 'config/' + sdkFolder + '/' + sdk) if not os.path.exists(sourcePath): log_utils.error("the sdk path not exists:" + sourcePath) return False workspacePath = os.path.join(outputPath, 'workspace/' + sdkFolder + '/' + sdk) if not os.path.isabs(workspacePath): workspacePath = os.path.abspath(workspacePath) file_utils.del_file_folder(workspacePath) if not os.path.exists(workspacePath): os.makedirs(workspacePath) # copy sdk folder workSdkPath = os.path.join(workspacePath, 'sdk') file_utils.copy_files(sourcePath, workSdkPath) # handle gradle and aar # copy temp proj gradleProjDir = os.path.join(clientPath, 'config/local/U8_Temp_AS_Project') targetProjDir = os.path.join(workspacePath, 'U8_Temp_AS_Project') file_utils.copy_files(gradleProjDir, targetProjDir) sdkObj = read_sdk_config(workSdkPath, sdk) if 'dependencyList' in sdkObj and len(sdkObj['dependencyList']) > 0: log_utils.debug("begin to handle gradle dependencies:") try: ret = gradle_utils.handle_dependencies(workSdkPath, sdkObj['dependencyList']) if not ret: log_utils.error("gradle handle failed for :" + sdk) return False except Exception as e: log_utils.error("can not parse config.xml.path:" + configFile) log_utils.exception(e) return False # handle aar log_utils.debug("begin to handle aar for " + sdk) manifestNames = [ 'SDKManifest.xml', 'SDKManifest_portrait.xml', 'SDKManifest_landscape.xml' ] for m in manifestNames: if not os.path.exists(os.path.join(workSdkPath, m)): continue ret = aar_utils.handle_sdk_aars(sdkObj, workSdkPath, m) if not ret: log_utils.error("handle sdk aar files failed:", sdk) return False # copy assets in jar log_utils.debug("begin to copy assets in jars for sdk:" + sdk) copy_assets_in_jars(workSdkPath) # dump config.xml dump_sdk_config(workSdkPath, sdkObj) targetPath = os.path.join(outputPath, 'config/' + sdkFolder + '/' + sdk) file_utils.del_file_folder(targetPath) file_utils.copy_files(workSdkPath, targetPath) log_utils.debug("handle sdk success for :" + sdk)
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" 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