Files
MaaAssistantArknights/src/MeoAssistant/AutoRecruitTask.h

108 lines
4.0 KiB
C++

#pragma once
#include "AbstractTask.h"
#include "AsstTypes.h"
#include <optional>
#include <set>
#include <vector>
namespace asst
{
class ReportDataTask;
class AutoRecruitTask final : public AbstractTask
{
public:
using AbstractTask::AbstractTask;
virtual ~AutoRecruitTask() override = default;
AutoRecruitTask& set_select_level(std::vector<int> select_level) noexcept;
AutoRecruitTask& set_confirm_level(std::vector<int> confirm_level) noexcept;
AutoRecruitTask& set_need_refresh(bool need_refresh) noexcept;
AutoRecruitTask& set_max_times(int max_times) noexcept;
AutoRecruitTask& set_use_expedited(bool use_or_not) noexcept;
AutoRecruitTask& set_skip_robot(bool skip_robot) noexcept;
AutoRecruitTask& set_set_time(bool set_time) noexcept;
AutoRecruitTask& set_recruitment_time(std::unordered_map<int, int>) noexcept;
AutoRecruitTask& set_penguin_enabled(bool enable, std::string penguin_id = std::string()) noexcept;
AutoRecruitTask& set_yituliu_enabled(bool enable, std::string yituliu_id = std::string()) noexcept;
AutoRecruitTask& set_server(std::string server) noexcept;
protected:
virtual bool _run() override;
bool is_calc_only_task() { return m_max_times <= 0 || m_confirm_level.empty(); }
std::optional<Rect> try_get_start_button(const cv::Mat&);
bool recruit_one(const Rect&);
bool check_recruit_home_page();
bool recruit_begin();
bool check_timer(int);
bool recruit_now();
bool confirm();
bool refresh();
bool hire_all(const cv::Mat&);
bool hire_all();
bool initialize_dirty_slot_info(const cv::Mat&);
static std::vector<TextRect> start_recruit_analyze(const cv::Mat& image);
void upload_result(const json::value& details);
void upload_to_penguin(const json::value& details);
void upload_to_yituliu(const json::value& details);
static void report_penguin_callback(AsstMsg msg, const json::value& detail, void* custom_arg);
static void report_yituliu_callback(AsstMsg msg, const json::value& detail, void* custom_arg);
using slot_index = size_t;
struct calc_task_result_type
{
bool success = false;
bool force_skip = false;
int recruitment_time = 60;
[[maybe_unused]] int tags_selected = 0;
};
calc_task_result_type recruit_calc_task(slot_index = 0);
bool m_force_discard_flag = false;
std::vector<int> m_select_level;
std::vector<int> m_confirm_level;
bool m_need_refresh = false;
bool m_use_expedited = false;
int m_max_times = 0;
bool m_skip_robot = true;
bool m_set_time = true;
std::unordered_map<int /*level*/, int /*minutes*/> m_desired_time_map;
int m_slot_fail = 0;
int m_cur_times = 0;
std::set<slot_index> m_force_skipped;
// Do not report tags from these slot. Already reported, or we can not make sure whether it has been reported.
// e.g. those that were already empty (*Recruit Now*) when we open the recruit page, because
// we can not make sure whether they were already reported yesterday but stayed untouched for some reason.
std::set<slot_index> m_dirty_slots = { 0, 1, 2, 3 };
std::string m_server = "CN";
bool m_upload_to_penguin = false;
bool m_upload_to_yituliu = false;
std::string m_penguin_id;
std::string m_yituliu_id;
std::shared_ptr<ReportDataTask> m_report_penguin_task_ptr = nullptr;
std::shared_ptr<ReportDataTask> m_report_yituliu_task_ptr = nullptr;
static slot_index slot_index_from_rect(const Rect& r)
{
/* 公开招募
* 0 | 1
* 2 | 3 */
int cx = r.x + r.width / 2;
int cy = r.y + r.height / 2;
return (cx > 640) + 2 * (cy > 444);
}
};
} // namespace asst