From a081c4d9ea2676788923e2821de187b3d8f0a19f Mon Sep 17 00:00:00 2001 From: zzyyyl Date: Fri, 7 Oct 2022 23:13:15 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E9=83=A8?= =?UTF-8?q?=E5=88=86=20string()=20=E5=92=8C=20Logger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../General/MatchImageAnalyzer.cpp | 11 +++++------ .../General/MultiMatchImageAnalyzer.cpp | 7 +------ src/MeoAssistant/Utils/AsstTypes.h | 17 ++++++++++++----- src/MeoAssistant/Utils/Logger.hpp | 6 +++--- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/MeoAssistant/ImageAnalyzer/General/MatchImageAnalyzer.cpp b/src/MeoAssistant/ImageAnalyzer/General/MatchImageAnalyzer.cpp index 65765ffc92..55b9338e46 100644 --- a/src/MeoAssistant/ImageAnalyzer/General/MatchImageAnalyzer.cpp +++ b/src/MeoAssistant/ImageAnalyzer/General/MatchImageAnalyzer.cpp @@ -102,19 +102,19 @@ void asst::MatchImageAnalyzer::set_task_info(MatchTaskInfo task_info) noexcept bool asst::MatchImageAnalyzer::match_templ(const cv::Mat templ) { if (m_roi.x < 0) { - Log.warn("roi is out of range", m_roi.to_string()); + Log.warn("roi is out of range", m_roi); m_roi.x = 0; } if (m_roi.y < 0) { - Log.warn("roi is out of range", m_roi.to_string()); + Log.warn("roi is out of range", m_roi); m_roi.y = 0; } if (m_roi.x + m_roi.width > m_image.cols) { - Log.warn("roi is out of range", m_roi.to_string()); + Log.warn("roi is out of range", m_roi); m_roi.width = m_image.cols - m_roi.x; } if (m_roi.y + m_roi.height > m_image.rows) { - Log.warn("roi is out of range", m_roi.to_string()); + Log.warn("roi is out of range", m_roi); m_roi.height = m_image.rows - m_roi.y; } @@ -148,8 +148,7 @@ bool asst::MatchImageAnalyzer::match_templ(const cv::Mat templ) max_val = 0; } if (max_val > m_templ_thres * 0.7) { // 得分太低的肯定不对,没必要打印 - Log.trace("match_templ |", m_templ_name, "score:", max_val, "rect:", rect.to_string(), - "roi:", m_roi.to_string()); + Log.trace("match_templ |", m_templ_name, "score:", max_val, "rect:", rect, "roi:", m_roi); } if (m_templ_thres <= max_val && max_val < 2.0) { diff --git a/src/MeoAssistant/ImageAnalyzer/General/MultiMatchImageAnalyzer.cpp b/src/MeoAssistant/ImageAnalyzer/General/MultiMatchImageAnalyzer.cpp index 8cb93c8c86..bfd76abfb2 100644 --- a/src/MeoAssistant/ImageAnalyzer/General/MultiMatchImageAnalyzer.cpp +++ b/src/MeoAssistant/ImageAnalyzer/General/MultiMatchImageAnalyzer.cpp @@ -157,12 +157,7 @@ bool asst::MultiMatchImageAnalyzer::multi_match_templ(const cv::Mat templ) } #endif - std::string log_str = "[ "; - for (const auto& res : m_result) { - log_str += res.rect.to_string() + " : " + std::to_string(res.score) + "; "; - } - log_str += "]"; - Log.trace("multi_match_templ | ", m_templ_name, log_str, "roi:", m_roi.to_string()); + Log.trace("multi_match_templ | ", m_templ_name, "result:", m_result, "roi:", m_roi); if (!m_result.empty()) { return true; diff --git a/src/MeoAssistant/Utils/AsstTypes.h b/src/MeoAssistant/Utils/AsstTypes.h index cee0aff934..1043ab3291 100644 --- a/src/MeoAssistant/Utils/AsstTypes.h +++ b/src/MeoAssistant/Utils/AsstTypes.h @@ -38,7 +38,8 @@ namespace asst Point& operator=(Point&&) noexcept = default; Point operator-() const noexcept { return { -x, -y }; } bool operator==(const Point& rhs) const noexcept { return x == rhs.x && y == rhs.y; } - std::string to_string() const { return "[ " + std::to_string(x) + ", " + std::to_string(y) + " ]"; } + std::string to_string() const { return "(" + std::to_string(x) + ", " + std::to_string(y) + ")"; } + explicit operator std::string() const { return to_string(); } static constexpr Point right() { return { 1, 0 }; } static constexpr Point down() { return { 0, 1 }; } static constexpr Point left() { return { -1, 0 }; } @@ -115,11 +116,11 @@ namespace asst } Rect& operator=(const Rect&) noexcept = default; Rect& operator=(Rect&&) noexcept = default; - bool empty() const noexcept { return width == 0 || height == 0; } bool operator==(const Rect& rhs) const noexcept { return x == rhs.x && y == rhs.y && width == rhs.width && height == rhs.height; } + bool empty() const noexcept { return width == 0 || height == 0; } bool include(const Rect& rhs) const noexcept { return x <= rhs.x && y <= rhs.y && (x + width) >= (rhs.x + rhs.width) && @@ -134,6 +135,7 @@ namespace asst return "[ " + std::to_string(x) + ", " + std::to_string(y) + ", " + std::to_string(width) + ", " + std::to_string(height) + " ]"; } + explicit operator std::string() const { return to_string(); } Rect move(Rect move) const { return { x + move.x, y + move.y, move.width, move.height }; } int x = 0; @@ -150,13 +152,16 @@ namespace asst TextRect(TextRect&&) noexcept = default; TextRect(double score, const Rect& rect, const std::string& text) : score(score), rect(rect), text(text) {} - explicit operator std::string() const noexcept { return text; } - explicit operator Rect() const noexcept { return rect; } - std::string to_string() const { return text + " : " + rect.to_string() + ", score: " + std::to_string(score); } TextRect& operator=(const TextRect&) = default; TextRect& operator=(TextRect&&) noexcept = default; bool operator==(const TextRect& rhs) const noexcept { return text == rhs.text && rect == rhs.rect; } bool operator==(const std::string& rhs) const noexcept { return text == rhs; } + explicit operator Rect() const noexcept { return rect; } + std::string to_string() const + { + return "[ " + text + " : " + rect.to_string() + ", score: " + std::to_string(score) + " ]"; + } + explicit operator std::string() const { return to_string(); } double score = 0.0; Rect rect; @@ -184,6 +189,8 @@ namespace asst explicit operator Rect() const noexcept { return rect; } MatchRect& operator=(const MatchRect&) = default; MatchRect& operator=(MatchRect&&) noexcept = default; + std::string to_string() const { return "[ " + rect.to_string() + ", score: " + std::to_string(score) + " ]"; } + explicit operator std::string() const { return to_string(); } double score = 0.0; Rect rect; diff --git a/src/MeoAssistant/Utils/Logger.hpp b/src/MeoAssistant/Utils/Logger.hpp index ca43bb7e10..23e89f0372 100644 --- a/src/MeoAssistant/Utils/Logger.hpp +++ b/src/MeoAssistant/Utils/Logger.hpp @@ -292,12 +292,12 @@ namespace asst #endif // END _WIN32 s << buff; } - else if constexpr (std::convertible_to) { - s << std::forward(v); - } else if constexpr (has_stream_insertion_operator) { s << std::forward(v); } + else if constexpr (std::constructible_from) { + s << std::string(std::forward(v)); + } else if constexpr (ranges::input_range) { s << "["; std::string_view comma_space {}; From a11ccd50abfe34ec70dda08d2207c43f20e72de4 Mon Sep 17 00:00:00 2001 From: zzyyyl Date: Sat, 8 Oct 2022 00:23:27 +0800 Subject: [PATCH 2/3] =?UTF-8?q?perf:=20=E7=BB=A7=E7=BB=AD=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MeoAssistant/Resource/OcrPack.cpp | 18 +++++++----------- src/MeoAssistant/Utils/AsstTypes.h | 7 +++++-- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/MeoAssistant/Resource/OcrPack.cpp b/src/MeoAssistant/Resource/OcrPack.cpp index 83b79c518c..5c83dd9147 100644 --- a/src/MeoAssistant/Resource/OcrPack.cpp +++ b/src/MeoAssistant/Resource/OcrPack.cpp @@ -105,8 +105,7 @@ std::vector asst::OcrPack::recognize(const cv::Mat& image, const } std::vector result; - std::string log_str_raw; - std::string log_str_proc; + std::vector raw_result; #ifdef ASST_DEBUG cv::Mat draw = image.clone(); @@ -121,10 +120,8 @@ std::vector asst::OcrPack::recognize(const cv::Mat& image, const int* box = m_boxes_buffer + i * 8; int x_collect[4] = { *(box + 0), *(box + 2), *(box + 4), *(box + 6) }; int y_collect[4] = { *(box + 1), *(box + 3), *(box + 5), *(box + 7) }; - int left = static_cast(*std::min_element(x_collect, x_collect + 4)); - int right = static_cast(*std::max_element(x_collect, x_collect + 4)); - int top = static_cast(*std::min_element(y_collect, y_collect + 4)); - int bottom = static_cast(*std::max_element(y_collect, y_collect + 4)); + auto [left, right] = ranges::minmax(x_collect); + auto [top, bottom] = ranges::minmax(y_collect); rect = Rect(left, top, right - left, bottom - top); } std::string text(*(m_strs_buffer + i)); @@ -137,15 +134,14 @@ std::vector asst::OcrPack::recognize(const cv::Mat& image, const #ifdef ASST_DEBUG cv::rectangle(draw, utils::make_rect(rect), cv::Scalar(0, 0, 255), 2); #endif - log_str_raw += tr.to_string() + ", "; + raw_result.emplace_back(tr); if (!pred || pred(tr)) { - log_str_proc += tr.to_string() + ", "; result.emplace_back(std::move(tr)); } } - Log.trace("OcrPack::recognize | raw : ", log_str_raw); - Log.trace("OcrPack::recognize | proc : ", log_str_proc); + Log.trace("OcrPack::recognize | raw:", raw_result); + Log.trace("OcrPack::recognize | proc:", result); return result; } @@ -162,7 +158,7 @@ std::vector asst::OcrPack::recognize(const cv::Mat& image, const } return pred(tr); }; - Log.trace("OcrPack::recognize | roi : ", roi.to_string()); + Log.trace("OcrPack::recognize | roi:", roi); cv::Mat roi_img = image(utils::make_rect(roi)); return recognize(roi_img, rect_cor, without_det); } diff --git a/src/MeoAssistant/Utils/AsstTypes.h b/src/MeoAssistant/Utils/AsstTypes.h index 1043ab3291..d99b7ef5a6 100644 --- a/src/MeoAssistant/Utils/AsstTypes.h +++ b/src/MeoAssistant/Utils/AsstTypes.h @@ -159,7 +159,7 @@ namespace asst explicit operator Rect() const noexcept { return rect; } std::string to_string() const { - return "[ " + text + " : " + rect.to_string() + ", score: " + std::to_string(score) + " ]"; + return "{ " + text + ": " + rect.to_string() + ", score: " + std::to_string(score) + " }"; } explicit operator std::string() const { return to_string(); } @@ -189,7 +189,10 @@ namespace asst explicit operator Rect() const noexcept { return rect; } MatchRect& operator=(const MatchRect&) = default; MatchRect& operator=(MatchRect&&) noexcept = default; - std::string to_string() const { return "[ " + rect.to_string() + ", score: " + std::to_string(score) + " ]"; } + std::string to_string() const + { + return "{ rect: " + rect.to_string() + ", score: " + std::to_string(score) + " }"; + } explicit operator std::string() const { return to_string(); } double score = 0.0; From 3e5543f5ef5011cce126118b7c55428b4734b27e Mon Sep 17 00:00:00 2001 From: Horror Proton <107091537+horror-proton@users.noreply.github.com> Date: Sat, 8 Oct 2022 12:51:25 +0800 Subject: [PATCH 3/3] fix: update recruit types, use tag id in penguin stats payload fix https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues/2222 --- src/MeoAssistant/Task/Sub/AutoRecruitTask.cpp | 43 +++++++++---------- src/MeoAssistant/Task/Sub/AutoRecruitTask.h | 6 ++- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/MeoAssistant/Task/Sub/AutoRecruitTask.cpp b/src/MeoAssistant/Task/Sub/AutoRecruitTask.cpp index f6fdddab13..6f43e001fb 100644 --- a/src/MeoAssistant/Task/Sub/AutoRecruitTask.cpp +++ b/src/MeoAssistant/Task/Sub/AutoRecruitTask.cpp @@ -18,14 +18,14 @@ namespace asst::recruit_calc { // all combinations and their operator list, excluding empty set and 6-star operators while there is no senior tag - auto get_all_combs(const std::vector& tags, + auto get_all_combs(const std::vector& tags, const std::vector& all_ops = RecruitData.get_all_opers()) { std::vector rcs_with_single_tag; { rcs_with_single_tag.reserve(tags.size()); - ranges::transform(tags, std::back_inserter(rcs_with_single_tag), [](const std::string& t) { + ranges::transform(tags, std::back_inserter(rcs_with_single_tag), [](const RecruitConfiger::TagId& t) { RecruitCombs result; result.tags = { t }; result.min_level = 6; @@ -86,7 +86,7 @@ namespace asst::recruit_calc static constexpr std::string_view SeniorOper = "高级资深干员"; for (auto comb_iter = result.begin(); comb_iter != result.end();) { - if (ranges::find(comb_iter->tags, SeniorOper) != comb_iter->tags.end()) { + if (ranges::find(comb_iter->tags, RecruitConfiger::TagId(SeniorOper)) != comb_iter->tags.end()) { ++comb_iter; continue; } @@ -350,16 +350,14 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc const std::vector& tags = image_analyzer.get_tags_result(); bool has_refresh = !image_analyzer.get_refresh_rect().empty(); - std::vector tag_names; - ranges::transform(tags, std::back_inserter(tag_names), std::mem_fn(&TextRect::text)); + std::vector tag_ids; + ranges::transform(tags, std::back_inserter(tag_ids), std::mem_fn(&TextRect::text)); bool has_special_tag = false; bool has_robot_tag = false; json::value info = basic_info(); - std::vector tag_name_vector; - ranges::transform(tags, std::back_inserter(tag_name_vector), std::mem_fn(&TextRect::text)); - info["details"]["tags"] = json::array(get_tag_names(tag_name_vector)); + info["details"]["tags"] = json::array(get_tag_names(tag_ids)); // tags result { @@ -369,8 +367,8 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc } // special tags - const std::vector SpecialTags = { "高级资深干员", "资深干员" }; - if (auto special_iter = ranges::find_first_of(SpecialTags, tag_names); special_iter != SpecialTags.cend()) + const std::vector SpecialTags = { "高级资深干员", "资深干员" }; + if (auto special_iter = ranges::find_first_of(SpecialTags, tag_ids); special_iter != SpecialTags.cend()) [[unlikely]] { has_special_tag = true; json::value cb_info = info; @@ -380,9 +378,8 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc } // robot tags - const std::vector RobotTags = { "支援机械" }; - if (auto robot_iter = ranges::find_first_of(RobotTags, tag_names); robot_iter != RobotTags.cend()) - [[unlikely]] { + const std::vector RobotTags = { "支援机械" }; + if (auto robot_iter = ranges::find_first_of(RobotTags, tag_ids); robot_iter != RobotTags.cend()) [[unlikely]] { has_robot_tag = true; json::value cb_info = info; cb_info["what"] = "RecruitSpecialTag"; @@ -390,7 +387,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc callback(AsstMsg::SubTaskExtraInfo, cb_info); } - std::vector result_vec = recruit_calc::get_all_combs(tag_names); + std::vector result_vec = recruit_calc::get_all_combs(tag_ids); // assuming timer would be set to 09:00:00 for (RecruitCombs& rc : result_vec) { @@ -471,7 +468,7 @@ asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc to_report = true; #endif if (to_report) { - upload_result(info["details"]); + upload_result(tag_ids, info["details"]); } if (need_exit()) return {}; @@ -679,25 +676,27 @@ bool asst::AutoRecruitTask::hire_all() std::vector asst::AutoRecruitTask::get_tag_names(const std::vector& ids) const { - std::vector names; + std::vector names; for (const RecruitConfiger::TagId& id : ids) { names.emplace_back(RecruitData.get_tag_name(id)); } return names; } -void asst::AutoRecruitTask::upload_result(const json::value& details) +template +void asst::AutoRecruitTask::upload_result(const Rng& tag_ids, const json::value& yituliu_details) { LogTraceFunction; if (m_upload_to_penguin) { - upload_to_penguin(details); + upload_to_penguin(tag_ids); } if (m_upload_to_yituliu) { - upload_to_yituliu(details); + upload_to_yituliu(yituliu_details); } } -void asst::AutoRecruitTask::upload_to_penguin(const json::value& details) +template +void asst::AutoRecruitTask::upload_to_penguin(Rng&& tags) { LogTraceFunction; @@ -705,10 +704,10 @@ void asst::AutoRecruitTask::upload_to_penguin(const json::value& details) body["server"] = m_server; body["stageId"] = "recruit"; auto& all_drops = body["drops"]; - for (const auto& tag : details.at("tags").as_array()) { + for (const auto& tag : tags) { all_drops.array_emplace(json::object { { "dropType", "NORMAL_DROP" }, - { "itemId", tag.as_string() }, + { "itemId", tag }, { "quantity", 1 }, }); } diff --git a/src/MeoAssistant/Task/Sub/AutoRecruitTask.h b/src/MeoAssistant/Task/Sub/AutoRecruitTask.h index e50c09932c..363fce214a 100644 --- a/src/MeoAssistant/Task/Sub/AutoRecruitTask.h +++ b/src/MeoAssistant/Task/Sub/AutoRecruitTask.h @@ -49,8 +49,10 @@ namespace asst std::vector get_tag_names(const std::vector& ids) const; static std::vector start_recruit_analyze(const cv::Mat& image); - void upload_result(const json::value& details); - void upload_to_penguin(const json::value& details); + template + void upload_result(const Rng& tag_ids, const json::value& details); + template + void upload_to_penguin(Rng&& tag_ids); void upload_to_yituliu(const json::value& details); static void report_penguin_callback(AsstMsg msg, const json::value& detail, void* custom_arg); static void report_yituliu_callback(AsstMsg msg, const json::value& detail, void* custom_arg);