From b0547c302a8ec00e912f28c034bbb04515e3ee80 Mon Sep 17 00:00:00 2001 From: MistEO Date: Tue, 3 Jan 2023 00:00:29 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=88=9D=E6=AD=A5=E8=B7=91=E9=80=9A?= =?UTF-8?q?=E4=BF=9D=E5=85=A8=E5=85=B3=E5=8D=A1=E5=88=87=E6=8D=A2=E6=B5=81?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resource/tasks.json | 33 ++++++-- src/MaaCore/Common/AsstBattleDef.h | 1 + src/MaaCore/MaaCore.vcxproj | 4 +- src/MaaCore/MaaCore.vcxproj.filters | 6 ++ src/MaaCore/Task/Interface/SSSCopilotTask.cpp | 24 +++--- src/MaaCore/Task/Interface/SSSCopilotTask.h | 6 +- .../Miscellaneous/SSSBattleProcessTask.cpp | 34 +++----- .../Task/Miscellaneous/SSSBattleProcessTask.h | 5 +- .../Miscellaneous/SSSStageManagerTask.cpp | 80 +++++++++++++++++++ .../Task/Miscellaneous/SSSStageManagerTask.h | 29 +++++++ 10 files changed, 174 insertions(+), 48 deletions(-) create mode 100644 src/MaaCore/Task/Miscellaneous/SSSStageManagerTask.cpp create mode 100644 src/MaaCore/Task/Miscellaneous/SSSStageManagerTask.h diff --git a/resource/tasks.json b/resource/tasks.json index 7d021b3146..7357d756bc 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -9475,10 +9475,16 @@ 576, 288, 144 - ], - "next": [ - "SSSStartFighting", - "SSSCloseTip" + ] + }, + "SSSStageNameOCR": { + "algorithm": "OcrDetect", + "text": [], + "roi": [ + 121, + 263, + 188, + 50 ] }, "SSSCloseTip": { @@ -9497,7 +9503,24 @@ "action": "ClickSelf", "algorithm": "OcrDetect", "text": [ - "开始部署" + "开始部署", + "重新部署" + ], + "roi": [ + 992, + 576, + 288, + 144 + ], + "next": [ + "SSSStartFighting2" + ] + }, + "SSSStartFighting2": { + "action": "ClickSelf", + "algorithm": "OcrDetect", + "text": [ + "开始行动" ], "roi": [ 992, diff --git a/src/MaaCore/Common/AsstBattleDef.h b/src/MaaCore/Common/AsstBattleDef.h index f5ffb91050..5c214162c9 100644 --- a/src/MaaCore/Common/AsstBattleDef.h +++ b/src/MaaCore/Common/AsstBattleDef.h @@ -200,6 +200,7 @@ namespace asst::battle { std::vector strategies; bool draw_as_possible = false; + int retry_times = 0; }; enum class EquipmentType diff --git a/src/MaaCore/MaaCore.vcxproj b/src/MaaCore/MaaCore.vcxproj index 3c457db70e..f093c27b0f 100644 --- a/src/MaaCore/MaaCore.vcxproj +++ b/src/MaaCore/MaaCore.vcxproj @@ -34,6 +34,7 @@ + @@ -154,6 +155,7 @@ + @@ -403,4 +405,4 @@ - + \ No newline at end of file diff --git a/src/MaaCore/MaaCore.vcxproj.filters b/src/MaaCore/MaaCore.vcxproj.filters index 68adfbfc4d..005985b86d 100644 --- a/src/MaaCore/MaaCore.vcxproj.filters +++ b/src/MaaCore/MaaCore.vcxproj.filters @@ -468,6 +468,9 @@ 源文件\Task\Roguelike + + 源文件\Task\Miscellaneous + @@ -767,5 +770,8 @@ 源文件\Task\Miscellaneous + + 源文件\Task\Miscellaneous + \ No newline at end of file diff --git a/src/MaaCore/Task/Interface/SSSCopilotTask.cpp b/src/MaaCore/Task/Interface/SSSCopilotTask.cpp index b6cfb7a37a..575115821f 100644 --- a/src/MaaCore/Task/Interface/SSSCopilotTask.cpp +++ b/src/MaaCore/Task/Interface/SSSCopilotTask.cpp @@ -3,7 +3,7 @@ #include "Config/Miscellaneous/SSSCopilotConfig.h" #include "Config/TaskData.h" #include "Task/Miscellaneous/BattleFormationTask.h" -#include "Task/Miscellaneous/SSSBattleProcessTask.h" +#include "Task/Miscellaneous/SSSStageManagerTask.h" #include "Task/ProcessTask.h" #include "Utils/Logger.hpp" #include "Utils/Platform.hpp" @@ -12,19 +12,19 @@ asst::SSSCopilotTask::SSSCopilotTask(const AsstCallback& callback, Assistant* in : InterfaceTask(callback, inst, TaskType), m_begin_task_ptr(std::make_shared(callback, inst, TaskType)), m_formation_task_ptr(std::make_shared(callback, inst, TaskType)), - m_battle_task_ptr(std::make_shared(callback, inst, TaskType)) + m_stage_task_ptr(std::make_shared(callback, inst, TaskType)) { - // m_begin_task_ptr->set_tasks({ inst_string() + "@SSSBegin" }).set_ignore_error(false); - // m_subtasks.emplace_back(m_begin_task_ptr); + m_begin_task_ptr->set_tasks({ inst_string() + "@SSSBegin" }).set_ignore_error(false); + m_subtasks.emplace_back(m_begin_task_ptr); - // m_formation_task_ptr->set_data_resource(BattleFormationTask::DataResource::SSSCopilot); - // m_subtasks.emplace_back(m_formation_task_ptr); + m_formation_task_ptr->set_data_resource(BattleFormationTask::DataResource::SSSCopilot); + m_subtasks.emplace_back(m_formation_task_ptr); - // auto start_2_tp = std::make_shared(callback, inst, TaskType); - // start_2_tp->set_tasks({ inst_string() + "@SSSTeamConfirm" }).set_ignore_error(false); - // m_subtasks.emplace_back(start_2_tp); + auto start_2_tp = std::make_shared(callback, inst, TaskType); + start_2_tp->set_tasks({ inst_string() + "@SSSTeamConfirm" }).set_ignore_error(false); + m_subtasks.emplace_back(start_2_tp); - m_subtasks.emplace_back(m_battle_task_ptr)->set_retry_times(0); + m_subtasks.emplace_back(m_stage_task_ptr); } bool asst::SSSCopilotTask::set_params(const json::value& params) @@ -62,9 +62,5 @@ bool asst::SSSCopilotTask::set_params(const json::value& params) }; m_formation_task_ptr->append_additional_formation(std::move(additional_formation)); - // for debug - m_battle_task_ptr->set_stage_index(0); - m_battle_task_ptr->set_stage_name("蜂拥而上"); - return true; } diff --git a/src/MaaCore/Task/Interface/SSSCopilotTask.h b/src/MaaCore/Task/Interface/SSSCopilotTask.h index 725929838b..51305d0dec 100644 --- a/src/MaaCore/Task/Interface/SSSCopilotTask.h +++ b/src/MaaCore/Task/Interface/SSSCopilotTask.h @@ -5,9 +5,9 @@ namespace asst { - class SSSBattleProcessTask; - class BattleFormationTask; class ProcessTask; + class BattleFormationTask; + class SSSStageManagerTask; // 保全派驻抄作业任务 class SSSCopilotTask final : public InterfaceTask @@ -23,6 +23,6 @@ namespace asst private: std::shared_ptr m_begin_task_ptr = nullptr; std::shared_ptr m_formation_task_ptr = nullptr; - std::shared_ptr m_battle_task_ptr = nullptr; + std::shared_ptr m_stage_task_ptr = nullptr; }; } diff --git a/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.cpp b/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.cpp index 6a493b3785..833bcc1651 100644 --- a/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.cpp @@ -8,11 +8,19 @@ using namespace asst::battle; using namespace asst::battle::sss; -bool asst::SSSBattleProcessTask::set_stage_name(const std::string& stage_name) +bool asst::SSSBattleProcessTask::set_stage_index(size_t index) { - LogTraceFunction; + Log.info(__FUNCTION__, index); - if (!BattleHelper::set_stage_name(stage_name)) { + if (index >= SSSCopilot.stages_size()) { + Log.error("SSS SSSBattleProcessTask: stage index out of range", index); + return false; + } + m_sss_combat_data = SSSCopilot.get_data(index); + ranges::transform(m_sss_combat_data.strategies, std::inserter(m_all_cores, m_all_cores.begin()), + [](const auto& strategy) { return strategy.core; }); + + if (!BattleHelper::set_stage_name(m_sss_combat_data.info.stage_name)) { json::value info = basic_info_with_what("UnsupportedLevel"); auto& details = info["details"]; details["level"] = m_stage_name; @@ -20,26 +28,6 @@ bool asst::SSSBattleProcessTask::set_stage_name(const std::string& stage_name) return false; } - if (m_stage_index >= SSSCopilot.stages_size()) { - Log.error("SSS CopilotConfig: stage index out of range", m_stage_index); - return false; - } - - m_sss_combat_data = SSSCopilot.get_data(m_stage_index); - ranges::transform(m_sss_combat_data.strategies, std::inserter(m_all_cores, m_all_cores.begin()), - [](const auto& strategy) { return strategy.core; }); - - return true; -} - -bool asst::SSSBattleProcessTask::set_stage_index(size_t index) -{ - Log.info(__FUNCTION__, index); - - if (index >= SSSCopilot.stages_size()) { - return false; - } - m_stage_index = index; return true; } diff --git a/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.h b/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.h index fd928e7fd3..ad37399796 100644 --- a/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.h +++ b/src/MaaCore/Task/Miscellaneous/SSSBattleProcessTask.h @@ -10,7 +10,6 @@ namespace asst virtual ~SSSBattleProcessTask() override = default; bool set_stage_index(size_t index); - virtual bool set_stage_name(const std::string& stage_name) override; protected: virtual bool do_derived_action(size_t action_index) override; @@ -24,6 +23,8 @@ namespace asst battle::sss::CombatData m_sss_combat_data; std::unordered_set m_all_cores; - size_t m_stage_index = SIZE_MAX; + + private: + using BattleProcessTask::set_stage_name; }; } diff --git a/src/MaaCore/Task/Miscellaneous/SSSStageManagerTask.cpp b/src/MaaCore/Task/Miscellaneous/SSSStageManagerTask.cpp new file mode 100644 index 0000000000..79bb46d128 --- /dev/null +++ b/src/MaaCore/Task/Miscellaneous/SSSStageManagerTask.cpp @@ -0,0 +1,80 @@ +#include "SSSStageManagerTask.h" + +#include "Config/Miscellaneous/SSSCopilotConfig.h" +#include "Controller.h" +#include "Task/Miscellaneous/SSSBattleProcessTask.h" +#include "Task/ProcessTask.h" +#include "Utils/Logger.hpp" +#include "Vision/OcrWithPreprocessImageAnalyzer.h" + +bool asst::SSSStageManagerTask::_run() +{ + LogTraceFunction; + + preprocess_data(); + size_t stage_count = SSSCopilot.get_data().stages_data.size(); + + while (!need_exit()) { + auto stage_opt = analyze_stage(); + if (!stage_opt) { + // TODO: 在点完开始之后,加载动画时,还会有一个很大的关卡名,可能识别成功率会更高 + // 如果这里识别失败,可以考虑再识别一下加载动画的 + Log.error("unknown stage"); + return false; + } + + if (!click_start_button()) { + return false; + } + const auto& [stage_name, stage_index] = stage_opt.value(); + int times = m_remaining_times[stage_name] + 1; + + SSSBattleProcessTask battle_task(m_callback, m_inst, m_task_chain); + battle_task.set_stage_index(stage_index); + + for (int i = 0; i < times; ++i) { + if (battle_task.run()) { + break; + } + } + if (stage_index >= stage_count) { + // TODO: 任务结束 + break; + } + } + return true; +} + +void asst::SSSStageManagerTask::preprocess_data() +{ + for (const auto& stage : SSSCopilot.get_data().stages_data) { + m_remaining_times[stage.info.stage_name] = stage.retry_times; + } +} + +std::optional asst::SSSStageManagerTask::analyze_stage() +{ + OcrWithPreprocessImageAnalyzer analyzer(ctrler()->get_image()); + analyzer.set_task_info("SSSStageNameOCR"); + if (!analyzer.analyze()) { + return std::nullopt; + } + + analyzer.sort_result_by_score(); + const std::string& text = analyzer.get_result().front().text; + + const auto& stages_data = SSSCopilot.get_data().stages_data; + for (int i = 0; i != stages_data.size(); ++i) { + if (stages_data.at(i).info.stage_name == text) { + Log.info("cur sss stage", text, ", index", i); + return StageInfo { .name = text, .index = i }; + } + } + + return std::nullopt; +} + +bool asst::SSSStageManagerTask::click_start_button() +{ + return ProcessTask(*this, { "SSSStartFighting", "SSSCloseTip" }).run(); +} diff --git a/src/MaaCore/Task/Miscellaneous/SSSStageManagerTask.h b/src/MaaCore/Task/Miscellaneous/SSSStageManagerTask.h new file mode 100644 index 0000000000..d321109025 --- /dev/null +++ b/src/MaaCore/Task/Miscellaneous/SSSStageManagerTask.h @@ -0,0 +1,29 @@ +#pragma once +#include "Task/AbstractTask.h" + +#include + +namespace asst +{ + class SSSStageManagerTask : public AbstractTask + { + public: + using AbstractTask::AbstractTask; + virtual ~SSSStageManagerTask() override = default; + + private: + virtual bool _run() override; + + void preprocess_data(); + + struct StageInfo + { + std::string name; + int index = 0; + }; + std::optional analyze_stage(); + bool click_start_button(); + + std::unordered_map m_remaining_times; + }; +}