diff --git a/MAA_README.md b/MAA_README.md
index 95e05c2..d73d203 100644
--- a/MAA_README.md
+++ b/MAA_README.md
@@ -43,16 +43,21 @@ MAA会以1秒的间隔持续轮询这个端点,尝试获取他要执行的任
},
{
"id": "15be4725-5bd3-443d-8ae3-0a5ae789254c", //任务的唯一id,字符串类型,在汇报任务时会使用
- "type": "LinkStart", //启动一键长草
+ "type": "LinkStart", //启动一键长草
},
{
"id": "15be4725-5bd3-443d-8ae3-0a5ae789254c", //任务的唯一id,字符串类型,在汇报任务时会使用
- "type": "LinkStart-Recruiting", //一键长草的子功能。立即根据当前配置,单独执行一键长草中的对应子功能,无视主界面上该功能的勾选框。这一类Type的可选值为:LinkStart-Base,LinkStart-WakeUp,LinkStart-Combat,LinkStart-Recruiting,LinkStart-Mall,LinkStart-Mission,LinkStart-AutoRoguelike,LinkStart-ReclamationAlgorithm
+ "type": "LinkStart-Recruiting", //立即根据当前配置,单独执行一键长草中的对应子功能,无视主界面上该功能的勾选框。这一类Type的可选值详见下述
},
{
"id": "b353c469-b902-4357-bd8f-d133199eea31", //任务的唯一id,字符串类型,在汇报任务时会使用
"type": "Toolbox-GachaOnce", //工具箱中的牛牛抽卡任务,该类Type的可选取值为:Toolbox-GachaOnce, Toolbox-GachaTenTimes
},
+ {
+ "id": "b353c469-b902-4357-bd8f-d133199eea31", //任务的唯一id,字符串类型,在汇报任务时会使用
+ "type": "Settings-ConnectionAddress", //修改配置项的任务,等同于执行ConfigurationHelper.SetValue("ConnectionAddress", params); 为了安全起见,不是每个配置都可以修改,能修改的配置详见下述。
+ "params": "value" //要修改的值
+ },
],
... // 如果你的这个端点还有其他用途,你可以自行添加可选的返回值,但是MAA只会读取tasks
}
@@ -61,6 +66,11 @@ MAA会以1秒的间隔持续轮询这个端点,尝试获取他要执行的任
这些任务会被按顺序执行,也就是说如果你先发下一个公招任务,再发下一个截图任务,则截图会在公招任务结束后执行。
该端点应当可以重入并且重复返回需要执行的任务,MAA会自动记录任务Id,对于相同的Id,不会重复执行。
+备注:
+- LinkStart-[TaskName]型的任务type的可选值为LinkStart-Base,LinkStart-WakeUp,LinkStart-Combat,LinkStart-Recruiting,LinkStart-Mall,LinkStart-Mission,LinkStart-AutoRoguelike,LinkStart-ReclamationAlgorithm
+- Settings-[SettingsName]型的任务的type的可选值为Settings-ConnectionAddress
+- Settings系列任务仍然是要按顺序执行的,并不会在收到任务的时候立刻执行,而是排在上一个任务的后面。
+
## 汇报任务端点
每当MAA执行完一个任务,他就会通过该端点将任务的执行结果汇报给远端。
diff --git a/README.md b/README.md
index 837547d..2bdfe75 100644
--- a/README.md
+++ b/README.md
@@ -2,21 +2,22 @@
**财产损失警告!MAA控制的是你真实的明日方舟账户。尽管MAA的开发者和本插件的开发者尽了最大努力,但是程序开发不可避免的存在Bug。因此,对于使用MAA,以及本插件,所造成的的财产损失,本插件的开发者,以及MAA的开发者概不负责。**
+**喜报!远程控制功能已经正式加入官方MAA,从最新版的v4.25.0开始,可以直接使用官方MAA对接此插件进行控制。**
+
**和MAA的对接需要大量测试!希望各位用户和开发者,能够尽可能多在Github上提Issue,不管是提交Bug,还是推荐新的功能。(不过我只有每天晚上有时间写代码呜呜呜)**
-如果你发现MAA在远控时执行逻辑有问题,比如说“执行完十连抽后执行基建排班会导致页面卡死,因为基建排班功能不能从抽卡页面起始。”这样的bug,也请汇报给我,让我修改兔兔插件的任务下发逻辑,比如在基建排班之前插入一个唤醒之类的。
+如果你发现MAA在远控时执行逻辑有问题,比如说“执行完十连抽后执行基建排班会导致页面卡死,因为基建排班功能不能从抽卡页面起始。”这样的bug,也请汇报给我,让我修改兔兔插件的任务下发逻辑,比如在基建排班之前插入一个唤醒,或者调整MAA的相关代码之类的。
## 更新提示
-2.0版本起,不再使用独立开发的被控端,转而使用一个特制的WindowsWPF版MAA客户端。用来防止各种各样的连接问题。
-
-**新旧插件不兼容!**如果你发现新版本有问题,并且旧版本可以使用,你可以先暂时使用旧版插件以及旧版被控端。
-
+2.0版本起,将直接使用MAA的远程控制功能。**新旧插件不兼容!**,因为MAA已经正式支持远控,建议所有用户放弃旧版插件。
现在,再连不上模拟器,就去找玛丽报Bug吧:-)
+2.2版本加入了切换连接地址的命令。
+
## 这是什么
-1. 安装了该插件以后,使用一个特殊版本的MAA,可以实现通过兔兔聊天控制MAA。
+1. 安装了该插件以后,可以实现通过兔兔聊天控制MAA。
2. 每个群友需要自己启动模拟器和安装配置MAA。
3. 兔兔部署者则需要提供一个公网域名或者IP,以供群友的被控端连接。
4. 安装该插件后,插件会检查你的链接密钥,就是连接Console填写的那个,**如果这个密钥强度不够,则不允许使用本功能**。这是为了防止兔兔被暴露到公网后,出现各种安全隐患。密钥要求必须要有一个大写字母,一个小写字母,一个数字和一个特殊符号,并且要8位以上。
@@ -34,7 +35,7 @@
如果你还不知道MAA的话,快去下面的链接看看吧。
-[快去给玛丽点赞把](https://github.com/MaaAssistantArknights/MaaAssistantArknights)
+[快去给玛丽点赞吧](https://github.com/MaaAssistantArknights/MaaAssistantArknights)
## 如何使用
@@ -43,24 +44,22 @@
1. 首先您需要到控制台的设置页面填入您的公网ip地址和域名,就像填写在控制台里的那样。
2. 然后,然后就完事了,剩下的就交给兔兔。
-3. 有条件的话,建议最好去Github上下载这个特制的MAA.exe并放到群文件里,因为Github有些地方的人可能打不开。
- [特制MAA下载地址](https://github.com/hsyhhssyy/amiyabot-arknights-hsyhhssyy-maa/releases/)
+**注意,目前版本的兔兔,Web服务启动时,有可能会出现顺序异常导致服务不生效,具体表现为有人访问/maa/getTask或/maa/reportStatus时报告404NotFound,兔兔会在未来版本修复此问题。目前遇到时请重启兔兔,还不行的话多重启几次就会好,一旦没问题了,只要兔兔不关闭,就不会再出问题。**
我是兔兔的群友
-1. 首先你需要下载安装一个MAA,目前仅支持Windows版本。
-2. 你需要下载特殊版本的MAA.exe文件并用它替换MAA文件夹下的对应文件。
-3. 启动这个特制的MAA,确定能用它连接模拟器并配置好了各项功能。至少配置好一键长草并确定可以执行。具体流程请参照MAA的教程。
-4. 打开MAA的设置,进入“远程控制”,在用户标识符中填入你的QQ号。
-5. 如果设备标识符为空,按一下旁边的重新生成按钮,生成一个。
-6. 在群聊中说`兔兔如何连接MAA`,兔兔会回复你要填写的地址。
-7. 将兔兔说的地址,填写到MAA中`远程控制`设置的`获取任务端点`和`汇报任务端点`文本框里
-8. 复制设备标识符,然后到群里,说`兔兔记录MAA设备<设备标识符>`让兔兔记住。不必担心其他人看到,他们就算复制了这个标识符也没用。
+1. 首先你需要下载安装一个MAA,目前仅支持Windows版本的MAA。
+2. 启动MAA,确定能用它连接模拟器并配置好了各项功能。至少配置好一键长草并确定可以执行。具体流程请参照MAA的教程。
+3. 打开MAA的设置,进入“远程控制”,在用户标识符中填入你的QQ号。
+4. 如果设备标识符为空,按一下旁边的重新生成按钮,生成一个。
+5. 在群聊中说`兔兔如何连接MAA`,兔兔会回复你要填写的地址。
+6. 将兔兔说的地址,填写到MAA中`远程控制`设置的`获取任务端点`和`汇报任务端点`文本框里
+7. 复制设备标识符,然后到群里,说`兔兔记录MAA设备<设备标识符>`让兔兔记住。不必担心其他人看到,他们就算复制了这个标识符也没用。
- ![记住密钥](https://raw.githubusercontent.com/hsyhhssyy/amiyabot-arknights-hsyhhssyy-maa/master/docs/remember_did.png)
+![记住密钥](https://raw.githubusercontent.com/hsyhhssyy/amiyabot-arknights-hsyhhssyy-maa/master/docs/remember_did.png)
-9. 接下来就是挂机,然后去群聊里和兔兔聊天吧。
+8. 接下来就是挂机,然后去群聊里和兔兔聊天吧。
## 兔兔支持的命令
@@ -94,6 +93,12 @@
| 兔兔MAA十连抽 | 进行一次十连抽(这是真实抽卡!) | 2.1 |
| 兔兔MAA单抽 | 进行一次单抽(这是真实抽卡!) | 2.1 |
+### 修改配置子功能
+
+| 命令 | 说明 | 引入版本 |
+| ---- | ---- | ---- |
+| 兔兔MAA切换连接地址emulator-5554 | 修改`设置->连接设置->连接地址`配置项的值,可用于切换模拟器。使用时连接地址紧跟在命令后。 | 2.2 |
+
**任务会按顺序执行,如果你下发了一个无限持续的任务(比如刷999999把肉鸽),那你后续的指令都不会生效了。**
截图存储在resource/maa-adapter/screenshots文件夹下,请注意定时清理。
@@ -102,22 +107,26 @@
## 我也想做一个控制端
-如果也想要利用这个特制的MAA.exe实现一个自己的控制端,你可以 [看这里](https://github.com/hsyhhssyy/amiyabot-arknights-hsyhhssyy-maa/blob/master/MAA_README.md)
+现在可以去看MAA的[官方开发文档](
+https://maa.plus/docs/3.8-%E8%BF%9C%E7%A8%8B%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE.html)来了解如何开发控制端了。
+
## 鸣谢
> [插件项目地址:Github](https://github.com/hsyhhssyy/amiyabot-arknights-hsyhhssyy-maa/)
-> [被控端项目地址:Github](https://github.com/hsyhhssyy/amiyabot-maa-adapter/)
-
> [遇到问题可以在这里反馈(Github)](https://github.com/hsyhhssyy/amiyabot-arknights-hsyhhssyy-maa/issues/new/)
> [如果上面的连接无法打开可以在这里反馈(Gitee)](https://gitee.com/hsyhhssyy/amiyabot-plugin-bug-report/issues/new)
-> [Logo作者:Sesern老师](https://space.bilibili.com/305550122)
+> Logo作者: Stable-Diffusion
| 版本 | 变更 |
| ---- | ---- |
| 1.0 | 内部测试版本 |
| 1.1 | 提高了功能函数的优先级防止被公招功能覆盖,现在一键长草会说出下发的具体任务 |
-| 1.2 | 修改了检测秘钥的代码,输出更友好的信息 |
\ No newline at end of file
+| 1.2 | 修改了检测秘钥的代码,输出更友好的信息 |
+| 2.0 | 大幅修改并使用MAA自身来进行远控 |
+| 2.1 | 增加功能,并提供针对官方版MAA的说明 |
+| 2.2 | 增加功能 |
+| 2.3 | 适配新版兔兔 |
\ No newline at end of file
diff --git a/README_USE.md b/README_USE.md
index eae1998..3683224 100644
--- a/README_USE.md
+++ b/README_USE.md
@@ -1,14 +1,13 @@
## 如何连接
-1. 首先你需要下载安装一个MAA,目前仅支持Windows版本。
-2. 你需要下载特殊版本的MAA.exe文件并用它替换MAA文件夹下的对应文件。
-3. 启动这个特制的MAA,确定能用它连接模拟器并配置好了各项功能。至少配置好一键长草并确定可以执行。具体流程请参照MAA的教程。
-4. 打开MAA的设置,进入“远程控制”,在用户标识符中填入你的QQ号。
-5. 如果设备标识符为空,按一下旁边的重新生成按钮,生成一个。
-6. 在群聊中说`兔兔如何连接MAA`,兔兔会回复你要填写的地址。
-7. 将兔兔说的地址,填写到MAA中`远程控制`设置的`获取任务端点`和`汇报任务端点`文本框里
-8. 复制设备标识符,然后到群里,说`兔兔记录MAA设备<设备标识符>`让兔兔记住。不必担心其他人看到,他们就算复制了这个标识符也没用。
-9. 接下来就是挂机,然后去群聊里和兔兔聊天吧。
+1. 首先你需要下载安装一个MAA,目前仅支持Windows版本的MAA。
+2. 启动MAA,确定能用它连接模拟器并配置好了各项功能。至少配置好一键长草并确定可以执行。具体流程请参照MAA的教程。
+3. 打开MAA的设置,进入“远程控制”,在用户标识符中填入你的QQ号。
+4. 如果设备标识符为空,按一下旁边的重新生成按钮,生成一个。
+5. 在群聊中说`兔兔如何连接MAA`,兔兔会回复你要填写的地址。
+6. 将兔兔说的地址,填写到MAA中`远程控制`设置的`获取任务端点`和`汇报任务端点`文本框里
+7. 复制设备标识符,然后到群里,说`兔兔记录MAA设备<设备标识符>`让兔兔记住。不必担心其他人看到,他们就算复制了这个标识符也没用。
+8. 接下来就是挂机,然后去群聊里和兔兔聊天吧。
## 兔兔支持的命令
@@ -42,4 +41,10 @@
| 兔兔MAA十连抽 | 进行一次十连抽(这是真实抽卡!) | 2.1 |
| 兔兔MAA单抽 | 进行一次单抽(这是真实抽卡!) | 2.1 |
+### 修改配置子功能
+
+| 命令 | 说明 | 引入版本 |
+| ---- | ---- | ---- |
+| 兔兔MAA切换连接地址emulator-5554 | 修改`设置->连接设置->连接地址`配置项的值,可用于切换模拟器。使用时连接地址紧跟在命令后。 | 2.2 |
+
**任务会按顺序执行,如果你下发了一个无限持续的任务(比如刷999999把肉鸽),那你后续的指令都不会生效了。**
\ No newline at end of file
diff --git a/logo.png b/logo.png
index 28b3bc2..9d34037 100644
Binary files a/logo.png and b/logo.png differ
diff --git a/main.py b/main.py
index af78114..760afdc 100644
--- a/main.py
+++ b/main.py
@@ -9,7 +9,7 @@
from amiyabot import Message, Chain
from core.util import check_file_content
-from core.customPluginInstance import AmiyaBotPluginInstance
+from core import AmiyaBotPluginInstance
from .server import server_api
from .server.server_api import external_adapters
@@ -41,10 +41,10 @@ def install(self):
bot = MaaAdapterPluginInstance(
name='MAA对接器',
- version='2.1',
+ version='2.3',
plugin_id='amiyabot-arknights-hsyhhssyy-maa',
plugin_type='',
- description='用于对接MAA',
+ description='MAA远程控制功能控制端的兔兔实现',
document=f'{curr_dir}/README.md',
instruction=f'{curr_dir}/README_USE.md',
global_config_default=f'{curr_dir}/configs/global_config_default.json',
@@ -62,7 +62,7 @@ async def get_connection(data: Message):
AmiyaBotMAAConnection.user_id == data.user_id)
if conn is None:
- await data.send(Chain(data).text('博士,您还没有绑定连接秘钥。'))
+ await data.send(Chain(data).text('博士,您还没有绑定连接秘钥。请发送"兔兔如何连接MAA"查看如何绑定。'))
return False, None
if conn.validated == False:
@@ -81,9 +81,9 @@ async def maa_start(data: Message):
conn_str = bot.get_config("connection_string").rstrip("/")
if conn_str is None or conn_str == "":
- return Chain(data, at=False).text('博士,兔兔没有设置连接地址哦。')
+ return Chain(data, at=False).text('博士,兔兔没有设置连接地址,请联系兔兔管理员。')
- instStr = f'获取任务端点是: {conn_str}/maa/getTask \n汇报任务端点是: {conn_str}/maa/reportStatus \n特制的Maa.exe下载地址是: https://github.com/hsyhhssyy/amiyabot-arknights-hsyhhssyy-maa/releases/'
+ instStr = f'获取任务端点是: {conn_str}/maa/getTask \n汇报任务端点是: {conn_str}/maa/reportStatus'
return Chain(data, at=False).markdown(check_file_content(f'{curr_dir}/README_USE.md')).text(instStr)
@@ -125,6 +125,29 @@ async def message_loop():
def create_my_message_filter_lambda(original_data):
return lambda data: data.user_id == original_data.user_id
+@bot.on_message(keywords=['MAA强制停止'], level=5)
+async def maa_fight(data: Message):
+
+ valid, conn = await get_connection(data)
+
+ if not valid:
+ return
+
+ task_uuid = str(uuid.uuid4())
+ AmiyaBotMAATask.create(connection=conn.id, uuid=task_uuid, type="StopTask",
+ parameter=None, status="ASSIGNED", create_at=datetime.now())
+
+ async def message_loop():
+ while True:
+ await asyncio.sleep(1)
+ task = AmiyaBotMAATask.get(AmiyaBotMAATask.uuid == task_uuid)
+ # log.info(f'{task.payload}')
+ if task.status == "SUCCESS":
+ await data.send(Chain(data).text(f'博士,当前正在进行的任务已停止。'))
+ return
+
+ asyncio.create_task(message_loop())
+
@bot.on_message(keywords=['MAA截图'], level=5)
async def maa_fight(data: Message):
@@ -141,14 +164,52 @@ async def maa_fight(data: Message):
wait_snapshot(data,task_uuid)
-async def assign_simple_task_with_snapshot(data,maa_type,mission_str):
+@bot.on_message(keywords=['MAA立即截图'], level=5)
+async def maa_fight(data: Message):
+
+ valid, conn = await get_connection(data)
+
+ if not valid:
+ return
+
+ task_uuid = str(uuid.uuid4())
+ AmiyaBotMAATask.create(connection=conn.id, uuid=task_uuid, type="CaptureImageNow",
+ parameter=None, status="ASSIGNED", create_at=datetime.now())
+
+ wait_snapshot(data,task_uuid)
+
+@bot.on_message(keywords=['MAA当前任务'], level=5)
+async def maa_fight(data: Message):
+
+ valid, conn = await get_connection(data)
+
+ if not valid:
+ return
+
+ task_uuid = str(uuid.uuid4())
+ AmiyaBotMAATask.create(connection=conn.id, uuid=task_uuid, type="HeartBeat",
+ parameter=None, status="ASSIGNED", create_at=datetime.now())
+
+ async def message_loop():
+ while True:
+ await asyncio.sleep(1)
+ task = AmiyaBotMAATask.get(AmiyaBotMAATask.uuid == task_uuid)
+ # log.info(f'{task.payload}')
+ if task.payload is not None and task.payload != "":
+ currentTask = AmiyaBotMAATask.get(AmiyaBotMAATask.uuid == task.payload)
+ await data.send(Chain(data).text(f'博士,当前正在进行的任务是:{currentTask.type}。'))
+ return
+
+ asyncio.create_task(message_loop())
+
+async def assign_simple_task_with_snapshot(data,maa_type,mission_str,parameter=""):
valid, conn = await get_connection(data)
if not valid:
return
AmiyaBotMAATask.create(connection=conn.id, uuid=str(uuid.uuid4()), type=maa_type,
- parameter="", status="ASSIGNED", create_at=datetime.now())
+ parameter=parameter, status="ASSIGNED", create_at=datetime.now())
snapshot_task_uuid = str(uuid.uuid4())
AmiyaBotMAATask.create(connection=conn.id, uuid=snapshot_task_uuid, type="CaptureImage",
@@ -158,6 +219,17 @@ async def assign_simple_task_with_snapshot(data,maa_type,mission_str):
return Chain(data).text(f'博士,{mission_str}任务已布置,干员们会努力做好罗德岛的日常工作的,任务结束后将发送截图给您。')
+async def assign_simple_task(data,maa_type,mission_str,parameter=""):
+
+ valid, conn = await get_connection(data)
+ if not valid:
+ return
+
+ AmiyaBotMAATask.create(connection=conn.id, uuid=str(uuid.uuid4()), type=maa_type,
+ parameter=parameter, status="ASSIGNED", create_at=datetime.now())
+
+ return Chain(data).text(f'博士,{mission_str}任务已布置,干员们会努力做好罗德岛的日常工作的。')
+
@bot.on_message(keywords=['MAA一键长草'], level=5)
async def maa_fight(data: Message):
return await assign_simple_task_with_snapshot(data,"LinkStart","一键长草")
@@ -244,4 +316,17 @@ async def maa_gacha(data: Message):
else:
await data.send(Chain(data).text('博士,单次寻访任务已取消'))
- return
\ No newline at end of file
+ return
+
+@bot.on_message(keywords=['MAA切换连接地址'], level=5)
+async def maa_fight(data: Message):
+
+ pattern = r"MAA切换连接地址([\s\S]*)"
+
+ match = re.search(pattern, data.text_original)
+ if match:
+ newStr = match.group(1)
+ return await assign_simple_task(data,"Settings-ConnectAddress","切换连接地址",newStr)
+ else:
+ return Chain(data).text(f'博士,您没有提供连接地址。')
+
diff --git a/server/server_api.py b/server/server_api.py
index 9182b1d..e01b9f2 100644
--- a/server/server_api.py
+++ b/server/server_api.py
@@ -86,6 +86,8 @@ async def report_status(self, data: ReportStatusModel):
f.write(base64.b64decode(data.payload))
task.payload = f'{screenshot_dir}/{task.uuid}.png'
log.info(f'{task.payload}')
+ else:
+ task.payload = data.payload
task.save()