mirror of
https://github.com/LmeSzinc/AzurLaneAutoScript.git
synced 2025-01-09 09:57:43 +08:00
Opt: Remove unnecessary use of drags, fallback to swipe+click if drag is a must
This commit is contained in:
parent
7c4dfd8948
commit
df310b9d09
BIN
assets/cn/war_archives/WAR_ARCHIVES_SCROLL.png
Normal file
BIN
assets/cn/war_archives/WAR_ARCHIVES_SCROLL.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
BIN
assets/en/war_archives/WAR_ARCHIVES_SCROLL.png
Normal file
BIN
assets/en/war_archives/WAR_ARCHIVES_SCROLL.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
BIN
assets/jp/war_archives/WAR_ARCHIVES_SCROLL.png
Normal file
BIN
assets/jp/war_archives/WAR_ARCHIVES_SCROLL.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
BIN
assets/tw/war_archives/WAR_ARCHIVES_SCROLL.png
Normal file
BIN
assets/tw/war_archives/WAR_ARCHIVES_SCROLL.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
@ -1,16 +1,18 @@
|
||||
from module.base.utils import random_rectangle_vector
|
||||
from module.campaign.campaign_base import CampaignBase as CampaignBase_
|
||||
from module.exception import RequestHumanTakeover
|
||||
from module.logger import logger
|
||||
from module.ui.assets import WAR_ARCHIVES_CHECK
|
||||
from module.ui.page import page_archives
|
||||
from module.ui.scroll import Scroll
|
||||
from module.ui.switch import Switch
|
||||
from module.war_archives.assets import WAR_ARCHIVES_EX_ON, WAR_ARCHIVES_SP_ON, WAR_ARCHIVES_CAMPAIGN_CHECK
|
||||
from module.war_archives.assets import WAR_ARCHIVES_EX_ON, WAR_ARCHIVES_SP_ON, \
|
||||
WAR_ARCHIVES_CAMPAIGN_CHECK, WAR_ARCHIVES_SCROLL
|
||||
from module.war_archives.dictionary import dic_archives_template
|
||||
|
||||
WAR_ARCHIVES_SWITCH = Switch('War_Archives_switch', is_selector=True)
|
||||
WAR_ARCHIVES_SWITCH.add_status('ex', WAR_ARCHIVES_EX_ON)
|
||||
WAR_ARCHIVES_SWITCH.add_status('sp', WAR_ARCHIVES_SP_ON)
|
||||
WAR_ARCHIVES_SCROLL = Scroll(WAR_ARCHIVES_SCROLL, color=(247, 211, 66), name='WAR_ARCHIVES_SCROLL')
|
||||
|
||||
|
||||
class CampaignBase(CampaignBase_):
|
||||
@ -53,8 +55,6 @@ class CampaignBase(CampaignBase_):
|
||||
Fixed number of scrolls until give up, may need to
|
||||
increase as more war archives campaigns are added
|
||||
"""
|
||||
detection_area = (565, 125, 700, 675)
|
||||
|
||||
for _ in range(10):
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
@ -73,12 +73,11 @@ class CampaignBase(CampaignBase_):
|
||||
if entrance is not None:
|
||||
return entrance
|
||||
|
||||
# backup = self.config.cover(DEVICE_CONTROL_METHOD='minitouch')
|
||||
p1, p2 = random_rectangle_vector(
|
||||
(0, -275), box=detection_area, random_range=(-50, -50, 50, 50), padding=20)
|
||||
self.device.drag(p1, p2, segments=2, shake=(0, 25), point_random=(0, 0, 0, 0), shake_random=(0, -5, 0, 5))
|
||||
# backup.recover()
|
||||
self.device.sleep(0.3)
|
||||
if WAR_ARCHIVES_SCROLL.appear(main=self):
|
||||
WAR_ARCHIVES_SCROLL.next_page(main=self)
|
||||
continue
|
||||
else:
|
||||
break
|
||||
|
||||
logger.warning('Failed to find archives entrance')
|
||||
return None
|
||||
|
@ -147,7 +147,8 @@ def ensure_time(second, n=3, precision=3):
|
||||
"""
|
||||
if isinstance(second, tuple):
|
||||
multiply = 10 ** precision
|
||||
return random_normal_distribution_int(second[0] * multiply, second[1] * multiply, n) / multiply
|
||||
result = random_normal_distribution_int(second[0] * multiply, second[1] * multiply, n) / multiply
|
||||
return round(result, precision)
|
||||
elif isinstance(second, str):
|
||||
if ',' in second:
|
||||
lower, upper = second.replace(' ', '').split(',')
|
||||
@ -163,6 +164,29 @@ def ensure_time(second, n=3, precision=3):
|
||||
return second
|
||||
|
||||
|
||||
def ensure_int(*args):
|
||||
"""
|
||||
Convert all elements to int.
|
||||
Return the same structure as nested objects.
|
||||
|
||||
Args:
|
||||
*args:
|
||||
|
||||
Returns:
|
||||
list:
|
||||
"""
|
||||
def to_int(item):
|
||||
try:
|
||||
return int(item)
|
||||
except TypeError:
|
||||
result = [to_int(i) for i in item]
|
||||
if len(result) == 1:
|
||||
result = result[0]
|
||||
return result
|
||||
|
||||
return to_int(args)
|
||||
|
||||
|
||||
def area_offset(area, offset):
|
||||
"""
|
||||
|
||||
|
@ -506,5 +506,5 @@ def type_to_str(typ):
|
||||
str: Such as `int`, 'datetime.datetime'.
|
||||
"""
|
||||
if not isinstance(typ, type):
|
||||
typ = type(typ)
|
||||
return str(typ).strip("<class '>").replace('<', '_').replace('>', '_')
|
||||
typ = type(typ).__name__
|
||||
return str(typ)
|
||||
|
@ -1,3 +1,4 @@
|
||||
from module.base.button import Button
|
||||
from module.base.timer import Timer
|
||||
from module.base.utils import *
|
||||
from module.device.method.hermit import Hermit
|
||||
@ -21,6 +22,7 @@ class Control(Hermit, Uiautomator2, Minitouch):
|
||||
if control_check:
|
||||
self.handle_control_check(button)
|
||||
x, y = random_rectangle_point(button.button)
|
||||
x, y = ensure_int(x, y)
|
||||
logger.info(
|
||||
'Click %s @ %s' % (point2str(x, y), button)
|
||||
)
|
||||
@ -54,6 +56,7 @@ class Control(Hermit, Uiautomator2, Minitouch):
|
||||
"""
|
||||
self.handle_control_check(button)
|
||||
x, y = random_rectangle_point(button.button)
|
||||
x, y = ensure_int(x, y)
|
||||
duration = ensure_time(duration)
|
||||
logger.info(
|
||||
'Click %s @ %s, %s' % (point2str(x, y), button, duration)
|
||||
@ -68,10 +71,18 @@ class Control(Hermit, Uiautomator2, Minitouch):
|
||||
|
||||
def swipe(self, p1, p2, duration=(0.1, 0.2), name='SWIPE', distance_check=True):
|
||||
self.handle_control_check(name)
|
||||
p1, p2 = ensure_int(p1, p2)
|
||||
duration = ensure_time(duration)
|
||||
logger.info(
|
||||
'Swipe %s -> %s, %s' % (point2str(*p1), point2str(*p2), duration)
|
||||
)
|
||||
method = self.config.Emulator_ControlMethod
|
||||
if method == 'minitouch':
|
||||
logger.info('Swipe %s -> %s' % (point2str(*p1), point2str(*p2)))
|
||||
elif method == 'uiautomator2':
|
||||
logger.info('Swipe %s -> %s, %s' % (point2str(*p1), point2str(*p2), duration))
|
||||
else:
|
||||
# ADB needs to be slow, or swipe doesn't work
|
||||
duration *= 2.5
|
||||
logger.info('Swipe %s -> %s, %s' % (point2str(*p1), point2str(*p2), duration))
|
||||
|
||||
if distance_check:
|
||||
if np.linalg.norm(np.subtract(p1, p2)) < 10:
|
||||
# Should swipe a certain distance, otherwise AL will treat it as click.
|
||||
@ -79,7 +90,6 @@ class Control(Hermit, Uiautomator2, Minitouch):
|
||||
logger.info('Swipe distance < 10px, dropped')
|
||||
return
|
||||
|
||||
method = self.config.Emulator_ControlMethod
|
||||
if method == 'minitouch':
|
||||
self.swipe_minitouch(p1, p2)
|
||||
elif method == 'uiautomator2':
|
||||
@ -116,14 +126,21 @@ class Control(Hermit, Uiautomator2, Minitouch):
|
||||
self.swipe(p1, p2, duration=duration, name=name, distance_check=distance_check)
|
||||
|
||||
def drag(self, p1, p2, segments=1, shake=(0, 15), point_random=(-10, -10, 10, 10), shake_random=(-5, -5, 5, 5),
|
||||
swipe_duration=0.25, shake_duration=0.1):
|
||||
swipe_duration=0.25, shake_duration=0.1, name='DRAG'):
|
||||
self.handle_control_check(name)
|
||||
p1, p2 = ensure_int(p1, p2)
|
||||
logger.info(
|
||||
'Drag %s -> %s' % (point2str(*p1), point2str(*p2))
|
||||
)
|
||||
method = self.config.Emulator_ControlMethod
|
||||
if method == 'minitouch':
|
||||
self.drag_minitouch(p1, p2, point_random=point_random)
|
||||
else:
|
||||
elif method == 'uiautomator2':
|
||||
self.drag_uiautomator2(
|
||||
p1, p2, segments=segments, shake=shake, point_random=point_random, shake_random=shake_random,
|
||||
swipe_duration=swipe_duration, shake_duration=shake_duration)
|
||||
else:
|
||||
logger.warning(f'Control method {method} does not support drag well, '
|
||||
f'falling back to ADB swipe may cause unexpected behaviour')
|
||||
self.swipe_adb(p1, p2, duration=ensure_time(swipe_duration * 2))
|
||||
self.click(Button(area=(), color=(), button=area_offset(point_random, p2), name=name))
|
||||
|
@ -95,8 +95,9 @@ class Adb(Connection):
|
||||
self.adb_shell(['input', 'tap', x, y])
|
||||
|
||||
@retry
|
||||
def swipe_adb(self, fx, fy, tx, ty, duration=0.1):
|
||||
self.adb_shell(['input', 'swipe', fx, fy, tx, ty, duration])
|
||||
def swipe_adb(self, p1, p2, duration=0.1):
|
||||
duration = int(duration * 1000)
|
||||
self.adb_shell(['input', 'swipe', *p1, *p2, duration])
|
||||
|
||||
@retry
|
||||
def app_current_adb(self):
|
||||
|
@ -91,7 +91,7 @@ class RewardDorm(UI):
|
||||
self.device.minitouch_builder.up().commit()
|
||||
self.device.minitouch_send()
|
||||
|
||||
@Config.when(DEVICE_CONTROL_METHOD=None)
|
||||
@Config.when(DEVICE_CONTROL_METHOD='uiautomator2')
|
||||
def _dorm_feed_long_tap(self, button, count):
|
||||
timeout = Timer(count // 5 + 5).start()
|
||||
x, y = random_rectangle_point(button.button)
|
||||
@ -112,7 +112,13 @@ class RewardDorm(UI):
|
||||
|
||||
self.device.u2.touch.up(x, y)
|
||||
|
||||
def dorm_receive(self):
|
||||
@Config.when(DEVICE_CONTROL_METHOD=None)
|
||||
def _dorm_feed_long_tap(self, button, count):
|
||||
logger.warning(f'Current control method {self.config.Emulator_ControlMethod} '
|
||||
f'does not support DOWN/UP events, use multi-click instead')
|
||||
self.device.multi_click(button, count)
|
||||
|
||||
def dorm_collect(self):
|
||||
"""
|
||||
Click all coins and loves on current screen.
|
||||
Zoom-out dorm to detect coins and loves, because swipes in dorm may treat as dragging ships.
|
||||
@ -122,6 +128,12 @@ class RewardDorm(UI):
|
||||
in: page_dorm, without info_bar
|
||||
out: page_dorm, without info_bar
|
||||
"""
|
||||
logger.hr('Dorm collect')
|
||||
if self.config.Emulator_ControlMethod not in ['uiautomator2', 'minitouch']:
|
||||
logger.warning(f'Current control method {self.config.Emulator_ControlMethod} '
|
||||
f'does not support 2 finger zoom out, skip dorm collect')
|
||||
return
|
||||
|
||||
for _ in range(2):
|
||||
logger.info('Dorm zoom out')
|
||||
# Left hand down
|
||||
@ -282,7 +294,7 @@ class RewardDorm(UI):
|
||||
self.ui_goto(page_dorm, skip_first_screenshot=True)
|
||||
|
||||
if collect:
|
||||
self.dorm_receive()
|
||||
self.dorm_collect()
|
||||
|
||||
if feed:
|
||||
self.ui_click(click_button=DORM_FEED_ENTER, appear_button=DORM_CHECK, check_button=DORM_FEED_CHECK,
|
||||
|
@ -1,7 +1,6 @@
|
||||
from module.base.button import ButtonGrid
|
||||
from module.base.decorator import cached_property
|
||||
from module.base.timer import Timer
|
||||
from module.base.utils import *
|
||||
from module.shop.assets import *
|
||||
from module.ui.assets import BACK_ARROW
|
||||
from module.ui.navbar import Navbar
|
||||
@ -117,11 +116,7 @@ class ShopUI(UI):
|
||||
self.appear(SHOP_GENERAL_SWIPE_END, offset=(15, 5)):
|
||||
return True
|
||||
|
||||
# backup = self.config.cover(DEVICE_CONTROL_METHOD='minitouch')
|
||||
p1, p2 = random_rectangle_vector(
|
||||
(480, 0), box=detection_area, random_range=(-50, -50, 50, 50), padding=20)
|
||||
self.device.drag(p1, p2, segments=2, shake=(0, 25), point_random=(0, 0, 0, 0), shake_random=(0, -5, 0, 5))
|
||||
# backup.recover()
|
||||
self.device.swipe_vector((480, 0), box=detection_area, random_range=(-50, -10, 50, 10), padding=0)
|
||||
self.device.sleep(0.3)
|
||||
|
||||
return False
|
||||
@ -142,3 +137,7 @@ class ShopUI(UI):
|
||||
self.ui_ensure(page_munitions)
|
||||
|
||||
return self._shop_swipe()
|
||||
if __name__ == '__main__':
|
||||
self = ShopUI('alas')
|
||||
self.device.screenshot()
|
||||
self._shop_swipe()
|
@ -136,7 +136,7 @@ class Scroll:
|
||||
if self.drag_interval.reached():
|
||||
p1 = random_rectangle_point(self.position_to_screen(current), n=1)
|
||||
p2 = random_rectangle_point(self.position_to_screen(position, random_range=random_range), n=1)
|
||||
main.device.drag(p1, p2, shake=(0, 0), point_random=(0, 0, 0, 0), shake_random=(0, 0, 0, 0))
|
||||
main.device.swipe(p1, p2)
|
||||
main.device.sleep(0.3)
|
||||
self.drag_interval.reset()
|
||||
|
||||
@ -162,7 +162,7 @@ class Scroll:
|
||||
|
||||
multiply = self.length / (self.total - self.length)
|
||||
target = current + page * multiply
|
||||
target = min(max(target, 0), 1)
|
||||
target = round(min(max(target, 0), 1), 3)
|
||||
self.set(target, main=main, random_range=random_range, skip_first_screenshot=True)
|
||||
|
||||
def next_page(self, main, random_range=(-0.01, 0.01), skip_first_screenshot=True):
|
||||
|
@ -18,5 +18,6 @@ TEMPLATE_WINTERS_CROWN = Template(file={'cn': './assets/cn/war_archives/TEMPLATE
|
||||
WAR_ARCHIVES_CAMPAIGN_CHECK = Button(area={'cn': (1150, 101, 1166, 130), 'en': (1150, 101, 1166, 130), 'jp': (1150, 101, 1166, 130), 'tw': (1150, 101, 1166, 130)}, color={'cn': (134, 175, 207), 'en': (134, 175, 207), 'jp': (134, 175, 207), 'tw': (134, 175, 207)}, button={'cn': (1150, 101, 1166, 130), 'en': (1150, 101, 1166, 130), 'jp': (1150, 101, 1166, 130), 'tw': (1150, 101, 1166, 130)}, file={'cn': './assets/cn/war_archives/WAR_ARCHIVES_CAMPAIGN_CHECK.png', 'en': './assets/en/war_archives/WAR_ARCHIVES_CAMPAIGN_CHECK.png', 'jp': './assets/jp/war_archives/WAR_ARCHIVES_CAMPAIGN_CHECK.png', 'tw': './assets/tw/war_archives/WAR_ARCHIVES_CAMPAIGN_CHECK.png'})
|
||||
WAR_ARCHIVES_EX_OFF = Button(area={'cn': (908, 42, 991, 72), 'en': (908, 42, 991, 72), 'jp': (908, 42, 991, 72), 'tw': (908, 42, 991, 72)}, color={'cn': (40, 42, 56), 'en': (40, 42, 56), 'jp': (40, 42, 56), 'tw': (40, 42, 56)}, button={'cn': (908, 42, 991, 72), 'en': (908, 42, 991, 72), 'jp': (908, 42, 991, 72), 'tw': (908, 42, 991, 72)}, file={'cn': './assets/cn/war_archives/WAR_ARCHIVES_EX_OFF.png', 'en': './assets/en/war_archives/WAR_ARCHIVES_EX_OFF.png', 'jp': './assets/jp/war_archives/WAR_ARCHIVES_EX_OFF.png', 'tw': './assets/tw/war_archives/WAR_ARCHIVES_EX_OFF.png'})
|
||||
WAR_ARCHIVES_EX_ON = Button(area={'cn': (903, 42, 994, 72), 'en': (903, 42, 994, 72), 'jp': (903, 42, 994, 72), 'tw': (903, 42, 994, 72)}, color={'cn': (75, 93, 151), 'en': (75, 93, 151), 'jp': (75, 93, 151), 'tw': (75, 93, 151)}, button={'cn': (903, 42, 994, 72), 'en': (903, 42, 994, 72), 'jp': (903, 42, 994, 72), 'tw': (903, 42, 994, 72)}, file={'cn': './assets/cn/war_archives/WAR_ARCHIVES_EX_ON.png', 'en': './assets/en/war_archives/WAR_ARCHIVES_EX_ON.png', 'jp': './assets/jp/war_archives/WAR_ARCHIVES_EX_ON.png', 'tw': './assets/tw/war_archives/WAR_ARCHIVES_EX_ON.png'})
|
||||
WAR_ARCHIVES_SCROLL = Button(area={'cn': (1253, 130, 1260, 695), 'en': (1253, 130, 1260, 695), 'jp': (1253, 130, 1260, 695), 'tw': (1253, 130, 1260, 695)}, color={'cn': (142, 131, 75), 'en': (142, 131, 75), 'jp': (142, 131, 75), 'tw': (142, 131, 75)}, button={'cn': (1253, 130, 1260, 695), 'en': (1253, 130, 1260, 695), 'jp': (1253, 130, 1260, 695), 'tw': (1253, 130, 1260, 695)}, file={'cn': './assets/cn/war_archives/WAR_ARCHIVES_SCROLL.png', 'en': './assets/en/war_archives/WAR_ARCHIVES_SCROLL.png', 'jp': './assets/jp/war_archives/WAR_ARCHIVES_SCROLL.png', 'tw': './assets/tw/war_archives/WAR_ARCHIVES_SCROLL.png'})
|
||||
WAR_ARCHIVES_SP_OFF = Button(area={'cn': (1012, 43, 1095, 71), 'en': (1012, 43, 1095, 71), 'jp': (1012, 43, 1095, 71), 'tw': (1012, 43, 1095, 71)}, color={'cn': (40, 42, 56), 'en': (40, 42, 56), 'jp': (40, 42, 56), 'tw': (40, 42, 56)}, button={'cn': (1012, 43, 1095, 71), 'en': (1012, 43, 1095, 71), 'jp': (1012, 43, 1095, 71), 'tw': (1012, 43, 1095, 71)}, file={'cn': './assets/cn/war_archives/WAR_ARCHIVES_SP_OFF.png', 'en': './assets/en/war_archives/WAR_ARCHIVES_SP_OFF.png', 'jp': './assets/jp/war_archives/WAR_ARCHIVES_SP_OFF.png', 'tw': './assets/tw/war_archives/WAR_ARCHIVES_SP_OFF.png'})
|
||||
WAR_ARCHIVES_SP_ON = Button(area={'cn': (1010, 43, 1095, 71), 'en': (1010, 43, 1095, 71), 'jp': (1010, 43, 1095, 71), 'tw': (1010, 43, 1095, 71)}, color={'cn': (77, 95, 152), 'en': (77, 95, 152), 'jp': (77, 95, 152), 'tw': (77, 95, 152)}, button={'cn': (1010, 43, 1095, 71), 'en': (1010, 43, 1095, 71), 'jp': (1010, 43, 1095, 71), 'tw': (1010, 43, 1095, 71)}, file={'cn': './assets/cn/war_archives/WAR_ARCHIVES_SP_ON.png', 'en': './assets/en/war_archives/WAR_ARCHIVES_SP_ON.png', 'jp': './assets/jp/war_archives/WAR_ARCHIVES_SP_ON.png', 'tw': './assets/tw/war_archives/WAR_ARCHIVES_SP_ON.png'})
|
||||
|
Loading…
Reference in New Issue
Block a user