Skip to content

Add: PlayCover support - #5866

Open
DevSplash wants to merge 14 commits into
LmeSzinc:masterfrom
DevSplash:playcover
Open

DevSplash wants to merge 14 commits into
LmeSzinc:masterfrom
DevSplash:playcover

Conversation

@DevSplash

@DevSplash DevSplash commented Aug 9, 2026 •

Copy link
Copy Markdown
Contributor

增加PlayCover支持,参考了#4436 的思路

需要和修改版的PlayCover和PlayTools配套使用:
PlayCover:https://github.com/DevSplash/PlayCover
管理API、分辨率补偿
PlayTools:https://github.com/DevSplash/PlayTools
截图、触控同步

主要改动:

  • 通过管理API启动/关闭游戏:playcoverm://host:port (默认端口1718),管理api需要修改版playcover支持
  • 支持通过maatools连接:playcover://host:port (默认端口1717),但只能连接到已启动的客户端,无法主动启动和停止(停止行为会回落到返回主界面)
  • 使用playcover时不会初始化adb

已知限制:
1、装备方案码依赖安卓ADB、输入法和uiautomator2,暂不支持。
2、因MacOS下的字体差异,有些地方和原模板无法匹配,已经增加了部分已发现问题的CN服模板兜底,其他服模板、暂时没发现的不兼容的地方可能需后续再补充。

@LmeSzinc

Copy link
Copy Markdown
Owner

为什么会需要修改其他内容? mac 下的 bluestack air 和 mumu pro 都是无缝使用 alas 的,你没用 1280x720 然后偷加缩放了吧

@DevSplash

DevSplash commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor Author

为什么会需要修改其他内容? mac 下的 bluestack air 和 mumu pro 都是无缝使用 alas 的,你没用 1280x720 然后偷加缩放了吧

这个是上个月改的,有点久忘了提了。
playcover在mac上原生运行ios app时,如果app未针对mac优化,会有0.77倍的系统级缩放
https://developer.apple.com/design/human-interface-guidelines/mac-catalyst?changes=l_8_2

直接配置为1280×720时,UIKit逻辑尺寸是1280×720,但mac上实际显示尺寸只有大约985×554,所以截图后alas又会让0.77的倍率再缩放回1.0(相当于先*0.77显示,截图再/0.77),导致一些模板与安卓的匹配度低,此前测试的时候遇到不少科研识别错误、潜艇舰队按钮找不到之类的问题

没找到特别好的通用方案,当前修改的playcover的方案是把设置的分辨率按目标分辨率/0.77放大,也就是设置为1663×936,经过0.77倍的系统级缩放后会变成1280×720,等于逻辑尺寸是1663×936,缩放为1280x720
我测试的时候这个方案识别模板时比原版识别的置信度要高,虽然也有不少识别不了的模板,但像是前一种方式出现的大面积科研识别错误这种都已经解决了

模板或识别区域的相关的改动是解决已发现的识别错误用的

@guoh064

guoh064 commented Aug 16, 2026 •

Copy link
Copy Markdown
Collaborator

@DevSplash

DevSplash commented Aug 16, 2026 •

Copy link
Copy Markdown
Contributor Author

似乎可以考虑让用户自行配置PixelPerfect? https://github.com/cormiertyshawn895/PixelPerfect#can-i-use-pixel-perfect-with-iphone-and-ipad-apps-downloaded-from-third-party-websites-playcover-or-sideloadly

我测一下。如果可以的话应该也可以集成到playcover里

@DevSplash

Copy link
Copy Markdown
Contributor Author

似乎可以考虑让用户自行配置PixelPerfect? https://github.com/cormiertyshawn895/PixelPerfect#can-i-use-pixel-perfect-with-iphone-and-ipad-apps-downloaded-from-third-party-websites-playcover-or-sideloadly

拿playcover (playtools)用这个思路改了一下,部分新增的兜底和阈值改动的确可以去掉了

但海域专有模板可能还是要保留,拿原版套的话置信度大约在0.65~0.74,没过阈值
我在模拟器、playcover上对照测试了一下,发现是字体的问题
包没有指定字体,所以走的是默认字体,就导致安卓和ios所用字体存在出入
playcover里这几组文字用的字体是Arial Unicode,已经测试在安卓模拟器强制替换为这个字体后,与playcover截图的拟合度几乎接近1.0
PlayCover
ios
安卓+Arial Unicode
android

安卓我没定位到准确的字体,可能是NotoSansSC Regular,不确定。
本来想在playcover调模拟器的fallback字体试,但是因为替换字体要关SIP,就拿unity用相同字体画了个大小相近的3组文字,编译成ipa放到playcover里测试,拿原模板匹配置信度只有0.9,看起来也比模板略粗
test

不太可能去要求用户更换字体,所以感觉还是要两套模板,或者降低阈值(降阈值不一定可靠,置信度偶尔会低于0.7)

科研的样本暂时还不够,我这边加了点日志先堆几天看看

@DevSplash
DevSplash marked this pull request as draft August 18, 2026 01:42
@DevSplash

DevSplash commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor Author

科研的识别也没问题了,3个海域选择模板是字体问题,只能用单独的模板匹配
修改版 PlayCover 已支持100%缩放,建议配合使用
(注:原版maatools理论上也能用,但缺少管理API功能,且当前pr未实现本机端的游戏启停,原版maatools分支无法启动/停止游戏,因此还是建议使用修改版)

需进行以下配置
PlayCover应用选项:
1、管理 勾选 管理服务器。(按需配置监听IP、端口号、访问密钥,如 0.0.0.0,1718)
PlayCover游戏选项:
1、图像设置 -> macOS 内容缩放中选择 使用原生1:1缩放;
2、绕过 勾选 MaaTools。(按需配置端口号,如1717)

然后在ALAS的模拟器 Serial 中填入:playcoverm://127.0.0.1:1718 或 pm://127.0.0.1:1718 即可
如有手动修改了PlayCover端口,Serial里也应该一致
(无管理API的情况下也支持直连maatools,使用 playcover://127.0.0.1:1717 即可)


Serial有效写法

  • 使用管理 API(host默认值为127.0.0.1,port默认值为1718):
playcoverm
playcoverm:
playcoverm://
playcoverm://<host>
playcoverm://<host>:<port>
playcoverm:<host>
playcoverm:<host>:<port>

(playcoverm 可替换为 pm)

  • 直连 MaaTools(host默认值为127.0.0.1,port默认值为1717):
playcover
playcover:
playcover://
playcover://<host>
playcover://<host>:<port>
playcover:<host>
playcover:<host>:<port>

(playcover 可替换为 maatools)

@DevSplash
DevSplash marked this pull request as ready for review August 21, 2026 15:44
@DevSplash

DevSplash commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor Author

我在想要不要强制要求使用管理API,配置时只需要配管理API地址,maatools端口从API读,这样还能再少一个配置项
说到底Serial绑maatools地址只是为了兼容原版用的

改成用Serial区分是管理api还是maatools了

@LmeSzinc LmeSzinc left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

按照现有的缓存属性链与异常驱动模式编写,nemuipc maatouch 都是很好的例子,不然就会像现在这样陷入首次启动和重新启动的状态管理地狱,status reset force 变量在函数之间传来传去

  1. 实现 MaaToolsManager,launch 方法内完成 从manager启动 /apps/{package}/maatools/open,启动成功之后后续不再检查 status reachable 等等
  2. 实现 MaaToolsClient,输入MaaToolsManager创建的端口号,提供connect方法连接到端口,提供对发送和接收的封装,连接的时候同样不检查任何状态,默认端口可用。连接可用性与这两个实例完全绑定,不可以就释放实例
  3. 实现 Playcover 类,使用缓存属性创建 maatools_manager: MaaToolsManager, maatools_client: MaaToolsClient,提供截图和控制方法,里面像这样写
def screenshot_playcover():
      client = self.maatools_client
      client.send(...)
      data = client.recv(...)

首次启动的时候,缓存属性会依次创建,完整走完启动流程,不需要任何显式的函数去调用启动。
还可以进一步提供warmup,来提前启动,加快第一次截图

def playcover_warmup():
    _ = self.maatools_client
  1. 连接步骤通过缓存属性链完成,发生错误时清除节点及后面的缓存属性,重试时缓存属性链重新创建,步骤自然地重新执行,比如
  • recv 数据不符合预期的时候,抛出 PlaycoverDataTruncated,retry 捕获到进行重试
  • send/recv 超时的时候,抛出 PlaycoverDataTimeout,retry 捕获到进行重试
  • socket损坏无法发送的时候,抛出 MaaToolsClientError,retry 捕获到之后释放self.maatools_client,然后进行重试,重试的时候maatools_client 会被缓存属性重新创建,连接重新建立,因此不需要任何 reconnect 的方法,完全复用首次连接的逻辑。因为这是socket错误重新连接即可恢复,所以不需要释放maatools_manager,恢复开销最小化
  • bundle 不匹配的时候,抛出 MaaToolsManagerError,retry 捕获到之后释放self.maatools_client 和 self.maatools_manager,重试的时候会重新启动 /apps/{package}/maatools/open,同样通过缓存属性重新创建,不需要任何 reconnect 的方法

Comment thread module/os/globe_operation.py Outdated
Comment thread module/os/globe_operation.py Outdated
Comment thread alas.py Outdated
Comment thread module/device/connection.py Outdated
Comment thread module/device/connection.py Outdated
Comment thread module/device/method/playcover.py Outdated
Comment thread module/device/method/playcover.py Outdated
Comment thread module/device/method/playcover.py Outdated
Comment thread module/device/method/playcover.py Outdated
Comment thread module/device/method/playcover.py Outdated
@LmeSzinc

Copy link
Copy Markdown
Owner

playcover 能多开吗(是否允许多实例,是否允许实例内多开应用,是否能通过 /apps/{package} 连接后台应用),如果允许的话固定使用 1717 端口会有冲突

@DevSplash

Copy link
Copy Markdown
Contributor Author

playcover 能多开吗(是否允许多实例,是否允许实例内多开应用,是否能通过 /apps/{package} 连接后台应用),如果允许的话固定使用 1717 端口会有冲突

可以启动不同包名的app,单个app多开需要自己想办法把app的包名改成其他的,类似于手机端多开,所以这次暂时先不考虑多开的问题。

playcover侧已提供了端口的配置,如果用manager会自动查询对应包配置的端口,并使用该端口连接,而端口冲突的问题不应该是alas要考虑的问题,仅需要在协议连接后查一下包是否匹配(现在的版本已经做了这个检查)

/apps/{package}到的端口可达是tcp可达,如果端口冲突时依然会显示true,并不可靠,虽然会被maatools连接时挡掉

我想想这里怎么改合适

@DevSplash

Copy link
Copy Markdown
Contributor Author

现在修改版playcover的/apps/{package}接口会明确进行包探测,并返回准确的探测结果
因为探测存在开销,且在列举安装app列表时没有意义,/apps不再返回端口连通性结果
alas自己连接maatools时检查依然保留

同时运行多个服原本就支持,单服多开则需要用户自己在设备上改安装的app包名。
要兼容单服多开,alas这边理论上暴露一个自定义包名的选项就行,但暂时先不考虑。

@DevSplash

Copy link
Copy Markdown
Contributor Author

PlayCover本身对MacOS 27目前存在无法打开APP的兼容性问题,暂时先等待上游解决

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants