1
0
mirror of https://gitee.com/sui-feng-cb/AzurLaneAutoScript1 synced 2026-03-19 23:33:33 +08:00

Refractor: Island Project

This commit is contained in:
sui-feng-cb
2025-10-07 16:00:26 +08:00
parent f45f37dd88
commit 440efa17ca
37 changed files with 3738 additions and 60 deletions

View File

@@ -1,9 +1,14 @@
import cv2
import numpy as np
from scipy import signal
import module.config.server as server
from module.base.timer import Timer
from module.base.utils import rgb2gray
from module.base.utils import color_similarity_2d, random_rectangle_vector, rgb2gray
from module.config.deep import deep_get
from module.island.assets import *
from module.island.project import IslandProduct, IslandProject
from module.island.project_data import *
from module.island.project import IslandItem, IslandProduct, IslandProject
from module.island.ui import IslandUI
from module.logger import logger
from module.map.map_grids import SelectedGrids
@@ -39,9 +44,12 @@ class Island(IslandUI):
Returns:
bool: if received.
"""
logger.hr('Island Project', level=2)
self.device.click_record_clear()
self.interval_clear([ISLAND_MANAGEMENT_CHECK, PROJECT_COMPLETE,
GET_ITEMS_ISLAND, ROLE_SELECT_ENTER])
received = False
enter = True
timeout = Timer(3, count=6).start()
while 1:
if skip_first_screenshot:
@@ -58,24 +66,26 @@ class Island(IslandUI):
timeout.reset()
continue
if enter and self.appear_then_click(ROLE_SELECT_ENTER, offset=(5, 5), interval=2):
received = True
self.interval_clear(GET_ITEMS_ISLAND)
timeout.reset()
continue
if self.appear_then_click(PROJECT_COMPLETE, offset=(20, 20), interval=2):
received = True
enter = False
self.interval_clear(GET_ITEMS_ISLAND)
self.interval_reset(ROLE_SELECT_ENTER)
timeout.reset()
continue
if self.appear_then_click(GET_ITEMS_ISLAND, offset=(20, 20), interval=2):
enter = True
self.interval_clear(ROLE_SELECT_ENTER)
timeout.reset()
continue
if self.appear_then_click(ROLE_SELECT_ENTER, offset=(5, 5), interval=2):
received = True
self.interval_clear(GET_ITEMS_ISLAND)
timeout.reset()
continue
if self.appear(ROLE_SELECT_CONFIRM, offset=(20, 20)):
break
if timeout.reached():
@@ -111,6 +121,9 @@ class Island(IslandUI):
)
def island_select_role(self, skip_first_screenshot=True):
"""
Select a role to produce.
"""
timeout = Timer(1.5, count=3).start()
while 1:
if skip_first_screenshot:
@@ -130,7 +143,74 @@ class Island(IslandUI):
logger.info('No manjuu found')
continue
def island_select_product(self, skip_first_screenshot=True):
def island_current_product(self):
"""
Get currently selected product on self.device.image.
Returns:
IslandItem: currently selected item
"""
image = self.image_crop(ISLAND_PRODUCT_ITEMS, copy=False)
y_top = ISLAND_PRODUCT_ITEMS.area[1]
line = cv2.reduce(image, 1, cv2.REDUCE_AVG)
# blue line
line = color_similarity_2d(line, color=(57, 189, 255))[:, 0]
parameters = {
'height': 200,
'distance': 50,
}
peaks, _ = signal.find_peaks(line, **parameters)
peaks = np.array(peaks) + y_top
return IslandItem(self.device.image, peaks)
def island_select_product(self, option, skip_first_screenshot=True):
"""
Select a product in items list.
Args:
option (str): option to select
skip_first_screenshot (bool):
"""
logger.hr('Island Select Product')
last = None
click_interval = Timer(1)
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
current = self.island_current_product()
if option == current.name:
logger.info(f'Selected item {option}')
return True
drag = True
for item in current.items:
if option == item.name:
if click_interval.reached():
self.device.click(item.button)
self.device.sleep(0.2)
click_interval.reset()
drag = False
if last == current.items[-1]:
logger.info('Reach the bottom of items')
return False
if drag:
last = current.items[-1]
self.device.click(last.button)
self.island_drag_next_page((0, -300), ISLAND_PRODUCT_ITEMS.area, 0.5)
def island_product_confirm(self, skip_first_screenshot=True):
"""
Start the product after product selected.
Args:
skip_first_screenshot (bool):
"""
last = None
success = False
timeout = Timer(1.5, count=3).start()
@@ -170,17 +250,30 @@ class Island(IslandUI):
if self.island_in_management():
break
def island_run(self, names, skip_first_screenshot=True):
def island_drag_next_page(self, vector, box, sleep=0.5):
"""
Drag to the next page.
Args:
vector (tuple):
box (tuple):
sleep (float):
"""
p1, p2 = random_rectangle_vector(vector, box=box, random_range=(0, -5, 0, 5))
self.device.drag(p1, p2, segments=2, shake=(0, 25), point_random=(0, 0, 0, 0), shake_random=(0, -5, 0, 5))
self.device.sleep(sleep)
def island_run(self, names, trial=2, skip_first_screenshot=True):
"""
Execute island run to receive and start project.
Args:
names (bool):
trial (int):
skip_first_screenshot (bool):
"""
logger.hr('Island Run', level=1)
names = self.island_config_to_names(names)
success = False
end = False
timeout = Timer(3, count=3).start()
while 1:
if skip_first_screenshot:
@@ -192,20 +285,36 @@ class Island(IslandUI):
break
projects = self.project_detect(self.device.image)
projects = projects.filter(lambda proj: proj.name in names and proj.name not in self.project.get('name'))
if trial > 0 and not projects:
trial -= 1
continue
projects: SelectedGrids = projects.filter(
lambda proj: proj.name in names and proj.name not in self.project.get('name'))
self.project = self.project.add_by_eq(projects)
for proj in projects:
for button in proj.slot_buttons.buttons:
if proj.name == names[-1]:
end = True
proj_config = self.island_project_config(proj)
for button, option in zip(proj.slot_buttons.buttons, proj_config):
if option is None:
continue
self.device.click_record_clear()
self.device.click(button)
self.device.sleep(0.3)
self.device.click(ISLAND_CLICK_SAFE_AREA)
if self.project_receive(button):
self.island_select_role()
self.island_select_product()
success = True
self.island_select_product(option)
self.island_product_confirm()
timeout.reset()
if success:
if end:
break
self.island_drag_next_page((0, -500), ISLAND_PROJECT_SWIPE.area, 0.6)
# task delay
future_finish = sorted([f for f in self.total.get('finish_time') if f is not None])
logger.info(f'Project finish: {[str(f) for f in future_finish]}')
if len(future_finish):
@@ -214,22 +323,49 @@ class Island(IslandUI):
logger.info('No island project running')
self.config.task_delay(success=False)
def island_project_config(self, project: IslandProject):
"""
Args:
project (IslandProject):
Returns:
list[str]: a list of options for production
"""
slot_option = []
proj_id = project.id
for proj_slot in range(1, project.slot + 1):
option = self.config.__getattribute__(f'Island{proj_id}_Option{proj_slot}')
if option == 0:
slot_option.append(None)
continue
slot_option.append(deep_get(items_data_cn, [proj_id, option]))
return slot_option
@staticmethod
def island_config_to_names(config):
if config:
return ['沉石矿山', '翠土林场']
"""
Args:
config (list[bool]): list of config for island receive
Returns:
list[str]: a list of name for island receive
"""
if any(config):
return [name for add, name in zip(config, list(name_to_slot_cn.keys())) if add]
else:
return []
def run(self):
if server.server in ['cn']:
if self.config.Island_ReceiveMiningForaging:
names = self.island_config_to_names(
[self.config.__getattribute__(f'Island{i}_Receive') for i in range(1, 16)])
if len(names):
self.ui_ensure(page_dormmenu)
self.ui_goto(page_island, get_ship=False)
self.device.sleep(0.5)
self.ui_ensure(page_island_phone)
self.island_management_enter()
self.island_run(names=self.config.Island_ReceiveMiningForaging)
self.island_run(names=names)
self.island_management_quit()
self.ui_goto(page_main, get_ship=False)
else: