def get_pe_hash(pefilepath): ''' 获取 PE 文件的哈希值 ''' if not Common.is_file_exists(pefilepath): return None pe = pefile.PE(pefilepath, fast_load=True) return '%X%X' % (pe.FILE_HEADER.TimeDateStamp, pe.OPTIONAL_HEADER.SizeOfImage)
def has_changelog(ver): ''' 判断一个版本的信息是否存在于 Changelog.txt 中 存在返回 True 不在则返回 False ''' filepath = os.path.abspath(slndir('CHANGELOG.md')) if not Common.is_file_exists(filepath): return None matchgroup = Common.match_file_regex(filepath, ver) return True if matchgroup is not None else False
def get_pandas_ver(): ''' 读取当前 Pandas 在 src/config/pandas.hpp 定义的版本号 若读取不到版本号则返回 None ''' filepath = os.path.abspath(slndir('src/config/pandas.hpp')) if not Common.is_file_exists(filepath): return None matchgroup = match_file_regex(filepath, r'#define Pandas_Version "(.*)"') return matchgroup[0] if matchgroup is not None else None
def get_pdb_hash(pdbfilepath): ''' 获取 PDB 文件的哈希值 ''' if not Common.is_file_exists(pdbfilepath): return None p = pdbparse.parse(pdbfilepath, fast_load = True) pdb = p.streams[pdbparse.PDB_STREAM_PDB] pdb.load() guidstr = (u'%08x%04x%04x%s%x' % (pdb.GUID.Data1, pdb.GUID.Data2, pdb.GUID.Data3, binascii.hexlify( pdb.GUID.Data4).decode('ascii'), pdb.Age)).upper() return guidstr
def get_vcvarsall_path(): ''' 读取第一个有效 Visual Studio 的 vcvarsall.bat 所在路径 如果检测不到则返回 None ''' for vs in vs_configure: path = get_reg_value(vs) vcvarsall_path = None if Common.is_dir_exists(path): vcvarsall_path = os.path.join(path, vs['vcvarsall']) if Common.is_file_exists(vcvarsall_path): return vcvarsall_path return None
def execute(self, filename, savefile=None): if not Common.is_file_exists(filename): return False if not savefile: savefile = filename if not self.__silent: Message.ShowInfo('正在处理: %s (%s)' % (os.path.relpath( filename, self.__project_dir), self.__save_encoding)) contents = self.__load(filename) contents = self.__process(contents) return self.__save(contents, savefile)
def get_compile_result(): ''' 读取编译的结果, 返回四个值分别是: 读取成功与否, 成功项目数, 失败项目数, 跳过项目数 ''' filepath = os.path.abspath(slndir(compile_logfile)) if not Common.is_file_exists(filepath): return False, -1, -1, -1 pattern_list = [r'生成: 成功 (\d*) 个,失败 (\d*) 个,跳过 (\d*) 个'] for pattern in pattern_list: matchgroup = Common.match_file_regex(filepath, pattern) if matchgroup is not None and len(matchgroup) == 3: return True, matchgroup[0], matchgroup[1], matchgroup[2] return False, -1, -1, -1
def main(): # 加载 .env 中的配置信息 load_dotenv(dotenv_path='.config.env', encoding='UTF-8') # 若无配置信息则自动复制一份文件出来 if not Common.is_file_exists('.config.env'): shutil.copyfile('.config.env.sample', '.config.env') # 显示欢迎信息 Common.welcome('格式化占位符检查辅助脚本') print('') # 执行检查工作 for i in entrance_configure: do_check_file(os.path.abspath(project_slndir + i)) # 友好退出, 主要是在 Windows 环境里给予暂停 Common.exit_with_pause()
def __load(self, filename): if not Common.is_file_exists(filename): raise Exception('翻译对照表不存在: %s' % os.path.relpath(filename)) # 将文件中的内容读取成一个列表, 放在 contents 中 contents = [] with open(filename, 'r', encoding='UTF-8') as f: contents = f.readlines() # 进行编码校验工作 if self.__lang == 'zh-tw': for i, element in enumerate(contents): self.__encoding_check(element, 'big5', i + 1) elif self.__lang == 'zh-cn': for i, element in enumerate(contents): self.__encoding_check(element, 'gbk', i + 1) # 遍历处理列表中的全部内容, 让他们每一行都去掉左右的空格 contents = [x.strip() for x in contents] # 移除内容中有反斜杠的行 contents = [x for x in contents if not x.startswith('//')] # 把列表中的内容加工成字典, 若 ID 冲突则以最后读取到的为准 for line in contents: fields = line.split(',') if len(fields) != 2: continue if not fields[0]: continue if not fields[1]: continue mapid = str(fields[0]) self.__translateDict[mapid] = fields[1] self.__loaded = True
def main(): ''' 主入口函数 ''' # 加载 .env 中的配置信息 load_dotenv(dotenv_path='.config.env', encoding='UTF-8') # 若无配置信息则自动复制一份文件出来 if not Common.is_file_exists('.config.env'): shutil.copyfile('.config.env.sample', '.config.env') # 显示欢迎信息 Common.welcome('编译流程辅助脚本') # 只能在 Windows 环境运行 if platform.system() != 'Windows': Message.ShowError('很抱歉, 此脚本只能在 Windows 环境上运行') Common.exit_with_pause(-1) # 判断本机是否安装了支持的 Visual Studio detected_vs, vs_name = detect_vs() if not detected_vs: Message.ShowError('无法检测到合适的 Visual Studio 版本 (2015 或 2017)') Common.exit_with_pause(-1) else: Message.ShowStatus('检测到已安装: %s 应可正常编译' % vs_name) print('') # 读取当前的 Pandas 主程序版本号 pandas_ver = Common.get_pandas_ver(os.path.abspath(project_slndir)) Message.ShowInfo('当前模拟器的主版本是 %s' % pandas_ver) # 判断是否已经写入了对应的更新日志, 若没有则要给予提示再继续 if (has_changelog(pandas_ver)): Message.ShowStatus('已经在更新日志中找到了 %s 的版本信息.' % pandas_ver) else: Message.ShowWarning('没有在更新日志中找到 %s 版本的信息, 请注意完善!' % pandas_ver) # 判断当前 git 工作区是否干净, 若工作区不干净要给予提示 if git.Repo(project_slndir).is_dirty(): if not Inputer().requireBool({ 'tips': '当前模拟器代码仓库的工作区不干净, 要继续编译吗?', 'default': False }): Message.ShowStatus('您主动放弃了继续操作') Common.exit_with_pause(-1) else: Message.ShowStatus('当前模拟器代码仓库的工作区是干净的.') # 检查 Crashrpt 使用的信息是否都设置好了, 若没有且企图编译正式版, 则给与提示 if Common.is_pandas_release(os.path.abspath(project_slndir)): if not os.getenv("DEFINE_CRASHRPT_APPID"): Message.ShowWarning('当前并未设置 AppID, 且企图编译正式版.') Common.exit_with_pause(-1) if Common.md5(os.getenv("DEFINE_CRASHRPT_APPID") ) != '952648de2d8f063a07331ae3827bc406': Message.ShowWarning('当前已设置了 AppID, 但并非正式版使用的 AppID.') Common.exit_with_pause(-1) if not os.getenv("DEFINE_CRASHRPT_PUBLICKEY"): Message.ShowWarning('当前并未设置 PublicKey, 且企图编译正式版.') Common.exit_with_pause(-1) Message.ShowStatus('即将开始编译, 编译速度取决于电脑性能, 请耐心...') # 清理目前的工作目录, 把一些可明确移除的删掉 clean_environment() # 编译 Pandas 的复兴前版本 compile_prere(pandas_ver) # 编译 Pandas 的复兴后版本 compile_renewal(pandas_ver) Message.ShowStatus('编译工作已经全部结束, 请归档符号并执行打包流程.') # 友好退出, 主要是在 Windows 环境里给予暂停 Common.exit_with_pause()
def main(): ''' 主入口函数 ''' # 加载 .env 中的配置信息 load_dotenv(dotenv_path='.config.env', encoding='UTF-8') # 若无配置信息则自动复制一份文件出来 if not Common.is_file_exists('.config.env'): shutil.copyfile('.config.env.sample', '.config.env') # 显示欢迎信息 Common.welcome('打包流程辅助脚本') print('') pandas_ver = Common.get_pandas_ver(os.path.abspath(project_slndir)) Message.ShowInfo('当前模拟器的主版本是 %s' % pandas_ver) # 若环境变量为空则设置个默认值 if not os.getenv('DEFINE_PROJECT_NAME'): os.environ["DEFINE_PROJECT_NAME"] = "Pandas" if not os.getenv('DEFINE_COMPILE_MODE'): os.environ["DEFINE_COMPILE_MODE"] = "re,pre" Message.ShowInfo('当前输出的项目名称为: %s' % os.getenv('DEFINE_PROJECT_NAME')) # 检查是否已经完成了编译 if 're' in os.getenv('DEFINE_COMPILE_MODE').split(','): if not Common.is_compiled(project_slndir, checkmodel='re'): Message.ShowWarning('检测到打包需要的编译产物不完整, 请重新编译. 程序终止.') print('') Common.exit_with_pause(-1) if 'pre' in os.getenv('DEFINE_COMPILE_MODE').split(','): if not Common.is_compiled(project_slndir, checkmodel='pre'): Message.ShowWarning('检测到打包需要的编译产物不完整, 请重新编译. 程序终止.') print('') Common.exit_with_pause(-1) # 导出当前仓库, 变成一个归档压缩文件 Message.ShowInfo('正在将当前分支的 HEAD 内容导出成归档文件...') export_file = export() if not export_file: Message.ShowError('很抱歉, 导出归档文件失败, 程序终止.') Common.exit_with_pause(-1) Message.ShowInfo('归档文件导出完成, 此文件将在程序结束时被删除.') # 基于归档压缩文件, 进行打包处理 if 're' in os.getenv('DEFINE_COMPILE_MODE').split(','): process(export_file, renewal=True) if 'pre' in os.getenv('DEFINE_COMPILE_MODE').split(','): process(export_file, renewal=False) # 执行一些清理工作 clean(export_file) print('') Message.ShowInfo('已经成功打包相关文件, 请进行人工核验.') # 友好退出, 主要是在 Windows 环境里给予暂停 Common.exit_with_pause()
def main(): ''' 主入口函数 ''' # 加载 .env 中的配置信息 load_dotenv(dotenv_path='pyhelp.conf', encoding='UTF-8-SIG') # 若无配置信息则自动复制一份文件出来 if not Common.is_file_exists('pyhelp.conf'): shutil.copyfile('pyhelp.conf.sample', 'pyhelp.conf') # 显示欢迎信息 Common.welcome('编译流程辅助脚本') # 只能在 Windows 环境运行 if platform.system() != 'Windows': Message.ShowError('很抱歉, 此脚本只能在 Windows 环境上运行') Common.exit_with_pause(-1) # 判断本机是否安装了支持的 Visual Studio detected_vs, vs_name = detect_vs() if not detected_vs: Message.ShowError('无法检测到合适的 Visual Studio 版本 (2015 或 2017)') Common.exit_with_pause(-1) else: Message.ShowStatus('检测到已安装: %s 应可正常编译' % vs_name) print('') # 读取当前的 Pandas 主程序版本号 pandas_ver = get_pandas_ver() Message.ShowInfo('当前模拟器的主版本是 %s' % pandas_ver) # 判断是否已经写入了对应的更新日志, 若没有则要给予提示再继续 if (has_changelog(pandas_ver)): Message.ShowStatus('已经在更新日志中找到了 %s 的版本信息.' % pandas_ver) else: Message.ShowWarning('没有在更新日志中找到 %s 版本的信息, 请注意完善!' % pandas_ver) # 检查创建并尝试更新符号仓库 update_symstore() # 判断当前 git 工作区是否干净, 若工作区不干净要给予提示 if git.Repo(project_slndir).is_dirty(): if not Inputer().requireBool({ 'tips' : '当前模拟器代码仓库的工作区不干净, 要继续编译吗?', 'default' : False }): Message.ShowStatus('您主动放弃了继续操作') Common.exit_with_pause(-1) else: Message.ShowStatus('当前模拟器代码仓库的工作区是干净的.') Message.ShowStatus('即将开始编译, 编译速度取决于电脑性能, 请耐心...') # 清理目前的工作目录, 把一些可明确移除的删掉 clean_environment() # 编译 Pandas 的复兴前版本 compile_prere(pandas_ver) # 将复兴前版本的编译产物重命名一下, 避免编译复兴后版本时被覆盖 shutil.move(slndir('login-server.exe'), slndir('login-server-pre.exe')) shutil.move(slndir('login-server.pdb'), slndir('login-server-pre.pdb')) shutil.move(slndir('char-server.exe'), slndir('char-server-pre.exe')) shutil.move(slndir('char-server.pdb'), slndir('char-server-pre.pdb')) shutil.move(slndir('map-server.exe'), slndir('map-server-pre.exe')) shutil.move(slndir('map-server.pdb'), slndir('map-server-pre.pdb')) # 编译 Pandas 的复兴后版本 print('') compile_renewal(pandas_ver) print('') Message.ShowStatus('编译工作已经全部结束.') Message.ShowStatus('编译时产生的符号文件已存储, 记得提交符号文件.\n') # 友好退出, 主要是在 Windows 环境里给予暂停 Common.exit_with_pause(0)
def main(): # 加载 .env 中的配置信息 load_dotenv(dotenv_path='.config.env', encoding='UTF-8') # 若无配置信息则自动复制一份文件出来 if not Common.is_file_exists('.config.env'): shutil.copyfile('.config.env.sample', '.config.env') # 显示欢迎信息 Common.welcome('符号归档辅助脚本') print('') # 由于 pdbparse 只能在 Windows 环境下安装, 此处进行限制 if platform.system() != 'Windows': Message.ShowWarning('该脚本只能在 Windows 环境下运行, 程序终止.') Common.exit_with_pause(-1) # 若环境变量为空则设置个默认值 if not os.getenv('DEFINE_PROJECT_NAME'): os.environ["DEFINE_PROJECT_NAME"] = "Pandas" if not os.getenv('DEFINE_SYMBOLS_SOURCE'): os.environ["DEFINE_SYMBOLS_SOURCE"] = "PandasWS/Pandas" if not os.getenv('DEFINE_COMPILE_MODE'): os.environ["DEFINE_COMPILE_MODE"] = "re,pre" # 符号仓库工程路径 global project_symstoredir project_symstoredir = os.path.abspath(project_slndir + '../Symbols/' + os.getenv('DEFINE_PROJECT_NAME')) Message.ShowInfo('当前输出的项目名称为: %s' % os.getenv('DEFINE_PROJECT_NAME')) # 检查是否已经完成了编译 if 're' in os.getenv('DEFINE_COMPILE_MODE').split(','): if not Common.is_compiled(project_slndir, checkmodel='re'): Message.ShowWarning('检测到打包需要的编译产物不完整, 请重新编译. 程序终止.') Common.exit_with_pause(-1) if 'pre' in os.getenv('DEFINE_COMPILE_MODE').split(','): if not Common.is_compiled(project_slndir, checkmodel='pre'): Message.ShowWarning('检测到打包需要的编译产物不完整, 请重新编译. 程序终止.') Common.exit_with_pause(-1) # 检查符号仓库是否存在, 不存在则创建 if not ensure_store(): Message.ShowWarning('你放弃了拉取符号仓库, 后续工作无法继续. 程序终止.') Common.exit_with_pause(-1) else: Message.ShowStatus('符号仓库已经存在于本地, 开始确认工作区状态...') # 若符号文件存在, 则确保工作区干净 if not ensure_store_clean(): Message.ShowWarning('为了防止出现意外, 请确保符号仓库的工作区是干净的. 程序终止.') Common.exit_with_pause(-1) else: Message.ShowStatus('很好, 符号仓库的工作区是干净的.') # 尝试更新本地的符号仓库到最新 if not update_store(): Message.ShowWarning('为了防止出现意外, 请确保符号仓库同步到最新. 程序终止.') Common.exit_with_pause(-1) else: Message.ShowStatus('符号仓库已经同步到最新, 开始归档新的符号文件...') # 搜索工程目录全部 pdb 文件和 exe 文件, 进行归档 deploy_symbols(project_slndir) # 若环境变量为空则设置个默认值 if not os.getenv('DEFINE_SYMBOLS_COMMIT'): os.environ["DEFINE_SYMBOLS_COMMIT"] = "3" commit_flag = int(os.getenv('DEFINE_SYMBOLS_COMMIT')) # 自动进行 git 提交操作 if commit_flag & 1 == 1: if not Common.is_pandas_release(os.path.abspath(project_slndir)): Message.ShowStatus('符号文件已经归档完毕, 但并非正式版所以未自动提交...') Common.exit_with_pause() if commit_flag & 2 == 2: if Common.md5(os.getenv("DEFINE_CRASHRPT_APPID") ) != '952648de2d8f063a07331ae3827bc406': Message.ShowStatus( '符号文件已经归档完毕, 但未设置熊猫模拟器官方正式版的崩溃上报 APPID, 所以并未自动提交...') Common.exit_with_pause() Message.ShowStatus('符号文件已经归档完毕, 正在提交...') if not make_commit(): Message.ShowWarning('很抱歉, 提交失败! 请确认失败的原因. 程序终止.') Common.exit_with_pause(-1) else: Message.ShowStatus('提交成功, 请手工推送到远程仓库.') # 友好退出, 主要是在 Windows 环境里给予暂停 Common.exit_with_pause()