#include "IdentifyOperTask.h" #include #include #include #include #include #include #include #include #include "Configer.h" #include "InfrastConfiger.h" #include "Identify.h" #include "WinMacro.h" #include "Logger.hpp" using namespace asst; asst::IdentifyOperTask::IdentifyOperTask(AsstCallback callback, void* callback_arg) : OcrAbstractTask(callback, callback_arg), m_cropped_height_ratio(0.043), m_cropped_upper_y_ratio(0.480), m_cropped_lower_y_ratio(0.923) { ; } bool asst::IdentifyOperTask::run() { if (m_view_ptr == nullptr || m_identify_ptr == nullptr || m_control_ptr == nullptr) { m_callback(AsstMsg::PtrIsNull, json::value(), m_callback_arg); return false; } auto&& [width, height] = m_view_ptr->getAdbDisplaySize(); m_swipe_begin = Rect(width * 0.9, height * 0.5, 0, 0); m_swipe_end = Rect(width * 0.1, height * 0.5, 0, 0); auto&& detect_ret = swipe_and_detect(); if (!detect_ret) { return false; } const auto& detected_opers = std::move(detect_ret.value()); json::value result_json; std::vector opers_json_vec; for (const auto& [name, info] : detected_opers) { json::value info_json; info_json["name"] = info.name; info_json["elite"] = info.elite; //info_json["level"] = info.level; opers_json_vec.emplace_back(std::move(info_json)); } result_json["all"] = json::array(opers_json_vec); // 查找没有哪些干员(也可能是没识别到) std::vector not_found_vector; for (const std::string& name : InfrastConfiger::get_instance().m_all_opers_name) { auto iter = std::find_if(detected_opers.cbegin(), detected_opers.cend(), [&](const auto& pair) -> bool { return pair.first == name; }); if (iter == detected_opers.cend()) { not_found_vector.emplace_back(name); DebugTrace("Not Found", Utf8ToGbk(name)); } } result_json["not_found"] = json::array(not_found_vector); m_callback(AsstMsg::OpersIdtfResult, result_json, m_callback_arg); return true; } std::optional> asst::IdentifyOperTask::swipe_and_detect() { json::value task_start_json = json::object{ { "task_type", "InfrastStationTask" }, { "task_chain", OcrAbstractTask::m_task_chain}, }; m_callback(AsstMsg::TaskStart, task_start_json, m_callback_arg); std::unordered_map feature_cond = InfrastConfiger::get_instance().m_oper_name_feat; std::unordered_set feature_whatever = InfrastConfiger::get_instance().m_oper_name_feat_whatever; std::unordered_map detected_opers; int times = 0; bool reverse = false; // 一边识别一边滑动,把所有干员名字抓出来 // 正向完整滑一遍,再反向完整滑一遍,提高识别率 while (true) { const cv::Mat& image = OcrAbstractTask::get_format_image(true); // 异步进行滑动操作 std::future swipe_future = std::async( std::launch::async, &IdentifyOperTask::swipe, this, reverse); auto cur_name_textarea = detect_opers(image, feature_cond, feature_whatever); int oper_numer = detected_opers.size(); for (const TextArea& textarea : cur_name_textarea) { int elite = detect_elite(image, textarea.rect); if (elite == -1) { continue; } OperInfrastInfo info; info.elite = elite; info.name = textarea.text; detected_opers.emplace(textarea.text, std::move(info)); } json::value opers_json; std::vector opers_json_vec; for (const auto& [name, info] : detected_opers) { json::value info_json; info_json["name"] = Utf8ToGbk(info.name); info_json["elite"] = info.elite; //info_json["level"] = info.level; opers_json_vec.emplace_back(std::move(info_json)); } opers_json["all"] = json::array(opers_json_vec); m_callback(AsstMsg::OpersDetected, opers_json, m_callback_arg); // 正向滑动的时候 if (!reverse) { ++times; // 说明本次识别一个新的都没识别到,应该是滑动到最后了,直接结束循环 if (oper_numer == detected_opers.size()) { reverse = true; } } else { // 反向滑动的时候 if (--times <= 0) { break; } } // 阻塞等待本次滑动结束 if (!swipe_future.get()) { return std::nullopt; } } return detected_opers; } std::vector