diff --git a/resource/tasks.json b/resource/tasks.json
index 739384c921..0653018721 100644
--- a/resource/tasks.json
+++ b/resource/tasks.json
@@ -8586,6 +8586,18 @@
20
]
},
+ "ScreenshotTaskPlugin-Config": {
+ "Doc": "本任务是插件 ScreenshotTaskPlugin 的配置",
+ "Doc_2": "需要在任务 Task 开始时截图时,将 Task 加入到此任务的 next 列表。",
+ "algorithm": "JustReturn",
+ "next": []
+ },
+ "ScreenshotTaskPlugin-Config-Debug": {
+ "Doc": "本任务是插件 ScreenshotTaskPlugin 的配置",
+ "Doc_2": "存在 DEBUG 或 DEBUG.txt 时的额外截图",
+ "algorithm": "JustReturn",
+ "next": []
+ },
"Roguelike@Abandon": {
"Doc": "base_task",
"template": "empty.png",
diff --git a/src/MaaCore/MaaCore.vcxproj b/src/MaaCore/MaaCore.vcxproj
index 39741b1b95..d6b4cf594e 100644
--- a/src/MaaCore/MaaCore.vcxproj
+++ b/src/MaaCore/MaaCore.vcxproj
@@ -74,6 +74,7 @@
+
@@ -240,6 +241,7 @@
+
diff --git a/src/MaaCore/MaaCore.vcxproj.filters b/src/MaaCore/MaaCore.vcxproj.filters
index c2157f5ddc..96bd5d7dc4 100644
--- a/src/MaaCore/MaaCore.vcxproj.filters
+++ b/src/MaaCore/MaaCore.vcxproj.filters
@@ -648,6 +648,9 @@
Source\Task\Roguelike
+
+ Source\Task\Miscellaneous
+
@@ -1079,5 +1082,8 @@
Source\Task\Roguelike
+
+ Source\Task\Miscellaneous
+
\ No newline at end of file
diff --git a/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.cpp b/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.cpp
new file mode 100644
index 0000000000..5b0604dc8b
--- /dev/null
+++ b/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.cpp
@@ -0,0 +1,50 @@
+#include "ScreenshotTaskPlugin.h"
+
+#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)
+{
+ m_screenshot_tasks.clear();
+ if (auto ptr = Task.get(config_name)) {
+ ranges::copy(ptr->next, std::back_inserter(m_screenshot_tasks));
+ }
+ else {
+ Log.info(__FUNCTION__, "| no config found");
+ }
+
+#ifndef ASST_DEBUG
+ bool need_save_debug_img = std::ifstream("DEBUG").good() || std::ifstream("DEBUG.txt").good();
+ if (!need_save_debug_img) {
+ return;
+ }
+#endif
+ if (auto ptr = Task.get(debug_config_name)) {
+ ranges::copy(ptr->next, std::back_inserter(m_screenshot_tasks));
+ }
+ else {
+ Log.info(__FUNCTION__, "| no debug config found");
+ }
+}
+
+bool asst::ScreenshotTaskPlugin::verify(AsstMsg msg, const json::value& details) const
+{
+ if (msg != AsstMsg::SubTaskStart || details.get("subtask", std::string()) != "ProcessTask") {
+ return false;
+ }
+
+ const std::string& task = details.get("details", "task", "");
+ if (ranges::any_of(m_screenshot_tasks, [&task](std::string_view item) { return task.ends_with(item); })) {
+ return true;
+ }
+
+ return false;
+}
+
+bool asst::ScreenshotTaskPlugin::_run()
+{
+ save_img(utils::path("debug") / utils::path(std::string(m_task_chain)));
+ return true;
+}
diff --git a/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.h b/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.h
new file mode 100644
index 0000000000..80bfea8811
--- /dev/null
+++ b/src/MaaCore/Task/Miscellaneous/ScreenshotTaskPlugin.h
@@ -0,0 +1,24 @@
+#pragma once
+#include "Task/AbstractTaskPlugin.h"
+
+namespace asst
+{
+ 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;
+
+ 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";
+
+ std::vector m_screenshot_tasks;
+ };
+}