mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-15 17:30:27 +08:00
Merge pull request #745 from MaaAssistantArknights/perf/netcat
perf. 使用 nc 转发的方式,优化截图速度
This commit is contained in:
@@ -26,115 +26,131 @@
|
||||
"General": {
|
||||
"devices": "[Adb] devices",
|
||||
"addressRegex": "(.+)\tdevice",
|
||||
"connect": "[Adb] connect [Address]",
|
||||
"uuid": "[Adb] -s [Address] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [Address] shell input tap [x] [y]",
|
||||
"swipe": "[Adb] -s [Address] shell input swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [Address] shell dumpsys window displays | grep init=",
|
||||
"connect": "[Adb] connect [AdbSerial]",
|
||||
"uuid": "[Adb] -s [AdbSerial] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [AdbSerial] shell input tap [x] [y]",
|
||||
"swipe": "[Adb] -s [AdbSerial] shell input swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [AdbSerial] shell dumpsys window displays | grep init=",
|
||||
"displayFormat": " init=%dx%d",
|
||||
"screencapRawWithGzip": "[Adb] -s [Address] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [Address] exec-out screencap -p",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p",
|
||||
"release": "[Adb] kill-server",
|
||||
"start": "[Adb] -s [Address] shell am start -n [Intent]"
|
||||
"start": "[Adb] -s [AdbSerial] shell am start -n [Intent]"
|
||||
},
|
||||
"BlueStacks": {
|
||||
"devices": "[Adb] devices",
|
||||
"addressRegex": "(.+)\tdevice",
|
||||
"connect": "[Adb] connect [Address]",
|
||||
"uuid": "[Adb] -s [Address] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [Address] shell input tap [x] [y]",
|
||||
"swipe": "[Adb] -s [Address] shell input swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [Address] shell dumpsys window displays | grep init= | awk ' { print $3 } '",
|
||||
"connect": "[Adb] connect [AdbSerial]",
|
||||
"uuid": "[Adb] -s [AdbSerial] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [AdbSerial] shell input tap [x] [y]",
|
||||
"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",
|
||||
"screencapRawWithGzip": "[Adb] -s [Address] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [Address] exec-out screencap -p",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p",
|
||||
"release": "[Adb] kill-server",
|
||||
"start": "[Adb] -s [Address] shell am start -n [Intent]"
|
||||
"start": "[Adb] -s [AdbSerial] shell am start -n [Intent]"
|
||||
},
|
||||
"MuMuEmulator": {
|
||||
"devices": "[Adb] devices",
|
||||
"addressRegex": "(.+)\tdevice",
|
||||
"connect": "[Adb] connect [Address]",
|
||||
"uuid": "[Adb] -s [Address] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [Address] shell input tap [x] [y]",
|
||||
"swipe": "[Adb] -s [Address] shell input swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [Address] shell dumpsys window displays | grep init= | awk ' { print $3 } '",
|
||||
"connect": "[Adb] connect [AdbSerial]",
|
||||
"uuid": "[Adb] -s [AdbSerial] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [AdbSerial] shell input tap [x] [y]",
|
||||
"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",
|
||||
"screencapRawWithGzip": "[Adb] -s [Address] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [Address] exec-out screencap -p",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p",
|
||||
"release": "[Adb] kill-server",
|
||||
"start": "[Adb] -s [Address] shell am start -n [Intent]"
|
||||
"start": "[Adb] -s [AdbSerial] shell am start -n [Intent]"
|
||||
},
|
||||
"LDPlayer": {
|
||||
"devices": "[Adb] devices",
|
||||
"addressRegex": "(.+)\tdevice",
|
||||
"connect": "[Adb] connect [Address]",
|
||||
"uuid": "[Adb] -s [Address] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [Address] shell input tap [x] [y]",
|
||||
"swipe": "[Adb] -s [Address] shell input swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [Address] shell dumpsys window displays | grep init= | awk ' { print $3 } '",
|
||||
"connect": "[Adb] connect [AdbSerial]",
|
||||
"uuid": "[Adb] -s [AdbSerial] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [AdbSerial] shell input tap [x] [y]",
|
||||
"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",
|
||||
"screencapRawWithGzip": "[Adb] -s [Address] shell \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [Address] shell screencap -p",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] shell screencap -p",
|
||||
"release": "[Adb] kill-server",
|
||||
"start": "[Adb] -s [Address] shell am start -n [Intent]"
|
||||
"start": "[Adb] -s [AdbSerial] shell am start -n [Intent]"
|
||||
},
|
||||
"Nox": {
|
||||
"devices": "[Adb] devices",
|
||||
"addressRegex": "(.+)\tdevice",
|
||||
"connect": "[Adb] connect [Address]",
|
||||
"uuid": "[Adb] -s [Address] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [Address] shell input tap [x] [y]",
|
||||
"swipe": "[Adb] -s [Address] shell input swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [Address] shell dumpsys window displays | grep init= | awk ' { print $3 } '",
|
||||
"connect": "[Adb] connect [AdbSerial]",
|
||||
"uuid": "[Adb] -s [AdbSerial] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [AdbSerial] shell input tap [x] [y]",
|
||||
"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",
|
||||
"screencapRawWithGzip": "[Adb] -s [Address] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [Address] exec-out screencap -p",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p",
|
||||
"release": "[Adb] kill-server",
|
||||
"start": "[Adb] -s [Address] shell am start -n [Intent]"
|
||||
"start": "[Adb] -s [AdbSerial] shell am start -n [Intent]"
|
||||
},
|
||||
"XYAZ": {
|
||||
"devices": "[Adb] devices",
|
||||
"addressRegex": "(.+)\tdevice",
|
||||
"connect": "[Adb] connect [Address]",
|
||||
"uuid": "[Adb] -s [Address] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [Address] shell input tap [x] [y]",
|
||||
"swipe": "[Adb] -s [Address] shell input swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [Address] shell dumpsys window displays | grep init=",
|
||||
"connect": "[Adb] connect [AdbSerial]",
|
||||
"uuid": "[Adb] -s [AdbSerial] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [AdbSerial] shell input tap [x] [y]",
|
||||
"swipe": "[Adb] -s [AdbSerial] shell input swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [AdbSerial] shell dumpsys window displays | grep init=",
|
||||
"displayFormat": " init=%dx%d",
|
||||
"screencapRawWithGzip": "[Adb] -s [Address] shell \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [Address] shell screencap -p",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] shell screencap -p",
|
||||
"release": "[Adb] kill-server",
|
||||
"start": "[Adb] -s [Address] shell am start -n [Intent]"
|
||||
"start": "[Adb] -s [AdbSerial] shell am start -n [Intent]"
|
||||
},
|
||||
"WSA": {
|
||||
"devices": "[Adb] devices",
|
||||
"addressRegex": "(.+)\tdevice",
|
||||
"connect": "[Adb] connect [Address]",
|
||||
"displayId": "[Adb] -s [Address] shell dumpsys display | grep mUniqueId=virtual:com.microsoft.windows.systemapp:com.hypergryph.arknights",
|
||||
"uuid": "[Adb] -s [Address] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [Address] shell input -d [DisplayId] tap [x] [y]",
|
||||
"swipe": "[Adb] -s [Address] shell input -d [DisplayId] swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [Address] shell \"wm size -d [DisplayId]\"",
|
||||
"connect": "[Adb] connect [AdbSerial]",
|
||||
"displayId": "[Adb] -s [AdbSerial] shell dumpsys display | grep mUniqueId=virtual:com.microsoft.windows.systemapp:com.hypergryph.arknights",
|
||||
"uuid": "[Adb] -s [AdbSerial] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [AdbSerial] shell input -d [DisplayId] tap [x] [y]",
|
||||
"swipe": "[Adb] -s [AdbSerial] shell input -d [DisplayId] swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [AdbSerial] shell \"wm size -d [DisplayId]\"",
|
||||
"displayFormat": "Physical size:%dx%d",
|
||||
"screencapRawWithGzip": "[Adb] -s [Address] shell \"screencap -d [DisplayId] | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [Address] shell screencap -d [DisplayId] -p",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap -d [DisplayId] | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] shell screencap -d [DisplayId] -p",
|
||||
"release": "[Adb] kill-server",
|
||||
"start": "[Adb] -s [Address] shell am start -n [Intent]"
|
||||
"start": "[Adb] -s [AdbSerial] shell am start -n [Intent]"
|
||||
},
|
||||
"Compatible": {
|
||||
"devices": "[Adb] devices",
|
||||
"addressRegex": "(.+)\tdevice",
|
||||
"connect": "[Adb] connect [Address]",
|
||||
"uuid": "[Adb] -s [Address] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [Address] shell input tap [x] [y]",
|
||||
"swipe": "[Adb] -s [Address] shell input swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [Address] shell dumpsys window displays | grep init=",
|
||||
"connect": "[Adb] connect [AdbSerial]",
|
||||
"uuid": "[Adb] -s [AdbSerial] shell settings get secure android_id",
|
||||
"click": "[Adb] -s [AdbSerial] shell input tap [x] [y]",
|
||||
"swipe": "[Adb] -s [AdbSerial] shell input swipe [x1] [y1] [x2] [y2] [duration]",
|
||||
"display": "[Adb] -s [AdbSerial] shell dumpsys window displays | grep init=",
|
||||
"displayFormat": " init=%dx%d",
|
||||
"screencapRawWithGzip": "[Adb] -s [Address] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [Address] exec-out screencap -p",
|
||||
"screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"",
|
||||
"ncPort": 6723,
|
||||
"screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"",
|
||||
"screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p",
|
||||
"release": "[Adb] kill-server",
|
||||
"start": "[Adb] -s [Address] shell am start -n [Intent]"
|
||||
"start": "[Adb] -s [AdbSerial] shell am start -n [Intent]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4544,9 +4544,18 @@
|
||||
30
|
||||
]
|
||||
},
|
||||
"BattleWaitingToLoad": {
|
||||
"algorithm": "JustReturn",
|
||||
"rearDelay": 3000
|
||||
"BattleOfficiallyBegin": {
|
||||
"action": "DoNothing",
|
||||
"roi": [
|
||||
1165,
|
||||
20,
|
||||
65,
|
||||
65
|
||||
],
|
||||
"maskRange": [
|
||||
100,
|
||||
255
|
||||
]
|
||||
},
|
||||
"BattleSpeedUp": {
|
||||
"algorithm": "JustReturn",
|
||||
@@ -4590,17 +4599,22 @@
|
||||
600,
|
||||
60
|
||||
],
|
||||
"rectMove": [
|
||||
50,
|
||||
0,
|
||||
150,
|
||||
60
|
||||
],
|
||||
"maskRange": [
|
||||
1,
|
||||
255
|
||||
]
|
||||
},
|
||||
"BattleKills": {
|
||||
"algorithm": "OcrDetect",
|
||||
"text": [
|
||||
],
|
||||
"roi": [
|
||||
50,
|
||||
0,
|
||||
100,
|
||||
40
|
||||
]
|
||||
},
|
||||
"BattleCostData": {
|
||||
"algorithm": "OcrDetect",
|
||||
"text": [],
|
||||
@@ -4639,10 +4653,6 @@
|
||||
-110,
|
||||
90,
|
||||
90
|
||||
],
|
||||
"next": [
|
||||
"BattleSkillReadyOnClick",
|
||||
"Stop"
|
||||
]
|
||||
},
|
||||
"BattleSkillStopOnClick": {
|
||||
@@ -4659,23 +4669,19 @@
|
||||
-110,
|
||||
90,
|
||||
90
|
||||
],
|
||||
"next": [
|
||||
"BattleSkillStopOnClick",
|
||||
"Stop"
|
||||
]
|
||||
},
|
||||
"BattleUseOper": {
|
||||
"algorithm": "JustReturn",
|
||||
"preDelay": 500,
|
||||
"preDelay": 200,
|
||||
"rearDelay": 0,
|
||||
"Doc": "pre 是从点击干员,到干员信息弹出来等待的时间;rear 是干员上场,到设置朝向之间等待的时间"
|
||||
},
|
||||
"BattleSwipeOper": {
|
||||
"algorithm": "JustReturn",
|
||||
"preDelay": 1000,
|
||||
"rearDelay": 300,
|
||||
"Doc": "pre 是将干员滑动到场上的 duration;rear 是设置干员朝向滑动的 duration"
|
||||
"preDelay": 12000,
|
||||
"rearDelay": 100,
|
||||
"Doc": "pre 是将干员滑动到场上的 duration 系数;rear 是设置干员朝向滑动的 duration"
|
||||
},
|
||||
"BattleOpersFlag": {
|
||||
"templThreshold": 0.85,
|
||||
@@ -4984,25 +4990,9 @@
|
||||
40
|
||||
]
|
||||
},
|
||||
"BattleUseSkillBegin": {
|
||||
"algorithm": "JustReturn",
|
||||
"action": "DoNothing",
|
||||
"rearDelay": 1000,
|
||||
"next": [
|
||||
"BattleUseSkill"
|
||||
]
|
||||
},
|
||||
"BattleUseSkill": {
|
||||
"algorithm": "OcrDetect",
|
||||
"text": [
|
||||
"角色"
|
||||
],
|
||||
"roi": [
|
||||
900,
|
||||
500,
|
||||
380,
|
||||
150
|
||||
],
|
||||
"algorithm": "JustReturn",
|
||||
"rearDelay": 100,
|
||||
"action": "ClickRect",
|
||||
"specificRect": [
|
||||
820,
|
||||
@@ -5011,25 +5001,9 @@
|
||||
90
|
||||
]
|
||||
},
|
||||
"BattleOperRetreatBegin": {
|
||||
"algorithm": "JustReturn",
|
||||
"rearDelay": 500,
|
||||
"next": [
|
||||
"BattleOperRetreat"
|
||||
]
|
||||
},
|
||||
"BattleOperRetreat": {
|
||||
"algorithm": "OcrDetect",
|
||||
"text": [
|
||||
"角色"
|
||||
],
|
||||
"roi": [
|
||||
900,
|
||||
500,
|
||||
380,
|
||||
150
|
||||
],
|
||||
"rearDelay": 500,
|
||||
"algorithm": "JustReturn",
|
||||
"rearDelay": 100,
|
||||
"action": "ClickRect",
|
||||
"specificRect": [
|
||||
563,
|
||||
|
||||
BIN
resource/template/BattleOfficiallyBegin.png
Normal file
BIN
resource/template/BattleOfficiallyBegin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
@@ -4,8 +4,7 @@
|
||||
|
||||
#include "MultiMatchImageAnalyzer.h"
|
||||
#include "MatchImageAnalyzer.h"
|
||||
#include "OcrImageAnalyzer.h"
|
||||
#include "OcrWithPreprocessImageAnalyzer.h"
|
||||
#include "OcrWithFlagTemplImageAnalyzer.h"
|
||||
#include "HashImageAnalyzer.h"
|
||||
#include "Logger.hpp"
|
||||
#include "TaskData.h"
|
||||
@@ -430,20 +429,14 @@ bool asst::BattleImageAnalyzer::hp_analyze()
|
||||
|
||||
bool asst::BattleImageAnalyzer::kills_analyze()
|
||||
{
|
||||
const auto task_ptr = Task.get("BattleKillsFlag");
|
||||
MatchImageAnalyzer flag_analzyer(m_image);
|
||||
flag_analzyer.set_task_info(task_ptr);
|
||||
if (!flag_analzyer.analyze()) {
|
||||
return false;
|
||||
}
|
||||
OcrWithFlagTemplImageAnalyzer kills_analyzer(m_image);
|
||||
kills_analyzer.set_task_info("BattleKillsFlag", "BattleKills");
|
||||
kills_analyzer.set_replace(
|
||||
std::dynamic_pointer_cast<OcrTaskInfo>(Task.get("NumberOcrReplace"))->replace_map);
|
||||
|
||||
auto kills_roi = flag_analzyer.get_result().rect.move(task_ptr->rect_move);
|
||||
OcrImageAnalyzer kills_analyzer(m_image);
|
||||
kills_analyzer.set_roi(kills_roi);
|
||||
if (!kills_analyzer.analyze()) {
|
||||
return false;
|
||||
}
|
||||
kills_analyzer.sort_result_by_score();
|
||||
|
||||
std::string kills_text;
|
||||
size_t pos = std::string::npos;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
|
||||
#include "Controller.h"
|
||||
#include "Resource.h"
|
||||
@@ -53,6 +54,8 @@ bool asst::BattleProcessTask::_run()
|
||||
|
||||
bool asst::BattleProcessTask::get_stage_info()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
const auto& tile = Resrc.tile();
|
||||
|
||||
m_normal_tile_info = tile.calc(m_stage_name, false);
|
||||
@@ -84,49 +87,64 @@ bool asst::BattleProcessTask::analyze_opers_preview()
|
||||
callback(AsstMsg::SubTaskExtraInfo, info);
|
||||
}
|
||||
|
||||
MatchImageAnalyzer officially_begin_analyzer;
|
||||
officially_begin_analyzer.set_task_info("BattleOfficiallyBegin");
|
||||
cv::Mat image;
|
||||
while (!need_exit()) {
|
||||
image = m_ctrler->get_image();
|
||||
officially_begin_analyzer.set_image(image);
|
||||
if (officially_begin_analyzer.analyze()) {
|
||||
break;
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
BattleImageAnalyzer oper_analyzer;
|
||||
oper_analyzer.set_target(BattleImageAnalyzer::Target::Oper);
|
||||
|
||||
while (true) {
|
||||
oper_analyzer.set_image(m_ctrler->get_image());
|
||||
while (!need_exit()) {
|
||||
image = m_ctrler->get_image();
|
||||
oper_analyzer.set_image(image);
|
||||
if (oper_analyzer.analyze()) {
|
||||
break;
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
// 干员头像出来之后,还要过 2 秒左右才可以点击,这里要加个延时
|
||||
sleep(Task.get("BattleWaitingToLoad")->rear_delay);
|
||||
while (true) {
|
||||
oper_analyzer.set_image(m_ctrler->get_image());
|
||||
if (oper_analyzer.analyze()) {
|
||||
// 暂停游戏准备识别干员
|
||||
// 在刚进入游戏的时候(画面刚刚完全亮起来的时候),点暂停是没反应的
|
||||
// 所以这里一直点,直到真的点上了为止
|
||||
while (!need_exit()) {
|
||||
battle_pause();
|
||||
image = m_ctrler->get_image();
|
||||
officially_begin_analyzer.set_image(image);
|
||||
if (!officially_begin_analyzer.analyze()) {
|
||||
break;
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
{
|
||||
//#ifdef ASST_DEBUG
|
||||
auto draw = m_ctrler->get_image();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
cv::imwrite("map.png", draw);
|
||||
//#endif
|
||||
}
|
||||
battle_pause();
|
||||
});
|
||||
|
||||
auto opers = oper_analyzer.get_opers();
|
||||
|
||||
Rect cur_rect;
|
||||
int click_delay = Task.get("BattleUseOper")->pre_delay;
|
||||
for (size_t i = 0; i != opers.size(); ++i) {
|
||||
const auto& cur_oper = oper_analyzer.get_opers();
|
||||
size_t offset = opers.size() > cur_oper.size() ? opers.size() - cur_oper.size() : 0;
|
||||
m_ctrler->click(cur_oper.at(i - offset).rect);
|
||||
cur_rect = cur_oper.at(i - offset).rect;
|
||||
m_ctrler->click(cur_rect);
|
||||
sleep(click_delay);
|
||||
|
||||
sleep(Task.get("BattleUseOper")->pre_delay);
|
||||
|
||||
auto image = m_ctrler->get_image();
|
||||
image = m_ctrler->get_image();
|
||||
|
||||
OcrWithPreprocessImageAnalyzer name_analyzer(image);
|
||||
name_analyzer.set_task_info("BattleOperName");
|
||||
@@ -166,8 +184,12 @@ bool asst::BattleProcessTask::analyze_opers_preview()
|
||||
oper_analyzer.set_image(image);
|
||||
oper_analyzer.analyze();
|
||||
}
|
||||
|
||||
draw_future.wait();
|
||||
|
||||
m_ctrler->click(cur_rect);
|
||||
sleep(click_delay);
|
||||
battle_pause();
|
||||
cancel_selection();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -251,8 +273,9 @@ bool asst::BattleProcessTask::update_opers_info(const cv::Mat& image)
|
||||
oper_name = name_analyzer.get_result().front().text;
|
||||
}
|
||||
m_group_to_oper_mapping[oper_name] = BattleDeployOper{ oper_name };
|
||||
m_ctrler->click(cur_oper.rect);
|
||||
sleep(Task.get("BattleUseOper")->pre_delay);
|
||||
battle_pause();
|
||||
cancel_selection();
|
||||
}
|
||||
else {
|
||||
oper_name = matched_iter->first;
|
||||
@@ -362,7 +385,9 @@ bool asst::BattleProcessTask::wait_condition(const BattleAction& action)
|
||||
if (need_exit()) {
|
||||
return false;
|
||||
}
|
||||
image = m_ctrler->get_image();
|
||||
if (image.empty()) {
|
||||
image = m_ctrler->get_image();
|
||||
}
|
||||
BattleImageAnalyzer analyzer(image);
|
||||
analyzer.set_target(BattleImageAnalyzer::Target::Kills);
|
||||
if (analyzer.analyze()) {
|
||||
@@ -374,6 +399,7 @@ bool asst::BattleProcessTask::wait_condition(const BattleAction& action)
|
||||
|
||||
try_possible_skill(image);
|
||||
std::this_thread::yield();
|
||||
image = m_ctrler->get_image();
|
||||
}
|
||||
|
||||
// 部署干员还有额外等待费用够或 CD 转好
|
||||
@@ -383,7 +409,9 @@ bool asst::BattleProcessTask::wait_condition(const BattleAction& action)
|
||||
if (need_exit()) {
|
||||
return false;
|
||||
}
|
||||
image = m_ctrler->get_image();
|
||||
if (image.empty()) {
|
||||
image = m_ctrler->get_image();
|
||||
}
|
||||
update_opers_info(image);
|
||||
|
||||
if (auto iter = m_cur_opers_info.find(name);
|
||||
@@ -393,6 +421,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()) {
|
||||
@@ -421,7 +450,12 @@ bool asst::BattleProcessTask::oper_deploy(const BattleAction& action)
|
||||
Point placed_point = m_side_tile_info[action.location].pos;
|
||||
|
||||
Rect placed_rect{ placed_point.x ,placed_point.y, 1, 1 };
|
||||
m_ctrler->swipe(oper_rect, placed_rect, swipe_oper_task_ptr->pre_delay);
|
||||
int dist = static_cast<int>(
|
||||
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 / 1000.0 * dist); // 随便取的一个系数
|
||||
m_ctrler->swipe(oper_rect, placed_rect, duration, true, 0);
|
||||
|
||||
sleep(use_oper_task_ptr->rear_delay);
|
||||
|
||||
@@ -449,7 +483,7 @@ bool asst::BattleProcessTask::oper_deploy(const BattleAction& action)
|
||||
end_point.y = std::max(0, end_point.y);
|
||||
end_point.y = std::min(end_point.y, WindowHeightDefault);
|
||||
|
||||
m_ctrler->swipe(placed_point, end_point, swipe_oper_task_ptr->rear_delay);
|
||||
m_ctrler->swipe(placed_point, end_point, swipe_oper_task_ptr->rear_delay, true, 100);
|
||||
}
|
||||
|
||||
m_used_opers[iter->first] = BattleDeployInfo{
|
||||
@@ -559,8 +593,3 @@ bool asst::BattleProcessTask::battle_speedup()
|
||||
{
|
||||
return ProcessTask(*this, { "BattleSpeedUp" }).run();
|
||||
}
|
||||
|
||||
bool asst::BattleProcessTask::cancel_selection()
|
||||
{
|
||||
return ProcessTask(*this, { "BattleCancelSelection" }).run();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ namespace asst
|
||||
virtual bool get_stage_info();
|
||||
bool battle_pause();
|
||||
bool battle_speedup();
|
||||
bool cancel_selection(); // 取消选择干员
|
||||
bool analyze_opers_preview();
|
||||
bool update_opers_info(const cv::Mat& image);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <regex>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
@@ -26,6 +27,33 @@
|
||||
#include "Logger.hpp"
|
||||
#include "Resource.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
// for Windows socket
|
||||
class WsaHelper
|
||||
{
|
||||
public:
|
||||
~WsaHelper()
|
||||
{
|
||||
WSACleanup();
|
||||
}
|
||||
static WsaHelper& get_instance()
|
||||
{
|
||||
static WsaHelper instance;
|
||||
return instance;
|
||||
}
|
||||
bool operator()() const noexcept { return m_supports; }
|
||||
private:
|
||||
WsaHelper()
|
||||
{
|
||||
m_supports =
|
||||
WSAStartup(MAKEWORD(2, 2), &m_wsa_data) == 0 &&
|
||||
m_wsa_data.wVersion == MAKEWORD(2, 2);
|
||||
}
|
||||
WSADATA m_wsa_data = { 0 };
|
||||
bool m_supports = false;
|
||||
};
|
||||
#endif
|
||||
|
||||
asst::Controller::Controller(AsstCallback callback, void* callback_arg)
|
||||
: m_callback(callback),
|
||||
m_callback_arg(callback_arg),
|
||||
@@ -55,6 +83,16 @@ asst::Controller::Controller(AsstCallback callback, void* callback_arg)
|
||||
m_child_startup_info.hStdInput = m_pipe_child_read;
|
||||
m_child_startup_info.hStdOutput = m_pipe_child_write;
|
||||
m_child_startup_info.hStdError = m_pipe_child_write;
|
||||
|
||||
m_support_socket = false;
|
||||
do {
|
||||
if (!WsaHelper::get_instance()()) {
|
||||
Log.error("WSA not supports");
|
||||
break;
|
||||
}
|
||||
m_support_socket = true;
|
||||
} while (0);
|
||||
|
||||
#else
|
||||
int pipe_in_ret = pipe(m_pipe_in);
|
||||
int pipe_out_ret = pipe(m_pipe_out);
|
||||
@@ -64,11 +102,19 @@ asst::Controller::Controller(AsstCallback callback, void* callback_arg)
|
||||
throw "controller pipe created failed";
|
||||
}
|
||||
|
||||
// todo
|
||||
m_support_netcat = false;
|
||||
#endif
|
||||
m_pipe_buffer = std::make_unique<uchar[]>(PipeBuffSize);
|
||||
if (!m_pipe_buffer) {
|
||||
throw "controller pipe buffer allocated failed";
|
||||
}
|
||||
if (m_support_socket) {
|
||||
m_socket_buffer = std::make_unique<char[]>(SocketBuffSize);
|
||||
if (!m_socket_buffer) {
|
||||
throw "controller socket buffer allocated failed";
|
||||
}
|
||||
}
|
||||
|
||||
m_cmd_thread = std::thread(&Controller::pipe_working_proc, this);
|
||||
}
|
||||
@@ -86,13 +132,16 @@ asst::Controller::~Controller()
|
||||
m_cmd_thread.join();
|
||||
}
|
||||
|
||||
disconnect();
|
||||
if (--m_instance_count) {
|
||||
release();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
::CloseHandle(m_pipe_read);
|
||||
::CloseHandle(m_pipe_write);
|
||||
::CloseHandle(m_pipe_child_read);
|
||||
::CloseHandle(m_pipe_child_write);
|
||||
|
||||
#else
|
||||
close(m_pipe_in[PIPE_READ]);
|
||||
close(m_pipe_in[PIPE_WRITE]);
|
||||
@@ -193,14 +242,13 @@ void asst::Controller::pipe_working_proc()
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::vector<unsigned char>> asst::Controller::call_command(const std::string& cmd, int64_t timeout)
|
||||
std::optional<std::vector<unsigned char>> asst::Controller::call_command(const std::string& cmd, int64_t timeout, bool recv_by_socket)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
std::vector<uchar> pipe_data;
|
||||
|
||||
static std::mutex pipe_mutex;
|
||||
std::unique_lock<std::mutex> pipe_lock(pipe_mutex);
|
||||
std::unique_lock<std::mutex> pipe_lock(m_pipe_mutex);
|
||||
|
||||
auto start_time = std::chrono::steady_clock::now();
|
||||
auto check_timeout = [&]() -> bool {
|
||||
@@ -214,21 +262,39 @@ std::optional<std::vector<unsigned char>> asst::Controller::call_command(const s
|
||||
PROCESS_INFORMATION process_info = { 0 }; // 进程信息结构体
|
||||
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);
|
||||
return std::nullopt;
|
||||
}
|
||||
DWORD peek_num = 0;
|
||||
DWORD read_num = 0;
|
||||
do {
|
||||
//DWORD write_num = 0;
|
||||
//WriteFile(parent_write, cmd.c_str(), cmd.size(), &write_num, nullptr);
|
||||
while (::PeekNamedPipe(m_pipe_read, nullptr, 0, nullptr, &peek_num, nullptr) && peek_num > 0) {
|
||||
if (::ReadFile(m_pipe_read, m_pipe_buffer.get(), PipeBuffSize, &read_num, nullptr)) {
|
||||
pipe_data.insert(pipe_data.end(), m_pipe_buffer.get(), m_pipe_buffer.get() + read_num);
|
||||
if (!recv_by_socket) {
|
||||
DWORD peek_num = 0;
|
||||
DWORD read_num = 0;
|
||||
do {
|
||||
//DWORD write_num = 0;
|
||||
//WriteFile(parent_write, cmd.c_str(), cmd.size(), &write_num, nullptr);
|
||||
while (::PeekNamedPipe(m_pipe_read, nullptr, 0, nullptr, &peek_num, nullptr) && peek_num > 0) {
|
||||
if (::ReadFile(m_pipe_read, m_pipe_buffer.get(), PipeBuffSize, &read_num, nullptr)) {
|
||||
pipe_data.insert(pipe_data.end(), m_pipe_buffer.get(), m_pipe_buffer.get() + read_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (::WaitForSingleObject(process_info.hProcess, 0) == WAIT_TIMEOUT && !check_timeout());
|
||||
|
||||
DWORD exit_ret = 255;
|
||||
} 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));
|
||||
}
|
||||
DWORD exit_ret = 0;
|
||||
::GetExitCodeProcess(process_info.hProcess, &exit_ret);
|
||||
::CloseHandle(process_info.hProcess);
|
||||
::CloseHandle(process_info.hThread);
|
||||
@@ -369,6 +435,12 @@ void asst::Controller::clear_info() noexcept
|
||||
m_height = 0;
|
||||
m_control_scale = 1.0;
|
||||
m_scale_size = { WindowWidthDefault, WindowHeightDefault };
|
||||
m_server_started = false;
|
||||
if (m_support_socket && m_server_started && m_server_sock) {
|
||||
::closesocket(m_server_sock);
|
||||
m_server_sock = 0U;
|
||||
}
|
||||
--m_instance_count;
|
||||
}
|
||||
|
||||
int asst::Controller::push_cmd(const std::string& cmd)
|
||||
@@ -381,6 +453,54 @@ int asst::Controller::push_cmd(const std::string& cmd)
|
||||
return ++m_push_id;
|
||||
}
|
||||
|
||||
std::optional<asst::Controller::SocketInfo> asst::Controller::try_init_socket(const std::string& local_address, unsigned short try_port, unsigned short try_times)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
#ifdef _WIN32
|
||||
m_server_sock = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (m_server_sock == INVALID_SOCKET) {
|
||||
return std::nullopt;
|
||||
}
|
||||
m_server_addr.sin_family = PF_INET;
|
||||
m_server_addr.sin_addr.s_addr = inet_addr(local_address.c_str());
|
||||
#else
|
||||
// Linux, todo
|
||||
#endif
|
||||
|
||||
bool server_start = false;
|
||||
u_short port_result = 0;
|
||||
|
||||
u_short max_port = try_port + try_times;
|
||||
for (u_short port = try_port; port < max_port; ++port) {
|
||||
Log.trace("try bind port", port);
|
||||
|
||||
#ifdef _WIN32
|
||||
m_server_addr.sin_port = htons(port);
|
||||
int bind_ret = ::bind(m_server_sock, (SOCKADDR*)&m_server_addr, sizeof(SOCKADDR));
|
||||
int listen_ret = ::listen(m_server_sock, 3);
|
||||
server_start = bind_ret == 0 && listen_ret == 0;
|
||||
#else
|
||||
// todo
|
||||
#endif
|
||||
if (server_start) {
|
||||
port_result = port;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!server_start) {
|
||||
Log.info("not supports netcat");
|
||||
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 };
|
||||
}
|
||||
|
||||
void asst::Controller::wait(unsigned id) const noexcept
|
||||
{
|
||||
while (id > m_completed_id) {
|
||||
@@ -399,7 +519,35 @@ bool asst::Controller::screencap()
|
||||
// return true;
|
||||
//}
|
||||
|
||||
DecodeFunc decode_raw_with_gzip = [&](const std::vector<uchar>& data) -> bool {
|
||||
DecodeFunc decode_raw = [&](std::vector<uchar>& data) -> bool {
|
||||
if (data.empty()) {
|
||||
return false;
|
||||
}
|
||||
size_t std_size = m_width * m_height * 4;
|
||||
if (data.size() < std_size) {
|
||||
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;
|
||||
});
|
||||
if (is_all_zero) {
|
||||
return false;
|
||||
}
|
||||
cv::Mat temp(m_height, m_width, CV_8UC4, data.data() + header_size);
|
||||
if (temp.empty()) {
|
||||
return false;
|
||||
}
|
||||
cv::cvtColor(temp, temp, cv::COLOR_RGB2BGR);
|
||||
std::unique_lock<std::shared_mutex> image_lock(m_image_mutex);
|
||||
m_cache_image = temp;
|
||||
return true;
|
||||
};
|
||||
|
||||
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()) {
|
||||
@@ -429,7 +577,7 @@ bool asst::Controller::screencap()
|
||||
return true;
|
||||
};
|
||||
|
||||
DecodeFunc decode_encode = [&](const std::vector<uchar>& data) -> bool {
|
||||
DecodeFunc decode_encode = [&](std::vector<uchar>& data) -> bool {
|
||||
cv::Mat temp = cv::imdecode(data, cv::IMREAD_COLOR);
|
||||
if (temp.empty()) {
|
||||
return false;
|
||||
@@ -442,18 +590,31 @@ bool asst::Controller::screencap()
|
||||
switch (m_adb.screencap_method) {
|
||||
case AdbProperty::ScreencapMethod::UnknownYet:
|
||||
{
|
||||
if (screencap(m_adb.screencap_raw_with_gzip, decode_raw_with_gzip)) {
|
||||
if (m_support_socket && m_server_started &&
|
||||
screencap(m_adb.screencap_raw_by_nc, decode_raw, true)) {
|
||||
m_adb.screencap_method = AdbProperty::ScreencapMethod::RawByNc;
|
||||
Log.info("screencap by RawByNc");
|
||||
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");
|
||||
return true;
|
||||
}
|
||||
else if (screencap(m_adb.screencap_encode, decode_encode)) {
|
||||
m_adb.screencap_method = AdbProperty::ScreencapMethod::Encode;
|
||||
Log.info("screencap by Encode");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case AdbProperty::ScreencapMethod::RawByNc:
|
||||
{
|
||||
return screencap(m_adb.screencap_raw_by_nc, decode_raw, true);
|
||||
}
|
||||
break;
|
||||
case AdbProperty::ScreencapMethod::RawWithGzip:
|
||||
{
|
||||
return screencap(m_adb.screencap_raw_with_gzip, decode_raw_with_gzip);
|
||||
@@ -469,9 +630,13 @@ bool asst::Controller::screencap()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool asst::Controller::screencap(const std::string& cmd, DecodeFunc decode_func)
|
||||
bool asst::Controller::screencap(const std::string& cmd, DecodeFunc decode_func, bool by_socket)
|
||||
{
|
||||
auto ret = call_command(cmd);
|
||||
if ((!m_support_socket || !m_server_started) && by_socket) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ret = call_command(cmd, 20000, by_socket);
|
||||
|
||||
if (!ret || ret.value().empty()) {
|
||||
Log.error("data is empty!");
|
||||
@@ -485,6 +650,7 @@ bool asst::Controller::screencap(const std::string& cmd, DecodeFunc decode_func)
|
||||
|
||||
if (decode_func(data)) {
|
||||
if (m_adb.screencap_end_of_line == AdbProperty::ScreencapEndOfLine::UnknownYet) {
|
||||
Log.info("screencap_end_of_line is LF");
|
||||
m_adb.screencap_end_of_line = AdbProperty::ScreencapEndOfLine::LF;
|
||||
}
|
||||
return true;
|
||||
@@ -498,6 +664,7 @@ bool asst::Controller::screencap(const std::string& cmd, DecodeFunc decode_func)
|
||||
|
||||
if (decode_func(data)) {
|
||||
m_adb.screencap_end_of_line = AdbProperty::ScreencapEndOfLine::CRLF;
|
||||
Log.info("screencap_end_of_line is CRLF");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -680,12 +847,16 @@ 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;
|
||||
u_short nc_port = 0;
|
||||
|
||||
auto cmd_replace = [&](const std::string& cfg_cmd) -> std::string {
|
||||
const std::unordered_map<std::string, std::string> replacements = {
|
||||
{ "[Adb]", adb_path },
|
||||
{ "[Address]", address },
|
||||
{ "[DisplayId]", display_id }
|
||||
{ "[AdbSerial]", address },
|
||||
{ "[DisplayId]", display_id },
|
||||
{ "[NcPort]", std::to_string(nc_port) },
|
||||
{ "[NcAddress]", nc_address },
|
||||
};
|
||||
std::string formatted = cfg_cmd;
|
||||
for (const auto& [key, value] : replacements) {
|
||||
@@ -845,11 +1016,43 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a
|
||||
m_adb.release = cmd_replace(adb_cfg.release);
|
||||
m_adb.start = cmd_replace(adb_cfg.start);
|
||||
|
||||
if (m_support_socket && !m_server_started) {
|
||||
std::string bind_address;
|
||||
if (size_t pos = address.rfind(':');
|
||||
pos != std::string::npos) {
|
||||
bind_address = address.substr(0, pos);
|
||||
}
|
||||
else {
|
||||
bind_address = "127.0.0.1";
|
||||
}
|
||||
|
||||
auto socket_opt = try_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;
|
||||
m_adb.screencap_raw_by_nc = cmd_replace(adb_cfg.screencap_raw_by_nc);
|
||||
m_server_started = true;
|
||||
}
|
||||
else {
|
||||
m_server_started = false;
|
||||
}
|
||||
}
|
||||
|
||||
++m_instance_count;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asst::Controller::disconnect()
|
||||
bool asst::Controller::release()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (m_server_sock) {
|
||||
m_server_started = false;
|
||||
::closesocket(m_server_sock);
|
||||
m_server_sock = 0U;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
if (m_child)
|
||||
#else
|
||||
@@ -858,7 +1061,7 @@ bool asst::Controller::disconnect()
|
||||
{
|
||||
return call_command(m_adb.release).has_value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& asst::Controller::get_uuid() const
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace asst
|
||||
~Controller();
|
||||
|
||||
bool connect(const std::string& adb_path, const std::string& address, const std::string& config);
|
||||
bool disconnect();
|
||||
bool release();
|
||||
|
||||
const std::string& get_uuid() const;
|
||||
cv::Mat get_image(bool raw = false);
|
||||
@@ -62,12 +62,19 @@ namespace asst
|
||||
|
||||
private:
|
||||
void pipe_working_proc();
|
||||
std::optional<std::vector<unsigned char>> call_command(const std::string& cmd, int64_t timeout = 20000);
|
||||
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);
|
||||
|
||||
using DecodeFunc = std::function<bool(const std::vector<uchar>&)>;
|
||||
struct SocketInfo
|
||||
{
|
||||
std::string remote_address;
|
||||
unsigned short remote_port = 0U;
|
||||
};
|
||||
std::optional<SocketInfo> try_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 screencap(const std::string& cmd, DecodeFunc decode_func, bool by_nc = false);
|
||||
cv::Mat get_resized_image() const;
|
||||
|
||||
Point rand_point_in_rect(const Rect& rect);
|
||||
@@ -84,7 +91,11 @@ namespace asst
|
||||
std::minstd_rand m_rand_engine;
|
||||
|
||||
constexpr static int PipeBuffSize = 4 * 1024 * 1024; // 管道缓冲区大小
|
||||
constexpr static int SocketBuffSize = 4 * 1024 * 1024; // socket 缓冲区大小
|
||||
std::unique_ptr<uchar[]> m_pipe_buffer = nullptr;
|
||||
std::mutex m_pipe_mutex;
|
||||
std::unique_ptr<char[]> m_socket_buffer = nullptr;
|
||||
std::mutex m_socket_mutex;
|
||||
#ifdef _WIN32
|
||||
HANDLE m_pipe_read = nullptr; // 读管道句柄
|
||||
HANDLE m_pipe_write = nullptr; // 写管道句柄
|
||||
@@ -92,6 +103,10 @@ namespace asst
|
||||
HANDLE m_pipe_child_write = nullptr; // 子进程的写管道句柄
|
||||
SECURITY_ATTRIBUTES m_pipe_sec_attr = { 0 }; // 管道安全描述符
|
||||
STARTUPINFOA m_child_startup_info = { 0 }; // 子进程启动信息
|
||||
|
||||
WSADATA m_wsa_data = { 0 };
|
||||
SOCKET m_server_sock = 0ULL;
|
||||
sockaddr_in m_server_addr = { 0 };
|
||||
#else
|
||||
constexpr static int PIPE_READ = 0;
|
||||
constexpr static int PIPE_WRITE = 1;
|
||||
@@ -106,6 +121,7 @@ namespace asst
|
||||
std::string click;
|
||||
std::string swipe;
|
||||
|
||||
std::string screencap_raw_by_nc;
|
||||
std::string screencap_raw_with_gzip;
|
||||
std::string screencap_encode;
|
||||
std::string release;
|
||||
@@ -125,6 +141,7 @@ namespace asst
|
||||
{
|
||||
UnknownYet,
|
||||
Default,
|
||||
RawByNc,
|
||||
RawWithGzip,
|
||||
Encode
|
||||
} screencap_method = ScreencapMethod::UnknownYet;
|
||||
@@ -135,6 +152,10 @@ namespace asst
|
||||
double m_control_scale = 1.0;
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
bool m_support_socket = false;
|
||||
bool m_server_started = false;
|
||||
|
||||
inline static int m_instance_count = 0;
|
||||
|
||||
mutable std::shared_mutex m_image_mutex;
|
||||
cv::Mat m_cache_image;
|
||||
|
||||
@@ -49,6 +49,8 @@ bool asst::GeneralConfiger::parse(const json::value& json)
|
||||
adb.display = cfg_json.at("display").as_string();
|
||||
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_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();
|
||||
adb.start = cfg_json.at("start").as_string();
|
||||
|
||||
@@ -51,6 +51,8 @@ namespace asst
|
||||
std::string swipe;
|
||||
std::string display;
|
||||
std::string screencap_raw_with_gzip;
|
||||
std::string screencap_raw_by_nc;
|
||||
unsigned short nc_port = 0U;
|
||||
std::string screencap_encode;
|
||||
std::string release;
|
||||
std::string start;
|
||||
|
||||
@@ -247,7 +247,7 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ppocr.lib;opencv_world453.lib;zlibstatic.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ppocr.lib;opencv_world453.lib;zlibstatic.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
@@ -299,7 +299,7 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ppocr.lib;opencv_world453.lib;zlibstatic.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ppocr.lib;opencv_world453.lib;zlibstatic.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
|
||||
Reference in New Issue
Block a user