From e29cbcc5b2485341b2767fd89a43eb8af47e3094 Mon Sep 17 00:00:00 2001 From: MistEO Date: Thu, 16 Jun 2022 01:20:24 +0800 Subject: [PATCH] =?UTF-8?q?feat.=E6=96=B0=E5=A2=9E=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=88=AA=E5=9B=BE=E6=B5=8B=E9=80=9F=EF=BC=8C=E5=B9=B6=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E4=B8=80=E4=BA=9B=E8=BF=9E=E6=8E=A5=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MeoAssistant/Assistant.cpp | 13 +++-- src/MeoAssistant/Assistant.h | 1 + src/MeoAssistant/Controller.cpp | 91 +++++++++++++++++++++++------- src/MeoAssistant/Controller.h | 4 +- src/MeoAsstGui/Helper/AsstProxy.cs | 11 ++++ 5 files changed, 93 insertions(+), 27 deletions(-) diff --git a/src/MeoAssistant/Assistant.cpp b/src/MeoAssistant/Assistant.cpp index 9531ac3efd..a8cb14a2f3 100644 --- a/src/MeoAssistant/Assistant.cpp +++ b/src/MeoAssistant/Assistant.cpp @@ -60,7 +60,6 @@ bool asst::Assistant::connect(const std::string& adb_path, const std::string& ad { LogTraceFunction; - m_inited = false; std::unique_lock lock(m_mutex); stop(false); @@ -69,7 +68,6 @@ bool asst::Assistant::connect(const std::string& adb_path, const std::string& ad if (ret) { m_uuid = m_ctrler->get_uuid(); } - m_inited = ret; return ret; } @@ -161,7 +159,7 @@ bool asst::Assistant::set_task_params(TaskId task_id, const std::string& params) std::vector asst::Assistant::get_image() const { - if (!m_inited) { + if (!inited()) { return {}; } return m_ctrler->get_image_encode(); @@ -169,7 +167,7 @@ std::vector asst::Assistant::get_image() const bool asst::Assistant::ctrler_click(int x, int y, bool block) { - if (!m_inited) { + if (!inited()) { return false; } m_ctrler->click(Point(x, y), block); @@ -181,7 +179,7 @@ bool asst::Assistant::start(bool block) LogTraceFunction; Log.trace("Start |", block ? "block" : "non block"); - if (!m_thread_idle || !m_inited) { + if (!m_thread_idle || !inited()) { return false; } std::unique_lock lock; @@ -325,3 +323,8 @@ void Assistant::clear_cache() m_status->clear_rect(); m_status->clear_str(); } + +bool asst::Assistant::inited() const noexcept +{ + return m_ctrler && m_ctrler->inited(); +} diff --git a/src/MeoAssistant/Assistant.h b/src/MeoAssistant/Assistant.h index a498d23ccf..f0f8764853 100644 --- a/src/MeoAssistant/Assistant.h +++ b/src/MeoAssistant/Assistant.h @@ -52,6 +52,7 @@ namespace asst void append_callback(AsstMsg msg, json::value detail); void clear_cache(); + bool inited() const noexcept; bool m_inited = false; std::string m_uuid; diff --git a/src/MeoAssistant/Controller.cpp b/src/MeoAssistant/Controller.cpp index 71ee662a1f..1d795966b9 100644 --- a/src/MeoAssistant/Controller.cpp +++ b/src/MeoAssistant/Controller.cpp @@ -281,8 +281,8 @@ std::optional> asst::Controller::call_command(const s std::unique_lock pipe_lock(m_pipe_mutex); fd_set fdset = { 0 }; FD_SET(m_server_sock, &fdset); - constexpr int TimeoutMilliseconds = 10000; - timeval select_timeout = { TimeoutMilliseconds / 1000, (TimeoutMilliseconds % 1000) * 1000}; + constexpr int TimeoutMilliseconds = 5000; + timeval select_timeout = { TimeoutMilliseconds / 1000, (TimeoutMilliseconds % 1000) * 1000 }; select(static_cast(m_server_sock) + 1, &fdset, NULL, NULL, &select_timeout); if (FD_ISSET(m_server_sock, &fdset)) { SOCKET client_sock = ::accept(m_server_sock, NULL, NULL); @@ -356,6 +356,7 @@ std::optional> asst::Controller::call_command(const s else if (m_inited) { // 之前可以运行,突然运行不了了,这种情况多半是 adb 炸了。所以重新连接一下 m_inited = false; + std::this_thread::sleep_for(std::chrono::seconds(10)); auto reconnect_ret = call_command(m_adb.connect, 60 * 1000); bool is_reconnect_success = false; if (reconnect_ret) { @@ -380,6 +381,7 @@ std::optional> asst::Controller::call_command(const s { "cmd", cmd }, { "recv_by_socket", recv_by_socket} }} }; + m_inited = false; m_callback(AsstMsg::ConnectionInfo, info, m_callback_arg); } } @@ -391,6 +393,7 @@ std::optional> asst::Controller::call_command(const s { "details", json::object { { "cmd", m_adb.connect } }} }; + m_inited = false; m_callback(AsstMsg::ConnectionInfo, info, m_callback_arg); } } @@ -567,7 +570,7 @@ bool asst::Controller::screencap() if (data.empty()) { return false; } - size_t std_size = m_width * m_height * 4; + size_t std_size = 4ULL * m_width * m_height; if (data.size() < std_size) { return false; } @@ -594,7 +597,7 @@ bool asst::Controller::screencap() if (unzip_data.empty()) { return false; } - size_t std_size = m_width * m_height * 4; + size_t std_size = 4ULL * m_width * m_height; if (unzip_data.size() < std_size) { return false; } @@ -629,29 +632,60 @@ bool asst::Controller::screencap() switch (m_adb.screencap_method) { case AdbProperty::ScreencapMethod::UnknownYet: { + Log.info("Try to find the fastest way to screencap"); + m_inited = false; + auto min_cost = std::chrono::nanoseconds(MAXLONGLONG); + + auto start_time = std::chrono::high_resolution_clock::now(); 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"); - m_inited = true; - return true; - } - else if (screencap(m_adb.screencap_raw_with_gzip, decode_raw_with_gzip)) { - m_adb.screencap_method = AdbProperty::ScreencapMethod::RawWithGzip; - Log.info("screencap by RawWithGzip"); - m_inited = true; - return true; - } - else if (screencap(m_adb.screencap_encode, decode_encode)) { - m_adb.screencap_method = AdbProperty::ScreencapMethod::Encode; - Log.info("screencap by Encode"); - m_inited = true; - return true; + auto duration = std::chrono::high_resolution_clock::now() - start_time; + if (duration < min_cost) { + m_adb.screencap_method = AdbProperty::ScreencapMethod::RawByNc; + m_inited = true; + min_cost = duration; + clear_lf_info(); + } + Log.info("RawByNc cost", duration.count(), "ns"); } else { - return false; + Log.info("RawByNc is not supported"); } + + start_time = std::chrono::high_resolution_clock::now(); + if (screencap(m_adb.screencap_raw_with_gzip, decode_raw_with_gzip)) { + auto duration = std::chrono::high_resolution_clock::now() - start_time; + if (duration < min_cost) { + m_adb.screencap_method = AdbProperty::ScreencapMethod::RawWithGzip; + m_inited = true; + min_cost = duration; + clear_lf_info(); + } + Log.info("RawWithGzip cost", duration.count(), "ns"); + } + else { + Log.info("RawWithGzip is not supported"); + } + + start_time = std::chrono::high_resolution_clock::now(); + if (screencap(m_adb.screencap_encode, decode_encode)) { + auto duration = std::chrono::high_resolution_clock::now() - start_time; + if (duration < min_cost) { + m_adb.screencap_method = AdbProperty::ScreencapMethod::Encode; + m_inited = true; + min_cost = duration; + clear_lf_info(); + } + Log.info("Encode cost", duration.count(), "ns"); + } + else { + Log.info("Encode is not supported"); + } + + Log.info("The fastest way is", static_cast(m_adb.screencap_method), ", cost:", min_cost.count(), "ns"); + return m_inited; } + break; case AdbProperty::ScreencapMethod::RawByNc: { return screencap(m_adb.screencap_raw_by_nc, decode_raw, true); @@ -717,6 +751,11 @@ bool asst::Controller::screencap(const std::string& cmd, const DecodeFunc& decod } } +void asst::Controller::clear_lf_info() +{ + m_adb.screencap_end_of_line = AdbProperty::ScreencapEndOfLine::UnknownYet; +} + cv::Mat asst::Controller::get_resized_image() const { const static cv::Size dsize(m_scale_size.first, m_scale_size.second); @@ -1109,6 +1148,9 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a } } + // try to find the fastest way + screencap(); + ++m_instance_count; return true; } @@ -1133,6 +1175,11 @@ bool asst::Controller::release() } } +bool asst::Controller::inited() const noexcept +{ + return m_inited; +} + const std::string& asst::Controller::get_uuid() const { return m_uuid; @@ -1148,6 +1195,8 @@ cv::Mat asst::Controller::get_image(bool raw) } // 截图之前正常,截图之后不正常了,说明截图过程中发现 adb 炸了 if (inited && !m_inited) { + const static cv::Size dsize(m_scale_size.first, m_scale_size.second); + m_cache_image = cv::Mat(dsize, CV_8UC3); break; } } diff --git a/src/MeoAssistant/Controller.h b/src/MeoAssistant/Controller.h index adbac00e5c..448c2dc2c9 100644 --- a/src/MeoAssistant/Controller.h +++ b/src/MeoAssistant/Controller.h @@ -32,6 +32,7 @@ namespace asst bool connect(const std::string& adb_path, const std::string& address, const std::string& config); bool release(); + bool inited() const noexcept; const std::string& get_uuid() const; cv::Mat get_image(bool raw = false); @@ -71,6 +72,7 @@ namespace asst using DecodeFunc = std::function&)>; bool screencap(); bool screencap(const std::string& cmd, const DecodeFunc& decode_func, bool by_nc = false); + void clear_lf_info(); cv::Mat get_resized_image() const; Point rand_point_in_rect(const Rect& rect); @@ -137,7 +139,7 @@ namespace asst enum class ScreencapMethod { UnknownYet, - Default, + //Default, RawByNc, RawWithGzip, Encode diff --git a/src/MeoAsstGui/Helper/AsstProxy.cs b/src/MeoAsstGui/Helper/AsstProxy.cs index 3f7edc8d31..87a9433ead 100644 --- a/src/MeoAsstGui/Helper/AsstProxy.cs +++ b/src/MeoAsstGui/Helper/AsstProxy.cs @@ -209,6 +209,8 @@ namespace MeoAsstGui } } + private bool connected = false; + private void procConnectInfo(JObject details) { var what = details["what"].ToString(); @@ -217,19 +219,23 @@ namespace MeoAsstGui switch (what) { case "Connected": + connected = true; svm.ConnectAddress = details["details"]["address"].ToString(); break; case "UnsupportedResolution": + connected = false; mainModel.AddLog("分辨率过低,请设置为 720p 或更高", "darkred"); break; case "ResolutionError": + connected = false; mainModel.AddLog("分辨率获取失败,建议重启电脑,或更换模拟器后再试", "darkred"); break; case "Disconnect": case "CommandExecFailed": + connected = false; mainModel.AddLog("错误!连接断开!", "darkred"); AsstStop(); break; @@ -706,6 +712,11 @@ namespace MeoAsstGui return false; } + if (connected) + { + return true; + } + var settings = _container.Get(); if (settings.AdbPath == String.Empty || settings.ConnectAddress == String.Empty)