
MAA 远程控制协议开发指南构建基于 HTTP 的 MaaAssistantArknights 任务调度服务【免费下载链接】MaaAssistantArknights《明日方舟》小助手全日常一键长草| A one-click tool for the daily tasks of Arknights, supporting all clients.项目地址: https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknightsMAAMaaAssistantArknights为《明日方舟》自动化工具提供了完整的远程控制协议允许第三方服务通过两个匿名 HTTP(S) 端点向运行中的 MAA 实例下发任务、接收执行结果从而实现 QQ 机器人、网页管理后台等形态的远程调度。本文基于仓库中的 远程控制协议规范结合 RemoteControlService.cs 等源码实现完整讲解协议的数据格式、任务类型、配置方式与两类端到端接入示例。读完后你将能够独立实现一个合规的 MAA 远程控制服务端。协议概览两个端点一种轮询模型远程控制的核心是一个简单的请求-响应轮询模型。被控制的 MAA 客户端扮演轮询方而你的服务端只需要提供两个匿名可访问的 HTTP(S) Web 端点端点方向作用任务获取端点Task Retrieval EndpointMAA → 服务端MAA 以固定间隔持续轮询获取待执行任务并顺序执行任务汇报端点Task Reporting EndpointMAA → 服务端MAA 完成任务后向服务端汇报执行结果与附加数据两个端点均由服务端提供路径完全自由例如https://your-control-host.net/maa/getTask与https://your-control-host.net/maa/reportStatus。MAA 在配置界面中分别填入这两个地址即可建立连接。在 RemoteControlService.cs 中可以看到轮询的实现PollJobTaskLoop每经过RemoteControlPollIntervalMs默认 1000ms就向任务获取端点发起一次 POST 请求解析返回的tasks数组后根据任务类型分别放入顺序任务队列_sequentialTaskQueue或即时任务队列_instantTaskQueue由两个独立的执行循环ExecuteSequentialJobLoop与ExecuteInstantJobLoop消费。安全警告请务必使用 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设备标识符只读但可重新生成界面上设备标识符输入框为IsReadOnlyTrue旁边的重新生成按钮调用 RegenerateDeviceIdentity用Guid.NewGuid().ToString(N)生成新的设备标识。若你为用户管理设备请务必提示用户把重新生成后的标识更新到你的服务端。测试连接设置界面的测试连接按钮调用 ConnectionTest向任务获取端点发送一次POST { user, device }根据 HTTP 状态码弹窗提示连接测试成功或连接测试失败原因: {0}。这正是协议示例中用户按下测试连接按钮行为的来源。配置持久化与加密存储端点、用户标识、设备标识在写入配置时经过SimpleEncryptionHelper.Encrypt加密后落盘轮询间隔则以明文存储。从安全角度看这些凭据至少不是以明文形式保存在配置文件中。动态启停一旦填入了合法的任务获取端点RemoteControlService.InitializePollJobTask()会立即启动三个后台循环轮询、顺序任务执行、即时任务执行若端点被清空循环会自动退出并把_inited复位见 InitializePollJobTask。注意JSON 文件不支持注释。规范中的注释如// User identifier...仅用于演示切勿直接复制到生产配置中。任务获取端点协议请求格式端点必须接受POST请求Content-Typeapplication/json请求体为{ user: ea6c39eb-a45f-4d82-9ecc-33a7bf2ae4dc, device: f7cd9682-3de9-4eef-9137-ec124ea9e9ec }user用户在 MAA 设置中填写的用户标识符。deviceMAA 自动生成的设备标识符。除这两个字段外你可以按需增加自定义字段但 MAA 只发送user和device两者。在源码中该请求由 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工具箱单抽对应GachaOnceToolbox-GachaTenTimes工具箱十连对应GachaTenTimesCaptureImage截图当前模拟器画面截图以 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。当前白名单仅有ConnectAddress与Stage1两个其他任何设置都不接受远程修改。即时任务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任务执行结果取值为SUCCESS或FAILED。一般情况下即使任务实际执行失败也会返回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完整流程注册与识别getTask接口对所有请求返回200 OK和空的tasks列表。每次收到请求时检查数据库是否存在该设备记录若不存在则把device与user记录入库——该接口同时承担了用户注册职能。绑定机器人在 QQ 频道提供提交deviceId的命令。用户按要求在 MAA 的用户标识符栏填写自己的 QQ 号并通过 QQ 聊天把 MAA 生成的设备标识符发送给机器人。机器人收到后根据消息中的 QQ 号在数据库查对应记录查不到则提示用户先配置 MAA。验证由于 MAA 配置完成后会持续发送轮询请求用户通过 QQ 提交设备标识时数据库理应已存在对应记录。机器人将这条记录标记为已验证此后该deviceuser组合的getTask请求才会返回真实任务列表。下发任务用户在 QQ 发送命令后机器人把任务写入数据库getTask在下一次轮询时将其返回。示例中机器人还会在每个用户命令后自动附带一个截图任务以便回传执行画面。结果回传MAA 执行完毕后调用reportStatus汇报机器人解析结果并向用户发送 QQ 消息、展示截图。这个示例的巧妙之处在于轮询请求本身被复用为在线注册与心跳机制——只要 MAA 配置正确服务端就能持续感知实例的在线状态。端到端示例二用网页后台批量管理 MAA开发者 B 为批量管理 MAA 实例搭建了带用户体系的网站同样只提供两个匿名端点https://mywebsite.com/maa/getTask https://mywebsite.com/maa/reportStatus与示例一的差异点用户键网站将用户键User Key随机字符串展示给用户用户需将其填入 MAA 的用户标识符同时把设备标识符填回网站上的输入框。鉴权通过行为实现网站只有在 MAA 连接创建成功后才让getTask返回200 OK否则返回401 Unauthorized。用户若在 MAA 中填错信息并点击测试连接按钮就会收到连接测试失败通知——这正是 MAA 侧 ConnectionTest 根据非 2xx 状态码弹出失败提示的行为。任务管理用户可在网站上发布任务、排队、查看截图实现方式与 QQ 机器人示例同构——都是通过getTask下发、reportStatus回收结果。服务端实现要点总结综合规范与源码一个合规服务端需要满足以下硬性要求两个匿名端点均接受POST application/json无需任何鉴权头鉴权通过user/device与 HTTP 状态码隐式完成。tasks字段不可缺失getTask响应缺少tasks数组会被视为连接无效。任务 ID 全局唯一且可重入MAA 按 ID 去重同一 ID 不会重复执行端点应能安全地反复返回相同任务列表。立即执行的快捷任务StopTask需要配合HeartBeat使用才能可靠确认停止状态。注意负载单实例默认每 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),仅供参考