From 0ed763ed5472c132691701e3effd924da05ea627 Mon Sep 17 00:00:00 2001 From: xiaomcingn <63132881+xiaomcingn@users.noreply.github.com> Date: Sat, 23 May 2026 19:25:21 +0800 Subject: [PATCH] Fix: use drag_page instead of ROLE_SORTING to fix character detection failure --- module/island/assets.py | 1 + module/island/project.py | 70 ++++++++++++++++++++++++++++------------ 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/module/island/assets.py b/module/island/assets.py index a789420ea..8a09f0840 100644 --- a/module/island/assets.py +++ b/module/island/assets.py @@ -12,6 +12,7 @@ ISLAND_MANAGEMENT = Button(area={'cn': (1077, 493, 1119, 533), 'en': (1077, 493, ISLAND_MANAGEMENT_CHECK = Button(area={'cn': (123, 21, 304, 47), 'en': (123, 21, 304, 47), 'jp': (123, 21, 304, 47), 'tw': (123, 21, 304, 47)}, color={'cn': (77, 83, 96), 'en': (90, 96, 108), 'jp': (77, 83, 96), 'tw': (77, 83, 96)}, button={'cn': (123, 21, 304, 47), 'en': (123, 21, 304, 47), 'jp': (123, 21, 304, 47), 'tw': (123, 21, 304, 47)}, file={'cn': './assets/cn/island/ISLAND_MANAGEMENT_CHECK.png', 'en': './assets/en/island/ISLAND_MANAGEMENT_CHECK.png', 'jp': './assets/cn/island/ISLAND_MANAGEMENT_CHECK.png', 'tw': './assets/cn/island/ISLAND_MANAGEMENT_CHECK.png'}) ISLAND_MANAGEMENT_LOCKED = Button(area={'cn': (1092, 504, 1105, 520), 'en': (1092, 504, 1105, 520), 'jp': (1092, 504, 1105, 520), 'tw': (1092, 504, 1105, 520)}, color={'cn': (197, 206, 195), 'en': (197, 206, 195), 'jp': (197, 206, 195), 'tw': (197, 206, 195)}, button={'cn': (1092, 504, 1105, 520), 'en': (1092, 504, 1105, 520), 'jp': (1092, 504, 1105, 520), 'tw': (1092, 504, 1105, 520)}, file={'cn': './assets/cn/island/ISLAND_MANAGEMENT_LOCKED.png', 'en': './assets/cn/island/ISLAND_MANAGEMENT_LOCKED.png', 'jp': './assets/cn/island/ISLAND_MANAGEMENT_LOCKED.png', 'tw': './assets/cn/island/ISLAND_MANAGEMENT_LOCKED.png'}) ISLAND_PRODUCT_ITEMS = Button(area={'cn': (166, 68, 477, 652), 'en': (166, 68, 477, 652), 'jp': (166, 68, 477, 652), 'tw': (166, 68, 477, 652)}, color={'cn': (189, 200, 198), 'en': (189, 200, 198), 'jp': (189, 200, 198), 'tw': (189, 200, 198)}, button={'cn': (166, 68, 477, 652), 'en': (166, 68, 477, 652), 'jp': (166, 68, 477, 652), 'tw': (166, 68, 477, 652)}, file={'cn': './assets/cn/island/ISLAND_PRODUCT_ITEMS.png', 'en': './assets/cn/island/ISLAND_PRODUCT_ITEMS.png', 'jp': './assets/cn/island/ISLAND_PRODUCT_ITEMS.png', 'tw': './assets/cn/island/ISLAND_PRODUCT_ITEMS.png'}) +ISLAND_PROJECT_CHARACTER = Button(area={'cn': (544, 149, 640, 549), 'en': (544, 149, 640, 549), 'jp': (544, 149, 640, 549), 'tw': (544, 149, 640, 549)}, color={'cn': (128, 128, 128), 'en': (128, 128, 128), 'jp': (128, 128, 128), 'tw': (128, 128, 128)}, button={'cn': (544, 149, 640, 549), 'en': (544, 149, 640, 549), 'jp': (544, 149, 640, 549), 'tw': (544, 149, 640, 549)}, file={'cn': './assets/cn/island/ISLAND_PROJECT_CHARACTER.png', 'en': './assets/cn/island/ISLAND_PROJECT_CHARACTER.png', 'jp': './assets/cn/island/ISLAND_PROJECT_CHARACTER.png', 'tw': './assets/cn/island/ISLAND_PROJECT_CHARACTER.png'}) ISLAND_PROJECT_SWIPE = Button(area={'cn': (690, 80, 721, 641), 'en': (690, 80, 721, 641), 'jp': (690, 80, 721, 641), 'tw': (690, 80, 721, 641)}, color={'cn': (215, 218, 213), 'en': (215, 218, 213), 'jp': (215, 218, 213), 'tw': (215, 218, 213)}, button={'cn': (690, 80, 721, 641), 'en': (690, 80, 721, 641), 'jp': (690, 80, 721, 641), 'tw': (690, 80, 721, 641)}, file={'cn': './assets/cn/island/ISLAND_PROJECT_SWIPE.png', 'en': './assets/cn/island/ISLAND_PROJECT_SWIPE.png', 'jp': './assets/cn/island/ISLAND_PROJECT_SWIPE.png', 'tw': './assets/cn/island/ISLAND_PROJECT_SWIPE.png'}) ISLAND_TRANSPORT = Button(area={'cn': (905, 335, 986, 358), 'en': (905, 335, 986, 358), 'jp': (905, 335, 986, 358), 'tw': (905, 335, 986, 358)}, color={'cn': (228, 192, 122), 'en': (234, 192, 102), 'jp': (228, 192, 122), 'tw': (228, 192, 122)}, button={'cn': (898, 328, 1031, 459), 'en': (905, 335, 986, 358), 'jp': (898, 328, 1031, 459), 'tw': (898, 328, 1031, 459)}, file={'cn': './assets/cn/island/ISLAND_TRANSPORT.png', 'en': './assets/en/island/ISLAND_TRANSPORT.png', 'jp': './assets/cn/island/ISLAND_TRANSPORT.png', 'tw': './assets/cn/island/ISLAND_TRANSPORT.png'}) ISLAND_TRANSPORT_CHECK = Button(area={'cn': (264, 154, 317, 180), 'en': (264, 154, 317, 180), 'jp': (264, 154, 317, 180), 'tw': (264, 154, 317, 180)}, color={'cn': (142, 143, 143), 'en': (22, 0, 0), 'jp': (142, 143, 143), 'tw': (142, 143, 143)}, button={'cn': (264, 154, 317, 180), 'en': (264, 154, 317, 180), 'jp': (264, 154, 317, 180), 'tw': (264, 154, 317, 180)}, file={'cn': './assets/cn/island/ISLAND_TRANSPORT_CHECK.png', 'en': './assets/en/island/ISLAND_TRANSPORT_CHECK.png', 'jp': './assets/cn/island/ISLAND_TRANSPORT_CHECK.png', 'tw': './assets/cn/island/ISLAND_TRANSPORT_CHECK.png'}) diff --git a/module/island/project.py b/module/island/project.py index 3983dcc91..22dc8bd36 100644 --- a/module/island/project.py +++ b/module/island/project.py @@ -501,38 +501,65 @@ class IslandProjectRun(IslandUI): self.interval_clear(ISLAND_MANAGEMENT_CHECK) continue - def project_character_select(self, character='manjuu'): + def match_and_select_character(self, character, image): + """ + Match character template and select if found. + + Args: + character (str): character name to select + image: cropped image + + Returns: + bool: True if matched and selected, False otherwise + """ + sim, click_button = self.get_character_template(character).match_result(image) + if sim > 0.9: + check_button = self.get_character_check_button(character) + return self._project_character_select(click_button, check_button) + return False + + def project_character_select(self, character='manjuu', reset_swipe=False): """ Select a role to produce. Args: character (str): character name to select + reset_swipe (bool): if drag page to top before selecting Returns: bool: if selected """ logger.info(f'Island select role: {character}') - ROLE_SORTING.set('Descending', main=self) - timeout = Timer(5, count=3).start() - sort_switched = False + if reset_swipe: + logger.info('Resetting role page to top') + for _ in range(2): + self.drag_page((0, 350), ISLAND_PROJECT_CHARACTER.area, 0.6) + self.device.screenshot() + image = self.image_crop((0, 0, 1280, 720), copy=False) + if self.match_and_select_character(character, image): + return True + + timeout = Timer(5, count=3).start() + max_swipe = 2 + swipe_count = 0 for _ in self.loop(): if timeout.reached(): return False - image = self.image_crop((0, 0, 910, 1280), copy=False) - sim, click_button = self.get_character_template(character).match_result(image) + image = self.image_crop((0, 0, 1280, 720), copy=False) + if self.match_and_select_character(character, image): + return True - if sim > 0.9: - check_button = self.get_character_check_button(character) - return self._project_character_select(click_button, check_button) + if swipe_count < max_swipe: + logger.info(f'Character {character} not found, dragging down to find') + self.drag_page((0, -300), ISLAND_PROJECT_CHARACTER.area, 0.6) + swipe_count += 1 + timeout.reset() else: - if not sort_switched: - logger.info(f'Character {character} not found or not available, switching sort to retry') - ROLE_SORTING.set('Ascending', main=self) - sort_switched = True - continue + logger.warning(f'Character {character} not found after {max_swipe} swipes') + return False def retry_character_select(self, button, secondary_character=None): """ @@ -546,18 +573,21 @@ class IslandProjectRun(IslandUI): Returns: tuple(bool, str): (if selected, character selected) """ - # Try secondary character if provided + # Try secondary character if provided, reset swipe to top before searching if secondary_character and secondary_character != 'manjuu': logger.info(f'Trying secondary character: {secondary_character}') - if self.project_character_select(secondary_character): + if self.project_character_select(secondary_character, reset_swipe=True): return True, secondary_character - # Fallback to manjuu + # Fallback to manjuu directly since page is already at the bottom logger.info('Falling back to manjuu') - if self.project_character_select('manjuu'): + self.device.screenshot() + image = self.image_crop((0, 0, 1280, 720), copy=False) + if self.match_and_select_character('manjuu', image): return True, 'manjuu' - - return False, None + else: + logger.warning('Manjuu not found') + return False, None @staticmethod def get_character_template(character):