mirror of
https://github.com/0O0o0oOoO00/Alas.git
synced 2026-05-15 03:19:25 +08:00
Merge branch 'LmeSzinc:master' into 20230309
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
import socket
|
||||
import threading
|
||||
from functools import wraps
|
||||
|
||||
from adbutils.errors import AdbError
|
||||
|
||||
from module.base.decorator import cached_property, del_cached_property
|
||||
from module.base.decorator import cached_property, del_cached_property, has_cached_property
|
||||
from module.base.timer import Timer
|
||||
from module.base.utils import *
|
||||
from module.device.connection import Connection
|
||||
from module.device.method.minitouch import CommandBuilder, insert_swipe
|
||||
from module.device.method.utils import RETRY_TRIES, retry_sleep, handle_adb_error
|
||||
from module.device.method.utils import RETRY_TRIES, handle_adb_error, retry_sleep
|
||||
from module.exception import RequestHumanTakeover
|
||||
from module.logger import logger
|
||||
|
||||
@@ -36,20 +37,20 @@ def retry(func):
|
||||
|
||||
def init():
|
||||
self.adb_reconnect()
|
||||
del_cached_property(self, 'maatouch_builder')
|
||||
del_cached_property(self, '_maatouch_builder')
|
||||
# Emulator closed
|
||||
except ConnectionAbortedError as e:
|
||||
logger.error(e)
|
||||
|
||||
def init():
|
||||
self.adb_reconnect()
|
||||
del_cached_property(self, 'maatouch_builder')
|
||||
del_cached_property(self, '_maatouch_builder')
|
||||
# AdbError
|
||||
except AdbError as e:
|
||||
if handle_adb_error(e):
|
||||
def init():
|
||||
self.adb_reconnect()
|
||||
del_cached_property(self, 'maatouch_builder')
|
||||
del_cached_property(self, '_maatouch_builder')
|
||||
else:
|
||||
break
|
||||
# MaaTouchNotInstalledError: Received "Aborted" from MaaTouch
|
||||
@@ -58,12 +59,12 @@ def retry(func):
|
||||
|
||||
def init():
|
||||
self.maatouch_install()
|
||||
del_cached_property(self, 'maatouch_builder')
|
||||
del_cached_property(self, '_maatouch_builder')
|
||||
except BrokenPipeError as e:
|
||||
logger.error(e)
|
||||
|
||||
def init():
|
||||
del_cached_property(self, 'maatouch_builder')
|
||||
del_cached_property(self, '_maatouch_builder')
|
||||
# Unknown, probably a trucked image
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
@@ -77,6 +78,19 @@ def retry(func):
|
||||
return retry_wrapper
|
||||
|
||||
|
||||
class MaatouchBuilder(CommandBuilder):
|
||||
def __init__(self, device, contact=0, handle_orientation=False):
|
||||
"""
|
||||
Args:
|
||||
device (MaaTouch):
|
||||
"""
|
||||
|
||||
super().__init__(device, contact, handle_orientation)
|
||||
|
||||
def send(self):
|
||||
return self.device.maatouch_send(builder=self)
|
||||
|
||||
|
||||
class MaaTouchNotInstalledError(Exception):
|
||||
pass
|
||||
|
||||
@@ -90,12 +104,37 @@ class MaaTouch(Connection):
|
||||
max_y: int
|
||||
_maatouch_stream = socket.socket
|
||||
_maatouch_stream_storage = None
|
||||
_maatouch_init_thread = None
|
||||
|
||||
@cached_property
|
||||
def maatouch_builder(self):
|
||||
def _maatouch_builder(self):
|
||||
self.maatouch_init()
|
||||
# Orientation is handled inside MaaTouch
|
||||
return CommandBuilder(self, handle_orientation=False)
|
||||
return MaatouchBuilder(self)
|
||||
|
||||
@property
|
||||
def maatouch_builder(self):
|
||||
# Wait init thread
|
||||
if self._maatouch_init_thread is not None:
|
||||
self._maatouch_init_thread.join()
|
||||
del self._maatouch_init_thread
|
||||
self._maatouch_init_thread = None
|
||||
|
||||
return self._maatouch_builder
|
||||
|
||||
def early_maatouch_init(self):
|
||||
"""
|
||||
Start a thread to init maatouch connection while the Alas instance just starting to take screenshots
|
||||
This would speed up the first click 0.2 ~ 0.4s.
|
||||
"""
|
||||
if has_cached_property(self, '_maatouch_builder'):
|
||||
return
|
||||
|
||||
def early_maatouch_init_func():
|
||||
_ = self._maatouch_builder
|
||||
|
||||
thread = threading.Thread(target=early_maatouch_init_func, daemon=True)
|
||||
self._maatouch_init_thread = thread
|
||||
thread.start()
|
||||
|
||||
def maatouch_init(self):
|
||||
logger.hr('MaaTouch init')
|
||||
@@ -166,14 +205,14 @@ class MaaTouch(Connection):
|
||||
)
|
||||
)
|
||||
|
||||
def maatouch_send(self):
|
||||
content = self.maatouch_builder.to_minitouch()
|
||||
def maatouch_send(self, builder: MaatouchBuilder):
|
||||
content = builder.to_minitouch()
|
||||
# logger.info("send operation: {}".format(content.replace("\n", "\\n")))
|
||||
byte_content = content.encode('utf-8')
|
||||
self._maatouch_stream.sendall(byte_content)
|
||||
self._maatouch_stream.recv(0)
|
||||
self.sleep(self.maatouch_builder.delay / 1000 + self.maatouch_builder.DEFAULT_DELAY)
|
||||
self.maatouch_builder.clear()
|
||||
self.sleep(self.maatouch_builder.delay / 1000 + builder.DEFAULT_DELAY)
|
||||
builder.clear()
|
||||
|
||||
def maatouch_install(self):
|
||||
logger.hr('MaaTouch install')
|
||||
@@ -188,7 +227,7 @@ class MaaTouch(Connection):
|
||||
builder = self.maatouch_builder
|
||||
builder.down(x, y).commit()
|
||||
builder.up().commit()
|
||||
self.maatouch_send()
|
||||
builder.send()
|
||||
|
||||
@retry
|
||||
def long_click_maatouch(self, x, y, duration=1.0):
|
||||
@@ -196,7 +235,7 @@ class MaaTouch(Connection):
|
||||
builder = self.maatouch_builder
|
||||
builder.down(x, y).commit().wait(duration)
|
||||
builder.up().commit()
|
||||
self.maatouch_send()
|
||||
builder.send()
|
||||
|
||||
@retry
|
||||
def swipe_maatouch(self, p1, p2):
|
||||
@@ -204,14 +243,14 @@ class MaaTouch(Connection):
|
||||
builder = self.maatouch_builder
|
||||
|
||||
builder.down(*points[0]).commit()
|
||||
self.maatouch_send()
|
||||
builder.send()
|
||||
|
||||
for point in points[1:]:
|
||||
builder.move(*point).commit().wait(10)
|
||||
self.maatouch_send()
|
||||
builder.send()
|
||||
|
||||
builder.up().commit()
|
||||
self.maatouch_send()
|
||||
builder.send()
|
||||
|
||||
@retry
|
||||
def drag_maatouch(self, p1, p2, point_random=(-10, -10, 10, 10)):
|
||||
@@ -221,15 +260,15 @@ class MaaTouch(Connection):
|
||||
builder = self.maatouch_builder
|
||||
|
||||
builder.down(*points[0]).commit()
|
||||
self.maatouch_send()
|
||||
builder.send()
|
||||
|
||||
for point in points[1:]:
|
||||
builder.move(*point).commit().wait(10)
|
||||
self.maatouch_send()
|
||||
builder.send()
|
||||
|
||||
builder.move(*p2).commit().wait(140)
|
||||
builder.move(*p2).commit().wait(140)
|
||||
self.maatouch_send()
|
||||
builder.send()
|
||||
|
||||
builder.up().commit()
|
||||
self.maatouch_send()
|
||||
builder.send()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import asyncio
|
||||
import json
|
||||
import re
|
||||
import socket
|
||||
import threading
|
||||
import time
|
||||
from functools import wraps
|
||||
from typing import List
|
||||
@@ -10,11 +10,11 @@ import websockets
|
||||
from adbutils.errors import AdbError
|
||||
from uiautomator2 import _Service
|
||||
|
||||
from module.base.decorator import Config, cached_property, del_cached_property
|
||||
from module.base.decorator import Config, cached_property, del_cached_property, has_cached_property
|
||||
from module.base.timer import Timer
|
||||
from module.base.utils import *
|
||||
from module.device.connection import Connection
|
||||
from module.device.method.utils import RETRY_TRIES, retry_sleep, handle_adb_error
|
||||
from module.device.method.utils import RETRY_TRIES, handle_adb_error, retry_sleep
|
||||
from module.exception import RequestHumanTakeover, ScriptError
|
||||
from module.logger import logger
|
||||
|
||||
@@ -184,7 +184,7 @@ class CommandBuilder:
|
||||
max_x = 1280
|
||||
max_y = 720
|
||||
|
||||
def __init__(self, device, handle_orientation=True):
|
||||
def __init__(self, device, contact=0, handle_orientation=True):
|
||||
"""
|
||||
Args:
|
||||
device:
|
||||
@@ -192,6 +192,7 @@ class CommandBuilder:
|
||||
self.device = device
|
||||
self.commands = []
|
||||
self.delay = 0
|
||||
self.contact = contact
|
||||
self.handle_orientation = handle_orientation
|
||||
|
||||
@property
|
||||
@@ -243,21 +244,21 @@ class CommandBuilder:
|
||||
self.delay += ms
|
||||
return self
|
||||
|
||||
def up(self, contact=0):
|
||||
def up(self):
|
||||
""" add minitouch command: 'u <contact>\n' """
|
||||
self.commands.append(Command('u', contact=contact))
|
||||
self.commands.append(Command('u', contact=self.contact))
|
||||
return self
|
||||
|
||||
def down(self, x, y, contact=0, pressure=100):
|
||||
def down(self, x, y, pressure=100):
|
||||
""" add minitouch command: 'd <contact> <x> <y> <pressure>\n' """
|
||||
x, y = self.convert(x, y)
|
||||
self.commands.append(Command('d', x=x, y=y, contact=contact, pressure=pressure))
|
||||
self.commands.append(Command('d', x=x, y=y, contact=self.contact, pressure=pressure))
|
||||
return self
|
||||
|
||||
def move(self, x, y, contact=0, pressure=100):
|
||||
def move(self, x, y, pressure=100):
|
||||
""" add minitouch command: 'm <contact> <x> <y> <pressure>\n' """
|
||||
x, y = self.convert(x, y)
|
||||
self.commands.append(Command('m', x=x, y=y, contact=contact, pressure=pressure))
|
||||
self.commands.append(Command('m', x=x, y=y, contact=self.contact, pressure=pressure))
|
||||
return self
|
||||
|
||||
def clear(self):
|
||||
@@ -271,6 +272,9 @@ class CommandBuilder:
|
||||
def to_atx_agent(self) -> List[str]:
|
||||
return [command.to_atx_agent(self.max_x, self.max_y) for command in self.commands]
|
||||
|
||||
def send(self):
|
||||
return self.device.minitouch_send(builder=self)
|
||||
|
||||
|
||||
class MinitouchNotInstalledError(Exception):
|
||||
pass
|
||||
@@ -324,7 +328,7 @@ def retry(func):
|
||||
self.install_uiautomator2()
|
||||
if self._minitouch_port:
|
||||
self.adb_forward_remove(f'tcp:{self._minitouch_port}')
|
||||
del_cached_property(self, 'minitouch_builder')
|
||||
del_cached_property(self, '_minitouch_builder')
|
||||
# MinitouchOccupiedError: Timeout when connecting to minitouch
|
||||
except MinitouchOccupiedError as e:
|
||||
logger.error(e)
|
||||
@@ -333,7 +337,7 @@ def retry(func):
|
||||
self.restart_atx()
|
||||
if self._minitouch_port:
|
||||
self.adb_forward_remove(f'tcp:{self._minitouch_port}')
|
||||
del_cached_property(self, 'minitouch_builder')
|
||||
del_cached_property(self, '_minitouch_builder')
|
||||
# AdbError
|
||||
except AdbError as e:
|
||||
if handle_adb_error(e):
|
||||
@@ -345,7 +349,7 @@ def retry(func):
|
||||
logger.error(e)
|
||||
|
||||
def init():
|
||||
del_cached_property(self, 'minitouch_builder')
|
||||
del_cached_property(self, '_minitouch_builder')
|
||||
# Unknown, probably a trucked image
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
@@ -366,12 +370,38 @@ class Minitouch(Connection):
|
||||
_minitouch_ws: websockets.WebSocketClientProtocol
|
||||
max_x: int
|
||||
max_y: int
|
||||
_minitouch_init_thread = None
|
||||
|
||||
@cached_property
|
||||
def minitouch_builder(self):
|
||||
def _minitouch_builder(self):
|
||||
self.minitouch_init()
|
||||
return CommandBuilder(self)
|
||||
|
||||
@property
|
||||
def minitouch_builder(self):
|
||||
# Wait init thread
|
||||
if self._minitouch_init_thread is not None:
|
||||
self._minitouch_init_thread.join()
|
||||
del self._minitouch_init_thread
|
||||
self._minitouch_init_thread = None
|
||||
|
||||
return self._minitouch_builder
|
||||
|
||||
def early_minitouch_init(self):
|
||||
"""
|
||||
Start a thread to init minitouch connection while the Alas instance just starting to take screenshots
|
||||
This would speed up the first click 0.05s.
|
||||
"""
|
||||
if has_cached_property(self, '_minitouch_builder'):
|
||||
return
|
||||
|
||||
def early_minitouch_init_func():
|
||||
_ = self._minitouch_builder
|
||||
|
||||
thread = threading.Thread(target=early_minitouch_init_func, daemon=True)
|
||||
self._minitouch_init_thread = thread
|
||||
thread.start()
|
||||
|
||||
@Config.when(DEVICE_OVER_HTTP=False)
|
||||
def minitouch_init(self):
|
||||
logger.hr('MiniTouch init')
|
||||
@@ -446,14 +476,14 @@ class Minitouch(Connection):
|
||||
)
|
||||
|
||||
@Config.when(DEVICE_OVER_HTTP=False)
|
||||
def minitouch_send(self):
|
||||
content = self.minitouch_builder.to_minitouch()
|
||||
def minitouch_send(self, builder: CommandBuilder):
|
||||
content = builder.to_minitouch()
|
||||
# logger.info("send operation: {}".format(content.replace("\n", "\\n")))
|
||||
byte_content = content.encode('utf-8')
|
||||
self._minitouch_client.sendall(byte_content)
|
||||
self._minitouch_client.recv(0)
|
||||
time.sleep(self.minitouch_builder.delay / 1000 + self.minitouch_builder.DEFAULT_DELAY)
|
||||
self.minitouch_builder.clear()
|
||||
time.sleep(self.minitouch_builder.delay / 1000 + builder.DEFAULT_DELAY)
|
||||
builder.clear()
|
||||
|
||||
@cached_property
|
||||
def _minitouch_loop(self):
|
||||
@@ -514,8 +544,8 @@ class Minitouch(Connection):
|
||||
self._minitouch_ws = self._minitouch_loop_run(connect())
|
||||
|
||||
@Config.when(DEVICE_OVER_HTTP=True)
|
||||
def minitouch_send(self):
|
||||
content = self.minitouch_builder.to_atx_agent()
|
||||
def minitouch_send(self, builder: CommandBuilder):
|
||||
content = builder.to_atx_agent()
|
||||
|
||||
async def send():
|
||||
for row in content:
|
||||
@@ -523,15 +553,15 @@ class Minitouch(Connection):
|
||||
await self._minitouch_ws.send(row)
|
||||
|
||||
self._minitouch_loop_run(send())
|
||||
time.sleep(self.minitouch_builder.delay / 1000 + self.minitouch_builder.DEFAULT_DELAY)
|
||||
self.minitouch_builder.clear()
|
||||
time.sleep(builder.delay / 1000 + builder.DEFAULT_DELAY)
|
||||
builder.clear()
|
||||
|
||||
@retry
|
||||
def click_minitouch(self, x, y):
|
||||
builder = self.minitouch_builder
|
||||
builder.down(x, y).commit()
|
||||
builder.up().commit()
|
||||
self.minitouch_send()
|
||||
builder.send()
|
||||
|
||||
@retry
|
||||
def long_click_minitouch(self, x, y, duration=1.0):
|
||||
@@ -539,7 +569,7 @@ class Minitouch(Connection):
|
||||
builder = self.minitouch_builder
|
||||
builder.down(x, y).commit().wait(duration)
|
||||
builder.up().commit()
|
||||
self.minitouch_send()
|
||||
builder.send()
|
||||
|
||||
@retry
|
||||
def swipe_minitouch(self, p1, p2):
|
||||
@@ -547,14 +577,14 @@ class Minitouch(Connection):
|
||||
builder = self.minitouch_builder
|
||||
|
||||
builder.down(*points[0]).commit()
|
||||
self.minitouch_send()
|
||||
builder.send()
|
||||
|
||||
for point in points[1:]:
|
||||
builder.move(*point).commit().wait(10)
|
||||
self.minitouch_send()
|
||||
builder.send()
|
||||
|
||||
builder.up().commit()
|
||||
self.minitouch_send()
|
||||
builder.send()
|
||||
|
||||
@retry
|
||||
def drag_minitouch(self, p1, p2, point_random=(-10, -10, 10, 10)):
|
||||
@@ -564,15 +594,15 @@ class Minitouch(Connection):
|
||||
builder = self.minitouch_builder
|
||||
|
||||
builder.down(*points[0]).commit()
|
||||
self.minitouch_send()
|
||||
builder.send()
|
||||
|
||||
for point in points[1:]:
|
||||
builder.move(*point).commit().wait(10)
|
||||
self.minitouch_send()
|
||||
builder.send()
|
||||
|
||||
builder.move(*p2).commit().wait(140)
|
||||
builder.move(*p2).commit().wait(140)
|
||||
self.minitouch_send()
|
||||
builder.send()
|
||||
|
||||
builder.up().commit()
|
||||
self.minitouch_send()
|
||||
builder.send()
|
||||
|
||||
@@ -2,7 +2,7 @@ import asyncio
|
||||
import ctypes
|
||||
import os
|
||||
import sys
|
||||
from functools import wraps, partial
|
||||
from functools import partial, wraps
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
@@ -147,6 +147,8 @@ class CaptureNemuIpc(CaptureStd):
|
||||
# MuMuVMMSVC.exe died
|
||||
# b'nemu_capture_display rpc error: 1726\r\n'
|
||||
# No idea how to handle yet
|
||||
if b'error: 1722' in self.stderr or b'error: 1726' in self.stderr:
|
||||
raise NemuIpcError('Emulator instance is probably dead')
|
||||
|
||||
|
||||
def retry(func):
|
||||
@@ -172,7 +174,7 @@ def retry(func):
|
||||
break
|
||||
# Function call timeout
|
||||
except asyncio.TimeoutError:
|
||||
logger.warning(f'Func {func.__name__}() call timeout, retrying')
|
||||
logger.warning(f'Func {func.__name__}() call timeout, retrying: {_}')
|
||||
|
||||
def init():
|
||||
self.reconnect()
|
||||
@@ -236,11 +238,10 @@ class NemuIpcImpl:
|
||||
if self.connect_id > 0:
|
||||
return
|
||||
|
||||
with CaptureNemuIpc():
|
||||
connect_id = self.ev_run_sync(
|
||||
self.lib.nemu_connect,
|
||||
self.nemu_folder, self.instance_id
|
||||
)
|
||||
connect_id = self.ev_run_sync(
|
||||
self.lib.nemu_connect,
|
||||
self.nemu_folder, self.instance_id
|
||||
)
|
||||
if connect_id == 0:
|
||||
raise NemuIpcError(
|
||||
'Connection failed, please check if nemu_folder is correct and emulator is running'
|
||||
@@ -253,11 +254,10 @@ class NemuIpcImpl:
|
||||
if self.connect_id == 0:
|
||||
return
|
||||
|
||||
with CaptureNemuIpc():
|
||||
self.ev_run_sync(
|
||||
self.lib.nemu_disconnect,
|
||||
self.connect_id
|
||||
)
|
||||
self.ev_run_sync(
|
||||
self.lib.nemu_disconnect,
|
||||
self.connect_id
|
||||
)
|
||||
|
||||
# logger.info(f'NemuIpc disconnected: {self.connect_id}')
|
||||
self.connect_id = 0
|
||||
@@ -288,7 +288,9 @@ class NemuIpcImpl:
|
||||
asyncio.TimeoutError: If function call timeout
|
||||
"""
|
||||
func_wrapped = partial(func, *args, **kwargs)
|
||||
result = await asyncio.wait_for(self._ev.run_in_executor(None, func_wrapped), timeout=0.05)
|
||||
# Increased timeout for slow PCs
|
||||
# Default screenshot interval is 0.2s, so a 0.15s timeout would have a fast retry without extra time costs
|
||||
result = await asyncio.wait_for(self._ev.run_in_executor(None, func_wrapped), timeout=0.15)
|
||||
return result
|
||||
|
||||
def ev_run_sync(self, func, *args, **kwargs):
|
||||
@@ -300,8 +302,24 @@ class NemuIpcImpl:
|
||||
|
||||
Raises:
|
||||
asyncio.TimeoutError: If function call timeout
|
||||
NemuIpcIncompatible:
|
||||
NemuIpcError
|
||||
"""
|
||||
result = self._ev.run_until_complete(self.ev_run_async(func, *args, **kwargs))
|
||||
|
||||
err = False
|
||||
if func.__name__ == 'nemu_connect':
|
||||
if result == 0:
|
||||
err = True
|
||||
else:
|
||||
if result > 0:
|
||||
err = True
|
||||
# Get to actual error message printed in std
|
||||
if err:
|
||||
logger.warning(f'Failed to call {func.__name__}, result={result}')
|
||||
with CaptureNemuIpc():
|
||||
result = self._ev.run_until_complete(self.ev_run_async(func, *args, **kwargs))
|
||||
|
||||
return result
|
||||
|
||||
def get_resolution(self):
|
||||
@@ -315,11 +333,10 @@ class NemuIpcImpl:
|
||||
height_ptr = ctypes.pointer(ctypes.c_int(0))
|
||||
nullptr = ctypes.POINTER(ctypes.c_int)()
|
||||
|
||||
with CaptureNemuIpc():
|
||||
ret = self.ev_run_sync(
|
||||
self.lib.nemu_capture_display,
|
||||
self.connect_id, self.display_id, 0, width_ptr, height_ptr, nullptr
|
||||
)
|
||||
ret = self.ev_run_sync(
|
||||
self.lib.nemu_capture_display,
|
||||
self.connect_id, self.display_id, 0, width_ptr, height_ptr, nullptr
|
||||
)
|
||||
if ret > 0:
|
||||
raise NemuIpcError('nemu_capture_display failed during get_resolution()')
|
||||
self.width = width_ptr.contents.value
|
||||
@@ -335,18 +352,17 @@ class NemuIpcImpl:
|
||||
if self.connect_id == 0:
|
||||
self.connect()
|
||||
|
||||
with CaptureNemuIpc():
|
||||
self.get_resolution()
|
||||
self.get_resolution()
|
||||
|
||||
width_ptr = ctypes.pointer(ctypes.c_int(self.width))
|
||||
height_ptr = ctypes.pointer(ctypes.c_int(self.height))
|
||||
length = self.width * self.height * 4
|
||||
pixels_pointer = ctypes.pointer((ctypes.c_ubyte * length)())
|
||||
width_ptr = ctypes.pointer(ctypes.c_int(self.width))
|
||||
height_ptr = ctypes.pointer(ctypes.c_int(self.height))
|
||||
length = self.width * self.height * 4
|
||||
pixels_pointer = ctypes.pointer((ctypes.c_ubyte * length)())
|
||||
|
||||
ret = self.ev_run_sync(
|
||||
self.lib.nemu_capture_display,
|
||||
self.connect_id, self.display_id, length, width_ptr, height_ptr, pixels_pointer
|
||||
)
|
||||
ret = self.ev_run_sync(
|
||||
self.lib.nemu_capture_display,
|
||||
self.connect_id, self.display_id, length, width_ptr, height_ptr, pixels_pointer
|
||||
)
|
||||
if ret > 0:
|
||||
raise NemuIpcError('nemu_capture_display failed during screenshot()')
|
||||
|
||||
@@ -378,11 +394,10 @@ class NemuIpcImpl:
|
||||
|
||||
x, y = self.convert_xy(x, y)
|
||||
|
||||
with CaptureNemuIpc():
|
||||
ret = self.ev_run_sync(
|
||||
self.lib.nemu_input_event_touch_down,
|
||||
self.connect_id, self.display_id, x, y
|
||||
)
|
||||
ret = self.ev_run_sync(
|
||||
self.lib.nemu_input_event_touch_down,
|
||||
self.connect_id, self.display_id, x, y
|
||||
)
|
||||
if ret > 0:
|
||||
raise NemuIpcError('nemu_input_event_touch_down failed')
|
||||
|
||||
@@ -394,11 +409,10 @@ class NemuIpcImpl:
|
||||
if self.connect_id == 0:
|
||||
self.connect()
|
||||
|
||||
with CaptureNemuIpc():
|
||||
ret = self.ev_run_sync(
|
||||
self.lib.nemu_input_event_touch_up,
|
||||
self.connect_id, self.display_id
|
||||
)
|
||||
ret = self.ev_run_sync(
|
||||
self.lib.nemu_input_event_touch_up,
|
||||
self.connect_id, self.display_id
|
||||
)
|
||||
if ret > 0:
|
||||
raise NemuIpcError('nemu_input_event_touch_up failed')
|
||||
|
||||
@@ -448,7 +462,9 @@ class NemuIpc(Platform):
|
||||
# Search emulator instance
|
||||
# with E:\ProgramFiles\MuMuPlayer-12.0\shell\MuMuPlayer.exe
|
||||
# installation path is E:\ProgramFiles\MuMuPlayer-12.0
|
||||
_ = self.emulator_instance
|
||||
if self.emulator_instance is None:
|
||||
logger.error('Unable to use NemuIpc because emulator instance not found')
|
||||
raise RequestHumanTakeover
|
||||
try:
|
||||
return NemuIpcImpl(
|
||||
nemu_folder=self.emulator_instance.emulator.abspath('../'),
|
||||
@@ -486,44 +502,40 @@ class NemuIpc(Platform):
|
||||
|
||||
def click_nemu_ipc(self, x, y):
|
||||
down = ensure_time((0.010, 0.020))
|
||||
with CaptureNemuIpc():
|
||||
self.nemu_ipc.down(x, y)
|
||||
self.sleep(down)
|
||||
self.nemu_ipc.up()
|
||||
self.sleep(0.050 - down)
|
||||
self.nemu_ipc.down(x, y)
|
||||
self.sleep(down)
|
||||
self.nemu_ipc.up()
|
||||
self.sleep(0.050 - down)
|
||||
|
||||
def long_click_nemu_ipc(self, x, y, duration=1.0):
|
||||
with CaptureNemuIpc():
|
||||
self.nemu_ipc.down(x, y)
|
||||
self.sleep(duration)
|
||||
self.nemu_ipc.up()
|
||||
self.sleep(0.050)
|
||||
self.nemu_ipc.down(x, y)
|
||||
self.sleep(duration)
|
||||
self.nemu_ipc.up()
|
||||
self.sleep(0.050)
|
||||
|
||||
def swipe_nemu_ipc(self, p1, p2):
|
||||
points = insert_swipe(p0=p1, p3=p2)
|
||||
|
||||
with CaptureNemuIpc():
|
||||
for point in points:
|
||||
self.nemu_ipc.down(*point)
|
||||
self.sleep(0.010)
|
||||
for point in points:
|
||||
self.nemu_ipc.down(*point)
|
||||
self.sleep(0.010)
|
||||
|
||||
self.nemu_ipc.up()
|
||||
self.sleep(0.050)
|
||||
self.nemu_ipc.up()
|
||||
self.sleep(0.050)
|
||||
|
||||
def drag_nemu_ipc(self, p1, p2, point_random=(-10, -10, 10, 10)):
|
||||
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)
|
||||
|
||||
with CaptureNemuIpc():
|
||||
for point in points:
|
||||
self.nemu_ipc.down(*point)
|
||||
self.sleep(0.010)
|
||||
for point in points:
|
||||
self.nemu_ipc.down(*point)
|
||||
self.sleep(0.010)
|
||||
|
||||
self.nemu_ipc.down(*p2)
|
||||
self.sleep(0.140)
|
||||
self.nemu_ipc.down(*p2)
|
||||
self.sleep(0.140)
|
||||
self.nemu_ipc.down(*p2)
|
||||
self.sleep(0.140)
|
||||
self.nemu_ipc.down(*p2)
|
||||
self.sleep(0.140)
|
||||
|
||||
self.nemu_ipc.up()
|
||||
self.sleep(0.050)
|
||||
self.nemu_ipc.up()
|
||||
self.sleep(0.050)
|
||||
|
||||
Reference in New Issue
Block a user