mirror of
https://github.com/TheFunny/ArisuAutoSweeper
synced 2025-12-16 11:15:13 +00:00
style: format
This commit is contained in:
parent
e5f91e0c0a
commit
e6a3b79733
@ -1,7 +1,7 @@
|
||||
from module.base.base import ModuleBase
|
||||
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_popup import *
|
||||
|
||||
|
||||
class PopupHandler(ModuleBase):
|
||||
@ -111,16 +111,15 @@ class PopupHandler(ModuleBase):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def handle_level_up(self, interval=5) -> bool:
|
||||
if self.appear_then_click(LEVEL_UP, interval=interval):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def handle_quit(self, interval=5) -> bool:
|
||||
if self.appear_then_click(QUIT, interval=interval):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@ -5,10 +5,10 @@ from module.base.utils import get_color
|
||||
from module.exception import GameNotRunningError, GamePageUnknownError, RequestHumanTakeover
|
||||
from module.logger import logger
|
||||
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.page import Page, page_main
|
||||
from tasks.login.assets.assets_login import LOGIN_LOADING, OCR_YEAR
|
||||
from tasks.base.assets.assets_base_page import BACK
|
||||
|
||||
|
||||
class UI(MainPage):
|
||||
@ -24,7 +24,7 @@ class UI(MainPage):
|
||||
def appear_trademark_year(self):
|
||||
ocr_year = Digit(OCR_YEAR).ocr_single_line(self.device.image)
|
||||
return ocr_year == 2021
|
||||
|
||||
|
||||
def ui_page_appear(self, page):
|
||||
"""
|
||||
Args:
|
||||
@ -132,7 +132,7 @@ class UI(MainPage):
|
||||
self.interval_clear(list(Page.iter_check_buttons()))
|
||||
|
||||
# loading_timer = Timer(0.5)
|
||||
back_timer = Timer(15,15)
|
||||
back_timer = Timer(15, 15)
|
||||
logger.hr(f"UI goto {destination}")
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
@ -190,7 +190,6 @@ class UI(MainPage):
|
||||
self.device.back()
|
||||
logger.info("Unknown page, try to back")
|
||||
back_timer.reset()
|
||||
|
||||
|
||||
# Reset connection
|
||||
Page.clear_connection()
|
||||
@ -388,11 +387,11 @@ class UI(MainPage):
|
||||
return True
|
||||
# disabled because will exit the game if quit appears
|
||||
|
||||
#if self.handle_ap_exceed():
|
||||
# if self.handle_ap_exceed():
|
||||
# return True
|
||||
#if self.handle_insufficient_inventory():
|
||||
# if self.handle_insufficient_inventory():
|
||||
# return True
|
||||
#if self.handle_item_expired():
|
||||
# if self.handle_item_expired():
|
||||
# return True
|
||||
|
||||
return False
|
||||
@ -458,4 +457,4 @@ class UI(MainPage):
|
||||
logger.error("Failed to close popup")
|
||||
raise RequestHumanTakeover
|
||||
while not wait.reached():
|
||||
pass
|
||||
pass
|
||||
|
||||
@ -18,6 +18,7 @@ class Login(UI):
|
||||
GameTooManyClickError:
|
||||
GameNotRunningError:
|
||||
"""
|
||||
|
||||
def _page_main_twice_confirm():
|
||||
if self.ui_page_appear(page_main):
|
||||
timer = Timer(1).start()
|
||||
|
||||
@ -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 math
|
||||
from filelock import FileLock
|
||||
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):
|
||||
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
|
||||
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
|
||||
SWEEP = 4 # Sweep the stage
|
||||
RECHARGE = 5 # Recharge AP from other taks if they are enabled
|
||||
FINISH = -1 # Inidicate termination of Mission module
|
||||
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
|
||||
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
|
||||
SWEEP = 4 # Sweep the stage
|
||||
RECHARGE = 5 # Recharge AP from other taks if they are enabled
|
||||
FINISH = -1 # Inidicate termination of Mission module
|
||||
|
||||
|
||||
class Mission(MissionUI, CommissionsUI):
|
||||
@ -84,7 +84,7 @@ class Mission(MissionUI, CommissionsUI):
|
||||
logger.error("Failed to read configuration file")
|
||||
finally:
|
||||
return queue
|
||||
|
||||
|
||||
def check_reset_daily(self):
|
||||
# Check if it's time to reset the queue
|
||||
if self.reset_daily:
|
||||
@ -110,13 +110,13 @@ class Mission(MissionUI, CommissionsUI):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@property
|
||||
def valid_task(self) -> list:
|
||||
task = self.mission_info
|
||||
if not task:
|
||||
logger.warning('Mission enabled but no task set')
|
||||
#self.error_handler()
|
||||
# self.error_handler()
|
||||
return task
|
||||
|
||||
@property
|
||||
@ -131,12 +131,12 @@ class Mission(MissionUI, CommissionsUI):
|
||||
def current_count(self):
|
||||
if self.current_mode == "H" and self.task[0][2] > 3:
|
||||
return 3
|
||||
return self.task[0][2]
|
||||
return self.task[0][2]
|
||||
|
||||
@current_count.setter
|
||||
def current_count(self, value):
|
||||
self.task[0][2] = value
|
||||
|
||||
|
||||
def select(self) -> bool:
|
||||
"""
|
||||
A wrapper method to select the current_mode
|
||||
@ -154,7 +154,7 @@ class Mission(MissionUI, CommissionsUI):
|
||||
else:
|
||||
logger.error("Uknown mode")
|
||||
return False
|
||||
|
||||
|
||||
def get_realistic_count(self) -> int:
|
||||
"""
|
||||
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.
|
||||
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"])
|
||||
task = self.config.cross_get(["Task", "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]]
|
||||
if not modules:
|
||||
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:
|
||||
module(config=self.config, device=self.device).run()
|
||||
return True
|
||||
|
||||
|
||||
def handle_mission(self, status):
|
||||
match status:
|
||||
case MissionStatus.AP:
|
||||
@ -216,13 +217,13 @@ class Mission(MissionUI, CommissionsUI):
|
||||
return MissionStatus.FINISH
|
||||
self.realistic_count = self.get_realistic_count()
|
||||
if self.realistic_count == 0 and self.recharge_AP:
|
||||
self.recharge_AP = False
|
||||
return MissionStatus.RECHARGE
|
||||
self.recharge_AP = False
|
||||
return MissionStatus.RECHARGE
|
||||
elif self.realistic_count == 0 and not self.recharge_AP:
|
||||
return MissionStatus.FINISH
|
||||
else:
|
||||
return MissionStatus.NAVIGATE
|
||||
case MissionStatus.NAVIGATE:
|
||||
case MissionStatus.NAVIGATE:
|
||||
self.navigate(self.previous_mode, self.current_mode)
|
||||
return MissionStatus.SELECT
|
||||
case MissionStatus.SELECT:
|
||||
@ -241,7 +242,7 @@ class Mission(MissionUI, CommissionsUI):
|
||||
self.update_task()
|
||||
else:
|
||||
self.update_task(failure=True)
|
||||
return MissionStatus.AP
|
||||
return MissionStatus.AP
|
||||
case MissionStatus.RECHARGE:
|
||||
if self.recharge():
|
||||
DataUpdate(config=self.config, device=self.device).run()
|
||||
@ -261,10 +262,10 @@ class Mission(MissionUI, CommissionsUI):
|
||||
if self.task:
|
||||
action_timer = Timer(0.5, 1)
|
||||
status = MissionStatus.AP
|
||||
|
||||
|
||||
"""Update the dashboard to accurately calculate AP"""
|
||||
DataUpdate(config=self.config, device=self.device).run()
|
||||
|
||||
|
||||
while 1:
|
||||
self.device.screenshot()
|
||||
|
||||
@ -277,7 +278,6 @@ class Mission(MissionUI, CommissionsUI):
|
||||
|
||||
if status == MissionStatus.FINISH:
|
||||
break
|
||||
|
||||
|
||||
# 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)
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
from module.base.timer import Timer
|
||||
from module.logger import logger
|
||||
from module.ui.switch import Switch
|
||||
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.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.mission.assets.assets_mission import *
|
||||
from tasks.stage.ap import AP
|
||||
@ -13,7 +13,7 @@ from tasks.stage.sweep import StageSweep
|
||||
SHARED_LIST = StageList('SharedList')
|
||||
EVENT_LIST = StageList('EventList', EVENT_LIST, EVENT_INDEX, EVENT_ITEM, button_stars=EVENT_STARS)
|
||||
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)
|
||||
|
||||
SWITCH_NORMAL = Switch("Normal_switch")
|
||||
@ -25,8 +25,8 @@ SWITCH_HARD.add_state("on", HARD_ON)
|
||||
SWITCH_HARD.add_state("off", HARD_OFF)
|
||||
|
||||
SWITCH_QUEST = Switch("QUEST_switch")
|
||||
SWITCH_QUEST.add_state("on",QUEST_ON)
|
||||
SWITCH_QUEST.add_state("off",QUEST_OFF)
|
||||
SWITCH_QUEST.add_state("on", QUEST_ON)
|
||||
SWITCH_QUEST.add_state("off", QUEST_OFF)
|
||||
|
||||
"""
|
||||
A dictionary that maps the mode to a tuple where
|
||||
@ -38,7 +38,7 @@ MODE_TO_PAGE = {
|
||||
"H": (MISSION_CHECK, page_mission),
|
||||
"XP": (CHECK_XP, 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):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def select_area(self, num):
|
||||
""""
|
||||
May require further error handling for these cases.
|
||||
@ -67,9 +67,9 @@ class MissionUI(UI, AP):
|
||||
if current_area == num:
|
||||
return True
|
||||
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:
|
||||
[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:
|
||||
tries += 1
|
||||
if tries > 3:
|
||||
@ -107,12 +107,12 @@ class MissionUI(UI, AP):
|
||||
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 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])
|
||||
elif prev in ["XP", "CR"] and next in ["XP", "CR"]:
|
||||
self.go_back(CHECK_COMMISSIONS)
|
||||
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):
|
||||
while 1:
|
||||
@ -132,12 +132,14 @@ class MissionUI(UI, AP):
|
||||
if self.appear(EVENT_CHECK):
|
||||
break
|
||||
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():
|
||||
pass
|
||||
|
||||
|
||||
class CommissionsUI(UI, AP):
|
||||
"""Works the same way as select_bounty"""
|
||||
|
||||
def select_commission(self, mode):
|
||||
if mode == "CR":
|
||||
dest_enter, dest_check = SELECT_CR, CHECK_CR
|
||||
|
||||
@ -2,9 +2,9 @@ from enum import Enum
|
||||
|
||||
from module.base.timer import Timer
|
||||
from module.logger import logger
|
||||
from tasks.tactical_challenge.assets.assets_tactical_challenge import *
|
||||
from tasks.momotalk.ui import MomoTalkUI
|
||||
|
||||
|
||||
class MomoTalkStatus(Enum):
|
||||
OPEN = 0
|
||||
SORT = 1
|
||||
@ -13,6 +13,7 @@ class MomoTalkStatus(Enum):
|
||||
STORY = 4
|
||||
FINISHED = -1
|
||||
|
||||
|
||||
class MomoTalk(MomoTalkUI):
|
||||
def handle_momotalk(self, status):
|
||||
match status:
|
||||
@ -26,16 +27,16 @@ class MomoTalk(MomoTalkUI):
|
||||
case MomoTalkStatus.CHECK:
|
||||
if self.check_first_student():
|
||||
return MomoTalkStatus.CHAT
|
||||
return MomoTalkStatus.FINISHED
|
||||
return MomoTalkStatus.FINISHED
|
||||
case MomoTalkStatus.CHAT:
|
||||
if self.chat():
|
||||
return MomoTalkStatus.STORY
|
||||
return MomoTalkStatus.OPEN
|
||||
case MomoTalkStatus.STORY:
|
||||
if self.skip_story():
|
||||
return MomoTalkStatus.CHAT
|
||||
return MomoTalkStatus.CHAT
|
||||
case MomoTalkStatus.FINISHED:
|
||||
return status
|
||||
return status
|
||||
case _:
|
||||
logger.warning(f'Invalid status: {status}')
|
||||
return status
|
||||
@ -58,4 +59,3 @@ class MomoTalk(MomoTalkUI):
|
||||
break
|
||||
|
||||
self.config.task_delay(server_update=True)
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ REPLY_TEMPLATE = REPLY.matched_button.image
|
||||
STORY_TEMPLATE = STORY.matched_button.image
|
||||
CHATTING_TEMPLATE = CHATTING.matched_button.image
|
||||
|
||||
|
||||
class MomoTalkUI(UI):
|
||||
def __init__(self, config, device):
|
||||
super().__init__(config, device)
|
||||
@ -81,7 +82,7 @@ class MomoTalkUI(UI):
|
||||
switch.set(state, main=self)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
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.
|
||||
@ -116,7 +117,7 @@ class MomoTalkUI(UI):
|
||||
return True
|
||||
logger.warning("No students available for interaction")
|
||||
return False
|
||||
|
||||
|
||||
def sort_messages(self):
|
||||
"""
|
||||
Switch from newest to unread and sort the messages in descending order
|
||||
@ -140,7 +141,7 @@ class MomoTalkUI(UI):
|
||||
return True
|
||||
logger.warning("No students available for interaction")
|
||||
return False
|
||||
|
||||
|
||||
def chat(self):
|
||||
"""
|
||||
Waits for the chat area to be stable and then
|
||||
@ -164,8 +165,8 @@ class MomoTalkUI(UI):
|
||||
timer.reset()
|
||||
elif timer.reached():
|
||||
logger.info("No new message detected")
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
def skip_story(self):
|
||||
"""
|
||||
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():
|
||||
pass
|
||||
break
|
||||
|
||||
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import re
|
||||
from enum import Flag
|
||||
|
||||
from module.base.timer import Timer
|
||||
from module.exception import RequestHumanTakeover
|
||||
from module.logger import logger
|
||||
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.schedule.ui import ScheduleUI
|
||||
from tasks.base.assets.assets_base_page import SCHEDULE_CHECK
|
||||
|
||||
import re
|
||||
|
||||
class ScheduleStatus(Flag):
|
||||
OCR = 0
|
||||
@ -18,7 +18,7 @@ class ScheduleStatus(Flag):
|
||||
FINISH = 4
|
||||
|
||||
|
||||
class Schedule(ScheduleUI):
|
||||
class Schedule(ScheduleUI):
|
||||
@property
|
||||
def schedule_info(self):
|
||||
info = []
|
||||
@ -28,7 +28,8 @@ class Schedule(ScheduleUI):
|
||||
|
||||
for choice in choices:
|
||||
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
|
||||
elif isinstance(classrooms, int):
|
||||
classrooms_list = [str(classrooms)]
|
||||
@ -39,7 +40,7 @@ class Schedule(ScheduleUI):
|
||||
classrooms_list = []
|
||||
# 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]
|
||||
|
||||
|
||||
if self.valid_classroom(classrooms_list):
|
||||
info.append([location, classrooms_list])
|
||||
else:
|
||||
@ -57,7 +58,7 @@ class Schedule(ScheduleUI):
|
||||
if not 1 <= int(classroom) <= 9:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@property
|
||||
def valid_task(self) -> list:
|
||||
task = self.schedule_info
|
||||
@ -131,4 +132,4 @@ class Schedule(ScheduleUI):
|
||||
if status == ScheduleStatus.FINISH:
|
||||
break
|
||||
|
||||
self.config.task_delay(server_update=True)
|
||||
self.config.task_delay(server_update=True)
|
||||
|
||||
@ -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
|
||||
"""
|
||||
|
||||
from module.logger import logger
|
||||
from module.base.timer import Timer
|
||||
from module.logger import logger
|
||||
|
||||
|
||||
class ScrollSelect:
|
||||
@ -30,7 +30,9 @@ class ScrollSelect:
|
||||
finalclick: bool
|
||||
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.
|
||||
self.window_starty = window_button.area[1]
|
||||
self.window_endy = window_button.area[3]
|
||||
@ -54,8 +56,9 @@ class ScrollSelect:
|
||||
main.device.swipe((x1, y1), (x1, y1 - (distance + responsey)), duration=2)
|
||||
else:
|
||||
# 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:
|
||||
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))
|
||||
@ -75,9 +78,9 @@ class ScrollSelect:
|
||||
# Center point of the target element
|
||||
target_center_y = start_center_y + self.itemheight * target_index
|
||||
self.run_until(main,
|
||||
lambda: click_coords(self.clickx, target_center_y),
|
||||
lambda: main.appear(self.expected_button),
|
||||
)
|
||||
lambda: click_coords(self.clickx, target_center_y),
|
||||
lambda: main.appear(self.expected_button),
|
||||
)
|
||||
else:
|
||||
# Start scrolling from the gap in the middle of the levels
|
||||
scroll_start_from_y = self.window_endy - self.itemheight // 2
|
||||
@ -86,7 +89,8 @@ class ScrollSelect:
|
||||
scrolltotal_distance = (target_index - itemcount) * self.itemheight + 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
|
||||
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}")
|
||||
# Update scrolltotal_distance
|
||||
scrolltotal_distance -= hiddenlastitemheight
|
||||
@ -97,18 +101,20 @@ class ScrollSelect:
|
||||
else:
|
||||
scroll_distance = (itemcount - 1) * self.itemheight
|
||||
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
|
||||
if scrolltotal_distance > 5:
|
||||
# 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:
|
||||
# Click on the last row
|
||||
self.run_until(main,
|
||||
lambda: click_coords(self.clickx, self.window_endy - self.itemheight // 2),
|
||||
lambda: main.appear(self.expected_button)
|
||||
)
|
||||
|
||||
lambda: click_coords(self.clickx, self.window_endy - self.itemheight // 2),
|
||||
lambda: main.appear(self.expected_button)
|
||||
)
|
||||
|
||||
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.
|
||||
@ -146,4 +152,3 @@ class ScrollSelect:
|
||||
timer = Timer(0.5).start()
|
||||
while not timer.reached_and_reset():
|
||||
pass
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
from module.base.timer import Timer
|
||||
import numpy as np
|
||||
|
||||
from module.base.decorator import Config
|
||||
from module.base.timer import Timer
|
||||
from module.logger import logger
|
||||
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.ui import UI
|
||||
from tasks.schedule.assets.assets_schedule import *
|
||||
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)
|
||||
xs = np.linspace(299, 995, 3, dtype=int)
|
||||
ys = np.linspace(268, 573, 3, dtype=int)
|
||||
|
||||
|
||||
class ScheduleUI(UI):
|
||||
@Config.when(Emulator_GameLanguage='jp')
|
||||
def set_clickx(self):
|
||||
@ -20,7 +22,7 @@ class ScheduleUI(UI):
|
||||
@Config.when(Emulator_GameLanguage=None)
|
||||
def set_clickx(self):
|
||||
pass
|
||||
|
||||
|
||||
def select_then_check(self, dest_enter: ButtonWrapper, dest_check: ButtonWrapper):
|
||||
timer = Timer(8, 10).start()
|
||||
while 1:
|
||||
@ -30,10 +32,10 @@ class ScheduleUI(UI):
|
||||
timer.reset()
|
||||
if self.appear(dest_check):
|
||||
return True
|
||||
|
||||
|
||||
if timer.reached():
|
||||
return False
|
||||
|
||||
|
||||
def click_then_check(self, coords, dest_check: ButtonWrapper):
|
||||
click_coords = self.device.click_methods.get(self.config.Emulator_ControlMethod, self.device.click_adb)
|
||||
timer = Timer(3, 2).start()
|
||||
@ -47,14 +49,14 @@ class ScheduleUI(UI):
|
||||
pass
|
||||
if timer.reached():
|
||||
return False
|
||||
|
||||
|
||||
def enter_location(self, location):
|
||||
SCROLL_SELECT.select_location(self, location)
|
||||
if not self.appear(LOCATIONS):
|
||||
logger.error("Unable to navigate to page for location {}".format(location + 1))
|
||||
return False
|
||||
return self.select_then_check(LOCATIONS, LOCATIONS_POPUP)
|
||||
|
||||
|
||||
def select_classrooms(self, ticket, classrooms):
|
||||
for classroom in classrooms:
|
||||
if ticket == 0:
|
||||
@ -86,5 +88,5 @@ class ScheduleUI(UI):
|
||||
logger.warning('Invalid ticket')
|
||||
return False
|
||||
logger.attr('ScheduleTicket', ticket)
|
||||
#self.config.stored.BountyTicket.set(ticket)
|
||||
# self.config.stored.BountyTicket.set(ticket)
|
||||
return ticket
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
from enum import Flag
|
||||
|
||||
from module.base.timer import Timer
|
||||
from module.exception import RequestHumanTakeover
|
||||
from module.logger import logger
|
||||
from module.ui.switch import Switch
|
||||
from tasks.base.assets.assets_base_page import BACK
|
||||
@ -18,6 +17,7 @@ class ShopStatus(Flag):
|
||||
END = 4
|
||||
FINISH = -1
|
||||
|
||||
|
||||
class Shop(ShopUI):
|
||||
@property
|
||||
def shop_info(self):
|
||||
@ -58,7 +58,7 @@ class Shop(ShopUI):
|
||||
@property
|
||||
def current_purchase_count(self):
|
||||
return self.task[0][1]
|
||||
|
||||
|
||||
@property
|
||||
def current_item_list(self):
|
||||
return self.task[0][2]
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import numpy as np
|
||||
|
||||
from module.base.timer import Timer
|
||||
from module.base.base import ModuleBase
|
||||
from module.base.timer import Timer
|
||||
from module.base.utils import area_size
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import DigitCounter
|
||||
@ -16,13 +16,14 @@ ITEM_POSITIONS = {
|
||||
17: (650, 460), 18: (805, 460), 19: (960, 460), 20: (1110, 460),
|
||||
}
|
||||
|
||||
|
||||
class ShopUI(UI):
|
||||
def __init__(self, config, device):
|
||||
super().__init__(config, device)
|
||||
|
||||
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_flags = {8:False, 16: False}
|
||||
self.swipe_flags = {8: False, 16: False}
|
||||
self.list = ITEM_LIST
|
||||
|
||||
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)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def select_items(self, item_list):
|
||||
"""
|
||||
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():
|
||||
pass
|
||||
self.click_coords(*ITEM_POSITIONS[item])
|
||||
self.click_coords(*ITEM_POSITIONS[item])
|
||||
|
||||
def should_swipe(self, item):
|
||||
"""
|
||||
@ -104,12 +105,13 @@ class ShopUI(UI):
|
||||
self.swipe_flags[16] = True
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def reset_swipe_flags(self):
|
||||
self.swipe_flags[8], self.swipe_flags[16] = False, False
|
||||
|
||||
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
|
||||
logger.warning("No items were selected. Unable to purchase.")
|
||||
return False
|
||||
@ -125,7 +127,7 @@ class ShopUI(UI):
|
||||
logger.info("Refreshed the shop")
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_refresh_count(self):
|
||||
if not self.select_then_check(REFRESH, CONFIRM_REFRESH):
|
||||
logger.warning('OCR failed due to invalid page')
|
||||
@ -135,4 +137,3 @@ class ShopUI(UI):
|
||||
logger.warning('Invalid count')
|
||||
return False
|
||||
return count
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ class TacticalChallenge(TacticalChallengeUI):
|
||||
if not select:
|
||||
return random.choice(self.select_players)
|
||||
else:
|
||||
return self.select_players[select-1]
|
||||
return self.select_players[select - 1]
|
||||
|
||||
def _handle_challenge(self, status):
|
||||
match status:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user