1
0
mirror of https://github.com/TheFunny/ArisuAutoSweeper synced 2025-12-16 22:05:12 +00:00

style: format

This commit is contained in:
YoursFunny 2024-01-15 19:25:15 +08:00
parent e5f91e0c0a
commit e6a3b79733
Signed by: YoursFunny
GPG Key ID: 207EDC3CD5B40F9C
13 changed files with 124 additions and 115 deletions

View File

@ -1,7 +1,7 @@
from module.base.base import ModuleBase from module.base.base import ModuleBase
from module.base.timer import Timer from module.base.timer import Timer
from tasks.base.assets.assets_base_popup import *
from tasks.base.assets.assets_base_page import LOADING_CHECK from tasks.base.assets.assets_base_page import LOADING_CHECK
from tasks.base.assets.assets_base_popup import *
class PopupHandler(ModuleBase): class PopupHandler(ModuleBase):
@ -111,16 +111,15 @@ class PopupHandler(ModuleBase):
return True return True
return False return False
def handle_level_up(self, interval=5) -> bool: def handle_level_up(self, interval=5) -> bool:
if self.appear_then_click(LEVEL_UP, interval=interval): if self.appear_then_click(LEVEL_UP, interval=interval):
return True return True
return False return False
def handle_quit(self, interval=5) -> bool: def handle_quit(self, interval=5) -> bool:
if self.appear_then_click(QUIT, interval=interval): if self.appear_then_click(QUIT, interval=interval):
return True return True
return False return False

View File

@ -5,10 +5,10 @@ from module.base.utils import get_color
from module.exception import GameNotRunningError, GamePageUnknownError, RequestHumanTakeover from module.exception import GameNotRunningError, GamePageUnknownError, RequestHumanTakeover
from module.logger import logger from module.logger import logger
from module.ocr.ocr import Ocr, Digit from module.ocr.ocr import Ocr, Digit
from tasks.base.assets.assets_base_page import BACK
from tasks.base.main_page import MainPage from tasks.base.main_page import MainPage
from tasks.base.page import Page, page_main from tasks.base.page import Page, page_main
from tasks.login.assets.assets_login import LOGIN_LOADING, OCR_YEAR from tasks.login.assets.assets_login import LOGIN_LOADING, OCR_YEAR
from tasks.base.assets.assets_base_page import BACK
class UI(MainPage): class UI(MainPage):
@ -24,7 +24,7 @@ class UI(MainPage):
def appear_trademark_year(self): def appear_trademark_year(self):
ocr_year = Digit(OCR_YEAR).ocr_single_line(self.device.image) ocr_year = Digit(OCR_YEAR).ocr_single_line(self.device.image)
return ocr_year == 2021 return ocr_year == 2021
def ui_page_appear(self, page): def ui_page_appear(self, page):
""" """
Args: Args:
@ -132,7 +132,7 @@ class UI(MainPage):
self.interval_clear(list(Page.iter_check_buttons())) self.interval_clear(list(Page.iter_check_buttons()))
# loading_timer = Timer(0.5) # loading_timer = Timer(0.5)
back_timer = Timer(15,15) back_timer = Timer(15, 15)
logger.hr(f"UI goto {destination}") logger.hr(f"UI goto {destination}")
while 1: while 1:
if skip_first_screenshot: if skip_first_screenshot:
@ -190,7 +190,6 @@ class UI(MainPage):
self.device.back() self.device.back()
logger.info("Unknown page, try to back") logger.info("Unknown page, try to back")
back_timer.reset() back_timer.reset()
# Reset connection # Reset connection
Page.clear_connection() Page.clear_connection()
@ -388,11 +387,11 @@ class UI(MainPage):
return True return True
# disabled because will exit the game if quit appears # disabled because will exit the game if quit appears
#if self.handle_ap_exceed(): # if self.handle_ap_exceed():
# return True # return True
#if self.handle_insufficient_inventory(): # if self.handle_insufficient_inventory():
# return True # return True
#if self.handle_item_expired(): # if self.handle_item_expired():
# return True # return True
return False return False
@ -458,4 +457,4 @@ class UI(MainPage):
logger.error("Failed to close popup") logger.error("Failed to close popup")
raise RequestHumanTakeover raise RequestHumanTakeover
while not wait.reached(): while not wait.reached():
pass pass

View File

@ -18,6 +18,7 @@ class Login(UI):
GameTooManyClickError: GameTooManyClickError:
GameNotRunningError: GameNotRunningError:
""" """
def _page_main_twice_confirm(): def _page_main_twice_confirm():
if self.ui_page_appear(page_main): if self.ui_page_appear(page_main):
timer = Timer(1).start() timer = Timer(1).start()

View File

@ -1,28 +1,28 @@
from enum import Enum
from module.base.timer import Timer
from module.exception import RequestHumanTakeover
from module.logger import logger
from tasks.mission.ui import MissionUI, CommissionsUI, SWITCH_QUEST
from tasks.stage.ap import AP
from tasks.cafe.cafe import Cafe
from tasks.circle.circle import Circle
from tasks.task.task import Task
from tasks.mail.mail import Mail
from tasks.item.data_update import DataUpdate
import json import json
import math import math
from filelock import FileLock
from datetime import datetime, timedelta from datetime import datetime, timedelta
from enum import Enum
from filelock import FileLock
from module.base.timer import Timer
from module.logger import logger
from tasks.cafe.cafe import Cafe
from tasks.circle.circle import Circle
from tasks.item.data_update import DataUpdate
from tasks.mail.mail import Mail
from tasks.mission.ui import MissionUI, CommissionsUI, SWITCH_QUEST
from tasks.task.task import Task
class MissionStatus(Enum): class MissionStatus(Enum):
AP = 0 # Calculate AP and decide to terminate Mission module or not AP = 0 # Calculate AP and decide to terminate Mission module or not
NAVIGATE = 1 # Navigate to the stage page for example the commissions page or mission page NAVIGATE = 1 # Navigate to the stage page for example the commissions page or mission page
SELECT = 2 # Select the stage mode for example hard or normal in mission SELECT = 2 # Select the stage mode for example hard or normal in mission
ENTER = 3 # Search and for the stage in the stage list and enter ENTER = 3 # Search and for the stage in the stage list and enter
SWEEP = 4 # Sweep the stage SWEEP = 4 # Sweep the stage
RECHARGE = 5 # Recharge AP from other taks if they are enabled RECHARGE = 5 # Recharge AP from other taks if they are enabled
FINISH = -1 # Inidicate termination of Mission module FINISH = -1 # Inidicate termination of Mission module
class Mission(MissionUI, CommissionsUI): class Mission(MissionUI, CommissionsUI):
@ -84,7 +84,7 @@ class Mission(MissionUI, CommissionsUI):
logger.error("Failed to read configuration file") logger.error("Failed to read configuration file")
finally: finally:
return queue return queue
def check_reset_daily(self): def check_reset_daily(self):
# Check if it's time to reset the queue # Check if it's time to reset the queue
if self.reset_daily: if self.reset_daily:
@ -110,13 +110,13 @@ class Mission(MissionUI, CommissionsUI):
return True return True
return False return False
@property @property
def valid_task(self) -> list: def valid_task(self) -> list:
task = self.mission_info task = self.mission_info
if not task: if not task:
logger.warning('Mission enabled but no task set') logger.warning('Mission enabled but no task set')
#self.error_handler() # self.error_handler()
return task return task
@property @property
@ -131,12 +131,12 @@ class Mission(MissionUI, CommissionsUI):
def current_count(self): def current_count(self):
if self.current_mode == "H" and self.task[0][2] > 3: if self.current_mode == "H" and self.task[0][2] > 3:
return 3 return 3
return self.task[0][2] return self.task[0][2]
@current_count.setter @current_count.setter
def current_count(self, value): def current_count(self, value):
self.task[0][2] = value self.task[0][2] = value
def select(self) -> bool: def select(self) -> bool:
""" """
A wrapper method to select the current_mode A wrapper method to select the current_mode
@ -154,7 +154,7 @@ class Mission(MissionUI, CommissionsUI):
else: else:
logger.error("Uknown mode") logger.error("Uknown mode")
return False return False
def get_realistic_count(self) -> int: def get_realistic_count(self) -> int:
""" """
Calculate the possible number of sweeps based on the current AP Calculate the possible number of sweeps based on the current AP
@ -196,11 +196,12 @@ class Mission(MissionUI, CommissionsUI):
Check if AP related modules such as cafe, circle, task, mail are enabled and run them if they are. Check if AP related modules such as cafe, circle, task, mail are enabled and run them if they are.
task_call only works after the current task is finished so is not suitable. task_call only works after the current task is finished so is not suitable.
""" """
cafe_reward = self.config.cross_get(["Cafe", "Scheduler", "Enable"]) and self.config.cross_get(["Cafe", "Cafe", "Reward"]) cafe_reward = self.config.cross_get(["Cafe", "Scheduler", "Enable"]) and self.config.cross_get(
["Cafe", "Cafe", "Reward"])
circle = self.config.cross_get(["Circle", "Scheduler", "Enable"]) circle = self.config.cross_get(["Circle", "Scheduler", "Enable"])
task = self.config.cross_get(["Task", "Scheduler", "Enable"]) task = self.config.cross_get(["Task", "Scheduler", "Enable"])
mail = self.config.cross_get(["Mail", "Scheduler", "Enable"]) mail = self.config.cross_get(["Mail", "Scheduler", "Enable"])
ap_tasks = [(cafe_reward,Cafe), (circle, Circle), (task, Task), (mail, Mail)] ap_tasks = [(cafe_reward, Cafe), (circle, Circle), (task, Task), (mail, Mail)]
modules = [x[1] for x in ap_tasks if x[0]] modules = [x[1] for x in ap_tasks if x[0]]
if not modules: if not modules:
logger.info("Recharge AP was enabled but no AP related modules were enabled") logger.info("Recharge AP was enabled but no AP related modules were enabled")
@ -208,7 +209,7 @@ class Mission(MissionUI, CommissionsUI):
for module in modules: for module in modules:
module(config=self.config, device=self.device).run() module(config=self.config, device=self.device).run()
return True return True
def handle_mission(self, status): def handle_mission(self, status):
match status: match status:
case MissionStatus.AP: case MissionStatus.AP:
@ -216,13 +217,13 @@ class Mission(MissionUI, CommissionsUI):
return MissionStatus.FINISH return MissionStatus.FINISH
self.realistic_count = self.get_realistic_count() self.realistic_count = self.get_realistic_count()
if self.realistic_count == 0 and self.recharge_AP: if self.realistic_count == 0 and self.recharge_AP:
self.recharge_AP = False self.recharge_AP = False
return MissionStatus.RECHARGE return MissionStatus.RECHARGE
elif self.realistic_count == 0 and not self.recharge_AP: elif self.realistic_count == 0 and not self.recharge_AP:
return MissionStatus.FINISH return MissionStatus.FINISH
else: else:
return MissionStatus.NAVIGATE return MissionStatus.NAVIGATE
case MissionStatus.NAVIGATE: case MissionStatus.NAVIGATE:
self.navigate(self.previous_mode, self.current_mode) self.navigate(self.previous_mode, self.current_mode)
return MissionStatus.SELECT return MissionStatus.SELECT
case MissionStatus.SELECT: case MissionStatus.SELECT:
@ -241,7 +242,7 @@ class Mission(MissionUI, CommissionsUI):
self.update_task() self.update_task()
else: else:
self.update_task(failure=True) self.update_task(failure=True)
return MissionStatus.AP return MissionStatus.AP
case MissionStatus.RECHARGE: case MissionStatus.RECHARGE:
if self.recharge(): if self.recharge():
DataUpdate(config=self.config, device=self.device).run() DataUpdate(config=self.config, device=self.device).run()
@ -261,10 +262,10 @@ class Mission(MissionUI, CommissionsUI):
if self.task: if self.task:
action_timer = Timer(0.5, 1) action_timer = Timer(0.5, 1)
status = MissionStatus.AP status = MissionStatus.AP
"""Update the dashboard to accurately calculate AP""" """Update the dashboard to accurately calculate AP"""
DataUpdate(config=self.config, device=self.device).run() DataUpdate(config=self.config, device=self.device).run()
while 1: while 1:
self.device.screenshot() self.device.screenshot()
@ -277,7 +278,6 @@ class Mission(MissionUI, CommissionsUI):
if status == MissionStatus.FINISH: if status == MissionStatus.FINISH:
break break
# delay mission to 7 hours if there are still stages in the queue # delay mission to 7 hours if there are still stages in the queue
self.config.task_delay(minute=420) if self.task else self.config.task_delay(server_update=True) self.config.task_delay(minute=420) if self.task else self.config.task_delay(server_update=True)

View File

@ -1,9 +1,9 @@
from module.base.timer import Timer from module.base.timer import Timer
from module.logger import logger from module.logger import logger
from module.ui.switch import Switch
from module.ocr.ocr import Digit from module.ocr.ocr import Digit
from module.ui.switch import Switch
from tasks.base.assets.assets_base_page import BACK, MISSION_CHECK, EVENT_CHECK, WORK_GO_TO_EVENT from tasks.base.assets.assets_base_page import BACK, MISSION_CHECK, EVENT_CHECK, WORK_GO_TO_EVENT
from tasks.base.page import page_mission, page_commissions, page_work #,page_event from tasks.base.page import page_mission, page_commissions, page_work # ,page_event
from tasks.base.ui import UI from tasks.base.ui import UI
from tasks.mission.assets.assets_mission import * from tasks.mission.assets.assets_mission import *
from tasks.stage.ap import AP from tasks.stage.ap import AP
@ -13,7 +13,7 @@ from tasks.stage.sweep import StageSweep
SHARED_LIST = StageList('SharedList') SHARED_LIST = StageList('SharedList')
EVENT_LIST = StageList('EventList', EVENT_LIST, EVENT_INDEX, EVENT_ITEM, button_stars=EVENT_STARS) EVENT_LIST = StageList('EventList', EVENT_LIST, EVENT_INDEX, EVENT_ITEM, button_stars=EVENT_STARS)
SHARED_SWEEP = StageSweep('MissionSweep', 99) SHARED_SWEEP = StageSweep('MissionSweep', 99)
SHARED_SWEEP.set_button(button_check=CHECK_MISSION_SWEEP) # Check sweep is different for mission, event SHARED_SWEEP.set_button(button_check=CHECK_MISSION_SWEEP) # Check sweep is different for mission, event
COMMISSIONS_SWEEP = StageSweep('CommissionsSweep', 99) COMMISSIONS_SWEEP = StageSweep('CommissionsSweep', 99)
SWITCH_NORMAL = Switch("Normal_switch") SWITCH_NORMAL = Switch("Normal_switch")
@ -25,8 +25,8 @@ SWITCH_HARD.add_state("on", HARD_ON)
SWITCH_HARD.add_state("off", HARD_OFF) SWITCH_HARD.add_state("off", HARD_OFF)
SWITCH_QUEST = Switch("QUEST_switch") SWITCH_QUEST = Switch("QUEST_switch")
SWITCH_QUEST.add_state("on",QUEST_ON) SWITCH_QUEST.add_state("on", QUEST_ON)
SWITCH_QUEST.add_state("off",QUEST_OFF) SWITCH_QUEST.add_state("off", QUEST_OFF)
""" """
A dictionary that maps the mode to a tuple where A dictionary that maps the mode to a tuple where
@ -38,7 +38,7 @@ MODE_TO_PAGE = {
"H": (MISSION_CHECK, page_mission), "H": (MISSION_CHECK, page_mission),
"XP": (CHECK_XP, page_commissions), "XP": (CHECK_XP, page_commissions),
"CR": (CHECK_CR, page_commissions), "CR": (CHECK_CR, page_commissions),
"E" : (EVENT_CHECK, None) #page_event "E": (EVENT_CHECK, None) # page_event
} }
@ -49,7 +49,7 @@ class MissionUI(UI, AP):
if self.select_area(area) and self.select_mode(switch): if self.select_area(area) and self.select_mode(switch):
return True return True
return False return False
def select_area(self, num): def select_area(self, num):
"""" """"
May require further error handling for these cases. May require further error handling for these cases.
@ -67,9 +67,9 @@ class MissionUI(UI, AP):
if current_area == num: if current_area == num:
return True return True
elif current_area > num: elif current_area > num:
[self.click_with_interval(LEFT, interval=1) for x in range(abs(current_area-num))] [self.click_with_interval(LEFT, interval=1) for x in range(abs(current_area - num))]
elif current_area < num: elif current_area < num:
[self.click_with_interval(RIGHT, interval=1) for x in range(abs(current_area-num))] [self.click_with_interval(RIGHT, interval=1) for x in range(abs(current_area - num))]
except: except:
tries += 1 tries += 1
if tries > 3: if tries > 3:
@ -107,12 +107,12 @@ class MissionUI(UI, AP):
For example, "N" and "H" are in Mission so we call go_back. For example, "N" and "H" are in Mission so we call go_back.
If different, ui_ensure is called for example, "N" and "IR". If different, ui_ensure is called for example, "N" and "IR".
""" """
if prev==next or (prev in ["N", "H"] and next in ["N", "H"]): if prev == next or (prev in ["N", "H"] and next in ["N", "H"]):
self.go_back(MODE_TO_PAGE[next][0]) self.go_back(MODE_TO_PAGE[next][0])
elif prev in ["XP", "CR"] and next in ["XP", "CR"]: elif prev in ["XP", "CR"] and next in ["XP", "CR"]:
self.go_back(CHECK_COMMISSIONS) self.go_back(CHECK_COMMISSIONS)
else: else:
self.goto_event() if next == "E" else self.ui_ensure(MODE_TO_PAGE[next][1]) self.goto_event() if next == "E" else self.ui_ensure(MODE_TO_PAGE[next][1])
def go_back(self, check): def go_back(self, check):
while 1: while 1:
@ -132,12 +132,14 @@ class MissionUI(UI, AP):
if self.appear(EVENT_CHECK): if self.appear(EVENT_CHECK):
break break
self.appear_then_click(WORK_GO_TO_EVENT) self.appear_then_click(WORK_GO_TO_EVENT)
self.device.swipe((40,160), (260, 40)) self.device.swipe((40, 160), (260, 40))
while not timer.reached_and_reset(): while not timer.reached_and_reset():
pass pass
class CommissionsUI(UI, AP): class CommissionsUI(UI, AP):
"""Works the same way as select_bounty""" """Works the same way as select_bounty"""
def select_commission(self, mode): def select_commission(self, mode):
if mode == "CR": if mode == "CR":
dest_enter, dest_check = SELECT_CR, CHECK_CR dest_enter, dest_check = SELECT_CR, CHECK_CR

View File

@ -2,9 +2,9 @@ from enum import Enum
from module.base.timer import Timer from module.base.timer import Timer
from module.logger import logger from module.logger import logger
from tasks.tactical_challenge.assets.assets_tactical_challenge import *
from tasks.momotalk.ui import MomoTalkUI from tasks.momotalk.ui import MomoTalkUI
class MomoTalkStatus(Enum): class MomoTalkStatus(Enum):
OPEN = 0 OPEN = 0
SORT = 1 SORT = 1
@ -13,6 +13,7 @@ class MomoTalkStatus(Enum):
STORY = 4 STORY = 4
FINISHED = -1 FINISHED = -1
class MomoTalk(MomoTalkUI): class MomoTalk(MomoTalkUI):
def handle_momotalk(self, status): def handle_momotalk(self, status):
match status: match status:
@ -26,16 +27,16 @@ class MomoTalk(MomoTalkUI):
case MomoTalkStatus.CHECK: case MomoTalkStatus.CHECK:
if self.check_first_student(): if self.check_first_student():
return MomoTalkStatus.CHAT return MomoTalkStatus.CHAT
return MomoTalkStatus.FINISHED return MomoTalkStatus.FINISHED
case MomoTalkStatus.CHAT: case MomoTalkStatus.CHAT:
if self.chat(): if self.chat():
return MomoTalkStatus.STORY return MomoTalkStatus.STORY
return MomoTalkStatus.OPEN return MomoTalkStatus.OPEN
case MomoTalkStatus.STORY: case MomoTalkStatus.STORY:
if self.skip_story(): if self.skip_story():
return MomoTalkStatus.CHAT return MomoTalkStatus.CHAT
case MomoTalkStatus.FINISHED: case MomoTalkStatus.FINISHED:
return status return status
case _: case _:
logger.warning(f'Invalid status: {status}') logger.warning(f'Invalid status: {status}')
return status return status
@ -58,4 +59,3 @@ class MomoTalk(MomoTalkUI):
break break
self.config.task_delay(server_update=True) self.config.task_delay(server_update=True)

View File

@ -28,6 +28,7 @@ REPLY_TEMPLATE = REPLY.matched_button.image
STORY_TEMPLATE = STORY.matched_button.image STORY_TEMPLATE = STORY.matched_button.image
CHATTING_TEMPLATE = CHATTING.matched_button.image CHATTING_TEMPLATE = CHATTING.matched_button.image
class MomoTalkUI(UI): class MomoTalkUI(UI):
def __init__(self, config, device): def __init__(self, config, device):
super().__init__(config, device) super().__init__(config, device)
@ -81,7 +82,7 @@ class MomoTalkUI(UI):
switch.set(state, main=self) switch.set(state, main=self)
return True return True
def click_all(self, template, x_add=0, y_add=0): def click_all(self, template, x_add=0, y_add=0):
""" """
Find the all the locations of the template adding an offset if specified and click them. Find the all the locations of the template adding an offset if specified and click them.
@ -116,7 +117,7 @@ class MomoTalkUI(UI):
return True return True
logger.warning("No students available for interaction") logger.warning("No students available for interaction")
return False return False
def sort_messages(self): def sort_messages(self):
""" """
Switch from newest to unread and sort the messages in descending order Switch from newest to unread and sort the messages in descending order
@ -140,7 +141,7 @@ class MomoTalkUI(UI):
return True return True
logger.warning("No students available for interaction") logger.warning("No students available for interaction")
return False return False
def chat(self): def chat(self):
""" """
Waits for the chat area to be stable and then Waits for the chat area to be stable and then
@ -164,8 +165,8 @@ class MomoTalkUI(UI):
timer.reset() timer.reset()
elif timer.reached(): elif timer.reached():
logger.info("No new message detected") logger.info("No new message detected")
return False return False
def skip_story(self): def skip_story(self):
""" """
Skip story by executing a series of steps. Returns True if the confirm skip Skip story by executing a series of steps. Returns True if the confirm skip
@ -184,5 +185,3 @@ class MomoTalkUI(UI):
while not timer.reached_and_reset(): while not timer.reached_and_reset():
pass pass
break break

View File

@ -1,14 +1,14 @@
import re
from enum import Flag from enum import Flag
from module.base.timer import Timer from module.base.timer import Timer
from module.exception import RequestHumanTakeover from module.exception import RequestHumanTakeover
from module.logger import logger from module.logger import logger
from tasks.base.assets.assets_base_page import BACK from tasks.base.assets.assets_base_page import BACK
from tasks.base.assets.assets_base_page import SCHEDULE_CHECK
from tasks.base.page import page_schedule from tasks.base.page import page_schedule
from tasks.schedule.ui import ScheduleUI from tasks.schedule.ui import ScheduleUI
from tasks.base.assets.assets_base_page import SCHEDULE_CHECK
import re
class ScheduleStatus(Flag): class ScheduleStatus(Flag):
OCR = 0 OCR = 0
@ -18,7 +18,7 @@ class ScheduleStatus(Flag):
FINISH = 4 FINISH = 4
class Schedule(ScheduleUI): class Schedule(ScheduleUI):
@property @property
def schedule_info(self): def schedule_info(self):
info = [] info = []
@ -28,7 +28,8 @@ class Schedule(ScheduleUI):
for choice in choices: for choice in choices:
location, classrooms = schedule_config[choice]["Location"], schedule_config[choice]["Classrooms"] location, classrooms = schedule_config[choice]["Location"], schedule_config[choice]["Classrooms"]
if location == "None" or not classrooms or (isinstance(classrooms, str) and classrooms.replace(" ", "") == ""): if location == "None" or not classrooms or (
isinstance(classrooms, str) and classrooms.replace(" ", "") == ""):
continue continue
elif isinstance(classrooms, int): elif isinstance(classrooms, int):
classrooms_list = [str(classrooms)] classrooms_list = [str(classrooms)]
@ -39,7 +40,7 @@ class Schedule(ScheduleUI):
classrooms_list = [] classrooms_list = []
# tried to convert to set to remove duplicates but doesn't maintain order # tried to convert to set to remove duplicates but doesn't maintain order
[classrooms_list.append(x) for x in classrooms if x not in classrooms_list] [classrooms_list.append(x) for x in classrooms if x not in classrooms_list]
if self.valid_classroom(classrooms_list): if self.valid_classroom(classrooms_list):
info.append([location, classrooms_list]) info.append([location, classrooms_list])
else: else:
@ -57,7 +58,7 @@ class Schedule(ScheduleUI):
if not 1 <= int(classroom) <= 9: if not 1 <= int(classroom) <= 9:
return False return False
return True return True
@property @property
def valid_task(self) -> list: def valid_task(self) -> list:
task = self.schedule_info task = self.schedule_info
@ -131,4 +132,4 @@ class Schedule(ScheduleUI):
if status == ScheduleStatus.FINISH: if status == ScheduleStatus.FINISH:
break break
self.config.task_delay(server_update=True) self.config.task_delay(server_update=True)

View File

@ -3,8 +3,8 @@ Original Author: sanmusen214(https://github.com/sanmusen214)
Adapted from https://github.com/sanmusen214/BAAH/blob/1.2/modules/AllTask/SubTask/ScrollSelect.py Adapted from https://github.com/sanmusen214/BAAH/blob/1.2/modules/AllTask/SubTask/ScrollSelect.py
""" """
from module.logger import logger
from module.base.timer import Timer from module.base.timer import Timer
from module.logger import logger
class ScrollSelect: class ScrollSelect:
@ -30,7 +30,9 @@ class ScrollSelect:
finalclick: bool finalclick: bool
Whether to click on clickx and the last row after the sliding ends Whether to click on clickx and the last row after the sliding ends
""" """
def __init__(self, window_button, first_item_button, expected_button, clickx, swipeoffsetx=-100, finalclick=True) -> None:
def __init__(self, window_button, first_item_button, expected_button, clickx, swipeoffsetx=-100,
finalclick=True) -> None:
# TODO: Actually, only concerned about the height of one element, completely displaying the Y of the first button, completely displaying the Y of the bottom button, the number of complete elements that the window can contain, the height of the last element in the window, and the left offset and response distance. # TODO: Actually, only concerned about the height of one element, completely displaying the Y of the first button, completely displaying the Y of the bottom button, the number of complete elements that the window can contain, the height of the last element in the window, and the left offset and response distance.
self.window_starty = window_button.area[1] self.window_starty = window_button.area[1]
self.window_endy = window_button.area[3] self.window_endy = window_button.area[3]
@ -54,8 +56,9 @@ class ScrollSelect:
main.device.swipe((x1, y1), (x1, y1 - (distance + responsey)), duration=2) main.device.swipe((x1, y1), (x1, y1 - (distance + responsey)), duration=2)
else: else:
# Effective swipe distance for the Chinese server is 60 # Effective swipe distance for the Chinese server is 60
main.device.swipe((x1, y1), (x1, int(y1 - (distance + responsey - 4 * (1 + distance / 100)))), duration=1 + distance / 100) main.device.swipe((x1, y1), (x1, int(y1 - (distance + responsey - 4 * (1 + distance / 100)))),
duration=1 + distance / 100)
def select_location(self, main, target_index) -> None: def select_location(self, main, target_index) -> None:
click_coords = main.device.click_methods.get(main.config.Emulator_ControlMethod, main.device.click_adb) click_coords = main.device.click_methods.get(main.config.Emulator_ControlMethod, main.device.click_adb)
logger.info("Scroll and select the {}-th level".format(target_index + 1)) logger.info("Scroll and select the {}-th level".format(target_index + 1))
@ -75,9 +78,9 @@ class ScrollSelect:
# Center point of the target element # Center point of the target element
target_center_y = start_center_y + self.itemheight * target_index target_center_y = start_center_y + self.itemheight * target_index
self.run_until(main, self.run_until(main,
lambda: click_coords(self.clickx, target_center_y), lambda: click_coords(self.clickx, target_center_y),
lambda: main.appear(self.expected_button), lambda: main.appear(self.expected_button),
) )
else: else:
# Start scrolling from the gap in the middle of the levels # Start scrolling from the gap in the middle of the levels
scroll_start_from_y = self.window_endy - self.itemheight // 2 scroll_start_from_y = self.window_endy - self.itemheight // 2
@ -86,7 +89,8 @@ class ScrollSelect:
scrolltotal_distance = (target_index - itemcount) * self.itemheight + hiddenlastitemheight scrolltotal_distance = (target_index - itemcount) * self.itemheight + hiddenlastitemheight
logger.info("Height hidden by the last element: %d" % hiddenlastitemheight) logger.info("Height hidden by the last element: %d" % hiddenlastitemheight)
# First, slide up the hidden part, add a little distance to let the system recognize it as a swipe event # First, slide up the hidden part, add a little distance to let the system recognize it as a swipe event
self.compute_swipe(main, self.clickx + self.swipeoffsetx, scroll_start_from_y, hiddenlastitemheight, self.responsey) self.compute_swipe(main, self.clickx + self.swipeoffsetx, scroll_start_from_y, hiddenlastitemheight,
self.responsey)
logger.info(f"Swipe distance: {hiddenlastitemheight}") logger.info(f"Swipe distance: {hiddenlastitemheight}")
# Update scrolltotal_distance # Update scrolltotal_distance
scrolltotal_distance -= hiddenlastitemheight scrolltotal_distance -= hiddenlastitemheight
@ -97,18 +101,20 @@ class ScrollSelect:
else: else:
scroll_distance = (itemcount - 1) * self.itemheight scroll_distance = (itemcount - 1) * self.itemheight
while scroll_distance <= scrolltotal_distance: while scroll_distance <= scrolltotal_distance:
self.compute_swipe(main, self.clickx + self.swipeoffsetx, scroll_start_from_y, scroll_distance, self.responsey) self.compute_swipe(main, self.clickx + self.swipeoffsetx, scroll_start_from_y, scroll_distance,
self.responsey)
scrolltotal_distance -= scroll_distance scrolltotal_distance -= scroll_distance
if scrolltotal_distance > 5: if scrolltotal_distance > 5:
# Last slide # Last slide
self.compute_swipe(main, self.clickx + self.swipeoffsetx, scroll_start_from_y, scrolltotal_distance, self.responsey) self.compute_swipe(main, self.clickx + self.swipeoffsetx, scroll_start_from_y, scrolltotal_distance,
self.responsey)
if self.finalclick: if self.finalclick:
# Click on the last row # Click on the last row
self.run_until(main, self.run_until(main,
lambda: click_coords(self.clickx, self.window_endy - self.itemheight // 2), lambda: click_coords(self.clickx, self.window_endy - self.itemheight // 2),
lambda: main.appear(self.expected_button) lambda: main.appear(self.expected_button)
) )
def run_until(self, main, func1, func2, times=6, sleeptime=1.5) -> bool: def run_until(self, main, func1, func2, times=6, sleeptime=1.5) -> bool:
""" """
Repeat the execution of func1 up to a maximum of times or until func2 evaluates to True. Repeat the execution of func1 up to a maximum of times or until func2 evaluates to True.
@ -146,4 +152,3 @@ class ScrollSelect:
timer = Timer(0.5).start() timer = Timer(0.5).start()
while not timer.reached_and_reset(): while not timer.reached_and_reset():
pass pass

View File

@ -1,17 +1,19 @@
from module.base.timer import Timer import numpy as np
from module.base.decorator import Config from module.base.decorator import Config
from module.base.timer import Timer
from module.logger import logger from module.logger import logger
from module.ocr.ocr import DigitCounter from module.ocr.ocr import DigitCounter
from tasks.base.ui import UI
from tasks.base.assets.assets_base_page import SCHEDULE_CHECK from tasks.base.assets.assets_base_page import SCHEDULE_CHECK
from tasks.base.ui import UI
from tasks.schedule.assets.assets_schedule import * from tasks.schedule.assets.assets_schedule import *
from tasks.schedule.scroll_select import ScrollSelect from tasks.schedule.scroll_select import ScrollSelect
import numpy as np
SCROLL_SELECT = ScrollSelect(window_button=SCROLL, first_item_button=FIRST_ITEM, expected_button=LOCATIONS, clickx=1116) SCROLL_SELECT = ScrollSelect(window_button=SCROLL, first_item_button=FIRST_ITEM, expected_button=LOCATIONS, clickx=1116)
xs = np.linspace(299, 995, 3, dtype=int) xs = np.linspace(299, 995, 3, dtype=int)
ys = np.linspace(268, 573, 3, dtype=int) ys = np.linspace(268, 573, 3, dtype=int)
class ScheduleUI(UI): class ScheduleUI(UI):
@Config.when(Emulator_GameLanguage='jp') @Config.when(Emulator_GameLanguage='jp')
def set_clickx(self): def set_clickx(self):
@ -20,7 +22,7 @@ class ScheduleUI(UI):
@Config.when(Emulator_GameLanguage=None) @Config.when(Emulator_GameLanguage=None)
def set_clickx(self): def set_clickx(self):
pass pass
def select_then_check(self, dest_enter: ButtonWrapper, dest_check: ButtonWrapper): def select_then_check(self, dest_enter: ButtonWrapper, dest_check: ButtonWrapper):
timer = Timer(8, 10).start() timer = Timer(8, 10).start()
while 1: while 1:
@ -30,10 +32,10 @@ class ScheduleUI(UI):
timer.reset() timer.reset()
if self.appear(dest_check): if self.appear(dest_check):
return True return True
if timer.reached(): if timer.reached():
return False return False
def click_then_check(self, coords, dest_check: ButtonWrapper): def click_then_check(self, coords, dest_check: ButtonWrapper):
click_coords = self.device.click_methods.get(self.config.Emulator_ControlMethod, self.device.click_adb) click_coords = self.device.click_methods.get(self.config.Emulator_ControlMethod, self.device.click_adb)
timer = Timer(3, 2).start() timer = Timer(3, 2).start()
@ -47,14 +49,14 @@ class ScheduleUI(UI):
pass pass
if timer.reached(): if timer.reached():
return False return False
def enter_location(self, location): def enter_location(self, location):
SCROLL_SELECT.select_location(self, location) SCROLL_SELECT.select_location(self, location)
if not self.appear(LOCATIONS): if not self.appear(LOCATIONS):
logger.error("Unable to navigate to page for location {}".format(location + 1)) logger.error("Unable to navigate to page for location {}".format(location + 1))
return False return False
return self.select_then_check(LOCATIONS, LOCATIONS_POPUP) return self.select_then_check(LOCATIONS, LOCATIONS_POPUP)
def select_classrooms(self, ticket, classrooms): def select_classrooms(self, ticket, classrooms):
for classroom in classrooms: for classroom in classrooms:
if ticket == 0: if ticket == 0:
@ -86,5 +88,5 @@ class ScheduleUI(UI):
logger.warning('Invalid ticket') logger.warning('Invalid ticket')
return False return False
logger.attr('ScheduleTicket', ticket) logger.attr('ScheduleTicket', ticket)
#self.config.stored.BountyTicket.set(ticket) # self.config.stored.BountyTicket.set(ticket)
return ticket return ticket

View File

@ -1,7 +1,6 @@
from enum import Flag from enum import Flag
from module.base.timer import Timer from module.base.timer import Timer
from module.exception import RequestHumanTakeover
from module.logger import logger from module.logger import logger
from module.ui.switch import Switch from module.ui.switch import Switch
from tasks.base.assets.assets_base_page import BACK from tasks.base.assets.assets_base_page import BACK
@ -18,6 +17,7 @@ class ShopStatus(Flag):
END = 4 END = 4
FINISH = -1 FINISH = -1
class Shop(ShopUI): class Shop(ShopUI):
@property @property
def shop_info(self): def shop_info(self):
@ -58,7 +58,7 @@ class Shop(ShopUI):
@property @property
def current_purchase_count(self): def current_purchase_count(self):
return self.task[0][1] return self.task[0][1]
@property @property
def current_item_list(self): def current_item_list(self):
return self.task[0][2] return self.task[0][2]

View File

@ -1,7 +1,7 @@
import numpy as np import numpy as np
from module.base.timer import Timer
from module.base.base import ModuleBase from module.base.base import ModuleBase
from module.base.timer import Timer
from module.base.utils import area_size from module.base.utils import area_size
from module.logger import logger from module.logger import logger
from module.ocr.ocr import DigitCounter from module.ocr.ocr import DigitCounter
@ -16,13 +16,14 @@ ITEM_POSITIONS = {
17: (650, 460), 18: (805, 460), 19: (960, 460), 20: (1110, 460), 17: (650, 460), 18: (805, 460), 19: (960, 460), 20: (1110, 460),
} }
class ShopUI(UI): class ShopUI(UI):
def __init__(self, config, device): def __init__(self, config, device):
super().__init__(config, device) super().__init__(config, device)
self.click_coords = self.device.click_methods.get(self.config.Emulator_ControlMethod, self.device.click_adb) self.click_coords = self.device.click_methods.get(self.config.Emulator_ControlMethod, self.device.click_adb)
self.swipe_vector_range = (0.85, 0.9) self.swipe_vector_range = (0.85, 0.9)
self.swipe_flags = {8:False, 16: False} self.swipe_flags = {8: False, 16: False}
self.list = ITEM_LIST self.list = ITEM_LIST
def swipe_page(self, direction: str, main: ModuleBase, vector_range=None, reverse=False): def swipe_page(self, direction: str, main: ModuleBase, vector_range=None, reverse=False):
@ -71,7 +72,7 @@ class ShopUI(UI):
shop_switch.set('on', main=self) shop_switch.set('on', main=self)
return True return True
def select_items(self, item_list): def select_items(self, item_list):
""" """
Select items in the item list checking if swipe is required each time. Select items in the item list checking if swipe is required each time.
@ -89,7 +90,7 @@ class ShopUI(UI):
) )
while not timer.reached_and_reset(): while not timer.reached_and_reset():
pass pass
self.click_coords(*ITEM_POSITIONS[item]) self.click_coords(*ITEM_POSITIONS[item])
def should_swipe(self, item): def should_swipe(self, item):
""" """
@ -104,12 +105,13 @@ class ShopUI(UI):
self.swipe_flags[16] = True self.swipe_flags[16] = True
return True return True
return False return False
def reset_swipe_flags(self): def reset_swipe_flags(self):
self.swipe_flags[8], self.swipe_flags[16] = False, False self.swipe_flags[8], self.swipe_flags[16] = False, False
def make_purchase(self): def make_purchase(self):
if self.match_color(PURCHASE) and self.select_then_check(PURCHASE, CONFIRM_PURCHASE) and self.appear_then_click(CONFIRM_PURCHASE): if self.match_color(PURCHASE) and self.select_then_check(PURCHASE, CONFIRM_PURCHASE) and self.appear_then_click(
CONFIRM_PURCHASE):
return True return True
logger.warning("No items were selected. Unable to purchase.") logger.warning("No items were selected. Unable to purchase.")
return False return False
@ -125,7 +127,7 @@ class ShopUI(UI):
logger.info("Refreshed the shop") logger.info("Refreshed the shop")
return True return True
return False return False
def get_refresh_count(self): def get_refresh_count(self):
if not self.select_then_check(REFRESH, CONFIRM_REFRESH): if not self.select_then_check(REFRESH, CONFIRM_REFRESH):
logger.warning('OCR failed due to invalid page') logger.warning('OCR failed due to invalid page')
@ -135,4 +137,3 @@ class ShopUI(UI):
logger.warning('Invalid count') logger.warning('Invalid count')
return False return False
return count return count

View File

@ -36,7 +36,7 @@ class TacticalChallenge(TacticalChallengeUI):
if not select: if not select:
return random.choice(self.select_players) return random.choice(self.select_players)
else: else:
return self.select_players[select-1] return self.select_players[select - 1]
def _handle_challenge(self, status): def _handle_challenge(self, status):
match status: match status: