MAA 远程控制协议开发指南:构建基于 HTTP 的 MaaAssistantArknights 任务调度服务
2026/9/13 12:55:14 网站建设 项目流程

MAA 远程控制协议开发指南:构建基于 HTTP 的 MaaAssistantArknights 任务调度服务

【免费下载链接】MaaAssistantArknights《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients.项目地址: https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknights

MAA(MaaAssistantArknights)为《明日方舟》自动化工具提供了完整的远程控制协议,允许第三方服务通过两个匿名 HTTP(S) 端点向运行中的 MAA 实例下发任务、接收执行结果,从而实现 QQ 机器人、网页管理后台等形态的远程调度。本文基于仓库中的 远程控制协议规范,结合 RemoteControlService.cs 等源码实现,完整讲解协议的数据格式、任务类型、配置方式与两类端到端接入示例。读完后,你将能够独立实现一个合规的 MAA 远程控制服务端。

协议概览:两个端点,一种轮询模型

远程控制的核心是一个简单的请求-响应轮询模型。被控制的 MAA 客户端扮演"轮询方",而你的服务端只需要提供两个匿名可访问的 HTTP(S) Web 端点:

端点方向作用
任务获取端点(Task Retrieval Endpoint)MAA → 服务端MAA 以固定间隔持续轮询,获取待执行任务并顺序执行
任务汇报端点(Task Reporting Endpoint)MAA → 服务端MAA 完成任务后,向服务端汇报执行结果与附加数据

两个端点均由服务端提供,路径完全自由,例如https://your-control-host.net/maa/getTaskhttps://your-control-host.net/maa/reportStatus。MAA 在配置界面中分别填入这两个地址即可建立连接。

在 RemoteControlService.cs 中可以看到轮询的实现:PollJobTaskLoop每经过RemoteControlPollIntervalMs(默认 1000ms)就向任务获取端点发起一次 POST 请求,解析返回的tasks数组后,根据任务类型分别放入顺序任务队列_sequentialTaskQueue)或即时任务队列_instantTaskQueue),由两个独立的执行循环ExecuteSequentialJobLoopExecuteInstantJobLoop消费。

安全警告:请务必使用 HTTPS

协议规范明确要求:

如果端点使用 HTTP 协议,MAA 每次连接都会发出安全警告。在公网上部署明文传输服务极不推荐且危险,仅供测试使用。

这一警告在源码中同样落地——IsEndpointValid 会检查端点前缀:https://直接放行,http://放行但弹出"端点未启用 https,可能不安全"的提示(对应本地化字符串RemoteControlConnectionTestWarningHttpUnsafe),其他格式则判定为非法。此外 MAA 的设置界面还会展示一条醒目的安全提示(RemoteControlTooltips:"注意:随意填入未知来源的地址可能会导致您的账户受到损失")。由于该功能会执行一键长草、截图等敏感操作,服务端身份与链路加密缺一不可

MAA 侧配置:五个配置项

远程控制功能位于 MAA 设置界面的"远程控制"分区(视图见 RemoteControlUserControl.xaml,配置模型见 RemoteControl.cs):

配置项类型默认值说明
RemoteControlGetTaskEndpointUristring任务获取端点地址
RemoteControlReportStatusUristring任务汇报端点地址
RemoteControlUserIdentitystring用户标识符,由用户在设置中手动填写
RemoteControlDeviceIdentitystring设备标识符,由 MAA 自动生成(GUID),只读展示
RemoteControlPollIntervalMsint1000轮询间隔,单位毫秒

交互细节(对应 RemoteControlUserControlModel.cs):

  • 设备标识符只读但可重新生成:界面上"设备标识符"输入框为IsReadOnly="True",旁边的"重新生成"按钮调用 RegenerateDeviceIdentity,用Guid.NewGuid().ToString("N")生成新的设备标识。若你为用户管理设备,请务必提示用户把重新生成后的标识更新到你的服务端。
  • 测试连接:设置界面的"测试连接"按钮调用 ConnectionTest,向任务获取端点发送一次POST { user, device },根据 HTTP 状态码弹窗提示"连接测试成功"或"连接测试失败,原因: {0}"。这正是协议示例中"用户按下测试连接按钮"行为的来源。
  • 配置持久化与加密存储:端点、用户标识、设备标识在写入配置时经过SimpleEncryptionHelper.Encrypt加密后落盘,轮询间隔则以明文存储。从安全角度看,这些凭据至少不是以明文形式保存在配置文件中。
  • 动态启停:一旦填入了合法的任务获取端点,RemoteControlService.InitializePollJobTask()会立即启动三个后台循环(轮询、顺序任务执行、即时任务执行);若端点被清空,循环会自动退出并把_inited复位(见 InitializePollJobTask)。

注意:JSON 文件不支持注释。规范中的注释(如// User identifier...)仅用于演示,切勿直接复制到生产配置中。

任务获取端点协议

请求格式

端点必须接受POST请求,Content-Type=application/json,请求体为:

{ "user": "ea6c39eb-a45f-4d82-9ecc-33a7bf2ae4dc", "device": "f7cd9682-3de9-4eef-9137-ec124ea9e9ec" }
  • user:用户在 MAA 设置中填写的用户标识符。
  • device:MAA 自动生成的设备标识符。
  • 除这两个字段外,你可以按需增加自定义字段,但 MAA 只发送userdevice两者。

在源码中,该请求由 PollJobTaskLoop 通过Instances.HttpService.PostAsJsonAsync(endpoint, new { user = uid, device = did })发送,字段与规范完全一致。

响应格式与任务类型

端点必须返回至少包含tasks字段的 JSON,且tasks字段缺失时,连接将被视为无效

{ "tasks": [ { "id": "b353c469-b902-4357-bd8f-d133199eea31", "type": "CaptureImage" }, { "id": "15be4725-5bd3-443d-8ae3-0a5ae789254c", "type": "LinkStart" }, { "id": "15be4725-5bd3-443d-8ae3-0a5ae789254c", "type": "LinkStart-Recruiting" }, { "id": "b353c469-b902-4357-bd8f-d133199eea31", "type": "Toolbox-GachaOnce" }, { "id": "b353c469-b902-4357-bd8f-d133199eea31", "type": "Settings-ConnectAddress", "params": "value" }, { "id": "b353c469-b902-4357-bd8f-d133199eea31", "type": "CaptureImageNow" }, { "id": "b353c469-b902-4357-bd8f-d133199eea31", "type": "StopTask" }, { "id": "b353c469-b902-4357-bd8f-d133199eea31", "type": "HeartBeat" } ] }

字段说明:

  • id:字符串类型的唯一任务 ID,用于在任务汇报时标识该任务。MAA 内部维护_enqueueTaskIds列表,对相同 ID 的任务不会重复执行(见 PollJobTaskLoop),因此你的端点应当"可重入"——即便重复返回同一个任务列表,也不会导致任务被执行两次。这也意味着每个任务 ID 应当全局唯一(如使用 UUID)。
  • type:任务类型,决定 MAA 执行何种操作,见下表。
  • params:可选参数,仅配置修改类任务使用,值为字符串。

顺序任务(Sequential Tasks)

顺序任务进入_sequentialTaskQueue严格按下发顺序排队执行。例如先下发招募任务再下发截图任务,截图必然在招募完成后才执行。任务执行期间 MAA 会通过_currentSequentialTaskId记录当前正在执行的任务 ID(见 ExecuteSequentialJobLoop),该状态会被即时任务读取。

任务类型行为备注
LinkStart执行"一键长草"等价于主界面的一键长草按钮,执行全部已勾选任务
LinkStart-Base只执行基建换班忽略主界面勾选,立即执行对应子功能
LinkStart-WakeUp只执行唤醒同上
LinkStart-Combat只执行刷理智同上
LinkStart-Recruiting只执行公招同上
LinkStart-Mall只执行领取信用及购物同上
LinkStart-Mission只执行领取奖励同上
LinkStart-AutoRoguelike只执行自动肉鸽同上
LinkStart-Reclamation只执行生息演算同上
Toolbox-GachaOnce工具箱单抽对应GachaOnce
Toolbox-GachaTenTimes工具箱十连对应GachaTenTimes
CaptureImage截图当前模拟器画面截图以 Base64 字符串放入汇报的payload;截图可达数十 MB,注意网关请求体大小限制
Settings-ConnectAddress修改连接地址params为新地址,等价于修改连接设置中的ConnectAddress属性
Settings-Stage1修改关卡名params为新关卡名,写入作战任务的第一个关卡计划

LinkStart-[TaskName]Settings-[SettingsName]系列的具体取值即上表所列,与规范::: note提示块内容一致,且与源码 PollJobTaskLoop 中的case分支一一对应。其中LinkStart-*系列在 LinkStart 方法中通过反射式SerializeTask将当前配置序列化后启动,源码注释明确其"不调用 StartScript、不使用模型里的列表、在结尾等待 RunningStatus"等设计特点。

安全边界:并非所有设置都可被远程修改。规范强调"For security, not all settings can be modified"。当前白名单仅有ConnectAddressStage1两个,其他任何设置都不接受远程修改。

即时任务(Instant Tasks)

即时任务进入_instantTaskQueue,由独立的执行循环处理,因此可在顺序任务执行期间插入运行。MAA 保证这类任务会快速返回结果,通常用于控制远程控制功能本身:

任务类型行为备注
CaptureImageNow立即截图CaptureImage类似,但不等待其他任务,立即执行并返回截图
StopTask停止当前任务尝试结束正在运行的任务;若任务列表中还有其他任务则继续执行下一个。该任务不等待当前任务确认停止即返回,规范建议用心跳任务来确认停止是否生效
HeartBeat心跳立即返回,payload为当前正在执行的顺序任务 ID;若无任务在执行则为空字符串

即时任务同样按下发顺序执行,但由于它们本身执行极快,顺序通常无关紧要。源码 ExecuteInstantJobLoop 展示了实现:HeartBeat直接返回_currentSequentialTaskIdStopTask调用AsstStop()后立即返回(源码注释:"无需等待,甩出任务即可返回,远端应该用心跳来确认界面卡死和取消是否成功"),CaptureImageNow通过AsstConnect连接后调用AsstGetFreshImage()获取截图并编码为 PNG Base64。

一个关键细节:截图任务的体积问题

CaptureImage/CaptureImageNow会将模拟器当前画面编码为 PNG 并以 Base64 字符串放进汇报请求。源码 ExecuteSequentialJobLoop 中的实现路径是AsstConnect → AsstGetFreshImageAsync → PngBitmapEncoder → Convert.ToBase64String。规范特别提醒:单张截图可能达到几十 MB,超出常见网关的默认请求体大小限制。如果你的服务部署在 Nginx 等反向代理之后,务必为汇报端点调大client_max_body_size(或其他等价配置)。

任务汇报端点协议

当 MAA 完成任务后,会向汇报端点发送执行结果:

{ "user": "ea6c39eb-a45f-4d82-9ecc-33a7bf2ae4dc", "device": "f7cd9682-3de9-4eef-9137-ec124ea9e9ec", "task": "15be4725-5bd3-443d-8ae3-0a5ae789254c", "status": "SUCCESS", "payload": "" }

字段说明:

  • user/device:同任务获取请求,用于服务端识别是哪个 MAA 实例在汇报。
  • task:被汇报的任务 ID,对应任务获取响应中的id
  • status:任务执行结果,取值为SUCCESSFAILED一般情况下即使任务实际执行失败也会返回SUCCESS,仅当任务描述中特别说明的特殊情况(如CaptureImage截图失败、连接失败)才返回FAILED。从源码看,status的默认值即SUCCESS,仅当AsstConnect失败或截图为空时被置为FAILED
  • payload:附加数据,字符串类型,取决于任务类型——截图任务携带截图 Base64,心跳任务携带当前顺序任务 ID。

该端点的响应内容任意,MAA 不读取响应体、不检查状态码;汇报请求失败时,MAA 仅在日志中记录错误(源码中对应"RemoteControlService report task failed."Log.Logger.Error调用)。这意味着汇报端点可以设计为"异步落库即返回"以降低对 MAA 侧的影响。

端到端示例一:用 QQ 机器人控制 MAA

规范给出了完整的参考实现思路。开发者 A 希望用 QQ 机器人远程控制用户的 MAA,于是在公网部署了两个端点:

https://myqqbot.com/maa/getTask https://myqqbot.com/maa/reportStatus

完整流程:

  1. 注册与识别getTask接口对所有请求返回200 OK和空的tasks列表。每次收到请求时检查数据库是否存在该设备记录,若不存在则把deviceuser记录入库——该接口同时承担了用户注册职能
  2. 绑定:机器人在 QQ 频道提供提交deviceId的命令。用户按要求在 MAA 的"用户标识符"栏填写自己的 QQ 号,并通过 QQ 聊天把 MAA 生成的"设备标识符"发送给机器人。机器人收到后,根据消息中的 QQ 号在数据库查对应记录;查不到则提示用户先配置 MAA。
  3. 验证:由于 MAA 配置完成后会持续发送轮询请求,用户通过 QQ 提交设备标识时,数据库理应已存在对应记录。机器人将这条记录标记为"已验证",此后该device+user组合的getTask请求才会返回真实任务列表。
  4. 下发任务:用户在 QQ 发送命令后,机器人把任务写入数据库,getTask在下一次轮询时将其返回。示例中机器人还会在每个用户命令后自动附带一个截图任务,以便回传执行画面。
  5. 结果回传:MAA 执行完毕后调用reportStatus汇报,机器人解析结果并向用户发送 QQ 消息、展示截图。

这个示例的巧妙之处在于:轮询请求本身被复用为在线注册与心跳机制——只要 MAA 配置正确,服务端就能持续感知实例的在线状态。

端到端示例二:用网页后台批量管理 MAA

开发者 B 为批量管理 MAA 实例搭建了带用户体系的网站,同样只提供两个匿名端点:

https://mywebsite.com/maa/getTask https://mywebsite.com/maa/reportStatus

与示例一的差异点:

  1. 用户键:网站将"用户键"(User Key,随机字符串)展示给用户,用户需将其填入 MAA 的"用户标识符",同时把"设备标识符"填回网站上的输入框。
  2. 鉴权通过"行为"实现:网站只有在 MAA 连接创建成功后才让getTask返回200 OK,否则返回401 Unauthorized。用户若在 MAA 中填错信息并点击"测试连接"按钮,就会收到"连接测试失败"通知——这正是 MAA 侧 ConnectionTest 根据非 2xx 状态码弹出失败提示的行为。
  3. 任务管理:用户可在网站上发布任务、排队、查看截图,实现方式与 QQ 机器人示例同构——都是通过getTask下发、reportStatus回收结果。

服务端实现要点总结

综合规范与源码,一个合规服务端需要满足以下硬性要求:

  1. 两个匿名端点:均接受POST application/json,无需任何鉴权头(鉴权通过user/device与 HTTP 状态码隐式完成)。
  2. tasks字段不可缺失getTask响应缺少tasks数组会被视为连接无效。
  3. 任务 ID 全局唯一且可重入:MAA 按 ID 去重,同一 ID 不会重复执行;端点应能安全地反复返回相同任务列表。
  4. 立即执行的快捷任务StopTask需要配合HeartBeat使用才能可靠确认停止状态。
  5. 注意负载:单实例默认每 1 秒轮询一次(可调RemoteControlPollIntervalMs),大规模部署时应统计请求量并合理设计数据库读写;截图任务会带来数十 MB 的汇报请求,需要放大代理与网关的请求体上限。

作为被控制端,MAA 侧的全部逻辑集中在 RemoteControlService.cs,配置项定义在 RemoteControl.cs,设置界面见 RemoteControlUserControl.xaml。需要查阅更多协议细节时,可对照多语言版本规范文档(中文版、日文版)以及 MAA 总协议索引 protocol/README.md。

【免费下载链接】MaaAssistantArknights《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients.项目地址: https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknights

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询