mirror of
https://github.com/TheFunny/ArisuAutoSweeper
synced 2026-02-06 17:35:12 +00:00
Compare commits
No commits in common. "b8ecd0c9d6d57a97ba4824654cd1a39b4ba8e410" and "e61afaf43be57bcd43192c50e9a42cd81f802bf7" have entirely different histories.
b8ecd0c9d6
...
e61afaf43b
4
aas.py
4
aas.py
@ -38,10 +38,6 @@ class ArisuAutoSweeper(AzurLaneAutoScript):
|
|||||||
from tasks.bounty.bounty import Bounty
|
from tasks.bounty.bounty import Bounty
|
||||||
Bounty(config=self.config, device=self.device).run()
|
Bounty(config=self.config, device=self.device).run()
|
||||||
|
|
||||||
def scrimmage(self):
|
|
||||||
from tasks.scrimmage.scrimmage import Scrimmage
|
|
||||||
Scrimmage(config=self.config, device=self.device).run()
|
|
||||||
|
|
||||||
def tactical_challenge(self):
|
def tactical_challenge(self):
|
||||||
from tasks.tactical_challenge.tactical_challenge import TacticalChallenge
|
from tasks.tactical_challenge.tactical_challenge import TacticalChallenge
|
||||||
TacticalChallenge(config=self.config, device=self.device).run()
|
TacticalChallenge(config=self.config, device=self.device).run()
|
||||||
|
|||||||
@ -8,8 +8,7 @@ class ManualConfig:
|
|||||||
|
|
||||||
SCHEDULER_PRIORITY = """
|
SCHEDULER_PRIORITY = """
|
||||||
Restart
|
Restart
|
||||||
> Cafe > Circle > Mail > DataUpdate > Bounty
|
> Cafe > Circle > Mail > DataUpdate > Bounty > TacticalChallenge
|
||||||
> Scrimmage > TacticalChallenge
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -80,8 +80,6 @@ class Bounty(BountyUI):
|
|||||||
case BountyStatus.ENTER:
|
case BountyStatus.ENTER:
|
||||||
if self.enter_stage(self.current_stage):
|
if self.enter_stage(self.current_stage):
|
||||||
return BountyStatus.SWEEP
|
return BountyStatus.SWEEP
|
||||||
else:
|
|
||||||
self.error_handler()
|
|
||||||
case BountyStatus.SWEEP:
|
case BountyStatus.SWEEP:
|
||||||
if self.do_sweep(self.current_count):
|
if self.do_sweep(self.current_count):
|
||||||
self.task.pop(0)
|
self.task.pop(0)
|
||||||
|
|||||||
@ -22,7 +22,7 @@ class BountyUI(UI):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def enter_stage(self, index: int) -> bool:
|
def enter_stage(self, index: int) -> bool:
|
||||||
if BOUNTY_LIST.select_index_enter(self, index):
|
if BOUNTY_LIST.select_index_enter(index, self):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
@ -1,144 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
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.page import page_school_exchange
|
|
||||||
from tasks.scrimmage.assets.assets_scrimmage import *
|
|
||||||
from tasks.scrimmage.ui import ScrimmageUI
|
|
||||||
|
|
||||||
|
|
||||||
class ScrimmageStatus(Enum):
|
|
||||||
OCR = 0
|
|
||||||
SELECT = 1
|
|
||||||
ENTER = 2
|
|
||||||
SWEEP = 3
|
|
||||||
END = 4
|
|
||||||
FINISH = 5
|
|
||||||
|
|
||||||
|
|
||||||
class Scrimmage(ScrimmageUI):
|
|
||||||
@property
|
|
||||||
def scrimmage_info(self):
|
|
||||||
bounty = (SELECT_TRINITY, SELECT_GEHENNA, SELECT_MILLENNIUM)
|
|
||||||
check = (CHECK_TRINITY, CHECK_GEHENNA, CHECK_MILLENNIUM)
|
|
||||||
stage = (self.config.Trinity_Stage, self.config.Gehenna_Stage, self.config.Millennium_Stage)
|
|
||||||
count = (self.config.Trinity_Count, self.config.Gehenna_Count, self.config.Millennium_Count)
|
|
||||||
ap = (10 if stage == 1 else 15 for stage in stage)
|
|
||||||
info = zip(bounty, check, stage, count, ap)
|
|
||||||
return filter(lambda x: x[3] > 0, info)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def valid_task(self) -> list:
|
|
||||||
task = list(self.scrimmage_info)
|
|
||||||
if not task:
|
|
||||||
logger.warning('Scrimmage enabled but no task set')
|
|
||||||
self.error_handler()
|
|
||||||
return task
|
|
||||||
|
|
||||||
def error_handler(self):
|
|
||||||
action = self.config.Bounty_OnError
|
|
||||||
if action == 'stop':
|
|
||||||
raise RequestHumanTakeover
|
|
||||||
elif action == 'skip':
|
|
||||||
self.config.task_delay(server_update=True)
|
|
||||||
self.config.task_stop()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_ticket_enough(self) -> bool:
|
|
||||||
return self.current_ticket >= self.current_count
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_ap_enough(self) -> bool:
|
|
||||||
return self.current_ap >= self.current_task_ap
|
|
||||||
|
|
||||||
@property
|
|
||||||
def current_scrimmage(self):
|
|
||||||
return self.task[0][:2]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def current_stage(self):
|
|
||||||
return self.task[0][2]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def current_count(self):
|
|
||||||
return self.task[0][3]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def current_task_ap(self):
|
|
||||||
return self.task[0][4]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def current_ticket(self):
|
|
||||||
return self.config.stored.ScrimmageTicket.value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def current_ap(self):
|
|
||||||
return self.config.stored.AP.value
|
|
||||||
|
|
||||||
def update_ap(self):
|
|
||||||
ap = self.config.stored.AP
|
|
||||||
ap_old = ap.value
|
|
||||||
ap_new = ap_old - self.current_task_ap
|
|
||||||
ap.set(ap_new, ap.total)
|
|
||||||
logger.info(f'Set AP: {ap_old} -> {ap_new}')
|
|
||||||
|
|
||||||
def handle_scrimmage(self, status):
|
|
||||||
match status:
|
|
||||||
case ScrimmageStatus.OCR:
|
|
||||||
if self.get_ticket():
|
|
||||||
if self.current_ticket == 0 or not self.task:
|
|
||||||
return ScrimmageStatus.FINISH
|
|
||||||
return ScrimmageStatus.SELECT
|
|
||||||
case ScrimmageStatus.SELECT:
|
|
||||||
if not self.is_ticket_enough:
|
|
||||||
logger.warning('Scrimmage ticket not enough')
|
|
||||||
self.error_handler()
|
|
||||||
if not self.is_ap_enough:
|
|
||||||
logger.warning('AP not enough')
|
|
||||||
self.error_handler()
|
|
||||||
if self.select_scrimmage(*self.current_scrimmage):
|
|
||||||
return ScrimmageStatus.ENTER
|
|
||||||
case ScrimmageStatus.ENTER:
|
|
||||||
if self.enter_stage(self.current_stage):
|
|
||||||
return ScrimmageStatus.SWEEP
|
|
||||||
else:
|
|
||||||
self.error_handler()
|
|
||||||
case ScrimmageStatus.SWEEP:
|
|
||||||
if self.do_sweep(self.current_count):
|
|
||||||
self.update_ap()
|
|
||||||
self.task.pop(0)
|
|
||||||
return ScrimmageStatus.END
|
|
||||||
return ScrimmageStatus.ENTER
|
|
||||||
case ScrimmageStatus.END:
|
|
||||||
if self.appear(CHECK_SCRIMMAGE):
|
|
||||||
return ScrimmageStatus.OCR
|
|
||||||
self.click_with_interval(BACK, interval=2)
|
|
||||||
case ScrimmageStatus.FINISH:
|
|
||||||
return status
|
|
||||||
case _:
|
|
||||||
logger.warning(f'Invalid status: {status}')
|
|
||||||
return status
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.ui_ensure(page_school_exchange)
|
|
||||||
self.task = self.valid_task
|
|
||||||
action_timer = Timer(0.5, 1)
|
|
||||||
status = ScrimmageStatus.OCR
|
|
||||||
|
|
||||||
while 1:
|
|
||||||
self.device.screenshot()
|
|
||||||
|
|
||||||
if self.ui_additional():
|
|
||||||
continue
|
|
||||||
|
|
||||||
if action_timer.reached_and_reset():
|
|
||||||
logger.attr('Status', status)
|
|
||||||
status = self.handle_scrimmage(status)
|
|
||||||
|
|
||||||
if status == ScrimmageStatus.FINISH:
|
|
||||||
break
|
|
||||||
|
|
||||||
self.config.task_delay(server_update=True)
|
|
||||||
self.config.task_call('DataUpdate')
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
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.scrimmage.assets.assets_scrimmage import *
|
|
||||||
from tasks.stage.list import StageList
|
|
||||||
from tasks.stage.sweep import StageSweep
|
|
||||||
|
|
||||||
SCRIMMAGE_LIST = StageList('ScrimmageList')
|
|
||||||
SCRIMMAGE_SWEEP = StageSweep('ScrimmageSweep', 6)
|
|
||||||
|
|
||||||
|
|
||||||
class ScrimmageUI(UI):
|
|
||||||
def select_scrimmage(self, dest_enter: ButtonWrapper, dest_check: ButtonWrapper):
|
|
||||||
timer = Timer(5, 10).start()
|
|
||||||
while 1:
|
|
||||||
self.device.screenshot()
|
|
||||||
self.appear_then_click(dest_enter, interval=1)
|
|
||||||
if self.appear(dest_check):
|
|
||||||
return True
|
|
||||||
if timer.reached():
|
|
||||||
return False
|
|
||||||
|
|
||||||
def enter_stage(self, index: int) -> bool:
|
|
||||||
if SCRIMMAGE_LIST.select_index_enter(self, index, insight=False):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def do_sweep(self, num: int) -> bool:
|
|
||||||
if SCRIMMAGE_SWEEP.do_sweep(self, num=num):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_ticket(self):
|
|
||||||
"""
|
|
||||||
Page:
|
|
||||||
in: page_bounty
|
|
||||||
"""
|
|
||||||
if not self.appear(CHECK_SCRIMMAGE):
|
|
||||||
logger.warning('OCR failed due to invalid page')
|
|
||||||
return False
|
|
||||||
ticket, _, total = DigitCounter(OCR_TICKET).ocr_single_line(self.device.image)
|
|
||||||
if total == 0:
|
|
||||||
logger.warning('Invalid ticket')
|
|
||||||
return False
|
|
||||||
logger.attr('ScrimmageTicket', ticket)
|
|
||||||
self.config.stored.ScrimmageTicket.set(ticket)
|
|
||||||
return True
|
|
||||||
@ -148,37 +148,33 @@ class StageList:
|
|||||||
|
|
||||||
def select_index_enter(
|
def select_index_enter(
|
||||||
self,
|
self,
|
||||||
main: ModuleBase,
|
|
||||||
index: int,
|
index: int,
|
||||||
|
main: ModuleBase,
|
||||||
insight: bool = True,
|
insight: bool = True,
|
||||||
sweepable: bool = True,
|
sweepable: bool = True,
|
||||||
offset: tuple[int, int] = (-20, -15),
|
offset: tuple[int, int] = (-20, -15),
|
||||||
skip_first_screenshot: bool = True,
|
skip_first_screenshot: bool = True,
|
||||||
interval: int = 1.5
|
interval: int = 2
|
||||||
) -> bool:
|
) -> bool:
|
||||||
# insight index, if failed, return False
|
|
||||||
if insight and not self.insight_index(index, main, skip_first_screenshot):
|
if insight and not self.insight_index(index, main, skip_first_screenshot):
|
||||||
return False
|
return False
|
||||||
logger.info(f'Select index: {index}')
|
logger.info(f'Select index: {index}')
|
||||||
click_interval = Timer(interval)
|
click_interval = Timer(interval)
|
||||||
load_index_interval = Timer(1)
|
load_index_interval = Timer(1)
|
||||||
timeout = Timer(15, 10).start()
|
|
||||||
while 1:
|
while 1:
|
||||||
if skip_first_screenshot:
|
if skip_first_screenshot:
|
||||||
skip_first_screenshot = False
|
skip_first_screenshot = False
|
||||||
else:
|
else:
|
||||||
main.device.screenshot()
|
main.device.screenshot()
|
||||||
|
|
||||||
# load index if not insight
|
if load_index_interval.reached_and_reset():
|
||||||
if load_index_interval.reached_and_reset() and not insight:
|
|
||||||
self.load_stage_indexes(main=main)
|
self.load_stage_indexes(main=main)
|
||||||
|
|
||||||
# find box of index
|
|
||||||
index_box = next(filter(lambda x: int(x.ocr_text) == index, self.current_indexes), None)
|
index_box = next(filter(lambda x: int(x.ocr_text) == index, self.current_indexes), None)
|
||||||
|
|
||||||
if index_box is None:
|
if index_box is None:
|
||||||
logger.warning(f'No index {index} in {self.index_ocr.name}')
|
logger.warning(f'No index {index} in {self.index_ocr.name}')
|
||||||
continue
|
return False
|
||||||
|
|
||||||
stage_item_box = area_pad((*offset, *area_size(self.stage_item)))
|
stage_item_box = area_pad((*offset, *area_size(self.stage_item)))
|
||||||
search_box = area_offset(stage_item_box, index_box.box[:2])
|
search_box = area_offset(stage_item_box, index_box.box[:2])
|
||||||
@ -192,7 +188,7 @@ class StageList:
|
|||||||
|
|
||||||
if not points:
|
if not points:
|
||||||
logger.warning(f'No clickable {self.enter.name}')
|
logger.warning(f'No clickable {self.enter.name}')
|
||||||
continue
|
return False
|
||||||
|
|
||||||
point = area_offset((0, 0, *area_size(self.enter.button)), points[0])
|
point = area_offset((0, 0, *area_size(self.enter.button)), points[0])
|
||||||
click_button = ClickButton(area_offset(point, search_box[:2]), name=self.enter.name)
|
click_button = ClickButton(area_offset(point, search_box[:2]), name=self.enter.name)
|
||||||
@ -200,7 +196,3 @@ class StageList:
|
|||||||
if click_interval.reached_and_reset():
|
if click_interval.reached_and_reset():
|
||||||
main.device.click(click_button)
|
main.device.click(click_button)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if timeout.reached():
|
|
||||||
logger.warning(f'{self.enter.name} failed')
|
|
||||||
return False
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user