diff --git a/src/MaaCore/Task/Roguelike/JieGarden/RoguelikeCoppersTaskPlugin.cpp b/src/MaaCore/Task/Roguelike/JieGarden/RoguelikeCoppersTaskPlugin.cpp index a550118347..85e6335f1f 100644 --- a/src/MaaCore/Task/Roguelike/JieGarden/RoguelikeCoppersTaskPlugin.cpp +++ b/src/MaaCore/Task/Roguelike/JieGarden/RoguelikeCoppersTaskPlugin.cpp @@ -87,6 +87,7 @@ bool asst::RoguelikeCoppersTaskPlugin::_run() success = handle_pickup_mode(); break; case CoppersTaskRunMode::EXCHANGE: + m_retry_times = 1; // 交换模式只尝试两次 success = handle_exchange_mode(); break; } @@ -120,6 +121,8 @@ bool asst::RoguelikeCoppersTaskPlugin::handle_pickup_mode() return false; } + asst::Point click_point_fallback(0, 0); + // 遍历每个检测到的通宝,创建通宝对象 for (size_t i = 0; i < detections.size(); ++i) { const auto& detection = detections[i]; @@ -129,7 +132,9 @@ bool asst::RoguelikeCoppersTaskPlugin::handle_pickup_mode() // 根据识别到的名称创建通宝对象 auto copper_opt = create_copper_from_name(detection.name, 1, static_cast(i), false, detection.name_roi); if (!copper_opt) { - LogError << __FUNCTION__ << "| failed to create copper at position" << i; + LogError << __FUNCTION__ << "| failed to create copper at position" << i << " name:" << detection.name; + + click_point_fallback = detection.click_point; continue; } @@ -144,7 +149,13 @@ bool asst::RoguelikeCoppersTaskPlugin::handle_pickup_mode() if (m_pending_copper.empty()) { Log.error(__FUNCTION__, "| no valid coppers found for pickup"); - return false; + // 如果没有有效通宝,尝试点击最后一个检测到的名称错误的通宝位置作为回退 + if (click_point_fallback.x != 0 && click_point_fallback.y != 0) { + LogWarn << __FUNCTION__ << "| clicking fallback point at (" << click_point_fallback.x << "," + << click_point_fallback.y << ")"; + ctrler()->click(click_point_fallback); + return true; + } } // 从待选通宝中选择拾取优先级最高的 @@ -517,7 +528,7 @@ std::optional asst::RoguelikeCoppersTaskPlugin::create_co int col, int row, bool is_cast, - const Rect& pos) const + const Rect& pos) { // 从配置中查找通宝信息 if (auto found_copper = RoguelikeCoppers.find_copper(m_config->get_theme(), name)) { @@ -538,6 +549,11 @@ std::optional asst::RoguelikeCoppersTaskPlugin::create_co Log.error(__FUNCTION__, std::format("| copper not found in config: {}", name)); + // 将识别到的错误的名称发送到 WPF 进行反馈 + auto copper_info = basic_info_with_what("RoguelikeCoppersRecognitionError"); + copper_info["details"]["recognized_name"] = name; + callback(AsstMsg::SubTaskExtraInfo, copper_info); + // 如果通宝不在配置中,保存调试图像 try { cv::Mat screen = ctrler()->get_image(); @@ -545,7 +561,7 @@ std::optional asst::RoguelikeCoppersTaskPlugin::create_co cv::Mat screen_draw = screen.clone(); cv::rectangle(screen_draw, cv::Rect(pos.x, pos.y, pos.width, pos.height), cv::Scalar(0, 0, 255), 2); - save_debug_image(screen_draw, "unknown_draw"); + save_debug_image(screen_draw, "unknown_draw", false); } } catch (const std::exception& e) { @@ -596,7 +612,10 @@ void asst::RoguelikeCoppersTaskPlugin::draw_detection_debug( } // 保存调试图像到文件 -void asst::RoguelikeCoppersTaskPlugin::save_debug_image(const cv::Mat& image, const std::string& suffix) const +void asst::RoguelikeCoppersTaskPlugin::save_debug_image( + const cv::Mat& image, + const std::string& suffix, + bool auto_clean) const { try { const static std::vector jpeg_params = { cv::IMWRITE_JPEG_QUALITY, 95, cv::IMWRITE_JPEG_OPTIMIZE, 1 }; @@ -604,7 +623,7 @@ void asst::RoguelikeCoppersTaskPlugin::save_debug_image(const cv::Mat& image, co utils::save_debug_image( image, utils::path("debug") / "roguelike" / "coppers", - true, + auto_clean, "roguelikeCoppers debug", suffix, "jpeg", diff --git a/src/MaaCore/Task/Roguelike/JieGarden/RoguelikeCoppersTaskPlugin.h b/src/MaaCore/Task/Roguelike/JieGarden/RoguelikeCoppersTaskPlugin.h index dbacc37917..169f7ace4b 100644 --- a/src/MaaCore/Task/Roguelike/JieGarden/RoguelikeCoppersTaskPlugin.h +++ b/src/MaaCore/Task/Roguelike/JieGarden/RoguelikeCoppersTaskPlugin.h @@ -62,7 +62,7 @@ private: int row = 0, // 行位置 bool is_cast = false, // 是否已投出 const Rect& pos = Rect() // 位置信息,用于调试 - ) const; + ); // 调试绘制辅助函数,在图像上绘制检测结果 void draw_detection_debug( @@ -71,7 +71,7 @@ private: const cv::Scalar& color) const; // 保存调试图像到文件 - void save_debug_image(const cv::Mat& image, const std::string& suffix) const; + void save_debug_image(const cv::Mat& image, const std::string& suffix, bool auto_clean = true) const; mutable asst::CoppersTaskRunMode m_run_mode; // 当前运行模式 diff --git a/src/MaaWpfGui/Res/Localizations/en-us.xaml b/src/MaaWpfGui/Res/Localizations/en-us.xaml index 08f9d05617..deac251d79 100644 --- a/src/MaaWpfGui/Res/Localizations/en-us.xaml +++ b/src/MaaWpfGui/Res/Localizations/en-us.xaml @@ -1057,6 +1057,7 @@ Right-click to clear inactive jobs Bosky: Doubts Bosky: Turmoil Tongbao Exchange: {0} → {1} + Tongbao recognition failed: "{0}" Event:  Detected {0} options: Available option: {0} diff --git a/src/MaaWpfGui/Res/Localizations/ja-jp.xaml b/src/MaaWpfGui/Res/Localizations/ja-jp.xaml index 65617945ba..8548429a51 100644 --- a/src/MaaWpfGui/Res/Localizations/ja-jp.xaml +++ b/src/MaaWpfGui/Res/Localizations/ja-jp.xaml @@ -1058,6 +1058,7 @@ C:\\leidian\\LDPlayer9 スポット: 雑疑 スポット: 禍乱 通宝交換: {0} → {1} + 通宝認識失敗: 「{0}」 イベント: {0} 件の選択肢を検出しました: 選択可能な選択肢: {0} diff --git a/src/MaaWpfGui/Res/Localizations/ko-kr.xaml b/src/MaaWpfGui/Res/Localizations/ko-kr.xaml index 2eeccce35b..1cf7c54ab4 100644 --- a/src/MaaWpfGui/Res/Localizations/ko-kr.xaml +++ b/src/MaaWpfGui/Res/Localizations/ko-kr.xaml @@ -1059,6 +1059,7 @@ C:\\leidian\\LDPlayer9 잔식: 의문 잔식: 소란 주화 교환: {0} → {1} + 주화 인식 실패: "{0}" 이벤트: 선택지 {0}개 감지: 가능한 선택지: {0} diff --git a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml index 1a73f90190..4c1385e1a7 100644 --- a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml +++ b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml @@ -1058,6 +1058,7 @@ C:\\leidian\\LDPlayer9。\n 节点: 杂疑 节点: 灾祸 通宝交换: {0} → {1} + 通宝识别失败: "{0}" 事件: 识别到 {0} 个选项: 可选选项: {0} diff --git a/src/MaaWpfGui/Res/Localizations/zh-tw.xaml b/src/MaaWpfGui/Res/Localizations/zh-tw.xaml index 81468ef675..6d891c40f7 100644 --- a/src/MaaWpfGui/Res/Localizations/zh-tw.xaml +++ b/src/MaaWpfGui/Res/Localizations/zh-tw.xaml @@ -1059,6 +1059,7 @@ C:\\leidian\\LDPlayer9。\n 節點: 雜疑 節點: 災禍 通寶交換: {0} → {1} + 通寶識別失敗: "{0}" 事件: 識別到 {0} 個選項: 可選選項: {0} diff --git a/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/RoguelikeSettingsUserControlModel.cs b/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/RoguelikeSettingsUserControlModel.cs index 947c5831da..b96660639d 100644 --- a/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/RoguelikeSettingsUserControlModel.cs +++ b/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/RoguelikeSettingsUserControlModel.cs @@ -1126,6 +1126,14 @@ public class RoguelikeSettingsUserControlModel : TaskViewModel break; } + case "RoguelikeCoppersRecognitionError": + { + var recognizedName = subTaskDetails!["recognized_name"]?.ToString() ?? "Unknown"; + var message = string.Format(LocalizationHelper.GetString("RoguelikeCoppersRecognitionError"), recognizedName); + Instances.TaskQueueViewModel.AddLog(message, UiLogColor.Error); + break; + } + case "RoguelikeCoppersExchangeInfo": { var toDiscard = subTaskDetails!["to_discard"]?.ToString() ?? "Unknown";