1
0
mirror of https://gitee.com/sui-feng-cb/AzurLaneAutoScript1 synced 2026-03-09 13:59:02 +08:00
AzurLaneAutoScript/module/island/pearl_daemon.py
2026-02-17 20:58:33 +08:00

278 lines
8.1 KiB
Python

from rich.table import Table
from rich.text import Text
from module.base.timer import Timer
from module.island.assets import *
from module.island.ui import IslandUI
from module.logger import logger
from module.map.map_grids import SelectedGrids
from module.ocr.ocr import Digit, Ocr
from module.ui.page import page_island, page_island_phone
from module.ui.scroll import Scroll
ISLAND_FRIEND_SCROLL = Scroll(ISLAND_FRIEND_SCROLL, color=(255, 255, 255))
ISLAND_FRIEND_SCROLL.drag_threshold = 0.05
ISLAND_FRIEND_SCROLL.edge_threshold = 0.05
PEARL_PRICE_OCR = Digit(PEARL_PRICE_OCR, letter=(255, 255, 255), threshold=128)
class FriendNameOcr(Ocr):
def after_process(self, result):
result = super().after_process(result)
result = result.replace('/', '').replace('\\', '').replace('`', '').replace('_', '')
return result
class IslandFriend:
# If success to parse project
valid: bool
# button to visit
visit_button: Button
# OCR result
name: str
# if visited
visited: bool
# pearl price on this island
pearl_price: int
def __init__(self, image, visit_button, crop_area):
"""
Args:
image:
visit_button:
crop_area:
"""
self.image = image
self.visit_button = visit_button.move((crop_area[0], crop_area[1]))
self.crop_area = crop_area
self.x1, self.y1, self.x2, self.y2 = self.visit_button.area
self.valid = True
self.visited = False
self.pearl_price = 0
self.friend_parse()
def friend_parse(self):
area = (self.x1 - 504, self.y1 - 25, self.x1 - 504 + 168, self.y1 - 25 + 22)
if area[0] < 360 or area[1] < 98 or area[2] > 593 or area[3] > 693:
self.valid = False
return
button = Button(area=area, color=(), button=area, name='FRIEND_NAME')
ocr = FriendNameOcr(button, lang='cnocr', letter=(63, 64, 66), threshold=128)
self.name = ocr.ocr(self.image)
if not self.name:
self.valid = False
return
def __eq__(self, other):
"""
Args:
other (IslandFriend):
Returns:
bool:
"""
if not isinstance(other, IslandFriend):
return False
if not self.valid or not other.valid:
return False
if self.name != other.name:
return False
return True
def __str__(self):
return self.name
class IslandPearl(IslandUI):
def pearl_enter(self):
"""
Pages:
in: ISLAND_FRIEND_LEAVE
out: PEARL_CHECK
"""
logger.hr('Pearl Enter')
self.move_up(2.8)
self.move_right(1.6)
self.move_down(1.8)
for _ in self.loop():
if self.appear_then_click(PEARL_ENTER, offset=(20, 20), interval=2):
continue
if self.appear(PEARL_CHECK, offset=(20, 20)):
break
def pearl_price_get(self):
"""
Returns:
int: pearl price ocr result
"""
ocr = 0
for _ in self.loop(timeout=1.5):
ocr = PEARL_PRICE_OCR.ocr(self.device.image)
if ocr >= 200:
break
return ocr
def friend_detect(self):
"""
Get all friends from an image.
Args:
image (np.ndarray):
Returns:
SelectedGrids:
"""
self.handle_info_bar()
area = (880, 98, 960, 693)
friends = SelectedGrids(
[IslandFriend(self.device.image, button, area) for button in
TEMPLATE_FRIEND_VISIT.match_multi(self.image_crop(area, copy=False))]
)
return friends.select(valid=True)
def _friend_visit(self, friend):
"""
Args:
friend (IslandFriend):
Returns:
bool: if visited
"""
logger.info(f'Visiting {friend}')
confirm_timer = Timer(1, count=2).start()
for _ in self.loop():
if self.island_in_friend(interval=5):
self.device.click(friend.visit_button)
continue
if self.info_bar_count():
return False
if self.appear(ISLAND_FRIEND_LEAVE, offset=(20, 20)):
if confirm_timer.reached():
break
continue
else:
confirm_timer.reset()
return True
def friend_leave(self):
logger.hr('Friend Leave')
self.island_ui_back()
for _ in self.loop():
if self.appear_then_click(ISLAND_FRIEND_LEAVE, offset=(20, 20), interval=2):
continue
if self.ui_page_appear(page_island):
break
if self.ui_page_appear(page_island_phone):
break
self.device.sleep(1.5)
self.device.click_record_clear()
self.ui_ensure_friend_page()
# ISLAND_FRIEND_SCROLL.set_top(main=self)
def friend_visit(self, current_friends, friends):
"""
Visit a friend's island, get the pearl price then leave
Args:
current_friends (SelectedGrids):
friends (SelectedGrids):
Returns:
SelectedGrids:
"""
logger.hr('Friend Visit')
friend: IslandFriend = friends.intersect_by_eq(current_friends).select(visited=False).first_or_none()
if friend is None or friend.name not in current_friends.get('name'):
return friends
if self._friend_visit(friend):
self.device.sleep(2)
self.pearl_enter()
friend.pearl_price = self.pearl_price_get()
print(friend.name)
self.friend_leave()
friend.visited = True
return friends
def pearl_run(self):
"""
Visit each friend's island, get the pearl price, and show in the logger
Returns:
SelectedGrids:
"""
logger.hr('Island Pearl', level=1)
bottom = False
friends = SelectedGrids([])
if ISLAND_FRIEND_SCROLL.appear(main=self):
ISLAND_FRIEND_SCROLL.set_top(main=self)
count = 0
for _ in self.loop():
if count > 2:
break
current_friends = self.friend_detect()
friends = friends.add_by_eq(current_friends)
friends = self.friend_visit(current_friends, friends)
current_friends = friends.intersect_by_eq(current_friends)
if ISLAND_FRIEND_SCROLL.appear(main=self):
if ISLAND_FRIEND_SCROLL.at_bottom(main=self):
if not bottom:
ISLAND_FRIEND_SCROLL.drag_threshold = 0.01
ISLAND_FRIEND_SCROLL.edge_threshold = 0.01
bottom = True
continue
logger.info('Island friend reach bottom, stop')
break
elif not current_friends.select(visited=False):
ISLAND_FRIEND_SCROLL.next_page(main=self)
count += 1
return friends
@staticmethod
def show(data):
"""
+----------+---------------+
| Player | Pearl Price |
+----------+---------------+
| a | 200 |
| b | 300 |
| c | 400 |
+----------+---------------+
"""
table = Table(show_lines=True)
table.add_column(
'Player', header_style="bright_cyan", style="cyan", no_wrap=True
)
table.add_column("Pearl Price", style="magenta")
for row in zip(data.get('name'), data.get('pearl_price')):
table.add_row(
row[0],
str(row[1]),
)
logger.print(table, justify='center')
def run(self):
self.device.screenshot()
self.ui_ensure_friend_page()
friends = self.pearl_run()
friends = friends.select(visited=True)
self.show(friends)
if __name__ == '__main__':
self = IslandPearl('alas')
self.device.screenshot()
self.run()