diff --git a/.github/workflows/auto-merge-pr.yaml b/.github/workflows/auto-merge-pr.yaml index d05e81c480..c415af0abc 100644 --- a/.github/workflows/auto-merge-pr.yaml +++ b/.github/workflows/auto-merge-pr.yaml @@ -2,8 +2,8 @@ name: Auto Merge Sync PR on: schedule: - # 每周五北京时间12点触发(UTC时间4点) - - cron: '0 4 * * 5' + # 每周五北京时间2点07分触发(UTC时间周四18点07分) + - cron: '7 18 * * 4' workflow_dispatch: permissions: diff --git a/tasks/ActivityShikigami/script_task.py b/tasks/ActivityShikigami/script_task.py index 375725edbb..c33731ff60 100644 --- a/tasks/ActivityShikigami/script_task.py +++ b/tasks/ActivityShikigami/script_task.py @@ -265,6 +265,10 @@ def _run_pass(self): break if self.appear(self.I_CHECK_BATTLE_MAIN) and self.appear_then_click(self.I_UI_BACK_YELLOW, interval=2.5): continue + if self.appear_then_click(self.I_UI_BACK_CIRCLE, interval=2.5): + continue + if self.appear_then_click(self.I_UI_BACK_RED, interval=1.5): + continue def _run_ap(self): """ diff --git a/tasks/Component/GeneralBattle/assets.py b/tasks/Component/GeneralBattle/assets.py index 8be2b0ee69..f159f4d0ec 100644 --- a/tasks/Component/GeneralBattle/assets.py +++ b/tasks/Component/GeneralBattle/assets.py @@ -209,6 +209,8 @@ class GeneralBattleAssets: C_END_FRIENDS_32 = RuleClick(roi_front=(0,0,100,100), roi_back=(0,0,100,100), name="end_friends_32") # description C_END_FRIENDS_23 = RuleClick(roi_front=(0,0,100,100), roi_back=(0,0,100,100), name="end_friends_23") + # 御魂过多的【去清理】按钮 + C_OVERFLOW_GHOST = RuleClick(roi_front=(456, 381, 160, 82), roi_back=(456, 381, 160, 82), name="overflow_ghost") # Click Rule Assets diff --git a/tasks/Component/GeneralBattle/battle.py b/tasks/Component/GeneralBattle/battle.py index fa5c3c9a5a..cfb3030dca 100644 --- a/tasks/Component/GeneralBattle/battle.py +++ b/tasks/Component/GeneralBattle/battle.py @@ -1,4 +1,5 @@ import random +from functools import wraps from module.logger import logger from module.atom.image import RuleImage @@ -12,6 +13,16 @@ from tasks.Component.GeneralBattle.config_general_battle import GeneralBattleConfig, GreenMarkType + +def log_battle_start(func): + @wraps(func) + def wrapper(owner, *args, **kwargs): + logger.hr("General battle start", 2) + return func(owner, *args, **kwargs) + + return wrapper + + class Battle(BattleWait): def start_fire(self, buttons: list[RuleOcr | RuleImage], checks: list[RuleImage]) -> bool: @@ -47,6 +58,7 @@ def start_fire(self, buttons: list[RuleOcr | RuleImage], checks: list[RuleImage] continue return True + @log_battle_start @battle_wait_strategy() def battle_wait(self, *args, **kwargs): return self.battle_wait_with_strategy(*args, **kwargs) diff --git a/tasks/Component/GeneralBattle/battle_wait.py b/tasks/Component/GeneralBattle/battle_wait.py index 9b7820454a..f6189d3ff7 100644 --- a/tasks/Component/GeneralBattle/battle_wait.py +++ b/tasks/Component/GeneralBattle/battle_wait.py @@ -158,7 +158,7 @@ class OptionSuccessDefault: 'C_END_MESSAGE_RIGHT_TOP', 'C_END_BUFF_AREA_1', 'C_END_BUFF_AREA_2', 'C_END_SOUL_RECORD', 'C_END_SOUL_DETAILS', 'C_END_1_1', 'C_END_1_2', 'C_END_1_3', 'C_END_1_4', - 'C_END_1_5', 'C_END_1_6', + 'C_END_1_5', 'C_END_1_6', "C_OVERFLOW_GHOST", ]) @@ -1152,6 +1152,10 @@ def _bw_completion_default(self, pub: PublicContext, pri: PrivateContext) -> Hoo def _bw_interrupt_default(self, pub: PublicContext, pri: PrivateContext) -> HookSignal: # 比如 御魂溢出 + + # 结算的时候御魂溢出提示,点击【知道了】 + self.appear_then_click(self.I_OVER_GHOST) + return HookSignal.CONTINUE def _bw_success_default(self, pub: PublicContext, pri: PrivateContext) -> HookSignal: @@ -1180,6 +1184,14 @@ def _bw_success_default(self, pub: PublicContext, pri: PrivateContext) -> HookSi while 1: self.screenshot() + # 发现御魂溢出,直接跳出,在interupt里面处理 + if self.appear(self.I_OVER_GHOST): + return HookSignal.CONTINUE + + # 结算的时候御魂溢出提示,点击【知道了】 + if self.appear(self.I_OVER_GHOST): + self.click(self.I_OVER_GHOST) + # 不小心点到了具体的奖励,他会弹出这个物品的详细描述 里面必定包含有“获取途径” if self.appear(self.I_END_FIX_1) or self.appear(self.I_END_FIX_2): self.click(self.C_REWARD_2, interval=1.5) diff --git a/tasks/Component/GeneralBattle/general_battle.py b/tasks/Component/GeneralBattle/general_battle.py index 1969ec153a..f255580110 100644 --- a/tasks/Component/GeneralBattle/general_battle.py +++ b/tasks/Component/GeneralBattle/general_battle.py @@ -635,6 +635,7 @@ def check_and_open_buff(self, buff: BuffClass or list[BuffClass] = None): break if self.appear_then_click(self.I_BUFF, interval=1): continue + self.ui_click_until_disappear(self.I_PREPARE_HIGHLIGHT, interval=0.8) def boss_mark(self, enable=True) -> bool: if not enable or self._boss_mark_flag: diff --git a/tasks/Component/GeneralInvite/general_invite.py b/tasks/Component/GeneralInvite/general_invite.py index 69dbd30fdc..85cb3c7ad5 100644 --- a/tasks/Component/GeneralInvite/general_invite.py +++ b/tasks/Component/GeneralInvite/general_invite.py @@ -481,6 +481,8 @@ def invite_friends(self, config: InviteConfig) -> bool: logger.warning('Invite friend 1 failed') # 如果是邀请第二个人 if config.invite_number == InviteNumber.TWO: + # 确定邀请前等待一段时间,避免游戏弹出邀请过快 + sleep(3) success = self.invite_friend(config.friend_2, config.find_mode) if not success: logger.warning('Invite friend 2 failed') diff --git a/tasks/Delegation/script_task.py b/tasks/Delegation/script_task.py index 37726458e4..f5d43d9ec7 100644 --- a/tasks/Delegation/script_task.py +++ b/tasks/Delegation/script_task.py @@ -56,22 +56,44 @@ def ui_click(click, stop): if not self.ocr_appear(self.O_D_NAME): logger.warning(f'Delegation: {name} not found') return False + enter_timer = Timer(15).start() while 1: self.screenshot() if self.appear(self.I_D_START): break + if enter_timer.reached(): + logger.warning(f'Delegation: {name} enter timeout') + return False + + # 检测到弹出的勾玉确认框,优先点击取消保护勾玉 + if self.appear_then_click(self.I_UI_CANCEL, interval=1): + continue + # 如果出现’召回‘ ’返回‘ 说明这个是现在委派中 # 需要退出 if self.appear(self.I_D_BACK): logger.warning(f'Delegation: {name} is in delegation') - self.ui_click_until_disappear(self.I_D_BACK) - self.wait_until_appear(self.I_REWARDS_MIN) + back_timer = Timer(6).start() + while 1: + self.screenshot() + if not self.appear(self.I_D_BACK): + break + if back_timer.reached(): + logger.warning('Exit delegation detail timeout') + break + # 若此时被取消弹窗遮挡返回,优先点取消 + if self.appear_then_click(self.I_UI_CANCEL, interval=1): + continue + if self.appear_then_click(self.I_D_BACK, interval=1.2): + continue + self.wait_until_appear(self.I_REWARDS_MIN, wait_time=3) return False if self.appear_then_click(self.I_D_SKIP, interval=0.8): continue if self.appear_then_click(self.I_D_CONFIRM, interval=0.8): continue - if self.ocr_appear_click(self.O_D_NAME, interval=1): + # 点击委派任务名:防抖由 1s 提升至 3s,杜绝跨页面过渡时误触右上角"完成(30勾玉)" + if self.ocr_appear_click(self.O_D_NAME, interval=3): continue # 进入委派 fefe e fe logger.info(f'Enter Delegation: {name}') @@ -81,10 +103,14 @@ def ui_click(click, stop): ui_click(self.C_D_4, self.I_D_SELECT_4) # 委派开始 logger.info(f'Delegation: {name} start') + start_timer = Timer(10).start() while 1: self.screenshot() if not self.appear(self.I_D_START): break + if start_timer.reached(): + logger.warning(f'Delegation: {name} start timeout') + break if self.click(self.C_D_5, interval=0.8): continue if self.appear_then_click(self.I_D_START, interval=1.8): diff --git a/tasks/Duel/script_task.py b/tasks/Duel/script_task.py index 4811eb8ccd..9d02ea4433 100644 --- a/tasks/Duel/script_task.py +++ b/tasks/Duel/script_task.py @@ -191,7 +191,8 @@ def wait_battle(self) -> bool: self.duel_exit_battle() continue if ret is None and not battle_operated: # 进行战斗前的操作 - self.ui_click(self.O_D_HAND, self.O_D_AUTO, interval=0.8) + # https://github.com/runhey/OnmyojiAutoScript/pull/1934 + self.ui_click(self.O_D_HAND, self.O_D_AUTO, interval=6, timeout=45) self.green_mark(self.conf.duel_config.green_enable, self.conf.duel_config.green_mark) battle_operated = True self.reset_device('BATTLE_STATUS_S') diff --git a/tasks/Exploration/assets.py b/tasks/Exploration/assets.py index 91d5300af8..7f8ffc86af 100644 --- a/tasks/Exploration/assets.py +++ b/tasks/Exploration/assets.py @@ -154,7 +154,7 @@ class ExplorationAssets: # 探索右上角 突破卷的数量 O_REALM_RAID_NUMBER = RuleOcr(roi=(739,11,78,37), area=(739,11,78,37), mode="DigitCounter", method="Default", keyword="", name="realm_raid_number") # (点出困难28时候)探索右上角 突破卷的数量 - O_REALM_RAID_NUMBER1 = RuleOcr(roi=(936,10,82,36), area=(936,10,82,36), mode="DigitCounter", method="Default", keyword="", name="realm_raid_number1") + O_REALM_RAID_NUMBER1 = RuleOcr(roi=(920,12,78,30), area=(919,12,80,30), mode="DigitCounter", method="Default", keyword="", name="realm_raid_number1") # Swipe Rule Assets diff --git a/tasks/Exploration/base.py b/tasks/Exploration/base.py index 3cc7f87b73..c64925fbda 100644 --- a/tasks/Exploration/base.py +++ b/tasks/Exploration/base.py @@ -58,9 +58,9 @@ def _config(self): def _match_end(self): return RuleAnimate(self.I_SWIPE_END) - def is_swipe_unchanged(self, before_image, after_image, threshold: float = 20) -> bool: - # 对比滑屏前后同一块区域,变化很小说明地图大概率没有移动,已经滑到尽头。 - swipe_check_roi = (1216, 86, 64, 225) + def is_swipe_unchanged(self, before_image, after_image, threshold: float = 15) -> bool: + # 对比滑屏前后中上部背景区域(避开顶部跑马灯、下方小怪挑战图标及最右侧浮动鬼火),变化很小说明地图已滑到尽头。 + swipe_check_roi = (250, 140, 800, 90) before = self.I_SWIPE_END.corp(before_image, swipe_check_roi) after = self.I_SWIPE_END.corp(after_image, swipe_check_roi) diff = np.mean(np.abs(before.astype(np.int16) - after.astype(np.int16))) @@ -162,7 +162,7 @@ def open_expect_level(self): if self.appear_then_click(self.I_UI_CONFIRM_SAMLL, interval=1): continue self.device.click_record_clear() - self.swipe(self.S_SWIPE_LEVEL_UP) + self.swipe(self.S_SWIPE_LEVEL_DOWN) swipeCount += 1 debug_info = f"Swiped {swipeCount} times, current exploration level: {text1}" logger.info(debug_info) @@ -329,11 +329,11 @@ def search_up_fight(self, up_type: UpType = None): self.I_NORMAL_BATTLE_BUTTON.roi_front = roi_front logger.info(f"Target locked: sword at {roi_front} (aligned with UP icon)") return self.I_NORMAL_BATTLE_BUTTON - else: - # 没找到 UP 图标,返回 None 让外层逻辑去处理(滑动或退出) - return None + # 没找到 UP 图标或对应战斗图标,返回 None 让外层逻辑去处理(滑动或退出) + return None # 2. 如果是默认情况 (UpType.ALL),则只要有怪就打 + self.I_NORMAL_BATTLE_BUTTON.roi_back = (0, 0, 1279, 719) if self.appear(self.I_NORMAL_BATTLE_BUTTON): return self.I_NORMAL_BATTLE_BUTTON @@ -389,6 +389,7 @@ def check_exit(self) -> bool: def quit_explore(self): logger.info('Quit explore') + self.device.click_record_remove(self.S_SWIPE_BACKGROUND_RIGHT.name) boss_timer = Timer(15) boss_timer.start() # click_yellow_button = 0 #用于保证只点一次左上返回按钮,不要直接触发连点回到主界面 diff --git a/tasks/Exploration/res/ocr.json b/tasks/Exploration/res/ocr.json index c6dbd1e033..e50e538aaa 100644 --- a/tasks/Exploration/res/ocr.json +++ b/tasks/Exploration/res/ocr.json @@ -28,8 +28,8 @@ }, { "itemName": "realm_raid_number1", - "roiFront": "936,10,82,36", - "roiBack": "936,10,82,36", + "roiFront": "920,12,78,30", + "roiBack": "919,12,80,30", "mode": "DigitCounter", "method": "Default", "keyword": "", diff --git a/tasks/Exploration/solo.py b/tasks/Exploration/solo.py index 80cef942c2..018aa37cbe 100644 --- a/tasks/Exploration/solo.py +++ b/tasks/Exploration/solo.py @@ -18,7 +18,11 @@ class SoloExploration(BaseExploration): INVITE_FLAG_ON = (227, 193, 153) INVITE_TIMEOUT = 20 FRIEND_LEAVE_TIMEOUT = 3 + SEARCH_SWIPE_INTERVAL = 1.5 + MAX_SWIPE_COUNT = 2 explore_init = False + swipe_cnt: int = 0 + search_fail_timer: Timer = None @cached_property def _invite_config(self) -> InviteConfig: @@ -60,9 +64,65 @@ def _check_mate_leave(self, friend_leave_timer: Timer) -> bool: self.quit_explore() return True + def _reset_search_state(self, reset_swipe_cnt: bool = False) -> None: + if reset_swipe_cnt: + if self.swipe_cnt > 0: + logger.info(f"Exploration search reset (cleared count: {self.swipe_cnt})") + self.swipe_cnt = 0 + self.search_fail_timer.clear() + + def _search_next_area(self) -> None: + if not self.search_fail_timer.started(): + self.search_fail_timer.start() + return + if not self.search_fail_timer.reached(): + return + + # 若选择特定 UP(如经验怪),达到最大滑屏次数(默认2次,覆盖前3屏高密度区)超时仍无目标直接早退重开; + # 若选择“全部”,则不限次数滑动直到最右边界,以保证清完全图小怪并击杀 BOSS。 + is_specific_up = self._config.exploration_config.up_type != UpType.ALL + if is_specific_up and self.swipe_cnt >= self.MAX_SWIPE_COUNT: + logger.info(f"Max search swipe count ({self.MAX_SWIPE_COUNT}) reached for specific UP target. Quitting exploration early.") + self._reset_search_state(reset_swipe_cnt=True) + self.quit_explore() + return + + before_image = self.device.image + self.swipe(self.S_SWIPE_BACKGROUND_RIGHT) + sleep(0.3) + self.screenshot() + unchanged = self.is_swipe_unchanged(before_image, self.device.image) + if unchanged: + sleep(0.3) + self.screenshot() + unchanged = self.is_swipe_unchanged(before_image, self.device.image) + + if (self.get_current_scene() != Scene.MAIN + or self.appear(self.I_UI_CONFIRM) + or self.appear(self.I_UI_CONFIRM_SAMLL)): + self.search_fail_timer.reset() + return + + # 若未产生位移,原地做快速二次复核保底 + if unchanged: + sleep(0.3) + before_retry = self.device.image + self.swipe(self.S_SWIPE_BACKGROUND_RIGHT) + sleep(0.3) + self.screenshot() + if self.is_swipe_unchanged(before_retry, self.device.image): + logger.info("Reached rightmost boundary (confirmed twice). Quitting exploration.") + self._reset_search_state(reset_swipe_cnt=True) + self.quit_explore() + return + + self.device.click_record_remove(self.S_SWIPE_BACKGROUND_RIGHT.name) + self.swipe_cnt += 1 + self.search_fail_timer.reset() + def run_solo(self): logger.hr('solo') - search_fail_timer = Timer(3.2) # 这里设置的时间一定要大于S_SWIPE_BACKGROUND_RIGHT滑动的时间 + self.search_fail_timer = Timer(self.SEARCH_SWIPE_INTERVAL) while 1: self.screenshot() @@ -70,6 +130,9 @@ def run_solo(self): logger.info(f'[run_solo] Current scene: {scene.name}') # TODO 2026.06.22 之后删掉这个刷屏的 # if scene == Scene.WORLD: + self.explore_init = False + self._reset_search_state(reset_swipe_cnt=True) + self.device.click_record_remove(self.S_SWIPE_BACKGROUND_RIGHT.name) # 打开右边箭头 if not self.wait_world_stable(): continue @@ -79,6 +142,9 @@ def run_solo(self): continue # elif scene == Scene.ENTRANCE: + self.explore_init = False + self._reset_search_state(reset_swipe_cnt=True) + self.device.click_record_remove(self.S_SWIPE_BACKGROUND_RIGHT.name) if self.check_exit(): break self.ui_click(self.I_E_EXPLORATION_CLICK, stop=self.I_E_SETTINGS_BUTTON) @@ -90,37 +156,38 @@ def run_solo(self): self.enter_settings_and_do_operations() self.ui_click(self.I_E_AUTO_ROTATE_OFF, stop=self.I_E_AUTO_ROTATE_ON, timeout=5) self.explore_init = True + self._reset_search_state(reset_swipe_cnt=True) continue if self._handle_treasure_box(): + self._reset_search_state() continue if (self.appear_then_click(self.I_UI_CONFIRM, interval=1) or self.appear_then_click(self.I_UI_CONFIRM_SAMLL, interval=1)): + self._reset_search_state() continue # 小纸人 if self.appear(self.I_BATTLE_REWARD): if self.ui_get_reward(self.I_BATTLE_REWARD): + self._reset_search_state() continue # boss if self.appear(self.I_BOSS_BATTLE_BUTTON): + self._reset_search_state() + self.device.click_record_remove(self.S_SWIPE_BACKGROUND_RIGHT.name) if self.fire(self.I_BOSS_BATTLE_BUTTON): logger.info(f'Boss battle, minions cnt {self.minions_cnt}') continue # 小怪 fight_button = self.search_up_fight() if fight_button is not None: + self._reset_search_state() + self.device.click_record_remove(self.S_SWIPE_BACKGROUND_RIGHT.name) if self.fire(fight_button): logger.info(f'Fight, minions cnt {self.minions_cnt}') continue # 向后拉,寻找怪 - if search_fail_timer.reached(): - search_fail_timer.reset() - if self._match_end.stable(self.device.image, refresh_after_stable=True): - self.quit_explore() - continue - self.swipe(self.S_SWIPE_BACKGROUND_RIGHT, interval=3) - continue - if not search_fail_timer.started(): - search_fail_timer.start() + self._search_next_area() + continue # elif scene == Scene.BATTLE_PREPARE or scene == Scene.BATTLE_FIGHTING: self.check_take_over_battle(is_screenshot=False, config=self._config.general_battle_config) @@ -129,7 +196,7 @@ def run_solo(self): def run_leader(self): logger.hr('leader') - search_fail_timer = Timer(3.2) # 这里设置的时间一定要大于S_SWIPE_BACKGROUND_RIGHT滑动的时间 + self.search_fail_timer = Timer(self.SEARCH_SWIPE_INTERVAL) friend_leave_timer = Timer(self.FRIEND_LEAVE_TIMEOUT) while 1: @@ -137,6 +204,9 @@ def run_leader(self): scene = self.get_current_scene() # 探索大世界 if scene == Scene.WORLD: + self.explore_init = False + self._reset_search_state(reset_swipe_cnt=True) + self.device.click_record_remove(self.S_SWIPE_BACKGROUND_RIGHT.name) # 打开右边箭头 if not self.wait_world_stable(): continue @@ -155,6 +225,9 @@ def run_leader(self): # 邀请好友, 非常有可能是后面邀请好友,然后直接跳到组队了 elif scene == Scene.ENTRANCE: + self.explore_init = False + self._reset_search_state(reset_swipe_cnt=True) + self.device.click_record_remove(self.S_SWIPE_BACKGROUND_RIGHT.name) while 1: self.screenshot() if self.is_in_room(): @@ -170,6 +243,8 @@ def run_leader(self): continue # elif scene == Scene.TEAM: + self.explore_init = False + self._reset_search_state(reset_swipe_cnt=True) self.wait_until_stable(self.I_ADD_2, timer=Timer(0.8, 1)) if self.appear(self.I_FIRE, threshold=0.8) and not self.appear(self.I_ADD_2): self.ui_click_until_disappear(self.I_FIRE, interval=1) @@ -196,37 +271,42 @@ def run_leader(self): self.enter_settings_and_do_operations() self.ui_click(self.I_E_AUTO_ROTATE_OFF, stop=self.I_E_AUTO_ROTATE_ON) self.explore_init = True + self._reset_search_state(reset_swipe_cnt=True) continue if self._handle_treasure_box(): + self._reset_search_state() + continue + if (self.appear_then_click(self.I_UI_CONFIRM, interval=1) + or self.appear_then_click(self.I_UI_CONFIRM_SAMLL, interval=1)): + self._reset_search_state() continue # 小纸人 if self.appear(self.I_BATTLE_REWARD): if self.ui_get_reward(self.I_BATTLE_REWARD): + self._reset_search_state() continue # 中途有人跑路 if self._check_mate_leave(friend_leave_timer): + self._reset_search_state() continue # boss if self.appear(self.I_BOSS_BATTLE_BUTTON): + self._reset_search_state() + self.device.click_record_remove(self.S_SWIPE_BACKGROUND_RIGHT.name) if self.fire(self.I_BOSS_BATTLE_BUTTON): logger.info(f'Boss battle, minions cnt {self.minions_cnt}') continue # 小怪 fight_button = self.search_up_fight() if fight_button is not None: + self._reset_search_state() + self.device.click_record_remove(self.S_SWIPE_BACKGROUND_RIGHT.name) if self.fire(fight_button): logger.info(f'Fight, minions cnt {self.minions_cnt}') continue # 向后拉,寻找怪 - if search_fail_timer.reached(): - search_fail_timer.reset() - if self._match_end.stable(self.device.image, refresh_after_stable=True): - self.quit_explore() - continue - self.swipe(self.S_SWIPE_BACKGROUND_RIGHT, interval=3) - continue - if not search_fail_timer.started(): - search_fail_timer.start() + self._search_next_area() + continue # elif scene == Scene.BATTLE_PREPARE or scene == Scene.BATTLE_FIGHTING: self.check_take_over_battle(is_screenshot=False, config=self._config.general_battle_config) diff --git a/tasks/GameUi/default_pages.py b/tasks/GameUi/default_pages.py index 733bf0b90c..2860d86581 100644 --- a/tasks/GameUi/default_pages.py +++ b/tasks/GameUi/default_pages.py @@ -61,7 +61,7 @@ def handle_login_page(task) -> bool: # 庭院主页(此处通过提高阈值来处理部分探索章节会识别成原始庭院的问题, 后续有其他更好方法需改善) page_main = Page(GameUiAssets.I_CHECK_MAIN, category="global") page_main.add_enter_success_hooks( - GameUiAssets.I_AD_CLOSE_RED, GlobalGameAssets.I_UI_BACK_RED, RestartAssets.I_CANCEL_BATTLE, + GameUiAssets.I_AD_CLOSE_RED, GlobalGameAssets.I_UI_BACK_RED, GlobalGameAssets.I_UI_CANCEL_SAMLL, conditional_action(RestartAssets.I_LOGIN_COURTYARD, RestartAssets.C_LOGIN_SCROLL_CLOSE_AREA), ) diff --git a/tasks/GlobalGame/assets.py b/tasks/GlobalGame/assets.py index ae7808b18d..106569e11c 100644 --- a/tasks/GlobalGame/assets.py +++ b/tasks/GlobalGame/assets.py @@ -42,11 +42,11 @@ class GlobalGameAssets: # 长一点的确认(旧) I_UI_CONFIRM_OLD = RuleImage(roi_front=(685,376,179,66), roi_back=(663,334,232,193), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_confirm_old.png") # 长一点的确认 - I_UI_CONFIRM = RuleImage(roi_front=(664,407,179,66), roi_back=(643,389,214,95), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_confirm.png") + I_UI_CONFIRM = RuleImage(roi_front=(664,407,179,66), roi_back=(643,345,231,320), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_confirm.png") # 长一点的取消(旧) I_UI_CANCEL_OLD = RuleImage(roi_front=(417,368,177,62), roi_back=(366,349,261,173), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_cancel_old.png") # 长一点的取消 - I_UI_CANCEL = RuleImage(roi_front=(438,407,177,62), roi_back=(356,384,276,125), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_cancel.png") + I_UI_CANCEL = RuleImage(roi_front=(438,407,177,62), roi_back=(356,384,275,256), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_cancel.png") # '获得奖励' 四个大字 I_UI_REWARD = RuleImage(roi_front=(530,126,211,66), roi_back=(464,69,352,303), threshold=0.73, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_reward.png") # description @@ -64,12 +64,12 @@ class GlobalGameAssets: # 短一点的取消 I_UI_CANCEL_SAMLL = RuleImage(roi_front=(472,389,128,62), roi_back=(360,377,272,185), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_cancel_samll.png") # description - I_UI_UNCHECK = RuleImage(roi_front=(567,343,33,36), roi_back=(497,303,216,100), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_uncheck.png") + I_UI_UNCHECK = RuleImage(roi_front=(545,343,33,36), roi_back=(497,303,216,100), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_uncheck.png") # 勾选 I_UI_CHECK = RuleImage(roi_front=(564,341,40,38), roi_back=(512,329,164,78), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_check.png") # 知道了 I_UI_GOTIT_SMALL = RuleImage(roi_front=(678,396,127,60), roi_back=(622,371,242,100), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_gotit_small.png") # 圆形返回按钮(移植自mine) - # I_UI_BACK_CIRCLE = RuleImage(roi_front=(24,21,36,39), roi_back=(0,0,95,101), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_back_circle.png") + I_UI_BACK_CIRCLE = RuleImage(roi_front=(24,21,36,39), roi_back=(0,0,95,101), threshold=0.8, method="Template matching", file="./tasks/GlobalGame/ui/ui_ui_back_circle.png") diff --git a/tasks/GlobalGame/ui/image.json b/tasks/GlobalGame/ui/image.json index 9b721f7b63..be77145cac 100644 --- a/tasks/GlobalGame/ui/image.json +++ b/tasks/GlobalGame/ui/image.json @@ -12,7 +12,7 @@ "itemName": "ui_confirm", "imageName": "ui_ui_confirm.png", "roiFront": "664,407,179,66", - "roiBack": "643,389,214,95", + "roiBack": "643,345,231,320", "method": "Template matching", "threshold": 0.8, "description": "长一点的确认" @@ -30,7 +30,7 @@ "itemName": "ui_cancel", "imageName": "ui_ui_cancel.png", "roiFront": "438,407,177,62", - "roiBack": "356,384,276,125", + "roiBack": "356,384,275,256", "method": "Template matching", "threshold": 0.8, "description": "长一点的取消" @@ -110,7 +110,7 @@ { "itemName": "ui_uncheck", "imageName": "ui_ui_uncheck.png", - "roiFront": "567,343,33,36", + "roiFront": "545,343,33,36", "roiBack": "497,303,216,100", "method": "Template matching", "threshold": 0.8, diff --git a/tasks/Orochi/script_task.py b/tasks/Orochi/script_task.py index e45acc6075..504f756b88 100644 --- a/tasks/Orochi/script_task.py +++ b/tasks/Orochi/script_task.py @@ -433,6 +433,10 @@ def battle_wait(self, random_click_swipt_enable: bool) -> bool: continue while 1: self.screenshot() + # 处理御魂溢出 + if self.appear_then_click(self.I_OVER_GHOST): + continue + action_click = random.choice([self.C_REWARD_1, self.C_REWARD_2, self.C_REWARD_3]) if not self.appear(self.I_GREED_GHOST): break @@ -445,6 +449,10 @@ def battle_wait(self, random_click_swipt_enable: bool) -> bool: appear_greed_ghost = self.appear(self.I_GREED_GHOST) while 1: self.screenshot() + # 处理御魂溢出 + if self.appear_then_click(self.I_OVER_GHOST): + continue + action_click = random.choice([self.C_REWARD_1, self.C_REWARD_2, self.C_REWARD_3]) if self.appear_then_click(self.I_REWARD, action=action_click, interval=1.5): continue diff --git a/tasks/Restart/assets.py b/tasks/Restart/assets.py index ca2cb5af1e..a2cab9e647 100644 --- a/tasks/Restart/assets.py +++ b/tasks/Restart/assets.py @@ -44,8 +44,6 @@ class RestartAssets: I_HARVEST_MAIL_ALL = RuleImage(roi_front=(69,579,80,67), roi_back=(28,551,142,144), threshold=0.8, method="Template matching", file="./tasks/Restart/harvest/harvest_harvest_mail_all.png") # 有些邮件需要点击一次 I_HARVEST_MAIL_OPEN = RuleImage(roi_front=(163,367,45,48), roi_back=(139,86,100,487), threshold=0.9, method="Template matching", file="./tasks/Restart/harvest/harvest_harvest_mail_open.png") - # 确认收取邮件 - I_HARVEST_MAIL_CONFIRM = RuleImage(roi_front=(687,543,168,64), roi_back=(687,543,168,64), threshold=0.8, method="Template matching", file="./tasks/Restart/harvest/harvest_harvest_mail_confirm.png") # description I_HARVEST_SOUL = RuleImage(roi_front=(241,497,38,36), roi_back=(68,480,930,72), threshold=0.8, method="Template matching", file="./tasks/Restart/harvest/harvest_harvest_soul.png") # description @@ -108,8 +106,6 @@ class RestartAssets: I_LOGIN_YELLOW_CLOSE = RuleImage(roi_front=(29,17,46,44), roi_back=(0,0,94,86), threshold=0.8, method="Template matching", file="./tasks/Restart/login/login_login_yellow_close.png") # 用于判断是否出现登录选区的 I_LOGIN_8 = RuleImage(roi_front=(178,572,53,60), roi_back=(1,547,241,105), threshold=0.8, method="Template matching", file="./tasks/Restart/login/login_login_8.png") - # 登录时候不观看CG视频 - I_WATCH_VIDEO_CANCEL = RuleImage(roi_front=(466,396,130,61), roi_back=(466,396,130,61), threshold=0.8, method="Template matching", file="./tasks/Restart/login/login_watch_video_cancel.png") # 指定角色进入游戏,默认第一个 I_LOGIN_SPECIFIC_SERVE = RuleImage(roi_front=(0,0,120,120), roi_back=(0,0,120,120), threshold=0.8, method="Template matching", file="./tasks/Restart/login/login_login_specific_serve.png") # 下载插画 @@ -118,8 +114,6 @@ class RestartAssets: I_LOGIN_LOGIN_GOTO_BIND_PHONE = RuleImage(roi_front=(940,430,170,150), roi_back=(940,430,170,150), threshold=0.8, method="Template matching", file="./tasks/Restart/login/login_login_goto_bind_phone.png") # 登录界面 弹出框 确定绑定手机 I_LOGIN_LOGIN_ENSURE_BIND_PHONE = RuleImage(roi_front=(670,460,160,100), roi_back=(670,460,160,100), threshold=0.8, method="Template matching", file="./tasks/Restart/login/login_login_ensure_bind_phone.png") - # 登录界面 弹出框 取消绑定手机 - I_LOGIN_LOGIN_CANCEL_BIND_PHONE = RuleImage(roi_front=(450,460,160,100), roi_back=(450,460,160,100), threshold=0.8, method="Template matching", file="./tasks/Restart/login/login_login_cancel_bind_phone.png") # 登录界面 弹出框 阴阳师精灵 I_LOGIN_LOGIN_ONMYOJI_GENIE = RuleImage(roi_front=(80,110,280,120), roi_back=(80,110,280,120), threshold=0.8, method="Template matching", file="./tasks/Restart/login/login_login_onmyoji_genie.png") # 已有角色 @@ -130,8 +124,6 @@ class RestartAssets: I_EARLY_SERVER = RuleImage(roi_front=(596,269,115,33), roi_back=(596,269,115,33), threshold=0.8, method="Template matching", file="./tasks/Restart/login/login_early_server.png") # 取消体验服切换弹窗 I_EARLY_SERVER_CANCEL = RuleImage(roi_front=(435,404,172,56), roi_back=(435,404,172,56), threshold=0.8, method="Template matching", file="./tasks/Restart/login/login_early_server_cancel.png") - # 取消继续战斗 - I_CANCEL_BATTLE = RuleImage(roi_front=(471,395,129,55), roi_back=(367,227,545,296), threshold=0.8, method="Template matching", file="./tasks/Restart/login/login_cancel_battle.png") # 庭院卷轴收起状态标志(移植自mine) I_LOGIN_COURTYARD = RuleImage(roi_front=(40,640,100,50), roi_back=(40,640,100,50), threshold=0.8, method="Template matching", file="./tasks/Restart/login/login_courtyard.png") diff --git a/tasks/Restart/harvest/harvest_harvest_mail_confirm.png b/tasks/Restart/harvest/harvest_harvest_mail_confirm.png deleted file mode 100644 index 5495d26003..0000000000 Binary files a/tasks/Restart/harvest/harvest_harvest_mail_confirm.png and /dev/null differ diff --git a/tasks/Restart/harvest/image.json b/tasks/Restart/harvest/image.json index dc74bbfccd..e76f5ae282 100644 --- a/tasks/Restart/harvest/image.json +++ b/tasks/Restart/harvest/image.json @@ -62,15 +62,6 @@ "threshold": 0.9, "description": "有些邮件需要点击一次" }, - { - "itemName": "harvest_mail_confirm", - "imageName": "harvest_harvest_mail_confirm.png", - "roiFront": "687,543,168,64", - "roiBack": "687,543,168,64", - "method": "Template matching", - "threshold": 0.8, - "description": "确认收取邮件" - }, { "itemName": "harvest_soul", "imageName": "harvest_harvest_soul.png", @@ -251,4 +242,4 @@ "threshold": 0.8, "description": "邮件红点" } -] \ No newline at end of file +] diff --git a/tasks/Restart/login.py b/tasks/Restart/login.py index 453b38a909..e387032e22 100644 --- a/tasks/Restart/login.py +++ b/tasks/Restart/login.py @@ -46,7 +46,7 @@ def _app_handle_login(self) -> bool: self._burst() # 取消继续战斗 - if self.appear_then_click(self.I_CANCEL_BATTLE, interval=0.8): + if self.appear_then_click(self.I_UI_CANCEL_SAMLL, interval=0.8): logger.info('Cancel continue battle') continue # 确认进入庭院(优化:先检测加成图标确认在庭院页面,再检测式神录图标) @@ -79,7 +79,7 @@ def _app_handle_login(self) -> bool: logger.info('Download inbetweening') continue # 不观看视频 - if self.appear_then_click(self.I_WATCH_VIDEO_CANCEL, interval=0.6): + if self.appear_then_click(self.I_UI_CANCEL_SAMLL, interval=0.6): logger.info('Close video') continue # 右上角的红色的关闭 @@ -94,7 +94,7 @@ def _app_handle_login(self) -> bool: if self.appear_then_click(self.I_LOGIN_LOGIN_GOTO_BIND_PHONE): while 1: self.screenshot() - if self.appear_then_click(self.I_LOGIN_LOGIN_CANCEL_BIND_PHONE): + if self.appear_then_click(self.I_UI_CANCEL_SAMLL): logger.info("Close bind phone") break continue @@ -310,7 +310,7 @@ def harvest_mail(self) -> bool: self.screenshot() if timeout_timer.reached(): break - if self.appear_then_click(self.I_HARVEST_MAIL_CONFIRM, interval=0.8): + if self.appear_then_click(self.I_UI_CONFIRM, interval=0.8): break if self.appear_then_click(self.I_READ_ALL_MAIL, interval=1.5): diff --git a/tasks/Restart/login/image.json b/tasks/Restart/login/image.json index 5d13a6e205..26e04c4c3c 100644 --- a/tasks/Restart/login/image.json +++ b/tasks/Restart/login/image.json @@ -53,15 +53,6 @@ "threshold": 0.8, "description": "用于判断是否出现登录选区的" }, - { - "itemName": "watch_video_cancel", - "imageName": "login_watch_video_cancel.png", - "roiFront": "466,396,130,61", - "roiBack": "466,396,130,61", - "method": "Template matching", - "threshold": 0.8, - "description": "登录时候不观看CG视频" - }, { "itemName": "login_specific_serve", "imageName": "login_login_specific_serve.png", @@ -98,15 +89,6 @@ "threshold": 0.8, "description": "登录界面 弹出框 确定绑定手机" }, - { - "itemName": "login_login_cancel_bind_phone", - "imageName": "login_login_cancel_bind_phone.png", - "roiFront": "450,460,160,100", - "roiBack": "450,460,160,100", - "method": "Template matching", - "threshold": 0.8, - "description": "登录界面 弹出框 取消绑定手机" - }, { "itemName": "login_login_onmyoji_genie", "imageName": "login_login_onmyoji_genie.png", @@ -152,15 +134,6 @@ "threshold": 0.8, "description": "取消体验服切换弹窗" }, - { - "itemName": "cancel_battle", - "imageName": "login_cancel_battle.png", - "roiFront": "471,395,129,55", - "roiBack": "367,227,545,296", - "method": "Template matching", - "threshold": 0.8, - "description": "取消继续战斗" - }, { "itemName": "login_courtyard", "imageName": "login_courtyard.png", diff --git a/tasks/Restart/login/login_cancel_battle.png b/tasks/Restart/login/login_cancel_battle.png deleted file mode 100644 index 4e70bfc56c..0000000000 Binary files a/tasks/Restart/login/login_cancel_battle.png and /dev/null differ diff --git a/tasks/Restart/login/login_login_cancel_bind_phone.png b/tasks/Restart/login/login_login_cancel_bind_phone.png deleted file mode 100644 index 14835d46b5..0000000000 Binary files a/tasks/Restart/login/login_login_cancel_bind_phone.png and /dev/null differ diff --git a/tasks/Restart/login/login_watch_video_cancel.png b/tasks/Restart/login/login_watch_video_cancel.png deleted file mode 100644 index 63801e8079..0000000000 Binary files a/tasks/Restart/login/login_watch_video_cancel.png and /dev/null differ diff --git a/tasks/WantedQuests/script_task.py b/tasks/WantedQuests/script_task.py index 1f0a1f8c84..1763440361 100644 --- a/tasks/WantedQuests/script_task.py +++ b/tasks/WantedQuests/script_task.py @@ -405,7 +405,7 @@ def invite_random(self, add_button: RuleImage): self.click(self.I_WQ_FRIEND_5) sleep(0.2) self.screenshot() - if not self.appear(self.I_SELECTED): + if not self.appear(self.I_WQ_INVITE_SELECTED): logger.warning('No friend selected') return False self.ui_click_until_disappear(self.I_INVITE_ENSURE) diff --git a/tasks/base_task.py b/tasks/base_task.py index c9b048ab7b..15ee95f9d8 100644 --- a/tasks/base_task.py +++ b/tasks/base_task.py @@ -80,10 +80,10 @@ def get_task_name(self) -> str: uppercase_first_letter=True, ) - if model_task_name and model_task_name != path_task_name: - raise ScriptError( - f'Task name mismatch: model={model_task_name}, path={path_task_name}' - ) + # if model_task_name and model_task_name != path_task_name: + # raise ScriptError( + # f'Task name mismatch: model={model_task_name}, path={path_task_name}' + # ) return model_task_name or path_task_name def _burst(self) -> bool: