mirror of
https://github.com/W1NDes/M-AzurLaneAutoScript.git
synced 2026-05-14 07:08:04 +08:00
215 lines
8.7 KiB
Python
215 lines
8.7 KiB
Python
import random
|
|
from module.retire.dock import Dock
|
|
from module.logger import logger
|
|
from module.base.decorator import cached_property
|
|
from module.ui.setting import Setting
|
|
from module.base.button import ButtonGrid
|
|
from module.ui.page import page_handbook
|
|
from module.coalition.assets import NEONCITY_FLEET_PREPARATION, NEONCITY_PREPARATION_EXIT
|
|
from module.combat.assets import GET_SHIP
|
|
from module.exercise.assets import EXERCISE_PREPARATION
|
|
from module.handler.assets import (AUTO_SEARCH_MENU_EXIT, GAME_TIPS, LOGIN_CHECK, MAINTENANCE_ANNOUNCE)
|
|
from module.map.assets import (FLEET_PREPARATION, MAP_PREPARATION,MAP_PREPARATION_CANCEL, WITHDRAW)
|
|
from module.meowfficer.assets import MEOWFFICER_BUY
|
|
from module.os_handler.assets import AUTO_SEARCH_REWARD
|
|
from module.raid.assets import *
|
|
from module.ui.assets import *
|
|
from module.ship_ir.assets import *
|
|
from module.logger import logger
|
|
|
|
|
|
|
|
class Handbook(Dock):
|
|
|
|
def ui_additional(self, get_ship=True):
|
|
"""
|
|
Handle all annoying popups during UI switching.
|
|
|
|
Args:
|
|
get_ship:
|
|
"""
|
|
# Popups appear at page_os
|
|
# Has a popup_confirm variant
|
|
# so must take precedence
|
|
if self.ui_page_os_popups():
|
|
return True
|
|
|
|
# Research popup, lost connection popup
|
|
if self.handle_popup_confirm("UI_ADDITIONAL"):
|
|
return True
|
|
if self.handle_urgent_commission():
|
|
return True
|
|
|
|
# Popups appear at page_main, page_reward
|
|
if self.ui_page_main_popups(get_ship=get_ship):
|
|
return True
|
|
|
|
# Story
|
|
if self.handle_story_skip():
|
|
return True
|
|
|
|
# Game tips
|
|
# Event commission in Vacation Lane.
|
|
# 2025.05.29 game tips that infos skin feature when you enter dock
|
|
if self.appear(GAME_TIPS, offset=(30, 30), interval=2):
|
|
logger.info(f'UI additional: {GAME_TIPS} -> {GOTO_MAIN}')
|
|
self.device.click(GOTO_MAIN)
|
|
return True
|
|
|
|
# Dorm popup
|
|
if self.appear(DORM_INFO, offset=(30, 30), similarity=0.75, interval=3):
|
|
self.device.click(DORM_INFO)
|
|
return True
|
|
if self.appear_then_click(DORM_FEED_CANCEL, offset=(30, 30), interval=3):
|
|
return True
|
|
if self.appear_then_click(DORM_TROPHY_CONFIRM, offset=(30, 30), interval=3):
|
|
return True
|
|
|
|
# Meowfficer popup
|
|
if self.appear_then_click(MEOWFFICER_INFO, offset=(30, 30), interval=3):
|
|
self.interval_reset(GET_SHIP)
|
|
return True
|
|
if self.appear(MEOWFFICER_BUY, offset=(30, 30), interval=3):
|
|
logger.info(f'UI additional: {MEOWFFICER_BUY} -> {BACK_ARROW}')
|
|
self.device.click(BACK_ARROW)
|
|
self.interval_reset(GET_SHIP)
|
|
return True
|
|
|
|
# Campaign preparation
|
|
if self.appear(MAP_PREPARATION, offset=(30, 30), interval=3) \
|
|
or self.appear(FLEET_PREPARATION, offset=(20, 50), interval=3) \
|
|
or self.appear(RAID_FLEET_PREPARATION, offset=(30, 30), interval=3):
|
|
self.device.click(MAP_PREPARATION_CANCEL)
|
|
return True
|
|
if self.appear_then_click(AUTO_SEARCH_MENU_EXIT, offset=(200, 30), interval=3):
|
|
return True
|
|
if self.appear_then_click(AUTO_SEARCH_REWARD, offset=(50, 50), interval=3):
|
|
return True
|
|
if self.appear(WITHDRAW, offset=(30, 30), interval=3):
|
|
# Poor wait here, to handle a game client bug after the game patch in 2022-04-07
|
|
# To re-produce this game bug (100% success):
|
|
# - Enter any stage, 12-4 for example
|
|
# - Stop and restart game
|
|
# - Run task `Main` in Alas
|
|
# - Alas switches to page_campaign and retreat from an existing stage
|
|
# - Game client freezes at page_campaign W12, clicking anywhere on the screen doesn't get responses
|
|
# - Restart game client again fix the issue
|
|
logger.info("WITHDRAW button found, wait until map loaded to prevent bugs in game client")
|
|
self.device.sleep(2)
|
|
self.device.screenshot()
|
|
if self.appear_then_click(WITHDRAW, offset=(30, 30)):
|
|
self.interval_reset(WITHDRAW)
|
|
return True
|
|
else:
|
|
logger.warning("WITHDRAW button does not exist anymore")
|
|
self.interval_reset(WITHDRAW)
|
|
|
|
# Login
|
|
if self.appear_then_click(LOGIN_CHECK, offset=(30, 30), interval=3):
|
|
return True
|
|
if self.appear_then_click(MAINTENANCE_ANNOUNCE, offset=(30, 30), interval=3):
|
|
return True
|
|
|
|
# Mistaken click
|
|
if self.appear(EXERCISE_PREPARATION, interval=3):
|
|
logger.info(f'UI additional: {EXERCISE_PREPARATION} -> {GOTO_MAIN}')
|
|
self.device.click(GOTO_MAIN)
|
|
return True
|
|
|
|
|
|
# Neon city (coalition_20250626)
|
|
if self.appear(NEONCITY_FLEET_PREPARATION, offset=(20, 20), interval=3):
|
|
logger.info(f'{NEONCITY_FLEET_PREPARATION} -> {NEONCITY_PREPARATION_EXIT}')
|
|
self.device.click(NEONCITY_PREPARATION_EXIT)
|
|
return True
|
|
|
|
# Idle page
|
|
if self.handle_idle_page():
|
|
return True
|
|
|
|
return False
|
|
|
|
def handbook_swipe(self,x,delay_time=0.3):
|
|
self.device.drag((x+random.randint(-3,3),300),(x+random.randint(-3,3),220))
|
|
# self.device.sleep(delay_time)
|
|
self.device.sleep(delay_time)
|
|
|
|
def dock_filter_enter(self):
|
|
logger.info('Dock filter enter')
|
|
for _ in self.loop():
|
|
if self.appear(HANDBOOK_FILTER_CONFIRM, offset=(20, 20)):
|
|
break
|
|
if self.appear(HANDBOOK_CHECK, offset=(20, 20), interval=5):
|
|
self.device.click(HANDBOOK_FILTER)
|
|
continue
|
|
|
|
def dock_filter_confirm(self, wait_loading=True, skip_first_screenshot=True):
|
|
"""
|
|
Args:
|
|
wait_loading: Default to True, use False on continuous operation
|
|
skip_first_screenshot:
|
|
"""
|
|
while 1:
|
|
if skip_first_screenshot:
|
|
skip_first_screenshot = False
|
|
else:
|
|
self.device.screenshot()
|
|
|
|
# End
|
|
# sometimes you have dock filter without black-blurred background
|
|
# DOCK_FILTER_CONFIRM and DOCK_CHECK appears
|
|
if not self.appear(HANDBOOK_FILTER_CONFIRM, offset=(20, 20)):
|
|
if self.appear(HANDBOOK_CHECK, offset=(20, 20)):
|
|
break
|
|
if self.appear_then_click(HANDBOOK_FILTER_CONFIRM, offset=(20, 20), interval=3):
|
|
continue
|
|
|
|
if wait_loading:
|
|
self.handle_dock_cards_loading()
|
|
|
|
@cached_property
|
|
def dock_filter(self) -> Setting:
|
|
delta = (147 + 1 / 3, 57)
|
|
button_shape = (139, 42)
|
|
setting = Setting(name='HANDBOOK', main=self)
|
|
|
|
setting.add_setting(
|
|
setting='index',
|
|
option_buttons=ButtonGrid(
|
|
origin=(218, 147), delta=delta, button_shape=button_shape, grid_shape=(7, 2), name='FILTER_INDEX'),
|
|
option_names=['all', 'vanguard', 'main', 'dd', 'cl', 'ca', 'bb',
|
|
'cv', 'repair', 'ss', 'others', 'not_available', 'not_available', 'not_available'],
|
|
option_default='all'
|
|
)
|
|
setting.add_setting(
|
|
setting='faction',
|
|
option_buttons=ButtonGrid(
|
|
origin=(218, 277), delta=delta, button_shape=button_shape, grid_shape=(7, 2), name='FILTER_FACTION'),
|
|
option_names=['all', 'eagle', 'royal', 'sakura', 'iron', 'dragon', 'sardegna',
|
|
'northern', 'iris', 'vichya', 'tulipa', 'meta', 'tempesta', 'other'],
|
|
option_default='all'
|
|
)
|
|
setting.add_setting(
|
|
setting='rarity',
|
|
option_buttons=ButtonGrid(
|
|
origin=(218, 407), delta=delta, button_shape=button_shape, grid_shape=(7, 1), name='FILTER_RARITY'),
|
|
option_names=['all', 'common', 'rare', 'elite', 'super_rare', 'ultra', 'not_available'],
|
|
option_default='all'
|
|
)
|
|
setting.add_setting(
|
|
setting='extra',
|
|
option_buttons=ButtonGrid(
|
|
origin=(218, 480), delta=delta, button_shape=button_shape, grid_shape=(7, 1), name='FILTER_EXTRA'),
|
|
option_names=['no_limit','special','un_get','not_available', 'not_available', 'not_available', 'not_available'],
|
|
option_default='no_limit'
|
|
)
|
|
return setting
|
|
|
|
def pageCheck(self):
|
|
self.ui_ensure(page_handbook)
|
|
if self.appear(page_handbook.check_button, offset=(30, 30)):
|
|
logger.info('pageCheck: At page_handbook')
|
|
return True
|
|
else:
|
|
logger.warning('Unknown page_handbook')
|
|
return False |