Add: hold_duration for drag method

This commit is contained in:
guoh064 2026-05-12 15:33:30 +08:00
parent 8ea0de943e
commit ca35147c9f
6 changed files with 53 additions and 12 deletions

View File

@ -148,7 +148,7 @@ class Control(Hermit, Minitouch, Scrcpy, MaaTouch, NemuIpc):
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, name='DRAG'):
swipe_duration=0.25, shake_duration=0.1, hold_duration=0.0, name='DRAG'):
self.handle_control_check(name)
p1, p2 = ensure_int(p1, p2)
logger.info(
@ -156,19 +156,22 @@ class Control(Hermit, Minitouch, Scrcpy, MaaTouch, NemuIpc):
)
method = self.config.Emulator_ControlMethod
if method == 'minitouch':
self.drag_minitouch(p1, p2, point_random=point_random)
self.drag_minitouch(p1, p2, point_random=point_random, hold_duration=hold_duration)
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)
swipe_duration=swipe_duration, shake_duration=shake_duration, hold_duration=hold_duration)
elif method == 'scrcpy':
self.drag_scrcpy(p1, p2, point_random=point_random)
self.drag_scrcpy(p1, p2, point_random=point_random, hold_duration=hold_duration)
elif method == 'MaaTouch':
self.drag_maatouch(p1, p2, point_random=point_random)
self.drag_maatouch(p1, p2, point_random=point_random, hold_duration=hold_duration)
elif method == 'nemu_ipc':
self.drag_nemu_ipc(p1, p2, point_random=point_random)
self.drag_nemu_ipc(p1, p2, point_random=point_random, hold_duration=hold_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))
hold_duration = ensure_time(hold_duration)
if hold_duration > 0:
self.sleep(hold_duration)
self.click(Button(area=(), color=(), button=area_offset(point_random, p2), name=name), False)

View File

@ -367,7 +367,7 @@ class MaaTouch(Connection):
builder.send_sync()
@retry
def drag_maatouch(self, p1, p2, point_random=(-10, -10, 10, 10)):
def drag_maatouch(self, p1, p2, point_random=(-10, -10, 10, 10), hold_duration=0.0):
p1 = np.array(p1) - random_rectangle_point(point_random)
p2 = np.array(p2) - random_rectangle_point(point_random)
points = insert_swipe(p0=p1, p3=p2, speed=20)
@ -384,6 +384,12 @@ class MaaTouch(Connection):
builder.move(*p2).commit().wait(140)
builder.send_sync()
hold_duration = ensure_time(hold_duration) - 0.28
hold_ms = int(max(0.0, hold_duration) * 1000)
if hold_ms > 0:
builder.move(*p2).commit().wait(hold_ms)
builder.send_sync()
builder.up().commit()
builder.send_sync()

View File

@ -694,7 +694,7 @@ class Minitouch(Connection):
builder.send()
@retry
def drag_minitouch(self, p1, p2, point_random=(-10, -10, 10, 10)):
def drag_minitouch(self, p1, p2, point_random=(-10, -10, 10, 10), hold_duration=0.0):
p1 = np.array(p1) - random_rectangle_point(point_random)
p2 = np.array(p2) - random_rectangle_point(point_random)
points = insert_swipe(p0=p1, p3=p2, speed=20)
@ -711,5 +711,11 @@ class Minitouch(Connection):
builder.move(*p2).commit().wait(140)
builder.send()
hold_duration = ensure_time(hold_duration) - 0.28
hold_ms = int(max(0.0, hold_duration) * 1000)
if hold_ms > 0:
builder.move(*p2).commit().wait(hold_ms)
builder.send()
builder.up().commit()
builder.send()

View File

@ -616,7 +616,7 @@ class NemuIpc(Platform):
self.nemu_ipc.up()
self.sleep(0.050)
def drag_nemu_ipc(self, p1, p2, point_random=(-10, -10, 10, 10)):
def drag_nemu_ipc(self, p1, p2, point_random=(-10, -10, 10, 10), hold_duration=0.0):
p1 = np.array(p1) - random_rectangle_point(point_random)
p2 = np.array(p2) - random_rectangle_point(point_random)
points = insert_swipe(p0=p1, p3=p2, speed=20)
@ -630,5 +630,10 @@ class NemuIpc(Platform):
self.nemu_ipc.down(*p2)
self.sleep(0.140)
hold_duration = ensure_time(hold_duration) - 0.28
if hold_duration > 0:
self.nemu_ipc.down(*p2)
self.sleep(hold_duration)
self.nemu_ipc.up()
self.sleep(0.050)

View File

@ -6,7 +6,7 @@ import numpy as np
from adbutils.errors import AdbError, AdbTimeout
import module.device.method.scrcpy.const as const
from module.base.utils import random_rectangle_point
from module.base.utils import ensure_time, random_rectangle_point
from module.device.method.minitouch import insert_swipe
from module.device.method.scrcpy.core import ScrcpyCore, ScrcpyError
from module.device.method.uiautomator_2 import Uiautomator2
@ -143,7 +143,7 @@ class Scrcpy(ScrcpyCore, Uiautomator2):
self.sleep(0.05)
@retry
def drag_scrcpy(self, p1, p2, point_random=(-10, -10, 10, 10)):
def drag_scrcpy(self, p1, p2, point_random=(-10, -10, 10, 10), hold_duration=0.0):
self.scrcpy_ensure_running()
with self._scrcpy_control_socket_lock:
@ -162,5 +162,17 @@ class Scrcpy(ScrcpyCore, Uiautomator2):
self._scrcpy_control.touch(*p2, const.ACTION_MOVE)
self.sleep(0.002)
hold_duration = ensure_time(hold_duration) - 0.28
if hold_duration > 0:
step = 0.002
repeats = int(hold_duration // step)
for _ in range(repeats):
self._scrcpy_control.touch(*p2, const.ACTION_MOVE)
self.sleep(step)
remainder = hold_duration - (repeats * step)
if remainder > 0:
self._scrcpy_control.touch(*p2, const.ACTION_MOVE)
self.sleep(remainder)
self._scrcpy_control.touch(*p2, const.ACTION_UP)
self.sleep(0.05)

View File

@ -187,7 +187,8 @@ class Uiautomator2(Connection):
self.sleep(second)
def drag_uiautomator2(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):
shake_random=(-5, -5, 5, 5), swipe_duration=0.25, shake_duration=0.1,
hold_duration=0.0):
"""Drag and shake, like:
/\
+-----------+ + +
@ -204,6 +205,7 @@ class Uiautomator2(Connection):
shake_random: Add random to shake array.
swipe_duration: Duration between way points.
shake_duration: Duration between shake points.
hold_duration: Hold time before release.
"""
p1 = np.array(p1) - random_rectangle_point(point_random)
p2 = np.array(p2) - random_rectangle_point(point_random)
@ -213,6 +215,13 @@ class Uiautomator2(Connection):
(*p2 - shake - random_rectangle_point(shake_random), shake_duration),
(*p2, shake_duration)
]
internal_hold = ensure_time(shake_duration) * 3
hold_duration = ensure_time(hold_duration) - internal_hold
if hold_duration > 0:
path += [
(*p2, hold_duration),
(*p2, 0),
]
path = [(int(x), int(y), d) for x, y, d in path]
self._drag_along(path)