From 1b1bc15aca8859f039cb56f7b79377832c8e6e05 Mon Sep 17 00:00:00 2001 From: srdr0p Date: Sun, 26 Apr 2026 23:48:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=85=BE=E8=AE=AF?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E5=AE=9D=205.10.56.xx=20(#16292)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(connection): 新增腾讯应用宝模拟器支持 在 WinAdapter 和 config.json 中添加应用宝(Androws)模拟器入口。 本次仅支持 ADB Input 方式和官方渠道。 同步更新各语言连接文档(zh/en/ja/ko/tw)及 UI 本地化字符串。 * feat(controller): 为腾讯应用宝新增多渠道与 Minitouch 支持 应用宝的应用与 DisplayId 绑定,需在 connect() 前确定包名。 新增 InstanceOptionKey::ClientType (= 6),经由 AsstSetInstanceOption -> Assistant::set_instance_option -> Controller::set_client_type 传递渠道信息; AdbController::connect 在建立连接时通过 ctrler()->get_client_type() 读取并写入 AdbConnectionContext,用于替换命令模板中的 [PackageName]。 引入 AdbConnectionContext 保存 ADB 连接信息供 Minitouch 使用, 并通过 eventId 标识所绑定的输入设备。 --- docs/en-us/manual/connection.md | 2 + docs/en-us/manual/device/windows.md | 5 + docs/ja-jp/manual/connection.md | 1 + docs/ja-jp/manual/device/windows.md | 5 + docs/ko-kr/manual/connection.md | 2 + docs/ko-kr/manual/device/windows.md | 5 + docs/zh-cn/manual/connection.md | 2 + docs/zh-cn/manual/device/windows.md | 10 +- docs/zh-tw/manual/connection.md | 2 + docs/zh-tw/manual/device/windows.md | 10 +- resource/config.json | 13 +++ src/MaaCore/Assistant.cpp | 3 + src/MaaCore/Common/AsstTypes.h | 1 + src/MaaCore/Config/GeneralConfig.cpp | 1 + src/MaaCore/Config/GeneralConfig.h | 1 + src/MaaCore/Controller/AdbController.cpp | 96 +++++++++++-------- src/MaaCore/Controller/AdbController.h | 49 ++++++++++ src/MaaCore/Controller/Controller.cpp | 46 ++++----- src/MaaCore/Controller/Controller.h | 10 +- .../Controller/MinitouchController.cpp | 79 +++++---------- src/MaaCore/Controller/MinitouchController.h | 2 +- src/MaaWpfGui/Helper/WinAdapter.cs | 45 +++++++++ src/MaaWpfGui/Main/AsstProxy.cs | 7 ++ src/MaaWpfGui/Res/Localizations/en-us.xaml | 1 + src/MaaWpfGui/Res/Localizations/ja-jp.xaml | 1 + src/MaaWpfGui/Res/Localizations/ko-kr.xaml | 1 + src/MaaWpfGui/Res/Localizations/zh-cn.xaml | 1 + src/MaaWpfGui/Res/Localizations/zh-tw.xaml | 1 + .../ConnectSettingsUserControlModel.cs | 2 + 29 files changed, 267 insertions(+), 137 deletions(-) diff --git a/docs/en-us/manual/connection.md b/docs/en-us/manual/connection.md index 3f4e2cf258..6073b0ee63 100644 --- a/docs/en-us/manual/connection.md +++ b/docs/en-us/manual/connection.md @@ -16,6 +16,7 @@ As of MAA v5.22.3, the following emulators and connection addresses are supporte - LDPlayer 9: `emulator-5554/5556/5558/5560`, `127.0.0.1:5555/5557/5559/5561` - NoxPlayer: `127.0.0.1:62001/59865` - MEmu Play: `127.0.0.1:21503` +- Tencent App Store (after 5.10.56.xx): `127.0.0.1:5555` If detection fails, try launching MAA with UAC administrator privileges and detect again. If it still fails, refer to the manual setup instructions below and verify that your emulator and connection address are included in the list above. @@ -57,6 +58,7 @@ Emulators running on your local machine should use addresses like `127.0.0.1:\adb.exe`. For other emulators, refer to [Zhao Qingqing's blog](https://www.cnblogs.com/zhaoqingqing/p/15238464.html). diff --git a/docs/en-us/manual/device/windows.md b/docs/en-us/manual/device/windows.md index 5c98d965e9..11e31f76e9 100644 --- a/docs/en-us/manual/device/windows.md +++ b/docs/en-us/manual/device/windows.md @@ -40,6 +40,11 @@ const fullySupport = [ note: 'Fully compatible. Need to turn on ADB Connectivity in the emulator `Settings` → `Advanced` → `Android Debug Bridge` → `Enable`. Known to be compatible with Hyper-V.\n\n- Recommended to download [Offline Installer](https://support.bluestacks.com/hc/en-us/articles/4402611273485-BlueStacks-5-offline-installer) to avoid slow and bundled installation; recommend installing [Android 11](https://support.bluestacks.com/hc/en-us/articles/4402611273485-BlueStacks-5-offline-installer#:~:text=To%20install%20BlueStacks%205%20Android%2011) version; to uninstall it, please use the official [Uninstall Tool](https://support.bluestacks.com/hc/en-us/articles/360057724751-How-to-uninstall-BlueStacks-5-BlueStacks-X-and-BlueStacks-Services-completely-from-your-PC) to get rid of residues.\n- If the ADB port number keeps changing irregularly and is different every time you start it, it may be because your computer has [Hyper-V](https://support.bluestacks.com/hc/en-us/articles/4415238471053-System-requirements-for-BlueStacks-5-on-Hyper-V-enabled-Windows-10-and-11) enabled. MAA will now try to automatically read the port number from the BlueStacks emulator configuration file. If this doesn\'t work, or you need to use multiple instances, or have installed multiple emulator cores, please refer to [Connection Settings](../connection.html#bluestacks-emulator-hyper-v-port-number-changes-every-startup) to make adjustments. Since Hyper-V runs as administrator, operations that don\'t involve ADB such as automatic emulator shutdown or connection detection also need MAA to run as administrator.', }, ...shuffleArray([ + { + name: 'Tencent App Store', + link: 'https://sj.qq.com/', + note: 'Supports versions after 5.10.56.xx. Select `Tencent App Store` connection configuration in `Settings` - `Connection Settings`. Known to be compatible with Hyper-V.\n\n- ADB port is `127.0.0.1:5555`.\n- ADB path example: `C:\\Program Files\\Tencent\\Androws\\Application\\\\adb.exe`.\n\n- You need to first [enable ADB debugging](https://sj.qq.com/faq/3878) in the app.', + }, { name: 'Nox Player', link: 'https://www.bignox.com/', diff --git a/docs/ja-jp/manual/connection.md b/docs/ja-jp/manual/connection.md index e620d5a0a8..0ee79edd43 100644 --- a/docs/ja-jp/manual/connection.md +++ b/docs/ja-jp/manual/connection.md @@ -43,6 +43,7 @@ icon: mdi:plug - [MuMu Pro](https://mumu.163.com/mac/function/20240126/40028_1134600.html) `16384` - [逍遥](https://bbs.xyaz.cn/forum.php?mod=viewthread&tid=365537) `21503` - [夜神](https://support.yeshen.com/zh-CN/qt/ml) `62001` +- [テンセントアプリストア](https://sj.qq.com/faq/3878) (5.10.56.xx 以降):ADB ポートは `127.0.0.1:5555` 固定。ADB パス例:`C:\Program Files\Tencent\Androws\Application\バージョン番号\adb.exe`。 他のエミュレータについては[Zhaoqingqing's Blog](https://www.cnblogs.com/zhaoqingqing/p/15238464.html)を参照してください。 diff --git a/docs/ja-jp/manual/device/windows.md b/docs/ja-jp/manual/device/windows.md index fe293dbf98..aa673c495f 100644 --- a/docs/ja-jp/manual/device/windows.md +++ b/docs/ja-jp/manual/device/windows.md @@ -40,6 +40,11 @@ const fullySupport = [ note: 'サポートされています。エミュレーターの `設定` - `上位設定` で `Android Debug Bridge`をONにする必要があります。\n\n- ネットワーク環境が悪い場合は [オフラインパッケージ](https://support.bluestacks.com/hc/zh-tw/articles/4402611273485-BlueStacks-5-%E9%9B%A2%E7%B7%9A%E5%AE%89%E8%A3%9D%E7%A8%8B%E5%BC%8F)をダウンロードしてください。\n- adbポート番号が不規則に変化し続け、起動するたびに同じでない場合は、お使いのコンピュータが [Hyper-V](https://support.bluestacks.com/hc/ja/articles/4415238471053-BlueStacks-5-Hyper-V%E3%81%8C%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8BWindows-10%E3%81%A8Windows-11%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E8%A6%81%E4%BB%B6)を有効にしている可能性があります,\nこのような状況に対して、MAAはポート番号を自動的に取得する小さなバックドアを提供しています。この機能がは動作しません/複数のエミュレータが必要/複数のエミュレータコアがインストールされているの場合は [よくある質問](../よくある質問.html#blue-stackエミュレータが起動するたびにポート番号が異なるhyper-v) を参照して変更してください。Hyper-V は管理者として実行されるため、エミュレーターの自動シャットダウンや接続の自動検出など、adb を伴わない操作でも MAA を管理者として実行する必要があります。', }, ...shuffleArray([ + { + name: 'テンセントアプリストア', + link: 'https://sj.qq.com/', + note: 'バージョン 5.10.56.xx 以降をサポートしています。`設定` - `接続設定` で `テンセントアプリストア` 接続設定を選択してください。Hyper-V との互換性が確認されています。\n\n- ADB ポートは `127.0.0.1:5555` です。\n- ADB パス例:`C:\\Program Files\\Tencent\\Androws\\Application\\バージョン番号\\adb.exe`。\n\n- 事前にアプリストアで [ADB デバッグを有効化](https://sj.qq.com/faq/3878) する必要があります。', + }, { name: 'NOX', link: 'https://www.yeshen.com/', diff --git a/docs/ko-kr/manual/connection.md b/docs/ko-kr/manual/connection.md index f215da25b0..028a96217c 100644 --- a/docs/ko-kr/manual/connection.md +++ b/docs/ko-kr/manual/connection.md @@ -16,6 +16,7 @@ MAA v5.22.3까지 지원하는 감지 가능한 에뮬레이터 및 연결 주 - LDPlayer 9: `emulator-5554/5556/5558/5560`, `127.0.0.1:5555/5557/5559/5561` - 逍遥(Xiaoyao): `127.0.0.1:62001/59865` - 夜神(Yeshen): `127.0.0.1:21503` +- 텐센트 앱스토어 (5.10.56.xx 이후): `127.0.0.1:5555` 감지에 실패하면 UAC 관리자 권한으로 MAA를 시작하여 다시 감지해보세요. 여전히 실패한다면 아래 수동 설정을 참고하고, 에뮬레이터와 연결 주소가 위 목록에 포함되어 있는지 확인하세요. @@ -59,6 +60,7 @@ MAA 폴더에 직접 압축을 푸는 것을 권장합니다. 그러면 ADB 경 - [LDPlayer 9](https://help.ldmnq.com/docs/LD9adbserver#edc3863750608062bcb3feea256413dc) `emulator-5554` - [逍遥(Xiaoyao)](https://bbs.xyaz.cn/forum.php?mod=viewthread&tid=365537) `21503` - [夜神(Yeshen)](https://support.yeshen.com/zh-CN/qt/ml) `62001` +- [텐센트 앱스토어](https://sj.qq.com/faq/3878): ADB 포트는 `127.0.0.1:5555` 고정. ADB 경로 예시: `C:\Program Files\Tencent\Androws\Application\버전번호\adb.exe`. 기타 에뮬레이터는 [赵青青의 블로그](https://www.cnblogs.com/zhaoqingqing/p/15238464.html)를 참고하세요. diff --git a/docs/ko-kr/manual/device/windows.md b/docs/ko-kr/manual/device/windows.md index c7d5909992..7cfa0e3bbc 100644 --- a/docs/ko-kr/manual/device/windows.md +++ b/docs/ko-kr/manual/device/windows.md @@ -40,6 +40,11 @@ const fullySupport = [ note: '완전히 호환됩니다. 에뮬레이터의 `설정` - `고급 설정`에서 `ADB 기능`을 켜야 합니다. Hyper-V와 호환되는 것으로 알려져 있습니다.\n\n- 느리고 번들로 제공되는 설치를 피하기 위해 [오프라인 설치 프로그램](https://support.bluestacks.com/hc/en-us/articles/4402611273485-BlueStacks-5-offline-installer)을 다운로드하는 것이 좋습니다; [Android 11](https://support.bluestacks.com/hc/en-us/articles/4402611273485-BlueStacks-5-offline-installer#:~:text=To%20install%20BlueStacks%205%20Android%2011) 버전 설치를 권장합니다; 제거하려면 공식 [제거 도구](https://support.bluestacks.com/hc/en-us/articles/360057724751-How-to-uninstall-BlueStacks-5-BlueStacks-X-and-BlueStacks-Services-completely-from-your-PC)를 사용하여 잔여물을 제거하세요.\n- adb 포트 번호가 계속 불규칙하게 변경되고 시작할 때마다 다르다면 컴퓨터에 [Hyper-V](https://support.bluestacks.com/hc/en-us/articles/4415238471053-System-requirements-for-BlueStacks-5-on-Hyper-V-enabled-Windows-10-and-11)가 활성화되어 있기 때문일 수 있습니다. MAA는 이제 BlueStacks 에뮬레이터 구성 파일 내에서 포트 번호를 자동으로 읽으려고 시도할 것입니다. 이 방법이 작동하지 않거나 다중 실행/둘 이상의 에뮬레이터 커널이 설치된 경우 [연결 설정](../connection.md#bluestacks-에뮬레이터-hyper-v-포트-번호-변경)을 참조하여 변경하세요. Hyper-V는 관리자로 실행되므로 에뮬레이터 자동 종료, 자동 연결 감지 등 adb와 관련 없는 작업도 MAA를 관리자로 실행해야 합니다.', }, ...shuffleArray([ + { + name: '텐센트 앱스토어', + link: 'https://sj.qq.com/', + note: '5.10.56.xx 이후 버전을 지원합니다. `설정` - `연결 설정`에서 `텐센트 앱스토어` 연결 구성을 선택하세요. Hyper-V와 호환되는 것으로 알려져 있습니다.\n\n- ADB 포트는 `127.0.0.1:5555`입니다.\n- ADB 경로 예시: `C:\\Program Files\\Tencent\\Androws\\Application\\버전번호\\adb.exe`.\n\n- 먼저 앱스토어에서 [ADB 디버깅을 활성화](https://sj.qq.com/faq/3878)해야 합니다.', + }, { name: 'Nox', link: 'https://kr.bignox.com/', diff --git a/docs/zh-cn/manual/connection.md b/docs/zh-cn/manual/connection.md index 756b76a71b..b9a9fa2b16 100644 --- a/docs/zh-cn/manual/connection.md +++ b/docs/zh-cn/manual/connection.md @@ -16,6 +16,7 @@ MAA 可以通过当前**正在运行的单个模拟器**自动检测并填充 AD - 雷电模拟器 9:`emulator-5554/5556/5558/5560`、`127.0.0.1:5555/5557/5559/5561` - 夜神模拟器:`127.0.0.1:62001/59865` - 逍遥模拟器:`127.0.0.1:21503` +- 腾讯应用宝 (5.10.56.xx之后):`127.0.0.1:5555` 若检测失败,请尝试使用 UAC 管理员权限启动 MAA 并再次检测。若仍失败,则请阅读下文手动设置,并参考上述列表进行反馈。 @@ -57,6 +58,7 @@ MAA 可以通过当前**正在运行的单个模拟器**自动检测并填充 AD - [雷电模拟器 9](https://help.ldmnq.com/docs/LD9adbserver#edc3863750608062bcb3feea256413dc) - [夜神模拟器](https://support.yeshen.com/zh-CN/qt/ml) - [逍遥模拟器](https://bbs.xyaz.cn/forum.php?mod=viewthread&tid=365537) +- [腾讯应用宝](https://sj.qq.com/faq/3878):ADB 端口固定为 `127.0.0.1:5555`,ADB 路径示例:`C:\Program Files\Tencent\Androws\Application\版本号\adb.exe`。 其他模拟器可参考 [赵青青的博客](https://www.cnblogs.com/zhaoqingqing/p/15238464.html)。 diff --git a/docs/zh-cn/manual/device/windows.md b/docs/zh-cn/manual/device/windows.md index 68be4bba01..d2c25bc8bb 100644 --- a/docs/zh-cn/manual/device/windows.md +++ b/docs/zh-cn/manual/device/windows.md @@ -45,6 +45,11 @@ const fullySupport = [ note: '完美支持,需要在模拟器 `设定` - `进阶` 中打开 `Android调试桥`。已知兼容 Hyper-V。\n\n- 推荐下载 [离线安装包](https://support.bluestacks.com/hc/zh-tw/articles/4402611273485-BlueStacks-5-%E9%9B%A2%E7%B7%9A%E5%AE%89%E8%A3%9D%E7%A8%8B%E5%BC%8F),避免缓慢和捆绑安装;推荐安装 [Android 11](https://support.bluestacks.com/hc/zh-tw/articles/4402611273485-BlueStacks-5-%E9%9B%A2%E7%B7%9A%E5%AE%89%E8%A3%9D%E7%A8%8B%E5%BC%8F#:~:text=%E5%AE%89%E8%A3%9D%20BlueStacks%205%20%E7%9A%84%20Android%2011) 版本;卸载请使用官方提供的 [卸载工具](https://support.bluestacks.com/hc/zh-tw/articles/360057724751-%E5%A6%82%E4%BD%95%E5%BE%9E%E6%82%A8%E7%9A%84%E9%9B%BB%E8%85%A6%E4%B8%8A%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4-BlueStacks-5-BlueStacks-X-%E5%92%8C-BlueStacks-%E6%9C%8D%E5%8B%99) 以清除残留。\n- 若 ADB 端口号不断的无规律变动,每次启动都不相同,可能是因为您的电脑开启了 [Hyper-V](https://support.bluestacks.com/hc/zh-tw/articles/4415238471053-BlueStacks-5-%E6%94%AF%E6%8F%B4-Hyper-V-%E7%9A%84-Windows-10-%E5%92%8C-11-%E4%B8%8A%E7%9A%84%E9%9B%BB%E8%85%A6%E8%A6%8F%E6%A0%BC%E9%9C%80%E6%B1%82)。MAA 现在会尝试自动读取蓝叠模拟器配置文件内的端口号,若该功能失效/你有多开需求/安装了多个模拟器核心,请参考 [连接设置](../connection.html#蓝叠模拟器-hyper-v-每次启动端口号都不一样) 做出修改。由于 Hyper-V 以管理员身份运行,如自动关闭模拟器、自动检测连接等不涉及 ADB 的操作同样需要以管理员身份运行 MAA。', }, ...shuffleArray([ + { + name: '腾讯应用宝', + link: 'https://sj.qq.com/', + note: '支持 5.10.56.xx之后的版本。在 `设置` - `连接设置` 中选择 `腾讯应用宝` 连接配置。已知兼容 Hyper-V。\n\n- ADB 端口为 `127.0.0.1:5555`,\n- ADB路径示例:`C:\\Program Files\\Tencent\\Androws\\Application\\版本号\\adb.exe`。\n\n- 需要先在应用宝中 [开启 ADB 调试](https://sj.qq.com/faq/3878)。', + }, { name: '夜神模拟器', link: 'https://www.yeshen.com/', @@ -87,11 +92,6 @@ const notSupport = shuffleArray([ link: 'https://play.google.com/googleplaygames', note: '不支持,[玩家客户端](https://developer.android.com/games/playgames/pg-emulator?hl=zh-cn#installing-game-consumer)无法连接 ADB。', }, - { - name: '腾讯应用宝', - link: 'https://sj.qq.com/', - note: '不支持,腾讯应用宝没有给出adb连接选项,无法连接 ADB。', - }, ]); const md = new MarkdownIt(); diff --git a/docs/zh-tw/manual/connection.md b/docs/zh-tw/manual/connection.md index e3c34729f5..1a8bd344b9 100644 --- a/docs/zh-tw/manual/connection.md +++ b/docs/zh-tw/manual/connection.md @@ -16,6 +16,7 @@ MAA 可以透過目前**正在執行中的單一模擬器**,自動偵測並填 - 雷電模擬器 9:`emulator-5554/5556/5558/5560`、`127.0.0.1:5555/5557/5559/5561` - 夜神模擬器:`127.0.0.1:62001/59865` - 逍遙模擬器:`127.0.0.1:21503` +- 騰訊應用寶 (5.10.56.xx 之後):`127.0.0.1:5555` 若偵測失敗,請嘗試以系統管理員權限啟動 MAA 並再次偵測。若仍失敗,請參考下文進行手動設定,並參考上述清單向我們回報。 @@ -57,6 +58,7 @@ MAA 可以透過目前**正在執行中的單一模擬器**,自動偵測並填 - [雷電模擬器 9](https://help.ldmnq.com/docs/LD9adbserver#edc3863750608062bcb3feea256413dc) - [夜神模擬器](https://support.yeshen.com/zh-CN/qt/ml) - [逍遙模擬器](https://bbs.xyaz.cn/forum.php?mod=viewthread&tid=365537) +- [騰訊應用寶](https://sj.qq.com/faq/3878):ADB 連接埠固定為 `127.0.0.1:5555`,ADB 路徑範例:`C:\Program Files\Tencent\Androws\Application\版本號\adb.exe`。 其他模擬器可參閱 [趙青青的博客](https://www.cnblogs.com/zhaoqingqing/p/15238464.html)。 diff --git a/docs/zh-tw/manual/device/windows.md b/docs/zh-tw/manual/device/windows.md index 3f880b4eca..c804af0d4f 100644 --- a/docs/zh-tw/manual/device/windows.md +++ b/docs/zh-tw/manual/device/windows.md @@ -45,6 +45,11 @@ const fullySupport = [ note: '完美支援,需要在模擬器 `設定` - `進階` 中打開 `Android 調試橋 (ADB)`。已知相容 Hyper-V。\n\n- 推薦下載 [離線安裝程式](https://support.bluestacks.com/hc/zh-tw/articles/4402611273485-BlueStacks-5-%E9%9B%A2%E7%B7%9A%E5%AE%89%E8%A3%9D%E7%A8%8B%E5%BC%8F),避免下載緩慢或綑綁安裝;推薦安裝 [Android 11](https://support.bluestacks.com/hc/zh-tw/articles/4402611273485-BlueStacks-5-%E9%9B%A2%E7%B7%9A%E5%AE%89%E8%A3%9D%E7%A8%8B%E5%BC%8F#:~:text=%E5%AE%89%E8%A3%9D%20BlueStacks%205%20%E7%9A%84%20Android%2011) 版本;解除安裝請使用官方提供的 [解除安裝工具](https://support.bluestacks.com/hc/zh-tw/articles/360057724751-%E5%A6%82%E4%BD%95%E5%BE%9E%E6%82%A8%E7%9A%84%E9%9B%BB%E8%85%A6%E4%B8%8A%E5%AE%8C%E5%85%A8%E7%A7%BB%E9%99%A4-BlueStacks-5-BlueStacks-X-%E5%92%8C-BlueStacks-%E6%9C%8D%E5%8B%99) 以清除殘留。\n- 若 ADB 連接埠號碼不斷無規律變動,每次啟動都不相同,可能是因為您的電腦開啟了 [Hyper-V](https://support.bluestacks.com/hc/zh-tw/articles/4415238471053-BlueStacks-5-%E6%94%AF%E6%8F%B4-Hyper-V-%E7%9A%84-Windows-10-%E5%92%8C-11-%E4%B8%8A%E7%9A%84%E9%9B%BB%E8%85%A6%E8%A6%8F%E6%A0%BC%E9%9C%80%E6%B1%82)。MAA 目前會嘗試自動讀取藍疊模擬器配置檔案內的連接埠號碼,若該功能失效、有分身多開需求或安裝了多個模擬器核心,請參考 [連線設定](../connection.html#藍疊模擬器-hyper-v-每次啟動連接埠號都不一樣) 進行修改。由於 Hyper-V 以管理員身分執行,如自動關閉模擬器、自動偵測連線等不涉及 ADB 的操作同樣需要以系統管理員身分執行 MAA。', }, ...shuffleArray([ + { + name: '騰訊應用寶', + link: 'https://sj.qq.com/', + note: '支援 5.10.56.xx 之後的版本。在 `設定` - `連線設定` 中選擇 `騰訊應用寶` 連線配置。已知相容 Hyper-V。\n\n- ADB 連接埠為 `127.0.0.1:5555`。\n- ADB 路徑範例:`C:\\Program Files\\Tencent\\Androws\\Application\\版本號\\adb.exe`。\n\n- 需要先在應用寶中 [開啟 ADB 除錯](https://sj.qq.com/faq/3878)。', + }, { name: '夜神模擬器 (NoxPlayer)', link: 'https://www.yeshen.com/', @@ -87,11 +92,6 @@ const notSupport = shuffleArray([ link: 'https://play.google.com/googleplaygames', note: '不支援,[一般玩家版客戶端](https://developer.android.com/games/playgames/pg-emulator?hl=zh-tw#installing-game-consumer)無法連線 ADB。', }, - { - name: '騰訊應用寶', - link: 'https://sj.qq.com/', - note: '不支援,騰訊應用寶沒有提供 ADB 連線選項,無法連線 ADB。', - }, ]); const md = new MarkdownIt(); diff --git a/resource/config.json b/resource/config.json index bf188b83f9..02077e29c0 100644 --- a/resource/config.json +++ b/resource/config.json @@ -99,6 +99,19 @@ "baseConfig": "CapWithShell", "screencapRawByNC": "[Adb] -s [AdbSerial] shell \"screencap | busybox nc -w 3 [NcAddress] [NcPort]\"" }, + { + "configName": "Androws", + "baseConfig": "CapWithShell", + "displayId": "[Adb] -s [AdbSerial] shell \"dumpsys activity activities | awk '/^Display #/{match($0,/[0-9]+/); id=substr($0,RSTART,RLENGTH)} /packageName=[PackageName]/{print \\\"mDisplayId:\\\" id; }'\"", + "display": "[Adb] -s [AdbSerial] shell \"wm size -d [DisplayId] | grep -o -E [0-9]+\"", + "screencapRawByNC": "[Adb] -s [AdbSerial] shell \"screencap -d [DisplayId] | nc -w 3 [NcAddress] [NcPort]\"", + "screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap -d [DisplayId] | gzip -1\"", + "screencapEncode": "[Adb] -s [AdbSerial] shell screencap -d [DisplayId] -p", + "click": "[Adb] -s [AdbSerial] shell input -d [DisplayId] tap [x] [y]", + "swipe": "[Adb] -s [AdbSerial] shell input -d [DisplayId] swipe [x1] [y1] [x2] [y2] [duration]", + "eventId": "[Adb] -s [AdbSerial] shell \"EH_ID=$(dumpsys input | grep -E 'EventHub Devices:|Viewport.*displayId=[DisplayId],' | grep -B1 'displayId=[DisplayId],' | grep EventHub | head -1 | sed 's/.*\\[ *//;s/ *\\].*//'); dumpsys input | grep \\\" ${EH_ID}: \\\" -A2 | grep Path | head -1 | sed 's/.*event//'\"", + "callMinitouch": "[Adb] -s [AdbSerial] shell \"/data/local/tmp/[minitouchWorkingFile]\" -i -d /dev/input/event[EventId]" + }, { "configName": "Nox", "baseConfig": "General" diff --git a/src/MaaCore/Assistant.cpp b/src/MaaCore/Assistant.cpp index 889033b0f3..fff4f7a649 100644 --- a/src/MaaCore/Assistant.cpp +++ b/src/MaaCore/Assistant.cpp @@ -168,6 +168,9 @@ bool asst::Assistant::set_instance_option(InstanceOptionKey key, const std::stri return true; } break; + case InstanceOptionKey::ClientType: + m_ctrler->set_client_type(value); + return true; default: break; } diff --git a/src/MaaCore/Common/AsstTypes.h b/src/MaaCore/Common/AsstTypes.h index 4b868e9355..538c20d72b 100644 --- a/src/MaaCore/Common/AsstTypes.h +++ b/src/MaaCore/Common/AsstTypes.h @@ -46,6 +46,7 @@ enum class InstanceOptionKey DeploymentWithPause = 3, // 自动战斗、肉鸽、保全 是否使用 暂停下干员, "0" | "1" AdbLiteEnabled = 4, // 是否使用 AdbLite, "0" | "1" KillAdbOnExit = 5, // 退出时是否杀掉 Adb 进程, "0" | "1" + ClientType = 6, // 客户端类型(游戏渠道),用于连接时解析 PackageName }; enum class TouchMode diff --git a/src/MaaCore/Config/GeneralConfig.cpp b/src/MaaCore/Config/GeneralConfig.cpp index 5a10c16b76..4c5f3f9b02 100644 --- a/src/MaaCore/Config/GeneralConfig.cpp +++ b/src/MaaCore/Config/GeneralConfig.cpp @@ -85,6 +85,7 @@ bool asst::GeneralConfig::parse(const json::value& json) adb.chmod_minitouch = cfg_json.get("chmodMinitouch", base_cfg.chmod_minitouch); adb.call_minitouch = cfg_json.get("callMinitouch", base_cfg.call_minitouch); adb.call_maatouch = cfg_json.get("callMaatouch", base_cfg.call_maatouch); + adb.event_id = cfg_json.get("eventId", base_cfg.event_id); adb.back_to_home = cfg_json.get("back_to_home", base_cfg.back_to_home); } diff --git a/src/MaaCore/Config/GeneralConfig.h b/src/MaaCore/Config/GeneralConfig.h index 749649bd5d..4a17c18ff5 100644 --- a/src/MaaCore/Config/GeneralConfig.h +++ b/src/MaaCore/Config/GeneralConfig.h @@ -85,6 +85,7 @@ struct AdbCfg std::string chmod_minitouch; std::string call_minitouch; std::string call_maatouch; + std::string event_id; std::string back_to_home; json::object extras; }; diff --git a/src/MaaCore/Controller/AdbController.cpp b/src/MaaCore/Controller/AdbController.cpp index f1cb74aafb..e54f0ee369 100644 --- a/src/MaaCore/Controller/AdbController.cpp +++ b/src/MaaCore/Controller/AdbController.cpp @@ -1,6 +1,7 @@ #include "AdbController.h" #include "Assistant.h" +#include "Controller.h" #include "MaaUtils/NoWarningCV.hpp" #include #include @@ -867,6 +868,9 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string }; }; + std::string client_type = ctrler() ? ctrler()->get_client_type() : ""; + m_conn_ctx.reset(adb_path, address, client_type); + auto adb_ret = Config.get_adb_cfg(config); if (!adb_ret) { json::value info = get_info_json() | json::object { @@ -882,23 +886,8 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string #endif } - const auto& adb_cfg = adb_ret.value(); - std::string display_id; - std::string nc_address = "10.0.2.2"; - uint16_t nc_port = 0; - - // 里面的值每次执行命令后可能更新,所以要用 lambda 拿最新的 - auto cmd_replace = [&](const std::string& cfg_cmd) -> std::string { - return utils::string_replace_all( - cfg_cmd, - { - { "[Adb]", adb_path }, - { "[AdbSerial]", address }, - { "[DisplayId]", display_id }, - { "[NcPort]", std::to_string(nc_port) }, - { "[NcAddress]", nc_address }, - }); - }; + m_conn_ctx.adb_cfg = adb_ret.value(); + const auto& adb_cfg = m_conn_ctx.adb_cfg; if (need_exit()) { return false; @@ -907,8 +896,8 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string /* connect */ { // 先用 devices 读取输出 - m_adb.devices = cmd_replace(adb_cfg.devices); - m_adb.address_regex = cmd_replace(adb_cfg.address_regex); + m_adb.devices = m_conn_ctx.replace_cmd(adb_cfg.devices); + m_adb.address_regex = m_conn_ctx.replace_cmd(adb_cfg.address_regex); auto devices_ret = call_command(m_adb.devices, 60LL * 1000, false); bool need_connect = true; if (devices_ret) { @@ -934,8 +923,8 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string } // TODO: adb lite server 尚未实现,第一次连接需要执行一次 adb.exe 启动 daemon - m_adb.connect = cmd_replace(adb_cfg.connect); - m_adb.release = cmd_replace(adb_cfg.release); + m_adb.connect = m_conn_ctx.replace_cmd(adb_cfg.connect); + m_adb.release = m_conn_ctx.replace_cmd(adb_cfg.release); auto connect_ret = call_command(m_adb.connect, 60LL * 1000, false /* adb 连接时不允许重试 */); bool is_connect_success = false; if (connect_ret) { @@ -964,7 +953,7 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string /* get uuid (imei) */ { - auto uuid_ret = call_command(cmd_replace(adb_cfg.uuid), 20000, false /* adb 连接时不允许重试 */); + auto uuid_ret = call_command(m_conn_ctx.replace_cmd(adb_cfg.uuid), 20000, false /* adb 连接时不允许重试 */); if (!uuid_ret) { json::value info = get_info_json() | json::object { { "what", "ConnectFailed" }, @@ -1000,7 +989,7 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string } /* get android version */ { - auto version_ret = call_command(cmd_replace(adb_cfg.version)); + auto version_ret = call_command(m_conn_ctx.replace_cmd(adb_cfg.version)); if (!version_ret) { json::value info = get_info_json() | json::object { { "what", "ConnectFailed" }, @@ -1037,7 +1026,7 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string // 按需获取display ID 信息 if (!adb_cfg.display_id.empty()) { - auto display_id_ret = call_command(cmd_replace(adb_cfg.display_id)); + auto display_id_ret = call_command(m_conn_ctx.replace_cmd(adb_cfg.display_id)); if (!display_id_ret) { return false; } @@ -1049,9 +1038,35 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string return false; } - display_id = display_id_pipe_str.substr(last + 1); + m_conn_ctx.display_id = display_id_pipe_str.substr(last + 1); // 去掉换行 - display_id.pop_back(); + m_conn_ctx.display_id.pop_back(); + } + + if (need_exit()) { + return false; + } + + // 按需获取 event ID 信息(用于 minitouch 的 /dev/input/eventN) + if (!adb_cfg.event_id.empty()) { + auto event_id_ret = call_command(m_conn_ctx.replace_cmd(adb_cfg.event_id)); + if (!event_id_ret) { + Log.warn("Failed to get event_id, skip"); + } + else { + auto& event_id_pipe_str = event_id_ret.value(); + convert_lf(event_id_pipe_str); + // 去掉空白字符 + std::erase_if(event_id_pipe_str, [](char c) { return !std::isdigit(c); }); + + if (event_id_pipe_str.empty()) { + Log.warn("event_id is empty, skip"); + } + else { + m_conn_ctx.event_id = event_id_pipe_str; + Log.info("event_id:", m_conn_ctx.event_id); + } + } } if (need_exit()) { @@ -1060,7 +1075,7 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string /* display */ { - auto display_ret = call_command(cmd_replace(adb_cfg.display)); + auto display_ret = call_command(m_conn_ctx.replace_cmd(adb_cfg.display)); if (!display_ret) { json::value info = get_info_json() | json::object { { "what", "ConnectFailed" }, @@ -1110,15 +1125,15 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string callback(AsstMsg::ConnectionInfo, info); } - m_adb.click = cmd_replace(adb_cfg.click); - m_adb.input = cmd_replace(adb_cfg.input); - m_adb.swipe = cmd_replace(adb_cfg.swipe); - m_adb.press_esc = cmd_replace(adb_cfg.press_esc); - m_adb.screencap_raw_with_gzip = cmd_replace(adb_cfg.screencap_raw_with_gzip); - m_adb.screencap_encode = cmd_replace(adb_cfg.screencap_encode); - m_adb.start = cmd_replace(adb_cfg.start); - m_adb.stop = cmd_replace(adb_cfg.stop); - m_adb.back_to_home = cmd_replace(adb_cfg.back_to_home); + m_adb.click = m_conn_ctx.replace_cmd(adb_cfg.click); + m_adb.input = m_conn_ctx.replace_cmd(adb_cfg.input); + m_adb.swipe = m_conn_ctx.replace_cmd(adb_cfg.swipe); + m_adb.press_esc = m_conn_ctx.replace_cmd(adb_cfg.press_esc); + m_adb.screencap_raw_with_gzip = m_conn_ctx.replace_cmd(adb_cfg.screencap_raw_with_gzip); + m_adb.screencap_encode = m_conn_ctx.replace_cmd(adb_cfg.screencap_encode); + m_adb.start = m_conn_ctx.replace_cmd(adb_cfg.start); + m_adb.stop = m_conn_ctx.replace_cmd(adb_cfg.stop); + m_adb.back_to_home = m_conn_ctx.replace_cmd(adb_cfg.back_to_home); if (m_support_socket && !m_server_started) { std::string bind_address; @@ -1131,18 +1146,18 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string // reference from // https://github.com/ArknightsAutoHelper/ArknightsAutoHelper/blob/master/automator/connector/ADBConnector.py#L436 - auto nc_address_ret = call_command(cmd_replace(adb_cfg.nc_address)); + auto nc_address_ret = call_command(m_conn_ctx.replace_cmd(adb_cfg.nc_address)); if (nc_address_ret && !m_server_started) { auto& nc_result_str = nc_address_ret.value(); if (auto pos = nc_result_str.find(' '); pos != std::string::npos) { - nc_address = nc_result_str.substr(0, pos); + m_conn_ctx.nc_address = nc_result_str.substr(0, pos); } } auto socket_opt = init_socket(bind_address); if (socket_opt) { - nc_port = socket_opt.value(); - m_adb.screencap_raw_by_nc = cmd_replace(adb_cfg.screencap_raw_by_nc); + m_conn_ctx.nc_port = socket_opt.value(); + m_adb.screencap_raw_by_nc = m_conn_ctx.replace_cmd(adb_cfg.screencap_raw_by_nc); m_server_started = true; } else { @@ -1160,7 +1175,6 @@ bool asst::AdbController::connect(const std::string& adb_path, const std::string else if (config == "LDPlayer") { init_ld_extras(adb_cfg, address); } - if (need_exit()) { return false; } diff --git a/src/MaaCore/Controller/AdbController.h b/src/MaaCore/Controller/AdbController.h index 4e3285da30..961f104b2a 100644 --- a/src/MaaCore/Controller/AdbController.h +++ b/src/MaaCore/Controller/AdbController.h @@ -12,9 +12,56 @@ #include "InstHelper.h" #include "LDExtras.h" #include "MumuExtras.h" +#include "Utils/StringMisc.hpp" namespace asst { + +// 连接过程中的临时状态,基类 connect() 填充后子类直接复用 +struct AdbConnectionContext +{ + // 连接基本信息(reset 时设置) + std::string adb_path; + std::string address; + std::string package_name; + + // 缓存的 ADB 配置(基类 connect 获取后存入) + AdbCfg adb_cfg; + + // 连接过程中获取/更新的动态状态 + std::string display_id; + std::string event_id; + std::string nc_address = "10.0.2.2"; + uint16_t nc_port = 0; + + void reset(const std::string& adb, const std::string& addr, const std::string& client_type) + { + adb_path = adb; + address = addr; + package_name = client_type.empty() ? "" : Config.get_package_name(client_type).value_or(""); + adb_cfg = {}; + display_id.clear(); + event_id.clear(); + nc_address = "10.0.2.2"; + nc_port = 0; + } + + std::string replace_cmd(const std::string& cfg_cmd) const + { + return utils::string_replace_all( + cfg_cmd, + { + { "[Adb]", adb_path }, + { "[AdbSerial]", address }, + { "[DisplayId]", display_id }, + { "[EventId]", event_id }, + { "[NcPort]", std::to_string(nc_port) }, + { "[NcAddress]", nc_address }, + { "[PackageName]", package_name }, + }); + } +}; + class AdbController : public ControllerAPI, protected InstHelper { public: @@ -101,6 +148,8 @@ protected: // 导致解码错误,所以这里转一下回来(点名批评 mumu 和雷电) static bool convert_lf(std::string& data); + AdbConnectionContext m_conn_ctx; + AsstCallback m_callback; std::mutex m_callcmd_mutex; diff --git a/src/MaaCore/Controller/Controller.cpp b/src/MaaCore/Controller/Controller.cpp index 776f05a0b3..ba5d94b95c 100644 --- a/src/MaaCore/Controller/Controller.cpp +++ b/src/MaaCore/Controller/Controller.cpp @@ -43,31 +43,21 @@ asst::Controller::~Controller() LogTraceFunction; } -std::shared_ptr asst::Controller::create_controller( - ControllerType type, - const std::string& adb_path, - const std::string& address, - const std::string& config, - PlatformType platform_type) const +std::shared_ptr + asst::Controller::create_controller(ControllerType type, PlatformType platform_type) const { - std::shared_ptr controller; try { switch (type) { case ControllerType::Adb: - controller = std::make_shared(m_callback, m_inst, platform_type); - break; + return std::make_shared(m_callback, m_inst, platform_type); case ControllerType::Minitouch: - controller = std::make_shared(m_callback, m_inst, platform_type); - break; + return std::make_shared(m_callback, m_inst, platform_type); case ControllerType::Maatouch: - controller = std::make_shared(m_callback, m_inst, platform_type); - break; + return std::make_shared(m_callback, m_inst, platform_type); case ControllerType::MacPlayTools: - controller = std::make_shared(m_callback, m_inst, platform_type); - break; + return std::make_shared(m_callback, m_inst, platform_type); case ControllerType::MaaFwAdb: - controller = std::make_shared(m_callback, m_inst, platform_type); - break; + return std::make_shared(m_callback, m_inst, platform_type); default: return nullptr; } @@ -76,10 +66,6 @@ std::shared_ptr asst::Controller::create_controller( Log.error("Unable to create controller: {}", e.what()); return nullptr; } - if (controller->connect(adb_path, address, config)) { - return controller; - } - return nullptr; } size_t asst::Controller::get_pipe_data_size() const noexcept @@ -238,7 +224,7 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a clear_info(); - m_controller = create_controller(m_controller_type, adb_path, address, config, m_platform_type); + m_controller = create_controller(m_controller_type, m_platform_type); if (!m_controller) { Log.error("connect failed"); return false; @@ -246,6 +232,12 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a sync_params(); + if (!m_controller->connect(adb_path, address, config)) { + Log.error("connect failed"); + m_controller = nullptr; + return false; + } + m_uuid = m_controller->get_uuid(); #ifdef ASST_DEBUG @@ -397,6 +389,16 @@ void asst::Controller::set_kill_adb_on_exit(bool enable) noexcept sync_params(); } +void asst::Controller::set_client_type(const std::string& client_type) noexcept +{ + m_client_type = client_type; +} + +const std::string& asst::Controller::get_client_type() const noexcept +{ + return m_client_type; +} + const std::string& asst::Controller::get_uuid() const { return m_uuid; diff --git a/src/MaaCore/Controller/Controller.h b/src/MaaCore/Controller/Controller.h index e1b7f1ea1f..dde291b7b0 100644 --- a/src/MaaCore/Controller/Controller.h +++ b/src/MaaCore/Controller/Controller.h @@ -37,12 +37,7 @@ public: Controller(Controller&&) = delete; ~Controller(); - std::shared_ptr create_controller( - ControllerType type, - const std::string& adb_path, - const std::string& address, - const std::string& config, - PlatformType platform_type) const; + std::shared_ptr create_controller(ControllerType type, PlatformType platform_type) const; bool connect(const std::string& adb_path, const std::string& address, const std::string& config); #ifdef _WIN32 @@ -57,6 +52,8 @@ public: void set_swipe_with_pause(bool enable) noexcept; void set_adb_lite_enabled(bool enable) noexcept; void set_kill_adb_on_exit(bool enable) noexcept; + void set_client_type(const std::string& client_type) noexcept; + const std::string& get_client_type() const noexcept; const std::string& get_uuid() const; @@ -130,6 +127,7 @@ private: bool m_swipe_with_pause = false; bool m_kill_adb_on_exit = false; + std::string m_client_type; mutable std::shared_mutex m_image_mutex; cv::Mat m_cache_image; diff --git a/src/MaaCore/Controller/MinitouchController.cpp b/src/MaaCore/Controller/MinitouchController.cpp index bc29a6da0f..b2cf34442d 100644 --- a/src/MaaCore/Controller/MinitouchController.cpp +++ b/src/MaaCore/Controller/MinitouchController.cpp @@ -317,26 +317,26 @@ void asst::MinitouchController::clear_info() noexcept m_minitouch_props = decltype(m_minitouch_props)(); } -bool asst::MinitouchController::probe_minitouch( - const AdbCfg& adb_cfg, - std::function cmd_replace) +bool asst::MinitouchController::probe_minitouch() { LogTraceFunction; + const auto& adb_cfg = m_conn_ctx.adb_cfg; + std::string_view touch_program; if (m_use_maa_touch) { touch_program = "maatouch"; m_minitouch_props.orientation = 0; } else { - std::string abilist = call_command(cmd_replace(adb_cfg.abilist)).value_or(std::string()); + std::string abilist = call_command(m_conn_ctx.replace_cmd(adb_cfg.abilist)).value_or(std::string()); for (const auto& abi : Config.get_options().minitouch_programs_order) { if (abilist.find(abi) != std::string::npos) { touch_program = abi; break; } } - std::string orientation_str = call_command(cmd_replace(adb_cfg.orientation)).value_or("0"); + std::string orientation_str = call_command(m_conn_ctx.replace_cmd(adb_cfg.orientation)).value_or("0"); if (!orientation_str.empty()) { char first = orientation_str.front(); if (first == '0' || first == '1' || first == '2' || first == '3') { @@ -353,7 +353,7 @@ bool asst::MinitouchController::probe_minitouch( auto minitouch_cmd_rep = [&](const std::string& cfg_cmd) -> std::string { using namespace asst::utils::path_literals; return utils::string_replace_all( - cmd_replace(cfg_cmd), + m_conn_ctx.replace_cmd(cfg_cmd), { { "[minitouchLocalPath]", utils::path_to_utf8_string(ResDir.get() / "minitouch"_p / touch_program / "minitouch"_p) }, @@ -400,59 +400,24 @@ bool asst::MinitouchController::connect( return false; } - auto get_info_json = [&]() -> json::value { - return json::object { - { "uuid", m_uuid }, - { "details", - json::object { - { "adb", adb_path }, - { "address", address }, - { "config", config }, - } }, - }; - }; - - std::string display_id; - std::string nc_address = "10.0.2.2"; - uint16_t nc_port = 0; - - auto cmd_replace = [&](const std::string& cfg_cmd) -> std::string { - return utils::string_replace_all( - cfg_cmd, - { - { "[Adb]", adb_path }, - { "[AdbSerial]", address }, - { "[DisplayId]", display_id }, - { "[NcPort]", std::to_string(nc_port) }, - { "[NcAddress]", nc_address }, - }); - }; - - auto adb_ret = Config.get_adb_cfg(config); - - if (!adb_ret) { - json::value info = get_info_json() | json::object { - { "what", "ConnectFailed" }, - { "why", "ConfigNotFound" }, - }; - callback(AsstMsg::ConnectionInfo, info); -#ifdef ASST_DEBUG - return false; -#else - Log.error("config ", config, "not found"); - adb_ret = Config.get_adb_cfg("General"); -#endif - } - - const auto& adb_cfg = adb_ret.value(); - - m_minitouch_available = probe_minitouch(adb_cfg, cmd_replace); + // AdbController::connect() 已填充 m_conn_ctx(含 adb_cfg、display_id 等),直接使用 + m_minitouch_available = probe_minitouch(); if (!m_minitouch_available) { - json::value info = get_info_json() | json::object { - { "what", "TouchModeNotAvailable" }, - { "why", "" }, - }; + json::value info = + json::object { + { "uuid", m_uuid }, + { "details", + json::object { + { "adb", adb_path }, + { "address", address }, + { "config", config }, + } }, + } | + json::object { + { "what", "TouchModeNotAvailable" }, + { "why", "" }, + }; callback(AsstMsg::ConnectionInfo, info); return false; } diff --git a/src/MaaCore/Controller/MinitouchController.h b/src/MaaCore/Controller/MinitouchController.h index 02114948ff..1f0209a912 100644 --- a/src/MaaCore/Controller/MinitouchController.h +++ b/src/MaaCore/Controller/MinitouchController.h @@ -49,7 +49,7 @@ protected: bool call_and_hup_minitouch(); - bool probe_minitouch(const AdbCfg& adb_cfg, std::function cmd_replace); + bool probe_minitouch(); bool input_to_minitouch(const std::string& cmd); void release_minitouch(bool force = false); diff --git a/src/MaaWpfGui/Helper/WinAdapter.cs b/src/MaaWpfGui/Helper/WinAdapter.cs index 0036f730be..a164776b5f 100644 --- a/src/MaaWpfGui/Helper/WinAdapter.cs +++ b/src/MaaWpfGui/Helper/WinAdapter.cs @@ -18,6 +18,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using Microsoft.Win32; using Serilog; namespace MaaWpfGui.Helper; @@ -96,9 +97,53 @@ public class WinAdapter } } + var androwsAdbPath = GetAndrowsAdbPathFromRegistry(); + if (androwsAdbPath != null && detectedEmulators.Add($"Androws\n{androwsAdbPath}")) + { + emulators.Add(new DetectedEmulatorInfo("Androws", androwsAdbPath)); + } + return emulators; } + /// + /// Gets the ADB path for Androws emulator from Windows Registry. + /// Androws runs as an elevated process, so its path cannot be obtained via process.MainModule. + /// + /// The ADB executable path, or null if Androws is not installed. + private static string? GetAndrowsAdbPathFromRegistry() + { + try + { + using var installKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Tencent\Androws"); + if (installKey == null) + { + return null; + } + + var installPath = installKey.GetValue("InstallPath") as string; + if (string.IsNullOrEmpty(installPath)) + { + return null; + } + + using var appKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Tencent\Androws\Androws"); + var version = appKey?.GetValue("Version") as string; + if (string.IsNullOrEmpty(version)) + { + return null; + } + + var adbPath = Path.Combine(installPath, "Application", version, "adb.exe"); + return File.Exists(adbPath) ? adbPath : null; + } + catch (Exception e) + { + _logger.Warning(e, "Failed to get Androws adb path from registry"); + return null; + } + } + /// /// Gets the preferred ADB path for a process. /// diff --git a/src/MaaWpfGui/Main/AsstProxy.cs b/src/MaaWpfGui/Main/AsstProxy.cs index ba47a2d47c..06785290db 100644 --- a/src/MaaWpfGui/Main/AsstProxy.cs +++ b/src/MaaWpfGui/Main/AsstProxy.cs @@ -2640,6 +2640,8 @@ public class AsstProxy } } + AsstSetInstanceOption(InstanceOptionKey.ClientType, SettingsViewModel.GameSettings.ClientType); + bool ret = AsstConnect(_handle, SettingsViewModel.ConnectSettings.AdbPath, SettingsViewModel.ConnectSettings.ConnectAddress, SettingsViewModel.ConnectSettings.ConnectConfig); // 如果连接失败,等待回调完成以获取详细错误信息 @@ -3207,4 +3209,9 @@ public enum InstanceOptionKey /// Indicates whether the ADB server process should be killed when the instance is exited. /// KillAdbOnExit = 5, + + /// + /// Indicates the client type (game channel) used for resolving PackageName on connect. + /// + ClientType = 6, } diff --git a/src/MaaWpfGui/Res/Localizations/en-us.xaml b/src/MaaWpfGui/Res/Localizations/en-us.xaml index 5234cded4b..c92971e94a 100644 --- a/src/MaaWpfGui/Res/Localizations/en-us.xaml +++ b/src/MaaWpfGui/Res/Localizations/en-us.xaml @@ -179,6 +179,7 @@ To customize rotation schedules, please use 「{key=InfrastModeCustom}」.MuMu Emulator 12 LD Player Android Virtual Device (AVD) + Androws Nox MEmu Old version of WSA diff --git a/src/MaaWpfGui/Res/Localizations/ja-jp.xaml b/src/MaaWpfGui/Res/Localizations/ja-jp.xaml index 8afc48f231..78e7d712da 100644 --- a/src/MaaWpfGui/Res/Localizations/ja-jp.xaml +++ b/src/MaaWpfGui/Res/Localizations/ja-jp.xaml @@ -179,6 +179,7 @@ MuMu Player LDPlayer Android Virtual Device (AVD) + Androws NoxPlayer MEmu 古いバージョンのWSA diff --git a/src/MaaWpfGui/Res/Localizations/ko-kr.xaml b/src/MaaWpfGui/Res/Localizations/ko-kr.xaml index 2f7214738c..2447b78252 100644 --- a/src/MaaWpfGui/Res/Localizations/ko-kr.xaml +++ b/src/MaaWpfGui/Res/Localizations/ko-kr.xaml @@ -179,6 +179,7 @@ MuMu Player LD Player Android Virtual Device (AVD) + Androws Nox MEmu WSA 레거시 버전 diff --git a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml index 87cb5e097a..f1e0603b54 100644 --- a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml +++ b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml @@ -179,6 +179,7 @@ MuMu 模拟器 Android 虚拟设备(AVD) 雷电模拟器 + 应用宝模拟器 夜神模拟器 逍遥模拟器 WSA 旧版本 diff --git a/src/MaaWpfGui/Res/Localizations/zh-tw.xaml b/src/MaaWpfGui/Res/Localizations/zh-tw.xaml index dbaf26f5eb..3e2c123ebb 100644 --- a/src/MaaWpfGui/Res/Localizations/zh-tw.xaml +++ b/src/MaaWpfGui/Res/Localizations/zh-tw.xaml @@ -179,6 +179,7 @@ MuMu 模擬器 12 雷電模擬器 Android 虛擬裝置(AVD) + 應用寶模擬器 夜神模擬器 逍遙模擬器 WSA 舊版本 diff --git a/src/MaaWpfGui/ViewModels/UserControl/Settings/ConnectSettingsUserControlModel.cs b/src/MaaWpfGui/ViewModels/UserControl/Settings/ConnectSettingsUserControlModel.cs index 0e87c6745d..550e700ec9 100644 --- a/src/MaaWpfGui/ViewModels/UserControl/Settings/ConnectSettingsUserControlModel.cs +++ b/src/MaaWpfGui/ViewModels/UserControl/Settings/ConnectSettingsUserControlModel.cs @@ -73,6 +73,7 @@ public class ConnectSettingsUserControlModel : PropertyChangedBase new() { Display = LocalizationHelper.GetString("BlueStacks"), Value = "BlueStacks" }, new() { Display = LocalizationHelper.GetString("MuMuEmulator12"), Value = "MuMuEmulator12" }, new() { Display = LocalizationHelper.GetString("LDPlayer"), Value = "LDPlayer" }, + new() { Display = LocalizationHelper.GetString("Androws"), Value = "Androws" }, new() { Display = LocalizationHelper.GetString("AVD"), Value = "AVD" }, new() { Display = LocalizationHelper.GetString("Nox"), Value = "Nox" }, new() { Display = LocalizationHelper.GetString("XYAZ"), Value = "XYAZ" }, @@ -837,6 +838,7 @@ public class ConnectSettingsUserControlModel : PropertyChangedBase { "LDPlayer", ["emulator-5554", "emulator-5556", "emulator-5558", "emulator-5560", "127.0.0.1:5555", "127.0.0.1:5557", "127.0.0.1:5559", "127.0.0.1:5561"] }, { "Nox", ["127.0.0.1:62001", "127.0.0.1:59865"] }, { "XYAZ", ["127.0.0.1:21503"] }, + { "Androws", ["127.0.0.1:5555"] }, { "WSA", ["127.0.0.1:58526"] }, };