From 1af0a01ced2b2647023d2d241f91bb4c56f73837 Mon Sep 17 00:00:00 2001 From: MistEO Date: Sat, 4 Jun 2022 04:35:07 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat.=E4=B8=8D=E7=94=A8=E7=94=A8=E9=9B=B7?= =?UTF-8?q?=E7=94=B5=EF=BC=8C=E4=BC=9A=E5=8F=98=E5=BE=97=E4=B8=8D=E5=B9=B8?= =?UTF-8?q?.jpg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MeoAsstGui/Helper/AsstProxy.cs | 6 ++++++ src/MeoAsstGui/ViewModels/CopilotViewModel.cs | 5 +++++ src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs | 7 ++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/MeoAsstGui/Helper/AsstProxy.cs b/src/MeoAsstGui/Helper/AsstProxy.cs index d8ab552425..57eb353e3c 100644 --- a/src/MeoAsstGui/Helper/AsstProxy.cs +++ b/src/MeoAsstGui/Helper/AsstProxy.cs @@ -607,6 +607,7 @@ namespace MeoAsstGui public bool AsstConnect(ref string error) { + error = ""; var settings = _container.Get(); if (settings.AdbPath == String.Empty || settings.ConnectAddress == String.Empty) @@ -618,6 +619,11 @@ namespace MeoAsstGui } settings.TryToSetBlueStacksHyperVAddress(); + if (settings.ConnectConfig == "LDPlayer") + { + error = "检测到您正在使用雷电模拟器\n由于雷电模拟器过于离谱\nMAA 不推荐使用\n若您遇到任何问题\n建议更换模拟器并再次尝试"; + } + bool ret = AsstConnect(_handle, settings.AdbPath, settings.ConnectAddress, settings.ConnectConfig); // 尝试默认的备选端口 diff --git a/src/MeoAsstGui/ViewModels/CopilotViewModel.cs b/src/MeoAsstGui/ViewModels/CopilotViewModel.cs index cdc6b1cea5..4225747162 100644 --- a/src/MeoAsstGui/ViewModels/CopilotViewModel.cs +++ b/src/MeoAsstGui/ViewModels/CopilotViewModel.cs @@ -209,6 +209,11 @@ namespace MeoAsstGui AddLog(errMsg, "darkred"); return; } + if (errMsg.Length != 0) + { + AddLog(errMsg, "darkred"); + } + if (Filename.Length == 0 || !File.Exists(Filename)) { AddLog("作业文件不存在", "darkred"); diff --git a/src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs b/src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs index 9e56fe558b..3c3785dcf0 100644 --- a/src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs +++ b/src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs @@ -44,6 +44,7 @@ namespace MeoAsstGui } private Visibility _visible = Visibility.Collapsed; + public Visibility Visible { get { return _visible; } @@ -127,7 +128,7 @@ namespace MeoAsstGui new CombData { Display = "SV-7", Value = "SV-7" }, new CombData { Display = "SV-8", Value = "SV-8" }, new CombData { Display = "SV-9", Value = "SV-9" }, - + // “愚人号” 活动关卡 //new CombData { Display = "SN-8", Value = "SN-8" }, //new CombData { Display = "SN-9", Value = "SN-9" }, @@ -228,6 +229,10 @@ namespace MeoAsstGui Idle = true; return; } + if (errMsg.Length != 0) + { + AddLog(errMsg, "darkred"); + } bool ret = true; // 直接遍历TaskItemViewModels里面的内容,是排序后的 From d94f0a9f61935d4833f090730b378c61a0f1444a Mon Sep 17 00:00:00 2001 From: MistEO Date: Sat, 4 Jun 2022 08:48:11 +0800 Subject: [PATCH 2/6] =?UTF-8?q?feat.=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90so?= =?UTF-8?q?cket=E9=80=9A=E8=AE=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/config.json | 138 ++++++++++-------- src/MeoAssistant/Controller.cpp | 199 ++++++++++++++++++++++++-- src/MeoAssistant/Controller.h | 18 ++- src/MeoAssistant/GeneralConfiger.cpp | 3 + src/MeoAssistant/GeneralConfiger.h | 3 + src/MeoAssistant/MeoAssistant.vcxproj | 4 +- 6 files changed, 294 insertions(+), 71 deletions(-) diff --git a/resource/config.json b/resource/config.json index 366d834b1d..deae952fed 100644 --- a/resource/config.json +++ b/resource/config.json @@ -22,106 +22,130 @@ "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", + "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", + "ncPort": 6054, + "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", + "screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"", + "screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p", "release": "[Adb] kill-server" }, "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", + "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", + "ncPort": 6054, + "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", + "screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"", + "screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p", "release": "[Adb] kill-server" }, "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", + "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", + "ncPort": 6054, + "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", + "screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"", + "screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p", "release": "[Adb] kill-server" }, "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", + "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", + "ncPort": 6054, + "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", + "screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap | gzip -1\"", + "screencapEncode": "[Adb] -s [AdbSerial] shell screencap -p", "release": "[Adb] kill-server" }, "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", + "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", + "ncPort": 6054, + "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", + "screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"", + "screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p", "release": "[Adb] kill-server" }, "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", + "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", + "ncPort": 6054, + "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", + "screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap | gzip -1\"", + "screencapEncode": "[Adb] -s [AdbSerial] shell screencap -p", "release": "[Adb] kill-server" }, "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", + "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", + "ncPort": 6054, + "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", + "screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap -d [DisplayId] | gzip -1\"", + "screencapEncode": "[Adb] -s [AdbSerial] shell screencap -d [DisplayId] -p", "release": "[Adb] kill-server" }, "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", + "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", + "ncPort": 6054, + "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", + "screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"", + "screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p", "release": "[Adb] kill-server" } } diff --git a/src/MeoAssistant/Controller.cpp b/src/MeoAssistant/Controller.cpp index 9ab6a6249f..57c1569f9b 100644 --- a/src/MeoAssistant/Controller.cpp +++ b/src/MeoAssistant/Controller.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -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,20 @@ 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_netcat = false; + do { + if (!WsaHelper::get_instance()()) { + Log.error("WSA not supports"); + break; + } + m_server_sock = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + if (m_server_sock == INVALID_SOCKET) { + break; + } + m_support_netcat = true; + } while (0); + #else int pipe_in_ret = pipe(m_pipe_in); int pipe_out_ret = pipe(m_pipe_out); @@ -64,11 +106,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(PipeBuffSize); if (!m_pipe_buffer) { throw "controller pipe buffer allocated failed"; } + if (m_support_netcat) { + m_socket_buffer = std::make_unique(SocketBuffSize); + if (!m_socket_buffer) { + throw "controller socket buffer allocated failed"; + } + } m_cmd_thread = std::thread(&Controller::pipe_working_proc, this); } @@ -86,20 +136,27 @@ 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); + + if (m_server_sock) { + ::closesocket(m_server_sock); + m_server_sock = 0U; + } #else close(m_pipe_in[PIPE_READ]); close(m_pipe_in[PIPE_WRITE]); close(m_pipe_out[PIPE_READ]); close(m_pipe_out[PIPE_WRITE]); #endif -} + } //asst::Rect asst::Controller::shaped_correct(const Rect & rect) const //{ @@ -199,8 +256,7 @@ std::optional> asst::Controller::call_command(const s std::vector pipe_data; - static std::mutex pipe_mutex; - std::unique_lock pipe_lock(pipe_mutex); + std::unique_lock pipe_lock(m_pipe_mutex); auto start_time = std::chrono::steady_clock::now(); auto check_timeout = [&]() -> bool { @@ -269,7 +325,7 @@ std::optional> asst::Controller::call_command(const s else { // failed to create child process return std::nullopt; - } +} #endif Log.trace("Call `", cmd, "` ret", exit_ret, ", output size:", pipe_data.size()); @@ -285,6 +341,57 @@ std::optional> asst::Controller::call_command(const s } } +std::optional> asst::Controller::recv_data_by_socket(int64_t timeout) +{ + LogTraceFunction; + + if (!m_support_netcat) { + return std::nullopt; + } + + std::vector socket_data; + + std::unique_lock nc_lock(m_socket_mutex); + + auto start_time = std::chrono::steady_clock::now(); + auto check_timeout = [&]() -> bool { + return timeout && + timeout < std::chrono::duration_cast( + std::chrono::steady_clock::now() - start_time) + .count(); + }; + +#ifdef _WIN32 + SOCKADDR client_addr = { 0 }; + int size = sizeof(SOCKADDR); + + std::unique_ptr> client_sock_ptr( + new SOCKET(::accept(m_server_sock, (SOCKADDR*)&client_addr, &size)), + [](SOCKET* socket) { if (*socket) { ::closesocket(*socket); *socket = 0U; }}); + + while (!check_timeout()) { + int recv_size = ::recv(*client_sock_ptr, m_socket_buffer.get(), SocketBuffSize, NULL); + if (recv_size < 0) { + Log.error("recv error", recv_size); + return std::nullopt; + } + if (recv_size == 0) { + break; + } + socket_data.insert(socket_data.end(), m_socket_buffer.get(), m_socket_buffer.get() + recv_size); + } +#else + // todo +#endif // _WIN32 + + Log.trace("socket data size:", socket_data.size()); + + if (socket_data.empty()) { + return std::nullopt; + } + return socket_data; + } + void asst::Controller::convert_lf(std::vector& data) { LogTraceFunction; @@ -369,6 +476,7 @@ void asst::Controller::clear_info() noexcept m_height = 0; m_control_scale = 1.0; m_scale_size = { WindowWidthDefault, WindowHeightDefault }; + --m_instance_count; } int asst::Controller::push_cmd(const std::string& cmd) @@ -442,18 +550,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_netcat && + screencap(m_adb.screencap_raw_with_gzip_and_nc, decode_raw_with_gzip, true)) { + m_adb.screencap_method = AdbProperty::ScreencapMethod::RawWithGzipAndNc; + Log.info("screencap by RawWithGzipAndNc"); + 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::RawWithGzipAndNc: + { + return screencap(m_adb.screencap_raw_with_gzip_and_nc, decode_raw_with_gzip, true); + } + break; case AdbProperty::ScreencapMethod::RawWithGzip: { return screencap(m_adb.screencap_raw_with_gzip, decode_raw_with_gzip); @@ -469,10 +590,18 @@ 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) { + if (!m_support_netcat && by_socket) { + return false; + } + auto ret = call_command(cmd); + if (by_socket && ret) { + ret = recv_data_by_socket(); + } + if (!ret || ret.value().empty()) { Log.error("data is empty!"); return false; @@ -485,6 +614,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 +628,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 { @@ -665,12 +796,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 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) { @@ -823,16 +958,60 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a m_callback(AsstMsg::ConnectionInfo, info, m_callback_arg); } + if (size_t pos = address.rfind(':'); + pos != std::string::npos) { + nc_address = address.substr(0, pos); + } + else { + nc_address = "127.0.0.1"; + } + m_adb.click = cmd_replace(adb_cfg.click); m_adb.swipe = cmd_replace(adb_cfg.swipe); m_adb.screencap_raw_with_gzip = cmd_replace(adb_cfg.screencap_raw_with_gzip); m_adb.screencap_encode = cmd_replace(adb_cfg.screencap_encode); m_adb.release = cmd_replace(adb_cfg.release); + if (m_support_netcat) { +#ifdef _WIN32 + m_server_addr.sin_family = PF_INET; + m_server_addr.sin_addr.s_addr = inet_addr(nc_address.c_str()); +#else + // todo +#endif + bool server_start = false; + u_short max_port = adb_cfg.nc_port + 100; + for (nc_port = adb_cfg.nc_port; nc_port < max_port; ++nc_port) { + Log.trace("try nc port", nc_port); +#ifdef _WIN32 + + m_server_addr.sin_port = htons(nc_port); + int bind_ret = ::bind(m_server_sock, (SOCKADDR*)&m_server_addr, sizeof(SOCKADDR)); + int listen_ret = ::listen(m_server_sock, 20); + server_start = bind_ret == 0 && listen_ret == 0; +#else + // todo +#endif + if (server_start) { + break; + } + } + if (server_start && call_command(cmd_replace(adb_cfg.nc_port_reverse))) { + Log.info("supports netcat"); + m_support_netcat = true; + } + else { + Log.info("not supports netcat"); + m_support_netcat = false; + } + m_adb.screencap_raw_with_gzip_and_nc = cmd_replace(adb_cfg.screencap_raw_with_gzip_and_nc); + } + + ++m_instance_count; return true; } -bool asst::Controller::disconnect() +bool asst::Controller::release() { #ifndef _WIN32 if (m_child) diff --git a/src/MeoAssistant/Controller.h b/src/MeoAssistant/Controller.h index 47e2d117bb..1029b4c2cd 100644 --- a/src/MeoAssistant/Controller.h +++ b/src/MeoAssistant/Controller.h @@ -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); @@ -61,11 +61,12 @@ namespace asst private: void pipe_working_proc(); std::optional> call_command(const std::string& cmd, int64_t timeout = 20000); + std::optional> recv_data_by_socket(int64_t timeout = 20000); int push_cmd(const std::string& cmd); using DecodeFunc = std::function&)>; 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); @@ -82,7 +83,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 m_pipe_buffer = nullptr; + std::mutex m_pipe_mutex; + std::unique_ptr m_socket_buffer = nullptr; + std::mutex m_socket_mutex; #ifdef _WIN32 HANDLE m_pipe_read = nullptr; // 读管道句柄 HANDLE m_pipe_write = nullptr; // 写管道句柄 @@ -90,6 +95,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; @@ -104,6 +113,7 @@ namespace asst std::string click; std::string swipe; + std::string screencap_raw_with_gzip_and_nc; std::string screencap_raw_with_gzip; std::string screencap_encode; std::string release; @@ -121,6 +131,7 @@ namespace asst { UnknownYet, Default, + RawWithGzipAndNc, RawWithGzip, Encode } screencap_method = ScreencapMethod::UnknownYet; @@ -131,6 +142,9 @@ namespace asst double m_control_scale = 1.0; int m_width = 0; int m_height = 0; + bool m_support_netcat = false; + + inline static int m_instance_count = 0; mutable std::shared_mutex m_image_mutex; cv::Mat m_cache_image; diff --git a/src/MeoAssistant/GeneralConfiger.cpp b/src/MeoAssistant/GeneralConfiger.cpp index 47c372bcb1..30f50ec666 100644 --- a/src/MeoAssistant/GeneralConfiger.cpp +++ b/src/MeoAssistant/GeneralConfiger.cpp @@ -43,6 +43,9 @@ 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_with_gzip_and_nc = cfg_json.at("screencapRawWithGzipAndNC").as_string(); + adb.nc_port = static_cast(cfg_json.at("ncPort").as_integer()); + adb.nc_port_reverse = cfg_json.at("ncPortReverse").as_string(); adb.screencap_encode = cfg_json.at("screencapEncode").as_string(); adb.release = cfg_json.at("release").as_string(); //adb.pullscreen = cfg_json.at("pullscreen").as_string(); diff --git a/src/MeoAssistant/GeneralConfiger.h b/src/MeoAssistant/GeneralConfiger.h index cb1ee76c99..f57c464086 100644 --- a/src/MeoAssistant/GeneralConfiger.h +++ b/src/MeoAssistant/GeneralConfiger.h @@ -51,6 +51,9 @@ namespace asst std::string swipe; std::string display; std::string screencap_raw_with_gzip; + std::string screencap_raw_with_gzip_and_nc; + unsigned short nc_port = 0U; + std::string nc_port_reverse; std::string screencap_encode; std::string release; }; diff --git a/src/MeoAssistant/MeoAssistant.vcxproj b/src/MeoAssistant/MeoAssistant.vcxproj index 27bed142f1..293b9e6117 100644 --- a/src/MeoAssistant/MeoAssistant.vcxproj +++ b/src/MeoAssistant/MeoAssistant.vcxproj @@ -245,7 +245,7 @@ true true true - ppocr.lib;opencv_world453.lib;zlibstatic.lib;%(AdditionalDependencies) + ppocr.lib;opencv_world453.lib;zlibstatic.lib;ws2_32.lib;%(AdditionalDependencies) RequireAdministrator @@ -297,7 +297,7 @@ true true true - ppocr.lib;opencv_world453.lib;zlibstatic.lib;%(AdditionalDependencies) + ppocr.lib;opencv_world453.lib;zlibstatic.lib;ws2_32.lib;%(AdditionalDependencies) RequireAdministrator From f8b2f30994d4165845479431c26015fe62e65401 Mon Sep 17 00:00:00 2001 From: MistEO Date: Sun, 5 Jun 2022 02:28:38 +0800 Subject: [PATCH 3/6] =?UTF-8?q?fix.=E4=BF=AE=E5=A4=8Dsocket=E8=BD=AC?= =?UTF-8?q?=E5=8F=91=E6=88=AA=E5=9B=BE=E5=8F=8D=E4=BB=A3=E5=A4=B1=E6=95=88?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E5=B9=B6=E5=8F=96=E6=B6=88?= =?UTF-8?q?gzip=E5=8E=8B=E7=BC=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/config.json | 32 +-- src/MeoAssistant/Controller.cpp | 284 +++++++++++++++------------ src/MeoAssistant/Controller.h | 19 +- src/MeoAssistant/GeneralConfiger.cpp | 3 +- src/MeoAssistant/GeneralConfiger.h | 3 +- 5 files changed, 185 insertions(+), 156 deletions(-) diff --git a/resource/config.json b/resource/config.json index deae952fed..757d9b1d59 100644 --- a/resource/config.json +++ b/resource/config.json @@ -28,8 +28,8 @@ "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", - "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", - "ncPort": 6054, + "screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"", + "ncPort": 6723, "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", "screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"", "screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p", @@ -44,8 +44,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", - "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", - "ncPort": 6054, + "screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"", + "ncPort": 6723, "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", "screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"", "screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p", @@ -60,8 +60,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", - "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", - "ncPort": 6054, + "screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"", + "ncPort": 6723, "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", "screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"", "screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p", @@ -76,8 +76,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", - "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", - "ncPort": 6054, + "screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"", + "ncPort": 6723, "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", "screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap | gzip -1\"", "screencapEncode": "[Adb] -s [AdbSerial] shell screencap -p", @@ -92,8 +92,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", - "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", - "ncPort": 6054, + "screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"", + "ncPort": 6723, "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", "screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"", "screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p", @@ -108,8 +108,8 @@ "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", - "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", - "ncPort": 6054, + "screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"", + "ncPort": 6723, "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", "screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap | gzip -1\"", "screencapEncode": "[Adb] -s [AdbSerial] shell screencap -p", @@ -125,8 +125,8 @@ "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", - "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", - "ncPort": 6054, + "screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"", + "ncPort": 6723, "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", "screencapRawWithGzip": "[Adb] -s [AdbSerial] shell \"screencap -d [DisplayId] | gzip -1\"", "screencapEncode": "[Adb] -s [AdbSerial] shell screencap -d [DisplayId] -p", @@ -141,8 +141,8 @@ "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", - "screencapRawWithGzipAndNC": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1 | nc [NcAddress] [NcPort]\"", - "ncPort": 6054, + "screencapRawByNC": "[Adb] -s [AdbSerial] exec-out \"screencap | nc -w 3 [NcAddress] [NcPort]\"", + "ncPort": 6723, "ncPortReverse": "[Adb] -s [AdbSerial] reverse tcp:[NcPort] tcp:[NcPort]", "screencapRawWithGzip": "[Adb] -s [AdbSerial] exec-out \"screencap | gzip -1\"", "screencapEncode": "[Adb] -s [AdbSerial] exec-out screencap -p", diff --git a/src/MeoAssistant/Controller.cpp b/src/MeoAssistant/Controller.cpp index 57c1569f9b..0fde0d7dab 100644 --- a/src/MeoAssistant/Controller.cpp +++ b/src/MeoAssistant/Controller.cpp @@ -84,17 +84,13 @@ asst::Controller::Controller(AsstCallback callback, void* callback_arg) m_child_startup_info.hStdOutput = m_pipe_child_write; m_child_startup_info.hStdError = m_pipe_child_write; - m_support_netcat = false; + m_support_socket = false; do { if (!WsaHelper::get_instance()()) { Log.error("WSA not supports"); break; } - m_server_sock = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (m_server_sock == INVALID_SOCKET) { - break; - } - m_support_netcat = true; + m_support_socket = true; } while (0); #else @@ -113,7 +109,7 @@ asst::Controller::Controller(AsstCallback callback, void* callback_arg) if (!m_pipe_buffer) { throw "controller pipe buffer allocated failed"; } - if (m_support_netcat) { + if (m_support_socket) { m_socket_buffer = std::make_unique(SocketBuffSize); if (!m_socket_buffer) { throw "controller socket buffer allocated failed"; @@ -146,17 +142,13 @@ asst::Controller::~Controller() ::CloseHandle(m_pipe_child_read); ::CloseHandle(m_pipe_child_write); - if (m_server_sock) { - ::closesocket(m_server_sock); - m_server_sock = 0U; - } #else close(m_pipe_in[PIPE_READ]); close(m_pipe_in[PIPE_WRITE]); close(m_pipe_out[PIPE_READ]); close(m_pipe_out[PIPE_WRITE]); #endif - } +} //asst::Rect asst::Controller::shaped_correct(const Rect & rect) const //{ @@ -250,7 +242,7 @@ void asst::Controller::pipe_working_proc() } } -std::optional> asst::Controller::call_command(const std::string& cmd, int64_t timeout) +std::optional> asst::Controller::call_command(const std::string& cmd, int64_t timeout, bool recv_by_socket) { LogTraceFunction; @@ -270,21 +262,39 @@ std::optional> asst::Controller::call_command(const s PROCESS_INFORMATION process_info = { 0 }; // 进程信息结构体 BOOL create_ret = ::CreateProcessA(nullptr, const_cast(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(timeout)); + } + DWORD exit_ret = 0; ::GetExitCodeProcess(process_info.hProcess, &exit_ret); ::CloseHandle(process_info.hProcess); ::CloseHandle(process_info.hThread); @@ -325,7 +335,7 @@ std::optional> asst::Controller::call_command(const s else { // failed to create child process return std::nullopt; -} + } #endif Log.trace("Call `", cmd, "` ret", exit_ret, ", output size:", pipe_data.size()); @@ -341,57 +351,6 @@ std::optional> asst::Controller::call_command(const s } } -std::optional> asst::Controller::recv_data_by_socket(int64_t timeout) -{ - LogTraceFunction; - - if (!m_support_netcat) { - return std::nullopt; - } - - std::vector socket_data; - - std::unique_lock nc_lock(m_socket_mutex); - - auto start_time = std::chrono::steady_clock::now(); - auto check_timeout = [&]() -> bool { - return timeout && - timeout < std::chrono::duration_cast( - std::chrono::steady_clock::now() - start_time) - .count(); - }; - -#ifdef _WIN32 - SOCKADDR client_addr = { 0 }; - int size = sizeof(SOCKADDR); - - std::unique_ptr> client_sock_ptr( - new SOCKET(::accept(m_server_sock, (SOCKADDR*)&client_addr, &size)), - [](SOCKET* socket) { if (*socket) { ::closesocket(*socket); *socket = 0U; }}); - - while (!check_timeout()) { - int recv_size = ::recv(*client_sock_ptr, m_socket_buffer.get(), SocketBuffSize, NULL); - if (recv_size < 0) { - Log.error("recv error", recv_size); - return std::nullopt; - } - if (recv_size == 0) { - break; - } - socket_data.insert(socket_data.end(), m_socket_buffer.get(), m_socket_buffer.get() + recv_size); - } -#else - // todo -#endif // _WIN32 - - Log.trace("socket data size:", socket_data.size()); - - if (socket_data.empty()) { - return std::nullopt; - } - return socket_data; - } - void asst::Controller::convert_lf(std::vector& data) { LogTraceFunction; @@ -476,6 +435,11 @@ 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; } @@ -489,6 +453,54 @@ int asst::Controller::push_cmd(const std::string& cmd) return ++m_push_id; } +std::optional 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) { @@ -507,7 +519,35 @@ bool asst::Controller::screencap() // return true; //} - DecodeFunc decode_raw_with_gzip = [&](const std::vector& data) -> bool { + DecodeFunc decode_raw = [&](std::vector& 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 image_lock(m_image_mutex); + m_cache_image = temp; + return true; + }; + + DecodeFunc decode_raw_with_gzip = [&](std::vector& data) -> bool { auto unzip_data = gzip::decompress(data.data(), data.size()); Log.trace("unzip data size:", unzip_data.size()); if (unzip_data.empty()) { @@ -537,7 +577,7 @@ bool asst::Controller::screencap() return true; }; - DecodeFunc decode_encode = [&](const std::vector& data) -> bool { + DecodeFunc decode_encode = [&](std::vector& data) -> bool { cv::Mat temp = cv::imdecode(data, cv::IMREAD_COLOR); if (temp.empty()) { return false; @@ -550,10 +590,10 @@ bool asst::Controller::screencap() switch (m_adb.screencap_method) { case AdbProperty::ScreencapMethod::UnknownYet: { - if (m_support_netcat && - screencap(m_adb.screencap_raw_with_gzip_and_nc, decode_raw_with_gzip, true)) { - m_adb.screencap_method = AdbProperty::ScreencapMethod::RawWithGzipAndNc; - Log.info("screencap by RawWithGzipAndNc"); + 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)) { @@ -570,9 +610,9 @@ bool asst::Controller::screencap() return false; } } - case AdbProperty::ScreencapMethod::RawWithGzipAndNc: + case AdbProperty::ScreencapMethod::RawByNc: { - return screencap(m_adb.screencap_raw_with_gzip_and_nc, decode_raw_with_gzip, true); + return screencap(m_adb.screencap_raw_by_nc, decode_raw, true); } break; case AdbProperty::ScreencapMethod::RawWithGzip: @@ -592,15 +632,11 @@ bool asst::Controller::screencap() bool asst::Controller::screencap(const std::string& cmd, DecodeFunc decode_func, bool by_socket) { - if (!m_support_netcat && by_socket) { + if ((!m_support_socket || !m_server_started) && by_socket) { return false; } - auto ret = call_command(cmd); - - if (by_socket && ret) { - ret = recv_data_by_socket(); - } + auto ret = call_command(cmd, 20000, by_socket); if (!ret || ret.value().empty()) { Log.error("data is empty!"); @@ -958,53 +994,33 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a m_callback(AsstMsg::ConnectionInfo, info, m_callback_arg); } - if (size_t pos = address.rfind(':'); - pos != std::string::npos) { - nc_address = address.substr(0, pos); - } - else { - nc_address = "127.0.0.1"; - } - m_adb.click = cmd_replace(adb_cfg.click); m_adb.swipe = cmd_replace(adb_cfg.swipe); m_adb.screencap_raw_with_gzip = cmd_replace(adb_cfg.screencap_raw_with_gzip); m_adb.screencap_encode = cmd_replace(adb_cfg.screencap_encode); m_adb.release = cmd_replace(adb_cfg.release); - if (m_support_netcat) { -#ifdef _WIN32 - m_server_addr.sin_family = PF_INET; - m_server_addr.sin_addr.s_addr = inet_addr(nc_address.c_str()); -#else - // todo -#endif - bool server_start = false; - u_short max_port = adb_cfg.nc_port + 100; - for (nc_port = adb_cfg.nc_port; nc_port < max_port; ++nc_port) { - Log.trace("try nc port", nc_port); -#ifdef _WIN32 - - m_server_addr.sin_port = htons(nc_port); - int bind_ret = ::bind(m_server_sock, (SOCKADDR*)&m_server_addr, sizeof(SOCKADDR)); - int listen_ret = ::listen(m_server_sock, 20); - server_start = bind_ret == 0 && listen_ret == 0; -#else - // todo -#endif - if (server_start) { - break; - } - } - if (server_start && call_command(cmd_replace(adb_cfg.nc_port_reverse))) { - Log.info("supports netcat"); - m_support_netcat = true; + 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 { - Log.info("not supports netcat"); - m_support_netcat = false; + 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_adb.screencap_raw_with_gzip_and_nc = cmd_replace(adb_cfg.screencap_raw_with_gzip_and_nc); } ++m_instance_count; @@ -1013,6 +1029,14 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a 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 @@ -1021,7 +1045,7 @@ bool asst::Controller::release() { return call_command(m_adb.release).has_value(); } -} + } const std::string& asst::Controller::get_uuid() const { diff --git a/src/MeoAssistant/Controller.h b/src/MeoAssistant/Controller.h index 1029b4c2cd..92da86f57f 100644 --- a/src/MeoAssistant/Controller.h +++ b/src/MeoAssistant/Controller.h @@ -60,11 +60,17 @@ namespace asst private: void pipe_working_proc(); - std::optional> call_command(const std::string& cmd, int64_t timeout = 20000); - std::optional> recv_data_by_socket(int64_t timeout = 20000); + std::optional> 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&)>; + struct SocketInfo + { + std::string remote_address; + unsigned short remote_port = 0U; + }; + std::optional try_init_socket(const std::string& local_address, unsigned short try_port, unsigned short try_times = 10U); + + using DecodeFunc = std::function&)>; bool screencap(); bool screencap(const std::string& cmd, DecodeFunc decode_func, bool by_nc = false); cv::Mat get_resized_image() const; @@ -113,7 +119,7 @@ namespace asst std::string click; std::string swipe; - std::string screencap_raw_with_gzip_and_nc; + std::string screencap_raw_by_nc; std::string screencap_raw_with_gzip; std::string screencap_encode; std::string release; @@ -131,7 +137,7 @@ namespace asst { UnknownYet, Default, - RawWithGzipAndNc, + RawByNc, RawWithGzip, Encode } screencap_method = ScreencapMethod::UnknownYet; @@ -142,7 +148,8 @@ namespace asst double m_control_scale = 1.0; int m_width = 0; int m_height = 0; - bool m_support_netcat = false; + bool m_support_socket = false; + bool m_server_started = false; inline static int m_instance_count = 0; diff --git a/src/MeoAssistant/GeneralConfiger.cpp b/src/MeoAssistant/GeneralConfiger.cpp index 30f50ec666..a8cbd7ac9c 100644 --- a/src/MeoAssistant/GeneralConfiger.cpp +++ b/src/MeoAssistant/GeneralConfiger.cpp @@ -43,9 +43,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_with_gzip_and_nc = cfg_json.at("screencapRawWithGzipAndNC").as_string(); + adb.screencap_raw_by_nc = cfg_json.at("screencapRawByNC").as_string(); adb.nc_port = static_cast(cfg_json.at("ncPort").as_integer()); - adb.nc_port_reverse = cfg_json.at("ncPortReverse").as_string(); adb.screencap_encode = cfg_json.at("screencapEncode").as_string(); adb.release = cfg_json.at("release").as_string(); //adb.pullscreen = cfg_json.at("pullscreen").as_string(); diff --git a/src/MeoAssistant/GeneralConfiger.h b/src/MeoAssistant/GeneralConfiger.h index f57c464086..42c478871c 100644 --- a/src/MeoAssistant/GeneralConfiger.h +++ b/src/MeoAssistant/GeneralConfiger.h @@ -51,9 +51,8 @@ namespace asst std::string swipe; std::string display; std::string screencap_raw_with_gzip; - std::string screencap_raw_with_gzip_and_nc; + std::string screencap_raw_by_nc; unsigned short nc_port = 0U; - std::string nc_port_reverse; std::string screencap_encode; std::string release; }; From a2e4ee6d76112963baece0380e587bf5fff537f2 Mon Sep 17 00:00:00 2001 From: MistEO Date: Sun, 5 Jun 2022 03:06:27 +0800 Subject: [PATCH 4/6] =?UTF-8?q?perf.=E4=BC=98=E5=8C=96=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=88=98=E6=96=97=E4=BB=8E=E5=85=A5=E5=9C=BA=E5=88=B0=E5=BC=80?= =?UTF-8?q?=E5=A7=8B=E8=AF=86=E5=88=AB=E5=B9=B2=E5=91=98=E4=B9=8B=E9=97=B4?= =?UTF-8?q?=E7=9A=84=E5=BB=B6=E8=BF=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/tasks.json | 15 +++++-- resource/template/BattleOfficiallyBegin.png | Bin 0 -> 1685 bytes src/MeoAssistant/BattleProcessTask.cpp | 47 ++++++++++++++------ 3 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 resource/template/BattleOfficiallyBegin.png diff --git a/resource/tasks.json b/resource/tasks.json index 48adaef05d..d5bb44312d 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -4540,9 +4540,18 @@ 30 ] }, - "BattleWaitingToLoad": { - "algorithm": "JustReturn", - "rearDelay": 3000 + "BattleOfficiallyBegin": { + "action": "DoNothing", + "roi": [ + 1165, + 20, + 65, + 65 + ], + "maskRange": [ + 100, + 255 + ] }, "BattleSpeedUp": { "algorithm": "JustReturn", diff --git a/resource/template/BattleOfficiallyBegin.png b/resource/template/BattleOfficiallyBegin.png new file mode 100644 index 0000000000000000000000000000000000000000..7e60d424365118edb45177f1a088855af95dbd1b GIT binary patch literal 1685 zcmV;G25R|+|4Xp6#=;+x}>`WHE)|Aq>~gAT*^qQ2n+)4>^V zXn__;S}bX$K!GGJtxd9feAw(~?xweAl5F;Vob$V9&pjV^sWkl|BS79QfzbW<+QOsc zZ3uCd5l3A8M4_vn1a&*e9YB$jWDKN26@beC9%=#sx_eJ{D*+Hf>)y*56OoJ0>~z3= z@D3OQHWy|vTY)}L;}p0zO%u#4UzD#=?_vf4_~Oei@zvMgAbTW>R;wKW2hcPPM1{p~UmTg^%&;jTmZbs$t zW6a;Wr6dFZrcRthE|&u{+h56;dcBT~^>t;QlarH3rcymxmN^6AZ+rT56_1vel?7$9 zS&ZikFijIyNK+2AS}iM9l&7nFHkymZOs&@W^JY#u~t?eAmh;X`FX>2w;&R0=}Vr2Q6Ku$Xc8&K+f*V;_tm zlg)ytzv+l@gT;*HrH8HuIS_m%gWSjn01EK&o~X^ITB)Gjj*cCEipLWum&*qRYT=0S z4_v8M(Q38O>2wYhWEciMxp*-EnteA!cKldbsiN6zDuD-pe4)_G&nLqM&%s6p@N8`j z)k*~e0|QEe&X&*FkJw@0m&o?dcC(4MZ{H~K6GC8i?gDh(&0cyEK}L7OxEZMIZU4} z_O(&dGI9U@q7rZbNG20fFJ`0kYaae5?QO8Vy}bj42q7SZIKV~;%zUUwn@pxKIW^f6 zHv+PmZ6EJ`yTa>@2AYkAvan*Q1j8`ksQ`g108}eg> z$>oq59)>@z1S&LUuw~)zyXwJee0&_E$BsdefXsNLnkOQVAk5FtD+@}*;}{zo16xsA zwU@C{twv^`VT#3KIC0_xG);phiQrQ3%nZx2H?4}t0f0m@iDKzYz~u&@lfAjCl?v*I zNc?7IXF){L1q%vQ;Pzv;ZER(=iuFSj5@*Zh$UbJ}q|MCEAf3s;E2)FT%-G%A#naVQWuEbP9EM@QVu|LXCOI4T{-Ro75kepq8^Xlo zq&wG7M1UZHcB_qr1@+?Oy^#?dKYmpJXhaUsFpH=l<^A8=+r#35y4??_(-_a^-DD|z z)=2;?)54>rWu?T=q3P2_x3F=TMQWbNTg2MhKgvR4u^3Jli!e>IZ-A@So*n9l&z`N>X5zC!XC8qdG!5^M zj$&wN$dxDK?Huav@9*RF))pF#y7%6oANcS;?nch2mjDh>f6D6~8~G=a?^s)s2>H*F z9G>Kp@0@JwA)b<>WIvGp6b2G`WY_)am({Z~hMnSuf^`CSZC>T=M-Y_S%Z~s&j#5c@ fP9JU@^t=B9xWADJ@Uxap00000NkvXXu0mjfxd$<0 literal 0 HcmV?d00001 diff --git a/src/MeoAssistant/BattleProcessTask.cpp b/src/MeoAssistant/BattleProcessTask.cpp index cbd4207bfc..1575f21838 100644 --- a/src/MeoAssistant/BattleProcessTask.cpp +++ b/src/MeoAssistant/BattleProcessTask.cpp @@ -2,6 +2,7 @@ #include #include +#include #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,38 +87,52 @@ 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(); } - { + + auto draw_future = std::async(std::launch::async, [&]() { //#ifdef ASST_DEBUG - auto draw = m_ctrler->get_image(); + 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(); @@ -126,7 +143,7 @@ bool asst::BattleProcessTask::analyze_opers_preview() 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,6 +183,8 @@ bool asst::BattleProcessTask::analyze_opers_preview() oper_analyzer.set_image(image); oper_analyzer.analyze(); } + + draw_future.wait(); battle_pause(); cancel_selection(); From e6e1153880d9f4f69b1dcc59392fddd6eac5d48a Mon Sep 17 00:00:00 2001 From: MistEO Date: Sun, 5 Jun 2022 04:40:19 +0800 Subject: [PATCH 5/6] =?UTF-8?q?perf.=E4=BC=98=E5=8C=96=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=88=98=E6=96=97=E7=9A=84=E4=B8=80=E4=BA=9B=E5=BB=B6=E8=BF=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/tasks.json | 73 ++++++------------------ src/MeoAssistant/BattleImageAnalyzer.cpp | 17 ++---- src/MeoAssistant/BattleProcessTask.cpp | 40 ++++++++----- src/MeoAssistant/BattleProcessTask.h | 1 - 4 files changed, 49 insertions(+), 82 deletions(-) diff --git a/resource/tasks.json b/resource/tasks.json index d5bb44312d..0abd2050b0 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -4595,17 +4595,22 @@ 600, 60 ], - "rectMove": [ - 50, - 0, - 150, - 60 - ], "maskRange": [ 1, 255 ] }, + "BattleKills": { + "algorithm": "OcrDetect", + "text": [ + ], + "roi": [ + 50, + 0, + 100, + 40 + ] + }, "BattleCostData": { "algorithm": "OcrDetect", "text": [], @@ -4644,10 +4649,6 @@ -110, 90, 90 - ], - "next": [ - "BattleSkillReadyOnClick", - "Stop" ] }, "BattleSkillStopOnClick": { @@ -4664,23 +4665,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": 10000, + "rearDelay": 100, + "Doc": "pre 是将干员滑动到场上的 duration 系数;rear 是设置干员朝向滑动的 duration" }, "BattleOpersFlag": { "templThreshold": 0.85, @@ -4989,25 +4986,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, @@ -5016,25 +4997,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, diff --git a/src/MeoAssistant/BattleImageAnalyzer.cpp b/src/MeoAssistant/BattleImageAnalyzer.cpp index 75deef6198..93e53e3a7b 100644 --- a/src/MeoAssistant/BattleImageAnalyzer.cpp +++ b/src/MeoAssistant/BattleImageAnalyzer.cpp @@ -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(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; diff --git a/src/MeoAssistant/BattleProcessTask.cpp b/src/MeoAssistant/BattleProcessTask.cpp index 1575f21838..c1db41a417 100644 --- a/src/MeoAssistant/BattleProcessTask.cpp +++ b/src/MeoAssistant/BattleProcessTask.cpp @@ -124,7 +124,6 @@ bool asst::BattleProcessTask::analyze_opers_preview() } auto draw_future = std::async(std::launch::async, [&]() { - //#ifdef ASST_DEBUG 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) + " )"; @@ -136,12 +135,14 @@ bool asst::BattleProcessTask::analyze_opers_preview() 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); - - sleep(Task.get("BattleUseOper")->pre_delay); + cur_rect = cur_oper.at(i - offset).rect; + m_ctrler->click(cur_rect); + sleep(click_delay); image = m_ctrler->get_image(); @@ -185,8 +186,10 @@ bool asst::BattleProcessTask::analyze_opers_preview() } draw_future.wait(); + + m_ctrler->click(cur_rect); + sleep(click_delay); battle_pause(); - cancel_selection(); return true; } @@ -270,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; @@ -381,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()) { @@ -393,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 转好 @@ -402,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); @@ -412,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()) { @@ -440,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( + std::sqrt( + (std::abs(placed_point.x - oper_rect.x) << 1) + + (std::abs(placed_point.y - oper_rect.y) << 1))); + int duration = static_cast(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); @@ -468,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{ @@ -578,8 +593,3 @@ bool asst::BattleProcessTask::battle_speedup() { return ProcessTask(*this, { "BattleSpeedUp" }).run(); } - -bool asst::BattleProcessTask::cancel_selection() -{ - return ProcessTask(*this, { "BattleCancelSelection" }).run(); -} diff --git a/src/MeoAssistant/BattleProcessTask.h b/src/MeoAssistant/BattleProcessTask.h index 3b44c1ca27..0e6a3400a4 100644 --- a/src/MeoAssistant/BattleProcessTask.h +++ b/src/MeoAssistant/BattleProcessTask.h @@ -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); From 6926ecb59224bc24e64900f703ca4652963adee1 Mon Sep 17 00:00:00 2001 From: MistEO Date: Sun, 5 Jun 2022 23:39:40 +0800 Subject: [PATCH 6/6] =?UTF-8?q?chore.=E7=AE=80=E5=8D=95=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E4=B8=80=E4=B8=8B=E5=BB=B6=E8=BF=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/tasks.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resource/tasks.json b/resource/tasks.json index 0abd2050b0..23475003fd 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -4675,7 +4675,7 @@ }, "BattleSwipeOper": { "algorithm": "JustReturn", - "preDelay": 10000, + "preDelay": 12000, "rearDelay": 100, "Doc": "pre 是将干员滑动到场上的 duration 系数;rear 是设置干员朝向滑动的 duration" },