diff --git a/CHANGELOG.md b/CHANGELOG.md index a4310bb692..518b18bf8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## v5.16.8 + +### 修复 | Fix + +* 自动编队干员Ocr左侧内缩过度 @status102 +* RegionOcr阈值过滤膨胀后超出原roi @status102 +* 自动编队roi溢出闪退 @status102 +* 修复roi超限 @status102 + +### 其他 | Other + +* 别再把 maa 放在 Program Files 里了 @ABA2396 + ## v5.16.7 ### 改进 | Improved diff --git a/resource/global/YoStarEN/resource/tasks/tasks.json b/resource/global/YoStarEN/resource/tasks/tasks.json index ad9d8eb5ef..eadbdd5b3b 100644 --- a/resource/global/YoStarEN/resource/tasks/tasks.json +++ b/resource/global/YoStarEN/resource/tasks/tasks.json @@ -1333,8 +1333,8 @@ "text": ["All"] }, "BattleQuickFormationOCR": { - "roi": [0, 231, 116, 22], - "specialParams": [105, 2, 7, 0] + "rectMove": [0, 231, 116, 22], + "specialParams": [105, 2, 7, 0, -3, 10] }, "BattleStartPre": { "text": ["Start", "Start Challenge"] diff --git a/resource/tasks/tasks.json b/resource/tasks/tasks.json index 35f5c5c2a5..5348f40f4a 100644 --- a/resource/tasks/tasks.json +++ b/resource/tasks/tasks.json @@ -2469,7 +2469,7 @@ }, "InfrastRotationClick": { "template": "InfrastQueueRotation.png", - "roi": [1020, 600, 150, 130], + "roi": [1020, 600, 150, 120], "action": "ClickSelf", "next": ["InfrastEnterTrim"] }, @@ -2481,7 +2481,7 @@ }, "InfrastTrimClick": { "template": "InfrastOperatorTrim.png", - "roi": [1020, 600, 150, 130], + "roi": [1020, 600, 150, 120], "postDelay": 1000, "action": "ClickSelf", "next": ["InfrastRotationReturn"] @@ -3598,10 +3598,18 @@ "algorithm": "OcrDetect", "fullMatch": true, "text": [], - "roi": [-2, 233, 118, 22], + "rectMove": [-2, 233, 118, 22], "postDelay": 200, "specialParams_Doc": "Added for the YostarEN client. Used in BattleFormationTask.cpp for OCR manipulation. CN values are from OCRerConfig.h", - "specialParams": [140, 2, 0, 0] + "specialParams_doc": [ + "bin_threshold", + "bin_expansion", + "trim_threshold_low", + "trim_threshold_high", + "左侧收缩时检测图的底部收缩", + "左侧收缩时连续n像素低于bin_thresh" + ], + "specialParams": [140, 2, 0, 0, -3, 10] }, "BattleQuickFormationSkill1": { "algorithm": "JustReturn", diff --git a/resource/version.json b/resource/version.json index 59b7d71db6..7392baf187 100644 --- a/resource/version.json +++ b/resource/version.json @@ -7,5 +7,5 @@ "pool": "定向甄选", "time": 1747296000 }, - "last_updated": "2025-05-14 10:07:00.704" + "last_updated": "2025-05-15 11:07:00.705" } diff --git a/src/MaaCore/Task/Miscellaneous/BattleFormationTask.cpp b/src/MaaCore/Task/Miscellaneous/BattleFormationTask.cpp index b2401b1bbb..e9076d8b9a 100644 --- a/src/MaaCore/Task/Miscellaneous/BattleFormationTask.cpp +++ b/src/MaaCore/Task/Miscellaneous/BattleFormationTask.cpp @@ -364,7 +364,22 @@ std::vector continue; } for (const auto& flag : multi.get_result()) { - ocr = make_roi(image, flag.rect.move(ocr_task->roi)); + auto roi = flag.rect.move(ocr_task->rect_move); + if (roi.x < 0) { + roi.x = 0; + roi.width = roi.width + roi.x; + } + if (roi.y < 0) { + roi.y = 0; + roi.height = roi.height + roi.y; + } + if (roi.x + roi.width > image.cols) { + roi.width = image.cols - roi.x; + } + if (roi.y + roi.height > image.rows) { + roi.height = image.rows - roi.y; + } + ocr = make_roi(image, roi); cv::cvtColor(ocr, gray, cv::COLOR_BGR2GRAY); cv::inRange(gray, ocr_task->special_params[0], 255, bin); for (int r = bin.cols - 1; r >= 0; --r) { @@ -374,8 +389,8 @@ std::vector } } - bin = bin.adjustROI(0, -2, 0, 0); // 底部收缩排除白线 - int width = 5; + bin = bin.adjustROI(0, ocr_task->special_params[4], 0, 0); // 底部收缩排除白线 + int width = ocr_task->special_params[5]; for (int r = bin.cols - width - 1; r >= 0; --r) { if (!cv::hasNonZero(bin.colRange(r, r + width))) { // 左边界排除无文字区域 ocr = ocr.adjustROI(0, 0, -r - 3, 0); diff --git a/src/MaaCore/Vision/RegionOCRer.cpp b/src/MaaCore/Vision/RegionOCRer.cpp index e4edb7fc5a..93ebb6a870 100644 --- a/src/MaaCore/Vision/RegionOCRer.cpp +++ b/src/MaaCore/Vision/RegionOCRer.cpp @@ -38,6 +38,7 @@ RegionOCRer::ResultOpt RegionOCRer::analyze() const #ifdef ASST_DEBUG cv::rectangle(m_image_draw, make_rect(new_roi), cv::Scalar(0, 0, 255), 1); #endif // ASST_DEBUG + new_roi = correct_rect(new_roi, m_roi); OCRer ocr_analyzer; if (m_use_raw) { diff --git a/src/MaaCore/Vision/VisionHelper.cpp b/src/MaaCore/Vision/VisionHelper.cpp index 969db75c94..b0d3a37bd7 100644 --- a/src/MaaCore/Vision/VisionHelper.cpp +++ b/src/MaaCore/Vision/VisionHelper.cpp @@ -41,6 +41,38 @@ void VisionHelper::set_log_tracing(bool enable) m_log_tracing = enable; } +Rect asst::VisionHelper::correct_rect(const Rect& rect, const Rect& main_roi) +{ + if (main_roi.empty()) { + return { 0, 0, 0, 0 }; + } + + Rect res = rect; + if (res.x < 0) { + res.x = 0; + res.width = rect.width + rect.x; + } + if (res.y < 0) { + res.y = 0; + res.height = rect.height + rect.y; + } + if (res.x < main_roi.x) { + res.x = main_roi.x; + res.width = res.width - (main_roi.x - res.x); + } + if (res.y < main_roi.y) { + res.y = main_roi.y; + res.height = res.height - (main_roi.y - res.y); + } + if (res.x + res.width > main_roi.x + main_roi.width) { + res.width = main_roi.x + main_roi.width - res.x; + } + if (res.y + res.height > main_roi.y + main_roi.height) { + res.height = main_roi.y + main_roi.height - res.y; + } + return res; +} + Rect VisionHelper::correct_rect(const Rect& rect, const cv::Mat& image) { if (image.empty()) { diff --git a/src/MaaCore/Vision/VisionHelper.h b/src/MaaCore/Vision/VisionHelper.h index 925592f89b..ecb39d9f65 100644 --- a/src/MaaCore/Vision/VisionHelper.h +++ b/src/MaaCore/Vision/VisionHelper.h @@ -35,6 +35,7 @@ public: virtual void set_log_tracing(bool enable); bool save_img(const std::filesystem::path& relative_dir = utils::path("debug")); + static Rect correct_rect(const Rect& rect, const Rect& main_roi); #ifdef ASST_DEBUG const cv::Mat& get_draw() const { return m_image_draw; } diff --git a/src/MaaWpfGui/Main/Bootstrapper.cs b/src/MaaWpfGui/Main/Bootstrapper.cs index e2df256568..a43f0df193 100644 --- a/src/MaaWpfGui/Main/Bootstrapper.cs +++ b/src/MaaWpfGui/Main/Bootstrapper.cs @@ -88,6 +88,21 @@ namespace MaaWpfGui.Main } } + public static bool IsWritable(string path) + { + try + { + string testFile = Path.Combine(path, "write_test.tmp"); + File.WriteAllText(testFile, "test"); + File.Delete(testFile); + return true; + } + catch + { + return false; + } + } + /// /// 初始化些啥自己加。 protected override void OnStart() @@ -221,6 +236,11 @@ namespace MaaWpfGui.Main return; } + if (!IsWritable(AppDomain.CurrentDomain.BaseDirectory)) + { + Task.Run(() => MessageBoxHelper.Show(LocalizationHelper.GetString("SoftwareLocationWarning"), LocalizationHelper.GetString("Warning"), MessageBoxButton.OK, MessageBoxImage.Error)); + } + base.OnStart(); _hasMutex = true; diff --git a/src/MaaWpfGui/Res/Localizations/en-us.xaml b/src/MaaWpfGui/Res/Localizations/en-us.xaml index be19db1ff4..518de1fa24 100644 --- a/src/MaaWpfGui/Res/Localizations/en-us.xaml +++ b/src/MaaWpfGui/Res/Localizations/en-us.xaml @@ -1050,6 +1050,7 @@ Click "OK" to execute the installation script and exit MAA. Click "Cancel" to ex Only one instance can be launched under the same path! If you want to run multiple MAA at the same time, please copy the whole MAA and start under different path with the same adb and different connect address. + The current software location cannot save data, which may cause settings loss or runtime errors. Please move the software to a writable directory. Do not place it in system-protected directories (e.g., Program Files, System32, or Windows directories). Encryption and decryption failed, please reconfigure the relevant settings, otherwise the encrypted content will be stored in plain text in the configuration file. diff --git a/src/MaaWpfGui/Res/Localizations/ja-jp.xaml b/src/MaaWpfGui/Res/Localizations/ja-jp.xaml index 25de5e83ff..0e76d44c84 100644 --- a/src/MaaWpfGui/Res/Localizations/ja-jp.xaml +++ b/src/MaaWpfGui/Res/Localizations/ja-jp.xaml @@ -1054,6 +1054,7 @@ Microsoft Visual C++ redistributable 2015-2022 (x64) がインストールされ 同じパスの下で起動できるのは1つのインスタンスのみ! MAA を複数開くには、新しい MAA を他のフォルダにコピーし、異なる MAA、同じ adb、異なるシミュレータアドレスを使用して複数の操作を行うように設定します。 + 現在のソフトウェアの場所ではデータを保存できません。設定が失われるか、実行時に問題が発生する可能性があります。書き込み可能なディレクトリに移動してください。システム保護ディレクトリ(Program Files、System32、Windows ディレクトリなど)には配置しないでください。 暗号化と復号化に失敗しました。関連設定を再設定してください。そうでないと、暗号化された内容は設定ファイルに平文で保存されます。 diff --git a/src/MaaWpfGui/Res/Localizations/ko-kr.xaml b/src/MaaWpfGui/Res/Localizations/ko-kr.xaml index b858fd4c4d..c0a961256c 100644 --- a/src/MaaWpfGui/Res/Localizations/ko-kr.xaml +++ b/src/MaaWpfGui/Res/Localizations/ko-kr.xaml @@ -1051,6 +1051,7 @@ Microsoft Visual C++ redistributable 2015-2022(x64) 가 설치되지 않았거 동일한 경로에서는 하나의 인스턴스만 실행할 수 있습니다! 여러 개의 MAA를 동시에 실행하려면 MAA 전체 폴더를 복사한 뒤, 같은 adb를 사용하되 연결 주소는 다르게 설정하여 서로 다른 경로에서 실행하세요. + 현재 소프트웨어 위치에서는 데이터를 저장할 수 없어 설정이 손실되거나 실행 오류가 발생할 수 있습니다. 쓰기 가능한 디렉터리로 이동하십시오. 시스템 보호 디렉터리(예: Program Files, System32 또는 Windows 디렉터리)에 두지 마십시오. 암호화 또는 복호화에 실패했습니다. 관련 설정을 다시 구성해 주세요. 그렇지 않으면 암호화된 내용이 설정 파일에 그대로 저장됩니다. diff --git a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml index 73810dae77..6efa826568 100644 --- a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml +++ b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml @@ -1054,6 +1054,7 @@ C:\\leidian\\LDPlayer9。\n 同一路径下只能启动一个实例! 如需多开 MAA,请复制一份新的 MAA 到其他文件夹下,并设置使用不同的 MAA,相同的 adb 和不同的模拟器地址进行多开操作。 + 当前软件所在的位置无法保存数据,可能会导致设置丢失或运行异常。建议将软件移动到可写目录中运行,请勿放置在系统保护目录(如 Program Files、System32 或 Windows 目录)中。 加解密失败,请重新配置相关设置,否则加密内容将以明文形式存储在配置文件中。 diff --git a/src/MaaWpfGui/Res/Localizations/zh-tw.xaml b/src/MaaWpfGui/Res/Localizations/zh-tw.xaml index d537665073..df16fab57b 100644 --- a/src/MaaWpfGui/Res/Localizations/zh-tw.xaml +++ b/src/MaaWpfGui/Res/Localizations/zh-tw.xaml @@ -1054,6 +1054,7 @@ C:\\leidian\\LDPlayer9。\n 同一路徑下只能啟動一個實例! 如需多開MAA,請複製一份新的MAA到其他資料夾下,並設定使用不同的 MAA,相同的 adb 和不同的模擬器地址進行多開操作。 + 當前軟體所在的位置無法儲存資料,可能會導致設定遺失或執行異常。建議將軟體移動到可寫入的目錄中執行,請勿放置在系統保護目錄(如 Program Files、System32 或 Windows 目錄)中。 加解密失敗,請重新配置相關設置,否則加密內容將以明文形式存儲在配置文件中。