mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-20 10:57:45 +08:00
Merge branch 'MaaAssistantArknights:dev' into dev
This commit is contained in:
@@ -1,20 +1,12 @@
|
||||
- 自动战斗
|
||||
- 大幅优化识别及操作延迟
|
||||
- 新增支持按坐标撤退/释放技能(不填坐标就还是按干员名,仍推荐尽量用干员名)
|
||||
- 新增支持关卡 id 输入(第十章磨难关卡请使用关卡 id)
|
||||
- 修复几个干员名识别问题
|
||||
- 修复作业制作器的一些小问题
|
||||
- 修复击杀数识别错误
|
||||
- 修复偶尔部署不上去的问题
|
||||
|
||||
- 肉鸽
|
||||
- 新增支持月底小队,但仍然是无限刷的,请手动结束任务
|
||||
- 同样大幅优化识别及操作延迟
|
||||
|
||||
- 自动公招
|
||||
- 新增支持跳过 `支援机械` 并弹出通知,可在设置中关闭
|
||||
- 刷理智
|
||||
- 新增支持游戏崩溃重连,需要在设置中开启 `唤醒设置`
|
||||
- 修复一个刷理智时的识别错误
|
||||
- 修复一个掉落识别错误的
|
||||
- 修复勾选材料后刷几次就自动停了的问题
|
||||
|
||||
- 其他
|
||||
- 大幅优化截图延迟及性能消耗
|
||||
- 新增支持启动明日方舟(不包括模拟器),请进入设置中开启~
|
||||
- 新增支持选择自动关机还是休眠/睡眠,在勾选 `自动关机` 后按 `H` 键弹出选项
|
||||
- Win10 将默认使用系统通知
|
||||
- 修复关卡导航失败的问题
|
||||
- 新增 adb 出错后的重连机制;及重连失败时的报错
|
||||
|
||||
@@ -22,13 +22,15 @@
|
||||
|
||||
"action": "ClickSelf", // 可选项,表示识别到后的动作
|
||||
// 不填写时默认为 DoNothing
|
||||
// - ClickSelf: 点击识别到的位置(识别到的目标范围内随机点)
|
||||
// - ClickRand: 点击整个画面中随机位置
|
||||
// - DoNothing: 什么都不做
|
||||
// - Stop: 停止当前任务
|
||||
// - ClickRect: 点击指定的区域,对应 specificRect 字段,不建议使用该选项
|
||||
// - SwipeToTheLeft: 滑动到最左侧
|
||||
// - SwipeToTheRight: 滑动到最右侧
|
||||
// - ClickSelf: 点击识别到的位置(识别到的目标范围内随机点)
|
||||
// - ClickRand: 点击整个画面中随机位置
|
||||
// - DoNothing: 什么都不做
|
||||
// - Stop: 停止当前任务
|
||||
// - ClickRect: 点击指定的区域,对应 specificRect 字段,不建议使用该选项
|
||||
// - SwipeToTheLeft: 滑动到最左侧
|
||||
// - SwipeToTheRight: 滑动到最右侧
|
||||
// - SlowlySwipeToTheLeft: 缓慢左滑
|
||||
// - SlowlySwipeToTheRight: 缓慢右滑
|
||||
|
||||
"sub": [ "SubTaskName1", "SubTaskName2" ],
|
||||
// 可选项,子任务。会在执行完当前任务后,依次执行每一个子任务
|
||||
@@ -40,7 +42,7 @@
|
||||
// 为 true 时,子任务是否出错没有影响
|
||||
|
||||
"next": [ "OtherTaskName1", "OtherTaskName2"],
|
||||
// 可选项,表示执行完当前任务后,下一个要执行的任务
|
||||
// 可选项,表示执行完当前任务和 sub 任务后,下一个要执行的任务
|
||||
// 会从前往后依次去识别,去执行第一个匹配上的
|
||||
// 不填写默认执行完当前任务直接停止
|
||||
|
||||
@@ -64,21 +66,24 @@
|
||||
// 但仅适用于待识别目标位置完全不会变的任务,若待识别目标位置会变请设为 false
|
||||
|
||||
"rectMove": [0, 0, 0, 0], // 可选项,识别后的目标移动,不建议使用该选项。以 1280 * 720 为基准自动缩放
|
||||
// 例如识别到了 A 图标,但实际要点击的是 A 图标旁边的某个位置,则进行移动后再点击。可以的话尽量直接识别要点击的位置,不建议使用该选项
|
||||
// 例如识别到了 A 图标,但实际要点击的是 A 图标旁边的某个位置,则进行移动后再点击。
|
||||
// 可以的话尽量直接识别要点击的位置,不建议使用该选项
|
||||
|
||||
"reduceOtherTimes": [ "OtherTaskName1", "OtherTaskName2" ],
|
||||
// 可选项,执行后减少其他任务的执行计数。
|
||||
// 例如执行了吃理智药,则说明上一次点击蓝色开始行动按钮没生效,所以蓝色开始行动要-1
|
||||
|
||||
"specificRect": [ 100, 100, 50, 50],
|
||||
// 仅当 action 为 ClickRect 时有效且必选,表示指定的点击位置(范围内随机一点)。以 1280 * 720 为基准自动缩放
|
||||
// 仅当 action 为 ClickRect 时有效且必选,表示指定的点击位置(范围内随机一点)。
|
||||
// 以 1280 * 720 为基准自动缩放
|
||||
|
||||
/* 以下字段仅当 algorithm 为 MatchTemplate 时有效 */
|
||||
|
||||
"templThreshold": 0.8, // 可选项,图片模板匹配得分的阈值,超过阈值才认为识别到了。
|
||||
// 默认 0.8, 可根据日志查看实际得分是多少
|
||||
|
||||
"maskRange": [ 1, 255 ], // 可选项,灰度掩码范围。例如将图片不需要识别的部分涂成黑色(灰度值为 0),然后设置 [ 1, 255 ], 匹配的时候即刻忽略涂黑的部分
|
||||
"maskRange": [ 1, 255 ], // 可选项,灰度掩码范围。例如将图片不需要识别的部分涂成黑色(灰度值为 0)
|
||||
// 然后设置"maskRange"的范围为 [ 1, 255 ], 匹配的时候即刻忽略涂黑的部分
|
||||
|
||||
|
||||
/* 以下字段仅当 algorithm 为 OcrDetect 时有效 */
|
||||
|
||||
@@ -81,6 +81,10 @@ Todo
|
||||
分辨率不被支持
|
||||
- `ResolutionError`
|
||||
分辨率获取错误
|
||||
- `Disconnect`
|
||||
连接断开(adb / 模拟器 炸了,且已经重试过一次)
|
||||
- `CommandExecFailed`
|
||||
命令执行失败(adb / 模拟器 炸了,且已经重试过一次)
|
||||
|
||||
#### AllTasksCompleted
|
||||
|
||||
|
||||
@@ -45,6 +45,12 @@ TaskId ASSTAPI AsstAppendTask(AsstHandle handle, const char* type, const char* p
|
||||
"medicine": int, // 最大使用理智药数量,可选,默认 0
|
||||
"stone": int, // 最大吃石头数量,可选,默认 0
|
||||
"times": int, // 指定次数,可选,默认无穷大
|
||||
"drops": { // 指定掉落数量,可选,默认不指定
|
||||
"30011": int, // key - item_id, value 数量. key 可参考 resource/item_index.json 文件
|
||||
"30062": int // 是或的关系
|
||||
},
|
||||
/* 以上全部是或的关系,即任一达到即停止任务 */
|
||||
|
||||
"report_to_penguin": bool, // 是否汇报企鹅数据,可选,默认 false
|
||||
"penguin_id": string, // 企鹅数据汇报 id, 可选,默认为空。仅在 report_to_penguin 为 true 时有效
|
||||
"server": string // 服务器,可选,默认 "CN", 会影响掉落识别及上传
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
"display": "[Adb] -s [AdbSerial] shell dumpsys window displays | grep init=",
|
||||
"displayFormat": " init=%dx%d",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncAddress": "[Adb] -s [AdbSerial] shell \" cat /proc/net/arp | grep : \"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p",
|
||||
@@ -49,6 +50,7 @@
|
||||
"display": "[Adb] -s [AdbSerial] shell dumpsys window displays | grep init= | awk ' { print $3 } '",
|
||||
"displayFormat": "cur=%dx%d",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncAddress": "[Adb] -s [AdbSerial] shell \" cat /proc/net/arp | grep : \"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p",
|
||||
@@ -65,6 +67,7 @@
|
||||
"display": "[Adb] -s [AdbSerial] shell dumpsys window displays | grep init= | awk ' { print $3 } '",
|
||||
"displayFormat": "cur=%dx%d",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncAddress": "[Adb] -s [AdbSerial] shell \" cat /proc/net/arp | grep : \"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p",
|
||||
@@ -80,7 +83,8 @@
|
||||
"swipe": "[Adb] -s [AdbSerial] shell input swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [AdbSerial] shell dumpsys window displays | grep init= | awk ' { print $3 } '",
|
||||
"displayFormat": "cur=%dx%d",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] shell \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncAddress": "[Adb] -s [AdbSerial] shell \" cat /proc/net/arp | grep : \"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] shell screencap -p",
|
||||
@@ -97,6 +101,7 @@
|
||||
"display": "[Adb] -s [AdbSerial] shell dumpsys window displays | grep init= | awk ' { print $3 } '",
|
||||
"displayFormat": "cur=%dx%d",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncAddress": "[Adb] -s [AdbSerial] shell \" cat /proc/net/arp | grep : \"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p",
|
||||
@@ -113,6 +118,7 @@
|
||||
"display": "[Adb] -s [AdbSerial] shell dumpsys window displays | grep init=",
|
||||
"displayFormat": " init=%dx%d",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncAddress": "[Adb] -s [AdbSerial] shell \" cat /proc/net/arp | grep : \"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] shell screencap -p",
|
||||
@@ -130,6 +136,7 @@
|
||||
"display": "[Adb] -s [AdbSerial] shell \"wm size -d [DisplayId]\"",
|
||||
"displayFormat": "Physical size:%dx%d",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncAddress": "[Adb] -s [AdbSerial] shell \" cat /proc/net/arp | grep : \"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap -d [DisplayId] | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] shell screencap -d [DisplayId] -p",
|
||||
@@ -146,6 +153,7 @@
|
||||
"display": "[Adb] -s [AdbSerial] shell dumpsys window displays | grep init=",
|
||||
"displayFormat": " init=%dx%d",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncAddress": "[Adb] -s [AdbSerial] shell \" cat /proc/net/arp | grep : \"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p",
|
||||
|
||||
@@ -500,31 +500,19 @@
|
||||
},
|
||||
"StageCE": {
|
||||
"action": "ClickSelf",
|
||||
"cache": false,
|
||||
"next": [
|
||||
"StageCE6"
|
||||
]
|
||||
"cache": false
|
||||
},
|
||||
"StageLS": {
|
||||
"action": "ClickSelf",
|
||||
"cache": false,
|
||||
"next": [
|
||||
"StageLS6"
|
||||
]
|
||||
"cache": false
|
||||
},
|
||||
"StageCA": {
|
||||
"action": "ClickSelf",
|
||||
"cache": false,
|
||||
"next": [
|
||||
"StageCA5"
|
||||
]
|
||||
"cache": false
|
||||
},
|
||||
"StageAP": {
|
||||
"action": "ClickSelf",
|
||||
"cache": false,
|
||||
"next": [
|
||||
"StageAP5"
|
||||
]
|
||||
"cache": false
|
||||
},
|
||||
"AbleToAgent": {
|
||||
"algorithm": "JustReturn",
|
||||
@@ -827,6 +815,7 @@
|
||||
"UsePrts",
|
||||
"UsePrts-StageSN",
|
||||
"StartButton1",
|
||||
"PRTS3",
|
||||
"PRTS",
|
||||
"PRTS2",
|
||||
"EndOfAction"
|
||||
@@ -847,6 +836,10 @@
|
||||
1,
|
||||
255
|
||||
],
|
||||
"reduceOtherTimes": [
|
||||
"StartButton1",
|
||||
"StartButton2"
|
||||
],
|
||||
"next": [
|
||||
"GameStart",
|
||||
"StartToWakeUp",
|
||||
@@ -1161,6 +1154,7 @@
|
||||
340
|
||||
],
|
||||
"next": [
|
||||
"PRTS3",
|
||||
"PRTS",
|
||||
"PRTS2",
|
||||
"EndOfAction",
|
||||
@@ -1185,6 +1179,7 @@
|
||||
"rearDelay": 5000,
|
||||
"next": [
|
||||
"PRTS",
|
||||
"PRTS3",
|
||||
"PRTS2",
|
||||
"EndOfAction",
|
||||
"PrtsErrorConfirm",
|
||||
@@ -1206,6 +1201,7 @@
|
||||
"action": "DoNothing",
|
||||
"rearDelay": 5000,
|
||||
"next": [
|
||||
"PRTS3",
|
||||
"PRTS2",
|
||||
"PRTS",
|
||||
"EndOfAction",
|
||||
@@ -1214,26 +1210,52 @@
|
||||
"WaitAfterPRTS"
|
||||
]
|
||||
},
|
||||
"PRTS3": {
|
||||
"action": "DoNothing",
|
||||
"template": "BattleOfficiallyBegin.png",
|
||||
"roi": [
|
||||
1165,
|
||||
20,
|
||||
65,
|
||||
65
|
||||
],
|
||||
"maskRange": [
|
||||
100,
|
||||
255
|
||||
],
|
||||
"rearDelay": 5000,
|
||||
"next": [
|
||||
"PRTS3",
|
||||
"PRTS",
|
||||
"PRTS2",
|
||||
"EndOfAction",
|
||||
"PrtsErrorConfirm",
|
||||
"OfflineConfirm",
|
||||
"WaitAfterPRTS"
|
||||
]
|
||||
},
|
||||
"WaitAfterPRTS": {
|
||||
"algorithm": "JustReturn",
|
||||
"action": "DoNothing",
|
||||
"next": [
|
||||
"PRTS3",
|
||||
"PRTS",
|
||||
"PRTS2",
|
||||
"EndOfAction",
|
||||
"ClickCornerAfterPRTS"
|
||||
"ClickCornerAfterPRTS_1"
|
||||
]
|
||||
},
|
||||
"ClickCornerAfterPRTS": {
|
||||
"ClickCornerAfterPRTS_1": {
|
||||
"ClickCorner_Doc": "点击屏幕右边,不会点到掉落物品,且不会关掉关卡选择的一块区域",
|
||||
"algorithm": "JustReturn",
|
||||
"action": "ClickRect",
|
||||
"specificRect": [
|
||||
1000,
|
||||
10,
|
||||
120,
|
||||
270,
|
||||
120
|
||||
10
|
||||
],
|
||||
"rearDelay": 3000,
|
||||
"next": [
|
||||
"EndOfAction",
|
||||
"StartButton1",
|
||||
@@ -1241,7 +1263,59 @@
|
||||
"UseMedicine",
|
||||
"UseStone",
|
||||
"NoStone",
|
||||
"ClickCornerAfterPRTS"
|
||||
"ClickCornerAfterPRTS_2"
|
||||
]
|
||||
},
|
||||
"ClickCornerAfterPRTS_2": {
|
||||
"ClickCorner_Doc": "点击屏幕右边,不会点到掉落物品,且不会关掉关卡选择的一块区域",
|
||||
"algorithm": "JustReturn",
|
||||
"action": "ClickRect",
|
||||
"specificRect": [
|
||||
1000,
|
||||
120,
|
||||
270,
|
||||
10
|
||||
],
|
||||
"rearDelay": 3000,
|
||||
"next": [
|
||||
"EndOfAction",
|
||||
"StartButton1",
|
||||
"StartButton2",
|
||||
"UseMedicine",
|
||||
"UseStone",
|
||||
"NoStone",
|
||||
"MaybeCrashAndRestartGame"
|
||||
]
|
||||
},
|
||||
"MaybeCrashAndRestartGame": {
|
||||
"ClickCorner_Doc": "一般能点这么多下还不行的,多半是游戏崩了,所以重启游戏试试",
|
||||
"Doc": "本任务注册了插件 GameCrashRestartTaskPlugin",
|
||||
"algorithm": "JustReturn",
|
||||
"action": "ClickRect",
|
||||
"specificRect": [
|
||||
1000,
|
||||
120,
|
||||
270,
|
||||
10
|
||||
],
|
||||
"rearDelay": 3000,
|
||||
"next": [
|
||||
"EndOfAction",
|
||||
"StartButton1",
|
||||
"StartButton2",
|
||||
"UseMedicine",
|
||||
"UseStone",
|
||||
"NoStone",
|
||||
"GameStart",
|
||||
"StartToWakeUp",
|
||||
"StartUpConnectingFlag",
|
||||
"StartLoginBServer",
|
||||
"Terminal",
|
||||
"CloseAnno",
|
||||
"TodaysSupplies",
|
||||
"ReturnToTerminal",
|
||||
"OfflineConfirm",
|
||||
"StageSNFlag"
|
||||
]
|
||||
},
|
||||
"EndOfAction": {
|
||||
@@ -1267,9 +1341,9 @@
|
||||
"action": "ClickRect",
|
||||
"specificRect": [
|
||||
1000,
|
||||
10,
|
||||
120,
|
||||
270,
|
||||
120
|
||||
10
|
||||
],
|
||||
"next": [
|
||||
"StartButton1",
|
||||
@@ -1438,6 +1512,7 @@
|
||||
160
|
||||
],
|
||||
"next": [
|
||||
"PRTS3",
|
||||
"PRTS",
|
||||
"PRTS2",
|
||||
"PrtsErrorConfirm",
|
||||
@@ -6562,7 +6637,7 @@
|
||||
1280,
|
||||
2
|
||||
],
|
||||
"templThreshold": 25,
|
||||
"templThreshold": 17,
|
||||
"templThreshold_Doc": "这里用来作为基线间距阈值",
|
||||
"specialThreshold": 100,
|
||||
"specialThreshold_Doc": "基建长度阈值(不小于120)",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "Controller.h"
|
||||
#include "Logger.hpp"
|
||||
|
||||
asst::AbstractImageAnalyzer::AbstractImageAnalyzer(const cv::Mat image)
|
||||
asst::AbstractImageAnalyzer::AbstractImageAnalyzer(const cv::Mat& image)
|
||||
: m_image(image), m_roi(empty_rect_to_full(Rect(), image))
|
||||
#ifdef ASST_DEBUG
|
||||
,
|
||||
@@ -12,7 +12,7 @@ asst::AbstractImageAnalyzer::AbstractImageAnalyzer(const cv::Mat image)
|
||||
#endif
|
||||
{}
|
||||
|
||||
asst::AbstractImageAnalyzer::AbstractImageAnalyzer(const cv::Mat image, const Rect& roi)
|
||||
asst::AbstractImageAnalyzer::AbstractImageAnalyzer(const cv::Mat& image, const Rect& roi)
|
||||
: m_image(image),
|
||||
m_roi(empty_rect_to_full(roi, image))
|
||||
#ifdef ASST_DEBUG
|
||||
@@ -20,7 +20,6 @@ asst::AbstractImageAnalyzer::AbstractImageAnalyzer(const cv::Mat image, const Re
|
||||
m_image_draw(image.clone())
|
||||
#endif
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void asst::AbstractImageAnalyzer::set_image(const cv::Mat image)
|
||||
@@ -42,13 +41,13 @@ void asst::AbstractImageAnalyzer::set_roi(const Rect& roi) noexcept
|
||||
m_roi = empty_rect_to_full(roi, m_image);
|
||||
}
|
||||
|
||||
asst::Rect asst::AbstractImageAnalyzer::empty_rect_to_full(const Rect& rect, const cv::Mat image) noexcept
|
||||
asst::Rect asst::AbstractImageAnalyzer::empty_rect_to_full(const Rect& rect, const cv::Mat& image) noexcept
|
||||
{
|
||||
if (image.empty()) {
|
||||
return rect;
|
||||
}
|
||||
if (rect.empty()) {
|
||||
return Rect(0, 0, image.cols, image.rows);
|
||||
return {0, 0, image.cols, image.rows};
|
||||
}
|
||||
|
||||
Rect res = rect;
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace asst
|
||||
{
|
||||
public:
|
||||
AbstractImageAnalyzer() = default;
|
||||
AbstractImageAnalyzer(const cv::Mat image);
|
||||
AbstractImageAnalyzer(const cv::Mat image, const Rect& roi);
|
||||
AbstractImageAnalyzer(const cv::Mat& image);
|
||||
AbstractImageAnalyzer(const cv::Mat& image, const Rect& roi);
|
||||
AbstractImageAnalyzer(const AbstractImageAnalyzer&) = delete;
|
||||
AbstractImageAnalyzer(AbstractImageAnalyzer&&) = delete;
|
||||
virtual ~AbstractImageAnalyzer() = default;
|
||||
@@ -31,7 +31,7 @@ namespace asst
|
||||
AbstractImageAnalyzer& operator=(AbstractImageAnalyzer&&) = delete;
|
||||
|
||||
protected:
|
||||
static Rect empty_rect_to_full(const Rect& rect, const cv::Mat image) noexcept;
|
||||
static Rect empty_rect_to_full(const Rect& rect, const cv::Mat& image) noexcept;
|
||||
|
||||
bool save_img();
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <regex>
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <utility>
|
||||
|
||||
#include "AsstUtils.hpp"
|
||||
#include "Controller.h"
|
||||
@@ -16,11 +17,10 @@
|
||||
using namespace asst;
|
||||
|
||||
AbstractTask::AbstractTask(AsstCallback callback, void* callback_arg, std::string task_chain)
|
||||
: m_callback(callback),
|
||||
: m_callback(std::move(callback)),
|
||||
m_callback_arg(callback_arg),
|
||||
m_task_chain(std::move(task_chain))
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
bool asst::AbstractTask::run()
|
||||
@@ -64,13 +64,13 @@ AbstractTask& asst::AbstractTask::set_retry_times(int times) noexcept
|
||||
|
||||
AbstractTask& asst::AbstractTask::set_ctrler(std::shared_ptr<Controller> ctrler) noexcept
|
||||
{
|
||||
m_ctrler = ctrler;
|
||||
m_ctrler = std::move(ctrler);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AbstractTask& asst::AbstractTask::set_status(std::shared_ptr<RuntimeStatus> status) noexcept
|
||||
{
|
||||
m_status = status;
|
||||
m_status = std::move(status);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ bool AbstractTask::sleep(unsigned millisecond)
|
||||
return !need_exit();
|
||||
}
|
||||
|
||||
bool AbstractTask::save_image(const cv::Mat image, const std::string& dir)
|
||||
bool AbstractTask::save_image(const cv::Mat& image, const std::string& dir)
|
||||
{
|
||||
std::filesystem::create_directory(dir);
|
||||
const std::string time_str = utils::string_replace_all(utils::string_replace_all(utils::get_format_time(), " ", "_"), ":", "-");
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace asst
|
||||
json::value basic_info_with_what(std::string what) const;
|
||||
bool sleep(unsigned millisecond);
|
||||
bool need_exit() const;
|
||||
bool save_image(const cv::Mat image, const std::string& dir);
|
||||
bool save_image(const cv::Mat& image, const std::string& dir);
|
||||
|
||||
bool m_enable = true;
|
||||
bool m_ignore_error = true;
|
||||
|
||||
@@ -47,7 +47,7 @@ bool asst::AipOcr::request_access_token(const std::string& client_id, const std:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asst::AipOcr::request_ocr_general(const cv::Mat image, std::vector<TextRect>& out_result, const TextRectProc& pred)
|
||||
bool asst::AipOcr::request_ocr_general(const cv::Mat& image, std::vector<TextRect>& out_result, const TextRectProc& pred)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
@@ -62,7 +62,7 @@ bool asst::AipOcr::request_ocr_general(const cv::Mat image, std::vector<TextRect
|
||||
return request_ocr_and_parse(cmd_fmt, image, out_result, pred);
|
||||
}
|
||||
|
||||
bool asst::AipOcr::request_ocr_accurate(const cv::Mat image, std::vector<TextRect>& out_result, const TextRectProc& pred)
|
||||
bool asst::AipOcr::request_ocr_accurate(const cv::Mat& image, std::vector<TextRect>& out_result, const TextRectProc& pred)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
@@ -77,7 +77,7 @@ bool asst::AipOcr::request_ocr_accurate(const cv::Mat image, std::vector<TextRec
|
||||
return request_ocr_and_parse(cmd_fmt, image, out_result, pred);
|
||||
}
|
||||
|
||||
bool asst::AipOcr::request_ocr_and_parse(std::string_view cmd_fmt, const cv::Mat image, std::vector<TextRect>& out_result, const TextRectProc& pred)
|
||||
bool asst::AipOcr::request_ocr_and_parse(std::string_view cmd_fmt, const cv::Mat& image, std::vector<TextRect>& out_result, const TextRectProc& pred)
|
||||
{
|
||||
if (m_access_token.empty()) {
|
||||
return false;
|
||||
@@ -90,7 +90,7 @@ bool asst::AipOcr::request_ocr_and_parse(std::string_view cmd_fmt, const cv::Mat
|
||||
std::string encoded = base64_encode(enc_msg, buf.size());
|
||||
|
||||
size_t cmd_len = encoded.size() + cmd_fmt.size() + m_access_token.size();
|
||||
char* cmd = new char[cmd_len];
|
||||
auto cmd = new char[cmd_len];
|
||||
memset(cmd, 0, cmd_len);
|
||||
#ifdef _MSC_VER
|
||||
sprintf_s(cmd, cmd_len, cmd_fmt.data(), m_access_token.c_str(), encoded.c_str());
|
||||
|
||||
@@ -27,15 +27,15 @@ namespace asst
|
||||
}
|
||||
|
||||
bool request_access_token(const std::string& client_id, const std::string& client_secret);
|
||||
bool request_ocr_general(const cv::Mat image, std::vector<TextRect>& out_result, const TextRectProc& pred = nullptr);
|
||||
bool request_ocr_accurate(const cv::Mat image, std::vector<TextRect>& out_result, const TextRectProc& pred = nullptr);
|
||||
bool request_ocr_general(const cv::Mat& image, std::vector<TextRect>& out_result, const TextRectProc& pred = nullptr);
|
||||
bool request_ocr_accurate(const cv::Mat& image, std::vector<TextRect>& out_result, const TextRectProc& pred = nullptr);
|
||||
|
||||
private:
|
||||
AipOcr() = default;
|
||||
AipOcr(const AipOcr&) = default;
|
||||
AipOcr(AipOcr&&) noexcept = default;
|
||||
|
||||
bool request_ocr_and_parse(std::string_view cmd_fmt, const cv::Mat image, std::vector<TextRect>& out_result, const TextRectProc& pred = nullptr);
|
||||
bool request_ocr_and_parse(std::string_view cmd_fmt, const cv::Mat& image, std::vector<TextRect>& out_result, const TextRectProc& pred = nullptr);
|
||||
bool parse_response(const json::value& json, std::vector<TextRect>& out_result, const TextRectProc& pred = nullptr);
|
||||
|
||||
std::string m_access_token;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "Assistant.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <ctime>
|
||||
|
||||
#include <meojson/json.hpp>
|
||||
#include <opencv2/opencv.hpp>
|
||||
@@ -33,7 +33,7 @@ Assistant::Assistant(AsstApiCallback callback, void* callback_arg)
|
||||
LogTraceFunction;
|
||||
|
||||
m_status = std::make_shared<RuntimeStatus>();
|
||||
m_ctrler = std::make_shared<Controller>(task_callback, (void*)this);
|
||||
m_ctrler = std::make_shared<Controller>(task_callback, static_cast<void*>(this));
|
||||
|
||||
m_working_thread = std::thread(&Assistant::working_proc, this);
|
||||
m_msg_thread = std::thread(&Assistant::msg_proc, this);
|
||||
@@ -85,31 +85,31 @@ asst::Assistant::TaskId asst::Assistant::append_task(const std::string& type, co
|
||||
std::shared_ptr<PackageTask> ptr = nullptr;
|
||||
|
||||
if (type == FightTask::TaskType) {
|
||||
ptr = std::make_shared<FightTask>(task_callback, (void*)this);
|
||||
ptr = std::make_shared<FightTask>(task_callback, static_cast<void*>(this));
|
||||
}
|
||||
else if (type == StartUpTask::TaskType) {
|
||||
ptr = std::make_shared<StartUpTask>(task_callback, (void*)this);
|
||||
ptr = std::make_shared<StartUpTask>(task_callback, static_cast<void*>(this));
|
||||
}
|
||||
else if (type == AwardTask::TaskType) {
|
||||
ptr = std::make_shared<AwardTask>(task_callback, (void*)this);
|
||||
ptr = std::make_shared<AwardTask>(task_callback, static_cast<void*>(this));
|
||||
}
|
||||
else if (type == VisitTask::TaskType) {
|
||||
ptr = std::make_shared<VisitTask>(task_callback, (void*)this);
|
||||
ptr = std::make_shared<VisitTask>(task_callback, static_cast<void*>(this));
|
||||
}
|
||||
else if (type == MallTask::TaskType) {
|
||||
ptr = std::make_shared<MallTask>(task_callback, (void*)this);
|
||||
ptr = std::make_shared<MallTask>(task_callback, static_cast<void*>(this));
|
||||
}
|
||||
else if (type == InfrastTask::TaskType) {
|
||||
ptr = std::make_shared<InfrastTask>(task_callback, (void*)this);
|
||||
ptr = std::make_shared<InfrastTask>(task_callback, static_cast<void*>(this));
|
||||
}
|
||||
else if (type == RecruitTask::TaskType) {
|
||||
ptr = std::make_shared<RecruitTask>(task_callback, (void*)this);
|
||||
ptr = std::make_shared<RecruitTask>(task_callback, static_cast<void*>(this));
|
||||
}
|
||||
else if (type == RoguelikeTask::TaskType) {
|
||||
ptr = std::make_shared<RoguelikeTask>(task_callback, (void*)this);
|
||||
ptr = std::make_shared<RoguelikeTask>(task_callback, static_cast<void*>(this));
|
||||
}
|
||||
else if (type == CopilotTask::TaskType) {
|
||||
ptr = std::make_shared<CopilotTask>(task_callback, (void*)this);
|
||||
ptr = std::make_shared<CopilotTask>(task_callback, static_cast<void*>(this));
|
||||
}
|
||||
#ifdef ASST_DEBUG
|
||||
else if (type == DebugTask::TaskType) {
|
||||
@@ -162,7 +162,7 @@ bool asst::Assistant::set_task_params(TaskId task_id, const std::string& params)
|
||||
std::vector<uchar> asst::Assistant::get_image() const
|
||||
{
|
||||
if (!m_inited) {
|
||||
return std::vector<uchar>();
|
||||
return {};
|
||||
}
|
||||
return m_ctrler->get_image_encode();
|
||||
}
|
||||
@@ -276,7 +276,7 @@ void Assistant::msg_proc()
|
||||
if (!m_msg_queue.empty()) {
|
||||
// 结构化绑定只能是引用,后续的pop会使引用失效,所以需要重新构造一份,这里采用了move的方式
|
||||
auto&& [temp_msg, temp_detail] = m_msg_queue.front();
|
||||
AsstMsg msg = std::move(temp_msg);
|
||||
AsstMsg msg = temp_msg;
|
||||
json::value detail = std::move(temp_detail);
|
||||
m_msg_queue.pop();
|
||||
lock.unlock();
|
||||
@@ -293,7 +293,7 @@ void Assistant::msg_proc()
|
||||
|
||||
void Assistant::task_callback(AsstMsg msg, const json::value& detail, void* custom_arg)
|
||||
{
|
||||
Assistant* p_this = (Assistant*)custom_arg;
|
||||
auto p_this = static_cast<Assistant*>(custom_arg);
|
||||
json::value more_detail = detail;
|
||||
more_detail["uuid"] = p_this->m_uuid;
|
||||
|
||||
@@ -321,6 +321,6 @@ void asst::Assistant::append_callback(AsstMsg msg, json::value detail)
|
||||
|
||||
void Assistant::clear_cache()
|
||||
{
|
||||
m_status->clear_data();
|
||||
m_status->clear_number();
|
||||
//Task.clear_cache();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "AsstCaller.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#include <meojson/json.hpp>
|
||||
@@ -122,7 +122,7 @@ TaskId AsstAppendTask(AsstHandle handle, const char* type, const char* params)
|
||||
bool AsstSetTaskParams(AsstHandle handle, TaskId id, const char* params)
|
||||
{
|
||||
if (!inited || handle == nullptr) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return handle->set_task_params(id, params ? params : "");
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace asst
|
||||
}
|
||||
Rect move(Rect move) const
|
||||
{
|
||||
return Rect(x + move.x, y + move.y, move.width, move.height);
|
||||
return {x + move.x, y + move.y, move.width, move.height};
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
|
||||
@@ -90,13 +90,13 @@ namespace asst
|
||||
const char* src_str = ansi_str.c_str();
|
||||
int len = MultiByteToWideChar(CP_ACP, 0, src_str, -1, nullptr, 0);
|
||||
const std::size_t wstr_length = static_cast<std::size_t>(len) + 1U;
|
||||
wchar_t *wstr = new wchar_t[wstr_length];
|
||||
auto wstr = new wchar_t[wstr_length];
|
||||
memset(wstr, 0, sizeof(wstr[0]) * wstr_length);
|
||||
MultiByteToWideChar(CP_ACP, 0, src_str, -1, wstr, len);
|
||||
|
||||
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr);
|
||||
const std::size_t str_length = static_cast<std::size_t>(len) + 1;
|
||||
char *str = new char[str_length];
|
||||
auto str = new char[str_length];
|
||||
memset(str, 0, sizeof(str[0]) * str_length);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, nullptr, nullptr);
|
||||
std::string strTemp = str;
|
||||
@@ -121,13 +121,13 @@ namespace asst
|
||||
const char* src_str = utf8_str.c_str();
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, src_str, -1, nullptr, 0);
|
||||
const std::size_t wsz_ansi_length = static_cast<std::size_t>(len) + 1;
|
||||
wchar_t *wsz_ansi = new wchar_t[wsz_ansi_length];
|
||||
auto wsz_ansi = new wchar_t[wsz_ansi_length];
|
||||
memset(wsz_ansi, 0, sizeof(wsz_ansi[0]) * wsz_ansi_length);
|
||||
MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wsz_ansi, len);
|
||||
|
||||
len = WideCharToMultiByte(CP_ACP, 0, wsz_ansi, -1, nullptr, 0, nullptr, nullptr);
|
||||
const std::size_t sz_ansi_length = static_cast<std::size_t>(len) + 1;
|
||||
char *sz_ansi = new char[sz_ansi_length];
|
||||
auto sz_ansi = new char[sz_ansi_length];
|
||||
memset(sz_ansi, 0, sizeof(sz_ansi[0]) * sz_ansi_length);
|
||||
WideCharToMultiByte(CP_ACP, 0, wsz_ansi, -1, sz_ansi, len, nullptr, nullptr);
|
||||
std::string strTemp(sz_ansi);
|
||||
@@ -156,7 +156,7 @@ namespace asst
|
||||
{
|
||||
std::ifstream ifs(filename, std::ios::in);
|
||||
if (!ifs.is_open()) {
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
std::stringstream iss;
|
||||
iss << ifs.rdbuf();
|
||||
@@ -197,7 +197,7 @@ namespace asst
|
||||
si.hStdOutput = pipe_child_write;
|
||||
si.hStdError = pipe_child_write;
|
||||
|
||||
PROCESS_INFORMATION pi = { 0 };
|
||||
PROCESS_INFORMATION pi = { nullptr };
|
||||
|
||||
BOOL p_ret = CreateProcessA(nullptr, const_cast<LPSTR>(cmdline.c_str()), nullptr, nullptr, TRUE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi);
|
||||
if (p_ret) {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#include "AwardTask.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "ProcessTask.h"
|
||||
|
||||
asst::AwardTask::AwardTask(AsstCallback callback, void* callback_arg)
|
||||
: PackageTask(callback, callback_arg, TaskType),
|
||||
: PackageTask(std::move(callback), callback_arg, TaskType),
|
||||
m_award_task_ptr(std::make_shared<ProcessTask>(m_callback, m_callback_arg, TaskType))
|
||||
{
|
||||
m_award_task_ptr->set_tasks({ "AwardBegin" });
|
||||
|
||||
@@ -15,6 +15,11 @@ bool asst::BattleImageAnalyzer::set_target(int target)
|
||||
return true;
|
||||
}
|
||||
|
||||
void asst::BattleImageAnalyzer::set_pre_total_kills(int pre_total_kills)
|
||||
{
|
||||
m_pre_total_kills = pre_total_kills;
|
||||
}
|
||||
|
||||
bool asst::BattleImageAnalyzer::analyze()
|
||||
{
|
||||
clear();
|
||||
@@ -86,6 +91,11 @@ int asst::BattleImageAnalyzer::get_kills() const noexcept
|
||||
return m_kills;
|
||||
}
|
||||
|
||||
int asst::BattleImageAnalyzer::get_total_kills() const noexcept
|
||||
{
|
||||
return m_total_kills;
|
||||
}
|
||||
|
||||
int asst::BattleImageAnalyzer::get_cost() const noexcept
|
||||
{
|
||||
return m_cost;
|
||||
@@ -172,7 +182,7 @@ asst::BattleRole asst::BattleImageAnalyzer::oper_role_analyze(const Rect& roi)
|
||||
|
||||
MatchImageAnalyzer role_analyzer(m_image);
|
||||
|
||||
BattleRole result = BattleRole::Unknown;
|
||||
auto result = BattleRole::Unknown;
|
||||
double max_score = 0;
|
||||
for (auto&& [role, role_name] : RolesName) {
|
||||
role_analyzer.set_task_info("BattleOperRole" + role_name);
|
||||
@@ -414,7 +424,7 @@ bool asst::BattleImageAnalyzer::hp_analyze()
|
||||
for (const std::string& num_name : hash_analyzer.get_min_dist_name()) {
|
||||
if (num_name.empty()) {
|
||||
Log.error("hash result is empty");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
hp *= 10;
|
||||
hp += num_name.at(0) - '0';
|
||||
@@ -438,20 +448,37 @@ bool asst::BattleImageAnalyzer::kills_analyze()
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string kills_text;
|
||||
size_t pos = std::string::npos;
|
||||
for (auto& res : kills_analyzer.get_result()) {
|
||||
// 这里的结果应该是 "击杀数/总的敌人数",例如 "0/41"
|
||||
pos = res.text.find('/');
|
||||
if (pos != std::string::npos) {
|
||||
kills_text = res.text;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos == std::string::npos) {
|
||||
std::string kills_text = kills_analyzer.get_result().front().text;
|
||||
if (kills_text.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t pos = kills_text.find('/');
|
||||
if (pos == std::string::npos) {
|
||||
Log.warn("cannot found flag /");
|
||||
// 这种时候绝大多数是把 "0/41" 中的 '/' 识别成了别的什么东西(其中又有绝大部分情况是识别成了 '1')
|
||||
// 所以这里依赖 m_pre_total_kills 转一下
|
||||
if (m_pre_total_kills == 0) {
|
||||
// 第一次识别就识别错了,识别成了 "0141"
|
||||
if (kills_text.at(0) == '0') {
|
||||
pos = 1;
|
||||
}
|
||||
else {
|
||||
Log.error("m_pre_total_kills is zero");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
size_t pre_pos = kills_text.find(std::to_string(m_pre_total_kills));
|
||||
if (pre_pos == std::string::npos || pre_pos == 0) {
|
||||
Log.error("can't get pre_pos");
|
||||
return false;
|
||||
}
|
||||
Log.trace("pre total kills pos:", pre_pos);
|
||||
pos = pre_pos - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 例子中的"0"
|
||||
std::string kills_count = kills_text.substr(0, pos);
|
||||
if (kills_count.empty() ||
|
||||
@@ -461,7 +488,22 @@ bool asst::BattleImageAnalyzer::kills_analyze()
|
||||
}
|
||||
int cur_kills = std::stoi(kills_count);
|
||||
m_kills = std::max(m_kills, cur_kills);
|
||||
Log.trace("Kills:", m_kills, cur_kills);
|
||||
|
||||
// 例子中的"41"
|
||||
std::string total_kills = kills_text.substr(pos + 1, std::string::npos);
|
||||
int cur_total_kills = 0;
|
||||
if (total_kills.empty() ||
|
||||
!std::all_of(total_kills.cbegin(), total_kills.cend(),
|
||||
[](char c) -> bool {return std::isdigit(c);})) {
|
||||
Log.warn("total kills recognition failed, set to", m_pre_total_kills);
|
||||
cur_total_kills = m_pre_total_kills;
|
||||
}
|
||||
else {
|
||||
cur_total_kills = std::stoi(total_kills);
|
||||
}
|
||||
m_total_kills = std::max(cur_total_kills, m_pre_total_kills);
|
||||
|
||||
Log.trace("Kills:", m_kills, "/", m_total_kills);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace asst
|
||||
virtual ~BattleImageAnalyzer() = default;
|
||||
|
||||
bool set_target(int target);
|
||||
void set_pre_total_kills(int pre_total_kills);
|
||||
virtual bool analyze() override;
|
||||
|
||||
virtual const std::vector<BattleRealTimeOper>& get_opers() const noexcept;
|
||||
@@ -34,6 +35,7 @@ namespace asst
|
||||
const std::vector<Rect>& get_ready_skills() const noexcept;
|
||||
int get_hp() const noexcept;
|
||||
int get_kills() const noexcept;
|
||||
int get_total_kills() const noexcept;
|
||||
int get_cost() const noexcept;
|
||||
|
||||
void clear() noexcept;
|
||||
@@ -53,6 +55,7 @@ namespace asst
|
||||
bool vacancies_analyze();// 识别剩余可部署人数
|
||||
|
||||
int m_target = 0; // 待识别的目标
|
||||
int m_pre_total_kills = 0; // 之前的击杀总数,因为击杀数经常识别不准所以依赖外部传入作为参考
|
||||
|
||||
/* 识别结果缓存 */
|
||||
std::vector<BattleRealTimeOper> m_opers; // 下方干员信息
|
||||
@@ -60,6 +63,7 @@ namespace asst
|
||||
std::vector<Rect> m_ready_skills; // 可以释放的技能(Rect实际是干员的位置)
|
||||
int m_hp = 0; // 剩余生命值
|
||||
int m_kills = 0; // 击杀数
|
||||
int m_total_kills = 0; // 击杀总数
|
||||
int m_cost = 0; // 部署费用
|
||||
};
|
||||
}
|
||||
|
||||
@@ -110,6 +110,15 @@ bool asst::BattleProcessTask::analyze_opers_preview()
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
// 识别一帧总击杀数
|
||||
BattleImageAnalyzer kills_analyzer(image);
|
||||
kills_analyzer.set_target(BattleImageAnalyzer::Target::Kills);
|
||||
if (kills_analyzer.analyze()) {
|
||||
m_kills = kills_analyzer.get_kills();
|
||||
m_total_kills = kills_analyzer.get_total_kills();
|
||||
}
|
||||
auto draw = image.clone();
|
||||
|
||||
// 暂停游戏准备识别干员
|
||||
// 在刚进入游戏的时候(画面刚刚完全亮起来的时候),点暂停是没反应的
|
||||
// 所以这里一直点,直到真的点上了为止
|
||||
@@ -124,7 +133,6 @@ bool asst::BattleProcessTask::analyze_opers_preview()
|
||||
}
|
||||
|
||||
auto draw_future = std::async(std::launch::async, [&]() {
|
||||
auto draw = image.clone();
|
||||
for (const auto& [loc, info] : m_normal_tile_info) {
|
||||
std::string text = "( " + std::to_string(loc.x) + ", " + std::to_string(loc.y) + " )";
|
||||
cv::putText(draw, text, cv::Point(info.pos.x - 30, info.pos.y), 1, 1.2, cv::Scalar(0, 0, 255), 2);
|
||||
@@ -389,9 +397,13 @@ bool asst::BattleProcessTask::wait_condition(const BattleAction& action)
|
||||
image = m_ctrler->get_image();
|
||||
}
|
||||
BattleImageAnalyzer analyzer(image);
|
||||
if (m_total_kills) {
|
||||
analyzer.set_pre_total_kills(m_total_kills);
|
||||
}
|
||||
analyzer.set_target(BattleImageAnalyzer::Target::Kills);
|
||||
if (analyzer.analyze()) {
|
||||
m_kills = analyzer.get_kills();
|
||||
m_total_kills = analyzer.get_total_kills();
|
||||
if (m_kills >= action.kills) {
|
||||
break;
|
||||
}
|
||||
@@ -422,7 +434,7 @@ bool asst::BattleProcessTask::wait_condition(const BattleAction& action)
|
||||
try_possible_skill(image);
|
||||
std::this_thread::yield();
|
||||
image = m_ctrler->get_image();
|
||||
};
|
||||
}
|
||||
}
|
||||
if (image.empty()) {
|
||||
image = m_ctrler->get_image();
|
||||
@@ -454,7 +466,7 @@ bool asst::BattleProcessTask::oper_deploy(const BattleAction& action)
|
||||
std::sqrt(
|
||||
(std::abs(placed_point.x - oper_rect.x) << 1)
|
||||
+ (std::abs(placed_point.y - oper_rect.y) << 1)));
|
||||
int duration = static_cast<int>(swipe_oper_task_ptr->pre_delay / 500.0 * dist); // 随便取的一个系数
|
||||
int duration = static_cast<int>(swipe_oper_task_ptr->pre_delay / 1000 * dist); // 随便取的一个系数
|
||||
m_ctrler->swipe(oper_rect, placed_rect, duration, true, 0);
|
||||
|
||||
sleep(use_oper_task_ptr->rear_delay);
|
||||
@@ -503,7 +515,7 @@ bool asst::BattleProcessTask::oper_retreat(const BattleAction& action)
|
||||
const std::string& name = m_group_to_oper_mapping[action.group_name].name;
|
||||
Point pos;
|
||||
if (auto iter = m_used_opers.find(name);
|
||||
action.location.x != 0 && action.location.y != 0 &&
|
||||
action.location.x == 0 && action.location.y == 0 &&
|
||||
iter != m_used_opers.cend()) {
|
||||
pos = iter->second.pos;
|
||||
m_used_opers.erase(name);
|
||||
@@ -522,7 +534,7 @@ bool asst::BattleProcessTask::use_skill(const BattleAction& action)
|
||||
const std::string& name = m_group_to_oper_mapping[action.group_name].name;
|
||||
Point pos;
|
||||
if (auto iter = m_used_opers.find(name);
|
||||
action.location.x != 0 && action.location.y != 0 &&
|
||||
action.location.x == 0 && action.location.y == 0 &&
|
||||
iter != m_used_opers.cend()) {
|
||||
pos = iter->second.pos;
|
||||
m_used_opers.erase(name);
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace asst
|
||||
|
||||
/* 实时更新的数据 */
|
||||
int m_kills = 0;
|
||||
int m_total_kills = 0;
|
||||
std::unordered_map<std::string, BattleRealTimeOper> m_all_opers_info;
|
||||
std::unordered_map<std::string, BattleRealTimeOper> m_cur_opers_info;
|
||||
std::unordered_map<std::string, BattleDeployInfo> m_used_opers;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <regex>
|
||||
@@ -55,7 +55,7 @@ private:
|
||||
#endif
|
||||
|
||||
asst::Controller::Controller(AsstCallback callback, void* callback_arg)
|
||||
: m_callback(callback),
|
||||
: m_callback(std::move(callback)),
|
||||
m_callback_arg(callback_arg),
|
||||
m_rand_engine(static_cast<unsigned int>(time(nullptr)))
|
||||
{
|
||||
@@ -91,7 +91,7 @@ asst::Controller::Controller(AsstCallback callback, void* callback_arg)
|
||||
break;
|
||||
}
|
||||
m_support_socket = true;
|
||||
} while (0);
|
||||
} while (false);
|
||||
|
||||
#else
|
||||
int pipe_in_ret = pipe(m_pipe_in);
|
||||
@@ -244,12 +244,10 @@ void asst::Controller::pipe_working_proc()
|
||||
|
||||
std::optional<std::vector<unsigned char>> asst::Controller::call_command(const std::string& cmd, int64_t timeout, bool recv_by_socket)
|
||||
{
|
||||
LogTraceFunction;
|
||||
LogTraceScope(std::string(__FUNCTION__) + " | `" + cmd + "`");
|
||||
|
||||
std::vector<uchar> pipe_data;
|
||||
|
||||
std::unique_lock<std::mutex> pipe_lock(m_pipe_mutex);
|
||||
|
||||
auto start_time = std::chrono::steady_clock::now();
|
||||
auto check_timeout = [&]() -> bool {
|
||||
return timeout &&
|
||||
@@ -259,15 +257,16 @@ std::optional<std::vector<unsigned char>> asst::Controller::call_command(const s
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
PROCESS_INFORMATION process_info = { 0 }; // 进程信息结构体
|
||||
PROCESS_INFORMATION process_info = { nullptr }; // 进程信息结构体
|
||||
BOOL create_ret = ::CreateProcessA(nullptr, const_cast<LPSTR>(cmd.c_str()), nullptr, nullptr, TRUE, CREATE_NO_WINDOW, nullptr, nullptr, &m_child_startup_info, &process_info);
|
||||
if (!create_ret) {
|
||||
Log.error("Call `", cmd, "` create error, ret", create_ret);
|
||||
Log.error("Call `", cmd, "` create process failed, ret", create_ret);
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!recv_by_socket) {
|
||||
DWORD peek_num = 0;
|
||||
DWORD read_num = 0;
|
||||
std::unique_lock<std::mutex> pipe_lock(m_pipe_mutex);
|
||||
do {
|
||||
//DWORD write_num = 0;
|
||||
//WriteFile(parent_write, cmd.c_str(), cmd.size(), &write_num, nullptr);
|
||||
@@ -279,20 +278,25 @@ std::optional<std::vector<unsigned char>> asst::Controller::call_command(const s
|
||||
} while (::WaitForSingleObject(process_info.hProcess, 0) == WAIT_TIMEOUT && !check_timeout());
|
||||
}
|
||||
else {
|
||||
SOCKADDR client_addr = { 0 };
|
||||
int size = sizeof(SOCKADDR);
|
||||
SOCKET client_sock = ::accept(m_server_sock, (SOCKADDR*)&client_addr, &size);
|
||||
int recv_size = 0;
|
||||
do {
|
||||
recv_size = ::recv(client_sock, (char*)m_socket_buffer.get(), SocketBuffSize, NULL);
|
||||
if (recv_size < 0) {
|
||||
Log.error("recv error", recv_size);
|
||||
break;
|
||||
}
|
||||
pipe_data.insert(pipe_data.end(), m_socket_buffer.get(), m_socket_buffer.get() + recv_size);
|
||||
} while (recv_size > 0 && !check_timeout());
|
||||
::closesocket(client_sock);
|
||||
::WaitForSingleObject(process_info.hProcess, static_cast<DWORD>(timeout));
|
||||
std::unique_lock<std::mutex> pipe_lock(m_pipe_mutex);
|
||||
fd_set fdset = { 0 };
|
||||
FD_SET(m_server_sock, &fdset);
|
||||
timeval select_timeout = { 3, 0 };
|
||||
select(static_cast<int>(m_server_sock) + 1, &fdset, NULL, NULL, &select_timeout);
|
||||
if (FD_ISSET(m_server_sock, &fdset)) {
|
||||
SOCKET client_sock = ::accept(m_server_sock, NULL, NULL);
|
||||
int recv_size = 0;
|
||||
do {
|
||||
recv_size = ::recv(client_sock, (char*)m_socket_buffer.get(), SocketBuffSize, NULL);
|
||||
if (recv_size < 0) {
|
||||
Log.error("recv error", recv_size);
|
||||
break;
|
||||
}
|
||||
pipe_data.insert(pipe_data.end(), m_socket_buffer.get(), m_socket_buffer.get() + recv_size);
|
||||
} while (recv_size > 0 && !check_timeout());
|
||||
::closesocket(client_sock);
|
||||
}
|
||||
::WaitForSingleObject(process_info.hProcess, 3000);
|
||||
}
|
||||
DWORD exit_ret = 0;
|
||||
::GetExitCodeProcess(process_info.hProcess, &exit_ret);
|
||||
@@ -323,6 +327,7 @@ std::optional<std::vector<unsigned char>> asst::Controller::call_command(const s
|
||||
else if (m_child > 0) {
|
||||
// parent process
|
||||
// LogTraceScope("Parent process: " + cmd);
|
||||
std::unique_lock<std::mutex> pipe_lock(m_pipe_mutex);
|
||||
do {
|
||||
ssize_t read_num = read(m_pipe_out[PIPE_READ], m_pipe_buffer.get(), PipeBuffSize);
|
||||
|
||||
@@ -346,9 +351,48 @@ std::optional<std::vector<unsigned char>> asst::Controller::call_command(const s
|
||||
if (!exit_ret) {
|
||||
return pipe_data;
|
||||
}
|
||||
else {
|
||||
return std::nullopt;
|
||||
else if (m_inited) {
|
||||
// 之前可以运行,突然运行不了了,这种情况多半是 adb 炸了。所以重新连接一下
|
||||
m_inited = false;
|
||||
auto reconnect_ret = call_command(m_adb.connect, 60 * 1000);
|
||||
bool is_reconnect_success = false;
|
||||
if (reconnect_ret) {
|
||||
auto& reconnect_val = reconnect_ret.value();
|
||||
std::string reconnect_str(
|
||||
std::make_move_iterator(reconnect_val.begin()),
|
||||
std::make_move_iterator(reconnect_val.end()));
|
||||
is_reconnect_success = reconnect_str.find("error") == std::string::npos;
|
||||
}
|
||||
if (is_reconnect_success) {
|
||||
auto recall_ret = call_command(cmd, timeout, recv_by_socket);
|
||||
if (recall_ret) {
|
||||
m_inited = true;
|
||||
return recall_ret;
|
||||
}
|
||||
else {
|
||||
json::value info = json::object{
|
||||
{ "uuid", m_uuid},
|
||||
{ "what", "CommandExecFailed" },
|
||||
{ "why", "I dont fucking know, go look at the log!" },
|
||||
{ "details", json::object {
|
||||
{ "cmd", cmd },
|
||||
{ "recv_by_socket", recv_by_socket}
|
||||
}} };
|
||||
m_callback(AsstMsg::ConnectionInfo, info, m_callback_arg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
json::value info = json::object{
|
||||
{ "uuid", m_uuid},
|
||||
{ "what", "Disconnect" },
|
||||
{ "why", "Reconnect failed" },
|
||||
{ "details", json::object {
|
||||
{ "cmd", m_adb.connect }
|
||||
}} };
|
||||
m_callback(AsstMsg::ConnectionInfo, info, m_callback_arg);
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void asst::Controller::convert_lf(std::vector<unsigned char>& data)
|
||||
@@ -378,11 +422,11 @@ void asst::Controller::convert_lf(std::vector<unsigned char>& data)
|
||||
Iter next_iter = first_iter;
|
||||
while (++first_iter != end_r1_iter) {
|
||||
if (!pred(first_iter)) {
|
||||
*next_iter = std::move(*first_iter);
|
||||
*next_iter = *first_iter;
|
||||
++next_iter;
|
||||
}
|
||||
}
|
||||
*next_iter = std::move(*end_r1_iter);
|
||||
*next_iter = *end_r1_iter;
|
||||
++next_iter;
|
||||
data.erase(next_iter, data.end());
|
||||
}
|
||||
@@ -407,7 +451,7 @@ asst::Point asst::Controller::rand_point_in_rect(const Rect& rect)
|
||||
y = y_rand + rect.y;
|
||||
}
|
||||
|
||||
return Point(x, y);
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
void asst::Controller::random_delay() const
|
||||
@@ -429,6 +473,7 @@ void asst::Controller::random_delay() const
|
||||
|
||||
void asst::Controller::clear_info() noexcept
|
||||
{
|
||||
m_inited = false;
|
||||
m_adb = decltype(m_adb)();
|
||||
m_uuid.clear();
|
||||
m_width = 0;
|
||||
@@ -453,7 +498,7 @@ int asst::Controller::push_cmd(const std::string& cmd)
|
||||
return ++m_push_id;
|
||||
}
|
||||
|
||||
std::optional<asst::Controller::SocketInfo> asst::Controller::try_to_init_socket(const std::string& local_address, unsigned short try_port, unsigned short try_times)
|
||||
std::optional<unsigned short> asst::Controller::try_to_init_socket(const std::string& local_address, unsigned short try_port, unsigned short try_times)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
@@ -477,7 +522,7 @@ std::optional<asst::Controller::SocketInfo> asst::Controller::try_to_init_socket
|
||||
|
||||
#ifdef _WIN32
|
||||
m_server_addr.sin_port = htons(port);
|
||||
int bind_ret = ::bind(m_server_sock, (SOCKADDR*)&m_server_addr, sizeof(SOCKADDR));
|
||||
int bind_ret = ::bind(m_server_sock, reinterpret_cast<SOCKADDR*>(&m_server_addr), sizeof(SOCKADDR));
|
||||
int listen_ret = ::listen(m_server_sock, 3);
|
||||
server_start = bind_ret == 0 && listen_ret == 0;
|
||||
#else
|
||||
@@ -494,11 +539,8 @@ std::optional<asst::Controller::SocketInfo> asst::Controller::try_to_init_socket
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Todo: detect remote address, and check remote port
|
||||
// reference from https://github.com/ArknightsAutoHelper/ArknightsAutoHelper/blob/master/automator/connector/ADBConnector.py#L436
|
||||
std::string remote_address = "10.0.2.2";
|
||||
Log.info("server_start", remote_address, port_result);
|
||||
return SocketInfo{ remote_address, port_result };
|
||||
Log.info("server_start", local_address, port_result);
|
||||
return port_result;
|
||||
}
|
||||
|
||||
void asst::Controller::wait(unsigned id) const noexcept
|
||||
@@ -528,8 +570,6 @@ bool asst::Controller::screencap()
|
||||
return false;
|
||||
}
|
||||
size_t header_size = data.size() - std_size;
|
||||
Log.trace("header size:", header_size);
|
||||
|
||||
bool is_all_zero = std::all_of(data.data() + header_size, data.data() + std_size,
|
||||
[](uchar uch) -> bool {
|
||||
return uch == 0;
|
||||
@@ -549,7 +589,6 @@ bool asst::Controller::screencap()
|
||||
|
||||
DecodeFunc decode_raw_with_gzip = [&](std::vector<uchar>& data) -> bool {
|
||||
auto unzip_data = gzip::decompress(data.data(), data.size());
|
||||
Log.trace("unzip data size:", unzip_data.size());
|
||||
if (unzip_data.empty()) {
|
||||
return false;
|
||||
}
|
||||
@@ -558,8 +597,6 @@ bool asst::Controller::screencap()
|
||||
return false;
|
||||
}
|
||||
size_t header_size = unzip_data.size() - std_size;
|
||||
Log.trace("header size:", header_size);
|
||||
|
||||
bool is_all_zero = std::all_of(unzip_data.data() + header_size, unzip_data.data() + std_size,
|
||||
[](uchar uch) -> bool {
|
||||
return uch == 0;
|
||||
@@ -594,16 +631,19 @@ bool asst::Controller::screencap()
|
||||
screencap(m_adb.screencap_raw_by_nc, decode_raw, true)) {
|
||||
m_adb.screencap_method = AdbProperty::ScreencapMethod::RawByNc;
|
||||
Log.info("screencap by RawByNc");
|
||||
m_inited = true;
|
||||
return true;
|
||||
}
|
||||
else if (screencap(m_adb.screencap_raw_with_gzip, decode_raw_with_gzip)) {
|
||||
m_adb.screencap_method = AdbProperty::ScreencapMethod::RawWithGzip;
|
||||
Log.info("screencap by RawWithGzip");
|
||||
m_inited = true;
|
||||
return true;
|
||||
}
|
||||
else if (screencap(m_adb.screencap_encode, decode_encode)) {
|
||||
m_adb.screencap_method = AdbProperty::ScreencapMethod::Encode;
|
||||
Log.info("screencap by Encode");
|
||||
m_inited = true;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -630,7 +670,7 @@ bool asst::Controller::screencap()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool asst::Controller::screencap(const std::string& cmd, DecodeFunc decode_func, bool by_socket)
|
||||
bool asst::Controller::screencap(const std::string& cmd, const DecodeFunc& decode_func, bool by_socket)
|
||||
{
|
||||
if ((!m_support_socket || !m_server_started) && by_socket) {
|
||||
return false;
|
||||
@@ -682,7 +722,7 @@ cv::Mat asst::Controller::get_resized_image() const
|
||||
std::shared_lock<std::shared_mutex> image_lock(m_image_mutex);
|
||||
if (m_cache_image.empty()) {
|
||||
Log.error("image is empty");
|
||||
return cv::Mat(dsize, CV_8UC3);
|
||||
return { dsize, CV_8UC3 };
|
||||
}
|
||||
cv::Mat resized_mat;
|
||||
cv::resize(m_cache_image, resized_mat, dsize, 0.0, 0.0, cv::INTER_AREA);
|
||||
@@ -781,7 +821,7 @@ int asst::Controller::swipe_without_scale(const Point& p1, const Point& p2, int
|
||||
extra_cmd = utils::string_replace_all(extra_cmd, "[y1]", std::to_string(p2.y));
|
||||
int end_x = 0, end_y = 0;
|
||||
if (p2.x != p1.x) {
|
||||
double k = (double)(p2.y - p1.y) / (p2.x - p1.x);
|
||||
double k = static_cast<double>(p2.y - p1.y) / (p2.x - p1.x);
|
||||
double temp = extra_swipe_dist / std::sqrt(1 + k * k);
|
||||
end_x = p2.x + static_cast<int>((p2.x > p1.x ? -1.0 : 1.0) * temp);
|
||||
end_y = p2.y + static_cast<int>((p2.y > p1.y ? -1.0 : 1.0) * std::fabs(k) * temp);
|
||||
@@ -848,7 +888,7 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a
|
||||
|
||||
const auto adb_cfg = std::move(adb_ret.value());
|
||||
std::string display_id;
|
||||
std::string nc_address;
|
||||
std::string nc_address = "10.0.2.2";
|
||||
u_short nc_port = 0;
|
||||
|
||||
auto cmd_replace = [&](const std::string& cfg_cmd) -> std::string {
|
||||
@@ -868,9 +908,18 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a
|
||||
|
||||
/* connect */
|
||||
{
|
||||
auto connect_ret = call_command(cmd_replace(adb_cfg.connect), 60 * 1000);
|
||||
m_adb.connect = cmd_replace(adb_cfg.connect);
|
||||
auto connect_ret = call_command(m_adb.connect, 60 * 1000);
|
||||
// 端口即使错误,命令仍然会返回0,TODO 对connect_result进行判断
|
||||
if (!connect_ret) {
|
||||
bool is_connect_success = false;
|
||||
if (connect_ret) {
|
||||
auto& connect_val = connect_ret.value();
|
||||
std::string connect_str(
|
||||
std::make_move_iterator(connect_val.begin()),
|
||||
std::make_move_iterator(connect_val.end()));
|
||||
is_connect_success = connect_str.find("error") == std::string::npos;
|
||||
}
|
||||
if (!is_connect_success) {
|
||||
json::value info = get_info_json() |
|
||||
json::object{
|
||||
{ "what", "ConnectFailed" },
|
||||
@@ -1033,11 +1082,23 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a
|
||||
bind_address = "127.0.0.1";
|
||||
}
|
||||
|
||||
// Todo: detect remote address, and check remote port
|
||||
// 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));
|
||||
if (nc_address_ret) {
|
||||
auto& nc_result = nc_address_ret.value();
|
||||
std::string nc_result_str(
|
||||
std::make_move_iterator(nc_result.begin()),
|
||||
std::make_move_iterator(nc_result.end()));
|
||||
if (auto pos = nc_result_str.find(' ');
|
||||
pos != std::string::npos) {
|
||||
nc_address = nc_result_str.substr(0, pos);
|
||||
}
|
||||
}
|
||||
|
||||
auto socket_opt = try_to_init_socket(bind_address, adb_cfg.nc_port);
|
||||
if (socket_opt) {
|
||||
auto& socket_info = socket_opt.value();
|
||||
nc_address = socket_info.remote_address;
|
||||
nc_port = socket_info.remote_port;
|
||||
nc_port = socket_opt.value();
|
||||
m_adb.screencap_raw_by_nc = cmd_replace(adb_cfg.screencap_raw_by_nc);
|
||||
m_server_started = true;
|
||||
}
|
||||
@@ -1077,11 +1138,16 @@ const std::string& asst::Controller::get_uuid() const
|
||||
|
||||
cv::Mat asst::Controller::get_image(bool raw)
|
||||
{
|
||||
bool inited = m_inited;
|
||||
// 有些模拟器adb偶尔会莫名其妙截图失败,多试几次
|
||||
for (int i = 0; i != 20; ++i) {
|
||||
if (screencap()) {
|
||||
break;
|
||||
}
|
||||
// 截图之前正常,截图之后不正常了,说明截图过程中发现 adb 炸了
|
||||
if (inited && !m_inited) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (raw) {
|
||||
|
||||
@@ -66,16 +66,11 @@ namespace asst
|
||||
std::optional<std::vector<unsigned char>> call_command(const std::string& cmd, int64_t timeout = 20000, bool recv_by_socket = false);
|
||||
int push_cmd(const std::string& cmd);
|
||||
|
||||
struct SocketInfo
|
||||
{
|
||||
std::string remote_address;
|
||||
unsigned short remote_port = 0U;
|
||||
};
|
||||
std::optional<SocketInfo> try_to_init_socket(const std::string& local_address, unsigned short try_port, unsigned short try_times = 10U);
|
||||
std::optional<unsigned short> try_to_init_socket(const std::string& local_address, unsigned short try_port, unsigned short try_times = 10U);
|
||||
|
||||
using DecodeFunc = std::function<bool(std::vector<uchar>&)>;
|
||||
bool screencap();
|
||||
bool screencap(const std::string& cmd, DecodeFunc decode_func, bool by_nc = false);
|
||||
bool screencap(const std::string& cmd, const DecodeFunc& decode_func, bool by_nc = false);
|
||||
cv::Mat get_resized_image() const;
|
||||
|
||||
Point rand_point_in_rect(const Rect& rect);
|
||||
@@ -119,6 +114,7 @@ namespace asst
|
||||
struct AdbProperty
|
||||
{
|
||||
/* command */
|
||||
std::string connect;
|
||||
std::string click;
|
||||
std::string swipe;
|
||||
|
||||
@@ -155,6 +151,7 @@ namespace asst
|
||||
int m_height = 0;
|
||||
bool m_support_socket = false;
|
||||
bool m_server_started = false;
|
||||
bool m_inited = false;
|
||||
|
||||
inline static int m_instance_count = 0;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "BattleProcessTask.h"
|
||||
#include "BattleFormationTask.h"
|
||||
|
||||
asst::CopilotTask::CopilotTask(AsstCallback callback, void* callback_arg)
|
||||
asst::CopilotTask::CopilotTask(const AsstCallback& callback, void* callback_arg)
|
||||
: PackageTask(callback, callback_arg, TaskType),
|
||||
m_formation_task_ptr(std::make_shared<BattleFormationTask>(callback, callback_arg, TaskType)),
|
||||
m_battle_task_ptr(std::make_shared<BattleProcessTask>(callback, callback_arg, TaskType))
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace asst
|
||||
class CopilotTask final : public PackageTask
|
||||
{
|
||||
public:
|
||||
CopilotTask(AsstCallback callback, void* callback_arg);
|
||||
CopilotTask(const AsstCallback& callback, void* callback_arg);
|
||||
virtual ~CopilotTask() = default;
|
||||
|
||||
virtual bool set_params(const json::value& params) override;
|
||||
|
||||
@@ -51,7 +51,7 @@ bool asst::CreditShopImageAnalyzer::commoditys_analyze()
|
||||
commodity.y = mr.rect.y + commodity_task_ptr->rect_move.y;
|
||||
commodity.width = commodity_task_ptr->rect_move.width;
|
||||
commodity.height = commodity_task_ptr->rect_move.height;
|
||||
m_commoditys.emplace_back(std::move(commodity));
|
||||
m_commoditys.emplace_back(commodity);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "StageDropsTaskPlugin.h"
|
||||
|
||||
asst::DebugTask::DebugTask(AsstCallback callback, void* callback_arg)
|
||||
asst::DebugTask::DebugTask(const AsstCallback& callback, void* callback_arg)
|
||||
: PackageTask(callback, callback_arg, TaskType)
|
||||
{
|
||||
//auto task_ptr = std::make_shared<RoguelikeSkillSelectionTaskPlugin>(callback, callback_arg, TaskType);
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace asst
|
||||
class DebugTask : public PackageTask
|
||||
{
|
||||
public:
|
||||
DebugTask(AsstCallback callback, void* callback_arg);
|
||||
DebugTask(const AsstCallback& callback, void* callback_arg);
|
||||
virtual ~DebugTask() = default;
|
||||
|
||||
static constexpr const char* TaskType = "Debug";
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#include "FightTask.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "ProcessTask.h"
|
||||
#include "StageDropsTaskPlugin.h"
|
||||
#include "GameCrashRestartTaskPlugin.h"
|
||||
|
||||
asst::FightTask::FightTask(AsstCallback callback, void* callback_arg)
|
||||
: PackageTask(callback, callback_arg, TaskType),
|
||||
: PackageTask(std::move(callback), callback_arg, TaskType),
|
||||
m_start_up_task_ptr(std::make_shared<ProcessTask>(m_callback, m_callback_arg, TaskType)),
|
||||
m_stage_task_ptr(std::make_shared<ProcessTask>(m_callback, m_callback_arg, TaskType)),
|
||||
m_fight_task_ptr(std::make_shared<ProcessTask>(m_callback, m_callback_arg, TaskType))
|
||||
@@ -37,6 +40,8 @@ asst::FightTask::FightTask(AsstCallback callback, void* callback_arg)
|
||||
.set_times_limit("StartButton2", INT_MAX);
|
||||
m_stage_drops_plugin_ptr = m_fight_task_ptr->regiseter_plugin<StageDropsTaskPlugin>();
|
||||
m_stage_drops_plugin_ptr->set_retry_times(0);
|
||||
m_game_restart_plugin_ptr = m_fight_task_ptr->regiseter_plugin<GameCrashRestartTaskPlugin>();
|
||||
m_game_restart_plugin_ptr->set_retry_times(0);
|
||||
|
||||
m_subtasks.emplace_back(m_start_up_task_ptr);
|
||||
m_subtasks.emplace_back(m_stage_task_ptr);
|
||||
@@ -52,6 +57,15 @@ bool asst::FightTask::set_params(const json::value& params)
|
||||
bool enable_penguid = params.get("report_to_penguin", false);
|
||||
std::string penguin_id = params.get("penguin_id", "");
|
||||
std::string server = params.get("server", "CN");
|
||||
std::string client_type = params.get("client_type", std::string());
|
||||
|
||||
if (params.contains("drops")) {
|
||||
std::unordered_map<std::string, int> drops;
|
||||
for (const auto& [item_id, quantity] : params.at("drops").as_object()) {
|
||||
drops.insert_or_assign(item_id, quantity.as_integer());
|
||||
}
|
||||
m_stage_drops_plugin_ptr->set_specify_quantity(drops);
|
||||
}
|
||||
|
||||
if (!m_runned) {
|
||||
if (stage.empty()) {
|
||||
@@ -71,6 +85,9 @@ bool asst::FightTask::set_params(const json::value& params)
|
||||
.set_times_limit("StartButton2", times);
|
||||
m_stage_drops_plugin_ptr->set_enable_penguid(enable_penguid);
|
||||
m_stage_drops_plugin_ptr->set_penguin_id(std::move(penguin_id));
|
||||
if (!client_type.empty()) {
|
||||
m_game_restart_plugin_ptr->set_client_type(client_type);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace asst
|
||||
{
|
||||
class ProcessTask;
|
||||
class StageDropsTaskPlugin;
|
||||
class GameCrashRestartTaskPlugin;
|
||||
|
||||
class FightTask final : public PackageTask
|
||||
{
|
||||
@@ -23,5 +24,6 @@ namespace asst
|
||||
std::shared_ptr<ProcessTask> m_stage_task_ptr = nullptr;
|
||||
std::shared_ptr<ProcessTask> m_fight_task_ptr = nullptr;
|
||||
std::shared_ptr<StageDropsTaskPlugin> m_stage_drops_plugin_ptr = nullptr;
|
||||
std::shared_ptr<GameCrashRestartTaskPlugin> m_game_restart_plugin_ptr = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
16
src/MeoAssistant/GameCrashRestartTaskPlugin.cpp
Normal file
16
src/MeoAssistant/GameCrashRestartTaskPlugin.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "GameCrashRestartTaskPlugin.h"
|
||||
|
||||
bool asst::GameCrashRestartTaskPlugin::verify(AsstMsg msg, const json::value& details) const
|
||||
{
|
||||
if (msg != AsstMsg::SubTaskCompleted
|
||||
|| details.get("subtask", std::string()) != "ProcessTask") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (details.at("details").at("task").as_string() == "MaybeCrashAndRestartGame") {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
14
src/MeoAssistant/GameCrashRestartTaskPlugin.h
Normal file
14
src/MeoAssistant/GameCrashRestartTaskPlugin.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include "StartGameTaskPlugin.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class GameCrashRestartTaskPlugin : public StartGameTaskPlugin
|
||||
{
|
||||
public:
|
||||
using StartGameTaskPlugin::StartGameTaskPlugin;
|
||||
virtual ~GameCrashRestartTaskPlugin() noexcept = default;
|
||||
|
||||
virtual bool verify(AsstMsg msg, const json::value& details) const override;
|
||||
};
|
||||
}
|
||||
@@ -48,6 +48,7 @@ bool asst::GeneralConfiger::parse(const json::value& json)
|
||||
adb.display_format = cfg_json.at("displayFormat").as_string();
|
||||
adb.screencap_raw_with_gzip = cfg_json.at("screencapRawWithGzip").as_string();
|
||||
adb.screencap_raw_by_nc = cfg_json.at("screencapRawByNC").as_string();
|
||||
adb.nc_address = cfg_json.at("ncAddress").as_string();
|
||||
adb.nc_port = static_cast<unsigned short>(cfg_json.at("ncPort").as_integer());
|
||||
adb.screencap_encode = cfg_json.at("screencapEncode").as_string();
|
||||
adb.release = cfg_json.at("release").as_string();
|
||||
|
||||
@@ -52,6 +52,7 @@ namespace asst
|
||||
std::string display;
|
||||
std::string screencap_raw_with_gzip;
|
||||
std::string screencap_raw_by_nc;
|
||||
std::string nc_address;
|
||||
unsigned short nc_port = 0U;
|
||||
std::string screencap_encode;
|
||||
std::string release;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "InfrastAbstractTask.h"
|
||||
|
||||
#include <regex>
|
||||
#include <utility>
|
||||
|
||||
#include "AsstMsg.h"
|
||||
#include "Controller.h"
|
||||
@@ -12,7 +13,7 @@
|
||||
#include "ProcessTask.h"
|
||||
|
||||
asst::InfrastAbstractTask::InfrastAbstractTask(AsstCallback callback, void* callback_arg, std::string task_chain)
|
||||
: AbstractTask(callback, callback_arg, task_chain)
|
||||
: AbstractTask(std::move(callback), callback_arg, std::move(task_chain))
|
||||
{
|
||||
m_retry_times = TaskRetryTimes;
|
||||
}
|
||||
|
||||
@@ -31,11 +31,11 @@ namespace asst
|
||||
{
|
||||
if (auto iter = m_result.find(name);
|
||||
iter == m_result.cend()) {
|
||||
return Rect();
|
||||
return {};
|
||||
}
|
||||
else {
|
||||
if (index < 0 || index >= iter->second.size()) {
|
||||
return Rect();
|
||||
return {};
|
||||
}
|
||||
else {
|
||||
return iter->second.at(index).rect;
|
||||
|
||||
@@ -20,7 +20,7 @@ bool asst::InfrastInfoTask::_run()
|
||||
for (auto&& [name, res] : analyzer.get_result()) {
|
||||
std::string key = "NumOf" + name;
|
||||
//int size = static_cast<int>(res.size());
|
||||
m_status->set_data(key, res.size());
|
||||
m_status->set_number(key, res.size());
|
||||
Log.trace("InfrastInfoTask | ", key, res.size());
|
||||
}
|
||||
|
||||
|
||||
@@ -319,7 +319,7 @@ bool asst::InfrastProductionTask::optimal_calc()
|
||||
// 条件判断,不符合的直接过滤掉
|
||||
bool meet_condition = true;
|
||||
for (const auto& [cond, cond_value] : group.conditions) {
|
||||
auto cond_opt = m_status->get_data(cond);
|
||||
auto cond_opt = m_status->get_number(cond);
|
||||
if (!cond_opt) {
|
||||
continue;
|
||||
}
|
||||
@@ -614,7 +614,7 @@ asst::InfrastProductionTask::efficient_regex_calc(
|
||||
// TODO 报错!
|
||||
}
|
||||
std::string status_key = cur_formula.substr(pos + 1, rp_pos - pos - 1);
|
||||
auto status_opt = m_status->get_data(status_key);
|
||||
auto status_opt = m_status->get_number(status_key);
|
||||
const int64_t status_value = status_opt ? status_opt.value() : 0;
|
||||
cur_formula.replace(pos, rp_pos - pos + 1, std::to_string(status_value));
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "DronesForShamareTaskPlugin.h"
|
||||
#include "ReplenishOriginiumShardTaskPlugin.h"
|
||||
|
||||
asst::InfrastTask::InfrastTask(AsstCallback callback, void* callback_arg)
|
||||
asst::InfrastTask::InfrastTask(const AsstCallback& callback, void* callback_arg)
|
||||
: PackageTask(callback, callback_arg, TaskType),
|
||||
m_infrast_begin_task_ptr(std::make_shared<ProcessTask>(callback, callback_arg, TaskType)),
|
||||
m_info_task_ptr(std::make_shared<InfrastInfoTask>(callback, callback_arg, TaskType)),
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace asst
|
||||
{
|
||||
public:
|
||||
public:
|
||||
InfrastTask(AsstCallback callback, void* callback_arg);
|
||||
InfrastTask(const AsstCallback& callback, void* callback_arg);
|
||||
virtual ~InfrastTask() = default;
|
||||
|
||||
virtual bool set_params(const json::value& params) override;
|
||||
|
||||
@@ -107,7 +107,6 @@ namespace asst
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
;
|
||||
}
|
||||
}
|
||||
void log_init_info()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "ProcessTask.h"
|
||||
#include "CreditShoppingTask.h"
|
||||
|
||||
asst::MallTask::MallTask(AsstCallback callback, void* callback_arg)
|
||||
asst::MallTask::MallTask(const AsstCallback& callback, void* callback_arg)
|
||||
: PackageTask(callback, callback_arg, TaskType),
|
||||
m_mall_task_ptr(std::make_shared<ProcessTask>(callback, callback_arg, TaskType)),
|
||||
m_shopping_first_task_ptr(std::make_shared<CreditShoppingTask>(callback, callback_arg, TaskType)),
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace asst
|
||||
class MallTask final : public PackageTask
|
||||
{
|
||||
public:
|
||||
MallTask(AsstCallback callback, void* callback_arg);
|
||||
MallTask(const AsstCallback& callback, void* callback_arg);
|
||||
virtual ~MallTask() = default;
|
||||
|
||||
virtual bool set_params(const json::value& params) override;
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
#include "Logger.hpp"
|
||||
#include "Resource.h"
|
||||
|
||||
asst::MatchImageAnalyzer::MatchImageAnalyzer(const cv::Mat image, const Rect& roi, std::string templ_name, double templ_thres)
|
||||
asst::MatchImageAnalyzer::MatchImageAnalyzer(const cv::Mat& image, const Rect& roi, std::string templ_name, double templ_thres)
|
||||
: AbstractImageAnalyzer(image, roi),
|
||||
m_templ_name(std::move(templ_name)),
|
||||
m_templ_thres(templ_thres)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
bool asst::MatchImageAnalyzer::analyze()
|
||||
@@ -54,7 +53,7 @@ void asst::MatchImageAnalyzer::set_threshold(double templ_thres) noexcept
|
||||
m_templ_thres = templ_thres;
|
||||
}
|
||||
|
||||
void asst::MatchImageAnalyzer::set_task_info(std::shared_ptr<TaskInfo> task_ptr)
|
||||
void asst::MatchImageAnalyzer::set_task_info(const std::shared_ptr<TaskInfo>& task_ptr)
|
||||
{
|
||||
set_task_info(*std::dynamic_pointer_cast<MatchTaskInfo>(task_ptr));
|
||||
}
|
||||
@@ -66,7 +65,7 @@ void asst::MatchImageAnalyzer::set_task_info(const std::string& task_name)
|
||||
|
||||
void asst::MatchImageAnalyzer::set_region_of_appeared(Rect region) noexcept
|
||||
{
|
||||
m_region_of_appeared = std::move(region);
|
||||
m_region_of_appeared = region;
|
||||
if (m_use_cache && !m_region_of_appeared.empty()) {
|
||||
m_roi = m_region_of_appeared;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace asst
|
||||
{
|
||||
public:
|
||||
using AbstractImageAnalyzer::AbstractImageAnalyzer;
|
||||
MatchImageAnalyzer(const cv::Mat image, const Rect& roi, std::string templ_name, double templ_thres = 0.0);
|
||||
MatchImageAnalyzer(const cv::Mat& image, const Rect& roi, std::string templ_name, double templ_thres = 0.0);
|
||||
virtual ~MatchImageAnalyzer() = default;
|
||||
|
||||
virtual bool analyze() override;
|
||||
@@ -18,7 +18,7 @@ namespace asst
|
||||
void set_templ_name(std::string templ_name) noexcept;
|
||||
void set_templ(cv::Mat templ) noexcept;
|
||||
void set_threshold(double templ_thres) noexcept;
|
||||
void set_task_info(std::shared_ptr<TaskInfo> task_ptr);
|
||||
void set_task_info(const std::shared_ptr<TaskInfo>& task_ptr);
|
||||
void set_task_info(const std::string& task_name);
|
||||
void set_region_of_appeared(Rect region) noexcept;
|
||||
void set_mask_with_close(int with_close) noexcept;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<ClInclude Include="BattleFormationTask.h" />
|
||||
<ClInclude Include="BattleImageAnalyzer.h" />
|
||||
<ClInclude Include="BattleProcessTask.h" />
|
||||
<ClInclude Include="GameCrashRestartTaskPlugin.h" />
|
||||
<ClInclude Include="RoguelikeRecruitConfiger.h" />
|
||||
<ClInclude Include="CopilotTask.h" />
|
||||
<ClInclude Include="DebugTask.h" />
|
||||
@@ -86,7 +87,7 @@
|
||||
<ClInclude Include="StageDropsConfiger.h" />
|
||||
<ClInclude Include="StageDropsImageAnalyzer.h" />
|
||||
<ClInclude Include="StageDropsTaskPlugin.h" />
|
||||
<ClInclude Include="StartGameTask.h" />
|
||||
<ClInclude Include="StartGameTaskPlugin.h" />
|
||||
<ClInclude Include="StartUpTask.h" />
|
||||
<ClInclude Include="TaskData.h" />
|
||||
<ClInclude Include="MatchImageAnalyzer.h" />
|
||||
@@ -108,6 +109,7 @@
|
||||
<ClCompile Include="BattleFormationTask.cpp" />
|
||||
<ClCompile Include="BattleImageAnalyzer.cpp" />
|
||||
<ClCompile Include="BattleProcessTask.cpp" />
|
||||
<ClCompile Include="GameCrashRestartTaskPlugin.cpp" />
|
||||
<ClCompile Include="RoguelikeRecruitConfiger.cpp" />
|
||||
<ClCompile Include="CopilotTask.cpp" />
|
||||
<ClCompile Include="DebugTask.cpp" />
|
||||
@@ -166,7 +168,7 @@
|
||||
<ClCompile Include="StageDropsConfiger.cpp" />
|
||||
<ClCompile Include="StageDropsImageAnalyzer.cpp" />
|
||||
<ClCompile Include="StageDropsTaskPlugin.cpp" />
|
||||
<ClCompile Include="StartGameTask.cpp" />
|
||||
<ClCompile Include="StartGameTaskPlugin.cpp" />
|
||||
<ClCompile Include="StartUpTask.cpp" />
|
||||
<ClCompile Include="TaskData.cpp" />
|
||||
<ClCompile Include="MatchImageAnalyzer.cpp" />
|
||||
@@ -336,4 +338,4 @@
|
||||
<UserProperties _1_1_4_1_1_4resource_4config_1json__JsonSchema="" _1_1_4_1_1_4resource_4tasks_1json__JsonSchema="../docs/maa_tasks_schema.json" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -240,9 +240,6 @@
|
||||
<ClInclude Include="RecruitCalcTask.h">
|
||||
<Filter>头文件\Task\Sub</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="StartGameTask.h">
|
||||
<Filter>头文件\Task\Sub</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BattleImageAnalyzer.h">
|
||||
<Filter>头文件\ImageAnalyzer\Final</Filter>
|
||||
</ClInclude>
|
||||
@@ -336,6 +333,12 @@
|
||||
<ClInclude Include="RoguelikeRecruitImageAnalyzer.h">
|
||||
<Filter>头文件\ImageAnalyzer\Final</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="StartGameTaskPlugin.h">
|
||||
<Filter>头文件\Task\Plugin</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GameCrashRestartTaskPlugin.h">
|
||||
<Filter>头文件\Task\Plugin</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Controller.cpp">
|
||||
@@ -476,9 +479,6 @@
|
||||
<ClCompile Include="ProcessTask.cpp">
|
||||
<Filter>源文件\Task\Sub</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StartGameTask.cpp">
|
||||
<Filter>源文件\Task\Sub</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BattleImageAnalyzer.cpp">
|
||||
<Filter>源文件\ImageAnalyzer\Final</Filter>
|
||||
</ClCompile>
|
||||
@@ -569,6 +569,12 @@
|
||||
<ClCompile Include="RoguelikeRecruitImageAnalyzer.cpp">
|
||||
<Filter>源文件\ImageAnalyzer\Final</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StartGameTaskPlugin.cpp">
|
||||
<Filter>源文件\Task\Plugin</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GameCrashRestartTaskPlugin.cpp">
|
||||
<Filter>源文件\Task\Plugin</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\resource\config.json">
|
||||
@@ -584,4 +590,4 @@
|
||||
<Filter>资源文件</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,15 +1,16 @@
|
||||
#include "MultiMatchImageAnalyzer.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "Logger.hpp"
|
||||
#include "Resource.h"
|
||||
#include "TaskData.h"
|
||||
|
||||
asst::MultiMatchImageAnalyzer::MultiMatchImageAnalyzer(const cv::Mat image, const Rect& roi, std::string templ_name, double templ_thres)
|
||||
asst::MultiMatchImageAnalyzer::MultiMatchImageAnalyzer(const cv::Mat& image, const Rect& roi, std::string templ_name, double templ_thres)
|
||||
: AbstractImageAnalyzer(image, roi),
|
||||
m_templ_name(templ_name),
|
||||
m_templ_name(std::move(templ_name)),
|
||||
m_templ_thres(templ_thres)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
bool asst::MultiMatchImageAnalyzer::analyze()
|
||||
@@ -68,7 +69,7 @@ void asst::MultiMatchImageAnalyzer::set_task_info(MatchTaskInfo task_info) noexc
|
||||
set_roi(task_info.roi);
|
||||
}
|
||||
|
||||
void asst::MultiMatchImageAnalyzer::set_task_info(std::shared_ptr<TaskInfo> task_ptr)
|
||||
void asst::MultiMatchImageAnalyzer::set_task_info(const std::shared_ptr<TaskInfo>& task_ptr)
|
||||
{
|
||||
set_task_info(*std::dynamic_pointer_cast<MatchTaskInfo>(task_ptr));
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace asst
|
||||
{
|
||||
public:
|
||||
using AbstractImageAnalyzer::AbstractImageAnalyzer;
|
||||
MultiMatchImageAnalyzer(const cv::Mat image, const Rect& roi, std::string templ_name, double templ_thres);
|
||||
MultiMatchImageAnalyzer(const cv::Mat& image, const Rect& roi, std::string templ_name, double templ_thres);
|
||||
virtual ~MultiMatchImageAnalyzer() = default;
|
||||
|
||||
virtual bool analyze() override;
|
||||
@@ -19,7 +19,7 @@ namespace asst
|
||||
void set_templ_name(std::string templ_name) noexcept;
|
||||
void set_threshold(double templ_thres) noexcept;
|
||||
|
||||
void set_task_info(std::shared_ptr<TaskInfo> task_ptr);
|
||||
void set_task_info(const std::shared_ptr<TaskInfo>& task_ptr);
|
||||
void set_task_info(const std::string& task_name);
|
||||
|
||||
const std::vector<MatchRect>& get_result() const noexcept;
|
||||
|
||||
@@ -154,7 +154,7 @@ void asst::OcrImageAnalyzer::set_task_info(const std::string& task_name)
|
||||
|
||||
void asst::OcrImageAnalyzer::set_region_of_appeared(Rect region) noexcept
|
||||
{
|
||||
m_region_of_appeared = std::move(region);
|
||||
m_region_of_appeared = region;
|
||||
if (m_use_cache && !m_region_of_appeared.empty()) {
|
||||
m_roi = m_region_of_appeared;
|
||||
m_without_det = true;
|
||||
|
||||
@@ -34,10 +34,10 @@ bool asst::OcrPack::load(const std::string& dir)
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr static const char* DetName = "/det";
|
||||
constexpr static auto DetName = "/det";
|
||||
//constexpr static const char* ClsName = "/cls";
|
||||
constexpr static const char* RecName = "/rec";
|
||||
constexpr static const char* KeysName = "/ppocr_keys_v1.txt";
|
||||
constexpr static auto RecName = "/rec";
|
||||
constexpr static auto KeysName = "/ppocr_keys_v1.txt";
|
||||
|
||||
const std::string dst_filename = dir + DetName;
|
||||
//const std::string cls_filename = dir + ClsName;
|
||||
@@ -52,7 +52,7 @@ bool asst::OcrPack::load(const std::string& dir)
|
||||
return m_ocr != nullptr;
|
||||
}
|
||||
|
||||
std::vector<asst::TextRect> asst::OcrPack::recognize(const cv::Mat image, const asst::TextRectProc& pred, bool without_det)
|
||||
std::vector<asst::TextRect> asst::OcrPack::recognize(const cv::Mat& image, const asst::TextRectProc& pred, bool without_det)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
@@ -89,10 +89,10 @@ std::vector<asst::TextRect> asst::OcrPack::recognize(const cv::Mat image, const
|
||||
int* box = m_boxes_buffer + i * 8;
|
||||
int x_collect[4] = { *(box + 0), *(box + 2), *(box + 4), *(box + 6) };
|
||||
int y_collect[4] = { *(box + 1), *(box + 3), *(box + 5), *(box + 7) };
|
||||
int left = int(*std::min_element(x_collect, x_collect + 4));
|
||||
int right = int(*std::max_element(x_collect, x_collect + 4));
|
||||
int top = int(*std::min_element(y_collect, y_collect + 4));
|
||||
int bottom = int(*std::max_element(y_collect, y_collect + 4));
|
||||
int left = static_cast<int>(*std::min_element(x_collect, x_collect + 4));
|
||||
int right = static_cast<int>(*std::max_element(x_collect, x_collect + 4));
|
||||
int top = static_cast<int>(*std::min_element(y_collect, y_collect + 4));
|
||||
int bottom = static_cast<int>(*std::max_element(y_collect, y_collect + 4));
|
||||
rect = Rect(left, top, right - left, bottom - top);
|
||||
}
|
||||
std::string text(*(m_strs_buffer + i));
|
||||
@@ -117,7 +117,7 @@ std::vector<asst::TextRect> asst::OcrPack::recognize(const cv::Mat image, const
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<asst::TextRect> asst::OcrPack::recognize(const cv::Mat image, const asst::Rect& roi, const asst::TextRectProc& pred, bool without_det)
|
||||
std::vector<asst::TextRect> asst::OcrPack::recognize(const cv::Mat& image, const asst::Rect& roi, const asst::TextRectProc& pred, bool without_det)
|
||||
{
|
||||
auto rect_cor = [&roi, &pred, &without_det](TextRect& tr) -> bool {
|
||||
if (without_det) {
|
||||
|
||||
@@ -23,15 +23,15 @@ namespace asst
|
||||
|
||||
virtual bool load(const std::string& dir) override;
|
||||
|
||||
std::vector<TextRect> recognize(const cv::Mat image, const TextRectProc& pred = nullptr, bool without_det = false);
|
||||
std::vector<TextRect> recognize(const cv::Mat image, const Rect& roi, const TextRectProc& pred = nullptr, bool without_det = false);
|
||||
std::vector<TextRect> recognize(const cv::Mat& image, const TextRectProc& pred = nullptr, bool without_det = false);
|
||||
std::vector<TextRect> recognize(const cv::Mat& image, const Rect& roi, const TextRectProc& pred = nullptr, bool without_det = false);
|
||||
|
||||
private:
|
||||
paddle_ocr_t* m_ocr = nullptr;
|
||||
|
||||
// each box has 8 value ( 4 points, x and y )
|
||||
int m_boxes_buffer[MaxBoxSize * 8] = { 0 };
|
||||
char* m_strs_buffer[MaxBoxSize] = { 0 };
|
||||
char* m_strs_buffer[MaxBoxSize] = { nullptr };
|
||||
float m_scores_buffer[MaxBoxSize] = { 0 };
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
#include "TaskData.h"
|
||||
|
||||
asst::OcrWithFlagTemplImageAnalyzer::OcrWithFlagTemplImageAnalyzer(const cv::Mat image)
|
||||
asst::OcrWithFlagTemplImageAnalyzer::OcrWithFlagTemplImageAnalyzer(const cv::Mat& image)
|
||||
: OcrWithPreprocessImageAnalyzer(image),
|
||||
m_multi_match_image_analyzer(image)
|
||||
{}
|
||||
|
||||
asst::OcrWithFlagTemplImageAnalyzer::OcrWithFlagTemplImageAnalyzer(const cv::Mat image, const Rect& roi)
|
||||
asst::OcrWithFlagTemplImageAnalyzer::OcrWithFlagTemplImageAnalyzer(const cv::Mat& image, const Rect& roi)
|
||||
: OcrWithPreprocessImageAnalyzer(image, roi),
|
||||
m_multi_match_image_analyzer(image, roi)
|
||||
{}
|
||||
@@ -59,17 +59,18 @@ const std::vector<asst::TextRect>& asst::OcrWithFlagTemplImageAnalyzer::get_resu
|
||||
return m_all_result;
|
||||
}
|
||||
|
||||
void asst::OcrWithFlagTemplImageAnalyzer::set_task_info(std::string templ_task_name, std::string ocr_task_name)
|
||||
void asst::OcrWithFlagTemplImageAnalyzer::set_task_info(const std::string& templ_task_name, const std::string&
|
||||
ocr_task_name)
|
||||
{
|
||||
auto ocr_task_ptr = std::dynamic_pointer_cast<OcrTaskInfo>(Task.get(ocr_task_name));
|
||||
OcrWithPreprocessImageAnalyzer::set_task_info(*ocr_task_ptr);
|
||||
m_flag_rect_move = ocr_task_ptr->roi;
|
||||
m_multi_match_image_analyzer.set_task_info(std::move(templ_task_name));
|
||||
m_multi_match_image_analyzer.set_task_info(templ_task_name);
|
||||
}
|
||||
|
||||
void asst::OcrWithFlagTemplImageAnalyzer::set_flag_rect_move(Rect flag_rect_move)
|
||||
{
|
||||
m_flag_rect_move = std::move(flag_rect_move);
|
||||
m_flag_rect_move = flag_rect_move;
|
||||
}
|
||||
|
||||
std::vector<asst::TextRect>& asst::OcrWithFlagTemplImageAnalyzer::get_result() noexcept
|
||||
|
||||
@@ -8,8 +8,8 @@ namespace asst
|
||||
{
|
||||
public:
|
||||
OcrWithFlagTemplImageAnalyzer() = default;
|
||||
OcrWithFlagTemplImageAnalyzer(const cv::Mat image);
|
||||
OcrWithFlagTemplImageAnalyzer(const cv::Mat image, const Rect& roi);
|
||||
OcrWithFlagTemplImageAnalyzer(const cv::Mat& image);
|
||||
OcrWithFlagTemplImageAnalyzer(const cv::Mat& image, const Rect& roi);
|
||||
virtual ~OcrWithFlagTemplImageAnalyzer() = default;
|
||||
|
||||
virtual void set_image(const cv::Mat image);
|
||||
@@ -21,7 +21,7 @@ namespace asst
|
||||
virtual const std::vector<TextRect>& get_result() const noexcept override;
|
||||
virtual std::vector<TextRect>& get_result() noexcept override;
|
||||
|
||||
void set_task_info(std::string templ_task_name, std::string ocr_task_name);
|
||||
void set_task_info(const std::string& templ_task_name, const std::string& ocr_task_name);
|
||||
void set_flag_rect_move(Rect flag_rect_move);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -14,7 +14,7 @@ bool asst::OcrWithPreprocessImageAnalyzer::analyze()
|
||||
cv::Rect bounding_rect = cv::boundingRect(bin);
|
||||
bounding_rect.x += m_roi.x;
|
||||
bounding_rect.y += m_roi.y;
|
||||
Rect new_roi = utils::make_rect<Rect>(bounding_rect);
|
||||
auto new_roi = utils::make_rect<Rect>(bounding_rect);
|
||||
|
||||
if (new_roi.empty()) {
|
||||
return false;
|
||||
|
||||
@@ -205,7 +205,7 @@ bool ProcessTask::_run()
|
||||
break;
|
||||
}
|
||||
|
||||
m_status->set_data("Last" + cur_name, time(nullptr));
|
||||
m_status->set_number("Last" + cur_name, time(nullptr));
|
||||
|
||||
// 减少其他任务的执行次数
|
||||
// 例如,进入吃理智药的界面了,相当于上一次点蓝色开始行动没生效
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "ProcessTaskImageAnalyzer.h"
|
||||
|
||||
#include <regex>
|
||||
#include <utility>
|
||||
|
||||
#include "AsstUtils.hpp"
|
||||
#include "Logger.hpp"
|
||||
@@ -9,16 +10,14 @@
|
||||
#include "Resource.h"
|
||||
#include "RuntimeStatus.h"
|
||||
|
||||
asst::ProcessTaskImageAnalyzer::ProcessTaskImageAnalyzer(const cv::Mat image, std::vector<std::string> tasks_name)
|
||||
asst::ProcessTaskImageAnalyzer::ProcessTaskImageAnalyzer(const cv::Mat& image, std::vector<std::string> tasks_name)
|
||||
: AbstractImageAnalyzer(image),
|
||||
m_tasks_name(std::move(tasks_name))
|
||||
{
|
||||
;
|
||||
}
|
||||
{}
|
||||
|
||||
asst::ProcessTaskImageAnalyzer::~ProcessTaskImageAnalyzer() = default;
|
||||
|
||||
bool asst::ProcessTaskImageAnalyzer::match_analyze(std::shared_ptr<TaskInfo> task_ptr)
|
||||
bool asst::ProcessTaskImageAnalyzer::match_analyze(const std::shared_ptr<TaskInfo>& task_ptr)
|
||||
{
|
||||
if (!m_match_analyzer) {
|
||||
m_match_analyzer = std::make_unique<MatchImageAnalyzer>(m_image);
|
||||
@@ -26,7 +25,7 @@ bool asst::ProcessTaskImageAnalyzer::match_analyze(std::shared_ptr<TaskInfo> tas
|
||||
const auto match_task_ptr = std::dynamic_pointer_cast<MatchTaskInfo>(task_ptr);
|
||||
m_match_analyzer->set_region_of_appeared(Rect());
|
||||
m_match_analyzer->set_task_info(match_task_ptr);
|
||||
auto region_opt = m_status->get_region(match_task_ptr->name);
|
||||
auto region_opt = m_status->get_rect(match_task_ptr->name);
|
||||
if (region_opt) {
|
||||
m_match_analyzer->set_region_of_appeared(region_opt.value());
|
||||
}
|
||||
@@ -34,13 +33,13 @@ bool asst::ProcessTaskImageAnalyzer::match_analyze(std::shared_ptr<TaskInfo> tas
|
||||
if (m_match_analyzer->analyze()) {
|
||||
m_result = match_task_ptr;
|
||||
m_result_rect = m_match_analyzer->get_result().rect;
|
||||
m_status->set_region(match_task_ptr->name, m_result_rect);
|
||||
m_status->set_rect(match_task_ptr->name, m_result_rect);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool asst::ProcessTaskImageAnalyzer::ocr_analyze(std::shared_ptr<TaskInfo> task_ptr)
|
||||
bool asst::ProcessTaskImageAnalyzer::ocr_analyze(const std::shared_ptr<TaskInfo>& task_ptr)
|
||||
{
|
||||
std::shared_ptr<OcrTaskInfo> ocr_task_ptr = std::dynamic_pointer_cast<OcrTaskInfo>(task_ptr);
|
||||
|
||||
@@ -75,7 +74,7 @@ bool asst::ProcessTaskImageAnalyzer::ocr_analyze(std::shared_ptr<TaskInfo> task_
|
||||
}
|
||||
m_ocr_analyzer->set_region_of_appeared(Rect());
|
||||
m_ocr_analyzer->set_task_info(ocr_task_ptr);
|
||||
auto region_opt = m_status->get_region(ocr_task_ptr->name);
|
||||
auto region_opt = m_status->get_rect(ocr_task_ptr->name);
|
||||
if (region_opt) {
|
||||
m_ocr_analyzer->set_region_of_appeared(region_opt.value());
|
||||
}
|
||||
@@ -88,7 +87,7 @@ bool asst::ProcessTaskImageAnalyzer::ocr_analyze(std::shared_ptr<TaskInfo> task_
|
||||
auto& res = ocr_result.front();
|
||||
m_result = ocr_task_ptr;
|
||||
m_result_rect = res.rect;
|
||||
m_status->set_region(ocr_task_ptr->name, m_result_rect);
|
||||
m_status->set_rect(ocr_task_ptr->name, m_result_rect);
|
||||
//m_ocr_cache.insert(m_ocr_cache.end(), ocr_result.begin(), ocr_result.end());
|
||||
Log.trace("ProcessTaskImageAnalyzer::ocr_analyze | found", res.to_string());
|
||||
}
|
||||
@@ -149,5 +148,5 @@ void asst::ProcessTaskImageAnalyzer::set_tasks(std::vector<std::string> tasks_na
|
||||
|
||||
void asst::ProcessTaskImageAnalyzer::set_status(std::shared_ptr<RuntimeStatus> status) noexcept
|
||||
{
|
||||
m_status = status;
|
||||
m_status = std::move(status);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace asst
|
||||
public:
|
||||
using AbstractImageAnalyzer::AbstractImageAnalyzer;
|
||||
ProcessTaskImageAnalyzer(const cv::Mat image, const Rect& roi) = delete;
|
||||
ProcessTaskImageAnalyzer(const cv::Mat image, std::vector<std::string> tasks_name);
|
||||
ProcessTaskImageAnalyzer(const cv::Mat& image, std::vector<std::string> tasks_name);
|
||||
virtual ~ProcessTaskImageAnalyzer();
|
||||
|
||||
virtual bool analyze() override;
|
||||
@@ -49,8 +49,8 @@ namespace asst
|
||||
{
|
||||
AbstractImageAnalyzer::set_image(image, roi);
|
||||
}
|
||||
bool match_analyze(std::shared_ptr<TaskInfo> task_ptr);
|
||||
bool ocr_analyze(std::shared_ptr<TaskInfo> task_ptr);
|
||||
bool match_analyze(const std::shared_ptr<TaskInfo>& task_ptr);
|
||||
bool ocr_analyze(const std::shared_ptr<TaskInfo>& task_ptr);
|
||||
void reset() noexcept;
|
||||
|
||||
std::unique_ptr<OcrImageAnalyzer> m_ocr_analyzer;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "RecruitCalcTask.h"
|
||||
#include "ProcessTask.h"
|
||||
|
||||
asst::RecruitTask::RecruitTask(AsstCallback callback, void* callback_arg)
|
||||
asst::RecruitTask::RecruitTask(const AsstCallback& callback, void* callback_arg)
|
||||
: PackageTask(callback, callback_arg, TaskType),
|
||||
m_recruit_begin_task_ptr(std::make_shared<ProcessTask>(callback, callback_arg, TaskType)),
|
||||
m_auto_recruit_task_ptr(std::make_shared<AutoRecruitTask>(callback, callback_arg, TaskType)),
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace asst
|
||||
class RecruitTask final : public PackageTask
|
||||
{
|
||||
public:
|
||||
RecruitTask(AsstCallback callback, void* callback_arg);
|
||||
RecruitTask(const AsstCallback& callback, void* callback_arg);
|
||||
virtual ~RecruitTask() = default;
|
||||
|
||||
virtual bool set_params(const json::value& params) override;
|
||||
|
||||
@@ -13,20 +13,20 @@ bool asst::Resource::load(const std::string& dir)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
constexpr static const char* TemplsFilename = "template";
|
||||
constexpr static const char* GeneralCfgFilename = "config.json";
|
||||
constexpr static const char* TaskDataFilename = "tasks.json";
|
||||
constexpr static const char* RoguelikeRecruitCfgFilename = "roguelike_recruit.json";
|
||||
constexpr static const char* RecruitCfgFilename = "recruit.json";
|
||||
constexpr static const char* ItemCfgFilename = "item_index.json";
|
||||
constexpr static const char* InfrastCfgFilename = "infrast.json";
|
||||
constexpr static const char* InfrastTempls = "template/infrast";
|
||||
constexpr static auto TemplsFilename = "template";
|
||||
constexpr static auto GeneralCfgFilename = "config.json";
|
||||
constexpr static auto TaskDataFilename = "tasks.json";
|
||||
constexpr static auto RoguelikeRecruitCfgFilename = "roguelike_recruit.json";
|
||||
constexpr static auto RecruitCfgFilename = "recruit.json";
|
||||
constexpr static auto ItemCfgFilename = "item_index.json";
|
||||
constexpr static auto InfrastCfgFilename = "infrast.json";
|
||||
constexpr static auto InfrastTempls = "template/infrast";
|
||||
//constexpr static const char* CopilotCfgDirname = "copilot";
|
||||
constexpr static const char* RoguelikeCfgDirname = "roguelike";
|
||||
constexpr static const char* OcrResourceFilename = "PaddleOCR";
|
||||
constexpr static const char* TilesCalcResourceFilename = "Arknights-Tile-Pos";
|
||||
constexpr static const char* StageDropsCfgFilename = "stages.json";
|
||||
constexpr static const char* StageDropsTempls = "template/items";
|
||||
constexpr static auto RoguelikeCfgDirname = "roguelike";
|
||||
constexpr static auto OcrResourceFilename = "PaddleOCR";
|
||||
constexpr static auto TilesCalcResourceFilename = "Arknights-Tile-Pos";
|
||||
constexpr static auto StageDropsCfgFilename = "stages.json";
|
||||
constexpr static auto StageDropsTempls = "template/items";
|
||||
|
||||
bool overload = false;
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@ bool asst::RoguelikeBattleTaskPlugin::auto_battle()
|
||||
}
|
||||
|
||||
// 将干员拖动到场上
|
||||
Loc loc = Loc::All;
|
||||
auto loc = Loc::All;
|
||||
switch (opt_oper.role) {
|
||||
case BattleRole::Medic:
|
||||
case BattleRole::Support:
|
||||
@@ -296,7 +296,7 @@ bool asst::RoguelikeBattleTaskPlugin::auto_battle()
|
||||
std::sqrt(
|
||||
(std::abs(placed_point.x - opt_oper.rect.x) << 1)
|
||||
+ (std::abs(placed_point.y - opt_oper.rect.y) << 1)));
|
||||
int duration = static_cast<int>(swipe_oper_task_ptr->pre_delay / 1000.0 * dist); // 随便取的一个系数
|
||||
int duration = static_cast<int>(swipe_oper_task_ptr->pre_delay / 800.0 * dist); // 随便取的一个系数
|
||||
m_ctrler->swipe(opt_oper.rect, placed_rect, duration, true, 0);
|
||||
sleep(use_oper_task_ptr->rear_delay);
|
||||
|
||||
@@ -373,7 +373,7 @@ void asst::RoguelikeBattleTaskPlugin::clear()
|
||||
m_used_tiles.clear();
|
||||
|
||||
for (auto& [key, status] : m_restore_status) {
|
||||
m_status->set_data(key, status);
|
||||
m_status->set_number(key, status);
|
||||
}
|
||||
m_restore_status.clear();
|
||||
}
|
||||
@@ -388,8 +388,8 @@ bool asst::RoguelikeBattleTaskPlugin::try_possible_skill(const cv::Mat& image)
|
||||
bool used = false;
|
||||
for (auto& [loc, name] : m_used_tiles) {
|
||||
std::string status_key = "RoguelikeSkillUsage-" + name;
|
||||
BattleSkillUsage usage = BattleSkillUsage::Possibly;
|
||||
auto usage_opt = m_status->get_data(status_key);
|
||||
auto usage = BattleSkillUsage::Possibly;
|
||||
auto usage_opt = m_status->get_number(status_key);
|
||||
if (usage_opt) {
|
||||
usage = static_cast<BattleSkillUsage>(usage_opt.value());
|
||||
}
|
||||
@@ -408,7 +408,7 @@ bool asst::RoguelikeBattleTaskPlugin::try_possible_skill(const cv::Mat& image)
|
||||
m_ctrler->click(pos_rect);
|
||||
used |= ProcessTask(*this, { "BattleSkillReadyOnClick" }).set_task_delay(0).run();
|
||||
if (usage == BattleSkillUsage::Once) {
|
||||
m_status->set_data(status_key, static_cast<int64_t>(BattleSkillUsage::OnceUsed));
|
||||
m_status->set_number(status_key, static_cast<int64_t>(BattleSkillUsage::OnceUsed));
|
||||
m_restore_status[status_key] = static_cast<int64_t>(BattleSkillUsage::Once);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ bool asst::RoguelikeFormationImageAnalyzer::analyze()
|
||||
}
|
||||
#endif
|
||||
|
||||
m_result.emplace_back(std::move(oper));
|
||||
m_result.emplace_back(oper);
|
||||
}
|
||||
|
||||
return !m_result.empty();
|
||||
|
||||
@@ -26,7 +26,7 @@ bool asst::RoguelikeRecruitConfiger::parse(const json::value& json)
|
||||
for (const auto& role_name : json.at("roles").as_array()) {
|
||||
std::string str_role = role_name.as_string();
|
||||
for (const auto& oper_info : json.at(str_role).as_array()) {
|
||||
std::string name = oper_info.at("name").as_string();;
|
||||
std::string name = oper_info.at("name").as_string();
|
||||
RoguelikeOperInfo info;
|
||||
info.name = name;
|
||||
info.level = oper_info.at("level").as_integer();
|
||||
|
||||
@@ -82,6 +82,6 @@ int asst::RoguelikeRecruitImageAnalyzer::match_level(const Rect& raw_roi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string level = analyzer.get_result().front().text;;
|
||||
std::string level = analyzer.get_result().front().text;
|
||||
return std::stoi(level);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ std::string asst::RoguelikeSkillSelectionImageAnalyzer::name_analyze(const Rect&
|
||||
->replace_map);
|
||||
|
||||
if (!analyzer.analyze()) {
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
return analyzer.get_result().front().text;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ bool asst::RoguelikeSkillSelectionTaskPlugin::_run()
|
||||
}
|
||||
const auto& oper_info = rg_src.get_oper_info(name);
|
||||
int index = 0;
|
||||
BattleSkillUsage usage = BattleSkillUsage::Possibly;
|
||||
auto usage = BattleSkillUsage::Possibly;
|
||||
if (skill_vec.size() >= oper_info.skill) {
|
||||
index = oper_info.skill - 1;
|
||||
usage = oper_info.skill_usage;
|
||||
@@ -56,7 +56,7 @@ bool asst::RoguelikeSkillSelectionTaskPlugin::_run()
|
||||
Log.info(__FUNCTION__, name, " select skill:", index + 1);
|
||||
m_ctrler->click(skill_vec.at(index));
|
||||
}
|
||||
m_status->set_data("RoguelikeSkillUsage-" + name, static_cast<int>(usage));
|
||||
m_status->set_number("RoguelikeSkillUsage-" + name, static_cast<int>(usage));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "Logger.hpp"
|
||||
|
||||
asst::RoguelikeTask::RoguelikeTask(AsstCallback callback, void* callback_arg)
|
||||
asst::RoguelikeTask::RoguelikeTask(const AsstCallback& callback, void* callback_arg)
|
||||
: PackageTask(callback, callback_arg, TaskType),
|
||||
m_roguelike_task_ptr(std::make_shared<ProcessTask>(callback, callback_arg, TaskType))
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace asst
|
||||
class RoguelikeTask : public PackageTask
|
||||
{
|
||||
public:
|
||||
RoguelikeTask(AsstCallback callback, void* callback_arg);
|
||||
RoguelikeTask(const AsstCallback& callback, void* callback_arg);
|
||||
virtual ~RoguelikeTask() = default;
|
||||
|
||||
virtual bool set_params(const json::value& params) override;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "RuntimeStatus.h"
|
||||
|
||||
std::optional<int64_t> asst::RuntimeStatus::get_data(const std::string& key) const noexcept
|
||||
std::optional<int64_t> asst::RuntimeStatus::get_number(const std::string& key) const noexcept
|
||||
{
|
||||
if (auto iter = m_data.find(key);
|
||||
iter != m_data.cend()) {
|
||||
if (auto iter = m_number.find(key);
|
||||
iter != m_number.cend()) {
|
||||
return iter->second;
|
||||
}
|
||||
else {
|
||||
@@ -11,20 +11,20 @@ std::optional<int64_t> asst::RuntimeStatus::get_data(const std::string& key) con
|
||||
}
|
||||
}
|
||||
|
||||
void asst::RuntimeStatus::set_data(std::string key, int64_t value)
|
||||
void asst::RuntimeStatus::set_number(std::string key, int64_t value)
|
||||
{
|
||||
m_data[std::move(key)] = value;
|
||||
m_number.insert_or_assign(std::move(key), value);
|
||||
}
|
||||
|
||||
void asst::RuntimeStatus::clear_data() noexcept
|
||||
void asst::RuntimeStatus::clear_number() noexcept
|
||||
{
|
||||
m_data.clear();
|
||||
m_number.clear();
|
||||
}
|
||||
|
||||
std::optional<asst::Rect> asst::RuntimeStatus::get_region(const std::string& key) const noexcept
|
||||
std::optional<asst::Rect> asst::RuntimeStatus::get_rect(const std::string& key) const noexcept
|
||||
{
|
||||
if (auto iter = m_region_of_appeared.find(key);
|
||||
iter != m_region_of_appeared.cend()) {
|
||||
if (auto iter = m_rect.find(key);
|
||||
iter != m_rect.cend()) {
|
||||
return iter->second;
|
||||
}
|
||||
else {
|
||||
@@ -32,12 +32,33 @@ std::optional<asst::Rect> asst::RuntimeStatus::get_region(const std::string& key
|
||||
}
|
||||
}
|
||||
|
||||
void asst::RuntimeStatus::set_region(std::string key, Rect rect)
|
||||
void asst::RuntimeStatus::set_rect(std::string key, Rect rect)
|
||||
{
|
||||
m_region_of_appeared[std::move(key)] = std::move(rect);
|
||||
m_rect.insert_or_assign(std::move(key), rect);
|
||||
}
|
||||
|
||||
void asst::RuntimeStatus::clear_region() noexcept
|
||||
void asst::RuntimeStatus::clear_rect() noexcept
|
||||
{
|
||||
m_region_of_appeared.clear();
|
||||
m_rect.clear();
|
||||
}
|
||||
|
||||
std::optional<std::string> asst::RuntimeStatus::get_str(const std::string& key) const noexcept
|
||||
{
|
||||
if (auto iter = m_string.find(key);
|
||||
iter != m_string.cend()) {
|
||||
return iter->second;
|
||||
}
|
||||
else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void asst::RuntimeStatus::set_str(std::string key, std::string value)
|
||||
{
|
||||
m_string.insert_or_assign(std::move(key), std::move(value));
|
||||
}
|
||||
|
||||
void asst::RuntimeStatus::clear_str() noexcept
|
||||
{
|
||||
m_string.clear();
|
||||
}
|
||||
|
||||
@@ -17,20 +17,25 @@ namespace asst
|
||||
RuntimeStatus(RuntimeStatus&& rhs) noexcept = delete;
|
||||
~RuntimeStatus() = default;
|
||||
|
||||
std::optional<int64_t> get_data(const std::string& key) const noexcept;
|
||||
void set_data(std::string key, int64_t value);
|
||||
void clear_data() noexcept;
|
||||
std::optional<int64_t> get_number(const std::string& key) const noexcept;
|
||||
void set_number(std::string key, int64_t value);
|
||||
void clear_number() noexcept;
|
||||
|
||||
std::optional<Rect> get_region(const std::string& key) const noexcept;
|
||||
void set_region(std::string key, Rect rect);
|
||||
void clear_region() noexcept;
|
||||
std::optional<Rect> get_rect(const std::string& key) const noexcept;
|
||||
void set_rect(std::string key, Rect rect);
|
||||
void clear_rect() noexcept;
|
||||
|
||||
std::optional<std::string> get_str(const std::string& key) const noexcept;
|
||||
void set_str(std::string key, std::string value);
|
||||
void clear_str() noexcept;
|
||||
|
||||
RuntimeStatus& operator=(const RuntimeStatus& rhs) = delete;
|
||||
RuntimeStatus& operator=(RuntimeStatus&& rhs) noexcept = delete;
|
||||
|
||||
private:
|
||||
|
||||
std::unordered_map<std::string, int64_t> m_data;
|
||||
std::unordered_map<std::string, Rect> m_region_of_appeared;
|
||||
std::unordered_map<std::string, int64_t> m_number;
|
||||
std::unordered_map<std::string, Rect> m_rect;
|
||||
std::unordered_map<std::string, std::string> m_string;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ bool asst::StageDropsImageAnalyzer::analyze_difficulty()
|
||||
};
|
||||
|
||||
MatchImageAnalyzer analyzer(m_image);
|
||||
StageDifficulty matched = StageDifficulty::Normal;
|
||||
auto matched = StageDifficulty::Normal;
|
||||
double max_score = 0.0;
|
||||
|
||||
#ifdef ASST_DEBUG
|
||||
@@ -188,7 +188,7 @@ bool asst::StageDropsImageAnalyzer::analyze_drops()
|
||||
for (int i = 1; i <= size; ++i) {
|
||||
// 因为第一个黄色的 baseline 是渐变的,圈出来的一般左边会少一段,所以这里直接从右边开始往左推
|
||||
int x = baseline.x + baseline.width - i * roi.width;
|
||||
Rect item_roi = Rect(x, baseline.y + roi.y, roi.width, roi.height);
|
||||
auto item_roi = Rect(x, baseline.y + roi.y, roi.width, roi.height);
|
||||
|
||||
std::string item = match_item(item_roi, droptype, size - i, size);
|
||||
int quantity = match_quantity(item_roi);
|
||||
@@ -322,7 +322,7 @@ asst::StageDropType asst::StageDropsImageAnalyzer::match_droptype(const Rect& ro
|
||||
};
|
||||
|
||||
MatchImageAnalyzer analyzer(m_image);
|
||||
StageDropType matched = StageDropType::Unknown;
|
||||
auto matched = StageDropType::Unknown;
|
||||
double max_score = 0.0;
|
||||
|
||||
#ifdef ASST_DEBUG
|
||||
@@ -380,7 +380,7 @@ std::string asst::StageDropsImageAnalyzer::match_item(const Rect& roi, StageDrop
|
||||
}
|
||||
else {
|
||||
Log.error("StageDropType::ExpAndLMB, size", size);
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
break;
|
||||
case StageDropType::Furniture:
|
||||
@@ -391,7 +391,7 @@ std::string asst::StageDropsImageAnalyzer::match_item(const Rect& roi, StageDrop
|
||||
return "4003"; // 合成玉
|
||||
}
|
||||
|
||||
auto match_item_with_templs = [&](std::vector<std::string> templs_list) -> std::string {
|
||||
auto match_item_with_templs = [&](const std::vector<std::string>& templs_list) -> std::string {
|
||||
MatchImageAnalyzer analyzer(m_image);
|
||||
analyzer.set_task_info("StageDrops-Item");
|
||||
analyzer.set_mask_with_close(true);
|
||||
|
||||
@@ -22,9 +22,9 @@ bool asst::StageDropsTaskPlugin::verify(AsstMsg msg, const json::value& details)
|
||||
}
|
||||
|
||||
if (details.at("details").at("task").as_string() == "EndOfAction") {
|
||||
auto pre_time_opt = m_status->get_data("LastStartButton2");
|
||||
auto pre_time_opt = m_status->get_number("LastStartButton2");
|
||||
int64_t pre_start_time = pre_time_opt ? pre_time_opt.value() : 0;
|
||||
auto pre_reg_time_opt = m_status->get_data("LastRecognizeDrops");
|
||||
auto pre_reg_time_opt = m_status->get_number("LastRecognizeDrops");
|
||||
int64_t pre_recognize_time = pre_reg_time_opt ? pre_reg_time_opt.value() : 0;
|
||||
if (pre_start_time + RecognizationTimeOffset == pre_recognize_time) {
|
||||
Log.info("Recognization time too close, pass", pre_start_time, pre_recognize_time);
|
||||
@@ -61,6 +61,12 @@ bool asst::StageDropsTaskPlugin::set_server(std::string server)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asst::StageDropsTaskPlugin::set_specify_quantity(std::unordered_map<std::string, int> quantity)
|
||||
{
|
||||
m_specify_quantity = std::move(quantity);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asst::StageDropsTaskPlugin::_run()
|
||||
{
|
||||
LogTraceFunction;
|
||||
@@ -75,7 +81,9 @@ bool asst::StageDropsTaskPlugin::_run()
|
||||
}
|
||||
drop_info_callback();
|
||||
|
||||
check_stage_valid();
|
||||
if (!check_stage_valid() || check_specify_quantity()) {
|
||||
stop_task();
|
||||
}
|
||||
|
||||
if (m_enable_penguid) {
|
||||
auto upload_future = std::async(
|
||||
@@ -111,9 +119,9 @@ bool asst::StageDropsTaskPlugin::recognize_drops()
|
||||
m_stars = analyzer.get_stars();
|
||||
m_cur_drops = analyzer.get_drops();
|
||||
|
||||
auto last_time_opt = m_status->get_data("LastStartButton2");
|
||||
auto last_time_opt = m_status->get_number("LastStartButton2");
|
||||
auto last_time = last_time_opt ? last_time_opt.value() : 0;
|
||||
m_status->set_data("LastRecognizeDrops", last_time + RecognizationTimeOffset);
|
||||
m_status->set_number("LastRecognizeDrops", last_time + RecognizationTimeOffset);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -170,7 +178,7 @@ void asst::StageDropsTaskPlugin::set_startbutton_delay()
|
||||
LogTraceFunction;
|
||||
|
||||
if (!m_startbutton_delay_setted) {
|
||||
auto last_time_opt = m_status->get_data("LastStartButton2");;
|
||||
auto last_time_opt = m_status->get_number("LastStartButton2");
|
||||
int64_t pre_start_time = last_time_opt ? last_time_opt.value() : 0;
|
||||
|
||||
if (pre_start_time > 0) {
|
||||
@@ -257,12 +265,26 @@ bool asst::StageDropsTaskPlugin::check_stage_valid()
|
||||
info["why"] = "EX关卡";
|
||||
callback(AsstMsg::SubTaskError, info);
|
||||
|
||||
m_cast_ptr->set_times_limit("StartButton1", 0)
|
||||
.set_times_limit("StartButton2", 0)
|
||||
.set_times_limit("MedicineConfirm", 0)
|
||||
.set_times_limit("StoneConfirm", 0);
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asst::StageDropsTaskPlugin::check_specify_quantity() const
|
||||
{
|
||||
for (const auto& [id, quantity] : m_specify_quantity) {
|
||||
if (auto find_iter = m_drop_stats.find(id);
|
||||
find_iter != m_drop_stats.end() && find_iter->second >= quantity) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void asst::StageDropsTaskPlugin::stop_task()
|
||||
{
|
||||
m_cast_ptr->set_times_limit("StartButton1", 0)
|
||||
.set_times_limit("StartButton2", 0)
|
||||
.set_times_limit("MedicineConfirm", 0)
|
||||
.set_times_limit("StoneConfirm", 0);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace asst
|
||||
bool set_enable_penguid(bool enable);
|
||||
bool set_penguin_id(std::string id);
|
||||
bool set_server(std::string server);
|
||||
bool set_specify_quantity(std::unordered_map<std::string, int> quantity);
|
||||
private:
|
||||
virtual bool _run() override;
|
||||
|
||||
@@ -31,6 +32,8 @@ namespace asst
|
||||
void drop_info_callback();
|
||||
void set_startbutton_delay();
|
||||
bool check_stage_valid();
|
||||
bool check_specify_quantity() const;
|
||||
void stop_task();
|
||||
void upload_to_penguin();
|
||||
|
||||
static constexpr int64_t RecognizationTimeOffset = 20;
|
||||
@@ -48,5 +51,6 @@ namespace asst
|
||||
bool m_enable_penguid = false;
|
||||
std::string m_penguin_id;
|
||||
std::string m_server = "CN";
|
||||
std::unordered_map<std::string, int> m_specify_quantity;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "AbstractTask.h"
|
||||
#include "AsstTypes.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class StartGameTask : public AbstractTask
|
||||
{
|
||||
public:
|
||||
using AbstractTask::AbstractTask;
|
||||
~StartGameTask() override = default;
|
||||
|
||||
StartGameTask& set_param(std::string client_type) noexcept;
|
||||
|
||||
protected:
|
||||
bool _run() override;
|
||||
|
||||
std::string m_client_type = "";
|
||||
};
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "StartGameTask.h"
|
||||
#include "StartGameTaskPlugin.h"
|
||||
|
||||
#include "Controller.h"
|
||||
|
||||
using namespace asst;
|
||||
|
||||
bool StartGameTask::_run()
|
||||
bool StartGameTaskPlugin::_run()
|
||||
{
|
||||
if (m_client_type.empty()) {
|
||||
return false;
|
||||
@@ -12,7 +12,7 @@ bool StartGameTask::_run()
|
||||
return m_ctrler->start_game(m_client_type).has_value();
|
||||
}
|
||||
|
||||
StartGameTask& StartGameTask::set_param(std::string client_type) noexcept
|
||||
StartGameTaskPlugin& StartGameTaskPlugin::set_client_type(std::string client_type) noexcept
|
||||
{
|
||||
m_client_type = std::move(client_type);
|
||||
return *this;
|
||||
28
src/MeoAssistant/StartGameTaskPlugin.h
Normal file
28
src/MeoAssistant/StartGameTaskPlugin.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "AbstractTaskPlugin.h"
|
||||
#include "AsstTypes.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
inline static const std::string ClientTypeKey = "client_type";
|
||||
|
||||
class StartGameTaskPlugin : public AbstractTaskPlugin
|
||||
{
|
||||
public:
|
||||
using AbstractTaskPlugin::AbstractTaskPlugin;
|
||||
virtual ~StartGameTaskPlugin() noexcept = default;
|
||||
|
||||
virtual bool verify(AsstMsg msg, const json::value& details) const override
|
||||
{
|
||||
std::ignore = msg; std::ignore = details; return true;
|
||||
};
|
||||
|
||||
StartGameTaskPlugin& set_client_type(std::string client_type) noexcept;
|
||||
|
||||
protected:
|
||||
bool _run() override;
|
||||
|
||||
std::string m_client_type = "";
|
||||
};
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
#include "StartUpTask.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "ProcessTask.h"
|
||||
|
||||
asst::StartUpTask::StartUpTask(AsstCallback callback, void* callback_arg)
|
||||
: PackageTask(callback, callback_arg, TaskType),
|
||||
m_start_game_task_ptr(std::make_shared<StartGameTask>(m_callback, m_callback_arg, TaskType)),
|
||||
: PackageTask(std::move(callback), callback_arg, TaskType),
|
||||
m_start_game_task_ptr(std::make_shared<StartGameTaskPlugin>(m_callback, m_callback_arg, TaskType)),
|
||||
m_start_up_task_ptr(std::make_shared<ProcessTask>(m_callback, m_callback_arg, TaskType))
|
||||
{
|
||||
m_start_up_task_ptr->set_tasks({ "StartUp" })
|
||||
@@ -16,7 +18,7 @@ asst::StartUpTask::StartUpTask(AsstCallback callback, void* callback_arg)
|
||||
|
||||
bool asst::StartUpTask::set_params(const json::value& params)
|
||||
{
|
||||
m_start_game_task_ptr->set_param(params.get("client_type", ""))
|
||||
m_start_game_task_ptr->set_client_type(params.get("client_type", ""))
|
||||
.set_enable(params.get("start_game_enable", false));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include "PackageTask.h"
|
||||
#include "StartGameTask.h"
|
||||
#include "StartGameTaskPlugin.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
@@ -16,7 +16,7 @@ namespace asst
|
||||
|
||||
static constexpr const char* TaskType = "StartUp";
|
||||
private:
|
||||
std::shared_ptr<StartGameTask> m_start_game_task_ptr = nullptr;
|
||||
std::shared_ptr<StartGameTaskPlugin> m_start_game_task_ptr = nullptr;
|
||||
std::shared_ptr<ProcessTask> m_start_up_task_ptr = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ bool asst::TaskData::parse(const json::value& json)
|
||||
for (const auto& [name, task_json] : json.as_object()) {
|
||||
std::string algorithm_str = task_json.get("algorithm", "matchtemplate");
|
||||
std::transform(algorithm_str.begin(), algorithm_str.end(), algorithm_str.begin(), to_lower);
|
||||
AlgorithmType algorithm = AlgorithmType::Invalid;
|
||||
auto algorithm = AlgorithmType::Invalid;
|
||||
if (algorithm_str == "matchtemplate") {
|
||||
algorithm = AlgorithmType::MatchTemplate;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ bool asst::TilePack::load(const std::string& dir)
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr static const char* filename = "/levels.json";
|
||||
constexpr static auto filename = "/levels.json";
|
||||
|
||||
try {
|
||||
m_tile_calculator = std::make_unique<Map::TileCalc>(
|
||||
@@ -40,7 +40,7 @@ std::unordered_map<asst::Point, asst::TilePack::TileInfo> asst::TilePack::calc(
|
||||
Log.trace("After tiles cacl run");
|
||||
if (!ret) {
|
||||
Log.info("Tiles calc error!");
|
||||
return std::unordered_map<asst::Point, asst::TilePack::TileInfo>();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unordered_map<asst::Point, asst::TilePack::TileInfo> dst;
|
||||
@@ -62,7 +62,7 @@ std::unordered_map<asst::Point, asst::TilePack::TileInfo> asst::TilePack::calc(
|
||||
const auto& cv_p = pos[y][x];
|
||||
const auto& tile = tiles[y][x];
|
||||
|
||||
TileKey key = TileKey::Invalid;
|
||||
auto key = TileKey::Invalid;
|
||||
if (auto iter = TileKeyMapping.find(tile.tileKey);
|
||||
iter != TileKeyMapping.cend()) {
|
||||
key = iter->second;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#include "VisitTask.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "ProcessTask.h"
|
||||
|
||||
asst::VisitTask::VisitTask(AsstCallback callback, void* callback_arg)
|
||||
: PackageTask(callback, callback_arg, TaskType),
|
||||
: PackageTask(std::move(callback), callback_arg, TaskType),
|
||||
m_visit_task_ptr(std::make_shared<ProcessTask>(m_callback, m_callback_arg, TaskType))
|
||||
{
|
||||
m_visit_task_ptr->set_tasks({ "VisitBegin" });
|
||||
|
||||
@@ -170,11 +170,17 @@ namespace MeoAsstGui
|
||||
break;
|
||||
|
||||
case "UnsupportedResolution":
|
||||
mainModel.AddLog("分辨率过低\n请设置为 720p 或更高", "darkred");
|
||||
mainModel.AddLog("分辨率过低,请设置为 720p 或更高", "darkred");
|
||||
break;
|
||||
|
||||
case "ResolutionError":
|
||||
mainModel.AddLog("分辨率获取失败\n建议重启电脑\n或更换模拟器后再试", "darkred");
|
||||
mainModel.AddLog("分辨率获取失败,建议重启电脑,或更换模拟器后再试", "darkred");
|
||||
break;
|
||||
|
||||
case "Disconnect":
|
||||
case "CommandExecFailed":
|
||||
mainModel.AddLog("错误!连接断开!", "darkred");
|
||||
AsstStop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -258,8 +264,8 @@ namespace MeoAsstGui
|
||||
|
||||
switch (subTask)
|
||||
{
|
||||
case "StartGameTask":
|
||||
mainModel.AddLog("打开客户端失败,请\n检查配置文件", "darkred");
|
||||
case "StartGameTaskPlugin":
|
||||
mainModel.AddLog("打开客户端失败,请检查配置文件", "darkred");
|
||||
break;
|
||||
|
||||
case "AutoRecruitTask":
|
||||
@@ -376,6 +382,14 @@ namespace MeoAsstGui
|
||||
case "Roguelike1StageTraderInvestSystemFull":
|
||||
mainModel.AddLog("投资达到上限", "darkcyan");
|
||||
break;
|
||||
|
||||
case "MaybeCrashAndRestartGame":
|
||||
mainModel.AddLog("游戏崩溃,重新启动");
|
||||
break;
|
||||
|
||||
case "OfflineConfirm":
|
||||
mainModel.AddLog("游戏掉线,重新连接");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -670,7 +684,7 @@ namespace MeoAsstGui
|
||||
return AsstAppendTask(_handle, type, JsonConvert.SerializeObject(task_params)) != 0;
|
||||
}
|
||||
|
||||
public bool AsstAppendFight(string stage, int max_medicine, int max_stone, int max_times)
|
||||
public bool AsstAppendFight(string stage, int max_medicine, int max_stone, int max_times, string drops_item_id, int drops_item_quantity)
|
||||
{
|
||||
var task_params = new JObject();
|
||||
task_params["stage"] = stage;
|
||||
@@ -678,7 +692,13 @@ namespace MeoAsstGui
|
||||
task_params["stone"] = max_stone;
|
||||
task_params["times"] = max_times;
|
||||
task_params["report_to_penguin"] = true;
|
||||
if (drops_item_quantity != 0)
|
||||
{
|
||||
task_params["drops"] = new JObject();
|
||||
task_params["drops"][drops_item_id] = drops_item_quantity;
|
||||
}
|
||||
var settings = _container.Get<SettingsViewModel>();
|
||||
task_params["client_type"] = settings.ClientType;
|
||||
task_params["penguin_id"] = settings.PenguinId;
|
||||
task_params["server"] = "CN";
|
||||
return AsstAppendTaskWithEncoding("Fight", task_params);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="0" VerticalAlignment="Center">
|
||||
<CheckBox IsChecked="{Binding UseMedicine}" IsHitTestVisible="{Binding Idle}" Content="吃理智药" Margin="10" />
|
||||
@@ -33,15 +34,26 @@
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="2" VerticalAlignment="Center">
|
||||
<CheckBox IsChecked="{Binding HasTimesLimited}" IsHitTestVisible="{Binding Idle}" Content="指定次数" Margin="10" />
|
||||
<TextBox Text="{Binding MaxTimes}" IsReadOnly="{c:Binding Path=!Idle}" TextWrapping="Wrap" Margin="10"
|
||||
Width="50" InputMethod.IsInputMethodEnabled="False" />
|
||||
<TextBlock Style="{StaticResource TextBlockDefault}" Text="次" />
|
||||
<CheckBox IsChecked="{Binding IsSpecifiedDrops}" IsHitTestVisible="{Binding Idle}" Content="指定材料" Margin="10" />
|
||||
<ComboBox Width="120" Margin="10"
|
||||
IsHitTestVisible ="{Binding Path=Idle}"
|
||||
IsEditable="True"
|
||||
IsTextSearchEnabled ="True"
|
||||
DisplayMemberPath="Display"
|
||||
SelectedValuePath="Value"
|
||||
ItemsSource="{Binding DropsList}"
|
||||
SelectedValue="{Binding DropsItemId}" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="3" VerticalAlignment="Center">
|
||||
<!--<TextBlock Style="{StaticResource TextBlockDefault}" Margin="35,10,0,10" Text="掉落数 " />-->
|
||||
<TextBox Text="{Binding DropsQuantity}" IsReadOnly="{c:Binding Path=!Idle}" TextWrapping="Wrap"
|
||||
Width="95" Margin="98,10,10,10" InputMethod.IsInputMethodEnabled="False" />
|
||||
<TextBlock Style="{StaticResource TextBlockDefault}" Text="个" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="4" Orientation="Horizontal">
|
||||
<TextBlock Style="{StaticResource TextBlockDefault}" Margin="10" VerticalAlignment="Center"
|
||||
Text="关卡选择" />
|
||||
<ComboBox Width="110" Margin="10"
|
||||
<TextBlock Style="{StaticResource TextBlockDefault}" Margin="10,10,0,10" VerticalAlignment="Center"
|
||||
Text="关卡选择" FontSize="14" />
|
||||
<ComboBox Width="120" Margin="31,10,10,10"
|
||||
IsHitTestVisible ="{Binding Path=Idle}"
|
||||
ItemsSource="{Binding StageList}"
|
||||
DisplayMemberPath="Display"
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY
|
||||
|
||||
using System.IO;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Controls;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace MeoAsstGui
|
||||
{
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace MeoAsstGui
|
||||
new CombData { Display = "刷源石锭投资,投资过后退出", Value = "2" }
|
||||
};
|
||||
|
||||
ServerTypeList = new List<CombData>
|
||||
ClientTypeList = new List<CombData>
|
||||
{
|
||||
new CombData { Display = "官服", Value = "Official" },
|
||||
new CombData { Display = "Bilibili服", Value = "Bilibili" }
|
||||
@@ -177,15 +177,15 @@ namespace MeoAsstGui
|
||||
}
|
||||
}
|
||||
|
||||
private string _serverType = ViewStatusStorage.Get("Start.ServerType", "Official");
|
||||
private string _clientType = ViewStatusStorage.Get("Start.ClientType", "Official");
|
||||
|
||||
public string ServerType
|
||||
public string ClientType
|
||||
{
|
||||
get { return _serverType; }
|
||||
get { return _clientType; }
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _serverType, value);
|
||||
ViewStatusStorage.Set("Start.ServerType", value);
|
||||
SetAndNotify(ref _clientType, value);
|
||||
ViewStatusStorage.Set("Start.ClientType", value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ namespace MeoAsstGui
|
||||
|
||||
public List<CombData> UsesOfDronesList { get; set; }
|
||||
public List<CombData> RoguelikeModeList { get; set; }
|
||||
public List<CombData> ServerTypeList { get; set; }
|
||||
public List<CombData> ClientTypeList { get; set; }
|
||||
public List<CombData> ConnectConfigList { get; set; }
|
||||
|
||||
private int _dormThreshold = Convert.ToInt32(ViewStatusStorage.Get("Infrast.DormThreshold", "30"));
|
||||
|
||||
@@ -12,8 +12,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Stylet;
|
||||
using StyletIoC;
|
||||
|
||||
@@ -118,7 +122,7 @@ namespace MeoAsstGui
|
||||
{
|
||||
new CombData { Display = "当前关卡", Value = string.Empty },
|
||||
new CombData { Display = "上次作战", Value = "LastBattle" },
|
||||
|
||||
|
||||
// “覆潮之下” 活动关卡 //复刻活动,结束后直接删除
|
||||
new CombData { Display = "SV-9", Value = "SV-9" },
|
||||
new CombData { Display = "SV-8", Value = "SV-8" },
|
||||
@@ -129,7 +133,6 @@ namespace MeoAsstGui
|
||||
new CombData { Display = "经验-6/5", Value = "LS-6" },
|
||||
new CombData { Display = "红票-5", Value = "AP-5" },
|
||||
new CombData { Display = "技能-5", Value = "CA-5" },
|
||||
new CombData { Display = "剿灭作战", Value = "Annihilation" },
|
||||
|
||||
// “愚人号” 活动关卡
|
||||
//new CombData { Display = "SN-8", Value = "SN-8" },
|
||||
@@ -139,7 +142,9 @@ namespace MeoAsstGui
|
||||
//// “风雪过境” 活动关卡
|
||||
//new CombData { Display = "BI-7", Value = "BI-7" },
|
||||
//new CombData { Display = "BI-8", Value = "BI-8" }
|
||||
};
|
||||
};
|
||||
|
||||
InitDrops();
|
||||
|
||||
UpdateDatePrompt();
|
||||
}
|
||||
@@ -330,19 +335,21 @@ namespace MeoAsstGui
|
||||
ViewStatusStorage.Set("MainFunction.UseMedicine.Quantity", MedicineNumber);
|
||||
// 吃石头颗数
|
||||
ViewStatusStorage.Set("MainFunction.UseStone.Quantity", StoneNumber);
|
||||
// 指定刷关次数
|
||||
ViewStatusStorage.Set("MainFunction.TimesLimited.Quantity", MaxTimes);
|
||||
// 指定掉落材料
|
||||
ViewStatusStorage.Set("MainFunction.Drops.ItemId", DropsItemId);
|
||||
// 指定掉落材料数量
|
||||
ViewStatusStorage.Set("MainFunction.Drops.Quantity", DropsQuantity);
|
||||
}
|
||||
|
||||
private bool appendStart()
|
||||
{
|
||||
var settings = _container.Get<SettingsViewModel>();
|
||||
var asstProxy = _container.Get<AsstProxy>();
|
||||
var mode = settings.ServerType;
|
||||
var mode = settings.ClientType;
|
||||
var enable = settings.StartGameEnable;
|
||||
return asstProxy.AsstAppendStartUp(mode, enable);
|
||||
}
|
||||
|
||||
|
||||
private bool appendFight()
|
||||
{
|
||||
int medicine = 0;
|
||||
@@ -361,17 +368,25 @@ namespace MeoAsstGui
|
||||
stone = 0;
|
||||
}
|
||||
}
|
||||
int times = int.MaxValue;
|
||||
if (HasTimesLimited)
|
||||
//int times = int.MaxValue;
|
||||
//if (IsSpecifiedDrops)
|
||||
//{
|
||||
// if (!int.TryParse(DropsQuantity, out times))
|
||||
// {
|
||||
// times = 0;
|
||||
// }
|
||||
//}
|
||||
int drops_quantity = 0;
|
||||
if (IsSpecifiedDrops)
|
||||
{
|
||||
if (!int.TryParse(MaxTimes, out times))
|
||||
if (!int.TryParse(DropsQuantity, out drops_quantity))
|
||||
{
|
||||
times = 0;
|
||||
drops_quantity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var asstProxy = _container.Get<AsstProxy>();
|
||||
return asstProxy.AsstAppendFight(Stage, medicine, stone, times);
|
||||
return asstProxy.AsstAppendFight(Stage, medicine, stone, int.MaxValue, DropsItemId, drops_quantity);
|
||||
}
|
||||
|
||||
private bool appendInfrast()
|
||||
@@ -590,25 +605,71 @@ namespace MeoAsstGui
|
||||
}
|
||||
}
|
||||
|
||||
private bool _hasTimesLimited;
|
||||
private bool _isSpecifiedDrops = System.Convert.ToBoolean(ViewStatusStorage.Get("MainFunction.Drops.Enable", bool.FalseString));
|
||||
|
||||
public bool HasTimesLimited
|
||||
public bool IsSpecifiedDrops
|
||||
{
|
||||
get { return _hasTimesLimited; }
|
||||
get { return _isSpecifiedDrops; }
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _hasTimesLimited, value);
|
||||
SetAndNotify(ref _isSpecifiedDrops, value);
|
||||
ViewStatusStorage.Set("MainFunction.Drops.Enable", value.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private string _maxTimes = ViewStatusStorage.Get("MainFunction.TimesLimited.Quantity", "5");
|
||||
private static readonly string _DropsFilename = System.Environment.CurrentDirectory + "\\resource\\item_index.json";
|
||||
|
||||
public string MaxTimes
|
||||
public List<CombData> AllDrops { get; set; } = new List<CombData>();
|
||||
|
||||
private void InitDrops()
|
||||
{
|
||||
get { return _maxTimes; }
|
||||
string jsonStr = File.ReadAllText(_DropsFilename);
|
||||
var reader = (JObject)JsonConvert.DeserializeObject(jsonStr);
|
||||
foreach (var item in reader)
|
||||
{
|
||||
var val = item.Key;
|
||||
if (!int.TryParse(val, out _)) // 不是数字的东西都是正常关卡不会掉的(大概吧)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var dis = item.Value["name"].ToString();
|
||||
if (dis.EndsWith("双芯片") || dis.EndsWith("寻访凭证") || dis.EndsWith("加固建材")
|
||||
|| dis.EndsWith("许可") || dis == "资质凭证" || dis == "高级凭证" || dis == "演习券"
|
||||
|| dis.Contains("源石") || dis == "D32钢" || dis == "双极纳米片" || dis == "聚合剂" || dis == "晶体电子单元")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AllDrops.Add(new CombData { Display = dis, Value = val });
|
||||
}
|
||||
AllDrops.Sort((a, b) =>
|
||||
{
|
||||
return a.Value.CompareTo(b.Value);
|
||||
});
|
||||
DropsList = new ObservableCollection<CombData>(AllDrops);
|
||||
}
|
||||
|
||||
public ObservableCollection<CombData> DropsList { get; set; }
|
||||
|
||||
private string _dropsItemId = ViewStatusStorage.Get("MainFunction.Drops.ItemId", "0");
|
||||
|
||||
public string DropsItemId
|
||||
{
|
||||
get { return _dropsItemId; }
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _maxTimes, value);
|
||||
SetAndNotify(ref _dropsItemId, value);
|
||||
}
|
||||
}
|
||||
|
||||
private string _dropsQuantity = ViewStatusStorage.Get("MainFunction.Drops.Quantity", "5");
|
||||
|
||||
public string DropsQuantity
|
||||
{
|
||||
get { return _dropsQuantity; }
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _dropsQuantity, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user