1
0
mirror of https://gitee.com/sui-feng-cb/AzurLaneAutoScript1 synced 2026-03-09 18:39:04 +08:00
AzurLaneAutoScript/module/base/base.py

178 lines
5.8 KiB
Python
Raw Normal View History

from PIL import Image
2020-03-29 01:22:46 +08:00
from module.base.button import Button
from module.base.timer import Timer
from module.base.utils import *
2020-03-29 01:22:46 +08:00
from module.config.config import AzurLaneConfig
from module.device.device import Device
from module.logger import logger
from module.statistics.azurstats import AzurStats
2020-03-29 01:22:46 +08:00
class ModuleBase:
2021-01-19 14:36:47 +08:00
config: AzurLaneConfig
device: Device
stat: AzurStats
2021-01-19 14:36:47 +08:00
2020-03-29 01:22:46 +08:00
def __init__(self, config, device=None):
"""
Args:
config (AzurLaneConfig, str):
2020-03-29 01:22:46 +08:00
device (Device):
"""
if isinstance(config, str):
self.config = AzurLaneConfig(config)
else:
self.config = config
2020-03-29 01:22:46 +08:00
if device is not None:
self.device = device
else:
self.device = Device(config=self.config)
self.stat = AzurStats(config=self.config)
self.interval_timer = {}
2020-03-29 01:22:46 +08:00
def appear(self, button, offset=0, interval=0, threshold=None):
2020-03-29 01:22:46 +08:00
"""
Args:
button (Button, Template):
offset (bool, int):
interval (int, float): interval between two active events.
threshold (int, float): 0 to 1 if use offset, bigger means more similar,
0 to 255 if not use offset, smaller means more similar
2020-03-29 01:22:46 +08:00
Returns:
bool:
"""
2020-07-04 07:42:48 +08:00
self.device.stuck_record_add(button)
2020-03-29 01:22:46 +08:00
if interval:
if button.name not in self.interval_timer:
self.interval_timer[button.name] = Timer(interval)
if not self.interval_timer[button.name].reached():
return False
if offset:
if isinstance(offset, bool):
offset = self.config.BUTTON_OFFSET
appear = button.match(self.device.image, offset=offset,
threshold=self.config.BUTTON_MATCH_SIMILARITY if threshold is None else threshold)
2020-03-29 01:22:46 +08:00
else:
appear = button.appear_on(self.device.image,
threshold=self.config.COLOR_SIMILAR_THRESHOLD if threshold is None else threshold)
2020-03-29 01:22:46 +08:00
if appear and interval:
self.interval_timer[button.name].reset()
return appear
def appear_then_click(self, button, screenshot=False, genre='items', offset=0, interval=0):
appear = self.appear(button, offset=offset, interval=interval)
if appear:
if screenshot:
self.device.sleep(self.config.WAIT_BEFORE_SAVING_SCREEN_SHOT)
self.device.screenshot()
self.device.save_screenshot(genre=genre)
self.device.click(button)
return appear
2020-06-01 08:20:13 +08:00
def wait_until_appear(self, button, offset=0, skip_first_screenshot=False):
2020-03-29 01:22:46 +08:00
while 1:
2020-06-01 08:20:13 +08:00
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
2020-03-29 01:22:46 +08:00
if self.appear(button, offset=offset):
break
def wait_until_appear_then_click(self, button, offset=0):
self.wait_until_appear(button, offset=offset)
self.device.click(button)
def wait_until_disappear(self, button, offset=0):
while 1:
self.device.screenshot()
if not self.appear(button, offset=offset):
break
2021-07-10 22:27:47 +08:00
def wait_until_stable(self, button, timer=Timer(0.3, count=1), timeout=Timer(5, count=10), skip_first_screenshot=True):
button._match_init = False
timeout.start()
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if button._match_init:
if button.match(self.device.image, offset=(0, 0)):
if timer.reached():
break
else:
button.load_color(self.device.image)
timer.reset()
else:
button.load_color(self.device.image)
button._match_init = True
if timeout.reached():
logger.warning(f'wait_until_stable({button}) timeout')
break
2020-03-29 01:22:46 +08:00
def image_area(self, button):
"""Extract the area from image.
Args:
button(Button, tuple): Button instance or area tuple.
2020-03-29 01:22:46 +08:00
"""
if isinstance(button, Button):
return self.device.image.crop(button.area)
else:
return self.device.image.crop(button)
2020-03-29 01:22:46 +08:00
def image_color_count(self, button, color, threshold=221, count=50):
"""
Args:
button (Button, tuple): Button instance or area.
color (tuple): RGB.
threshold: 255 means colors are the same, the lower the worse.
count (int): Pixels count.
Returns:
bool:
"""
if isinstance(button, Button):
image = self.device.image.crop(button.area)
else:
image = self.device.image.crop(button)
mask = color_similarity_2d(image, color=color) > threshold
return np.sum(mask) > count
2020-03-29 01:22:46 +08:00
def interval_reset(self, button):
if button.name in self.interval_timer:
self.interval_timer[button.name].reset()
def interval_clear(self, button):
if button.name in self.interval_timer:
self.interval_timer[button.name].clear()
_image_file = ''
@property
def image_file(self):
return self._image_file
@image_file.setter
def image_file(self, value):
"""
For development.
Load image from local file system and set it to self.device.image
Test an image without taking a screenshot from emulator.
"""
if isinstance(value, np.ndarray):
value = Image.fromarray(value)
elif isinstance(value, str):
value = Image.open(value).convert('RGB')
self.device.image = value