|
|
@@ -0,0 +1,378 @@
|
|
|
+# -*- coding:utf-8 -*-
|
|
|
+import os
|
|
|
+import re
|
|
|
+import shutil
|
|
|
+import subprocess
|
|
|
+import sys
|
|
|
+import time
|
|
|
+
|
|
|
+import win32api
|
|
|
+import win32con
|
|
|
+import yaml
|
|
|
+import xml.etree.ElementTree as ET
|
|
|
+channel_rose = '朱雀'
|
|
|
+channel_coolpad='FAKE'
|
|
|
+channel_xmy = '小绵羊'
|
|
|
+channel_9hgame = '九狐'
|
|
|
+channel_icefoxgame = '冰狐'
|
|
|
+# 测试组游戏地址,需要根据游戏修改
|
|
|
+# 测试组游戏地址,需要根据游戏修改
|
|
|
+# 测试组游戏地址,需要根据游戏修改
|
|
|
+game_dir = r'\\10.8.230.114\public\测试组\青雀\秦皇汉武Y'
|
|
|
+# 其他情况使用BPM上面的任务名称
|
|
|
+game_channel = '秦皇汉武Y-朱雀'
|
|
|
+
|
|
|
+def copy_mommy_for_9hgame(decompile_dir_path):
|
|
|
+ htprotect_dir_path = os.path.join(decompile_dir_path, 'smali', 'com', 'ydzs', 'framework')
|
|
|
+ if not os.path.exists(htprotect_dir_path):
|
|
|
+ os.makedirs(htprotect_dir_path)
|
|
|
+ shutil.copy(os.path.join(r'D:\special_problem\九狐', 'MommyUtils.smali'), htprotect_dir_path)
|
|
|
+
|
|
|
+if ' ' in game_channel:
|
|
|
+ game_channel = game_channel.replace(' ', '-')
|
|
|
+print(sys.argv)
|
|
|
+if len(sys.argv) == 3:
|
|
|
+ game_dir = sys.argv[1]
|
|
|
+ game_channel = sys.argv[2]
|
|
|
+print(game_dir)
|
|
|
+print(game_channel)
|
|
|
+
|
|
|
+def fix_install_fail_bug(decompile_dir_path):
|
|
|
+ namespace = '{http://schemas.android.com/apk/res/android}'
|
|
|
+ ET.register_namespace('android', 'http://schemas.android.com/apk/res/android')
|
|
|
+ manifest_path = os.path.join(decompile_dir_path, 'AndroidManifest.xml')
|
|
|
+ xml_tree = ET.parse(manifest_path)
|
|
|
+ xml_root = xml_tree.getroot()
|
|
|
+ application_node = xml_root.find('./application')
|
|
|
+ etract_value = application_node.get(f'{namespace}extractNativeLibs')
|
|
|
+ if etract_value is not None and etract_value == 'false':
|
|
|
+ # 修改extractNativeLib
|
|
|
+ application_node.set(f'{namespace}extractNativeLibs', 'true')
|
|
|
+ xml_tree.write(manifest_path, encoding='utf-8', xml_declaration=True)
|
|
|
+
|
|
|
+ yaml_path = os.path.join(decompile_dir_path, 'apktool.yml')
|
|
|
+ file = open(yaml_path, 'r', encoding='utf-8')
|
|
|
+ yaml_result = yaml.load(file, Loader=yaml.BaseLoader)
|
|
|
+ sdk_info = yaml_result['sdkInfo']
|
|
|
+ yaml_result['packageInfo']['renameManifestPackage'] = None
|
|
|
+ print(sdk_info)
|
|
|
+ if int(sdk_info['targetSdkVersion']) > 29:
|
|
|
+ sdk_info['targetSdkVersion'] = '29'
|
|
|
+ print(sdk_info)
|
|
|
+ file.close()
|
|
|
+ with open(yaml_path, 'w', encoding='utf-8') as f:
|
|
|
+ yaml.dump(yaml_result, f)
|
|
|
+
|
|
|
+def rindex(lst, value):
|
|
|
+ for i, v in enumerate(reversed(lst)):
|
|
|
+ if v == value:
|
|
|
+ return len(lst) - i - 1 # return the index in the original list`
|
|
|
+ return None
|
|
|
+
|
|
|
+
|
|
|
+def move_game_apk_to_work():
|
|
|
+ cmd_move_str = f'copy {game_path} {work_path}'
|
|
|
+ print(cmd_move_str)
|
|
|
+ result = subprocess.getoutput(cmd_move_str)
|
|
|
+ print(result)
|
|
|
+
|
|
|
+
|
|
|
+def get_decompile_dir_name(apk_path):
|
|
|
+ s_index = apk_path.index('.')
|
|
|
+ print('s_index', s_index)
|
|
|
+ p_index = rindex(apk_path, '\\')
|
|
|
+ print('p_index:', p_index)
|
|
|
+ dir_name = apk_path[:rindex(apk_path, '\\') + 1] + apk_path[p_index + 1:s_index]
|
|
|
+ print('dir_name:', dir_name)
|
|
|
+ return dir_name
|
|
|
+
|
|
|
+
|
|
|
+def find_r_smali_and_replace(smali_file_path, regex_str):
|
|
|
+ with open(smali_file_path, 'r') as f:
|
|
|
+ smali_str = f.read()
|
|
|
+ pattern = re.compile(regex_str)
|
|
|
+ resource_arr = pattern.findall(smali_str)
|
|
|
+ if len(resource_arr) > 0:
|
|
|
+ print(smali_file_path)
|
|
|
+ for r_str in resource_arr:
|
|
|
+ virtual_name = r_str[r_str.index(' ') + 1:r_str.index(',')]
|
|
|
+ print(virtual_name)
|
|
|
+ resource_type = r_str[r_str.index('R$') + 2:r_str.index(';')].capitalize()
|
|
|
+ print(resource_type)
|
|
|
+ resource_name = r_str[r_str.index('->') + 2:r_str.index(':')]
|
|
|
+ print(resource_name)
|
|
|
+ new_r_str = "const-string %s, \"%s\"\n\n\tinvoke-static {%s}, Lcom/ydzs/framework/MommyUtils;->get%sId(Ljava/lang/String;)I\n\n\tmove-result %s" % (
|
|
|
+ virtual_name, resource_name, virtual_name, resource_type, virtual_name)
|
|
|
+ print(new_r_str)
|
|
|
+ smali_str = smali_str.replace(r_str, new_r_str)
|
|
|
+ with open(smali_file_path, 'w') as f:
|
|
|
+ f.write(smali_str)
|
|
|
+
|
|
|
+
|
|
|
+def replace_rose_resource(d_dir):
|
|
|
+ r_regex_str = r'sget[^\n]*R\$layout[^\n]*I|sget[^\n]*R\$id[^\n]*I|sget[^\n]*R\$drawable[^\n]*I|sget[^\n]*R\$string[^\n]*I|sget[^\n]*R\$array[^\n]*I|sget[^\n]*R\$bool[^\n]*I|sget[^\n]*R\$integer[^\n]*I'
|
|
|
+ for dirpath, dirnames, filenames in os.walk(d_dir):
|
|
|
+ if r'com\wanwu' in dirpath or r'com\ydzs' in dirpath:
|
|
|
+ for smali_file in filenames:
|
|
|
+ smali_file_path = os.path.join(dirpath, smali_file)
|
|
|
+ # print(smali_file_path)
|
|
|
+ find_r_smali_and_replace(smali_file_path, r_regex_str)
|
|
|
+
|
|
|
+
|
|
|
+def fix_coolpad_version_3_method_name_change_bug(decompile_dir):
|
|
|
+ is_version_3_sdk = False
|
|
|
+ is_new_sdk_and_version_lt_version_3 = False
|
|
|
+ for dirpath, dirnames, filenames in os.walk(decompile_dir):
|
|
|
+ if r'com\yulong\sdk\promoter' in dirpath and 'OnGameAuthListener.smali' in filenames:
|
|
|
+ auth_listener_path = os.path.join(dirpath, 'OnGameAuthListener.smali')
|
|
|
+ with open(auth_listener_path, 'r', encoding='utf-8') as f:
|
|
|
+ smali_str_arr = f.read()
|
|
|
+ if 'onSuccess' in smali_str_arr:
|
|
|
+ is_version_3_sdk = True
|
|
|
+ if 'onResult' in smali_str_arr:
|
|
|
+ is_new_sdk_and_version_lt_version_3 = True
|
|
|
+ break
|
|
|
+ for dirpath, dirnames, filenames in os.walk(decompile_dir):
|
|
|
+ if r'com\yulong\sdk\promoter' in dirpath and 'PromoterGameAuthApi$1.smali' in filenames:
|
|
|
+ smali_path = os.path.join(dirpath, 'PromoterGameAuthApi$1.smali')
|
|
|
+ print(smali_path)
|
|
|
+ with open(smali_path, 'r', encoding='utf-8') as f:
|
|
|
+ smali_str_arr = f.readlines()
|
|
|
+ index_str = r'onSuccess'
|
|
|
+ if is_new_sdk_and_version_lt_version_3:
|
|
|
+ index_str = r'onSuccess'
|
|
|
+ elif is_version_3_sdk:
|
|
|
+ index_str = r'onResult'
|
|
|
+ for line in smali_str_arr:
|
|
|
+ if index_str in line:
|
|
|
+ print(line)
|
|
|
+ index = smali_str_arr.index(line)
|
|
|
+ if is_new_sdk_and_version_lt_version_3:
|
|
|
+ smali_str_arr[index] = line.replace(index_str, 'onResult')
|
|
|
+ elif is_version_3_sdk:
|
|
|
+ smali_str_arr[index] = line.replace(index_str, 'onSuccess')
|
|
|
+ print(smali_str_arr[index])
|
|
|
+ break
|
|
|
+ with open(smali_path, 'w', encoding='utf-8') as f:
|
|
|
+ f.write(''.join(smali_str_arr))
|
|
|
+ break
|
|
|
+ return is_version_3_sdk
|
|
|
+
|
|
|
+
|
|
|
+def fix_coolpad_version_3_login_fail_bug(decompile_dir_path):
|
|
|
+ insert_str_list = [
|
|
|
+ '\n\t.locals 0\n\n',
|
|
|
+ '\treturn-void\n\n']
|
|
|
+ for dirpath, dirnames, filenames in os.walk(decompile_dir_path):
|
|
|
+ if r'com\yulong\account\auth' in dirpath and 'AuthCodeApiImpl.smali' in filenames:
|
|
|
+ smali_path = os.path.join(dirpath, 'AuthCodeApiImpl.smali')
|
|
|
+ with open(smali_path, 'r', encoding='utf-8') as f:
|
|
|
+ smali_str_arr = f.readlines()
|
|
|
+ index_str = '.method private returnAuthError(Lcom/yulong/account/common/info/ErrorInfo;)V'
|
|
|
+ end_method_str = '.end method'
|
|
|
+ insert_str = ''.join(insert_str_list)
|
|
|
+ on_create_index = 0
|
|
|
+ insert_index = 0
|
|
|
+ for line in smali_str_arr:
|
|
|
+ if index_str in line:
|
|
|
+ on_create_index = smali_str_arr.index(line)
|
|
|
+ print('on_create_index', on_create_index, line)
|
|
|
+ break
|
|
|
+ for index, value in enumerate(smali_str_arr):
|
|
|
+ if index > on_create_index and end_method_str in value:
|
|
|
+ insert_index = index
|
|
|
+ print('insert_index', index)
|
|
|
+ break
|
|
|
+ print(on_create_index, insert_index)
|
|
|
+ del smali_str_arr[on_create_index + 1:insert_index]
|
|
|
+ smali_str_arr.insert(on_create_index + 1, insert_str)
|
|
|
+ with open(smali_path, 'w', encoding='utf-8') as f:
|
|
|
+ f.write(''.join(smali_str_arr))
|
|
|
+ break
|
|
|
+
|
|
|
+start_time = int(time.time())
|
|
|
+# 判断游戏是否需要修复并且是否是朱雀游戏,不需要修复就只需要拷贝arm64
|
|
|
+script_dir_list = os.listdir(r'F:\python_learn\day_1\script')
|
|
|
+is_need_fix = False
|
|
|
+for py_name in script_dir_list:
|
|
|
+ if game_channel in py_name:
|
|
|
+ is_need_fix = True
|
|
|
+ break
|
|
|
+
|
|
|
+print("aaaaaaaaaaaaaaa", is_need_fix)
|
|
|
+
|
|
|
+game_path = 'game_path is empty'
|
|
|
+for game_name in os.listdir(game_dir):
|
|
|
+ if ((channel_rose in game_channel or '青雀' in game_channel) and channel_rose in game_name) \
|
|
|
+ or ((channel_coolpad in game_channel or 'fake' in game_channel) and channel_coolpad in game_name)\
|
|
|
+ or ((channel_icefoxgame in game_channel or '冰狐' in game_channel) and channel_icefoxgame in game_name)\
|
|
|
+ or (channel_9hgame in game_channel and channel_9hgame in game_name)\
|
|
|
+ or (channel_xmy in game_channel and channel_xmy in game_name)\
|
|
|
+ or ('遥望' in game_channel and '遥望' in game_name):
|
|
|
+ game_path = os.path.join(game_dir, game_name)
|
|
|
+ break
|
|
|
+print('game_path:', game_path)
|
|
|
+work_path = r"D:\work"
|
|
|
+apk_file_path = f'{work_path}' + game_path[rindex(game_path, "\\"):]
|
|
|
+apk_file_path_copy = os.path.join(work_path, 'copy_'+game_path[rindex(game_path, "\\")+1:])
|
|
|
+print(apk_file_path_copy)
|
|
|
+if '全民泡泡' in game_channel:
|
|
|
+ if channel_rose in game_channel:
|
|
|
+ decompile_dir_name = os.path.join(work_path, 'qmpp_rose')
|
|
|
+ elif channel_coolpad in game_channel or 'fake' in game_channel:
|
|
|
+ decompile_dir_name = os.path.join(work_path, 'qmpp_coolpad')
|
|
|
+ elif channel_9hgame in game_channel:
|
|
|
+ decompile_dir_name = os.path.join(work_path, 'qmpp_9hgame')
|
|
|
+ else:
|
|
|
+ decompile_dir_name = os.path.join(work_path, 'qmpp_xmy')
|
|
|
+elif '我的安吉拉2' in game_channel:
|
|
|
+ if channel_rose in game_channel:
|
|
|
+ decompile_dir_name = os.path.join(work_path, 'wdajl_rose')
|
|
|
+ elif channel_coolpad in game_channel or 'fake' in game_channel:
|
|
|
+ decompile_dir_name = os.path.join(work_path, 'wdajl_coolpad')
|
|
|
+ elif channel_9hgame in game_channel:
|
|
|
+ decompile_dir_name = os.path.join(work_path, 'wdajl_9hgame')
|
|
|
+ else:
|
|
|
+ decompile_dir_name = os.path.join(work_path, 'wdajl_xmy')
|
|
|
+else:
|
|
|
+ decompile_dir_name = get_decompile_dir_name(apk_file_path)
|
|
|
+
|
|
|
+
|
|
|
+kfzs_sign = "kfzs_sign"
|
|
|
+kfzs_sign_youliang = "kfzs_sign_youliang"
|
|
|
+ydzs_sign = "ydzs_sign"
|
|
|
+# 签名文件,需要根据游戏修改
|
|
|
+# 签名文件,需要根据游戏修改
|
|
|
+# 签名文件,需要根据游戏修改
|
|
|
+current_sign = kfzs_sign
|
|
|
+if channel_rose in game_path or channel_coolpad in game_path or channel_9hgame in game_path:
|
|
|
+ current_sign = ydzs_sign
|
|
|
+elif channel_xmy in game_path:
|
|
|
+ current_sign = kfzs_sign
|
|
|
+
|
|
|
+# 修复脚本文件名,需要根据游戏修改
|
|
|
+# 修复脚本文件名,需要根据游戏修改
|
|
|
+# 修复脚本文件名,需要根据游戏修改
|
|
|
+if is_need_fix:
|
|
|
+ fix_python_path = os.path.join(r'F:\python_learn\day_1\script', f'{game_channel}.py')
|
|
|
+ print('fix_python_path', fix_python_path)
|
|
|
+
|
|
|
+# # 拷贝游戏包
|
|
|
+move_game_apk_to_work()
|
|
|
+# 复制一个原始包,只第一次复制
|
|
|
+if apk_file_path_copy[rindex(apk_file_path, '\\')+1:] not in os.listdir(work_path):
|
|
|
+ print("执行拷贝原始游戏包")
|
|
|
+ copy_origin_game_apk = f'copy {apk_file_path} {apk_file_path_copy}'
|
|
|
+ subprocess.getoutput(copy_origin_game_apk)
|
|
|
+else:
|
|
|
+ print("不执行拷贝原始游戏包")
|
|
|
+# # 解包
|
|
|
+cmd_decompile_str = rf'apktool d {apk_file_path} -f -o {decompile_dir_name} --only-main-classes'
|
|
|
+print(cmd_decompile_str)
|
|
|
+os.system(cmd_decompile_str)
|
|
|
+
|
|
|
+if channel_9hgame in game_path or channel_icefoxgame in game_path:
|
|
|
+ copy_mommy_for_9hgame(decompile_dir_name)
|
|
|
+
|
|
|
+#朱雀包拷贝arm64
|
|
|
+if (channel_rose in game_path or channel_coolpad in game_path or channel_9hgame in game_path or channel_icefoxgame in game_path) and 'arm64-v8a' in os.listdir(os.path.join(decompile_dir_name, 'lib')):
|
|
|
+ print('朱雀拷贝arm64')
|
|
|
+ arm64_path = os.path.join(decompile_dir_name, 'lib', 'arm64-v8a')
|
|
|
+ cmd_copy_arm64 = rf'copy D:\special_problem\朱雀arm64\libydzs.so {arm64_path}'
|
|
|
+ os.system(cmd_copy_arm64)
|
|
|
+ cmd_copy_arm64 = rf'copy D:\special_problem\朱雀arm64\libwanwusdk.so {arm64_path}'
|
|
|
+ os.system(cmd_copy_arm64)
|
|
|
+#朱雀包拷贝x86
|
|
|
+if (channel_rose in game_path or channel_coolpad in game_path or channel_9hgame in game_path or channel_icefoxgame in game_path) and 'x86' in os.listdir(os.path.join(decompile_dir_name, 'lib')):
|
|
|
+ print('朱雀拷贝x86')
|
|
|
+ x86_path = os.path.join(decompile_dir_name, 'lib', 'x86')
|
|
|
+ cmd_copy_x86 = rf'copy D:\special_problem\朱雀x86\libydzs.so {x86_path}'
|
|
|
+ os.system(cmd_copy_x86)
|
|
|
+
|
|
|
+#朱雀包修改资源获取方式
|
|
|
+if channel_rose in game_path or channel_coolpad in game_path or channel_9hgame in game_path or channel_icefoxgame in game_path:
|
|
|
+ print('执行朱雀包修改资源脚本')
|
|
|
+ replace_rose_resource(decompile_dir_name)
|
|
|
+ for dirpath, dirnames, filenames in os.walk(decompile_dir_name):
|
|
|
+ if r'com\ydzs\framework\java' in dirpath and 'YDZSSDKUser.smali' in filenames:
|
|
|
+ smali_path = os.path.join(dirpath, 'YDZSSDKUser.smali')
|
|
|
+ print(smali_path)
|
|
|
+ with open(smali_path, 'r', encoding='utf-8') as f:
|
|
|
+ smali_str_arr = f.readlines()
|
|
|
+ index_str = 'invoke-static {}, Lcom/ydzs/framework/SDKNativeWrapper;->nativeGetRealnameStatus()Ljava/lang/String;'
|
|
|
+ index_str2 = 'invoke-static {p1}, Lcom/ydzs/framework/SDKNativeWrapper;->nativeEnterGame(Ljava/util/HashMap;)Ljava/lang/String;'
|
|
|
+ replace_str = '\tinvoke-static {}, Lcom/ydzs/framework/SDKNativeWrapper;->nativeGetRealnameStatus()V\n'
|
|
|
+ replace_str2 = '\tinvoke-static {p1}, Lcom/ydzs/framework/SDKNativeWrapper;->nativeEnterGame(Ljava/util/HashMap;)V\n'
|
|
|
+ for line in smali_str_arr:
|
|
|
+ if index_str in line:
|
|
|
+ smali_str_arr[smali_str_arr.index(line)] = replace_str
|
|
|
+ if index_str2 in line:
|
|
|
+ smali_str_arr[smali_str_arr.index(line)] = replace_str2
|
|
|
+ with open(smali_path, 'w', encoding='utf-8') as f:
|
|
|
+ f.write(''.join(smali_str_arr))
|
|
|
+
|
|
|
+ if r'com\ydzs\framework' in dirpath and 'SDKNativeWrapper.smali' in filenames:
|
|
|
+ smali_path = os.path.join(dirpath, 'SDKNativeWrapper.smali')
|
|
|
+ print(smali_path)
|
|
|
+ with open(smali_path, 'r', encoding='utf-8') as f:
|
|
|
+ smali_str_arr = f.readlines()
|
|
|
+ index_str = '.method public static native nativeGetRealnameStatus()Ljava/lang/String;'
|
|
|
+ index_str2 = '.method public static native nativeEnterGame(Ljava/util/HashMap;)Ljava/lang/String;'
|
|
|
+ replace_str = '.method public static native nativeGetRealnameStatus()V\n'
|
|
|
+ replace_str2 = '.method public static native nativeEnterGame(Ljava/util/HashMap;)V\n'
|
|
|
+ for line in smali_str_arr:
|
|
|
+ if index_str in line:
|
|
|
+ smali_str_arr[smali_str_arr.index(line)] = replace_str
|
|
|
+ if index_str2 in line:
|
|
|
+ smali_str_arr[smali_str_arr.index(line)] = replace_str2
|
|
|
+ with open(smali_path, 'w', encoding='utf-8') as f:
|
|
|
+ f.write(''.join(smali_str_arr))
|
|
|
+
|
|
|
+# # 修复脚本
|
|
|
+if is_need_fix:
|
|
|
+ os.system(f'python {fix_python_path} {decompile_dir_name} {game_dir}')
|
|
|
+
|
|
|
+#修复酷派新sdk 3.0接口方法名改变登录后闪退bug
|
|
|
+is_version_3_sdk = fix_coolpad_version_3_method_name_change_bug(decompile_dir_name)
|
|
|
+print('is_version_3_sdk: ', is_version_3_sdk)
|
|
|
+if is_version_3_sdk:
|
|
|
+ fix_coolpad_version_3_login_fail_bug(decompile_dir_name)
|
|
|
+
|
|
|
+fix_install_fail_bug(decompile_dir_name)
|
|
|
+
|
|
|
+# # 合包
|
|
|
+if '全民泡泡' in game_channel or '我的安吉拉2' in game_channel:
|
|
|
+ cmd_build_str = f'apktool b {decompile_dir_name} -f -o {apk_file_path} --use-aapt2'
|
|
|
+elif '乱世终结' in game_channel:
|
|
|
+ cmd_build_str = f'apktool b {decompile_dir_name} -f -o {apk_file_path} -api 29'
|
|
|
+else:
|
|
|
+ cmd_build_str = f'apktool b {decompile_dir_name} -f -o {apk_file_path}'
|
|
|
+print('cmd_build_str:', cmd_build_str)
|
|
|
+os.system(cmd_build_str)
|
|
|
+# 签名
|
|
|
+if '极无双' in game_channel or '终末阵线' in game_channel\
|
|
|
+ or '灌篮高手' in game_channel or '炼仙传说' in game_channel\
|
|
|
+ or '生死狙击' in game_channel or '全明星激斗' in game_channel\
|
|
|
+ or '弹弹堂大冒险' in game_channel or '勇者秘境' in game_channel\
|
|
|
+ or '狩猎吧原始人' in game_channel:
|
|
|
+ current_sign = kfzs_sign_youliang
|
|
|
+
|
|
|
+if '航海王启航D' in game_channel:
|
|
|
+ current_sign = ydzs_sign
|
|
|
+
|
|
|
+if '我叫MT:经典再现Y' in game_channel:
|
|
|
+ current_sign = kfzs_sign
|
|
|
+
|
|
|
+cmd_sign_str = rf'{current_sign} {apk_file_path}'
|
|
|
+print(cmd_sign_str)
|
|
|
+cmd_result = subprocess.getoutput(cmd_sign_str)
|
|
|
+print(cmd_result)
|
|
|
+# 拷贝回测试组
|
|
|
+cmd_move_back_to_test_public = f'copy {apk_file_path} {game_dir}'
|
|
|
+print(cmd_move_back_to_test_public)
|
|
|
+cmd_result = subprocess.getoutput(cmd_move_back_to_test_public)
|
|
|
+print(cmd_result)
|
|
|
+end_time = int(time.time())
|
|
|
+print('执行时间s:', end_time-start_time)
|
|
|
+print('执行时间m:', (end_time-start_time)/60)
|
|
|
+win32api.MessageBox(0, "游戏修复完毕", "提醒", win32con.MB_OK)
|