From 9ec37b5f37b3565092ee7ca8fbeb1356593a3d08 Mon Sep 17 00:00:00 2001 From: MistEO Date: Sun, 9 Jan 2022 00:42:48 +0800 Subject: [PATCH] =?UTF-8?q?refactor.=E8=A7=A3=E8=80=A6=E5=85=B3=E5=8D=A1?= =?UTF-8?q?=E6=8E=89=E8=90=BD=E7=9B=B8=E5=85=B3=E4=BB=BB=E5=8A=A1=EF=BC=8C?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/回调消息协议.md | 4 +- resource/tasks.json | 8 +- src/MeoAssistant/AbstractTask.cpp | 34 ++++- src/MeoAssistant/AbstractTask.h | 25 +++- src/MeoAssistant/AbstractTaskPlugin.cpp | 26 ++++ src/MeoAssistant/AbstractTaskPlugin.h | 37 +++++ src/MeoAssistant/Assistant.cpp | 42 +----- src/MeoAssistant/Assistant.h | 1 - src/MeoAssistant/AsstDef.h | 1 - src/MeoAssistant/AutoRecruitTask.cpp | 2 +- src/MeoAssistant/InfrastAbstractTask.cpp | 2 +- src/MeoAssistant/InfrastProductionTask.cpp | 2 +- src/MeoAssistant/ItemConfiger.h | 32 ---- src/MeoAssistant/MeoAssistant.vcxproj | 6 +- src/MeoAssistant/MeoAssistant.vcxproj.filters | 24 ++- src/MeoAssistant/PenguinUploader.cpp | 58 -------- src/MeoAssistant/PenguinUploader.h | 21 --- src/MeoAssistant/ProcessTask.cpp | 68 +++------ src/MeoAssistant/ProcessTask.h | 2 +- src/MeoAssistant/RecruitTask.cpp | 8 +- src/MeoAssistant/StageDropsTaskPlugin.cpp | 137 ++++++++++++++++++ src/MeoAssistant/StageDropsTaskPlugin.h | 33 +++++ src/MeoAssistant/TaskData.cpp | 3 - src/MeoAsstGui/Helper/AsstProxy.cs | 9 +- 24 files changed, 351 insertions(+), 234 deletions(-) create mode 100644 src/MeoAssistant/AbstractTaskPlugin.cpp create mode 100644 src/MeoAssistant/AbstractTaskPlugin.h delete mode 100644 src/MeoAssistant/PenguinUploader.cpp delete mode 100644 src/MeoAssistant/PenguinUploader.h create mode 100644 src/MeoAssistant/StageDropsTaskPlugin.cpp create mode 100644 src/MeoAssistant/StageDropsTaskPlugin.h diff --git a/docs/回调消息协议.md b/docs/回调消息协议.md index a7c2d7fd3e..dae7b4dbdf 100644 --- a/docs/回调消息协议.md +++ b/docs/回调消息协议.md @@ -60,7 +60,7 @@ Todo ```jsonc { - "task_chain": string, // 当前的任务链 + "taskchain": string, // 当前的任务链 "pre_taskchain": string, // 上一个任务链 "next_taskchain": string, // 下一个任务链 "details": object, // 详情 @@ -111,7 +111,7 @@ Todo ### 子任务类型 `class` 字段 -- `ProcessTask` +- `class asst::ProcessTask` ```jsonc // 对应的 details 字段举例 diff --git a/resource/tasks.json b/resource/tasks.json index 609ad3d9e3..5535a684b8 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -505,13 +505,15 @@ 440, 280 ], - "preDelay": 5000, - "action": "stageDrops", - "action_Doc": "为“行动结束”特化的action,包含截图、识别关卡掉落等功能", + "action": "doNothing", "next": [ "ClickCorner" ] }, + "StageDrops": { + "algorithm": "JustReturn", + "preDelay": 5000 + }, "ClickCorner": { "ClickCorner_Doc": "点击屏幕右边,不会点到掉落物品,且不会关掉关卡选择的一块区域", "algorithm": "justreturn", diff --git a/src/MeoAssistant/AbstractTask.cpp b/src/MeoAssistant/AbstractTask.cpp index f859ecc4ac..c45bdbc874 100644 --- a/src/MeoAssistant/AbstractTask.cpp +++ b/src/MeoAssistant/AbstractTask.cpp @@ -10,6 +10,7 @@ #include "Controller.h" #include "Logger.hpp" #include "Resource.h" +#include "AbstractTaskPlugin.h" using namespace asst; @@ -23,10 +24,10 @@ AbstractTask::AbstractTask(AsstCallback callback, void* callback_arg, std::strin bool asst::AbstractTask::run() { - m_callback(AsstMsg::SubTaskStart, basic_info(), m_callback_arg); + callback(AsstMsg::SubTaskStart, basic_info()); for (m_cur_retry = 0; m_cur_retry < m_retry_times; ++m_cur_retry) { if (_run()) { - m_callback(AsstMsg::SubTaskCompleted, basic_info(), m_callback_arg); + callback(AsstMsg::SubTaskCompleted, basic_info()); return true; } if (need_exit()) { @@ -36,11 +37,11 @@ bool asst::AbstractTask::run() sleep(delay); if (!on_run_fails()) { - m_callback(AsstMsg::SubTaskError, basic_info(), m_callback_arg); + callback(AsstMsg::SubTaskError, basic_info()); return false; } } - m_callback(AsstMsg::SubTaskError, basic_info(), m_callback_arg); + callback(AsstMsg::SubTaskError, basic_info()); return false; } @@ -56,6 +57,11 @@ AbstractTask& asst::AbstractTask::set_retry_times(int times) noexcept return *this; } +void asst::AbstractTask::clear_plugin() noexcept +{ + m_plugins.clear(); +} + json::value asst::AbstractTask::basic_info() const { return json::object{ @@ -99,7 +105,7 @@ bool AbstractTask::save_image(const cv::Mat image, const std::string& dir) bool ret = cv::imwrite(filename, image); - return true; + return ret; } bool asst::AbstractTask::need_exit() const @@ -107,6 +113,24 @@ bool asst::AbstractTask::need_exit() const return m_exit_flag != nullptr && *m_exit_flag == true; } +void asst::AbstractTask::callback(AsstMsg msg, const json::value& detail) +{ + for (TaskPluginPtr plugin : m_plugins) { + plugin->set_plugin_exit_flag(m_exit_flag); + + if (!plugin->verify(msg, detail)) { + continue; + } + + plugin->run(this); + + if (plugin->block()) { + break; + } + } + m_callback(msg, detail, m_callback_arg); +} + void asst::AbstractTask::click_return_button() { LogTraceFunction; diff --git a/src/MeoAssistant/AbstractTask.h b/src/MeoAssistant/AbstractTask.h index b8e056913c..b0b0c0091b 100644 --- a/src/MeoAssistant/AbstractTask.h +++ b/src/MeoAssistant/AbstractTask.h @@ -1,6 +1,8 @@ #pragma once #include +#include +#include #include "AsstMsg.h" @@ -15,6 +17,9 @@ namespace json namespace asst { + class AbstractTaskPlugin; + using TaskPluginPtr = std::shared_ptr; + class AbstractTask { public: @@ -27,25 +32,39 @@ namespace asst AbstractTask& set_exit_flag(bool* exit_flag) noexcept; AbstractTask& set_retry_times(int times) noexcept; + + template + AbstractTask& regiseter_plugin() + { + static_assert(std::is_base_of::value, + "Plugin must inherit AbstractTaskPlugin as public"); + m_plugins.emplace(std::make_shared(m_callback, m_callback_arg, m_task_chain)); + return *this; + } + void clear_plugin() noexcept; + const std::string& get_task_chain() const noexcept { return m_task_chain; } + virtual json::value basic_info() const; constexpr static int RetryTimesDefault = 20; protected: virtual bool _run() = 0; virtual bool on_run_fails() { return true; } - virtual json::value basic_info() const; + virtual void callback(AsstMsg msg, const json::value& detail); + + virtual void click_return_button(); bool sleep(unsigned millisecond); bool save_image(const cv::Mat image, const std::string& dir); bool need_exit() const; - virtual void click_return_button(); - AsstCallback m_callback; void* m_callback_arg = nullptr; bool* m_exit_flag = nullptr; const std::string m_task_chain; int m_cur_retry = 0; int m_retry_times = RetryTimesDefault; + + std::set m_plugins; }; } diff --git a/src/MeoAssistant/AbstractTaskPlugin.cpp b/src/MeoAssistant/AbstractTaskPlugin.cpp new file mode 100644 index 0000000000..e63f5f679d --- /dev/null +++ b/src/MeoAssistant/AbstractTaskPlugin.cpp @@ -0,0 +1,26 @@ +#include "AbstractTaskPlugin.h" + +int asst::AbstractTaskPlugin::priority() const +{ + return m_priority; +} + +bool asst::AbstractTaskPlugin::block() const +{ + return m_block; +} + +void asst::AbstractTaskPlugin::set_priority(int priority) +{ + m_priority = priority; +} + +void asst::AbstractTaskPlugin::set_block(bool block) +{ + m_block = block; +} + +void asst::AbstractTaskPlugin::set_plugin_exit_flag(bool* exit_flag) noexcept +{ + AbstractTask::set_exit_flag(exit_flag); +} diff --git a/src/MeoAssistant/AbstractTaskPlugin.h b/src/MeoAssistant/AbstractTaskPlugin.h new file mode 100644 index 0000000000..d079fce197 --- /dev/null +++ b/src/MeoAssistant/AbstractTaskPlugin.h @@ -0,0 +1,37 @@ +#pragma once + +#include + +#include "AsstMsg.h" +#include "AbstractTask.h" + +namespace asst +{ + class AbstractTaskPlugin : protected AbstractTask + { + public: + using AbstractTask::AbstractTask; + virtual ~AbstractTaskPlugin() = default; + + int priority() const; + bool block() const; + + void set_priority(int priority); + void set_block(bool block); + + virtual bool verify(AsstMsg msg, const json::value& details) const = 0; + virtual bool run(AbstractTask* ptr) = 0; + + bool operator<(const AbstractTaskPlugin& rhs) const + { + return priority() < rhs.priority(); + } + void set_plugin_exit_flag(bool* exit_flag) noexcept; + + protected: + virtual bool _run() override { return false; } + + int m_priority = 0; + bool m_block = false; + }; +} diff --git a/src/MeoAssistant/Assistant.cpp b/src/MeoAssistant/Assistant.cpp index 6f13cf2620..fa05a81968 100644 --- a/src/MeoAssistant/Assistant.cpp +++ b/src/MeoAssistant/Assistant.cpp @@ -24,6 +24,7 @@ #include "AutoRecruitTask.h" #include "InfrastControlTask.h" #include "RuntimeStatus.h" +#include "StageDropsTaskPlugin.h" using namespace asst; @@ -210,7 +211,8 @@ bool asst::Assistant::append_fight(const std::string& stage, int mecidine, int s .set_times_limit("MedicineConfirm", mecidine) .set_times_limit("StoneConfirm", stone) .set_times_limit("StartButton1", times) - .set_times_limit("StartButton2", times); + .set_times_limit("StartButton2", times) + .regiseter_plugin(); std::unique_lock lock(m_mutex); @@ -596,14 +598,10 @@ void Assistant::task_callback(AsstMsg msg, const json::value& detail, void* cust case AsstMsg::ConnectionError: p_this->stop(false); break; - //case AsstMsg::StageDrops: - // more_detail = p_this->organize_stage_drop(more_detail); - // break; default: break; } - // Todo: 有些不需要回调给外部的消息,得在这里给拦截掉 // 加入回调消息队列,由回调消息线程外抛给外部 p_this->append_callback(msg, std::move(more_detail)); } @@ -618,39 +616,5 @@ void asst::Assistant::append_callback(AsstMsg msg, json::value detail) void Assistant::clear_cache() { Status.clear(); - Resrc.item().clear_drop_count(); //Task.clear_cache(); } - -json::value asst::Assistant::organize_stage_drop(const json::value& rec) -{ - json::value dst = rec; - auto& item = Resrc.item(); - for (json::value& drop : dst["drops"].as_array()) { - std::string id = drop["itemId"].as_string(); - int quantity = drop["quantity"].as_integer(); - item.increase_drop_count(id, quantity); - const std::string& name = item.get_item_name(id); - drop["itemName"] = name.empty() ? "未知材料" : name; - } - std::vector statistics_vec; - for (auto&& [id, count] : item.get_drop_count()) { - json::value info; - info["itemId"] = id; - const std::string& name = item.get_item_name(id); - info["itemName"] = name.empty() ? "未知材料" : name; - info["count"] = count; - statistics_vec.emplace_back(std::move(info)); - } - //// 排个序,数量多的放前面 - //std::sort(statistics_vec.begin(), statistics_vec.end(), - // [](const json::value& lhs, const json::value& rhs) -> bool { - // return lhs.at("count").as_integer() > rhs.at("count").as_integer(); - // }); - - dst["statistics"] = json::array(std::move(statistics_vec)); - - Log.trace("organize_stage_drop | ", dst.to_string()); - - return dst; -} diff --git a/src/MeoAssistant/Assistant.h b/src/MeoAssistant/Assistant.h index 9720371194..c4f659287e 100644 --- a/src/MeoAssistant/Assistant.h +++ b/src/MeoAssistant/Assistant.h @@ -90,7 +90,6 @@ namespace asst bool append_process_task(const std::string& task_name, std::string task_chain = std::string(), int retry_times = ProcessTaskRetryTimesDefault); void append_callback(AsstMsg msg, json::value detail); void clear_cache(); - json::value organize_stage_drop(const json::value& rec); // 整理关卡掉落的材料信息 bool m_inited = false; std::string m_dirname; diff --git a/src/MeoAssistant/AsstDef.h b/src/MeoAssistant/AsstDef.h index c701331935..3403d24932 100644 --- a/src/MeoAssistant/AsstDef.h +++ b/src/MeoAssistant/AsstDef.h @@ -174,7 +174,6 @@ namespace asst ClickRand = BasicClick | 4, // 点击随机区域 DoNothing = 0x200, // 什么都不做 Stop = 0x400, // 停止当前Task - StageDrops = 0x800, // 关卡结束,特化动作 BasicSwipe = 0x1000, SwipeToTheLeft = BasicSwipe | 1, // 往左划一下 SwipeToTheRight = BasicSwipe | 2, // 往右划一下 diff --git a/src/MeoAssistant/AutoRecruitTask.cpp b/src/MeoAssistant/AutoRecruitTask.cpp index 32db0b1d38..8e277e9846 100644 --- a/src/MeoAssistant/AutoRecruitTask.cpp +++ b/src/MeoAssistant/AutoRecruitTask.cpp @@ -115,7 +115,7 @@ bool asst::AutoRecruitTask::calc_and_recruit() // 识别错误,放弃这个公招位,直接返回 if (!recurit_task.run()) { - m_callback(AsstMsg::SubTaskError, basic_info(), m_callback_arg); + callback(AsstMsg::SubTaskError, basic_info()); click_return_button(); return true; } diff --git a/src/MeoAssistant/InfrastAbstractTask.cpp b/src/MeoAssistant/InfrastAbstractTask.cpp index d5f8594e9b..40032d4235 100644 --- a/src/MeoAssistant/InfrastAbstractTask.cpp +++ b/src/MeoAssistant/InfrastAbstractTask.cpp @@ -68,7 +68,7 @@ bool asst::InfrastAbstractTask::enter_facility(const std::string& facility, int { "facility", facility }, { "index", index } }; - m_callback(AsstMsg::SubTaskExtraInfo, info, m_callback_arg); + callback(AsstMsg::SubTaskExtraInfo, info); const auto image = Ctrler.get_image(); diff --git a/src/MeoAssistant/InfrastProductionTask.cpp b/src/MeoAssistant/InfrastProductionTask.cpp index f8b7e39f7f..a5d9ece8c0 100644 --- a/src/MeoAssistant/InfrastProductionTask.cpp +++ b/src/MeoAssistant/InfrastProductionTask.cpp @@ -65,7 +65,7 @@ bool asst::InfrastProductionTask::shift_facility_list() { "facility", m_facility }, { "index", index } }; - m_callback(AsstMsg::SubTaskExtraInfo, info, m_callback_arg); + callback(AsstMsg::SubTaskExtraInfo, info); } ++index; diff --git a/src/MeoAssistant/ItemConfiger.h b/src/MeoAssistant/ItemConfiger.h index 7dd1c6ec19..548c90fdcc 100644 --- a/src/MeoAssistant/ItemConfiger.h +++ b/src/MeoAssistant/ItemConfiger.h @@ -22,43 +22,11 @@ namespace asst return empty; } } - const std::unordered_map& get_drop_count() const noexcept - { - return m_drop_count; - } - std::unordered_map& get_drop_count() noexcept - { - return m_drop_count; - } - int get_drop_count(const std::string& id) const noexcept - { - if (auto iter = m_drop_count.find(id); - iter != m_drop_count.cend()) { - return iter->second; - } - else { - return 0; - } - } - void set_drop_count(std::string id, int count) - { - m_drop_count.emplace(std::move(id), count); - } - void increase_drop_count(std::string id, int count) - { - m_drop_count[std::move(id)] += count; - } - void clear_drop_count() noexcept - { - m_drop_count.clear(); - } protected: virtual bool parse(const json::value& json) override; // key:材料编号Id,value:材料名(zh,utf8) std::unordered_map m_item_name; - // key:材料编号Id,value:数量 - std::unordered_map m_drop_count; }; } diff --git a/src/MeoAssistant/MeoAssistant.vcxproj b/src/MeoAssistant/MeoAssistant.vcxproj index 95d5305716..24236d8b67 100644 --- a/src/MeoAssistant/MeoAssistant.vcxproj +++ b/src/MeoAssistant/MeoAssistant.vcxproj @@ -17,6 +17,7 @@ + @@ -52,11 +53,11 @@ - + @@ -69,6 +70,7 @@ + @@ -100,11 +102,11 @@ - + diff --git a/src/MeoAssistant/MeoAssistant.vcxproj.filters b/src/MeoAssistant/MeoAssistant.vcxproj.filters index ea9ce55a7b..c52107cf88 100644 --- a/src/MeoAssistant/MeoAssistant.vcxproj.filters +++ b/src/MeoAssistant/MeoAssistant.vcxproj.filters @@ -64,6 +64,12 @@ {6cd85910-b561-4cf3-85a2-20be3cd1dd76} + + {34a52261-b34b-49ac-8102-22b0125617f5} + + + {f5faaa93-ae82-472e-9c59-9eccc29294a0} + @@ -216,12 +222,15 @@ 头文件\Task\Infrast - - 头文件\Requester - 头文件\Requester + + 头文件\TaskPlugin + + + 头文件\TaskPlugin + @@ -257,9 +266,6 @@ 源文件\Task - - 源文件\Requester - 源文件\Resource @@ -359,6 +365,12 @@ 源文件\Requester + + 源文件\TaskPlugin + + + 源文件\TaskPlugin + diff --git a/src/MeoAssistant/PenguinUploader.cpp b/src/MeoAssistant/PenguinUploader.cpp deleted file mode 100644 index cc81c92d7e..0000000000 --- a/src/MeoAssistant/PenguinUploader.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "PenguinUploader.h" - -// #include - -#include - -#include "AsstUtils.hpp" -#include "Logger.hpp" -#include "Resource.h" -#include "Version.h" - -bool asst::PenguinUploader::upload(const std::string& rec_res) -{ - std::string body = cvt_json(rec_res); - return request_penguin(body); -} - -std::string asst::PenguinUploader::cvt_json(const std::string& rec_res) -{ - auto parse_ret = json::parse(rec_res); - if (!parse_ret) { - return std::string(); - } - json::value rec = std::move(parse_ret.value()); - - // Doc: https://developer.penguin-stats.io/public-api/api-v2-instruction/report-api - json::value body; - auto& opt = Resrc.cfg().get_options(); - body["server"] = opt.penguin_report.server; - body["stageId"] = rec["stage"]["stageId"]; - // To fix: https://github.com/MistEO/MeoAssistantArknights/issues/40 - body["drops"] = json::array(); - for (auto&& drop : rec["drops"].as_array()) { - if (!drop["itemId"].as_string().empty()) { - body["drops"].as_array().emplace_back(drop); - } - } - body["source"] = "MeoAssistant"; - body["version"] = Version; - - return body.to_string(); -} - -bool asst::PenguinUploader::request_penguin(const std::string& body) -{ - auto& opt = Resrc.cfg().get_options(); - std::string body_escape = utils::string_replace_all(body, "\"", "\\\""); - std::string cmd_line = utils::string_replace_all(opt.penguin_report.cmd_format, "[body]", body_escape); - cmd_line = utils::string_replace_all(cmd_line, "[extra]", opt.penguin_report.extra_param); - - Log.trace("request_penguin |", cmd_line); - - std::string response = utils::callcmd(cmd_line); - - Log.trace("response:\n", response); - - return true; -} diff --git a/src/MeoAssistant/PenguinUploader.h b/src/MeoAssistant/PenguinUploader.h deleted file mode 100644 index 8dd95353ad..0000000000 --- a/src/MeoAssistant/PenguinUploader.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -namespace json -{ - class value; -} - -namespace asst -{ - class PenguinUploader - { - public: - static bool upload(const std::string& rec_res); - - private: - static std::string cvt_json(const std::string& rec_res); - static bool request_penguin(const std::string& body); - }; -} diff --git a/src/MeoAssistant/ProcessTask.cpp b/src/MeoAssistant/ProcessTask.cpp index 91c708c3ad..0b97243a7e 100644 --- a/src/MeoAssistant/ProcessTask.cpp +++ b/src/MeoAssistant/ProcessTask.cpp @@ -7,7 +7,6 @@ #include "AsstUtils.hpp" #include "Controller.h" -#include "PenguinUploader.h" #include "ProcessTaskImageAnalyzer.h" #include "Resource.h" #include "Logger.hpp" @@ -41,7 +40,7 @@ bool asst::ProcessTask::run() return false; } } - m_callback(AsstMsg::SubTaskError, basic_info(), m_callback_arg); + callback(AsstMsg::SubTaskError, basic_info()); return false; } @@ -57,6 +56,12 @@ ProcessTask& asst::ProcessTask::set_times_limit(std::string name, int limit) return *this; } +ProcessTask& asst::ProcessTask::set_rear_delay(std::string name, int delay) +{ + m_rear_delay.emplace(std::move(name), delay); + return *this; +} + bool ProcessTask::_run() { LogTraceFunction; @@ -108,6 +113,16 @@ bool ProcessTask::_run() max_times = iter->second; } + if (exec_times >= max_times) { + Log.info("exec times exceeds the limit", info.to_string()); + set_tasks(m_cur_task_ptr->exceeded_next); + sleep(task_delay); + continue; + } + + m_cur_retry = 0; + ++exec_times; + info["details"] = json::object{ { "task", cur_name }, { "action", static_cast(m_cur_task_ptr->action) }, @@ -116,14 +131,7 @@ bool ProcessTask::_run() { "algorithm", static_cast(m_cur_task_ptr->algorithm) } }; - if (exec_times >= max_times) { - Log.info("exec times exceeds the limit", info.to_string()); - set_tasks(m_cur_task_ptr->exceeded_next); - sleep(task_delay); - continue; - } - - m_callback(AsstMsg::SubTaskStart, info, m_callback_arg); + callback(AsstMsg::SubTaskStart, info); // 前置固定延时 if (!sleep(m_cur_task_ptr->pre_delay)) { @@ -153,14 +161,9 @@ bool ProcessTask::_run() Log.info("stop action", info.to_string()); need_stop = true; break; - case ProcessTaskAction::StageDrops: { - exec_stage_drops(); - } break; default: break; } - m_cur_retry = 0; - ++exec_times; Status.set("Last" + cur_name, time(nullptr)); @@ -171,9 +174,6 @@ bool ProcessTask::_run() --m_exec_times[reduce]; } - info["details"]["exec_times"] = exec_times; - m_callback(AsstMsg::SubTaskCompleted, info, m_callback_arg); - // 后置固定延时 int rear_delay = m_cur_task_ptr->rear_delay; if (auto iter = m_rear_delay.find(cur_name); @@ -184,6 +184,8 @@ bool ProcessTask::_run() return false; } + callback(AsstMsg::SubTaskCompleted, info); + if (need_stop) { return true; } @@ -194,36 +196,6 @@ bool ProcessTask::_run() return true; } -void asst::ProcessTask::exec_stage_drops() -{ - cv::Mat image = Ctrler.get_image(true); - std::string res = Resrc.penguin().recognize(image); - - json::value info = basic_info(); - info["what"] = "StageDrops"; - info["details"] = json::parse(res).value(); - - m_callback(AsstMsg::SubTaskExtraInfo, info, m_callback_arg); - - if (m_rear_delay.find("StartButton2") == m_rear_delay.cend()) { - int64_t start_times = Status.get("LastStartButton2"); - if (start_times > 0) { - int64_t duration = time(nullptr) - start_times; - int64_t delay = duration * 1000 - m_cur_task_ptr->rear_delay; - m_rear_delay["StartButton2"] = static_cast(delay); - } - } - - auto& opt = Resrc.cfg().get_options(); - //if (opt.print_window) { - // //static const std::string dirname = utils::get_cur_dir() + "screenshot\\"; - // //save_image(image, dirname); - //} - if (opt.penguin_report.enable) { - PenguinUploader::upload(res); - } -} - void ProcessTask::exec_click_task(const Rect& matched_rect) { Ctrler.click(matched_rect); diff --git a/src/MeoAssistant/ProcessTask.h b/src/MeoAssistant/ProcessTask.h index 5c69e2850e..ebc694cc84 100644 --- a/src/MeoAssistant/ProcessTask.h +++ b/src/MeoAssistant/ProcessTask.h @@ -19,11 +19,11 @@ namespace asst ProcessTask& set_tasks(std::vector tasks_name) noexcept; ProcessTask& set_times_limit(std::string name, int limit); + ProcessTask& set_rear_delay(std::string name, int delay); protected: virtual bool _run() override; - void exec_stage_drops(); void exec_click_task(const Rect& matched_rect); void exec_swipe_task(ProcessTaskAction action); diff --git a/src/MeoAssistant/RecruitTask.cpp b/src/MeoAssistant/RecruitTask.cpp index 86bcecbbcb..6ced9d0965 100644 --- a/src/MeoAssistant/RecruitTask.cpp +++ b/src/MeoAssistant/RecruitTask.cpp @@ -47,7 +47,7 @@ bool RecruitTask::_run() info["details"] = json::object{ { "tags", json::array(all_tags_json_vector) } }; - m_callback(AsstMsg::SubTaskExtraInfo, info, m_callback_arg); + callback(AsstMsg::SubTaskExtraInfo, info); /* 针对特殊Tag的额外回调消息 */ static const std::string SeniorOper = "高级资深干员"; @@ -59,7 +59,7 @@ bool RecruitTask::_run() info["details"] = json::object{ { "tag", *special_iter } }; - m_callback(AsstMsg::SubTaskExtraInfo, info, m_callback_arg); + callback(AsstMsg::SubTaskExtraInfo, info); m_has_special_tag = true; } @@ -189,7 +189,7 @@ bool RecruitTask::_run() } info["what"] = "RecruitResult"; info["details"] = results_json; - m_callback(AsstMsg::SubTaskExtraInfo, info, m_callback_arg); + callback(AsstMsg::SubTaskExtraInfo, info); if (!result_vec.empty()) { /* 点击最优解的tags */ @@ -206,7 +206,7 @@ bool RecruitTask::_run() info["details"] = json::object{ { "tags", json::array(final_tags_name) } }; - m_callback(AsstMsg::SubTaskExtraInfo, info, m_callback_arg); + callback(AsstMsg::SubTaskExtraInfo, info); } } diff --git a/src/MeoAssistant/StageDropsTaskPlugin.cpp b/src/MeoAssistant/StageDropsTaskPlugin.cpp new file mode 100644 index 0000000000..27b2fab3e2 --- /dev/null +++ b/src/MeoAssistant/StageDropsTaskPlugin.cpp @@ -0,0 +1,137 @@ +#include "StageDropsTaskPlugin.h" + +#include +#include + +#include "Controller.h" +#include "Resource.h" +#include "ProcessTask.h" +#include "RuntimeStatus.h" +#include "Version.h" +#include "AsstUtils.hpp" +#include "Logger.hpp" +#include "TaskData.h" + +bool asst::StageDropsTaskPlugin::verify(AsstMsg msg, const json::value& details) const +{ + if (msg != AsstMsg::SubTaskCompleted + || details.get("class", std::string()) != "class asst::ProcessTask") { + return false; + } + + if (details.at("details").at("task").as_string() == "EndOfAction") { + return true; + } + else { + return false; + } +} + +bool asst::StageDropsTaskPlugin::run(AbstractTask* ptr) +{ + ProcessTask* cast_ptr = dynamic_cast(ptr); + + set_startbutton_delay(cast_ptr); + + recognize_drops(); + if (need_exit()) { + return false; + } + drop_info_callback(); + + auto upload_future = std::async( + std::launch::async, + std::bind(&StageDropsTaskPlugin::upload_to_penguin, this)); + m_upload_pending.emplace_back(std::move(upload_future)); +} + +void asst::StageDropsTaskPlugin::recognize_drops() +{ + sleep(Task.get("PRTS")->rear_delay); + if (need_exit()) { + return; + } + cv::Mat image = Ctrler.get_image(true); + m_cur_drops = json::parse(Resrc.penguin().recognize(image)).value(); +} + +void asst::StageDropsTaskPlugin::drop_info_callback() +{ + json::value drops_details = m_cur_drops; + auto& item = Resrc.item(); + for (json::value& drop : drops_details["drops"].as_array()) { + std::string id = drop["itemId"].as_string(); + int quantity = drop["quantity"].as_integer(); + m_drop_stats[id] += quantity; + const std::string& name = item.get_item_name(id); + drop["itemName"] = name.empty() ? "未知材料" : name; + } + std::vector statistics_vec; + for (auto&& [id, count] : m_drop_stats) { + json::value info; + info["itemId"] = id; + const std::string& name = item.get_item_name(id); + info["itemName"] = name.empty() ? "未知材料" : name; + info["count"] = count; + statistics_vec.emplace_back(std::move(info)); + } + //// 排个序,数量多的放前面 + //std::sort(statistics_vec.begin(), statistics_vec.end(), + // [](const json::value& lhs, const json::value& rhs) -> bool { + // return lhs.at("count").as_integer() > rhs.at("count").as_integer(); + // }); + + drops_details["statistics"] = json::array(std::move(statistics_vec)); + + json::value info = basic_info(); + info["what"] = "StageDrops"; + info["details"] = drops_details; + + callback(AsstMsg::SubTaskExtraInfo, info); +} + +void asst::StageDropsTaskPlugin::set_startbutton_delay(ProcessTask* ptr) +{ + if (!m_startbutton_delay_setted) { + int64_t start_times = Status.get("LastStartButton2"); + + if (start_times > 0) { + int64_t duration = time(nullptr) - start_times; + int elapsed = Task.get("EndOfAction")->pre_delay + Task.get("PRTS")->rear_delay; + int64_t delay = duration * 1000 - elapsed; + ptr->set_rear_delay("StartButton2", static_cast(delay)); + } + } +} + +void asst::StageDropsTaskPlugin::upload_to_penguin() +{ + auto& opt = Resrc.cfg().get_options(); + if (!opt.penguin_report.enable) { + return; + } + + // Doc: https://developer.penguin-stats.io/public-api/api-v2-instruction/report-api + json::value body; + body["server"] = opt.penguin_report.server; + body["stageId"] = m_cur_drops["stage"]["stageId"]; + // To fix: https://github.com/MistEO/MeoAssistantArknights/issues/40 + body["drops"] = json::array(); + for (auto&& drop : m_cur_drops["drops"].as_array()) { + if (!drop["itemId"].as_string().empty()) { + body["drops"].as_array().emplace_back(drop); + } + } + body["source"] = "MeoAssistant"; + body["version"] = Version; + + std::string body_escape = utils::string_replace_all(body.to_string(), "\"", "\\\""); + std::string cmd_line = utils::string_replace_all(opt.penguin_report.cmd_format, "[body]", body_escape); + cmd_line = utils::string_replace_all(cmd_line, "[extra]", opt.penguin_report.extra_param); + + Log.trace("request_penguin |", cmd_line); + + std::string response = utils::callcmd(cmd_line); + + Log.trace("response:\n", response); +} diff --git a/src/MeoAssistant/StageDropsTaskPlugin.h b/src/MeoAssistant/StageDropsTaskPlugin.h new file mode 100644 index 0000000000..ecd4e1ec11 --- /dev/null +++ b/src/MeoAssistant/StageDropsTaskPlugin.h @@ -0,0 +1,33 @@ +#pragma once +#include "AbstractTaskPlugin.h" + +#include +#include + +#include + +namespace asst +{ + class ProcessTask; + + class StageDropsTaskPlugin : public AbstractTaskPlugin + { + public: + using AbstractTaskPlugin::AbstractTaskPlugin; + virtual ~StageDropsTaskPlugin() = default; + + virtual bool verify(AsstMsg msg, const json::value& details) const override; + virtual bool run(AbstractTask* ptr) override; + + private: + void recognize_drops(); + void drop_info_callback(); + void set_startbutton_delay(ProcessTask* ptr); + void upload_to_penguin(); + + std::unordered_map m_drop_stats; + json::value m_cur_drops; + bool m_startbutton_delay_setted = false; + std::vector> m_upload_pending; + }; +} diff --git a/src/MeoAssistant/TaskData.cpp b/src/MeoAssistant/TaskData.cpp index a0f3c6e3b4..88f9e855b9 100644 --- a/src/MeoAssistant/TaskData.cpp +++ b/src/MeoAssistant/TaskData.cpp @@ -123,9 +123,6 @@ bool asst::TaskData::parse(const json::value& json) rect_json[2].as_integer(), rect_json[3].as_integer()); } - else if (action == "stagedrops") { - task_info_ptr->action = ProcessTaskAction::StageDrops; - } else if (action == "swipetotheleft") { task_info_ptr->action = ProcessTaskAction::SwipeToTheLeft; } diff --git a/src/MeoAsstGui/Helper/AsstProxy.cs b/src/MeoAsstGui/Helper/AsstProxy.cs index d5d7a18659..3d13e67769 100644 --- a/src/MeoAsstGui/Helper/AsstProxy.cs +++ b/src/MeoAsstGui/Helper/AsstProxy.cs @@ -196,6 +196,7 @@ namespace MeoAsstGui break; case AsstMsg.SubTaskStart: + procSubTaskStart(details); break; case AsstMsg.SubTaskCompleted: @@ -220,7 +221,7 @@ namespace MeoAsstGui } } - private void procSubTaskCompleted(JObject details) + private void procSubTaskStart(JObject details) { string classType = details["class"].ToString(); @@ -255,6 +256,10 @@ namespace MeoAsstGui } } + private void procSubTaskCompleted(JObject details) + { + } + private void procSubTaskExtraInfo(JObject details) { string taskChain = details["taskchain"].ToString(); @@ -285,7 +290,7 @@ namespace MeoAsstGui mainModel.AddLog("当次掉落:\n" + cur_drops); string all_drops = ""; - JArray statistics = (JArray)details["statistics"]; + JArray statistics = (JArray)subTaskDetails["statistics"]; foreach (var item in statistics) { string itemName = item["itemName"].ToString();