diff --git a/include/AsstCaller.h b/include/AsstCaller.h index d643e569bd..f644354d57 100644 --- a/include/AsstCaller.h +++ b/include/AsstCaller.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "AsstPort.h" @@ -28,7 +28,7 @@ extern "C" { bool ASSTAPI AsstAppendMall(asst::Assistant* p_asst, bool with_shopping); // bool ASSTAPI AsstAppendProcessTask(asst::Assistant* p_asst, const char* task_name); bool ASSTAPI AsstAppendInfrast(asst::Assistant* p_asst, int work_mode, const char** order, int order_size, const char* uses_of_drones, double dorm_threshold); - bool ASSTAPI AsstAppendRecruit(asst::Assistant* p_asst, int max_times, const int select_level[], int select_len, const int confirm_level[], int confirm_len, bool need_refresh); + bool ASSTAPI AsstAppendRecruit(asst::Assistant* p_asst, int max_times, const int select_level[], int select_len, const int confirm_level[], int confirm_len, bool need_refresh, bool use_expedited); bool ASSTAPI AsstAppendDebug(asst::Assistant* p_asst); bool ASSTAPI AsstStartRecruitCalc(asst::Assistant* p_asst, const int select_level[], int required_len, bool set_time); diff --git a/resource/tasks.json b/resource/tasks.json index 562d6c9d1e..a4acd451e1 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -904,6 +904,36 @@ ], "action": "Stop" }, + "RecruitNow": { + "algorithm": "OcrDetect", + "action": "clickSelf", + "rearDelay": 500, + "cache": false, + "text": [ + "立即招" + ], + "roi": [ + 0, + 300, + 1280, + 420 + ], + "next": [ + "RecruitNowConfirm" + ] + }, + "RecruitNowConfirm": { + "action": "clickSelf", + "roi": [ + 640, + 450, + 640, + 150 + ], + "next": [ + "RecruitFinish" + ] + }, "AwardBegin": { "algorithm": "justreturn", "action": "doNothing", diff --git a/resource/template/RecruitNowConfirm.png b/resource/template/RecruitNowConfirm.png new file mode 100644 index 0000000000..dffffa1eff Binary files /dev/null and b/resource/template/RecruitNowConfirm.png differ diff --git a/src/MeoAssistant/AbstractTask.h b/src/MeoAssistant/AbstractTask.h index 54d0d69ab4..aa94f09f6f 100644 --- a/src/MeoAssistant/AbstractTask.h +++ b/src/MeoAssistant/AbstractTask.h @@ -26,7 +26,7 @@ namespace asst void set_task_chain(std::string name) noexcept { m_task_chain = std::move(name); } const std::string& get_task_chain() const noexcept { return m_task_chain; } - constexpr static int RetryTimesDefault = 50; + constexpr static int RetryTimesDefault = 20; protected: virtual bool _run() = 0; virtual bool on_run_fails() { return true; } diff --git a/src/MeoAssistant/Assistant.cpp b/src/MeoAssistant/Assistant.cpp index bc0b3c858e..58e06241d1 100644 --- a/src/MeoAssistant/Assistant.cpp +++ b/src/MeoAssistant/Assistant.cpp @@ -304,7 +304,7 @@ bool Assistant::append_process_task(const std::string& task_name, std::string ta return true; } -bool asst::Assistant::append_recruit(unsigned max_times, const std::vector& select_level, const std::vector& confirm_level, bool need_refresh) +bool asst::Assistant::append_recruit(unsigned max_times, const std::vector& select_level, const std::vector& confirm_level, bool need_refresh, bool use_expedited) { LogTraceFunction; if (!m_inited) { @@ -317,6 +317,7 @@ bool asst::Assistant::append_recruit(unsigned max_times, const std::vector& auto recruit_task_ptr = std::make_shared(task_callback, (void*)this); recruit_task_ptr->set_max_times(max_times); recruit_task_ptr->set_need_refresh(need_refresh); + recruit_task_ptr->set_use_expedited(use_expedited); recruit_task_ptr->set_select_level(select_level); recruit_task_ptr->set_confirm_level(confirm_level); recruit_task_ptr->set_task_chain(TaskChain); diff --git a/src/MeoAssistant/Assistant.h b/src/MeoAssistant/Assistant.h index 65c6553d19..fd05f18465 100644 --- a/src/MeoAssistant/Assistant.h +++ b/src/MeoAssistant/Assistant.h @@ -53,10 +53,12 @@ namespace asst bool append_infrast(infrast::WorkMode work_mode, const std::vector& order, const std::string& uses_of_drones, double dorm_threshold, bool only_append = true); // 添加自动公招任务 - // 参数max_times: 最多进行几次公招 - // 参数select_level: 需要的选择Tags的等级 - // 参数confirm_level: 需要点击确认按钮的等级 - bool append_recruit(unsigned max_times, const std::vector& select_level, const std::vector& confirm_level, bool need_refresh); + // 参数 max_times: 最多进行几次公招 + // 参数 select_level: 需要的选择Tags的等级 + // 参数 confirm_level: 需要点击确认按钮的等级 + // 参数 need_refresh: 是否刷新 3 星 Tags + // 参数 use_expedited: 是否使用加急券 + bool append_recruit(unsigned max_times, const std::vector& select_level, const std::vector& confirm_level, bool need_refresh, bool use_expedited); #ifdef LOG_TRACE // 调试用 @@ -78,7 +80,7 @@ namespace asst static constexpr int ProcessTaskRetryTimesDefault = AbstractTask::RetryTimesDefault; static constexpr int OpenRecruitTaskRetryTimesDefault = 5; - static constexpr int AutoRecruitTaskRetryTimesDefault = 10; + static constexpr int AutoRecruitTaskRetryTimesDefault = 5; private: void working_proc(); diff --git a/src/MeoAssistant/AsstCaller.cpp b/src/MeoAssistant/AsstCaller.cpp index 8ce8d4947a..984999f03e 100644 --- a/src/MeoAssistant/AsstCaller.cpp +++ b/src/MeoAssistant/AsstCaller.cpp @@ -197,7 +197,7 @@ bool AsstAppendInfrast(asst::Assistant* p_asst, int work_mode, const char** orde dorm_threshold); } -bool AsstAppendRecruit(asst::Assistant* p_asst, int max_times, const int select_level[], int select_len, const int confirm_level[], int confirm_len, bool need_refresh) +bool AsstAppendRecruit(asst::Assistant* p_asst, int max_times, const int select_level[], int select_len, const int confirm_level[], int confirm_len, bool need_refresh, bool use_expedited) { if (p_asst == nullptr) { return false; @@ -207,7 +207,7 @@ bool AsstAppendRecruit(asst::Assistant* p_asst, int max_times, const int select_ std::vector confirm_vector; confirm_vector.assign(confirm_level, confirm_level + confirm_len); - return p_asst->append_recruit(max_times, required_vector, confirm_vector, need_refresh); + return p_asst->append_recruit(max_times, required_vector, confirm_vector, need_refresh, use_expedited); } bool AsstStart(asst::Assistant* p_asst) diff --git a/src/MeoAssistant/AutoRecruitTask.cpp b/src/MeoAssistant/AutoRecruitTask.cpp index 1ef47615ea..fd200a172e 100644 --- a/src/MeoAssistant/AutoRecruitTask.cpp +++ b/src/MeoAssistant/AutoRecruitTask.cpp @@ -27,6 +27,11 @@ void asst::AutoRecruitTask::set_max_times(int max_times) noexcept m_max_times = max_times; } +void asst::AutoRecruitTask::set_use_expedited(bool use_or_not) noexcept +{ + m_use_expedited = use_or_not; +} + bool asst::AutoRecruitTask::_run() { json::value task_start_json = json::object{ @@ -37,60 +42,97 @@ bool asst::AutoRecruitTask::_run() int delay = Resrc.cfg().get_options().task_delay; - auto image = Ctrler.get_image(); - OcrImageAnalyzer start_analyzer(image); + OcrImageAnalyzer start_analyzer; const auto start_task_ptr = std::dynamic_pointer_cast(Task.get("StartRecruit")); start_analyzer.set_task_info(*start_task_ptr); + std::vector start_res; - if (!start_analyzer.analyze()) { - return false; - } - - const auto& start_res = start_analyzer.get_result(); - for (; m_cur_times < start_res.size() && m_cur_times < m_max_times; ++m_cur_times) { - if (need_exit()) { + auto analyze_start = [&]() -> bool { + auto image = Ctrler.get_image(); + start_analyzer.set_image(image); + if (!start_analyzer.analyze()) { return false; } - Rect start_rect = start_res.at(m_cur_times).rect; + start_analyzer.sort_result(); + start_res = start_analyzer.get_result(); + return true; + }; + + for (; m_cur_times < m_max_times; ++m_cur_times) { + analyze_start(); + if (m_cur_times >= start_res.size()) { + if (m_use_expedited) { + recruit_now(); + analyze_start(); + } + else { + break; + } + } + if (start_res.empty()) { + if (check_recruit_home_page()) { + return true; + } + else { + return false; + } + } + Rect start_rect = start_res.at(0).rect; Ctrler.click(start_rect); sleep(delay); - while (true) { - RecruitTask recurit_task(m_callback, m_callback_arg); - recurit_task.set_retry_times(10); - recurit_task.set_param(m_select_level, true); - recurit_task.set_task_chain(m_task_chain); - - // 识别错误,放弃这个公招位,直接返回 - if (!recurit_task.run()) { - m_callback(AsstMsg::RecruitError, json::value(), m_callback_arg); - click_return_button(); - break; - } - - int maybe_level = recurit_task.get_maybe_level(); - - // 尝试刷新 - if (m_need_refresh && maybe_level == 3 - && !recurit_task.get_has_special_tag() - && recurit_task.get_has_refresh()) { - ProcessTask refresh_task(*this, { "RecruitRefresh" }); - if (refresh_task.run()) { - continue; - } - } - if (std::find(m_confirm_level.cbegin(), m_confirm_level.cend(), maybe_level) != m_confirm_level.cend()) { - ProcessTask confirm_task(*this, { "RecruitConfirm" }); - if (!confirm_task.run()) { - return false; - } - break; - } - else { - click_return_button(); - break; - } + if (!calc_and_recruit()) { + return false; } } return true; } + +bool asst::AutoRecruitTask::calc_and_recruit() +{ + RecruitTask recurit_task(m_callback, m_callback_arg); + recurit_task.set_retry_times(10); + recurit_task.set_param(m_select_level, true); + recurit_task.set_task_chain(m_task_chain); + + // 识别错误,放弃这个公招位,直接返回 + if (!recurit_task.run()) { + m_callback(AsstMsg::RecruitError, json::value(), m_callback_arg); + click_return_button(); + return true; + } + + int maybe_level = recurit_task.get_maybe_level(); + + // 尝试刷新 + if (m_need_refresh && maybe_level == 3 + && !recurit_task.get_has_special_tag() + && recurit_task.get_has_refresh()) { + ProcessTask refresh_task(*this, { "RecruitRefresh" }); + if (refresh_task.run()) { + return calc_and_recruit(); + } + } + if (std::find(m_confirm_level.cbegin(), m_confirm_level.cend(), maybe_level) != m_confirm_level.cend()) { + ProcessTask confirm_task(*this, { "RecruitConfirm" }); + if (!confirm_task.run()) { + return false; + } + } + else { + click_return_button(); + } + return true; +} + +bool asst::AutoRecruitTask::check_recruit_home_page() +{ + ProcessTask task(*this, { "RecruitFlag" }); + return task.run(); +} + +bool asst::AutoRecruitTask::recruit_now() +{ + ProcessTask task(*this, { "RecruitNow" }); + return task.run(); +} diff --git a/src/MeoAssistant/AutoRecruitTask.h b/src/MeoAssistant/AutoRecruitTask.h index 5497834a9d..e36470065f 100644 --- a/src/MeoAssistant/AutoRecruitTask.h +++ b/src/MeoAssistant/AutoRecruitTask.h @@ -13,13 +13,19 @@ namespace asst void set_confirm_level(std::vector confirm_level) noexcept; void set_need_refresh(bool need_refresh) noexcept; void set_max_times(int max_times) noexcept; + void set_use_expedited(bool use_or_not) noexcept; protected: virtual bool _run() override; + bool calc_and_recruit(); + bool check_recruit_home_page(); + bool recruit_now(); + std::vector m_select_level; std::vector m_confirm_level; bool m_need_refresh = false; + bool m_use_expedited = false; int m_max_times = 0; int m_cur_times = 0; }; diff --git a/src/MeoAssistant/OcrImageAnalyzer.cpp b/src/MeoAssistant/OcrImageAnalyzer.cpp index 7e87ff9701..9ba8f98586 100644 --- a/src/MeoAssistant/OcrImageAnalyzer.cpp +++ b/src/MeoAssistant/OcrImageAnalyzer.cpp @@ -67,3 +67,18 @@ bool asst::OcrImageAnalyzer::analyze() //log.trace("ocr result", m_ocr_result); return !m_ocr_result.empty(); } + +void asst::OcrImageAnalyzer::sort_result() +{ + // 按位置排个序 + std::sort(m_ocr_result.begin(), m_ocr_result.end(), + [](const TextRect& lhs, const TextRect& rhs) -> bool { + if (std::abs(lhs.rect.y - rhs.rect.y) < 5) { // y差距较小则理解为是同一排的,按x排序 + return lhs.rect.x < rhs.rect.x; + } + else { + return lhs.rect.y < rhs.rect.y; + } + } + ); +} diff --git a/src/MeoAssistant/OcrImageAnalyzer.h b/src/MeoAssistant/OcrImageAnalyzer.h index 9eb18a1346..fb01f8a8b4 100644 --- a/src/MeoAssistant/OcrImageAnalyzer.h +++ b/src/MeoAssistant/OcrImageAnalyzer.h @@ -17,6 +17,8 @@ namespace asst virtual bool analyze() override; + void sort_result(); // 按位置排序,左上角的排在前面 + void set_required(std::vector required, bool full_match = false) noexcept { m_required = std::move(required); diff --git a/src/MeoAssistant/Version.h b/src/MeoAssistant/Version.h index ce25bfdd94..59ae7562c7 100644 --- a/src/MeoAssistant/Version.h +++ b/src/MeoAssistant/Version.h @@ -2,5 +2,5 @@ namespace asst { - constexpr static const char* Version = "v2.6.3"; + constexpr static const char* Version = "v2.6.4"; } diff --git a/src/MeoAsstGui/Helper/AsstProxy.cs b/src/MeoAsstGui/Helper/AsstProxy.cs index 95b5207cd3..880eae5a7e 100644 --- a/src/MeoAsstGui/Helper/AsstProxy.cs +++ b/src/MeoAsstGui/Helper/AsstProxy.cs @@ -47,7 +47,7 @@ namespace MeoAsstGui [DllImport("MeoAssistant.dll")] private static extern bool AsstAppendInfrast(IntPtr ptr, int work_mode, string[] order, int order_len, string uses_of_drones, double dorm_threshold); - [DllImport("MeoAssistant.dll")] private static extern bool AsstAppendRecruit(IntPtr ptr, int max_times, int[] select_level, int required_len, int[] confirm_level, int confirm_len, bool need_refresh); + [DllImport("MeoAssistant.dll")] private static extern bool AsstAppendRecruit(IntPtr ptr, int max_times, int[] select_level, int required_len, int[] confirm_level, int confirm_len, bool need_refresh, bool use_expedited); [DllImport("MeoAssistant.dll")] private static extern bool AsstStartRecruitCalc(IntPtr ptr, int[] select_level, int required_len, bool set_time); @@ -409,9 +409,9 @@ namespace MeoAsstGui return AsstAppendMall(_ptr, with_shopping); } - public bool AsstAppendRecruit(int max_times, int[] select_level, int required_len, int[] confirm_level, int confirm_len, bool need_refresh) + public bool AsstAppendRecruit(int max_times, int[] select_level, int required_len, int[] confirm_level, int confirm_len, bool need_refresh, bool use_expedited) { - return AsstAppendRecruit(_ptr, max_times, select_level, required_len, confirm_level, confirm_len, need_refresh); + return AsstAppendRecruit(_ptr, max_times, select_level, required_len, confirm_level, confirm_len, need_refresh, use_expedited); } public bool AsstAppendInfrast(int work_mode, string[] order, int order_len, string uses_of_drones, double dorm_threshold) diff --git a/src/MeoAsstGui/UserControl/AutoRecruitSettingsUserControl.xaml b/src/MeoAsstGui/UserControl/AutoRecruitSettingsUserControl.xaml index 2603b38e99..c7a9997955 100644 --- a/src/MeoAsstGui/UserControl/AutoRecruitSettingsUserControl.xaml +++ b/src/MeoAsstGui/UserControl/AutoRecruitSettingsUserControl.xaml @@ -14,6 +14,7 @@ + diff --git a/src/MeoAsstGui/ViewModels/SettingsViewModel.cs b/src/MeoAsstGui/ViewModels/SettingsViewModel.cs index fb21fc972d..952cc06cb1 100644 --- a/src/MeoAsstGui/ViewModels/SettingsViewModel.cs +++ b/src/MeoAsstGui/ViewModels/SettingsViewModel.cs @@ -250,7 +250,7 @@ namespace MeoAsstGui } } - private double _scrollHeight = 660; // ScrollViewer.ScrollableHeight, 不知道该咋获取,当前的默认值是这个 + private double _scrollHeight = 684; // ScrollViewer.ScrollableHeight, 不知道该咋获取,当前的默认值是这个 public double ScrollHeight { @@ -314,6 +314,14 @@ namespace MeoAsstGui } } + private bool _useExpedited = false; + + public bool UseExpedited + { + get { return _useExpedited; } + set { SetAndNotify(ref _useExpedited, value); } + } + private bool _chooseLevel3 = System.Convert.ToBoolean(ViewStatusStorage.Get("AutoRecruit.ChooseLevel3", bool.TrueString)); public bool ChooseLevel3 diff --git a/src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs b/src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs index 1ac0efbdd8..a92eac7a66 100644 --- a/src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs +++ b/src/MeoAsstGui/ViewModels/TaskQueueViewModel.cs @@ -256,9 +256,11 @@ namespace MeoAsstGui } bool need_refresh = settings.RefreshLevel3; + bool use_expedited = settings.UseExpedited; var asstProxy = _container.Get(); - return asstProxy.AsstAppendRecruit(max_times, reqList.ToArray(), reqList.Count, cfmList.ToArray(), cfmList.Count, need_refresh); + return asstProxy.AsstAppendRecruit( + max_times, reqList.ToArray(), reqList.Count, cfmList.ToArray(), cfmList.Count, need_refresh, use_expedited); } private void setPenguinId() diff --git a/src/Python/interface.py b/src/Python/interface.py index 1add7cec4f..a867666438 100644 --- a/src/Python/interface.py +++ b/src/Python/interface.py @@ -117,7 +117,7 @@ class Asst: order_arr, order_len, uses_of_drones.encode('utf-8'), dorm_threshold) - def append_recruit(self, max_times: int, select_level: list, confirm_level: list, need_refresh: bool) -> bool: + def append_recruit(self, max_times: int, select_level: list, confirm_level: list, need_refresh: bool, use_expedited: bool) -> bool: """ 添加自动公招任务 @@ -126,6 +126,7 @@ class Asst: ``select_level``: 要点击的Tags等级(例如3级Tags不选也可以直接确认),int list ``confirm_level``: 要确认开始招募的Tags等级,int list ``need_refresh``: 是否刷新3级Tags + ``use_expedited``: 是否使用加急许可 """ select_len = len(select_level) select_arr = (ctypes.c_int * select_len)() @@ -137,7 +138,8 @@ class Asst: return self.__lib.AsstAppendRecruit(self.__ptr, max_times, select_arr, select_len, - confirm_arr, confirm_len, need_refresh) + confirm_arr, confirm_len, + need_refresh, use_expedited) def start(self) -> bool: """ @@ -224,7 +226,8 @@ class Asst: self.__lib.AsstAppendRecruit.argtypes = ( ctypes.c_void_p, ctypes.c_int, ctypes.POINTER(ctypes.c_int), ctypes.c_int, - ctypes.POINTER(ctypes.c_int), ctypes.c_int, ctypes.c_bool,) + ctypes.POINTER(ctypes.c_int), ctypes.c_int, + ctypes.c_bool, ctypes.c_bool,) self.__lib.AsstStart.restype = ctypes.c_bool self.__lib.AsstStart.argtypes = (ctypes.c_void_p,) diff --git a/tools/TestCaller/main.cpp b/tools/TestCaller/main.cpp index 1b8d39daa3..5e287543e4 100644 --- a/tools/TestCaller/main.cpp +++ b/tools/TestCaller/main.cpp @@ -17,7 +17,8 @@ int main(int argc, char** argv) if (ptr == nullptr) { return -1; } - auto ret = AsstCatchCustom(ptr, "127.0.0.1:5555"); + //auto ret = AsstCatchCustom(ptr, "127.0.0.1:5555"); + auto ret = AsstCatchDefault(ptr); if (!ret) { std::cout << "connect failed" << std::endl; if (ptr) { @@ -43,10 +44,10 @@ int main(int argc, char** argv) //} // AsstAppendProcessTask(ptr, "AwardBegin"); //{ - // const int required[] = { 4 }; - // const int confirm[] = { 3, 4 }; - // AsstAppendRecruit(ptr, 2, required, sizeof(required) / sizeof(int), confirm, sizeof(confirm) / sizeof(int)); - // } + // const int required[] = { 4 }; + // const int confirm[] = { 3, 4 }; + // AsstAppendRecruit(ptr, 3, required, sizeof(required) / sizeof(int), confirm, sizeof(confirm) / sizeof(int), true, true); + //} AsstStart(ptr); ch = static_cast(getchar());