diff --git a/MeoAssistance/include/Assistance.h b/MeoAssistance/include/Assistance.h index 8f5fc9bb0a..03bd5d9dca 100644 --- a/MeoAssistance/include/Assistance.h +++ b/MeoAssistance/include/Assistance.h @@ -20,7 +20,7 @@ namespace asst { ~Assistance(); std::optional setSimulator(const std::string & simulator_name = std::string()); - + void start(const std::string & task); void stop(); diff --git a/MeoAssistance/include/AsstDef.h b/MeoAssistance/include/AsstDef.h index 913419091e..30bc9be0d6 100644 --- a/MeoAssistance/include/AsstDef.h +++ b/MeoAssistance/include/AsstDef.h @@ -1,9 +1,9 @@ #pragma once -#include "json_value.h" -#include "json_array.h" - #include +#include +#include +#include #include #include @@ -34,8 +34,8 @@ namespace asst { } Rect center_zoom(double scale) { - int half_width_scale = static_cast(width * (1- scale) / 2) ; - int half_hight_scale = static_cast(height * (1 - scale) / 2) ; + int half_width_scale = static_cast(width * (1 - scale) / 2); + int half_hight_scale = static_cast(height * (1 - scale) / 2); return { x + half_width_scale, y + half_hight_scale, width - half_width_scale, height - half_hight_scale }; } int x = 0; @@ -44,36 +44,61 @@ namespace asst { int height = 0; }; - static Rect jsonToRect(const json::array& arr) + static std::string GetCurrentDir() { - if (arr.size() != 4) { - return { 0, 0, 0, 0 }; + static std::string cur_dir; + if (cur_dir.empty()) { + char exepath_buff[_MAX_PATH] = { 0 }; + ::GetModuleFileNameA(NULL, exepath_buff, _MAX_PATH); + std::string exepath(exepath_buff); + cur_dir = exepath.substr(0, exepath.find_last_of('\\') + 1); } - return Rect(arr[0].as_integer(), arr[1].as_integer(), arr[2].as_integer(), arr[3].as_integer()); + return cur_dir; + } + static std::string GetResourceDir() + { + static std::string res_dir = GetCurrentDir() + "resource\\"; + return res_dir; } + inline void StreamArgs(std::ostream& os) + { + os << std::endl; + } + template + inline void StreamArgs(std::ostream& os, T&& first, Args && ...rest) + { + os << first << " "; + StreamArgs(os, std::forward(rest)...); + } template void DebugPrint(const std::string& level, Args &&... args) { static std::mutex trace_mutex; std::unique_lock trace_lock(trace_mutex); +#ifdef _DEBUG + auto & out_stream = std::cout; +#else + std::ofstream out_stream(GetCurrentDir() + "asst.log", std::ios::out | std::ios::app); +#endif SYSTEMTIME curtime; GetLocalTime(&curtime); - printf("[%04d-%02d-%02d %02d:%02d:%02d.%03d][%s][Px%x][Tx%x] ", + char buff[64] = { 0 }; + sprintf_s(buff, "[%04d-%02d-%02d %02d:%02d:%02d.%03d][%s][Px%x][Tx%x]", curtime.wYear, curtime.wMonth, curtime.wDay, curtime.wHour, curtime.wMinute, curtime.wSecond, curtime.wMilliseconds, level.c_str(), _getpid(), GetCurrentThreadId()); - printf(std::forward(args)...); - printf("\n"); + + StreamArgs(out_stream, buff, std::forward(args)...); } template inline void DebugTrace(Args &&... args) { -//#ifdef _DEBUG + //#ifdef _DEBUG DebugPrint("TRC", std::forward(args)...); -//#endif + //#endif } template inline void DebugTraceInfo(Args &&... args) diff --git a/MeoAssistance/include/Configer.h b/MeoAssistance/include/Configer.h index 785eb2cbec..7f9e8d9a84 100644 --- a/MeoAssistance/include/Configer.h +++ b/MeoAssistance/include/Configer.h @@ -3,6 +3,7 @@ #include #include #include +#include "AsstDef.h" namespace asst { struct HandleInfo { @@ -23,7 +24,8 @@ namespace asst { ClickSelf, ClickRand, DoNothing, - Stop + Stop, + ClickRect }; struct TaskInfo { @@ -31,8 +33,11 @@ namespace asst { double threshold = 0; TaskType type; std::vector next; - unsigned int exec_times = 0; - unsigned int max_times = UINT_MAX; + int exec_times = 0; + int max_times = INT_MAX; + asst::Rect specific_area; + int pre_delay = 0; + int rear_delay = 0; }; struct Options { std::string delayType; @@ -46,8 +51,6 @@ namespace asst { ~Configer() = default; static bool reload(); - static std::string getCurDir(); - static std::string getResDir(); static std::string m_version; static Options m_options; diff --git a/MeoAssistance/src/Assistance.cpp b/MeoAssistance/src/Assistance.cpp index 186ffb726e..a30e30683d 100644 --- a/MeoAssistance/src/Assistance.cpp +++ b/MeoAssistance/src/Assistance.cpp @@ -13,7 +13,7 @@ Assistance::Assistance() m_pIder = std::make_shared(); for (auto&& [name, info] : Configer::m_tasks) { - m_pIder->addImage(name, Configer::getResDir() + info.filename); + m_pIder->addImage(name, GetResourceDir() + info.filename); } m_pIder->setUseCache(Configer::m_options.cache); @@ -115,10 +115,10 @@ void Assistance::workingProc(Assistance* pThis) for (auto&& task_name : pThis->m_next_tasks) { double threshold = Configer::m_tasks[task_name].threshold; auto&& [algorithm, value, rect] = pThis->m_pIder->findImage(curImg, task_name, threshold); - DebugTrace("%-20s Type:%d, Value:%f", task_name.c_str(), algorithm, value); + DebugTrace(task_name, "Type:", algorithm, "Value:", value); if (algorithm == 0 || (algorithm == 1 && value >= threshold) - || (algorithm == 2 && value >= 0.9999)) { + || (algorithm == 2 && value >= 0.9998)) { matched_task = task_name; matched_rect = rect; break; @@ -127,12 +127,17 @@ void Assistance::workingProc(Assistance* pThis) if (!matched_task.empty()) { auto && task = Configer::m_tasks[matched_task]; - DebugTraceInfo("Matched: %s, Type: %d", matched_task.c_str(), task.type); - + DebugTraceInfo("Matched:", matched_task, "Type:", static_cast(task.type)); + if (task.pre_delay > 0) { + DebugTrace("PreDelay", task.pre_delay); + std::this_thread::sleep_for(std::chrono::milliseconds(task.pre_delay)); + } switch (task.type) { + case TaskType::ClickRect: + matched_rect = task.specific_area; case TaskType::ClickSelf: - if (task.max_times != UINT_MAX) { - DebugTrace("CurTimes: %d, MaxTimes: %d", task.exec_times, task.max_times); + if (task.max_times != INT_MAX) { + DebugTrace("CurTimes:", task.exec_times, "MaxTimes:", task.max_times); } if (task.exec_times >= task.max_times) { DebugTraceInfo("Reached limit, Stop."); @@ -155,19 +160,23 @@ void Assistance::workingProc(Assistance* pThis) continue; break; default: - DebugTraceError("Unknown option type: %d", task.type); + DebugTraceError("Unknown option type:", static_cast(task.type)); break; } + if (task.rear_delay > 0) { + DebugTrace("RearDelay", task.rear_delay); + std::this_thread::sleep_for(std::chrono::milliseconds(task.rear_delay)); + } pThis->m_next_tasks = Configer::m_tasks[matched_task].next; - std::string nexts; + std::string nexts_str; for (auto&& name : pThis->m_next_tasks) { - nexts += name + ","; + nexts_str += name + ","; } - if (nexts.back() == ',') { - nexts.pop_back(); + if (nexts_str.back() == ',') { + nexts_str.pop_back(); } - DebugTrace("Next: %s", nexts.c_str()); + DebugTrace("Next:", nexts_str); } pThis->m_condvar.wait_for(lock, std::chrono::milliseconds(Configer::m_options.delayFixedTime)); } diff --git a/MeoAssistance/src/Configer.cpp b/MeoAssistance/src/Configer.cpp index 18362d4b42..90586abe05 100644 --- a/MeoAssistance/src/Configer.cpp +++ b/MeoAssistance/src/Configer.cpp @@ -18,7 +18,7 @@ std::unordered_map Configer::m_handles; bool Configer::reload() { - std::string filename = getResDir() + "config.json"; + std::string filename = GetResourceDir() + "config.json"; std::ifstream ifs(filename, std::ios::in); if (!ifs.is_open()) { return false; @@ -62,13 +62,30 @@ bool Configer::reload() else if (type == "stop") { task_info.type = TaskType::Stop; } + else if (type == "clickrect") { + task_info.type = TaskType::ClickRect; + auto area_json = task_json["specificArea"].as_array(); + task_info.specific_area = Rect( + area_json[0].as_integer(), + area_json[1].as_integer(), + area_json[2].as_integer(), + area_json[3].as_integer()); + } else { - DebugTraceError("Task: %s 's type error: %s", name.c_str(), type.c_str()); + DebugTraceError("Task:", name, "error:", type); return false; } if (task_json.as_object().exist("maxTimes")) { task_info.max_times = task_json["maxTimes"].as_integer(); } + if (task_json.as_object().exist("preDelay")) { + task_info.pre_delay = task_json["preDelay"].as_integer(); + } + if (task_json.as_object().exist("rearDelay")) { + task_info.rear_delay = task_json["rearDelay"].as_integer(); + } + + auto next_arr = task_json["next"].as_array(); for (auto&& name : next_arr) { task_info.next.emplace_back(name.as_string()); @@ -111,7 +128,7 @@ bool Configer::reload() } } catch (json::exception& e) { - DebugTraceError("Load config json error!: %s", e.what()); + DebugTraceError("Load config json error!", e.what()); return false; } @@ -139,8 +156,11 @@ bool Configer::setParam(const std::string& type, const std::string& param, const else if (type == "stop") { task_info.type = TaskType::Stop; } + else if (type == "clickrect") { + task_info.type = TaskType::ClickRect; + } else { - DebugTraceError("Task: %s 's type error: %s", param.c_str(), type.c_str()); + DebugTraceError("Task", param, "'s type error:", type); return false; } } @@ -151,20 +171,4 @@ bool Configer::setParam(const std::string& type, const std::string& param, const m_tasks[param].max_times = std::stoi(value); } return true; -} - -std::string Configer::getCurDir() -{ - if (m_curDir.empty()) { - char exepath_buff[_MAX_PATH] = { 0 }; - ::GetModuleFileNameA(NULL, exepath_buff, _MAX_PATH); - std::string exepath(exepath_buff); - m_curDir = exepath.substr(0, exepath.find_last_of('\\') + 1); - } - return m_curDir; -} - -std::string Configer::getResDir() -{ - return getCurDir() + "resource\\"; -} +} \ No newline at end of file diff --git a/MeoAssistance/src/Identify.cpp b/MeoAssistance/src/Identify.cpp index 70fc907e24..4d1bc8466c 100644 --- a/MeoAssistance/src/Identify.cpp +++ b/MeoAssistance/src/Identify.cpp @@ -82,7 +82,7 @@ std::tuple Identify::findImage(const Mat& cur, const st auto&& templ_mat = m_mat_map.at(templ); auto&& [value, point] = findImage(cur, templ_mat); cv::Rect raw_rect(point.x, point.y, templ_mat.cols, templ_mat.rows); - + if (m_use_cache && value >= threshold) { m_cache_map.emplace(templ, std::make_pair(raw_rect, image2Hist(cur(raw_rect)))); } diff --git a/MeoAssistance/src/WinMacro.cpp b/MeoAssistance/src/WinMacro.cpp index 38a1c78c04..e3651da858 100644 --- a/MeoAssistance/src/WinMacro.cpp +++ b/MeoAssistance/src/WinMacro.cpp @@ -45,7 +45,7 @@ bool WinMacro::findHandle() handle_vec = info.control; break; default: - DebugTraceError("Handle type error!: %d", m_handle_type); + DebugTraceError("Handle type error!", static_cast(m_handle_type)); return false; } @@ -78,7 +78,7 @@ bool WinMacro::findHandle() } } - DebugTrace("Handle: 0x%x, Name: %s, Type: %d", m_handle, m_simulator_name.c_str(), m_handle_type); + DebugTrace("Handle:", m_handle, "Name:", m_simulator_name, "Type:", static_cast(m_handle_type)); if (m_handle != NULL) { return true; @@ -166,7 +166,7 @@ bool WinMacro::click(const Point& p) int x = (p.x + m_xOffset) / getScreenScale(); int y = (p.y + m_yOffset) / getScreenScale(); - DebugTrace("click, raw: %d, %d, cor: %d, %d", p.x, p.y, x, y); + DebugTrace("click, raw:", p.x, p.y, "cor:", x, y); LPARAM lparam = MAKELPARAM(x, y); @@ -242,10 +242,12 @@ cv::Mat WinMacro::getImage(const Rect& rect) DeleteDC(memDC); ReleaseDC(m_handle, pDC); +/* #ifdef _DEBUG - std::string filename = Configer::getCurDir() + "\\test.bmp"; + std::string filename = GetCurrentDir() + "\\print.bmp"; cv::imwrite(filename, dst_mat); #endif +*/ return dst_mat; } \ No newline at end of file diff --git a/Tools/Sanity/main.cpp b/Tools/Sanity/main.cpp index e39513d9e1..ca20e979a8 100644 --- a/Tools/Sanity/main.cpp +++ b/Tools/Sanity/main.cpp @@ -13,7 +13,7 @@ int main(int argc, char** argv) return -1; } else { - DebugTraceInfo("Find Simulator: %s", ret->c_str()); + DebugTraceInfo("Find Simulator:", ret.value()); } DebugTraceInfo("Start"); diff --git a/resource/config.json b/resource/config.json index 0d9e1e52ff..70d3005914 100644 --- a/resource/config.json +++ b/resource/config.json @@ -3,7 +3,7 @@ "options": { "delay": { "type": "fixedTime", - "fixedTime": 1000 + "fixedTime": 200 }, "cache": true }, @@ -188,13 +188,14 @@ "filename": "StartButton2.png", "threshold": 0.99, "type": "clickSelf", + "rearDelay": 10000, "next": [ "PRTS" ] }, "PRTS": { "filename": "PRTS.png", - "threshold": 0.98, + "threshold": 0.99, "type": "doNothing", "next": [ "PRTS", @@ -205,12 +206,27 @@ "Random": { "filename": "", "threshold": 0, - "type": "clickRand", + "type": "clickRect", + "specificArea": [ + 1100, + 700, + 150, + 30 + ], "next": [ + "Loading", "StartButton1", "Random" ] }, + "Loading": { + "filename": "Loading.png", + "threshold": 0.99, + "type": "doNothing", + "next": [ + "StartButton1" + ] + }, "UseMedicine": { "filename": "UseMedicine.png", "threshold": 0.99, @@ -308,7 +324,7 @@ }, "VisitNext": { "filename": "VisitNext.png", - "threshold": 0.98, + "threshold": 0.999, "type": "clickSelf", "maxTimes": 10, "next": [