mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-19 02:23:01 +08:00
Merge branch 'dev' of https://github.com/MaaAssistantArknights/MaaAssistantArknights into dev
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -105,8 +105,7 @@ std::vector<asst::TextRect> asst::OcrPack::recognize(const cv::Mat& image, const
|
||||
}
|
||||
|
||||
std::vector<TextRect> result;
|
||||
std::string log_str_raw;
|
||||
std::string log_str_proc;
|
||||
std::vector<TextRect> raw_result;
|
||||
|
||||
#ifdef ASST_DEBUG
|
||||
cv::Mat draw = image.clone();
|
||||
@@ -121,10 +120,8 @@ std::vector<asst::TextRect> asst::OcrPack::recognize(const cv::Mat& image, const
|
||||
int* box = m_boxes_buffer + i * 8;
|
||||
int x_collect[4] = { *(box + 0), *(box + 2), *(box + 4), *(box + 6) };
|
||||
int y_collect[4] = { *(box + 1), *(box + 3), *(box + 5), *(box + 7) };
|
||||
int left = static_cast<int>(*std::min_element(x_collect, x_collect + 4));
|
||||
int right = static_cast<int>(*std::max_element(x_collect, x_collect + 4));
|
||||
int top = static_cast<int>(*std::min_element(y_collect, y_collect + 4));
|
||||
int bottom = static_cast<int>(*std::max_element(y_collect, y_collect + 4));
|
||||
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::TextRect> asst::OcrPack::recognize(const cv::Mat& image, const
|
||||
#ifdef ASST_DEBUG
|
||||
cv::rectangle(draw, utils::make_rect<cv::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::TextRect> 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<cv::Rect>(roi));
|
||||
return recognize(roi_img, rect_cor, without_det);
|
||||
}
|
||||
|
||||
@@ -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<std::string>& tags,
|
||||
auto get_all_combs(const std::vector<RecruitConfiger::TagId>& tags,
|
||||
const std::vector<RecruitOperInfo>& all_ops = RecruitData.get_all_opers())
|
||||
{
|
||||
std::vector<RecruitCombs> 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<TextRect>& tags = image_analyzer.get_tags_result();
|
||||
bool has_refresh = !image_analyzer.get_refresh_rect().empty();
|
||||
|
||||
std::vector<std::string> tag_names;
|
||||
ranges::transform(tags, std::back_inserter(tag_names), std::mem_fn(&TextRect::text));
|
||||
std::vector<RecruitConfiger::TagId> 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<std::string> 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<std::string> SpecialTags = { "高级资深干员", "资深干员" };
|
||||
if (auto special_iter = ranges::find_first_of(SpecialTags, tag_names); special_iter != SpecialTags.cend())
|
||||
const std::vector<RecruitConfiger::TagId> 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<std::string> RobotTags = { "支援机械" };
|
||||
if (auto robot_iter = ranges::find_first_of(RobotTags, tag_names); robot_iter != RobotTags.cend())
|
||||
[[unlikely]] {
|
||||
const std::vector<RecruitConfiger::TagId> 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<RecruitCombs> result_vec = recruit_calc::get_all_combs(tag_names);
|
||||
std::vector<RecruitCombs> 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<std::string> asst::AutoRecruitTask::get_tag_names(const std::vector<RecruitConfiger::TagId>& ids) const
|
||||
{
|
||||
std::vector<RecruitConfiger::TagId> names;
|
||||
std::vector<std::string> 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 <typename Rng>
|
||||
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 <typename Rng>
|
||||
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 },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -49,8 +49,10 @@ namespace asst
|
||||
std::vector<std::string> get_tag_names(const std::vector<RecruitConfiger::TagId>& ids) const;
|
||||
static std::vector<TextRect> start_recruit_analyze(const cv::Mat& image);
|
||||
|
||||
void upload_result(const json::value& details);
|
||||
void upload_to_penguin(const json::value& details);
|
||||
template <typename Rng>
|
||||
void upload_result(const Rng& tag_ids, const json::value& details);
|
||||
template <typename Rng>
|
||||
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);
|
||||
|
||||
@@ -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,11 @@ 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: " + rect.to_string() + ", score: " + std::to_string(score) + " }";
|
||||
}
|
||||
explicit operator std::string() const { return to_string(); }
|
||||
|
||||
double score = 0.0;
|
||||
Rect rect;
|
||||
|
||||
@@ -292,12 +292,12 @@ namespace asst
|
||||
#endif // END _WIN32
|
||||
s << buff;
|
||||
}
|
||||
else if constexpr (std::convertible_to<T, std::string_view>) {
|
||||
s << std::forward<T>(v);
|
||||
}
|
||||
else if constexpr (has_stream_insertion_operator<Stream, T>) {
|
||||
s << std::forward<T>(v);
|
||||
}
|
||||
else if constexpr (std::constructible_from<std::string, T>) {
|
||||
s << std::string(std::forward<T>(v));
|
||||
}
|
||||
else if constexpr (ranges::input_range<T>) {
|
||||
s << "[";
|
||||
std::string_view comma_space {};
|
||||
|
||||
Reference in New Issue
Block a user