From 4f9f7f7f21b41dbf888971e9b1fad26cb4967969 Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Tue, 30 Jul 2024 00:19:12 +0100 Subject: [PATCH 01/16] feat: separate update script --- .gitignore | 2 + modules/configs/MyConfig.py | 31 ++++++++----- update.py | 89 +++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 update.py diff --git a/.gitignore b/.gitignore index 684938c..1df4c18 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ compact_log.txt /BAAH.exe /BAAH_GUI.exe /platform-tools-latest.zip +/DATA/update/ +/BAAH*_update.zip # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/modules/configs/MyConfig.py b/modules/configs/MyConfig.py index 7fba82f..dd6e4e7 100644 --- a/modules/configs/MyConfig.py +++ b/modules/configs/MyConfig.py @@ -199,24 +199,35 @@ def save_software_config(self): with open(file_path, 'w', encoding="utf8") as f: json.dump(self.softwareconfigdict, f, indent=4, ensure_ascii=False) - def get_one_version_num(self, versionstr="nothing"): + def get_one_version_num(self, versionstr=None): """ 将版本号字符串转换成数字 + + 如 1.4.10 -> 10410 """ - if versionstr == "nothing": - versionstr = self.NOWVERSION - versionlist = versionstr.split(".") - if len(versionlist) != 3: + + try: + if versionstr is None: + versionstr = self.NOWVERSION + versionlist = versionstr.split(".") + return int(versionlist[0])*10000+int(versionlist[1])*100+int(versionlist[2]) + except Exception as e: + print(e) return -1 - return int(versionlist[0])*10000+int(versionlist[1])*100+int(versionlist[2]) - def get_version_str(self, versionnum=-1): + def get_version_str(self, versionnum=None): """ 将版本号数字转换成字符串 """ - if versionnum == -1: - versionnum = self.get_one_version_num() - return f"{int(versionnum/10000)}.{int(versionnum%10000/100)}.{versionnum%100}" + if versionnum is None: + return self.NOWVERSION + try: + assert isinstance(versionnum, int) + assert versionnum > 0 + return f"{int(versionnum/10000)}.{int(versionnum%10000/100)}.{versionnum%100}" + except Exception as e: + print(e) + return "0.0.0" diff --git a/update.py b/update.py new file mode 100644 index 0000000..15f9c75 --- /dev/null +++ b/update.py @@ -0,0 +1,89 @@ +import subprocess +import requests +import os +import zipfile +import time +from modules.configs.MyConfig import config + +def check_and_update(): + urls = { + "gitee": "https://gitee.com/api/v5/repos/sammusen/BAAH/releases/latest", + "github": "https://api.github.com/repos/sanmusen214/BAAH/releases/latest" + } + + eachtime = {} + eachnewesttag = {} + eachdownloadurl = {} + + for key in urls: + nowtime = time.time() + try: + response = requests.get(urls[key], timeout=5) + if response.status_code == 200: + eachtime[key] = time.time() - nowtime + data = response.json() + eachnewesttag[key] = data["tag_name"].replace("BAAH", "") + eachdownloadurl[key] = [each["browser_download_url"] for each in data["assets"]] + except Exception as e: + print(f"Error accessing {key}: {e}") + continue + + if not eachtime: + print("Failed to check for updates.") + return + + fastestkey = min(eachtime, key=eachtime.get) + newest_tag = eachnewesttag[fastestkey] + + current_version_num = config.get_one_version_num() + new_version_num = config.get_one_version_num(newest_tag) + + if new_version_num > current_version_num: + print(f'New version available: {newest_tag} ({fastestkey})') + + target_urls = eachdownloadurl[fastestkey] + target_url = next((url for url in target_urls if url.endswith("_update.zip")), "") + + if not target_url: + print("Failed to check for updates.") + return + + targetfilename = os.path.basename(target_url) + if not os.path.exists(targetfilename): + try: + response = requests.get(target_url, timeout=10) + if response.status_code == 200: + with open(targetfilename, "wb") as f: + f.write(response.content) + print("Downloading new version: Success") + else: + print("Downloading new version: Failed") + return + except Exception as e: + print("Downloading new version: Failed") + print(f"Error downloading file: {e}") + return + + # Check and terminate BAAH.exe and BAAH_GUI.exe processes + processes_to_terminate = ["BAAH.exe", "BAAH_GUI.exe"] + for process in processes_to_terminate: + try: + # Windows + subprocess.run(f'taskkill /f /im {process}', shell=True, check=True) + print(f"Terminated process: {process}") + except subprocess.CalledProcessError as e: + print(f"Failed to terminate process {process}: {e}") + + # Extract the downloaded ZIP file + try: + os.makedirs(os.path.join("DATA", "update"), exist_ok=True) + with zipfile.ZipFile(targetfilename, 'r') as zip_ref: + zip_ref.extractall(os.path.join("DATA", "update")) + print("Update successful, files extracted.") + # TODO: Move the extracted files to the root directory + except zipfile.BadZipFile: + print("Failed to extract the ZIP file.") + else: + print("No new version available.") + +check_and_update() \ No newline at end of file From cd74edf761181b94abcd920d769d98d1b867c4fe Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Tue, 30 Jul 2024 00:21:38 +0100 Subject: [PATCH 02/16] Fix: do not explore event story again --- modules/AllTask/InEvent/InEvent.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/AllTask/InEvent/InEvent.py b/modules/AllTask/InEvent/InEvent.py index 8871f92..859cb88 100644 --- a/modules/AllTask/InEvent/InEvent.py +++ b/modules/AllTask/InEvent/InEvent.py @@ -225,8 +225,8 @@ def on_run(self) -> None: logging.info({"zh_CN": "成功进入Event页面", "en_US": "Successfully entered the Event page"}) today = time.localtime().tm_mday - # 检测并跳过剧情 - if config.userconfigdict["AUTO_EVENT_STORY_PUSH"]: + # 检测并跳过剧情,如果已经进入过活动一次了,就不用再跳过剧情了 + if config.userconfigdict["AUTO_EVENT_STORY_PUSH"] and not config.sessiondict["HAS_ENTER_EVENT"]: EventStory().run() # 推图任务,如果已经进入过活动一次了,就不用再推图了 if config.userconfigdict["AUTO_PUSH_EVENT_QUEST"] and not config.sessiondict["HAS_ENTER_EVENT"]: From 88045778e8c659eaa1331a9f62580aeba1b88fca Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Tue, 30 Jul 2024 18:21:31 +0100 Subject: [PATCH 03/16] Fix: ocr simple quest tab --- BAAH_CONFIGS/example.json | 4 +++- DATA/i18n/en_US.json | 1 + DATA/i18n/jp_JP.json | 1 + DATA/i18n/zh_CN.json | 1 + gui/pages/Setting_hard.py | 1 + gui/pages/Setting_normal.py | 1 + modules/AllTask/InQuest/PushQuest.py | 21 +++++++++++++-------- modules/configs/defaultSettings.py | 2 ++ 8 files changed, 23 insertions(+), 9 deletions(-) diff --git a/BAAH_CONFIGS/example.json b/BAAH_CONFIGS/example.json index 559ee04..7375401 100644 --- a/BAAH_CONFIGS/example.json +++ b/BAAH_CONFIGS/example.json @@ -255,5 +255,7 @@ "POST_COMMAND": "", "SHOP_NORMAL_SWITCH": true, "SHOP_CONTEST_SWITCH": true, - "USER_DEF_TASKS": "" + "USER_DEF_TASKS": "", + "PUSH_NORMAL_USE_SIMPLE": false, + "PUSH_HARD_USE_SIMPLE": false } \ No newline at end of file diff --git a/DATA/i18n/en_US.json b/DATA/i18n/en_US.json index 94fa8d4..3636201 100644 --- a/DATA/i18n/en_US.json +++ b/DATA/i18n/en_US.json @@ -132,6 +132,7 @@ "config_buy_ap_add_times":"Number of times to buy AP", "config_pre_command":"Command before task start, leave blank to ignore", "config_post_command":"Command after task end, leave blank to ignore", + "config_use_simple_explore":"Use simple explore", "config_server_jp": "Japanese Server", "config_server_cn": "Chinese Official Server", diff --git a/DATA/i18n/jp_JP.json b/DATA/i18n/jp_JP.json index 0d1cad1..b0ade44 100644 --- a/DATA/i18n/jp_JP.json +++ b/DATA/i18n/jp_JP.json @@ -132,6 +132,7 @@ "config_buy_ap_add_times":"APを購入する回数", "config_pre_command":"タスク開始前に実行するコマンド", "config_post_command":"タスク終了後に実行するコマンド", + "config_use_simple_explore":"簡易攻略を使用する", "config_server_jp": "日本サーバー", "config_server_cn": "中国公式サーバー", diff --git a/DATA/i18n/zh_CN.json b/DATA/i18n/zh_CN.json index 3dd7002..bf2459a 100644 --- a/DATA/i18n/zh_CN.json +++ b/DATA/i18n/zh_CN.json @@ -132,6 +132,7 @@ "config_buy_ap_add_times":"购买体力组数", "config_pre_command":"任务开始前执行命令, 留空忽略", "config_post_command":"任务结束后执行命令, 留空忽略", + "config_use_simple_explore":"使用简易攻略", "config_server_jp":"日服", diff --git a/gui/pages/Setting_hard.py b/gui/pages/Setting_hard.py index fed2c1c..f342c92 100644 --- a/gui/pages/Setting_hard.py +++ b/gui/pages/Setting_hard.py @@ -29,6 +29,7 @@ def set_hard(config): ui.label(config.get_text("config_explore_attention")) with ui.card(): + ui.checkbox(config.get_text("config_use_simple_explore")).bind_value(config.userconfigdict, "PUSH_HARD_USE_SIMPLE") ui.checkbox(config.get_text("config_rainbow_teams_desc")).bind_value(config.userconfigdict, "EXPLORE_RAINBOW_TEAMS") ui.number(config.get_text("config_push_hard_desc"), min=1, precision=0, step=1).bind_value(config.userconfigdict, "PUSH_HARD_QUEST", forward=lambda x: int(x)).style("width: 300px") ui.number(config.get_text("config_level"), min=1, precision=0, step=1).bind_value(config.userconfigdict, "PUSH_HARD_QUEST_LEVEL", forward=lambda x:int(x)).style("width: 300px") diff --git a/gui/pages/Setting_normal.py b/gui/pages/Setting_normal.py index c3495b3..0dadc41 100644 --- a/gui/pages/Setting_normal.py +++ b/gui/pages/Setting_normal.py @@ -29,6 +29,7 @@ def set_normal(config): ui.label(config.get_text("config_explore_attention")) with ui.card(): + ui.checkbox(config.get_text("config_use_simple_explore")).bind_value(config.userconfigdict, "PUSH_NORMAL_USE_SIMPLE") ui.checkbox(config.get_text("config_rainbow_teams_desc")).bind_value(config.userconfigdict, "EXPLORE_RAINBOW_TEAMS") ui.number(config.get_text("config_push_normal_desc"), min=4, precision=0, step=1).bind_value(config.userconfigdict, "PUSH_NORMAL_QUEST", forward=lambda x: int(x)).style("width: 300px") ui.number(config.get_text("config_level"), min=1, precision=0, step=1).bind_value(config.userconfigdict, "PUSH_NORMAL_QUEST_LEVEL", forward=lambda x:int(x)).style("width: 300px") diff --git a/modules/AllTask/InQuest/PushQuest.py b/modules/AllTask/InQuest/PushQuest.py index a5a39f9..596d68a 100644 --- a/modules/AllTask/InQuest/PushQuest.py +++ b/modules/AllTask/InQuest/PushQuest.py @@ -81,7 +81,6 @@ def on_run(self) -> None: # 此时应该看到扫荡弹窗 # 判断是否有简易攻略tab - has_easy_tab = quest_has_easy_tab() # 向右翻self.level_ind次 logging.info({"zh_CN": "尝试翻到关卡 {}".format(self.level_ind + 1), "en_US": "Try flipping to level {}".format(self.level_ind + 1)}) @@ -92,6 +91,8 @@ def on_run(self) -> None: if match_pixel(Page.MAGICPOINT, Page.COLOR_WHITE): logging.info({"zh_CN": "关卡弹窗消失,结束此任务","en_US": "Level popup disappears, end this task"}) return + # 此时判断是否有简易攻略tab + has_easy_tab = quest_has_easy_tab() # 当前关卡就是这次需要推图的关卡 # 国服弹窗往右偏移了50 offsetx = 0 @@ -144,21 +145,25 @@ def on_run(self) -> None: # ===========正式开始推图=================== # 看到弹窗,ocr是否有S ocr_s = ocr_area((327 + offsetx, 257 + offsety), (370 + offsetx, 288 + offsety)) - # 如果有简易攻略 + # 如果有简易攻略tab,有简易攻略tab存在,这个图肯定默认是格子图 if has_easy_tab: - if self.is_normal: - logging.info({"zh_CN": "使用简易攻略", "en_US": "Easy to use guide"}) + if (self.is_normal and config.userconfigdict["PUSH_NORMAL_USE_SIMPLE"]) or (not self.is_normal and config.userconfigdict["PUSH_HARD_USE_SIMPLE"]): + logging.info({"zh_CN": "使用简易攻略", "en_US": "Use simple explore"}) click(easy_tab_pos_R) click(easy_tab_pos_R) - ocr_s = "easy" + # 简易攻略的话,把ocr_s设为_,让后面不要走格子(no "S") + ocr_s = ["_", 1.0] else: - logging.info({"zh_CN": "困难图,走格子拿钻石", - "en_US": "Difficulty diagram, walk the grid to get the diamond"}) + logging.info({"zh_CN": "不使用简易攻略", + "en_US": "Do not use simple explore"}) click(center_tab_pos_L) click(center_tab_pos_L) + # 切换到集中指挥tab后,才会出现s标签,没有必要再次识别 + ocr_s = ["S", 1.0] + walk_grid = None - logging.info(ocr_s[0].upper()) + logging.info("OCR: "+ocr_s[0].upper()) if "S" not in ocr_s[0].upper(): logging.info({"zh_CN": "未识别到S等级,判断为普通战斗", "en_US": "S grade not recognized, judged as normal battle"}) diff --git a/modules/configs/defaultSettings.py b/modules/configs/defaultSettings.py index b02351f..a899be0 100644 --- a/modules/configs/defaultSettings.py +++ b/modules/configs/defaultSettings.py @@ -24,8 +24,10 @@ "TASK_ORDER": {"d":["登录游戏"]}, "SHOP_NORMAL": {"d":[]}, "SHOP_CONTEST": {"d":[]}, + "PUSH_NORMAL_USE_SIMPLE": {"d":False}, "PUSH_NORMAL_QUEST": {"d":0}, "PUSH_NORMAL_QUEST_LEVEL": {"d":1}, + "PUSH_HARD_USE_SIMPLE": {"d":False}, "PUSH_HARD_QUEST": {"d":0}, "PUSH_HARD_QUEST_LEVEL": {"d":1}, "TASK_ACTIVATE": {"d":[True]}, From 78897d372d7dc7c9b6ecb50a9c7bffe880284106 Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Thu, 1 Aug 2024 00:23:34 +0100 Subject: [PATCH 04/16] Feat: updator --- .gitignore | 1 + modules/configs/MyConfig.py | 4 +- modules/configs/defaultSettings.py | 1 + package.py | 9 ++ update.py | 213 ++++++++++++++++++++++------- 5 files changed, 179 insertions(+), 49 deletions(-) diff --git a/.gitignore b/.gitignore index 1df4c18..09bf1b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ tools/ test.spec jsoneditor.spec +update.spec BAAH.spec compact_log.txt /*.png diff --git a/modules/configs/MyConfig.py b/modules/configs/MyConfig.py index dd6e4e7..6f0b483 100644 --- a/modules/configs/MyConfig.py +++ b/modules/configs/MyConfig.py @@ -66,6 +66,8 @@ def parse_software_config(self, file_name): # 检查缺失的配置 self._check_software_config() # 强制设定VERSION + # 保存读取的json里的旧版本号 + self.sessiondict["READ_SOFTWARE_VERSION"] = self.softwareconfigdict["NOWVERSION"] self.softwareconfigdict["NOWVERSION"] = self.NOWVERSION # 输出 # print("software config字典内容: "+ ",".join([k for k in self.softwareconfigdict])) @@ -207,7 +209,7 @@ def get_one_version_num(self, versionstr=None): """ try: - if versionstr is None: + if not versionstr: versionstr = self.NOWVERSION versionlist = versionstr.split(".") return int(versionlist[0])*10000+int(versionlist[1])*100+int(versionlist[2]) diff --git a/modules/configs/defaultSettings.py b/modules/configs/defaultSettings.py index a899be0..ac8204f 100644 --- a/modules/configs/defaultSettings.py +++ b/modules/configs/defaultSettings.py @@ -193,4 +193,5 @@ "INFO_LIST":{"d":[]}, # 截图文件读取失败的次数 "SCREENSHOT_READ_FAIL_TIMES":{"d":0}, + "READ_SOFTWARE_VERSION":{"d":""}, } \ No newline at end of file diff --git a/package.py b/package.py index 508a589..331906d 100644 --- a/package.py +++ b/package.py @@ -112,6 +112,14 @@ def package_remove_folder(path): ] subprocess.call(guicmd) +# 打包update.py,名字为BAAH_UPDATE +updatecmd = [ + 'pyinstaller', + 'update.py', + '--n', 'BAAH_UPDATE', + '-y' +] +subprocess.call(updatecmd) # 当前目录 print("当前目录:", os.getcwd()) @@ -152,6 +160,7 @@ def package_remove_folder(path): package_copyfolder("./DATA/assets_global_en", "./dist/BAAH/DATA/assets_global_en") package_copyfolder("./DATA/grid_solution", "./dist/BAAH/DATA/grid_solution") package_copyfile("./dist/jsoneditor/jsoneditor.exe", "./dist/BAAH/jsoneditor.exe") +package_copyfile("./dist/BAAH_UPDATE/BAAH_UPDATE.exe", "./dist/BAAH/BAAH_UPDATE.exe") time.sleep(2) diff --git a/update.py b/update.py index 15f9c75..c7a5c16 100644 --- a/update.py +++ b/update.py @@ -1,19 +1,51 @@ +import hashlib +import shutil import subprocess +import traceback import requests import os import zipfile import time from modules.configs.MyConfig import config +#TODO: 这里有个问题是MyConfig版本号变化会导致update哈希值变化,从而导致文件覆写错误,需要解耦 +print("This Updator Version: 0.1.0") -def check_and_update(): +class VersionInfo: + def __init__(self): + self.has_new_version = False + self.msg = "No new version" + self.version_str = "" + self.update_zip_url = "" + + +def file_checksum(file_path): + """计算文件的 SHA256 哈希值""" + sha256 = hashlib.sha256() + with open(file_path, 'rb') as f: + for block in iter(lambda: f.read(4096), b''): + sha256.update(block) + return sha256.hexdigest() + +def zip_file_checksum(zip_file, file_in_zip): + """计算压缩包内文件的 SHA256 哈希值""" + sha256 = hashlib.sha256() + with zip_file.open(file_in_zip) as f: + for block in iter(lambda: f.read(4096), b''): + sha256.update(block) + return sha256.hexdigest() + +def whether_has_new_version(): + """ + 检查是否有新版本 + """ urls = { "gitee": "https://gitee.com/api/v5/repos/sammusen/BAAH/releases/latest", "github": "https://api.github.com/repos/sanmusen214/BAAH/releases/latest" } eachtime = {} - eachnewesttag = {} - eachdownloadurl = {} + eachnewesttag = {} # 存放各个平台上最新的版本号 如 1.5.3 + eachdownloadurl = {} # 存放各个平台上最新的下载链接 for key in urls: nowtime = time.time() @@ -29,61 +61,146 @@ def check_and_update(): continue if not eachtime: - print("Failed to check for updates.") - return + print("Failed to check time spent for accessing github nor gitee.") + vi = VersionInfo() + vi.msg = "Failed to check time spent for accessing github nor gitee." + return vi fastestkey = min(eachtime, key=eachtime.get) newest_tag = eachnewesttag[fastestkey] - current_version_num = config.get_one_version_num() + # 这里读取sessiondict,也就是software_config.json实际存储的字符串 + # softwaredict里的NOWVERSION会被当前update.py文件的版本号覆盖,不能用 + current_version_num = config.get_one_version_num(config.sessiondict["READ_SOFTWARE_VERSION"]) new_version_num = config.get_one_version_num(newest_tag) if new_version_num > current_version_num: - print(f'New version available: {newest_tag} ({fastestkey})') - - target_urls = eachdownloadurl[fastestkey] - target_url = next((url for url in target_urls if url.endswith("_update.zip")), "") + vi = VersionInfo() + vi.has_new_version = True + vi.msg = f"New version available: {newest_tag} ({fastestkey})" + vi.version_str = newest_tag + vi.update_zip_url = next((url for url in eachdownloadurl[fastestkey] if url.endswith("_update.zip")), "") + # 如果没有以update末尾的文件,说明没有更新文件 + if vi.update_zip_url == "": + vi.msg += "\nFailed to get the download URL." + vi.has_new_version = False + return vi + else: + vi = VersionInfo() + vi.msg = "No new version" + return vi - if not target_url: - print("Failed to check for updates.") +def check_and_update(): + # 判断路径下是否有BAAH.exe,如果没有说明运行目录不对 + if not os.path.exists("BAAH.exe"): + print("Please run this script in the same directory as BAAH.exe.") + return + + version_info = whether_has_new_version() + # 如果没有新版本,直接返回 + if not version_info.has_new_version: + print("No new version available.") + print(version_info.msg) + return + # 根据update.zip结尾的url下载文件 + target_url = version_info.update_zip_url + targetfilename = os.path.basename(target_url) + # 不存在zip文件则下载 + if not os.path.exists(targetfilename): + try: + response = requests.get(target_url, timeout=10) + if response.status_code == 200: + with open(targetfilename, "wb") as f: + f.write(response.content) + print("Downloading update zip: Success") + else: + print("Downloading update zip: Failed") + return + except Exception as e: + print("Downloading new version: Failed") + print(f"Error downloading file: {e}") return - - targetfilename = os.path.basename(target_url) - if not os.path.exists(targetfilename): - try: - response = requests.get(target_url, timeout=10) - if response.status_code == 200: - with open(targetfilename, "wb") as f: - f.write(response.content) - print("Downloading new version: Success") + else: + print(f"Update ZIP file: {targetfilename} already exists.") + + # Check and terminate BAAH.exe and BAAH_GUI.exe processes + # 中断已有的BAAH进程 + processes_to_terminate = ["BAAH.exe", "BAAH_GUI.exe"] + for process in processes_to_terminate: + try: + #! only for Windows now + # Windows,未来多平台可以考虑使用psutil库 + subprocess.run(f'taskkill /f /im {process}', shell=True, check=True) + print(f"Terminated process: {process}") + except subprocess.CalledProcessError as e: + print(f"Failed to terminate process {process}: {e}") + + # Extract the downloaded ZIP file + # 解压下载下来的zip文件 + try: + # zip第一层是一个BAAH1.5.4这样的大文件夹,跳过 + total_sub_files_extracted = 0 + with zipfile.ZipFile(targetfilename, 'r') as zip_ref: + all_files = zip_ref.namelist() + # 把BAAH_UPDATE.exe放到最后 + file_updateexe_name = next((file for file in all_files if file.endswith("BAAH_UPDATE.exe")), None) + if file_updateexe_name: + all_files.remove(file_updateexe_name) + all_files.append(file_updateexe_name) + for file in all_files: + if file.endswith("/"): + # 文件夹不作为文件处理 + continue + if file.startswith(f"BAAH{version_info.version_str}/"): + # 去除第一层文件夹 + relative_path = os.path.relpath(file, f"BAAH{version_info.version_str}/") + # 如果有深层文件夹,创建深层文件夹 + os.makedirs(os.path.dirname(relative_path), exist_ok=True) if os.path.dirname(relative_path) else None + # 判断文件是否存在 + if os.path.exists(relative_path): + # 如果存在,检查hash是否一致 + src_hash = zip_file_checksum(zip_ref, file) + dst_hash = file_checksum(relative_path) + # print(f"src_hash: {src_hash}, dst_hash: {dst_hash}") + if src_hash == dst_hash: + continue + else: + print(f"detected file change: {relative_path}") + else: + print(f"file not exists: {relative_path}, write it.") + print(f" Extracting {file} to {relative_path}") + # 解压文件到relative_path,覆盖 + with zip_ref.open(file) as zf, open(relative_path, "wb") as f: + shutil.copyfileobj(zf, f) + total_sub_files_extracted += 1 else: - print("Downloading new version: Failed") - return - except Exception as e: - print("Downloading new version: Failed") - print(f"Error downloading file: {e}") - return + print(f"Skipped {file}, this is not start with BAAH{version_info.version_str}/ in zip") + print(f"\nUpdate successful, {total_sub_files_extracted} files extracted.\n") + except zipfile.BadZipFile: + print("Failed to extract the ZIP file. Bad ZIP file.") - # Check and terminate BAAH.exe and BAAH_GUI.exe processes - processes_to_terminate = ["BAAH.exe", "BAAH_GUI.exe"] - for process in processes_to_terminate: - try: - # Windows - subprocess.run(f'taskkill /f /im {process}', shell=True, check=True) - print(f"Terminated process: {process}") - except subprocess.CalledProcessError as e: - print(f"Failed to terminate process {process}: {e}") + # 删除下载的zip文件 + os.remove(targetfilename) + print(f"Deleted the downloaded ZIP file: {targetfilename}.") + + # 重新启动BAAH_GUI.exe + # 注意这里CREATE_NEW_CONSOLE即使把本文件关了,也不会影响BAAH_GUI.exe的运行 + + try: + # Windows only + subprocess.Popen(["BAAH_GUI.exe"], creationflags=subprocess.CREATE_NEW_CONSOLE, close_fds=True) + print("BAAH_GUI.exe started.") + except Exception as e: + print(f"Failed to start BAAH_GUI.exe: {e}") - # Extract the downloaded ZIP file - try: - os.makedirs(os.path.join("DATA", "update"), exist_ok=True) - with zipfile.ZipFile(targetfilename, 'r') as zip_ref: - zip_ref.extractall(os.path.join("DATA", "update")) - print("Update successful, files extracted.") - # TODO: Move the extracted files to the root directory - except zipfile.BadZipFile: - print("Failed to extract the ZIP file.") - else: - print("No new version available.") -check_and_update() \ No newline at end of file +if __name__ == "__main__": + try: + check_and_update() + print("========== [SUCCESS] =========") + except Exception as e: + traceback.print_exc() + print("========== ERROR! =========") + if "BAAH_UPDATE.exe" in str(e): + print(">>> You can not use this script to replace itself. Please unzip the zip manually. <<<") + input("Press Enter to exit.") \ No newline at end of file From 3db4cdaf1c2a1180b8e612a1229c83b42f2bcbda Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Thu, 1 Aug 2024 11:00:38 +0100 Subject: [PATCH 05/16] Fix: encoupled update and Config --- .gitignore | 2 +- modules/configs/MyConfig.py | 2 - modules/configs/defaultSettings.py | 3 +- update.py | 69 ++++++++++++++++++++---------- 4 files changed, 48 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index 09bf1b9..ebf719b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ tools/ test.spec jsoneditor.spec -update.spec +BAAH_UPDATE.spec BAAH.spec compact_log.txt /*.png diff --git a/modules/configs/MyConfig.py b/modules/configs/MyConfig.py index 6f0b483..c4c68c8 100644 --- a/modules/configs/MyConfig.py +++ b/modules/configs/MyConfig.py @@ -66,8 +66,6 @@ def parse_software_config(self, file_name): # 检查缺失的配置 self._check_software_config() # 强制设定VERSION - # 保存读取的json里的旧版本号 - self.sessiondict["READ_SOFTWARE_VERSION"] = self.softwareconfigdict["NOWVERSION"] self.softwareconfigdict["NOWVERSION"] = self.NOWVERSION # 输出 # print("software config字典内容: "+ ",".join([k for k in self.softwareconfigdict])) diff --git a/modules/configs/defaultSettings.py b/modules/configs/defaultSettings.py index ac8204f..3b0f249 100644 --- a/modules/configs/defaultSettings.py +++ b/modules/configs/defaultSettings.py @@ -192,6 +192,5 @@ "INFO_DICT":{"d":{}}, "INFO_LIST":{"d":[]}, # 截图文件读取失败的次数 - "SCREENSHOT_READ_FAIL_TIMES":{"d":0}, - "READ_SOFTWARE_VERSION":{"d":""}, + "SCREENSHOT_READ_FAIL_TIMES":{"d":0} } \ No newline at end of file diff --git a/update.py b/update.py index c7a5c16..409820a 100644 --- a/update.py +++ b/update.py @@ -1,4 +1,5 @@ import hashlib +import json import shutil import subprocess import traceback @@ -6,10 +7,25 @@ import os import zipfile import time -from modules.configs.MyConfig import config -#TODO: 这里有个问题是MyConfig版本号变化会导致update哈希值变化,从而导致文件覆写错误,需要解耦 + print("This Updator Version: 0.1.0") +def get_one_version_num(versionstr=None): + """ + 将版本号字符串转换成数字 + + 如 1.4.10 -> 10410 + """ + + try: + if not versionstr: + versionstr = self.NOWVERSION + versionlist = versionstr.split(".") + return int(versionlist[0])*10000+int(versionlist[1])*100+int(versionlist[2]) + except Exception as e: + print(e) + return -1 + class VersionInfo: def __init__(self): self.has_new_version = False @@ -69,10 +85,12 @@ def whether_has_new_version(): fastestkey = min(eachtime, key=eachtime.get) newest_tag = eachnewesttag[fastestkey] - # 这里读取sessiondict,也就是software_config.json实际存储的字符串 - # softwaredict里的NOWVERSION会被当前update.py文件的版本号覆盖,不能用 - current_version_num = config.get_one_version_num(config.sessiondict["READ_SOFTWARE_VERSION"]) - new_version_num = config.get_one_version_num(newest_tag) + # 这里读取software_config.json实际存储的字符串 + # DATA/CONFIGS/software_config.json里的NOWVERSION字段 + with open(os.path.join("DATA", "CONFIGS", "software_config.json"), "r") as f: + confile = json.load(f) + current_version_num = get_one_version_num(confile["NOWVERSION"]) + new_version_num = get_one_version_num(newest_tag) if new_version_num > current_version_num: vi = VersionInfo() @@ -119,7 +137,7 @@ def check_and_update(): except Exception as e: print("Downloading new version: Failed") print(f"Error downloading file: {e}") - return + raise Exception("Failed to download the ZIP file.") else: print(f"Update ZIP file: {targetfilename} already exists.") @@ -133,8 +151,11 @@ def check_and_update(): subprocess.run(f'taskkill /f /im {process}', shell=True, check=True) print(f"Terminated process: {process}") except subprocess.CalledProcessError as e: + # but thats fine, maybe it is not running print(f"Failed to terminate process {process}: {e}") - + # 之后重新启动GUI + global open_GUI_again + open_GUI_again = True # Extract the downloaded ZIP file # 解压下载下来的zip文件 try: @@ -177,30 +198,32 @@ def check_and_update(): print(f"Skipped {file}, this is not start with BAAH{version_info.version_str}/ in zip") print(f"\nUpdate successful, {total_sub_files_extracted} files extracted.\n") except zipfile.BadZipFile: - print("Failed to extract the ZIP file. Bad ZIP file.") + raise Exception("Failed to extract the ZIP file. Bad ZIP file.") + # 删除下载的zip文件 os.remove(targetfilename) print(f"Deleted the downloaded ZIP file: {targetfilename}.") - - # 重新启动BAAH_GUI.exe - # 注意这里CREATE_NEW_CONSOLE即使把本文件关了,也不会影响BAAH_GUI.exe的运行 - - try: - # Windows only - subprocess.Popen(["BAAH_GUI.exe"], creationflags=subprocess.CREATE_NEW_CONSOLE, close_fds=True) - print("BAAH_GUI.exe started.") - except Exception as e: - print(f"Failed to start BAAH_GUI.exe: {e}") - +open_GUI_again = False if __name__ == "__main__": try: check_and_update() - print("========== [SUCCESS] =========") + print("========== [UPDATE SUCCESS] =========") except Exception as e: traceback.print_exc() print("========== ERROR! =========") - if "BAAH_UPDATE.exe" in str(e): + if "BAAH_UPDATE.exe" in str(e) and "Permission denied" in str(e): print(">>> You can not use this script to replace itself. Please unzip the zip manually. <<<") - input("Press Enter to exit.") \ No newline at end of file + + # 重新启动BAAH_GUI.exe + # 注意这里CREATE_NEW_CONSOLE即使把本文件关了,也不会影响BAAH_GUI.exe的运行 + if open_GUI_again: + try: + # Windows only + subprocess.Popen(["BAAH_GUI.exe"], creationflags=subprocess.CREATE_NEW_CONSOLE, close_fds=True) + print("BAAH_GUI.exe started.") + except Exception as e: + print(f"Failed to start BAAH_GUI.exe: {e}") + + input("Press Enter to exit the updater.") \ No newline at end of file From be9c0952f21b1bc3eaa29448a6b677dbddca4b67 Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Thu, 1 Aug 2024 11:24:50 +0100 Subject: [PATCH 06/16] Add icon for updater --- DATA/assets/kayoko.ico | Bin 0 -> 27354 bytes package.py | 1 + 2 files changed, 1 insertion(+) create mode 100644 DATA/assets/kayoko.ico diff --git a/DATA/assets/kayoko.ico b/DATA/assets/kayoko.ico new file mode 100644 index 0000000000000000000000000000000000000000..80845bca1f72d6fba999406d3668601d3b634996 GIT binary patch literal 27354 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 literal 0 HcmV?d00001 diff --git a/package.py b/package.py index 331906d..fe59eca 100644 --- a/package.py +++ b/package.py @@ -117,6 +117,7 @@ def package_remove_folder(path): 'pyinstaller', 'update.py', '--n', 'BAAH_UPDATE', + '--icon', './DATA/assets/kayoko.ico', '-y' ] subprocess.call(updatecmd) From 89b4a12d65c30d362509bf21e81ccce45484571e Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Thu, 1 Aug 2024 11:33:43 +0100 Subject: [PATCH 07/16] Feat: advanced update in GUI --- DATA/i18n/en_US.json | 1 + DATA/i18n/jp_JP.json | 1 + DATA/i18n/zh_CN.json | 1 + gui/pages/Setting_BAAH.py | 13 ++++++++++++- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/DATA/i18n/en_US.json b/DATA/i18n/en_US.json index 3636201..6612ec6 100644 --- a/DATA/i18n/en_US.json +++ b/DATA/i18n/en_US.json @@ -47,6 +47,7 @@ "button_save_and_run_gui":"Save and execute (GUI, experimental)", "button_save_and_run_terminal":"Save and execute (Terminal)", "button_check_version": "Check for Updates and Download(Make sure BAAH is not running)", + "button_update_advance":"One Click to update to the latest version (experimental)", "button_select_all": "Select All", "button_select_none": "Deselect All", "button_enable": "Enable", diff --git a/DATA/i18n/jp_JP.json b/DATA/i18n/jp_JP.json index b0ade44..a1dc79b 100644 --- a/DATA/i18n/jp_JP.json +++ b/DATA/i18n/jp_JP.json @@ -47,6 +47,7 @@ "button_save_and_run_gui": "保存して実行(GUI、実験的)", "button_save_and_run_terminal": "保存して実行(ターミナル)", "button_check_version": "更新を確認してダウンロードする(BAAHが実行されていないことを確認してください)", + "button_update_advance":"最新バージョンに一括更新(実験的)", "button_select_all": "すべて選択", "button_select_none": "選択解除", "button_enable": "有効にする", diff --git a/DATA/i18n/zh_CN.json b/DATA/i18n/zh_CN.json index bf2459a..36f7ccc 100644 --- a/DATA/i18n/zh_CN.json +++ b/DATA/i18n/zh_CN.json @@ -47,6 +47,7 @@ "button_save_and_run_gui":"保存并执行(GUI,实验性功能)", "button_save_and_run_terminal":"保存并执行(终端)", "button_check_version":"检查更新并下载(确保BAAH不在运行),下载完成后请关闭BAAH手动解压更新补丁", + "button_update_advance":"一键更新到最新版本(实验性功能)", "button_select_all":"全选", "button_select_none":"全不选", "button_enable":"启用", diff --git a/gui/pages/Setting_BAAH.py b/gui/pages/Setting_BAAH.py index e198510..a9d0050 100644 --- a/gui/pages/Setting_BAAH.py +++ b/gui/pages/Setting_BAAH.py @@ -1,4 +1,5 @@ -from nicegui import ui +import subprocess +from nicegui import ui, app from gui.components.check_update import get_newest_version def set_BAAH(config, shared_softwareconfig): @@ -22,8 +23,18 @@ def select_language(value): ui.label(config.get_text("BAAH_get_version")) + # 下载更新包 ui.button(config.get_text("button_check_version"), on_click=lambda e, c=config:get_newest_version(c)) + # 一键更新,唤起更新程序,结束gui进程 + def update_advance(): + try: + subprocess.Popen(["BAAH_UPDATE.exe"], creationflags=subprocess.CREATE_NEW_CONSOLE, close_fds=True) + app.shutdown() + except Exception as e: + ui.notify(f"Failed to start BAAH_UPDATE.exe: {e}", type="warning") + ui.button(config.get_text("button_update_advance"), on_click=update_advance) + web_url = { "github": "https://github.com/sanmusen214/BAAH", "bilibili":"https://space.bilibili.com/7331920" From a9d651b61ef592f4b4c22eb4e0c5b4b3de73ca92 Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Thu, 1 Aug 2024 11:38:21 +0100 Subject: [PATCH 08/16] Fix: name param when pyinstaller --- package.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.py b/package.py index fe59eca..49b7ed0 100644 --- a/package.py +++ b/package.py @@ -116,7 +116,7 @@ def package_remove_folder(path): updatecmd = [ 'pyinstaller', 'update.py', - '--n', 'BAAH_UPDATE', + '-n', 'BAAH_UPDATE', '--icon', './DATA/assets/kayoko.ico', '-y' ] From beb5ba72b1977e239ad58a3ae6989b7201dffa88 Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Thu, 1 Aug 2024 11:53:07 +0100 Subject: [PATCH 09/16] Update: add more print out --- update.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/update.py b/update.py index 409820a..669ed4e 100644 --- a/update.py +++ b/update.py @@ -8,6 +8,7 @@ import zipfile import time +# 本文件内容不要频繁变更 print("This Updator Version: 0.1.0") def get_one_version_num(versionstr=None): @@ -62,10 +63,11 @@ def whether_has_new_version(): eachtime = {} eachnewesttag = {} # 存放各个平台上最新的版本号 如 1.5.3 eachdownloadurl = {} # 存放各个平台上最新的下载链接 - + print("Checking for new version...") for key in urls: nowtime = time.time() try: + print(f"Checking: {key}...") response = requests.get(urls[key], timeout=5) if response.status_code == 200: eachtime[key] = time.time() - nowtime @@ -81,7 +83,8 @@ def whether_has_new_version(): vi = VersionInfo() vi.msg = "Failed to check time spent for accessing github nor gitee." return vi - + print(eachtime) + print(eachnewesttag) fastestkey = min(eachtime, key=eachtime.get) newest_tag = eachnewesttag[fastestkey] @@ -214,7 +217,7 @@ def check_and_update(): traceback.print_exc() print("========== ERROR! =========") if "BAAH_UPDATE.exe" in str(e) and "Permission denied" in str(e): - print(">>> You can not use this script to replace itself. Please unzip the zip manually. <<<") + print(">>> You can not use this script to replace itself. Please unpack the zip manually. <<<") # 重新启动BAAH_GUI.exe # 注意这里CREATE_NEW_CONSOLE即使把本文件关了,也不会影响BAAH_GUI.exe的运行 From 2eb9839c7ccf7ff95e8fca843488c5f6dac488ee Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Thu, 1 Aug 2024 11:54:44 +0100 Subject: [PATCH 10/16] version 1.6.0 --- modules/configs/MyConfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/configs/MyConfig.py b/modules/configs/MyConfig.py index c4c68c8..c4704e7 100644 --- a/modules/configs/MyConfig.py +++ b/modules/configs/MyConfig.py @@ -10,7 +10,7 @@ class MyConfigger: """ 维护config字典,包含软件config,用户任务config,语言包 """ - NOWVERSION="1.5.5" + NOWVERSION="1.6.0" USER_CONFIG_FOLDER="./BAAH_CONFIGS" SOFTWARE_CONFIG_FOLDER="./DATA/CONFIGS" LANGUAGE_PACKAGE_FOLDER="./DATA/i18n" From 89576a88662e53a4df95723f822fa9abd6837ffc Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Thu, 1 Aug 2024 18:57:29 +0100 Subject: [PATCH 11/16] Feat: craft GUI --- BAAH_CONFIGS/example.json | 3 ++- DATA/i18n/en_US.json | 3 +++ DATA/i18n/jp_JP.json | 3 +++ DATA/i18n/zh_CN.json | 3 +++ gui/__init__.py | 6 ++++++ gui/pages/Setting_Craft.py | 17 +++++++++++++++++ modules/AllTask/InCraft/InCraft.py | 16 ++++++++++++++++ modules/configs/defaultSettings.py | 2 ++ 8 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 gui/pages/Setting_Craft.py diff --git a/BAAH_CONFIGS/example.json b/BAAH_CONFIGS/example.json index 7375401..24d7c6d 100644 --- a/BAAH_CONFIGS/example.json +++ b/BAAH_CONFIGS/example.json @@ -257,5 +257,6 @@ "SHOP_CONTEST_SWITCH": true, "USER_DEF_TASKS": "", "PUSH_NORMAL_USE_SIMPLE": false, - "PUSH_HARD_USE_SIMPLE": false + "PUSH_HARD_USE_SIMPLE": false, + "CRAFT_TIMES": 1 } \ No newline at end of file diff --git a/DATA/i18n/en_US.json b/DATA/i18n/en_US.json index 6612ec6..c883898 100644 --- a/DATA/i18n/en_US.json +++ b/DATA/i18n/en_US.json @@ -21,6 +21,7 @@ "push_main_story":"Explore Eposide", "task_assault": "Assault", "task_user_def_task": "User Defined Task", + "task_craft":"Craft", "setting_emulator": "Emulator Configuration", "setting_server": "Server Configuration", @@ -134,6 +135,8 @@ "config_pre_command":"Command before task start, leave blank to ignore", "config_post_command":"Command after task end, leave blank to ignore", "config_use_simple_explore":"Use simple explore", + "config_craft_desc":"Currently, the craft task only supports one node and does not support the priority of specified items. After the Chinese server implements one-click manufacturing, it will be supported through one-click manufacturing", + "config_craft_max_times":"Maximum times of craft", "config_server_jp": "Japanese Server", "config_server_cn": "Chinese Official Server", diff --git a/DATA/i18n/jp_JP.json b/DATA/i18n/jp_JP.json index a1dc79b..e2138d1 100644 --- a/DATA/i18n/jp_JP.json +++ b/DATA/i18n/jp_JP.json @@ -21,6 +21,7 @@ "push_main_story": "メインストーリーの進行", "task_assault": "総力戦", "task_user_def_task": "ユーザー定義タスク", + "task_craft":"クラフト", "setting_emulator": "エミュレータ設定", "setting_server": "サーバー設定", @@ -134,6 +135,8 @@ "config_pre_command":"タスク開始前に実行するコマンド", "config_post_command":"タスク終了後に実行するコマンド", "config_use_simple_explore":"簡易攻略を使用する", + "config_craft_desc":"現在、クラフトタスクは1つのノードのみをサポートし、指定されたアイテムの優先順位をサポートしていません。国内サーバーがワンクリック製造を実装した後、ワンクリック製造を使用してサポートする予定です", + "config_craft_max_times":"最大製造回数", "config_server_jp": "日本サーバー", "config_server_cn": "中国公式サーバー", diff --git a/DATA/i18n/zh_CN.json b/DATA/i18n/zh_CN.json index 36f7ccc..854dba6 100644 --- a/DATA/i18n/zh_CN.json +++ b/DATA/i18n/zh_CN.json @@ -21,6 +21,7 @@ "push_main_story":"推主线剧情", "task_assault":"总力战", "task_user_def_task": "自定义任务", + "task_craft":"制造", "setting_emulator":"模拟器配置", "setting_server":"服务器配置", @@ -134,6 +135,8 @@ "config_pre_command":"任务开始前执行命令, 留空忽略", "config_post_command":"任务结束后执行命令, 留空忽略", "config_use_simple_explore":"使用简易攻略", + "config_craft_desc":"制造任务目前只能一个节点,且不支持指定物品的优先级,等国服实装一键制造后会通过一键制造来支持", + "config_craft_max_times":"尝试制造次数", "config_server_jp":"日服", diff --git a/gui/__init__.py b/gui/__init__.py index 34f7d35..634b2da 100644 --- a/gui/__init__.py +++ b/gui/__init__.py @@ -5,6 +5,7 @@ import os from gui.components.run_baah_in_gui import run_baah_task from gui.pages.Setting_BAAH import set_BAAH +from gui.pages.Setting_Craft import set_craft from gui.pages.Setting_cafe import set_cafe from gui.pages.Setting_emulator import set_emulator from gui.pages.Setting_event import set_event @@ -43,6 +44,7 @@ def show_GUI(load_jsonname, config, shared_softwareconfig): "咖啡馆只摸头":config.get_text("task_cafe_deprecated"), # 为了兼容以前的配置里的咖啡馆只摸头,这里只改显示名 "课程表":config.get_text("task_timetable"), "社团":config.get_text("task_club"), + "制造":config.get_text("task_craft"), "商店":config.get_text("task_shop"), "购买AP":config.get_text("task_buy_ap"), "悬赏通缉":config.get_text("task_wanted"), @@ -77,6 +79,7 @@ def show_GUI(load_jsonname, config, shared_softwareconfig): # ui.link(config.get_text("setting_next_config"), '#NEXT_CONFIG') ui.link(config.get_text("task_cafe"), '#CAFE') ui.link(config.get_text("task_timetable"), '#TIME_TABLE') + ui.link(config.get_text("task_craft"), '#CRAFT') ui.link(config.get_text("task_shop"), '#SHOP_NORMAL') ui.link(config.get_text("task_buy_ap"), '#BUY_AP') ui.link(config.get_text("task_wanted"), '#WANTED') @@ -114,6 +117,9 @@ def show_GUI(load_jsonname, config, shared_softwareconfig): # 课程表 set_timetable(config) + + # 制造 + set_craft(config) # 商店 set_shop(config) diff --git a/gui/pages/Setting_Craft.py b/gui/pages/Setting_Craft.py new file mode 100644 index 0000000..444ac28 --- /dev/null +++ b/gui/pages/Setting_Craft.py @@ -0,0 +1,17 @@ +from nicegui import ui + +def set_craft(config): + with ui.row(): + ui.link_target("CRAFT") + ui.label(config.get_text("task_craft")).style('font-size: x-large') + + + ui.label(config.get_text("config_craft_desc")) + + ui.number(config.get_text("config_craft_max_times"), + step=1, + precision=0, + min=1, + max=3 + ).bind_value(config.userconfigdict, 'CRAFT_TIMES', forward=lambda v: int(v), backward=lambda v:int(v)).style('width: 400px') + \ No newline at end of file diff --git a/modules/AllTask/InCraft/InCraft.py b/modules/AllTask/InCraft/InCraft.py index 9f510e0..95435ad 100644 --- a/modules/AllTask/InCraft/InCraft.py +++ b/modules/AllTask/InCraft/InCraft.py @@ -59,6 +59,8 @@ def dealing_with_craft(self): CN: "点击制造失败", EN: "Failed to click craft button" })) + # 没制造材料,跳过之后的制造任务 + self.status=Task.STATUS_SKIP return # 点击开放按钮 click(self.BUTTON_CRAFT) @@ -114,6 +116,7 @@ def on_run(self) -> None: # 获取当前制造状态 status_list = self.getNowCraftStatus() logging.info(status_list) + now_craft_number = 0 for ind, item in enumerate(status_list): # 处理每一个位置 if item == self.STATUS_CRAFT_DOING: @@ -134,6 +137,19 @@ def on_run(self) -> None: lambda: not Page.is_page(PageName.PAGE_CRAFT) ) self.dealing_with_craft() + if self.status == Task.STATUS_SKIP: + logging.warn(istr({ + CN: "制造材料不足,跳过之后的制造任务", + EN: "Insufficient crafting materials, skip subsequent crafting tasks" + })) + return + now_craft_number += 1 + if now_craft_number >= config.userconfigdict["CRAFT_TIMES"]: + logging.info(istr({ + CN: f"制造次数已达上限 {config.userconfigdict['CRAFT_TIMES']}", + EN: f"The number of crafting has reached the upper limit {config.userconfigdict['CRAFT_TIMES']}" + })) + return diff --git a/modules/configs/defaultSettings.py b/modules/configs/defaultSettings.py index 3b0f249..af2e071 100644 --- a/modules/configs/defaultSettings.py +++ b/modules/configs/defaultSettings.py @@ -155,6 +155,8 @@ # 自定义任务 "USER_DEF_TASKS":{"d":""}, + + "CRAFT_TIMES":{"d":1}, } # 软件的config里的默认值 From 9b0be4ed07a4930928cb9ac00fa5894cc1575b6b Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Thu, 1 Aug 2024 21:03:55 +0100 Subject: [PATCH 12/16] Fix: can not read property of None --- modules/AllTask/SubTask/FightQuest.py | 14 ++++++++++---- modules/utils/__init__.py | 4 +++- update.py | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/modules/AllTask/SubTask/FightQuest.py b/modules/AllTask/SubTask/FightQuest.py index 60ddb2c..d06bc57 100644 --- a/modules/AllTask/SubTask/FightQuest.py +++ b/modules/AllTask/SubTask/FightQuest.py @@ -102,16 +102,20 @@ def on_run(self) -> None: sleeptime=2 ) # 1. 如果是白色UI,进入战斗 - if match_pixel((1250, 32), Page.COLOR_BUTTON_WHITE): + if match_pixel((1250, 32), Page.COLOR_BUTTON_WHITE, printit=True): # 战斗中 logging.info({"zh_CN": "战斗中...", "en_US": "Fighting"}) break + else: + logging.info({"zh_CN": "无法匹配右上暂停", "en_US": "Cannot match the upper right fight pause"}) # 2. 如果是剧情,跳过剧情 if match(button_pic(ButtonName.BUTTON_STORY_MENU)): logging.info({"zh_CN": "剧情中...", "en_US": "In the plot..."}) SkipStory(pre_times=3).run() # 跳过剧情后,重新判断是否进入了战斗 continue + else: + logging.info({"zh_CN": "无法匹配剧情按钮", "en_US": "Cannot match the story pause button"}) # 切换AUTO logging.info({"zh_CN": "切换AUTO...", "en_US": "Toggle Auto..."}) self.run_until( @@ -151,9 +155,11 @@ def on_run(self) -> None: self.run_until( lambda: click(Page.MAGICPOINT), lambda: match(button_pic(ButtonName.BUTTON_FIGHT_RESULT_CONFIRMB)) or match( - button_pic(ButtonName.BUTTON_CONFIRMY) or self.backtopic(), threshold=0.8), - times=90, - sleeptime=2 + button_pic(ButtonName.BUTTON_CONFIRMY), + threshold=0.8 + ) or self.backtopic(), + times=90, + sleeptime=2 ) if self.backtopic(): # 此处返回到backtopic,意味着错误进入了战斗 diff --git a/modules/utils/__init__.py b/modules/utils/__init__.py index 5114ada..1e31d11 100644 --- a/modules/utils/__init__.py +++ b/modules/utils/__init__.py @@ -229,8 +229,10 @@ def check_connect(): logging.info({"zh_CN":"adb与模拟器连接正常" , "en_US":"The connection between adb and the emulator is normal"}) # 检查图片长和宽 img = cv2.imread(f"./{get_config_screenshot_name()}") + if img is None: + logging.error({"zh_CN": "图片读取失败,多次出现请尝试重启模拟器", "en_US":"Image read failed, try restart emulator if encountered multiple times"}) # 第一维度是高,第二维度是宽 - if img.shape[0] == 720 and img.shape[1] == 1280: + elif img.shape[0] == 720 and img.shape[1] == 1280: logging.info({"zh_CN": "图片分辨率为1280*720", "en_US":"The resolution is 1280*720"}) return True elif img.shape[0] == 1280 and img.shape[1] == 720: diff --git a/update.py b/update.py index 669ed4e..b4a3a70 100644 --- a/update.py +++ b/update.py @@ -220,7 +220,7 @@ def check_and_update(): print(">>> You can not use this script to replace itself. Please unpack the zip manually. <<<") # 重新启动BAAH_GUI.exe - # 注意这里CREATE_NEW_CONSOLE即使把本文件关了,也不会影响BAAH_GUI.exe的运行 + # 注意这里CREATE_NEW_CONSOLE即使把本文件命令行窗口关了,也不会影响BAAH_GUI.exe的运行 if open_GUI_again: try: # Windows only From 9741b2e8c4f9c4502395dd9ea7b6137f1c53ebd2 Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Thu, 1 Aug 2024 21:07:55 +0100 Subject: [PATCH 13/16] chore: text --- gui/pages/Setting_server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/pages/Setting_server.py b/gui/pages/Setting_server.py index 30c2fdf..2815c2a 100644 --- a/gui/pages/Setting_server.py +++ b/gui/pages/Setting_server.py @@ -14,7 +14,7 @@ def set_server(config): "CN_BILI":config.get_text("config_server_cn_b")}, value=config.userconfigdict['SERVER_TYPE'], on_change=lambda a:set_server_info(a.value)).props('inline') - fanhexie = ui.checkbox("如果游戏开了反和谐请勾选此项").bind_value(config.userconfigdict, "FANHEXIE").bind_visibility_from(config.userconfigdict, "SERVER_TYPE", lambda x: x in ["CN", "CN_BILI"]) + fanhexie = ui.checkbox('如果游戏开了反和谐请勾选此项(手机显示“momotalk”勾选,手机显示“桃信”不要勾)').bind_value(config.userconfigdict, "FANHEXIE").bind_visibility_from(config.userconfigdict, "SERVER_TYPE", lambda x: x in ["CN", "CN_BILI"]) def set_server_info(servername): config.userconfigdict['SERVER_TYPE'] = servername From 87af2a4739c586036a7e98bb96bda921749e250b Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Fri, 2 Aug 2024 11:56:10 +0100 Subject: [PATCH 14/16] Remove: useless split --- BAAH.py | 3 ++- modules/utils/subprocess_helper.py | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/BAAH.py b/BAAH.py index bbafd3b..f75fcfe 100644 --- a/BAAH.py +++ b/BAAH.py @@ -85,7 +85,8 @@ def BAAH_start_emulator(): try: # 以列表形式传命令行参数 logging.info({"zh_CN": "启动模拟器", "en_US": "Starting the emulator"}) - emulator_process = subprocess_run(config.userconfigdict['TARGET_EMULATOR_PATH'].split(" "), isasync=True) + # 不能用shell,否则得到的是shell的pid + emulator_process = subprocess_run(config.userconfigdict['TARGET_EMULATOR_PATH'], isasync=True) logging.info({"zh_CN": "模拟器pid: " + str(emulator_process.pid), "en_US": "The emulator pid: " + str(emulator_process.pid)}) time.sleep(5) diff --git a/modules/utils/subprocess_helper.py b/modules/utils/subprocess_helper.py index b7a18eb..f6f3345 100644 --- a/modules/utils/subprocess_helper.py +++ b/modules/utils/subprocess_helper.py @@ -6,24 +6,26 @@ logging.getLogger("subprocess").setLevel(logging.WARNING) -def subprocess_run(cmd: Tuple[str], isasync=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding = "utf-8"): +def subprocess_run(cmd: Tuple[str]|str, isasync=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding = "utf-8", shell=False): """ Run a command in a subprocess and return the instance. Parameters ========== - cmd: list + cmd: list|str The command to run. Returns ======= pipeline """ + # https://www.cnblogs.com/superbaby11/p/16195273.html + # shell 为True时,cmd可以是字符串,否则是列表。列表的第一个元素是命令,后面的元素是传递给shell1的参数。 if isasync: # 异步非阻塞执行 - return subprocess.Popen(cmd, stdout=stdout, stderr=stderr, encoding=encoding) + return subprocess.Popen(cmd, stdout=stdout, stderr=stderr, encoding=encoding, shell=shell) else: # 同步阻塞执行 - return subprocess.run(cmd, stdout=stdout, stderr=stderr, encoding=encoding) + return subprocess.run(cmd, stdout=stdout, stderr=stderr, encoding=encoding, shell=shell) \ No newline at end of file From 4623d02089c43fcd6dba3f761d839abd194bedc5 Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Fri, 2 Aug 2024 12:00:33 +0100 Subject: [PATCH 15/16] chore: text --- modules/utils/adb_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/utils/adb_utils.py b/modules/utils/adb_utils.py index 0ef9d80..7efb013 100644 --- a/modules/utils/adb_utils.py +++ b/modules/utils/adb_utils.py @@ -112,7 +112,7 @@ def get_now_running_app(use_config=None): # 找到当前运行的app那行 output = sentence if "null" in output: - logging.warn({"zh_CN": "MUMU模拟器需要设置里关闭保活!", + logging.warn({"zh_CN": ">>> MUMU模拟器需要设置里关闭保活! <<<", "en_US": "If you are using MUMU emulator, please turn off the keep alive in the settings!"}) break # 截取app activity From 983c3ca5eac2f590b1a2f6a42e65b88c1ccc32c0 Mon Sep 17 00:00:00 2001 From: Yusen Wu Date: Fri, 2 Aug 2024 21:53:40 +0100 Subject: [PATCH 16/16] chore: text --- modules/AllTask/SubTask/FightQuest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/AllTask/SubTask/FightQuest.py b/modules/AllTask/SubTask/FightQuest.py index d06bc57..84bf484 100644 --- a/modules/AllTask/SubTask/FightQuest.py +++ b/modules/AllTask/SubTask/FightQuest.py @@ -108,6 +108,7 @@ def on_run(self) -> None: break else: logging.info({"zh_CN": "无法匹配右上暂停", "en_US": "Cannot match the upper right fight pause"}) + logging.warn({"zh_CN": "请确认游戏设置:战斗时上下黑边 为 关", "en_US": "Please confirm the game settings: Black edges during battle are off"}) # 2. 如果是剧情,跳过剧情 if match(button_pic(ButtonName.BUTTON_STORY_MENU)): logging.info({"zh_CN": "剧情中...", "en_US": "In the plot..."})