diff --git a/MeoAssistance/include/Assistance.h b/MeoAssistance/include/Assistance.h index e6cf6f1680..a736f0e3d0 100644 --- a/MeoAssistance/include/Assistance.h +++ b/MeoAssistance/include/Assistance.h @@ -29,11 +29,14 @@ namespace asst { // 开始刷理智 void start_sanity(); - // 开始访问基建 + // 开始访问好友基建 void start_visit(); // 开始公开招募操作 void start_open_recruit(const std::vector& required_level, bool set_time = true); + // 开始基建换班任务 + void start_infrast(); + // 开始匹配任务,调试用 void start_match_task(const std::string& task, int retry_times = ProcessTaskRetryTimesDefault, bool block = true); // 开始OCR测试,调试用 diff --git a/MeoAssistance/include/AsstCaller.h b/MeoAssistance/include/AsstCaller.h index d063218e65..cd8dde0fa8 100644 --- a/MeoAssistance/include/AsstCaller.h +++ b/MeoAssistance/include/AsstCaller.h @@ -18,6 +18,7 @@ extern "C" { MEOAPI_PORT void AsstStop(asst::Assistance* p_asst); MEOAPI_PORT bool AsstSetParam(asst::Assistance* p_asst, const char* type, const char* param, const char* value); MEOAPI_PORT bool AsstRunOpenRecruit(asst::Assistance* p_asst, const int required_level[], bool set_time); + MEOAPI_PORT bool AsstStartInfrast(asst::Assistance* p_asst); MEOAPI_PORT bool AsstTestOcr(asst::Assistance* p_asst, const char** text_array, int array_size, bool need_click); MEOAPI_PORT bool CheckVersionUpdate(char* tag_buffer, int tag_bufsize, char* html_url_buffer, int html_bufsize, char* body_buffer, int body_bufsize); diff --git a/MeoAssistance/include/Task.h b/MeoAssistance/include/Task.h index 1f6a482d89..1d00123a15 100644 --- a/MeoAssistance/include/Task.h +++ b/MeoAssistance/include/Task.h @@ -59,8 +59,25 @@ namespace asst { RecruitTagsDetected, OcrResultError, RecruitSpecialTag, - RecruitResult + RecruitResult, + /* Infrast Msg*/ + InfrastOpers, // 识别到基建干员s + InfrastComb // 当前设置的最优干员组合 }; + + // 设施类型 + enum class FacilityType { + Invalid, + Manufacturing, // 制造站 + Trade, // 贸易站 + PowerStation, // 发电站 + ControlInterface, // 控制中枢 + ReceptionRoom, // 会客室 + Dormitory, // 宿舍 + Office // 办公室 + // 训练室和加工站用不上,不加了 + }; + static std::ostream& operator<<(std::ostream& os, const AsstMsg& type) { static const std::unordered_map _type_name = { @@ -85,7 +102,10 @@ namespace asst { {AsstMsg::OcrResultError, "OcrResultError"}, {AsstMsg::RecruitSpecialTag, "RecruitSpecialTag"}, {AsstMsg::RecruitResult, "RecruitResult"}, - {AsstMsg::AppendTask, "AppendTask"} + {AsstMsg::AppendTask, "AppendTask"}, + {AsstMsg::InfrastOpers, "InfrastOpers"}, + {AsstMsg::InfrastComb, "InfrastComb"} + }; return os << _type_name.at(type); } @@ -236,6 +256,33 @@ namespace asst { bool m_set_time = false; }; + // 基建进驻任务 + class InfrastStationTask : public OcrAbstractTask + { + public: + InfrastStationTask(AsstCallback callback, void* callback_arg); + virtual ~InfrastStationTask() = default; + + virtual bool run() override; + void set_swipe_param(int delay, const Rect& begin_rect, const Rect& end_rect, int max_times = 20) + { + m_swipe_delay = delay; + m_swipe_begin = begin_rect; + m_swipe_end = end_rect; + m_swipe_max_times = max_times; + } + void set_facility(FacilityType facility) + { + m_facility = facility; + } + private: + FacilityType m_facility = FacilityType::Invalid; + int m_swipe_delay = 0; + Rect m_swipe_begin; + Rect m_swipe_end; + int m_swipe_max_times = 0; + }; + // for debug class TestOcrTask : public OcrAbstractTask { diff --git a/MeoAssistance/src/Assistance.cpp b/MeoAssistance/src/Assistance.cpp index 916b61b022..06bc0170fb 100644 --- a/MeoAssistance/src/Assistance.cpp +++ b/MeoAssistance/src/Assistance.cpp @@ -214,6 +214,27 @@ void Assistance::start_open_recruit(const std::vector& required_level, bool m_condvar.notify_one(); } +void asst::Assistance::start_infrast() +{ + DebugTraceFunction; + if (!m_thread_idle || !m_inited) + { + return; + } + + std::unique_lock lock(m_mutex); + + auto task_ptr = std::make_shared(task_callback, (void*)this); + // TODO 这个参数写到配置文件里 + task_ptr->set_swipe_param(2000, Rect(600, 300, 0, 0), Rect(450, 300, 0, 0), 20); + task_ptr->set_facility(FacilityType::Manufacturing); + task_ptr->set_task_chain("Infrast"); + m_tasks_queue.emplace(task_ptr); + + m_thread_idle = false; + m_condvar.notify_one(); +} + void Assistance::stop(bool block) { DebugTraceFunction; diff --git a/MeoAssistance/src/AsstCaller.cpp b/MeoAssistance/src/AsstCaller.cpp index eda8d53193..e65172c73e 100644 --- a/MeoAssistance/src/AsstCaller.cpp +++ b/MeoAssistance/src/AsstCaller.cpp @@ -111,6 +111,15 @@ bool AsstRunOpenRecruit(asst::Assistance* p_asst, const int required_level[], bo return true; } +bool AsstStartInfrast(asst::Assistance* p_asst) +{ + if (p_asst == NULL) { + return false; + } + p_asst->start_infrast(); + return true; +} + bool AsstTestOcr(asst::Assistance* p_asst, const char** text_array, int array_size, bool need_click) { if (p_asst == NULL || text_array == nullptr) { diff --git a/MeoAssistance/src/Task.cpp b/MeoAssistance/src/Task.cpp index 85695a199a..31719e27fb 100644 --- a/MeoAssistance/src/Task.cpp +++ b/MeoAssistance/src/Task.cpp @@ -791,4 +791,146 @@ bool TestOcrTask::run() //} return true; -} \ No newline at end of file +} + +asst::InfrastStationTask::InfrastStationTask(AsstCallback callback, void* callback_arg) + : OcrAbstractTask(callback, callback_arg) +{ +} + +bool asst::InfrastStationTask::run() +{ + if (m_view_ptr == NULL + || m_identify_ptr == NULL) + { + m_callback(AsstMsg::PtrIsNull, json::value(), m_callback_arg); + return false; + } + + std::vector> all_oper_combs; // 所有的干员组合 + std::unordered_set all_oper_name; // 所有干员名 + std::string oper_end_flag; // 干员名结束标记,识别到这个string就认为识别完成了 + + switch (m_facility) { + case FacilityType::Manufacturing: + all_oper_combs = InfrastConfiger::get_instance().m_mfg_combs; + all_oper_name = InfrastConfiger::get_instance().m_mfg_opers; + oper_end_flag = InfrastConfiger::get_instance().m_mfg_end; + break; + // TODO 贸易站和其他啥的,有空再做 + default: + break; + } + + json::value task_start_json = json::object{ + { "task_type", "InfrastStationTask" }, + { "task_chain", m_task_chain}, + }; + m_callback(AsstMsg::TaskStart, task_start_json, m_callback_arg); + + auto swipe_foo = [&](bool reverse = false) -> bool { + bool ret = false; + if (!reverse) { + ret = m_control_ptr->swipe(m_swipe_begin, m_swipe_end); + } + else { + ret = m_control_ptr->swipe(m_swipe_end, m_swipe_begin); + } + ret &= sleep(m_swipe_delay); + return ret; + }; + + // 识别到的干员名 + std::unordered_set detected_names; + + // 一边识别一边滑动,把所有制造站干员名字抓出来 + for (int i = 0; i != m_swipe_max_times; ++i) { + const cv::Mat& image = get_format_image(); + // 异步进行滑动操作 + std::future swipe_future = std::async(std::launch::async, swipe_foo); + + std::vector