From ce02c80498364e2e36e3af55d2b5b54a7c376243 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 08:40:20 +0000 Subject: [PATCH] chore: Auto update by pre-commit hooks [skip changelog] --- src/MaaCore/Assistant.cpp | 21 +- src/MaaCore/Assistant.h | 237 ++--- src/MaaCore/AsstCaller.cpp | 28 +- src/MaaCore/Common/AsstBattleDef.h | 2 +- src/MaaCore/Common/AsstConf.h | 4 +- src/MaaCore/Common/AsstInfrastDef.h | 248 ++--- src/MaaCore/Common/AsstMsg.h | 104 +-- src/MaaCore/Common/AsstTypes.h | 867 +++++++++--------- src/MaaCore/Common/AsstVersion.h | 6 +- src/MaaCore/Config/AbstractConfigWithTempl.h | 12 +- src/MaaCore/Config/GeneralConfig.cpp | 21 +- src/MaaCore/Config/GeneralConfig.h | 19 +- .../Miscellaneous/AvatarCacheManager.cpp | 8 +- .../Config/Miscellaneous/AvatarCacheManager.h | 41 +- .../Config/Miscellaneous/BattleDataConfig.h | 152 ++- .../Config/Miscellaneous/CopilotConfig.h | 40 +- .../Config/Miscellaneous/InfrastConfig.h | 75 +- .../Config/Miscellaneous/ItemConfig.cpp | 5 +- src/MaaCore/Config/Miscellaneous/ItemConfig.h | 65 +- src/MaaCore/Config/Miscellaneous/OcrConfig.h | 23 +- src/MaaCore/Config/Miscellaneous/OcrPack.cpp | 20 +- src/MaaCore/Config/Miscellaneous/OcrPack.h | 84 +- .../Config/Miscellaneous/RecruitConfig.h | 195 ++-- .../Config/Miscellaneous/SSSCopilotConfig.h | 33 +- .../Config/Miscellaneous/StageDropsConfig.h | 166 ++-- src/MaaCore/Config/Miscellaneous/TilePack.cpp | 3 +- src/MaaCore/Config/Miscellaneous/TilePack.h | 4 +- src/MaaCore/Config/OnnxSessions.cpp | 12 +- src/MaaCore/Config/OnnxSessions.h | 30 +- src/MaaCore/Config/ResourceLoader.cpp | 54 +- src/MaaCore/Config/ResourceLoader.h | 8 +- .../Roguelike/RoguelikeCopilotConfig.cpp | 39 +- .../Config/Roguelike/RoguelikeCopilotConfig.h | 22 +- .../Roguelike/RoguelikeRecruitConfig.cpp | 2 +- .../Config/Roguelike/RoguelikeRecruitConfig.h | 24 +- .../Roguelike/RoguelikeShoppingConfig.h | 42 +- .../RoguelikeStageEncounterConfig.cpp | 12 +- .../Roguelike/RoguelikeStageEncounterConfig.h | 144 +-- .../Sami/RoguelikeCollapsalParadigmConfig.h | 69 +- .../Sami/RoguelikeFoldartalConfig.cpp | 1 - .../Roguelike/Sami/RoguelikeFoldartalConfig.h | 46 +- src/MaaCore/Config/TaskData.cpp | 200 ++-- src/MaaCore/Config/TaskData.h | 225 ++--- .../Config/TaskData/TaskDataSymbol.cpp | 4 +- src/MaaCore/Config/TaskData/TaskDataSymbol.h | 255 +++--- .../Config/TaskData/TaskDataSymbolStream.cpp | 9 +- .../Config/TaskData/TaskDataSymbolStream.h | 26 +- src/MaaCore/Config/TaskData/TaskDataTypes.h | 72 +- src/MaaCore/Config/TemplResource.h | 24 +- src/MaaCore/Controller/AdbController.cpp | 2 +- src/MaaCore/Controller/ControlScaleProxy.cpp | 40 +- src/MaaCore/Controller/ControlScaleProxy.h | 70 +- src/MaaCore/Controller/Controller.cpp | 16 +- src/MaaCore/Controller/Controller.h | 3 +- src/MaaCore/Controller/ControllerAPI.h | 5 +- .../Controller/MaaThriftController.cpp | 22 +- src/MaaCore/Controller/MaaThriftController.h | 132 +-- src/MaaCore/Controller/MaatouchController.h | 23 +- .../Controller/MinitouchController.cpp | 108 ++- src/MaaCore/Controller/MinitouchController.h | 422 +++++---- src/MaaCore/Controller/Platform/AdbLiteIO.cpp | 14 +- src/MaaCore/Controller/Platform/AdbLiteIO.h | 66 +- .../Controller/Platform/PlatformFactory.h | 26 +- src/MaaCore/Controller/Platform/PlatformIO.h | 56 +- src/MaaCore/Controller/Platform/PosixIO.cpp | 41 +- src/MaaCore/Controller/Platform/PosixIO.h | 95 +- src/MaaCore/Controller/Platform/Win32IO.cpp | 160 +++- src/MaaCore/Controller/Platform/Win32IO.h | 116 +-- .../Controller/PlayToolsController.cpp | 30 +- src/MaaCore/Controller/PlayToolsController.h | 19 +- src/MaaCore/Controller/adb-lite/client.cpp | 595 ++++++------ src/MaaCore/Controller/adb-lite/client.hpp | 294 +++--- src/MaaCore/Controller/adb-lite/protocol.cpp | 188 ++-- src/MaaCore/Controller/adb-lite/protocol.hpp | 95 +- src/MaaCore/InstHelper.cpp | 7 +- src/MaaCore/InstHelper.h | 44 +- src/MaaCore/LDExtras.cpp | 14 +- src/MaaCore/LDExtras.h | 9 +- src/MaaCore/Status.h | 60 +- src/MaaCore/Task/AbstractTask.cpp | 25 +- src/MaaCore/Task/AbstractTask.h | 129 +-- src/MaaCore/Task/AbstractTaskPlugin.h | 36 +- src/MaaCore/Task/BattleHelper.h | 151 +-- .../CombatRecordRecognitionTask.cpp | 26 +- .../Experiment/CombatRecordRecognitionTask.h | 140 +-- .../Experiment/SingleStepBattleProcessTask.h | 37 +- src/MaaCore/Task/Fight/DrGrandetTaskPlugin.h | 30 +- src/MaaCore/Task/Fight/FightTimesTaskPlugin.h | 28 +- .../Task/Fight/SanityBeforeStageTaskPlugin.h | 25 +- .../Task/Fight/SideStoryReopenTask.cpp | 13 +- src/MaaCore/Task/Fight/SideStoryReopenTask.h | 72 +- .../Task/Fight/StageDropsTaskPlugin.cpp | 5 +- src/MaaCore/Task/Fight/StageDropsTaskPlugin.h | 98 +- .../Task/Fight/StageNavigationTask.cpp | 7 +- src/MaaCore/Task/Fight/StageNavigationTask.h | 38 +- .../StageQueueMissionCompletedTaskPlugin.cpp | 20 +- .../StageQueueMissionCompletedTaskPlugin.h | 57 +- .../Task/Infrast/DronesForShamareTaskPlugin.h | 26 +- .../Task/Infrast/InfrastAbstractTask.cpp | 35 +- .../Task/Infrast/InfrastAbstractTask.h | 129 +-- src/MaaCore/Task/Infrast/InfrastControlTask.h | 22 +- src/MaaCore/Task/Infrast/InfrastDormTask.h | 64 +- src/MaaCore/Task/Infrast/InfrastInfoTask.h | 16 +- src/MaaCore/Task/Infrast/InfrastMfgTask.h | 24 +- src/MaaCore/Task/Infrast/InfrastOfficeTask.h | 16 +- src/MaaCore/Task/Infrast/InfrastPowerTask.h | 18 +- .../Task/Infrast/InfrastProcessingTask.h | 16 +- .../Task/Infrast/InfrastProductionTask.cpp | 33 +- .../Task/Infrast/InfrastProductionTask.h | 68 +- .../Task/Infrast/InfrastReceptionTask.cpp | 3 +- .../Task/Infrast/InfrastReceptionTask.h | 40 +- src/MaaCore/Task/Infrast/InfrastTradeTask.h | 24 +- .../Task/Infrast/InfrastTrainingTask.cpp | 24 +- .../Task/Infrast/InfrastTrainingTask.h | 47 +- .../ReplenishOriginiumShardTaskPlugin.h | 20 +- src/MaaCore/Task/Interface/AwardTask.cpp | 17 +- src/MaaCore/Task/Interface/AwardTask.h | 32 +- src/MaaCore/Task/Interface/CloseDownTask.cpp | 6 +- src/MaaCore/Task/Interface/CustomTask.cpp | 3 +- src/MaaCore/Task/Interface/CustomTask.h | 18 +- src/MaaCore/Task/Interface/DebugTask.cpp | 5 +- src/MaaCore/Task/Interface/DebugTask.h | 26 +- src/MaaCore/Task/Interface/DepotTask.cpp | 3 +- src/MaaCore/Task/Interface/DepotTask.h | 14 +- src/MaaCore/Task/Interface/FightTask.cpp | 12 +- src/MaaCore/Task/Interface/FightTask.h | 48 +- src/MaaCore/Task/Interface/InfrastTask.cpp | 45 +- src/MaaCore/Task/Interface/InfrastTask.h | 84 +- src/MaaCore/Task/Interface/MallTask.cpp | 16 +- src/MaaCore/Task/Interface/MallTask.h | 36 +- src/MaaCore/Task/Interface/OperBoxTask.cpp | 3 +- src/MaaCore/Task/Interface/OperBoxTask.h | 14 +- src/MaaCore/Task/Interface/RecruitTask.cpp | 6 +- src/MaaCore/Task/Interface/RecruitTask.h | 24 +- src/MaaCore/Task/Interface/SSSCopilotTask.h | 32 +- src/MaaCore/Task/Interface/SingleStepTask.cpp | 4 +- src/MaaCore/Task/Interface/SingleStepTask.h | 24 +- src/MaaCore/Task/Interface/StartUpTask.cpp | 13 +- src/MaaCore/Task/Interface/StartUpTask.h | 30 +- .../Task/Interface/VideoRecognitionTask.cpp | 4 +- .../Task/Interface/VideoRecognitionTask.h | 18 +- src/MaaCore/Task/InterfaceTask.h | 14 +- .../Task/Miscellaneous/AccountSwitchTask.h | 58 +- .../Task/Miscellaneous/AutoRecruitTask.cpp | 105 +-- .../Task/Miscellaneous/AutoRecruitTask.h | 208 ++--- .../Task/Miscellaneous/BattleProcessTask.cpp | 39 +- .../Task/Miscellaneous/BattleProcessTask.h | 70 +- .../Task/Miscellaneous/CreditFightTask.cpp | 4 +- .../Task/Miscellaneous/CreditFightTask.h | 20 +- .../Task/Miscellaneous/CreditShoppingTask.h | 50 +- .../Task/Miscellaneous/DepotRecognitionTask.h | 24 +- .../Miscellaneous/OperBoxRecognitionTask.cpp | 1 + .../Miscellaneous/OperBoxRecognitionTask.h | 24 +- .../Miscellaneous/ScreenshotTaskPlugin.cpp | 8 +- .../Task/Miscellaneous/ScreenshotTaskPlugin.h | 32 +- .../Miscellaneous/StartGameTaskPlugin.cpp | 3 +- .../Task/Miscellaneous/TaskFileReloadTask.h | 24 +- src/MaaCore/Task/PackageTask.h | 26 +- .../AbstractReclamationTaskPlugin.h | 2 +- .../ReclamationCraftTaskPlugin.cpp | 3 +- .../Reclamation/ReclamationCraftTaskPlugin.h | 4 +- src/MaaCore/Task/ReportDataTask.h | 83 +- .../Task/Roguelike/Map/RoguelikeMap.cpp | 10 +- src/MaaCore/Task/Roguelike/Map/RoguelikeMap.h | 14 +- .../Map/RoguelikeRoutingTaskPlugin.h | 22 +- .../Roguelike/RoguelikeBattleTaskPlugin.h | 292 +++--- .../Task/Roguelike/RoguelikeConfig.cpp | 1 - .../RoguelikeCustomStartTaskPlugin.h | 58 +- .../Task/Roguelike/RoguelikeDebugTaskPlugin.h | 31 +- .../RoguelikeDifficultySelectionTaskPlugin.h | 20 +- .../Roguelike/RoguelikeFormationTaskPlugin.h | 44 +- .../Roguelike/RoguelikeLastRewardTaskPlugin.h | 24 +- .../Roguelike/RoguelikeRecruitTaskPlugin.h | 4 +- .../Task/Roguelike/RoguelikeResetTaskPlugin.h | 18 +- .../RoguelikeSettlementTaskPlugin.cpp | 13 +- .../Roguelike/RoguelikeSettlementTaskPlugin.h | 28 +- .../Roguelike/RoguelikeShoppingTaskPlugin.cpp | 37 +- .../Roguelike/RoguelikeShoppingTaskPlugin.h | 26 +- .../RoguelikeSkillSelectionTaskPlugin.h | 18 +- .../RoguelikeStageEncounterTaskPlugin.cpp | 9 +- .../RoguelikeStageEncounterTaskPlugin.h | 30 +- .../RoguelikeStrategyChangeTaskPlugin.h | 24 +- .../RoguelikeCollapsalParadigmTaskPlugin.cpp | 6 +- .../RoguelikeCollapsalParadigmTaskPlugin.h | 6 +- .../Sami/RoguelikeFoldartalGainTaskPlugin.h | 47 +- .../Sami/RoguelikeFoldartalUseTaskPlugin.cpp | 39 +- .../Sami/RoguelikeFoldartalUseTaskPlugin.h | 78 +- src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp | 8 +- src/MaaCore/Task/SSS/SSSBattleProcessTask.h | 48 +- .../Task/SSS/SSSDropRewardsTaskPlugin.cpp | 5 +- .../Task/SSS/SSSDropRewardsTaskPlugin.h | 18 +- src/MaaCore/Task/SSS/SSSStageManagerTask.h | 30 +- src/MaaCore/Utils/Algorithm.hpp | 498 +++++----- src/MaaCore/Utils/Demangle.hpp | 40 +- src/MaaCore/Utils/File.hpp | 70 +- src/MaaCore/Utils/ImageIo.hpp | 68 +- src/MaaCore/Utils/JsonMisc.hpp | 301 +++--- src/MaaCore/Utils/LibraryHolder.hpp | 1 - src/MaaCore/Utils/Locale.hpp | 99 +- src/MaaCore/Utils/Logger.hpp | 70 +- src/MaaCore/Utils/Meta.hpp | 4 +- src/MaaCore/Utils/Platform.hpp | 36 +- src/MaaCore/Utils/Platform/Platform.h | 166 ++-- src/MaaCore/Utils/Platform/PlatformWin32.cpp | 107 +-- src/MaaCore/Utils/Platform/PlatformWin32.h | 15 +- src/MaaCore/Utils/Ranges.hpp | 12 +- src/MaaCore/Utils/SingletonHolder.hpp | 39 +- src/MaaCore/Utils/StringMisc.hpp | 225 ++--- src/MaaCore/Utils/Time.hpp | 55 +- src/MaaCore/Utils/WorkingDir.hpp | 46 +- .../Vision/Battle/BattleFormationAnalyzer.cpp | 14 +- .../Vision/Battle/BattleFormationAnalyzer.h | 40 +- .../Vision/Battle/BattlefieldClassifier.cpp | 2 +- .../Vision/Battle/BattlefieldClassifier.h | 129 +-- .../Vision/Battle/BattlefieldDetector.cpp | 27 +- .../Vision/Battle/BattlefieldDetector.h | 84 +- .../Vision/Battle/BattlefieldMatcher.cpp | 31 +- .../Vision/Battle/BattlefieldMatcher.h | 114 +-- src/MaaCore/Vision/BestMatcher.h | 83 +- src/MaaCore/Vision/Config/MatcherConfig.h | 78 +- src/MaaCore/Vision/Config/OCRerConfig.cpp | 12 +- src/MaaCore/Vision/Config/OCRerConfig.h | 87 +- src/MaaCore/Vision/Hasher.cpp | 4 +- src/MaaCore/Vision/Hasher.h | 52 +- .../Infrast/InfrastClueVacancyImageAnalyzer.h | 40 +- .../Infrast/InfrastFacilityImageAnalyzer.h | 75 +- .../Infrast/InfrastOperImageAnalyzer.cpp | 15 +- .../Vision/Infrast/InfrastOperImageAnalyzer.h | 95 +- .../Infrast/InfrastSmileyImageAnalyzer.h | 20 +- src/MaaCore/Vision/Matcher.cpp | 16 +- src/MaaCore/Vision/Matcher.h | 58 +- .../Miscellaneous/BrightPointAnalyzer.h | 1 + .../Miscellaneous/CreditShopImageAnalyzer.cpp | 5 +- .../Miscellaneous/CreditShopImageAnalyzer.h | 42 +- .../Miscellaneous/DepotImageAnalyzer.cpp | 72 +- .../Vision/Miscellaneous/DepotImageAnalyzer.h | 74 +- .../Miscellaneous/OperBoxImageAnalyzer.cpp | 40 +- .../Miscellaneous/OperBoxImageAnalyzer.h | 57 +- .../Vision/Miscellaneous/PipelineAnalyzer.h | 47 +- .../Miscellaneous/RecruitImageAnalyzer.cpp | 8 +- .../Miscellaneous/RecruitImageAnalyzer.h | 54 +- .../Miscellaneous/StageDropsImageAnalyzer.cpp | 161 +++- .../Miscellaneous/StageDropsImageAnalyzer.h | 87 +- src/MaaCore/Vision/MultiMatcher.cpp | 9 +- src/MaaCore/Vision/MultiMatcher.h | 37 +- src/MaaCore/Vision/OCRer.h | 55 +- src/MaaCore/Vision/OnnxHelper.h | 46 +- src/MaaCore/Vision/RegionOCRer.cpp | 4 +- src/MaaCore/Vision/RegionOCRer.h | 47 +- .../RoguelikeFormationImageAnalyzer.cpp | 4 +- .../RoguelikeFormationImageAnalyzer.h | 52 +- .../Roguelike/RoguelikeParameterAnalyzer.h | 4 +- .../RoguelikeRecruitImageAnalyzer.cpp | 5 +- .../Roguelike/RoguelikeRecruitImageAnalyzer.h | 24 +- .../RoguelikeRecruitSupportAnalyzer.cpp | 31 +- .../RoguelikeRecruitSupportAnalyzer.h | 45 +- .../RoguelikeSkillSelectionImageAnalyzer.cpp | 5 +- .../RoguelikeSkillSelectionImageAnalyzer.h | 39 +- src/MaaCore/Vision/TemplDetOCRer.h | 80 +- src/MaaCore/Vision/VisionHelper.cpp | 15 +- src/MaaCore/Vision/VisionHelper.h | 196 ++-- 261 files changed, 7746 insertions(+), 7012 deletions(-) diff --git a/src/MaaCore/Assistant.cpp b/src/MaaCore/Assistant.cpp index 5194a447f0..901014964b 100644 --- a/src/MaaCore/Assistant.cpp +++ b/src/MaaCore/Assistant.cpp @@ -59,7 +59,9 @@ bool ::AsstExtAPI::set_static_option(StaticOptionKey key, const std::string& val return false; } -Assistant::Assistant(ApiCallback callback, void* callback_arg) : m_callback(callback), m_callback_arg(callback_arg) +Assistant::Assistant(ApiCallback callback, void* callback_arg) : + m_callback(callback), + m_callback_arg(callback_arg) { LogTraceFunction; @@ -218,7 +220,8 @@ asst::Assistant::TaskId asst::Assistant::append_task(const std::string& type, co ptr = std::make_shared(append_callback_for_inst, this); \ } - if constexpr (false) {} + if constexpr (false) { + } ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(FightTask) ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(StartUpTask) ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(CloseDownTask) @@ -311,14 +314,18 @@ bool asst::Assistant::connect(const std::string& adb_path, const std::string& ad return ctrl_connect(adb_path, address, config); } -asst::Assistant::AsyncCallId asst::Assistant::async_connect(const std::string& adb_path, const std::string& address, - const std::string& config, bool block) +asst::Assistant::AsyncCallId asst::Assistant::async_connect( + const std::string& adb_path, + const std::string& address, + const std::string& config, + bool block) { LogTraceFunction; return append_async_call( AsyncCallItem::Type::Connect, - AsyncCallItem::ConnectParams { .adb_path = adb_path, .address = address, .config = config }, block); + AsyncCallItem::ConnectParams { .adb_path = adb_path, .address = address, .config = config }, + block); } asst::Assistant::AsyncCallId asst::Assistant::async_click(int x, int y, bool block) @@ -486,8 +493,8 @@ void Assistant::msg_proc() } } -asst::Assistant::AsyncCallId asst::Assistant::append_async_call(AsyncCallItem::Type type, AsyncCallItem::Parmas params, - bool block) +asst::Assistant::AsyncCallId + asst::Assistant::append_async_call(AsyncCallItem::Type type, AsyncCallItem::Parmas params, bool block) { LogTraceFunction; diff --git a/src/MaaCore/Assistant.h b/src/MaaCore/Assistant.h index dbaca7c1c6..442ab9c1ee 100644 --- a/src/MaaCore/Assistant.h +++ b/src/MaaCore/Assistant.h @@ -28,8 +28,11 @@ public: // FIXME: 5.0 版本将废弃此接口 virtual bool connect(const std::string& adb_path, const std::string& address, const std::string& config) = 0; // 异步连接 - virtual AsyncCallId async_connect(const std::string& adb_path, const std::string& address, - const std::string& config, bool block = false) = 0; + virtual AsyncCallId async_connect( + const std::string& adb_path, + const std::string& address, + const std::string& config, + bool block = false) = 0; // 异步点击 virtual AsyncCallId async_click(int x, int y, bool block = false) = 0; // 异步截图 @@ -62,124 +65,134 @@ public: namespace asst { - class Controller; - class InterfaceTask; - class Status; +class Controller; +class InterfaceTask; +class Status; - class Assistant : public AsstExtAPI +class Assistant : public AsstExtAPI +{ +public: + Assistant(ApiCallback callback = nullptr, void* callback_arg = nullptr); + virtual ~Assistant() override; + + virtual bool set_instance_option(InstanceOptionKey key, const std::string& value) override; + + virtual bool connect(const std::string& adb_path, const std::string& address, const std::string& config) override; + virtual AsyncCallId async_connect( + const std::string& adb_path, + const std::string& address, + const std::string& config, + bool block = false) override; + virtual AsyncCallId async_click(int x, int y, bool block = false) override; + virtual AsyncCallId async_screencap(bool block = false) override; + + virtual bool connected() const override; + + virtual TaskId append_task(const std::string& type, const std::string& params) override; + virtual bool set_task_params(TaskId task_id, const std::string& params) override; + + virtual bool start(bool block = true) override; + virtual bool stop(bool block = true) override; + virtual bool running() const override; + + virtual std::vector get_image() const override; + virtual std::string get_uuid() const override; + virtual std::vector get_tasks_list() const override; + + virtual bool back_to_home() const override; + +public: + std::shared_ptr ctrler() const { return m_ctrler; } + + std::shared_ptr status() const { return m_status; } + + bool need_exit() const { return m_thread_idle && m_running; } + +private: + void append_callback(AsstMsg msg, const json::value& detail); + static void append_callback_for_inst(AsstMsg msg, const json::value& detail, Assistant* inst); + +private: + struct AsyncCallItem { - public: - Assistant(ApiCallback callback = nullptr, void* callback_arg = nullptr); - virtual ~Assistant() override; - - virtual bool set_instance_option(InstanceOptionKey key, const std::string& value) override; - - virtual bool connect(const std::string& adb_path, const std::string& address, - const std::string& config) override; - virtual AsyncCallId async_connect(const std::string& adb_path, const std::string& address, - const std::string& config, bool block = false) override; - virtual AsyncCallId async_click(int x, int y, bool block = false) override; - virtual AsyncCallId async_screencap(bool block = false) override; - - virtual bool connected() const override; - - virtual TaskId append_task(const std::string& type, const std::string& params) override; - virtual bool set_task_params(TaskId task_id, const std::string& params) override; - - virtual bool start(bool block = true) override; - virtual bool stop(bool block = true) override; - virtual bool running() const override; - - virtual std::vector get_image() const override; - virtual std::string get_uuid() const override; - virtual std::vector get_tasks_list() const override; - - virtual bool back_to_home() const override; - - public: - std::shared_ptr ctrler() const { return m_ctrler; } - std::shared_ptr status() const { return m_status; } - bool need_exit() const { return m_thread_idle && m_running; } - - private: - void append_callback(AsstMsg msg, const json::value& detail); - static void append_callback_for_inst(AsstMsg msg, const json::value& detail, Assistant* inst); - - private: - struct AsyncCallItem + enum class Type { - enum class Type - { - Connect, - Click, - Screencap, - }; - struct ConnectParams - { - std::string adb_path; - std::string address; - std::string config; - }; - struct ClickParams - { - int x = 0; - int y = 0; - }; - struct ScreencapParams - {}; - using Parmas = std::variant; - - AsyncCallId id; - Type type; - Parmas params; + Connect, + Click, + Screencap, }; - AsyncCallId append_async_call(AsyncCallItem::Type type, AsyncCallItem::Parmas params, bool block = false); - bool wait_async_id(AsyncCallId id); - private: - void call_proc(); - void working_proc(); - void msg_proc(); + struct ConnectParams + { + std::string adb_path; + std::string address; + std::string config; + }; - private: - void clear_cache(); - bool inited() const noexcept; + struct ClickParams + { + int x = 0; + int y = 0; + }; - bool ctrl_connect(const std::string& adb_path, const std::string& address, const std::string& config); - bool ctrl_click(int x, int y); - bool ctrl_screencap(); + struct ScreencapParams + { + }; - std::string m_uuid; + using Parmas = std::variant; - std::shared_ptr m_ctrler = nullptr; - std::shared_ptr m_status = nullptr; - - std::atomic_bool m_thread_exit = false; - std::list>> m_tasks_list; - inline static TaskId m_task_id = 0; // 进程级唯一 - ApiCallback m_callback = nullptr; - void* m_callback_arg = nullptr; - - std::atomic_bool m_thread_idle = true; - std::atomic_bool m_running = false; - mutable std::mutex m_mutex; - std::condition_variable m_condvar; - - std::queue> m_msg_queue; - std::mutex m_msg_mutex; - std::condition_variable m_msg_condvar; - - inline static std::atomic m_call_id = 0; // 进程级唯一 - std::queue m_call_queue; - std::mutex m_call_mutex; - std::condition_variable m_call_condvar; - - AsyncCallId m_completed_call = 0; // 每个实例有自己独立的执行队列,所以不能静态 - std::mutex m_completed_call_mutex; - std::condition_variable m_completed_call_condvar; - - std::thread m_msg_thread; - std::thread m_call_thread; - std::thread m_working_thread; + AsyncCallId id; + Type type; + Parmas params; }; + + AsyncCallId append_async_call(AsyncCallItem::Type type, AsyncCallItem::Parmas params, bool block = false); + bool wait_async_id(AsyncCallId id); + +private: + void call_proc(); + void working_proc(); + void msg_proc(); + +private: + void clear_cache(); + bool inited() const noexcept; + + bool ctrl_connect(const std::string& adb_path, const std::string& address, const std::string& config); + bool ctrl_click(int x, int y); + bool ctrl_screencap(); + + std::string m_uuid; + + std::shared_ptr m_ctrler = nullptr; + std::shared_ptr m_status = nullptr; + + std::atomic_bool m_thread_exit = false; + std::list>> m_tasks_list; + inline static TaskId m_task_id = 0; // 进程级唯一 + ApiCallback m_callback = nullptr; + void* m_callback_arg = nullptr; + + std::atomic_bool m_thread_idle = true; + std::atomic_bool m_running = false; + mutable std::mutex m_mutex; + std::condition_variable m_condvar; + + std::queue> m_msg_queue; + std::mutex m_msg_mutex; + std::condition_variable m_msg_condvar; + + inline static std::atomic m_call_id = 0; // 进程级唯一 + std::queue m_call_queue; + std::mutex m_call_mutex; + std::condition_variable m_call_condvar; + + AsyncCallId m_completed_call = 0; // 每个实例有自己独立的执行队列,所以不能静态 + std::mutex m_completed_call_mutex; + std::condition_variable m_completed_call_condvar; + + std::thread m_msg_thread; + std::thread m_call_thread; + std::thread m_working_thread; +}; } // namespace asst diff --git a/src/MaaCore/AsstCaller.cpp b/src/MaaCore/AsstCaller.cpp index ce27b2ae90..e868da930e 100644 --- a/src/MaaCore/AsstCaller.cpp +++ b/src/MaaCore/AsstCaller.cpp @@ -70,9 +70,7 @@ AsstBool AsstLoadResource(const char* path) AsstBool AsstSetStaticOption(AsstStaticOptionKey key, const char* value) { - return AsstExtAPI::set_static_option(static_cast(key), value) - ? AsstTrue - : AsstFalse; + return AsstExtAPI::set_static_option(static_cast(key), value) ? AsstTrue : AsstFalse; } AsstHandle AsstCreate() @@ -107,25 +105,17 @@ AsstBool AsstSetInstanceOption(AsstHandle handle, AsstInstanceOptionKey key, con return AsstFalse; } - return handle->set_instance_option(static_cast(key), value) - ? AsstTrue - : AsstFalse; + return handle->set_instance_option(static_cast(key), value) ? AsstTrue : AsstFalse; } -AsstBool - AsstConnect(AsstHandle handle, const char* adb_path, const char* address, const char* config) +AsstBool AsstConnect(AsstHandle handle, const char* adb_path, const char* address, const char* config) { if (!inited() || handle == nullptr) { - Log.error( - __FUNCTION__, - "Cannot connect to device, asst not inited or handle is null", - inited(), - handle); + Log.error(__FUNCTION__, "Cannot connect to device, asst not inited or handle is null", inited(), handle); return AsstFalse; } - return handle->connect(adb_path, address, config ? config : std::string()) ? AsstTrue - : AsstFalse; + return handle->connect(adb_path, address, config ? config : std::string()) ? AsstTrue : AsstFalse; } AsstBool AsstStart(AsstHandle handle) @@ -173,12 +163,8 @@ AsstBool ASSTAPI AsstBackToHome(AsstHandle handle) return handle->back_to_home() ? AsstTrue : AsstFalse; } -AsstAsyncCallId AsstAsyncConnect( - AsstHandle handle, - const char* adb_path, - const char* address, - const char* config, - AsstBool block) +AsstAsyncCallId + AsstAsyncConnect(AsstHandle handle, const char* adb_path, const char* address, const char* config, AsstBool block) { if (!inited() || handle == nullptr) { return InvalidId; diff --git a/src/MaaCore/Common/AsstBattleDef.h b/src/MaaCore/Common/AsstBattleDef.h index 089968d324..10492485cb 100644 --- a/src/MaaCore/Common/AsstBattleDef.h +++ b/src/MaaCore/Common/AsstBattleDef.h @@ -1,9 +1,9 @@ #pragma once +#include #include #include #include -#include #include "AsstTypes.h" #include "Utils/NoWarningCVMat.h" diff --git a/src/MaaCore/Common/AsstConf.h b/src/MaaCore/Common/AsstConf.h index f629ebc9a5..ff1931a8b4 100644 --- a/src/MaaCore/Common/AsstConf.h +++ b/src/MaaCore/Common/AsstConf.h @@ -4,7 +4,7 @@ #define ASST_USE_RANGES_STL #endif -#if !defined (ASST_WITH_EMULATOR_EXTRAS) +#if !defined(ASST_WITH_EMULATOR_EXTRAS) #define ASST_WITH_EMULATOR_EXTRAS 1 #endif @@ -19,7 +19,7 @@ #ifdef _MSC_VER #define ASST_SUPPRESS_CV_WARNINGS_START \ ASST_DO_PRAGMA(warning(push)) \ - ASST_DO_PRAGMA(warning(disable : 5054 4251 4305 4275 4100 4244)) + ASST_DO_PRAGMA(warning(disable: 5054 4251 4305 4275 4100 4244)) #define ASST_SUPPRESS_CV_WARNINGS_END ASST_DO_PRAGMA(warning(pop)) #elif defined(__clang__) #define ASST_SUPPRESS_CV_WARNINGS_START \ diff --git a/src/MaaCore/Common/AsstInfrastDef.h b/src/MaaCore/Common/AsstInfrastDef.h index 775641b224..df4b73904e 100644 --- a/src/MaaCore/Common/AsstInfrastDef.h +++ b/src/MaaCore/Common/AsstInfrastDef.h @@ -5,150 +5,152 @@ namespace asst::infrast { - struct Facility - { - std::string id; - std::vector products; - int max_num_of_opers = 0; - }; +struct Facility +{ + std::string id; + std::vector products; + int max_num_of_opers = 0; +}; - enum class SmileyType - { - Invalid = -1, - Rest, // 休息完成,绿色笑脸 - Work, // 工作中,黄色笑脸 - Distract // 注意力涣散,红色哭脸 - }; - struct Smiley - { - SmileyType type = SmileyType::Invalid; - Rect rect; - }; - enum class Doing // 正在做什么 - { - Invalid = -1, - Nothing, // 什么都不在做,也不在休息也不在工作 - Resting, // 休息中 - Working // 工作中 - }; +enum class SmileyType +{ + Invalid = -1, + Rest, // 休息完成,绿色笑脸 + Work, // 工作中,黄色笑脸 + Distract // 注意力涣散,红色哭脸 +}; - struct Skill - { - std::string id; - std::string templ_name; - std::vector names; // 很多基建技能是一样的,就是名字不同。所以一个技能id可能对应多个名字 - std::string desc; - std::unordered_map efficient; // 技能效率,key:产品名(赤金、经验书等), value: 效率数值 - std::unordered_map - efficient_regex; // 技能效率正则,key:产品名(赤金、经验书等), value: 效率正则。 - // 如不为空,会先对正则进行计算,再加上efficient里面的值 - int max_num = INT_MAX; // 最多选几个该技能 +struct Smiley +{ + SmileyType type = SmileyType::Invalid; + Rect rect; +}; +enum class Doing // 正在做什么 +{ + Invalid = -1, + Nothing, // 什么都不在做,也不在休息也不在工作 + Resting, // 休息中 + Working // 工作中 +}; - bool operator==(const Skill& skill) const noexcept { return id == skill.id; } - }; +struct Skill +{ + std::string id; + std::string templ_name; + std::vector names; // 很多基建技能是一样的,就是名字不同。所以一个技能id可能对应多个名字 + std::string desc; + std::unordered_map efficient; // 技能效率,key:产品名(赤金、经验书等), value: 效率数值 + std::unordered_map + efficient_regex; // 技能效率正则,key:产品名(赤金、经验书等), value: 效率正则。 + // 如不为空,会先对正则进行计算,再加上efficient里面的值 + int max_num = INT_MAX; // 最多选几个该技能 + + bool operator==(const Skill& skill) const noexcept { return id == skill.id; } +}; } namespace std { - template <> - struct hash - { - size_t operator()(const asst::infrast::Skill& skill) const noexcept - { - return ::std::hash()(skill.id); - } - }; +template <> +struct hash +{ + size_t operator()(const asst::infrast::Skill& skill) const noexcept { return ::std::hash()(skill.id); } +}; } namespace asst::infrast { - struct Oper - { - std::string face_hash; // 有些干员的技能是完全一样的,做个hash区分一下不同干员 - Smiley smiley; - double mood_ratio = 0; // 心情进度条的百分比 - Doing doing = Doing::Invalid; - bool selected = false; // 干员是否已被选择(蓝色的选择框) - std::unordered_set skills; - Rect rect; - // 因为OCR识别名字比较费时间,所以仅在name_filter不为空(有识别名字需求)的时候才识别,否则仅保存图片但不识别 - cv::Mat name_img; - cv::Mat facility_img; - }; +struct Oper +{ + std::string face_hash; // 有些干员的技能是完全一样的,做个hash区分一下不同干员 + Smiley smiley; + double mood_ratio = 0; // 心情进度条的百分比 + Doing doing = Doing::Invalid; + bool selected = false; // 干员是否已被选择(蓝色的选择框) + std::unordered_set skills; + Rect rect; + // 因为OCR识别名字比较费时间,所以仅在name_filter不为空(有识别名字需求)的时候才识别,否则仅保存图片但不识别 + cv::Mat name_img; + cv::Mat facility_img; +}; - struct SkillsComb +struct SkillsComb +{ + SkillsComb() = default; + + SkillsComb(std::unordered_set skill_vec) { - SkillsComb() = default; - SkillsComb(std::unordered_set skill_vec) - { - skills = std::move(skill_vec); - for (const auto& s : skills) { - for (const auto& [key, value] : s.efficient) { - efficient[key] += value; - } - for (const auto& [key, reg] : s.efficient_regex) { - efficient_regex[key] += "+(" + reg + ")"; - } + skills = std::move(skill_vec); + for (const auto& s : skills) { + for (const auto& [key, value] : s.efficient) { + efficient[key] += value; + } + for (const auto& [key, reg] : s.efficient_regex) { + efficient_regex[key] += "+(" + reg + ")"; } } - bool operator==(const SkillsComb& rhs) const { return skills == rhs.skills; } + } - std::string desc; - std::unordered_set skills; - std::unordered_map efficient; - std::unordered_map efficient_regex; + bool operator==(const SkillsComb& rhs) const { return skills == rhs.skills; } - std::vector name_filter; - // 因为OCR识别名字比较费时间,所以仅在name_filter不为空(有识别名字需求)的时候才识别,否则仅保存图片但不识别 - cv::Mat name_img; - }; - // 基建技能组 - struct SkillsGroup + std::string desc; + std::unordered_set skills; + std::unordered_map efficient; + std::unordered_map efficient_regex; + + std::vector name_filter; + // 因为OCR识别名字比较费时间,所以仅在name_filter不为空(有识别名字需求)的时候才识别,否则仅保存图片但不识别 + cv::Mat name_img; +}; + +// 基建技能组 +struct SkillsGroup +{ + std::string desc; // 文字介绍,实际不起作用 + std::unordered_map conditions; // 技能组合可用条件,例如:key 发电站数量,value 3 + std::vector necessary; // 必选技能。这里面的缺少任一,则该技能组合不可用 + std::vector optional; // 可选技能。 + bool allow_external = false; // 当干员数没满3个的时候,是否允许补充外部干员 +}; + +struct CustomRoomConfig +{ + enum class Product { - std::string desc; // 文字介绍,实际不起作用 - std::unordered_map conditions; // 技能组合可用条件,例如:key 发电站数量,value 3 - std::vector necessary; // 必选技能。这里面的缺少任一,则该技能组合不可用 - std::vector optional; // 可选技能。 - bool allow_external = false; // 当干员数没满3个的时候,是否允许补充外部干员 + Unknown, + BattleRecord, + PureGold, + Dualchip, + OriginiumShard, + LMD, + Orundum, }; - struct CustomRoomConfig + bool skip = false; + // 是否使用干员编组 + bool use_operator_groups = false; + // 干员编组列表 + std::unordered_map> operator_groups; + // 自定干员 + std::vector names; + bool autofill = false; + Product product = Product::Unknown; + std::vector candidates; + int selected = 0; + bool sort = false; +}; + +using CustomFacilityConfig = std::vector; + +struct CustomDronesConfig +{ + enum class Order { - enum class Product - { - Unknown, - BattleRecord, - PureGold, - Dualchip, - OriginiumShard, - LMD, - Orundum, - }; - - bool skip = false; - // 是否使用干员编组 - bool use_operator_groups = false; - // 干员编组列表 - std::unordered_map> operator_groups; - // 自定干员 - std::vector names; - bool autofill = false; - Product product = Product::Unknown; - std::vector candidates; - int selected = 0; - bool sort = false; + Pre, + Post, }; - using CustomFacilityConfig = std::vector; - struct CustomDronesConfig - { - enum class Order - { - Pre, - Post, - }; - - int index = 0; - Order order = Order::Pre; - }; + int index = 0; + Order order = Order::Pre; +}; } // namespace asst::infrast diff --git a/src/MaaCore/Common/AsstMsg.h b/src/MaaCore/Common/AsstMsg.h index 7fbc0aa571..d4e34b91bd 100644 --- a/src/MaaCore/Common/AsstMsg.h +++ b/src/MaaCore/Common/AsstMsg.h @@ -8,60 +8,60 @@ namespace asst { - enum class AsstMsg - { +enum class AsstMsg +{ + /* Global Info */ + InternalError = 0, // 内部错误 + InitFailed, // 初始化失败 + ConnectionInfo, // 连接相关错误 + AllTasksCompleted, // 全部任务完成 + AsyncCallInfo, // 外部异步调用信息 + Destroyed, // 实例已销毁 + /* TaskChain Info */ + TaskChainError = 10000, // 任务链执行/识别错误 + TaskChainStart, // 任务链开始 + TaskChainCompleted, // 任务链完成 + TaskChainExtraInfo, // 任务链额外信息 + TaskChainStopped, // 任务链停止(手动停止) + /* SubTask Info */ + SubTaskError = 20000, // 原子任务执行/识别错误 + SubTaskStart, // 原子任务开始 + SubTaskCompleted, // 原子任务完成 + SubTaskExtraInfo, // 原子任务额外信息 + SubTaskStopped, // 原子任务停止(手动停止) +}; + +inline std::ostream& operator<<(std::ostream& os, const AsstMsg& type) +{ + static const std::unordered_map _type_name = { /* Global Info */ - InternalError = 0, // 内部错误 - InitFailed, // 初始化失败 - ConnectionInfo, // 连接相关错误 - AllTasksCompleted, // 全部任务完成 - AsyncCallInfo, // 外部异步调用信息 - Destroyed, // 实例已销毁 + { AsstMsg::InternalError, "InternalError" }, + { AsstMsg::InitFailed, "InitFailed" }, + { AsstMsg::ConnectionInfo, "ConnectionInfo" }, + { AsstMsg::AllTasksCompleted, "AllTasksCompleted" }, + { AsstMsg::AsyncCallInfo, "AsyncCallInfo" }, + { AsstMsg::Destroyed, "Destroyed" }, /* TaskChain Info */ - TaskChainError = 10000, // 任务链执行/识别错误 - TaskChainStart, // 任务链开始 - TaskChainCompleted, // 任务链完成 - TaskChainExtraInfo, // 任务链额外信息 - TaskChainStopped, // 任务链停止(手动停止) + { AsstMsg::TaskChainError, "TaskChainError" }, + { AsstMsg::TaskChainStart, "TaskChainStart" }, + { AsstMsg::TaskChainCompleted, "TaskChainCompleted" }, + { AsstMsg::TaskChainExtraInfo, "TaskChainExtraInfo" }, + { AsstMsg::TaskChainStopped, "TaskChainStopped" }, /* SubTask Info */ - SubTaskError = 20000, // 原子任务执行/识别错误 - SubTaskStart, // 原子任务开始 - SubTaskCompleted, // 原子任务完成 - SubTaskExtraInfo, // 原子任务额外信息 - SubTaskStopped, // 原子任务停止(手动停止) + { AsstMsg::SubTaskError, "SubTaskError" }, + { AsstMsg::SubTaskStart, "SubTaskStart" }, + { AsstMsg::SubTaskCompleted, "SubTaskCompleted" }, + { AsstMsg::SubTaskExtraInfo, "SubTaskExtraInfo" }, + { AsstMsg::SubTaskStopped, "SubTaskStopped" }, }; - - inline std::ostream& operator<<(std::ostream& os, const AsstMsg& type) - { - static const std::unordered_map _type_name = { - /* Global Info */ - { AsstMsg::InternalError, "InternalError" }, - { AsstMsg::InitFailed, "InitFailed" }, - { AsstMsg::ConnectionInfo, "ConnectionInfo" }, - { AsstMsg::AllTasksCompleted, "AllTasksCompleted" }, - { AsstMsg::AsyncCallInfo, "AsyncCallInfo" }, - { AsstMsg::Destroyed, "Destroyed" }, - /* TaskChain Info */ - { AsstMsg::TaskChainError, "TaskChainError" }, - { AsstMsg::TaskChainStart, "TaskChainStart" }, - { AsstMsg::TaskChainCompleted, "TaskChainCompleted" }, - { AsstMsg::TaskChainExtraInfo, "TaskChainExtraInfo" }, - { AsstMsg::TaskChainStopped, "TaskChainStopped" }, - /* SubTask Info */ - { AsstMsg::SubTaskError, "SubTaskError" }, - { AsstMsg::SubTaskStart, "SubTaskStart" }, - { AsstMsg::SubTaskCompleted, "SubTaskCompleted" }, - { AsstMsg::SubTaskExtraInfo, "SubTaskExtraInfo" }, - { AsstMsg::SubTaskStopped, "SubTaskStopped" }, - }; - return os << _type_name.at(type); - } - - // 对外的回调接口 - using AsstMsgId = int32_t; - using ApiCallback = void (*)(AsstMsgId msg, const char* details_json, void* custom_arg); - - // 内部使用的回调 - class Assistant; - using AsstCallback = std::function; + return os << _type_name.at(type); +} + +// 对外的回调接口 +using AsstMsgId = int32_t; +using ApiCallback = void (*)(AsstMsgId msg, const char* details_json, void* custom_arg); + +// 内部使用的回调 +class Assistant; +using AsstCallback = std::function; } diff --git a/src/MaaCore/Common/AsstTypes.h b/src/MaaCore/Common/AsstTypes.h index fa42039547..b85dfd9e09 100644 --- a/src/MaaCore/Common/AsstTypes.h +++ b/src/MaaCore/Common/AsstTypes.h @@ -19,78 +19,95 @@ namespace asst { - constexpr double DoubleDiff = 1e-12; +constexpr double DoubleDiff = 1e-12; - static constexpr int WindowWidthDefault = 1280; - static constexpr int WindowHeightDefault = 720; +static constexpr int WindowWidthDefault = 1280; +static constexpr int WindowHeightDefault = 720; - static constexpr double TemplThresholdDefault = 0.8; +static constexpr double TemplThresholdDefault = 0.8; - enum class StaticOptionKey +enum class StaticOptionKey +{ + Invalid = 0, + CpuOCR = 1, // use CPU to OCR, no value. It does not support switching after the resource is loaded. + GpuOCR = 2, // use GPU to OCR, value is gpu_id int to string. It does not support switching after the resource + // is loaded. +}; + +enum class InstanceOptionKey +{ + Invalid = 0, + /* Deprecated */ // MinitouchEnabled = 1, + TouchMode = 2, // 触控模式设置, "minitouch" | "maatouch" | "adb" + DeploymentWithPause = 3, // 自动战斗、肉鸽、保全 是否使用 暂停下干员, "0" | "1" + AdbLiteEnabled = 4, // 是否使用 AdbLite, "0" | "1" + KillAdbOnExit = 5, // 退出时是否杀掉 Adb 进程, "0" | "1" +}; + +enum class TouchMode +{ + Adb = 0, + Minitouch = 1, + Maatouch = 2, + MacPlayTools = 3, +}; + +namespace ControlFeat +{ +using Feat = int64_t; +constexpr Feat NONE = 0; +constexpr Feat SWIPE_WITH_PAUSE = 1 << 0; +constexpr Feat PRECISE_SWIPE = 1 << 1; + +inline bool support(Feat feat, Feat target) noexcept +{ + return (feat & target) == target; +} +} + +struct Point +{ + Point() = default; + ~Point() = default; + Point(const Point&) noexcept = default; + Point(Point&&) noexcept = default; + + constexpr Point(int x, int y) : + x(x), + y(y) { - Invalid = 0, - CpuOCR = 1, // use CPU to OCR, no value. It does not support switching after the resource is loaded. - GpuOCR = 2, // use GPU to OCR, value is gpu_id int to string. It does not support switching after the resource - // is loaded. - }; - - enum class InstanceOptionKey - { - Invalid = 0, - /* Deprecated */ // MinitouchEnabled = 1, - TouchMode = 2, // 触控模式设置, "minitouch" | "maatouch" | "adb" - DeploymentWithPause = 3, // 自动战斗、肉鸽、保全 是否使用 暂停下干员, "0" | "1" - AdbLiteEnabled = 4, // 是否使用 AdbLite, "0" | "1" - KillAdbOnExit = 5, // 退出时是否杀掉 Adb 进程, "0" | "1" - }; - - enum class TouchMode - { - Adb = 0, - Minitouch = 1, - Maatouch = 2, - MacPlayTools = 3, - }; - - namespace ControlFeat - { - using Feat = int64_t; - constexpr Feat NONE = 0; - constexpr Feat SWIPE_WITH_PAUSE = 1 << 0; - constexpr Feat PRECISE_SWIPE = 1 << 1; - - inline bool support(Feat feat, Feat target) noexcept - { - return (feat & target) == target; - } } - struct Point - { - Point() = default; - ~Point() = default; - Point(const Point&) noexcept = default; - Point(Point&&) noexcept = default; - constexpr Point(int x, int y) : x(x), y(y) {} - Point& operator=(const Point&) noexcept = default; - Point& operator=(Point&&) noexcept = default; - Point operator-() const noexcept { return { -x, -y }; } - bool operator==(const Point& rhs) const noexcept { return x == rhs.x && y == rhs.y; } - std::string to_string() const { return "(" + std::to_string(x) + ", " + std::to_string(y) + ")"; } - explicit operator std::string() const { return to_string(); } - static constexpr Point right() { return { 1, 0 }; } - static constexpr Point down() { return { 0, 1 }; } - static constexpr Point left() { return { -1, 0 }; } - static constexpr Point up() { return { 0, -1 }; } - static constexpr Point zero() { return { 0, 0 }; } - bool empty() const noexcept { return x == 0 && y == 0; } - // for std::map - bool operator<(const Point& rhs) const noexcept { return x < rhs.x || (x == rhs.x && y < rhs.y); } + Point& operator=(const Point&) noexcept = default; + Point& operator=(Point&&) noexcept = default; - int x = 0; - int y = 0; + Point operator-() const noexcept { return { -x, -y }; } - // clang-format off + bool operator==(const Point& rhs) const noexcept { return x == rhs.x && y == rhs.y; } + + std::string to_string() const { return "(" + std::to_string(x) + ", " + std::to_string(y) + ")"; } + + explicit operator std::string() const { return to_string(); } + + static constexpr Point right() { return { 1, 0 }; } + + static constexpr Point down() { return { 0, 1 }; } + + static constexpr Point left() { return { -1, 0 }; } + + static constexpr Point up() { return { 0, -1 }; } + + static constexpr Point zero() { return { 0, 0 }; } + + bool empty() const noexcept { return x == 0 && y == 0; } + + // for std::map + bool operator<(const Point& rhs) const noexcept { return x < rhs.x || (x == rhs.x && y < rhs.y); } + + int x = 0; + int y = 0; + + // clang-format off #define DEFINE_ASST_POINT_BINARY_OP_AND_ARG_ASSIGN(Op) \ friend Point operator Op(const Point& lhs, const Point& rhs) noexcept \ { \ @@ -102,410 +119,426 @@ namespace asst val.y Op## = opd.y; \ return val; \ } - // clang-format on + // clang-format on - DEFINE_ASST_POINT_BINARY_OP_AND_ARG_ASSIGN(+) - DEFINE_ASST_POINT_BINARY_OP_AND_ARG_ASSIGN(-) - DEFINE_ASST_POINT_BINARY_OP_AND_ARG_ASSIGN(*) + DEFINE_ASST_POINT_BINARY_OP_AND_ARG_ASSIGN(+) + DEFINE_ASST_POINT_BINARY_OP_AND_ARG_ASSIGN(-) + DEFINE_ASST_POINT_BINARY_OP_AND_ARG_ASSIGN(*) #undef DEFINE_ASST_POINT_BINARY_OP_AND_ARG_ASSIGN - friend Point operator*(int scalar, const Point& value) noexcept - { - return { value.x * scalar, value.y * scalar }; - } - friend Point operator*(const Point& value, int scalar) noexcept - { - return { value.x * scalar, value.y * scalar }; - } - static int dot(const Point& lhs, const Point& rhs) noexcept { return (lhs.x * rhs.x) + (lhs.y * rhs.y); } - static double distance(const Point& lhs, const Point& rhs) noexcept - { - return std::sqrt(std::pow(rhs.x - lhs.x, 2) + std::pow(rhs.y - lhs.y, 2)); - } - double length() const noexcept { return std::sqrt(static_cast(dot(*this, *this))); } - }; + friend Point operator*(int scalar, const Point& value) noexcept { return { value.x * scalar, value.y * scalar }; } - struct Rect + friend Point operator*(const Point& value, int scalar) noexcept { return { value.x * scalar, value.y * scalar }; } + + static int dot(const Point& lhs, const Point& rhs) noexcept { return (lhs.x * rhs.x) + (lhs.y * rhs.y); } + + static double distance(const Point& lhs, const Point& rhs) noexcept { - Rect() = default; - ~Rect() = default; - Rect(const Rect&) noexcept = default; - Rect(Rect&&) noexcept = default; - Rect(int x, int y, int width, int height) : x(x), y(y), width(width), height(height) {} - Rect operator*(double rhs) const - { - return { x, y, static_cast(width * rhs), static_cast(height * rhs) }; - } - int area() const noexcept { return width * height; } - Rect center_zoom(double scale, int max_width = INT_MAX, int max_height = INT_MAX) const - { - const int half_width_scale = static_cast(width * (1 - scale) / 2); - const int half_height_scale = static_cast(height * (1 - scale) / 2); - Rect dst(x + half_width_scale, y + half_height_scale, static_cast(width * scale), - static_cast(height * scale)); - if (dst.x < 0) { - dst.x = 0; - } - if (dst.y < 0) { - dst.y = 0; - } - if (dst.width + dst.x >= max_width) { - dst.width = max_width - dst.x; - } - if (dst.height + dst.y >= max_height) { - dst.height = max_height - dst.y; - } - return dst; - } - Rect& operator=(const Rect&) noexcept = default; - Rect& operator=(Rect&&) noexcept = default; - bool operator==(const Rect& rhs) const noexcept - { - return x == rhs.x && y == rhs.y && width == rhs.width && height == rhs.height; - } - bool empty() const noexcept { return width == 0 || height == 0; } - bool include(const Rect& rhs) const noexcept - { - return x <= rhs.x && y <= rhs.y && (x + width) >= (rhs.x + rhs.width) && - (y + height) >= (rhs.y + rhs.height); - } - bool include(const Point& rhs) const noexcept - { - return x <= rhs.x && y <= rhs.y && (x + width) >= rhs.x && (y + height) >= rhs.y; - } - std::string to_string() const - { - return "[ " + std::to_string(x) + ", " + std::to_string(y) + ", " + std::to_string(width) + ", " + - std::to_string(height) + " ]"; - } - explicit operator std::string() const { return to_string(); } - Rect move(Rect move) const { return { x + move.x, y + move.y, move.width, move.height }; } - - int x = 0; - int y = 0; - int width = 0; - int height = 0; - }; - - template - inline constexpr To make_rect(const From& rect) - { - return To { rect.x, rect.y, rect.width, rect.height }; + return std::sqrt(std::pow(rhs.x - lhs.x, 2) + std::pow(rhs.y - lhs.y, 2)); } - struct TextRect + double length() const noexcept { return std::sqrt(static_cast(dot(*this, *this))); } +}; + +struct Rect +{ + Rect() = default; + ~Rect() = default; + Rect(const Rect&) noexcept = default; + Rect(Rect&&) noexcept = default; + + Rect(int x, int y, int width, int height) : + x(x), + y(y), + width(width), + height(height) { - std::string to_string() const - { - return "{ " + text + ": " + rect.to_string() + ", score: " + std::to_string(score) + " }"; - } - explicit operator std::string() const { return to_string(); } + } - Rect rect; - double score = 0.0; - std::string text; - }; + Rect operator*(double rhs) const { return { x, y, static_cast(width * rhs), static_cast(height * rhs) }; } - struct MatchRect + int area() const noexcept { return width * height; } + + Rect center_zoom(double scale, int max_width = INT_MAX, int max_height = INT_MAX) const { - std::string to_string() const - { - return "{ rect: " + rect.to_string() + ", score: " + std::to_string(score) + " }"; + const int half_width_scale = static_cast(width * (1 - scale) / 2); + const int half_height_scale = static_cast(height * (1 - scale) / 2); + Rect dst( + x + half_width_scale, + y + half_height_scale, + static_cast(width * scale), + static_cast(height * scale)); + if (dst.x < 0) { + dst.x = 0; } - explicit operator std::string() const { return to_string(); } + if (dst.y < 0) { + dst.y = 0; + } + if (dst.width + dst.x >= max_width) { + dst.width = max_width - dst.x; + } + if (dst.height + dst.y >= max_height) { + dst.height = max_height - dst.y; + } + return dst; + } - Rect rect; - double score = 0.0; - std::string templ_name; - }; + Rect& operator=(const Rect&) noexcept = default; + Rect& operator=(Rect&&) noexcept = default; + + bool operator==(const Rect& rhs) const noexcept + { + return x == rhs.x && y == rhs.y && width == rhs.width && height == rhs.height; + } + + bool empty() const noexcept { return width == 0 || height == 0; } + + bool include(const Rect& rhs) const noexcept + { + return x <= rhs.x && y <= rhs.y && (x + width) >= (rhs.x + rhs.width) && (y + height) >= (rhs.y + rhs.height); + } + + bool include(const Point& rhs) const noexcept + { + return x <= rhs.x && y <= rhs.y && (x + width) >= rhs.x && (y + height) >= rhs.y; + } + + std::string to_string() const + { + return "[ " + std::to_string(x) + ", " + std::to_string(y) + ", " + std::to_string(width) + ", " + + std::to_string(height) + " ]"; + } + + explicit operator std::string() const { return to_string(); } + + Rect move(Rect move) const { return { x + move.x, y + move.y, move.width, move.height }; } + + int x = 0; + int y = 0; + int width = 0; + int height = 0; +}; + +template +inline constexpr To make_rect(const From& rect) +{ + return To { rect.x, rect.y, rect.width, rect.height }; +} + +struct TextRect +{ + std::string to_string() const + { + return "{ " + text + ": " + rect.to_string() + ", score: " + std::to_string(score) + " }"; + } + + explicit operator std::string() const { return to_string(); } + + Rect rect; + double score = 0.0; + std::string text; +}; + +struct MatchRect +{ + std::string to_string() const { return "{ rect: " + rect.to_string() + ", score: " + std::to_string(score) + " }"; } + + explicit operator std::string() const { return to_string(); } + + Rect rect; + double score = 0.0; + std::string templ_name; +}; } // namespace asst namespace std { - template <> - struct hash +template <> +struct hash +{ + size_t operator()(const asst::Point& point) const noexcept { - size_t operator()(const asst::Point& point) const noexcept - { - return std::hash()(point.x) ^ std::hash()(point.y); - } - }; + return std::hash()(point.x) ^ std::hash()(point.y); + } +}; - template <> - struct hash +template <> +struct hash +{ + size_t operator()(const asst::Rect& rect) const noexcept { - size_t operator()(const asst::Rect& rect) const noexcept - { - return std::hash()(rect.x) ^ std::hash()(rect.y) ^ std::hash()(rect.width) ^ - std::hash()(rect.height); - } - }; + return std::hash()(rect.x) ^ std::hash()(rect.y) ^ std::hash()(rect.width) ^ + std::hash()(rect.height); + } +}; } namespace asst { - template - struct ContainerHasher +template +struct ContainerHasher +{ + std::size_t operator()(const CType& container) const { - std::size_t operator()(const CType& container) const - { - using value_type = typename CType::value_type; - std::size_t seed = container.size(); - for (const value_type& e : container) { - seed ^= std::hash()(e) + 0x9e3779b9 + (seed << 6) + (seed >> 2); - } - return seed; + using value_type = typename CType::value_type; + std::size_t seed = container.size(); + for (const value_type& e : container) { + seed ^= std::hash()(e) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } + return seed; + } +}; + +enum class AlgorithmType +{ + Invalid = -1, + JustReturn, + MatchTemplate, + OcrDetect, +}; + +inline AlgorithmType get_algorithm_type(std::string algorithm_str) +{ + utils::tolowers(algorithm_str); + static const std::unordered_map algorithm_map = { + { "matchtemplate", AlgorithmType::MatchTemplate }, + { "justreturn", AlgorithmType::JustReturn }, + { "ocrdetect", AlgorithmType::OcrDetect }, }; + if (algorithm_map.contains(algorithm_str)) { + return algorithm_map.at(algorithm_str); + } + return AlgorithmType::Invalid; +} - enum class AlgorithmType - { - Invalid = -1, - JustReturn, - MatchTemplate, - OcrDetect, +inline std::string enum_to_string(AlgorithmType algo) +{ + static const std::unordered_map algorithm_map = { + { AlgorithmType::Invalid, "Invalid" }, + { AlgorithmType::JustReturn, "JustReturn" }, + { AlgorithmType::MatchTemplate, "MatchTemplate" }, + { AlgorithmType::OcrDetect, "OcrDetect" }, }; - - inline AlgorithmType get_algorithm_type(std::string algorithm_str) - { - utils::tolowers(algorithm_str); - static const std::unordered_map algorithm_map = { - { "matchtemplate", AlgorithmType::MatchTemplate }, - { "justreturn", AlgorithmType::JustReturn }, - { "ocrdetect", AlgorithmType::OcrDetect }, - }; - if (algorithm_map.contains(algorithm_str)) { - return algorithm_map.at(algorithm_str); - } - return AlgorithmType::Invalid; + if (auto it = algorithm_map.find(algo); it != algorithm_map.end()) { + return it->second; } + return "Invalid"; +} - inline std::string enum_to_string(AlgorithmType algo) - { - static const std::unordered_map algorithm_map = { - { AlgorithmType::Invalid, "Invalid" }, - { AlgorithmType::JustReturn, "JustReturn" }, - { AlgorithmType::MatchTemplate, "MatchTemplate" }, - { AlgorithmType::OcrDetect, "OcrDetect" }, - }; - if (auto it = algorithm_map.find(algo); it != algorithm_map.end()) { - return it->second; - } - return "Invalid"; - } +enum class ProcessTaskAction +{ + Invalid = 0, + BasicClick = 0x100, + ClickSelf = BasicClick | 1, // 点击自身位置 + ClickRect = BasicClick | 2, // 点击指定区域 + // ClickRand = BasicClick | 4, // 点击随机区域 + DoNothing = 0x200, // 什么都不做 + Stop = 0x400, // 停止当前Task + Swipe = 0x1000, // 滑动 +}; - enum class ProcessTaskAction - { - Invalid = 0, - BasicClick = 0x100, - ClickSelf = BasicClick | 1, // 点击自身位置 - ClickRect = BasicClick | 2, // 点击指定区域 - // ClickRand = BasicClick | 4, // 点击随机区域 - DoNothing = 0x200, // 什么都不做 - Stop = 0x400, // 停止当前Task - Swipe = 0x1000, // 滑动 +inline ProcessTaskAction get_action_type(std::string action_str) +{ + utils::tolowers(action_str); + static const std::unordered_map action_map = { + { "", ProcessTaskAction::DoNothing }, { "donothing", ProcessTaskAction::DoNothing }, + { "clickself", ProcessTaskAction::ClickSelf }, { "clickrect", ProcessTaskAction::ClickRect }, + { "stop", ProcessTaskAction::Stop }, { "swipe", ProcessTaskAction::Swipe }, }; - - inline ProcessTaskAction get_action_type(std::string action_str) - { - utils::tolowers(action_str); - static const std::unordered_map action_map = { - { "", ProcessTaskAction::DoNothing }, { "donothing", ProcessTaskAction::DoNothing }, - { "clickself", ProcessTaskAction::ClickSelf }, { "clickrect", ProcessTaskAction::ClickRect }, - { "stop", ProcessTaskAction::Stop }, { "swipe", ProcessTaskAction::Swipe }, - }; - if (auto it = action_map.find(action_str); it != action_map.end()) { - return it->second; - } - return ProcessTaskAction::Invalid; + if (auto it = action_map.find(action_str); it != action_map.end()) { + return it->second; } + return ProcessTaskAction::Invalid; +} - inline std::string enum_to_string(ProcessTaskAction action) - { - static const std::unordered_map action_map = { - { ProcessTaskAction::Invalid, "Invalid" }, - { ProcessTaskAction::DoNothing, "DoNothing" }, - { ProcessTaskAction::BasicClick, "BasicClick" }, - { ProcessTaskAction::ClickSelf, "ClickSelf" }, - { ProcessTaskAction::ClickRect, "ClickRect" }, - { ProcessTaskAction::Stop, "Stop" }, - { ProcessTaskAction::Swipe, "Swipe" }, - }; - if (auto it = action_map.find(action); it != action_map.end()) { - return it->second; - } - return "Invalid"; - } - - enum class TaskDerivedType - { - Invalid = -1, - Raw, // 原始任务 - BaseTask, // BaseTask - Implicit, // 隐式 TemplateTask - Template, // 显式 TemplateTask +inline std::string enum_to_string(ProcessTaskAction action) +{ + static const std::unordered_map action_map = { + { ProcessTaskAction::Invalid, "Invalid" }, { ProcessTaskAction::DoNothing, "DoNothing" }, + { ProcessTaskAction::BasicClick, "BasicClick" }, { ProcessTaskAction::ClickSelf, "ClickSelf" }, + { ProcessTaskAction::ClickRect, "ClickRect" }, { ProcessTaskAction::Stop, "Stop" }, + { ProcessTaskAction::Swipe, "Swipe" }, }; - - inline std::string enum_to_string(TaskDerivedType task_derived_type) - { - static const std::unordered_map task_derived_type_map = { - { TaskDerivedType::Raw, "Raw" }, - { TaskDerivedType::BaseTask, "BaseTask" }, - { TaskDerivedType::Implicit, "Implicit" }, - { TaskDerivedType::Template, "Template" }, - }; - if (auto it = task_derived_type_map.find(task_derived_type); it != task_derived_type_map.end()) { - return it->second; - } - return "Invalid"; + if (auto it = action_map.find(action); it != action_map.end()) { + return it->second; } + return "Invalid"; +} - enum class MatchMethod - { - Invalid = -1, - Ccoeff = 0, - RGBCount, - HSVCount, +enum class TaskDerivedType +{ + Invalid = -1, + Raw, // 原始任务 + BaseTask, // BaseTask + Implicit, // 隐式 TemplateTask + Template, // 显式 TemplateTask +}; + +inline std::string enum_to_string(TaskDerivedType task_derived_type) +{ + static const std::unordered_map task_derived_type_map = { + { TaskDerivedType::Raw, "Raw" }, + { TaskDerivedType::BaseTask, "BaseTask" }, + { TaskDerivedType::Implicit, "Implicit" }, + { TaskDerivedType::Template, "Template" }, }; - - inline MatchMethod get_match_method(std::string method_str) - { - utils::tolowers(method_str); - static const std::unordered_map method_map = { - { "ccoeff", MatchMethod::Ccoeff }, - { "rgbcount", MatchMethod::RGBCount }, - { "hsvcount", MatchMethod::HSVCount }, - }; - if (auto it = method_map.find(method_str); it != method_map.end()) { - return it->second; - } - return MatchMethod::Invalid; + if (auto it = task_derived_type_map.find(task_derived_type); it != task_derived_type_map.end()) { + return it->second; } + return "Invalid"; +} - inline std::string enum_to_string(MatchMethod method) - { - static const std::unordered_map method_map = { - { MatchMethod::Invalid, "Invalid" }, - { MatchMethod::Ccoeff, "Ccoeff" }, - { MatchMethod::RGBCount, "RGBCount" }, - { MatchMethod::HSVCount, "HSVCount" }, - }; - if (auto it = method_map.find(method); it != method_map.end()) { - return it->second; - } - return "Invalid"; +enum class MatchMethod +{ + Invalid = -1, + Ccoeff = 0, + RGBCount, + HSVCount, +}; + +inline MatchMethod get_match_method(std::string method_str) +{ + utils::tolowers(method_str); + static const std::unordered_map method_map = { + { "ccoeff", MatchMethod::Ccoeff }, + { "rgbcount", MatchMethod::RGBCount }, + { "hsvcount", MatchMethod::HSVCount }, + }; + if (auto it = method_map.find(method_str); it != method_map.end()) { + return it->second; } + return MatchMethod::Invalid; +} + +inline std::string enum_to_string(MatchMethod method) +{ + static const std::unordered_map method_map = { + { MatchMethod::Invalid, "Invalid" }, + { MatchMethod::Ccoeff, "Ccoeff" }, + { MatchMethod::RGBCount, "RGBCount" }, + { MatchMethod::HSVCount, "HSVCount" }, + }; + if (auto it = method_map.find(method); it != method_map.end()) { + return it->second; + } + return "Invalid"; +} } // namespace asst namespace asst { - using TaskList = std::vector; +using TaskList = std::vector; - // 任务流程信息 - struct TaskPipelineInfo - { - constexpr TaskPipelineInfo() = default; - constexpr virtual ~TaskPipelineInfo() = default; - constexpr TaskPipelineInfo(const TaskPipelineInfo&) = default; - constexpr TaskPipelineInfo(TaskPipelineInfo&&) noexcept = default; - constexpr TaskPipelineInfo& operator=(const TaskPipelineInfo&) = default; - constexpr TaskPipelineInfo& operator=(TaskPipelineInfo&&) noexcept = default; - std::string name; // 任务名 - TaskList next; // 下一个可能的任务(列表) - TaskList sub; // 子任务(列表) - TaskList on_error_next; // 任务出错之后要去执行什么 - TaskList exceeded_next; // 达到最多次数了之后,下一个可能的任务(列表) - TaskList reduce_other_times; // 执行了该任务后,需要减少别的任务的执行次数。例如执行了吃理智药, - // 则说明上一次点击蓝色开始行动按钮没生效,所以蓝色开始行动要-1 - }; - using TaskPipelinePtr = std::shared_ptr; - using TaskPipelineConstPtr = std::shared_ptr; +// 任务流程信息 +struct TaskPipelineInfo +{ + constexpr TaskPipelineInfo() = default; + constexpr virtual ~TaskPipelineInfo() = default; + constexpr TaskPipelineInfo(const TaskPipelineInfo&) = default; + constexpr TaskPipelineInfo(TaskPipelineInfo&&) noexcept = default; + constexpr TaskPipelineInfo& operator=(const TaskPipelineInfo&) = default; + constexpr TaskPipelineInfo& operator=(TaskPipelineInfo&&) noexcept = default; + std::string name; // 任务名 + TaskList next; // 下一个可能的任务(列表) + TaskList sub; // 子任务(列表) + TaskList on_error_next; // 任务出错之后要去执行什么 + TaskList exceeded_next; // 达到最多次数了之后,下一个可能的任务(列表) + TaskList reduce_other_times; // 执行了该任务后,需要减少别的任务的执行次数。例如执行了吃理智药, + // 则说明上一次点击蓝色开始行动按钮没生效,所以蓝色开始行动要-1 +}; - // 任务继承信息 - struct TaskDerivedInfo : public TaskPipelineInfo - { - constexpr TaskDerivedInfo() = default; - constexpr virtual ~TaskDerivedInfo() = default; - constexpr TaskDerivedInfo(const TaskDerivedInfo&) = default; - constexpr TaskDerivedInfo(TaskDerivedInfo&&) noexcept = default; - constexpr TaskDerivedInfo& operator=(const TaskDerivedInfo&) = default; - constexpr TaskDerivedInfo& operator=(TaskDerivedInfo&&) noexcept = default; - TaskDerivedType type = TaskDerivedType::Raw; // 任务类型 - std::string base = ""; // 继承自哪个任务(Raw 任务不需要) - std::string prefix = ""; // 需要添加的前缀(仅对 TemplateTask 生效) - }; - using TaskDerivedPtr = std::shared_ptr; - using TaskDerivedConstPtr = std::shared_ptr; +using TaskPipelinePtr = std::shared_ptr; +using TaskPipelineConstPtr = std::shared_ptr; - // 任务信息 - struct TaskInfo : public TaskPipelineInfo - { - constexpr TaskInfo() = default; - constexpr virtual ~TaskInfo() = default; - constexpr TaskInfo(const TaskInfo&) = default; - constexpr TaskInfo(TaskInfo&&) noexcept = default; - constexpr TaskInfo& operator=(const TaskInfo&) = default; - constexpr TaskInfo& operator=(TaskInfo&&) noexcept = default; - AlgorithmType algorithm = AlgorithmType::Invalid; // 图像算法类型 - ProcessTaskAction action = ProcessTaskAction::Invalid; // 要进行的操作 - bool sub_error_ignored = false; // 子任务如果失败了,是否继续执行剩下的任务 - int max_times = INT_MAX; // 任务最多执行多少次 - Rect specific_rect; // 指定区域,目前仅针对ClickRect任务有用,会点这个区域 - int pre_delay = 0; // 执行该任务前的延时 - int post_delay = 0; // 执行该任务后的延时 - int retry_times = INT_MAX; // 未找到图像时的重试次数 - Rect roi; // 要识别的区域,若为0则全图识别 - Rect rect_move; // 识别结果移动:有些结果识别到的,和要点击的不是同一个位置。 - // 即识别到了res,点击res + result_move的位置 - bool cache = false; // 是否使用缓存区域 - std::vector special_params; // 某些任务会用到的特殊参数 - }; - using TaskPtr = std::shared_ptr; - using TaskConstPtr = std::shared_ptr; +// 任务继承信息 +struct TaskDerivedInfo : public TaskPipelineInfo +{ + constexpr TaskDerivedInfo() = default; + constexpr virtual ~TaskDerivedInfo() = default; + constexpr TaskDerivedInfo(const TaskDerivedInfo&) = default; + constexpr TaskDerivedInfo(TaskDerivedInfo&&) noexcept = default; + constexpr TaskDerivedInfo& operator=(const TaskDerivedInfo&) = default; + constexpr TaskDerivedInfo& operator=(TaskDerivedInfo&&) noexcept = default; + TaskDerivedType type = TaskDerivedType::Raw; // 任务类型 + std::string base = ""; // 继承自哪个任务(Raw 任务不需要) + std::string prefix = ""; // 需要添加的前缀(仅对 TemplateTask 生效) +}; - // 文字识别任务的信息 - struct OcrTaskInfo : public TaskInfo - { - constexpr OcrTaskInfo() = default; - constexpr virtual ~OcrTaskInfo() override = default; - constexpr OcrTaskInfo(const OcrTaskInfo&) = default; - constexpr OcrTaskInfo(OcrTaskInfo&&) noexcept = default; - constexpr OcrTaskInfo& operator=(const OcrTaskInfo&) = default; - constexpr OcrTaskInfo& operator=(OcrTaskInfo&&) noexcept = default; - std::vector text; // 文字的容器,匹配到这里面任一个,就算匹配上了 - bool full_match = false; // 是否需要全匹配,否则搜索到子串就算匹配上了 - bool is_ascii = false; // 是否启用字符数字模型 - bool without_det = false; // 是否不使用检测模型 - bool replace_full = false; // 匹配之后,是否将整个字符串replace(false是只替换match的部分) - std::vector> - replace_map; // 部分文字容易识别错,字符串强制replace之后,再进行匹配 - }; - using OcrTaskPtr = std::shared_ptr; - using OcrTaskConstPtr = std::shared_ptr; +using TaskDerivedPtr = std::shared_ptr; +using TaskDerivedConstPtr = std::shared_ptr; - // 图片匹配任务的信息 - struct MatchTaskInfo : public TaskInfo - { - constexpr MatchTaskInfo() = default; - constexpr virtual ~MatchTaskInfo() override = default; - constexpr MatchTaskInfo(const MatchTaskInfo&) = default; - constexpr MatchTaskInfo(MatchTaskInfo&&) noexcept = default; - constexpr MatchTaskInfo& operator=(const MatchTaskInfo&) = default; - constexpr MatchTaskInfo& operator=(MatchTaskInfo&&) noexcept = default; - using GrayRange = std::pair; - using ColorRange = std::pair, std::array>; - using Range = std::variant; - using Ranges = std::vector; - std::vector templ_names; // 匹配模板图片文件名 - std::vector templ_thresholds; // 模板匹配阈值 - std::vector methods; // 匹配方法 - Ranges mask_ranges; // 匹配掩码范围,TaskData 仅允许 array,但保留彩色掩码支持 - Ranges color_scales; // 数色掩码范围 - bool color_close = true; // 数色时是否使用闭运算处理 - }; - using MatchTaskPtr = std::shared_ptr; - using MatchTaskConstPtr = std::shared_ptr; +// 任务信息 +struct TaskInfo : public TaskPipelineInfo +{ + constexpr TaskInfo() = default; + constexpr virtual ~TaskInfo() = default; + constexpr TaskInfo(const TaskInfo&) = default; + constexpr TaskInfo(TaskInfo&&) noexcept = default; + constexpr TaskInfo& operator=(const TaskInfo&) = default; + constexpr TaskInfo& operator=(TaskInfo&&) noexcept = default; + AlgorithmType algorithm = AlgorithmType::Invalid; // 图像算法类型 + ProcessTaskAction action = ProcessTaskAction::Invalid; // 要进行的操作 + bool sub_error_ignored = false; // 子任务如果失败了,是否继续执行剩下的任务 + int max_times = INT_MAX; // 任务最多执行多少次 + Rect specific_rect; // 指定区域,目前仅针对ClickRect任务有用,会点这个区域 + int pre_delay = 0; // 执行该任务前的延时 + int post_delay = 0; // 执行该任务后的延时 + int retry_times = INT_MAX; // 未找到图像时的重试次数 + Rect roi; // 要识别的区域,若为0则全图识别 + Rect rect_move; // 识别结果移动:有些结果识别到的,和要点击的不是同一个位置。 + // 即识别到了res,点击res + result_move的位置 + bool cache = false; // 是否使用缓存区域 + std::vector special_params; // 某些任务会用到的特殊参数 +}; - inline static const std::string UploadDataSource = "MeoAssistant"; +using TaskPtr = std::shared_ptr; +using TaskConstPtr = std::shared_ptr; + +// 文字识别任务的信息 +struct OcrTaskInfo : public TaskInfo +{ + constexpr OcrTaskInfo() = default; + constexpr virtual ~OcrTaskInfo() override = default; + constexpr OcrTaskInfo(const OcrTaskInfo&) = default; + constexpr OcrTaskInfo(OcrTaskInfo&&) noexcept = default; + constexpr OcrTaskInfo& operator=(const OcrTaskInfo&) = default; + constexpr OcrTaskInfo& operator=(OcrTaskInfo&&) noexcept = default; + std::vector text; // 文字的容器,匹配到这里面任一个,就算匹配上了 + bool full_match = false; // 是否需要全匹配,否则搜索到子串就算匹配上了 + bool is_ascii = false; // 是否启用字符数字模型 + bool without_det = false; // 是否不使用检测模型 + bool replace_full = false; // 匹配之后,是否将整个字符串replace(false是只替换match的部分) + std::vector> + replace_map; // 部分文字容易识别错,字符串强制replace之后,再进行匹配 +}; + +using OcrTaskPtr = std::shared_ptr; +using OcrTaskConstPtr = std::shared_ptr; + +// 图片匹配任务的信息 +struct MatchTaskInfo : public TaskInfo +{ + constexpr MatchTaskInfo() = default; + constexpr virtual ~MatchTaskInfo() override = default; + constexpr MatchTaskInfo(const MatchTaskInfo&) = default; + constexpr MatchTaskInfo(MatchTaskInfo&&) noexcept = default; + constexpr MatchTaskInfo& operator=(const MatchTaskInfo&) = default; + constexpr MatchTaskInfo& operator=(MatchTaskInfo&&) noexcept = default; + using GrayRange = std::pair; + using ColorRange = std::pair, std::array>; + using Range = std::variant; + using Ranges = std::vector; + std::vector templ_names; // 匹配模板图片文件名 + std::vector templ_thresholds; // 模板匹配阈值 + std::vector methods; // 匹配方法 + Ranges mask_ranges; // 匹配掩码范围,TaskData 仅允许 array,但保留彩色掩码支持 + Ranges color_scales; // 数色掩码范围 + bool color_close = true; // 数色时是否使用闭运算处理 +}; + +using MatchTaskPtr = std::shared_ptr; +using MatchTaskConstPtr = std::shared_ptr; + +inline static const std::string UploadDataSource = "MeoAssistant"; } // namespace asst diff --git a/src/MaaCore/Common/AsstVersion.h b/src/MaaCore/Common/AsstVersion.h index 83cf23b5d2..d28aa198ef 100644 --- a/src/MaaCore/Common/AsstVersion.h +++ b/src/MaaCore/Common/AsstVersion.h @@ -2,10 +2,10 @@ namespace asst { - static constexpr const char* Version = +static constexpr const char* Version = #ifdef MAA_VERSION - MAA_VERSION; + MAA_VERSION; #else - "DEBUG VERSION"; + "DEBUG VERSION"; #endif } diff --git a/src/MaaCore/Config/AbstractConfigWithTempl.h b/src/MaaCore/Config/AbstractConfigWithTempl.h index 7b3f1f96b3..96265620b5 100644 --- a/src/MaaCore/Config/AbstractConfigWithTempl.h +++ b/src/MaaCore/Config/AbstractConfigWithTempl.h @@ -6,11 +6,11 @@ namespace asst { - class AbstractConfigWithTempl : public AbstractConfig - { - public: - virtual ~AbstractConfigWithTempl() override = default; +class AbstractConfigWithTempl : public AbstractConfig +{ +public: + virtual ~AbstractConfigWithTempl() override = default; - virtual const std::unordered_set& get_templ_required() const noexcept = 0; - }; + virtual const std::unordered_set& get_templ_required() const noexcept = 0; +}; } diff --git a/src/MaaCore/Config/GeneralConfig.cpp b/src/MaaCore/Config/GeneralConfig.cpp index 936d7ad7ba..93d5bb376b 100644 --- a/src/MaaCore/Config/GeneralConfig.cpp +++ b/src/MaaCore/Config/GeneralConfig.cpp @@ -27,19 +27,13 @@ bool asst::GeneralConfig::parse(const json::value& json) // m_options.print_window = options_json.at("printWindow").as_boolean(); m_options.adb_extra_swipe_dist = options_json.get("adbExtraSwipeDist", 100); m_options.adb_extra_swipe_duration = options_json.get("adbExtraSwipeDuration", -1); - m_options.adb_swipe_duration_multiplier = - options_json.get("adbSwipeDurationMultiplier", 10.0); - m_options.adb_swipe_x_distance_multiplier = - options_json.get("adbSwipeXDistanceMultiplier", 0.8); + m_options.adb_swipe_duration_multiplier = options_json.get("adbSwipeDurationMultiplier", 10.0); + m_options.adb_swipe_x_distance_multiplier = options_json.get("adbSwipeXDistanceMultiplier", 0.8); m_options.minitouch_extra_swipe_dist = options_json.get("minitouchExtraSwipeDist", 100); - m_options.minitouch_extra_swipe_duration = - options_json.get("minitouchExtraSwipeDuration", -1); - m_options.minitouch_swipe_default_duration = - options_json.get("minitouchSwipeDefaultDuration", 200); - m_options.minitouch_swipe_extra_end_delay = - options_json.get("minitouchSwipeExtraEndDelay", 150); - m_options.swipe_with_pause_required_distance = - options_json.get("swipeWithPauseRequiredDistance", 50); + m_options.minitouch_extra_swipe_duration = options_json.get("minitouchExtraSwipeDuration", -1); + m_options.minitouch_swipe_default_duration = options_json.get("minitouchSwipeDefaultDuration", 200); + m_options.minitouch_swipe_extra_end_delay = options_json.get("minitouchSwipeExtraEndDelay", 150); + m_options.swipe_with_pause_required_distance = options_json.get("swipeWithPauseRequiredDistance", 50); if (auto order = options_json.find("minitouchProgramsOrder")) { m_options.minitouch_programs_order.clear(); for (const auto& type : *order) { @@ -92,8 +86,7 @@ bool asst::GeneralConfig::parse(const json::value& json) adb.swipe = cfg_json.get("swipe", base_cfg.swipe); adb.press_esc = cfg_json.get("pressEsc", base_cfg.press_esc); adb.display = cfg_json.get("display", base_cfg.display); - adb.screencap_raw_with_gzip = - cfg_json.get("screencapRawWithGzip", base_cfg.screencap_raw_with_gzip); + adb.screencap_raw_with_gzip = cfg_json.get("screencapRawWithGzip", base_cfg.screencap_raw_with_gzip); adb.screencap_raw_by_nc = cfg_json.get("screencapRawByNC", base_cfg.screencap_raw_by_nc); adb.nc_address = cfg_json.get("ncAddress", base_cfg.nc_address); adb.screencap_encode = cfg_json.get("screencapEncode", base_cfg.screencap_encode); diff --git a/src/MaaCore/Config/GeneralConfig.h b/src/MaaCore/Config/GeneralConfig.h index 905acf2ed9..1b239590d7 100644 --- a/src/MaaCore/Config/GeneralConfig.h +++ b/src/MaaCore/Config/GeneralConfig.h @@ -33,12 +33,12 @@ struct DebugConf struct Options { - int task_delay = 0; // 任务间延时:越快操作越快,但会增加CPU消耗 - int sss_fight_screencap_interval = 0; // 保全战斗截图最小间隔 - int roguelike_fight_screencap_interval = 0; // 肉鸽战斗截图最小间隔 - int copilot_fight_screencap_interval = 0; // 抄作业战斗截图最小间隔 - int control_delay_lower = 0; // 点击随机延时下限:每次点击操作会进行随机延时 - int control_delay_upper = 0; // 点击随机延时上限:每次点击操作会进行随机延时 + int task_delay = 0; // 任务间延时:越快操作越快,但会增加CPU消耗 + int sss_fight_screencap_interval = 0; // 保全战斗截图最小间隔 + int roguelike_fight_screencap_interval = 0; // 肉鸽战斗截图最小间隔 + int copilot_fight_screencap_interval = 0; // 抄作业战斗截图最小间隔 + int control_delay_lower = 0; // 点击随机延时下限:每次点击操作会进行随机延时 + int control_delay_upper = 0; // 点击随机延时上限:每次点击操作会进行随机延时 // bool print_window = false;// 截图功能:开启后每次结算界面会截图到screenshot目录下 int adb_extra_swipe_dist = 0; // 额外的滑动距离: // adb有bug,同样的参数,偶尔会划得非常远。 @@ -57,8 +57,7 @@ struct Options std::vector minitouch_programs_order; RequestInfo penguin_report; // 企鹅物流汇报:每次到结算界面,汇报掉落数据至企鹅物流 https://penguin-stats.io DepotExportTemplate depot_export_template; // 仓库识别结果导出模板 - RequestInfo - yituliu_report; // 一图流大数据汇报:目前只有公招功能,https://ark.yituliu.cn/survey/maarecruitdata + RequestInfo yituliu_report; // 一图流大数据汇报:目前只有公招功能,https://ark.yituliu.cn/survey/maarecruitdata DebugConf debug; }; @@ -92,9 +91,7 @@ struct AdbCfg json::object extras; }; -class GeneralConfig final - : public SingletonHolder - , public AbstractConfig +class GeneralConfig final : public SingletonHolder, public AbstractConfig { public: virtual ~GeneralConfig() override = default; diff --git a/src/MaaCore/Config/Miscellaneous/AvatarCacheManager.cpp b/src/MaaCore/Config/Miscellaneous/AvatarCacheManager.cpp index 593a822a5b..6beb2dd3d8 100644 --- a/src/MaaCore/Config/Miscellaneous/AvatarCacheManager.cpp +++ b/src/MaaCore/Config/Miscellaneous/AvatarCacheManager.cpp @@ -49,8 +49,11 @@ void asst::AvatarCacheManager::remove_avatars(battle::Role role) m_avatars.erase(role); } -void asst::AvatarCacheManager::set_avatar(const std::string& name, battle::Role role, const cv::Mat& avatar, - bool overlay) +void asst::AvatarCacheManager::set_avatar( + const std::string& name, + battle::Role role, + const cv::Mat& avatar, + bool overlay) { LogTraceFunction; Log.info(__FUNCTION__, name, ", overlay:", overlay); @@ -89,7 +92,6 @@ void asst::AvatarCacheManager::_load(LoadItem waiting_to_load) for (const auto& [role, name_and_paths] : waiting_to_load) { for (const auto& [name, filepath] : name_and_paths) { - #ifdef ASST_DEBUG Log.trace(__FUNCTION__, name, filepath.lexically_relative(UserDir.get())); #endif diff --git a/src/MaaCore/Config/Miscellaneous/AvatarCacheManager.h b/src/MaaCore/Config/Miscellaneous/AvatarCacheManager.h index e983665aa1..62cdcae160 100644 --- a/src/MaaCore/Config/Miscellaneous/AvatarCacheManager.h +++ b/src/MaaCore/Config/Miscellaneous/AvatarCacheManager.h @@ -13,30 +13,31 @@ namespace asst { - class AvatarCacheManager final : public SingletonHolder, public AbstractResource - { - public: - using AvatarsMap = std::unordered_map; - inline static const std::string CacheExtension = ".png"; +class AvatarCacheManager final : public SingletonHolder, public AbstractResource +{ +public: + using AvatarsMap = std::unordered_map; + inline static const std::string CacheExtension = ".png"; - public: - virtual ~AvatarCacheManager() override = default; +public: + virtual ~AvatarCacheManager() override = default; - virtual bool load(const std::filesystem::path& path) override; + virtual bool load(const std::filesystem::path& path) override; - const AvatarsMap& get_avatars(battle::Role role); - void remove_avatars(battle::Role role); - void set_avatar(const std::string& name, battle::Role role, const cv::Mat& avatar, bool overlay = true); + const AvatarsMap& get_avatars(battle::Role role); + void remove_avatars(battle::Role role); + void set_avatar(const std::string& name, battle::Role role, const cv::Mat& avatar, bool overlay = true); - private: - using LoadItem = std::unordered_map>; - void _load(LoadItem waiting_to_load); +private: + using LoadItem = std::unordered_map>; + void _load(LoadItem waiting_to_load); - std::filesystem::path m_save_path; - std::future m_load_future; - std::mutex m_load_mutex; + std::filesystem::path m_save_path; + std::future m_load_future; + std::mutex m_load_mutex; - std::unordered_map> m_avatars; - }; - inline static auto& AvatarCache = AvatarCacheManager::get_instance(); + std::unordered_map> m_avatars; +}; + +inline static auto& AvatarCache = AvatarCacheManager::get_instance(); } diff --git a/src/MaaCore/Config/Miscellaneous/BattleDataConfig.h b/src/MaaCore/Config/Miscellaneous/BattleDataConfig.h index 78732d454e..b871b9d5a5 100644 --- a/src/MaaCore/Config/Miscellaneous/BattleDataConfig.h +++ b/src/MaaCore/Config/Miscellaneous/BattleDataConfig.h @@ -8,105 +8,103 @@ namespace asst { - class BattleDataConfig final : public SingletonHolder, public AbstractConfig +class BattleDataConfig final : public SingletonHolder, public AbstractConfig +{ +public: + virtual ~BattleDataConfig() override = default; + + static inline const std::string& EmptyId = ""; + + const std::string get_id(const std::string& name) const { - public: - virtual ~BattleDataConfig() override = default; - - static inline const std::string& EmptyId = ""; - - const std::string get_id(const std::string& name) const - { - auto iter = m_chars.find(name); - if (iter == m_chars.cend()) { - return EmptyId; - } - return iter->second.id; + auto iter = m_chars.find(name); + if (iter == m_chars.cend()) { + return EmptyId; } + return iter->second.id; + } - const std::string get_en(const std::string& name) const { return m_chars.find(name)->second.name_en; } + const std::string get_en(const std::string& name) const { return m_chars.find(name)->second.name_en; } - const std::string get_jp(const std::string& name) const { return m_chars.find(name)->second.name_jp; } + const std::string get_jp(const std::string& name) const { return m_chars.find(name)->second.name_jp; } - const std::string get_kr(const std::string& name) const { return m_chars.find(name)->second.name_kr; } + const std::string get_kr(const std::string& name) const { return m_chars.find(name)->second.name_kr; } - const std::string get_tw(const std::string& name) const { return m_chars.find(name)->second.name_tw; } + const std::string get_tw(const std::string& name) const { return m_chars.find(name)->second.name_tw; } - battle::Role get_role(const std::string& name) const - { - auto iter = m_chars.find(name); - if (iter == m_chars.cend()) { - return battle::Role::Unknown; - } - return iter->second.role; + battle::Role get_role(const std::string& name) const + { + auto iter = m_chars.find(name); + if (iter == m_chars.cend()) { + return battle::Role::Unknown; } + return iter->second.role; + } - int get_rarity(const std::string& name) const - { - auto iter = m_chars.find(name); - if (iter == m_chars.cend()) { - return 0; - } - return iter->second.rarity; + int get_rarity(const std::string& name) const + { + auto iter = m_chars.find(name); + if (iter == m_chars.cend()) { + return 0; } + return iter->second.rarity; + } - battle::LocationType get_location_type(const std::string& name) const - { - auto iter = m_chars.find(name); - if (iter == m_chars.cend()) { - return battle::LocationType::Invalid; - } - return iter->second.location_type; + battle::LocationType get_location_type(const std::string& name) const + { + auto iter = m_chars.find(name); + if (iter == m_chars.cend()) { + return battle::LocationType::Invalid; } + return iter->second.location_type; + } - static inline const battle::AttackRange& EmptyRange { { 0, 0 } }; + static inline const battle::AttackRange& EmptyRange { { 0, 0 } }; - const battle::AttackRange& get_range(const std::string& name, size_t index) const - { - auto char_iter = m_chars.find(name); - if (char_iter == m_chars.cend()) { + const battle::AttackRange& get_range(const std::string& name, size_t index) const + { + auto char_iter = m_chars.find(name); + if (char_iter == m_chars.cend()) { + return EmptyRange; + } + const auto& ranges = char_iter->second.ranges; + if (index >= ranges.size()) { + if (ranges.empty()) { return EmptyRange; } - const auto& ranges = char_iter->second.ranges; - if (index >= ranges.size()) { - if (ranges.empty()) { - return EmptyRange; - } - index = 0; - } - - const std::string& range_name = ranges.at(index); - auto range_iter = m_ranges.find(range_name); - if (range_iter == m_ranges.cend()) { - return EmptyRange; - } - return range_iter->second; + index = 0; } - const std::vector& get_tokens(const std::string& name) const - { - auto char_iter = m_chars.find(name); - if (char_iter == m_chars.cend()) { - static const std::vector Empty; - return Empty; - } - return char_iter->second.tokens; + const std::string& range_name = ranges.at(index); + auto range_iter = m_ranges.find(range_name); + if (range_iter == m_ranges.cend()) { + return EmptyRange; } + return range_iter->second; + } - bool is_name_invalid(const std::string& name) const - { - return name.empty() || m_chars.find(name) == m_chars.cend(); + const std::vector& get_tokens(const std::string& name) const + { + auto char_iter = m_chars.find(name); + if (char_iter == m_chars.cend()) { + static const std::vector Empty; + return Empty; } + return char_iter->second.tokens; + } - const std::unordered_set& get_all_oper_names() const noexcept { return m_opers; } + bool is_name_invalid(const std::string& name) const { return name.empty() || m_chars.find(name) == m_chars.cend(); } - protected: - virtual bool parse(const json::value& json) override; + const std::unordered_set& get_all_oper_names() const noexcept { return m_opers; } - private: - std::unordered_map m_chars; - std::unordered_map m_ranges; - std::unordered_set m_opers; - }; - inline static auto& BattleData = BattleDataConfig::get_instance(); +protected: + virtual bool parse(const json::value& json) override; + +private: + std::unordered_map m_chars; + std::unordered_map m_ranges; + std::unordered_set m_opers; +}; + +inline static auto& BattleData = BattleDataConfig::get_instance(); } // namespace asst diff --git a/src/MaaCore/Config/Miscellaneous/CopilotConfig.h b/src/MaaCore/Config/Miscellaneous/CopilotConfig.h index 2ea9d92971..6c73d8688f 100644 --- a/src/MaaCore/Config/Miscellaneous/CopilotConfig.h +++ b/src/MaaCore/Config/Miscellaneous/CopilotConfig.h @@ -4,28 +4,30 @@ namespace asst { - class CopilotConfig : public SingletonHolder, public AbstractConfig - { - public: - static battle::copilot::BasicInfo parse_basic_info(const json::value& json); - static battle::copilot::OperUsageGroups parse_groups(const json::value& json); - static std::vector parse_actions(const json::value& json); - static battle::RoleCounts parse_role_counts(const json::value& json); - static battle::DeployDirection string_to_direction(const std::string& str); +class CopilotConfig : public SingletonHolder, public AbstractConfig +{ +public: + static battle::copilot::BasicInfo parse_basic_info(const json::value& json); + static battle::copilot::OperUsageGroups parse_groups(const json::value& json); + static std::vector parse_actions(const json::value& json); + static battle::RoleCounts parse_role_counts(const json::value& json); + static battle::DeployDirection string_to_direction(const std::string& str); - public: - virtual ~CopilotConfig() override = default; +public: + virtual ~CopilotConfig() override = default; - const battle::copilot::CombatData& get_data() const noexcept { return m_data; } - const std::string& get_stage_name() const noexcept { return m_data.info.stage_name; } - bool parse_magic_code(const std::string& copilot_magic_code); - void clear(); + const battle::copilot::CombatData& get_data() const noexcept { return m_data; } - protected: - virtual bool parse(const json::value& json) override; + const std::string& get_stage_name() const noexcept { return m_data.info.stage_name; } - battle::copilot::CombatData m_data; - }; + bool parse_magic_code(const std::string& copilot_magic_code); + void clear(); - inline static auto& Copilot = CopilotConfig::get_instance(); +protected: + virtual bool parse(const json::value& json) override; + + battle::copilot::CombatData m_data; +}; + +inline static auto& Copilot = CopilotConfig::get_instance(); } diff --git a/src/MaaCore/Config/Miscellaneous/InfrastConfig.h b/src/MaaCore/Config/Miscellaneous/InfrastConfig.h index 984ec0d53e..84504296c5 100644 --- a/src/MaaCore/Config/Miscellaneous/InfrastConfig.h +++ b/src/MaaCore/Config/Miscellaneous/InfrastConfig.h @@ -8,46 +8,49 @@ namespace asst { - class InfrastConfig final : public SingletonHolder, public AbstractConfigWithTempl +class InfrastConfig final : public SingletonHolder, public AbstractConfigWithTempl +{ +public: + virtual ~InfrastConfig() override = default; + + virtual const std::unordered_set& get_templ_required() const noexcept override { - public: - virtual ~InfrastConfig() override = default; + return m_templ_required; + } - virtual const std::unordered_set& get_templ_required() const noexcept override - { - return m_templ_required; - } - auto get_skills(const std::string& facility_name) const - -> const std::unordered_map& - { - return m_skills.at(facility_name); - } - auto get_skills_group(const std::string& facility) const -> const std::vector& - { - return m_skills_groups.at(facility); - } - auto get_facility_info(const std::string& facility) const -> const infrast::Facility& - { - return m_facilities_info.at(facility); - } - auto get_facility_info() const noexcept -> const std::unordered_map& - { - return m_facilities_info; - } + auto get_skills(const std::string& facility_name) const -> const std::unordered_map& + { + return m_skills.at(facility_name); + } - protected: - virtual bool parse(const json::value& json) override; + auto get_skills_group(const std::string& facility) const -> const std::vector& + { + return m_skills_groups.at(facility); + } - // 所有基建技能,key:设施名,value:map<技能id,技能> - std::unordered_map> m_skills; - // 所有设施信息,key:设施名,value:信息 - std::unordered_map m_facilities_info; - // 所有加成技能组 - std::unordered_map> m_skills_groups; + auto get_facility_info(const std::string& facility) const -> const infrast::Facility& + { + return m_facilities_info.at(facility); + } - // 需要加载的模板 - std::unordered_set m_templ_required; - }; + auto get_facility_info() const noexcept -> const std::unordered_map& + { + return m_facilities_info; + } - inline static auto& InfrastData = InfrastConfig::get_instance(); +protected: + virtual bool parse(const json::value& json) override; + + // 所有基建技能,key:设施名,value:map<技能id,技能> + std::unordered_map> m_skills; + // 所有设施信息,key:设施名,value:信息 + std::unordered_map m_facilities_info; + // 所有加成技能组 + std::unordered_map> m_skills_groups; + + // 需要加载的模板 + std::unordered_set m_templ_required; +}; + +inline static auto& InfrastData = InfrastConfig::get_instance(); } diff --git a/src/MaaCore/Config/Miscellaneous/ItemConfig.cpp b/src/MaaCore/Config/Miscellaneous/ItemConfig.cpp index fb50b47b1e..12a7dc8a94 100644 --- a/src/MaaCore/Config/Miscellaneous/ItemConfig.cpp +++ b/src/MaaCore/Config/Miscellaneous/ItemConfig.cpp @@ -23,8 +23,9 @@ bool asst::ItemConfig::parse(const json::value& json) m_ordered_material_item_id.clear(); m_ordered_material_item_id.reserve(material_sortid.size()); ranges::copy(material_sortid | views::keys, std::back_inserter(m_ordered_material_item_id)); - ranges::sort(m_ordered_material_item_id, std::less {}, - [&](const std::string& name) -> int { return material_sortid[name]; }); + ranges::sort(m_ordered_material_item_id, std::less {}, [&](const std::string& name) -> int { + return material_sortid[name]; + }); return true; } diff --git a/src/MaaCore/Config/Miscellaneous/ItemConfig.h b/src/MaaCore/Config/Miscellaneous/ItemConfig.h index 477606d100..ed5863462a 100644 --- a/src/MaaCore/Config/Miscellaneous/ItemConfig.h +++ b/src/MaaCore/Config/Miscellaneous/ItemConfig.h @@ -8,41 +8,44 @@ namespace asst { - class ItemConfig final : public SingletonHolder, public AbstractConfigWithTempl +class ItemConfig final : public SingletonHolder, public AbstractConfigWithTempl +{ +public: + virtual ~ItemConfig() override = default; + + const std::string& get_item_name(const std::string& id) const noexcept { - public: - virtual ~ItemConfig() override = default; - - const std::string& get_item_name(const std::string& id) const noexcept - { - if (id.empty()) { - static const std::string unknown = "Unknown"; - return unknown; - } - if (auto iter = m_item_name.find(id); iter != m_item_name.cend()) { - return iter->second; - } - else { - static const std::string empty; - return empty; - } + if (id.empty()) { + static const std::string unknown = "Unknown"; + return unknown; } - const auto& get_all_item_id() const noexcept { return m_all_item_id; } - virtual const std::unordered_set& get_templ_required() const noexcept override - { - return get_all_item_id(); + if (auto iter = m_item_name.find(id); iter != m_item_name.cend()) { + return iter->second; } - const auto& get_ordered_material_item_id() const noexcept { return m_ordered_material_item_id; } + else { + static const std::string empty; + return empty; + } + } - protected: - virtual bool parse(const json::value& json) override; - void clear(); + const auto& get_all_item_id() const noexcept { return m_all_item_id; } - // key:材料编号Id,value:材料名(对应客户端材料名称,utf8) - std::unordered_map m_item_name; - std::unordered_set m_all_item_id; - std::vector m_ordered_material_item_id; - }; + virtual const std::unordered_set& get_templ_required() const noexcept override + { + return get_all_item_id(); + } - inline static auto& ItemData = ItemConfig::get_instance(); + const auto& get_ordered_material_item_id() const noexcept { return m_ordered_material_item_id; } + +protected: + virtual bool parse(const json::value& json) override; + void clear(); + + // key:材料编号Id,value:材料名(对应客户端材料名称,utf8) + std::unordered_map m_item_name; + std::unordered_set m_all_item_id; + std::vector m_ordered_material_item_id; +}; + +inline static auto& ItemData = ItemConfig::get_instance(); } diff --git a/src/MaaCore/Config/Miscellaneous/OcrConfig.h b/src/MaaCore/Config/Miscellaneous/OcrConfig.h index 23868093d9..0e0f63ad83 100644 --- a/src/MaaCore/Config/Miscellaneous/OcrConfig.h +++ b/src/MaaCore/Config/Miscellaneous/OcrConfig.h @@ -13,19 +13,20 @@ namespace asst { - class OcrConfig final : public SingletonHolder, public AbstractConfig - { - public: - virtual ~OcrConfig() override = default; +class OcrConfig final : public SingletonHolder, public AbstractConfig +{ +public: + virtual ~OcrConfig() override = default; - std::string process_equivalence_class(const std::string& str) const; - auto get_eq_classes() const noexcept { return m_eq_classes; } + std::string process_equivalence_class(const std::string& str) const; - protected: - virtual bool parse(const json::value& json) override; + auto get_eq_classes() const noexcept { return m_eq_classes; } - using equivalence_class = std::vector; +protected: + virtual bool parse(const json::value& json) override; - std::vector m_eq_classes; - }; + using equivalence_class = std::vector; + + std::vector m_eq_classes; +}; } // namespace asst diff --git a/src/MaaCore/Config/Miscellaneous/OcrPack.cpp b/src/MaaCore/Config/Miscellaneous/OcrPack.cpp index 57e3979ddc..bc790ae0ac 100644 --- a/src/MaaCore/Config/Miscellaneous/OcrPack.cpp +++ b/src/MaaCore/Config/Miscellaneous/OcrPack.cpp @@ -16,7 +16,10 @@ ASST_SUPPRESS_CV_WARNINGS_END #include "Utils/Ranges.hpp" #include "Utils/StringMisc.hpp" -asst::OcrPack::OcrPack() : m_det(nullptr), m_rec(nullptr), m_ocr(nullptr) +asst::OcrPack::OcrPack() : + m_det(nullptr), + m_rec(nullptr), + m_ocr(nullptr) { LogTraceFunction; } @@ -149,14 +152,21 @@ bool asst::OcrPack::check_and_load() auto det_model = asst::utils::read_file(m_det_model_path); option.SetModelBuffer(det_model.data(), det_model.size(), nullptr, 0, fastdeploy::ModelFormat::ONNX); - m_det = std::make_unique("dummy.onnx", std::string(), option, - fastdeploy::ModelFormat::ONNX); + m_det = std::make_unique( + "dummy.onnx", + std::string(), + option, + fastdeploy::ModelFormat::ONNX); auto rec_model = asst::utils::read_file(m_rec_model_path); std::string rec_label = asst::utils::read_file(m_rec_label_path); option.SetModelBuffer(rec_model.data(), rec_model.size(), nullptr, 0, fastdeploy::ModelFormat::ONNX); - m_rec = std::make_unique("dummy.onnx", std::string(), rec_label, option, - fastdeploy::ModelFormat::ONNX); + m_rec = std::make_unique( + "dummy.onnx", + std::string(), + rec_label, + option, + fastdeploy::ModelFormat::ONNX); if (m_det && m_rec) { m_ocr = std::make_unique(m_det.get(), m_rec.get()); diff --git a/src/MaaCore/Config/Miscellaneous/OcrPack.h b/src/MaaCore/Config/Miscellaneous/OcrPack.h index fc00dfa6fb..96363c53e2 100644 --- a/src/MaaCore/Config/Miscellaneous/OcrPack.h +++ b/src/MaaCore/Config/Miscellaneous/OcrPack.h @@ -8,65 +8,67 @@ namespace cv { - class Mat; +class Mat; } namespace fastdeploy { - namespace vision::ocr - { - class DBDetector; - class Recognizer; - } +namespace vision::ocr +{ +class DBDetector; +class Recognizer; +} - namespace pipeline - { - class PPOCRv3; - } +namespace pipeline +{ +class PPOCRv3; +} - struct RuntimeOption; +struct RuntimeOption; } namespace asst { - class OcrPack : public AbstractResource - { - public: - using Result = TextRect; - using ResultsVec = std::vector; +class OcrPack : public AbstractResource +{ +public: + using Result = TextRect; + using ResultsVec = std::vector; - public: - virtual ~OcrPack() override; +public: + virtual ~OcrPack() override; - virtual bool load(const std::filesystem::path& path) override; - void use_cpu() { m_gpu_id = std::nullopt; } - void use_gpu(int gpu_id) { m_gpu_id = gpu_id; } + virtual bool load(const std::filesystem::path& path) override; - ResultsVec recognize(const cv::Mat& image, bool without_det = false); + void use_cpu() { m_gpu_id = std::nullopt; } - protected: - OcrPack(); + void use_gpu(int gpu_id) { m_gpu_id = gpu_id; } - bool check_and_load(); + ResultsVec recognize(const cv::Mat& image, bool without_det = false); - std::unique_ptr m_det; - std::unique_ptr m_rec; - std::unique_ptr m_ocr; +protected: + OcrPack(); - std::filesystem::path m_det_model_path; - std::filesystem::path m_rec_model_path; - std::filesystem::path m_rec_label_path; + bool check_and_load(); - std::optional m_gpu_id = std::nullopt; - }; + std::unique_ptr m_det; + std::unique_ptr m_rec; + std::unique_ptr m_ocr; - class WordOcr final : public SingletonHolder, public OcrPack - { - friend class SingletonHolder; - }; + std::filesystem::path m_det_model_path; + std::filesystem::path m_rec_model_path; + std::filesystem::path m_rec_label_path; - class CharOcr final : public SingletonHolder, public OcrPack - { - friend class SingletonHolder; - }; + std::optional m_gpu_id = std::nullopt; +}; + +class WordOcr final : public SingletonHolder, public OcrPack +{ + friend class SingletonHolder; +}; + +class CharOcr final : public SingletonHolder, public OcrPack +{ + friend class SingletonHolder; +}; } diff --git a/src/MaaCore/Config/Miscellaneous/RecruitConfig.h b/src/MaaCore/Config/Miscellaneous/RecruitConfig.h index 2ddc555e73..22d3d7cbef 100644 --- a/src/MaaCore/Config/Miscellaneous/RecruitConfig.h +++ b/src/MaaCore/Config/Miscellaneous/RecruitConfig.h @@ -13,118 +13,135 @@ namespace asst { - // 干员信息,公开招募相关 - struct Recruitment +// 干员信息,公开招募相关 +struct Recruitment +{ + std::string name; + std::string id; + int level = 0; + std::unordered_set tags; + + bool has_tag(const std::string& tag) const { return tags.contains(tag); } + + friend std::strong_ordering operator<=>(const Recruitment& lhs, const Recruitment& rhs) { - std::string name; - std::string id; - int level = 0; - std::unordered_set tags; - - bool has_tag(const std::string& tag) const { return tags.contains(tag); } - - friend std::strong_ordering operator<=>(const Recruitment& lhs, const Recruitment& rhs) - { - if (lhs.level != rhs.level) return lhs.level <=> rhs.level; // increment order + if (lhs.level != rhs.level) { + return lhs.level <=> rhs.level; // increment order + } #ifdef __clang__ - if (rhs.name < lhs.name) - return std::strong_ordering::less; - else if (rhs.name > lhs.name) - return std::strong_ordering::greater; - else - return std::strong_ordering::equal; + if (rhs.name < lhs.name) { + return std::strong_ordering::less; + } + else if (rhs.name > lhs.name) { + return std::strong_ordering::greater; + } + else { + return std::strong_ordering::equal; + } #else - return rhs.name <=> lhs.name; // decrement order (print reversely) + return rhs.name <=> lhs.name; // decrement order (print reversely) #endif - } + } - friend bool operator==(const Recruitment& lhs, const Recruitment& rhs) - { - return lhs.id == rhs.id && lhs.level == rhs.level; - } - }; - - // 选择额外 Tags 的模式 - enum class ExtraTagsMode + friend bool operator==(const Recruitment& lhs, const Recruitment& rhs) { - NoExtra, // 0 - 默认行为 - Extra, // 1 - 选 3 个 Tags, 即使可能冲突 - ExtraOnlyRare, // 2 - 如果可能, 同时选择更多的高星 Tag 组合, 即使可能冲突 - }; + return lhs.id == rhs.id && lhs.level == rhs.level; + } +}; - class RecruitConfig final : public SingletonHolder, public AbstractConfig +// 选择额外 Tags 的模式 +enum class ExtraTagsMode +{ + NoExtra, // 0 - 默认行为 + Extra, // 1 - 选 3 个 Tags, 即使可能冲突 + ExtraOnlyRare, // 2 - 如果可能, 同时选择更多的高星 Tag 组合, 即使可能冲突 +}; + +class RecruitConfig final : public SingletonHolder, public AbstractConfig +{ +public: + using TagId = std::string; + +public: + static constexpr bool is_valid_extra_tags_mode(ExtraTagsMode mode) { - public: - using TagId = std::string; + return mode == ExtraTagsMode::NoExtra || mode == ExtraTagsMode::Extra || mode == ExtraTagsMode::ExtraOnlyRare; + } - public: - static constexpr bool is_valid_extra_tags_mode(ExtraTagsMode mode) - { - return mode == ExtraTagsMode::NoExtra || mode == ExtraTagsMode::Extra || mode == ExtraTagsMode::ExtraOnlyRare; - } +public: + virtual ~RecruitConfig() override = default; + static constexpr int CorrectNumberOfTags = 5; - public: - virtual ~RecruitConfig() override = default; - static constexpr int CorrectNumberOfTags = 5; + const std::unordered_set& get_all_tags() const noexcept { return m_all_tags; } - const std::unordered_set& get_all_tags() const noexcept { return m_all_tags; } - const std::vector& get_all_opers() const noexcept { return m_all_opers; } - std::string get_tag_name(const TagId& id) const noexcept; + const std::vector& get_all_opers() const noexcept { return m_all_opers; } - protected: - virtual bool parse(const json::value& json) override; + std::string get_tag_name(const TagId& id) const noexcept; - void clear(); +protected: + virtual bool parse(const json::value& json) override; - std::unordered_set m_all_tags; - std::vector m_all_opers; - std::unordered_map m_all_tags_name; - }; + void clear(); - // 公开招募的干员组合 - struct RecruitCombs + std::unordered_set m_all_tags; + std::vector m_all_opers; + std::unordered_map m_all_tags_name; +}; + +// 公开招募的干员组合 +struct RecruitCombs +{ + // TODO: using vector here can be expensive + std::vector tags; + std::vector opers; + int max_level = 0; + int min_level = 0; + double avg_level = 0; + + void update_attributes() { - // TODO: using vector here can be expensive - std::vector tags; - std::vector opers; - int max_level = 0; - int min_level = 0; - double avg_level = 0; + min_level = std::transform_reduce( + opers.cbegin(), + opers.cend(), + 7, + [](int a, int b) -> int { return (std::min)(a, b); }, + std::mem_fn(&Recruitment::level)); - void update_attributes() - { - min_level = std::transform_reduce( - opers.cbegin(), opers.cend(), 7, [](int a, int b) -> int { return (std::min)(a, b); }, - std::mem_fn(&Recruitment::level)); + max_level = std::transform_reduce( + opers.cbegin(), + opers.cend(), + 0, + [](int a, int b) -> int { return (std::max)(a, b); }, + std::mem_fn(&Recruitment::level)); - max_level = std::transform_reduce( - opers.cbegin(), opers.cend(), 0, [](int a, int b) -> int { return (std::max)(a, b); }, - std::mem_fn(&Recruitment::level)); + avg_level = std::transform_reduce( + opers.cbegin(), + opers.cend(), + 0., + std::plus {}, + std::mem_fn(&Recruitment::level)) / + static_cast(opers.size()); + } - avg_level = std::transform_reduce(opers.cbegin(), opers.cend(), 0., std::plus {}, - std::mem_fn(&Recruitment::level)) / - static_cast(opers.size()); - } + // intersection of two recruit combs + friend RecruitCombs operator*(RecruitCombs& lhs, RecruitCombs& rhs) + { + ranges::sort(lhs.tags); + ranges::sort(lhs.opers); + ranges::sort(rhs.tags); + ranges::sort(rhs.opers); - // intersection of two recruit combs - friend RecruitCombs operator*(RecruitCombs& lhs, RecruitCombs& rhs) - { - ranges::sort(lhs.tags); - ranges::sort(lhs.opers); - ranges::sort(rhs.tags); - ranges::sort(rhs.opers); + RecruitCombs result; - RecruitCombs result; + ranges::set_union(lhs.tags, rhs.tags, std::back_inserter(result.tags)); - ranges::set_union(lhs.tags, rhs.tags, std::back_inserter(result.tags)); + ranges::set_intersection(lhs.opers, rhs.opers, std::back_inserter(result.opers)); - ranges::set_intersection(lhs.opers, rhs.opers, std::back_inserter(result.opers)); + result.update_attributes(); - result.update_attributes(); + return result; + } +}; - return result; - } - }; - - inline static auto& RecruitData = RecruitConfig::get_instance(); +inline static auto& RecruitData = RecruitConfig::get_instance(); } // namespace asst diff --git a/src/MaaCore/Config/Miscellaneous/SSSCopilotConfig.h b/src/MaaCore/Config/Miscellaneous/SSSCopilotConfig.h index 09802dda4c..a07d9c54af 100644 --- a/src/MaaCore/Config/Miscellaneous/SSSCopilotConfig.h +++ b/src/MaaCore/Config/Miscellaneous/SSSCopilotConfig.h @@ -4,24 +4,27 @@ namespace asst { - class SSSCopilotConfig : public SingletonHolder, public AbstractConfig +class SSSCopilotConfig : public SingletonHolder, public AbstractConfig +{ +public: + virtual ~SSSCopilotConfig() override = default; + + const battle::sss::CompleteData& get_data() const noexcept { return m_data; } + + bool contains(const std::string& name) const noexcept { return m_data.stages_data.contains(name); } + + const battle::sss::CombatData& get_data(const std::string& name) const noexcept { - public: - virtual ~SSSCopilotConfig() override = default; + return m_data.stages_data.at(name); + } - const battle::sss::CompleteData& get_data() const noexcept { return m_data; } - bool contains(const std::string& name) const noexcept { return m_data.stages_data.contains(name); } - const battle::sss::CombatData& get_data(const std::string& name) const noexcept - { - return m_data.stages_data.at(name); - } - void clear(); + void clear(); - protected: - virtual bool parse(const json::value& json) override; +protected: + virtual bool parse(const json::value& json) override; - battle::sss::CompleteData m_data; - }; + battle::sss::CompleteData m_data; +}; - inline static auto& SSSCopilot = SSSCopilotConfig::get_instance(); +inline static auto& SSSCopilot = SSSCopilotConfig::get_instance(); } diff --git a/src/MaaCore/Config/Miscellaneous/StageDropsConfig.h b/src/MaaCore/Config/Miscellaneous/StageDropsConfig.h index 72e9beb12c..4bc19b6d09 100644 --- a/src/MaaCore/Config/Miscellaneous/StageDropsConfig.h +++ b/src/MaaCore/Config/Miscellaneous/StageDropsConfig.h @@ -8,91 +8,101 @@ namespace asst { - enum class StageDifficulty - { - Normal, - Tough +enum class StageDifficulty +{ + Normal, + Tough +}; + +inline std::string enum_to_string(StageDifficulty algo) +{ + static const std::unordered_map algorithm_map = { + { StageDifficulty::Normal, "Normal" }, + { StageDifficulty::Tough, "Tough" } }; - inline std::string enum_to_string(StageDifficulty algo) - { - static const std::unordered_map algorithm_map = { - { StageDifficulty::Normal, "Normal" }, { StageDifficulty::Tough, "Tough" } - }; - if (auto it = algorithm_map.find(algo); it != algorithm_map.end()) { - return it->second; - } - return "Invalid"; + if (auto it = algorithm_map.find(algo); it != algorithm_map.end()) { + return it->second; } - struct StageKey + return "Invalid"; +} + +struct StageKey +{ + std::string code; + StageDifficulty difficulty = StageDifficulty::Normal; + + bool operator==(const StageKey& other) const { return code == other.code && difficulty == other.difficulty; } +}; + +struct StageKeyHasher +{ + size_t operator()(const StageKey& key) const { - std::string code; - StageDifficulty difficulty = StageDifficulty::Normal; - bool operator==(const StageKey& other) const { return code == other.code && difficulty == other.difficulty; } - }; - struct StageKeyHasher + return std::hash()(key.code) ^ (static_cast(key.difficulty) << 1); + } +}; + +enum class StageDropType +{ + Unknown, + ExpAndLMB, + Normal, + Extra, + Furniture, // 家具 + Special, // 稀有材料、周年庆箱子等 + Sanity, // 理智返还 + Reward // 报酬(合成玉,仅剿灭) +}; + +struct StageInfo +{ + std::string stage_id; + int ap_cost = 0; + std::unordered_map> drops; +}; + +struct StageDropInfo +{ + StageDropType drop_type = StageDropType::Unknown; + std::string drop_type_name; + std::string item_id; + std::string item_name; + int quantity = 0; +}; + +class StageDropsConfig final : public SingletonHolder, public AbstractConfig +{ +public: + virtual ~StageDropsConfig() override = default; + + const auto& get_stage_info(const std::string& code, StageDifficulty difficulty) const { - size_t operator()(const StageKey& key) const - { - return std::hash()(key.code) ^ (static_cast(key.difficulty) << 1); + StageKey key { code, difficulty }; + if (auto find_iter = m_stage_info.find(key); find_iter != m_stage_info.end()) { + return find_iter->second; } - }; - - enum class StageDropType - { - Unknown, - ExpAndLMB, - Normal, - Extra, - Furniture, // 家具 - Special, // 稀有材料、周年庆箱子等 - Sanity, // 理智返还 - Reward // 报酬(合成玉,仅剿灭) - }; - struct StageInfo - { - std::string stage_id; - int ap_cost = 0; - std::unordered_map> drops; - }; - struct StageDropInfo - { - StageDropType drop_type = StageDropType::Unknown; - std::string drop_type_name; - std::string item_id; - std::string item_name; - int quantity = 0; - }; - - class StageDropsConfig final : public SingletonHolder, public AbstractConfig - { - public: - virtual ~StageDropsConfig() override = default; - - const auto& get_stage_info(const std::string& code, StageDifficulty difficulty) const - { - StageKey key { code, difficulty }; - if (auto find_iter = m_stage_info.find(key); find_iter != m_stage_info.end()) { - return find_iter->second; - } - else { - static StageInfo empty_info; - return empty_info; - } - } - const auto& get_all_stage_code() const { return m_all_stage_code; } - const auto& get_all_item_id() const { return m_all_item_id; } - void append_drops(const StageKey& stage_key, StageDropType type, std::string item_id) - { - m_stage_info[stage_key].drops[type].emplace_back(std::move(item_id)); + else { + static StageInfo empty_info; + return empty_info; } + } - protected: - virtual bool parse(const json::value& json) override; + const auto& get_all_stage_code() const { return m_all_stage_code; } - std::unordered_set m_all_stage_code; - std::unordered_set m_all_item_id; - std::unordered_map m_stage_info; - }; + const auto& get_all_item_id() const { return m_all_item_id; } - inline static auto& StageDrops = StageDropsConfig::get_instance(); + void append_drops(const StageKey& stage_key, StageDropType type, std::string item_id) + { + m_stage_info[stage_key].drops[type].emplace_back(std::move(item_id)); + } + +protected: + virtual bool parse(const json::value& json) override; + + std::unordered_set m_all_stage_code; + std::unordered_set m_all_item_id; + std::unordered_map m_stage_info; +}; + +inline static auto& StageDrops = StageDropsConfig::get_instance(); } // namespace asst diff --git a/src/MaaCore/Config/Miscellaneous/TilePack.cpp b/src/MaaCore/Config/Miscellaneous/TilePack.cpp index cc35400610..0e34343c94 100644 --- a/src/MaaCore/Config/Miscellaneous/TilePack.cpp +++ b/src/MaaCore/Config/Miscellaneous/TilePack.cpp @@ -83,8 +83,7 @@ bool proc_data( return true; } -asst::TilePack::result_type - asst::TilePack::calc_(const Map::Level& level, double shift_x, double shift_y) +asst::TilePack::result_type asst::TilePack::calc_(const Map::Level& level, double shift_x, double shift_y) { LogTraceFunction; diff --git a/src/MaaCore/Config/Miscellaneous/TilePack.h b/src/MaaCore/Config/Miscellaneous/TilePack.h index 6adf66173b..35f9691844 100644 --- a/src/MaaCore/Config/Miscellaneous/TilePack.h +++ b/src/MaaCore/Config/Miscellaneous/TilePack.h @@ -10,9 +10,7 @@ ASST_SUPPRESS_CV_WARNINGS_END namespace asst { -class TilePack final - : public SingletonHolder - , public AbstractConfig +class TilePack final : public SingletonHolder, public AbstractConfig { public: using LevelKey = Map::LevelKey; diff --git a/src/MaaCore/Config/OnnxSessions.cpp b/src/MaaCore/Config/OnnxSessions.cpp index df483fa1c7..5a96071831 100644 --- a/src/MaaCore/Config/OnnxSessions.cpp +++ b/src/MaaCore/Config/OnnxSessions.cpp @@ -43,7 +43,9 @@ Ort::Session& asst::OnnxSessions::get(const std::string& name) bool asst::OnnxSessions::use_cpu() { - if (m_sessions.size() != 0) return false; + if (m_sessions.size() != 0) { + return false; + } m_options = Ort::SessionOptions(); gpu_enabled = false; return true; @@ -51,8 +53,12 @@ bool asst::OnnxSessions::use_cpu() bool asst::OnnxSessions::use_gpu(int device_id) { - if (gpu_enabled) return true; - if (m_sessions.size() != 0) return false; + if (gpu_enabled) { + return true; + } + if (m_sessions.size() != 0) { + return false; + } auto all_providers = Ort::GetAvailableProviders(); bool support_cuda = false; bool support_dml = false; diff --git a/src/MaaCore/Config/OnnxSessions.h b/src/MaaCore/Config/OnnxSessions.h index e7d86ddbba..1d89d2deaa 100644 --- a/src/MaaCore/Config/OnnxSessions.h +++ b/src/MaaCore/Config/OnnxSessions.h @@ -14,21 +14,21 @@ namespace asst { - class OnnxSessions final : public SingletonHolder, public AbstractResource - { - public: - virtual ~OnnxSessions(); - virtual bool load(const std::filesystem::path& path) override; +class OnnxSessions final : public SingletonHolder, public AbstractResource +{ +public: + virtual ~OnnxSessions(); + virtual bool load(const std::filesystem::path& path) override; - Ort::Session& get(const std::string& name); - bool use_cpu(); - bool use_gpu(int device_id); + Ort::Session& get(const std::string& name); + bool use_cpu(); + bool use_gpu(int device_id); - private: - Ort::Env m_env; - Ort::SessionOptions m_options; - std::unordered_map m_sessions; - std::unordered_map m_model_paths; - bool gpu_enabled = false; - }; +private: + Ort::Env m_env; + Ort::SessionOptions m_options; + std::unordered_map m_sessions; + std::unordered_map m_model_paths; + bool gpu_enabled = false; +}; } diff --git a/src/MaaCore/Config/ResourceLoader.cpp b/src/MaaCore/Config/ResourceLoader.cpp index 589e43c618..7944826a33 100644 --- a/src/MaaCore/Config/ResourceLoader.cpp +++ b/src/MaaCore/Config/ResourceLoader.cpp @@ -20,8 +20,8 @@ #include "Roguelike/RoguelikeRecruitConfig.h" #include "Roguelike/RoguelikeShoppingConfig.h" #include "Roguelike/RoguelikeStageEncounterConfig.h" -#include "Roguelike/Sami/RoguelikeFoldartalConfig.h" #include "Roguelike/Sami/RoguelikeCollapsalParadigmConfig.h" +#include "Roguelike/Sami/RoguelikeFoldartalConfig.h" #include "TaskData.h" #include "TemplResource.h" #include "Utils/Logger.hpp" @@ -175,32 +175,16 @@ bool asst::ResourceLoader::load(const std::filesystem::path& path) LoadResourceAndCheckRet(RoguelikeCopilotConfig, "roguelike"_p / "Sarkaz"_p / "autopilot"_p); // –––––––– Roguelike Recruitment Config –––––––––––––––––––––––––––––––––––––––––– - LoadResourceAndCheckRet( - RoguelikeRecruitConfig, - "roguelike"_p / "Phantom"_p / "recruitment.json"_p); - LoadResourceAndCheckRet( - RoguelikeRecruitConfig, - "roguelike"_p / "Mizuki"_p / "recruitment.json"_p); - LoadResourceAndCheckRet( - RoguelikeRecruitConfig, - "roguelike"_p / "Sami"_p / "recruitment.json"_p); - LoadResourceAndCheckRet( - RoguelikeRecruitConfig, - "roguelike"_p / "Sarkaz"_p / "recruitment.json"_p); + LoadResourceAndCheckRet(RoguelikeRecruitConfig, "roguelike"_p / "Phantom"_p / "recruitment.json"_p); + LoadResourceAndCheckRet(RoguelikeRecruitConfig, "roguelike"_p / "Mizuki"_p / "recruitment.json"_p); + LoadResourceAndCheckRet(RoguelikeRecruitConfig, "roguelike"_p / "Sami"_p / "recruitment.json"_p); + LoadResourceAndCheckRet(RoguelikeRecruitConfig, "roguelike"_p / "Sarkaz"_p / "recruitment.json"_p); // –––––––– Roguelike Shopping Config ––––––––––––––––––––––––––––––––––––––––––––– - LoadResourceAndCheckRet( - RoguelikeShoppingConfig, - "roguelike"_p / "Phantom"_p / "shopping.json"_p); - LoadResourceAndCheckRet( - RoguelikeShoppingConfig, - "roguelike"_p / "Mizuki"_p / "shopping.json"_p); - LoadResourceAndCheckRet( - RoguelikeShoppingConfig, - "roguelike"_p / "Sami"_p / "shopping.json"_p); - LoadResourceAndCheckRet( - RoguelikeShoppingConfig, - "roguelike"_p / "Sarkaz"_p / "shopping.json"_p); + LoadResourceAndCheckRet(RoguelikeShoppingConfig, "roguelike"_p / "Phantom"_p / "shopping.json"_p); + LoadResourceAndCheckRet(RoguelikeShoppingConfig, "roguelike"_p / "Mizuki"_p / "shopping.json"_p); + LoadResourceAndCheckRet(RoguelikeShoppingConfig, "roguelike"_p / "Sami"_p / "shopping.json"_p); + LoadResourceAndCheckRet(RoguelikeShoppingConfig, "roguelike"_p / "Sarkaz"_p / "shopping.json"_p); // –––––––– Roguelike Encounter Config –––––––––––––––––––––––––––––––––––––––––––– LoadResourceAndCheckRet( @@ -209,9 +193,7 @@ bool asst::ResourceLoader::load(const std::filesystem::path& path) LoadResourceAndCheckRet( RoguelikeStageEncounterConfig, "roguelike"_p / "Mizuki"_p / "encounter"_p / "default.json"_p); - LoadResourceAndCheckRet( - RoguelikeStageEncounterConfig, - "roguelike"_p / "Sami"_p / "encounter"_p / "default.json"_p); + LoadResourceAndCheckRet(RoguelikeStageEncounterConfig, "roguelike"_p / "Sami"_p / "encounter"_p / "default.json"_p); LoadResourceAndCheckRet( RoguelikeStageEncounterConfig, "roguelike"_p / "Sarkaz"_p / "encounter"_p / "default.json"_p); @@ -221,9 +203,7 @@ bool asst::ResourceLoader::load(const std::filesystem::path& path) LoadResourceAndCheckRet( RoguelikeStageEncounterConfig, "roguelike"_p / "Mizuki"_p / "encounter"_p / "deposit.json"_p); - LoadResourceAndCheckRet( - RoguelikeStageEncounterConfig, - "roguelike"_p / "Sami"_p / "encounter"_p / "deposit.json"_p); + LoadResourceAndCheckRet(RoguelikeStageEncounterConfig, "roguelike"_p / "Sami"_p / "encounter"_p / "deposit.json"_p); LoadResourceAndCheckRet( RoguelikeStageEncounterConfig, "roguelike"_p / "Sarkaz"_p / "encounter"_p / "deposit.json"_p); @@ -232,17 +212,11 @@ bool asst::ResourceLoader::load(const std::filesystem::path& path) "roguelike"_p / "Sami"_p / "encounter"_p / "collapse.json"_p); // –––––––– Roguelike Map Config ––––––––––––––––––––––––––––––––––––––––––––------ - LoadResourceAndCheckRet( - RoguelikeMapConfig, - "roguelike"_p / "Sarkaz"_p / "map.json"_p); + LoadResourceAndCheckRet(RoguelikeMapConfig, "roguelike"_p / "Sarkaz"_p / "map.json"_p); // –––––––– Sami Plugin Config –––––––––––––––––––––––––––––––––––––––––––––––––––– - LoadResourceAndCheckRet( - RoguelikeFoldartalConfig, - "roguelike"_p / "Sami"_p / "foldartal.json"_p); - LoadResourceAndCheckRet( - RoguelikeCollapsalParadigmConfig, - "roguelike"_p / "Sami"_p / "collapsal_paradigms.json"_p); + LoadResourceAndCheckRet(RoguelikeFoldartalConfig, "roguelike"_p / "Sami"_p / "foldartal.json"_p); + LoadResourceAndCheckRet(RoguelikeCollapsalParadigmConfig, "roguelike"_p / "Sami"_p / "collapsal_paradigms.json"_p); #undef LoadTemplByConfigAndCheckRet #undef LoadResourceAndCheckRet diff --git a/src/MaaCore/Config/ResourceLoader.h b/src/MaaCore/Config/ResourceLoader.h index 63597dee25..be0e489442 100644 --- a/src/MaaCore/Config/ResourceLoader.h +++ b/src/MaaCore/Config/ResourceLoader.h @@ -12,9 +12,7 @@ namespace asst { -class ResourceLoader final - : public SingletonHolder - , public AbstractResource +class ResourceLoader final : public SingletonHolder, public AbstractResource { public: virtual ~ResourceLoader() override; @@ -44,9 +42,7 @@ private: template requires std::is_base_of_v - bool load_resource_with_templ( - const std::filesystem::path& path, - const std::filesystem::path& templ_dir) + bool load_resource_with_templ(const std::filesystem::path& path, const std::filesystem::path& templ_dir) { if (!load_resource(path)) { return false; diff --git a/src/MaaCore/Config/Roguelike/RoguelikeCopilotConfig.cpp b/src/MaaCore/Config/Roguelike/RoguelikeCopilotConfig.cpp index b7e067bdb3..c0730c1d63 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeCopilotConfig.cpp +++ b/src/MaaCore/Config/Roguelike/RoguelikeCopilotConfig.cpp @@ -23,8 +23,7 @@ bool asst::RoguelikeCopilotConfig::load(const std::filesystem::path& path) return ret; } -std::optional - asst::RoguelikeCopilotConfig::get_stage_data(const std::string& stage_name) const +std::optional asst::RoguelikeCopilotConfig::get_stage_data(const std::string& stage_name) const { auto it = m_stage_data.find(stage_name); if (it == m_stage_data.end()) { @@ -61,11 +60,9 @@ bool asst::RoguelikeCopilotConfig::parse(const json::value& json) if (auto opt = json.find("replacement_home")) { for (auto& point : opt.value()) { ReplacementHome home; - home.location = - Point(point["location"][0].as_integer(), point["location"][1].as_integer()); + home.location = Point(point["location"][0].as_integer(), point["location"][1].as_integer()); const std::string& direction_str = point.get("direction", "none"); - if (auto iter = DeployDirectionMapping.find(direction_str); - iter != DeployDirectionMapping.end()) { + if (auto iter = DeployDirectionMapping.find(direction_str); iter != DeployDirectionMapping.end()) { home.direction = iter->second; } else { @@ -107,16 +104,15 @@ bool asst::RoguelikeCopilotConfig::parse(const json::value& json) std::unordered_set specified_role; std::vector role_order; bool is_legal = true; - if (ranges::find_if_not(raw_roles | views::all, std::mem_fn(&json::value::is_string)) - != raw_roles.end()) { + if (ranges::find_if_not(raw_roles | views::all, std::mem_fn(&json::value::is_string)) != raw_roles.end()) { Log.error("Role should be string"); return false; } - auto roles = raw_roles | filter(&json::value::is_string) - | transform(&json::value::as_string) | transform([&](std::string name) { - utils::tolowers(name); - return name; - }); + auto roles = raw_roles | filter(&json::value::is_string) | transform(&json::value::as_string) | + transform([&](std::string name) { + utils::tolowers(name); + return name; + }); for (const std::string& role_name : roles) { const auto role = get_role_type(role_name); if (role == Role::Unknown) [[unlikely]] { @@ -154,11 +150,9 @@ bool asst::RoguelikeCopilotConfig::parse(const json::value& json) if (auto opt = json.find("force_deploy_direction")) { for (auto& point : opt.value()) { ForceDeployDirection fd_dir; - Point location = - Point(point["location"][0].as_integer(), point["location"][1].as_integer()); + Point location = Point(point["location"][0].as_integer(), point["location"][1].as_integer()); const std::string& direction_str = point.get("direction", "none"); - if (auto iter = DeployDirectionMapping.find(direction_str); - iter != DeployDirectionMapping.end()) { + if (auto iter = DeployDirectionMapping.find(direction_str); iter != DeployDirectionMapping.end()) { fd_dir.direction = iter->second; } else { @@ -186,12 +180,9 @@ bool asst::RoguelikeCopilotConfig::parse(const json::value& json) int rank = 1; for (auto& deploy_info : opt.value()) { DeployInfoWithRank info; - info.location = Point( - deploy_info["location"][0].as_integer(), - deploy_info["location"][1].as_integer()); + info.location = Point(deploy_info["location"][0].as_integer(), deploy_info["location"][1].as_integer()); const std::string& direction_str = deploy_info.get("direction", "none"); - if (auto iter = DeployDirectionMapping.find(direction_str); - iter != DeployDirectionMapping.end()) { + if (auto iter = DeployDirectionMapping.find(direction_str); iter != DeployDirectionMapping.end()) { info.direction = iter->second; } if (auto condition = deploy_info.find("condition")) { @@ -216,9 +207,7 @@ bool asst::RoguelikeCopilotConfig::parse(const json::value& json) if (auto opt = json.find("retreat_plan")) { for (auto& retreat_info : opt.value()) { DeployInfoWithRank info; - info.location = Point( - retreat_info["location"][0].as_integer(), - retreat_info["location"][1].as_integer()); + info.location = Point(retreat_info["location"][0].as_integer(), retreat_info["location"][1].as_integer()); if (auto condition = retreat_info.find("condition")) { info.kill_lower_bound = condition.value()[0].as_integer(); info.kill_upper_bound = condition.value()[1].as_integer(); diff --git a/src/MaaCore/Config/Roguelike/RoguelikeCopilotConfig.h b/src/MaaCore/Config/Roguelike/RoguelikeCopilotConfig.h index 8f3b8fbd12..969c720860 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeCopilotConfig.h +++ b/src/MaaCore/Config/Roguelike/RoguelikeCopilotConfig.h @@ -7,19 +7,19 @@ namespace asst { - class RoguelikeCopilotConfig final : public SingletonHolder, public AbstractConfig - { - public: - virtual ~RoguelikeCopilotConfig() override = default; +class RoguelikeCopilotConfig final : public SingletonHolder, public AbstractConfig +{ +public: + virtual ~RoguelikeCopilotConfig() override = default; - virtual bool load(const std::filesystem::path& path) override; + virtual bool load(const std::filesystem::path& path) override; - std::optional get_stage_data(const std::string& stage_name) const; + std::optional get_stage_data(const std::string& stage_name) const; - protected: - virtual bool parse(const json::value& json) override; - std::unordered_map m_stage_data; - }; +protected: + virtual bool parse(const json::value& json) override; + std::unordered_map m_stage_data; +}; - inline static auto& RoguelikeCopilot = RoguelikeCopilotConfig::get_instance(); +inline static auto& RoguelikeCopilot = RoguelikeCopilotConfig::get_instance(); } diff --git a/src/MaaCore/Config/Roguelike/RoguelikeRecruitConfig.cpp b/src/MaaCore/Config/Roguelike/RoguelikeRecruitConfig.cpp index aeaa764150..30bbd3fe5c 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeRecruitConfig.cpp +++ b/src/MaaCore/Config/Roguelike/RoguelikeRecruitConfig.cpp @@ -194,7 +194,7 @@ bool asst::RoguelikeRecruitConfig::parse(const json::value& json) } for (auto& offset : oper_info.recruit_priority_offsets) { // 干员的所有 offset 策略组 for (auto& group : offset.groups) { // 策略组内的每个干员组 - offset.opers.insert( // 向当前策略组计入这个干员组的无重复干员 + offset.opers.insert( // 向当前策略组计入这个干员组的无重复干员 get_group_info(theme, group).opers.begin(), get_group_info(theme, group).opers.end()); } diff --git a/src/MaaCore/Config/Roguelike/RoguelikeRecruitConfig.h b/src/MaaCore/Config/Roguelike/RoguelikeRecruitConfig.h index 06cdac4f75..75e353aec8 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeRecruitConfig.h +++ b/src/MaaCore/Config/Roguelike/RoguelikeRecruitConfig.h @@ -16,9 +16,9 @@ struct RecruitPriorityOffset { std::vector groups; // 造成优先级改变的所有干员组 std::unordered_set opers; // 所有干员组的所有无重复干员 - int threshold = 0; // 已拥有组内干员数量阈值,达到此阈值时应用优先级改变 - bool is_less = false; // 高于阈值时改变还是低于阈值时改变 - int offset = 0; // 优先级改变的大小 + int threshold = 0; // 已拥有组内干员数量阈值,达到此阈值时应用优先级改变 + bool is_less = false; // 高于阈值时改变还是低于阈值时改变 + int offset = 0; // 优先级改变的大小 }; // 收藏品 priority 影响因子 @@ -31,13 +31,13 @@ struct CollectionPriorityOffset // 干员信息,战斗相关 struct RoguelikeOperInfo { - std::string name; // 干员名 - std::vector group_id = {}; // 干员组 id,允许一个干员存在于多个干员组 - std::unordered_map order_in_group; // 干员在干员组内的顺序 干员组 id:干员组内顺序 - int recruit_priority = 0; // 招募优先级 (0-1000) - int promote_priority = 0; // 晋升优先级 (0-1000) - int recruit_priority_when_team_full = 0; // 队伍满时的招募优先级 (0-1000) - int promote_priority_when_team_full = 0; // 队伍满时的晋升优先级 (0-1000) + std::string name; // 干员名 + std::vector group_id = {}; // 干员组 id,允许一个干员存在于多个干员组 + std::unordered_map order_in_group; // 干员在干员组内的顺序 干员组 id:干员组内顺序 + int recruit_priority = 0; // 招募优先级 (0-1000) + int promote_priority = 0; // 晋升优先级 (0-1000) + int recruit_priority_when_team_full = 0; // 队伍满时的招募优先级 (0-1000) + int promote_priority_when_team_full = 0; // 队伍满时的晋升优先级 (0-1000) std::vector> recruit_priority_offset; // [deprecated] bool offset_melee = false; // [deprecated] bool is_key = false; // 是否为核心干员 @@ -46,7 +46,7 @@ struct RoguelikeOperInfo std::vector collection_priority_offsets; // 收藏品 priority 影响因子 bool is_alternate = false; // 是否后备干员 (允许重复招募、划到后备干员时不再往右划动) int skill = 0; // 使用几技能 - int alternate_skill = 0; // 当没有指定技能时使用的备选技能,一般是6星干员未精二且精二后使用3技能时才需要指定 + int alternate_skill = 0; // 当没有指定技能时使用的备选技能,一般是6星干员未精二且精二后使用3技能时才需要指定 battle::SkillUsage skill_usage = battle::SkillUsage::Possibly; // 技能使用模式 int skill_times = 1; // 技能使用次数 battle::SkillUsage alternate_skill_usage = battle::SkillUsage::Possibly; // 备选技能使用模式 @@ -79,7 +79,7 @@ public: const noexcept; // 获取该肉鸽内用到的干员组[干员组1,干员组2, ...], renamed from "get_group_info" int get_group_id_from_name( const std::string& theme, - const std::string& group_name) noexcept; // 用干员组名获取干员组 id + const std::string& group_name) noexcept; // 用干员组名获取干员组 id const std::string get_group_name_from_id(const std::string& theme, const int group_id) const noexcept; // 用干员组 id 获取干员组名 diff --git a/src/MaaCore/Config/Roguelike/RoguelikeShoppingConfig.h b/src/MaaCore/Config/Roguelike/RoguelikeShoppingConfig.h index bbb9885889..b96964b188 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeShoppingConfig.h +++ b/src/MaaCore/Config/Roguelike/RoguelikeShoppingConfig.h @@ -8,31 +8,31 @@ namespace asst { - struct RoguelikeGoods - { - std::string name; - std::vector roles; - std::vector chars; - int promotion = 0; // 晋升 N 个干员 - bool no_longer_buy = false; - bool ignore_no_longer_buy = false; - bool decrease_collapse = false; - }; +struct RoguelikeGoods +{ + std::string name; + std::vector roles; + std::vector chars; + int promotion = 0; // 晋升 N 个干员 + bool no_longer_buy = false; + bool ignore_no_longer_buy = false; + bool decrease_collapse = false; +}; - class RoguelikeShoppingConfig final : public SingletonHolder, public AbstractConfig - { - public: - virtual ~RoguelikeShoppingConfig() override = default; +class RoguelikeShoppingConfig final : public SingletonHolder, public AbstractConfig +{ +public: + virtual ~RoguelikeShoppingConfig() override = default; - const auto& get_goods(const std::string& theme) const noexcept { return m_goods.at(theme); } + const auto& get_goods(const std::string& theme) const noexcept { return m_goods.at(theme); } - private: - virtual bool parse(const json::value& json) override; +private: + virtual bool parse(const json::value& json) override; - void clear(); + void clear(); - std::unordered_map> m_goods; - }; + std::unordered_map> m_goods; +}; - inline static auto& RoguelikeShopping = RoguelikeShoppingConfig::get_instance(); +inline static auto& RoguelikeShopping = RoguelikeShoppingConfig::get_instance(); } diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp index 0cb6a036d4..8ad47f297b 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.cpp @@ -9,17 +9,18 @@ bool asst::RoguelikeStageEncounterConfig::parse(const json::value& json) LogTraceFunction; const std::string theme = json.at("theme").as_string(); - + // m_event[(肉鸽主题,模式)] 默认继承 m_event["(肉鸽主题,std::nullopt)"] std::pair key = std::make_pair(theme, -1); - std::vector modes = json.get("mode", std::vector{}); + std::vector modes = json.get("mode", std::vector {}); std::unordered_map events; if (!modes.empty()) { events = m_events.at(key); - } else { + } + else { modes.emplace_back(-1); } - + std::vector& event_names = m_event_names[theme]; for (const auto& event_json : json.at("stage").as_array()) { @@ -42,8 +43,7 @@ bool asst::RoguelikeStageEncounterConfig::parse(const json::value& json) auto name = requirement_json.get("name", ""); if (name == "Vision") { choice.vision.value = requirement_json.get("value", ""); - choice.vision.type = - parse_comparison_type(requirement_json.get("type", "")); + choice.vision.type = parse_comparison_type(requirement_json.get("type", "")); } else if (name == "Relic") { // not supported diff --git a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h index 6c389bd2f4..1659d3c8cd 100644 --- a/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h +++ b/src/MaaCore/Config/Roguelike/RoguelikeStageEncounterConfig.h @@ -9,81 +9,85 @@ namespace asst { - // steal from https://www.boost.org/doc/libs/1_85_0/libs/container_hash/doc/html/hash.html#notes_hash_combine - // use boost if you prefer - template - struct PairHash { - std::size_t operator()(const std::pair& p) const { - std::size_t hash1 = std::hash{}(p.first); - std::size_t hash2 = std::hash{}(p.second); - hash1 ^= hash2 + 0x9e3779b9 + (hash1 << 6) + (hash1 >> 2); - - hash1 ^= hash1 >> 32; - hash1 *= 0xe9846af9b1a615d; - hash1 ^= hash1 >> 32; - hash1 *= 0xe9846af9b1a615d; - hash1 ^= hash1 >> 28; - - return hash1; - } - }; - - class RoguelikeStageEncounterConfig final : public SingletonHolder, - public AbstractConfig +// steal from https://www.boost.org/doc/libs/1_85_0/libs/container_hash/doc/html/hash.html#notes_hash_combine +// use boost if you prefer +template +struct PairHash +{ + std::size_t operator()(const std::pair& p) const { - public: - virtual ~RoguelikeStageEncounterConfig() override = default; + std::size_t hash1 = std::hash {}(p.first); + std::size_t hash2 = std::hash {}(p.second); + hash1 ^= hash2 + 0x9e3779b9 + (hash1 << 6) + (hash1 >> 2); - const auto& get_events(const std::string& theme, const RoguelikeMode& mode) const noexcept { - std::pair key = std::make_pair(theme, static_cast(mode)); - if (!m_events.contains(key)) { - key.second = -1; - } - return m_events.at(key); - } - - const auto& get_event_names(const std::string& theme) const noexcept { - return m_event_names.at(theme); + hash1 ^= hash1 >> 32; + hash1 *= 0xe9846af9b1a615d; + hash1 ^= hash1 >> 32; + hash1 *= 0xe9846af9b1a615d; + hash1 ^= hash1 >> 28; + + return hash1; + } +}; + +class RoguelikeStageEncounterConfig final : public SingletonHolder, public AbstractConfig +{ +public: + virtual ~RoguelikeStageEncounterConfig() override = default; + + const auto& get_events(const std::string& theme, const RoguelikeMode& mode) const noexcept + { + std::pair key = std::make_pair(theme, static_cast(mode)); + if (!m_events.contains(key)) { + key.second = -1; } + return m_events.at(key); + } - enum class ComparisonType - { - GreaterThan, - LessThan, - Equal, - None, // 没有配置 - Unsupported, // 配置错误或其他 - }; + const auto& get_event_names(const std::string& theme) const noexcept { return m_event_names.at(theme); } - struct Vision - { - std::string value; - ComparisonType type = ComparisonType::None; - }; - struct ChoiceRequire - { - std::string name; - int choose = -1; - Vision vision; // 现在只有Vision解析,之后要改成requirements且支持多个条件判断同一个选择 - }; - struct RoguelikeEvent - { - std::string name; - int option_num = 0; - int default_choose = 0; - std::vector choice_require; - }; - - private: - virtual bool parse(const json::value& json) override; - - static ComparisonType parse_comparison_type(const std::string& type_str); - - std::unordered_map, - std::unordered_map, - PairHash> m_events; - std::unordered_map> m_event_names; + enum class ComparisonType + { + GreaterThan, + LessThan, + Equal, + None, // 没有配置 + Unsupported, // 配置错误或其他 }; - inline static auto& RoguelikeStageEncounter = RoguelikeStageEncounterConfig::get_instance(); + struct Vision + { + std::string value; + ComparisonType type = ComparisonType::None; + }; + + struct ChoiceRequire + { + std::string name; + int choose = -1; + Vision vision; // 现在只有Vision解析,之后要改成requirements且支持多个条件判断同一个选择 + }; + + struct RoguelikeEvent + { + std::string name; + int option_num = 0; + int default_choose = 0; + std::vector choice_require; + }; + +private: + virtual bool parse(const json::value& json) override; + + static ComparisonType parse_comparison_type(const std::string& type_str); + + std::unordered_map< + std::pair, + std::unordered_map, + PairHash> + m_events; + std::unordered_map> m_event_names; +}; + +inline static auto& RoguelikeStageEncounter = RoguelikeStageEncounterConfig::get_instance(); } diff --git a/src/MaaCore/Config/Roguelike/Sami/RoguelikeCollapsalParadigmConfig.h b/src/MaaCore/Config/Roguelike/Sami/RoguelikeCollapsalParadigmConfig.h index 14ca0a1d41..259d223497 100644 --- a/src/MaaCore/Config/Roguelike/Sami/RoguelikeCollapsalParadigmConfig.h +++ b/src/MaaCore/Config/Roguelike/Sami/RoguelikeCollapsalParadigmConfig.h @@ -8,41 +8,46 @@ namespace asst { - // 坍缩范式 - struct CollapsalParadigmClass - { - std::string level_1; // 一级范式 - std::string level_2; // 二级范式 - std::string rarity; // 稀有度 - }; +// 坍缩范式 +struct CollapsalParadigmClass +{ + std::string level_1; // 一级范式 + std::string level_2; // 二级范式 + std::string rarity; // 稀有度 +}; - class RoguelikeCollapsalParadigmConfig final : public SingletonHolder, public AbstractConfig - { - public: - virtual ~RoguelikeCollapsalParadigmConfig() override = default; +class RoguelikeCollapsalParadigmConfig final : + public SingletonHolder, + public AbstractConfig +{ +public: + virtual ~RoguelikeCollapsalParadigmConfig() override = default; - const auto& get_clp_pd_classes(const std::string& theme) const noexcept { return m_clp_pd_classes.at(theme); } - const auto& get_clp_pd_dict(const std::string& theme) const noexcept { return m_clp_pd_dict.at(theme); } - const auto& get_rare_clp_pds(const std::string& theme) const noexcept { - auto it = m_rare_clp_pds.find(theme); - if (it == m_rare_clp_pds.end()) { - static const std::unordered_set empty_set; - return empty_set; - } - else { - return it->second; - } + const auto& get_clp_pd_classes(const std::string& theme) const noexcept { return m_clp_pd_classes.at(theme); } + + const auto& get_clp_pd_dict(const std::string& theme) const noexcept { return m_clp_pd_dict.at(theme); } + + const auto& get_rare_clp_pds(const std::string& theme) const noexcept + { + auto it = m_rare_clp_pds.find(theme); + if (it == m_rare_clp_pds.end()) { + static const std::unordered_set empty_set; + return empty_set; } - - private: - virtual bool parse(const json::value& json) override; - - void clear(); + else { + return it->second; + } + } - std::unordered_map> m_clp_pd_classes; - std::unordered_map> m_clp_pd_dict; - std::unordered_map> m_rare_clp_pds; - }; +private: + virtual bool parse(const json::value& json) override; - inline static auto& RoguelikeCollapsalParadigms = RoguelikeCollapsalParadigmConfig::get_instance(); + void clear(); + + std::unordered_map> m_clp_pd_classes; + std::unordered_map> m_clp_pd_dict; + std::unordered_map> m_rare_clp_pds; +}; + +inline static auto& RoguelikeCollapsalParadigms = RoguelikeCollapsalParadigmConfig::get_instance(); } diff --git a/src/MaaCore/Config/Roguelike/Sami/RoguelikeFoldartalConfig.cpp b/src/MaaCore/Config/Roguelike/Sami/RoguelikeFoldartalConfig.cpp index cae9d0f6c2..f7dfc8683c 100644 --- a/src/MaaCore/Config/Roguelike/Sami/RoguelikeFoldartalConfig.cpp +++ b/src/MaaCore/Config/Roguelike/Sami/RoguelikeFoldartalConfig.cpp @@ -12,7 +12,6 @@ bool asst::RoguelikeFoldartalConfig::parse(const json::value& json) m_foldartal_combination.erase(theme); for (const auto& combination_json : json.at("groups").as_array()) { - RoguelikeFoldartalCombination combination; combination.usage = combination_json.get("usage", "none"); diff --git a/src/MaaCore/Config/Roguelike/Sami/RoguelikeFoldartalConfig.h b/src/MaaCore/Config/Roguelike/Sami/RoguelikeFoldartalConfig.h index 0bee73a4b4..161cfb6cdd 100644 --- a/src/MaaCore/Config/Roguelike/Sami/RoguelikeFoldartalConfig.h +++ b/src/MaaCore/Config/Roguelike/Sami/RoguelikeFoldartalConfig.h @@ -8,33 +8,31 @@ namespace asst { - // 板子组合 - struct FoldartalPair - { - std::vector up_board; // 上板子 - std::vector down_board; // 下板子 - }; - struct RoguelikeFoldartalCombination - { - std::string usage; // 适用的节点类型和用法 - std::vector pairs; // 适用的板子组合 - }; +// 板子组合 +struct FoldartalPair +{ + std::vector up_board; // 上板子 + std::vector down_board; // 下板子 +}; - class RoguelikeFoldartalConfig final : public SingletonHolder, public AbstractConfig - { - public: - virtual ~RoguelikeFoldartalConfig() override = default; +struct RoguelikeFoldartalCombination +{ + std::string usage; // 适用的节点类型和用法 + std::vector pairs; // 适用的板子组合 +}; - const auto& get_combination(const std::string& theme) const noexcept - { - return m_foldartal_combination.at(theme); - } +class RoguelikeFoldartalConfig final : public SingletonHolder, public AbstractConfig +{ +public: + virtual ~RoguelikeFoldartalConfig() override = default; - private: - virtual bool parse(const json::value& json) override; + const auto& get_combination(const std::string& theme) const noexcept { return m_foldartal_combination.at(theme); } - std::unordered_map> m_foldartal_combination; - }; +private: + virtual bool parse(const json::value& json) override; - inline static auto& RoguelikeFoldartal = RoguelikeFoldartalConfig::get_instance(); + std::unordered_map> m_foldartal_combination; +}; + +inline static auto& RoguelikeFoldartal = RoguelikeFoldartalConfig::get_instance(); } diff --git a/src/MaaCore/Config/TaskData.cpp b/src/MaaCore/Config/TaskData.cpp index d3a16a073c..de176f6a8f 100644 --- a/src/MaaCore/Config/TaskData.cpp +++ b/src/MaaCore/Config/TaskData.cpp @@ -21,6 +21,7 @@ const std::unordered_set& asst::TaskData::get_templ_required() cons { return m_templ_required; } + asst::TaskDerivedConstPtr asst::TaskData::get_raw(std::string_view name) { if (!generate_raw_task_and_base(name, true)) [[unlikely]] { @@ -127,40 +128,42 @@ bool asst::TaskData::lazy_parse(const json::value& json) validity = false; continue; } - auto check_tasklist = [&](const TaskList& task_list, std::string_view list_type, - bool enable_justreturn_check = false) { - std::unordered_set tasks_set {}; - std::string justreturn_task_name = ""; - for (const std::string& task_name : task_list) { - if (tasks_set.contains(task_name)) [[unlikely]] { - continue; - } - // 检查是否有 JustReturn 任务不是最后一个任务 - if (enable_justreturn_check && !justreturn_task_name.empty()) [[unlikely]] { - Log.error((std::string(name) += "->") += list_type, - "has a not-final JustReturn task:", justreturn_task_name); - justreturn_task_name = ""; - validity = false; + auto check_tasklist = + [&](const TaskList& task_list, std::string_view list_type, bool enable_justreturn_check = false) { + std::unordered_set tasks_set {}; + std::string justreturn_task_name = ""; + for (const std::string& task_name : task_list) { + if (tasks_set.contains(task_name)) [[unlikely]] { + continue; + } + // 检查是否有 JustReturn 任务不是最后一个任务 + if (enable_justreturn_check && !justreturn_task_name.empty()) [[unlikely]] { + Log.error( + (std::string(name) += "->") += list_type, + "has a not-final JustReturn task:", + justreturn_task_name); + justreturn_task_name = ""; + validity = false; + } + + if (auto ptr = get(task_name); ptr == nullptr) [[unlikely]] { + Log.error(task_name, "in", (std::string(name) += "->") += list_type, "is null"); + validity = false; + continue; + } + else if (ptr->algorithm == AlgorithmType::JustReturn) { + justreturn_task_name = ptr->name; + } + + if (!checking_task_set.contains(task_name)) { + task_queue.emplace(task_name_view(task_name)); + checking_task_set.emplace(task_name_view(task_name)); + } + tasks_set.emplace(task_name_view(task_name)); } - if (auto ptr = get(task_name); ptr == nullptr) [[unlikely]] { - Log.error(task_name, "in", (std::string(name) += "->") += list_type, "is null"); - validity = false; - continue; - } - else if (ptr->algorithm == AlgorithmType::JustReturn) { - justreturn_task_name = ptr->name; - } - - if (!checking_task_set.contains(task_name)) { - task_queue.emplace(task_name_view(task_name)); - checking_task_set.emplace(task_name_view(task_name)); - } - tasks_set.emplace(task_name_view(task_name)); - } - - return true; - }; + return true; + }; bool enable_justreturn_check = true; if (name.ends_with("LoadingText") || name.ends_with("LoadingIcon")) { // 放宽对 Loading 类任务的限制,不然 JustReturn 的任务如果本身有 JR 的 next,就不能 @Loading 了 @@ -191,7 +194,9 @@ bool asst::TaskData::lazy_parse(const json::value& json) Log.trace(checking_task_set.size(), "tasks checked."); } clear_tasks(); - if (!validity) return false; + if (!validity) { + return false; + } } #endif @@ -202,7 +207,9 @@ bool asst::TaskData::parse(const json::value& json) { LogTraceFunction; - if (!lazy_parse(json)) return false; + if (!lazy_parse(json)) { + return false; + } // 本来重构之后完全支持惰性加载,但是发现模板图片不支持( for (std::string_view name : m_json_all_tasks_info | views::keys) { @@ -229,8 +236,12 @@ void asst::TaskData::set_task_base(const std::string_view task_name, std::string clear_tasks(); } -bool asst::TaskData::generate_raw_task_info(std::string_view name, std::string_view prefix, std::string_view base, - const json::value& json, TaskDerivedType type) +bool asst::TaskData::generate_raw_task_info( + std::string_view name, + std::string_view prefix, + std::string_view base, + const json::value& json, + TaskDerivedType type) { TaskPipelineConstPtr base_task = base.empty() ? nullptr : get_raw(base); if (base_task == nullptr) { @@ -243,16 +254,21 @@ bool asst::TaskData::generate_raw_task_info(std::string_view name, std::string_v task->type = type; task->base = base; task->prefix = prefix; - utils::get_and_check_value_or(name, json, "next", task->next, - [&]() { return append_prefix(base_task->next, prefix); }); - utils::get_and_check_value_or(name, json, "sub", task->sub, - [&]() { return append_prefix(base_task->sub, prefix); }); - utils::get_and_check_value_or(name, json, "exceededNext", task->exceeded_next, - [&]() { return append_prefix(base_task->exceeded_next, prefix); }); - utils::get_and_check_value_or(name, json, "onErrorNext", task->on_error_next, - [&]() { return append_prefix(base_task->on_error_next, prefix); }); - utils::get_and_check_value_or(name, json, "reduceOtherTimes", task->reduce_other_times, - [&]() { return append_prefix(base_task->reduce_other_times, prefix); }); + utils::get_and_check_value_or(name, json, "next", task->next, [&]() { + return append_prefix(base_task->next, prefix); + }); + utils::get_and_check_value_or(name, json, "sub", task->sub, [&]() { + return append_prefix(base_task->sub, prefix); + }); + utils::get_and_check_value_or(name, json, "exceededNext", task->exceeded_next, [&]() { + return append_prefix(base_task->exceeded_next, prefix); + }); + utils::get_and_check_value_or(name, json, "onErrorNext", task->on_error_next, [&]() { + return append_prefix(base_task->on_error_next, prefix); + }); + utils::get_and_check_value_or(name, json, "reduceOtherTimes", task->reduce_other_times, [&]() { + return append_prefix(base_task->reduce_other_times, prefix); + }); m_task_status[task_name_view(name)] = NotToBeGenerate; // 保存虚任务未展开的任务 @@ -431,8 +447,8 @@ asst::TaskPtr asst::TaskData::generate_task_info(std::string_view name) && algorithm != asst::AlgorithmType::JustReturn // 非 JustReturn && !task->next.empty() // 有 next && (algorithm != asst::AlgorithmType::MatchTemplate // template 不是 empty - || std::dynamic_pointer_cast(task)->templ_names - != std::vector { "empty.png" })) { + || std::dynamic_pointer_cast(task)->templ_names != + std::vector { "empty.png" })) { // 符合上述条件时,我们认为此时的隐式全屏 roi 不是期望行为,给个警告 Log.warn("Task", name, "has implicit fullscreen roi."); } @@ -448,8 +464,11 @@ asst::TaskPtr asst::TaskData::generate_task_info(std::string_view name) return task; } -asst::TaskPtr asst::TaskData::generate_match_task_info(std::string_view name, const json::value& task_json, - MatchTaskConstPtr default_ptr, TaskDerivedType derived_type) +asst::TaskPtr asst::TaskData::generate_match_task_info( + std::string_view name, + const json::value& task_json, + MatchTaskConstPtr default_ptr, + TaskDerivedType derived_type) { if (default_ptr == nullptr) { default_ptr = default_match_task_info_ptr; @@ -470,17 +489,20 @@ asst::TaskPtr asst::TaskData::generate_match_task_info(std::string_view name, co auto threshold_opt = task_json.find("templThreshold"); if (!threshold_opt) { match_task_info_ptr->templ_thresholds = default_ptr->templ_thresholds; - match_task_info_ptr->templ_thresholds.resize(match_task_info_ptr->templ_names.size(), - default_ptr->templ_thresholds.back()); + match_task_info_ptr->templ_thresholds.resize( + match_task_info_ptr->templ_names.size(), + default_ptr->templ_thresholds.back()); } else if (threshold_opt->is_number()) { // 单个数值时,所有模板都使用这个阈值 - match_task_info_ptr->templ_thresholds.resize(match_task_info_ptr->templ_names.size(), - threshold_opt->as_double()); + match_task_info_ptr->templ_thresholds.resize( + match_task_info_ptr->templ_names.size(), + threshold_opt->as_double()); } else if (threshold_opt->is_array()) { - ranges::copy(threshold_opt->as_array() | views::transform(&json::value::as_double), - std::back_inserter(match_task_info_ptr->templ_thresholds)); + ranges::copy( + threshold_opt->as_array() | views::transform(&json::value::as_double), + std::back_inserter(match_task_info_ptr->templ_thresholds)); } else { Log.error("Invalid templThreshold type in task", name); @@ -500,19 +522,18 @@ asst::TaskPtr asst::TaskData::generate_match_task_info(std::string_view name, co auto method_opt = task_json.find("method"); if (!method_opt) { match_task_info_ptr->methods = default_ptr->methods; - match_task_info_ptr->methods.resize(match_task_info_ptr->templ_names.size(), - default_ptr->methods.back()); + match_task_info_ptr->methods.resize(match_task_info_ptr->templ_names.size(), default_ptr->methods.back()); } else if (method_opt->is_string()) { // 单个数值时,所有模板都使用这个阈值 - match_task_info_ptr->methods.resize(match_task_info_ptr->templ_names.size(), - get_match_method(method_opt->as_string())); + match_task_info_ptr->methods.resize( + match_task_info_ptr->templ_names.size(), + get_match_method(method_opt->as_string())); } else if (method_opt->is_array()) { - ranges::copy(method_opt->as_array() | - views::transform(&json::value::as_string) | - views::transform(&get_match_method), - std::back_inserter(match_task_info_ptr->methods)); + ranges::copy( + method_opt->as_array() | views::transform(&json::value::as_string) | views::transform(&get_match_method), + std::back_inserter(match_task_info_ptr->methods)); } else { Log.error("Invalid method type in task", name); @@ -580,7 +601,10 @@ asst::TaskPtr asst::TaskData::generate_match_task_info(std::string_view name, co } const auto& color_range = color_array_item.as_array(); if (color_range.size() != 2) { // lower & upper, 2 elements - Log.error("Invalid color_range in task", name, ", should have 2 elements (lower & upper) in each array"); + Log.error( + "Invalid color_range in task", + name, + ", should have 2 elements (lower & upper) in each array"); return nullptr; } @@ -639,8 +663,10 @@ asst::TaskPtr asst::TaskData::generate_match_task_info(std::string_view name, co return match_task_info_ptr; } -asst::TaskPtr asst::TaskData::generate_ocr_task_info(std::string_view name, const json::value& task_json, - OcrTaskConstPtr default_ptr) +asst::TaskPtr asst::TaskData::generate_ocr_task_info( + std::string_view name, + const json::value& task_json, + OcrTaskConstPtr default_ptr) { if (default_ptr == nullptr) { default_ptr = default_ocr_task_info_ptr; @@ -657,14 +683,31 @@ asst::TaskPtr asst::TaskData::generate_ocr_task_info(std::string_view name, cons #endif utils::get_and_check_value_or(name, task_json, "fullMatch", ocr_task_info_ptr->full_match, default_ptr->full_match); utils::get_and_check_value_or(name, task_json, "isAscii", ocr_task_info_ptr->is_ascii, default_ptr->is_ascii); - utils::get_and_check_value_or(name, task_json, "withoutDet", ocr_task_info_ptr->without_det, default_ptr->without_det); - utils::get_and_check_value_or(name, task_json, "replaceFull", ocr_task_info_ptr->replace_full, default_ptr->replace_full); - utils::get_and_check_value_or(name, task_json, "ocrReplace", ocr_task_info_ptr->replace_map, default_ptr->replace_map); + utils::get_and_check_value_or( + name, + task_json, + "withoutDet", + ocr_task_info_ptr->without_det, + default_ptr->without_det); + utils::get_and_check_value_or( + name, + task_json, + "replaceFull", + ocr_task_info_ptr->replace_full, + default_ptr->replace_full); + utils::get_and_check_value_or( + name, + task_json, + "ocrReplace", + ocr_task_info_ptr->replace_map, + default_ptr->replace_map); return ocr_task_info_ptr; } asst::ResultOrError asst::TaskData::compile_raw_tasklist( - const TaskList& raw_tasks, std::string_view self_name, std::function get_raw, + const TaskList& raw_tasks, + std::string_view self_name, + std::function get_raw, bool allow_duplicate) { RawCompileResult ret { .task_changed = false, .symbols = {} }; @@ -687,7 +730,10 @@ asst::ResultOrError asst::TaskData::compile_ra auto opt = symbol_stream.decode( [&](const TaskDataSymbol& symbol, const TaskDataSymbol& prefix) -> TaskDataSymbol::SymbolsOrError { return TaskDataSymbol::append_prefix( - symbol, prefix, self_name, get_raw, + symbol, + prefix, + self_name, + get_raw, [&](const TaskList& raw_or_empty) -> TaskDataSymbol::SymbolsOrError { if (auto opt = compile_raw_tasklist(raw_or_empty, self_name, get_raw, allow_duplicate)) { return opt.value().symbols; @@ -716,14 +762,16 @@ asst::ResultOrError asst::TaskData::compile_ra return ret; } -asst::ResultOrError asst::TaskData::compile_tasklist(const TaskList& raw_tasks, - std::string_view self_name, - bool allow_duplicate) +asst::ResultOrError + asst::TaskData::compile_tasklist(const TaskList& raw_tasks, std::string_view self_name, bool allow_duplicate) { CompileResult ret { .task_changed = false, .tasks = {} }; std::vector new_symbols; if (auto opt = compile_raw_tasklist( - raw_tasks, self_name, [&](std::string_view name) { return get_raw(name); }, allow_duplicate); + raw_tasks, + self_name, + [&](std::string_view name) { return get_raw(name); }, + allow_duplicate); !opt) { return { std::nullopt, std::move(opt.error()) }; } diff --git a/src/MaaCore/Config/TaskData.h b/src/MaaCore/Config/TaskData.h index f948ef4dba..b728f9742c 100644 --- a/src/MaaCore/Config/TaskData.h +++ b/src/MaaCore/Config/TaskData.h @@ -10,113 +10,132 @@ namespace asst { - class TaskData final : public SingletonHolder, public AbstractConfigWithTempl +class TaskData final : public SingletonHolder, public AbstractConfigWithTempl +{ +private: + static MatchTaskConstPtr _default_match_task_info(); + static OcrTaskConstPtr _default_ocr_task_info(); + static TaskConstPtr _default_task_info(); + + // 从模板任务生成 + static inline const MatchTaskConstPtr default_match_task_info_ptr = _default_match_task_info(); + static inline const OcrTaskConstPtr default_ocr_task_info_ptr = _default_ocr_task_info(); + static inline const TaskConstPtr default_task_info_ptr = _default_task_info(); + + static std::string append_prefix(std::string_view task_name, std::string_view task_prefix); + static TaskList append_prefix(const TaskList& base_task_list, std::string_view task_prefix); + + template + requires( + !std::same_as, std::string> && + requires { std::declval>().as_string(); }) + static TaskList to_string_list(const ListType& other_string_list) { - private: - static MatchTaskConstPtr _default_match_task_info(); - static OcrTaskConstPtr _default_ocr_task_info(); - static TaskConstPtr _default_task_info(); + TaskList task_list = {}; + task_list.reserve(other_string_list.size()); + ranges::copy( + other_string_list | views::transform(&ranges::range_value_t::as_string), + std::back_inserter(task_list)); + return task_list; + } - // 从模板任务生成 - static inline const MatchTaskConstPtr default_match_task_info_ptr = _default_match_task_info(); - static inline const OcrTaskConstPtr default_ocr_task_info_ptr = _default_ocr_task_info(); - static inline const TaskConstPtr default_task_info_ptr = _default_task_info(); + static inline std::unordered_set m_task_names {}; - static std::string append_prefix(std::string_view task_name, std::string_view task_prefix); - static TaskList append_prefix(const TaskList& base_task_list, std::string_view task_prefix); + static const std::string& task_name_view(std::string_view name) { return *m_task_names.emplace(name).first; } - template - requires(!std::same_as, std::string> && - requires { std::declval>().as_string(); }) - static TaskList to_string_list(const ListType& other_string_list) - { - TaskList task_list = {}; - task_list.reserve(other_string_list.size()); - ranges::copy(other_string_list | views::transform(&ranges::range_value_t::as_string), - std::back_inserter(task_list)); - return task_list; - } - - static inline std::unordered_set m_task_names {}; - static const std::string& task_name_view(std::string_view name) { return *m_task_names.emplace(name).first; } - - struct RawCompileResult - { - bool task_changed; - TaskDataSymbol::Symbols symbols; - }; - static ResultOrError compile_raw_tasklist( - const TaskList& raw_tasks, std::string_view self_name, - std::function get_raw, bool allow_duplicate); - - private: - TaskPtr generate_task_info(std::string_view name); - TaskPtr generate_match_task_info(std::string_view name, const json::value&, MatchTaskConstPtr default_ptr, - TaskDerivedType derived_type); - TaskPtr generate_ocr_task_info(std::string_view name, const json::value&, OcrTaskConstPtr default_ptr); - decltype(auto) insert_or_assign_raw_task(std::string_view task_name, TaskDerivedPtr task_info_ptr) - { - return m_raw_all_tasks_info.insert_or_assign(task_name_view(task_name), task_info_ptr); - } - decltype(auto) insert_or_assign_task(std::string_view task_name, TaskPtr task_info_ptr) - { - return m_all_tasks_info.insert_or_assign(task_name_view(task_name), task_info_ptr); - } - struct CompileResult - { - bool task_changed; - TaskList tasks; - }; - ResultOrError compile_tasklist(const TaskList& raw_tasks, std::string_view self_name, - bool allow_duplicate); - bool generate_raw_task_info(std::string_view name, std::string_view prefix, std::string_view base_name, - const json::value& task_json, TaskDerivedType type); - bool generate_raw_task_and_base(std::string_view name, bool must_true, bool allow_implicit = true); -#ifdef ASST_DEBUG - bool syntax_check(std::string_view task_name, const json::value& task_json); -#endif - TaskDerivedConstPtr get_raw(std::string_view name); - - public: - virtual ~TaskData() override = default; - virtual const std::unordered_set& get_templ_required() const noexcept override; - void clear_tasks(); - void set_task_base(const std::string_view task_name, std::string base_task_name); - bool lazy_parse(const json::value& json); - - TaskPtr get(std::string_view name); - template - requires(std::derived_from && - !std::same_as) // Parameter must be a TaskInfo - std::shared_ptr get(std::string_view name) - { - // TODO: should be const - // any `Task.get(name)->x = y` could be transformed to - // ``` - // json::object json = {}; - // json[name][x] = y; - // Task.lazy_parse(json); - // ``` - return std::dynamic_pointer_cast(get(name)); - } - - protected: - enum TaskStatus - { - NotToBeGenerate = 0, // 已经显式生成 或 不是待显式生成 的任务 - ToBeGenerate, // 待生成 的任务 - Generating, // 正在生成 的任务 - NotExists, // 不存在的任务 - }; - - virtual bool parse(const json::value& json) override; - - std::unordered_set m_templ_required; - std::unordered_map m_task_status; - std::unordered_map m_json_all_tasks_info; // 原始的 json 信息 - std::unordered_map m_raw_all_tasks_info; // 未展开虚任务的任务信息 - std::unordered_map m_all_tasks_info; // 已展开虚任务的任务信息 + struct RawCompileResult + { + bool task_changed; + TaskDataSymbol::Symbols symbols; }; - inline static auto& Task = TaskData::get_instance(); + static ResultOrError compile_raw_tasklist( + const TaskList& raw_tasks, + std::string_view self_name, + std::function get_raw, + bool allow_duplicate); + +private: + TaskPtr generate_task_info(std::string_view name); + TaskPtr generate_match_task_info( + std::string_view name, + const json::value&, + MatchTaskConstPtr default_ptr, + TaskDerivedType derived_type); + TaskPtr generate_ocr_task_info(std::string_view name, const json::value&, OcrTaskConstPtr default_ptr); + + decltype(auto) insert_or_assign_raw_task(std::string_view task_name, TaskDerivedPtr task_info_ptr) + { + return m_raw_all_tasks_info.insert_or_assign(task_name_view(task_name), task_info_ptr); + } + + decltype(auto) insert_or_assign_task(std::string_view task_name, TaskPtr task_info_ptr) + { + return m_all_tasks_info.insert_or_assign(task_name_view(task_name), task_info_ptr); + } + + struct CompileResult + { + bool task_changed; + TaskList tasks; + }; + + ResultOrError + compile_tasklist(const TaskList& raw_tasks, std::string_view self_name, bool allow_duplicate); + bool generate_raw_task_info( + std::string_view name, + std::string_view prefix, + std::string_view base_name, + const json::value& task_json, + TaskDerivedType type); + bool generate_raw_task_and_base(std::string_view name, bool must_true, bool allow_implicit = true); +#ifdef ASST_DEBUG + bool syntax_check(std::string_view task_name, const json::value& task_json); +#endif + TaskDerivedConstPtr get_raw(std::string_view name); + +public: + virtual ~TaskData() override = default; + virtual const std::unordered_set& get_templ_required() const noexcept override; + void clear_tasks(); + void set_task_base(const std::string_view task_name, std::string base_task_name); + bool lazy_parse(const json::value& json); + + TaskPtr get(std::string_view name); + + template + requires( + std::derived_from && + !std::same_as) // Parameter must be a TaskInfo + std::shared_ptr get(std::string_view name) + { + // TODO: should be const + // any `Task.get(name)->x = y` could be transformed to + // ``` + // json::object json = {}; + // json[name][x] = y; + // Task.lazy_parse(json); + // ``` + return std::dynamic_pointer_cast(get(name)); + } + +protected: + enum TaskStatus + { + NotToBeGenerate = 0, // 已经显式生成 或 不是待显式生成 的任务 + ToBeGenerate, // 待生成 的任务 + Generating, // 正在生成 的任务 + NotExists, // 不存在的任务 + }; + + virtual bool parse(const json::value& json) override; + + std::unordered_set m_templ_required; + std::unordered_map m_task_status; + std::unordered_map m_json_all_tasks_info; // 原始的 json 信息 + std::unordered_map m_raw_all_tasks_info; // 未展开虚任务的任务信息 + std::unordered_map m_all_tasks_info; // 已展开虚任务的任务信息 +}; + +inline static auto& Task = TaskData::get_instance(); } // namespace asst diff --git a/src/MaaCore/Config/TaskData/TaskDataSymbol.cpp b/src/MaaCore/Config/TaskData/TaskDataSymbol.cpp index 0b3f2a1d82..0cd402f983 100644 --- a/src/MaaCore/Config/TaskData/TaskDataSymbol.cpp +++ b/src/MaaCore/Config/TaskData/TaskDataSymbol.cpp @@ -1,7 +1,9 @@ #include "TaskDataSymbol.h" asst::TaskDataSymbol::SymbolsOrError asst::TaskDataSymbol::append_prefix( - const TaskDataSymbol& symbol, const TaskDataSymbol& prefix, std::string_view self_name, + const TaskDataSymbol& symbol, + const TaskDataSymbol& prefix, + std::string_view self_name, std::function get_raw, std::function compile_tasklist) { diff --git a/src/MaaCore/Config/TaskData/TaskDataSymbol.h b/src/MaaCore/Config/TaskData/TaskDataSymbol.h index c4209a757e..0e9c8e0cec 100644 --- a/src/MaaCore/Config/TaskData/TaskDataSymbol.h +++ b/src/MaaCore/Config/TaskData/TaskDataSymbol.h @@ -11,125 +11,142 @@ namespace asst { - class TaskDataSymbol final +class TaskDataSymbol final +{ +public: + using Symbols = std::vector; + using SymbolsOrError = ResultOrError; + + enum Type { - public: - using Symbols = std::vector; - using SymbolsOrError = ResultOrError; - - enum Type - { - End, - LambdaTaskSep, - LParen, - RParen, - LBrace, - RBrace, - At, - Sharp, - Mul, - Add, - Sub, - SharpSub, - SharpNext, - SharpOnErrorNext, - SharpExceededNext, - SharpReduceOtherTimes, - SharpSelf, - SharpBack, - SharpNone, - Name, - }; - - static const inline std::unordered_map symbol_repr_to_type = { - { "__END__", End }, - { ",", LambdaTaskSep }, - { "(", LParen }, - { ")", RParen }, - { "{", LBrace }, - { "}", RBrace }, - { "@", At }, - { "#", Sharp }, - { "*", Mul }, - { "+", Add }, - { "^", Sub }, - { "sub", SharpSub }, - { "next", SharpNext }, - { "on_error_next", SharpOnErrorNext }, - { "exceeded_next", SharpExceededNext }, - { "reduce_other_times", SharpReduceOtherTimes }, - { "self", SharpSelf }, - { "back", SharpBack }, - { "none", SharpNone }, - { "__name__", Name }, - }; - static const inline std::unordered_map symbol_type_to_repr = { - { End, "__END__" }, - { LambdaTaskSep, "," }, - { LParen, "(" }, - { RParen, ")" }, - { LBrace, "{" }, - { RBrace, "}" }, - { At, "@" }, - { Sharp, "#" }, - { Mul, "*" }, - { Add, "+" }, - { Sub, "^" }, - { SharpSub, "sub" }, - { SharpNext, "next" }, - { SharpOnErrorNext, "on_error_next" }, - { SharpExceededNext, "exceeded_next" }, - { SharpReduceOtherTimes, "reduce_other_times" }, - { SharpSelf, "self" }, - { SharpBack, "back" }, - { SharpNone, "none" }, - { Name, "__name__" }, - }; - - Type m_symbol; - std::string m_name; - - public: - bool operator==(Type other) const noexcept { return m_symbol == other; } - bool operator==(std::string_view other) const noexcept { return m_symbol == Name && m_name == other; } - bool operator==(const TaskDataSymbol& other) const noexcept - { - return m_symbol == other.m_symbol && (m_symbol != Name || m_name == other.m_name); - } - TaskDataSymbol(Type symbol) : m_symbol(symbol) {} - template - requires(std::constructible_from) - TaskDataSymbol(StringT&& name) : m_symbol(Name), m_name(std::forward(name)) - {} - - static bool is_sharp_type(Type type) noexcept - { - static std::unordered_set sharp_types = { - SharpSub, SharpNext, SharpOnErrorNext, SharpExceededNext, SharpReduceOtherTimes, - SharpSelf, SharpBack, SharpNone, - }; - return sharp_types.contains(type); - } - static const std::string& repr(Type type) - { - const auto pos = symbol_type_to_repr.find(type); - return pos == symbol_type_to_repr.end() ? symbol_type_to_repr.at(Name) : pos->second; - } - static Type type(std::string_view repr) - { - const auto pos = symbol_repr_to_type.find(repr); - return pos == symbol_repr_to_type.end() ? Name : pos->second; - } - - static SymbolsOrError append_prefix(const TaskDataSymbol& symbol, const TaskDataSymbol& prefix, - std::string_view self_name, - std::function get_raw, - std::function compile_tasklist); - - bool is_name() const noexcept { return m_symbol == Name; } - bool is_sharp_type() const noexcept { return is_sharp_type(m_symbol); } - Type type() const noexcept { return m_symbol; } - // const std::string& repr() const& noexcept { return repr(m_symbol); } - const std::string& name() const& noexcept { return is_name() ? m_name : repr(m_symbol); } + End, + LambdaTaskSep, + LParen, + RParen, + LBrace, + RBrace, + At, + Sharp, + Mul, + Add, + Sub, + SharpSub, + SharpNext, + SharpOnErrorNext, + SharpExceededNext, + SharpReduceOtherTimes, + SharpSelf, + SharpBack, + SharpNone, + Name, }; + + static const inline std::unordered_map symbol_repr_to_type = { + { "__END__", End }, + { ",", LambdaTaskSep }, + { "(", LParen }, + { ")", RParen }, + { "{", LBrace }, + { "}", RBrace }, + { "@", At }, + { "#", Sharp }, + { "*", Mul }, + { "+", Add }, + { "^", Sub }, + { "sub", SharpSub }, + { "next", SharpNext }, + { "on_error_next", SharpOnErrorNext }, + { "exceeded_next", SharpExceededNext }, + { "reduce_other_times", SharpReduceOtherTimes }, + { "self", SharpSelf }, + { "back", SharpBack }, + { "none", SharpNone }, + { "__name__", Name }, + }; + static const inline std::unordered_map symbol_type_to_repr = { + { End, "__END__" }, + { LambdaTaskSep, "," }, + { LParen, "(" }, + { RParen, ")" }, + { LBrace, "{" }, + { RBrace, "}" }, + { At, "@" }, + { Sharp, "#" }, + { Mul, "*" }, + { Add, "+" }, + { Sub, "^" }, + { SharpSub, "sub" }, + { SharpNext, "next" }, + { SharpOnErrorNext, "on_error_next" }, + { SharpExceededNext, "exceeded_next" }, + { SharpReduceOtherTimes, "reduce_other_times" }, + { SharpSelf, "self" }, + { SharpBack, "back" }, + { SharpNone, "none" }, + { Name, "__name__" }, + }; + + Type m_symbol; + std::string m_name; + +public: + bool operator==(Type other) const noexcept { return m_symbol == other; } + + bool operator==(std::string_view other) const noexcept { return m_symbol == Name && m_name == other; } + + bool operator==(const TaskDataSymbol& other) const noexcept + { + return m_symbol == other.m_symbol && (m_symbol != Name || m_name == other.m_name); + } + + TaskDataSymbol(Type symbol) : + m_symbol(symbol) + { + } + + template + requires(std::constructible_from) + TaskDataSymbol(StringT&& name) : + m_symbol(Name), + m_name(std::forward(name)) + { + } + + static bool is_sharp_type(Type type) noexcept + { + static std::unordered_set sharp_types = { + SharpSub, SharpNext, SharpOnErrorNext, SharpExceededNext, SharpReduceOtherTimes, + SharpSelf, SharpBack, SharpNone, + }; + return sharp_types.contains(type); + } + + static const std::string& repr(Type type) + { + const auto pos = symbol_type_to_repr.find(type); + return pos == symbol_type_to_repr.end() ? symbol_type_to_repr.at(Name) : pos->second; + } + + static Type type(std::string_view repr) + { + const auto pos = symbol_repr_to_type.find(repr); + return pos == symbol_repr_to_type.end() ? Name : pos->second; + } + + static SymbolsOrError append_prefix( + const TaskDataSymbol& symbol, + const TaskDataSymbol& prefix, + std::string_view self_name, + std::function get_raw, + std::function compile_tasklist); + + bool is_name() const noexcept { return m_symbol == Name; } + + bool is_sharp_type() const noexcept { return is_sharp_type(m_symbol); } + + Type type() const noexcept { return m_symbol; } + + // const std::string& repr() const& noexcept { return repr(m_symbol); } + const std::string& name() const& noexcept { return is_name() ? m_name : repr(m_symbol); } +}; } // namespace asst diff --git a/src/MaaCore/Config/TaskData/TaskDataSymbolStream.cpp b/src/MaaCore/Config/TaskData/TaskDataSymbolStream.cpp index 6624b31bac..14fc0444ee 100644 --- a/src/MaaCore/Config/TaskData/TaskDataSymbolStream.cpp +++ b/src/MaaCore/Config/TaskData/TaskDataSymbolStream.cpp @@ -59,8 +59,9 @@ asst::ResultOrError asst::TaskDataSymbolStream::parse(std::string_view tas auto symbol = TaskDataSymbol::type(std::string_view { std::addressof(*p), 1 }); if (symbol == TaskDataSymbol::Name) [[unlikely]] { // should not happen - return { std::nullopt, std::string("Error when decode symbol ") + *p + " at " + - std::to_string(p - task_expr.cbegin()) + " in " += task_expr }; + return { std::nullopt, + std::string("Error when decode symbol ") + *p + " at " + + std::to_string(p - task_expr.cbegin()) + " in " += task_expr }; } m_symbolstream.emplace_back(symbol); break; @@ -75,8 +76,8 @@ asst::ResultOrError asst::TaskDataSymbolStream::parse(std::string_view tas return task_changed; } -asst::TaskDataSymbolStream::SymbolsOrError asst::TaskDataSymbolStream::decode(AppendPrefixFunc append_prefix, - std::string_view self_name) const +asst::TaskDataSymbolStream::SymbolsOrError + asst::TaskDataSymbolStream::decode(AppendPrefixFunc append_prefix, std::string_view self_name) const { /* $name = 至少一位的任务名 diff --git a/src/MaaCore/Config/TaskData/TaskDataSymbolStream.h b/src/MaaCore/Config/TaskData/TaskDataSymbolStream.h index 81a02a9061..77d2d4e9b3 100644 --- a/src/MaaCore/Config/TaskData/TaskDataSymbolStream.h +++ b/src/MaaCore/Config/TaskData/TaskDataSymbolStream.h @@ -9,19 +9,19 @@ namespace asst { - class TaskDataSymbolStream final - { - public: - using Symbol = TaskDataSymbol; - using Symbols = TaskDataSymbol::Symbols; - using SymbolsOrError = TaskDataSymbol::SymbolsOrError; - using AppendPrefixFunc = std::function; +class TaskDataSymbolStream final +{ +public: + using Symbol = TaskDataSymbol; + using Symbols = TaskDataSymbol::Symbols; + using SymbolsOrError = TaskDataSymbol::SymbolsOrError; + using AppendPrefixFunc = std::function; - private: - Symbols m_symbolstream; +private: + Symbols m_symbolstream; - public: - ResultOrError parse(std::string_view task_expr); - SymbolsOrError decode(AppendPrefixFunc append_prefix, std::string_view self_name) const; - }; +public: + ResultOrError parse(std::string_view task_expr); + SymbolsOrError decode(AppendPrefixFunc append_prefix, std::string_view self_name) const; +}; } // namespace asst diff --git a/src/MaaCore/Config/TaskData/TaskDataTypes.h b/src/MaaCore/Config/TaskData/TaskDataTypes.h index f185d8f541..d724ff110d 100644 --- a/src/MaaCore/Config/TaskData/TaskDataTypes.h +++ b/src/MaaCore/Config/TaskData/TaskDataTypes.h @@ -6,40 +6,54 @@ namespace asst { - template - class ResultOrError +template +class ResultOrError +{ + using _variant_t = std::variant; + bool m_success; + _variant_t m_result_or_error; + +public: + template + requires std::constructible_from + constexpr ResultOrError(Args&&... args) : + m_success(true), + m_result_or_error(std::in_place_index<0>, std::forward(args)...) { - using _variant_t = std::variant; - bool m_success; - _variant_t m_result_or_error; + } - public: - template - requires std::constructible_from - constexpr ResultOrError(Args&&... args) - : m_success(true), m_result_or_error(std::in_place_index<0>, std::forward(args)...) - {} + constexpr ResultOrError([[maybe_unused]] std::nullopt_t nullopt, std::string result) : + m_success(false), + m_result_or_error(std::in_place_index<1>, std::move(result)) + { + } - constexpr ResultOrError([[maybe_unused]] std::nullopt_t nullopt, std::string result) - : m_success(false), m_result_or_error(std::in_place_index<1>, std::move(result)) - {} + constexpr operator bool() const noexcept { return m_success; } - constexpr operator bool() const noexcept { return m_success; } - constexpr bool has_value() const noexcept { return m_success; } + constexpr bool has_value() const noexcept { return m_success; } - constexpr ResultT& operator*() & { return std::get<0>(m_result_or_error); } - constexpr const ResultT& operator*() const& { return std::get<0>(m_result_or_error); } - constexpr ResultT&& operator*() && { return std::move(std::get<0>(m_result_or_error)); } - constexpr const ResultT&& operator*() const&& { return std::move(std::get<0>(m_result_or_error)); } + constexpr ResultT& operator*() & { return std::get<0>(m_result_or_error); } - constexpr ResultT& value() & { return std::get<0>(m_result_or_error); } - constexpr const ResultT& value() const& { return std::get<0>(m_result_or_error); } - constexpr ResultT&& value() && { return std::move(std::get<0>(m_result_or_error)); } - constexpr const ResultT&& value() const&& { return std::move(std::get<0>(m_result_or_error)); } + constexpr const ResultT& operator*() const& { return std::get<0>(m_result_or_error); } - constexpr std::string& error() & { return std::get<1>(m_result_or_error); } - constexpr const std::string& error() const& { return std::get<1>(m_result_or_error); } - constexpr std::string&& error() && { return std::move(std::get<1>(m_result_or_error)); } - constexpr const std::string&& error() const&& { return std::move(std::get<1>(m_result_or_error)); } - }; + constexpr ResultT&& operator*() && { return std::move(std::get<0>(m_result_or_error)); } + + constexpr const ResultT&& operator*() const&& { return std::move(std::get<0>(m_result_or_error)); } + + constexpr ResultT& value() & { return std::get<0>(m_result_or_error); } + + constexpr const ResultT& value() const& { return std::get<0>(m_result_or_error); } + + constexpr ResultT&& value() && { return std::move(std::get<0>(m_result_or_error)); } + + constexpr const ResultT&& value() const&& { return std::move(std::get<0>(m_result_or_error)); } + + constexpr std::string& error() & { return std::get<1>(m_result_or_error); } + + constexpr const std::string& error() const& { return std::get<1>(m_result_or_error); } + + constexpr std::string&& error() && { return std::move(std::get<1>(m_result_or_error)); } + + constexpr const std::string&& error() const&& { return std::move(std::get<1>(m_result_or_error)); } +}; } // namespace asst diff --git a/src/MaaCore/Config/TemplResource.h b/src/MaaCore/Config/TemplResource.h index eb1baa37cf..176e33652a 100644 --- a/src/MaaCore/Config/TemplResource.h +++ b/src/MaaCore/Config/TemplResource.h @@ -10,19 +10,19 @@ namespace asst { - class TemplResource final : public SingletonHolder, public AbstractResource - { - public: - virtual ~TemplResource() override = default; +class TemplResource final : public SingletonHolder, public AbstractResource +{ +public: + virtual ~TemplResource() override = default; - void set_load_required(std::unordered_set required) noexcept; - virtual bool load(const std::filesystem::path& path) override; + void set_load_required(std::unordered_set required) noexcept; + virtual bool load(const std::filesystem::path& path) override; - const cv::Mat& get_templ(const std::string& name); + const cv::Mat& get_templ(const std::string& name); - private: - std::unordered_set m_load_required; - std::unordered_map m_templs; - std::unordered_map m_templ_paths; - }; +private: + std::unordered_set m_load_required; + std::unordered_map m_templs; + std::unordered_map m_templ_paths; +}; } diff --git a/src/MaaCore/Controller/AdbController.cpp b/src/MaaCore/Controller/AdbController.cpp index 23a3be0fee..a1aa2da6a9 100644 --- a/src/MaaCore/Controller/AdbController.cpp +++ b/src/MaaCore/Controller/AdbController.cpp @@ -316,7 +316,7 @@ bool asst::AdbController::stop_game(const std::string& client_type) return false; } std::string cur_cmd = utils::string_replace_all(m_adb.stop, "[PackageName]", package_name.value()); - bool ret = call_command(cur_cmd).has_value(); + bool ret = call_command(cur_cmd).has_value(); set_mumu_package(""); diff --git a/src/MaaCore/Controller/ControlScaleProxy.cpp b/src/MaaCore/Controller/ControlScaleProxy.cpp index 212674e507..c52bbcbd26 100644 --- a/src/MaaCore/Controller/ControlScaleProxy.cpp +++ b/src/MaaCore/Controller/ControlScaleProxy.cpp @@ -3,10 +3,14 @@ #include "Config/GeneralConfig.h" #include "Utils/Logger.hpp" -asst::ControlScaleProxy::ControlScaleProxy(std::shared_ptr controller, ControllerType controller_type, - ProxyCallback proxy_callback) - : m_controller(controller), m_controller_type(controller_type), m_callback(proxy_callback), - m_rand_engine(std::random_device {}()) +asst::ControlScaleProxy::ControlScaleProxy( + std::shared_ptr controller, + ControllerType controller_type, + ProxyCallback proxy_callback) : + m_controller(controller), + m_controller_type(controller_type), + m_callback(proxy_callback), + m_rand_engine(std::random_device {}()) { auto screen_res = m_controller->get_screen_res(); @@ -27,8 +31,10 @@ asst::ControlScaleProxy::ControlScaleProxy(std::shared_ptr contro callback(info); throw std::runtime_error("Unsupported resolution"); } - else if (std::fabs(static_cast(WindowWidthDefault) / static_cast(WindowHeightDefault) - - static_cast(width) / static_cast(height)) > 1e-7) { + else if ( + std::fabs( + static_cast(WindowWidthDefault) / static_cast(WindowHeightDefault) - + static_cast(width) / static_cast(height)) > 1e-7) { info["what"] = "UnsupportedResolution"; info["why"] = "Not 16:9"; callback(info); @@ -58,7 +64,7 @@ bool asst::ControlScaleProxy::click(const Point& p) int y = static_cast(p.y * m_control_scale); Log.trace("Click with scaled coordinates", p, m_control_scale); - + return m_controller->click(Point(x, y)); } @@ -67,8 +73,14 @@ bool asst::ControlScaleProxy::click(const Rect& rect) return click(rand_point_in_rect(rect)); } -bool asst::ControlScaleProxy::swipe(const Point& p1, const Point& p2, int duration, bool extra_swipe, double slope_in, - double slope_out, bool with_pause) +bool asst::ControlScaleProxy::swipe( + const Point& p1, + const Point& p2, + int duration, + bool extra_swipe, + double slope_in, + double slope_out, + bool with_pause) { int x1 = static_cast(p1.x * m_control_scale); int y1 = static_cast(p1.y * m_control_scale); @@ -80,8 +92,14 @@ bool asst::ControlScaleProxy::swipe(const Point& p1, const Point& p2, int durati return m_controller->swipe(Point(x1, y1), Point(x2, y2), duration, extra_swipe, slope_in, slope_out, with_pause); } -bool asst::ControlScaleProxy::swipe(const Rect& r1, const Rect& r2, int duration, bool extra_swipe, double slope_in, - double slope_out, bool with_pause) +bool asst::ControlScaleProxy::swipe( + const Rect& r1, + const Rect& r2, + int duration, + bool extra_swipe, + double slope_in, + double slope_out, + bool with_pause) { auto rand_p1 = rand_point_in_rect(r1); auto rand_p2 = rand_point_in_rect(r2); diff --git a/src/MaaCore/Controller/ControlScaleProxy.h b/src/MaaCore/Controller/ControlScaleProxy.h index 0bd9b3df65..32923849ee 100644 --- a/src/MaaCore/Controller/ControlScaleProxy.h +++ b/src/MaaCore/Controller/ControlScaleProxy.h @@ -9,43 +9,57 @@ namespace asst { - class ControlScaleProxy - { - public: - using ProxyCallback = std::function; +class ControlScaleProxy +{ +public: + using ProxyCallback = std::function; - public: - ControlScaleProxy(std::shared_ptr controller, ControllerType controller_type, - ProxyCallback proxy_callback); - ~ControlScaleProxy() = default; +public: + ControlScaleProxy( + std::shared_ptr controller, + ControllerType controller_type, + ProxyCallback proxy_callback); + ~ControlScaleProxy() = default; - ControlScaleProxy(const ControlScaleProxy&) = delete; - ControlScaleProxy(ControlScaleProxy&&) = delete; + ControlScaleProxy(const ControlScaleProxy&) = delete; + ControlScaleProxy(ControlScaleProxy&&) = delete; - bool click(const Point& p); - bool click(const Rect& rect); + bool click(const Point& p); + bool click(const Rect& rect); - bool swipe(const Point& p1, const Point& p2, int duration = 0, bool extra_swipe = false, double slope_in = 1, - double slope_out = 1, bool with_pause = false); - bool swipe(const Rect& r1, const Rect& r2, int duration = 0, bool extra_swipe = false, double slope_in = 1, - double slope_out = 1, bool with_pause = false); + bool swipe( + const Point& p1, + const Point& p2, + int duration = 0, + bool extra_swipe = false, + double slope_in = 1, + double slope_out = 1, + bool with_pause = false); + bool swipe( + const Rect& r1, + const Rect& r2, + int duration = 0, + bool extra_swipe = false, + double slope_in = 1, + double slope_out = 1, + bool with_pause = false); - bool inject_input_event(InputEvent event); + bool inject_input_event(InputEvent event); - std::pair get_scale_size() const noexcept; + std::pair get_scale_size() const noexcept; - private: - Point rand_point_in_rect(const Rect& rect); +private: + Point rand_point_in_rect(const Rect& rect); - void callback(const json::object& details); + void callback(const json::object& details); - std::shared_ptr m_controller; - ControllerType m_controller_type = ControllerType::Minitouch; - ProxyCallback m_callback = nullptr; + std::shared_ptr m_controller; + ControllerType m_controller_type = ControllerType::Minitouch; + ProxyCallback m_callback = nullptr; - std::minstd_rand m_rand_engine; + std::minstd_rand m_rand_engine; - std::pair m_scale_size = { WindowWidthDefault, WindowHeightDefault }; - double m_control_scale = 1.0; - }; + std::pair m_scale_size = { WindowWidthDefault, WindowHeightDefault }; + double m_control_scale = 1.0; +}; } diff --git a/src/MaaCore/Controller/Controller.cpp b/src/MaaCore/Controller/Controller.cpp index d23a2e3fca..9274898c8d 100644 --- a/src/MaaCore/Controller/Controller.cpp +++ b/src/MaaCore/Controller/Controller.cpp @@ -28,10 +28,10 @@ #include "Common/AsstTypes.h" #include "Utils/Logger.hpp" -asst::Controller::Controller(const AsstCallback& callback, Assistant* inst) - : InstHelper(inst) - , m_callback(callback) - , m_rand_engine(std::random_device {}()) +asst::Controller::Controller(const AsstCallback& callback, Assistant* inst) : + InstHelper(inst), + m_callback(callback), + m_rand_engine(std::random_device {}()) { LogTraceFunction; } @@ -219,10 +219,7 @@ asst::ControlFeat::Feat asst::Controller::support_features() return m_controller->support_features(); } -bool asst::Controller::connect( - const std::string& adb_path, - const std::string& address, - const std::string& config) +bool asst::Controller::connect(const std::string& adb_path, const std::string& address, const std::string& config) { LogTraceFunction; @@ -264,8 +261,7 @@ bool asst::Controller::connect( }; try { - m_scale_proxy = - std::make_shared(m_controller, m_controller_type, proxy_callback); + m_scale_proxy = std::make_shared(m_controller, m_controller_type, proxy_callback); } catch (const std::exception& e) { Log.error("Cannot create controller proxy: {}", e.what()); diff --git a/src/MaaCore/Controller/Controller.h b/src/MaaCore/Controller/Controller.h index e1204f7879..4ce09a2ee8 100644 --- a/src/MaaCore/Controller/Controller.h +++ b/src/MaaCore/Controller/Controller.h @@ -44,8 +44,7 @@ public: const std::string& config, PlatformType platform_type) const; - bool - connect(const std::string& adb_path, const std::string& address, const std::string& config); + bool connect(const std::string& adb_path, const std::string& address, const std::string& config); bool inited() noexcept; void set_touch_mode(const TouchMode& mode) noexcept; void set_swipe_with_pause(bool enable) noexcept; diff --git a/src/MaaCore/Controller/ControllerAPI.h b/src/MaaCore/Controller/ControllerAPI.h index a7f70b96d3..93dadcdd5a 100644 --- a/src/MaaCore/Controller/ControllerAPI.h +++ b/src/MaaCore/Controller/ControllerAPI.h @@ -22,10 +22,7 @@ class ControllerAPI public: virtual ~ControllerAPI() = default; - virtual bool connect( - const std::string& adb_path, - const std::string& address, - const std::string& config) = 0; + virtual bool connect(const std::string& adb_path, const std::string& address, const std::string& config) = 0; virtual bool inited() const noexcept = 0; virtual void set_swipe_with_pause([[maybe_unused]] bool enable) noexcept {} diff --git a/src/MaaCore/Controller/MaaThriftController.cpp b/src/MaaCore/Controller/MaaThriftController.cpp index c7ca1949cc..f152615ffb 100644 --- a/src/MaaCore/Controller/MaaThriftController.cpp +++ b/src/MaaCore/Controller/MaaThriftController.cpp @@ -4,7 +4,7 @@ #ifdef _MSC_VER #pragma warning(push) -#pragma warning(disable : 4245 4706) +#pragma warning(disable: 4245 4706) #endif #include #include @@ -22,8 +22,10 @@ asst::MaaThriftController::~MaaThriftController() close(); } -bool asst::MaaThriftController::connect([[maybe_unused]] const std::string& adb_path, - [[maybe_unused]] const std::string& address, const std::string& config) +bool asst::MaaThriftController::connect( + [[maybe_unused]] const std::string& adb_path, + [[maybe_unused]] const std::string& address, + const std::string& config) { LogTraceFunction; @@ -321,8 +323,14 @@ bool asst::MaaThriftController::click(const Point& p) return client_->click(click_param); } -bool asst::MaaThriftController::swipe(const Point& p1, const Point& p2, int duration, bool extra_swipe, double slope_in, - double slope_out, bool with_pause) +bool asst::MaaThriftController::swipe( + const Point& p1, + const Point& p2, + int duration, + bool extra_swipe, + double slope_in, + double slope_out, + bool with_pause) { if (!client_ || !transport_ || !transport_->isOpen()) { Log.error("client_ is not created or transport_ is not open"); @@ -484,7 +492,9 @@ std::pair asst::MaaThriftController::get_screen_res() const noexcept return m_screen_size; } -void asst::MaaThriftController::back_to_home() noexcept {} +void asst::MaaThriftController::back_to_home() noexcept +{ +} void asst::MaaThriftController::clear_info() noexcept { diff --git a/src/MaaCore/Controller/MaaThriftController.h b/src/MaaCore/Controller/MaaThriftController.h index 20ce43467f..daa5970deb 100644 --- a/src/MaaCore/Controller/MaaThriftController.h +++ b/src/MaaCore/Controller/MaaThriftController.h @@ -14,92 +14,102 @@ namespace asst { - class MaaThriftController : public ControllerAPI, protected InstHelper +class MaaThriftController : public ControllerAPI, protected InstHelper +{ +public: + MaaThriftController(const AsstCallback& callback, Assistant* inst, [[maybe_unused]] PlatformType type) : + InstHelper(inst), + m_callback(callback) { - public: - MaaThriftController(const AsstCallback& callback, Assistant* inst, [[maybe_unused]] PlatformType type) - : InstHelper(inst), m_callback(callback) - { - LogTraceFunction; - } - MaaThriftController(const MaaThriftController&) = delete; - MaaThriftController(MaaThriftController&&) = delete; - virtual ~MaaThriftController(); + LogTraceFunction; + } - virtual bool connect([[maybe_unused]] const std::string& adb_path, [[maybe_unused]] const std::string& address, - const std::string& config) override; - virtual bool inited() const noexcept override; + MaaThriftController(const MaaThriftController&) = delete; + MaaThriftController(MaaThriftController&&) = delete; + virtual ~MaaThriftController(); - virtual void set_swipe_with_pause(bool enable) noexcept override; + virtual bool connect( + [[maybe_unused]] const std::string& adb_path, + [[maybe_unused]] const std::string& address, + const std::string& config) override; + virtual bool inited() const noexcept override; - virtual const std::string& get_uuid() const override; + virtual void set_swipe_with_pause(bool enable) noexcept override; - virtual bool screencap(cv::Mat& image_payload, bool allow_reconnect = false) override; + virtual const std::string& get_uuid() const override; - virtual bool start_game(const std::string& client_type) override; - virtual bool stop_game() override; + virtual bool screencap(cv::Mat& image_payload, bool allow_reconnect = false) override; - virtual bool click(const Point& p) override; + virtual bool start_game(const std::string& client_type) override; + virtual bool stop_game() override; - virtual bool swipe(const Point& p1, const Point& p2, int duration = 0, bool extra_swipe = false, - double slope_in = 1, double slope_out = 1, bool with_pause = false) override; + virtual bool click(const Point& p) override; - virtual bool inject_input_event(const InputEvent& event) override; + virtual bool swipe( + const Point& p1, + const Point& p2, + int duration = 0, + bool extra_swipe = false, + double slope_in = 1, + double slope_out = 1, + bool with_pause = false) override; - virtual bool press_esc() override; - virtual ControlFeat::Feat support_features() const noexcept override; + virtual bool inject_input_event(const InputEvent& event) override; - virtual std::pair get_screen_res() const noexcept override; + virtual bool press_esc() override; + virtual ControlFeat::Feat support_features() const noexcept override; - MaaThriftController& operator=(const MaaThriftController&) = delete; - MaaThriftController& operator=(MaaThriftController&&) = delete; + virtual std::pair get_screen_res() const noexcept override; - virtual void back_to_home() noexcept override; + MaaThriftController& operator=(const MaaThriftController&) = delete; + MaaThriftController& operator=(MaaThriftController&&) = delete; - protected: - virtual void clear_info() noexcept; - void callback(AsstMsg msg, const json::value& details); + virtual void back_to_home() noexcept override; - bool support_precise_swipe() const noexcept; - bool support_swipe_with_pause() const noexcept; - bool use_swipe_with_pause() const noexcept; +protected: + virtual void clear_info() noexcept; + void callback(AsstMsg msg, const json::value& details); - AsstCallback m_callback; + bool support_precise_swipe() const noexcept; + bool support_swipe_with_pause() const noexcept; + bool use_swipe_with_pause() const noexcept; - std::string m_config; - std::string m_uuid; - ControlFeat::Feat m_support_features = ControlFeat::NONE; - bool m_inited = false; - bool m_swipe_with_pause_enabled = false; - std::pair m_screen_size = { 0, 0 }; - std::vector m_input_events; + AsstCallback m_callback; - static constexpr int DefaultClickDelay = 50; - static constexpr int DefaultSwipeDelay = 5; + std::string m_config; + std::string m_uuid; + ControlFeat::Feat m_support_features = ControlFeat::NONE; + bool m_inited = false; + bool m_swipe_with_pause_enabled = false; + std::pair m_screen_size = { 0, 0 }; + std::vector m_input_events; - bool toucher_down(const Point& p, const int delay = DefaultClickDelay, int contact = 0); - bool toucher_move(const Point& p, const int delay = DefaultSwipeDelay, int contact = 0); - bool toucher_up(const Point& p, const int delay = DefaultClickDelay, int contact = 0); + static constexpr int DefaultClickDelay = 50; + static constexpr int DefaultSwipeDelay = 5; - void toucher_wait(const int delay); + bool toucher_down(const Point& p, const int delay = DefaultClickDelay, int contact = 0); + bool toucher_move(const Point& p, const int delay = DefaultSwipeDelay, int contact = 0); + bool toucher_up(const Point& p, const int delay = DefaultClickDelay, int contact = 0); - std::shared_ptr client_ = nullptr; - std::shared_ptr transport_ = nullptr; + void toucher_wait(const int delay); - enum ThriftControllerTypeEnum - { - // param format should be "host:port" - MaaThriftControllerType_Socket = 1, + std::shared_ptr client_ = nullptr; + std::shared_ptr transport_ = nullptr; - // param should be unix domain socket path - MaaThriftControllerType_UnixDomainSocket = 2, - }; + enum ThriftControllerTypeEnum + { + // param format should be "host:port" + MaaThriftControllerType_Socket = 1, - private: - static constexpr int MinimalVersion = 2; - void close(); - bool open(); + // param should be unix domain socket path + MaaThriftControllerType_UnixDomainSocket = 2, }; + +private: + static constexpr int MinimalVersion = 2; + void close(); + bool open(); +}; } // namespace asst #endif // WITH_THRIFT diff --git a/src/MaaCore/Controller/MaatouchController.h b/src/MaaCore/Controller/MaatouchController.h index 3d1ede287c..7f52e2d272 100644 --- a/src/MaaCore/Controller/MaatouchController.h +++ b/src/MaaCore/Controller/MaatouchController.h @@ -4,16 +4,17 @@ namespace asst { - class MaatouchController : public MinitouchController +class MaatouchController : public MinitouchController +{ +public: + MaatouchController(const AsstCallback& callback, Assistant* inst, PlatformType type) : + MinitouchController(callback, inst, type) { - public: - MaatouchController(const AsstCallback& callback, Assistant* inst, PlatformType type) - : MinitouchController(callback, inst, type) - { - m_use_maa_touch = true; - } - MaatouchController(const MaatouchController&) = delete; - MaatouchController(MaatouchController&&) = delete; - virtual ~MaatouchController() = default; - }; + m_use_maa_touch = true; + } + + MaatouchController(const MaatouchController&) = delete; + MaatouchController(MaatouchController&&) = delete; + virtual ~MaatouchController() = default; +}; } diff --git a/src/MaaCore/Controller/MinitouchController.cpp b/src/MaaCore/Controller/MinitouchController.cpp index 74a5927546..0b263315bb 100644 --- a/src/MaaCore/Controller/MinitouchController.cpp +++ b/src/MaaCore/Controller/MinitouchController.cpp @@ -90,13 +90,14 @@ bool asst::MinitouchController::call_and_hup_minitouch() m_minitouch_props.y_scaling = static_cast(m_minitouch_props.max_y) / m_height; m_minitoucher = std::make_unique( - std::bind(&MinitouchController::input_to_minitouch, this, std::placeholders::_1), m_minitouch_props); + std::bind(&MinitouchController::input_to_minitouch, this, std::placeholders::_1), + m_minitouch_props); return true; } -std::optional asst::MinitouchController::reconnect(const std::string& cmd, int64_t timeout, - bool recv_by_socket) +std::optional + asst::MinitouchController::reconnect(const std::string& cmd, int64_t timeout, bool recv_by_socket) { LogTraceFunction; @@ -141,12 +142,20 @@ bool asst::MinitouchController::click(const Point& p) Log.trace(m_use_maa_touch ? "maatouch" : "minitouch", "click:", p); bool ret = m_minitoucher->down(p.x, p.y) && m_minitoucher->up(); - if (ret) m_minitoucher->extra_sleep(); + if (ret) { + m_minitoucher->extra_sleep(); + } return ret; } -bool asst::MinitouchController::swipe(const Point& p1, const Point& p2, int duration, bool extra_swipe, double slope_in, - double slope_out, bool with_pause) +bool asst::MinitouchController::swipe( + const Point& p1, + const Point& p2, + int duration, + bool extra_swipe, + double slope_in, + double slope_out, + bool with_pause) { if (!m_minitoucher) { Log.error("minitoucher is not initialized"); @@ -164,7 +173,9 @@ bool asst::MinitouchController::swipe(const Point& p1, const Point& p2, int dura } Log.trace(m_use_maa_touch ? "maatouch" : "minitouch", "swipe", p1, p2, duration, extra_swipe, slope_in, slope_out); - if (!m_minitoucher->down(x1, y1)) return false; + if (!m_minitoucher->down(x1, y1)) { + return false; + } constexpr int TimeInterval = Minitoucher::DefaultSwipeDelay; @@ -188,8 +199,12 @@ bool asst::MinitouchController::swipe(const Point& p1, const Point& p2, int dura need_pause = false; if (m_use_maa_touch) { constexpr int EscKeyCode = 111; - if (!m_minitoucher->key_down(EscKeyCode)) return false; - if (!m_minitoucher->key_up(EscKeyCode, 0)) return false; + if (!m_minitoucher->key_down(EscKeyCode)) { + return false; + } + if (!m_minitoucher->key_up(EscKeyCode, 0)) { + return false; + } } else { pause_future = std::async(std::launch::async, [&]() { press_esc(); }); @@ -198,22 +213,33 @@ bool asst::MinitouchController::swipe(const Point& p1, const Point& p2, int dura if (cur_x < 0 || cur_x > m_minitouch_props.max_x || cur_y < 0 || cur_y > m_minitouch_props.max_y) { continue; } - if (!m_minitoucher->move(cur_x, cur_y)) return false; + if (!m_minitoucher->move(cur_x, cur_y)) { + return false; + } } if (_x2 >= 0 && _x2 <= m_minitouch_props.max_x && _y2 >= 0 && _y2 <= m_minitouch_props.max_y) { - if (!m_minitoucher->move(_x2, _y2)) return false; + if (!m_minitoucher->move(_x2, _y2)) { + return false; + } } return true; }; - if (!minitouch_move(x1, y1, x2, y2, duration ? duration : opt.minitouch_swipe_default_duration)) return false; + if (!minitouch_move(x1, y1, x2, y2, duration ? duration : opt.minitouch_swipe_default_duration)) { + return false; + } if (extra_swipe && opt.minitouch_extra_swipe_duration > 0) { - if (!m_minitoucher->wait(opt.minitouch_swipe_extra_end_delay)) return false; // 停留终点 - if (!minitouch_move(x2, y2, x2, y2 - opt.minitouch_extra_swipe_dist, opt.minitouch_extra_swipe_duration)) + if (!m_minitoucher->wait(opt.minitouch_swipe_extra_end_delay)) { + return false; // 停留终点 + } + if (!minitouch_move(x2, y2, x2, y2 - opt.minitouch_extra_swipe_dist, opt.minitouch_extra_swipe_duration)) { return false; + } + } + if (!m_minitoucher->up()) { + return false; } - if (!m_minitoucher->up()) return false; m_minitoucher->extra_sleep(); return true; } @@ -267,8 +293,9 @@ void asst::MinitouchController::clear_info() noexcept m_minitouch_props = decltype(m_minitouch_props)(); } -bool asst::MinitouchController::probe_minitouch(const AdbCfg& adb_cfg, - std::function cmd_replace) +bool asst::MinitouchController::probe_minitouch( + const AdbCfg& adb_cfg, + std::function cmd_replace) { LogTraceFunction; @@ -295,7 +322,9 @@ bool asst::MinitouchController::probe_minitouch(const AdbCfg& adb_cfg, } Log.info("touch_program", touch_program, "orientation", m_minitouch_props.orientation); - if (touch_program.empty()) return false; + if (touch_program.empty()) { + return false; + } auto minitouch_cmd_rep = [&](const std::string& cfg_cmd) -> std::string { using namespace asst::utils::path_literals; @@ -308,19 +337,27 @@ bool asst::MinitouchController::probe_minitouch(const AdbCfg& adb_cfg, }); }; - if (!call_command(minitouch_cmd_rep(adb_cfg.push_minitouch))) return false; - if (!call_command(minitouch_cmd_rep(adb_cfg.chmod_minitouch))) return false; + if (!call_command(minitouch_cmd_rep(adb_cfg.push_minitouch))) { + return false; + } + if (!call_command(minitouch_cmd_rep(adb_cfg.chmod_minitouch))) { + return false; + } m_adb.call_minitouch = minitouch_cmd_rep(adb_cfg.call_minitouch); m_adb.call_maatouch = minitouch_cmd_rep(adb_cfg.call_maatouch); - if (!call_and_hup_minitouch()) return false; + if (!call_and_hup_minitouch()) { + return false; + } return true; } -bool asst::MinitouchController::connect(const std::string& adb_path, const std::string& address, - const std::string& config) +bool asst::MinitouchController::connect( + const std::string& adb_path, + const std::string& address, + const std::string& config) { LogTraceFunction; @@ -356,23 +393,24 @@ bool asst::MinitouchController::connect(const std::string& adb_path, const std:: uint16_t nc_port = 0; auto cmd_replace = [&](const std::string& cfg_cmd) -> std::string { - return utils::string_replace_all(cfg_cmd, { - { "[Adb]", adb_path }, - { "[AdbSerial]", address }, - { "[DisplayId]", display_id }, - { "[NcPort]", std::to_string(nc_port) }, - { "[NcAddress]", nc_address }, - }); + return utils::string_replace_all( + cfg_cmd, + { + { "[Adb]", adb_path }, + { "[AdbSerial]", address }, + { "[DisplayId]", display_id }, + { "[NcPort]", std::to_string(nc_port) }, + { "[NcAddress]", nc_address }, + }); }; auto adb_ret = Config.get_adb_cfg(config); if (!adb_ret) { - json::value info = get_info_json() - | json::object { - { "what", "ConnectFailed" }, - { "why", "ConfigNotFound" }, - }; + json::value info = get_info_json() | json::object { + { "what", "ConnectFailed" }, + { "why", "ConfigNotFound" }, + }; callback(AsstMsg::ConnectionInfo, info); #ifdef ASST_DEBUG return false; diff --git a/src/MaaCore/Controller/MinitouchController.h b/src/MaaCore/Controller/MinitouchController.h index cc6b8bcaa3..5f4fbb1475 100644 --- a/src/MaaCore/Controller/MinitouchController.h +++ b/src/MaaCore/Controller/MinitouchController.h @@ -8,233 +8,269 @@ namespace asst { - class MinitouchController : public AdbController +class MinitouchController : public AdbController +{ +public: + MinitouchController(const AsstCallback& callback, Assistant* inst, PlatformType type) : + AdbController(callback, inst, type) + { + } + + MinitouchController(const MinitouchController&) = delete; + MinitouchController(MinitouchController&&) = delete; + virtual ~MinitouchController(); + + virtual bool connect(const std::string& adb_path, const std::string& address, const std::string& config) override; + + virtual void set_swipe_with_pause(bool enable) noexcept override; + + virtual bool click(const Point& p) override; + + virtual bool swipe( + const Point& p1, + const Point& p2, + int duration = 0, + bool extra_swipe = false, + double slope_in = 1, + double slope_out = 1, + bool with_pause = false) override; + + virtual bool inject_input_event(const InputEvent& event) override; + + virtual ControlFeat::Feat support_features() const noexcept override; + + MinitouchController& operator=(const MinitouchController&) = delete; + MinitouchController& operator=(MinitouchController&&) = delete; + + virtual void back_to_home() noexcept override; + +protected: + virtual std::optional reconnect(const std::string& cmd, int64_t timeout, bool recv_by_socket) override; + + bool call_and_hup_minitouch(); + + bool probe_minitouch(const AdbCfg& adb_cfg, std::function cmd_replace); + + bool input_to_minitouch(const std::string& cmd); + void release_minitouch(bool force = false); + + bool use_swipe_with_pause() const noexcept; + + virtual void clear_info() noexcept override; + + bool m_minitouch_available = false; + bool m_use_maa_touch = false; + bool m_swipe_with_pause_enabled = false; + + std::shared_ptr m_minitouch_handler = nullptr; + + class Minitoucher; + std::unique_ptr m_minitoucher = nullptr; + + struct MinitouchProps + { + int max_contacts = 0; + int max_x = 0; + int max_y = 0; + int max_pressure = 0; + + double x_scaling = 0; + double y_scaling = 0; + int orientation = 0; + } m_minitouch_props; + + class Minitoucher { public: - MinitouchController(const AsstCallback& callback, Assistant* inst, PlatformType type) - : AdbController(callback, inst, type) - {} - MinitouchController(const MinitouchController&) = delete; - MinitouchController(MinitouchController&&) = delete; - virtual ~MinitouchController(); + using InputFunc = std::function; - virtual bool connect(const std::string& adb_path, const std::string& address, - const std::string& config) override; + public: + static constexpr int DefaultClickDelay = 50; + static constexpr int DefaultSwipeDelay = 2; + static constexpr int ExtraDelay = 0; - virtual void set_swipe_with_pause(bool enable) noexcept override; - - virtual bool click(const Point& p) override; - - virtual bool swipe(const Point& p1, const Point& p2, int duration = 0, bool extra_swipe = false, - double slope_in = 1, double slope_out = 1, bool with_pause = false) override; - - virtual bool inject_input_event(const InputEvent& event) override; - - virtual ControlFeat::Feat support_features() const noexcept override; - - MinitouchController& operator=(const MinitouchController&) = delete; - MinitouchController& operator=(MinitouchController&&) = delete; - - virtual void back_to_home() noexcept override; - - protected: - virtual std::optional reconnect(const std::string& cmd, int64_t timeout, - bool recv_by_socket) override; - - bool call_and_hup_minitouch(); - - bool probe_minitouch(const AdbCfg& adb_cfg, std::function cmd_replace); - - bool input_to_minitouch(const std::string& cmd); - void release_minitouch(bool force = false); - - bool use_swipe_with_pause() const noexcept; - - virtual void clear_info() noexcept override; - - bool m_minitouch_available = false; - bool m_use_maa_touch = false; - bool m_swipe_with_pause_enabled = false; - - std::shared_ptr m_minitouch_handler = nullptr; - - class Minitoucher; - std::unique_ptr m_minitoucher = nullptr; - - struct MinitouchProps + Minitoucher(InputFunc func, const MinitouchProps& props) : + m_input_func(func), + m_props(props) { - int max_contacts = 0; - int max_x = 0; - int max_y = 0; - int max_pressure = 0; + } - double x_scaling = 0; - double y_scaling = 0; - int orientation = 0; - } m_minitouch_props; + ~Minitoucher() = default; - class Minitoucher + // nodiscard! for false return value may indicating *this got replaced in m_input_func + [[nodiscard]] bool reset() { return m_input_func(reset_cmd()); } + + [[nodiscard]] bool commit() { return m_input_func(commit_cmd()); } + + [[nodiscard]] bool down(int x, int y, int wait_ms = DefaultClickDelay, bool with_commit = true, int contact = 0) { - public: - using InputFunc = std::function; + return m_input_func(down_cmd(x, y, wait_ms, with_commit, contact)); + } - public: - static constexpr int DefaultClickDelay = 50; - static constexpr int DefaultSwipeDelay = 2; - static constexpr int ExtraDelay = 0; + [[nodiscard]] bool move(int x, int y, int wait_ms = DefaultSwipeDelay, bool with_commit = true, int contact = 0) + { + return m_input_func(move_cmd(x, y, wait_ms, with_commit, contact)); + } - Minitoucher(InputFunc func, const MinitouchProps& props) : m_input_func(func), m_props(props) {} + [[nodiscard]] bool up(int wait_ms = DefaultClickDelay, bool with_commit = true, int contact = 0) + { + return m_input_func(up_cmd(wait_ms, with_commit, contact)); + } - ~Minitoucher() = default; + [[nodiscard]] bool key_down(int key_code, int wait_ms = DefaultClickDelay, bool with_commit = true) + { + return m_input_func(key_down_cmd(key_code, wait_ms, with_commit)); + } - // nodiscard! for false return value may indicating *this got replaced in m_input_func - [[nodiscard]] bool reset() { return m_input_func(reset_cmd()); } - [[nodiscard]] bool commit() { return m_input_func(commit_cmd()); } - [[nodiscard]] bool down(int x, int y, int wait_ms = DefaultClickDelay, bool with_commit = true, - int contact = 0) - { - return m_input_func(down_cmd(x, y, wait_ms, with_commit, contact)); - } - [[nodiscard]] bool move(int x, int y, int wait_ms = DefaultSwipeDelay, bool with_commit = true, - int contact = 0) - { - return m_input_func(move_cmd(x, y, wait_ms, with_commit, contact)); - } - [[nodiscard]] bool up(int wait_ms = DefaultClickDelay, bool with_commit = true, int contact = 0) - { - return m_input_func(up_cmd(wait_ms, with_commit, contact)); - } - [[nodiscard]] bool key_down(int key_code, int wait_ms = DefaultClickDelay, bool with_commit = true) - { - return m_input_func(key_down_cmd(key_code, wait_ms, with_commit)); - } - [[nodiscard]] bool key_up(int key_code, int wait_ms = DefaultClickDelay, bool with_commit = true) - { - return m_input_func(key_up_cmd(key_code, wait_ms, with_commit)); - } - [[nodiscard]] bool wait(int ms) { return m_input_func(wait_cmd(ms)); } - void clear() noexcept { m_wait_ms_count = 0; } + [[nodiscard]] bool key_up(int key_code, int wait_ms = DefaultClickDelay, bool with_commit = true) + { + return m_input_func(key_up_cmd(key_code, wait_ms, with_commit)); + } - void extra_sleep() { sleep(); } + [[nodiscard]] bool wait(int ms) { return m_input_func(wait_cmd(ms)); } - private: - [[nodiscard]] std::string reset_cmd() const noexcept { return "r\n"; } - [[nodiscard]] std::string commit_cmd() const noexcept { return "c\n"; } + void clear() noexcept { m_wait_ms_count = 0; } + + void extra_sleep() { sleep(); } + + private: + [[nodiscard]] std::string reset_cmd() const noexcept { return "r\n"; } + + [[nodiscard]] std::string commit_cmd() const noexcept { return "c\n"; } #ifdef _MSC_VER #pragma warning(push) -#pragma warning(disable : 4996) +#pragma warning(disable: 4996) #endif - [[nodiscard]] std::string down_cmd(int x, int y, int wait_ms = DefaultClickDelay, bool with_commit = true, - int contact = 0) - { - // mac 编不过 - // std::string str = std::format("d {} {} {} {}\n", contact, x, y, pressure); + [[nodiscard]] std::string + down_cmd(int x, int y, int wait_ms = DefaultClickDelay, bool with_commit = true, int contact = 0) + { + // mac 编不过 + // std::string str = std::format("d {} {} {} {}\n", contact, x, y, pressure); - char buff[64] = { 0 }; - auto [c_x, c_y] = scale(x, y); - sprintf(buff, "d %d %d %d %d\n", contact, c_x, c_y, m_props.max_pressure); - std::string str = buff; + char buff[64] = { 0 }; + auto [c_x, c_y] = scale(x, y); + sprintf(buff, "d %d %d %d %d\n", contact, c_x, c_y, m_props.max_pressure); + std::string str = buff; - if (with_commit) str += commit_cmd(); - if (wait_ms) str += wait_cmd(wait_ms); - return str; + if (with_commit) { + str += commit_cmd(); } - - [[nodiscard]] std::string move_cmd(int x, int y, int wait_ms = DefaultSwipeDelay, bool with_commit = true, - int contact = 0) - { - char buff[64] = { 0 }; - auto [c_x, c_y] = scale(x, y); - sprintf(buff, "m %d %d %d %d\n", contact, c_x, c_y, m_props.max_pressure); - std::string str = buff; - - if (with_commit) str += commit_cmd(); - if (wait_ms) str += wait_cmd(wait_ms); - return str; + if (wait_ms) { + str += wait_cmd(wait_ms); } + return str; + } - [[nodiscard]] std::string up_cmd(int wait_ms = DefaultClickDelay, bool with_commit = true, int contact = 0) - { - char buff[16] = { 0 }; - sprintf(buff, "u %d\n", contact); - std::string str = buff; + [[nodiscard]] std::string + move_cmd(int x, int y, int wait_ms = DefaultSwipeDelay, bool with_commit = true, int contact = 0) + { + char buff[64] = { 0 }; + auto [c_x, c_y] = scale(x, y); + sprintf(buff, "m %d %d %d %d\n", contact, c_x, c_y, m_props.max_pressure); + std::string str = buff; - if (with_commit) str += commit_cmd(); - if (wait_ms) str += wait_cmd(wait_ms); - return str; + if (with_commit) { + str += commit_cmd(); } - - [[nodiscard]] std::string key_down_cmd(int key_code, int wait_ms = DefaultClickDelay, - bool with_commit = true) - { - char buff[64] = { 0 }; - sprintf(buff, "k %d d\n", key_code); - std::string str = buff; - - if (with_commit) str += commit_cmd(); - if (wait_ms) str += wait_cmd(wait_ms); - return str; + if (wait_ms) { + str += wait_cmd(wait_ms); } + return str; + } - [[nodiscard]] std::string key_up_cmd(int key_code, int wait_ms = DefaultClickDelay, bool with_commit = true) - { - char buff[64] = { 0 }; - sprintf(buff, "k %d u\n", key_code); - std::string str = buff; + [[nodiscard]] std::string up_cmd(int wait_ms = DefaultClickDelay, bool with_commit = true, int contact = 0) + { + char buff[16] = { 0 }; + sprintf(buff, "u %d\n", contact); + std::string str = buff; - if (with_commit) str += commit_cmd(); - if (wait_ms) str += wait_cmd(wait_ms); - return str; + if (with_commit) { + str += commit_cmd(); } - - [[nodiscard]] std::string wait_cmd(int ms) - { - m_wait_ms_count += ms; - char buff[16] = { 0 }; - sprintf(buff, "w %d\n", ms); - return buff; + if (wait_ms) { + str += wait_cmd(wait_ms); } + return str; + } + + [[nodiscard]] std::string key_down_cmd(int key_code, int wait_ms = DefaultClickDelay, bool with_commit = true) + { + char buff[64] = { 0 }; + sprintf(buff, "k %d d\n", key_code); + std::string str = buff; + + if (with_commit) { + str += commit_cmd(); + } + if (wait_ms) { + str += wait_cmd(wait_ms); + } + return str; + } + + [[nodiscard]] std::string key_up_cmd(int key_code, int wait_ms = DefaultClickDelay, bool with_commit = true) + { + char buff[64] = { 0 }; + sprintf(buff, "k %d u\n", key_code); + std::string str = buff; + + if (with_commit) { + str += commit_cmd(); + } + if (wait_ms) { + str += wait_cmd(wait_ms); + } + return str; + } + + [[nodiscard]] std::string wait_cmd(int ms) + { + m_wait_ms_count += ms; + char buff[16] = { 0 }; + sprintf(buff, "w %d\n", ms); + return buff; + } #ifdef _MSC_VER #pragma warning(pop) #endif - void sleep() - { - using namespace std::chrono_literals; - std::this_thread::sleep_for(m_wait_ms_count * 1ms); - m_wait_ms_count = 0; - } + void sleep() + { + using namespace std::chrono_literals; + std::this_thread::sleep_for(m_wait_ms_count * 1ms); + m_wait_ms_count = 0; + } - private: - Point scale(int x, int y) const noexcept - { - switch (m_props.orientation) { - case 0: - default: - return { - static_cast(x * m_props.x_scaling), - static_cast(y * m_props.y_scaling), - }; - case 1: - return { - m_props.max_y - static_cast(y * m_props.y_scaling), - static_cast(x * m_props.x_scaling), - }; - case 2: - return { - m_props.max_x - static_cast(x * m_props.x_scaling), - m_props.max_y - static_cast(y * m_props.y_scaling), - }; - case 3: - return { - static_cast(y * m_props.y_scaling), - m_props.max_x - static_cast(x * m_props.x_scaling), - }; - } + private: + Point scale(int x, int y) const noexcept + { + switch (m_props.orientation) { + case 0: + default: + return { + static_cast(x * m_props.x_scaling), + static_cast(y * m_props.y_scaling), + }; + case 1: + return { + m_props.max_y - static_cast(y * m_props.y_scaling), + static_cast(x * m_props.x_scaling), + }; + case 2: + return { + m_props.max_x - static_cast(x * m_props.x_scaling), + m_props.max_y - static_cast(y * m_props.y_scaling), + }; + case 3: + return { + static_cast(y * m_props.y_scaling), + m_props.max_x - static_cast(x * m_props.x_scaling), + }; } + } - const std::function m_input_func = nullptr; - const MinitouchProps& m_props; - int m_wait_ms_count = ExtraDelay; - }; + const std::function m_input_func = nullptr; + const MinitouchProps& m_props; + int m_wait_ms_count = ExtraDelay; }; +}; } // namespace asst diff --git a/src/MaaCore/Controller/Platform/AdbLiteIO.cpp b/src/MaaCore/Controller/Platform/AdbLiteIO.cpp index d61998ed71..61d81cd7d3 100644 --- a/src/MaaCore/Controller/Platform/AdbLiteIO.cpp +++ b/src/MaaCore/Controller/Platform/AdbLiteIO.cpp @@ -4,9 +4,13 @@ #include "Utils/Logger.hpp" -std::optional asst::AdbLiteIO::call_command(const std::string& cmd, bool recv_by_socket, std::string& pipe_data, - std::string& sock_data, int64_t timeout, - std::chrono::steady_clock::time_point start_time) +std::optional asst::AdbLiteIO::call_command( + const std::string& cmd, + bool recv_by_socket, + std::string& pipe_data, + std::string& sock_data, + int64_t timeout, + std::chrono::steady_clock::time_point start_time) { // TODO: 从上面的 call_command_win32/posix 里抽取出 socket 接收的部分 if (recv_by_socket) { @@ -193,7 +197,9 @@ void asst::AdbLiteIO::release_adb(const std::string& adb_release, int64_t timeou bool asst::AdbLiteIO::remove_quotes(std::string& data) { - if (data.size() < 2) return false; + if (data.size() < 2) { + return false; + } if (data.front() == '"' && data.back() == '"') { data.erase(data.begin()); diff --git a/src/MaaCore/Controller/Platform/AdbLiteIO.h b/src/MaaCore/Controller/Platform/AdbLiteIO.h index d4705bf788..ed054451c1 100644 --- a/src/MaaCore/Controller/Platform/AdbLiteIO.h +++ b/src/MaaCore/Controller/Platform/AdbLiteIO.h @@ -15,44 +15,50 @@ namespace asst { #ifdef _WIN32 - using NativeIO = asst::Win32IO; +using NativeIO = asst::Win32IO; #else - using NativeIO = asst::PosixIO; +using NativeIO = asst::PosixIO; #endif - class AdbLiteIO : public NativeIO - { - public: - AdbLiteIO(Assistant* inst) : NativeIO(inst) {}; - AdbLiteIO(const AdbLiteIO&) = delete; - AdbLiteIO(AdbLiteIO&&) = delete; - virtual ~AdbLiteIO() = default; +class AdbLiteIO : public NativeIO +{ +public: + AdbLiteIO(Assistant* inst) : + NativeIO(inst) {}; + AdbLiteIO(const AdbLiteIO&) = delete; + AdbLiteIO(AdbLiteIO&&) = delete; + virtual ~AdbLiteIO() = default; - virtual std::optional call_command(const std::string& cmd, bool recv_by_socket, std::string& pipe_data, - std::string& sock_data, int64_t timeout, - std::chrono::steady_clock::time_point start_time) override; + virtual std::optional call_command( + const std::string& cmd, + bool recv_by_socket, + std::string& pipe_data, + std::string& sock_data, + int64_t timeout, + std::chrono::steady_clock::time_point start_time) override; - virtual std::shared_ptr interactive_shell(const std::string& cmd) override; + virtual std::shared_ptr interactive_shell(const std::string& cmd) override; - virtual void release_adb(const std::string& adb_release, int64_t timeout = 20000) override; + virtual void release_adb(const std::string& adb_release, int64_t timeout = 20000) override; - private: - static bool remove_quotes(std::string& data); +private: + static bool remove_quotes(std::string& data); - std::shared_ptr m_adb_client = nullptr; - }; + std::shared_ptr m_adb_client = nullptr; +}; - class IOHandlerAdbLite : public IOHandler - { - public: - IOHandlerAdbLite(std::shared_ptr handle) : m_handle(handle) {}; - IOHandlerAdbLite(const IOHandlerAdbLite&) = delete; - IOHandlerAdbLite(IOHandlerAdbLite&&) = delete; - virtual ~IOHandlerAdbLite() = default; +class IOHandlerAdbLite : public IOHandler +{ +public: + IOHandlerAdbLite(std::shared_ptr handle) : + m_handle(handle) {}; + IOHandlerAdbLite(const IOHandlerAdbLite&) = delete; + IOHandlerAdbLite(IOHandlerAdbLite&&) = delete; + virtual ~IOHandlerAdbLite() = default; - virtual bool write(const std::string_view data) override; - virtual std::string read(unsigned timeout_sec) override; + virtual bool write(const std::string_view data) override; + virtual std::string read(unsigned timeout_sec) override; - private: - std::shared_ptr m_handle = nullptr; - }; +private: + std::shared_ptr m_handle = nullptr; +}; } // namespace asst diff --git a/src/MaaCore/Controller/Platform/PlatformFactory.h b/src/MaaCore/Controller/Platform/PlatformFactory.h index 8a6ecc4030..f18e3ee7c2 100644 --- a/src/MaaCore/Controller/Platform/PlatformFactory.h +++ b/src/MaaCore/Controller/Platform/PlatformFactory.h @@ -9,19 +9,19 @@ namespace asst { - class PlatformFactory +class PlatformFactory +{ +public: + static std::shared_ptr create_platform(Assistant* inst, PlatformType type) { - public: - static std::shared_ptr create_platform(Assistant* inst, PlatformType type) - { - switch (type) { - case PlatformType::AdbLite: - return std::make_shared(inst); - case PlatformType::Native: - return std::make_shared(inst); - default: - return nullptr; - } + switch (type) { + case PlatformType::AdbLite: + return std::make_shared(inst); + case PlatformType::Native: + return std::make_shared(inst); + default: + return nullptr; } - }; + } +}; } diff --git a/src/MaaCore/Controller/Platform/PlatformIO.h b/src/MaaCore/Controller/Platform/PlatformIO.h index 2aa06ef58f..f0f67c4476 100644 --- a/src/MaaCore/Controller/Platform/PlatformIO.h +++ b/src/MaaCore/Controller/Platform/PlatformIO.h @@ -7,39 +7,43 @@ namespace asst { - class IOHandler; +class IOHandler; - enum class PlatformType - { - Native, // Win32IO or PosixIO - AdbLite // AdbLiteIO - }; +enum class PlatformType +{ + Native, // Win32IO or PosixIO + AdbLite // AdbLiteIO +}; - class PlatformIO - { - public: - virtual ~PlatformIO() = default; +class PlatformIO +{ +public: + virtual ~PlatformIO() = default; - virtual std::optional call_command(const std::string& cmd, bool recv_by_socket, std::string& pipe_data, - std::string& sock_data, int64_t timeout, - std::chrono::steady_clock::time_point start_time) = 0; + virtual std::optional call_command( + const std::string& cmd, + bool recv_by_socket, + std::string& pipe_data, + std::string& sock_data, + int64_t timeout, + std::chrono::steady_clock::time_point start_time) = 0; - virtual std::optional init_socket(const std::string& local_address) = 0; - virtual void close_socket() noexcept = 0; + virtual std::optional init_socket(const std::string& local_address) = 0; + virtual void close_socket() noexcept = 0; - virtual std::shared_ptr interactive_shell(const std::string& cmd) = 0; + virtual std::shared_ptr interactive_shell(const std::string& cmd) = 0; - virtual void release_adb(const std::string& adb_release, int64_t timeout = 20000) = 0; + virtual void release_adb(const std::string& adb_release, int64_t timeout = 20000) = 0; - bool m_support_socket = false; - }; + bool m_support_socket = false; +}; - class IOHandler - { - public: - virtual ~IOHandler() = default; +class IOHandler +{ +public: + virtual ~IOHandler() = default; - virtual bool write(std::string_view data) = 0; - virtual std::string read(unsigned timeout_sec) = 0; - }; + virtual bool write(std::string_view data) = 0; + virtual std::string read(unsigned timeout_sec) = 0; +}; } diff --git a/src/MaaCore/Controller/Platform/PosixIO.cpp b/src/MaaCore/Controller/Platform/PosixIO.cpp index 850a5fc217..f7e2fb523e 100644 --- a/src/MaaCore/Controller/Platform/PosixIO.cpp +++ b/src/MaaCore/Controller/Platform/PosixIO.cpp @@ -19,7 +19,8 @@ #include "Utils/Logger.hpp" #include "Utils/NoWarningCV.h" -asst::PosixIO::PosixIO(Assistant* inst) : InstHelper(inst) +asst::PosixIO::PosixIO(Assistant* inst) : + InstHelper(inst) { LogTraceFunction; @@ -36,9 +37,13 @@ asst::PosixIO::~PosixIO() } } -std::optional asst::PosixIO::call_command(const std::string& cmd, const bool recv_by_socket, - std::string& pipe_data, std::string& sock_data, const int64_t timeout, - std::chrono::steady_clock::time_point start_time) +std::optional asst::PosixIO::call_command( + const std::string& cmd, + const bool recv_by_socket, + std::string& pipe_data, + std::string& sock_data, + const int64_t timeout, + std::chrono::steady_clock::time_point start_time) { using namespace std::chrono; @@ -208,7 +213,9 @@ std::shared_ptr asst::PosixIO::interactive_shell(const std::str int pipe_to_child[2]; int pipe_from_child[2]; - if (::pipe(pipe_to_child)) return nullptr; + if (::pipe(pipe_to_child)) { + return nullptr; + } if (::pipe(pipe_from_child)) { ::close(pipe_to_child[0]); ::close(pipe_to_child[1]); @@ -283,22 +290,34 @@ void asst::PosixIO::release_adb(const std::string& adb_release, int64_t timeout) asst::IOHandlerPosix::~IOHandlerPosix() { - if (m_write_fd != -1) ::close(m_write_fd); - if (m_read_fd != -1) ::close(m_read_fd); - if (m_process > 0) ::kill(m_process, SIGTERM); + if (m_write_fd != -1) { + ::close(m_write_fd); + } + if (m_read_fd != -1) { + ::close(m_read_fd); + } + if (m_process > 0) { + ::kill(m_process, SIGTERM); + } } bool asst::IOHandlerPosix::write(std::string_view data) { - if (m_process < 0 || m_write_fd < 0) return false; - if (::write(m_write_fd, data.data(), data.length()) >= 0) return true; + if (m_process < 0 || m_write_fd < 0) { + return false; + } + if (::write(m_write_fd, data.data(), data.length()) >= 0) { + return true; + } Log.error("Failed to write to IOHandlerPosix, err", errno); return false; } std::string asst::IOHandlerPosix::read(unsigned timeout_sec) { - if (m_process < 0 || m_read_fd < 0) return {}; + if (m_process < 0 || m_read_fd < 0) { + return {}; + } std::string ret_str; constexpr int PipeReadBuffSize = 4096ULL; diff --git a/src/MaaCore/Controller/Platform/PosixIO.h b/src/MaaCore/Controller/Platform/PosixIO.h index 4cd4f1be0a..adf62a3ebe 100644 --- a/src/MaaCore/Controller/Platform/PosixIO.h +++ b/src/MaaCore/Controller/Platform/PosixIO.h @@ -9,54 +9,59 @@ namespace asst { - class PosixIO : public PlatformIO, private InstHelper +class PosixIO : public PlatformIO, private InstHelper +{ +public: + PosixIO(Assistant* inst); + PosixIO(const PosixIO&) = delete; + PosixIO(PosixIO&&) = delete; + virtual ~PosixIO(); + + virtual std::optional call_command( + const std::string& cmd, + bool recv_by_socket, + std::string& pipe_data, + std::string& sock_data, + int64_t timeout, + std::chrono::steady_clock::time_point start_time) override; + + virtual std::optional init_socket(const std::string& local_address) override; + virtual void close_socket() noexcept override; + + virtual std::shared_ptr interactive_shell(const std::string& cmd) override; + + virtual void release_adb(const std::string& adb_release, int64_t timeout = 20000) override; + + int m_server_sock = -1; + sockaddr_in m_server_sock_addr {}; + static constexpr int PIPE_READ = 0; + static constexpr int PIPE_WRITE = 1; + int m_pipe_in[2] = { 0 }; + int m_pipe_out[2] = { 0 }; + int m_child = 0; +}; + +class IOHandlerPosix : public IOHandler +{ +public: + IOHandlerPosix(int read_fd, int write_fd, ::pid_t process) { - public: - PosixIO(Assistant* inst); - PosixIO(const PosixIO&) = delete; - PosixIO(PosixIO&&) = delete; - virtual ~PosixIO(); + m_read_fd = read_fd; + m_write_fd = write_fd; + m_process = process; + } - virtual std::optional call_command(const std::string& cmd, bool recv_by_socket, std::string& pipe_data, - std::string& sock_data, int64_t timeout, - std::chrono::steady_clock::time_point start_time) override; + IOHandlerPosix(const IOHandlerPosix&) = delete; + IOHandlerPosix(IOHandlerPosix&&) = delete; + virtual ~IOHandlerPosix() override; - virtual std::optional init_socket(const std::string& local_address) override; - virtual void close_socket() noexcept override; + virtual bool write(std::string_view data) override; + virtual std::string read(unsigned timeout_sec) override; - virtual std::shared_ptr interactive_shell(const std::string& cmd) override; - - virtual void release_adb(const std::string& adb_release, int64_t timeout = 20000) override; - - int m_server_sock = -1; - sockaddr_in m_server_sock_addr {}; - static constexpr int PIPE_READ = 0; - static constexpr int PIPE_WRITE = 1; - int m_pipe_in[2] = { 0 }; - int m_pipe_out[2] = { 0 }; - int m_child = 0; - }; - - class IOHandlerPosix : public IOHandler - { - public: - IOHandlerPosix(int read_fd, int write_fd, ::pid_t process) - { - m_read_fd = read_fd; - m_write_fd = write_fd; - m_process = process; - } - IOHandlerPosix(const IOHandlerPosix&) = delete; - IOHandlerPosix(IOHandlerPosix&&) = delete; - virtual ~IOHandlerPosix() override; - - virtual bool write(std::string_view data) override; - virtual std::string read(unsigned timeout_sec) override; - - private: - int m_read_fd = -1; - int m_write_fd = -1; - ::pid_t m_process = -1; - }; +private: + int m_read_fd = -1; + int m_write_fd = -1; + ::pid_t m_process = -1; +}; } #endif diff --git a/src/MaaCore/Controller/Platform/Win32IO.cpp b/src/MaaCore/Controller/Platform/Win32IO.cpp index 0a0638db33..e35ecf4418 100644 --- a/src/MaaCore/Controller/Platform/Win32IO.cpp +++ b/src/MaaCore/Controller/Platform/Win32IO.cpp @@ -5,7 +5,8 @@ #include "Utils/Logger.hpp" -asst::Win32IO::Win32IO(Assistant* inst) : InstHelper(inst) +asst::Win32IO::Win32IO(Assistant* inst) : + InstHelper(inst) { LogTraceFunction; @@ -20,9 +21,13 @@ asst::Win32IO::~Win32IO() } } -std::optional asst::Win32IO::call_command(const std::string& cmd, bool recv_by_socket, std::string& pipe_data, - std::string& sock_data, int64_t timeout, - std::chrono::steady_clock::time_point start_time) +std::optional asst::Win32IO::call_command( + const std::string& cmd, + bool recv_by_socket, + std::string& pipe_data, + std::string& sock_data, + int64_t timeout, + std::chrono::steady_clock::time_point start_time) { using namespace std::chrono; @@ -31,8 +36,14 @@ std::optional asst::Win32IO::call_command(const std::string& cmd, bool recv HANDLE pipe_parent_read = INVALID_HANDLE_VALUE, pipe_child_write = INVALID_HANDLE_VALUE; SECURITY_ATTRIBUTES sa_inherit { .nLength = sizeof(SECURITY_ATTRIBUTES), .bInheritHandle = TRUE }; - if (!asst::win32::CreateOverlappablePipe(&pipe_parent_read, &pipe_child_write, nullptr, &sa_inherit, - (DWORD)pipe_buffer.size(), true, false)) { + if (!asst::win32::CreateOverlappablePipe( + &pipe_parent_read, + &pipe_child_write, + nullptr, + &sa_inherit, + (DWORD)pipe_buffer.size(), + true, + false)) { DWORD err = GetLastError(); Log.error("CreateOverlappablePipe failed, err", err); return std::nullopt; @@ -64,15 +75,31 @@ std::optional asst::Win32IO::call_command(const std::string& cmd, bool recv Log.error("Call `", cmd, "` InitializeProcThreadAttributeList failed, ret error code:", err); return std::nullopt; } - attr_success = UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &pipe_child_write, sizeof(HANDLE), nullptr, nullptr); + attr_success = UpdateProcThreadAttribute( + si.lpAttributeList, + 0, + PROC_THREAD_ATTRIBUTE_HANDLE_LIST, + &pipe_child_write, + sizeof(HANDLE), + nullptr, + nullptr); if (!attr_success) { DWORD err = GetLastError(); Log.error("Call `", cmd, "` UpdateProcThreadAttribute failed, ret error code:", err); return std::nullopt; } auto cmdline_osstr = asst::utils::to_osstring(cmd); - BOOL create_ret = - CreateProcessW(nullptr, cmdline_osstr.data(), nullptr, nullptr, TRUE, EXTENDED_STARTUPINFO_PRESENT, nullptr, nullptr, &si.StartupInfo, &process_info); + BOOL create_ret = CreateProcessW( + nullptr, + cmdline_osstr.data(), + nullptr, + nullptr, + TRUE, + EXTENDED_STARTUPINFO_PRESENT, + nullptr, + nullptr, + &si.StartupInfo, + &process_info); DeleteProcThreadAttributeList(si.lpAttributeList); if (!create_ret) { DWORD err = GetLastError(); @@ -101,9 +128,15 @@ std::optional asst::Win32IO::call_command(const std::string& cmd, bool recv sockov.hEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr); client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); DWORD dummy; - if (!m_server_accept_ex(m_server_sock, client_socket, sock_buffer.get(), - (DWORD)sock_buffer.size() - ((sizeof(sockaddr_in) + 16) * 2), sizeof(sockaddr_in) + 16, - sizeof(sockaddr_in) + 16, &dummy, &sockov)) { + if (!m_server_accept_ex( + m_server_sock, + client_socket, + sock_buffer.get(), + (DWORD)sock_buffer.size() - ((sizeof(sockaddr_in) + 16) * 2), + sizeof(sockaddr_in) + 16, + sizeof(sockaddr_in) + 16, + &dummy, + &sockov)) { DWORD err = WSAGetLastError(); if (err == ERROR_IO_PENDING) { accept_pending = true; @@ -119,16 +152,24 @@ std::optional asst::Win32IO::call_command(const std::string& cmd, bool recv while (!need_exit()) { wait_handles.clear(); - if (process_running) wait_handles.push_back(process_info.hProcess); - if (!pipe_eof) wait_handles.push_back(pipeov.hEvent); + if (process_running) { + wait_handles.push_back(process_info.hProcess); + } + if (!pipe_eof) { + wait_handles.push_back(pipeov.hEvent); + } if (recv_by_socket && ((accept_pending && process_running) || !socket_eof)) { wait_handles.push_back(sockov.hEvent); } - if (wait_handles.empty()) break; + if (wait_handles.empty()) { + break; + } auto elapsed = steady_clock::now() - start_time; // TODO: 这里目前是隔 5000ms 判断一次,应该可以加一个 wait_handle 来判断外部中断(need_exit) auto wait_time = (std::min)(timeout - duration_cast(elapsed).count(), 5LL * 1000); - if (wait_time < 0 || !process_running) wait_time = 0; + if (wait_time < 0 || !process_running) { + wait_time = 0; + } auto wait_result = WaitForMultipleObjectsEx((DWORD)wait_handles.size(), wait_handles.data(), FALSE, (DWORD)wait_time, TRUE); HANDLE signaled_object = INVALID_HANDLE_VALUE; @@ -203,7 +244,9 @@ std::optional asst::Win32IO::call_command(const std::string& cmd, bool recv DWORD len = 0; if (GetOverlappedResult(reinterpret_cast(m_server_sock), &sockov, &len, FALSE)) { accept_pending = false; - if (recv_by_socket) sock_data.insert(sock_data.end(), sock_buffer.get(), sock_buffer.get() + len); + if (recv_by_socket) { + sock_data.insert(sock_data.end(), sock_buffer.get(), sock_buffer.get() + len); + } if (len == 0) { socket_eof = true; @@ -215,8 +258,12 @@ std::optional asst::Win32IO::call_command(const std::string& cmd, bool recv sockov = {}; sockov.hEvent = event; - (void)ReadFile(reinterpret_cast(client_socket), sock_buffer.get(), - (DWORD)sock_buffer.size(), nullptr, &sockov); + (void)ReadFile( + reinterpret_cast(client_socket), + sock_buffer.get(), + (DWORD)sock_buffer.size(), + nullptr, + &sockov); } } } @@ -224,14 +271,20 @@ std::optional asst::Win32IO::call_command(const std::string& cmd, bool recv // ReadFile DWORD len = 0; if (GetOverlappedResult(reinterpret_cast(client_socket), &sockov, &len, FALSE)) { - if (recv_by_socket) sock_data.insert(sock_data.end(), sock_buffer.get(), sock_buffer.get() + len); + if (recv_by_socket) { + sock_data.insert(sock_data.end(), sock_buffer.get(), sock_buffer.get() + len); + } if (len == 0) { socket_eof = true; ::closesocket(client_socket); } else { - (void)ReadFile(reinterpret_cast(client_socket), sock_buffer.get(), - (DWORD)sock_buffer.size(), nullptr, &sockov); + (void)ReadFile( + reinterpret_cast(client_socket), + sock_buffer.get(), + (DWORD)sock_buffer.size(), + nullptr, + &sockov); } } else { @@ -283,8 +336,16 @@ std::optional asst::Win32IO::init_socket(const std::string& loca DWORD dummy = 0; GUID guid_accept_ex = WSAID_ACCEPTEX; - int err = WSAIoctl(m_server_sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid_accept_ex, sizeof(guid_accept_ex), - &m_server_accept_ex, sizeof(m_server_accept_ex), &dummy, NULL, NULL); + int err = WSAIoctl( + m_server_sock, + SIO_GET_EXTENSION_FUNCTION_POINTER, + &guid_accept_ex, + sizeof(guid_accept_ex), + &m_server_accept_ex, + sizeof(m_server_accept_ex), + &dummy, + NULL, + NULL); if (err == SOCKET_ERROR) { err = WSAGetLastError(); Log.error("failed to resolve AcceptEx, err:", err); @@ -336,16 +397,27 @@ std::shared_ptr asst::Win32IO::interactive_shell(const std::str PROCESS_INFORMATION m_process_info = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0 }; HANDLE pipe_parent_read = INVALID_HANDLE_VALUE, pipe_child_write = INVALID_HANDLE_VALUE; HANDLE pipe_child_read = INVALID_HANDLE_VALUE, pipe_parent_write = INVALID_HANDLE_VALUE; - if (!asst::win32::CreateOverlappablePipe(&pipe_parent_read, &pipe_child_write, nullptr, &sa_attr_inherit, - PipeReadBuffSize, true, false) || - !asst::win32::CreateOverlappablePipe(&pipe_child_read, &pipe_parent_write, &sa_attr_inherit, nullptr, - PipeWriteBuffSize, false, false)) { + if (!asst::win32::CreateOverlappablePipe( + &pipe_parent_read, + &pipe_child_write, + nullptr, + &sa_attr_inherit, + PipeReadBuffSize, + true, + false) || + !asst::win32::CreateOverlappablePipe( + &pipe_child_read, + &pipe_parent_write, + &sa_attr_inherit, + nullptr, + PipeWriteBuffSize, + false, + false)) { DWORD err = GetLastError(); Log.error("Failed to create pipe for minitouch, err", err); return nullptr; } - HANDLE handles_to_inherit[] = { pipe_child_read, pipe_child_write }; STARTUPINFOEXW si {}; si.StartupInfo.cb = sizeof(STARTUPINFOEXW); @@ -371,15 +443,31 @@ std::shared_ptr asst::Win32IO::interactive_shell(const std::str Log.error("Call `", cmd, "` InitializeProcThreadAttributeList failed, ret error code:", err); return nullptr; } - attr_success = UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, &handles_to_inherit, sizeof(handles_to_inherit), nullptr, nullptr); + attr_success = UpdateProcThreadAttribute( + si.lpAttributeList, + 0, + PROC_THREAD_ATTRIBUTE_HANDLE_LIST, + &handles_to_inherit, + sizeof(handles_to_inherit), + nullptr, + nullptr); if (!attr_success) { DWORD err = GetLastError(); Log.error("Call `", cmd, "` UpdateProcThreadAttribute failed, ret error code:", err); return nullptr; } auto cmd_osstr = utils::to_osstring(cmd); - BOOL create_ret = - CreateProcessW(NULL, cmd_osstr.data(), nullptr, nullptr, TRUE, EXTENDED_STARTUPINFO_PRESENT, nullptr, nullptr, &si.StartupInfo, &m_process_info); + BOOL create_ret = CreateProcessW( + NULL, + cmd_osstr.data(), + nullptr, + nullptr, + TRUE, + EXTENDED_STARTUPINFO_PRESENT, + nullptr, + nullptr, + &si.StartupInfo, + &m_process_info); DeleteProcThreadAttributeList(si.lpAttributeList); CloseHandle(pipe_child_write); @@ -464,8 +552,12 @@ bool asst::IOHandlerWin32::write(std::string_view data) return false; } DWORD written = 0; - if (!WriteFile(m_write, data.data(), static_cast(data.size() * sizeof(std::string::value_type)), &written, - NULL)) { + if (!WriteFile( + m_write, + data.data(), + static_cast(data.size() * sizeof(std::string::value_type)), + &written, + NULL)) { auto err = GetLastError(); Log.error("Failed to write to IOHandlerWin32, err", err); return false; diff --git a/src/MaaCore/Controller/Platform/Win32IO.h b/src/MaaCore/Controller/Platform/Win32IO.h index 445426bcb8..71bf2ae594 100644 --- a/src/MaaCore/Controller/Platform/Win32IO.h +++ b/src/MaaCore/Controller/Platform/Win32IO.h @@ -12,71 +12,81 @@ namespace asst { - class Win32IO : public PlatformIO, private InstHelper +class Win32IO : public PlatformIO, private InstHelper +{ +public: + Win32IO(Assistant* inst); + Win32IO(const Win32IO&) = delete; + Win32IO(Win32IO&&) = delete; + virtual ~Win32IO(); + + virtual std::optional call_command( + const std::string& cmd, + bool recv_by_socket, + std::string& pipe_data, + std::string& sock_data, + int64_t timeout, + std::chrono::steady_clock::time_point start_time) override; + + virtual std::optional init_socket(const std::string& local_address) override; + virtual void close_socket() noexcept override; + + virtual std::shared_ptr interactive_shell(const std::string& cmd) override; + + virtual void release_adb(const std::string& adb_release, int64_t timeout = 20000); + + ASST_AUTO_DEDUCED_ZERO_INIT_START + WSADATA m_wsa_data {}; + SOCKET m_server_sock = INVALID_SOCKET; + sockaddr_in m_server_sock_addr {}; + LPFN_ACCEPTEX m_server_accept_ex = nullptr; + ASST_AUTO_DEDUCED_ZERO_INIT_END + +private: + // for Windows socket + class WsaHelper : public SingletonHolder { + friend class SingletonHolder; + public: - Win32IO(Assistant* inst); - Win32IO(const Win32IO&) = delete; - Win32IO(Win32IO&&) = delete; - virtual ~Win32IO(); + virtual ~WsaHelper() override { WSACleanup(); } - virtual std::optional call_command(const std::string& cmd, bool recv_by_socket, std::string& pipe_data, - std::string& sock_data, int64_t timeout, - std::chrono::steady_clock::time_point start_time) override; - - virtual std::optional init_socket(const std::string& local_address) override; - virtual void close_socket() noexcept override; - - virtual std::shared_ptr interactive_shell(const std::string& cmd) override; - - virtual void release_adb(const std::string& adb_release, int64_t timeout = 20000); - - ASST_AUTO_DEDUCED_ZERO_INIT_START - WSADATA m_wsa_data {}; - SOCKET m_server_sock = INVALID_SOCKET; - sockaddr_in m_server_sock_addr {}; - LPFN_ACCEPTEX m_server_accept_ex = nullptr; - ASST_AUTO_DEDUCED_ZERO_INIT_END + bool operator()() const noexcept { return m_supports; } private: - // for Windows socket - class WsaHelper : public SingletonHolder + WsaHelper() { - friend class SingletonHolder; + m_supports = WSAStartup(MAKEWORD(2, 2), &m_wsa_data) == 0 && m_wsa_data.wVersion == MAKEWORD(2, 2); + } - public: - virtual ~WsaHelper() override { WSACleanup(); } - bool operator()() const noexcept { return m_supports; } - - private: - WsaHelper() - { - m_supports = WSAStartup(MAKEWORD(2, 2), &m_wsa_data) == 0 && m_wsa_data.wVersion == MAKEWORD(2, 2); - } - WSADATA m_wsa_data = { 0 }; - bool m_supports = false; - }; + WSADATA m_wsa_data = { 0 }; + bool m_supports = false; }; +}; - class IOHandlerWin32 : public IOHandler +class IOHandlerWin32 : public IOHandler +{ +public: + IOHandlerWin32(HANDLE read, HANDLE write, PROCESS_INFORMATION process_info) : + m_read(read), + m_write(write), + m_process_info(process_info) { - public: - IOHandlerWin32(HANDLE read, HANDLE write, PROCESS_INFORMATION process_info) - : m_read(read), m_write(write), m_process_info(process_info) - {} - IOHandlerWin32(const IOHandlerWin32&) = delete; - IOHandlerWin32(IOHandlerWin32&&) = delete; - virtual ~IOHandlerWin32(); + } - virtual bool write(std::string_view data) override; - virtual std::string read(unsigned timeout_sec) override; + IOHandlerWin32(const IOHandlerWin32&) = delete; + IOHandlerWin32(IOHandlerWin32&&) = delete; + virtual ~IOHandlerWin32(); - private: - HANDLE m_read = INVALID_HANDLE_VALUE; - HANDLE m_write = INVALID_HANDLE_VALUE; - PROCESS_INFORMATION m_process_info = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0 }; + virtual bool write(std::string_view data) override; + virtual std::string read(unsigned timeout_sec) override; - const int PipeBufferSize = 4096; - }; +private: + HANDLE m_read = INVALID_HANDLE_VALUE; + HANDLE m_write = INVALID_HANDLE_VALUE; + PROCESS_INFORMATION m_process_info = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0 }; + + const int PipeBufferSize = 4096; +}; } // namespace asst #endif diff --git a/src/MaaCore/Controller/PlayToolsController.cpp b/src/MaaCore/Controller/PlayToolsController.cpp index e9bc6b78de..e8db7ae617 100644 --- a/src/MaaCore/Controller/PlayToolsController.cpp +++ b/src/MaaCore/Controller/PlayToolsController.cpp @@ -11,10 +11,10 @@ namespace socket_ops = asio::detail::socket_ops; asst::PlayToolsController::PlayToolsController( const AsstCallback& callback, Assistant* inst, - PlatformType type [[maybe_unused]]) - : InstHelper(inst) - , m_callback(callback) - , m_socket(m_context) + PlatformType type [[maybe_unused]]) : + InstHelper(inst), + m_callback(callback), + m_socket(m_context) { LogTraceFunction; } @@ -58,9 +58,7 @@ size_t asst::PlayToolsController::get_version() const noexcept return size_t(); } -bool asst::PlayToolsController::screencap( - cv::Mat& image_payload, - bool allow_reconnect [[maybe_unused]]) +bool asst::PlayToolsController::screencap(cv::Mat& image_payload, bool allow_reconnect [[maybe_unused]]) { LogTraceFunction; @@ -156,10 +154,8 @@ bool asst::PlayToolsController::swipe( }; // TODO: move this to math.hpp const auto progressive_move = [&](int _x1, int _y1, int _x2, int _y2, int _duration) { - for (int cur_time = DefaultSwipeDelay; cur_time < _duration; - cur_time += DefaultSwipeDelay) { - double progress = - cubic_spline(slope_in, slope_out, static_cast(cur_time) / duration); + for (int cur_time = DefaultSwipeDelay; cur_time < _duration; cur_time += DefaultSwipeDelay) { + double progress = cubic_spline(slope_in, slope_out, static_cast(cur_time) / duration); int cur_x = static_cast(std::lerp(_x1, _x2, progress)); int cur_y = static_cast(std::lerp(_y1, _y2, progress)); if (cur_x < 0 || cur_x > width || cur_y < 0 || cur_y > height) { @@ -178,12 +174,7 @@ bool asst::PlayToolsController::swipe( if (extra_swipe && opt.minitouch_extra_swipe_duration > 0) { toucher_wait(opt.minitouch_swipe_extra_end_delay); // 停留终点 - progressive_move( - x2, - y2, - x2, - y2 - opt.minitouch_extra_swipe_dist, - opt.minitouch_extra_swipe_duration); + progressive_move(x2, y2, x2, y2 - opt.minitouch_extra_swipe_dist, opt.minitouch_extra_swipe_duration); } return toucher_up(p2); @@ -324,10 +315,7 @@ bool asst::PlayToolsController::fetch_screen_res() return true; } -bool asst::PlayToolsController::toucher_commit( - const TouchPhase phase, - const Point& p, - const int delay) +bool asst::PlayToolsController::toucher_commit(const TouchPhase phase, const Point& p, const int delay) { open(); uint16_t x = socket_ops::host_to_network_short(static_cast(p.x)); diff --git a/src/MaaCore/Controller/PlayToolsController.h b/src/MaaCore/Controller/PlayToolsController.h index 38ecfecc19..6dfb3ca344 100644 --- a/src/MaaCore/Controller/PlayToolsController.h +++ b/src/MaaCore/Controller/PlayToolsController.h @@ -13,9 +13,7 @@ namespace asst { -class PlayToolsController - : public ControllerAPI - , protected InstHelper +class PlayToolsController : public ControllerAPI, protected InstHelper { public: PlayToolsController(const AsstCallback& callback, Assistant* inst, PlatformType type); @@ -23,10 +21,7 @@ public: PlayToolsController(PlayToolsController&&) = delete; virtual ~PlayToolsController(); - virtual bool connect( - const std::string& adb_path, - const std::string& address, - const std::string& config) override; + virtual bool connect(const std::string& adb_path, const std::string& address, const std::string& config) override; virtual bool inited() const noexcept override; virtual const std::string& get_uuid() const override; @@ -51,17 +46,11 @@ public: double slope_out = 1, bool with_pause = false) override; - virtual bool inject_input_event([[maybe_unused]] const InputEvent& event) override - { - return false; - } + virtual bool inject_input_event([[maybe_unused]] const InputEvent& event) override { return false; } virtual bool press_esc() override; - virtual ControlFeat::Feat support_features() const noexcept override - { - return ControlFeat::NONE; - } + virtual ControlFeat::Feat support_features() const noexcept override { return ControlFeat::NONE; } virtual std::pair get_screen_res() const noexcept override; diff --git a/src/MaaCore/Controller/adb-lite/client.cpp b/src/MaaCore/Controller/adb-lite/client.cpp index 1ff27700ef..39114d1400 100644 --- a/src/MaaCore/Controller/adb-lite/client.cpp +++ b/src/MaaCore/Controller/adb-lite/client.cpp @@ -15,329 +15,330 @@ using adb::protocol::send_sync_request; namespace adb { - static inline std::string version(asio::io_context& context, const tcp_endpoints& endpoints) - { - tcp::socket socket(context); - asio::connect(socket, endpoints); +static inline std::string version(asio::io_context& context, const tcp_endpoints& endpoints) +{ + tcp::socket socket(context); + asio::connect(socket, endpoints); - const auto request = "host:version"; - send_host_request(socket, request); + const auto request = "host:version"; + send_host_request(socket, request); - return protocol::host_message(socket); - } + return protocol::host_message(socket); +} - static inline std::string devices(asio::io_context& context, const tcp_endpoints& endpoints) - { - tcp::socket socket(context); - asio::connect(socket, endpoints); +static inline std::string devices(asio::io_context& context, const tcp_endpoints& endpoints) +{ + tcp::socket socket(context); + asio::connect(socket, endpoints); - const auto request = "host:devices"; - send_host_request(socket, request); + const auto request = "host:devices"; + send_host_request(socket, request); - return protocol::host_message(socket); - } + return protocol::host_message(socket); +} - std::string version() - { - asio::io_context context; - tcp::resolver resolver(context); - const auto endpoints = resolver.resolve("127.0.0.1", "5037"); - return version(context, endpoints); - } +std::string version() +{ + asio::io_context context; + tcp::resolver resolver(context); + const auto endpoints = resolver.resolve("127.0.0.1", "5037"); + return version(context, endpoints); +} - std::string devices() - { - asio::io_context context; - tcp::resolver resolver(context); - const auto endpoints = resolver.resolve("127.0.0.1", "5037"); - return devices(context, endpoints); - } +std::string devices() +{ + asio::io_context context; + tcp::resolver resolver(context); + const auto endpoints = resolver.resolve("127.0.0.1", "5037"); + return devices(context, endpoints); +} - void kill_server() - { - asio::io_context context; - tcp::resolver resolver(context); - const auto endpoints = resolver.resolve("127.0.0.1", "5037"); +void kill_server() +{ + asio::io_context context; + tcp::resolver resolver(context); + const auto endpoints = resolver.resolve("127.0.0.1", "5037"); - tcp::socket socket(context); - asio::connect(socket, endpoints); + tcp::socket socket(context); + asio::connect(socket, endpoints); - const auto request = "host:kill"; - send_host_request(socket, request); - } + const auto request = "host:kill"; + send_host_request(socket, request); +} - class io_handle_impl : public io_handle - { - public: - io_handle_impl(std::unique_ptr context, tcp::socket socket); - void write(const std::string_view data) override; - std::string read(unsigned timeout = 0) override; +class io_handle_impl : public io_handle +{ +public: + io_handle_impl(std::unique_ptr context, tcp::socket socket); + void write(const std::string_view data) override; + std::string read(unsigned timeout = 0) override; - private: - friend class client_impl; +private: + friend class client_impl; - const std::unique_ptr m_context; - asio::ip::tcp::socket m_socket; - }; + const std::unique_ptr m_context; + asio::ip::tcp::socket m_socket; +}; - io_handle_impl::io_handle_impl(std::unique_ptr context, tcp::socket socket) - : m_context(std::move(context)), m_socket(std::move(socket)) - { - asio::socket_base::keep_alive option(true); - m_socket.set_option(option); - } +io_handle_impl::io_handle_impl(std::unique_ptr context, tcp::socket socket) : + m_context(std::move(context)), + m_socket(std::move(socket)) +{ + asio::socket_base::keep_alive option(true); + m_socket.set_option(option); +} - std::string io_handle_impl::read(unsigned timeout) - { - std::array buffer; - - if (timeout == 0) { - const auto bytes_read = m_socket.read_some(asio::buffer(buffer)); - return std::string(buffer.data(), bytes_read); - } - - std::error_code ec; - size_t bytes_read = 0; - asio::steady_timer timer(*m_context, std::chrono::seconds(timeout)); - - m_socket.async_read_some(asio::buffer(buffer), [&](const asio::error_code& error, size_t bytes_transferred) { - if (error) { - ec = error; - return; - } - bytes_read = bytes_transferred; - timer.cancel(); - }); - - timer.async_wait([&](const asio::error_code& error) { - if (error) { - ec = error; - return; - } - m_socket.cancel(ec); - }); - - m_context->restart(); - while (m_context->run_one()) { - if (ec == asio::error::eof) { - break; - } - else if (ec == asio::error::operation_aborted) { - break; - } - else if (ec) { - throw std::system_error(ec); - } - } +std::string io_handle_impl::read(unsigned timeout) +{ + std::array buffer; + if (timeout == 0) { + const auto bytes_read = m_socket.read_some(asio::buffer(buffer)); return std::string(buffer.data(), bytes_read); } - void io_handle_impl::write(const std::string_view data) - { - m_socket.write_some(asio::buffer(data)); - } + std::error_code ec; + size_t bytes_read = 0; + asio::steady_timer timer(*m_context, std::chrono::seconds(timeout)); - class client_impl : public client - { - public: - client_impl(const std::string_view serial); - std::string connect() override; - std::string disconnect() override; - std::string version() override; - std::string devices() override; - std::string shell(const std::string_view command) override; - std::string exec(const std::string_view command) override; - bool push(const std::string_view src, const std::string_view dst, int perm) override; - std::shared_ptr interactive_shell(const std::string_view command) override; - std::string root() override; - std::string unroot() override; - void wait_for_device() override; - - private: - friend class client; - - std::string m_serial; - asio::io_context m_context; - tcp_endpoints m_endpoints; - - /// Switch the connection to the device. - /** - * @param socket Opened adb connection. - * @note Should be used only by the client class. - * @note Local services (e.g. shell, push) can be requested after this. - */ - void switch_to_device(asio::ip::tcp::socket& socket); - }; - - std::shared_ptr client::create(const std::string_view serial) - { - return std::make_shared(serial); - } - - client_impl::client_impl(const std::string_view serial) - { - m_serial = serial; - - tcp::resolver resolver(m_context); - m_endpoints = resolver.resolve("127.0.0.1", "5037"); - } - - std::string client_impl::connect() - { - tcp::socket socket(m_context); - asio::connect(socket, m_endpoints); - - const auto request = "host:connect:" + m_serial; - send_host_request(socket, request); - - return protocol::host_message(socket); - } - - std::string client_impl::disconnect() - { - tcp::socket socket(m_context); - asio::connect(socket, m_endpoints); - - const auto request = "host:disconnect:" + m_serial; - send_host_request(socket, request); - - return protocol::host_message(socket); - } - - std::string client_impl::version() - { - return adb::version(m_context, m_endpoints); - } - - std::string client_impl::devices() - { - return adb::devices(m_context, m_endpoints); - } - - std::string client_impl::shell(const std::string_view command) - { - tcp::socket socket(m_context); - asio::connect(socket, m_endpoints); - - switch_to_device(socket); - - const auto request = std::string("shell:") + command.data(); - send_host_request(socket, request); - - return protocol::host_data(socket); - } - - std::string client_impl::exec(const std::string_view command) - { - tcp::socket socket(m_context); - asio::connect(socket, m_endpoints); - - switch_to_device(socket); - - const auto request = std::string("exec:") + command.data(); - send_host_request(socket, request); - - return protocol::host_data(socket); - } - - bool client_impl::push(const std::string_view src, const std::string_view dst, int perm) - { - tcp::socket socket(m_context); - asio::connect(socket, m_endpoints); - - switch_to_device(socket); - - // Switch to sync mode - const auto sync = "sync:"; - send_host_request(socket, sync); - - // SEND request: destination, permissions - const auto send_request = std::string(dst) + "," + std::to_string(perm); - const auto request_size = static_cast(send_request.size()); - send_sync_request(socket, "SEND", request_size, send_request.data()); - - // DATA request: file data trunk, trunk size - std::ifstream file(src.data(), std::ios::binary); - const auto buf_size = 64000; - std::array buffer; - while (!file.eof()) { - file.read(buffer.data(), buf_size); - const auto bytes_read = static_cast(file.gcount()); - send_sync_request(socket, "DATA", bytes_read, buffer.data()); + m_socket.async_read_some(asio::buffer(buffer), [&](const asio::error_code& error, size_t bytes_transferred) { + if (error) { + ec = error; + return; } - file.close(); + bytes_read = bytes_transferred; + timer.cancel(); + }); - // DONE request: timestamp - const auto now = std::chrono::system_clock::now().time_since_epoch(); - const auto timestamp = std::chrono::duration_cast(now).count(); - const auto done_request = protocol::sync_request("DONE", static_cast(timestamp)); - socket.write_some(asio::buffer(done_request)); - - std::string result; - uint32_t length; - protocol::sync_response(socket, result, length); - if (result != "OKAY") { - return false; + timer.async_wait([&](const asio::error_code& error) { + if (error) { + ec = error; + return; } + m_socket.cancel(ec); + }); - return true; - } - - std::string client_impl::root() - { - tcp::socket socket(m_context); - asio::connect(socket, m_endpoints); - - switch_to_device(socket); - - const auto request = "root:"; - send_host_request(socket, request); - - return protocol::host_data(socket); - } - - std::string client_impl::unroot() - { - tcp::socket socket(m_context); - asio::connect(socket, m_endpoints); - - switch_to_device(socket); - - const auto request = "unroot:"; - send_host_request(socket, request); - - return protocol::host_data(socket); - } - - std::shared_ptr client_impl::interactive_shell(const std::string_view command) - { - auto context = std::make_unique(); - tcp::socket socket(*context); - asio::connect(socket, m_endpoints); - - switch_to_device(socket); - - const auto request = std::string("shell:") + command.data(); - send_host_request(socket, request); - - return std::make_shared(std::move(context), std::move(socket)); - } - - void client_impl::wait_for_device() - { - // If adbd restarts, we should wait the device to get offline first. - std::this_thread::sleep_for(std::chrono::seconds(1)); - - const auto pattern = m_serial + "\tdevice"; - while (devices().find(pattern) == std::string::npos) { - std::this_thread::sleep_for(std::chrono::microseconds(500)); + m_context->restart(); + while (m_context->run_one()) { + if (ec == asio::error::eof) { + break; + } + else if (ec == asio::error::operation_aborted) { + break; + } + else if (ec) { + throw std::system_error(ec); } } - void client_impl::switch_to_device(tcp::socket& socket) - { - const auto request = "host:transport:" + m_serial; - send_host_request(socket, request); + return std::string(buffer.data(), bytes_read); +} + +void io_handle_impl::write(const std::string_view data) +{ + m_socket.write_some(asio::buffer(data)); +} + +class client_impl : public client +{ +public: + client_impl(const std::string_view serial); + std::string connect() override; + std::string disconnect() override; + std::string version() override; + std::string devices() override; + std::string shell(const std::string_view command) override; + std::string exec(const std::string_view command) override; + bool push(const std::string_view src, const std::string_view dst, int perm) override; + std::shared_ptr interactive_shell(const std::string_view command) override; + std::string root() override; + std::string unroot() override; + void wait_for_device() override; + +private: + friend class client; + + std::string m_serial; + asio::io_context m_context; + tcp_endpoints m_endpoints; + + /// Switch the connection to the device. + /** + * @param socket Opened adb connection. + * @note Should be used only by the client class. + * @note Local services (e.g. shell, push) can be requested after this. + */ + void switch_to_device(asio::ip::tcp::socket& socket); +}; + +std::shared_ptr client::create(const std::string_view serial) +{ + return std::make_shared(serial); +} + +client_impl::client_impl(const std::string_view serial) +{ + m_serial = serial; + + tcp::resolver resolver(m_context); + m_endpoints = resolver.resolve("127.0.0.1", "5037"); +} + +std::string client_impl::connect() +{ + tcp::socket socket(m_context); + asio::connect(socket, m_endpoints); + + const auto request = "host:connect:" + m_serial; + send_host_request(socket, request); + + return protocol::host_message(socket); +} + +std::string client_impl::disconnect() +{ + tcp::socket socket(m_context); + asio::connect(socket, m_endpoints); + + const auto request = "host:disconnect:" + m_serial; + send_host_request(socket, request); + + return protocol::host_message(socket); +} + +std::string client_impl::version() +{ + return adb::version(m_context, m_endpoints); +} + +std::string client_impl::devices() +{ + return adb::devices(m_context, m_endpoints); +} + +std::string client_impl::shell(const std::string_view command) +{ + tcp::socket socket(m_context); + asio::connect(socket, m_endpoints); + + switch_to_device(socket); + + const auto request = std::string("shell:") + command.data(); + send_host_request(socket, request); + + return protocol::host_data(socket); +} + +std::string client_impl::exec(const std::string_view command) +{ + tcp::socket socket(m_context); + asio::connect(socket, m_endpoints); + + switch_to_device(socket); + + const auto request = std::string("exec:") + command.data(); + send_host_request(socket, request); + + return protocol::host_data(socket); +} + +bool client_impl::push(const std::string_view src, const std::string_view dst, int perm) +{ + tcp::socket socket(m_context); + asio::connect(socket, m_endpoints); + + switch_to_device(socket); + + // Switch to sync mode + const auto sync = "sync:"; + send_host_request(socket, sync); + + // SEND request: destination, permissions + const auto send_request = std::string(dst) + "," + std::to_string(perm); + const auto request_size = static_cast(send_request.size()); + send_sync_request(socket, "SEND", request_size, send_request.data()); + + // DATA request: file data trunk, trunk size + std::ifstream file(src.data(), std::ios::binary); + const auto buf_size = 64000; + std::array buffer; + while (!file.eof()) { + file.read(buffer.data(), buf_size); + const auto bytes_read = static_cast(file.gcount()); + send_sync_request(socket, "DATA", bytes_read, buffer.data()); } + file.close(); + + // DONE request: timestamp + const auto now = std::chrono::system_clock::now().time_since_epoch(); + const auto timestamp = std::chrono::duration_cast(now).count(); + const auto done_request = protocol::sync_request("DONE", static_cast(timestamp)); + socket.write_some(asio::buffer(done_request)); + + std::string result; + uint32_t length; + protocol::sync_response(socket, result, length); + if (result != "OKAY") { + return false; + } + + return true; +} + +std::string client_impl::root() +{ + tcp::socket socket(m_context); + asio::connect(socket, m_endpoints); + + switch_to_device(socket); + + const auto request = "root:"; + send_host_request(socket, request); + + return protocol::host_data(socket); +} + +std::string client_impl::unroot() +{ + tcp::socket socket(m_context); + asio::connect(socket, m_endpoints); + + switch_to_device(socket); + + const auto request = "unroot:"; + send_host_request(socket, request); + + return protocol::host_data(socket); +} + +std::shared_ptr client_impl::interactive_shell(const std::string_view command) +{ + auto context = std::make_unique(); + tcp::socket socket(*context); + asio::connect(socket, m_endpoints); + + switch_to_device(socket); + + const auto request = std::string("shell:") + command.data(); + send_host_request(socket, request); + + return std::make_shared(std::move(context), std::move(socket)); +} + +void client_impl::wait_for_device() +{ + // If adbd restarts, we should wait the device to get offline first. + std::this_thread::sleep_for(std::chrono::seconds(1)); + + const auto pattern = m_serial + "\tdevice"; + while (devices().find(pattern) == std::string::npos) { + std::this_thread::sleep_for(std::chrono::microseconds(500)); + } +} + +void client_impl::switch_to_device(tcp::socket& socket) +{ + const auto request = "host:transport:" + m_serial; + send_host_request(socket, request); +} } // namespace adb diff --git a/src/MaaCore/Controller/adb-lite/client.hpp b/src/MaaCore/Controller/adb-lite/client.hpp index 4e4cf79d97..56e5aa57cc 100644 --- a/src/MaaCore/Controller/adb-lite/client.hpp +++ b/src/MaaCore/Controller/adb-lite/client.hpp @@ -6,175 +6,175 @@ namespace adb { +/// Retrieve the version of local adb server. +/** + * @return 4-byte string of the version number. + * @throw std::system_error if the server is not available. + */ +std::string version(); + +/// Retrieve the available Android devices. +/** + * @return A string of the list of devices. + * @throw std::system_error if the server is not available. + * @note Equivalent to `adb devices`. + */ +std::string devices(); + +/// Kill the adb server if it is running. +/** + * @throw std::system_error if the server is not running. + * @note Equivalent to `adb kill-server`. + */ +void kill_server(); + +class io_handle_impl; + +/// Context for an interactive adb connection. +/** + * @note Should be used only by the client class, after a shell request. + * @note The socket will be closed when the handle is destroyed. + */ +class io_handle +{ +public: + virtual ~io_handle() = default; + + /// Write data to the adb connection. + /** + * @param data Data to write. + * @throw std::runtime_error Thrown on socket failure. + * @note Typically used to write stdin of a shell command. + * @note The data should end with a newline. + */ + virtual void write(const std::string_view data) = 0; + + /// Read data from the adb connection. + /** + * @param timeout Timeout in seconds. 0 means no timeout. + * @return Data read. Empty if timeout or the connection is closed. + * @throw std::runtime_error Thrown on socket failure. + * @note Typically used to read stdout of a shell command. + */ + virtual std::string read(unsigned timeout = 0) = 0; + +protected: + io_handle() = default; +}; + +class client_impl; + +/// A client for the Android Debug Bridge. +class client +{ +public: + /// Create a client for a specific device. + /** + * @param serial serial number of the device. + * @note If the serial is empty, the unique device will be used. If there + * are multiple devices, an exception will be thrown. + */ + static std::shared_ptr create(const std::string_view serial); + virtual ~client() = default; + + /// Connect to the device. + /** + * @return A string of the connection status. + * @throw std::system_error if the server is not available. + * @note Equivalent to `adb connect `. + */ + virtual std::string connect() = 0; + + /// Disconnect from the device. + /** + * @return A string of the disconnection status. + * @throw std::system_error if the server is not available. + * @note Equivalent to `adb disconnect `. + */ + virtual std::string disconnect() = 0; + /// Retrieve the version of local adb server. /** * @return 4-byte string of the version number. * @throw std::system_error if the server is not available. + * @note This function reuses the class member io_context, which is + * thread-safe for the client. */ - std::string version(); + virtual std::string version() = 0; /// Retrieve the available Android devices. /** * @return A string of the list of devices. * @throw std::system_error if the server is not available. * @note Equivalent to `adb devices`. + * @note This function reuses the class member io_context, which is + * thread-safe for the client. */ - std::string devices(); + virtual std::string devices() = 0; - /// Kill the adb server if it is running. + /// Send an one-shot shell command to the device. /** - * @throw std::system_error if the server is not running. - * @note Equivalent to `adb kill-server`. + * @param command Command to execute. + * @return A string of the command output. + * @throw std::system_error if the server is not available. + * @note Equivalent to `adb -s shell ` without stdin. */ - void kill_server(); + virtual std::string shell(const std::string_view command) = 0; - class io_handle_impl; - - /// Context for an interactive adb connection. + /// Send an one-shot shell command to the device, using raw PTY. /** - * @note Should be used only by the client class, after a shell request. - * @note The socket will be closed when the handle is destroyed. + * @param command Command to execute. + * @return A string of the command output, which is not mangled. + * @throw std::system_error if the server is not available. + * @note Equivalent to `adb -s exec-out ` without stdin. */ - class io_handle - { - public: - virtual ~io_handle() = default; + virtual std::string exec(const std::string_view command) = 0; - /// Write data to the adb connection. - /** - * @param data Data to write. - * @throw std::runtime_error Thrown on socket failure. - * @note Typically used to write stdin of a shell command. - * @note The data should end with a newline. - */ - virtual void write(const std::string_view data) = 0; + /// Send a file to the device. + /** + * @return true if the file is successfully sent. + * @param src Path to the source file. + * @param dst Path to the destination file. + * @param perm Permission of the destination file. + * @throw std::system_error if the server is not available. + * @note Equivalent to `adb -s push `. + */ + virtual bool push(const std::string_view src, const std::string_view dst, int perm) = 0; - /// Read data from the adb connection. - /** - * @param timeout Timeout in seconds. 0 means no timeout. - * @return Data read. Empty if timeout or the connection is closed. - * @throw std::runtime_error Thrown on socket failure. - * @note Typically used to read stdout of a shell command. - */ - virtual std::string read(unsigned timeout = 0) = 0; + /// Set the user of adbd to root on the device. + /** + * @throw std::system_error if the server is not available. + * @note Equivalent to `adb -s root`. + * @note The device might be offline after this command. Remember to wait + * for the restart. + */ + virtual std::string root() = 0; - protected: - io_handle() = default; - }; + /// Set the user of adbd to non-root on the device. + /** + * @throw std::system_error if the server is not available. + * @note Equivalent to `adb -s unroot`. + * @note The device might be offline after this command. Remember to wait + * for the restart. + */ + virtual std::string unroot() = 0; - class client_impl; + /// Start an interactive shell session on the device. + /** + * @param command Command to execute. + * @return An io_handle for the interactive session. + * @throw std::system_error if the server is not available. + * @note Equivalent to `adb -s shell ` with stdin. + */ + virtual std::shared_ptr interactive_shell(const std::string_view command) = 0; - /// A client for the Android Debug Bridge. - class client - { - public: - /// Create a client for a specific device. - /** - * @param serial serial number of the device. - * @note If the serial is empty, the unique device will be used. If there - * are multiple devices, an exception will be thrown. - */ - static std::shared_ptr create(const std::string_view serial); - virtual ~client() = default; + /// Wait for the device to be available. + /** + * @throw std::system_error if the server is not available. + */ + virtual void wait_for_device() = 0; - /// Connect to the device. - /** - * @return A string of the connection status. - * @throw std::system_error if the server is not available. - * @note Equivalent to `adb connect `. - */ - virtual std::string connect() = 0; - - /// Disconnect from the device. - /** - * @return A string of the disconnection status. - * @throw std::system_error if the server is not available. - * @note Equivalent to `adb disconnect `. - */ - virtual std::string disconnect() = 0; - - /// Retrieve the version of local adb server. - /** - * @return 4-byte string of the version number. - * @throw std::system_error if the server is not available. - * @note This function reuses the class member io_context, which is - * thread-safe for the client. - */ - virtual std::string version() = 0; - - /// Retrieve the available Android devices. - /** - * @return A string of the list of devices. - * @throw std::system_error if the server is not available. - * @note Equivalent to `adb devices`. - * @note This function reuses the class member io_context, which is - * thread-safe for the client. - */ - virtual std::string devices() = 0; - - /// Send an one-shot shell command to the device. - /** - * @param command Command to execute. - * @return A string of the command output. - * @throw std::system_error if the server is not available. - * @note Equivalent to `adb -s shell ` without stdin. - */ - virtual std::string shell(const std::string_view command) = 0; - - /// Send an one-shot shell command to the device, using raw PTY. - /** - * @param command Command to execute. - * @return A string of the command output, which is not mangled. - * @throw std::system_error if the server is not available. - * @note Equivalent to `adb -s exec-out ` without stdin. - */ - virtual std::string exec(const std::string_view command) = 0; - - /// Send a file to the device. - /** - * @return true if the file is successfully sent. - * @param src Path to the source file. - * @param dst Path to the destination file. - * @param perm Permission of the destination file. - * @throw std::system_error if the server is not available. - * @note Equivalent to `adb -s push `. - */ - virtual bool push(const std::string_view src, const std::string_view dst, int perm) = 0; - - /// Set the user of adbd to root on the device. - /** - * @throw std::system_error if the server is not available. - * @note Equivalent to `adb -s root`. - * @note The device might be offline after this command. Remember to wait - * for the restart. - */ - virtual std::string root() = 0; - - /// Set the user of adbd to non-root on the device. - /** - * @throw std::system_error if the server is not available. - * @note Equivalent to `adb -s unroot`. - * @note The device might be offline after this command. Remember to wait - * for the restart. - */ - virtual std::string unroot() = 0; - - /// Start an interactive shell session on the device. - /** - * @param command Command to execute. - * @return An io_handle for the interactive session. - * @throw std::system_error if the server is not available. - * @note Equivalent to `adb -s shell ` with stdin. - */ - virtual std::shared_ptr interactive_shell(const std::string_view command) = 0; - - /// Wait for the device to be available. - /** - * @throw std::system_error if the server is not available. - */ - virtual void wait_for_device() = 0; - - protected: - client() = default; - }; +protected: + client() = default; +}; } // namespace adb diff --git a/src/MaaCore/Controller/adb-lite/protocol.cpp b/src/MaaCore/Controller/adb-lite/protocol.cpp index ef29484651..a2be598b93 100644 --- a/src/MaaCore/Controller/adb-lite/protocol.cpp +++ b/src/MaaCore/Controller/adb-lite/protocol.cpp @@ -7,111 +7,111 @@ using asio::ip::tcp; namespace adb::protocol { - /// Encoded the ADB host request. - /** - * @param body Body of the request. - * @return Encoded request. - */ - static inline std::string host_request(const std::string_view body) - { - std::stringstream ss; - ss << std::setfill('0') << std::setw(4) << std::hex << body.size() << body; - return ss.str(); +/// Encoded the ADB host request. +/** + * @param body Body of the request. + * @return Encoded request. + */ +static inline std::string host_request(const std::string_view body) +{ + std::stringstream ss; + ss << std::setfill('0') << std::setw(4) << std::hex << body.size() << body; + return ss.str(); +} + +/// Receive and check the response. +/** + * @param socket Opened adb connection. + * @param failure Error message if the response is not OKAY. + * @return `true` if the response is OKAY, `false` otherwise. + * @throw std::runtime_error Thrown on socket failure + */ +static inline bool host_response(tcp::socket& socket, std::string& failure) +{ + std::array header; + socket.read_some(asio::buffer(header)); + const auto result = std::string_view(header.data(), 4); + if (result == "OKAY") { + return true; } - /// Receive and check the response. - /** - * @param socket Opened adb connection. - * @param failure Error message if the response is not OKAY. - * @return `true` if the response is OKAY, `false` otherwise. - * @throw std::runtime_error Thrown on socket failure - */ - static inline bool host_response(tcp::socket& socket, std::string& failure) - { - std::array header; - socket.read_some(asio::buffer(header)); - const auto result = std::string_view(header.data(), 4); - if (result == "OKAY") { - return true; - } - - if (result != "FAIL") { - failure = "unknown response"; - return false; - } - - failure = host_message(socket); + if (result != "FAIL") { + failure = "unknown response"; return false; } - std::string host_message(tcp::socket& socket) - { - std::array header; - socket.read_some(asio::buffer(header)); - auto remain = std::stoull(std::string(header.data(), 4), nullptr, 16); + failure = host_message(socket); + return false; +} - std::string message; - std::array buffer; - while (remain > 0) { - const auto length = socket.read_some(asio::buffer(buffer)); - message.append(buffer.data(), length); - remain -= length; +std::string host_message(tcp::socket& socket) +{ + std::array header; + socket.read_some(asio::buffer(header)); + auto remain = std::stoull(std::string(header.data(), 4), nullptr, 16); + + std::string message; + std::array buffer; + while (remain > 0) { + const auto length = socket.read_some(asio::buffer(buffer)); + message.append(buffer.data(), length); + remain -= length; + } + + return message; +} + +std::string host_data(tcp::socket& socket) +{ + std::string data; + std::array buffer; + asio::error_code ec; + + while (!ec) { + const auto length = socket.read_some(asio::buffer(buffer), ec); + if (ec == asio::error::eof) { + break; } - - return message; + data.append(buffer.data(), length); } - std::string host_data(tcp::socket& socket) - { - std::string data; - std::array buffer; - asio::error_code ec; + return data; +} - while (!ec) { - const auto length = socket.read_some(asio::buffer(buffer), ec); - if (ec == asio::error::eof) { - break; - } - data.append(buffer.data(), length); - } +std::string sync_request(const std::string_view id, const uint32_t length) +{ + const auto len = { + static_cast(length & 0xff), + static_cast((length >> 8) & 0xff), + static_cast((length >> 16) & 0xff), + static_cast((length >> 24) & 0xff), + }; - return data; + return std::string(id) + std::string(len.begin(), len.end()); +} + +void sync_response(tcp::socket& socket, std::string& id, uint32_t& length) +{ + std::array response; + socket.read_some(asio::buffer(response)); + + id = std::string(response.data(), 4); + length = response[4] | (response[5] << 8) | (response[6] << 16) | (response[7] << 24); +} + +void send_host_request(tcp::socket& socket, const std::string_view request) +{ + socket.write_some(asio::buffer(protocol::host_request(request))); + std::string failure; + if (!protocol::host_response(socket, failure)) { + throw std::runtime_error(failure); } +} - std::string sync_request(const std::string_view id, const uint32_t length) - { - const auto len = { - static_cast(length & 0xff), - static_cast((length >> 8) & 0xff), - static_cast((length >> 16) & 0xff), - static_cast((length >> 24) & 0xff), - }; - - return std::string(id) + std::string(len.begin(), len.end()); - } - - void sync_response(tcp::socket& socket, std::string& id, uint32_t& length) - { - std::array response; - socket.read_some(asio::buffer(response)); - - id = std::string(response.data(), 4); - length = response[4] | (response[5] << 8) | (response[6] << 16) | (response[7] << 24); - } - - void send_host_request(tcp::socket& socket, const std::string_view request) - { - socket.write_some(asio::buffer(protocol::host_request(request))); - std::string failure; - if (!protocol::host_response(socket, failure)) { - throw std::runtime_error(failure); - } - } - - void send_sync_request(tcp::socket& socket, const std::string_view id, uint32_t length, const char* body) - { - auto data_request = protocol::sync_request(id, length); - socket.write_some(asio::buffer(data_request)); - socket.write_some(asio::buffer(body, length)); - } +void send_sync_request(tcp::socket& socket, const std::string_view id, uint32_t length, const char* body) +{ + auto data_request = protocol::sync_request(id, length); + socket.write_some(asio::buffer(data_request)); + socket.write_some(asio::buffer(body, length)); +} } // namespace adb::protocol diff --git a/src/MaaCore/Controller/adb-lite/protocol.hpp b/src/MaaCore/Controller/adb-lite/protocol.hpp index 02ffbc1d50..f4bc229191 100644 --- a/src/MaaCore/Controller/adb-lite/protocol.hpp +++ b/src/MaaCore/Controller/adb-lite/protocol.hpp @@ -6,55 +6,58 @@ namespace adb::protocol { - /// Receive encoded data from the host. - /** - * @param socket Opened adb connection. - * @return Data from the host. - * @throw std::runtime_error Thrown on socket failure. - */ - std::string host_message(asio::ip::tcp::socket& socket); +/// Receive encoded data from the host. +/** + * @param socket Opened adb connection. + * @return Data from the host. + * @throw std::runtime_error Thrown on socket failure. + */ +std::string host_message(asio::ip::tcp::socket& socket); - /// Receive all data from the host. - /** - * @param socket Opened adb connection. - * @return Data from the host. - * @throw std::runtime_error Thrown on socket failure. - * @note The function will keep reading until the connection is closed. - */ - std::string host_data(asio::ip::tcp::socket& socket); +/// Receive all data from the host. +/** + * @param socket Opened adb connection. + * @return Data from the host. + * @throw std::runtime_error Thrown on socket failure. + * @note The function will keep reading until the connection is closed. + */ +std::string host_data(asio::ip::tcp::socket& socket); - /// Encode the ADB sync request. - /** - * @param id 4-byte string of the request id. - * @param length Length of the body. - */ - std::string sync_request(const std::string_view id, const uint32_t length); +/// Encode the ADB sync request. +/** + * @param id 4-byte string of the request id. + * @param length Length of the body. + */ +std::string sync_request(const std::string_view id, const uint32_t length); - /// Receive the sync response. - /** - * @param socket Opened adb connection. - * @param id 4-byte string of the response id. - * @param length Length of the body. - * @throw std::runtime_error Thrown on socket failure. - */ - void sync_response(asio::ip::tcp::socket& socket, std::string& id, uint32_t& length); +/// Receive the sync response. +/** + * @param socket Opened adb connection. + * @param id 4-byte string of the response id. + * @param length Length of the body. + * @throw std::runtime_error Thrown on socket failure. + */ +void sync_response(asio::ip::tcp::socket& socket, std::string& id, uint32_t& length); - /// Send an ADB host request and check its response. - /** - * @param socket Opened adb connection. - * @param request Encoded request. - * @throw std::runtime_error Thrown on socket failure or adb FAIL response. - */ - void send_host_request(asio::ip::tcp::socket& socket, const std::string_view request); +/// Send an ADB host request and check its response. +/** + * @param socket Opened adb connection. + * @param request Encoded request. + * @throw std::runtime_error Thrown on socket failure or adb FAIL response. + */ +void send_host_request(asio::ip::tcp::socket& socket, const std::string_view request); - /// Send an ADB sync request. - /** - * @param socket Opened adb connection. - * @param id 4-byte string of the request id. - * @param length Length of the body. - * @param body Body of the request. - * @throw std::runtime_error Thrown on socket failure. - */ - void send_sync_request(asio::ip::tcp::socket& socket, const std::string_view id, const uint32_t length, - const char* body); +/// Send an ADB sync request. +/** + * @param socket Opened adb connection. + * @param id 4-byte string of the request id. + * @param length Length of the body. + * @param body Body of the request. + * @throw std::runtime_error Thrown on socket failure. + */ +void send_sync_request( + asio::ip::tcp::socket& socket, + const std::string_view id, + const uint32_t length, + const char* body); } // namespace adb::protocol diff --git a/src/MaaCore/InstHelper.cpp b/src/MaaCore/InstHelper.cpp index fd851e2342..a2250ccb60 100644 --- a/src/MaaCore/InstHelper.cpp +++ b/src/MaaCore/InstHelper.cpp @@ -5,16 +5,21 @@ #include "Assistant.h" #include "Utils/Logger.hpp" -asst::InstHelper::InstHelper(asst::Assistant* inst) : m_inst(inst) {} +asst::InstHelper::InstHelper(asst::Assistant* inst) : + m_inst(inst) +{ +} std::shared_ptr asst::InstHelper::ctrler() const { return m_inst ? m_inst->ctrler() : nullptr; } + std::shared_ptr asst::InstHelper::status() const { return m_inst ? m_inst->status() : nullptr; } + bool asst::InstHelper::need_exit() const { return m_inst != nullptr && m_inst->need_exit(); diff --git a/src/MaaCore/InstHelper.h b/src/MaaCore/InstHelper.h index d12361556a..3ba34e22a4 100644 --- a/src/MaaCore/InstHelper.h +++ b/src/MaaCore/InstHelper.h @@ -5,31 +5,31 @@ namespace asst { - class Assistant; - class Controller; - class Status; +class Assistant; +class Controller; +class Status; - class InstHelper - { - public: - InstHelper() = default; - InstHelper(const InstHelper&) = default; - InstHelper(InstHelper&&) noexcept = default; - InstHelper(Assistant* inst); - virtual ~InstHelper() noexcept = default; +class InstHelper +{ +public: + InstHelper() = default; + InstHelper(const InstHelper&) = default; + InstHelper(InstHelper&&) noexcept = default; + InstHelper(Assistant* inst); + virtual ~InstHelper() noexcept = default; - std::shared_ptr ctrler() const; - std::shared_ptr status() const; - bool need_exit() const; - bool sleep(unsigned millisecond) const; + std::shared_ptr ctrler() const; + std::shared_ptr status() const; + bool need_exit() const; + bool sleep(unsigned millisecond) const; - Assistant* inst() noexcept; - std::string inst_string() const; + Assistant* inst() noexcept; + std::string inst_string() const; - InstHelper& operator=(const InstHelper&) = default; - InstHelper& operator=(InstHelper&&) noexcept = default; + InstHelper& operator=(const InstHelper&) = default; + InstHelper& operator=(InstHelper&&) noexcept = default; - protected: - Assistant* m_inst = nullptr; - }; +protected: + Assistant* m_inst = nullptr; +}; } diff --git a/src/MaaCore/LDExtras.cpp b/src/MaaCore/LDExtras.cpp index 3b2ca95ec1..1dc085c255 100644 --- a/src/MaaCore/LDExtras.cpp +++ b/src/MaaCore/LDExtras.cpp @@ -5,9 +5,9 @@ #include "Utils/Logger.hpp" #include "Utils/NoWarningCV.h" #include "Utils/Platform/SafeWindows.h" -#include -#include #include +#include +#include namespace asst { @@ -16,7 +16,12 @@ LDExtras::~LDExtras() uninit(); } -bool LDExtras::init(const std::filesystem::path& ld_path, unsigned int ld_inst_index, unsigned int ld_pid, int width, int height) +bool LDExtras::init( + const std::filesystem::path& ld_path, + unsigned int ld_inst_index, + unsigned int ld_pid, + int width, + int height) { const bool same = ld_inst_index == ld_inst_index_ && ld_pid == ld_pid_; @@ -77,7 +82,8 @@ bool LDExtras::load_ld_library() return false; } - create_screenshot_instance_func_ = get_function(kCreateScreenShotInstanceFuncName); + create_screenshot_instance_func_ = + get_function(kCreateScreenShotInstanceFuncName); if (!create_screenshot_instance_func_) { LogError << "Failed to get function" << VAR(kCreateScreenShotInstanceFuncName); return false; diff --git a/src/MaaCore/LDExtras.h b/src/MaaCore/LDExtras.h index 3cd516f895..3b79fa425f 100644 --- a/src/MaaCore/LDExtras.h +++ b/src/MaaCore/LDExtras.h @@ -4,10 +4,10 @@ #if ASST_WITH_EMULATOR_EXTRAS +#include "Utils/Platform/SafeWindows.h" #include #include #include -#include "Utils/Platform/SafeWindows.h" #include "LD/dnopengl/dnopengl.h" @@ -25,7 +25,12 @@ public: bool inited() const { return inited_; } - bool init(const std::filesystem::path& ld_path, unsigned int ld_inst_index, unsigned int ld_pid, int width, int height); + bool init( + const std::filesystem::path& ld_path, + unsigned int ld_inst_index, + unsigned int ld_pid, + int width, + int height); bool reload(); void uninit(); diff --git a/src/MaaCore/Status.h b/src/MaaCore/Status.h index fd82bcf46b..20d7f58bfd 100644 --- a/src/MaaCore/Status.h +++ b/src/MaaCore/Status.h @@ -9,42 +9,42 @@ namespace asst { - class Status - { - public: - Status() = default; - Status(const Status& rhs) = delete; - Status(Status&& rhs) noexcept = delete; - ~Status() = default; +class Status +{ +public: + Status() = default; + Status(const Status& rhs) = delete; + Status(Status&& rhs) noexcept = delete; + ~Status() = default; - std::optional get_number(const std::string& key) const noexcept; - void set_number(std::string key, int64_t value); - void clear_number() noexcept; + std::optional get_number(const std::string& key) const noexcept; + void set_number(std::string key, int64_t value); + void clear_number() noexcept; - std::optional get_rect(const std::string& key) const noexcept; - void set_rect(std::string key, Rect rect); - void clear_rect() noexcept; + std::optional get_rect(const std::string& key) const noexcept; + void set_rect(std::string key, Rect rect); + void clear_rect() noexcept; - std::optional get_str(const std::string& key) const noexcept; - void set_str(std::string key, std::string value); - void clear_str() noexcept; + std::optional get_str(const std::string& key) const noexcept; + void set_str(std::string key, std::string value); + void clear_str() noexcept; - std::optional get_properties(const std::string& key) const noexcept; - void set_properties(std::string key, std::string value); - void clear_properties() noexcept; + std::optional get_properties(const std::string& key) const noexcept; + void set_properties(std::string key, std::string value); + void clear_properties() noexcept; - Status& operator=(const Status& rhs) = delete; - Status& operator=(Status&& rhs) noexcept = delete; + Status& operator=(const Status& rhs) = delete; + Status& operator=(Status&& rhs) noexcept = delete; - public: - static inline const std::string InfrastAvailableOpersForGroup = "InfrastAvailableOpersForGroup"; +public: + static inline const std::string InfrastAvailableOpersForGroup = "InfrastAvailableOpersForGroup"; - static inline const std::string ProcessTaskLastTimePrefix = "#LastTime#"; + static inline const std::string ProcessTaskLastTimePrefix = "#LastTime#"; - private: - std::unordered_map m_number; - std::unordered_map m_rect; - std::unordered_map m_string; // 跨任务时会被清理的量 - std::unordered_map m_properties; // 跨任务时不会清理的量 - }; +private: + std::unordered_map m_number; + std::unordered_map m_rect; + std::unordered_map m_string; // 跨任务时会被清理的量 + std::unordered_map m_properties; // 跨任务时不会清理的量 +}; } diff --git a/src/MaaCore/Task/AbstractTask.cpp b/src/MaaCore/Task/AbstractTask.cpp index 3d1247c59a..7475dcba68 100644 --- a/src/MaaCore/Task/AbstractTask.cpp +++ b/src/MaaCore/Task/AbstractTask.cpp @@ -20,9 +20,12 @@ using namespace asst; -AbstractTask::AbstractTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain) - : InstHelper(inst), m_callback(callback), m_task_chain(task_chain) -{} +AbstractTask::AbstractTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain) : + InstHelper(inst), + m_callback(callback), + m_task_chain(task_chain) +{ +} bool asst::AbstractTask::run() { @@ -199,12 +202,16 @@ size_t asst::AbstractTask::filenum_ctrl(const std::filesystem::path& relative_di } } - std::sort(filepaths.begin(), filepaths.end(), - [](const std::pair& a, - const std::pair& b) { - if (a.first != b.first) return a.first < b.first; - return a.second < b.second; - }); + std::sort( + filepaths.begin(), + filepaths.end(), + [](const std::pair& a, + const std::pair& b) { + if (a.first != b.first) { + return a.first < b.first; + } + return a.second < b.second; + }); long long to_del = file_nums - max_files; size_t deleted = 0; diff --git a/src/MaaCore/Task/AbstractTask.h b/src/MaaCore/Task/AbstractTask.h index 87515e0c72..fd91d91178 100644 --- a/src/MaaCore/Task/AbstractTask.h +++ b/src/MaaCore/Task/AbstractTask.h @@ -11,82 +11,91 @@ namespace cv { - class Mat; +class Mat; } namespace asst { - class AbstractTaskPlugin; - using TaskPluginPtr = std::shared_ptr; +class AbstractTaskPlugin; +using TaskPluginPtr = std::shared_ptr; - class Controller; - class Status; - class TaskData; +class Controller; +class Status; +class TaskData; - class AbstractTask : protected InstHelper +class AbstractTask : protected InstHelper +{ +public: + AbstractTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); + AbstractTask(const AbstractTask&) = default; + AbstractTask(AbstractTask&&) noexcept = default; + virtual ~AbstractTask() noexcept = default; + using InstHelper::inst; + + virtual bool run(); + + virtual AbstractTask& set_retry_times(int times) noexcept; + virtual AbstractTask& set_enable(bool enable) noexcept; + virtual AbstractTask& set_ignore_error(bool ignore) noexcept; + virtual AbstractTask& set_task_id(int task_id) noexcept; + + template + requires std::derived_from // Plugin must inherit AbstractTaskPlugin + std::shared_ptr register_plugin(Args&&... args) { - public: - AbstractTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); - AbstractTask(const AbstractTask&) = default; - AbstractTask(AbstractTask&&) noexcept = default; - virtual ~AbstractTask() noexcept = default; - using InstHelper::inst; + auto plugin = std::make_shared(m_callback, m_inst, m_task_chain, std::forward(args)...); + m_plugins.emplace_back(plugin); + return plugin; + } - virtual bool run(); + template + requires std::derived_from // Plugin must inherit AbstractTaskPlugin + void append_plugin(const std::shared_ptr& plugin) + { + m_plugins.emplace_back(plugin); + } - virtual AbstractTask& set_retry_times(int times) noexcept; - virtual AbstractTask& set_enable(bool enable) noexcept; - virtual AbstractTask& set_ignore_error(bool ignore) noexcept; - virtual AbstractTask& set_task_id(int task_id) noexcept; + void clear_plugin() noexcept; - template - requires std::derived_from // Plugin must inherit AbstractTaskPlugin - std::shared_ptr register_plugin(Args&&... args) - { - auto plugin = std::make_shared(m_callback, m_inst, m_task_chain, std::forward(args)...); - m_plugins.emplace_back(plugin); - return plugin; - } + bool get_enable() const noexcept { return m_enable; } - template - requires std::derived_from // Plugin must inherit AbstractTaskPlugin - void append_plugin(const std::shared_ptr& plugin) - { - m_plugins.emplace_back(plugin); - } + bool get_ignore_error() const noexcept { return m_ignore_error; } - void clear_plugin() noexcept; + std::string_view get_task_chain() const noexcept { return m_task_chain; } - bool get_enable() const noexcept { return m_enable; } - bool get_ignore_error() const noexcept { return m_ignore_error; } - std::string_view get_task_chain() const noexcept { return m_task_chain; } - std::vector get_plugins() const noexcept { return m_plugins; } - int get_task_id() const noexcept { return m_task_id; } - virtual json::value basic_info() const; + std::vector get_plugins() const noexcept { return m_plugins; } - static constexpr int RetryTimesDefault = 20; + int get_task_id() const noexcept { return m_task_id; } - protected: - virtual bool _run() = 0; - virtual bool on_run_fails() { return true; } - virtual void callback(AsstMsg msg, const json::value& detail); - virtual void click_return_button(); - bool save_img(const std::filesystem::path& relative_dir = utils::path("debug"), bool use_cache = true, - bool auto_clean = true); - size_t filenum_ctrl(const std::filesystem::path& relative_dir, size_t max_files = 1000); + virtual json::value basic_info() const; - json::value basic_info_with_what(std::string what) const; + static constexpr int RetryTimesDefault = 20; - bool m_enable = true; - bool m_ignore_error = false; - AsstCallback m_callback = nullptr; - std::string_view m_task_chain; - int m_cur_retry = 0; - int m_retry_times = RetryTimesDefault; +protected: + virtual bool _run() = 0; - mutable json::value m_basic_info_cache; - int m_task_id = 0; - std::vector m_plugins; - std::map m_save_file_cnt; - }; + virtual bool on_run_fails() { return true; } + + virtual void callback(AsstMsg msg, const json::value& detail); + virtual void click_return_button(); + bool save_img( + const std::filesystem::path& relative_dir = utils::path("debug"), + bool use_cache = true, + bool auto_clean = true); + size_t filenum_ctrl(const std::filesystem::path& relative_dir, size_t max_files = 1000); + + json::value basic_info_with_what(std::string what) const; + + bool m_enable = true; + bool m_ignore_error = false; + AsstCallback m_callback = nullptr; + std::string_view m_task_chain; + int m_cur_retry = 0; + int m_retry_times = RetryTimesDefault; + + mutable json::value m_basic_info_cache; + int m_task_id = 0; + std::vector m_plugins; + std::map m_save_file_cnt; +}; } // namespace asst diff --git a/src/MaaCore/Task/AbstractTaskPlugin.h b/src/MaaCore/Task/AbstractTaskPlugin.h index b97e857a85..0b517b47a4 100644 --- a/src/MaaCore/Task/AbstractTaskPlugin.h +++ b/src/MaaCore/Task/AbstractTaskPlugin.h @@ -7,28 +7,28 @@ namespace asst { - class AbstractTaskPlugin : public AbstractTask - { - public: - using AbstractTask::AbstractTask; - virtual ~AbstractTaskPlugin() override = default; +class AbstractTaskPlugin : public AbstractTask +{ +public: + using AbstractTask::AbstractTask; + virtual ~AbstractTaskPlugin() override = default; - int priority() const; - bool block() const; + int priority() const; + bool block() const; - void set_priority(int priority); - void set_block(bool block); + void set_priority(int priority); + void set_block(bool block); - virtual void set_task_ptr(AbstractTask* ptr); + virtual void set_task_ptr(AbstractTask* ptr); - virtual bool verify(AsstMsg msg, const json::value& details) const = 0; + virtual bool verify(AsstMsg msg, const json::value& details) const = 0; - std::strong_ordering operator<=>(const AbstractTaskPlugin& rhs) const; - bool operator==(const AbstractTaskPlugin& rhs) const; + std::strong_ordering operator<=>(const AbstractTaskPlugin& rhs) const; + bool operator==(const AbstractTaskPlugin& rhs) const; - protected: - AbstractTask* m_task_ptr = nullptr; - int m_priority = 0; - bool m_block = false; - }; +protected: + AbstractTask* m_task_ptr = nullptr; + int m_priority = 0; + bool m_block = false; +}; } diff --git a/src/MaaCore/Task/BattleHelper.h b/src/MaaCore/Task/BattleHelper.h index 15d9231c39..b6a783fb1a 100644 --- a/src/MaaCore/Task/BattleHelper.h +++ b/src/MaaCore/Task/BattleHelper.h @@ -14,92 +14,99 @@ namespace asst { - class BattleHelper - { - public: - ~BattleHelper() = default; +class BattleHelper +{ +public: + ~BattleHelper() = default; - protected: - BattleHelper(Assistant* inst); +protected: + BattleHelper(Assistant* inst); - virtual AbstractTask& this_task() = 0; + virtual AbstractTask& this_task() = 0; - virtual bool set_stage_name(const std::string& name); - virtual void clear(); - virtual const std::string oper_name_ocr_task_name() const noexcept { return "BattleOperName"; } - virtual bool do_strategic_action(const cv::Mat& reusable = cv::Mat()); + virtual bool set_stage_name(const std::string& name); + virtual void clear(); - bool calc_tiles_info(const std::string& stage_name, double shift_x = 0, double shift_y = 0); + virtual const std::string oper_name_ocr_task_name() const noexcept { return "BattleOperName"; } - bool pause(); - bool speed_up(); - bool abandon(); + virtual bool do_strategic_action(const cv::Mat& reusable = cv::Mat()); - bool update_deployment(bool init = false, const cv::Mat& reusable = cv::Mat(), bool need_oper_cost = false); - bool update_kills(const cv::Mat& reusable = cv::Mat()); - bool update_cost(const cv::Mat& reusable = cv::Mat()); + bool calc_tiles_info(const std::string& stage_name, double shift_x = 0, double shift_y = 0); - cv::Mat get_top_view(const cv::Mat& cam_img, bool side = true); + bool pause(); + bool speed_up(); + bool abandon(); - bool deploy_oper(const std::string& name, const Point& loc, battle::DeployDirection direction); - bool retreat_oper(const std::string& name); - bool retreat_oper(const Point& loc, bool manually = true); - bool is_skill_ready(const Point& loc, const cv::Mat& reusable = cv::Mat()); - bool is_skill_ready(const std::string& name, const cv::Mat& reusable = cv::Mat()); - bool use_skill(const std::string& name, bool keep_waiting = true); - bool use_skill(const Point& loc, bool keep_waiting = true); - bool check_pause_button(const cv::Mat& reusable = cv::Mat()); - bool check_skip_plot_button(const cv::Mat& reusable = cv::Mat()); - bool check_in_speed_up(const cv::Mat& reusable = cv::Mat()); - virtual bool check_in_battle(const cv::Mat& reusable = cv::Mat(), bool weak = true); - virtual bool wait_until_start(bool weak = true); - bool wait_until_end(bool weak = true); - bool use_all_ready_skill(const cv::Mat& reusable = cv::Mat()); - bool check_and_use_skill(const std::string& name, bool& has_error, const cv::Mat& reusable = cv::Mat()); - bool check_and_use_skill(const Point& loc, bool& has_error, const cv::Mat& reusable = cv::Mat()); - void save_map(const cv::Mat& image); + bool update_deployment(bool init = false, const cv::Mat& reusable = cv::Mat(), bool need_oper_cost = false); + bool update_kills(const cv::Mat& reusable = cv::Mat()); + bool update_cost(const cv::Mat& reusable = cv::Mat()); - bool click_oper_on_deployment(const std::string& name); - bool click_oper_on_deployment(const Rect& rect); - bool click_oper_on_battlefield(const std::string& name); - bool click_oper_on_battlefield(const Point& loc); - bool click_retreat(); // 这个是不带识别的,直接点 - bool click_skill(bool keep_waiting = true); // 这个是带识别的,转好了才点 - bool cancel_oper_selection(); - // 修正终点超出范围的滑动,纠正时是否需要顺时针旋转 - void fix_swipe_out_of_limit(Point& p1, Point& p2, int width, int height, int max_distance = INT_MAX, - double radian = 0); - bool move_camera(const std::pair& delta); + cv::Mat get_top_view(const cv::Mat& cam_img, bool side = true); - std::string analyze_detail_page_oper_name(const cv::Mat& image); + bool deploy_oper(const std::string& name, const Point& loc, battle::DeployDirection direction); + bool retreat_oper(const std::string& name); + bool retreat_oper(const Point& loc, bool manually = true); + bool is_skill_ready(const Point& loc, const cv::Mat& reusable = cv::Mat()); + bool is_skill_ready(const std::string& name, const cv::Mat& reusable = cv::Mat()); + bool use_skill(const std::string& name, bool keep_waiting = true); + bool use_skill(const Point& loc, bool keep_waiting = true); + bool check_pause_button(const cv::Mat& reusable = cv::Mat()); + bool check_skip_plot_button(const cv::Mat& reusable = cv::Mat()); + bool check_in_speed_up(const cv::Mat& reusable = cv::Mat()); + virtual bool check_in_battle(const cv::Mat& reusable = cv::Mat(), bool weak = true); + virtual bool wait_until_start(bool weak = true); + bool wait_until_end(bool weak = true); + bool use_all_ready_skill(const cv::Mat& reusable = cv::Mat()); + bool check_and_use_skill(const std::string& name, bool& has_error, const cv::Mat& reusable = cv::Mat()); + bool check_and_use_skill(const Point& loc, bool& has_error, const cv::Mat& reusable = cv::Mat()); + void save_map(const cv::Mat& image); - std::optional get_oper_rect_on_deployment(const std::string& name) const; + bool click_oper_on_deployment(const std::string& name); + bool click_oper_on_deployment(const Rect& rect); + bool click_oper_on_battlefield(const std::string& name); + bool click_oper_on_battlefield(const Point& loc); + bool click_retreat(); // 这个是不带识别的,直接点 + bool click_skill(bool keep_waiting = true); // 这个是带识别的,转好了才点 + bool cancel_oper_selection(); + // 修正终点超出范围的滑动,纠正时是否需要顺时针旋转 + void fix_swipe_out_of_limit( + Point& p1, + Point& p2, + int width, + int height, + int max_distance = INT_MAX, + double radian = 0); + bool move_camera(const std::pair& delta); - std::string m_stage_name; - Map::Level m_map_data; - std::unordered_map m_side_tile_info; // 子弹时间的坐标映射 - std::unordered_map m_normal_tile_info; // 正常的坐标映射 - Point m_skill_button_pos; - Point m_retreat_button_pos; - std::unordered_map m_skill_usage; - std::unordered_map m_skill_times; - std::unordered_map m_skill_error_count; - std::unordered_map m_last_use_skill_time; - int m_camera_count = 0; - std::pair m_camera_shift = { 0., 0. }; + std::string analyze_detail_page_oper_name(const cv::Mat& image); - /* 实时更新的数据 */ - bool m_in_battle = false; - int m_kills = 0; - int m_total_kills = 0; - int m_cost = 0; + std::optional get_oper_rect_on_deployment(const std::string& name) const; - std::vector m_cur_deployment_opers; + std::string m_stage_name; + Map::Level m_map_data; + std::unordered_map m_side_tile_info; // 子弹时间的坐标映射 + std::unordered_map m_normal_tile_info; // 正常的坐标映射 + Point m_skill_button_pos; + Point m_retreat_button_pos; + std::unordered_map m_skill_usage; + std::unordered_map m_skill_times; + std::unordered_map m_skill_error_count; + std::unordered_map m_last_use_skill_time; + int m_camera_count = 0; + std::pair m_camera_shift = { 0., 0. }; - std::map m_battlefield_opers; - std::map m_used_tiles; + /* 实时更新的数据 */ + bool m_in_battle = false; + int m_kills = 0; + int m_total_kills = 0; + int m_cost = 0; - private: - InstHelper m_inst_helper; - }; + std::vector m_cur_deployment_opers; + + std::map m_battlefield_opers; + std::map m_used_tiles; + +private: + InstHelper m_inst_helper; +}; } // namespace asst diff --git a/src/MaaCore/Task/Experiment/CombatRecordRecognitionTask.cpp b/src/MaaCore/Task/Experiment/CombatRecordRecognitionTask.cpp index 9e886c8071..0c4970478c 100644 --- a/src/MaaCore/Task/Experiment/CombatRecordRecognitionTask.cpp +++ b/src/MaaCore/Task/Experiment/CombatRecordRecognitionTask.cpp @@ -449,8 +449,11 @@ bool asst::CombatRecordRecognitionTask::slice_video() for (auto iter = m_clips.begin(); iter != m_clips.end();) { ClipInfo& clip = *iter; if (clip.end_frame_index <= clip.start_frame_index) { - Log.warn(__FUNCTION__, "deployment has no changes or frame error", clip.start_frame_index, - clip.end_frame_index); + Log.warn( + __FUNCTION__, + "deployment has no changes or frame error", + clip.start_frame_index, + clip.end_frame_index); iter = m_clips.erase(iter); continue; } @@ -614,8 +617,9 @@ bool asst::CombatRecordRecognitionTask::detect_operators(ClipInfo& clip, [[maybe } /* 取众数 */ - auto oper_det_iter = ranges::max_element(oper_det_samping, - [&](const auto& lhs, const auto& rhs) { return lhs.second < rhs.second; }); + auto oper_det_iter = ranges::max_element(oper_det_samping, [&](const auto& lhs, const auto& rhs) { + return lhs.second < rhs.second; + }); if (oper_det_iter == oper_det_samping.end()) { Log.error(__FUNCTION__, "oper_det_samping is empty"); callback(AsstMsg::SubTaskError, basic_info_with_what("DetectOperators")); @@ -744,8 +748,9 @@ bool asst::CombatRecordRecognitionTask::process_changes(ClipInfo& clip, ClipInfo m_location_operators.insert_or_assign(loc, name); } } - else if (pre_clip_ptr->deployment.size() < clip.deployment.size() || - pre_clip_ptr->battlefield.size() > clip.battlefield.size()) { + else if ( + pre_clip_ptr->deployment.size() < clip.deployment.size() || + pre_clip_ptr->battlefield.size() > clip.battlefield.size()) { // 撤退 for (const auto& [pre_loc, pre_oper] : pre_clip_ptr->battlefield) { if (clip.battlefield.contains(pre_loc)) { @@ -766,8 +771,13 @@ bool asst::CombatRecordRecognitionTask::process_changes(ClipInfo& clip, ClipInfo } } else { - Log.warn("Unknown changes, deployment:", pre_clip_ptr->deployment.size(), clip.deployment.size(), - "battlefield:", pre_clip_ptr->battlefield.size(), clip.battlefield.size()); + Log.warn( + "Unknown changes, deployment:", + pre_clip_ptr->deployment.size(), + clip.deployment.size(), + "battlefield:", + pre_clip_ptr->battlefield.size(), + clip.battlefield.size()); } return true; diff --git a/src/MaaCore/Task/Experiment/CombatRecordRecognitionTask.h b/src/MaaCore/Task/Experiment/CombatRecordRecognitionTask.h index ac532ab149..4f88cb0616 100644 --- a/src/MaaCore/Task/Experiment/CombatRecordRecognitionTask.h +++ b/src/MaaCore/Task/Experiment/CombatRecordRecognitionTask.h @@ -10,96 +10,96 @@ namespace cv { - class VideoCapture; +class VideoCapture; } namespace asst { - class VisionHelper; +class VisionHelper; - class CombatRecordRecognitionTask : public AbstractTask +class CombatRecordRecognitionTask : public AbstractTask +{ +public: + using AbstractTask::AbstractTask; + virtual ~CombatRecordRecognitionTask() override = default; + + bool set_video_path(const std::filesystem::path& path); + +protected: + virtual bool _run() override; + +private: + struct BattlefieldOper { - public: - using AbstractTask::AbstractTask; - virtual ~CombatRecordRecognitionTask() override = default; + bool new_here = false; + battle::DeployDirection direction = battle::DeployDirection::None; + std::string name; + }; - bool set_video_path(const std::filesystem::path& path); + struct ClipInfo + { + size_t start_frame_index = 0; + size_t end_frame_index = 0; + cv::Mat start_frame; + cv::Mat end_frame; + std::vector deployment; + bool deployment_changed = true; + std::unordered_map battlefield; + std::vector random_frames; + std::string ends_oper_name; + }; - protected: - virtual bool _run() override; + bool analyze_formation(); + bool analyze_stage(); + bool analyze_deployment(); + bool slice_video(); + bool compare_skill(ClipInfo& clip, ClipInfo& pre_clip); - private: - struct BattlefieldOper - { - bool new_here = false; - battle::DeployDirection direction = battle::DeployDirection::None; - std::string name; - }; + bool analyze_clip(ClipInfo& clip, ClipInfo* pre_clip_ptr); + bool detect_operators(ClipInfo& clip, ClipInfo* pre_clip_ptr); + bool classify_direction(ClipInfo& clip, ClipInfo* pre_clip_ptr); + bool process_changes(ClipInfo& clip, ClipInfo* pre_clip_ptr); + void ananlyze_deployment_names(ClipInfo& clip); - struct ClipInfo - { - size_t start_frame_index = 0; - size_t end_frame_index = 0; - cv::Mat start_frame; - cv::Mat end_frame; - std::vector deployment; - bool deployment_changed = true; - std::unordered_map battlefield; - std::vector random_frames; - std::string ends_oper_name; - }; + json::object analyze_action_condition(ClipInfo& clip, ClipInfo* pre_clip_ptr); + size_t skip_frames(size_t count); - bool analyze_formation(); - bool analyze_stage(); - bool analyze_deployment(); - bool slice_video(); - bool compare_skill(ClipInfo& clip, ClipInfo& pre_clip); + static std::string analyze_detail_page_oper_name(const cv::Mat& frame); - bool analyze_clip(ClipInfo& clip, ClipInfo* pre_clip_ptr); - bool detect_operators(ClipInfo& clip, ClipInfo* pre_clip_ptr); - bool classify_direction(ClipInfo& clip, ClipInfo* pre_clip_ptr); - bool process_changes(ClipInfo& clip, ClipInfo* pre_clip_ptr); - void ananlyze_deployment_names(ClipInfo& clip); + std::filesystem::path m_video_path; + std::shared_ptr m_video_ptr = nullptr; + std::string m_stage_name; + double m_video_fps = 0; + size_t m_video_frame_count = 0; + double m_scale = 0; - json::object analyze_action_condition(ClipInfo& clip, ClipInfo* pre_clip_ptr); - size_t skip_frames(size_t count); + int m_formation_fps = 2; + int m_stage_ocr_fps = 2; + int m_deployment_fps = 5; - static std::string analyze_detail_page_oper_name(const cv::Mat& frame); + size_t m_formation_end_frame = 0; + size_t m_stage_ocr_end_frame = 0; + size_t m_battle_start_frame = 0; + size_t m_battle_end_frame = 0; - std::filesystem::path m_video_path; - std::shared_ptr m_video_ptr = nullptr; - std::string m_stage_name; - double m_video_fps = 0; - size_t m_video_frame_count = 0; - double m_scale = 0; + std::vector m_clips; + std::vector> m_frame_kills; - int m_formation_fps = 2; - int m_stage_ocr_fps = 2; - int m_deployment_fps = 5; + std::unordered_map m_normal_tile_info; + std::unordered_map m_formation; + std::unordered_map m_all_avatars; - size_t m_formation_end_frame = 0; - size_t m_stage_ocr_end_frame = 0; - size_t m_battle_start_frame = 0; - size_t m_battle_end_frame = 0; + std::unordered_map m_operator_locations; + std::unordered_map m_location_operators; - std::vector m_clips; - std::vector> m_frame_kills; + json::value m_copilot_json; + int m_pre_action_costs = -1; - std::unordered_map m_normal_tile_info; - std::unordered_map m_formation; - std::unordered_map m_all_avatars; - - std::unordered_map m_operator_locations; - std::unordered_map m_location_operators; - - json::value m_copilot_json; - int m_pre_action_costs = -1; - - void show_img(const VisionHelper& analyzer); - void show_img(const cv::Mat& img); + void show_img(const VisionHelper& analyzer); + void show_img(const cv::Mat& img); #ifdef ASST_DEBUG - inline static const std::string DrawWindow = "CombatRecord"; + inline static const std::string DrawWindow = "CombatRecord"; #endif - }; +}; } // namespace asst diff --git a/src/MaaCore/Task/Experiment/SingleStepBattleProcessTask.h b/src/MaaCore/Task/Experiment/SingleStepBattleProcessTask.h index 95d5e088c4..1e71d24289 100644 --- a/src/MaaCore/Task/Experiment/SingleStepBattleProcessTask.h +++ b/src/MaaCore/Task/Experiment/SingleStepBattleProcessTask.h @@ -3,28 +3,29 @@ namespace asst { - class SingleStepBattleProcessTask : public BattleProcessTask - { - public: - using Actions = std::vector; +class SingleStepBattleProcessTask : public BattleProcessTask +{ +public: + using Actions = std::vector; - public: - using BattleProcessTask::BattleProcessTask; - virtual ~SingleStepBattleProcessTask() override = default; +public: + using BattleProcessTask::BattleProcessTask; + virtual ~SingleStepBattleProcessTask() override = default; - using BattleProcessTask::clear; + using BattleProcessTask::clear; - static bool set_stage_name_cache(const std::string& stage_name); - void set_actions(Actions actions); + static bool set_stage_name_cache(const std::string& stage_name); + void set_actions(Actions actions); - protected: - virtual bool _run() override; - virtual bool need_to_wait_until_end() const noexcept override { return false; } +protected: + virtual bool _run() override; - private: - Actions m_actions; + virtual bool need_to_wait_until_end() const noexcept override { return false; } - // for debug - inline static std::string m_stage_name_cache; - }; +private: + Actions m_actions; + + // for debug + inline static std::string m_stage_name_cache; +}; } diff --git a/src/MaaCore/Task/Fight/DrGrandetTaskPlugin.h b/src/MaaCore/Task/Fight/DrGrandetTaskPlugin.h index 12ed948020..056c60c6de 100644 --- a/src/MaaCore/Task/Fight/DrGrandetTaskPlugin.h +++ b/src/MaaCore/Task/Fight/DrGrandetTaskPlugin.h @@ -3,22 +3,22 @@ namespace asst { - // 博朗台(抠门碎石)任务插件 - // 识别理智恢复时间,仅在 5:55 以上才碎石,否则等待 - // ref to https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues/1607 - class DrGrandetTaskPlugin : public AbstractTaskPlugin - { - public: - using AbstractTaskPlugin::AbstractTaskPlugin; - virtual ~DrGrandetTaskPlugin() override = default; +// 博朗台(抠门碎石)任务插件 +// 识别理智恢复时间,仅在 5:55 以上才碎石,否则等待 +// ref to https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues/1607 +class DrGrandetTaskPlugin : public AbstractTaskPlugin +{ +public: + using AbstractTaskPlugin::AbstractTaskPlugin; + virtual ~DrGrandetTaskPlugin() override = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; + virtual bool verify(AsstMsg msg, const json::value& details) const override; - // 识别“理智将在x:xx后恢复”,返回 x:xx 对应的 毫秒 数 - // 若识别失败返回 < 0 - static int analyze_time_left(const cv::Mat& img); + // 识别“理智将在x:xx后恢复”,返回 x:xx 对应的 毫秒 数 + // 若识别失败返回 < 0 + static int analyze_time_left(const cv::Mat& img); - private: - virtual bool _run() override; - }; +private: + virtual bool _run() override; +}; } diff --git a/src/MaaCore/Task/Fight/FightTimesTaskPlugin.h b/src/MaaCore/Task/Fight/FightTimesTaskPlugin.h index ddb0829dd3..b5596e9243 100644 --- a/src/MaaCore/Task/Fight/FightTimesTaskPlugin.h +++ b/src/MaaCore/Task/Fight/FightTimesTaskPlugin.h @@ -1,21 +1,23 @@ #pragma once #include "Task/AbstractTaskPlugin.h" + namespace asst { - class FightTimesTaskPlugin : public AbstractTaskPlugin - { - public: - using AbstractTaskPlugin::AbstractTaskPlugin; - virtual ~FightTimesTaskPlugin() override = default; +class FightTimesTaskPlugin : public AbstractTaskPlugin +{ +public: + using AbstractTaskPlugin::AbstractTaskPlugin; + virtual ~FightTimesTaskPlugin() override = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; - void set_series(int series) { m_series = series; } + virtual bool verify(AsstMsg msg, const json::value& details) const override; - protected: - virtual bool _run() override; + void set_series(int series) { m_series = series; } - private: - bool inited = false; // 是否成功初始化为1次,初始化后后续不再检测 (实现调整次数后移除此变量 - int m_series = 1; // 连续战斗次数 - }; +protected: + virtual bool _run() override; + +private: + bool inited = false; // 是否成功初始化为1次,初始化后后续不再检测 (实现调整次数后移除此变量 + int m_series = 1; // 连续战斗次数 +}; } diff --git a/src/MaaCore/Task/Fight/SanityBeforeStageTaskPlugin.h b/src/MaaCore/Task/Fight/SanityBeforeStageTaskPlugin.h index 54fc24c984..0c153bd8b8 100644 --- a/src/MaaCore/Task/Fight/SanityBeforeStageTaskPlugin.h +++ b/src/MaaCore/Task/Fight/SanityBeforeStageTaskPlugin.h @@ -1,19 +1,20 @@ #pragma once #include "Task/AbstractTaskPlugin.h" + namespace asst { - class SanityBeforeStageTaskPlugin final : public AbstractTaskPlugin - { - public: - using AbstractTaskPlugin::AbstractTaskPlugin; - virtual ~SanityBeforeStageTaskPlugin() override = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; +class SanityBeforeStageTaskPlugin final : public AbstractTaskPlugin +{ +public: + using AbstractTaskPlugin::AbstractTaskPlugin; + virtual ~SanityBeforeStageTaskPlugin() override = default; + virtual bool verify(AsstMsg msg, const json::value& details) const override; - private: - virtual bool _run() override; +private: + virtual bool _run() override; - // 获取 当前理智/最大理智 - // 返回 是否获取成功 - bool get_sanity_before_stage(); - }; + // 获取 当前理智/最大理智 + // 返回 是否获取成功 + bool get_sanity_before_stage(); +}; } diff --git a/src/MaaCore/Task/Fight/SideStoryReopenTask.cpp b/src/MaaCore/Task/Fight/SideStoryReopenTask.cpp index c26f7e342b..0d184c47d1 100644 --- a/src/MaaCore/Task/Fight/SideStoryReopenTask.cpp +++ b/src/MaaCore/Task/Fight/SideStoryReopenTask.cpp @@ -9,8 +9,9 @@ void asst::SideStoryReopenTask::set_sidestory_name(std::string sidestory_name) { std::string upper_prefix = std::move(sidestory_name); - ranges::transform(upper_prefix, upper_prefix.begin(), - [](char ch) -> char { return static_cast(::toupper(ch)); }); + ranges::transform(upper_prefix, upper_prefix.begin(), [](char ch) -> char { + return static_cast(::toupper(ch)); + }); m_sidestory_name = upper_prefix; } @@ -34,22 +35,26 @@ bool asst::SideStoryReopenTask::set_server(std::string server) m_server = std::move(server); return true; } + bool asst::SideStoryReopenTask::set_enable_penguin(bool enable) { m_enable_penguin = enable; return true; } + bool asst::SideStoryReopenTask::set_penguin_id(std::string id) { m_penguin_id = std::move(id); return true; } + bool asst::SideStoryReopenTask::set_enable_yituliu(bool enable) { // 暂时没用上,其他地方加了这里也加一个 m_enable_yituliu = enable; return true; } + bool asst::SideStoryReopenTask::_run() { LogTraceFunction; @@ -131,6 +136,7 @@ bool asst::SideStoryReopenTask::_run() } return true; } + bool asst::SideStoryReopenTask::at_normal_page() { std::vector stage_name; @@ -144,6 +150,7 @@ bool asst::SideStoryReopenTask::at_normal_page() return ProcessTask(*this, { m_sidestory_name + "@ClickStageName" }).set_retry_times(0).run(); } + /// /// 从首页导航至普通关页面 /// @@ -154,6 +161,7 @@ bool asst::SideStoryReopenTask::navigate_to_normal_page() return ProcessTask(*this, { "StageBegin" }).set_times_limit("GoLastBattle", 0).run() && ProcessTask(*this, { "SideStoryReopen" }).run(); } + /// /// 点选关卡 /// @@ -168,6 +176,7 @@ bool asst::SideStoryReopenTask::select_stage(int stage_index) Task.get(m_stage_code + "@ClickedCorrectStage")->text = { m_stage_code }; return ProcessTask(*this, { m_stage_code + "@StageNavigationBegin" }).run(); } + /// /// 检查 / 激活代理 /// diff --git a/src/MaaCore/Task/Fight/SideStoryReopenTask.h b/src/MaaCore/Task/Fight/SideStoryReopenTask.h index 7938d947e0..61036338b8 100644 --- a/src/MaaCore/Task/Fight/SideStoryReopenTask.h +++ b/src/MaaCore/Task/Fight/SideStoryReopenTask.h @@ -3,46 +3,46 @@ namespace asst { - class SideStoryReopenTask final : public AbstractTask - { - public: - using AbstractTask::AbstractTask; - // SideStoryReopenTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); - virtual ~SideStoryReopenTask() noexcept override = default; +class SideStoryReopenTask final : public AbstractTask +{ +public: + using AbstractTask::AbstractTask; + // SideStoryReopenTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); + virtual ~SideStoryReopenTask() noexcept override = default; - void set_sidestory_name(std::string sidestory_name); - void set_medicine(int medicine); - void set_expiring_medicine(int expiring_medicine); - void set_stone(int stone); + void set_sidestory_name(std::string sidestory_name); + void set_medicine(int medicine); + void set_expiring_medicine(int expiring_medicine); + void set_stone(int stone); - bool set_enable_penguin(bool enable); - bool set_penguin_id(std::string id); - bool set_server(std::string server); + bool set_enable_penguin(bool enable); + bool set_penguin_id(std::string id); + bool set_server(std::string server); - bool set_enable_yituliu(bool enable); + bool set_enable_yituliu(bool enable); - private: - virtual bool _run() override; - // 判断如果处于普通关页面,直接短路导航 - bool at_normal_page(); - bool navigate_to_normal_page(); - bool select_stage(int stage_index); - bool activate_prts(); - bool fight(bool use_medicine, bool use_stone); - void clear(); +private: + virtual bool _run() override; + // 判断如果处于普通关页面,直接短路导航 + bool at_normal_page(); + bool navigate_to_normal_page(); + bool select_stage(int stage_index); + bool activate_prts(); + bool fight(bool use_medicine, bool use_stone); + void clear(); - std::string m_sidestory_name; // 活动名简称:IC、CW等 - int m_medicine = 0; - int m_expiring_medicine = 0; - int m_stone = 0; - int m_cur_medicine; // 已使用的理智药数量,不计算临期药品。在每次任务开始前,通过clear()清空 - int m_cur_stone; // 已碎石数量。在每次任务开始前,通过clear()清空 - bool m_sanity_not_enough = false; // 理智不够,需要吃药 / 碎石 - std::unordered_map m_drop_stats; - bool m_enable_penguin = false; // 企鹅物流上报用 - std::string m_penguin_id; - std::string m_server = "CN"; - bool m_enable_yituliu = false; // 一图流上报用 - }; + std::string m_sidestory_name; // 活动名简称:IC、CW等 + int m_medicine = 0; + int m_expiring_medicine = 0; + int m_stone = 0; + int m_cur_medicine; // 已使用的理智药数量,不计算临期药品。在每次任务开始前,通过clear()清空 + int m_cur_stone; // 已碎石数量。在每次任务开始前,通过clear()清空 + bool m_sanity_not_enough = false; // 理智不够,需要吃药 / 碎石 + std::unordered_map m_drop_stats; + bool m_enable_penguin = false; // 企鹅物流上报用 + std::string m_penguin_id; + std::string m_server = "CN"; + bool m_enable_yituliu = false; // 一图流上报用 +}; } diff --git a/src/MaaCore/Task/Fight/StageDropsTaskPlugin.cpp b/src/MaaCore/Task/Fight/StageDropsTaskPlugin.cpp index e8fb771a47..ef2f9546b4 100644 --- a/src/MaaCore/Task/Fight/StageDropsTaskPlugin.cpp +++ b/src/MaaCore/Task/Fight/StageDropsTaskPlugin.cpp @@ -183,8 +183,9 @@ bool asst::StageDropsTaskPlugin::recognize_drops() auto&& [code, difficulty] = analyzer.get_stage_key(); m_stage_code = std::move(code); - ranges::transform(m_stage_code, m_stage_code.begin(), - [](char ch) -> char { return static_cast(::toupper(ch)); }); + ranges::transform(m_stage_code, m_stage_code.begin(), [](char ch) -> char { + return static_cast(::toupper(ch)); + }); m_stage_difficulty = difficulty; m_stars = analyzer.get_stars(); m_cur_drops = analyzer.get_drops(); diff --git a/src/MaaCore/Task/Fight/StageDropsTaskPlugin.h b/src/MaaCore/Task/Fight/StageDropsTaskPlugin.h index 560bb5f6f9..9fd99bc901 100644 --- a/src/MaaCore/Task/Fight/StageDropsTaskPlugin.h +++ b/src/MaaCore/Task/Fight/StageDropsTaskPlugin.h @@ -12,62 +12,62 @@ namespace asst { - class ProcessTask; - class ReportDataTask; +class ProcessTask; +class ReportDataTask; - class StageDropsTaskPlugin final : public AbstractTaskPlugin - { - public: - using AbstractTaskPlugin::AbstractTaskPlugin; - virtual ~StageDropsTaskPlugin() override = default; +class StageDropsTaskPlugin final : public AbstractTaskPlugin +{ +public: + using AbstractTaskPlugin::AbstractTaskPlugin; + virtual ~StageDropsTaskPlugin() override = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; - virtual void set_task_ptr(AbstractTask* ptr) override; + virtual bool verify(AsstMsg msg, const json::value& details) const override; + virtual void set_task_ptr(AbstractTask* ptr) override; - bool set_enable_penguin(bool enable); - bool set_penguin_id(std::string id); - bool set_server(std::string server); - bool set_specify_quantity(std::unordered_map quantity); + bool set_enable_penguin(bool enable); + bool set_penguin_id(std::string id); + bool set_server(std::string server); + bool set_specify_quantity(std::unordered_map quantity); - bool set_enable_yituliu(bool enable); + bool set_enable_yituliu(bool enable); - private: - virtual bool _run() override; +private: + virtual bool _run() override; - bool recognize_drops(); - void drop_info_callback(); - void set_start_button_delay(); - bool check_stage_valid(); - bool check_specify_quantity() const; - void stop_task(); - bool upload_to_server(const std::string& subtask, ReportType report_type); - bool upload_to_penguin(); // 返回值表示该次掉落是否通过企鹅检查 - void upload_to_yituliu(); - static void report_penguin_callback(AsstMsg msg, const json::value& detail, AbstractTask* task_ptr); - static void report_yituliu_callback(AsstMsg msg, const json::value& detail, AbstractTask* task_ptr); + bool recognize_drops(); + void drop_info_callback(); + void set_start_button_delay(); + bool check_stage_valid(); + bool check_specify_quantity() const; + void stop_task(); + bool upload_to_server(const std::string& subtask, ReportType report_type); + bool upload_to_penguin(); // 返回值表示该次掉落是否通过企鹅检查 + void upload_to_yituliu(); + static void report_penguin_callback(AsstMsg msg, const json::value& detail, AbstractTask* task_ptr); + static void report_yituliu_callback(AsstMsg msg, const json::value& detail, AbstractTask* task_ptr); - static inline constexpr int64_t RecognitionTimeOffset = 20; - static inline const std::string LastStartTimeKey = Status::ProcessTaskLastTimePrefix + "Fight@StartButton2"; - static inline const std::string LastPRTS1TimeKey = Status::ProcessTaskLastTimePrefix + "Fight@PRTS1"; - static inline const std::string RecognitionRestrictionsKey = "StageDropsTaskPluginRestrictions"; + static inline constexpr int64_t RecognitionTimeOffset = 20; + static inline const std::string LastStartTimeKey = Status::ProcessTaskLastTimePrefix + "Fight@StartButton2"; + static inline const std::string LastPRTS1TimeKey = Status::ProcessTaskLastTimePrefix + "Fight@PRTS1"; + static inline const std::string RecognitionRestrictionsKey = "StageDropsTaskPluginRestrictions"; - std::string m_stage_code; - StageDifficulty m_stage_difficulty = StageDifficulty::Normal; - int m_stars = 0; - int m_times = -2; // -2 means recognition failed, -1 means not found - std::vector m_cur_drops; - std::unordered_map m_drop_stats; - json::value m_cur_info_json; + std::string m_stage_code; + StageDifficulty m_stage_difficulty = StageDifficulty::Normal; + int m_stars = 0; + int m_times = -2; // -2 means recognition failed, -1 means not found + std::vector m_cur_drops; + std::unordered_map m_drop_stats; + json::value m_cur_info_json; - mutable bool m_is_annihilation = false; - bool m_start_button_delay_is_set = false; - ProcessTask* m_cast_ptr = nullptr; - std::shared_ptr m_report_penguin_task_ptr = nullptr; - std::shared_ptr m_report_yituliu_task_ptr = nullptr; - bool m_enable_penguin = false; - std::string m_penguin_id; - bool m_enable_yituliu = false; - std::string m_server = "CN"; - std::unordered_map m_specify_quantity; - }; + mutable bool m_is_annihilation = false; + bool m_start_button_delay_is_set = false; + ProcessTask* m_cast_ptr = nullptr; + std::shared_ptr m_report_penguin_task_ptr = nullptr; + std::shared_ptr m_report_yituliu_task_ptr = nullptr; + bool m_enable_penguin = false; + std::string m_penguin_id; + bool m_enable_yituliu = false; + std::string m_server = "CN"; + std::unordered_map m_specify_quantity; +}; } diff --git a/src/MaaCore/Task/Fight/StageNavigationTask.cpp b/src/MaaCore/Task/Fight/StageNavigationTask.cpp index 80b64f1fc9..d0209491f2 100644 --- a/src/MaaCore/Task/Fight/StageNavigationTask.cpp +++ b/src/MaaCore/Task/Fight/StageNavigationTask.cpp @@ -113,9 +113,6 @@ bool asst::StageNavigationTask::swipe_and_find_stage() Task.get(m_stage_code + "@ClickStageName")->text = { m_stage_code }; std::string replace_m_stage_code = m_stage_code; utils::string_replace_all_in_place(replace_m_stage_code, { { "-", "" } }); - Task.get(m_stage_code + "@ClickedCorrectStage")->text = { m_stage_code, - replace_m_stage_code }; - return ProcessTask(*this, { m_stage_code + "@StageNavigationBegin" }) - .set_retry_times(RetryTimesDefault) - .run(); + Task.get(m_stage_code + "@ClickedCorrectStage")->text = { m_stage_code, replace_m_stage_code }; + return ProcessTask(*this, { m_stage_code + "@StageNavigationBegin" }).set_retry_times(RetryTimesDefault).run(); } diff --git a/src/MaaCore/Task/Fight/StageNavigationTask.h b/src/MaaCore/Task/Fight/StageNavigationTask.h index e7d423a273..83694e481a 100644 --- a/src/MaaCore/Task/Fight/StageNavigationTask.h +++ b/src/MaaCore/Task/Fight/StageNavigationTask.h @@ -3,27 +3,27 @@ namespace asst { - class StageNavigationTask : public AbstractTask - { - public: - using AbstractTask::AbstractTask; - virtual ~StageNavigationTask() noexcept override = default; +class StageNavigationTask : public AbstractTask +{ +public: + using AbstractTask::AbstractTask; + virtual ~StageNavigationTask() noexcept override = default; - bool set_stage_name(const std::string& stage_name); + bool set_stage_name(const std::string& stage_name); - protected: - virtual bool _run() override; - void clear() noexcept; +protected: + virtual bool _run() override; + void clear() noexcept; - bool chapter_wayfinding(); - bool swipe_and_find_stage(); + bool chapter_wayfinding(); + bool swipe_and_find_stage(); - // 是否有定义任务名的Task - bool m_is_directly = false; - std::string m_directly_task; - // Not directly - std::string m_chapter_task; - std::string m_difficulty_task; - std::string m_stage_code; - }; + // 是否有定义任务名的Task + bool m_is_directly = false; + std::string m_directly_task; + // Not directly + std::string m_chapter_task; + std::string m_difficulty_task; + std::string m_stage_code; +}; } diff --git a/src/MaaCore/Task/Fight/StageQueueMissionCompletedTaskPlugin.cpp b/src/MaaCore/Task/Fight/StageQueueMissionCompletedTaskPlugin.cpp index c55e1bf0ad..efefdad775 100644 --- a/src/MaaCore/Task/Fight/StageQueueMissionCompletedTaskPlugin.cpp +++ b/src/MaaCore/Task/Fight/StageQueueMissionCompletedTaskPlugin.cpp @@ -68,10 +68,12 @@ void asst::StageQueueMissionCompletedTaskPlugin::mission_completed() drop_info_callback(stage_code, difficulty, analyzer); } + // 抄自StageDropsTaskPlugin -void asst::StageQueueMissionCompletedTaskPlugin::drop_info_callback(std::string stage_code, - StageDifficulty stage_difficulty, - StageDropsImageAnalyzer analyzer) +void asst::StageQueueMissionCompletedTaskPlugin::drop_info_callback( + std::string stage_code, + StageDifficulty stage_difficulty, + StageDropsImageAnalyzer analyzer) { LogTraceFunction; @@ -122,27 +124,32 @@ void asst::StageQueueMissionCompletedTaskPlugin::drop_info_callback(std::string upload_to_penguin(stage_code, analyzer.get_stars()); } } + bool asst::StageQueueMissionCompletedTaskPlugin::set_server(std::string server) { m_server = std::move(server); return true; } + bool asst::StageQueueMissionCompletedTaskPlugin::set_enable_penguin(bool enable) { m_enable_penguin = enable; return true; } + bool asst::StageQueueMissionCompletedTaskPlugin::set_penguin_id(std::string id) { m_penguin_id = std::move(id); return true; } + bool asst::StageQueueMissionCompletedTaskPlugin::set_enable_yituliu(bool enable) { // 暂时没用上,其他地方加了这里也加一个 m_enable_yituliu = enable; return true; } + void asst::StageQueueMissionCompletedTaskPlugin::upload_to_penguin(std::string stage_code, int stars) { LogTraceFunction; @@ -214,8 +221,11 @@ void asst::StageQueueMissionCompletedTaskPlugin::upload_to_penguin(std::string s .set_retry_times(5) .run(); } -void asst::StageQueueMissionCompletedTaskPlugin::report_penguin_callback(AsstMsg msg, const json::value& detail, - AbstractTask* task_ptr) + +void asst::StageQueueMissionCompletedTaskPlugin::report_penguin_callback( + AsstMsg msg, + const json::value& detail, + AbstractTask* task_ptr) { LogTraceFunction; diff --git a/src/MaaCore/Task/Fight/StageQueueMissionCompletedTaskPlugin.h b/src/MaaCore/Task/Fight/StageQueueMissionCompletedTaskPlugin.h index 7aade61e2f..0f7d2f55eb 100644 --- a/src/MaaCore/Task/Fight/StageQueueMissionCompletedTaskPlugin.h +++ b/src/MaaCore/Task/Fight/StageQueueMissionCompletedTaskPlugin.h @@ -13,38 +13,37 @@ namespace asst { - class StageQueueMissionCompletedTaskPlugin : public AbstractTaskPlugin - { - public: - using AbstractTaskPlugin::AbstractTaskPlugin; - virtual ~StageQueueMissionCompletedTaskPlugin() override = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; - void set_drop_stats(std::unordered_map m_drop_stats); - std::unordered_map get_drop_stats(); +class StageQueueMissionCompletedTaskPlugin : public AbstractTaskPlugin +{ +public: + using AbstractTaskPlugin::AbstractTaskPlugin; + virtual ~StageQueueMissionCompletedTaskPlugin() override = default; + virtual bool verify(AsstMsg msg, const json::value& details) const override; + void set_drop_stats(std::unordered_map m_drop_stats); + std::unordered_map get_drop_stats(); - bool set_enable_penguin(bool enable); - bool set_penguin_id(std::string id); - bool set_server(std::string server); + bool set_enable_penguin(bool enable); + bool set_penguin_id(std::string id); + bool set_server(std::string server); - bool set_enable_yituliu(bool enable); + bool set_enable_yituliu(bool enable); - private: - virtual bool _run() override; +private: + virtual bool _run() override; - void mission_completed(); - void drop_info_callback(std::string stage_code, StageDifficulty stage_difficulty, - StageDropsImageAnalyzer analyzer); - void upload_to_penguin(std::string stage_code, int stars); - static void report_penguin_callback(AsstMsg msg, const json::value& detail, AbstractTask* task_ptr); + void mission_completed(); + void drop_info_callback(std::string stage_code, StageDifficulty stage_difficulty, StageDropsImageAnalyzer analyzer); + void upload_to_penguin(std::string stage_code, int stars); + static void report_penguin_callback(AsstMsg msg, const json::value& detail, AbstractTask* task_ptr); - std::unordered_map m_drop_stats; - json::value m_cur_info_json; - // 企鹅物流上报用 - bool m_enable_penguin = false; - std::string m_penguin_id; - std::string m_server = "CN"; - std::shared_ptr m_report_penguin_task_ptr = nullptr; - // 一图流上报用 - bool m_enable_yituliu = false; - }; + std::unordered_map m_drop_stats; + json::value m_cur_info_json; + // 企鹅物流上报用 + bool m_enable_penguin = false; + std::string m_penguin_id; + std::string m_server = "CN"; + std::shared_ptr m_report_penguin_task_ptr = nullptr; + // 一图流上报用 + bool m_enable_yituliu = false; +}; } diff --git a/src/MaaCore/Task/Infrast/DronesForShamareTaskPlugin.h b/src/MaaCore/Task/Infrast/DronesForShamareTaskPlugin.h index 14a53fced2..d82869909d 100644 --- a/src/MaaCore/Task/Infrast/DronesForShamareTaskPlugin.h +++ b/src/MaaCore/Task/Infrast/DronesForShamareTaskPlugin.h @@ -4,21 +4,21 @@ namespace asst { - class InfrastProductionTask; +class InfrastProductionTask; - // 识别干员“巫恋”,并优先为其使用无人机 的任务插件 - class DronesForShamareTaskPlugin final : public AbstractTaskPlugin - { - public: - using AbstractTaskPlugin::AbstractTaskPlugin; - virtual ~DronesForShamareTaskPlugin() override = default; +// 识别干员“巫恋”,并优先为其使用无人机 的任务插件 +class DronesForShamareTaskPlugin final : public AbstractTaskPlugin +{ +public: + using AbstractTaskPlugin::AbstractTaskPlugin; + virtual ~DronesForShamareTaskPlugin() override = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; - virtual void set_task_ptr(AbstractTask* ptr) override; + virtual bool verify(AsstMsg msg, const json::value& details) const override; + virtual void set_task_ptr(AbstractTask* ptr) override; - private: - virtual bool _run() override; +private: + virtual bool _run() override; - InfrastProductionTask* m_cast_ptr = nullptr; - }; + InfrastProductionTask* m_cast_ptr = nullptr; +}; } diff --git a/src/MaaCore/Task/Infrast/InfrastAbstractTask.cpp b/src/MaaCore/Task/Infrast/InfrastAbstractTask.cpp index 966a2fdc8c..072124e3cf 100644 --- a/src/MaaCore/Task/Infrast/InfrastAbstractTask.cpp +++ b/src/MaaCore/Task/Infrast/InfrastAbstractTask.cpp @@ -17,9 +17,11 @@ #include "Vision/OCRer.h" #include "Vision/RegionOCRer.h" -asst::InfrastAbstractTask::InfrastAbstractTask(const AsstCallback& callback, Assistant* inst, - std::string_view task_chain) - : AbstractTask(callback, inst, task_chain) +asst::InfrastAbstractTask::InfrastAbstractTask( + const AsstCallback& callback, + Assistant* inst, + std::string_view task_chain) : + AbstractTask(callback, inst, task_chain) { m_retry_times = TaskRetryTimes; } @@ -134,10 +136,11 @@ bool asst::InfrastAbstractTask::match_operator_groups() // 筛选第一个满足要求的干员组 for (const auto& oper_group_pair : current_room_config().operator_groups) { if (ranges::all_of(oper_group_pair.second, [opers](const std::string& oper) { return opers.contains(oper); })) { - ranges::for_each(oper_group_pair.second, [&opers](const std::string& oper) { opers.erase(oper); }); - current_room_config().names.insert(current_room_config().names.end(), oper_group_pair.second.begin(), - oper_group_pair.second.end()); + current_room_config().names.insert( + current_room_config().names.end(), + oper_group_pair.second.begin(), + oper_group_pair.second.end()); json::value sanity_info = basic_info_with_what("CustomInfrastRoomGroupsMatch"); sanity_info["details"]["group"] = oper_group_pair.first; @@ -305,7 +308,7 @@ bool asst::InfrastAbstractTask::swipe_and_select_custom_opers(bool is_dorm_order ++swipe_times; // 最后一页会触底反弹,先糊个屎避免一下 // 总不能有成体系的干员了还没160个人吧) - if(swipe_times > 20) { + if (swipe_times > 20) { sleep(500); } } @@ -345,8 +348,9 @@ bool asst::InfrastAbstractTask::swipe_and_select_custom_opers(bool is_dorm_order /// @param origin_room_config 期望的配置 /// @param num_of_opers_expect 期望选中的人数,空置则按names.size()判断 /// @return 是否符合期望 -bool asst::InfrastAbstractTask::select_opers_review(infrast::CustomRoomConfig const& origin_room_config, - size_t num_of_opers_expect) +bool asst::InfrastAbstractTask::select_opers_review( + infrast::CustomRoomConfig const& origin_room_config, + size_t num_of_opers_expect) { LogTraceFunction; // save_img("debug/"); @@ -354,8 +358,8 @@ bool asst::InfrastAbstractTask::select_opers_review(infrast::CustomRoomConfig co const auto image = ctrler()->get_image(); InfrastOperImageAnalyzer oper_analyzer(image); - oper_analyzer.set_to_be_calced(InfrastOperImageAnalyzer::ToBeCalced::Selected | - InfrastOperImageAnalyzer::ToBeCalced::Doing); + oper_analyzer.set_to_be_calced( + InfrastOperImageAnalyzer::ToBeCalced::Selected | InfrastOperImageAnalyzer::ToBeCalced::Doing); if (!oper_analyzer.analyze()) { Log.warn("No oper"); return false; @@ -364,8 +368,13 @@ bool asst::InfrastAbstractTask::select_opers_review(infrast::CustomRoomConfig co const auto& oper_analyzer_res = oper_analyzer.get_result(); size_t selected_count = ranges::count_if(oper_analyzer_res, [](const infrast::Oper& info) { return info.selected; }); - Log.info("selected_count,config.names.size,num_of_opers_expect = ", selected_count, ",", room_config.names.size(), - ",", num_of_opers_expect); + Log.info( + "selected_count,config.names.size,num_of_opers_expect = ", + selected_count, + ",", + room_config.names.size(), + ",", + num_of_opers_expect); if (selected_count < num_of_opers_expect) { Log.warn("select opers review fail: unexpected number of selected operators "); diff --git a/src/MaaCore/Task/Infrast/InfrastAbstractTask.h b/src/MaaCore/Task/Infrast/InfrastAbstractTask.h index ce0b21225b..4f3c7a7fc2 100644 --- a/src/MaaCore/Task/Infrast/InfrastAbstractTask.h +++ b/src/MaaCore/Task/Infrast/InfrastAbstractTask.h @@ -7,77 +7,80 @@ namespace asst { - class InfrastAbstractTask : public AbstractTask - { - public: - InfrastAbstractTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); +class InfrastAbstractTask : public AbstractTask +{ +public: + InfrastAbstractTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); - virtual ~InfrastAbstractTask() override = default; - InfrastAbstractTask& set_mood_threshold(double mood_thres) noexcept; + virtual ~InfrastAbstractTask() override = default; + InfrastAbstractTask& set_mood_threshold(double mood_thres) noexcept; - virtual json::value basic_info() const override; - virtual std::string facility_name() const; - virtual size_t max_num_of_facilities() const noexcept { return 1ULL; } - virtual size_t max_num_of_opers() const noexcept { return 1ULL; } + virtual json::value basic_info() const override; + virtual std::string facility_name() const; - void set_custom_config(infrast::CustomFacilityConfig config) noexcept; - void clear_custom_config() noexcept; + virtual size_t max_num_of_facilities() const noexcept { return 1ULL; } - static constexpr int OperSelectRetryTimes = 3; - static constexpr int TaskRetryTimes = 3; + virtual size_t max_num_of_opers() const noexcept { return 1ULL; } - protected: - virtual bool on_run_fails() override; + void set_custom_config(infrast::CustomFacilityConfig config) noexcept; + void clear_custom_config() noexcept; - bool enter_facility(int index = 0); - // 从刚点进设施的界面,到干员列表页 - bool enter_oper_list_page(); + static constexpr int OperSelectRetryTimes = 3; + static constexpr int TaskRetryTimes = 3; - virtual int operlist_swipe_times() const noexcept { return 2; } - // 滑动到干员列表的最左侧 - void swipe_to_the_left_of_operlist(int loop_times = -1); - // 滑动基建的主界面到最左侧 - void swipe_to_the_left_of_main_ui(); - // 滑动基建的主界面到最右侧 - void swipe_to_the_right_of_main_ui(); - void swipe_of_operlist(); - bool is_use_custom_opers(); - infrast::CustomRoomConfig& current_room_config(); - // 将定义的干员编组解释为具体干员,每次基建换班任务的第一次调用时缓存可用干员列表 - bool match_operator_groups(); - // 编组匹配用的可用干员列表,每次基建换班任务清空 - std::set get_available_oper_for_group(); - void set_available_oper_for_group(std::set opers); +protected: + virtual bool on_run_fails() override; - bool swipe_and_select_custom_opers(bool is_dorm_order = false); - bool select_custom_opers(std::vector& partial_result); - // 扫描当前页满足心情条件的所有干员名 - bool get_opers(std::vector& result, double mood = 1); - // 复核干员选择是否符合期望 - bool select_opers_review(infrast::CustomRoomConfig const& origin_room_config, size_t num_of_opers_expect = 0); - void order_opers_selection(const std::vector& names); + bool enter_facility(int index = 0); + // 从刚点进设施的界面,到干员列表页 + bool enter_oper_list_page(); - virtual void click_return_button() override; - // 点击进入设施后,左下角的tab(我也不知道这玩意该叫啥) - virtual bool click_bottom_left_tab(); - // 点击干员选择页面的“清空选择”按钮 - virtual bool click_clear_button(); - // 点击干员选择页面的“按信赖值排序”按钮 - virtual bool click_sort_by_trust_button(); - // 点击干员选择页面的筛选菜单按钮的“未进驻”按钮 - virtual bool click_filter_menu_not_stationed_button(); - // 取消点击干员选择页面的筛选菜单按钮的“未进驻”按钮 - virtual bool click_filter_menu_cancel_not_stationed_button(); - // 点击干员选择页面的“确认”按钮 - virtual bool click_confirm_button(); + virtual int operlist_swipe_times() const noexcept { return 2; } - int m_last_swipe_id = 0; - const std::string m_work_mode_name = - "Aggressive"; // 历史遗留问题,之前是分工作模式的,后来发现其他模式都不好用,就全删了只保留了这一个 - double m_mood_threshold = 0; - mutable std::string m_facility_name_cache; - int m_cur_facility_index = 0; - bool m_is_custom = false; - infrast::CustomFacilityConfig m_custom_config; - }; + // 滑动到干员列表的最左侧 + void swipe_to_the_left_of_operlist(int loop_times = -1); + // 滑动基建的主界面到最左侧 + void swipe_to_the_left_of_main_ui(); + // 滑动基建的主界面到最右侧 + void swipe_to_the_right_of_main_ui(); + void swipe_of_operlist(); + bool is_use_custom_opers(); + infrast::CustomRoomConfig& current_room_config(); + // 将定义的干员编组解释为具体干员,每次基建换班任务的第一次调用时缓存可用干员列表 + bool match_operator_groups(); + // 编组匹配用的可用干员列表,每次基建换班任务清空 + std::set get_available_oper_for_group(); + void set_available_oper_for_group(std::set opers); + + bool swipe_and_select_custom_opers(bool is_dorm_order = false); + bool select_custom_opers(std::vector& partial_result); + // 扫描当前页满足心情条件的所有干员名 + bool get_opers(std::vector& result, double mood = 1); + // 复核干员选择是否符合期望 + bool select_opers_review(infrast::CustomRoomConfig const& origin_room_config, size_t num_of_opers_expect = 0); + void order_opers_selection(const std::vector& names); + + virtual void click_return_button() override; + // 点击进入设施后,左下角的tab(我也不知道这玩意该叫啥) + virtual bool click_bottom_left_tab(); + // 点击干员选择页面的“清空选择”按钮 + virtual bool click_clear_button(); + // 点击干员选择页面的“按信赖值排序”按钮 + virtual bool click_sort_by_trust_button(); + // 点击干员选择页面的筛选菜单按钮的“未进驻”按钮 + virtual bool click_filter_menu_not_stationed_button(); + // 取消点击干员选择页面的筛选菜单按钮的“未进驻”按钮 + virtual bool click_filter_menu_cancel_not_stationed_button(); + // 点击干员选择页面的“确认”按钮 + virtual bool click_confirm_button(); + + int m_last_swipe_id = 0; + const std::string m_work_mode_name = + "Aggressive"; // 历史遗留问题,之前是分工作模式的,后来发现其他模式都不好用,就全删了只保留了这一个 + double m_mood_threshold = 0; + mutable std::string m_facility_name_cache; + int m_cur_facility_index = 0; + bool m_is_custom = false; + infrast::CustomFacilityConfig m_custom_config; +}; } // namespace asst diff --git a/src/MaaCore/Task/Infrast/InfrastControlTask.h b/src/MaaCore/Task/Infrast/InfrastControlTask.h index 205e0bf1b5..3643d377de 100644 --- a/src/MaaCore/Task/Infrast/InfrastControlTask.h +++ b/src/MaaCore/Task/Infrast/InfrastControlTask.h @@ -3,18 +3,18 @@ namespace asst { - class InfrastControlTask final : public InfrastProductionTask - { - public: - using InfrastProductionTask::InfrastProductionTask; - virtual ~InfrastControlTask() override = default; +class InfrastControlTask final : public InfrastProductionTask +{ +public: + using InfrastProductionTask::InfrastProductionTask; + virtual ~InfrastControlTask() override = default; - virtual size_t max_num_of_opers() const noexcept override { return 5ULL; } + virtual size_t max_num_of_opers() const noexcept override { return 5ULL; } - protected: - virtual int operlist_swipe_times() const noexcept override { return 4; } +protected: + virtual int operlist_swipe_times() const noexcept override { return 4; } - private: - virtual bool _run() override; - }; +private: + virtual bool _run() override; +}; } diff --git a/src/MaaCore/Task/Infrast/InfrastDormTask.h b/src/MaaCore/Task/Infrast/InfrastDormTask.h index f36e911d33..4903b17f1d 100644 --- a/src/MaaCore/Task/Infrast/InfrastDormTask.h +++ b/src/MaaCore/Task/Infrast/InfrastDormTask.h @@ -3,38 +3,38 @@ namespace asst { - class InfrastDormTask final : public InfrastAbstractTask +class InfrastDormTask final : public InfrastAbstractTask +{ +public: + using InfrastAbstractTask::InfrastAbstractTask; + virtual ~InfrastDormTask() override = default; + + virtual size_t max_num_of_opers() const noexcept override { return 5ULL; } + + InfrastDormTask& set_notstationed_enabled(bool dorm_notstationed_enabled) noexcept; + InfrastDormTask& set_trust_enabled(bool m_dorm_trust_enabled) noexcept; + +private: + virtual bool _run() override; + // virtual bool click_confirm_button() override; + + bool opers_choose(asst::infrast::CustomRoomConfig const& origin_room_config); + bool click_order_by_mood(); + + bool m_dorm_notstationed_enabled = false; // 设置是否启用未进驻筛选 + bool m_dorm_trust_enabled = true; // 设置是否启用蹭信赖 + + int m_max_num_of_dorm = 4; + + enum class NextStep { - public: - using InfrastAbstractTask::InfrastAbstractTask; - virtual ~InfrastDormTask() override = default; - - virtual size_t max_num_of_opers() const noexcept override { return 5ULL; } - - InfrastDormTask& set_notstationed_enabled(bool dorm_notstationed_enabled) noexcept; - InfrastDormTask& set_trust_enabled(bool m_dorm_trust_enabled) noexcept; - - private: - virtual bool _run() override; - // virtual bool click_confirm_button() override; - - bool opers_choose(asst::infrast::CustomRoomConfig const& origin_room_config); - bool click_order_by_mood(); - - bool m_dorm_notstationed_enabled = false; // 设置是否启用未进驻筛选 - bool m_dorm_trust_enabled = true; // 设置是否启用蹭信赖 - - int m_max_num_of_dorm = 4; - - enum class NextStep - { - Rest, - RestDone, - Trust, - Fill, - AllDone, - }; - NextStep m_next_step = NextStep::Rest; - bool m_if_filter_notstationed_haspressed = false; + Rest, + RestDone, + Trust, + Fill, + AllDone, }; + NextStep m_next_step = NextStep::Rest; + bool m_if_filter_notstationed_haspressed = false; +}; } diff --git a/src/MaaCore/Task/Infrast/InfrastInfoTask.h b/src/MaaCore/Task/Infrast/InfrastInfoTask.h index f069f1ce7a..64f68799d1 100644 --- a/src/MaaCore/Task/Infrast/InfrastInfoTask.h +++ b/src/MaaCore/Task/Infrast/InfrastInfoTask.h @@ -3,13 +3,13 @@ namespace asst { - class InfrastInfoTask : public InfrastAbstractTask - { - public: - using InfrastAbstractTask::InfrastAbstractTask; - virtual ~InfrastInfoTask() override = default; +class InfrastInfoTask : public InfrastAbstractTask +{ +public: + using InfrastAbstractTask::InfrastAbstractTask; + virtual ~InfrastInfoTask() override = default; - protected: - virtual bool _run() override; - }; +protected: + virtual bool _run() override; +}; } diff --git a/src/MaaCore/Task/Infrast/InfrastMfgTask.h b/src/MaaCore/Task/Infrast/InfrastMfgTask.h index 381972cc54..73213bc203 100644 --- a/src/MaaCore/Task/Infrast/InfrastMfgTask.h +++ b/src/MaaCore/Task/Infrast/InfrastMfgTask.h @@ -3,17 +3,19 @@ namespace asst { - class InfrastMfgTask final : public InfrastProductionTask - { - public: - using InfrastProductionTask::InfrastProductionTask; - virtual ~InfrastMfgTask() override = default; +class InfrastMfgTask final : public InfrastProductionTask +{ +public: + using InfrastProductionTask::InfrastProductionTask; + virtual ~InfrastMfgTask() override = default; - virtual size_t max_num_of_facilities() const noexcept override { return 5ULL; } - virtual size_t max_num_of_opers() const noexcept override { return 3ULL; } + virtual size_t max_num_of_facilities() const noexcept override { return 5ULL; } - protected: - virtual bool _run() override; - virtual int operlist_swipe_times() const noexcept override { return 5; } - }; + virtual size_t max_num_of_opers() const noexcept override { return 3ULL; } + +protected: + virtual bool _run() override; + + virtual int operlist_swipe_times() const noexcept override { return 5; } +}; } diff --git a/src/MaaCore/Task/Infrast/InfrastOfficeTask.h b/src/MaaCore/Task/Infrast/InfrastOfficeTask.h index bf3de20bd4..246a4a141f 100644 --- a/src/MaaCore/Task/Infrast/InfrastOfficeTask.h +++ b/src/MaaCore/Task/Infrast/InfrastOfficeTask.h @@ -3,13 +3,13 @@ namespace asst { - class InfrastOfficeTask final : public InfrastProductionTask - { - public: - using InfrastProductionTask::InfrastProductionTask; - virtual ~InfrastOfficeTask() override = default; +class InfrastOfficeTask final : public InfrastProductionTask +{ +public: + using InfrastProductionTask::InfrastProductionTask; + virtual ~InfrastOfficeTask() override = default; - protected: - virtual bool _run() override; - }; +protected: + virtual bool _run() override; +}; } diff --git a/src/MaaCore/Task/Infrast/InfrastPowerTask.h b/src/MaaCore/Task/Infrast/InfrastPowerTask.h index 834862a051..536931c578 100644 --- a/src/MaaCore/Task/Infrast/InfrastPowerTask.h +++ b/src/MaaCore/Task/Infrast/InfrastPowerTask.h @@ -3,15 +3,15 @@ namespace asst { - class InfrastPowerTask final : public InfrastProductionTask - { - public: - using InfrastProductionTask::InfrastProductionTask; - virtual ~InfrastPowerTask() override = default; +class InfrastPowerTask final : public InfrastProductionTask +{ +public: + using InfrastProductionTask::InfrastProductionTask; + virtual ~InfrastPowerTask() override = default; - virtual size_t max_num_of_facilities() const noexcept override { return 3ULL; } + virtual size_t max_num_of_facilities() const noexcept override { return 3ULL; } - protected: - virtual bool _run() override; - }; +protected: + virtual bool _run() override; +}; } diff --git a/src/MaaCore/Task/Infrast/InfrastProcessingTask.h b/src/MaaCore/Task/Infrast/InfrastProcessingTask.h index eae707ab51..40528a9281 100644 --- a/src/MaaCore/Task/Infrast/InfrastProcessingTask.h +++ b/src/MaaCore/Task/Infrast/InfrastProcessingTask.h @@ -3,13 +3,13 @@ namespace asst { - class InfrastProcessingTask final : public InfrastProductionTask - { - public: - using InfrastProductionTask::InfrastProductionTask; - virtual ~InfrastProcessingTask() override = default; +class InfrastProcessingTask final : public InfrastProductionTask +{ +public: + using InfrastProductionTask::InfrastProductionTask; + virtual ~InfrastProcessingTask() override = default; - protected: - virtual bool _run() override; - }; +protected: + virtual bool _run() override; +}; } diff --git a/src/MaaCore/Task/Infrast/InfrastProductionTask.cpp b/src/MaaCore/Task/Infrast/InfrastProductionTask.cpp index 7098c4c902..9639bad59b 100644 --- a/src/MaaCore/Task/Infrast/InfrastProductionTask.cpp +++ b/src/MaaCore/Task/Infrast/InfrastProductionTask.cpp @@ -464,8 +464,9 @@ bool asst::InfrastProductionTask::optimal_calc() // necessary里的技能,一个都不能少 // TODO necessary暂时没做hash校验。因为没有需要比hash的necessary干员( for (const infrast::SkillsComb& nec_skills : group.necessary) { - auto find_iter = ranges::find_if(cur_available_opers, - [&](const infrast::SkillsComb& arg) -> bool { return arg == nec_skills; }); + auto find_iter = ranges::find_if(cur_available_opers, [&](const infrast::SkillsComb& arg) -> bool { + return arg == nec_skills; + }); if (find_iter == cur_available_opers.cend()) { group_unavailable = true; break; @@ -498,8 +499,10 @@ bool asst::InfrastProductionTask::optimal_calc() for (const infrast::SkillsComb& opt : optional) { auto find_iter = cur_available_opers.cbegin(); while (cur_combs.size() != static_cast(cur_max_num_of_opers)) { - find_iter = std::find_if(find_iter, cur_available_opers.cend(), - [&](const infrast::SkillsComb& arg) -> bool { return arg == opt; }); + find_iter = + std::find_if(find_iter, cur_available_opers.cend(), [&](const infrast::SkillsComb& arg) -> bool { + return arg == opt; + }); if (find_iter != cur_available_opers.cend()) { bool hash_matched = false; if (opt.name_filter.empty()) { @@ -507,13 +510,13 @@ bool asst::InfrastProductionTask::optimal_calc() } else { RegionOCRer name_analyzer(find_iter->name_img); - name_analyzer.set_replace(Task.get("CharsNameOcrReplace")->replace_map, - Task.get("CharsNameOcrReplace")->replace_full); + name_analyzer.set_replace( + Task.get("CharsNameOcrReplace")->replace_map, + Task.get("CharsNameOcrReplace")->replace_full); Log.trace("Analyze name filter"); if (name_analyzer.analyze()) { std::string name = name_analyzer.get_result().text; - hash_matched = - ranges::find(opt.name_filter, name) != opt.name_filter.cend(); + hash_matched = ranges::find(opt.name_filter, name) != opt.name_filter.cend(); } else { hash_matched = false; @@ -621,8 +624,9 @@ bool asst::InfrastProductionTask::opers_choose() auto cur_all_opers = oper_analyzer.get_result(); Log.trace("before mood filter, opers size:", cur_all_opers.size()); // 小于心情阈值的干员则不可用 - std::erase_if(cur_all_opers, - [&](const infrast::Oper& rhs) -> bool { return rhs.mood_ratio < m_mood_threshold; }); + std::erase_if(cur_all_opers, [&](const infrast::Oper& rhs) -> bool { + return rhs.mood_ratio < m_mood_threshold; + }); Log.trace("after mood filter, opers size:", cur_all_opers.size()); for (auto opt_iter = m_optimal_combs.begin(); opt_iter != m_optimal_combs.end();) { Log.trace("to find", opt_iter->skills.begin()->names.front()); @@ -635,8 +639,9 @@ bool asst::InfrastProductionTask::opers_choose() } else { RegionOCRer name_analyzer(lhs.name_img); - name_analyzer.set_replace(Task.get("CharsNameOcrReplace")->replace_map, - Task.get("CharsNameOcrReplace")->replace_full); + name_analyzer.set_replace( + Task.get("CharsNameOcrReplace")->replace_map, + Task.get("CharsNameOcrReplace")->replace_full); Log.trace("Analyze name filter"); if (!name_analyzer.analyze()) { return false; @@ -711,8 +716,8 @@ bool asst::InfrastProductionTask::use_drone() return task_temp.run(); } -asst::infrast::SkillsComb asst::InfrastProductionTask::efficient_regex_calc( - std::unordered_set skills) const +asst::infrast::SkillsComb + asst::InfrastProductionTask::efficient_regex_calc(std::unordered_set skills) const { infrast::SkillsComb comb(std::move(skills)); // 根据正则,计算当前干员的实际效率 diff --git a/src/MaaCore/Task/Infrast/InfrastProductionTask.h b/src/MaaCore/Task/Infrast/InfrastProductionTask.h index 5b278bab67..120a820f66 100644 --- a/src/MaaCore/Task/Infrast/InfrastProductionTask.h +++ b/src/MaaCore/Task/Infrast/InfrastProductionTask.h @@ -6,43 +6,43 @@ namespace asst { - // 生产类设施的任务,适用于制造站、贸易站、控制中枢 - class InfrastProductionTask : public InfrastAbstractTask - { - public: - using InfrastAbstractTask::InfrastAbstractTask; - virtual ~InfrastProductionTask() override = default; +// 生产类设施的任务,适用于制造站、贸易站、控制中枢 +class InfrastProductionTask : public InfrastAbstractTask +{ +public: + using InfrastAbstractTask::InfrastAbstractTask; + virtual ~InfrastProductionTask() override = default; - InfrastProductionTask& set_uses_of_drone(std::string uses_of_drones) noexcept; - std::string get_uses_of_drone() const noexcept; - void set_custom_drones_config(infrast::CustomDronesConfig drones_config); - void clear_custom_drones_config(); + InfrastProductionTask& set_uses_of_drone(std::string uses_of_drones) noexcept; + std::string get_uses_of_drone() const noexcept; + void set_custom_drones_config(infrast::CustomDronesConfig drones_config); + void clear_custom_drones_config(); - protected: - bool shift_facility_list(); - bool facility_list_detect(); - bool opers_detect_with_swipe(); - // 返回当前页面的干员数 (可用? - size_t opers_detect(); - bool optimal_calc(); - bool opers_choose(); - bool use_drone(); - void set_product(std::string product_name) noexcept; +protected: + bool shift_facility_list(); + bool facility_list_detect(); + bool opers_detect_with_swipe(); + // 返回当前页面的干员数 (可用? + size_t opers_detect(); + bool optimal_calc(); + bool opers_choose(); + bool use_drone(); + void set_product(std::string product_name) noexcept; - infrast::SkillsComb efficient_regex_calc(std::unordered_set skills) const; + infrast::SkillsComb efficient_regex_calc(std::unordered_set skills) const; - std::string m_product; - std::string m_uses_of_drones; - int m_cur_num_of_locked_opers = 0; - std::vector m_all_available_opers; - std::vector m_optimal_combs; - std::vector m_facility_list_tabs; - size_t max_num_of_opers_per_page = 0; - bool m_is_use_custom_drones = false; - infrast::CustomDronesConfig m_custom_drones_config; + std::string m_product; + std::string m_uses_of_drones; + int m_cur_num_of_locked_opers = 0; + std::vector m_all_available_opers; + std::vector m_optimal_combs; + std::vector m_facility_list_tabs; + size_t max_num_of_opers_per_page = 0; + bool m_is_use_custom_drones = false; + infrast::CustomDronesConfig m_custom_drones_config; - protected: - void change_product(); - bool m_is_product_incorrect = false; - }; +protected: + void change_product(); + bool m_is_product_incorrect = false; +}; } diff --git a/src/MaaCore/Task/Infrast/InfrastReceptionTask.cpp b/src/MaaCore/Task/Infrast/InfrastReceptionTask.cpp index fc2b9c5b2b..23e50a1e8d 100644 --- a/src/MaaCore/Task/Infrast/InfrastReceptionTask.cpp +++ b/src/MaaCore/Task/Infrast/InfrastReceptionTask.cpp @@ -51,7 +51,8 @@ bool asst::InfrastReceptionTask::close_end_of_clue_exchange() bool asst::InfrastReceptionTask::get_clue() { ProcessTask task_temp( - *this, { "InfrastClueSelfNew", "InfrastClueFriendNew", "InfrastClueSelfMaybeFull", "ReceptionFlag" }); + *this, + { "InfrastClueSelfNew", "InfrastClueFriendNew", "InfrastClueSelfMaybeFull", "ReceptionFlag" }); return task_temp.set_retry_times(ProcessTask::RetryTimesDefault).run(); } diff --git a/src/MaaCore/Task/Infrast/InfrastReceptionTask.h b/src/MaaCore/Task/Infrast/InfrastReceptionTask.h index 203414271f..74266b3f87 100644 --- a/src/MaaCore/Task/Infrast/InfrastReceptionTask.h +++ b/src/MaaCore/Task/Infrast/InfrastReceptionTask.h @@ -3,25 +3,27 @@ namespace asst { - class InfrastReceptionTask final : public InfrastProductionTask - { - public: - using InfrastProductionTask::InfrastProductionTask; - virtual ~InfrastReceptionTask() override = default; - virtual size_t max_num_of_opers() const noexcept override { return 2ULL; } +class InfrastReceptionTask final : public InfrastProductionTask +{ +public: + using InfrastProductionTask::InfrastProductionTask; + virtual ~InfrastReceptionTask() override = default; - protected: - virtual bool _run() override; + virtual size_t max_num_of_opers() const noexcept override { return 2ULL; } - private: - virtual int operlist_swipe_times() const noexcept override { return 4; } - bool close_end_of_clue_exchange(); - bool get_clue(); - bool use_clue(); - bool proc_clue_vacancy(); - bool unlock_clue_exchange(); - bool back_to_reception_main(); - bool send_clue(); - bool shift(); - }; +protected: + virtual bool _run() override; + +private: + virtual int operlist_swipe_times() const noexcept override { return 4; } + + bool close_end_of_clue_exchange(); + bool get_clue(); + bool use_clue(); + bool proc_clue_vacancy(); + bool unlock_clue_exchange(); + bool back_to_reception_main(); + bool send_clue(); + bool shift(); +}; } diff --git a/src/MaaCore/Task/Infrast/InfrastTradeTask.h b/src/MaaCore/Task/Infrast/InfrastTradeTask.h index 22076053ee..63f089ef81 100644 --- a/src/MaaCore/Task/Infrast/InfrastTradeTask.h +++ b/src/MaaCore/Task/Infrast/InfrastTradeTask.h @@ -3,17 +3,19 @@ namespace asst { - class InfrastTradeTask final : public InfrastProductionTask - { - public: - using InfrastProductionTask::InfrastProductionTask; - virtual ~InfrastTradeTask() override = default; +class InfrastTradeTask final : public InfrastProductionTask +{ +public: + using InfrastProductionTask::InfrastProductionTask; + virtual ~InfrastTradeTask() override = default; - virtual size_t max_num_of_facilities() const noexcept override { return 5ULL; } - virtual size_t max_num_of_opers() const noexcept override { return 3ULL; } + virtual size_t max_num_of_facilities() const noexcept override { return 5ULL; } - protected: - virtual bool _run() override; - virtual int operlist_swipe_times() const noexcept override { return 5; } - }; + virtual size_t max_num_of_opers() const noexcept override { return 3ULL; } + +protected: + virtual bool _run() override; + + virtual int operlist_swipe_times() const noexcept override { return 5; } +}; } diff --git a/src/MaaCore/Task/Infrast/InfrastTrainingTask.cpp b/src/MaaCore/Task/Infrast/InfrastTrainingTask.cpp index d33881c1f2..e0af83c6d7 100644 --- a/src/MaaCore/Task/Infrast/InfrastTrainingTask.cpp +++ b/src/MaaCore/Task/Infrast/InfrastTrainingTask.cpp @@ -23,7 +23,9 @@ bool asst::InfrastTrainingTask::_run() } enter_facility(); - if (!analyze_status()) return false; + if (!analyze_status()) { + return false; + } if (m_continue_training && m_level != 3) { click_bottom_left_tab(); @@ -96,7 +98,9 @@ bool asst::InfrastTrainingTask::analyze_status() m_continue_training = false; - if (!time_left_analyze(image)) return false; + if (!time_left_analyze(image)) { + return false; + } { json::value cb_info = basic_info_with_what("InfrastTrainingTimeLeft"); @@ -120,7 +124,9 @@ bool asst::InfrastTrainingTask::level_analyze(cv::Mat image) std::string level_temp_name = task_name + std::to_string(i) + ".png"; analyzer.append_templ(level_temp_name); } - if (!analyzer.analyze()) return false; + if (!analyzer.analyze()) { + return false; + } const auto& res = analyzer.get_result(); utils::chars_to_number(res.templ_info.name.substr(task_name.size(), 1), m_level); Log.info(__FUNCTION__, "level has been set to ", m_level); @@ -143,7 +149,9 @@ bool asst::InfrastTrainingTask::time_left_analyze(cv::Mat image) for (int i = 0; i < 3; ++i) { progress_analyzer.set_task_info("InfrastTrainingTimeRec" + std::to_string(i)); - if (!progress_analyzer.analyze()) return false; + if (!progress_analyzer.analyze()) { + return false; + } std::string raw_str = progress_analyzer.get_result().text; Log.info(__FUNCTION__, raw_str); @@ -179,7 +187,11 @@ bool asst::InfrastTrainingTask::continue_train(int index) int asst::InfrastTrainingTask::skill_index_from_rect(const Rect& r) { int cy = r.y + r.height / 2; - if (cy <= 300) return 1; - if (cy <= 500) return 2; + if (cy <= 300) { + return 1; + } + if (cy <= 500) { + return 2; + } return 3; } diff --git a/src/MaaCore/Task/Infrast/InfrastTrainingTask.h b/src/MaaCore/Task/Infrast/InfrastTrainingTask.h index fcfc2c6593..b87f89b961 100644 --- a/src/MaaCore/Task/Infrast/InfrastTrainingTask.h +++ b/src/MaaCore/Task/Infrast/InfrastTrainingTask.h @@ -1,35 +1,36 @@ #pragma once #include "InfrastProductionTask.h" + // #include "Config/Miscellaneous/BattleDataConfig.h" // TODO: 根据角色职业增加换班功能 namespace asst { - class InfrastTrainingTask final : public InfrastProductionTask - { - public: - using InfrastProductionTask::InfrastProductionTask; - virtual ~InfrastTrainingTask() override = default; +class InfrastTrainingTask final : public InfrastProductionTask +{ +public: + using InfrastProductionTask::InfrastProductionTask; + virtual ~InfrastTrainingTask() override = default; - InfrastTrainingTask& set_continue_training(bool continue_training) noexcept; + InfrastTrainingTask& set_continue_training(bool continue_training) noexcept; - protected: - virtual bool _run() override; +protected: + virtual bool _run() override; - private: - bool analyze_status(); - bool level_analyze(cv::Mat image); - bool training_completed(); - bool time_left_analyze(cv::Mat image); - bool continue_train(int index); - static int skill_index_from_rect(const Rect& r); +private: + bool analyze_status(); + bool level_analyze(cv::Mat image); + bool training_completed(); + bool time_left_analyze(cv::Mat image); + bool continue_train(int index); + static int skill_index_from_rect(const Rect& r); - int m_level; - int time_left[3]; - std::string m_operator_name; - std::string m_skill_name; - // asst::battle::Role m_operator_role; - - bool m_continue_training = false; - }; + int m_level; + int time_left[3]; + std::string m_operator_name; + std::string m_skill_name; + // asst::battle::Role m_operator_role; + + bool m_continue_training = false; +}; } diff --git a/src/MaaCore/Task/Infrast/ReplenishOriginiumShardTaskPlugin.h b/src/MaaCore/Task/Infrast/ReplenishOriginiumShardTaskPlugin.h index b126fd4588..b66d5a737c 100644 --- a/src/MaaCore/Task/Infrast/ReplenishOriginiumShardTaskPlugin.h +++ b/src/MaaCore/Task/Infrast/ReplenishOriginiumShardTaskPlugin.h @@ -3,16 +3,16 @@ namespace asst { - // 制造站“源石碎片”自动补货任务插件 - class ReplenishOriginiumShardTaskPlugin : public AbstractTaskPlugin - { - public: - using AbstractTaskPlugin::AbstractTaskPlugin; - virtual ~ReplenishOriginiumShardTaskPlugin() override = default; +// 制造站“源石碎片”自动补货任务插件 +class ReplenishOriginiumShardTaskPlugin : public AbstractTaskPlugin +{ +public: + using AbstractTaskPlugin::AbstractTaskPlugin; + virtual ~ReplenishOriginiumShardTaskPlugin() override = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; + virtual bool verify(AsstMsg msg, const json::value& details) const override; - private: - virtual bool _run() override; - }; +private: + virtual bool _run() override; +}; } diff --git a/src/MaaCore/Task/Interface/AwardTask.cpp b/src/MaaCore/Task/Interface/AwardTask.cpp index 5c1090caa7..74718740d7 100644 --- a/src/MaaCore/Task/Interface/AwardTask.cpp +++ b/src/MaaCore/Task/Interface/AwardTask.cpp @@ -6,14 +6,14 @@ #include "Utils/Logger.hpp" -asst::AwardTask::AwardTask(const AsstCallback& callback, Assistant* inst) - : InterfaceTask(callback, inst, TaskType), - award_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), - mail_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), - recruit_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), - orundum_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), - mining_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), - specialaccess_task_ptr(std::make_shared(m_callback, m_inst, TaskType)) +asst::AwardTask::AwardTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType), + award_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), + mail_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), + recruit_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), + orundum_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), + mining_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), + specialaccess_task_ptr(std::make_shared(m_callback, m_inst, TaskType)) { LogTraceFunction; @@ -24,7 +24,6 @@ asst::AwardTask::AwardTask(const AsstCallback& callback, Assistant* inst) orundum_task_ptr->set_tasks({ "OrundumActivitiesBegin" }); mining_task_ptr->set_tasks({ "MiningActivitiesBegin" }); specialaccess_task_ptr->set_tasks({ "SpecialAccessActivitiesBegin" }); - m_subtasks.emplace_back(award_task_ptr); m_subtasks.emplace_back(mail_task_ptr); diff --git a/src/MaaCore/Task/Interface/AwardTask.h b/src/MaaCore/Task/Interface/AwardTask.h index 5dcd421998..240d770819 100644 --- a/src/MaaCore/Task/Interface/AwardTask.h +++ b/src/MaaCore/Task/Interface/AwardTask.h @@ -3,24 +3,24 @@ namespace asst { - class ProcessTask; +class ProcessTask; - class AwardTask final : public InterfaceTask - { - public: - inline static constexpr std::string_view TaskType = "Award"; +class AwardTask final : public InterfaceTask +{ +public: + inline static constexpr std::string_view TaskType = "Award"; - AwardTask(const AsstCallback& callback, Assistant* inst); - virtual ~AwardTask() override = default; + AwardTask(const AsstCallback& callback, Assistant* inst); + virtual ~AwardTask() override = default; - virtual bool set_params(const json::value& params) override; + virtual bool set_params(const json::value& params) override; - private: - std::shared_ptr award_task_ptr = nullptr; - std::shared_ptr mail_task_ptr = nullptr; - std::shared_ptr recruit_task_ptr = nullptr; - std::shared_ptr orundum_task_ptr = nullptr; - std::shared_ptr mining_task_ptr = nullptr; - std::shared_ptr specialaccess_task_ptr = nullptr; - }; +private: + std::shared_ptr award_task_ptr = nullptr; + std::shared_ptr mail_task_ptr = nullptr; + std::shared_ptr recruit_task_ptr = nullptr; + std::shared_ptr orundum_task_ptr = nullptr; + std::shared_ptr mining_task_ptr = nullptr; + std::shared_ptr specialaccess_task_ptr = nullptr; +}; } diff --git a/src/MaaCore/Task/Interface/CloseDownTask.cpp b/src/MaaCore/Task/Interface/CloseDownTask.cpp index 0a9c06e221..53cb178288 100644 --- a/src/MaaCore/Task/Interface/CloseDownTask.cpp +++ b/src/MaaCore/Task/Interface/CloseDownTask.cpp @@ -6,9 +6,9 @@ #include "Task/Miscellaneous/StopGameTaskPlugin.h" #include "Task/ProcessTask.h" -asst::CloseDownTask::CloseDownTask(const AsstCallback& callback, Assistant* inst) - : InterfaceTask(callback, inst, TaskType) - , m_stop_game_task_ptr(std::make_shared(m_callback, m_inst, TaskType)) +asst::CloseDownTask::CloseDownTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType), + m_stop_game_task_ptr(std::make_shared(m_callback, m_inst, TaskType)) { m_subtasks.emplace_back(m_stop_game_task_ptr); } diff --git a/src/MaaCore/Task/Interface/CustomTask.cpp b/src/MaaCore/Task/Interface/CustomTask.cpp index d31ed37982..9957aeffc2 100644 --- a/src/MaaCore/Task/Interface/CustomTask.cpp +++ b/src/MaaCore/Task/Interface/CustomTask.cpp @@ -3,7 +3,8 @@ #include "Utils/Logger.hpp" -asst::CustomTask::CustomTask(const AsstCallback& callback, Assistant* inst) : InterfaceTask(callback, inst, TaskType) +asst::CustomTask::CustomTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType) { LogTraceFunction; } diff --git a/src/MaaCore/Task/Interface/CustomTask.h b/src/MaaCore/Task/Interface/CustomTask.h index 1eecefd0ee..f9fb376f3b 100644 --- a/src/MaaCore/Task/Interface/CustomTask.h +++ b/src/MaaCore/Task/Interface/CustomTask.h @@ -3,15 +3,15 @@ namespace asst { - class ProcessTask; +class ProcessTask; - class CustomTask final : public InterfaceTask - { - public: - inline static constexpr std::string_view TaskType = "Custom"; +class CustomTask final : public InterfaceTask +{ +public: + inline static constexpr std::string_view TaskType = "Custom"; - CustomTask(const AsstCallback& callback, Assistant* inst); - virtual ~CustomTask() override = default; - virtual bool set_params(const json::value& params) override; - }; + CustomTask(const AsstCallback& callback, Assistant* inst); + virtual ~CustomTask() override = default; + virtual bool set_params(const json::value& params) override; +}; } diff --git a/src/MaaCore/Task/Interface/DebugTask.cpp b/src/MaaCore/Task/Interface/DebugTask.cpp index c191b72c90..33e2394641 100644 --- a/src/MaaCore/Task/Interface/DebugTask.cpp +++ b/src/MaaCore/Task/Interface/DebugTask.cpp @@ -13,7 +13,10 @@ #include "Vision/Miscellaneous/DepotImageAnalyzer.h" #include "Vision/Miscellaneous/StageDropsImageAnalyzer.h" -asst::DebugTask::DebugTask(const AsstCallback& callback, Assistant* inst) : InterfaceTask(callback, inst, TaskType) {} +asst::DebugTask::DebugTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType) +{ +} bool asst::DebugTask::run() { diff --git a/src/MaaCore/Task/Interface/DebugTask.h b/src/MaaCore/Task/Interface/DebugTask.h index 9c4214de11..5369066eba 100644 --- a/src/MaaCore/Task/Interface/DebugTask.h +++ b/src/MaaCore/Task/Interface/DebugTask.h @@ -3,20 +3,20 @@ namespace asst { - class DebugTask : public InterfaceTask - { - public: - inline static constexpr std::string_view TaskType = "Debug"; +class DebugTask : public InterfaceTask +{ +public: + inline static constexpr std::string_view TaskType = "Debug"; - DebugTask(const AsstCallback& callback, Assistant* inst); - virtual ~DebugTask() override = default; + DebugTask(const AsstCallback& callback, Assistant* inst); + virtual ~DebugTask() override = default; - virtual bool run() override; + virtual bool run() override; - private: - void test_drops(); - void test_skill_ready(); - void test_battle_image(); - void test_match_template(); - }; +private: + void test_drops(); + void test_skill_ready(); + void test_battle_image(); + void test_match_template(); +}; } diff --git a/src/MaaCore/Task/Interface/DepotTask.cpp b/src/MaaCore/Task/Interface/DepotTask.cpp index d47dae3ae6..ece446052e 100644 --- a/src/MaaCore/Task/Interface/DepotTask.cpp +++ b/src/MaaCore/Task/Interface/DepotTask.cpp @@ -3,7 +3,8 @@ #include "Task/Miscellaneous/DepotRecognitionTask.h" #include "Task/ProcessTask.h" -asst::DepotTask::DepotTask(const AsstCallback& callback, Assistant* inst) : InterfaceTask(callback, inst, TaskType) +asst::DepotTask::DepotTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType) { auto enter_task = std::make_shared(m_callback, m_inst, TaskType); enter_task->set_tasks({ "DepotBegin" }).set_ignore_error(true); diff --git a/src/MaaCore/Task/Interface/DepotTask.h b/src/MaaCore/Task/Interface/DepotTask.h index 9ff3a7e754..7b97afefc0 100644 --- a/src/MaaCore/Task/Interface/DepotTask.h +++ b/src/MaaCore/Task/Interface/DepotTask.h @@ -3,12 +3,12 @@ namespace asst { - class DepotTask final : public InterfaceTask - { - public: - inline static constexpr std::string_view TaskType = "Depot"; +class DepotTask final : public InterfaceTask +{ +public: + inline static constexpr std::string_view TaskType = "Depot"; - DepotTask(const AsstCallback& callback, Assistant* inst); - virtual ~DepotTask() override = default; - }; + DepotTask(const AsstCallback& callback, Assistant* inst); + virtual ~DepotTask() override = default; +}; } diff --git a/src/MaaCore/Task/Interface/FightTask.cpp b/src/MaaCore/Task/Interface/FightTask.cpp index 88a42fb534..de518f7d6e 100644 --- a/src/MaaCore/Task/Interface/FightTask.cpp +++ b/src/MaaCore/Task/Interface/FightTask.cpp @@ -14,12 +14,12 @@ #include "Utils/Logger.hpp" #include "Utils/Ranges.hpp" -asst::FightTask::FightTask(const AsstCallback& callback, Assistant* inst) - : InterfaceTask(callback, inst, TaskType), - m_start_up_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), - m_stage_navigation_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), - m_fight_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), - m_sidestory_reopen_task_ptr(std::make_shared(m_callback, m_inst, TaskType)) +asst::FightTask::FightTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType), + m_start_up_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), + m_stage_navigation_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), + m_fight_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), + m_sidestory_reopen_task_ptr(std::make_shared(m_callback, m_inst, TaskType)) { LogTraceFunction; diff --git a/src/MaaCore/Task/Interface/FightTask.h b/src/MaaCore/Task/Interface/FightTask.h index e9b59a0681..6b0848c4cd 100644 --- a/src/MaaCore/Task/Interface/FightTask.h +++ b/src/MaaCore/Task/Interface/FightTask.h @@ -5,32 +5,32 @@ namespace asst { - class FightTimesTaskPlugin; - class ProcessTask; - class StageDropsTaskPlugin; - class StageNavigationTask; - class DrGrandetTaskPlugin; - class SideStoryReopenTask; - class MedicineCounterTaskPlugin; +class FightTimesTaskPlugin; +class ProcessTask; +class StageDropsTaskPlugin; +class StageNavigationTask; +class DrGrandetTaskPlugin; +class SideStoryReopenTask; +class MedicineCounterTaskPlugin; - class FightTask final : public InterfaceTask - { - public: - inline static constexpr std::string_view TaskType = "Fight"; +class FightTask final : public InterfaceTask +{ +public: + inline static constexpr std::string_view TaskType = "Fight"; - FightTask(const AsstCallback& callback, Assistant* inst); - virtual ~FightTask() override = default; + FightTask(const AsstCallback& callback, Assistant* inst); + virtual ~FightTask() override = default; - virtual bool set_params(const json::value& params) override; + virtual bool set_params(const json::value& params) override; - protected: - std::shared_ptr m_start_up_task_ptr = nullptr; - std::shared_ptr m_stage_navigation_task_ptr = nullptr; - std::shared_ptr m_fight_task_ptr = nullptr; - std::shared_ptr m_fight_times_task_plugin_prt = nullptr; - std::shared_ptr m_medicine_plugin = nullptr; - std::shared_ptr m_stage_drops_plugin_ptr = nullptr; - std::shared_ptr m_dr_grandet_task_plugin_ptr = nullptr; - std::shared_ptr m_sidestory_reopen_task_ptr = nullptr; - }; +protected: + std::shared_ptr m_start_up_task_ptr = nullptr; + std::shared_ptr m_stage_navigation_task_ptr = nullptr; + std::shared_ptr m_fight_task_ptr = nullptr; + std::shared_ptr m_fight_times_task_plugin_prt = nullptr; + std::shared_ptr m_medicine_plugin = nullptr; + std::shared_ptr m_stage_drops_plugin_ptr = nullptr; + std::shared_ptr m_dr_grandet_task_plugin_ptr = nullptr; + std::shared_ptr m_sidestory_reopen_task_ptr = nullptr; +}; } diff --git a/src/MaaCore/Task/Interface/InfrastTask.cpp b/src/MaaCore/Task/Interface/InfrastTask.cpp index b59928a99e..07b4dc5585 100644 --- a/src/MaaCore/Task/Interface/InfrastTask.cpp +++ b/src/MaaCore/Task/Interface/InfrastTask.cpp @@ -8,27 +8,27 @@ #include "Task/Infrast/InfrastInfoTask.h" #include "Task/Infrast/InfrastMfgTask.h" #include "Task/Infrast/InfrastOfficeTask.h" -#include "Task/Infrast/InfrastTrainingTask.h" #include "Task/Infrast/InfrastPowerTask.h" #include "Task/Infrast/InfrastProcessingTask.h" #include "Task/Infrast/InfrastReceptionTask.h" #include "Task/Infrast/InfrastTradeTask.h" +#include "Task/Infrast/InfrastTrainingTask.h" #include "Task/Infrast/ReplenishOriginiumShardTaskPlugin.h" #include "Task/ProcessTask.h" -asst::InfrastTask::InfrastTask(const AsstCallback& callback, Assistant* inst) - : InterfaceTask(callback, inst, TaskType), - m_infrast_begin_task_ptr(std::make_shared(callback, inst, TaskType)), - m_info_task_ptr(std::make_shared(callback, inst, TaskType)), - m_mfg_task_ptr(std::make_shared(callback, inst, TaskType)), - m_trade_task_ptr(std::make_shared(callback, inst, TaskType)), - m_power_task_ptr(std::make_shared(callback, inst, TaskType)), - m_control_task_ptr(std::make_shared(callback, inst, TaskType)), - m_reception_task_ptr(std::make_shared(callback, inst, TaskType)), - m_office_task_ptr(std::make_shared(callback, inst, TaskType)), - m_processing_task_ptr(std::make_shared(callback, inst, TaskType)), - m_training_task_ptr(std::make_shared(callback, inst, TaskType)), - m_dorm_task_ptr(std::make_shared(callback, inst, TaskType)) +asst::InfrastTask::InfrastTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType), + m_infrast_begin_task_ptr(std::make_shared(callback, inst, TaskType)), + m_info_task_ptr(std::make_shared(callback, inst, TaskType)), + m_mfg_task_ptr(std::make_shared(callback, inst, TaskType)), + m_trade_task_ptr(std::make_shared(callback, inst, TaskType)), + m_power_task_ptr(std::make_shared(callback, inst, TaskType)), + m_control_task_ptr(std::make_shared(callback, inst, TaskType)), + m_reception_task_ptr(std::make_shared(callback, inst, TaskType)), + m_office_task_ptr(std::make_shared(callback, inst, TaskType)), + m_processing_task_ptr(std::make_shared(callback, inst, TaskType)), + m_training_task_ptr(std::make_shared(callback, inst, TaskType)), + m_dorm_task_ptr(std::make_shared(callback, inst, TaskType)) { LogTraceFunction; @@ -61,7 +61,9 @@ bool asst::InfrastTask::set_params(const json::value& params) return false; } - auto append_infrast_begin = [&]() { m_subtasks.emplace_back(m_infrast_begin_task_ptr); }; + auto append_infrast_begin = [&]() { + m_subtasks.emplace_back(m_infrast_begin_task_ptr); + }; m_subtasks.clear(); append_infrast_begin(); @@ -247,12 +249,13 @@ bool asst::InfrastTask::parse_and_set_custom_config(const std::filesystem::path& // name数组此后可以作废 std::set name_set; name_set.insert(room_config.names.begin(), room_config.names.end()); - ranges::for_each(ori_operator_groups, - [name_set, &room_config](std::pair> pair) { - if (name_set.contains(pair.first)) { - room_config.operator_groups[pair.first] = std::move(pair.second); - } - }); + ranges::for_each( + ori_operator_groups, + [name_set, &room_config](std::pair> pair) { + if (name_set.contains(pair.first)) { + room_config.operator_groups[pair.first] = std::move(pair.second); + } + }); } } diff --git a/src/MaaCore/Task/Interface/InfrastTask.h b/src/MaaCore/Task/Interface/InfrastTask.h index 2d2b8a0950..a2e5cdf136 100644 --- a/src/MaaCore/Task/Interface/InfrastTask.h +++ b/src/MaaCore/Task/Interface/InfrastTask.h @@ -5,49 +5,49 @@ namespace asst { - class ProcessTask; - class InfrastInfoTask; - class InfrastMfgTask; - class InfrastTradeTask; - class InfrastPowerTask; - class InfrastControlTask; - class InfrastReceptionTask; - class InfrastOfficeTask; - class InfrastTrainingTask; - class InfrastDormTask; - class ReplenishOriginiumShardTaskPlugin; - class InfrastProcessingTask; +class ProcessTask; +class InfrastInfoTask; +class InfrastMfgTask; +class InfrastTradeTask; +class InfrastPowerTask; +class InfrastControlTask; +class InfrastReceptionTask; +class InfrastOfficeTask; +class InfrastTrainingTask; +class InfrastDormTask; +class ReplenishOriginiumShardTaskPlugin; +class InfrastProcessingTask; - class InfrastTask final : public InterfaceTask +class InfrastTask final : public InterfaceTask +{ + enum class Mode { - enum class Mode - { - Default = 0, - Custom = 10000, - }; - - public: - inline static constexpr std::string_view TaskType = "Infrast"; - - InfrastTask(const AsstCallback& callback, Assistant* inst); - virtual ~InfrastTask() override = default; - - virtual bool set_params(const json::value& params) override; - - private: - bool parse_and_set_custom_config(const std::filesystem::path& path, int index); - - std::shared_ptr m_infrast_begin_task_ptr = nullptr; - std::shared_ptr m_info_task_ptr = nullptr; - std::shared_ptr m_mfg_task_ptr = nullptr; - std::shared_ptr m_trade_task_ptr = nullptr; - std::shared_ptr m_power_task_ptr = nullptr; - std::shared_ptr m_control_task_ptr = nullptr; - std::shared_ptr m_reception_task_ptr = nullptr; - std::shared_ptr m_office_task_ptr = nullptr; - std::shared_ptr m_processing_task_ptr = nullptr; - std::shared_ptr m_training_task_ptr = nullptr; - std::shared_ptr m_dorm_task_ptr = nullptr; - std::shared_ptr m_replenish_task_ptr = nullptr; + Default = 0, + Custom = 10000, }; + +public: + inline static constexpr std::string_view TaskType = "Infrast"; + + InfrastTask(const AsstCallback& callback, Assistant* inst); + virtual ~InfrastTask() override = default; + + virtual bool set_params(const json::value& params) override; + +private: + bool parse_and_set_custom_config(const std::filesystem::path& path, int index); + + std::shared_ptr m_infrast_begin_task_ptr = nullptr; + std::shared_ptr m_info_task_ptr = nullptr; + std::shared_ptr m_mfg_task_ptr = nullptr; + std::shared_ptr m_trade_task_ptr = nullptr; + std::shared_ptr m_power_task_ptr = nullptr; + std::shared_ptr m_control_task_ptr = nullptr; + std::shared_ptr m_reception_task_ptr = nullptr; + std::shared_ptr m_office_task_ptr = nullptr; + std::shared_ptr m_processing_task_ptr = nullptr; + std::shared_ptr m_training_task_ptr = nullptr; + std::shared_ptr m_dorm_task_ptr = nullptr; + std::shared_ptr m_replenish_task_ptr = nullptr; +}; } diff --git a/src/MaaCore/Task/Interface/MallTask.cpp b/src/MaaCore/Task/Interface/MallTask.cpp index 24c2432aaa..3db18e361e 100644 --- a/src/MaaCore/Task/Interface/MallTask.cpp +++ b/src/MaaCore/Task/Interface/MallTask.cpp @@ -6,14 +6,14 @@ #include "Utils/Logger.hpp" -asst::MallTask::MallTask(const AsstCallback& callback, Assistant* inst) - : InterfaceTask(callback, inst, TaskType), - m_visit_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), - m_credit_fight_task_ptr(std::make_shared(callback, inst, TaskType)), - m_mall_task_ptr(std::make_shared(callback, inst, TaskType)), - m_shopping_first_task_ptr(std::make_shared(callback, inst, TaskType)), - m_shopping_task_ptr(std::make_shared(callback, inst, TaskType)), - m_shopping_force_task_ptr(std::make_shared(callback, inst, TaskType)) +asst::MallTask::MallTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType), + m_visit_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), + m_credit_fight_task_ptr(std::make_shared(callback, inst, TaskType)), + m_mall_task_ptr(std::make_shared(callback, inst, TaskType)), + m_shopping_first_task_ptr(std::make_shared(callback, inst, TaskType)), + m_shopping_task_ptr(std::make_shared(callback, inst, TaskType)), + m_shopping_force_task_ptr(std::make_shared(callback, inst, TaskType)) { LogTraceFunction; diff --git a/src/MaaCore/Task/Interface/MallTask.h b/src/MaaCore/Task/Interface/MallTask.h index b73dd709d5..824f782e57 100644 --- a/src/MaaCore/Task/Interface/MallTask.h +++ b/src/MaaCore/Task/Interface/MallTask.h @@ -3,26 +3,26 @@ namespace asst { - class ProcessTask; - class CreditFightTask; - class CreditShoppingTask; +class ProcessTask; +class CreditFightTask; +class CreditShoppingTask; - class MallTask final : public InterfaceTask - { - public: - inline static constexpr std::string_view TaskType = "Mall"; +class MallTask final : public InterfaceTask +{ +public: + inline static constexpr std::string_view TaskType = "Mall"; - MallTask(const AsstCallback& callback, Assistant* inst); - virtual ~MallTask() override = default; + MallTask(const AsstCallback& callback, Assistant* inst); + virtual ~MallTask() override = default; - virtual bool set_params(const json::value& params) override; + virtual bool set_params(const json::value& params) override; - private: - std::shared_ptr m_visit_task_ptr = nullptr; - std::shared_ptr m_credit_fight_task_ptr = nullptr; - std::shared_ptr m_mall_task_ptr = nullptr; - std::shared_ptr m_shopping_first_task_ptr = nullptr; - std::shared_ptr m_shopping_task_ptr = nullptr; - std::shared_ptr m_shopping_force_task_ptr = nullptr; - }; +private: + std::shared_ptr m_visit_task_ptr = nullptr; + std::shared_ptr m_credit_fight_task_ptr = nullptr; + std::shared_ptr m_mall_task_ptr = nullptr; + std::shared_ptr m_shopping_first_task_ptr = nullptr; + std::shared_ptr m_shopping_task_ptr = nullptr; + std::shared_ptr m_shopping_force_task_ptr = nullptr; +}; } diff --git a/src/MaaCore/Task/Interface/OperBoxTask.cpp b/src/MaaCore/Task/Interface/OperBoxTask.cpp index 2536117676..bc47222d6b 100644 --- a/src/MaaCore/Task/Interface/OperBoxTask.cpp +++ b/src/MaaCore/Task/Interface/OperBoxTask.cpp @@ -3,7 +3,8 @@ #include "Task/Miscellaneous/OperBoxRecognitionTask.h" #include "Task/ProcessTask.h" -asst::OperBoxTask::OperBoxTask(const AsstCallback& callback, Assistant* inst) : InterfaceTask(callback, inst, TaskType) +asst::OperBoxTask::OperBoxTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType) { auto enter_task = std::make_shared(m_callback, m_inst, TaskType); enter_task->set_tasks({ "OperBoxBegin" }).set_ignore_error(true); diff --git a/src/MaaCore/Task/Interface/OperBoxTask.h b/src/MaaCore/Task/Interface/OperBoxTask.h index 69a9ad0042..9444d7d422 100644 --- a/src/MaaCore/Task/Interface/OperBoxTask.h +++ b/src/MaaCore/Task/Interface/OperBoxTask.h @@ -3,12 +3,12 @@ namespace asst { - class OperBoxTask final : public InterfaceTask - { - public: - inline static constexpr std::string_view TaskType = "OperBox"; +class OperBoxTask final : public InterfaceTask +{ +public: + inline static constexpr std::string_view TaskType = "OperBox"; - OperBoxTask(const AsstCallback& callback, Assistant* inst); - virtual ~OperBoxTask() override = default; - }; + OperBoxTask(const AsstCallback& callback, Assistant* inst); + virtual ~OperBoxTask() override = default; +}; } diff --git a/src/MaaCore/Task/Interface/RecruitTask.cpp b/src/MaaCore/Task/Interface/RecruitTask.cpp index 26e919635a..71a348adc9 100644 --- a/src/MaaCore/Task/Interface/RecruitTask.cpp +++ b/src/MaaCore/Task/Interface/RecruitTask.cpp @@ -4,9 +4,9 @@ #include "Task/ProcessTask.h" #include "Utils/Logger.hpp" -asst::RecruitTask::RecruitTask(const AsstCallback& callback, Assistant* inst) - : InterfaceTask(callback, inst, TaskType), - m_auto_recruit_task_ptr(std::make_shared(callback, inst, TaskType)) +asst::RecruitTask::RecruitTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType), + m_auto_recruit_task_ptr(std::make_shared(callback, inst, TaskType)) { LogTraceFunction; diff --git a/src/MaaCore/Task/Interface/RecruitTask.h b/src/MaaCore/Task/Interface/RecruitTask.h index 5dd99555d5..a886a8d78e 100644 --- a/src/MaaCore/Task/Interface/RecruitTask.h +++ b/src/MaaCore/Task/Interface/RecruitTask.h @@ -3,20 +3,20 @@ namespace asst { - class ProcessTask; - class AutoRecruitTask; +class ProcessTask; +class AutoRecruitTask; - class RecruitTask final : public InterfaceTask - { - public: - inline static constexpr std::string_view TaskType = "Recruit"; +class RecruitTask final : public InterfaceTask +{ +public: + inline static constexpr std::string_view TaskType = "Recruit"; - RecruitTask(const AsstCallback& callback, Assistant* inst); - virtual ~RecruitTask() override = default; + RecruitTask(const AsstCallback& callback, Assistant* inst); + virtual ~RecruitTask() override = default; - virtual bool set_params(const json::value& params) override; + virtual bool set_params(const json::value& params) override; - private: - std::shared_ptr m_auto_recruit_task_ptr = nullptr; - }; +private: + std::shared_ptr m_auto_recruit_task_ptr = nullptr; +}; } diff --git a/src/MaaCore/Task/Interface/SSSCopilotTask.h b/src/MaaCore/Task/Interface/SSSCopilotTask.h index 51305d0dec..509e762a3a 100644 --- a/src/MaaCore/Task/Interface/SSSCopilotTask.h +++ b/src/MaaCore/Task/Interface/SSSCopilotTask.h @@ -5,24 +5,24 @@ namespace asst { - class ProcessTask; - class BattleFormationTask; - class SSSStageManagerTask; +class ProcessTask; +class BattleFormationTask; +class SSSStageManagerTask; - // 保全派驻抄作业任务 - class SSSCopilotTask final : public InterfaceTask - { - public: - inline static constexpr std::string_view TaskType = "SSSCopilot"; +// 保全派驻抄作业任务 +class SSSCopilotTask final : public InterfaceTask +{ +public: + inline static constexpr std::string_view TaskType = "SSSCopilot"; - SSSCopilotTask(const AsstCallback& callback, Assistant* inst); - virtual ~SSSCopilotTask() override = default; + SSSCopilotTask(const AsstCallback& callback, Assistant* inst); + virtual ~SSSCopilotTask() override = default; - virtual bool set_params(const json::value& params) override; + virtual bool set_params(const json::value& params) override; - private: - std::shared_ptr m_begin_task_ptr = nullptr; - std::shared_ptr m_formation_task_ptr = nullptr; - std::shared_ptr m_stage_task_ptr = nullptr; - }; +private: + std::shared_ptr m_begin_task_ptr = nullptr; + std::shared_ptr m_formation_task_ptr = nullptr; + std::shared_ptr m_stage_task_ptr = nullptr; +}; } diff --git a/src/MaaCore/Task/Interface/SingleStepTask.cpp b/src/MaaCore/Task/Interface/SingleStepTask.cpp index dcc00c6fe1..60f861e5dd 100644 --- a/src/MaaCore/Task/Interface/SingleStepTask.cpp +++ b/src/MaaCore/Task/Interface/SingleStepTask.cpp @@ -5,8 +5,8 @@ #include "Task/ProcessTask.h" #include "Utils/Logger.hpp" -asst::SingleStepTask::SingleStepTask(const AsstCallback& callback, Assistant* inst) - : InterfaceTask(callback, inst, TaskType) +asst::SingleStepTask::SingleStepTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType) { LogTraceFunction; } diff --git a/src/MaaCore/Task/Interface/SingleStepTask.h b/src/MaaCore/Task/Interface/SingleStepTask.h index 719f97cd5b..2df6b7505b 100644 --- a/src/MaaCore/Task/Interface/SingleStepTask.h +++ b/src/MaaCore/Task/Interface/SingleStepTask.h @@ -5,19 +5,19 @@ namespace asst { - class SingleStepTask final : public InterfaceTask - { - public: - inline static constexpr std::string_view TaskType = "SingleStep"; +class SingleStepTask final : public InterfaceTask +{ +public: + inline static constexpr std::string_view TaskType = "SingleStep"; - SingleStepTask(const AsstCallback& callback, Assistant* inst); - virtual ~SingleStepTask() override = default; + SingleStepTask(const AsstCallback& callback, Assistant* inst); + virtual ~SingleStepTask() override = default; - virtual bool set_params(const json::value& params) override; + virtual bool set_params(const json::value& params) override; - private: - bool set_copilot_stage(const json::value& details); - bool append_copllot_start(); - bool append_copilot_action(const json::value& details); - }; +private: + bool set_copilot_stage(const json::value& details); + bool append_copllot_start(); + bool append_copilot_action(const json::value& details); +}; } diff --git a/src/MaaCore/Task/Interface/StartUpTask.cpp b/src/MaaCore/Task/Interface/StartUpTask.cpp index af700b59f9..b660c0fc41 100644 --- a/src/MaaCore/Task/Interface/StartUpTask.cpp +++ b/src/MaaCore/Task/Interface/StartUpTask.cpp @@ -8,11 +8,11 @@ #include "Task/ProcessTask.h" #include "Utils/Logger.hpp" -asst::StartUpTask::StartUpTask(const AsstCallback& callback, Assistant* inst) - : InterfaceTask(callback, inst, TaskType), - m_start_game_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), - m_start_up_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), - m_account_switch_task_ptr(std::make_shared(m_callback, m_inst, TaskType)) +asst::StartUpTask::StartUpTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType), + m_start_game_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), + m_start_up_task_ptr(std::make_shared(m_callback, m_inst, TaskType)), + m_account_switch_task_ptr(std::make_shared(m_callback, m_inst, TaskType)) { LogTraceFunction; @@ -34,8 +34,7 @@ bool asst::StartUpTask::set_params(const json::value& params) std::string account_name = params.get("account_name", std::string()); std::string client_type = params.get("client_type", std::string()); - m_start_game_task_ptr->set_client_type(client_type) - .set_enable(params.get("start_game_enabled", false)); + m_start_game_task_ptr->set_client_type(client_type).set_enable(params.get("start_game_enabled", false)); m_account_switch_task_ptr->set_enable(!account_name.empty()); m_account_switch_task_ptr->set_account(std::move(account_name)); m_account_switch_task_ptr->set_client_type(std::move(client_type)); diff --git a/src/MaaCore/Task/Interface/StartUpTask.h b/src/MaaCore/Task/Interface/StartUpTask.h index c38e5c87fc..a309b41025 100644 --- a/src/MaaCore/Task/Interface/StartUpTask.h +++ b/src/MaaCore/Task/Interface/StartUpTask.h @@ -3,23 +3,23 @@ namespace asst { - class StartGameTaskPlugin; - class ProcessTask; - class AccountSwitchTask; +class StartGameTaskPlugin; +class ProcessTask; +class AccountSwitchTask; - class StartUpTask final : public InterfaceTask - { - public: - inline static constexpr std::string_view TaskType = "StartUp"; +class StartUpTask final : public InterfaceTask +{ +public: + inline static constexpr std::string_view TaskType = "StartUp"; - StartUpTask(const AsstCallback& callback, Assistant* inst); - virtual ~StartUpTask() override = default; + StartUpTask(const AsstCallback& callback, Assistant* inst); + virtual ~StartUpTask() override = default; - bool set_params(const json::value& params) override; + bool set_params(const json::value& params) override; - private: - std::shared_ptr m_start_game_task_ptr = nullptr; - std::shared_ptr m_start_up_task_ptr = nullptr; - std::shared_ptr m_account_switch_task_ptr = nullptr; - }; +private: + std::shared_ptr m_start_game_task_ptr = nullptr; + std::shared_ptr m_start_up_task_ptr = nullptr; + std::shared_ptr m_account_switch_task_ptr = nullptr; +}; } diff --git a/src/MaaCore/Task/Interface/VideoRecognitionTask.cpp b/src/MaaCore/Task/Interface/VideoRecognitionTask.cpp index d239d75821..417912eb35 100644 --- a/src/MaaCore/Task/Interface/VideoRecognitionTask.cpp +++ b/src/MaaCore/Task/Interface/VideoRecognitionTask.cpp @@ -5,8 +5,8 @@ #include -asst::VideoRecognitionTask::VideoRecognitionTask(const AsstCallback& callback, Assistant* inst) - : InterfaceTask(callback, inst, TaskType) +asst::VideoRecognitionTask::VideoRecognitionTask(const AsstCallback& callback, Assistant* inst) : + InterfaceTask(callback, inst, TaskType) { LogTraceFunction; } diff --git a/src/MaaCore/Task/Interface/VideoRecognitionTask.h b/src/MaaCore/Task/Interface/VideoRecognitionTask.h index 6d846a923b..431d49af8c 100644 --- a/src/MaaCore/Task/Interface/VideoRecognitionTask.h +++ b/src/MaaCore/Task/Interface/VideoRecognitionTask.h @@ -4,16 +4,16 @@ namespace asst { - class ProcessTask; +class ProcessTask; - class VideoRecognitionTask final : public InterfaceTask - { - public: - inline static constexpr std::string_view TaskType = "VideoRecognition"; +class VideoRecognitionTask final : public InterfaceTask +{ +public: + inline static constexpr std::string_view TaskType = "VideoRecognition"; - VideoRecognitionTask(const AsstCallback& callback, Assistant* inst); - virtual ~VideoRecognitionTask() override = default; + VideoRecognitionTask(const AsstCallback& callback, Assistant* inst); + virtual ~VideoRecognitionTask() override = default; - bool set_params(const json::value& params) override; - }; + bool set_params(const json::value& params) override; +}; } diff --git a/src/MaaCore/Task/InterfaceTask.h b/src/MaaCore/Task/InterfaceTask.h index fff49c49dc..0a20282656 100644 --- a/src/MaaCore/Task/InterfaceTask.h +++ b/src/MaaCore/Task/InterfaceTask.h @@ -3,12 +3,12 @@ namespace asst { - class InterfaceTask : public PackageTask - { - public: - using PackageTask::PackageTask; - virtual ~InterfaceTask() override = default; +class InterfaceTask : public PackageTask +{ +public: + using PackageTask::PackageTask; + virtual ~InterfaceTask() override = default; - virtual bool set_params([[maybe_unused]] const json::value& params) { return true; } - }; + virtual bool set_params([[maybe_unused]] const json::value& params) { return true; } +}; } diff --git a/src/MaaCore/Task/Miscellaneous/AccountSwitchTask.h b/src/MaaCore/Task/Miscellaneous/AccountSwitchTask.h index 70191d964f..83052b5151 100644 --- a/src/MaaCore/Task/Miscellaneous/AccountSwitchTask.h +++ b/src/MaaCore/Task/Miscellaneous/AccountSwitchTask.h @@ -5,35 +5,37 @@ namespace asst { - class AccountSwitchTask : public AbstractTask - { - public: - using AbstractTask::AbstractTask; - virtual ~AccountSwitchTask() noexcept override = default; - void set_account(std::string account) { m_account = std::move(account); } - void set_client_type(std::string client_type) { m_client_type = std::move(client_type); } +class AccountSwitchTask : public AbstractTask +{ +public: + using AbstractTask::AbstractTask; + virtual ~AccountSwitchTask() noexcept override = default; - private: - virtual bool _run() override; + void set_account(std::string account) { m_account = std::move(account); } - // 导航至账号管理页 - bool navigate_to_start_page(); - bool equal_current_account(); - bool equal_current_account_b(); - // 账号列表里面点登录 - bool click_manager_login_button(); - // 打开账号列表 - bool show_account_list(); - bool swipe_and_select(bool to_top = false); - // 往下滑账号列表 - void swipe_account_list(bool to_top = false); - // 识别并选择m_account - bool select_account(); + void set_client_type(std::string client_type) { m_client_type = std::move(client_type); } - std::string m_account; - std::string m_target_account; - std::string m_client_type; // 客户端类型 - const std::vector - SupportedClientType = { "Official", "Bilibili" /*, "YoStarEN", "YoStarJP", "YoStarKR", "txwy" */ }; - }; +private: + virtual bool _run() override; + + // 导航至账号管理页 + bool navigate_to_start_page(); + bool equal_current_account(); + bool equal_current_account_b(); + // 账号列表里面点登录 + bool click_manager_login_button(); + // 打开账号列表 + bool show_account_list(); + bool swipe_and_select(bool to_top = false); + // 往下滑账号列表 + void swipe_account_list(bool to_top = false); + // 识别并选择m_account + bool select_account(); + + std::string m_account; + std::string m_target_account; + std::string m_client_type; // 客户端类型 + const std::vector + SupportedClientType = { "Official", "Bilibili" /*, "YoStarEN", "YoStarJP", "YoStarKR", "txwy" */ }; +}; } diff --git a/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.cpp b/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.cpp index 5b04d62095..7ec46a25ae 100644 --- a/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.cpp @@ -27,17 +27,14 @@ auto get_all_combs( { rcs_with_single_tag.reserve(tags.size()); - ranges::transform( - tags, - std::back_inserter(rcs_with_single_tag), - [](const RecruitConfig::TagId& t) { - RecruitCombs result; - result.tags = { t }; - result.min_level = 6; - result.max_level = 0; - result.avg_level = 0; - return result; - }); + ranges::transform(tags, std::back_inserter(rcs_with_single_tag), [](const RecruitConfig::TagId& t) { + RecruitCombs result; + result.tags = { t }; + result.min_level = 6; + result.max_level = 0; + result.avg_level = 0; + return result; + }); for (const auto& op : all_ops) { for (auto& rc : rcs_with_single_tag) { @@ -61,8 +58,7 @@ auto get_all_combs( std::vector result; const size_t tag_size = tags.size(); - result.reserve( - tag_size * (tag_size * tag_size + 5) / 6); // C(size, 3) + C(size, 2) + C(size, 1) + result.reserve(tag_size * (tag_size * tag_size + 5) / 6); // C(size, 3) + C(size, 2) + C(size, 1) // select one tag first for (size_t i = 0; i < tag_size; ++i) { @@ -94,15 +90,13 @@ auto get_all_combs( static constexpr std::string_view SeniorOper = "高级资深干员"; for (auto comb_iter = result.begin(); comb_iter != result.end();) { - if (ranges::find(comb_iter->tags, RecruitConfig::TagId(SeniorOper)) - != comb_iter->tags.end()) { + if (ranges::find(comb_iter->tags, RecruitConfig::TagId(SeniorOper)) != comb_iter->tags.end()) { ++comb_iter; continue; } // no senior tag, remove 6-star operators // assuming sorted by level - auto iter = - ranges::find_if(comb_iter->opers, [](const Recruitment& op) { return op.level >= 6; }); + auto iter = ranges::find_if(comb_iter->opers, [](const Recruitment& op) { return op.level >= 6; }); if (iter == comb_iter->opers.end()) { ++comb_iter; continue; @@ -120,15 +114,13 @@ auto get_all_combs( } } // namespace asst::recruit_calc -asst::AutoRecruitTask& - asst::AutoRecruitTask::set_select_level(std::vector select_level) noexcept +asst::AutoRecruitTask& asst::AutoRecruitTask::set_select_level(std::vector select_level) noexcept { m_select_level = std::move(select_level); return *this; } -asst::AutoRecruitTask& - asst::AutoRecruitTask::set_confirm_level(std::vector confirm_level) noexcept +asst::AutoRecruitTask& asst::AutoRecruitTask::set_confirm_level(std::vector confirm_level) noexcept { m_confirm_level = std::move(confirm_level); return *this; @@ -152,15 +144,13 @@ asst::AutoRecruitTask& asst::AutoRecruitTask::set_use_expedited(bool use_or_not) return *this; } -asst::AutoRecruitTask& - asst::AutoRecruitTask::set_select_extra_tags(ExtraTagsMode select_extra_tags_mode) noexcept +asst::AutoRecruitTask& asst::AutoRecruitTask::set_select_extra_tags(ExtraTagsMode select_extra_tags_mode) noexcept { m_select_extra_tags_mode = select_extra_tags_mode; return *this; } -asst::AutoRecruitTask& - asst::AutoRecruitTask::set_first_tags(std::vector first_tags) noexcept +asst::AutoRecruitTask& asst::AutoRecruitTask::set_first_tags(std::vector first_tags) noexcept { m_first_tags = first_tags; return *this; @@ -184,15 +174,13 @@ asst::AutoRecruitTask& asst::AutoRecruitTask::set_force_refresh(bool force_refre return *this; } -asst::AutoRecruitTask& - asst::AutoRecruitTask::set_recruitment_time(std::unordered_map time_map) noexcept +asst::AutoRecruitTask& asst::AutoRecruitTask::set_recruitment_time(std::unordered_map time_map) noexcept { m_desired_time_map = std::move(time_map); return *this; } -asst::AutoRecruitTask& - asst::AutoRecruitTask::set_penguin_enabled(bool enable, std::string penguin_id) noexcept +asst::AutoRecruitTask& asst::AutoRecruitTask::set_penguin_enabled(bool enable, std::string penguin_id) noexcept { m_upload_to_penguin = enable; if (!penguin_id.empty()) { @@ -201,8 +189,7 @@ asst::AutoRecruitTask& return *this; } -asst::AutoRecruitTask& - asst::AutoRecruitTask::set_yituliu_enabled(bool enable, std::string yituliu_id) noexcept +asst::AutoRecruitTask& asst::AutoRecruitTask::set_yituliu_enabled(bool enable, std::string yituliu_id) noexcept { m_upload_to_yituliu = enable; if (!yituliu_id.empty()) { @@ -398,8 +385,7 @@ bool asst::AutoRecruitTask::recruit_one(const Rect& button) } // set recruit timer and tags only -asst::AutoRecruitTask::calc_task_result_type - asst::AutoRecruitTask::recruit_calc_task(slot_index index) +asst::AutoRecruitTask::calc_task_result_type asst::AutoRecruitTask::recruit_calc_task(slot_index index) { LogTraceFunction; @@ -441,8 +427,8 @@ asst::AutoRecruitTask::calc_task_result_type // special tags const std::vector SpecialTags = { "高级资深干员", "资深干员" }; - if (auto special_iter = ranges::find_first_of(SpecialTags, tag_ids); - special_iter != SpecialTags.cend()) [[unlikely]] { + if (auto special_iter = ranges::find_first_of(SpecialTags, tag_ids); special_iter != SpecialTags.cend()) + [[unlikely]] { has_special_tag = true; json::value cb_info = info; cb_info["what"] = "RecruitSpecialTag"; @@ -452,8 +438,7 @@ asst::AutoRecruitTask::calc_task_result_type // robot tags const std::vector RobotTags = { "支援机械", "元素" }; - if (auto robot_iter = ranges::find_first_of(RobotTags, tag_ids); - robot_iter != RobotTags.cend()) [[unlikely]] { + if (auto robot_iter = ranges::find_first_of(RobotTags, tag_ids); robot_iter != RobotTags.cend()) [[unlikely]] { has_robot_tag = true; json::value cb_info = info; cb_info["what"] = "RecruitSpecialTag"; @@ -485,8 +470,7 @@ asst::AutoRecruitTask::calc_task_result_type if (rc.min_level < 3) { // find another min level (assuming operator list sorted in increment order by // level) - auto sec = - ranges::find_if(rc.opers, [](const Recruitment& op) { return op.level >= 3; }); + auto sec = ranges::find_if(rc.opers, [](const Recruitment& op) { return op.level >= 3; }); if (sec != rc.opers.end()) { rc.min_level = sec->level; rc.avg_level = std::transform_reduce( @@ -494,8 +478,8 @@ asst::AutoRecruitTask::calc_task_result_type rc.opers.end(), 0., std::plus {}, - std::mem_fn(&Recruitment::level)) - / static_cast(std::distance(sec, rc.opers.end())); + std::mem_fn(&Recruitment::level)) / + static_cast(std::distance(sec, rc.opers.end())); } } } @@ -582,9 +566,8 @@ asst::AutoRecruitTask::calc_task_result_type } // refresh - if (m_need_refresh && m_has_refresh && !has_special_tag - && (final_combination.min_level == 3 && !has_preferred_tag) - && !(m_skip_robot && has_robot_tag)) { + if (m_need_refresh && m_has_refresh && !has_special_tag && + (final_combination.min_level == 3 && !has_preferred_tag) && !(m_skip_robot && has_robot_tag)) { if (refresh_count > refresh_limit) [[unlikely]] { json::value cb_info = basic_info(); cb_info["what"] = "RecruitError"; @@ -640,10 +623,8 @@ asst::AutoRecruitTask::calc_task_result_type if (!is_calc_only_task()) { // do not confirm, force skip - if (!(final_combination.min_level == 3 && has_preferred_tag) - && ranges::none_of(m_confirm_level, [&](const auto& i) { - return i == final_combination.min_level; - })) { + if (!(final_combination.min_level == 3 && has_preferred_tag) && + ranges::none_of(m_confirm_level, [&](const auto& i) { return i == final_combination.min_level; })) { calc_task_result_type result; result.success = true; result.force_skip = true; @@ -670,8 +651,7 @@ asst::AutoRecruitTask::calc_task_result_type const int desired_minute_div_10 = (recruitment_time % 60) / 10; const int temp = desired_hour + (desired_minute_div_10 != 0); const int hour_delta = (1 < temp) ? (1 + 9 - temp) : (temp - 1); - const int minute_delta = - (0 < desired_minute_div_10) ? (0 + 6 - desired_minute_div_10) : (0); + const int minute_delta = (0 < desired_minute_div_10) ? (0 + 6 - desired_minute_div_10) : (0); for (int i = 0; i < hour_delta; ++i) { ctrler()->click(image_analyzer.get_hour_decrement_rect()); } @@ -681,10 +661,8 @@ asst::AutoRecruitTask::calc_task_result_type } // nothing to select, leave the selection empty - if (!(final_combination.min_level == 3 && has_preferred_tag) - && ranges::none_of(m_select_level, [&](const auto& i) { - return i == final_combination.min_level; - })) { + if (!(final_combination.min_level == 3 && has_preferred_tag) && + ranges::none_of(m_select_level, [&](const auto& i) { return i == final_combination.min_level; })) { calc_task_result_type result; result.success = true; result.force_skip = false; @@ -698,8 +676,7 @@ asst::AutoRecruitTask::calc_task_result_type // select tags for (const std::string& final_tag_name : final_select) { - auto tag_rect_iter = - ranges::find_if(tags, [&](const TextRect& r) { return r.text == final_tag_name; }); + auto tag_rect_iter = ranges::find_if(tags, [&](const TextRect& r) { return r.text == final_tag_name; }); if (tag_rect_iter != tags.cend()) { ctrler()->click(tag_rect_iter->rect); } @@ -708,8 +685,7 @@ asst::AutoRecruitTask::calc_task_result_type { json::value cb_info = basic_info(); cb_info["what"] = "RecruitTagsSelected"; - cb_info["details"] = - json::object { { "tags", json::array(get_tag_names(final_select)) } }; + cb_info["details"] = json::object { { "tags", json::array(get_tag_names(final_select)) } }; callback(AsstMsg::SubTaskExtraInfo, cb_info); } @@ -831,8 +807,7 @@ bool asst::AutoRecruitTask::hire_all() return true; } -std::vector - asst::AutoRecruitTask::get_tag_names(const std::vector& ids) const +std::vector asst::AutoRecruitTask::get_tag_names(const std::vector& ids) const { std::vector names; for (const RecruitConfig::TagId& id : ids) { @@ -989,10 +964,7 @@ void asst::AutoRecruitTask::upload_to_yituliu(const json::value& details) .run(); } -void asst::AutoRecruitTask::report_penguin_callback( - AsstMsg msg, - const json::value& detail, - AbstractTask* task_ptr) +void asst::AutoRecruitTask::report_penguin_callback(AsstMsg msg, const json::value& detail, AbstractTask* task_ptr) { LogTraceFunction; @@ -1009,10 +981,7 @@ void asst::AutoRecruitTask::report_penguin_callback( p_this->callback(msg, detail); } -void asst::AutoRecruitTask::report_yituliu_callback( - AsstMsg msg, - const json::value& detail, - AbstractTask* task_ptr) +void asst::AutoRecruitTask::report_yituliu_callback(AsstMsg msg, const json::value& detail, AbstractTask* task_ptr) { LogTraceFunction; diff --git a/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.h b/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.h index 0019918edf..01ce28e9db 100644 --- a/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.h +++ b/src/MaaCore/Task/Miscellaneous/AutoRecruitTask.h @@ -10,110 +10,112 @@ namespace asst { - class ReportDataTask; +class ReportDataTask; - class AutoRecruitTask final : public AbstractTask +class AutoRecruitTask final : public AbstractTask +{ +public: + using AbstractTask::AbstractTask; + virtual ~AutoRecruitTask() override = default; + + AutoRecruitTask& set_select_level(std::vector select_level) noexcept; + AutoRecruitTask& set_confirm_level(std::vector 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_select_extra_tags(ExtraTagsMode select_extra_tags_mode) noexcept; + AutoRecruitTask& set_first_tags(std::vector first_tags) noexcept; + AutoRecruitTask& set_skip_robot(bool skip_robot) noexcept; + AutoRecruitTask& set_set_time(bool set_time) noexcept; + AutoRecruitTask& set_force_refresh(bool force_refrest) noexcept; + AutoRecruitTask& set_recruitment_time(std::unordered_map) 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; + virtual void click_return_button() override; + + bool is_calc_only_task() { return m_max_times <= 0 && m_confirm_level.empty(); } + + std::optional 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&); + std::vector get_tag_names(const std::vector& ids) const; + std::vector + get_select_tags(const std::vector& combinations, std::vector tag_ids); + static std::vector start_recruit_analyze(const cv::Mat& image); + + template + void upload_result(const Rng& tag_ids, const json::value& details); + template + void upload_to_penguin(Rng&& tag_ids); + void upload_to_yituliu(const json::value& details); + static void report_penguin_callback(AsstMsg msg, const json::value& detail, AbstractTask* task_ptr); + static void report_yituliu_callback(AsstMsg msg, const json::value& detail, AbstractTask* task_ptr); + + using slot_index = size_t; + + struct calc_task_result_type { - public: - using AbstractTask::AbstractTask; - virtual ~AutoRecruitTask() override = default; - - AutoRecruitTask& set_select_level(std::vector select_level) noexcept; - AutoRecruitTask& set_confirm_level(std::vector 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_select_extra_tags(ExtraTagsMode select_extra_tags_mode) noexcept; - AutoRecruitTask& set_first_tags(std::vector first_tags) noexcept; - AutoRecruitTask& set_skip_robot(bool skip_robot) noexcept; - AutoRecruitTask& set_set_time(bool set_time) noexcept; - AutoRecruitTask& set_force_refresh(bool force_refrest) noexcept; - AutoRecruitTask& set_recruitment_time(std::unordered_map) 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; - virtual void click_return_button() override; - - bool is_calc_only_task() { return m_max_times <= 0 && m_confirm_level.empty(); } - std::optional 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&); - std::vector get_tag_names(const std::vector& ids) const; - std::vector get_select_tags(const std::vector& combinations, std::vector tag_ids); - static std::vector start_recruit_analyze(const cv::Mat& image); - - template - void upload_result(const Rng& tag_ids, const json::value& details); - template - void upload_to_penguin(Rng&& tag_ids); - void upload_to_yituliu(const json::value& details); - static void report_penguin_callback(AsstMsg msg, const json::value& detail, AbstractTask* task_ptr); - static void report_yituliu_callback(AsstMsg msg, const json::value& detail, AbstractTask* task_ptr); - - 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); - - std::vector m_select_level; - std::vector m_confirm_level; - bool m_need_refresh = false; - bool m_use_expedited = false; - ExtraTagsMode m_select_extra_tags_mode = ExtraTagsMode::NoExtra; - std::vector m_first_tags; - int m_max_times = 0; - bool m_has_permit = true; - bool m_has_refresh = true; - bool m_skip_robot = true; - bool m_set_time = true; - bool m_force_refresh = true; - std::unordered_map m_desired_time_map; - - int m_slot_fail = 0; - int m_cur_times = 0; - - std::set 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 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 m_report_penguin_task_ptr = nullptr; - std::shared_ptr 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); - } + 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); + + std::vector m_select_level; + std::vector m_confirm_level; + bool m_need_refresh = false; + bool m_use_expedited = false; + ExtraTagsMode m_select_extra_tags_mode = ExtraTagsMode::NoExtra; + std::vector m_first_tags; + int m_max_times = 0; + bool m_has_permit = true; + bool m_has_refresh = true; + bool m_skip_robot = true; + bool m_set_time = true; + bool m_force_refresh = true; + std::unordered_map m_desired_time_map; + + int m_slot_fail = 0; + int m_cur_times = 0; + + std::set 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 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 m_report_penguin_task_ptr = nullptr; + std::shared_ptr 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 diff --git a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp index 1da91bec52..c2b46dd1f2 100644 --- a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp @@ -24,9 +24,11 @@ using namespace asst::battle; using namespace asst::battle::copilot; -asst::BattleProcessTask::BattleProcessTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain) - : AbstractTask(callback, inst, task_chain), BattleHelper(inst) -{} +asst::BattleProcessTask::BattleProcessTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain) : + AbstractTask(callback, inst, task_chain), + BattleHelper(inst) +{ +} bool asst::BattleProcessTask::_run() { @@ -85,7 +87,8 @@ void asst::BattleProcessTask::set_wait_until_end(bool wait_until_end) m_need_to_wait_until_end = wait_until_end; } -void asst::BattleProcessTask::set_formation_task_ptr(std::shared_ptr> value) +void asst::BattleProcessTask::set_formation_task_ptr( + std::shared_ptr> value) { m_formation_ptr = value; } @@ -169,11 +172,11 @@ bool asst::BattleProcessTask::do_action(const battle::copilot::Action& action, s notify_action(action); thread_local auto prev_frame_time = std::chrono::steady_clock::time_point {}; - static const auto min_frame_interval = std::chrono::milliseconds(Config.get_options().copilot_fight_screencap_interval); + static const auto min_frame_interval = + std::chrono::milliseconds(Config.get_options().copilot_fight_screencap_interval); // prevent our program from consuming too much CPU - if (const auto now = std::chrono::steady_clock::now(); - prev_frame_time > now - min_frame_interval) [[unlikely]] { + if (const auto now = std::chrono::steady_clock::now(); prev_frame_time > now - min_frame_interval) [[unlikely]] { Log.debug("Sleeping for framerate limit"); std::this_thread::sleep_for(min_frame_interval - (now - prev_frame_time)); } @@ -182,7 +185,7 @@ bool asst::BattleProcessTask::do_action(const battle::copilot::Action& action, s return false; } - prev_frame_time = std::chrono::steady_clock::now(); + prev_frame_time = std::chrono::steady_clock::now(); if (action.pre_delay > 0) { sleep_and_do_strategy(action.pre_delay); @@ -197,17 +200,23 @@ bool asst::BattleProcessTask::do_action(const battle::copilot::Action& action, s switch (action.type) { case ActionType::Deploy: ret = deploy_oper(name, location, action.direction); - if (ret) m_in_bullet_time = false; + if (ret) { + m_in_bullet_time = false; + } break; case ActionType::Retreat: ret = m_in_bullet_time ? click_retreat() : (location.empty() ? retreat_oper(name) : retreat_oper(location)); - if (ret) m_in_bullet_time = false; + if (ret) { + m_in_bullet_time = false; + } break; case ActionType::UseSkill: ret = m_in_bullet_time ? click_skill() : (location.empty() ? use_skill(name) : use_skill(location)); - if (ret) m_in_bullet_time = false; + if (ret) { + m_in_bullet_time = false; + } break; case ActionType::SwitchSpeed: @@ -216,12 +225,16 @@ bool asst::BattleProcessTask::do_action(const battle::copilot::Action& action, s case ActionType::BulletTime: ret = enter_bullet_time(name, location); - if (ret) m_in_bullet_time = true; + if (ret) { + m_in_bullet_time = true; + } break; case ActionType::SkillUsage: m_skill_usage[name] = action.modify_usage; - if (action.modify_usage == SkillUsage::Times) m_skill_times[name] = action.modify_times; + if (action.modify_usage == SkillUsage::Times) { + m_skill_times[name] = action.modify_times; + } ret = true; break; diff --git a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h index dc363ee4de..f819c6563f 100644 --- a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h +++ b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.h @@ -8,45 +8,49 @@ namespace asst { - class BattleProcessTask : public AbstractTask, public BattleHelper +class BattleProcessTask : public AbstractTask, public BattleHelper +{ +public: + BattleProcessTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); + virtual ~BattleProcessTask() override = default; + + virtual bool set_stage_name(const std::string& stage_name) override; + void set_wait_until_end(bool wait_until_end); + void set_formation_task_ptr(std::shared_ptr> value); + +protected: + virtual bool _run() override; + + virtual AbstractTask& this_task() override { return *this; } + + virtual void clear() override; + + virtual bool + do_derived_action([[maybe_unused]] const battle::copilot::Action& action, [[maybe_unused]] size_t index) { - public: - BattleProcessTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); - virtual ~BattleProcessTask() override = default; + return false; + } - virtual bool set_stage_name(const std::string& stage_name) override; - void set_wait_until_end(bool wait_until_end); - void set_formation_task_ptr(std::shared_ptr> value); + virtual battle::copilot::CombatData& get_combat_data() { return m_combat_data; } - protected: - virtual bool _run() override; - virtual AbstractTask& this_task() override { return *this; } - virtual void clear() override; + virtual bool need_to_wait_until_end() const { return m_need_to_wait_until_end; } - virtual bool do_derived_action([[maybe_unused]] const battle::copilot::Action& action, - [[maybe_unused]] size_t index) - { - return false; - } - virtual battle::copilot::CombatData& get_combat_data() { return m_combat_data; } - virtual bool need_to_wait_until_end() const { return m_need_to_wait_until_end; } + bool to_group(); + bool do_action(const battle::copilot::Action& action, size_t index); - bool to_group(); - bool do_action(const battle::copilot::Action& action, size_t index); + const std::string& get_name_from_group(const std::string& action_name); + void notify_action(const battle::copilot::Action& action); + bool wait_condition(const battle::copilot::Action& action); + bool enter_bullet_time(const std::string& name, const Point& location); + void sleep_and_do_strategy(unsigned millisecond); - const std::string& get_name_from_group(const std::string& action_name); - void notify_action(const battle::copilot::Action& action); - bool wait_condition(const battle::copilot::Action& action); - bool enter_bullet_time(const std::string& name, const Point& location); - void sleep_and_do_strategy(unsigned millisecond); + virtual bool check_in_battle(const cv::Mat& reusable = cv::Mat(), bool weak = true) override; - virtual bool check_in_battle(const cv::Mat& reusable = cv::Mat(), bool weak = true) override; + battle::copilot::CombatData m_combat_data; + std::unordered_map m_oper_in_group; - battle::copilot::CombatData m_combat_data; - std::unordered_map m_oper_in_group; - - bool m_in_bullet_time = false; - bool m_need_to_wait_until_end = false; - std::shared_ptr> m_formation_ptr = nullptr; - }; + bool m_in_bullet_time = false; + bool m_need_to_wait_until_end = false; + std::shared_ptr> m_formation_ptr = nullptr; +}; } diff --git a/src/MaaCore/Task/Miscellaneous/CreditFightTask.cpp b/src/MaaCore/Task/Miscellaneous/CreditFightTask.cpp index 5a172d4599..c7d50774d7 100644 --- a/src/MaaCore/Task/Miscellaneous/CreditFightTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/CreditFightTask.cpp @@ -7,8 +7,8 @@ #include "Task/ProcessTask.h" #include "Utils/Ranges.hpp" -asst::CreditFightTask::CreditFightTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain) - : PackageTask(callback, inst, task_chain) +asst::CreditFightTask::CreditFightTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain) : + PackageTask(callback, inst, task_chain) { auto start_up_task_ptr = std::make_shared(m_callback, m_inst, task_chain); auto stage_navigation_task_ptr = std::make_shared(m_callback, m_inst, task_chain); diff --git a/src/MaaCore/Task/Miscellaneous/CreditFightTask.h b/src/MaaCore/Task/Miscellaneous/CreditFightTask.h index 1d21c7412f..886b5690e5 100644 --- a/src/MaaCore/Task/Miscellaneous/CreditFightTask.h +++ b/src/MaaCore/Task/Miscellaneous/CreditFightTask.h @@ -10,17 +10,17 @@ namespace asst { - class CreditFightTask final : public PackageTask - { - public: - inline static constexpr std::string_view TaskType = "CreditFight"; +class CreditFightTask final : public PackageTask +{ +public: + inline static constexpr std::string_view TaskType = "CreditFight"; - CreditFightTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); - virtual ~CreditFightTask() override = default; + CreditFightTask(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); + virtual ~CreditFightTask() override = default; - void set_select_formation(int index); + void set_select_formation(int index); - private: - std::shared_ptr m_copilot_task_ptr = nullptr; - }; +private: + std::shared_ptr m_copilot_task_ptr = nullptr; +}; } // namespace asst diff --git a/src/MaaCore/Task/Miscellaneous/CreditShoppingTask.h b/src/MaaCore/Task/Miscellaneous/CreditShoppingTask.h index 6b443211e7..62fc522c81 100644 --- a/src/MaaCore/Task/Miscellaneous/CreditShoppingTask.h +++ b/src/MaaCore/Task/Miscellaneous/CreditShoppingTask.h @@ -8,36 +8,36 @@ namespace asst { - class CreditShoppingTask final : public AbstractTask - { - public: - using AbstractTask::AbstractTask; - virtual ~CreditShoppingTask() override = default; +class CreditShoppingTask final : public AbstractTask +{ +public: + using AbstractTask::AbstractTask; + virtual ~CreditShoppingTask() override = default; - void set_black_list(std::vector black_list); - void set_white_list(std::vector white_list); + void set_black_list(std::vector black_list); + void set_white_list(std::vector white_list); - static constexpr int MaxCredit = 300; + static constexpr int MaxCredit = 300; - CreditShoppingTask& set_force_shopping_if_credit_full(bool force_shopping_if_credit_full) noexcept; - CreditShoppingTask& set_only_buy_discount(bool only_buy_discount) noexcept; - CreditShoppingTask& set_reserve_max_credit(bool reserve_max_credit) noexcept; - CreditShoppingTask& set_info_credit_full(bool info_credit_full) noexcept; + CreditShoppingTask& set_force_shopping_if_credit_full(bool force_shopping_if_credit_full) noexcept; + CreditShoppingTask& set_only_buy_discount(bool only_buy_discount) noexcept; + CreditShoppingTask& set_reserve_max_credit(bool reserve_max_credit) noexcept; + CreditShoppingTask& set_info_credit_full(bool info_credit_full) noexcept; - protected: - virtual bool _run() override; - bool m_force_shopping_if_credit_full = false; // 设置是否防止信用值溢出 - bool m_only_buy_discount = false; // 设置只购买折扣信用商品(未打折的白名单物品仍会购买) - bool m_reserve_max_credit = false; // 设置消耗信用点至300以下时停止购买商品(仍然会购买白名单物品) - bool m_info_credit_full = false; // 设置是否在不购买黑名单物品阶段通知信用点溢出 - int credit_ocr(); +protected: + virtual bool _run() override; + bool m_force_shopping_if_credit_full = false; // 设置是否防止信用值溢出 + bool m_only_buy_discount = false; // 设置只购买折扣信用商品(未打折的白名单物品仍会购买) + bool m_reserve_max_credit = false; // 设置消耗信用点至300以下时停止购买商品(仍然会购买白名单物品) + bool m_info_credit_full = false; // 设置是否在不购买黑名单物品阶段通知信用点溢出 + int credit_ocr(); - // 用于在信用商店界面识别商品信息左上角的折扣信息 - int discount_ocr(const Rect& commodity); + // 用于在信用商店界面识别商品信息左上角的折扣信息 + int discount_ocr(const Rect& commodity); - bool credit_shopping(bool white_list_enabled, bool credit_ocr_enabled); + bool credit_shopping(bool white_list_enabled, bool credit_ocr_enabled); - std::vector m_shopping_list; - bool m_is_white_list = false; - }; + std::vector m_shopping_list; + bool m_is_white_list = false; +}; } diff --git a/src/MaaCore/Task/Miscellaneous/DepotRecognitionTask.h b/src/MaaCore/Task/Miscellaneous/DepotRecognitionTask.h index 6bda7fce95..8e93ffcb3b 100644 --- a/src/MaaCore/Task/Miscellaneous/DepotRecognitionTask.h +++ b/src/MaaCore/Task/Miscellaneous/DepotRecognitionTask.h @@ -7,18 +7,18 @@ namespace asst { - class DepotRecognitionTask : public AbstractTask - { - public: - using AbstractTask::AbstractTask; - virtual ~DepotRecognitionTask() noexcept override = default; +class DepotRecognitionTask : public AbstractTask +{ +public: + using AbstractTask::AbstractTask; + virtual ~DepotRecognitionTask() noexcept override = default; - protected: - virtual bool _run() override; +protected: + virtual bool _run() override; - bool swipe_and_analyze(); - void callback_analyze_result(bool done); - void swipe(); - std::unordered_map m_all_items; - }; + bool swipe_and_analyze(); + void callback_analyze_result(bool done); + void swipe(); + std::unordered_map m_all_items; +}; } diff --git a/src/MaaCore/Task/Miscellaneous/OperBoxRecognitionTask.cpp b/src/MaaCore/Task/Miscellaneous/OperBoxRecognitionTask.cpp index 839d65ca27..4b8033c073 100644 --- a/src/MaaCore/Task/Miscellaneous/OperBoxRecognitionTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/OperBoxRecognitionTask.cpp @@ -20,6 +20,7 @@ bool asst::OperBoxRecognitionTask::_run() callback_analyze_result(true); return ret; } + bool asst::OperBoxRecognitionTask::swipe_and_analyze() { LogTraceFunction; diff --git a/src/MaaCore/Task/Miscellaneous/OperBoxRecognitionTask.h b/src/MaaCore/Task/Miscellaneous/OperBoxRecognitionTask.h index fda13d88ee..a5994d1d1f 100644 --- a/src/MaaCore/Task/Miscellaneous/OperBoxRecognitionTask.h +++ b/src/MaaCore/Task/Miscellaneous/OperBoxRecognitionTask.h @@ -5,18 +5,18 @@ namespace asst { - class OperBoxRecognitionTask : public AbstractTask - { - public: - using AbstractTask::AbstractTask; - virtual ~OperBoxRecognitionTask() override = default; +class OperBoxRecognitionTask : public AbstractTask +{ +public: + using AbstractTask::AbstractTask; + virtual ~OperBoxRecognitionTask() override = default; - protected: - virtual bool _run() override; - void swipe_page(); - void callback_analyze_result(bool done); - bool swipe_and_analyze(); +protected: + virtual bool _run() override; + void swipe_page(); + void callback_analyze_result(bool done); + bool swipe_and_analyze(); - std::unordered_map m_own_opers; - }; + std::unordered_map m_own_opers; +}; } diff --git a/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.cpp b/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.cpp index 255fced19c..545cc841d9 100644 --- a/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.cpp +++ b/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.cpp @@ -3,9 +3,11 @@ #include "Config/TaskData.h" #include "Utils/Logger.hpp" -asst::ScreenshotTaskPlugin::ScreenshotTaskPlugin(const AsstCallback& callback, Assistant* inst, - std::string_view task_chain) - : AbstractTaskPlugin(callback, inst, task_chain) +asst::ScreenshotTaskPlugin::ScreenshotTaskPlugin( + const AsstCallback& callback, + Assistant* inst, + std::string_view task_chain) : + AbstractTaskPlugin(callback, inst, task_chain) { m_screenshot_tasks.clear(); if (auto ptr = Task.get(config_name)) { diff --git a/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.h b/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.h index 202454a48f..b4a9e84fcb 100644 --- a/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.h +++ b/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.h @@ -3,24 +3,24 @@ namespace asst { - class ScreenshotTaskPlugin : public AbstractTaskPlugin - { - public: - ScreenshotTaskPlugin(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); - virtual ~ScreenshotTaskPlugin() override = default; +class ScreenshotTaskPlugin : public AbstractTaskPlugin +{ +public: + ScreenshotTaskPlugin(const AsstCallback& callback, Assistant* inst, std::string_view task_chain); + virtual ~ScreenshotTaskPlugin() override = default; - public: - virtual bool verify(AsstMsg msg, const json::value& details) const override; +public: + virtual bool verify(AsstMsg msg, const json::value& details) const override; - protected: - virtual bool _run() override; +protected: + virtual bool _run() override; - private: - static const constexpr std::string_view config_name = "ScreenshotTaskPlugin-Config"; - static const constexpr std::string_view debug_config_name = "ScreenshotTaskPlugin-Config-Debug"; +private: + static const constexpr std::string_view config_name = "ScreenshotTaskPlugin-Config"; + static const constexpr std::string_view debug_config_name = "ScreenshotTaskPlugin-Config-Debug"; - std::vector m_screenshot_tasks; - mutable std::string m_last_triggered_task; // 上次触发的任务这次不再触发 - mutable std::chrono::steady_clock::time_point m_last_triggered_time; // 触发的时间 - }; + std::vector m_screenshot_tasks; + mutable std::string m_last_triggered_task; // 上次触发的任务这次不再触发 + mutable std::chrono::steady_clock::time_point m_last_triggered_time; // 触发的时间 +}; } diff --git a/src/MaaCore/Task/Miscellaneous/StartGameTaskPlugin.cpp b/src/MaaCore/Task/Miscellaneous/StartGameTaskPlugin.cpp index a591ec4419..a859061994 100644 --- a/src/MaaCore/Task/Miscellaneous/StartGameTaskPlugin.cpp +++ b/src/MaaCore/Task/Miscellaneous/StartGameTaskPlugin.cpp @@ -4,8 +4,7 @@ using namespace asst; -bool StartGameTaskPlugin::start_game_with_retries(size_t pipe_data_size_limit, bool newer_android) - const +bool StartGameTaskPlugin::start_game_with_retries(size_t pipe_data_size_limit, bool newer_android) const { int extra_runs = 0; for (int i = 0; i < 30; ++i) { diff --git a/src/MaaCore/Task/Miscellaneous/TaskFileReloadTask.h b/src/MaaCore/Task/Miscellaneous/TaskFileReloadTask.h index 695f536451..4664862ab5 100644 --- a/src/MaaCore/Task/Miscellaneous/TaskFileReloadTask.h +++ b/src/MaaCore/Task/Miscellaneous/TaskFileReloadTask.h @@ -3,17 +3,17 @@ namespace asst { - class TaskFileReloadTask : public AbstractTask - { - public: - using AbstractTask::AbstractTask; - virtual ~TaskFileReloadTask() override = default; - void set_magic_code(std::string code); - void set_path(std::string path); +class TaskFileReloadTask : public AbstractTask +{ +public: + using AbstractTask::AbstractTask; + virtual ~TaskFileReloadTask() override = default; + void set_magic_code(std::string code); + void set_path(std::string path); - private: - virtual bool _run() override; - std::string m_file; - bool is_path = false, is_magic_code = false; - }; +private: + virtual bool _run() override; + std::string m_file; + bool is_path = false, is_magic_code = false; +}; } diff --git a/src/MaaCore/Task/PackageTask.h b/src/MaaCore/Task/PackageTask.h index 93b26870b5..788aee7a27 100644 --- a/src/MaaCore/Task/PackageTask.h +++ b/src/MaaCore/Task/PackageTask.h @@ -8,21 +8,21 @@ namespace asst { - class PackageTask : public AbstractTask - { - public: - using AbstractTask::AbstractTask; - virtual ~PackageTask() override = default; +class PackageTask : public AbstractTask +{ +public: + using AbstractTask::AbstractTask; + virtual ~PackageTask() override = default; - virtual bool run() override; + virtual bool run() override; - virtual AbstractTask& set_retry_times(int times) noexcept override; - virtual AbstractTask& set_task_id(int task_id) noexcept override; + virtual AbstractTask& set_retry_times(int times) noexcept override; + virtual AbstractTask& set_task_id(int task_id) noexcept override; - protected: - virtual bool _run() override { return true; } +protected: + virtual bool _run() override { return true; } - bool m_running = false; - std::vector> m_subtasks; - }; + bool m_running = false; + std::vector> m_subtasks; +}; } diff --git a/src/MaaCore/Task/Reclamation/AbstractReclamationTaskPlugin.h b/src/MaaCore/Task/Reclamation/AbstractReclamationTaskPlugin.h index d604b8431f..361682fe3f 100644 --- a/src/MaaCore/Task/Reclamation/AbstractReclamationTaskPlugin.h +++ b/src/MaaCore/Task/Reclamation/AbstractReclamationTaskPlugin.h @@ -2,8 +2,8 @@ #include -#include "Task/AbstractTaskPlugin.h" #include "ReclamationConfig.h" +#include "Task/AbstractTaskPlugin.h" namespace asst { diff --git a/src/MaaCore/Task/Reclamation/ReclamationCraftTaskPlugin.cpp b/src/MaaCore/Task/Reclamation/ReclamationCraftTaskPlugin.cpp index d347c43dac..dd01a69f07 100644 --- a/src/MaaCore/Task/Reclamation/ReclamationCraftTaskPlugin.cpp +++ b/src/MaaCore/Task/Reclamation/ReclamationCraftTaskPlugin.cpp @@ -161,7 +161,8 @@ bool asst::ReclamationCraftTaskPlugin::calc_craft_amount(int& value) std::string value_str; if (craft_amount_analyzer.analyze()) { value_str = craft_amount_analyzer.get_result().text; - } else { // 此时组装数量显示为灰色的 1 + } + else { // 此时组装数量显示为灰色的 1 value_str = "0"; } diff --git a/src/MaaCore/Task/Reclamation/ReclamationCraftTaskPlugin.h b/src/MaaCore/Task/Reclamation/ReclamationCraftTaskPlugin.h index 865077008d..16782b9216 100644 --- a/src/MaaCore/Task/Reclamation/ReclamationCraftTaskPlugin.h +++ b/src/MaaCore/Task/Reclamation/ReclamationCraftTaskPlugin.h @@ -20,13 +20,13 @@ private: bool calc_craft_amount(int& value); // ———————— constants and variables ——————————————————————————————————————————————— - enum class IncrementMode // 点击加号按钮增加组装数量的方式 + enum class IncrementMode // 点击加号按钮增加组装数量的方式 { Click = 0, Hold = 1 }; - std::string m_tool_to_craft = "荧光棒"; // 要组装的支援道具 + std::string m_tool_to_craft = "荧光棒"; // 要组装的支援道具 int m_num_craft_batches = 16; // 支援道具组装批次数, 每批组装 99 个 IncrementMode m_increment_mode = IncrementMode::Click; // 点击加号按钮增加组装数量的方式 }; diff --git a/src/MaaCore/Task/ReportDataTask.h b/src/MaaCore/Task/ReportDataTask.h index 4d564bcade..731cab2162 100644 --- a/src/MaaCore/Task/ReportDataTask.h +++ b/src/MaaCore/Task/ReportDataTask.h @@ -10,54 +10,57 @@ namespace asst { - enum class ReportType - { - Invalid, - PenguinStats, - YituliuBigDataAutoRecruit, - YituliuBigDataStageDrops, - }; +enum class ReportType +{ + Invalid, + PenguinStats, + YituliuBigDataAutoRecruit, + YituliuBigDataStageDrops, +}; - using TaskCallback = std::function; +using TaskCallback = std::function; - class ReportDataTask : public AbstractTask - { - public: - ReportDataTask(const TaskCallback& task_callback, AbstractTask* upper_task); - ReportDataTask(const ReportDataTask&) = default; - ReportDataTask(ReportDataTask&&) = default; +class ReportDataTask : public AbstractTask +{ +public: + ReportDataTask(const TaskCallback& task_callback, AbstractTask* upper_task); + ReportDataTask(const ReportDataTask&) = default; + ReportDataTask(ReportDataTask&&) = default; - virtual ~ReportDataTask() override = default; + virtual ~ReportDataTask() override = default; - ReportDataTask& set_report_type(ReportType type); + ReportDataTask& set_report_type(ReportType type); - ReportDataTask& set_body(std::string body); - ReportDataTask& set_extra_headers(std::unordered_map headers); + ReportDataTask& set_body(std::string body); + ReportDataTask& set_extra_headers(std::unordered_map headers); - protected: - using HttpResponsePred = std::function; +protected: + using HttpResponsePred = std::function; - virtual bool _run() override; - virtual void callback(AsstMsg msg, const json::value& detail) override; + virtual bool _run() override; + virtual void callback(AsstMsg msg, const json::value& detail) override; - void report_to_penguin(); - void report_to_yituliu(ReportType reportType); - cpr::Response report( - std::string_view subtask, const std::string& url, const cpr::Header& headers, const int timeout, - HttpResponsePred success_cond = [](const cpr::Response& response) -> bool { - return response.status_code == 200; - }, - HttpResponsePred retry_cond = [](const cpr::Response& response) -> bool { - return !response.status_code || (response.status_code >= 500 && response.status_code < 600); - }, - bool callback_on_failure = true); + void report_to_penguin(); + void report_to_yituliu(ReportType reportType); + cpr::Response report( + std::string_view subtask, + const std::string& url, + const cpr::Header& headers, + const int timeout, + HttpResponsePred success_cond = [](const cpr::Response& response) -> bool { + return response.status_code == 200; + }, + HttpResponsePred retry_cond = [](const cpr::Response& response) -> bool { + return !response.status_code || (response.status_code >= 500 && response.status_code < 600); + }, + bool callback_on_failure = true); - ReportType m_report_type = ReportType::Invalid; - std::string m_body; - std::unordered_map m_extra_headers; - std::vector> m_upload_pending; + ReportType m_report_type = ReportType::Invalid; + std::string m_body; + std::unordered_map m_extra_headers; + std::vector> m_upload_pending; - TaskCallback m_task_callback = nullptr; - AbstractTask* m_upper_task = nullptr; - }; + TaskCallback m_task_callback = nullptr; + AbstractTask* m_upper_task = nullptr; +}; } // namespace asst diff --git a/src/MaaCore/Task/Roguelike/Map/RoguelikeMap.cpp b/src/MaaCore/Task/Roguelike/Map/RoguelikeMap.cpp index f0fead458c..340de81480 100644 --- a/src/MaaCore/Task/Roguelike/Map/RoguelikeMap.cpp +++ b/src/MaaCore/Task/Roguelike/Map/RoguelikeMap.cpp @@ -101,10 +101,9 @@ size_t asst::RoguelikeMap::get_next_node() const return m_curr_pos; } - const size_t next_index = - ranges::min(curr->succs, [&](const size_t& node1_index, const size_t& node2_index) { - return m_nodes.at(node1_index)->cost < m_nodes.at(node2_index)->cost; - }); + const size_t next_index = ranges::min(curr->succs, [&](const size_t& node1_index, const size_t& node2_index) { + return m_nodes.at(node1_index)->cost < m_nodes.at(node2_index)->cost; + }); return next_index; } @@ -238,8 +237,7 @@ std::optional asst::RoguelikeMap::insert_node(const RoguelikeNodePtr& no return std::nullopt; } // 只允许有一个 init node - if (column == init_index && column < m_column_indices.size() && m_column_indices.at(column) > 0) - [[unlikely]] { + if (column == init_index && column < m_column_indices.size() && m_column_indices.at(column) > 0) [[unlikely]] { Log.error(__FUNCTION__, "| init node has already exist"); return std::nullopt; } diff --git a/src/MaaCore/Task/Roguelike/Map/RoguelikeMap.h b/src/MaaCore/Task/Roguelike/Map/RoguelikeMap.h index 354528fee2..0e411fe48a 100644 --- a/src/MaaCore/Task/Roguelike/Map/RoguelikeMap.h +++ b/src/MaaCore/Task/Roguelike/Map/RoguelikeMap.h @@ -69,19 +69,23 @@ public: // ———————— update map ———————————————————————————————————————————————————————————— // 创建并插入一个 node,返回新 node 的 index - std::optional - create_and_insert_node(const RoguelikeNodeType& type, const size_t& column, const int& y); + std::optional create_and_insert_node(const RoguelikeNodeType& type, const size_t& column, const int& y); void add_edge(const size_t& source, const size_t& target); void set_curr_pos(const size_t& node_index); + void set_cost_fun(const RoguelikeNodeCostFun& cost_fun) { m_cost_fun = cost_fun; } + void update_node_costs(); void reset(); // ———————— get map details ——————————————————————————————————————————————————————— size_t size() const { return m_nodes.size(); } + size_t get_num_columns() const { return m_column_indices.size(); } + size_t get_curr_pos() const { return m_curr_pos; } + size_t get_column_begin(const size_t& column) const; size_t get_column_end(const size_t& column) const; size_t get_next_node() const; @@ -102,7 +106,7 @@ public: void set_node_refresh_times(const size_t& node_index, int refresh_times); // ———————— constants and variables ——————————————————————————————————————————————— - const size_t init_index = 0; // 常量,既是 init 的 node index 也是它的 column index + const size_t init_index = 0; // 常量,既是 init 的 node index 也是它的 column index private: // ———————— update map ———————————————————————————————————————————————————————————— @@ -112,6 +116,8 @@ private: std::vector m_nodes; std::vector m_column_indices; // m_column_indices[c] 代表列 c 的 node index 的上限 (exclusive) size_t m_curr_pos = 0; // 当前位置的 node index - RoguelikeNodeCostFun m_cost_fun = [&]([[maybe_unused]] const RoguelikeNodePtr& node) { return 0; }; + RoguelikeNodeCostFun m_cost_fun = [&]([[maybe_unused]] const RoguelikeNodePtr& node) { + return 0; + }; }; } diff --git a/src/MaaCore/Task/Roguelike/Map/RoguelikeRoutingTaskPlugin.h b/src/MaaCore/Task/Roguelike/Map/RoguelikeRoutingTaskPlugin.h index 3d9f358d96..a5401576be 100644 --- a/src/MaaCore/Task/Roguelike/Map/RoguelikeRoutingTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/Map/RoguelikeRoutingTaskPlugin.h @@ -28,17 +28,17 @@ private: // ———————— constants and variables ——————————————————————————————————————————————— RoguelikeMap m_map; bool m_need_generate_map = true; - size_t m_selected_column = 0; // 当前选中节点所在列 - int m_selected_x = 0; // 当前选中节点的横坐标 (Rect.x) + size_t m_selected_column = 0; // 当前选中节点所在列 + int m_selected_x = 0; // 当前选中节点的横坐标 (Rect.x) - int m_origin_x = 0; // 第一列节点的默认横坐标 (Rect.x) - int m_middle_x = 0; // 中间列节点的默认横坐标 (Rect.x) - int m_last_x = 0; // 最后列节点的默认横坐标 (Rect.x) - int m_node_width = 0; // 节点 Rect.width - int m_node_height = 0; // 节点 Rect.height - int m_column_offset = 0; // 两列节点之间的距离 - int m_nameplate_offset = 0; // 节点 Rect 下边缘到节点铭牌下边缘的距离 - int m_roi_margin = 0; // roi 时的 margin offset - int m_direction_threshold = 0; // 节点间连线方向判定的阈值 + int m_origin_x = 0; // 第一列节点的默认横坐标 (Rect.x) + int m_middle_x = 0; // 中间列节点的默认横坐标 (Rect.x) + int m_last_x = 0; // 最后列节点的默认横坐标 (Rect.x) + int m_node_width = 0; // 节点 Rect.width + int m_node_height = 0; // 节点 Rect.height + int m_column_offset = 0; // 两列节点之间的距离 + int m_nameplate_offset = 0; // 节点 Rect 下边缘到节点铭牌下边缘的距离 + int m_roi_margin = 0; // roi 时的 margin offset + int m_direction_threshold = 0; // 节点间连线方向判定的阈值 }; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.h index d967ae56e0..20bdd875e3 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.h @@ -11,145 +11,163 @@ namespace asst { - class RoguelikeBattleTaskPlugin : public AbstractRoguelikeTaskPlugin, private BattleHelper +class RoguelikeBattleTaskPlugin : public AbstractRoguelikeTaskPlugin, private BattleHelper +{ + using Time_Point = std::chrono::time_point; + + inline static const std::unordered_set DiceSet = { "骰子", "8面骰子", "12面骰子" }; + +public: + RoguelikeBattleTaskPlugin( + const AsstCallback& callback, + Assistant* inst, + std::string_view task_chain, + const std::shared_ptr& roguelike_config_ptr, + const std::shared_ptr& control); + virtual ~RoguelikeBattleTaskPlugin() override = default; + + virtual bool verify(AsstMsg msg, const json::value& details) const override; + +protected: + virtual bool _run() override; + + virtual AbstractTask& this_task() override { return *this; } + + virtual void clear() override; + + bool do_once(); + + struct DeployPlanInfo { - using Time_Point = std::chrono::time_point; + // int oper_priority; // 干员招募优先级 + std::string oper_name; // 干员名称 + int oper_order_in_group; // 干员在干员组中排名 + int rank; // 干员组在部署指令扁平化后的排名 + Point placed; // 指令坐标 + battle::DeployDirection direction; // 部署朝向 - inline static const std::unordered_set DiceSet = { "骰子", "8面骰子", "12面骰子" }; - - public: - RoguelikeBattleTaskPlugin( - const AsstCallback& callback, - Assistant* inst, - std::string_view task_chain, - const std::shared_ptr& roguelike_config_ptr, - const std::shared_ptr& control); - virtual ~RoguelikeBattleTaskPlugin() override = default; - - virtual bool verify(AsstMsg msg, const json::value& details) const override; - - protected: - virtual bool _run() override; - virtual AbstractTask& this_task() override { return *this; } - virtual void clear() override; - - bool do_once(); - struct DeployPlanInfo + bool operator<(const DeployPlanInfo& x) const // 重载小于号,同rank时先部署组内排名靠前的 { - // int oper_priority; // 干员招募优先级 - std::string oper_name; // 干员名称 - int oper_order_in_group; // 干员在干员组中排名 - int rank; // 干员组在部署指令扁平化后的排名 - Point placed; // 指令坐标 - battle::DeployDirection direction; // 部署朝向 - bool operator<(const DeployPlanInfo& x) const // 重载小于号,同rank时先部署组内排名靠前的 - { - return (rank < x.rank) || (rank == x.rank && oper_order_in_group < x.oper_order_in_group); - } - }; - bool do_best_deploy(); - bool calc_stage_info(); - - void all_melee_retreat(); - - std::optional check_urgent(const std::unordered_set& pre_cooling, - const std::unordered_set& cur_cooling, - const std::map& pre_battlefield); - - std::optional calc_best_oper() const; - - struct DeployInfo - { - Point placed; - battle::DeployDirection direction; - }; - std::optional calc_best_loc(const battle::DeploymentOper& oper) const; - battle::AttackRange get_attack_range(const battle::DeploymentOper& oper, - battle::DeployDirection direction = battle::DeployDirection::Right) const; - - struct DirectionAndScore - { - battle::DeployDirection direction; - int score = 0; - }; - DirectionAndScore calc_best_direction_and_score(Point loc, const battle::DeploymentOper& oper, - battle::DeployDirection recommended_direction) const; - - void postproc_of_deployment_conditions(const battle::DeploymentOper& oper, const Point& placed_loc, - battle::DeployDirection direction); - - void check_drone_tiles(); - void wait_until_start_button_clicked(); - - std::string oper_name_in_config(const battle::DeploymentOper& oper) const; - battle::LocationType get_oper_location_type(const battle::DeploymentOper& oper) const; - std::vector available_locations(const battle::DeploymentOper& oper) const; - std::vector available_locations(battle::LocationType type) const; - bool get_position_full(const battle::DeploymentOper& oper) const; - bool get_position_full(battle::LocationType loc_type) const; - void set_position_full(const battle::DeploymentOper& oper, bool full); - void set_position_full(battle::LocationType loc_type, bool full); - void set_position_full(const Point& loc, bool full); - battle::OperPosition get_role_position(const battle::Role& role) const; - - /* from config */ - - std::vector m_homes; - bool m_allow_to_use_dice = true; - std::unordered_set m_blacklist_location; - std::array m_role_order {}; - std::unordered_map m_force_deploy_direction; - - struct AirDefenseData - { - /* from config */ - int stop_blocking_deploy_num = INT_MAX; - int deploy_air_defense_num = 0; - bool ban_medic = false; - /* real time */ - int has_deployed_blocking_num = 0; - int has_deployed_air_defense_num = 0; - bool has_finished_deploy_air_defense = false; - }; - AirDefenseData m_force_air_defense; - - /* real time */ - - size_t m_cur_home_index = 0; - bool m_first_deploy = true; - bool m_melee_full = false; - bool m_ranged_full = false; - - struct HomeInfo - { - bool wait_blocking = true; - bool wait_medic = true; - Point blocking_pos; - }; - std::vector m_homes_status; - std::unordered_map m_blocking_for_home_index; - std::unordered_map> m_medic_for_home_index; - std::deque m_urgent_home_index; - - struct DroneTile - { - Time_Point placed_time; - Point placed_loc; - DroneTile(Time_Point placed_time, Point placed_loc) - { - this->placed_time = placed_time; - this->placed_loc = placed_loc; - } - bool operator<(const DroneTile& x) const { return x.placed_time < placed_time; } - }; - std::priority_queue m_need_clear_tiles; - std::unordered_map> m_deploy_plan; - std::vector m_retreat_plan; - std::unordered_map m_deployed_time; - - // 缓存干员精英 - std::unordered_map m_oper_elite; - // 缓存干员精英情况 - void cache_oper_elite_status(); + return (rank < x.rank) || (rank == x.rank && oper_order_in_group < x.oper_order_in_group); + } }; + + bool do_best_deploy(); + bool calc_stage_info(); + + void all_melee_retreat(); + + std::optional check_urgent( + const std::unordered_set& pre_cooling, + const std::unordered_set& cur_cooling, + const std::map& pre_battlefield); + + std::optional calc_best_oper() const; + + struct DeployInfo + { + Point placed; + battle::DeployDirection direction; + }; + + std::optional calc_best_loc(const battle::DeploymentOper& oper) const; + battle::AttackRange get_attack_range( + const battle::DeploymentOper& oper, + battle::DeployDirection direction = battle::DeployDirection::Right) const; + + struct DirectionAndScore + { + battle::DeployDirection direction; + int score = 0; + }; + + DirectionAndScore calc_best_direction_and_score( + Point loc, + const battle::DeploymentOper& oper, + battle::DeployDirection recommended_direction) const; + + void postproc_of_deployment_conditions( + const battle::DeploymentOper& oper, + const Point& placed_loc, + battle::DeployDirection direction); + + void check_drone_tiles(); + void wait_until_start_button_clicked(); + + std::string oper_name_in_config(const battle::DeploymentOper& oper) const; + battle::LocationType get_oper_location_type(const battle::DeploymentOper& oper) const; + std::vector available_locations(const battle::DeploymentOper& oper) const; + std::vector available_locations(battle::LocationType type) const; + bool get_position_full(const battle::DeploymentOper& oper) const; + bool get_position_full(battle::LocationType loc_type) const; + void set_position_full(const battle::DeploymentOper& oper, bool full); + void set_position_full(battle::LocationType loc_type, bool full); + void set_position_full(const Point& loc, bool full); + battle::OperPosition get_role_position(const battle::Role& role) const; + + /* from config */ + + std::vector m_homes; + bool m_allow_to_use_dice = true; + std::unordered_set m_blacklist_location; + std::array m_role_order {}; + std::unordered_map m_force_deploy_direction; + + struct AirDefenseData + { + /* from config */ + int stop_blocking_deploy_num = INT_MAX; + int deploy_air_defense_num = 0; + bool ban_medic = false; + /* real time */ + int has_deployed_blocking_num = 0; + int has_deployed_air_defense_num = 0; + bool has_finished_deploy_air_defense = false; + }; + + AirDefenseData m_force_air_defense; + + /* real time */ + + size_t m_cur_home_index = 0; + bool m_first_deploy = true; + bool m_melee_full = false; + bool m_ranged_full = false; + + struct HomeInfo + { + bool wait_blocking = true; + bool wait_medic = true; + Point blocking_pos; + }; + + std::vector m_homes_status; + std::unordered_map m_blocking_for_home_index; + std::unordered_map> m_medic_for_home_index; + std::deque m_urgent_home_index; + + struct DroneTile + { + Time_Point placed_time; + Point placed_loc; + + DroneTile(Time_Point placed_time, Point placed_loc) + { + this->placed_time = placed_time; + this->placed_loc = placed_loc; + } + + bool operator<(const DroneTile& x) const { return x.placed_time < placed_time; } + }; + + std::priority_queue m_need_clear_tiles; + std::unordered_map> m_deploy_plan; + std::vector m_retreat_plan; + std::unordered_map m_deployed_time; + + // 缓存干员精英 + std::unordered_map m_oper_elite; + // 缓存干员精英情况 + void cache_oper_elite_status(); +}; } // namespace asst diff --git a/src/MaaCore/Task/Roguelike/RoguelikeConfig.cpp b/src/MaaCore/Task/Roguelike/RoguelikeConfig.cpp index bba395ade5..21c7592d3b 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeConfig.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeConfig.cpp @@ -44,7 +44,6 @@ bool asst::RoguelikeConfig::verify_and_load_params(const json::value& params) Task.set_task_base("Roguelike@LastReward3", "Roguelike@LastReward_default"); Task.set_task_base("Roguelike@LastReward4", "Roguelike@LastReward_default"); Task.set_task_base("Roguelike@LastRewardRand", "Roguelike@LastReward_default"); - if (m_mode == RoguelikeMode::Investment) { bool investment_with_more_score = params.get("investment_with_more_score", false); diff --git a/src/MaaCore/Task/Roguelike/RoguelikeCustomStartTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeCustomStartTaskPlugin.h index 1f57a8b214..1ff1c98b84 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeCustomStartTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeCustomStartTaskPlugin.h @@ -3,38 +3,38 @@ namespace asst { - enum class RoguelikeCustomType - { - None, - Squad, // 分队类型, like 指挥分队, 矛头分队, etc - Roles, // 职业类型, like 先手必胜, 稳扎稳打, etc - CoreChar, // 首选干员, 干员名 - UseSupport, // 使用助战 - UseNonfriendSupport // 可以使用非好友助战 - // CoCoreChar, // 次选干员, 干员名 - }; +enum class RoguelikeCustomType +{ + None, + Squad, // 分队类型, like 指挥分队, 矛头分队, etc + Roles, // 职业类型, like 先手必胜, 稳扎稳打, etc + CoreChar, // 首选干员, 干员名 + UseSupport, // 使用助战 + UseNonfriendSupport // 可以使用非好友助战 + // CoCoreChar, // 次选干员, 干员名 +}; - class RoguelikeCustomStartTaskPlugin : public AbstractRoguelikeTaskPlugin - { - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - virtual ~RoguelikeCustomStartTaskPlugin() override = default; +class RoguelikeCustomStartTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeCustomStartTaskPlugin() override = default; - public: - virtual bool verify(AsstMsg msg, const json::value& details) const override; - virtual bool load_params([[maybe_unused]] const json::value& params) override; - void set_custom(RoguelikeCustomType type, std::string custom); +public: + virtual bool verify(AsstMsg msg, const json::value& details) const override; + virtual bool load_params([[maybe_unused]] const json::value& params) override; + void set_custom(RoguelikeCustomType type, std::string custom); - protected: - virtual bool _run() override; +protected: + virtual bool _run() override; - private: - bool hijack_squad(); - bool hijack_roles(); - bool hijack_core_char(); +private: + bool hijack_squad(); + bool hijack_roles(); + bool hijack_core_char(); - private: - std::unordered_map m_customs; - mutable RoguelikeCustomType m_waiting_to_run = RoguelikeCustomType::None; - }; +private: + std::unordered_map m_customs; + mutable RoguelikeCustomType m_waiting_to_run = RoguelikeCustomType::None; +}; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeDebugTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeDebugTaskPlugin.h index 3c947b8973..76c070824a 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeDebugTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeDebugTaskPlugin.h @@ -3,21 +3,22 @@ namespace asst { - class RoguelikeDebugTaskPlugin : public AbstractRoguelikeTaskPlugin +class RoguelikeDebugTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeDebugTaskPlugin() override = default; + +public: + virtual bool verify(AsstMsg msg, const json::value& details) const override; + + virtual bool load_params([[maybe_unused]] const json::value& params) override { - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - virtual ~RoguelikeDebugTaskPlugin() override = default; + // 投资模式下不开启调试任务 + return m_config->get_mode() != RoguelikeMode::Investment; + } - public: - virtual bool verify(AsstMsg msg, const json::value& details) const override; - virtual bool load_params([[maybe_unused]] const json::value& params) override - { - // 投资模式下不开启调试任务 - return m_config->get_mode() != RoguelikeMode::Investment; - } - - protected: - virtual bool _run() override; - }; +protected: + virtual bool _run() override; +}; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeDifficultySelectionTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeDifficultySelectionTaskPlugin.h index c594899781..7a22983a01 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeDifficultySelectionTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeDifficultySelectionTaskPlugin.h @@ -3,16 +3,16 @@ namespace asst { - class RoguelikeDifficultySelectionTaskPlugin : public AbstractRoguelikeTaskPlugin - { - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - virtual ~RoguelikeDifficultySelectionTaskPlugin() override = default; +class RoguelikeDifficultySelectionTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeDifficultySelectionTaskPlugin() override = default; - public: - virtual bool verify(AsstMsg msg, const json::value& details) const override; +public: + virtual bool verify(AsstMsg msg, const json::value& details) const override; - protected: - virtual bool _run() override; - }; +protected: + virtual bool _run() override; +}; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeFormationTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeFormationTaskPlugin.h index 55722accf7..feb9752550 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeFormationTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeFormationTaskPlugin.h @@ -5,31 +5,31 @@ namespace asst { - // 集成战略模式快捷编队任务 - class RoguelikeFormationTaskPlugin : public AbstractRoguelikeTaskPlugin - { - public: - static constexpr size_t MaxNumOfOperPerPage = 8; +// 集成战略模式快捷编队任务 +class RoguelikeFormationTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + static constexpr size_t MaxNumOfOperPerPage = 8; - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - virtual ~RoguelikeFormationTaskPlugin() override = default; +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeFormationTaskPlugin() override = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; + virtual bool verify(AsstMsg msg, const json::value& details) const override; - protected: - virtual bool _run() override; +protected: + virtual bool _run() override; - void clear_and_reselect(); - bool analyze(); - bool select(RoguelikeFormationImageAnalyzer::FormationOper oper); - void swipe_to_first_page(); - void scan_oper(); + void clear_and_reselect(); + bool analyze(); + bool select(RoguelikeFormationImageAnalyzer::FormationOper oper); + void swipe_to_first_page(); + void scan_oper(); - private: - int cur_page = 1; - int max_page = 1; - std::vector oper_list; - std::vector m_last_detected_oper_names; // 上一页识别到的干员 - }; +private: + int cur_page = 1; + int max_page = 1; + std::vector oper_list; + std::vector m_last_detected_oper_names; // 上一页识别到的干员 +}; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeLastRewardTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeLastRewardTaskPlugin.h index b5855035cc..4d182f4e60 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeLastRewardTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeLastRewardTaskPlugin.h @@ -3,19 +3,19 @@ namespace asst { - class RoguelikeLastRewardTaskPlugin : public AbstractRoguelikeTaskPlugin - { - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - virtual ~RoguelikeLastRewardTaskPlugin() override = default; +class RoguelikeLastRewardTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeLastRewardTaskPlugin() override = default; - public: - virtual bool verify(AsstMsg msg, const json::value& details) const override; +public: + virtual bool verify(AsstMsg msg, const json::value& details) const override; - protected: - virtual bool _run() override; +protected: + virtual bool _run() override; - private: - mutable bool m_is_next_hardest = false; // 下一局是否是高难烧水局 - }; +private: + mutable bool m_is_next_hardest = false; // 下一局是否是高难烧水局 +}; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeRecruitTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeRecruitTaskPlugin.h index ec4b46a493..a6894d878e 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeRecruitTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeRecruitTaskPlugin.h @@ -55,8 +55,8 @@ private: const RecruitPriorityOffset& condition, const std::unordered_map& chars_map); - int m_recruit_count = 0; // 第几次招募 + int m_recruit_count = 0; // 第几次招募 bool m_starts_complete = false; // 开局干员是否已经招募,阵容中必须有开局干员,没有前仅招募start干员或预备干员 - bool m_team_complete = false; // 阵容是否完备,阵容完备前,仅招募key干员或预备干员 + bool m_team_complete = false; // 阵容是否完备,阵容完备前,仅招募key干员或预备干员 }; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeResetTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeResetTaskPlugin.h index 5f048e6c49..6b20177788 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeResetTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeResetTaskPlugin.h @@ -3,15 +3,15 @@ namespace asst { - class RoguelikeResetTaskPlugin : public AbstractRoguelikeTaskPlugin - { - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - virtual ~RoguelikeResetTaskPlugin() = default; +class RoguelikeResetTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeResetTaskPlugin() = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; + virtual bool verify(AsstMsg msg, const json::value& details) const override; - protected: - virtual bool _run() override; - }; +protected: + virtual bool _run() override; +}; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeSettlementTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeSettlementTaskPlugin.cpp index ee0eb0a3d2..adfd54bb36 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeSettlementTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeSettlementTaskPlugin.cpp @@ -107,9 +107,10 @@ bool asst::RoguelikeSettlementTaskPlugin::get_settlement_info(json::value& info, "RoguelikeSettlementOcr-Combat", "RoguelikeSettlementOcr-Recruit", "RoguelikeSettlementOcr-Collection", "RoguelikeSettlementOcr-BOSS", "RoguelikeSettlementOcr-Emergency" }; - static const auto text_task_name = - std::vector { "RoguelikeSettlementOcr-Difficulty", "RoguelikeSettlementOcr-Score", - "RoguelikeSettlementOcr-Exp", "RoguelikeSettlementOcr-Skill" }; + static const auto text_task_name = std::vector { "RoguelikeSettlementOcr-Difficulty", + "RoguelikeSettlementOcr-Score", + "RoguelikeSettlementOcr-Exp", + "RoguelikeSettlementOcr-Skill" }; ranges::for_each(battle_task_name, analyze_battle_data); @@ -142,8 +143,10 @@ bool asst::RoguelikeSettlementTaskPlugin::wait_for_whole_page() return false; } -void asst::RoguelikeSettlementTaskPlugin::save_img(const cv::Mat& image, const std::filesystem::path& relative_dir, - std::string name) +void asst::RoguelikeSettlementTaskPlugin::save_img( + const cv::Mat& image, + const std::filesystem::path& relative_dir, + std::string name) { if (image.empty()) { return; diff --git a/src/MaaCore/Task/Roguelike/RoguelikeSettlementTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeSettlementTaskPlugin.h index 87cf0fba5d..5d164cffb7 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeSettlementTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeSettlementTaskPlugin.h @@ -3,20 +3,20 @@ namespace asst { - // 肉鸽结算图保存及统计 - class RoguelikeSettlementTaskPlugin : public AbstractRoguelikeTaskPlugin - { - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - virtual ~RoguelikeSettlementTaskPlugin() override = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; +// 肉鸽结算图保存及统计 +class RoguelikeSettlementTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeSettlementTaskPlugin() override = default; + virtual bool verify(AsstMsg msg, const json::value& details) const override; - private: - virtual bool _run() override; - bool get_settlement_info(json::value& info, const cv::Mat& image); - bool wait_for_whole_page(); - void save_img(const cv::Mat& image, const std::filesystem::path& path, std::string name); +private: + virtual bool _run() override; + bool get_settlement_info(json::value& info, const cv::Mat& image); + bool wait_for_whole_page(); + void save_img(const cv::Mat& image, const std::filesystem::path& path, std::string name); - mutable bool m_game_pass = false; - }; + mutable bool m_game_pass = false; +}; } // namespace asst diff --git a/src/MaaCore/Task/Roguelike/RoguelikeShoppingTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeShoppingTaskPlugin.cpp index 42d7ce456c..a2d626235f 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeShoppingTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeShoppingTaskPlugin.cpp @@ -22,8 +22,7 @@ bool asst::RoguelikeShoppingTaskPlugin::verify(AsstMsg msg, const json::value& d } if (details.get("details", "task", "").ends_with("Roguelike@TraderRandomShopping")) { - return m_config->get_mode() != RoguelikeMode::Investment - || m_config->get_invest_with_more_score(); + return m_config->get_mode() != RoguelikeMode::Investment || m_config->get_invest_with_more_score(); } else { return false; @@ -36,9 +35,9 @@ bool asst::RoguelikeShoppingTaskPlugin::_run() buy_once(); const auto& theme = m_config->get_theme(); - if ((theme == RoguelikeTheme::Sami || theme == RoguelikeTheme::Sarkaz) - && m_config->get_mode() == RoguelikeMode::Exp) { - //点击刷新 + if ((theme == RoguelikeTheme::Sami || theme == RoguelikeTheme::Sarkaz) && + m_config->get_mode() == RoguelikeMode::Exp) { + // 点击刷新 ProcessTask(*this, { theme + "@Roguelike@StageTraderRefresh" }).run(); buy_once(); } @@ -91,8 +90,7 @@ bool asst::RoguelikeShoppingTaskPlugin::buy_once() map_roles_count[role] += 1; static const std::unordered_map RarityPromotionLevel = { - { 0, INT_MAX }, { 1, INT_MAX }, { 2, INT_MAX }, { 3, INT_MAX }, - { 4, 60 }, { 5, 70 }, { 6, 80 }, + { 0, INT_MAX }, { 1, INT_MAX }, { 2, INT_MAX }, { 3, INT_MAX }, { 4, 60 }, { 5, 70 }, { 6, 80 }, }; int rarity = BattleData.get_rarity(name); if (elite == 1 && level >= RarityPromotionLevel.at(rarity)) { @@ -116,10 +114,9 @@ bool asst::RoguelikeShoppingTaskPlugin::buy_once() // bool bought = false; auto& all_goods = RoguelikeShopping.get_goods(m_config->get_theme()); - std::vector all_foldartal = - m_config->get_theme() == RoguelikeTheme::Sami - ? Task.get("Sami@Roguelike@FoldartalGainOcr")->text - : std::vector(); + std::vector all_foldartal = m_config->get_theme() == RoguelikeTheme::Sami + ? Task.get("Sami@Roguelike@FoldartalGainOcr")->text + : std::vector(); for (const auto& goods : all_goods) { if (need_exit()) { return false; @@ -134,8 +131,7 @@ bool asst::RoguelikeShoppingTaskPlugin::buy_once() } auto find_it = ranges::find_if(result, [&](const TextRect& tr) -> bool { - return tr.text.find(goods.name) != std::string::npos - || goods.name.find(tr.text) != std::string::npos; + return tr.text.find(goods.name) != std::string::npos || goods.name.find(tr.text) != std::string::npos; }); if (find_it == result.cend()) { continue; @@ -150,20 +146,14 @@ bool asst::RoguelikeShoppingTaskPlugin::buy_once() } } if (!role_matched) { - Log.trace( - "Ready to buy", - goods.name, - ", but there is no such professional operator, skip"); + Log.trace("Ready to buy", goods.name, ", but there is no such professional operator, skip"); continue; } } if (goods.promotion != 0) { if (total_wait_promotion == 0) { - Log.trace( - "Ready to buy", - goods.name, - ", but there is no one waiting for promotion, skip"); + Log.trace("Ready to buy", goods.name, ", but there is no one waiting for promotion, skip"); continue; } if (!goods.roles.empty()) { @@ -175,10 +165,7 @@ bool asst::RoguelikeShoppingTaskPlugin::buy_once() } } if (!role_matched) { - Log.trace( - "Ready to buy", - goods.name, - ", but there is no one waiting for promotion, skip"); + Log.trace("Ready to buy", goods.name, ", but there is no one waiting for promotion, skip"); continue; } } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeShoppingTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeShoppingTaskPlugin.h index b2cbfd1b59..4ba601e119 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeShoppingTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeShoppingTaskPlugin.h @@ -3,19 +3,19 @@ namespace asst { - class RoguelikeShoppingTaskPlugin : public AbstractRoguelikeTaskPlugin - { - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - virtual ~RoguelikeShoppingTaskPlugin() override = default; +class RoguelikeShoppingTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeShoppingTaskPlugin() override = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; + virtual bool verify(AsstMsg msg, const json::value& details) const override; - protected: - virtual bool _run() override; - - private: - // 购买一次 - bool buy_once(); - }; +protected: + virtual bool _run() override; + +private: + // 购买一次 + bool buy_once(); +}; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeSkillSelectionTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeSkillSelectionTaskPlugin.h index efb55e099b..0ace0e3bf5 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeSkillSelectionTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeSkillSelectionTaskPlugin.h @@ -6,15 +6,15 @@ namespace asst { - class RoguelikeSkillSelectionTaskPlugin final : public AbstractRoguelikeTaskPlugin - { - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - virtual ~RoguelikeSkillSelectionTaskPlugin() override = default; +class RoguelikeSkillSelectionTaskPlugin final : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeSkillSelectionTaskPlugin() override = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; + virtual bool verify(AsstMsg msg, const json::value& details) const override; - protected: - virtual bool _run() override; - }; +protected: + virtual bool _run() override; +}; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp index a32a11128e..46ab0d82bc 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.cpp @@ -40,7 +40,7 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() const RoguelikeMode& mode = m_config->get_mode(); std::unordered_map event_map = RoguelikeStageEncounter.get_events(theme, mode); std::vector event_names = RoguelikeStageEncounter.get_event_names(theme); - + const auto event_name_task_ptr = Task.get("Roguelike@StageEncounterOcr"); sleep(event_name_task_ptr->pre_delay); @@ -89,8 +89,7 @@ bool asst::RoguelikeStageEncounterTaskPlugin::_run() callback(AsstMsg::SubTaskExtraInfo, info); const auto click_option_task_name = [&](const int item, const int total) { - return m_config->get_theme() + "@Roguelike@OptionChoose" + std::to_string(total) + "-" - + std::to_string(item); + return m_config->get_theme() + "@Roguelike@OptionChoose" + std::to_string(total) + "-" + std::to_string(item); }; for (int j = 0; j < 2; ++j) { @@ -169,9 +168,7 @@ bool asst::RoguelikeStageEncounterTaskPlugin::satisfies_condition( return true; } -int asst::RoguelikeStageEncounterTaskPlugin::process_task( - const Config::RoguelikeEvent& event, - const int special_val) +int asst::RoguelikeStageEncounterTaskPlugin::process_task(const Config::RoguelikeEvent& event, const int special_val) { for (const auto& requirement : event.choice_require) { if (requirement.choose == -1) { diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h index d4929bc492..4a0691125c 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStageEncounterTaskPlugin.h @@ -2,25 +2,25 @@ #include "AbstractRoguelikeTaskPlugin.h" #include "Config/Roguelike/RoguelikeStageEncounterConfig.h" #include "Config/TaskData.h" -#include "Vision/OCRer.h" #include "Sami/RoguelikeCollapsalParadigmTaskPlugin.h" +#include "Vision/OCRer.h" namespace asst { - class RoguelikeStageEncounterTaskPlugin : public AbstractRoguelikeTaskPlugin - { - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - using Config = RoguelikeStageEncounterConfig; - virtual ~RoguelikeStageEncounterTaskPlugin() override = default; +class RoguelikeStageEncounterTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + using Config = RoguelikeStageEncounterConfig; + virtual ~RoguelikeStageEncounterTaskPlugin() override = default; - public: - virtual bool verify(AsstMsg msg, const json::value& details) const override; +public: + virtual bool verify(AsstMsg msg, const json::value& details) const override; - protected: - virtual bool _run() override; - static bool satisfies_condition(const Config::ChoiceRequire& requirement, int special_val); - static int process_task(const Config::RoguelikeEvent& event, const int special_val); - static int hp(const cv::Mat& image); - }; +protected: + virtual bool _run() override; + static bool satisfies_condition(const Config::ChoiceRequire& requirement, int special_val); + static int process_task(const Config::RoguelikeEvent& event, const int special_val); + static int hp(const cv::Mat& image); +}; } diff --git a/src/MaaCore/Task/Roguelike/RoguelikeStrategyChangeTaskPlugin.h b/src/MaaCore/Task/Roguelike/RoguelikeStrategyChangeTaskPlugin.h index 86fc733ae2..ed616862e2 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeStrategyChangeTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/RoguelikeStrategyChangeTaskPlugin.h @@ -3,19 +3,19 @@ namespace asst { - class RoguelikeStrategyChangeTaskPlugin : public AbstractRoguelikeTaskPlugin - { - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - virtual ~RoguelikeStrategyChangeTaskPlugin() override = default; +class RoguelikeStrategyChangeTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeStrategyChangeTaskPlugin() override = default; - public: - virtual bool verify(AsstMsg msg, const json::value& details) const override; +public: + virtual bool verify(AsstMsg msg, const json::value& details) const override; - protected: - virtual bool _run() override; +protected: + virtual bool _run() override; - private: - mutable json::object m_result; - }; +private: + mutable json::object m_result; +}; } diff --git a/src/MaaCore/Task/Roguelike/Sami/RoguelikeCollapsalParadigmTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/Sami/RoguelikeCollapsalParadigmTaskPlugin.cpp index 7ab8d2e978..8d289aeb43 100644 --- a/src/MaaCore/Task/Roguelike/Sami/RoguelikeCollapsalParadigmTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/Sami/RoguelikeCollapsalParadigmTaskPlugin.cpp @@ -143,8 +143,8 @@ void asst::RoguelikeCollapsalParadigmTaskPlugin::check_banner() sort_by_vertical_(ocr_results1); // 按照垂直方向排序(从上到下) sort_by_vertical_(ocr_results2); // 按照垂直方向排序(从上到下) - auto result_it1 = ocr_results1.begin(); - auto result_it2 = ocr_results2.begin(); + auto result_it1 = ocr_results1.begin(); + auto result_it2 = ocr_results2.begin(); std::vector::iterator it; while (result_it1 != ocr_results1.end() && result_it2 != ocr_results2.end()) { @@ -289,7 +289,7 @@ void asst::RoguelikeCollapsalParadigmTaskPlugin::check_panel() #endif } - auto it = prev_clp_pds.begin(); + auto it = prev_clp_pds.begin(); for (const std::string& cur_clp_pd : cur_clp_pds) { // 判断坍缩范式变动 const unsigned int& cur_index = clp_pd_dict.at(cur_clp_pd); diff --git a/src/MaaCore/Task/Roguelike/Sami/RoguelikeCollapsalParadigmTaskPlugin.h b/src/MaaCore/Task/Roguelike/Sami/RoguelikeCollapsalParadigmTaskPlugin.h index c7ed99845d..4968d54fe7 100644 --- a/src/MaaCore/Task/Roguelike/Sami/RoguelikeCollapsalParadigmTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/Sami/RoguelikeCollapsalParadigmTaskPlugin.h @@ -50,13 +50,13 @@ private: bool m_double_check_clp_pds = false; // 是否在每次回到地图时验证坍缩范式 // ———————— 插件配置信息,从 tasks.json 中读取 —————————————————————————————— - std::string m_deepen_text; // 坍缩范式变动通知中"坍缩范式加深"的文字 + std::string m_deepen_text; // 坍缩范式变动通知中"坍缩范式加深"的文字 - std::unordered_set m_banner_triggers_start; // 通过 SubTaskStart 触发 banner check 的任务 + std::unordered_set m_banner_triggers_start; // 通过 SubTaskStart 触发 banner check 的任务 std::unordered_set m_banner_triggers_completed; // 通过 SubTaskCompleted 触发 banner check 的任务 std::unordered_set m_panel_triggers; // 通过 SubTaskStart 触发 panel check 的任务 - std::unordered_map m_zone_dict; // template 名与区域名的映射关系 + std::unordered_map m_zone_dict; // template 名与区域名的映射关系 // ———————— 插件内部常量 ——————————————————————————————————————————————— const std::string_view m_banner_check_error_message = diff --git a/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalGainTaskPlugin.h b/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalGainTaskPlugin.h index 56fb1b400f..bc10cc1d02 100644 --- a/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalGainTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalGainTaskPlugin.h @@ -3,32 +3,33 @@ namespace asst { - class RoguelikeFoldartalGainTaskPlugin : public AbstractRoguelikeTaskPlugin - { - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - virtual ~RoguelikeFoldartalGainTaskPlugin() override = default; +class RoguelikeFoldartalGainTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeFoldartalGainTaskPlugin() override = default; - public: - virtual bool load_params(const json::value& params) override; - virtual bool verify(AsstMsg msg, const json::value& details) const override; - void set_start_floor_foldartal(std::string value) { m_start_floor_foldartal = value; } +public: + virtual bool load_params(const json::value& params) override; + virtual bool verify(AsstMsg msg, const json::value& details) const override; - protected: - virtual bool _run() override; - virtual void reset_in_run_variables() override; + void set_start_floor_foldartal(std::string value) { m_start_floor_foldartal = value; } - private: - void enter_next_floor(); - bool gain_stage_award(); +protected: + virtual bool _run() override; + virtual void reset_in_run_variables() override; - void gain_foldartal(std::string name); - // 战斗后识别密文板 - mutable bool m_ocr_after_combat = false; - // 进入新一层后识别密文板 - mutable bool m_ocr_next_level = false; +private: + void enter_next_floor(); + bool gain_stage_award(); - std::string m_start_floor_foldartal; // 需要凹的远见 - std::optional m_foldartal_floor; // 当前层的预见密文板,在下一层获得 - }; + void gain_foldartal(std::string name); + // 战斗后识别密文板 + mutable bool m_ocr_after_combat = false; + // 进入新一层后识别密文板 + mutable bool m_ocr_next_level = false; + + std::string m_start_floor_foldartal; // 需要凹的远见 + std::optional m_foldartal_floor; // 当前层的预见密文板,在下一层获得 +}; } diff --git a/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalUseTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalUseTaskPlugin.cpp index af0d7f6f93..cd2418027b 100644 --- a/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalUseTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalUseTaskPlugin.cpp @@ -9,8 +9,7 @@ #include -bool asst::RoguelikeFoldartalUseTaskPlugin::verify(const AsstMsg msg, const json::value& details) - const +bool asst::RoguelikeFoldartalUseTaskPlugin::verify(const AsstMsg msg, const json::value& details) const { if (msg != AsstMsg::SubTaskStart || details.get("subtask", std::string()) != "ProcessTask") { return false; @@ -37,8 +36,7 @@ bool asst::RoguelikeFoldartalUseTaskPlugin::verify(const AsstMsg msg, const json if (task_view.ends_with(task_name_suf)) { task_view.remove_suffix(task_name_suf.length()); } - if (task_view == "CombatDps" || task_view == "EmergencyDps" - || task_view == "FerociousPresage") { + if (task_view == "CombatDps" || task_view == "EmergencyDps" || task_view == "FerociousPresage") { if (mode == RoguelikeMode::Investment || mode == RoguelikeMode::Collectible) { m_stage = "SkipBattle"; } @@ -59,9 +57,9 @@ bool asst::RoguelikeFoldartalUseTaskPlugin::verify(const AsstMsg msg, const json m_stage = "Encounter"; return true; } - if ((task_view == "Gambling" || task_view == "EmergencyTransportation" - || task_view == "WindAndRain" || task_view == "MysteriousPresage") - && mode == RoguelikeMode::Exp) { + if ((task_view == "Gambling" || task_view == "EmergencyTransportation" || task_view == "WindAndRain" || + task_view == "MysteriousPresage") && + mode == RoguelikeMode::Exp) { m_stage = "Gambling"; return true; } @@ -86,13 +84,11 @@ bool asst::RoguelikeFoldartalUseTaskPlugin::_run() { LogTraceFunction; - std::vector combination = - RoguelikeFoldartal.get_combination(m_config->get_theme()); + std::vector combination = RoguelikeFoldartal.get_combination(m_config->get_theme()); auto foldartal_list = m_config->get_foldartal(); Log.trace("All foldartal got yet:", foldartal_list); - auto filter = views::filter( - [&](const RoguelikeFoldartalCombination& usage) { return m_stage == usage.usage; }); + auto filter = views::filter([&](const RoguelikeFoldartalCombination& usage) { return m_stage == usage.usage; }); for (const auto& comb : combination | filter) { if (need_exit()) { break; @@ -185,9 +181,7 @@ void asst::RoguelikeFoldartalUseTaskPlugin::use_enable_pair( } asst::RoguelikeFoldartalUseTaskPlugin::UseBoardResult - asst::RoguelikeFoldartalUseTaskPlugin::use_board( - const std::string& up_board, - const std::string& down_board) const + asst::RoguelikeFoldartalUseTaskPlugin::use_board(const std::string& up_board, const std::string& down_board) const { LogTraceFunction; @@ -210,8 +204,7 @@ asst::RoguelikeFoldartalUseTaskPlugin::UseBoardResult else if (!search_and_click_stage()) { result = UseBoardResult::StageNotFound; } - else if (ProcessTask(*this, { m_config->get_theme() + "@Roguelike@FoldartalUseConfirm" }) - .run()) { + else if (ProcessTask(*this, { m_config->get_theme() + "@Roguelike@FoldartalUseConfirm" }).run()) { return UseBoardResult::UseBoardResultSuccess; } else { @@ -240,8 +233,7 @@ bool asst::RoguelikeFoldartalUseTaskPlugin::search_and_click_board(const std::st slowly_swipe(true); } else { - ctrler()->click( - analyzer.get_result().front().rect.move(Task.get(task_name)->rect_move)); + ctrler()->click(analyzer.get_result().front().rect.move(Task.get(task_name)->rect_move)); return true; } try_time++; @@ -261,15 +253,13 @@ bool asst::RoguelikeFoldartalUseTaskPlugin::search_and_click_stage() const sleep(1000); // 节点会闪烁,所以这里不用单次Match - if (ProcessTask(*this, { m_config->get_theme() + "@Roguelike@FoldartalUseOnStage" + m_stage }) - .run()) { + if (ProcessTask(*this, { m_config->get_theme() + "@Roguelike@FoldartalUseOnStage" + m_stage }).run()) { return true; } // 滑到最右边,萨米的地图只有两页,暂时先这么糊着,出现识别不到再写循环 ProcessTask(*this, { "SwipeToTheRight" }).run(); sleep(1000); - if (ProcessTask(*this, { m_config->get_theme() + "@Roguelike@FoldartalUseOnStage" + m_stage }) - .run()) { + if (ProcessTask(*this, { m_config->get_theme() + "@Roguelike@FoldartalUseOnStage" + m_stage }).run()) { return true; } return false; @@ -316,10 +306,7 @@ void asst::RoguelikeFoldartalUseTaskPlugin::slowly_swipe(const bool direction, i const Rect& start_point = swipe_task->specific_rect; ctrler()->swipe( start_point, - { start_point.x + swipe_dist - start_point.width, - start_point.y, - start_point.width, - start_point.height }, + { start_point.x + swipe_dist - start_point.width, start_point.y, start_point.width, start_point.height }, swipe_task->special_params.empty() ? 0 : swipe_task->special_params.at(0), (swipe_task->special_params.size() < 2) ? false : swipe_task->special_params.at(1), (swipe_task->special_params.size() < 3) ? 1 : swipe_task->special_params.at(2), diff --git a/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalUseTaskPlugin.h b/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalUseTaskPlugin.h index 0f58294507..67c49cfbe8 100644 --- a/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalUseTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/Sami/RoguelikeFoldartalUseTaskPlugin.h @@ -5,45 +5,45 @@ namespace asst { - class RoguelikeFoldartalUseTaskPlugin : public AbstractRoguelikeTaskPlugin +class RoguelikeFoldartalUseTaskPlugin : public AbstractRoguelikeTaskPlugin +{ +public: + using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; + virtual ~RoguelikeFoldartalUseTaskPlugin() override = default; + +public: + virtual bool verify(AsstMsg msg, const json::value& details) const override; + virtual bool load_params([[maybe_unused]] const json::value& params) override; + +protected: + virtual bool _run() override; + +private: + // 遍历配置里的组合 + void use_enable_pair(std::vector& list, const asst::RoguelikeFoldartalCombination& usage); + // 使用板子对结果 + enum class UseBoardResult { - public: - using AbstractRoguelikeTaskPlugin::AbstractRoguelikeTaskPlugin; - virtual ~RoguelikeFoldartalUseTaskPlugin() override = default; - - public: - virtual bool verify(AsstMsg msg, const json::value& details) const override; - virtual bool load_params([[maybe_unused]] const json::value& params) override; - - protected: - virtual bool _run() override; - - private: - // 遍历配置里的组合 - void use_enable_pair(std::vector& list, const asst::RoguelikeFoldartalCombination& usage); - // 使用板子对结果 - enum class UseBoardResult - { - ClickFoldartalError, - UseBoardResultSuccess, - UpBoardNotFound, - DownBoardNotFound, - StageNotFound, - CanNotUseConfirm, - UnknownError, - }; - // 使用板子对 - UseBoardResult use_board(const std::string& up_board, const std::string& down_board) const; - // 找到并点击指定板子 - bool search_and_click_board(const std::string& board) const; - // 找到并点击指定节点 - bool search_and_click_stage() const; - // 滑到最上面 - void swipe_to_top() const; - // 缓慢滑动 - void slowly_swipe(bool direction, int swipe_dist = 200) const; - // 节点类型 - mutable std::string m_stage; - bool m_use_foldartal = true; // 是否使用密文板 + ClickFoldartalError, + UseBoardResultSuccess, + UpBoardNotFound, + DownBoardNotFound, + StageNotFound, + CanNotUseConfirm, + UnknownError, }; + // 使用板子对 + UseBoardResult use_board(const std::string& up_board, const std::string& down_board) const; + // 找到并点击指定板子 + bool search_and_click_board(const std::string& board) const; + // 找到并点击指定节点 + bool search_and_click_stage() const; + // 滑到最上面 + void swipe_to_top() const; + // 缓慢滑动 + void slowly_swipe(bool direction, int swipe_dist = 200) const; + // 节点类型 + mutable std::string m_stage; + bool m_use_foldartal = true; // 是否使用密文板 +}; } diff --git a/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp b/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp index a033ae5e10..c679cb87b9 100644 --- a/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp +++ b/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp @@ -242,8 +242,7 @@ bool asst::SSSBattleProcessTask::check_and_do_strategy(const cv::Mat& reusable) } #ifdef ASST_DEBUG LogDebug << __FUNCTION__ << "| Checking strategy at" << strategy.location << "with core" - << strategy.core.value_or("(empty)") - << "and tool_men" + << strategy.core.value_or("(empty)") << "and tool_men" << (strategy.tool_men | views::transform([](const auto& rolecounts) { return asst::enum_to_string(rolecounts.first) + ": " + std::to_string(rolecounts.second); })); @@ -272,9 +271,8 @@ bool asst::SSSBattleProcessTask::check_and_do_strategy(const cv::Mat& reusable) return deploy_oper(core.name, strategy.location, strategy.direction) && update_deployment(); } - auto required_roles_view = strategy.tool_men | - views::filter([](const auto& tool_man) { return tool_man.second > 0; }) | - views::keys; + auto required_roles_view = + strategy.tool_men | views::filter([](const auto& tool_man) { return tool_man.second > 0; }) | views::keys; auto required_roles = std::unordered_set(required_roles_view.begin(), required_roles_view.end()); // 如果有费用转好的干员,直接使用 diff --git a/src/MaaCore/Task/SSS/SSSBattleProcessTask.h b/src/MaaCore/Task/SSS/SSSBattleProcessTask.h index cd5c515224..1bb6039d0c 100644 --- a/src/MaaCore/Task/SSS/SSSBattleProcessTask.h +++ b/src/MaaCore/Task/SSS/SSSBattleProcessTask.h @@ -5,30 +5,34 @@ namespace asst { - class SSSBattleProcessTask : public BattleProcessTask - { - public: - using BattleProcessTask::BattleProcessTask; - virtual ~SSSBattleProcessTask() override = default; +class SSSBattleProcessTask : public BattleProcessTask +{ +public: + using BattleProcessTask::BattleProcessTask; + virtual ~SSSBattleProcessTask() override = default; - virtual bool set_stage_name(const std::string& stage_name) override; + virtual bool set_stage_name(const std::string& stage_name) override; - protected: - virtual bool do_derived_action(const battle::copilot::Action& action, size_t index) override; - virtual bool do_strategic_action(const cv::Mat& reusable = cv::Mat()) override; - virtual battle::copilot::CombatData& get_combat_data() override { return m_sss_combat_data; } - virtual const std::string oper_name_ocr_task_name() const noexcept override { return "SSSBattleOperName"; } - virtual bool need_to_wait_until_end() const noexcept override { return true; } - virtual bool wait_until_start(bool weak = true) override; +protected: + virtual bool do_derived_action(const battle::copilot::Action& action, size_t index) override; + virtual bool do_strategic_action(const cv::Mat& reusable = cv::Mat()) override; - bool update_deployment_with_skip(const cv::Mat& reusable = cv::Mat()); - bool check_and_do_strategy(const cv::Mat& reusable = cv::Mat()); - bool check_if_start_over(const battle::copilot::Action& action); - bool draw_card(bool with_retry = true, const cv::Mat& reusable = cv::Mat()); - bool check_and_get_drops(const cv::Mat& reusable = cv::Mat()); + virtual battle::copilot::CombatData& get_combat_data() override { return m_sss_combat_data; } - battle::sss::CombatData m_sss_combat_data; - std::multiset m_all_cores; - std::unordered_set m_all_action_opers; - }; + virtual const std::string oper_name_ocr_task_name() const noexcept override { return "SSSBattleOperName"; } + + virtual bool need_to_wait_until_end() const noexcept override { return true; } + + virtual bool wait_until_start(bool weak = true) override; + + bool update_deployment_with_skip(const cv::Mat& reusable = cv::Mat()); + bool check_and_do_strategy(const cv::Mat& reusable = cv::Mat()); + bool check_if_start_over(const battle::copilot::Action& action); + bool draw_card(bool with_retry = true, const cv::Mat& reusable = cv::Mat()); + bool check_and_get_drops(const cv::Mat& reusable = cv::Mat()); + + battle::sss::CombatData m_sss_combat_data; + std::multiset m_all_cores; + std::unordered_set m_all_action_opers; +}; } diff --git a/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.cpp b/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.cpp index e706166ce0..cebca12b45 100644 --- a/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.cpp +++ b/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.cpp @@ -45,8 +45,9 @@ bool asst::SSSDropRewardsTaskPlugin::_run() continue; } auto role = BattleData.get_role(result.text); - opers.emplace_back(DropRecruitment { - .ocr_res = result, .role = role == Role::Unknown ? std::nullopt : std::optional(role) }); + opers.emplace_back( + DropRecruitment { .ocr_res = result, + .role = role == Role::Unknown ? std::nullopt : std::optional(role) }); } bool operSelect = false; diff --git a/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.h b/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.h index 1261dc7a8a..f2dcfb1d48 100644 --- a/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.h +++ b/src/MaaCore/Task/SSS/SSSDropRewardsTaskPlugin.h @@ -4,15 +4,15 @@ namespace asst { - class SSSDropRewardsTaskPlugin : public AbstractTaskPlugin - { - public: - using AbstractTaskPlugin::AbstractTaskPlugin; - virtual ~SSSDropRewardsTaskPlugin() noexcept override = default; +class SSSDropRewardsTaskPlugin : public AbstractTaskPlugin +{ +public: + using AbstractTaskPlugin::AbstractTaskPlugin; + virtual ~SSSDropRewardsTaskPlugin() noexcept override = default; - virtual bool verify(AsstMsg msg, const json::value& details) const override; + virtual bool verify(AsstMsg msg, const json::value& details) const override; - protected: - bool _run() override; - }; +protected: + bool _run() override; +}; } diff --git a/src/MaaCore/Task/SSS/SSSStageManagerTask.h b/src/MaaCore/Task/SSS/SSSStageManagerTask.h index 656e02412e..3f169901cd 100644 --- a/src/MaaCore/Task/SSS/SSSStageManagerTask.h +++ b/src/MaaCore/Task/SSS/SSSStageManagerTask.h @@ -5,22 +5,22 @@ namespace asst { - class SSSStageManagerTask : public AbstractTask - { - public: - using AbstractTask::AbstractTask; - virtual ~SSSStageManagerTask() override = default; +class SSSStageManagerTask : public AbstractTask +{ +public: + using AbstractTask::AbstractTask; + virtual ~SSSStageManagerTask() override = default; - private: - virtual bool _run() override; +private: + virtual bool _run() override; - void preprocess_data(); - std::optional analyze_stage(); - bool confirm_battle_complete(); - bool click_start_button(); - bool settle(); // 结算奖励(退出整局保全战斗) - bool check_on_start_screen(); + void preprocess_data(); + std::optional analyze_stage(); + bool confirm_battle_complete(); + bool click_start_button(); + bool settle(); // 结算奖励(退出整局保全战斗) + bool check_on_start_screen(); - std::unordered_map m_stage_try_times; - }; + std::unordered_map m_stage_try_times; +}; } diff --git a/src/MaaCore/Utils/Algorithm.hpp b/src/MaaCore/Utils/Algorithm.hpp index efd3c32c68..0e3f3b9a3f 100644 --- a/src/MaaCore/Utils/Algorithm.hpp +++ b/src/MaaCore/Utils/Algorithm.hpp @@ -7,265 +7,277 @@ namespace asst::algorithm { - /** - * @brief 根据传入的分组规则及干员列表, 求解一个可行的分配方案 - * @param group_list 分组规则, key 为组名, value 为组内干员列表, 如:\n - * {\n - * "A": {"干员1", "干员2"},\n - * "B": {"干员2", "干员3"}\n - * } - * @param char_set 干员列表, 如:\n - * {\n - * "干员1",\n - * "干员2"\n - * } - * @return 可行的分配方案, key 为组名, value 为该组分配的干员, 若无可行方案则返回 std::nullopt, 如:\n - * {\n - * "A": "干员1",\n - * "B": "干员2"\n - * } +/** + * @brief 根据传入的分组规则及干员列表, 求解一个可行的分配方案 + * @param group_list 分组规则, key 为组名, value 为组内干员列表, 如:\n + * {\n + * "A": {"干员1", "干员2"},\n + * "B": {"干员2", "干员3"}\n + * } + * @param char_set 干员列表, 如:\n + * {\n + * "干员1",\n + * "干员2"\n + * } + * @return 可行的分配方案, key 为组名, value 为该组分配的干员, 若无可行方案则返回 std::nullopt, 如:\n + * {\n + * "A": "干员1",\n + * "B": "干员2"\n + * } + */ +inline static std::optional> get_char_allocation_for_each_group( + const std::unordered_map>& group_list, + const std::unordered_set& char_set) +{ + /* + * * dlx 算法简介 + * + * https://oi-wiki.org/search/dlx/ + * + * + * * dlx 算法作用 + * + * 在形如: + * a: 10010 + * b: 01110 + * c: 01001 + * d: 00100 + * e: 11010 + * 这样的数据里, + * dlx 可以找到 {a, c, d} 这样每列恰好出现且仅出现一次 1 的数据, + * 也即对全集的一个精确覆盖: + * a: 10010 + * c: 01001 + * d: 00100 + * 11111 + * + * + * * dlx 算法建模 + * + * dlx 的列分为 [组号] [干员号] 两部分 + * dlx 的行分为 [可能的选择对] [不选择该干员] 两部分 + * + * [可能的选择对]: + * 每行对应一种可能的选择, + * 将组号,干员号对应位置的列设为1 + * + * [不选择该干员]: + * 每行对应不选择某干员的情况, + * 将干员号对应位置的列设为1 + * + * + * * dlx 建模示例 + * + * 有以下分组: + * a: {1, 3, 4} + * b: {2, 3, 5} + * c: {1, 2, 3} + * 拥有的干员: + * {1, 2, 4, 5, 6} + * + * 先处理出所有可能的情况: + * a: {1, 4} + * b: {2, 5} + * c: {1, 2} + * + * 构造表: + * abc 1245 + * 1 100 1000 + * 2 100 0010 + * 3 010 0100 + * 4 010 0001 + * 5 001 1000 + * 6 001 0100 + * 7 000 1000 ~1 + * 9 000 0100 ~2 + * 9 000 0010 ~4 + * A 000 0001 ~5 + * + * 使用dlx求得一组解: + * 一个可能的结果是: + * 行号 {2, 3, 5, A} + * 即 {, , , ~5} + * + * 输出分组结果: + * a: 4 + * b: 2 + * c: 1 + * */ - inline static std::optional> get_char_allocation_for_each_group( - const std::unordered_map>& group_list, - const std::unordered_set& char_set) + + // dlx 算法模板类 + class DancingLinksModel { - /* - * * dlx 算法简介 - * - * https://oi-wiki.org/search/dlx/ - * - * - * * dlx 算法作用 - * - * 在形如: - * a: 10010 - * b: 01110 - * c: 01001 - * d: 00100 - * e: 11010 - * 这样的数据里, - * dlx 可以找到 {a, c, d} 这样每列恰好出现且仅出现一次 1 的数据, - * 也即对全集的一个精确覆盖: - * a: 10010 - * c: 01001 - * d: 00100 - * 11111 - * - * - * * dlx 算法建模 - * - * dlx 的列分为 [组号] [干员号] 两部分 - * dlx 的行分为 [可能的选择对] [不选择该干员] 两部分 - * - * [可能的选择对]: - * 每行对应一种可能的选择, - * 将组号,干员号对应位置的列设为1 - * - * [不选择该干员]: - * 每行对应不选择某干员的情况, - * 将干员号对应位置的列设为1 - * - * - * * dlx 建模示例 - * - * 有以下分组: - * a: {1, 3, 4} - * b: {2, 3, 5} - * c: {1, 2, 3} - * 拥有的干员: - * {1, 2, 4, 5, 6} - * - * 先处理出所有可能的情况: - * a: {1, 4} - * b: {2, 5} - * c: {1, 2} - * - * 构造表: - * abc 1245 - * 1 100 1000 - * 2 100 0010 - * 3 010 0100 - * 4 010 0001 - * 5 001 1000 - * 6 001 0100 - * 7 000 1000 ~1 - * 9 000 0100 ~2 - * 9 000 0010 ~4 - * A 000 0001 ~5 - * - * 使用dlx求得一组解: - * 一个可能的结果是: - * 行号 {2, 3, 5, A} - * 即 {, , , ~5} - * - * 输出分组结果: - * a: 4 - * b: 2 - * c: 1 - * - */ + private: + size_t index {}; + std::vector first, size; + std::vector left, right, up, down; + std::vector column, row; - // dlx 算法模板类 - class DancingLinksModel + void remove(const size_t& column_id) { - private: - size_t index {}; - std::vector first, size; - std::vector left, right, up, down; - std::vector column, row; - - void remove(const size_t& column_id) - { - left[right[column_id]] = left[column_id]; - right[left[column_id]] = right[column_id]; - for (size_t i = down[column_id]; i != column_id; i = down[i]) { - for (size_t j = right[i]; j != i; j = right[j]) { - up[down[j]] = up[j]; - down[up[j]] = down[j]; - --size[column[j]]; - } + left[right[column_id]] = left[column_id]; + right[left[column_id]] = right[column_id]; + for (size_t i = down[column_id]; i != column_id; i = down[i]) { + for (size_t j = right[i]; j != i; j = right[j]) { + up[down[j]] = up[j]; + down[up[j]] = down[j]; + --size[column[j]]; } } + } - void recover(const size_t& column_id) - { - for (size_t i = up[column_id]; i != column_id; i = up[i]) { - for (size_t j = left[i]; j != i; j = left[j]) { - up[down[j]] = down[up[j]] = j; - ++size[column[j]]; - } - } - left[right[column_id]] = right[left[column_id]] = column_id; - } - - public: - size_t answer_stack_size {}; - std::vector answer_stack; - - DancingLinksModel(const size_t& max_node_num, const size_t& max_ans_size) - : first(max_node_num), size(max_node_num), left(max_node_num), right(max_node_num), up(max_node_num), - down(max_node_num), column(max_node_num), row(max_node_num), answer_stack(max_ans_size) - {} - - void build(const size_t& column_id) - { - for (size_t i = 0; i <= column_id; i++) { - left[i] = i - 1; - right[i] = i + 1; - up[i] = down[i] = i; - } - left[0] = column_id; - right[column_id] = 0; - index = column_id; - } - - void insert(const size_t& row_id, const size_t& column_id) - { - column[++index] = column_id; - row[index] = row_id; - ++size[column_id]; - down[index] = down[column_id]; - up[down[column_id]] = index; - up[index] = column_id; - down[column_id] = index; - if (!first[row_id]) { - first[row_id] = left[index] = right[index] = index; - } - else { - right[index] = right[first[row_id]]; - left[right[first[row_id]]] = index; - left[index] = first[row_id]; - right[first[row_id]] = index; + void recover(const size_t& column_id) + { + for (size_t i = up[column_id]; i != column_id; i = up[i]) { + for (size_t j = left[i]; j != i; j = left[j]) { + up[down[j]] = down[up[j]] = j; + ++size[column[j]]; } } + left[right[column_id]] = right[left[column_id]] = column_id; + } - bool dance(const size_t& depth) - { - if (!right[0]) { - answer_stack_size = depth; + public: + size_t answer_stack_size {}; + std::vector answer_stack; + + DancingLinksModel(const size_t& max_node_num, const size_t& max_ans_size) : + first(max_node_num), + size(max_node_num), + left(max_node_num), + right(max_node_num), + up(max_node_num), + down(max_node_num), + column(max_node_num), + row(max_node_num), + answer_stack(max_ans_size) + { + } + + void build(const size_t& column_id) + { + for (size_t i = 0; i <= column_id; i++) { + left[i] = i - 1; + right[i] = i + 1; + up[i] = down[i] = i; + } + left[0] = column_id; + right[column_id] = 0; + index = column_id; + } + + void insert(const size_t& row_id, const size_t& column_id) + { + column[++index] = column_id; + row[index] = row_id; + ++size[column_id]; + down[index] = down[column_id]; + up[down[column_id]] = index; + up[index] = column_id; + down[column_id] = index; + if (!first[row_id]) { + first[row_id] = left[index] = right[index] = index; + } + else { + right[index] = right[first[row_id]]; + left[right[first[row_id]]] = index; + left[index] = first[row_id]; + right[first[row_id]] = index; + } + } + + bool dance(const size_t& depth) + { + if (!right[0]) { + answer_stack_size = depth; + return true; + } + size_t column_id = right[0]; + for (size_t i = right[0]; i != 0; i = right[i]) { + if (size[i] < size[column_id]) { + column_id = i; + } + } + remove(column_id); + for (size_t i = down[column_id]; i != column_id; i = down[i]) { + answer_stack[depth] = row[i]; + for (size_t j = right[i]; j != i; j = right[j]) { + remove(column[j]); + } + if (dance(depth + 1)) { return true; } - size_t column_id = right[0]; - for (size_t i = right[0]; i != 0; i = right[i]) { - if (size[i] < size[column_id]) { - column_id = i; - } - } - remove(column_id); - for (size_t i = down[column_id]; i != column_id; i = down[i]) { - answer_stack[depth] = row[i]; - for (size_t j = right[i]; j != i; j = right[j]) { - remove(column[j]); - } - if (dance(depth + 1)) { - return true; - } - for (size_t j = left[i]; j != i; j = left[j]) { - recover(column[j]); - } - } - recover(column_id); - return false; - } - }; - - // 建立结点、组、干员与各自 id 的映射关系 - std::vector> node_id_mapping; - std::vector group_id_mapping; - std::vector char_id_mapping; - std::unordered_map group_name_mapping; - std::unordered_map char_name_mapping; - - for (auto& i : group_list) { - group_name_mapping[i.first] = group_id_mapping.size(); - group_id_mapping.emplace_back(i.first); - bool is_empty = true; - for (auto& j : i.second) { - if (char_set.contains(j)) { - is_empty = false; - node_id_mapping.emplace_back(i.first, j); - if (!char_name_mapping.contains(j)) { - char_name_mapping[j] = char_id_mapping.size(); - char_id_mapping.emplace_back(j); - } + for (size_t j = left[i]; j != i; j = left[j]) { + recover(column[j]); } } - if (is_empty) { - return std::nullopt; + recover(column_id); + return false; + } + }; + + // 建立结点、组、干员与各自 id 的映射关系 + std::vector> node_id_mapping; + std::vector group_id_mapping; + std::vector char_id_mapping; + std::unordered_map group_name_mapping; + std::unordered_map char_name_mapping; + + for (auto& i : group_list) { + group_name_mapping[i.first] = group_id_mapping.size(); + group_id_mapping.emplace_back(i.first); + bool is_empty = true; + for (auto& j : i.second) { + if (char_set.contains(j)) { + is_empty = false; + node_id_mapping.emplace_back(i.first, j); + if (!char_name_mapping.contains(j)) { + char_name_mapping[j] = char_id_mapping.size(); + char_id_mapping.emplace_back(j); + } } } - - // 建 01 矩阵 - const size_t node_num = node_id_mapping.size(); - const size_t group_num = group_id_mapping.size(); - const size_t char_num = char_id_mapping.size(); - - DancingLinksModel dancing_links_model(2 * node_num + group_num + 2 * char_num + 1, group_num + char_num); - - dancing_links_model.build(group_num + char_num); - - for (size_t i = 0; i < node_num; i++) { - dancing_links_model.insert(i + 1, group_name_mapping[node_id_mapping[i].first] + 1); - dancing_links_model.insert(i + 1, group_num + char_name_mapping[node_id_mapping[i].second] + 1); + if (is_empty) { + return std::nullopt; } - - for (size_t i = 0; i < char_num; i++) { - dancing_links_model.insert(i + node_num + 1, i + group_num + 1); - } - - // dance!! - bool has_solution = dancing_links_model.dance(1); - - // 判定结果 - if (!has_solution) return std::nullopt; - - std::unordered_map return_value; - - for (size_t i = 1; i < dancing_links_model.answer_stack_size; i++) { - if (dancing_links_model.answer_stack[i] > node_num) continue; - return_value.insert(node_id_mapping[dancing_links_model.answer_stack[i] - 1]); - } - - return return_value; } + + // 建 01 矩阵 + const size_t node_num = node_id_mapping.size(); + const size_t group_num = group_id_mapping.size(); + const size_t char_num = char_id_mapping.size(); + + DancingLinksModel dancing_links_model(2 * node_num + group_num + 2 * char_num + 1, group_num + char_num); + + dancing_links_model.build(group_num + char_num); + + for (size_t i = 0; i < node_num; i++) { + dancing_links_model.insert(i + 1, group_name_mapping[node_id_mapping[i].first] + 1); + dancing_links_model.insert(i + 1, group_num + char_name_mapping[node_id_mapping[i].second] + 1); + } + + for (size_t i = 0; i < char_num; i++) { + dancing_links_model.insert(i + node_num + 1, i + group_num + 1); + } + + // dance!! + bool has_solution = dancing_links_model.dance(1); + + // 判定结果 + if (!has_solution) { + return std::nullopt; + } + + std::unordered_map return_value; + + for (size_t i = 1; i < dancing_links_model.answer_stack_size; i++) { + if (dancing_links_model.answer_stack[i] > node_num) { + continue; + } + return_value.insert(node_id_mapping[dancing_links_model.answer_stack[i] - 1]); + } + + return return_value; +} } // namespace asst::algorithm diff --git a/src/MaaCore/Utils/Demangle.hpp b/src/MaaCore/Utils/Demangle.hpp index c18691a000..58bb0ac8f6 100644 --- a/src/MaaCore/Utils/Demangle.hpp +++ b/src/MaaCore/Utils/Demangle.hpp @@ -7,22 +7,30 @@ namespace asst::utils { - inline std::string demangle(const char* name_from_typeid) - { +inline std::string demangle(const char* name_from_typeid) +{ #ifndef _MSC_VER - int status = 0; - std::size_t size = 0; - char* p = abi::__cxa_demangle(name_from_typeid, NULL, &size, &status); - if (!p) return name_from_typeid; - std::string result(p); - std::free(p); - return result; -#else - std::string_view temp(name_from_typeid); - if (temp.substr(0, 6) == "class ") return std::string(temp.substr(6)); - if (temp.substr(0, 7) == "struct ") return std::string(temp.substr(7)); - if (temp.substr(0, 5) == "enum ") return std::string(temp.substr(5)); - return std::string(temp); -#endif + int status = 0; + std::size_t size = 0; + char* p = abi::__cxa_demangle(name_from_typeid, NULL, &size, &status); + if (!p) { + return name_from_typeid; } + std::string result(p); + std::free(p); + return result; +#else + std::string_view temp(name_from_typeid); + if (temp.substr(0, 6) == "class ") { + return std::string(temp.substr(6)); + } + if (temp.substr(0, 7) == "struct ") { + return std::string(temp.substr(7)); + } + if (temp.substr(0, 5) == "enum ") { + return std::string(temp.substr(5)); + } + return std::string(temp); +#endif +} } diff --git a/src/MaaCore/Utils/File.hpp b/src/MaaCore/Utils/File.hpp index 3c6c1a1a13..cb81d0cf9a 100644 --- a/src/MaaCore/Utils/File.hpp +++ b/src/MaaCore/Utils/File.hpp @@ -5,41 +5,43 @@ namespace asst::utils { - template - concept ByteValueType = std::is_integral_v && sizeof(ValueType) == 1; +template +concept ByteValueType = std::is_integral_v && sizeof(ValueType) == 1; - template - concept AppendableBytesContainer = requires(ContainerType a) { - requires ranges::contiguous_range; - requires ByteValueType; - requires std::is_constructible_v; - requires std::is_constructible_v; // std::string(count, ch), - // std::vector(count, value) - a.insert(a.end(), a.begin(), a.begin() + (size_t)1); - a.resize(a.size()); - }; +template +concept AppendableBytesContainer = requires(ContainerType a) { + requires ranges::contiguous_range; + requires ByteValueType; + requires std::is_constructible_v; + requires std::is_constructible_v< + ContainerType, + size_t, + typename ContainerType::value_type>; // std::string(count, ch), + // std::vector(count, value) + a.insert(a.end(), a.begin(), a.begin() + (size_t)1); + a.resize(a.size()); +}; - template - ContainerType read_file(const std::filesystem::path& path) - { - ContainerType result; - std::ifstream file(path, std::ios::binary | std::ios::ate); - auto fileSize = file.tellg(); - if (fileSize != -1) { - result.resize(fileSize); - file.seekg(0, std::ios::beg); - file.read(reinterpret_cast(result.data()), fileSize); - } - else { - // no size available, read to EOF - constexpr auto chunksize = 4096; - ContainerType chunk(chunksize, 0); - while (!file.fail()) { - file.read(reinterpret_cast(chunk.data()), chunksize); - result.insert(result.end(), chunk.data(), chunk.data() + file.gcount()); - } - } - return result; +template +ContainerType read_file(const std::filesystem::path& path) +{ + ContainerType result; + std::ifstream file(path, std::ios::binary | std::ios::ate); + auto fileSize = file.tellg(); + if (fileSize != -1) { + result.resize(fileSize); + file.seekg(0, std::ios::beg); + file.read(reinterpret_cast(result.data()), fileSize); } + else { + // no size available, read to EOF + constexpr auto chunksize = 4096; + ContainerType chunk(chunksize, 0); + while (!file.fail()) { + file.read(reinterpret_cast(chunk.data()), chunksize); + result.insert(result.end(), chunk.data(), chunk.data() + file.gcount()); + } + } + return result; +} } diff --git a/src/MaaCore/Utils/ImageIo.hpp b/src/MaaCore/Utils/ImageIo.hpp index 32af637f2f..de25c91985 100644 --- a/src/MaaCore/Utils/ImageIo.hpp +++ b/src/MaaCore/Utils/ImageIo.hpp @@ -13,42 +13,42 @@ namespace asst { - inline cv::Mat imread(const std::filesystem::path& path, int flags = cv::IMREAD_COLOR) - { - auto content = asst::utils::read_file>(path); - return cv::imdecode(content, flags); - } +inline cv::Mat imread(const std::filesystem::path& path, int flags = cv::IMREAD_COLOR) +{ + auto content = asst::utils::read_file>(path); + return cv::imdecode(content, flags); +} - inline cv::Mat imread(const std::string& utf8_path, int flags = cv::IMREAD_COLOR) - { - return imread(asst::utils::path(utf8_path), flags); - } +inline cv::Mat imread(const std::string& utf8_path, int flags = cv::IMREAD_COLOR) +{ + return imread(asst::utils::path(utf8_path), flags); +} - inline bool imwrite(const std::filesystem::path& path, cv::InputArray img, - const std::vector& params = std::vector()) - { - std::filesystem::path absolute_path; - if (path.is_relative()) [[likely]] { - const auto& user_dir = UserDir.get(); - absolute_path = user_dir / path; - } - else { - absolute_path = path; - } - std::filesystem::create_directories(absolute_path.parent_path()); - std::ofstream of(absolute_path, std::ios::out | std::ios::binary); - std::vector encoded; - auto ext = asst::utils::path_to_utf8_string(absolute_path.extension()); - if (cv::imencode(ext, img, encoded, params)) { - of.write(reinterpret_cast(encoded.data()), encoded.size()); - return true; - } - return false; +inline bool + imwrite(const std::filesystem::path& path, cv::InputArray img, const std::vector& params = std::vector()) +{ + std::filesystem::path absolute_path; + if (path.is_relative()) [[likely]] { + const auto& user_dir = UserDir.get(); + absolute_path = user_dir / path; } + else { + absolute_path = path; + } + std::filesystem::create_directories(absolute_path.parent_path()); + std::ofstream of(absolute_path, std::ios::out | std::ios::binary); + std::vector encoded; + auto ext = asst::utils::path_to_utf8_string(absolute_path.extension()); + if (cv::imencode(ext, img, encoded, params)) { + of.write(reinterpret_cast(encoded.data()), encoded.size()); + return true; + } + return false; +} - inline bool imwrite(const std::string& utf8_path, cv::InputArray img, - const std::vector& params = std::vector()) - { - return imwrite(asst::utils::path(utf8_path), img, params); - } +inline bool + imwrite(const std::string& utf8_path, cv::InputArray img, const std::vector& params = std::vector()) +{ + return imwrite(asst::utils::path(utf8_path), img, params); +} } // namespace asst diff --git a/src/MaaCore/Utils/JsonMisc.hpp b/src/MaaCore/Utils/JsonMisc.hpp index 8dd0ec2be8..00ecb2136d 100644 --- a/src/MaaCore/Utils/JsonMisc.hpp +++ b/src/MaaCore/Utils/JsonMisc.hpp @@ -9,170 +9,181 @@ namespace asst::utils { - // base types - template - requires(std::constructible_from) - bool parse_json_as(const json::value& input, OutT& output) - { - if (input.is()) { - output = input.as(); - return true; - } +// base types +template +requires(std::constructible_from) +bool parse_json_as(const json::value& input, OutT& output) +{ + if (input.is()) { + output = input.as(); + return true; + } + return false; +} + +bool parse_json_as(const json::value& input, AlgorithmType& output) +{ + if (input.is_string()) { + output = get_algorithm_type(input.as_string()); + return output != AlgorithmType::Invalid; + } + return false; +} + +bool parse_json_as(const json::value& input, ProcessTaskAction& output) +{ + if (input.is_string()) { + output = get_action_type(input.as_string()); + return output != ProcessTaskAction::Invalid; + } + return false; +} + +bool parse_json_as(const json::value& input, MatchMethod& output) +{ + if (input.is_string()) { + output = get_match_method(input.as_string()); + return output != MatchMethod::Invalid; + } + return false; +} + +// std::pair <- [first, second] +template +requires(requires(const json::value& input, FirstT x, SecondT y) { + parse_json_as(input, x) && parse_json_as(input, y); +}) +bool parse_json_as(const json::value& input, std::pair& output) +{ + if (!input.is_array()) { return false; } - - bool parse_json_as(const json::value& input, AlgorithmType& output) - { - if (input.is_string()) { - output = get_algorithm_type(input.as_string()); - return output != AlgorithmType::Invalid; - } + const auto& items = input.as_array(); + if (items.size() != 2) { return false; } + return parse_json_as(items[0], output.first) && parse_json_as(items[1], output.second); +} - bool parse_json_as(const json::value& input, ProcessTaskAction& output) - { - if (input.is_string()) { - output = get_action_type(input.as_string()); - return output != ProcessTaskAction::Invalid; - } - return false; - } - - bool parse_json_as(const json::value& input, MatchMethod& output) - { - if (input.is_string()) { - output = get_match_method(input.as_string()); - return output != MatchMethod::Invalid; - } - return false; - } - - // std::pair <- [first, second] - template - requires(requires(const json::value& input, FirstT x, SecondT y) { - parse_json_as(input, x) && parse_json_as(input, y); - }) - bool parse_json_as(const json::value& input, std::pair& output) - { - if (!input.is_array()) { - return false; - } - const auto& items = input.as_array(); - if (items.size() != 2) { - return false; - } - return parse_json_as(items[0], output.first) && parse_json_as(items[1], output.second); - } - - // std::vector <- val | [val, ...] - template - requires(requires(const json::value& input, ValT x) { parse_json_as(input, x); }) - bool parse_json_as(const json::value& input, std::vector& output) - { - if (!input.is_array()) { - if constexpr (std::constructible_from) { - if (input.is()) { - output = { input.as() }; - return true; - } +// std::vector <- val | [val, ...] +template +requires(requires(const json::value& input, ValT x) { parse_json_as(input, x); }) +bool parse_json_as(const json::value& input, std::vector& output) +{ + if (!input.is_array()) { + if constexpr (std::constructible_from) { + if (input.is()) { + output = { input.as() }; + return true; } + } + return false; + } + const auto& items = input.as_array(); + output.clear(); + for (const auto& item : items) { + ValT val; + if (!parse_json_as(item, val)) { + output.clear(); return false; } - const auto& items = input.as_array(); - output.clear(); - for (const auto& item : items) { - ValT val; - if (!parse_json_as(item, val)) { - output.clear(); - return false; - } - output.emplace_back(std::move(val)); + output.emplace_back(std::move(val)); + } + return true; +} + +// asst::Rect <- [int, int, int, int] +bool parse_json_as(const json::value& input, asst::Rect& output) +{ + if (!input.is_array()) { + return false; + } + const auto& items = input.as_array(); + if (items.size() != 4) { + return false; + } + return parse_json_as(items[0], output.x) && parse_json_as(items[1], output.y) && + parse_json_as(items[2], output.width) && parse_json_as(items[3], output.height); +} + +template +requires(requires(const json::value& input, OutT& output) { parse_json_as(input, output); }) +std::optional parse_json_as(const json::value& input) +{ + OutT output; + return parse_json_as(input, output) ? output : std::nullopt; +} + +template +requires(std::constructible_from || std::constructible_from>) +bool get_value_or( + std::string_view repr, + const json::value& input, + const std::string& key, + OutT& output, + DefaultT&& default_val) +{ + auto opt = input.find(key); + if (!opt) { + if constexpr (std::constructible_from) { + output = std::forward(default_val); + } + else { + output = default_val(); } return true; } - - // asst::Rect <- [int, int, int, int] - bool parse_json_as(const json::value& input, asst::Rect& output) - { - if (!input.is_array()) { - return false; - } - const auto& items = input.as_array(); - if (items.size() != 4) { - return false; - } - return parse_json_as(items[0], output.x) && parse_json_as(items[1], output.y) && - parse_json_as(items[2], output.width) && parse_json_as(items[3], output.height); - } - - template - requires(requires(const json::value& input, OutT& output) { parse_json_as(input, output); }) - std::optional parse_json_as(const json::value& input) - { - OutT output; - return parse_json_as(input, output) ? output : std::nullopt; - } - - template - requires(std::constructible_from || std::constructible_from>) - bool get_value_or(std::string_view repr, const json::value& input, const std::string& key, OutT& output, - DefaultT&& default_val) - { - auto opt = input.find(key); - if (!opt) { + if (parse_json_as(*opt, output)) { +#ifdef ASST_DEBUG + if constexpr (CheckDefault) { + // 如果有默认值,检查是否与默认值相同 if constexpr (std::constructible_from) { - output = std::forward(default_val); + if (output == default_val) { + Log.warn("Value of", key, "in", repr, "is same as default value"); + } } else { - output = default_val(); + if (output == default_val()) { + Log.warn("Value of", key, "in", repr, "is same as default value of construct function"); + } } - return true; } - if (parse_json_as(*opt, output)) { -#ifdef ASST_DEBUG - if constexpr (CheckDefault) { - // 如果有默认值,检查是否与默认值相同 - if constexpr (std::constructible_from) { - if (output == default_val) { - Log.warn("Value of", key, "in", repr, "is same as default value"); - } - } - else { - if (output == default_val()) { - Log.warn("Value of", key, "in", repr, "is same as default value of construct function"); - } - } - } #endif - return true; - } - Log.error("Invalid type of", key, "in", repr); - return false; + return true; } + Log.error("Invalid type of", key, "in", repr); + return false; +} - template - requires(std::constructible_from || std::constructible_from>) - std::optional get_value_or(std::string_view repr, const json::value& input, const std::string& key, - DefaultT&& default_val) - { - OutT output; - return get_value_or(repr, input, key, output, std::forward(default_val)) ? output : std::nullopt; - } +template +requires(std::constructible_from || std::constructible_from>) +std::optional + get_value_or(std::string_view repr, const json::value& input, const std::string& key, DefaultT&& default_val) +{ + OutT output; + return get_value_or(repr, input, key, output, std::forward(default_val)) ? output : std::nullopt; +} - template - requires(std::constructible_from || std::constructible_from>) - bool get_and_check_value_or( - std::string_view repr, const json::value& input, const std::string& key, OutT& output, DefaultT&& default_val) - { - return get_value_or(repr, input, key, output, std::forward(default_val)); - } +template +requires(std::constructible_from || std::constructible_from>) +bool get_and_check_value_or( + std::string_view repr, + const json::value& input, + const std::string& key, + OutT& output, + DefaultT&& default_val) +{ + return get_value_or(repr, input, key, output, std::forward(default_val)); +} - template - requires(std::constructible_from || std::constructible_from>) - std::optional get_and_check_value_or( - std::string_view repr, const json::value& input, const std::string& key, DefaultT&& default_val) - { - return get_value_or(repr, input, key, std::forward(default_val)); - } +template +requires(std::constructible_from || std::constructible_from>) +std::optional get_and_check_value_or( + std::string_view repr, + const json::value& input, + const std::string& key, + DefaultT&& default_val) +{ + return get_value_or(repr, input, key, std::forward(default_val)); +} } // namespace asst::utils diff --git a/src/MaaCore/Utils/LibraryHolder.hpp b/src/MaaCore/Utils/LibraryHolder.hpp index b29cba036c..9eaa2b407e 100644 --- a/src/MaaCore/Utils/LibraryHolder.hpp +++ b/src/MaaCore/Utils/LibraryHolder.hpp @@ -13,7 +13,6 @@ #include "Utils/Logger.hpp" - namespace asst { // template for ref_count diff --git a/src/MaaCore/Utils/Locale.hpp b/src/MaaCore/Utils/Locale.hpp index 87a37d9757..49382b338a 100644 --- a/src/MaaCore/Utils/Locale.hpp +++ b/src/MaaCore/Utils/Locale.hpp @@ -11,9 +11,9 @@ #include "Meta.hpp" #ifdef _WIN32 -#include -#include #include "Platform/SafeWindows.h" +#include +#include namespace asst::utils { @@ -119,62 +119,61 @@ inline std::string load_file_without_bom(const std::filesystem::path& path) return str; } - - class utf8_scope - { +class utf8_scope +{ #ifdef _WIN32 - bool active; - int thread_mode; - std::string old_locale; + bool active; + int thread_mode; + std::string old_locale; - static bool is_console_ostream(std::ostream& ofs) - { - if (&ofs == &std::cout) { - return _isatty(_fileno(stdout)); - } - if (&ofs == &std::cerr) { - return _isatty(_fileno(stderr)); - } - return false; + static bool is_console_ostream(std::ostream& ofs) + { + if (&ofs == &std::cout) { + return _isatty(_fileno(stdout)); } + if (&ofs == &std::cerr) { + return _isatty(_fileno(stderr)); + } + return false; + } - public: - utf8_scope(std::nullptr_t) - { +public: + utf8_scope(std::nullptr_t) + { + active = false; + thread_mode = 0; + } + + ~utf8_scope() + { + if (!active) { + return; + } + if (!old_locale.empty()) { + setlocale(LC_ALL, old_locale.c_str()); + } + _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); + } + + utf8_scope(std::ostream& ofs) + { + if (is_console_ostream(ofs)) { + active = true; + thread_mode = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); + auto old_locale_ptr = setlocale(LC_ALL, ".UTF-8"); + if (old_locale_ptr) { + old_locale = old_locale_ptr; + } + } + else { active = false; - thread_mode = 0; - } - - ~utf8_scope() - { - if (!active) return; - if (!old_locale.empty()) { - setlocale(LC_ALL, old_locale.c_str()); - } - _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); - } - - utf8_scope(std::ostream& ofs) - { - if (is_console_ostream(ofs)) { - active = true; - thread_mode = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); - auto old_locale_ptr = setlocale(LC_ALL, ".UTF-8"); - if (old_locale_ptr) { - old_locale = old_locale_ptr; - } - } - else { - active = false; - } } + } #else - public: - utf8_scope(std::ostream&) - { - } +public: + utf8_scope(std::ostream&) {} #endif - }; +}; } // namespace asst::utils diff --git a/src/MaaCore/Utils/Logger.hpp b/src/MaaCore/Utils/Logger.hpp index 85306ee9e9..d0dd4e42f1 100644 --- a/src/MaaCore/Utils/Logger.hpp +++ b/src/MaaCore/Utils/Logger.hpp @@ -143,8 +143,7 @@ public: std::string push(id& i) { i = 0; - if (auto iter = - std::find_if(m_state.rbegin(), m_state.rend(), [](int e) { return e != -1; }); + if (auto iter = std::find_if(m_state.rbegin(), m_state.rend(), [](int e) { return e != -1; }); iter != m_state.rend()) { i = *iter + 1; } @@ -258,13 +257,13 @@ public: console_ostream& operator=(console_ostream&&) = default; console_ostream& operator=(const console_ostream&) = default; - console_ostream(std::ostream& stream) - : m_ofs(stream) + console_ostream(std::ostream& stream) : + m_ofs(stream) { } - console_ostream(std::reference_wrapper stream) - : m_ofs(stream) + console_ostream(std::reference_wrapper stream) : + m_ofs(stream) { } @@ -304,8 +303,8 @@ public: ostreams& operator=(ostreams&&) = default; ostreams& operator=(const ostreams&) = default; - ostreams(Args&&... args) - : m_ofss(std::forward(args)...) + ostreams(Args&&... args) : + m_ofss(std::forward(args)...) { } @@ -330,8 +329,7 @@ public: } template - static void - streams_put(Tuple& t, std::ostream& (*pf)(std::ostream&), std::index_sequence) + static void streams_put(Tuple& t, std::ostream& (*pf)(std::ostream&), std::index_sequence) { ((convert_reference_wrapper(std::get(t)) << pf), ...); } @@ -349,8 +347,8 @@ public: constexpr separator(const separator&) = default; constexpr separator(separator&&) noexcept = default; - constexpr explicit separator(std::string_view s) noexcept - : str(s) + constexpr explicit separator(std::string_view s) noexcept : + str(s) { } @@ -377,8 +375,8 @@ public: constexpr level(const level&) = default; constexpr level(level&&) noexcept = default; - constexpr explicit level(std::string_view s) noexcept - : str(s) + constexpr explicit level(std::string_view s) noexcept : + str(s) { } @@ -427,29 +425,25 @@ public: } template - LogStream(std::mutex& mtx, _stream_t&& ofs, Logger::level lv) - : m_trace_lock(mtx) - , m_ofs(ofs) + LogStream(std::mutex& mtx, _stream_t&& ofs, Logger::level lv) : + m_trace_lock(mtx), + m_ofs(ofs) { *this << lv; } template - LogStream(std::mutex& mtx, _stream_t&& ofs, Logger::level lv, Args&&... buff) - : m_trace_lock(mtx) - , m_ofs(ofs) + LogStream(std::mutex& mtx, _stream_t&& ofs, Logger::level lv, Args&&... buff) : + m_trace_lock(mtx), + m_ofs(ofs) { ((*this << lv) << ... << std::forward(buff)); } template - LogStream( - std::unique_lock&& lock, - _stream_t&& ofs, - Logger::level lv, - Args&&... buff) - : m_trace_lock(std::move(lock)) - , m_ofs(ofs) + LogStream(std::unique_lock&& lock, _stream_t&& ofs, Logger::level lv, Args&&... buff) : + m_trace_lock(std::move(lock)), + m_ofs(ofs) { ((*this << lv) << ... << std::forward(buff)); } @@ -590,11 +584,7 @@ public: } else { #ifdef ASST_DEBUG - return LogStream( - m_trace_mutex, - ostreams { console_ostream(std::cout), m_ofs }, - level::trace, - arg); + return LogStream(m_trace_mutex, ostreams { console_ostream(std::cout), m_ofs }, level::trace, arg); #else return LogStream(m_trace_mutex, m_ofs, level::trace, arg); #endif @@ -692,8 +682,8 @@ public: private: friend class SingletonHolder; - Logger() - : m_directory(UserDir.get()) + Logger() : + m_directory(UserDir.get()) { std::filesystem::create_directories(m_log_path.parent_path()); rotate(); @@ -704,8 +694,7 @@ private: { constexpr uintmax_t MaxLogSize = 4ULL * 1024 * 1024; try { - if (std::filesystem::exists(m_log_path) - && std::filesystem::is_regular_file(m_log_path)) { + if (std::filesystem::exists(m_log_path) && std::filesystem::is_regular_file(m_log_path)) { const uintmax_t log_size = std::filesystem::file_size(m_log_path); if (log_size >= MaxLogSize) { std::filesystem::rename(m_log_path, m_log_bak_path); @@ -754,9 +743,9 @@ inline Logger::level Logger::level::error("ERR"); class LoggerAux { public: - explicit LoggerAux(std::string_view func_name) - : m_func_name(func_name) - , m_start_time(std::chrono::steady_clock::now()) + explicit LoggerAux(std::string_view func_name) : + m_func_name(func_name), + m_start_time(std::chrono::steady_clock::now()) { #ifdef ASST_DEBUG m_id = Logger::get_instance().push @@ -806,8 +795,7 @@ private: #define LogTraceScope LoggerAux _CatVarNameWithLine(_func_aux_) #ifndef _MSC_VER -inline constexpr std::string_view - summarize_pretty_function(std::string_view pf) // can be consteval? +inline constexpr std::string_view summarize_pretty_function(std::string_view pf) // can be consteval? { // unable to handle something like std::function gen_func() const auto paren = pf.find_first_of('('); diff --git a/src/MaaCore/Utils/Meta.hpp b/src/MaaCore/Utils/Meta.hpp index 38e29e001e..4369fee743 100644 --- a/src/MaaCore/Utils/Meta.hpp +++ b/src/MaaCore/Utils/Meta.hpp @@ -2,8 +2,8 @@ namespace asst::utils { - template - constexpr bool always_false = false; +template +constexpr bool always_false = false; } // delete instantiation of template with message, when static_assert(false, Message) does not work diff --git a/src/MaaCore/Utils/Platform.hpp b/src/MaaCore/Utils/Platform.hpp index 45f1ee3199..61bba60177 100644 --- a/src/MaaCore/Utils/Platform.hpp +++ b/src/MaaCore/Utils/Platform.hpp @@ -4,29 +4,29 @@ namespace asst::utils { - using os_string = platform::os_string; +using os_string = platform::os_string; #ifdef _WIN32 - static_assert(std::same_as); +static_assert(std::same_as); #else - static_assert(std::same_as); +static_assert(std::same_as); #endif - using platform::from_osstring; - using platform::path; - using platform::path_to_ansi_string; - using platform::path_to_crt_string; - using platform::path_to_utf8_string; - using platform::to_osstring; +using platform::from_osstring; +using platform::path; +using platform::path_to_ansi_string; +using platform::path_to_crt_string; +using platform::path_to_utf8_string; +using platform::to_osstring; - using platform::call_command; +using platform::call_command; - namespace path_literals - { - inline std::filesystem::path operator"" _p(const char* utf8_str, size_t len) - { - // 日后再优化( - return asst::utils::path(std::string(std::string_view(utf8_str, len))); - } - } +namespace path_literals +{ +inline std::filesystem::path operator"" _p(const char* utf8_str, size_t len) +{ + // 日后再优化( + return asst::utils::path(std::string(std::string_view(utf8_str, len))); +} +} } // namespace asst::utils diff --git a/src/MaaCore/Utils/Platform/Platform.h b/src/MaaCore/Utils/Platform/Platform.h index 9268c405b7..8af2682dd8 100644 --- a/src/MaaCore/Utils/Platform/Platform.h +++ b/src/MaaCore/Utils/Platform/Platform.h @@ -16,114 +16,120 @@ namespace asst::platform { - std::string call_command(const std::string& cmdline, bool* exit_flag = nullptr); +std::string call_command(const std::string& cmdline, bool* exit_flag = nullptr); - using os_string = std::filesystem::path::string_type; +using os_string = std::filesystem::path::string_type; - inline std::filesystem::path path(const os_string& os_str) - { - return std::filesystem::path(os_str); - } +inline std::filesystem::path path(const os_string& os_str) +{ + return std::filesystem::path(os_str); +} #ifdef _WIN32 - std::string path_to_crt_string(const std::filesystem::path&); - std::string path_to_ansi_string(const std::filesystem::path&); - os_string to_osstring(const std::string& utf8_str); - std::string from_osstring(const os_string&); +std::string path_to_crt_string(const std::filesystem::path&); +std::string path_to_ansi_string(const std::filesystem::path&); +os_string to_osstring(const std::string& utf8_str); +std::string from_osstring(const os_string&); - // Allow construct a path from utf8-string in win32 - inline std::filesystem::path path(const std::string& utf8_str) - { - return std::filesystem::path(to_osstring(utf8_str)); - } +// Allow construct a path from utf8-string in win32 +inline std::filesystem::path path(const std::string& utf8_str) +{ + return std::filesystem::path(to_osstring(utf8_str)); +} - inline std::string path_to_utf8_string(const std::filesystem::path& path) - { - return from_osstring(path.native()); - } +inline std::string path_to_utf8_string(const std::filesystem::path& path) +{ + return from_osstring(path.native()); +} - inline std::string path_to_crt_string(const std::string& utf8_path) - { - return path_to_crt_string(path(utf8_path)); - } +inline std::string path_to_crt_string(const std::string& utf8_path) +{ + return path_to_crt_string(path(utf8_path)); +} - inline std::string path_to_ansi_string(const std::string& utf8_path) - { - return path_to_crt_string(path(utf8_path)); - } +inline std::string path_to_ansi_string(const std::string& utf8_path) +{ + return path_to_crt_string(path(utf8_path)); +} #else - inline os_string to_osstring(const std::string& utf8_str) - { - return utf8_str; - } +inline os_string to_osstring(const std::string& utf8_str) +{ + return utf8_str; +} - inline std::string from_osstring(const os_string& os_str) - { - return os_str; - } +inline std::string from_osstring(const os_string& os_str) +{ + return os_str; +} - inline std::string path_to_utf8_string(const std::filesystem::path& path) - { - return path.native(); - } +inline std::string path_to_utf8_string(const std::filesystem::path& path) +{ + return path.native(); +} - inline std::string path_to_ansi_string(const std::filesystem::path& path) - { - return path.native(); - } +inline std::string path_to_ansi_string(const std::filesystem::path& path) +{ + return path.native(); +} - inline std::string path_to_crt_string(const std::filesystem::path& path) - { - return path.native(); - } +inline std::string path_to_crt_string(const std::filesystem::path& path) +{ + return path.native(); +} #endif - // --------- detail ------------ +// --------- detail ------------ - extern const size_t page_size; +extern const size_t page_size; - void* aligned_alloc(size_t len, size_t align); - void aligned_free(void* ptr); +void* aligned_alloc(size_t len, size_t align); +void aligned_free(void* ptr); - template - requires std::is_trivial_v - class single_page_buffer +template +requires std::is_trivial_v +class single_page_buffer +{ + TElem* _ptr = nullptr; + +public: + single_page_buffer() { - TElem* _ptr = nullptr; - - public: - single_page_buffer() - { - _ptr = reinterpret_cast(aligned_alloc(page_size, page_size)); - if (!_ptr) throw std::bad_alloc(); + _ptr = reinterpret_cast(aligned_alloc(page_size, page_size)); + if (!_ptr) { + throw std::bad_alloc(); } + } - explicit single_page_buffer(std::nullptr_t) {} + explicit single_page_buffer(std::nullptr_t) {} - ~single_page_buffer() - { - if (_ptr) aligned_free(reinterpret_cast(_ptr)); + ~single_page_buffer() + { + if (_ptr) { + aligned_free(reinterpret_cast(_ptr)); } + } - // disable copy construct - single_page_buffer(const single_page_buffer&) = delete; - single_page_buffer& operator=(const single_page_buffer&) = delete; + // disable copy construct + single_page_buffer(const single_page_buffer&) = delete; + single_page_buffer& operator=(const single_page_buffer&) = delete; - inline single_page_buffer(single_page_buffer&& other) noexcept { std::swap(_ptr, other._ptr); } - inline single_page_buffer& operator=(single_page_buffer&& other) noexcept - { - if (_ptr) { - aligned_free(reinterpret_cast(_ptr)); - _ptr = nullptr; - } - std::swap(_ptr, other._ptr); - return *this; + inline single_page_buffer(single_page_buffer&& other) noexcept { std::swap(_ptr, other._ptr); } + + inline single_page_buffer& operator=(single_page_buffer&& other) noexcept + { + if (_ptr) { + aligned_free(reinterpret_cast(_ptr)); + _ptr = nullptr; } + std::swap(_ptr, other._ptr); + return *this; + } - inline TElem* get() const { return _ptr; } - inline size_t size() const { return _ptr ? (page_size / sizeof(TElem)) : 0; } - }; + inline TElem* get() const { return _ptr; } + + inline size_t size() const { return _ptr ? (page_size / sizeof(TElem)) : 0; } +}; } // namespace asst::platform diff --git a/src/MaaCore/Utils/Platform/PlatformWin32.cpp b/src/MaaCore/Utils/Platform/PlatformWin32.cpp index 63b4f166b7..e084cd8f55 100644 --- a/src/MaaCore/Utils/Platform/PlatformWin32.cpp +++ b/src/MaaCore/Utils/Platform/PlatformWin32.cpp @@ -47,26 +47,13 @@ bool asst::win32::CreateOverlappablePipe( if (overlapped_write) { write_flag |= FILE_FLAG_OVERLAPPED; } - auto pipe_read = CreateNamedPipeW( - pipename.c_str(), - read_flag, - PIPE_TYPE_BYTE | PIPE_WAIT, - 1, - bufsize, - bufsize, - 0, - secattr_read); + auto pipe_read = + CreateNamedPipeW(pipename.c_str(), read_flag, PIPE_TYPE_BYTE | PIPE_WAIT, 1, bufsize, bufsize, 0, secattr_read); if (pipe_read == INVALID_HANDLE_VALUE) { return false; } - auto pipe_write = CreateFileW( - pipename.c_str(), - write_flag, - 0, - secattr_write, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - nullptr); + auto pipe_write = + CreateFileW(pipename.c_str(), write_flag, 0, secattr_write, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (pipe_write == INVALID_HANDLE_VALUE) { CloseHandle(pipe_read); return false; @@ -86,8 +73,7 @@ static std::string get_ansi_short_path(const std::filesystem::path& path) return {}; } BOOL failed = FALSE; - auto ansilen = - WideCharToMultiByte(CP_ACP, 0, short_path, shortlen, nullptr, 0, nullptr, &failed); + auto ansilen = WideCharToMultiByte(CP_ACP, 0, short_path, shortlen, nullptr, 0, nullptr, &failed); if (failed) { return {}; } @@ -123,26 +109,10 @@ std::string asst::platform::path_to_ansi_string(const std::filesystem::path& pat // so we use CRT wcstombs instead of WideCharToMultiByte BOOL failed = FALSE; auto& osstr = path.native(); - auto ansilen = WideCharToMultiByte( - CP_ACP, - 0, - osstr.c_str(), - (int)osstr.size(), - nullptr, - 0, - nullptr, - &failed); + auto ansilen = WideCharToMultiByte(CP_ACP, 0, osstr.c_str(), (int)osstr.size(), nullptr, 0, nullptr, &failed); if (!failed) { std::string result(ansilen, 0); - WideCharToMultiByte( - CP_ACP, - 0, - osstr.c_str(), - (int)osstr.size(), - result.data(), - ansilen, - nullptr, - &failed); + WideCharToMultiByte(CP_ACP, 0, osstr.c_str(), (int)osstr.size(), result.data(), ansilen, nullptr, &failed); return result; } else { @@ -161,25 +131,9 @@ asst::platform::os_string asst::platform::to_osstring(const std::string& utf8_st std::string asst::platform::from_osstring(const os_string& os_str) { - int len = WideCharToMultiByte( - CP_UTF8, - 0, - os_str.c_str(), - (int)os_str.size(), - nullptr, - 0, - nullptr, - nullptr); + int len = WideCharToMultiByte(CP_UTF8, 0, os_str.c_str(), (int)os_str.size(), nullptr, 0, nullptr, nullptr); std::string result(len, 0); - WideCharToMultiByte( - CP_UTF8, - 0, - os_str.c_str(), - (int)os_str.size(), - result.data(), - len, - nullptr, - nullptr); + WideCharToMultiByte(CP_UTF8, 0, os_str.c_str(), (int)os_str.size(), result.data(), len, nullptr, nullptr); return result; } @@ -190,8 +144,7 @@ std::string asst::platform::call_command(const std::string& cmdline, bool* exit_ std::string pipe_str; HANDLE pipe_parent_read = INVALID_HANDLE_VALUE, pipe_child_write = INVALID_HANDLE_VALUE; - SECURITY_ATTRIBUTES sa_inherit { .nLength = sizeof(SECURITY_ATTRIBUTES), - .bInheritHandle = TRUE }; + SECURITY_ATTRIBUTES sa_inherit { .nLength = sizeof(SECURITY_ATTRIBUTES), .bInheritHandle = TRUE }; if (!asst::win32::CreateOverlappablePipe( &pipe_parent_read, &pipe_child_write, @@ -220,11 +173,7 @@ std::string asst::platform::call_command(const std::string& cmdline, bool* exit_ InitializeProcThreadAttributeList(nullptr, 1, 0, &attrsize); if (attrsize == 0) { DWORD err = GetLastError(); - Log.error( - "Call `", - cmdline, - "` InitializeProcThreadAttributeList failed, ret error code:", - err); + Log.error("Call `", cmdline, "` InitializeProcThreadAttributeList failed, ret error code:", err); return {}; } attrs.resize(attrsize); @@ -232,11 +181,7 @@ std::string asst::platform::call_command(const std::string& cmdline, bool* exit_ auto attr_success = InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attrsize); if (!attr_success) { DWORD err = GetLastError(); - Log.error( - "Call `", - cmdline, - "` InitializeProcThreadAttributeList failed, ret error code:", - err); + Log.error("Call `", cmdline, "` InitializeProcThreadAttributeList failed, ret error code:", err); return {}; } attr_success = UpdateProcThreadAttribute( @@ -267,13 +212,7 @@ std::string asst::platform::call_command(const std::string& cmdline, bool* exit_ DeleteProcThreadAttributeList(si.lpAttributeList); if (!create_ret) { DWORD err = GetLastError(); - Log.error( - "Call `", - cmdline, - "` create process failed, ret", - create_ret, - "error code:", - err); + Log.error("Call `", cmdline, "` create process failed, ret", create_ret, "error code:", err); return {}; } @@ -298,12 +237,8 @@ std::string asst::platform::call_command(const std::string& cmdline, bool* exit_ if (wait_handles.empty()) { break; } - auto wait_result = WaitForMultipleObjectsEx( - (DWORD)wait_handles.size(), - wait_handles.data(), - FALSE, - INFINITE, - TRUE); + auto wait_result = + WaitForMultipleObjectsEx((DWORD)wait_handles.size(), wait_handles.data(), FALSE, INFINITE, TRUE); HANDLE signaled_object = INVALID_HANDLE_VALUE; if (wait_result >= WAIT_OBJECT_0 && wait_result < WAIT_OBJECT_0 + wait_handles.size()) { signaled_object = wait_handles[(size_t)wait_result - WAIT_OBJECT_0]; @@ -403,10 +338,7 @@ HANDLE asst::win32::OpenDirectory(const std::filesystem::path& path, BOOL bReadW HANDLE hToken; TOKEN_PRIVILEGES tp; OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken); - LookupPrivilegeValueW( - NULL, - (bReadWrite ? SE_RESTORE_NAME : SE_BACKUP_NAME), - &tp.Privileges[0].Luid); + LookupPrivilegeValueW(NULL, (bReadWrite ? SE_RESTORE_NAME : SE_BACKUP_NAME), &tp.Privileges[0].Luid); tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL); @@ -426,12 +358,9 @@ HANDLE asst::win32::OpenDirectory(const std::filesystem::path& path, BOOL bReadW return hDir; } -bool asst::win32::SetDirectoryReparsePoint( - const std::filesystem::path& link, - const std::filesystem::path& target) +bool asst::win32::SetDirectoryReparsePoint(const std::filesystem::path& link, const std::filesystem::path& target) { - auto normtarget = - asst::platform::path(asst::utils::string_replace_all(target.native(), L"/", L"\\")); + auto normtarget = asst::platform::path(asst::utils::string_replace_all(target.native(), L"/", L"\\")); auto nttarget = L"\\GLOBAL??\\" + std::filesystem::absolute(normtarget).native(); if (nttarget.back() != L'\\') { diff --git a/src/MaaCore/Utils/Platform/PlatformWin32.h b/src/MaaCore/Utils/Platform/PlatformWin32.h index a77b4a3546..3f2742300b 100644 --- a/src/MaaCore/Utils/Platform/PlatformWin32.h +++ b/src/MaaCore/Utils/Platform/PlatformWin32.h @@ -7,11 +7,16 @@ namespace asst::win32 { - bool CreateOverlappablePipe(HANDLE* read, HANDLE* write, SECURITY_ATTRIBUTES* secattr_read, - SECURITY_ATTRIBUTES* secattr_write, DWORD bufsize, bool overlapped_read, - bool overlapped_write); - HANDLE OpenDirectory(const std::filesystem::path& path, BOOL bReadWrite); - bool SetDirectoryReparsePoint(const std::filesystem::path& link, const std::filesystem::path& target); +bool CreateOverlappablePipe( + HANDLE* read, + HANDLE* write, + SECURITY_ATTRIBUTES* secattr_read, + SECURITY_ATTRIBUTES* secattr_write, + DWORD bufsize, + bool overlapped_read, + bool overlapped_write); +HANDLE OpenDirectory(const std::filesystem::path& path, BOOL bReadWrite); +bool SetDirectoryReparsePoint(const std::filesystem::path& link, const std::filesystem::path& target); } #endif diff --git a/src/MaaCore/Utils/Ranges.hpp b/src/MaaCore/Utils/Ranges.hpp index 781e9796c7..1cce42155e 100644 --- a/src/MaaCore/Utils/Ranges.hpp +++ b/src/MaaCore/Utils/Ranges.hpp @@ -8,8 +8,8 @@ namespace asst { - namespace ranges = ::ranges; - namespace views = ::ranges::views; +namespace ranges = ::ranges; +namespace views = ::ranges::views; } #elif defined(ASST_USE_RANGES_STL) @@ -18,8 +18,8 @@ namespace asst namespace asst { - namespace ranges = std::ranges; - namespace views = std::views; +namespace ranges = std::ranges; +namespace views = std::views; } #elif defined(ASST_USE_RANGES_BOOST) @@ -31,8 +31,8 @@ namespace asst namespace asst { - namespace ranges = boost::range; - namespace views = boost::adaptors; +namespace ranges = boost::range; +namespace views = boost::adaptors; } #else diff --git a/src/MaaCore/Utils/SingletonHolder.hpp b/src/MaaCore/Utils/SingletonHolder.hpp index 77ccb0db45..c0a7cde567 100644 --- a/src/MaaCore/Utils/SingletonHolder.hpp +++ b/src/MaaCore/Utils/SingletonHolder.hpp @@ -4,28 +4,29 @@ namespace asst { - template - class SingletonHolder +template +class SingletonHolder +{ +public: + static T& get_instance() { - public: - static T& get_instance() - { - static T unique_instance; - return unique_instance; - } - virtual ~SingletonHolder() = default; + static T unique_instance; + return unique_instance; + } - public: - SingletonHolder(const SingletonHolder&) = delete; - SingletonHolder(SingletonHolder&&) = delete; + virtual ~SingletonHolder() = default; - SingletonHolder& operator=(const SingletonHolder&) = delete; - SingletonHolder& operator=(SingletonHolder&&) = delete; +public: + SingletonHolder(const SingletonHolder&) = delete; + SingletonHolder(SingletonHolder&&) = delete; - protected: - SingletonHolder() = default; - }; + SingletonHolder& operator=(const SingletonHolder&) = delete; + SingletonHolder& operator=(SingletonHolder&&) = delete; - template - concept Singleton = std::is_base_of_v, T>; +protected: + SingletonHolder() = default; +}; + +template +concept Singleton = std::is_base_of_v, T>; } diff --git a/src/MaaCore/Utils/StringMisc.hpp b/src/MaaCore/Utils/StringMisc.hpp index 422af3dda5..579a575a51 100644 --- a/src/MaaCore/Utils/StringMisc.hpp +++ b/src/MaaCore/Utils/StringMisc.hpp @@ -17,136 +17,141 @@ namespace asst::utils { - namespace detail - { - template - using sv_type = std::basic_string_view::value_type, - typename std::remove_reference_t::traits_type>; +namespace detail +{ +template +using sv_type = std::basic_string_view< + typename std::remove_reference_t::value_type, + typename std::remove_reference_t::traits_type>; - template - using sv_pair = std::pair, sv_type>; - } // namespace detail +template +using sv_pair = std::pair, sv_type>; +} // namespace detail - template > - concept IsSomeKindOfString = std::same_as || std::same_as; +template > +concept IsSomeKindOfString = std::same_as || std::same_as; - template - inline constexpr void string_replace_all_in_place(StringT& str, detail::sv_type from, - detail::sv_type to) - { - for (size_t pos(0);; pos += to.length()) { - if ((pos = str.find(from, pos)) == StringT::npos) return; - str.replace(pos, from.length(), to); +template +inline constexpr void + string_replace_all_in_place(StringT& str, detail::sv_type from, detail::sv_type to) +{ + for (size_t pos(0);; pos += to.length()) { + if ((pos = str.find(from, pos)) == StringT::npos) { + return; } + str.replace(pos, from.length(), to); } +} - template - inline constexpr void string_replace_all_in_place(StringT& str, const detail::sv_pair& replace_pair) - { - string_replace_all_in_place(str, replace_pair.first, replace_pair.second); - } +template +inline constexpr void string_replace_all_in_place(StringT& str, const detail::sv_pair& replace_pair) +{ + string_replace_all_in_place(str, replace_pair.first, replace_pair.second); +} - template - inline constexpr void string_replace_all_in_place(StringT& str, - std::initializer_list> replace_pairs) - { - for (auto&& [from, to] : replace_pairs) { - string_replace_all_in_place(str, from, to); - } +template +inline constexpr void + string_replace_all_in_place(StringT& str, std::initializer_list> replace_pairs) +{ + for (auto&& [from, to] : replace_pairs) { + string_replace_all_in_place(str, from, to); } +} #ifdef ASST_USE_RANGES_RANGE_V3 - // workaround for P2210R2 - template - requires(requires(Rng rng) { std::basic_string_view(std::addressof(*rng.begin()), ranges::distance(rng)); }) - inline auto make_string_view(Rng&& rng) - { - return std::basic_string_view(std::addressof(*rng.begin()), ranges::distance(rng)); - } +// workaround for P2210R2 +template +requires(requires(Rng rng) { std::basic_string_view(std::addressof(*rng.begin()), ranges::distance(rng)); }) +inline auto make_string_view(Rng&& rng) +{ + return std::basic_string_view(std::addressof(*rng.begin()), ranges::distance(rng)); +} - template End> - requires(requires(It beg, End end) { std::basic_string_view(std::addressof(*beg), std::distance(beg, end)); }) - inline auto make_string_view(It beg, End end) - { - return std::basic_string_view(std::addressof(*beg), std::distance(beg, end)); - } +template End> +requires(requires(It beg, End end) { std::basic_string_view(std::addressof(*beg), std::distance(beg, end)); }) +inline auto make_string_view(It beg, End end) +{ + return std::basic_string_view(std::addressof(*beg), std::distance(beg, end)); +} #else - inline auto make_string_view(ranges::contiguous_range auto&& rng) - { - return std::basic_string_view(rng.begin(), rng.end()); - } +inline auto make_string_view(ranges::contiguous_range auto&& rng) +{ + return std::basic_string_view(rng.begin(), rng.end()); +} - template End> - requires(requires(It beg, End end) { std::basic_string_view(beg, end); }) - inline auto make_string_view(It beg, End end) - { - return std::basic_string_view(beg, end); - } +template End> +requires(requires(It beg, End end) { std::basic_string_view(beg, end); }) +inline auto make_string_view(It beg, End end) +{ + return std::basic_string_view(beg, end); +} #endif - template - [[nodiscard]] inline constexpr auto string_replace_all(StringT&& src, detail::sv_type from, - detail::sv_type to) - { - std::decay_t result = std::forward(src); +template +[[nodiscard]] inline constexpr auto + string_replace_all(StringT&& src, detail::sv_type from, detail::sv_type to) +{ + std::decay_t result = std::forward(src); + string_replace_all_in_place(result, from, to); + return result; +} + +template +[[nodiscard]] inline constexpr auto string_replace_all(StringT&& src, const detail::sv_pair& replace_pair) +{ + std::decay_t result = std::forward(src); + string_replace_all_in_place(result, replace_pair); + return result; +} + +template +[[nodiscard]] inline constexpr auto + string_replace_all(StringT&& str, std::initializer_list> replace_pairs) +{ + std::decay_t result = std::forward(str); + for (auto&& [from, to] : replace_pairs) { string_replace_all_in_place(result, from, to); - return result; } + return result; +} - template - [[nodiscard]] inline constexpr auto string_replace_all(StringT&& src, const detail::sv_pair& replace_pair) - { - std::decay_t result = std::forward(src); - string_replace_all_in_place(result, replace_pair); - return result; +template < + IsSomeKindOfString StringT, + typename CharT = ranges::range_value_t, + typename Pred = decltype([](CharT c) -> bool { return c != ' '; })> +inline void string_trim(StringT& str, Pred not_space = Pred {}) +{ + str.erase(ranges::find_if(str | views::reverse, not_space).base(), str.end()); + str.erase(str.begin(), ranges::find_if(str, not_space)); +} + +inline void tolowers(IsSomeKindOfString auto& str) +{ + using CharT = ranges::range_value_t; + ranges::for_each(str, [](CharT& ch) -> void { ch = static_cast(std::tolower(ch)); }); +} + +inline void touppers(IsSomeKindOfString auto& str) +{ + using CharT = ranges::range_value_t; + ranges::for_each(str, [](CharT& ch) -> void { ch = static_cast(std::toupper(ch)); }); +} + +template +requires(std::is_arithmetic_v) +inline bool chars_to_number(std::string_view integer, NumberT& result) noexcept +{ + const char* first = integer.data(); + const char* last = first + integer.size(); + auto&& [p, ec] = std::from_chars(first, last, result); + if (ec != std::errc {}) { + return false; } - - template - [[nodiscard]] inline constexpr auto string_replace_all( - StringT&& str, std::initializer_list> replace_pairs) - { - std::decay_t result = std::forward(str); - for (auto&& [from, to] : replace_pairs) { - string_replace_all_in_place(result, from, to); - } - return result; - } - - template , - typename Pred = decltype([](CharT c) -> bool { return c != ' '; })> - inline void string_trim(StringT& str, Pred not_space = Pred {}) - { - str.erase(ranges::find_if(str | views::reverse, not_space).base(), str.end()); - str.erase(str.begin(), ranges::find_if(str, not_space)); - } - - inline void tolowers(IsSomeKindOfString auto& str) - { - using CharT = ranges::range_value_t; - ranges::for_each(str, [](CharT& ch) -> void { ch = static_cast(std::tolower(ch)); }); - } - - inline void touppers(IsSomeKindOfString auto& str) - { - using CharT = ranges::range_value_t; - ranges::for_each(str, [](CharT& ch) -> void { ch = static_cast(std::toupper(ch)); }); - } - - template - requires(std::is_arithmetic_v) - inline bool chars_to_number(std::string_view integer, NumberT& result) noexcept - { - const char* first = integer.data(); - const char* last = first + integer.size(); - auto&& [p, ec] = std::from_chars(first, last, result); - if (ec != std::errc {}) { + if constexpr (FullMatch) { + if (p != last) { return false; } - if constexpr (FullMatch) { - if (p != last) { - return false; - } - } - return true; } + return true; +} } // namespace asst::utils diff --git a/src/MaaCore/Utils/Time.hpp b/src/MaaCore/Utils/Time.hpp index 46a1690b1a..2b900db0a0 100644 --- a/src/MaaCore/Utils/Time.hpp +++ b/src/MaaCore/Utils/Time.hpp @@ -15,35 +15,44 @@ namespace asst::utils { - inline std::string get_format_time() - { - char buff[128] = { 0 }; +inline std::string get_format_time() +{ + char buff[128] = { 0 }; #ifdef _WIN32 - SYSTEMTIME curtime; - GetLocalTime(&curtime); + SYSTEMTIME curtime; + GetLocalTime(&curtime); #ifdef _MSC_VER - sprintf_s(buff, sizeof(buff), + sprintf_s( + buff, + sizeof(buff), #else // ! _MSC_VER - sprintf(buff, + sprintf( + buff, #endif // END _MSC_VER - "%04d-%02d-%02d %02d:%02d:%02d.%03d", curtime.wYear, curtime.wMonth, curtime.wDay, curtime.wHour, - curtime.wMinute, curtime.wSecond, curtime.wMilliseconds); + "%04d-%02d-%02d %02d:%02d:%02d.%03d", + curtime.wYear, + curtime.wMonth, + curtime.wDay, + curtime.wHour, + curtime.wMinute, + curtime.wSecond, + curtime.wMilliseconds); #else // ! _WIN32 - struct timeval tv = {}; - gettimeofday(&tv, nullptr); - time_t nowtime = tv.tv_sec; - struct tm* tm_info = localtime(&nowtime); - auto offset = strftime(buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", tm_info); - sprintf(buff + offset, ".%03ld", static_cast(tv.tv_usec / 1000)); + struct timeval tv = {}; + gettimeofday(&tv, nullptr); + time_t nowtime = tv.tv_sec; + struct tm* tm_info = localtime(&nowtime); + auto offset = strftime(buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", tm_info); + sprintf(buff + offset, ".%03ld", static_cast(tv.tv_usec / 1000)); #endif // END _WIN32 - return buff; - } + return buff; +} - inline std::string get_time_filestem() - { - std::string stem = utils::get_format_time(); - string_replace_all_in_place(stem, { { ":", "-" }, { " ", "_" }, { ".", "-" } }); - return stem; - } +inline std::string get_time_filestem() +{ + std::string stem = utils::get_format_time(); + string_replace_all_in_place(stem, { { ":", "-" }, { " ", "_" }, { ".", "-" } }); + return stem; +} } // namespace asst::utils diff --git a/src/MaaCore/Utils/WorkingDir.hpp b/src/MaaCore/Utils/WorkingDir.hpp index ee01902afd..6cab023831 100644 --- a/src/MaaCore/Utils/WorkingDir.hpp +++ b/src/MaaCore/Utils/WorkingDir.hpp @@ -5,31 +5,33 @@ namespace asst { - enum class WorkingDirType - { - Res, - User, - }; +enum class WorkingDirType +{ + Res, + User, +}; - template - class WorkingDir : public SingletonHolder> +template +class WorkingDir : public SingletonHolder> +{ +public: + bool empty() const noexcept { return dir_.empty(); } + + const std::filesystem::path& get() const noexcept { return dir_; } + + bool set(std::filesystem::path dir) { - public: - bool empty() const noexcept { return dir_.empty(); } - const std::filesystem::path& get() const noexcept { return dir_; } - bool set(std::filesystem::path dir) - { - if (!std::filesystem::exists(dir) || !std::filesystem::is_directory(dir)) { - return false; - } - dir_ = std::move(dir); - return true; + if (!std::filesystem::exists(dir) || !std::filesystem::is_directory(dir)) { + return false; } + dir_ = std::move(dir); + return true; + } - private: - std::filesystem::path dir_; - }; +private: + std::filesystem::path dir_; +}; - static auto& ResDir = WorkingDir::get_instance(); - static auto& UserDir = WorkingDir::get_instance(); +static auto& ResDir = WorkingDir::get_instance(); +static auto& UserDir = WorkingDir::get_instance(); } // namespace asst diff --git a/src/MaaCore/Vision/Battle/BattleFormationAnalyzer.cpp b/src/MaaCore/Vision/Battle/BattleFormationAnalyzer.cpp index 08090c47ad..8e01fb0b5e 100644 --- a/src/MaaCore/Vision/Battle/BattleFormationAnalyzer.cpp +++ b/src/MaaCore/Vision/Battle/BattleFormationAnalyzer.cpp @@ -48,8 +48,8 @@ BattleFormationAnalyzer::ResultsVecOpt BattleFormationAnalyzer::analyze() const return results; } -BattleFormationAnalyzer::ResultsVec BattleFormationAnalyzer::proc_ocr_result( - const TemplDetOCRer::ResultsVec& ocr_result) const +BattleFormationAnalyzer::ResultsVec + BattleFormationAnalyzer::proc_ocr_result(const TemplDetOCRer::ResultsVec& ocr_result) const { ResultsVec results; @@ -67,8 +67,14 @@ BattleFormationAnalyzer::ResultsVec BattleFormationAnalyzer::proc_ocr_result( #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(name_res.rect), cv::Scalar(0, 255, 0), 2); cv::rectangle(m_image_draw, make_rect(avatar_rect), cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw, BattleData.get_id(name), cv::Point(avatar_rect.x, avatar_rect.y - 20), 1, 1.2, - cv::Scalar(0, 0, 255), 2); + cv::putText( + m_image_draw, + BattleData.get_id(name), + cv::Point(avatar_rect.x, avatar_rect.y - 20), + 1, + 1.2, + cv::Scalar(0, 0, 255), + 2); #endif } diff --git a/src/MaaCore/Vision/Battle/BattleFormationAnalyzer.h b/src/MaaCore/Vision/Battle/BattleFormationAnalyzer.h index 21a72fb267..8a9d505048 100644 --- a/src/MaaCore/Vision/Battle/BattleFormationAnalyzer.h +++ b/src/MaaCore/Vision/Battle/BattleFormationAnalyzer.h @@ -5,27 +5,29 @@ namespace asst { - class BattleFormationAnalyzer : public VisionHelper +class BattleFormationAnalyzer : public VisionHelper +{ +public: + struct Result { - public: - struct Result - { - std::string to_string() const { return name; } - explicit operator std::string() const { return to_string(); } + std::string to_string() const { return name; } - std::string name; - cv::Mat avatar; - }; - using ResultsVec = std::vector; - using ResultsVecOpt = std::optional; + explicit operator std::string() const { return to_string(); } - public: - using VisionHelper::VisionHelper; - virtual ~BattleFormationAnalyzer() override = default; - - ResultsVecOpt analyze() const; - - protected: - ResultsVec proc_ocr_result(const TemplDetOCRer::ResultsVec& ocr_result) const; + std::string name; + cv::Mat avatar; }; + + using ResultsVec = std::vector; + using ResultsVecOpt = std::optional; + +public: + using VisionHelper::VisionHelper; + virtual ~BattleFormationAnalyzer() override = default; + + ResultsVecOpt analyze() const; + +protected: + ResultsVec proc_ocr_result(const TemplDetOCRer::ResultsVec& ocr_result) const; +}; } diff --git a/src/MaaCore/Vision/Battle/BattlefieldClassifier.cpp b/src/MaaCore/Vision/Battle/BattlefieldClassifier.cpp index b5634ea716..caf592baa6 100644 --- a/src/MaaCore/Vision/Battle/BattlefieldClassifier.cpp +++ b/src/MaaCore/Vision/Battle/BattlefieldClassifier.cpp @@ -86,7 +86,7 @@ BattlefieldClassifier::SkillReadyResult BattlefieldClassifier::skill_ready_analy 1, 1.2, cv::Scalar(0, 165, 255), - 2); + 2); } #endif diff --git a/src/MaaCore/Vision/Battle/BattlefieldClassifier.h b/src/MaaCore/Vision/Battle/BattlefieldClassifier.h index e722d2c797..b8c6474e33 100644 --- a/src/MaaCore/Vision/Battle/BattlefieldClassifier.h +++ b/src/MaaCore/Vision/Battle/BattlefieldClassifier.h @@ -6,70 +6,71 @@ namespace asst { - class BattlefieldClassifier final : public VisionHelper, public OnnxHelper +class BattlefieldClassifier final : public VisionHelper, public OnnxHelper +{ +public: + struct ObjectOfInterest { - public: - struct ObjectOfInterest - { - bool skill_ready = false; - bool deploy_direction = false; - }; - - public: - struct SkillReadyResult - { - static constexpr size_t ClsSize = 2; - using Raw = std::array; - using Prob = Raw; - - bool ready = false; - Rect rect; - float score = .0f; - Raw raw; - Prob prob; // after softmax - - Point base_point; - }; - - struct DeployDirectionResult - { - static constexpr size_t ClsSize = 4; - using Raw = std::array; - using Prob = Raw; - - battle::DeployDirection direction = battle::DeployDirection::None; - Rect rect; - float score = .0f; - Raw raw; - Prob prob; // after softmax - - Point base_point; - }; - - struct Result - { - ObjectOfInterest object_of_interest; - - SkillReadyResult skill_ready; - DeployDirectionResult deploy_direction; - }; - - using ResultOpt = std::optional; - - public: - using VisionHelper::VisionHelper; - virtual ~BattlefieldClassifier() override = default; - - void set_object_of_interest(ObjectOfInterest obj) { m_object_of_interest = obj; } - void set_base_point(const Point& pt) { m_base_point = pt; } - - ResultOpt analyze() const; - - protected: - SkillReadyResult skill_ready_analyze() const; - DeployDirectionResult deploy_direction_analyze() const; - - ObjectOfInterest m_object_of_interest; // 待识别的目标 - Point m_base_point; + bool skill_ready = false; + bool deploy_direction = false; }; + +public: + struct SkillReadyResult + { + static constexpr size_t ClsSize = 2; + using Raw = std::array; + using Prob = Raw; + + bool ready = false; + Rect rect; + float score = .0f; + Raw raw; + Prob prob; // after softmax + + Point base_point; + }; + + struct DeployDirectionResult + { + static constexpr size_t ClsSize = 4; + using Raw = std::array; + using Prob = Raw; + + battle::DeployDirection direction = battle::DeployDirection::None; + Rect rect; + float score = .0f; + Raw raw; + Prob prob; // after softmax + + Point base_point; + }; + + struct Result + { + ObjectOfInterest object_of_interest; + + SkillReadyResult skill_ready; + DeployDirectionResult deploy_direction; + }; + + using ResultOpt = std::optional; + +public: + using VisionHelper::VisionHelper; + virtual ~BattlefieldClassifier() override = default; + + void set_object_of_interest(ObjectOfInterest obj) { m_object_of_interest = obj; } + + void set_base_point(const Point& pt) { m_base_point = pt; } + + ResultOpt analyze() const; + +protected: + SkillReadyResult skill_ready_analyze() const; + DeployDirectionResult deploy_direction_analyze() const; + + ObjectOfInterest m_object_of_interest; // 待识别的目标 + Point m_base_point; +}; } // namespace asst diff --git a/src/MaaCore/Vision/Battle/BattlefieldDetector.cpp b/src/MaaCore/Vision/Battle/BattlefieldDetector.cpp index b414087ff7..65b5057fe5 100644 --- a/src/MaaCore/Vision/Battle/BattlefieldDetector.cpp +++ b/src/MaaCore/Vision/Battle/BattlefieldDetector.cpp @@ -45,8 +45,12 @@ std::vector BattlefieldDetector::operator_a constexpr int64_t batch_size = 1; std::array input_shape { batch_size, image.channels(), image.cols, image.rows }; - Ort::Value input_tensor = Ort::Value::CreateTensor(memory_info, input.data(), input.size(), - input_shape.data(), input_shape.size()); + Ort::Value input_tensor = Ort::Value::CreateTensor( + memory_info, + input.data(), + input.size(), + input_shape.data(), + input_shape.size()); auto& session = OnnxSessions::get_instance().get("operators_det"); @@ -57,8 +61,13 @@ std::vector BattlefieldDetector::operator_a std::vector output_names = { output_name.c_str() }; Ort::RunOptions run_options; - auto output_tensors = session.Run(run_options, input_names.data(), &input_tensor, input_names.size(), - output_names.data(), output_names.size()); + auto output_tensors = session.Run( + run_options, + input_names.data(), + &input_tensor, + input_names.size(), + output_names.data(), + output_names.size()); const float* raw_output = output_tensors[0].GetTensorData(); // output_shape is { 1, 5, 8400 } @@ -114,8 +123,14 @@ std::vector BattlefieldDetector::operator_a draw_rect.y += draw_offset_y; draw_rect.height += draw_offset_h; cv::rectangle(m_image_draw, make_rect(draw_rect), cv::Scalar(0, 0, 255), 5); - cv::putText(m_image_draw, std::to_string(box.score), cv::Point(draw_rect.x, draw_rect.y - 10), - cv::FONT_HERSHEY_PLAIN, 1.2, cv::Scalar(0, 0, 255), 2); + cv::putText( + m_image_draw, + std::to_string(box.score), + cv::Point(draw_rect.x, draw_rect.y - 10), + cv::FONT_HERSHEY_PLAIN, + 1.2, + cv::Scalar(0, 0, 255), + 2); } #endif diff --git a/src/MaaCore/Vision/Battle/BattlefieldDetector.h b/src/MaaCore/Vision/Battle/BattlefieldDetector.h index b4effee310..6b798d1a80 100644 --- a/src/MaaCore/Vision/Battle/BattlefieldDetector.h +++ b/src/MaaCore/Vision/Battle/BattlefieldDetector.h @@ -4,48 +4,48 @@ namespace asst { - class BattlefieldDetector final : public VisionHelper, public OnnxHelper +class BattlefieldDetector final : public VisionHelper, public OnnxHelper +{ +public: + struct ObjectOfInterest { - public: - struct ObjectOfInterest - { - bool operators = false; - }; - - public: - // 战斗中干员(血条)检测,yolov8 模型 - struct OperatorResult - { - enum class Cls - { - Operator = 0, - }; - - Cls cls = Cls::Operator; - Rect rect; - float score = .0f; - }; - - struct Result - { - ObjectOfInterest object_of_interest; - - std::vector operators; - }; - - using ResultOpt = std::optional; - - public: - using VisionHelper::VisionHelper; - virtual ~BattlefieldDetector() override = default; - - void set_object_of_interest(ObjectOfInterest obj) { m_object_of_interest = obj; } - - ResultOpt analyze() const; - - protected: - std::vector operator_analyze() const; - - ObjectOfInterest m_object_of_interest; + bool operators = false; }; + +public: + // 战斗中干员(血条)检测,yolov8 模型 + struct OperatorResult + { + enum class Cls + { + Operator = 0, + }; + + Cls cls = Cls::Operator; + Rect rect; + float score = .0f; + }; + + struct Result + { + ObjectOfInterest object_of_interest; + + std::vector operators; + }; + + using ResultOpt = std::optional; + +public: + using VisionHelper::VisionHelper; + virtual ~BattlefieldDetector() override = default; + + void set_object_of_interest(ObjectOfInterest obj) { m_object_of_interest = obj; } + + ResultOpt analyze() const; + +protected: + std::vector operator_analyze() const; + + ObjectOfInterest m_object_of_interest; +}; } diff --git a/src/MaaCore/Vision/Battle/BattlefieldMatcher.cpp b/src/MaaCore/Vision/Battle/BattlefieldMatcher.cpp index 0b29db08d3..d248297102 100644 --- a/src/MaaCore/Vision/Battle/BattlefieldMatcher.cpp +++ b/src/MaaCore/Vision/Battle/BattlefieldMatcher.cpp @@ -131,8 +131,13 @@ std::vector BattlefieldMatcher::deployment_analyze() con #ifdef ASST_DEBUG if (oper.cooling) { - cv::putText(m_image_draw, "cooling", cv::Point(oper.rect.x, oper.rect.y - 20), 1, 1.2, - cv::Scalar(0, 0, 255)); + cv::putText( + m_image_draw, + "cooling", + cv::Point(oper.rect.x, oper.rect.y - 20), + 1, + 1.2, + cv::Scalar(0, 0, 255)); } #endif @@ -360,9 +365,14 @@ bool BattlefieldMatcher::pause_button_analyze() const #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(task_ptr->roi), cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw, std::to_string(count) + "/" + std::to_string(count_threshold), - cv::Point(task_ptr->roi.x, task_ptr->roi.y + task_ptr->roi.height + 10), cv::FONT_HERSHEY_PLAIN, 1.2, - cv::Scalar(255, 255, 255), 2); + cv::putText( + m_image_draw, + std::to_string(count) + "/" + std::to_string(count_threshold), + cv::Point(task_ptr->roi.x, task_ptr->roi.y + task_ptr->roi.height + 10), + cv::FONT_HERSHEY_PLAIN, + 1.2, + cv::Scalar(255, 255, 255), + 2); #endif return count > count_threshold; @@ -410,9 +420,14 @@ bool asst::BattlefieldMatcher::speed_button_analyze() const #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(task_ptr->roi), cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw, std::to_string(count) + "/" + std::to_string(count_threshold), - cv::Point(task_ptr->roi.x, task_ptr->roi.y + task_ptr->roi.height + 20), cv::FONT_HERSHEY_PLAIN, 1.2, - cv::Scalar(255, 255, 255), 2); + cv::putText( + m_image_draw, + std::to_string(count) + "/" + std::to_string(count_threshold), + cv::Point(task_ptr->roi.x, task_ptr->roi.y + task_ptr->roi.height + 20), + cv::FONT_HERSHEY_PLAIN, + 1.2, + cv::Scalar(255, 255, 255), + 2); #endif return count > count_threshold; diff --git a/src/MaaCore/Vision/Battle/BattlefieldMatcher.h b/src/MaaCore/Vision/Battle/BattlefieldMatcher.h index 2082fdf1d6..3e22388921 100644 --- a/src/MaaCore/Vision/Battle/BattlefieldMatcher.h +++ b/src/MaaCore/Vision/Battle/BattlefieldMatcher.h @@ -5,63 +5,63 @@ namespace asst { - class BattlefieldMatcher : public VisionHelper +class BattlefieldMatcher : public VisionHelper +{ +public: + struct ObjectOfInterest { - public: - struct ObjectOfInterest - { - bool flag = true; - bool deployment = false; - bool kills = false; - bool costs = false; - // bool in_detail = false; - bool speed_button = false; - bool oper_cost = false; - }; - - struct Result - { - ObjectOfInterest object_of_interest; - - std::vector deployment; - // kills / total_kills - std::optional> kills; - std::optional costs; - - // bool in_detail = false; - bool speed_button = false; - bool pause_button = false; - }; - - using ResultOpt = std::optional; - - public: - using VisionHelper::VisionHelper; - virtual ~BattlefieldMatcher() override = default; - - void set_object_of_interest(ObjectOfInterest obj); - void set_total_kills_prompt(int prompt); - - ResultOpt analyze() const; - - protected: - bool hp_flag_analyze() const; - bool kills_flag_analyze() const; - bool pause_button_analyze() const; - - std::vector deployment_analyze() const; // 识别干员 - battle::Role oper_role_analyze(const Rect& roi) const; - bool oper_cooling_analyze(const Rect& roi) const; - int oper_cost_analyze(const Rect& roi) const; - bool oper_available_analyze(const Rect& roi) const; - - std::optional> kills_analyze() const; // 识别击杀数 - bool cost_symbol_analyze() const; // 识别费用左侧图标 - std::optional costs_analyze() const; // 识别费用 - bool in_detail_analyze() const; // 识别是否在详情页 - bool speed_button_analyze() const; // 识别是否有加速按钮(在详情页就没有) - - ObjectOfInterest m_object_of_interest; // 待识别的目标 - int m_total_kills_prompt = 0; // 之前的击杀总数,因为击杀数经常识别不准所以依赖外部传入作为参考 + bool flag = true; + bool deployment = false; + bool kills = false; + bool costs = false; + // bool in_detail = false; + bool speed_button = false; + bool oper_cost = false; }; + + struct Result + { + ObjectOfInterest object_of_interest; + + std::vector deployment; + // kills / total_kills + std::optional> kills; + std::optional costs; + + // bool in_detail = false; + bool speed_button = false; + bool pause_button = false; + }; + + using ResultOpt = std::optional; + +public: + using VisionHelper::VisionHelper; + virtual ~BattlefieldMatcher() override = default; + + void set_object_of_interest(ObjectOfInterest obj); + void set_total_kills_prompt(int prompt); + + ResultOpt analyze() const; + +protected: + bool hp_flag_analyze() const; + bool kills_flag_analyze() const; + bool pause_button_analyze() const; + + std::vector deployment_analyze() const; // 识别干员 + battle::Role oper_role_analyze(const Rect& roi) const; + bool oper_cooling_analyze(const Rect& roi) const; + int oper_cost_analyze(const Rect& roi) const; + bool oper_available_analyze(const Rect& roi) const; + + std::optional> kills_analyze() const; // 识别击杀数 + bool cost_symbol_analyze() const; // 识别费用左侧图标 + std::optional costs_analyze() const; // 识别费用 + bool in_detail_analyze() const; // 识别是否在详情页 + bool speed_button_analyze() const; // 识别是否有加速按钮(在详情页就没有) + + ObjectOfInterest m_object_of_interest; // 待识别的目标 + int m_total_kills_prompt = 0; // 之前的击杀总数,因为击杀数经常识别不准所以依赖外部传入作为参考 +}; } // namespace asst diff --git a/src/MaaCore/Vision/BestMatcher.h b/src/MaaCore/Vision/BestMatcher.h index ef7f52c339..10665b5051 100644 --- a/src/MaaCore/Vision/BestMatcher.h +++ b/src/MaaCore/Vision/BestMatcher.h @@ -5,48 +5,47 @@ namespace asst { - class BestMatcher : public VisionHelper, public MatcherConfig +class BestMatcher : public VisionHelper, public MatcherConfig +{ +public: + struct TemplInfo { - public: - struct TemplInfo - { - std::string name; - cv::Mat templ; - }; - - struct Result - { - std::string to_string() const - { - return "{ name: " + templ_info.name + ", matched: " + rect.to_string() + " }"; - } - explicit operator std::string() const { return to_string(); } - - Rect rect; - double score = 0.0; - TemplInfo templ_info; - }; - - using ResultOpt = std::optional; - - public: - using VisionHelper::VisionHelper; - virtual ~BestMatcher() override = default; - - void append_templ(std::string name, const cv::Mat& templ = cv::Mat()); - - ResultOpt analyze() const; - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - const auto& get_result() const { return m_result; } - - protected: - virtual void _set_roi(const Rect& roi) override { set_roi(roi); } - - private: - using MatcherConfig::set_templ; - - std::vector m_templs; - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - mutable Result m_result; + std::string name; + cv::Mat templ; }; + + struct Result + { + std::string to_string() const { return "{ name: " + templ_info.name + ", matched: " + rect.to_string() + " }"; } + + explicit operator std::string() const { return to_string(); } + + Rect rect; + double score = 0.0; + TemplInfo templ_info; + }; + + using ResultOpt = std::optional; + +public: + using VisionHelper::VisionHelper; + virtual ~BestMatcher() override = default; + + void append_templ(std::string name, const cv::Mat& templ = cv::Mat()); + + ResultOpt analyze() const; + + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + const auto& get_result() const { return m_result; } + +protected: + virtual void _set_roi(const Rect& roi) override { set_roi(roi); } + +private: + using MatcherConfig::set_templ; + + std::vector m_templs; + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + mutable Result m_result; +}; } diff --git a/src/MaaCore/Vision/Config/MatcherConfig.h b/src/MaaCore/Vision/Config/MatcherConfig.h index 050d817e91..cc4103ea16 100644 --- a/src/MaaCore/Vision/Config/MatcherConfig.h +++ b/src/MaaCore/Vision/Config/MatcherConfig.h @@ -7,45 +7,45 @@ namespace asst { - class MatcherConfig +class MatcherConfig +{ +public: + struct Params { - public: - struct Params - { - std::vector> templs; - std::vector templ_thres; - std::vector methods; // 匹配方法 - MatchTaskInfo::Ranges mask_ranges; // 匹配时的颜色掩码范围 - bool mask_src = false; // 匹配时是否使用原图掩码(默认使用模板掩码) - bool mask_close = false; // 匹配时是否使用闭运算处理 - MatchTaskInfo::Ranges color_scales; // 数色时的颜色掩码范围 - bool color_close = true; // 数色时是否使用闭运算处理 - }; - - public: - MatcherConfig() = default; - virtual ~MatcherConfig() = default; - - void set_params(Params params); - - void set_task_info(const std::shared_ptr& task_ptr); - void set_task_info(const std::string& task_name); - - void set_templ(std::variant templ); - // void set_templ(std::vector> templs); - void set_threshold(double templ_thres) noexcept; - void set_threshold(std::vector templ_thres) noexcept; - void set_mask_range(int lower, int upper, bool mask_src = false, bool mask_close = false); - void set_mask_ranges(MatchTaskInfo::Ranges mask_ranges, bool mask_src = false, bool mask_close = false); - void set_color_scales(MatchTaskInfo::Ranges color_scales, bool color_close = true); - void set_method(MatchMethod method) noexcept; - - protected: - virtual void _set_roi(const Rect& roi) = 0; - - void _set_task_info(MatchTaskInfo task_info); - - protected: - Params m_params; + std::vector> templs; + std::vector templ_thres; + std::vector methods; // 匹配方法 + MatchTaskInfo::Ranges mask_ranges; // 匹配时的颜色掩码范围 + bool mask_src = false; // 匹配时是否使用原图掩码(默认使用模板掩码) + bool mask_close = false; // 匹配时是否使用闭运算处理 + MatchTaskInfo::Ranges color_scales; // 数色时的颜色掩码范围 + bool color_close = true; // 数色时是否使用闭运算处理 }; + +public: + MatcherConfig() = default; + virtual ~MatcherConfig() = default; + + void set_params(Params params); + + void set_task_info(const std::shared_ptr& task_ptr); + void set_task_info(const std::string& task_name); + + void set_templ(std::variant templ); + // void set_templ(std::vector> templs); + void set_threshold(double templ_thres) noexcept; + void set_threshold(std::vector templ_thres) noexcept; + void set_mask_range(int lower, int upper, bool mask_src = false, bool mask_close = false); + void set_mask_ranges(MatchTaskInfo::Ranges mask_ranges, bool mask_src = false, bool mask_close = false); + void set_color_scales(MatchTaskInfo::Ranges color_scales, bool color_close = true); + void set_method(MatchMethod method) noexcept; + +protected: + virtual void _set_roi(const Rect& roi) = 0; + + void _set_task_info(MatchTaskInfo task_info); + +protected: + Params m_params; +}; } diff --git a/src/MaaCore/Vision/Config/OCRerConfig.cpp b/src/MaaCore/Vision/Config/OCRerConfig.cpp index f8a83b8f7d..1aaf4cffe5 100644 --- a/src/MaaCore/Vision/Config/OCRerConfig.cpp +++ b/src/MaaCore/Vision/Config/OCRerConfig.cpp @@ -22,8 +22,9 @@ void OCRerConfig::set_required(std::vector required) noexcept } } -void OCRerConfig::set_replace(const std::vector>& replace, - bool replace_full) noexcept +void OCRerConfig::set_replace( + const std::vector>& replace, + bool replace_full) noexcept { m_params.replace.clear(); m_params.replace.reserve(replace.size()); @@ -32,12 +33,15 @@ void OCRerConfig::set_replace(const std::vector regex: "(?:s|S)" std::string eq_classes_regex = "(?:"; - for (const auto& elem : eq_class) + for (const auto& elem : eq_class) { (eq_classes_regex += elem) += '|'; + } eq_classes_regex.pop_back(); eq_classes_regex += ')'; ranges::for_each(eq_class, [&](std::string_view elem) { diff --git a/src/MaaCore/Vision/Config/OCRerConfig.h b/src/MaaCore/Vision/Config/OCRerConfig.h index 65dc647afd..65d468dd86 100644 --- a/src/MaaCore/Vision/Config/OCRerConfig.h +++ b/src/MaaCore/Vision/Config/OCRerConfig.h @@ -7,50 +7,51 @@ namespace asst { - class OCRerConfig +class OCRerConfig +{ +public: + struct Params { - public: - struct Params - { - std::vector> required; // raw, equivalent - bool full_match = false; - std::vector> replace; - bool replace_full = false; - bool without_det = false; - bool use_char_model = false; + std::vector> required; // raw, equivalent + bool full_match = false; + std::vector> replace; + bool replace_full = false; + bool without_det = false; + bool use_char_model = false; - int bin_threshold_lower = 140; - int bin_threshold_upper = 255; - int bin_expansion = 2; - int bin_left_trim_threshold = 0; - int bin_right_trim_threshold = 0; - }; - - public: - OCRerConfig() = default; - virtual ~OCRerConfig() = default; - - void set_params(Params params); - - void set_required(std::vector required) noexcept; - void set_replace(const std::vector>& replace, - bool replace_full = false) noexcept; - - virtual void set_task_info(std::shared_ptr task_ptr); - virtual void set_task_info(const std::string& task_name); - - void set_without_det(bool without_det) noexcept; - void set_use_char_model(bool enable) noexcept; - - void set_bin_threshold(int lower, int upper = 255); - void set_bin_expansion(int expansion); - void set_bin_trim_threshold(int left, int right); - - protected: - virtual void _set_roi(const Rect& roi) = 0; - virtual void _set_task_info(OcrTaskInfo task_info); - - protected: - Params m_params; + int bin_threshold_lower = 140; + int bin_threshold_upper = 255; + int bin_expansion = 2; + int bin_left_trim_threshold = 0; + int bin_right_trim_threshold = 0; }; + +public: + OCRerConfig() = default; + virtual ~OCRerConfig() = default; + + void set_params(Params params); + + void set_required(std::vector required) noexcept; + void set_replace( + const std::vector>& replace, + bool replace_full = false) noexcept; + + virtual void set_task_info(std::shared_ptr task_ptr); + virtual void set_task_info(const std::string& task_name); + + void set_without_det(bool without_det) noexcept; + void set_use_char_model(bool enable) noexcept; + + void set_bin_threshold(int lower, int upper = 255); + void set_bin_expansion(int expansion); + void set_bin_trim_threshold(int left, int right); + +protected: + virtual void _set_roi(const Rect& roi) = 0; + virtual void _set_task_info(OcrTaskInfo task_info); + +protected: + Params m_params; +}; } diff --git a/src/MaaCore/Vision/Hasher.cpp b/src/MaaCore/Vision/Hasher.cpp index 5feb00ca7f..b9dba56153 100644 --- a/src/MaaCore/Vision/Hasher.cpp +++ b/src/MaaCore/Vision/Hasher.cpp @@ -102,7 +102,9 @@ std::string asst::Hasher::s_hash(const cv::Mat& img) int tmp_dec = 0; for (int ro = 0; ro < 256; ro++) { tmp_dec = tmp_dec << 1; - if (*pix > 127) tmp_dec++; + if (*pix > 127) { + tmp_dec++; + } if (ro % 4 == 3) { hash_value << std::hex << tmp_dec; tmp_dec = 0; diff --git a/src/MaaCore/Vision/Hasher.h b/src/MaaCore/Vision/Hasher.h index eb894e2d21..af42913fbd 100644 --- a/src/MaaCore/Vision/Hasher.h +++ b/src/MaaCore/Vision/Hasher.h @@ -5,36 +5,36 @@ namespace asst { - // FIXME: 删掉这个类,以及对应的 task 类型 - class Hasher : public VisionHelper - { - public: - using VisionHelper::VisionHelper; - virtual ~Hasher() override = default; +// FIXME: 删掉这个类,以及对应的 task 类型 +class Hasher : public VisionHelper +{ +public: + using VisionHelper::VisionHelper; + virtual ~Hasher() override = default; - bool analyze(); + bool analyze(); - void set_mask_range(int lower, int upper) noexcept; - void set_mask_range(std::pair mask_range) noexcept; - void set_hash_templates(std::unordered_map hash_templates) noexcept; - void set_need_split(bool need_split) noexcept; - void set_need_bound(bool need_bound) noexcept; + void set_mask_range(int lower, int upper) noexcept; + void set_mask_range(std::pair mask_range) noexcept; + void set_hash_templates(std::unordered_map hash_templates) noexcept; + void set_need_split(bool need_split) noexcept; + void set_need_bound(bool need_bound) noexcept; - const std::vector& get_min_dist_name() const noexcept; - const std::vector& get_hash() const noexcept; + const std::vector& get_min_dist_name() const noexcept; + const std::vector& get_hash() const noexcept; - static std::string s_hash(const cv::Mat& img); - static int hamming(std::string hash1, std::string hash2); - static std::vector split_bin(const cv::Mat& bin); - static cv::Mat bound_bin(const cv::Mat& bin); + static std::string s_hash(const cv::Mat& img); + static int hamming(std::string hash1, std::string hash2); + static std::vector split_bin(const cv::Mat& bin); + static cv::Mat bound_bin(const cv::Mat& bin); - protected: - std::pair m_mask_range; - std::unordered_map m_hash_templates; - bool m_need_split = false; - bool m_need_bound = false; +protected: + std::pair m_mask_range; + std::unordered_map m_hash_templates; + bool m_need_split = false; + bool m_need_bound = false; - std::vector m_hash_result; - std::vector m_min_dist_name; - }; + std::vector m_hash_result; + std::vector m_min_dist_name; +}; } diff --git a/src/MaaCore/Vision/Infrast/InfrastClueVacancyImageAnalyzer.h b/src/MaaCore/Vision/Infrast/InfrastClueVacancyImageAnalyzer.h index bc4c83098b..dde4a282f1 100644 --- a/src/MaaCore/Vision/Infrast/InfrastClueVacancyImageAnalyzer.h +++ b/src/MaaCore/Vision/Infrast/InfrastClueVacancyImageAnalyzer.h @@ -3,28 +3,28 @@ namespace asst { - class InfrastClueVacancyImageAnalyzer final : public VisionHelper +class InfrastClueVacancyImageAnalyzer final : public VisionHelper +{ +public: + using VisionHelper::VisionHelper; + virtual ~InfrastClueVacancyImageAnalyzer() override = default; + InfrastClueVacancyImageAnalyzer(const cv::Mat& image, const Rect& roi) = delete; + + bool analyze(); + static constexpr int MaxNumOfClue = 7; + + void set_to_be_analyzed(std::vector to_be_analyzed) noexcept { - public: - using VisionHelper::VisionHelper; - virtual ~InfrastClueVacancyImageAnalyzer() override = default; - InfrastClueVacancyImageAnalyzer(const cv::Mat& image, const Rect& roi) = delete; + m_to_be_analyzed = std::move(to_be_analyzed); + } - bool analyze(); - static constexpr int MaxNumOfClue = 7; + const std::unordered_map& get_vacancy() const noexcept { return m_clue_vacancy; } - void set_to_be_analyzed(std::vector to_be_analyzed) noexcept - { - m_to_be_analyzed = std::move(to_be_analyzed); - } +private: + // 该分析器不支持外部设置ROI + using VisionHelper::set_roi; - const std::unordered_map& get_vacancy() const noexcept { return m_clue_vacancy; } - - private: - // 该分析器不支持外部设置ROI - using VisionHelper::set_roi; - - std::vector m_to_be_analyzed; - std::unordered_map m_clue_vacancy; - }; + std::vector m_to_be_analyzed; + std::unordered_map m_clue_vacancy; +}; } diff --git a/src/MaaCore/Vision/Infrast/InfrastFacilityImageAnalyzer.h b/src/MaaCore/Vision/Infrast/InfrastFacilityImageAnalyzer.h index 8412038960..ed5a20096f 100644 --- a/src/MaaCore/Vision/Infrast/InfrastFacilityImageAnalyzer.h +++ b/src/MaaCore/Vision/Infrast/InfrastFacilityImageAnalyzer.h @@ -3,52 +3,51 @@ namespace asst { - class InfrastFacilityImageAnalyzer final : public VisionHelper +class InfrastFacilityImageAnalyzer final : public VisionHelper +{ +public: + using VisionHelper::VisionHelper; + virtual ~InfrastFacilityImageAnalyzer() override = default; + InfrastFacilityImageAnalyzer(const cv::Mat& image, const Rect& roi) = delete; + + bool analyze(); + + void set_to_be_analyzed(std::vector facilities) noexcept { m_to_be_analyzed = std::move(facilities); } + + size_t get_quantity(const std::string& name) const { - public: - using VisionHelper::VisionHelper; - virtual ~InfrastFacilityImageAnalyzer() override = default; - InfrastFacilityImageAnalyzer(const cv::Mat& image, const Rect& roi) = delete; - - bool analyze(); - - void set_to_be_analyzed(std::vector facilities) noexcept - { - m_to_be_analyzed = std::move(facilities); + if (auto iter = m_result.find(name); iter == m_result.cend()) { + return 0; } - - size_t get_quantity(const std::string& name) const - { - if (auto iter = m_result.find(name); iter == m_result.cend()) { - return 0; - } - else { - return iter->second.size(); - } + else { + return iter->second.size(); } - Rect get_rect(const std::string& name, int index) const - { - if (auto iter = m_result.find(name); iter == m_result.cend()) { + } + + Rect get_rect(const std::string& name, int index) const + { + if (auto iter = m_result.find(name); iter == m_result.cend()) { + return {}; + } + else { + if (index < 0 || static_cast(index) >= iter->second.size()) { return {}; } else { - if (index < 0 || static_cast(index) >= iter->second.size()) { - return {}; - } - else { - return iter->second.at(index).rect; - } + return iter->second.at(index).rect; } } - const std::unordered_map>& get_result() const noexcept { return m_result; } + } - private: - // 该分析器不支持外部设置ROI - using VisionHelper::set_roi; + const std::unordered_map>& get_result() const noexcept { return m_result; } - // key:设施名,value:所有这种设施的当前Rect(例如所有制造站的位置) - std::unordered_map> m_result; - // 需要识别的设施名 - std::vector m_to_be_analyzed; - }; +private: + // 该分析器不支持外部设置ROI + using VisionHelper::set_roi; + + // key:设施名,value:所有这种设施的当前Rect(例如所有制造站的位置) + std::unordered_map> m_result; + // 需要识别的设施名 + std::vector m_to_be_analyzed; +}; } diff --git a/src/MaaCore/Vision/Infrast/InfrastOperImageAnalyzer.cpp b/src/MaaCore/Vision/Infrast/InfrastOperImageAnalyzer.cpp index 219d16cef6..20ef75f76c 100644 --- a/src/MaaCore/Vision/Infrast/InfrastOperImageAnalyzer.cpp +++ b/src/MaaCore/Vision/Infrast/InfrastOperImageAnalyzer.cpp @@ -298,8 +298,9 @@ void asst::InfrastOperImageAnalyzer::skill_analyze() else if (possible_skills.size() > 1) { // 匹配得分最高的id作为基准,排除有识别错误,其他的技能混进来了的情况 // 即排除容器中,除了有同一个技能的不同等级,还有别的技能的情况 - auto max_iter = ranges::max_element(possible_skills, std::less {}, - [](const auto& pair) { return pair.second.score; }); + auto max_iter = ranges::max_element(possible_skills, std::less {}, [](const auto& pair) { + return pair.second.score; + }); double base_score = max_iter->second.score; std::string base_id = max_iter->first.id; size_t level_pos = 0; @@ -390,8 +391,14 @@ void asst::InfrastOperImageAnalyzer::doing_analyze() if (working_analyzer.analyze()) { oper.doing = infrast::Doing::Working; #ifdef ASST_DEBUG - cv::putText(m_image_draw, "Working", cv::Point(working_rect.x, working_rect.y), 1, 1, cv::Scalar(0, 0, 255), - 2); + cv::putText( + m_image_draw, + "Working", + cv::Point(working_rect.x, working_rect.y), + 1, + 1, + cv::Scalar(0, 0, 255), + 2); #endif } // TODO: infrast::Doing::Resting的识别 diff --git a/src/MaaCore/Vision/Infrast/InfrastOperImageAnalyzer.h b/src/MaaCore/Vision/Infrast/InfrastOperImageAnalyzer.h index 4ebd8ef07b..7c9460a210 100644 --- a/src/MaaCore/Vision/Infrast/InfrastOperImageAnalyzer.h +++ b/src/MaaCore/Vision/Infrast/InfrastOperImageAnalyzer.h @@ -5,52 +5,55 @@ namespace asst { - class InfrastOperImageAnalyzer : public VisionHelper +class InfrastOperImageAnalyzer : public VisionHelper +{ +public: + enum ToBeCalced { - public: - enum ToBeCalced - { - None = 0, - Smiley = 1, - Mood = 2, - FaceHash = 4, - // NameHash = 8, - Selected = 16, - Doing = 32, - Skill = 64, - All = 127 - }; - - using VisionHelper::VisionHelper; - virtual ~InfrastOperImageAnalyzer() override = default; - InfrastOperImageAnalyzer(const cv::Mat& image, const Rect& roi) = delete; - - bool analyze(); - - void sort_by_loc(); - void sort_by_mood(); - - auto get_result() const noexcept -> const std::vector& { return m_result; } - int get_num_of_opers_with_skills() const noexcept { return m_num_of_opers_with_skills; } - void set_facility(std::string facility) noexcept { m_facility = std::move(facility); } - void set_to_be_calced(int to_be_calced) noexcept { m_to_be_calced = to_be_calced | Smiley; } - - static constexpr int MaxNumOfSkills = 2; // 单个干员最多有几个基建技能 - - private: - // 该分析器不支持外部设置ROI - using VisionHelper::set_roi; - - void oper_detect(); - void mood_analyze(); - void face_hash_analyze(); - void skill_analyze(); - void selected_analyze(); - void doing_analyze(); - - std::string m_facility; - std::vector m_result; - int m_to_be_calced = Smiley; - int m_num_of_opers_with_skills = 0; + None = 0, + Smiley = 1, + Mood = 2, + FaceHash = 4, + // NameHash = 8, + Selected = 16, + Doing = 32, + Skill = 64, + All = 127 }; + + using VisionHelper::VisionHelper; + virtual ~InfrastOperImageAnalyzer() override = default; + InfrastOperImageAnalyzer(const cv::Mat& image, const Rect& roi) = delete; + + bool analyze(); + + void sort_by_loc(); + void sort_by_mood(); + + auto get_result() const noexcept -> const std::vector& { return m_result; } + + int get_num_of_opers_with_skills() const noexcept { return m_num_of_opers_with_skills; } + + void set_facility(std::string facility) noexcept { m_facility = std::move(facility); } + + void set_to_be_calced(int to_be_calced) noexcept { m_to_be_calced = to_be_calced | Smiley; } + + static constexpr int MaxNumOfSkills = 2; // 单个干员最多有几个基建技能 + +private: + // 该分析器不支持外部设置ROI + using VisionHelper::set_roi; + + void oper_detect(); + void mood_analyze(); + void face_hash_analyze(); + void skill_analyze(); + void selected_analyze(); + void doing_analyze(); + + std::string m_facility; + std::vector m_result; + int m_to_be_calced = Smiley; + int m_num_of_opers_with_skills = 0; +}; } // namespace asst diff --git a/src/MaaCore/Vision/Infrast/InfrastSmileyImageAnalyzer.h b/src/MaaCore/Vision/Infrast/InfrastSmileyImageAnalyzer.h index ac1f9776f8..58f8f4f16c 100644 --- a/src/MaaCore/Vision/Infrast/InfrastSmileyImageAnalyzer.h +++ b/src/MaaCore/Vision/Infrast/InfrastSmileyImageAnalyzer.h @@ -5,17 +5,17 @@ namespace asst { - class InfrastSmileyImageAnalyzer : public VisionHelper - { - public: - using VisionHelper::VisionHelper; - virtual ~InfrastSmileyImageAnalyzer() override = default; +class InfrastSmileyImageAnalyzer : public VisionHelper +{ +public: + using VisionHelper::VisionHelper; + virtual ~InfrastSmileyImageAnalyzer() override = default; - bool analyze(); + bool analyze(); - auto get_result() const noexcept -> const std::vector& { return m_result; } + auto get_result() const noexcept -> const std::vector& { return m_result; } - protected: - std::vector m_result; - }; +protected: + std::vector m_result; +}; } diff --git a/src/MaaCore/Vision/Matcher.cpp b/src/MaaCore/Vision/Matcher.cpp index b0592f1914..89eff91ab1 100644 --- a/src/MaaCore/Vision/Matcher.cpp +++ b/src/MaaCore/Vision/Matcher.cpp @@ -93,8 +93,15 @@ std::vector Matcher::preproc_and_match(const cv::Mat& image, } if (templ.cols > image.cols || templ.rows > image.rows) { - Log.error("templ size is too large", templ_name, "image size:", image.cols, image.rows, - "templ size:", templ.cols, templ.rows); + Log.error( + "templ size is too large", + templ_name, + "image size:", + image.cols, + image.rows, + "templ size:", + templ.cols, + templ.rows); return {}; } @@ -121,8 +128,7 @@ std::vector Matcher::preproc_and_match(const cv::Mat& image, const MatchTaskInfo::Ranges mask_ranges, const cv::Mat& templ, const cv::Mat& templ_gray, - bool with_close) - -> std::optional { + bool with_close) -> std::optional { // Union all masks, not intersection cv::Mat mask = cv::Mat::zeros(templ_gray.size(), CV_8UC1); for (const auto& range : mask_ranges) { @@ -187,7 +193,7 @@ std::vector Matcher::preproc_and_match(const cv::Mat& image, fp.convertTo(fp, CV_32S); cv::Mat count_result; cv::divide(2 * tp, tp + fp + tp_fn, count_result, 1, CV_32F); // 数色结果为 f1_score - cv::multiply(matched, count_result, matched); // 最终结果是数色和模板匹配的点积 + cv::multiply(matched, count_result, matched); // 最终结果是数色和模板匹配的点积 } results.emplace_back(RawResult { .matched = matched, .templ = templ, .templ_name = templ_name }); } diff --git a/src/MaaCore/Vision/Matcher.h b/src/MaaCore/Vision/Matcher.h index aa5654821f..6c9e5861c7 100644 --- a/src/MaaCore/Vision/Matcher.h +++ b/src/MaaCore/Vision/Matcher.h @@ -5,34 +5,36 @@ namespace asst { - class Matcher : public VisionHelper, public MatcherConfig +class Matcher : public VisionHelper, public MatcherConfig +{ +public: + using Result = MatchRect; + using ResultOpt = std::optional; + +public: + using VisionHelper::VisionHelper; + virtual ~Matcher() override = default; + + ResultOpt analyze() const; + + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + const auto& get_result() const noexcept { return m_result; } + +public: + struct RawResult { - public: - using Result = MatchRect; - using ResultOpt = std::optional; - - public: - using VisionHelper::VisionHelper; - virtual ~Matcher() override = default; - - ResultOpt analyze() const; - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - const auto& get_result() const noexcept { return m_result; } - - public: - struct RawResult - { - cv::Mat matched; - cv::Mat templ; - std::string templ_name; - }; - static std::vector preproc_and_match(const cv::Mat& image, const MatcherConfig::Params& params); - - protected: - virtual void _set_roi(const Rect& roi) override { set_roi(roi); } - - private: - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - mutable Result m_result; + cv::Mat matched; + cv::Mat templ; + std::string templ_name; }; + + static std::vector preproc_and_match(const cv::Mat& image, const MatcherConfig::Params& params); + +protected: + virtual void _set_roi(const Rect& roi) override { set_roi(roi); } + +private: + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + mutable Result m_result; +}; } diff --git a/src/MaaCore/Vision/Miscellaneous/BrightPointAnalyzer.h b/src/MaaCore/Vision/Miscellaneous/BrightPointAnalyzer.h index d0050c71f3..fd2f02266c 100644 --- a/src/MaaCore/Vision/Miscellaneous/BrightPointAnalyzer.h +++ b/src/MaaCore/Vision/Miscellaneous/BrightPointAnalyzer.h @@ -15,6 +15,7 @@ public: virtual ~BrightPointAnalyzer() override = default; ResultsVecOpt analyze(); + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 const auto& get_result() const noexcept { return m_result; } diff --git a/src/MaaCore/Vision/Miscellaneous/CreditShopImageAnalyzer.cpp b/src/MaaCore/Vision/Miscellaneous/CreditShopImageAnalyzer.cpp index 1331dabaf2..6c8863d1e3 100644 --- a/src/MaaCore/Vision/Miscellaneous/CreditShopImageAnalyzer.cpp +++ b/src/MaaCore/Vision/Miscellaneous/CreditShopImageAnalyzer.cpp @@ -104,8 +104,9 @@ bool asst::CreditShopImageAnalyzer::whether_to_buy_analyze() } if (m_is_white_list) { - ranges::sort(m_need_to_buy, std::less {}, - [&](const auto& pair) { return ranges::find(m_shopping_list, pair.second); }); + ranges::sort(m_need_to_buy, std::less {}, [&](const auto& pair) { + return ranges::find(m_shopping_list, pair.second); + }); } return !m_need_to_buy.empty(); diff --git a/src/MaaCore/Vision/Miscellaneous/CreditShopImageAnalyzer.h b/src/MaaCore/Vision/Miscellaneous/CreditShopImageAnalyzer.h index 67dcf4a6db..ca15e7e3f2 100644 --- a/src/MaaCore/Vision/Miscellaneous/CreditShopImageAnalyzer.h +++ b/src/MaaCore/Vision/Miscellaneous/CreditShopImageAnalyzer.h @@ -3,31 +3,31 @@ namespace asst { - class CreditShopImageAnalyzer final : public VisionHelper - { - public: - using VisionHelper::VisionHelper; - virtual ~CreditShopImageAnalyzer() override = default; +class CreditShopImageAnalyzer final : public VisionHelper +{ +public: + using VisionHelper::VisionHelper; + virtual ~CreditShopImageAnalyzer() override = default; - bool analyze(); + bool analyze(); - void set_black_list(std::vector black_list); - void set_white_list(std::vector white_list); + void set_black_list(std::vector black_list); + void set_white_list(std::vector white_list); - const std::vector& get_result() const noexcept { return m_result; } + const std::vector& get_result() const noexcept { return m_result; } - private: - // 该分析器不支持外部设置ROI - using VisionHelper::set_roi; - bool commodities_analyze(); - bool whether_to_buy_analyze(); - bool sold_out_analyze(); +private: + // 该分析器不支持外部设置ROI + using VisionHelper::set_roi; + bool commodities_analyze(); + bool whether_to_buy_analyze(); + bool sold_out_analyze(); - std::vector m_commodities; - std::vector> m_need_to_buy; - std::vector m_result; + std::vector m_commodities; + std::vector> m_need_to_buy; + std::vector m_result; - std::vector m_shopping_list; - bool m_is_white_list = false; - }; + std::vector m_shopping_list; + bool m_is_white_list = false; +}; } diff --git a/src/MaaCore/Vision/Miscellaneous/DepotImageAnalyzer.cpp b/src/MaaCore/Vision/Miscellaneous/DepotImageAnalyzer.cpp index 7fb4cf1921..bd1ce8832a 100644 --- a/src/MaaCore/Vision/Miscellaneous/DepotImageAnalyzer.cpp +++ b/src/MaaCore/Vision/Miscellaneous/DepotImageAnalyzer.cpp @@ -60,10 +60,11 @@ template cv::Mat asst::DepotImageAnalyzer::image_from_function(const cv::Size& size, const F& func) { auto result = cv::Mat1f { size, CV_32F }; - for (int i = 0; i < result.cols; ++i) + for (int i = 0; i < result.cols; ++i) { for (int j = 0; j < result.rows; ++j) { result.at(j, i) = func(i, j); } + } return result; } @@ -101,7 +102,9 @@ bool asst::DepotImageAnalyzer::analyze_base_rect() const double phase = std::atan2(s_v, c_v); double x_first = phase / (2. * std::numbers::pi_v)*x_period + x_period / 2.; - if (phase < 0) x_first += x_period; + if (phase < 0) { + x_first += x_period; + } for (int x = static_cast(x_first); x <= m_image_resized.cols; x += x_period) { for (int y = y_first; y <= m_image_resized.rows; y += y_period) { @@ -138,10 +141,22 @@ bool asst::DepotImageAnalyzer::analyze_all_items() info.quantity = match_quantity(info); info.item_name = ItemData.get_item_name(item_id); #ifdef ASST_DEBUG - cv::putText(m_image_draw_resized, item_id, cv::Point(roi.x, roi.y - 10), cv::FONT_HERSHEY_SIMPLEX, 0.5, - cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw_resized, std::to_string(info.quantity), cv::Point(roi.x, roi.y + 10), - cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255), 2); + cv::putText( + m_image_draw_resized, + item_id, + cv::Point(roi.x, roi.y - 10), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 2); + cv::putText( + m_image_draw_resized, + std::to_string(info.quantity), + cv::Point(roi.x, roi.y + 10), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 2); #endif if (item_id.empty() || info.quantity == 0) { Log.error(__FUNCTION__, item_id, info.item_name, " quantity is zero"); @@ -165,8 +180,11 @@ bool asst::DepotImageAnalyzer::check_roi_empty(const Rect& roi) return false; } -size_t asst::DepotImageAnalyzer::match_item(const Rect& roi, /* out */ ItemInfo& item_info, size_t begin_index, - bool with_enlarge) +size_t asst::DepotImageAnalyzer::match_item( + const Rect& roi, + /* out */ ItemInfo& item_info, + size_t begin_index, + bool with_enlarge) { LogTraceFunction; @@ -221,9 +239,11 @@ int asst::DepotImageAnalyzer::match_quantity(const ItemInfo& item) auto item_templ = TemplResource::get_instance().get_templ(item.item_id); auto item_image = m_image_resized(make_rect(item.rect)); cv::Mat quotient; - cv::divide(item_image + cv::Scalar { 1, 1, 1 }, // I've forgot why I should plus 1 here - item_templ + cv::Scalar { 1, 1, 1 }, // plus 1 to avoid divide by zero - quotient, 255); + cv::divide( + item_image + cv::Scalar { 1, 1, 1 }, // I've forgot why I should plus 1 here + item_templ + cv::Scalar { 1, 1, 1 }, // plus 1 to avoid divide by zero + quotient, + 255); cv::Mat mask_r; cv::Mat mask_g; @@ -242,16 +262,22 @@ int asst::DepotImageAnalyzer::match_quantity(const ItemInfo& item) mask_rect.width -= 1; mask_rect.height -= 1; - if (mask_rect.height < 18) mask_rect.height = 18; + if (mask_rect.height < 18) { + mask_rect.height = 18; + } const auto mid_x = mask.cols / 2; // center of image - if (mask_rect.br().x - mid_x < 30) mask_rect.width = mid_x + 30 - mask_rect.x; + if (mask_rect.br().x - mid_x < 30) { + mask_rect.width = mid_x + 30 - mask_rect.x; + } // minus 2 to trim white pixels Rect ocr_roi { item.rect.x + mask_rect.x, item.rect.y + mask_rect.y, mask_rect.width - 2, mask_rect.height - 2 }; cv::Mat ocr_img = m_image_resized.clone(); - cv::subtract(m_image_resized(make_rect(item.rect)), item_templ * 0.41, - ocr_img(make_rect(item.rect))); + cv::subtract( + m_image_resized(make_rect(item.rect)), + item_templ * 0.41, + ocr_img(make_rect(item.rect))); RegionOCRer analyzer(m_image_resized); analyzer.set_task_info("NumberOcrReplace"); @@ -266,8 +292,14 @@ int asst::DepotImageAnalyzer::match_quantity(const ItemInfo& item) #ifdef ASST_DEBUG cv::rectangle(m_image_draw_resized, make_rect(result.rect), cv::Scalar(0, 0, 255)); - cv::putText(m_image_draw_resized, result.text, cv::Point(result.rect.x, result.rect.y - 5), - cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 2); + cv::putText( + m_image_draw_resized, + result.text, + cv::Point(result.rect.x, result.rect.y - 5), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 255, 0), + 2); #endif std::string digit_str = result.text; @@ -281,11 +313,11 @@ int asst::DepotImageAnalyzer::match_quantity(const ItemInfo& item) digit_str.erase(k_pos, digit_str.size()); } else if (size_t e_pos = digit_str.find("亿"); e_pos != std::string::npos) { - multiple = 100000000; + multiple = 100'000'000; digit_str.erase(e_pos, digit_str.size()); } else if (size_t m_pos = digit_str.find('M'); m_pos != std::string::npos) { - multiple = 1000000; + multiple = 1'000'000; digit_str.erase(m_pos, digit_str.size()); } else if (size_t n_pos = digit_str.find("만"); n_pos != std::string::npos) { @@ -293,7 +325,7 @@ int asst::DepotImageAnalyzer::match_quantity(const ItemInfo& item) digit_str.erase(n_pos, digit_str.size()); } else if (size_t o_pos = digit_str.find("억"); o_pos != std::string::npos) { - multiple = 100000000; + multiple = 100'000'000; digit_str.erase(o_pos, digit_str.size()); } diff --git a/src/MaaCore/Vision/Miscellaneous/DepotImageAnalyzer.h b/src/MaaCore/Vision/Miscellaneous/DepotImageAnalyzer.h index d1ebbe2ec7..052a92d714 100644 --- a/src/MaaCore/Vision/Miscellaneous/DepotImageAnalyzer.h +++ b/src/MaaCore/Vision/Miscellaneous/DepotImageAnalyzer.h @@ -3,49 +3,51 @@ namespace asst { - struct ItemInfo - { - std::string item_id; - std::string item_name; - int quantity = 0; - Rect rect; - }; - class DepotImageAnalyzer final : public VisionHelper - { - public: - static constexpr size_t NPos = ~0ULL; +struct ItemInfo +{ + std::string item_id; + std::string item_name; + int quantity = 0; + Rect rect; +}; - public: - using VisionHelper::VisionHelper; - virtual ~DepotImageAnalyzer() override = default; +class DepotImageAnalyzer final : public VisionHelper +{ +public: + static constexpr size_t NPos = ~0ULL; - bool analyze(); +public: + using VisionHelper::VisionHelper; + virtual ~DepotImageAnalyzer() override = default; - void set_match_begin_pos(size_t pos) noexcept; - size_t get_match_begin_pos() const noexcept; - const auto& get_result() const noexcept { return m_result; } + bool analyze(); - private: - void resize(); - bool analyze_base_rect(); - bool analyze_all_items(); + void set_match_begin_pos(size_t pos) noexcept; + size_t get_match_begin_pos() const noexcept; - bool check_roi_empty(const Rect& roi); - size_t match_item(const Rect& roi, /* out */ ItemInfo& item_info, size_t begin_index = 0ULL, - bool with_enlarge = true); - int match_quantity(const ItemInfo& item); - Rect resize_rect_to_raw_size(const Rect& rect); + const auto& get_result() const noexcept { return m_result; } - template - static cv::Mat image_from_function(const cv::Size& size, const F& func); +private: + void resize(); + bool analyze_base_rect(); + bool analyze_all_items(); - size_t m_match_begin_pos = 0ULL; - Rect m_resized_rect; - cv::Mat m_image_resized; + bool check_roi_empty(const Rect& roi); + size_t + match_item(const Rect& roi, /* out */ ItemInfo& item_info, size_t begin_index = 0ULL, bool with_enlarge = true); + int match_quantity(const ItemInfo& item); + Rect resize_rect_to_raw_size(const Rect& rect); + + template + static cv::Mat image_from_function(const cv::Size& size, const F& func); + + size_t m_match_begin_pos = 0ULL; + Rect m_resized_rect; + cv::Mat m_image_resized; #ifdef ASST_DEBUG - cv::Mat m_image_draw_resized; + cv::Mat m_image_draw_resized; #endif - std::vector m_all_items_roi; - std::unordered_map m_result; - }; + std::vector m_all_items_roi; + std::unordered_map m_result; +}; } diff --git a/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.cpp b/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.cpp index a841f277a1..1263064de7 100644 --- a/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.cpp +++ b/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.cpp @@ -109,8 +109,14 @@ bool asst::OperBoxImageAnalyzer::opers_analyze() #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(flag_rect), cv::Scalar(0, 255, 0), 1); - cv::putText(m_image_draw, std::to_string(oper.flag_score), cv::Point(flag_rect.x, flag_rect.y - 10), - cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255), 1); + cv::putText( + m_image_draw, + std::to_string(oper.flag_score), + cv::Point(flag_rect.x, flag_rect.y - 10), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 1); cv::rectangle(m_image_draw, make_rect(oper.rect), cv::Scalar(0, 255, 0), 1); #endif @@ -146,8 +152,14 @@ bool asst::OperBoxImageAnalyzer::level_analyze() box.level = level_num(level); #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(ocr_result.rect), cv::Scalar(0, 255, 0), 1); - cv::putText(m_image_draw, level, cv::Point(roi.x, roi.y - 10), cv::FONT_HERSHEY_SIMPLEX, 0.5, - cv::Scalar(0, 0, 255), 2); + cv::putText( + m_image_draw, + level, + cv::Point(roi.x, roi.y - 10), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 2); #endif // ASST_DEBUG} } return true; @@ -179,8 +191,14 @@ bool asst::OperBoxImageAnalyzer::elite_analyze() box.elite = std::stoi(elite); #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(roi), cv::Scalar(0, 255, 0), 1); - cv::putText(m_image_draw, std::to_string(box.elite), cv::Point(roi.x, roi.y - 10), cv::FONT_HERSHEY_SIMPLEX, - 0.5, cv::Scalar(0, 0, 255), 2); + cv::putText( + m_image_draw, + std::to_string(box.elite), + cv::Point(roi.x, roi.y - 10), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 2); #endif // ASST_DEBUG } return true; @@ -211,8 +229,14 @@ bool asst::OperBoxImageAnalyzer::potential_analyze() box.potential = std::stoi(potential); #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(roi), cv::Scalar(0, 255, 0), 1); - cv::putText(m_image_draw, std::to_string(box.potential), cv::Point(roi.x, roi.y - 10), cv::FONT_HERSHEY_SIMPLEX, - 0.5, cv::Scalar(0, 0, 255), 2); + cv::putText( + m_image_draw, + std::to_string(box.potential), + cv::Point(roi.x, roi.y - 10), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 2); #endif // ASST_DEBUG } return true; diff --git a/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.h b/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.h index 546c91c7bc..5ba8d8e49f 100644 --- a/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.h +++ b/src/MaaCore/Vision/Miscellaneous/OperBoxImageAnalyzer.h @@ -4,36 +4,37 @@ namespace asst { - struct OperBoxInfo - { - std::string id; - std::string name; - int level = 0; // 等级 - int elite = 0; // 精英度 - int potential = 0; // 潜能 - int rarity = 0; // 稀有度 +struct OperBoxInfo +{ + std::string id; + std::string name; + int level = 0; // 等级 + int elite = 0; // 精英度 + int potential = 0; // 潜能 + int rarity = 0; // 稀有度 - Rect rect; - bool own = false; - }; + Rect rect; + bool own = false; +}; - class OperBoxImageAnalyzer final : public VisionHelper - { - public: - using VisionHelper::VisionHelper; - virtual ~OperBoxImageAnalyzer() override = default; - bool analyze(); - const auto& get_result() const noexcept { return m_result; } +class OperBoxImageAnalyzer final : public VisionHelper +{ +public: + using VisionHelper::VisionHelper; + virtual ~OperBoxImageAnalyzer() override = default; + bool analyze(); - private: - int level_num(const std::string& level); - bool analyzer_oper_box(); - // 获取lv rect - bool opers_analyze(); - bool level_analyze(); - bool elite_analyze(); - bool potential_analyze(); + const auto& get_result() const noexcept { return m_result; } - std::vector m_result; - }; +private: + int level_num(const std::string& level); + bool analyzer_oper_box(); + // 获取lv rect + bool opers_analyze(); + bool level_analyze(); + bool elite_analyze(); + bool potential_analyze(); + + std::vector m_result; +}; } diff --git a/src/MaaCore/Vision/Miscellaneous/PipelineAnalyzer.h b/src/MaaCore/Vision/Miscellaneous/PipelineAnalyzer.h index ee0069d105..8730510999 100644 --- a/src/MaaCore/Vision/Miscellaneous/PipelineAnalyzer.h +++ b/src/MaaCore/Vision/Miscellaneous/PipelineAnalyzer.h @@ -12,29 +12,30 @@ namespace asst { - class PipelineAnalyzer : public VisionHelper +class PipelineAnalyzer : public VisionHelper +{ +public: + struct Result { - public: - struct Result - { - std::shared_ptr task_ptr; - std::variant result; - Rect rect; - }; - using ResultOpt = std::optional; - - public: - using VisionHelper::VisionHelper; - virtual ~PipelineAnalyzer() override = default; - - void set_tasks(std::vector tasks_name) { m_tasks_name = std::move(tasks_name); } - - ResultOpt analyze() const; - - private: - Matcher::ResultOpt match(const std::shared_ptr& task_ptr) const; - OCRer::ResultsVecOpt ocr(const std::shared_ptr& task_ptr) const; - - std::vector m_tasks_name; + std::shared_ptr task_ptr; + std::variant result; + Rect rect; }; + + using ResultOpt = std::optional; + +public: + using VisionHelper::VisionHelper; + virtual ~PipelineAnalyzer() override = default; + + void set_tasks(std::vector tasks_name) { m_tasks_name = std::move(tasks_name); } + + ResultOpt analyze() const; + +private: + Matcher::ResultOpt match(const std::shared_ptr& task_ptr) const; + OCRer::ResultsVecOpt ocr(const std::shared_ptr& task_ptr) const; + + std::vector m_tasks_name; +}; } diff --git a/src/MaaCore/Vision/Miscellaneous/RecruitImageAnalyzer.cpp b/src/MaaCore/Vision/Miscellaneous/RecruitImageAnalyzer.cpp index 0887544a23..3ac2a7586d 100644 --- a/src/MaaCore/Vision/Miscellaneous/RecruitImageAnalyzer.cpp +++ b/src/MaaCore/Vision/Miscellaneous/RecruitImageAnalyzer.cpp @@ -48,8 +48,12 @@ bool asst::RecruitImageAnalyzer::time_analyze() MultiMatcher decrement_a(m_image); decrement_a.set_task_info("RecruitTimerDecrement"); auto result_opt = decrement_a.analyze(); - if (!result_opt) return false; - if (result_opt->size() != 2) return false; // expecting two buttons + if (!result_opt) { + return false; + } + if (result_opt->size() != 2) { + return false; // expecting two buttons + } sort_by_horizontal_(*result_opt); m_hour_decrement = result_opt->at(0).rect; m_minute_decrement = result_opt->at(1).rect; diff --git a/src/MaaCore/Vision/Miscellaneous/RecruitImageAnalyzer.h b/src/MaaCore/Vision/Miscellaneous/RecruitImageAnalyzer.h index 36eeac099a..6110c84109 100644 --- a/src/MaaCore/Vision/Miscellaneous/RecruitImageAnalyzer.h +++ b/src/MaaCore/Vision/Miscellaneous/RecruitImageAnalyzer.h @@ -5,33 +5,37 @@ namespace asst { - class RecruitImageAnalyzer final : public VisionHelper - { - public: - using VisionHelper::VisionHelper; - RecruitImageAnalyzer(const cv::Mat& image, const Rect& roi) = delete; - virtual ~RecruitImageAnalyzer() override = default; +class RecruitImageAnalyzer final : public VisionHelper +{ +public: + using VisionHelper::VisionHelper; + RecruitImageAnalyzer(const cv::Mat& image, const Rect& roi) = delete; + virtual ~RecruitImageAnalyzer() override = default; - bool analyze(); + bool analyze(); - const std::vector& get_tags_result() const noexcept { return m_tags_result; } - Rect get_hour_decrement_rect() const noexcept { return m_hour_decrement; } - Rect get_minute_decrement_rect() const noexcept { return m_minute_decrement; } - Rect get_refresh_rect() const noexcept { return m_refresh_rect; } - Rect get_permit_rect() const noexcept { return m_permit_rect; } + const std::vector& get_tags_result() const noexcept { return m_tags_result; } - private: - // 该分析器不支持外部设置ROI - using VisionHelper::set_roi; - bool tags_analyze(); - bool time_analyze(); - bool refresh_analyze(); - bool permit_analyze(); + Rect get_hour_decrement_rect() const noexcept { return m_hour_decrement; } - std::vector m_tags_result; - Rect m_hour_decrement; - Rect m_minute_decrement; - Rect m_refresh_rect; - Rect m_permit_rect; - }; + Rect get_minute_decrement_rect() const noexcept { return m_minute_decrement; } + + Rect get_refresh_rect() const noexcept { return m_refresh_rect; } + + Rect get_permit_rect() const noexcept { return m_permit_rect; } + +private: + // 该分析器不支持外部设置ROI + using VisionHelper::set_roi; + bool tags_analyze(); + bool time_analyze(); + bool refresh_analyze(); + bool permit_analyze(); + + std::vector m_tags_result; + Rect m_hour_decrement; + Rect m_minute_decrement; + Rect m_refresh_rect; + Rect m_permit_rect; +}; } diff --git a/src/MaaCore/Vision/Miscellaneous/StageDropsImageAnalyzer.cpp b/src/MaaCore/Vision/Miscellaneous/StageDropsImageAnalyzer.cpp index 490e294bfa..e384b46c97 100644 --- a/src/MaaCore/Vision/Miscellaneous/StageDropsImageAnalyzer.cpp +++ b/src/MaaCore/Vision/Miscellaneous/StageDropsImageAnalyzer.cpp @@ -67,8 +67,14 @@ bool asst::StageDropsImageAnalyzer::analyze_stage_code() #ifdef ASST_DEBUG const Rect& text_rect = analyzer.get_result().rect; cv::rectangle(m_image_draw, make_rect(text_rect), cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw, m_stage_code, cv::Point(text_rect.x, text_rect.y - 10), cv::FONT_HERSHEY_SIMPLEX, 1, - cv::Scalar(0, 0, 255), 2); + cv::putText( + m_image_draw, + m_stage_code, + cv::Point(text_rect.x, text_rect.y - 10), + cv::FONT_HERSHEY_SIMPLEX, + 1, + cv::Scalar(0, 0, 255), + 2); #endif return true; @@ -85,8 +91,14 @@ bool asst::StageDropsImageAnalyzer::analyze_times() #ifdef ASST_DEBUG auto draw_rect = Task.get("StageDrops-TimesCheck")->roi; cv::rectangle(m_image_draw, make_rect(draw_rect), cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw, "Not found times", cv::Point(73, 410), cv::FONT_HERSHEY_SIMPLEX, 0.5, - cv::Scalar(0, 0, 255), 2); + cv::putText( + m_image_draw, + "Not found times", + cv::Point(73, 410), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 2); #endif return true; } @@ -121,8 +133,14 @@ bool asst::StageDropsImageAnalyzer::analyze_times() #ifdef ASST_DEBUG auto draw_rect = Task.get("StageDrops-TimesRec")->roi; cv::rectangle(m_image_draw, make_rect(draw_rect), cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw, "Times: " + std::to_string(m_times), cv::Point(73, 410), cv::FONT_HERSHEY_SIMPLEX, 0.5, - cv::Scalar(0, 0, 255), 2); + cv::putText( + m_image_draw, + "Times: " + std::to_string(m_times), + cv::Point(73, 410), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 2); #endif Log.info(__FUNCTION__, "times", m_times); @@ -168,9 +186,14 @@ bool asst::StageDropsImageAnalyzer::analyze_stars() #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(matched_rect), cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw, std::to_string(m_stars) + " stars", - cv::Point(matched_rect.x + 5, matched_rect.y + matched_rect.height - 5), cv::FONT_HERSHEY_SIMPLEX, 0.5, - cv::Scalar(0, 0, 255), 2); + cv::putText( + m_image_draw, + std::to_string(m_stars) + " stars", + cv::Point(matched_rect.x + 5, matched_rect.y + matched_rect.height - 5), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 2); #endif return true; @@ -192,8 +215,14 @@ bool asst::StageDropsImageAnalyzer::analyze_difficulty() Log.info(__FUNCTION__, "StageDifficulty::Tough"); } #ifdef ASST_DEBUG - cv::putText(m_image_draw, m_difficulty == StageDifficulty::Normal ? "Normal" : "Tough", cv::Point(75, 120), - cv::FONT_HERSHEY_SIMPLEX, 1.2, cv::Scalar(0, 0, 255), 2); + cv::putText( + m_image_draw, + m_difficulty == StageDifficulty::Normal ? "Normal" : "Tough", + cv::Point(75, 120), + cv::FONT_HERSHEY_SIMPLEX, + 1.2, + cv::Scalar(0, 0, 255), + 2); #endif }; @@ -262,10 +291,22 @@ bool asst::StageDropsImageAnalyzer::analyze_drops() Log.info("Item id:", item, ", quantity:", quantity); #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(item_roi), cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw, item, cv::Point(item_roi.x, item_roi.y - 10), cv::FONT_HERSHEY_SIMPLEX, 0.5, - cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw, std::to_string(quantity), cv::Point(item_roi.x, item_roi.y + 10), - cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 2); + cv::putText( + m_image_draw, + item, + cv::Point(item_roi.x, item_roi.y - 10), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 2); + cv::putText( + m_image_draw, + std::to_string(quantity), + cv::Point(item_roi.x, item_roi.y + 10), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 255, 0), + 2); #endif if (quantity <= 0) { has_error = true; @@ -303,8 +344,10 @@ bool asst::StageDropsImageAnalyzer::analyze_drops_for_CF() } LogTraceFunction; - static const std::array CFDrops = { "act24side_melding_1", "act24side_melding_2", - "act24side_melding_3", "act24side_melding_4", + static const std::array CFDrops = { "act24side_melding_1", + "act24side_melding_2", + "act24side_melding_3", + "act24side_melding_4", "act24side_melding_5" }; // "act24side_melding_6" bool has_error = false; @@ -329,10 +372,22 @@ bool asst::StageDropsImageAnalyzer::analyze_drops_for_CF() Log.info("Item id:", item_name, ", quantity:", quantity); #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(result.rect), cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw, std::string("CF: ") + item_name.back(), cv::Point(result.rect.x, result.rect.y - 10), - cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw, std::to_string(quantity), cv::Point(result.rect.x, result.rect.y + 30), - cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 0), 2); + cv::putText( + m_image_draw, + std::string("CF: ") + item_name.back(), + cv::Point(result.rect.x, result.rect.y - 10), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 2); + cv::putText( + m_image_draw, + std::to_string(quantity), + cv::Point(result.rect.x, result.rect.y + 30), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 255, 0), + 2); #endif if (quantity <= 0) { has_error = true; @@ -422,8 +477,11 @@ bool asst::StageDropsImageAnalyzer::analyze_baseline() temp.convertTo(preprocessed_roi, CV_8U, 255); // filling small gaps - cv::morphologyEx(preprocessed_roi, preprocessed_roi, cv::MORPH_CLOSE, - cv::getStructuringElement(cv::MORPH_RECT, { 3, 1 })); + cv::morphologyEx( + preprocessed_roi, + preprocessed_roi, + cv::MORPH_CLOSE, + cv::getStructuringElement(cv::MORPH_RECT, { 3, 1 })); // cropping after derivatives, dilation, and erosion auto roi = make_rect(task_ptr->roi); @@ -555,8 +613,14 @@ asst::StageDropType asst::StageDropsImageAnalyzer::match_droptype(const Rect& ro #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(matched_roi), cv::Scalar(0, 0, 255), 2); matched_name = matched_name.substr(matched_name.find_last_of('-') + 1, matched_name.size()); - cv::putText(m_image_draw, matched_name, cv::Point(matched_roi.x, matched_roi.y + matched_roi.height + 20), - cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255), 1); + cv::putText( + m_image_draw, + matched_name, + cv::Point(matched_roi.x, matched_roi.y + matched_roi.height + 20), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 1); #endif return matched; @@ -585,11 +649,11 @@ std::string asst::StageDropsImageAnalyzer::match_item(const Rect& roi, StageDrop } break; case StageDropType::Furniture: - return "furni"; // 家具 + return "furni"; // 家具 case StageDropType::Sanity: return "AP_GAMEPLAY"; // 理智返还 case StageDropType::Reward: - return "4003"; // 合成玉 + return "4003"; // 合成玉 default: break; } @@ -636,8 +700,8 @@ std::string asst::StageDropsImageAnalyzer::match_item(const Rect& roi, StageDrop return result; } -std::optional asst::StageDropsImageAnalyzer::match_quantity_string(const asst::Rect& roi, - bool use_word_model) +std::optional + asst::StageDropsImageAnalyzer::match_quantity_string(const asst::Rect& roi, bool use_word_model) { auto task_ptr = Task.get("StageDrops-Quantity"); if (task_ptr->color_scales.size() != 1 || @@ -710,9 +774,10 @@ std::optional asst::StageDropsImageAnalyzer::match_quantity_stri return analyzer.get_result(); } -std::optional asst::StageDropsImageAnalyzer::match_quantity_string(const asst::Rect& roi, - const std::string& item, - bool use_word_model) +std::optional asst::StageDropsImageAnalyzer::match_quantity_string( + const asst::Rect& roi, + const std::string& item, + bool use_word_model) { auto task_ptr = Task.get("StageDrops-Quantity"); if (task_ptr->color_scales.size() != 1 || @@ -766,7 +831,9 @@ std::optional asst::StageDropsImageAnalyzer::match_quantity_stri auto mask_rect = cv::boundingRect(mask); mask_rect.width -= 1; mask_rect.height -= 1; - if (mask_rect.height < 20) mask_rect.height = 20; + if (mask_rect.height < 20) { + mask_rect.height = 20; + } cv::Mat ocr_img = m_image.clone(); cv::subtract(ocr_img(make_rect(new_roi)), templ * 0.41, ocr_img(make_rect(new_roi))); @@ -820,24 +887,40 @@ int asst::StageDropsImageAnalyzer::match_quantity(const asst::Rect& roi, const s // is furniture? if (item.empty() || item == "furni") { auto opt = match_quantity_string(roi, use_word_model); - if (!opt) return 0; + if (!opt) { + return 0; + } result = opt.value(); } else { auto opt = match_quantity_string(roi, item, use_word_model); - if (!opt) return 0; + if (!opt) { + return 0; + } result = opt.value(); } #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(result.rect), cv::Scalar(0, 0, 255)); if (use_word_model) { - cv::putText(m_image_draw, result.text, cv::Point(result.rect.x, result.rect.y - 20), cv::FONT_HERSHEY_SIMPLEX, - 0.5, cv::Scalar(0, 0, 255), 2); + cv::putText( + m_image_draw, + result.text, + cv::Point(result.rect.x, result.rect.y - 20), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 0, 255), + 2); } else { - cv::putText(m_image_draw, result.text, cv::Point(result.rect.x, result.rect.y - 5), cv::FONT_HERSHEY_SIMPLEX, - 0.5, cv::Scalar(0, 255, 0), 2); + cv::putText( + m_image_draw, + result.text, + cv::Point(result.rect.x, result.rect.y - 5), + cv::FONT_HERSHEY_SIMPLEX, + 0.5, + cv::Scalar(0, 255, 0), + 2); } #endif diff --git a/src/MaaCore/Vision/Miscellaneous/StageDropsImageAnalyzer.h b/src/MaaCore/Vision/Miscellaneous/StageDropsImageAnalyzer.h index 7f7f76c395..eedd854846 100644 --- a/src/MaaCore/Vision/Miscellaneous/StageDropsImageAnalyzer.h +++ b/src/MaaCore/Vision/Miscellaneous/StageDropsImageAnalyzer.h @@ -6,57 +6,58 @@ namespace asst { - class StageDropsImageAnalyzer final : public VisionHelper - { - static constexpr const char* LMD_ID = "4001"; +class StageDropsImageAnalyzer final : public VisionHelper +{ + static constexpr const char* LMD_ID = "4001"; - public: - using VisionHelper::VisionHelper; - virtual ~StageDropsImageAnalyzer() override = default; +public: + using VisionHelper::VisionHelper; + virtual ~StageDropsImageAnalyzer() override = default; - bool analyze(); + bool analyze(); - StageKey get_stage_key() const; - int get_stars() const noexcept; - int get_times() const noexcept; + StageKey get_stage_key() const; + int get_stars() const noexcept; + int get_times() const noexcept; - // > - const auto& get_drops() const noexcept { return m_drops; } + // > + const auto& get_drops() const noexcept { return m_drops; } - bool analyze_baseline(); - std::vector> get_baseline() const noexcept { return m_baseline; } + bool analyze_baseline(); - // merge a new image with a different material position into m_image - // might resize m_image. - // return offset in pixels - std::optional merge_image(const cv::Mat& new_img); + std::vector> get_baseline() const noexcept { return m_baseline; } - protected: - bool analyze_stage_code(); - bool analyze_times(); - bool analyze_stars(); - bool analyze_difficulty(); - bool analyze_drops(); - // 落叶殇火 活动(异格夜刀), act24side, 2023-03 - bool analyze_drops_for_CF(); - // 第十二章主线 活动,前两次打有三倍掉落,过滤,2023-04 - bool analyze_drops_for_12(); + // merge a new image with a different material position into m_image + // might resize m_image. + // return offset in pixels + std::optional merge_image(const cv::Mat& new_img); - int match_quantity(const Rect& roi, const std::string& item, bool use_word_model = false); - std::optional match_quantity_string(const Rect& roi, bool use_word_model = false); - std::optional match_quantity_string(const Rect& roi, const std::string& item, - bool use_word_model = false); - static int quantity_string_to_int(const std::string& str); +protected: + bool analyze_stage_code(); + bool analyze_times(); + bool analyze_stars(); + bool analyze_difficulty(); + bool analyze_drops(); + // 落叶殇火 活动(异格夜刀), act24side, 2023-03 + bool analyze_drops_for_CF(); + // 第十二章主线 活动,前两次打有三倍掉落,过滤,2023-04 + bool analyze_drops_for_12(); - StageDropType match_droptype(const Rect& roi); - std::string match_item(const Rect& roi, StageDropType type, int index, int size); + int match_quantity(const Rect& roi, const std::string& item, bool use_word_model = false); + std::optional match_quantity_string(const Rect& roi, bool use_word_model = false); + std::optional + match_quantity_string(const Rect& roi, const std::string& item, bool use_word_model = false); + static int quantity_string_to_int(const std::string& str); - std::string m_stage_code; - int m_times = -1; // -2 means recognition failed, -1 means not found - StageDifficulty m_difficulty = StageDifficulty::Normal; - int m_stars = 0; - std::vector> m_baseline; - // > - std::vector m_drops; - }; + StageDropType match_droptype(const Rect& roi); + std::string match_item(const Rect& roi, StageDropType type, int index, int size); + + std::string m_stage_code; + int m_times = -1; // -2 means recognition failed, -1 means not found + StageDifficulty m_difficulty = StageDifficulty::Normal; + int m_stars = 0; + std::vector> m_baseline; + // > + std::vector m_drops; +}; } diff --git a/src/MaaCore/Vision/MultiMatcher.cpp b/src/MaaCore/Vision/MultiMatcher.cpp index 8d8dd0a99f..6f2aa64d59 100644 --- a/src/MaaCore/Vision/MultiMatcher.cpp +++ b/src/MaaCore/Vision/MultiMatcher.cpp @@ -68,8 +68,13 @@ MultiMatcher::ResultsVecOpt MultiMatcher::analyze() const #ifdef ASST_DEBUG for (const auto& rect : results) { cv::rectangle(m_image_draw, make_rect(rect.rect), cv::Scalar(0, 0, 255), 2); - cv::putText(m_image_draw, std::to_string(rect.score), cv::Point(rect.rect.x, rect.rect.y), 1, 1, - cv::Scalar(0, 0, 255)); + cv::putText( + m_image_draw, + std::to_string(rect.score), + cv::Point(rect.rect.x, rect.rect.y), + 1, + 1, + cv::Scalar(0, 0, 255)); } #endif diff --git a/src/MaaCore/Vision/MultiMatcher.h b/src/MaaCore/Vision/MultiMatcher.h index 1e0f5a1f14..115a4abb81 100644 --- a/src/MaaCore/Vision/MultiMatcher.h +++ b/src/MaaCore/Vision/MultiMatcher.h @@ -4,26 +4,27 @@ namespace asst { - class MultiMatcher : public VisionHelper, public MatcherConfig - { - public: - using Result = MatchRect; - using ResultsVec = std::vector; - using ResultsVecOpt = std::optional; +class MultiMatcher : public VisionHelper, public MatcherConfig +{ +public: + using Result = MatchRect; + using ResultsVec = std::vector; + using ResultsVecOpt = std::optional; - public: - using VisionHelper::VisionHelper; - virtual ~MultiMatcher() override = default; +public: + using VisionHelper::VisionHelper; + virtual ~MultiMatcher() override = default; - ResultsVecOpt analyze() const; - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - const auto& get_result() const noexcept { return m_result; } + ResultsVecOpt analyze() const; - protected: - virtual void _set_roi(const Rect& roi) override { set_roi(roi); } + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + const auto& get_result() const noexcept { return m_result; } - private: - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - mutable ResultsVec m_result; - }; +protected: + virtual void _set_roi(const Rect& roi) override { set_roi(roi); } + +private: + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + mutable ResultsVec m_result; +}; } diff --git a/src/MaaCore/Vision/OCRer.h b/src/MaaCore/Vision/OCRer.h index 54b3f6a601..ae5c5b6b2a 100644 --- a/src/MaaCore/Vision/OCRer.h +++ b/src/MaaCore/Vision/OCRer.h @@ -7,38 +7,39 @@ namespace asst { - class OCRer : public VisionHelper, public OCRerConfig - { - public: - using Result = OcrPack::Result; - using ResultsVec = OcrPack::ResultsVec; - using ResultsVecOpt = std::optional; +class OCRer : public VisionHelper, public OCRerConfig +{ +public: + using Result = OcrPack::Result; + using ResultsVec = OcrPack::ResultsVec; + using ResultsVecOpt = std::optional; - public: - using VisionHelper::VisionHelper; - virtual ~OCRer() override = default; +public: + using VisionHelper::VisionHelper; + virtual ~OCRer() override = default; - ResultsVecOpt analyze() const; - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - const auto& get_result() const noexcept { return m_result; } + ResultsVecOpt analyze() const; - protected: - virtual void _set_roi(const Rect& roi) override { set_roi(roi); } + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + const auto& get_result() const noexcept { return m_result; } - // Not working for OCR with detection - using OCRerConfig::set_bin_expansion; - using OCRerConfig::set_bin_threshold; - using OCRerConfig::set_bin_trim_threshold; +protected: + virtual void _set_roi(const Rect& roi) override { set_roi(roi); } - protected: - void postproc_rect_(Result& res) const; - void postproc_trim_(Result& res) const; - void postproc_replace_(Result& res) const; + // Not working for OCR with detection + using OCRerConfig::set_bin_expansion; + using OCRerConfig::set_bin_threshold; + using OCRerConfig::set_bin_trim_threshold; - bool filter_and_replace_by_required_(Result& res) const; +protected: + void postproc_rect_(Result& res) const; + void postproc_trim_(Result& res) const; + void postproc_replace_(Result& res) const; - private: - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - mutable ResultsVec m_result; - }; + bool filter_and_replace_by_required_(Result& res) const; + +private: + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + mutable ResultsVec m_result; +}; } diff --git a/src/MaaCore/Vision/OnnxHelper.h b/src/MaaCore/Vision/OnnxHelper.h index 165e52166d..ad6c30e408 100644 --- a/src/MaaCore/Vision/OnnxHelper.h +++ b/src/MaaCore/Vision/OnnxHelper.h @@ -4,31 +4,31 @@ namespace asst { - class OnnxHelper +class OnnxHelper +{ +public: + virtual ~OnnxHelper() = default; + +protected: + template + inline static T softmax(const T& input) { - public: - virtual ~OnnxHelper() = default; - - protected: - template - inline static T softmax(const T& input) - { - T output = input; - float rowmax = *std::max_element(output.begin(), output.end()); - std::vector y(output.size()); - float sum = 0.0f; - for (size_t i = 0; i != output.size(); ++i) { - sum += y[i] = std::exp(output[i] - rowmax); - } - for (size_t i = 0; i != output.size(); ++i) { - output[i] = y[i] / sum; - } - return output; + T output = input; + float rowmax = *std::max_element(output.begin(), output.end()); + std::vector y(output.size()); + float sum = 0.0f; + for (size_t i = 0; i != output.size(); ++i) { + sum += y[i] = std::exp(output[i] - rowmax); } + for (size_t i = 0; i != output.size(); ++i) { + output[i] = y[i] / sum; + } + return output; + } - static std::vector image_to_tensor(const cv::Mat& image); + static std::vector image_to_tensor(const cv::Mat& image); - private: - static cv::Mat hwc_to_chw(const cv::Mat& src); - }; +private: + static cv::Mat hwc_to_chw(const cv::Mat& src); +}; } diff --git a/src/MaaCore/Vision/RegionOCRer.cpp b/src/MaaCore/Vision/RegionOCRer.cpp index d558edf489..e4edb7fc5a 100644 --- a/src/MaaCore/Vision/RegionOCRer.cpp +++ b/src/MaaCore/Vision/RegionOCRer.cpp @@ -21,7 +21,9 @@ RegionOCRer::ResultOpt RegionOCRer::analyze() const return std::nullopt; } auto expand_roi = [](Rect& roi, int exp) { - if (exp == 0) return; + if (exp == 0) { + return; + } roi.x -= exp; roi.y -= exp; roi.width += 2 * exp; diff --git a/src/MaaCore/Vision/RegionOCRer.h b/src/MaaCore/Vision/RegionOCRer.h index cf568262e9..1d6a79ddc9 100644 --- a/src/MaaCore/Vision/RegionOCRer.h +++ b/src/MaaCore/Vision/RegionOCRer.h @@ -3,31 +3,34 @@ namespace asst { - class RegionOCRer : public VisionHelper, public OCRerConfig - { - public: - using Result = OCRer::Result; - using ResultOpt = std::optional; +class RegionOCRer : public VisionHelper, public OCRerConfig +{ +public: + using Result = OCRer::Result; + using ResultOpt = std::optional; - public: - using VisionHelper::VisionHelper; - virtual ~RegionOCRer() override = default; +public: + using VisionHelper::VisionHelper; + virtual ~RegionOCRer() override = default; - ResultOpt analyze() const; - void set_use_raw(bool use_raw) { m_use_raw = use_raw; } - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - const auto& get_result() const noexcept { return m_result; } + ResultOpt analyze() const; - protected: - using OCRerConfig::set_without_det; - virtual void _set_roi(const Rect& roi) override { set_roi(roi); } + void set_use_raw(bool use_raw) { m_use_raw = use_raw; } - void bin_left_trim(cv::Mat& bin) const; - void bin_right_trim(cv::Mat& bin) const; + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + const auto& get_result() const noexcept { return m_result; } - private: - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - mutable Result m_result; - bool m_use_raw = true; - }; +protected: + using OCRerConfig::set_without_det; + + virtual void _set_roi(const Rect& roi) override { set_roi(roi); } + + void bin_left_trim(cv::Mat& bin) const; + void bin_right_trim(cv::Mat& bin) const; + +private: + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + mutable Result m_result; + bool m_use_raw = true; +}; } diff --git a/src/MaaCore/Vision/Roguelike/RoguelikeFormationImageAnalyzer.cpp b/src/MaaCore/Vision/Roguelike/RoguelikeFormationImageAnalyzer.cpp index b513901b65..46e2370a36 100644 --- a/src/MaaCore/Vision/Roguelike/RoguelikeFormationImageAnalyzer.cpp +++ b/src/MaaCore/Vision/Roguelike/RoguelikeFormationImageAnalyzer.cpp @@ -43,8 +43,8 @@ bool asst::RoguelikeFormationImageAnalyzer::analyze() return !m_result.empty(); } -const std::vector& asst::RoguelikeFormationImageAnalyzer:: - get_result() const noexcept +const std::vector& + asst::RoguelikeFormationImageAnalyzer::get_result() const noexcept { return m_result; } diff --git a/src/MaaCore/Vision/Roguelike/RoguelikeFormationImageAnalyzer.h b/src/MaaCore/Vision/Roguelike/RoguelikeFormationImageAnalyzer.h index 1d6d6a6976..213823b942 100644 --- a/src/MaaCore/Vision/Roguelike/RoguelikeFormationImageAnalyzer.h +++ b/src/MaaCore/Vision/Roguelike/RoguelikeFormationImageAnalyzer.h @@ -3,32 +3,32 @@ namespace asst { - class RoguelikeFormationImageAnalyzer final : public VisionHelper +class RoguelikeFormationImageAnalyzer final : public VisionHelper +{ +public: + struct FormationOper { - public: - struct FormationOper - { - Rect rect; - bool selected = false; - std::string name; - int page = 0; - // TODO - }; - - public: - using VisionHelper::VisionHelper; - virtual ~RoguelikeFormationImageAnalyzer() override = default; - - bool analyze(); - - const std::vector& get_result() const noexcept; - - protected: - // 该分析器不支持外部设置ROI - using VisionHelper::set_roi; - - bool selected_analyze(const Rect& roi); - - std::vector m_result; + Rect rect; + bool selected = false; + std::string name; + int page = 0; + // TODO }; + +public: + using VisionHelper::VisionHelper; + virtual ~RoguelikeFormationImageAnalyzer() override = default; + + bool analyze(); + + const std::vector& get_result() const noexcept; + +protected: + // 该分析器不支持外部设置ROI + using VisionHelper::set_roi; + + bool selected_analyze(const Rect& roi); + + std::vector m_result; +}; } diff --git a/src/MaaCore/Vision/Roguelike/RoguelikeParameterAnalyzer.h b/src/MaaCore/Vision/Roguelike/RoguelikeParameterAnalyzer.h index 8aef67638b..39c8f7a127 100644 --- a/src/MaaCore/Vision/Roguelike/RoguelikeParameterAnalyzer.h +++ b/src/MaaCore/Vision/Roguelike/RoguelikeParameterAnalyzer.h @@ -13,14 +13,14 @@ public: using VisionHelper::VisionHelper; virtual ~RoguelikeParameterAnalyzer() noexcept override = default; - //bool analyze(); + // bool analyze(); int get_number(const cv::Mat& image, const std::string& task_name); // int update_hope(const cv::Mat& image); int update_hp(const cv::Mat& image); // int update_formation_upper_limit(const cv::Mat& image); - + // 识别萨米肉鸽抗干扰 int update_chaos(const cv::Mat& image); diff --git a/src/MaaCore/Vision/Roguelike/RoguelikeRecruitImageAnalyzer.cpp b/src/MaaCore/Vision/Roguelike/RoguelikeRecruitImageAnalyzer.cpp index a0a8059918..4de2503c4a 100644 --- a/src/MaaCore/Vision/Roguelike/RoguelikeRecruitImageAnalyzer.cpp +++ b/src/MaaCore/Vision/Roguelike/RoguelikeRecruitImageAnalyzer.cpp @@ -13,8 +13,9 @@ bool asst::RoguelikeRecruitImageAnalyzer::analyze() TemplDetOCRer analyzer(m_image); analyzer.set_task_info("RoguelikeRecruitOcrFlag", "RoguelikeRecruitOcr"); - analyzer.set_replace(Task.get("CharsNameOcrReplace")->replace_map, - Task.get("CharsNameOcrReplace")->replace_full); + analyzer.set_replace( + Task.get("CharsNameOcrReplace")->replace_map, + Task.get("CharsNameOcrReplace")->replace_full); analyzer.set_bin_threshold(Task.get("RoguelikeRecruitOcr")->specific_rect.x); auto result_opt = analyzer.analyze(); diff --git a/src/MaaCore/Vision/Roguelike/RoguelikeRecruitImageAnalyzer.h b/src/MaaCore/Vision/Roguelike/RoguelikeRecruitImageAnalyzer.h index be657c7f01..426030fd12 100644 --- a/src/MaaCore/Vision/Roguelike/RoguelikeRecruitImageAnalyzer.h +++ b/src/MaaCore/Vision/Roguelike/RoguelikeRecruitImageAnalyzer.h @@ -5,20 +5,20 @@ namespace asst { - class RoguelikeRecruitImageAnalyzer final : public VisionHelper - { - public: - using VisionHelper::VisionHelper; - virtual ~RoguelikeRecruitImageAnalyzer() noexcept override = default; +class RoguelikeRecruitImageAnalyzer final : public VisionHelper +{ +public: + using VisionHelper::VisionHelper; + virtual ~RoguelikeRecruitImageAnalyzer() noexcept override = default; - bool analyze(); + bool analyze(); - const auto& get_result() const noexcept { return m_result; } + const auto& get_result() const noexcept { return m_result; } - private: - int match_elite(const Rect& raw_roi); - static int match_level(const cv::Mat& image, const Rect& raw_roi); +private: + int match_elite(const Rect& raw_roi); + static int match_level(const cv::Mat& image, const Rect& raw_roi); - std::vector m_result; - }; + std::vector m_result; +}; } diff --git a/src/MaaCore/Vision/Roguelike/RoguelikeRecruitSupportAnalyzer.cpp b/src/MaaCore/Vision/Roguelike/RoguelikeRecruitSupportAnalyzer.cpp index 672ccd4b78..4461cb4f3c 100644 --- a/src/MaaCore/Vision/Roguelike/RoguelikeRecruitSupportAnalyzer.cpp +++ b/src/MaaCore/Vision/Roguelike/RoguelikeRecruitSupportAnalyzer.cpp @@ -23,7 +23,9 @@ bool asst::RoguelikeRecruitSupportAnalyzer::analyze() const auto& task = Task.get("RoguelikeChooseSupportBtnOcr"); analyzer.set_roi(task->roi); analyzer.set_required(task->text); - if (!analyzer.analyze()) return false; + if (!analyzer.analyze()) { + return false; + } m_choose_support_result = analyzer.get_result().front().rect; Log.info(__FUNCTION__, "| ChooseSupportBtn"); return true; @@ -33,9 +35,12 @@ bool asst::RoguelikeRecruitSupportAnalyzer::analyze() OCRer analyzer(m_image); analyzer.set_roi(Task.get("RoguelikeRecruitSupportOcr")->roi); analyzer.set_required(m_required); - analyzer.set_replace(Task.get("CharsNameOcrReplace")->replace_map, - Task.get("CharsNameOcrReplace")->replace_full); - if (!analyzer.analyze()) return false; + analyzer.set_replace( + Task.get("CharsNameOcrReplace")->replace_map, + Task.get("CharsNameOcrReplace")->replace_full); + if (!analyzer.analyze()) { + return false; + } const auto& char_name_rects = analyzer.get_result(); const auto& task_off1 = Task.get("RoguelikeRecruitSupportOff1"); @@ -64,7 +69,10 @@ bool asst::RoguelikeRecruitSupportAnalyzer::analyze() int char_elite = match_elite(elite_roi, task_off_elite->special_params.front()); battle::roguelike::RecruitSupportCharInfo char_info { - { char_rect.text, char_rect.rect, char_elite, char_level }, is_friend, char_elite, char_level + { char_rect.text, char_rect.rect, char_elite, char_level }, + is_friend, + char_elite, + char_level }; // 助战招募最多精一 @@ -84,9 +92,16 @@ bool asst::RoguelikeRecruitSupportAnalyzer::analyze() } } - Log.info(__FUNCTION__, "| AnalyzeChars append ", char_info.oper_info.name, char_info.oper_info.rect, - char_info.oper_info.elite, char_info.oper_info.level, is_friend, char_info.max_elite, - char_info.max_level); + Log.info( + __FUNCTION__, + "| AnalyzeChars append ", + char_info.oper_info.name, + char_info.oper_info.rect, + char_info.oper_info.elite, + char_info.oper_info.level, + is_friend, + char_info.max_elite, + char_info.max_level); m_char_result.push_back(char_info); } return !m_char_result.empty(); diff --git a/src/MaaCore/Vision/Roguelike/RoguelikeRecruitSupportAnalyzer.h b/src/MaaCore/Vision/Roguelike/RoguelikeRecruitSupportAnalyzer.h index 9695bf8e33..fb16ae10f5 100644 --- a/src/MaaCore/Vision/Roguelike/RoguelikeRecruitSupportAnalyzer.h +++ b/src/MaaCore/Vision/Roguelike/RoguelikeRecruitSupportAnalyzer.h @@ -5,30 +5,33 @@ namespace asst { - class RoguelikeRecruitSupportAnalyzer final : public VisionHelper - { - public: - using VisionHelper::VisionHelper; - virtual ~RoguelikeRecruitSupportAnalyzer() noexcept override = default; +class RoguelikeRecruitSupportAnalyzer final : public VisionHelper +{ +public: + using VisionHelper::VisionHelper; + virtual ~RoguelikeRecruitSupportAnalyzer() noexcept override = default; - bool analyze(); + bool analyze(); - void set_mode(battle::roguelike::SupportAnalyzeMode mode) noexcept { m_mode = mode; } - void set_required(std::vector required) noexcept { m_required = required; } + void set_mode(battle::roguelike::SupportAnalyzeMode mode) noexcept { m_mode = mode; } - const auto& get_result_choose_support() { return m_choose_support_result; } - const auto& get_result_char() { return m_char_result; } - const auto& get_result_refresh() { return m_refresh_result; } + void set_required(std::vector required) noexcept { m_required = required; } - private: - battle::roguelike::SupportAnalyzeMode m_mode = battle::roguelike::SupportAnalyzeMode::ChooseSupportBtn; - Rect m_choose_support_result; - battle::roguelike::RefreshSupportInfo m_refresh_result; - std::vector m_char_result; - std::vector m_required; + const auto& get_result_choose_support() { return m_choose_support_result; } - int judge_is_friend(const Rect& roi, const double r_threshold); - int match_elite(const Rect& roi, const int threshold); - int match_level(const Rect& roi); - }; + const auto& get_result_char() { return m_char_result; } + + const auto& get_result_refresh() { return m_refresh_result; } + +private: + battle::roguelike::SupportAnalyzeMode m_mode = battle::roguelike::SupportAnalyzeMode::ChooseSupportBtn; + Rect m_choose_support_result; + battle::roguelike::RefreshSupportInfo m_refresh_result; + std::vector m_char_result; + std::vector m_required; + + int judge_is_friend(const Rect& roi, const double r_threshold); + int match_elite(const Rect& roi, const int threshold); + int match_level(const Rect& roi); +}; } diff --git a/src/MaaCore/Vision/Roguelike/RoguelikeSkillSelectionImageAnalyzer.cpp b/src/MaaCore/Vision/Roguelike/RoguelikeSkillSelectionImageAnalyzer.cpp index b9072b3d9c..9fde88aa59 100644 --- a/src/MaaCore/Vision/Roguelike/RoguelikeSkillSelectionImageAnalyzer.cpp +++ b/src/MaaCore/Vision/Roguelike/RoguelikeSkillSelectionImageAnalyzer.cpp @@ -54,8 +54,9 @@ std::string asst::RoguelikeSkillSelectionImageAnalyzer::name_analyze(const Rect& analyzer.set_task_info(name_task_ptr); analyzer.set_image(m_image); analyzer.set_roi(roi.move(name_task_ptr->roi)); - analyzer.set_replace(std::dynamic_pointer_cast(Task.get("CharsNameOcrReplace"))->replace_map, - std::dynamic_pointer_cast(Task.get("CharsNameOcrReplace"))->replace_full); + analyzer.set_replace( + std::dynamic_pointer_cast(Task.get("CharsNameOcrReplace"))->replace_map, + std::dynamic_pointer_cast(Task.get("CharsNameOcrReplace"))->replace_full); if (!analyzer.analyze()) { return {}; diff --git a/src/MaaCore/Vision/Roguelike/RoguelikeSkillSelectionImageAnalyzer.h b/src/MaaCore/Vision/Roguelike/RoguelikeSkillSelectionImageAnalyzer.h index e48ed51b79..afe437cb42 100644 --- a/src/MaaCore/Vision/Roguelike/RoguelikeSkillSelectionImageAnalyzer.h +++ b/src/MaaCore/Vision/Roguelike/RoguelikeSkillSelectionImageAnalyzer.h @@ -3,29 +3,30 @@ namespace asst { - class RoguelikeSkillSelectionImageAnalyzer final : public VisionHelper - { - public: - static constexpr size_t MaxNumOfSkills = 3; +class RoguelikeSkillSelectionImageAnalyzer final : public VisionHelper +{ +public: + static constexpr size_t MaxNumOfSkills = 3; - public: - using VisionHelper::VisionHelper; - virtual ~RoguelikeSkillSelectionImageAnalyzer() override = default; +public: + using VisionHelper::VisionHelper; + virtual ~RoguelikeSkillSelectionImageAnalyzer() override = default; - bool analyze(); + bool analyze(); - const auto& get_result() const noexcept { return m_result; } - bool get_team_full() const noexcept { return m_team_full; } + const auto& get_result() const noexcept { return m_result; } - private: - // 该分析器不支持外部设置ROI - using VisionHelper::set_roi; + bool get_team_full() const noexcept { return m_team_full; } - std::string name_analyze(const Rect& roi); - std::vector skill_analyze(const Rect& roi); - void team_full_analyze(); +private: + // 该分析器不支持外部设置ROI + using VisionHelper::set_roi; - std::unordered_map> m_result; // 干员名 : 技能的位置(多个技能) - bool m_team_full = false; - }; + std::string name_analyze(const Rect& roi); + std::vector skill_analyze(const Rect& roi); + void team_full_analyze(); + + std::unordered_map> m_result; // 干员名 : 技能的位置(多个技能) + bool m_team_full = false; +}; } diff --git a/src/MaaCore/Vision/TemplDetOCRer.h b/src/MaaCore/Vision/TemplDetOCRer.h index adae8cc527..1d81731dd6 100644 --- a/src/MaaCore/Vision/TemplDetOCRer.h +++ b/src/MaaCore/Vision/TemplDetOCRer.h @@ -5,45 +5,47 @@ namespace asst { - class TemplDetOCRer : public VisionHelper, public OCRerConfig, public MatcherConfig +class TemplDetOCRer : public VisionHelper, public OCRerConfig, public MatcherConfig +{ +public: + struct Result : public TextRect { - public: - struct Result : public TextRect - { - Rect flag_rect; - double flag_score = .0; - }; - - using ResultsVec = std::vector; - using ResultsVecOpt = std::optional; - - public: - using VisionHelper::VisionHelper; - virtual ~TemplDetOCRer() override = default; - - void set_task_info(const std::string& templ_task_name, const std::string& ocr_task_name); - void set_flag_rect_move(Rect flag_rect_move); - void set_ocr_use_raw(bool use_raw) { m_use_raw = use_raw; } - - ResultsVecOpt analyze() const; - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - const auto& get_result() const noexcept { return m_result; } - - protected: - // from Config - virtual void _set_roi(const Rect& roi) override { std::ignore = roi; } - - protected: - using MatcherConfig::set_task_info; - using OCRerConfig::set_task_info; - using OCRerConfig::set_without_det; - - private: - Rect m_flag_rect_move; - bool m_use_raw = true; - - private: - // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 - mutable ResultsVec m_result; + Rect flag_rect; + double flag_score = .0; }; + + using ResultsVec = std::vector; + using ResultsVecOpt = std::optional; + +public: + using VisionHelper::VisionHelper; + virtual ~TemplDetOCRer() override = default; + + void set_task_info(const std::string& templ_task_name, const std::string& ocr_task_name); + void set_flag_rect_move(Rect flag_rect_move); + + void set_ocr_use_raw(bool use_raw) { m_use_raw = use_raw; } + + ResultsVecOpt analyze() const; + + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + const auto& get_result() const noexcept { return m_result; } + +protected: + // from Config + virtual void _set_roi(const Rect& roi) override { std::ignore = roi; } + +protected: + using MatcherConfig::set_task_info; + using OCRerConfig::set_task_info; + using OCRerConfig::set_without_det; + +private: + Rect m_flag_rect_move; + bool m_use_raw = true; + +private: + // FIXME: 老接口太难重构了,先弄个这玩意兼容下,后续慢慢全删掉 + mutable ResultsVec m_result; +}; } diff --git a/src/MaaCore/Vision/VisionHelper.cpp b/src/MaaCore/Vision/VisionHelper.cpp index f5e33d6ff0..996e8eafa4 100644 --- a/src/MaaCore/Vision/VisionHelper.cpp +++ b/src/MaaCore/Vision/VisionHelper.cpp @@ -11,14 +11,17 @@ using namespace asst; -VisionHelper::VisionHelper(const cv::Mat& image, const Rect& roi, Assistant* inst) - : InstHelper(inst), m_image(image) +VisionHelper::VisionHelper(const cv::Mat& image, const Rect& roi, Assistant* inst) : + InstHelper(inst), + m_image(image) #ifdef ASST_DEBUG - , - m_image_draw(image.clone()) + , + m_image_draw(image.clone()) #endif - , m_roi(correct_rect(roi, image)) -{} + , + m_roi(correct_rect(roi, image)) +{ +} void VisionHelper::set_image(const cv::Mat& image) { diff --git a/src/MaaCore/Vision/VisionHelper.h b/src/MaaCore/Vision/VisionHelper.h index 0e116aa2d5..af74df137a 100644 --- a/src/MaaCore/Vision/VisionHelper.h +++ b/src/MaaCore/Vision/VisionHelper.h @@ -12,128 +12,128 @@ namespace asst { - class TaskData; - class Status; - class Assistant; +class TaskData; +class Status; +class Assistant; } namespace asst { - class VisionHelper : protected InstHelper - { - public: - VisionHelper() = default; - VisionHelper(const cv::Mat& image, const Rect& roi = Rect(), Assistant* inst = nullptr); - virtual ~VisionHelper() = default; +class VisionHelper : protected InstHelper +{ +public: + VisionHelper() = default; + VisionHelper(const cv::Mat& image, const Rect& roi = Rect(), Assistant* inst = nullptr); + virtual ~VisionHelper() = default; - virtual void set_image(const cv::Mat& image); - virtual void set_roi(const Rect& roi); - virtual void set_log_tracing(bool enable); + virtual void set_image(const cv::Mat& image); + virtual void set_roi(const Rect& roi); + virtual void set_log_tracing(bool enable); - bool save_img(const std::filesystem::path& relative_dir = utils::path("debug")); + bool save_img(const std::filesystem::path& relative_dir = utils::path("debug")); #ifdef ASST_DEBUG - const cv::Mat& get_draw() const { return m_image_draw; } + const cv::Mat& get_draw() const { return m_image_draw; } #endif - protected: - using InstHelper::status; +protected: + using InstHelper::status; - protected: - static Rect correct_rect(const Rect& rect, const cv::Mat& image); +protected: + static Rect correct_rect(const Rect& rect, const cv::Mat& image); - cv::Mat m_image; + cv::Mat m_image; #ifdef ASST_DEBUG - cv::Mat m_image_draw; + cv::Mat m_image_draw; #endif - Rect m_roi; - bool m_log_tracing = true; + Rect m_roi; + bool m_log_tracing = true; - private: - using InstHelper::ctrler; - using InstHelper::need_exit; - }; +private: + using InstHelper::ctrler; + using InstHelper::need_exit; +}; - template - inline static cv::Mat make_roi(const cv::Mat& img, const RectTy& roi) - { - return img(make_rect(roi)); +template +inline static cv::Mat make_roi(const cv::Mat& img, const RectTy& roi) +{ + return img(make_rect(roi)); +} + +// | 1 2 3 4 | +// | 5 6 7 8 | +template +inline static void sort_by_horizontal_(ResultsVec& results) +{ + ranges::sort(results, [](const auto& lhs, const auto& rhs) -> bool { + // y 差距较小则理解为是同一排的,按x排序 + return std::abs(lhs.rect.y - rhs.rect.y) < 5 ? lhs.rect.x < rhs.rect.x : lhs.rect.y < rhs.rect.y; + }); +} + +// | 1 3 5 7 | +// | 2 4 6 8 | +template +inline static void sort_by_vertical_(ResultsVec& results) +{ + ranges::sort(results, [](const auto& lhs, const auto& rhs) -> bool { + // x 差距较小则理解为是同一排的,按y排序 + return std::abs(lhs.rect.x - rhs.rect.x) < 5 ? lhs.rect.y < rhs.rect.y : lhs.rect.x < rhs.rect.x; + }); +} + +template +inline static void sort_by_score_(ResultsVec& results) +{ + ranges::sort(results, std::greater {}, std::mem_fn(&ResultsVec::value_type::score)); +} + +template +inline static void sort_by_required_(ResultsVec& results, const std::vector& required) +{ + std::unordered_map req_cache; + for (size_t i = 0; i != required.size(); ++i) { + req_cache.emplace(required.at(i), i + 1); } - // | 1 2 3 4 | - // | 5 6 7 8 | - template - inline static void sort_by_horizontal_(ResultsVec& results) - { - ranges::sort(results, [](const auto& lhs, const auto& rhs) -> bool { - // y 差距较小则理解为是同一排的,按x排序 - return std::abs(lhs.rect.y - rhs.rect.y) < 5 ? lhs.rect.x < rhs.rect.x : lhs.rect.y < rhs.rect.y; - }); - } - - // | 1 3 5 7 | - // | 2 4 6 8 | - template - inline static void sort_by_vertical_(ResultsVec& results) - { - ranges::sort(results, [](const auto& lhs, const auto& rhs) -> bool { - // x 差距较小则理解为是同一排的,按y排序 - return std::abs(lhs.rect.x - rhs.rect.x) < 5 ? lhs.rect.y < rhs.rect.y : lhs.rect.x < rhs.rect.x; - }); - } - - template - inline static void sort_by_score_(ResultsVec& results) - { - ranges::sort(results, std::greater {}, std::mem_fn(&ResultsVec::value_type::score)); - } - - template - inline static void sort_by_required_(ResultsVec& results, const std::vector& required) - { - std::unordered_map req_cache; - for (size_t i = 0; i != required.size(); ++i) { - req_cache.emplace(required.at(i), i + 1); + // 不在 required 中的将被排在最后 + ranges::sort(results, [&req_cache](const auto& lhs, const auto& rhs) -> bool { + size_t lvalue = req_cache[lhs.text]; + size_t rvalue = req_cache[rhs.text]; + if (lvalue == 0) { + return false; } + else if (rvalue == 0) { + return true; + } + return lvalue < rvalue; + }); +} - // 不在 required 中的将被排在最后 - ranges::sort(results, [&req_cache](const auto& lhs, const auto& rhs) -> bool { - size_t lvalue = req_cache[lhs.text]; - size_t rvalue = req_cache[rhs.text]; - if (lvalue == 0) { - return false; - } - else if (rvalue == 0) { - return true; - } - return lvalue < rvalue; - }); - } +// Non-Maximum Suppression +template +inline static ResultsVec NMS(ResultsVec results, double threshold = 0.7) +{ + ranges::sort(results, [](const auto& a, const auto& b) { return a.score > b.score; }); - // Non-Maximum Suppression - template - inline static ResultsVec NMS(ResultsVec results, double threshold = 0.7) - { - ranges::sort(results, [](const auto& a, const auto& b) { return a.score > b.score; }); - - ResultsVec nms_results; - for (size_t i = 0; i < results.size(); ++i) { - const auto& box = results[i]; - if (box.score < 0.1f) { + ResultsVec nms_results; + for (size_t i = 0; i < results.size(); ++i) { + const auto& box = results[i]; + if (box.score < 0.1f) { + continue; + } + nms_results.emplace_back(box); + for (size_t j = i + 1; j < results.size(); ++j) { + auto& box2 = results[j]; + if (box2.score < 0.1f) { continue; } - nms_results.emplace_back(box); - for (size_t j = i + 1; j < results.size(); ++j) { - auto& box2 = results[j]; - if (box2.score < 0.1f) { - continue; - } - int iou_area = (make_rect(box.rect) & make_rect(box2.rect)).area(); - if (iou_area > threshold * box2.rect.area()) { - box2.score = 0; - } + int iou_area = (make_rect(box.rect) & make_rect(box2.rect)).area(); + if (iou_area > threshold * box2.rect.area()) { + box2.score = 0; } } - return nms_results; } + return nms_results; +} } // namespace asst