整理目录结构,分离Task

This commit is contained in:
MistEO
2021-08-20 16:24:04 +08:00
parent 9d15b33b50
commit 2af89dfed6
46 changed files with 1717 additions and 1854 deletions

View File

@@ -0,0 +1,270 @@
#include "ProcessTask.h"
#include <chrono>
#include <random>
#include <opencv2/opencv.hpp>
#include "AsstAux.h"
#include "Configer.h"
#include "WinMacro.h"
#include "Identify.h"
using namespace asst;
ProcessTask::ProcessTask(AsstCallback callback, void* callback_arg)
: OcrAbstractTask(callback, callback_arg)
{
m_task_type = TaskType::TaskTypeRecognition | TaskType::TaskTypeClick;
}
bool ProcessTask::run()
{
if (m_view_ptr == NULL
|| m_control_ptr == NULL
|| m_identify_ptr == NULL
|| m_control_ptr == NULL)
{
m_callback(AsstMsg::PtrIsNull, json::value(), m_callback_arg);
return false;
}
json::value task_start_json = json::object{
{ "task_type", "ProcessTask" },
{ "task_chain", m_task_chain},
};
m_callback(AsstMsg::TaskStart, task_start_json, m_callback_arg);
std::shared_ptr<TaskInfo> task_info_ptr = nullptr;
Rect rect;
task_info_ptr = match_image(&rect);
if (!task_info_ptr) {
return false;
}
json::value callback_json = json::object{
{ "name", task_info_ptr->name },
{ "type", static_cast<int>(task_info_ptr->type) },
{ "exec_times", task_info_ptr->exec_times },
{ "max_times", task_info_ptr->max_times },
{ "task_type", "ProcessTask"},
{ "algorithm", static_cast<int>(task_info_ptr->algorithm)}
};
m_callback(AsstMsg::TaskMatched, callback_json, m_callback_arg);
if (task_info_ptr->exec_times >= task_info_ptr->max_times)
{
m_callback(AsstMsg::ReachedLimit, callback_json, m_callback_arg);
json::value next_json = callback_json;
next_json["tasks"] = json::array(task_info_ptr->exceeded_next);
next_json["retry_times"] = m_retry_times;
next_json["task_chain"] = m_task_chain;
m_callback(AsstMsg::AppendProcessTask, next_json, m_callback_arg);
return true;
}
// 前置固定延时
if (!sleep(task_info_ptr->pre_delay))
{
return false;
}
bool need_stop = false;
switch (task_info_ptr->type) {
case ProcessTaskType::ClickRect:
rect = task_info_ptr->specific_area;
[[fallthrough]];
case ProcessTaskType::ClickSelf:
exec_click_task(rect);
break;
case ProcessTaskType::DoNothing:
break;
case ProcessTaskType::Stop:
m_callback(AsstMsg::TaskStop, json::object{ {"task_chain", m_task_chain} }, m_callback_arg);
need_stop = true;
break;
case ProcessTaskType::PrintWindow:
{
if (!sleep(Configer::get_instance().m_options.print_window_delay))
{
return false;
}
static const std::string dirname = GetCurrentDir() + "screenshot\\";
print_window(dirname);
}
break;
default:
break;
}
++task_info_ptr->exec_times;
// 减少其他任务的执行次数
// 例如,进入吃理智药的界面了,相当于上一次点蓝色开始行动没生效
// 所以要给蓝色开始行动的次数减一
for (const std::string& reduce : task_info_ptr->reduce_other_times) {
--Configer::get_instance().m_all_tasks_info[reduce]->exec_times;
}
if (need_stop) {
return true;
}
callback_json["exec_times"] = task_info_ptr->exec_times;
m_callback(AsstMsg::TaskCompleted, callback_json, m_callback_arg);
// 后置固定延时
if (!sleep(task_info_ptr->rear_delay)) {
return false;
}
json::value next_json = callback_json;
next_json["task_chain"] = m_task_chain;
next_json["retry_times"] = m_retry_times;
next_json["tasks"] = json::array(task_info_ptr->next);
m_callback(AsstMsg::AppendProcessTask, next_json, m_callback_arg);
return true;
}
std::shared_ptr<TaskInfo> ProcessTask::match_image(Rect* matched_rect)
{
//// 如果当前仅有一个任务且这个任务的阈值是0说明是justreturn的就不抓图像识别了直接返回就行
//if (m_cur_tasks_name.size() == 1)
//{
// // 能走到这个函数里的肯定是ProcessTaskInfo直接转
// auto task_info_ptr = std::dynamic_pointer_cast<MatchTaskInfo>(
// Configer::get_instance().m_all_tasks_info[m_cur_tasks_name[0]]);
// if (task_info_ptr->templ_threshold == 0) {
// json::value callback_json;
// callback_json["threshold"] = 0.0;
// callback_json["algorithm"] = "JustReturn";
// callback_json["rect"] = json::array({ 0, 0, 0, 0 });
// callback_json["name"] = m_cur_tasks_name[0];
// callback_json["algorithm_id"] = static_cast<std::underlying_type<ProcessTaskType>::type>(
// AlgorithmType::JustReturn);
// callback_json["value"] = 0;
// m_callback(AsstMsg::ImageFindResult, callback_json, m_callback_arg);
// m_callback(AsstMsg::ImageMatched, callback_json, m_callback_arg);
// return task_info_ptr;
// }
//}
const cv::Mat& cur_image = get_format_image();
if (cur_image.empty() || cur_image.rows < 100) {
return nullptr;
}
// 逐个匹配当前可能的任务
for (const std::string& task_name : m_cur_tasks_name) {
std::shared_ptr<TaskInfo> task_info_ptr = Configer::get_instance().m_all_tasks_info[task_name];
if (task_info_ptr == nullptr) {
m_callback(AsstMsg::PtrIsNull, json::value(), m_callback_arg);
continue;
}
json::value callback_json;
bool matched = false;
Rect rect;
switch (task_info_ptr->algorithm)
{
case AlgorithmType::JustReturn:
callback_json["algorithm"] = "JustReturn";
matched = true;
break;
case AlgorithmType::MatchTemplate:
{
std::shared_ptr<MatchTaskInfo> process_task_info_ptr =
std::dynamic_pointer_cast<MatchTaskInfo>(task_info_ptr);
double templ_threshold = process_task_info_ptr->templ_threshold;
double hist_threshold = process_task_info_ptr->hist_threshold;
auto&& [algorithm, value, temp_rect] = m_identify_ptr->find_image(cur_image, task_name, templ_threshold);
rect = std::move(temp_rect);
callback_json["value"] = value;
if (algorithm == AlgorithmType::MatchTemplate) {
callback_json["threshold"] = templ_threshold;
callback_json["algorithm"] = "MatchTemplate";
if (value >= templ_threshold) {
matched = true;
}
}
else if (algorithm == AlgorithmType::CompareHist) {
callback_json["threshold"] = hist_threshold;
callback_json["algorithm"] = "CompareHist";
if (value >= hist_threshold) {
matched = true;
}
}
else {
continue;
}
}
break;
case AlgorithmType::OcrDetect:
{
std::shared_ptr<OcrTaskInfo> ocr_task_info_ptr =
std::dynamic_pointer_cast<OcrTaskInfo>(task_info_ptr);
std::vector<TextArea> all_text_area = ocr_detect(cur_image);
std::vector<TextArea> match_result;
if (ocr_task_info_ptr->need_match) {
match_result = text_match(all_text_area,
ocr_task_info_ptr->text, ocr_task_info_ptr->replace_map);
}
else {
match_result = text_search(all_text_area,
ocr_task_info_ptr->text, ocr_task_info_ptr->replace_map);
}
// TODO如果搜出来多个结果怎么处理
// 暂时通过配置文件保证尽量只搜出来一个结果or一个都搜不到
if (!match_result.empty()) {
callback_json["text"] = Utf8ToGbk(match_result.at(0).text);
rect = match_result.at(0).rect;
matched = true;
}
}
break;
//CompareHist是MatchTemplate的衍生算法不应作为单独的配置参数出现
//case AlgorithmType::CompareHist:
// break;
default:
// TODO抛个报错的回调出去
break;
}
callback_json["elite_rect"] = json::array({ rect.x, rect.y, rect.width, rect.height });
callback_json["name"] = task_name;
if (matched_rect != NULL) {
*matched_rect = std::move(rect);
}
m_callback(AsstMsg::ImageFindResult, callback_json, m_callback_arg);
if (matched) {
m_callback(AsstMsg::ImageMatched, callback_json, m_callback_arg);
return task_info_ptr;
}
}
return nullptr;
}
void ProcessTask::exec_click_task(const Rect& matched_rect)
{
// 随机延时功能
if (Configer::get_instance().m_options.control_delay_upper != 0) {
static std::default_random_engine rand_engine(
std::chrono::system_clock::now().time_since_epoch().count());
static std::uniform_int_distribution<unsigned> rand_uni(
Configer::get_instance().m_options.control_delay_lower,
Configer::get_instance().m_options.control_delay_upper);
unsigned rand_delay = rand_uni(rand_engine);
if (!sleep(rand_delay)) {
return;
}
}
m_control_ptr->click(matched_rect);
}