diff --git a/assets/jp/os_ash/ASH_DAILY_STATUS.png b/assets/jp/os_ash/ASH_DAILY_STATUS.png index 5772d9e18..c19ff3240 100644 Binary files a/assets/jp/os_ash/ASH_DAILY_STATUS.png and b/assets/jp/os_ash/ASH_DAILY_STATUS.png differ diff --git a/campaign/event_20220224_cn/campaign_base.py b/campaign/event_20220224_cn/campaign_base.py index f96d2f7bf..c874590eb 100644 --- a/campaign/event_20220224_cn/campaign_base.py +++ b/campaign/event_20220224_cn/campaign_base.py @@ -1,4 +1,5 @@ from module.campaign.campaign_base import CampaignBase as CampaignBase_ +from module.ui.page import page_event class CampaignBase(CampaignBase_): @@ -6,3 +7,9 @@ class CampaignBase(CampaignBase_): if super().handle_clear_mode_config_cover(): self.config.MAP_SIREN_TEMPLATE = ['SS'] self.config.MAP_HAS_SIREN = True + + def handle_exp_info(self): + # Random background hits EXP_INFO_B + if self.ui_page_appear(page_event): + return False + return super().handle_exp_info() diff --git a/campaign/war_archives_20220224_cn/campaign_base.py b/campaign/war_archives_20220224_cn/campaign_base.py index 2eff6aa49..b8b32ebb9 100644 --- a/campaign/war_archives_20220224_cn/campaign_base.py +++ b/campaign/war_archives_20220224_cn/campaign_base.py @@ -1,3 +1,4 @@ +from module.ui.page import page_event from ..campaign_war_archives.campaign_base import CampaignBase as CampaignBase_ @@ -6,3 +7,9 @@ class CampaignBase(CampaignBase_): if super().handle_clear_mode_config_cover(): self.config.MAP_SIREN_TEMPLATE = ['SS'] self.config.MAP_HAS_SIREN = True + + def handle_exp_info(self): + # Random background hits EXP_INFO_B + if self.ui_page_appear(page_event): + return False + return super().handle_exp_info() diff --git a/module/config/utils.py b/module/config/utils.py index 1cf583025..9dc717e26 100644 --- a/module/config/utils.py +++ b/module/config/utils.py @@ -603,6 +603,17 @@ def get_server_weekday(): return result +def get_server_monthday(): + """ + Returns: + int: The server's current day of the month + """ + diff = server_time_offset() + server_now = datetime.now() - diff + result = server_now.day + return result + + def random_id(length=32): """ Args: diff --git a/module/daemon/benchmark.py b/module/daemon/benchmark.py index cce5e37a2..9283381d8 100644 --- a/module/daemon/benchmark.py +++ b/module/daemon/benchmark.py @@ -165,6 +165,9 @@ class Benchmark(DaemonBase, CampaignUI): if click_result: self.show(test='Control', data=click_result, evaluate_func=self.evaluate_click) fastest = sorted(click_result, key=lambda item: compare(item))[0] + # Prefer MaaTouch if both minitouch and MaaTouch are fastest + if 'MaaTouch' in click and fastest[0] == 'minitouch': + fastest[0] = 'MaaTouch' logger.info(f'Recommend control method: {fastest[0]} ({float2str(fastest[1])})') fastest_click = fastest[0] @@ -174,7 +177,7 @@ class Benchmark(DaemonBase, CampaignUI): device = self.config.Benchmark_DeviceType # device == 'emulator' screenshot = ['ADB', 'ADB_nc', 'uiautomator2', 'aScreenCap', 'aScreenCap_nc', 'DroidCast', 'DroidCast_raw'] - click = ['ADB', 'uiautomator2', 'minitouch'] + click = ['ADB', 'uiautomator2', 'minitouch', 'MaaTouch'] def remove(*args): return [l for l in screenshot if l not in args] diff --git a/module/device/connection.py b/module/device/connection.py index cbe709598..74a79ddaf 100644 --- a/module/device/connection.py +++ b/module/device/connection.py @@ -308,6 +308,23 @@ class Connection(ConnectionAttr): logger.attr('ro.product.brand', res) return 'waydroid' in res.lower() + @cached_property + @retry + def is_bluestacks_air(self): + # BlueStacks Air is the Mac version of BlueStacks + if not IS_MACINTOSH: + return False + if not self.is_ldplayer_bluestacks_family: + return False + # [bst.installed_images]: [Tiramisu64] + # [bst.instance]: [Tiramisu64] + # Tiramisu64 is Android 13 and BlueStacks Air is the only BlueStacks version that uses Android 13 + res = self.adb_getprop('bst.installed_images') + logger.attr('bst.installed_images', res) + if 'Tiramisu64' in res: + return True + return False + @cached_property @retry def nemud_app_keep_alive(self) -> str: @@ -401,11 +418,13 @@ class Connection(ConnectionAttr): host = '127.0.0.1' if IS_LINUX and host == '127.0.1.1': host = '127.0.0.1' + if self.is_bluestacks_air: + host = '127.0.0.1' logger.info(f'Connecting to local emulator, using host {host}') port = random_port(self.config.FORWARD_PORT_RANGE) # For AVD instance - if self.is_avd: + if self.is_avd or self.is_bluestacks_air: return host, port, "10.0.2.2", port return host, port, host, port diff --git a/module/guild/operations.py b/module/guild/operations.py index 3ec99c92a..b5ab5043e 100644 --- a/module/guild/operations.py +++ b/module/guild/operations.py @@ -3,6 +3,7 @@ from datetime import datetime from module.base.button import ButtonGrid from module.base.timer import Timer from module.base.utils import * +from module.config.utils import get_server_monthday from module.exception import GameBugError from module.guild.assets import * from module.guild.base import GuildBase @@ -89,7 +90,7 @@ class GuildOperations(GuildBase): if not self.config.GuildOperation_SelectNewOperation: return False - today = datetime.now().day + today = get_server_monthday() limit = self.config.GuildOperation_NewOperationMaxDate if today >= limit: logger.info(f'No new guild operations because, today\'s date {today} >= limit {limit}') diff --git a/module/os_ash/ash.py b/module/os_ash/ash.py index 963c2b4ff..aeee4e621 100644 --- a/module/os_ash/ash.py +++ b/module/os_ash/ash.py @@ -1,7 +1,5 @@ from datetime import datetime, timedelta -import module.config.server as server - from module.base.utils import image_left_strip from module.combat.combat import BATTLE_PREPARATION, Combat from module.config.utils import DEFAULT_TIME @@ -90,16 +88,10 @@ class OSAsh(UI, MapEventHandler): return 0 if self.image_color_count(ASH_COLLECT_STATUS, color=(235, 235, 235), threshold=221, count=20): logger.info('Ash beacon status: light') - if server.server != 'jp': - ocr_collect = DigitCounter( - ASH_COLLECT_STATUS, letter=(235, 235, 235), threshold=160, name='OCR_ASH_COLLECT_STATUS') - ocr_daily = DailyDigitCounter( - ASH_DAILY_STATUS, letter=(235, 235, 235), threshold=160, name='OCR_ASH_DAILY_STATUS') - else: - ocr_collect = DigitCounter( - ASH_COLLECT_STATUS, letter=(201, 201, 201), threshold=128, name='OCR_ASH_COLLECT_STATUS') - ocr_daily = DailyDigitCounter( - ASH_DAILY_STATUS, letter=(193, 193, 193), threshold=160, name='OCR_ASH_DAILY_STATUS') + ocr_collect = DigitCounter( + ASH_COLLECT_STATUS, letter=(235, 235, 235), threshold=160, name='OCR_ASH_COLLECT_STATUS') + ocr_daily = DailyDigitCounter( + ASH_DAILY_STATUS, letter=(235, 235, 235), threshold=160, name='OCR_ASH_DAILY_STATUS') elif self.image_color_count(ASH_COLLECT_STATUS, color=(140, 142, 140), threshold=221, count=20): logger.info('Ash beacon status: gray') ocr_collect = DigitCounter( diff --git a/module/os_ash/assets.py b/module/os_ash/assets.py index 0d86d32ac..0323b4685 100644 --- a/module/os_ash/assets.py +++ b/module/os_ash/assets.py @@ -5,7 +5,7 @@ from module.base.template import Template # Don't modify it manually. ASH_COLLECT_STATUS = Button(area={'cn': (640, 27, 720, 49), 'en': (640, 27, 720, 49), 'jp': (640, 27, 720, 49), 'tw': (640, 27, 720, 49)}, color={'cn': (82, 92, 99), 'en': (82, 92, 99), 'jp': (82, 92, 99), 'tw': (82, 92, 99)}, button={'cn': (640, 27, 720, 49), 'en': (640, 27, 720, 49), 'jp': (640, 27, 720, 49), 'tw': (640, 27, 720, 49)}, file={'cn': './assets/cn/os_ash/ASH_COLLECT_STATUS.png', 'en': './assets/en/os_ash/ASH_COLLECT_STATUS.png', 'jp': './assets/jp/os_ash/ASH_COLLECT_STATUS.png', 'tw': './assets/tw/os_ash/ASH_COLLECT_STATUS.png'}) -ASH_DAILY_STATUS = Button(area={'cn': (637, 0, 741, 19), 'en': (637, 0, 741, 19), 'jp': (637, 0, 741, 19), 'tw': (637, 0, 741, 19)}, color={'cn': (104, 112, 121), 'en': (104, 112, 121), 'jp': (104, 112, 121), 'tw': (104, 112, 121)}, button={'cn': (637, 0, 741, 19), 'en': (637, 0, 741, 19), 'jp': (637, 0, 741, 19), 'tw': (637, 0, 741, 19)}, file={'cn': './assets/cn/os_ash/ASH_DAILY_STATUS.png', 'en': './assets/en/os_ash/ASH_DAILY_STATUS.png', 'jp': './assets/jp/os_ash/ASH_DAILY_STATUS.png', 'tw': './assets/tw/os_ash/ASH_DAILY_STATUS.png'}) +ASH_DAILY_STATUS = Button(area={'cn': (637, 0, 741, 19), 'en': (637, 0, 741, 19), 'jp': (637, 2, 741, 18), 'tw': (637, 0, 741, 19)}, color={'cn': (104, 112, 121), 'en': (104, 112, 121), 'jp': (90, 109, 125), 'tw': (104, 112, 121)}, button={'cn': (637, 0, 741, 19), 'en': (637, 0, 741, 19), 'jp': (637, 2, 741, 18), 'tw': (637, 0, 741, 19)}, file={'cn': './assets/cn/os_ash/ASH_DAILY_STATUS.png', 'en': './assets/en/os_ash/ASH_DAILY_STATUS.png', 'jp': './assets/jp/os_ash/ASH_DAILY_STATUS.png', 'tw': './assets/tw/os_ash/ASH_DAILY_STATUS.png'}) ASH_QUIT = Button(area={'cn': (29, 25, 59, 49), 'en': (29, 25, 59, 49), 'jp': (22, 25, 54, 48), 'tw': (29, 25, 59, 49)}, color={'cn': (115, 63, 68), 'en': (115, 63, 68), 'jp': (114, 61, 67), 'tw': (115, 63, 68)}, button={'cn': (29, 25, 59, 49), 'en': (29, 25, 59, 49), 'jp': (22, 25, 54, 48), 'tw': (29, 25, 59, 49)}, file={'cn': './assets/cn/os_ash/ASH_QUIT.png', 'en': './assets/en/os_ash/ASH_QUIT.png', 'jp': './assets/jp/os_ash/ASH_QUIT.png', 'tw': './assets/tw/os_ash/ASH_QUIT.png'}) ASH_SHOWDOWN = Button(area={'cn': (120, 14, 262, 38), 'en': (120, 16, 319, 35), 'jp': (122, 15, 246, 39), 'tw': (120, 14, 262, 38)}, color={'cn': (153, 131, 131), 'en': (130, 106, 106), 'jp': (164, 144, 145), 'tw': (153, 131, 131)}, button={'cn': (120, 14, 262, 38), 'en': (120, 16, 319, 35), 'jp': (122, 15, 246, 39), 'tw': (120, 14, 262, 38)}, file={'cn': './assets/cn/os_ash/ASH_SHOWDOWN.png', 'en': './assets/en/os_ash/ASH_SHOWDOWN.png', 'jp': './assets/jp/os_ash/ASH_SHOWDOWN.png', 'tw': './assets/tw/os_ash/ASH_SHOWDOWN.png'}) ASH_START = Button(area={'cn': (1061, 635, 1259, 695), 'en': (1063, 637, 1255, 693), 'jp': (1058, 634, 1260, 697), 'tw': (1043, 637, 1242, 698)}, color={'cn': (236, 187, 115), 'en': (223, 184, 124), 'jp': (222, 185, 126), 'tw': (223, 186, 131)}, button={'cn': (1061, 635, 1259, 695), 'en': (1063, 637, 1255, 693), 'jp': (1058, 634, 1260, 697), 'tw': (1043, 637, 1242, 698)}, file={'cn': './assets/cn/os_ash/ASH_START.png', 'en': './assets/en/os_ash/ASH_START.png', 'jp': './assets/jp/os_ash/ASH_START.png', 'tw': './assets/tw/os_ash/ASH_START.png'}) diff --git a/module/research/project.py b/module/research/project.py index 7b11291ed..d6144d9d8 100644 --- a/module/research/project.py +++ b/module/research/project.py @@ -4,6 +4,7 @@ from scipy import signal from module.base.decorator import cached_property from module.base.utils import * +from module.device.method.utils import remove_suffix from module.logger import logger from module.ocr.ocr import Duration, Ocr from module.research.assets import * @@ -363,7 +364,9 @@ def research_jp_detect(image): """ project = ResearchProjectJp() project.series = get_research_series_jp(image) - project.duration = str(get_research_duration_jp(image) / 3600).rstrip('.0') + project.duration = remove_suffix(str(get_research_duration_jp(image) / 3600), '.0') + if project.duration == '': + project.duration = '0' project.genre = get_research_genre_jp(image) costs = get_research_cost_jp(image) for cost in costs: