diff --git a/MAA.sln.DotSettings b/MAA.sln.DotSettings index 6aa01a9b05..784fa2b25f 100644 --- a/MAA.sln.DotSettings +++ b/MAA.sln.DotSettings @@ -41,6 +41,7 @@ True True True + True True True True @@ -51,6 +52,7 @@ True True True + True True True True diff --git a/resource/config.json b/resource/config.json index 6d2cc61874..fd12efaec7 100644 --- a/resource/config.json +++ b/resource/config.json @@ -3,6 +3,12 @@ "options": { "taskDelay": 500, "taskDelay_Doc": "识别的延迟:越快识别频率越快,但会增加CPU消耗。单位毫秒,默认500", + "SSSFightScreencapInterval": 0, + "SSSFightScreencapInterval_Doc": "保全战斗截图最小间隔", + "RoguelikeFightScreencapInterval": 100, + "RoguelikeFightScreencapInterval_Doc": "肉鸽战斗截图最小间隔", + "CopilotFightScreencapInterval": 0, + "CopilotFightScreencapInterval_Doc": "抄作业战斗截图最小间隔", "controlDelayRange": [ 0, 0 diff --git a/src/MaaCore/Config/GeneralConfig.cpp b/src/MaaCore/Config/GeneralConfig.cpp index 5e3e01e865..51b0e57fdd 100644 --- a/src/MaaCore/Config/GeneralConfig.cpp +++ b/src/MaaCore/Config/GeneralConfig.cpp @@ -19,6 +19,9 @@ bool asst::GeneralConfig::parse(const json::value& json) { const json::value& options_json = json.at("options"); m_options.task_delay = options_json.at("taskDelay").as_integer(); + m_options.sss_fight_screencap_interval = options_json.at("SSSFightScreencapInterval").as_integer(); + m_options.roguelike_fight_screencap_interval = options_json.at("RoguelikeFightScreencapInterval").as_integer(); + m_options.copilot_fight_screencap_interval = options_json.at("CopilotFightScreencapInterval").as_integer(); m_options.control_delay_lower = options_json.at("controlDelayRange")[0].as_integer(); m_options.control_delay_upper = options_json.at("controlDelayRange")[1].as_integer(); // m_options.print_window = options_json.at("printWindow").as_boolean(); diff --git a/src/MaaCore/Config/GeneralConfig.h b/src/MaaCore/Config/GeneralConfig.h index cf0fef6dd4..9101a26d69 100644 --- a/src/MaaCore/Config/GeneralConfig.h +++ b/src/MaaCore/Config/GeneralConfig.h @@ -34,6 +34,9 @@ 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; // 点击随机延时上限:每次点击操作会进行随机延时 // bool print_window = false;// 截图功能:开启后每次结算界面会截图到screenshot目录下 diff --git a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp index a40ea28250..3f6a77e950 100644 --- a/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/BattleProcessTask.cpp @@ -167,9 +167,22 @@ 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 constexpr 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]] { + Log.debug("Sleeping for framerate limit"); + std::this_thread::sleep_for(min_frame_interval - (now - prev_frame_time)); + } + if (!wait_condition(action)) { return false; } + + prev_frame_time = std::chrono::steady_clock::now(); + if (action.pre_delay > 0) { sleep_and_do_strategy(action.pre_delay); // 等待之后画面可能会变化,更新下干员信息 diff --git a/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.cpp index f4eaa30749..040f45fe64 100644 --- a/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/RoguelikeBattleTaskPlugin.cpp @@ -454,8 +454,8 @@ bool asst::RoguelikeBattleTaskPlugin::do_once() check_drone_tiles(); // TODO: move this to controller - static thread_local auto prev_frame_time = std::chrono::steady_clock::time_point {}; - static constexpr auto min_frame_interval = std::chrono::milliseconds(100); + thread_local auto prev_frame_time = std::chrono::steady_clock::time_point {}; + static constexpr auto min_frame_interval = std::chrono::milliseconds(Config.get_options().roguelike_fight_screencap_interval); // prevent our program from consuming too much CPU if (const auto now = std::chrono::steady_clock::now(); diff --git a/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp b/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp index 76df0fa311..08b6aa665e 100644 --- a/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp +++ b/src/MaaCore/Task/SSS/SSSBattleProcessTask.cpp @@ -94,7 +94,19 @@ bool asst::SSSBattleProcessTask::do_derived_action(const battle::copilot::Action bool asst::SSSBattleProcessTask::do_strategic_action(const cv::Mat& reusable) { LogTraceFunction; + + thread_local auto prev_frame_time = std::chrono::steady_clock::time_point {}; + static constexpr auto min_frame_interval = std::chrono::milliseconds(Config.get_options().sss_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]] { + Log.debug("Sleeping for framerate limit"); + std::this_thread::sleep_for(min_frame_interval - (now - prev_frame_time)); + } + cv::Mat image = reusable.empty() ? ctrler()->get_image() : reusable; + prev_frame_time = std::chrono::steady_clock::now(); if (check_and_get_drops(image)) { return true;