Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,28 @@ OAS 在其基础上进行了如下优化:
- [安装教程](https://runhey.github.io/OnmyojiAutoScript-website/docs/user-manual/installation): 保姆式安装手册,多翻翻有惊喜
- [开发文档](https://runhey.github.io/OnmyojiAutoScript-website/docs/development/preamble): 虽然迭代很多、年久失修,但入门开发必读,具体以源码为准

## macOS PlayCover / MaaTools

### 中文

macOS 用户可以通过 [PlayCover](https://github.com/PlayCover/PlayCover) 运行 iOS 版游戏,并使用 MaaTools 连接 OAS。环境准备可参考 [MAA macOS 手册](https://docs.maa.plus/zh-cn/manual/device/macos.html)。

1. 从 [OASX Flutter 源码](https://github.com/runhey/OASX) 编译并运行本地 app。
2. 按 [`requirements-macos-playcover.txt`](requirements-macos-playcover.txt) 清单手动安装依赖。
3. 在 PlayCover 中将游戏设置为 `1280x720`。
4. 在 OASX 中选择 `PlayCover` / `MacPlayTools`,截图方式选择 `MacBGR`、`RGBA` 或 `MacSCK`;serial 示例为 `localhost:1718`。
5. `ADB` 与 `minitouch` 仍然保留,可继续用于原有的 Android/模拟器配置。

### English

On macOS, run the iOS game with [PlayCover](https://github.com/PlayCover/PlayCover) and connect OAS through MaaTools. See the [MAA macOS guide](https://docs.maa.plus/zh-cn/manual/device/macos.html) for environment setup.

1. Build and run a local app from the [OASX Flutter source](https://github.com/runhey/OASX).
2. Manually install the dependencies listed in [`requirements-macos-playcover.txt`](requirements-macos-playcover.txt).
3. Set the game in PlayCover to `1280x720`.
4. In OASX, choose `PlayCover` / `MacPlayTools`, then select `MacBGR`, `RGBA`, or `MacSCK` as the screenshot method; example serial: `localhost:1718`.
5. `ADB` and `minitouch` remain available for existing Android/emulator configurations.

## 鸣谢 Acknowledgements

感谢所有参与到开发/测试中的朋友们
Expand All @@ -123,4 +145,4 @@ OAS 在其基础上进行了如下优化:

![](https://profile-counter.glitch.me/runhey-OnmyojiAutoScript/count.svg)

</div>
</div>
11 changes: 11 additions & 0 deletions module/device/app_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ def app_is_alive(self, package_name=None) -> bool:

这用于区分“应用被切到后台”和“应用已经被真正杀掉”两种情况。
"""
if getattr(self, 'is_playcover', False):
return True
if not package_name:
package_name = self.package

Expand All @@ -31,6 +33,8 @@ def app_is_alive(self, package_name=None) -> bool:
return bool(result)

def app_is_running(self) -> bool:
if getattr(self, 'is_playcover', False):
return True
method = self.config.script.device.control_method
# if self.is_wsa:
# package = self.app_current_wsa()
Expand All @@ -44,6 +48,8 @@ def app_is_running(self) -> bool:
return package == self.package

def app_start(self):
if getattr(self, 'is_playcover', False):
return
method = self.config.script.device.screenshot_method
logger.info(f'App start: {self.package}')
# if self.config.Emulator_Serial == 'wsa-0':
Expand All @@ -54,6 +60,8 @@ def app_start(self):
self.app_start_adb()

def app_stop(self):
if getattr(self, 'is_playcover', False):
return
method = self.config.script.device.screenshot_method
logger.info(f'App stop: {self.package}')
if method in AppControl._app_u2_family:
Expand All @@ -66,6 +74,9 @@ def dump_hierarchy(self) -> etree._Element:
Returns:
etree._Element: Select elements with `self.hierarchy.xpath('//*[@text="Hermit"]')` for example.
"""
if getattr(self, 'is_playcover', False):
self.hierarchy = etree.Element('hierarchy')
return self.hierarchy
method = self.config.script.device.screenshot_method
if method in AppControl._app_u2_family:
self.hierarchy = self.dump_hierarchy_uiautomator2()
Expand Down
11 changes: 11 additions & 0 deletions module/device/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from module.base.decorator import Config, cached_property, del_cached_property
from module.base.utils import ensure_time
from module.device.connection_attr import ConnectionAttr
from module.device.method.playcover import PlayCoverClient
from module.device.method.utils import (
RETRY_TRIES, remove_shell_warning, retry_sleep,
handle_adb_error, PackageNotInstalled,
Expand Down Expand Up @@ -95,6 +96,16 @@ def __init__(self, config):
config (AzurLaneConfig, str): Name of the user config under ./config
"""
super().__init__(config)
if self.is_playcover:
self.playcover_client = PlayCoverClient(
self.serial,
screenshot_mode=self.config.script.device.screenshot_method,
)
self.playcover_client.connect()
self.package = 'com.netease.onmyoji'
logger.attr('PackageName', self.package)
return

if not self.is_over_http:
self.detect_device()

Expand Down
10 changes: 7 additions & 3 deletions module/device/connection_attr.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ def __init__(self, config):
else:
self.config = config

self.serial = str(self.config.script.device.serial)
self.is_playcover = self.config.script.device.control_method == 'MacPlayTools'
if self.is_playcover:
self.config.DEVICE_OVER_HTTP = False
logger.attr('PlayCover', self.serial)
return

# Init adb client
logger.attr('AdbBinary', self.adb_binary)
# Monkey patch to custom adb
Expand Down Expand Up @@ -65,7 +72,6 @@ def __init__(self, config):

# Parse custom serial
# self.serial = str(self.config.Emulator_Serial)
self.serial = str(self.config.script.device.serial)
self.serial_check()
self.config.DEVICE_OVER_HTTP = self.is_over_http

Expand Down Expand Up @@ -282,5 +288,3 @@ def u2(self) -> u2.Device:

logger.attr('u2.Device', f'Device(atx_agent_url={device._get_atx_agent_url()})')
return device


26 changes: 24 additions & 2 deletions module/device/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def click_methods(self):
'ADB': self.click_adb,
'uiautomator2': self.click_uiautomator2,
'minitouch': self.click_minitouch,
'MacPlayTools': self.click_playcover,
# 'Hermit': self.click_hermit,
# 'MaaTouch': self.click_maatouch,
}
Expand All @@ -47,7 +48,8 @@ def long_click_methods(self):
'ADB': self.long_click_adb,
'uiautomator2': self.long_click_uiautomator2,
'minitouch': self.long_click_minitouch,
'scrcpy': self.long_click_scrcpy
'scrcpy': self.long_click_scrcpy,
'MacPlayTools': self.long_click_playcover,
# 'Hermit': self.click_hermit,
# 'MaaTouch': self.click_maatouch,
}
Expand Down Expand Up @@ -119,6 +121,15 @@ def long_click(self, x: int, y: int, duration=(0.5, 2), control_name='LongClick'
elapsed = time.perf_counter() - start
logger.info(f'{self._format_action_duration(elapsed)}Click {point2str(x, y)} @ {control_name} {duration}')

def click_playcover(self, x, y):
self.playcover_client.click(x, y)

def long_click_playcover(self, x, y, duration=0.8):
self.playcover_client.long_click(x, y, duration=duration)

def swipe_playcover(self, p1, p2, duration=0.1):
self.playcover_client.swipe(p1, p2, duration=duration)

def swipe(self, p1, p2, duration=(0.1, 0.2), control_name='SWIPE', distance_check=True):
self.handle_control_check(control_name)
p1, p2 = ensure_int(p1, p2)
Expand All @@ -133,6 +144,8 @@ def swipe(self, p1, p2, duration=(0.1, 0.2), control_name='SWIPE', distance_chec
swipe_log = 'Swipe %s -> %s, %s' % (point2str(*p1), point2str(*p2), duration)
elif method == 'scrcpy':
swipe_log = 'Swipe %s -> %s' % (point2str(*p1), point2str(*p2))
elif method == 'MacPlayTools':
swipe_log = 'Swipe %s -> %s, %s' % (point2str(*p1), point2str(*p2), duration)
# elif method == 'MaaTouch':
# logger.info('Swipe %s -> %s' % (point2str(*p1), point2str(*p2)))
else:
Expand Down Expand Up @@ -164,6 +177,8 @@ def swipe(self, p1, p2, duration=(0.1, 0.2), control_name='SWIPE', distance_chec
self.swipe_uiautomator2(p1, p2, duration=duration)
elif method == 'scrcpy':
self.swipe_scrcpy(p1, p2)
elif method == 'MacPlayTools':
self.swipe_playcover(p1, p2, duration=duration)
# elif method == 'MaaTouch':
# self.swipe_maatouch(p1, p2)
else:
Expand Down Expand Up @@ -204,7 +219,12 @@ def drag(self, p1, p2, segments=1, shake=(0, 15), point_random=(-10, -10, 10, 10
self.handle_control_check(name)
p1, p2 = ensure_int(p1, p2)
drag_log = 'Drag %s -> %s' % (point2str(*p1), point2str(*p2))
method = self.config.script.emulator.control_method
configured_method = self.config.script.device.control_method
if configured_method == 'MacPlayTools' or getattr(self, 'is_playcover', False):
method = configured_method
self._invalidate_image_batch_cache()
else:
method = self.config.script.emulator.control_method
start = time.perf_counter()
if method == 'minitouch':
self.drag_minitouch(p1, p2, point_random=point_random)
Expand All @@ -214,6 +234,8 @@ def drag(self, p1, p2, segments=1, shake=(0, 15), point_random=(-10, -10, 10, 10
swipe_duration=swipe_duration, shake_duration=shake_duration)
elif method == 'scrcpy':
self.drag_scrcpy(p1, p2, point_random=point_random)
elif method == 'MacPlayTools':
self.playcover_client.swipe(p1, p2, duration=ensure_time(swipe_duration))
# elif method == 'MaaTouch':
# self.drag_maatouch(p1, p2, point_random=point_random)
else:
Expand Down
Loading