mirror of
https://gitee.com/sui-feng-cb/AzurLaneAutoScript1
synced 2026-03-09 13:59:02 +08:00
278 lines
8.1 KiB
Python
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()
|