Skip to content

feat(coffee): 增加咖啡 1-1 关卡无限刷每周都市活力功能#128

Open
VonLan233 wants to merge 35 commits into
1bananachicken:devfrom
VonLan233:feat/coffee
Open

feat(coffee): 增加咖啡 1-1 关卡无限刷每周都市活力功能#128
VonLan233 wants to merge 35 commits into
1bananachicken:devfrom
VonLan233:feat/coffee

Conversation

@VonLan233

@VonLan233 VonLan233 commented May 7, 2026

Copy link
Copy Markdown

关联 Issue

Resolves #92

改动概览

新增咖啡 1-1 关卡的自动化循环任务,用于高效消耗每周都市活力:

  • 新增 auto_coffee_1_1_farm.py:自动重复挑战咖啡 1-1 关卡
  • 每轮流程约 15 秒,完成第 3 个面包后立即退出领奖
  • 无需氪金角色即可稳定运行

流程说明

  1. 进入关卡:自动导航至咖啡玩法并选择 1-1 关卡
  2. 制作流程:按顺序完成 3 个面包的制作步骤
  3. 结算领奖:完成第 3 个面包后触发退出,领取奖励
  4. 循环判断:检测本周剩余都市活力,有则继续下一轮

关键特性

  • 固定关卡适配:1-1 关卡内容固定,不依赖随机变量,脚本行为稳定可预期
  • 短平快循环:单轮耗时约 15 秒,适合作为活力消耗的最优解
  • 零氪友好:不依赖任何氪金角色/道具,所有玩家均可使用
  • 防卡死保护:每个步骤均设置超时检测与重试机制,异常时自动返回主界面

Summary by Sourcery

重构咖啡自动制作(coffee auto-make)动作以使用共享工具并提升健壮性,并新增用于在截图上标记 ROI 区域的辅助工具。

增强功能:

  • 改进咖啡自动制作动作,采用更安全的参数解析方式、模板存在性检查,并复用共享的图像/交互工具。
  • 扩展通用的 click_rect 辅助函数,以支持可配置的点击次数和按住时长,从而实现更灵活的交互。

杂项/维护:

  • 添加 mark_roi 开发者工具,用于在截图上以交互方式标注并导出 ROI 定义。
Original summary in English

Summary by Sourcery

Refactor the coffee auto-make action to use shared utilities and improve robustness, and add a helper tool for marking ROI regions on screenshots.

Enhancements:

  • Improve the coffee auto-make action with safer parameter parsing, template existence checks, and reuse of shared image/interaction utilities.
  • Extend the generic click_rect helper to support configurable click count and hold duration for more flexible interactions.

Chores:

  • Add a mark_roi developer tool for interactively labeling and exporting ROI definitions from screenshots.

VonLan233 and others added 30 commits May 5, 2026 15:30
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@sourcery-ai

sourcery-ai Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

审阅者指南(Reviewer's Guide)

重构了现有的自动咖啡动作以复用共享工具函数,改进了遗留咖啡模式的健壮性和可配置性,并引入了新的 ROI 标注工具,用于支持为新的 1-1 周回流程编写基于图像的自动化脚本。

使用共享工具的遗留咖啡自动模式时序图

sequenceDiagram
actor Player
participant MaaPipeline
participant AutoMakeCoffee
participant Common_utils
participant Controller

Player->>MaaPipeline: start MakeCoffee task
MaaPipeline->>AutoMakeCoffee: run(context, argv)
AutoMakeCoffee->>AutoMakeCoffee: parse custom_action_param
AutoMakeCoffee->>AutoMakeCoffee: _run_evict(context, controller, make_count, check_freq, start_template, star_template, claim_template)

loop for each round
  AutoMakeCoffee->>Common_utils: click_rect(controller, select_level_target, delay, count, hold)
  Common_utils->>Controller: post_touch_down/post_touch_up
  AutoMakeCoffee->>Controller: post_screencap
  Controller-->>Common_utils: cached_image
  Common_utils-->>AutoMakeCoffee: get_image result
  AutoMakeCoffee->>Common_utils: match_template_in_region(img, start_roi, start_template, min_similarity)
  alt start button found
    AutoMakeCoffee->>Common_utils: click_rect(controller, start_button_rect, delay, count, hold)
  end

  loop wait for sales goal
    AutoMakeCoffee->>Common_utils: click_rect(controller, click_roi, delay, count, hold)
    AutoMakeCoffee->>Controller: post_screencap
    Controller-->>Common_utils: cached_image
    Common_utils-->>AutoMakeCoffee: get_image result
    AutoMakeCoffee->>Common_utils: match_template_in_region(img, star_roi, star_template, min_similarity)
    alt star reached
      AutoMakeCoffee->>Common_utils: click_rect(controller, exit_roi, delay, count, hold)
    end
  end

  loop wait for claim button
    AutoMakeCoffee->>Controller: post_screencap
    Controller-->>Common_utils: cached_image
    Common_utils-->>AutoMakeCoffee: get_image result
    AutoMakeCoffee->>Common_utils: match_template_in_region(img, claim_roi, claim_template, min_similarity)
    alt claim found
      AutoMakeCoffee->>Common_utils: click_rect(controller, claim_button_rect, delay, count, hold)
    end
  end

  AutoMakeCoffee->>Controller: post_key_down(key_f)
  AutoMakeCoffee->>Controller: post_key_up(key_f)
end

AutoMakeCoffee-->>MaaPipeline: RunResult(success)
MaaPipeline-->>Player: report automation finished
Loading

更新后的 AutoMakeCoffee 与新 RoiMarker 工具的类图

classDiagram
class AutoMakeCoffee {
  -start_template
  -star_template
  -claim_template
  +run(context, argv)
  +_run_evict(context, controller, make_count, check_freq, start_template, star_template, claim_template)
}

class Common_utils {
  +get_image(controller)
  +click_rect(controller, rect, delay, count, hold)
  +match_template_in_region(img, region, template, min_similarity, green_mask)
}

class RoiMarker {
  -image_path
  -labels
  -scale
  -image
  -display_base
  -window_name
  -rois
  -current_label_index
  -dragging
  -drag_start
  -drag_end
  +run()
  +current_label()
  +_on_mouse(event, x, y, flags, param)
  +_scaled_rect_to_original(start, end)
  +_render()
  +_original_rect_to_scaled(roi)
  +_next_label()
  +_undo()
  +_save()
}

class mark_roi_module {
  +parse_args()
  +main()
}

AutoMakeCoffee ..> Common_utils : uses
mark_roi_module ..> RoiMarker : instantiates
mark_roi_module ..> Common_utils : independent module
RoiMarker ..> cv2 : uses
AutoMakeCoffee ..> AgentServer : registered_as_custom_action
Loading

文件级变更

Change Details Files
重构 auto_make_coffee 以使用共享工具,并添加结构化的遗留“驱赶顾客”模式,带来更安全的参数处理和模板加载。
  • 用从 Common.utils 导入的 get_image、match_template_in_region 和 click_rect 替换了内联实现,以集中管理屏幕/交互辅助函数。
  • 添加 _load_template 辅助函数,以防御性方式加载模板,并在缺失必需图像时记录警告日志并提前退出。
  • 重写 run,以带类型校验地解析 custom_action_param,并委托给新的 _run_evict 方法封装原有工作流。
  • 确保控制器按键事件会等待完成,并在保持原有驱赶流程语义的前提下重命名常量(KEY_F → key_f)。
agent/custom/action/auto_make_coffee.py
扩展通用 click_rect 工具,以支持重复点击和可配置的长按时长,从而实现更可靠的交互。
  • 更改 click_rect 函数签名,使其接受仅限关键字参数的 count 和 hold,同时保留 delay 作为默认长按时长。
  • 实现循环的 touch_down/touch_up,并为每次按压设置独立的长按时间,以支持咖啡自动化中使用的多次点击场景。
agent/custom/action/Common/utils.py
引入独立的 ROI 标注命令行工具,用于帮助创建和可视化咖啡自动化(例如 1-1 周回)中的模板匹配区域。
  • 新增 tools/mark_roi.py,这是一个基于 cv2 的交互式 GUI,允许用户在截图上拖拽 ROI、用标签标记,并导出 JSON 定义和带注释的图像。
  • 实现了标签循环切换、撤销/清空操作、可配置显示缩放比例,以及为咖啡 1-1 的食物/计时器/进入/退出元素预设的默认标签集。
tools/mark_roi.py
为咖啡自动化流程准备/调整流水线和任务配置文件(可能用于接入新的 1-1 周回场景)。
  • 修改了 MakeCoffee 的流水线和任务 JSON;审阅者应对比这些文件,以查看为新的 1-1 周回实现而更新的步骤、ROI 或任务连接配置。
assets/resource/base/pipeline/MakeCoffee.json
assets/resource/tasks/MakeCoffee.json

与关联 Issue 的对应情况评估

Issue Objective Addressed Explanation
#92 实现一个可以自动、循环挑战咖啡 1-1 关卡,用于持续消耗每周都市活力的功能(根据剩余活力进行多轮周目)。
#92 在每轮中按照 1-1 固定关卡流程完成 3 个面包后立刻退出并结算领奖,将单轮时间控制在约 15 秒,且不依赖氪金角色即可运行。

可能关联的 Issues


提示与命令

与 Sourcery 交互

  • 触发新的审查: 在 Pull Request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub Issue: 在回复某条审查评论时请求 Sourcery 创建 Issue。你也可以直接回复审查评论 @sourcery-ai issue 来从该评论创建 Issue。
  • 生成 Pull Request 标题: 在 Pull Request 标题中任意位置写上 @sourcery-ai 即可随时生成标题。也可以在 Pull Request 中评论 @sourcery-ai title 随时(重新)生成标题。
  • 生成 Pull Request 摘要: 在 Pull Request 描述中任意位置写上 @sourcery-ai summary,即可在对应位置生成 PR 摘要。也可以在 Pull Request 中评论 @sourcery-ai summary 随时(重新)生成摘要。
  • 生成审阅者指南: 在 Pull Request 中评论 @sourcery-ai guide,即可随时(重新)生成审阅者指南。
  • 解决所有 Sourcery 评论: 在 Pull Request 中评论 @sourcery-ai resolve,以标记所有 Sourcery 评论为已解决。如果你已经处理完所有评论且不希望再看到它们,这会很实用。
  • 撤销所有 Sourcery 审查: 在 Pull Request 中评论 @sourcery-ai dismiss,以撤销所有现有 Sourcery 审查。尤其适用于你希望以一次全新的审查开始的情况——别忘了随后评论 @sourcery-ai review 以触发新的审查!

自定义你的体验

访问你的 控制面板 以:

  • 启用或禁用审查功能,例如 Sourcery 自动生成的 Pull Request 摘要、审阅者指南等。
  • 更改审查语言。
  • 添加、移除或编辑自定义审查说明。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

Refactors the existing auto coffee action to reuse shared utility functions, improves robustness and configurability of the legacy coffee mode, and introduces a new ROI marking tool to support authoring image-based automation for the new 1-1 farming flow.

Sequence diagram for legacy coffee auto mode with shared utilities

sequenceDiagram
actor Player
participant MaaPipeline
participant AutoMakeCoffee
participant Common_utils
participant Controller

Player->>MaaPipeline: start MakeCoffee task
MaaPipeline->>AutoMakeCoffee: run(context, argv)
AutoMakeCoffee->>AutoMakeCoffee: parse custom_action_param
AutoMakeCoffee->>AutoMakeCoffee: _run_evict(context, controller, make_count, check_freq, start_template, star_template, claim_template)

loop for each round
  AutoMakeCoffee->>Common_utils: click_rect(controller, select_level_target, delay, count, hold)
  Common_utils->>Controller: post_touch_down/post_touch_up
  AutoMakeCoffee->>Controller: post_screencap
  Controller-->>Common_utils: cached_image
  Common_utils-->>AutoMakeCoffee: get_image result
  AutoMakeCoffee->>Common_utils: match_template_in_region(img, start_roi, start_template, min_similarity)
  alt start button found
    AutoMakeCoffee->>Common_utils: click_rect(controller, start_button_rect, delay, count, hold)
  end

  loop wait for sales goal
    AutoMakeCoffee->>Common_utils: click_rect(controller, click_roi, delay, count, hold)
    AutoMakeCoffee->>Controller: post_screencap
    Controller-->>Common_utils: cached_image
    Common_utils-->>AutoMakeCoffee: get_image result
    AutoMakeCoffee->>Common_utils: match_template_in_region(img, star_roi, star_template, min_similarity)
    alt star reached
      AutoMakeCoffee->>Common_utils: click_rect(controller, exit_roi, delay, count, hold)
    end
  end

  loop wait for claim button
    AutoMakeCoffee->>Controller: post_screencap
    Controller-->>Common_utils: cached_image
    Common_utils-->>AutoMakeCoffee: get_image result
    AutoMakeCoffee->>Common_utils: match_template_in_region(img, claim_roi, claim_template, min_similarity)
    alt claim found
      AutoMakeCoffee->>Common_utils: click_rect(controller, claim_button_rect, delay, count, hold)
    end
  end

  AutoMakeCoffee->>Controller: post_key_down(key_f)
  AutoMakeCoffee->>Controller: post_key_up(key_f)
end

AutoMakeCoffee-->>MaaPipeline: RunResult(success)
MaaPipeline-->>Player: report automation finished
Loading

Class diagram for updated AutoMakeCoffee and new RoiMarker tool

classDiagram
class AutoMakeCoffee {
  -start_template
  -star_template
  -claim_template
  +run(context, argv)
  +_run_evict(context, controller, make_count, check_freq, start_template, star_template, claim_template)
}

class Common_utils {
  +get_image(controller)
  +click_rect(controller, rect, delay, count, hold)
  +match_template_in_region(img, region, template, min_similarity, green_mask)
}

class RoiMarker {
  -image_path
  -labels
  -scale
  -image
  -display_base
  -window_name
  -rois
  -current_label_index
  -dragging
  -drag_start
  -drag_end
  +run()
  +current_label()
  +_on_mouse(event, x, y, flags, param)
  +_scaled_rect_to_original(start, end)
  +_render()
  +_original_rect_to_scaled(roi)
  +_next_label()
  +_undo()
  +_save()
}

class mark_roi_module {
  +parse_args()
  +main()
}

AutoMakeCoffee ..> Common_utils : uses
mark_roi_module ..> RoiMarker : instantiates
mark_roi_module ..> Common_utils : independent module
RoiMarker ..> cv2 : uses
AutoMakeCoffee ..> AgentServer : registered_as_custom_action
Loading

File-Level Changes

Change Details Files
Refactor auto_make_coffee to use shared utilities and add a structured legacy 'evict customers' mode with safer parameter handling and template loading.
  • Replaced inline get_image, match_template_in_region, and click_rect implementations with imports from Common.utils to centralize screen/interaction helpers.
  • Added a _load_template helper to load templates defensively with warning logs and early-exit if required images are missing.
  • Reworked run to parse custom_action_param with type validation and to delegate to a new _run_evict method that encapsulates the previous workflow.
  • Ensured controller key events wait for completion and renamed constants (KEY_F → key_f) while keeping the original evict flow semantics.
agent/custom/action/auto_make_coffee.py
Extend generic click_rect utility to support repeated taps and configurable hold duration for more reliable interactions.
  • Changed click_rect signature to accept count and hold keyword-only parameters while keeping delay as a default hold value.
  • Implemented a looped touch_down/touch_up with per-press hold duration to support multi-tap scenarios used by coffee automation.
agent/custom/action/Common/utils.py
Introduce a standalone ROI marking CLI tool to aid in creating and visualizing template matching regions for coffee automation (e.g., 1-1 farming).
  • Added tools/mark_roi.py, a cv2-based interactive GUI that allows users to drag ROIs on screenshots, tag them with labels, and export both JSON definitions and annotated images.
  • Implemented features such as label cycling, undo/clear operations, configurable display scale, and default label sets tailored for coffee 1-1 food/timer/enter/exit elements.
tools/mark_roi.py
Prepare/adjust pipeline and task configuration files for the coffee automation flow (likely to hook in the new 1-1 farm scenario).
  • Touched MakeCoffee pipeline and task JSONs; reviewers should diff these files to see updated steps, ROIs, or task wiring for the new 1-1 loop implementation.
assets/resource/base/pipeline/MakeCoffee.json
assets/resource/tasks/MakeCoffee.json

Assessment against linked issues

Issue Objective Addressed Explanation
#92 实现一个可以自动、循环挑战咖啡 1-1 关卡,用于持续消耗每周都市活力的功能(根据剩余活力进行多轮周目)。
#92 在每轮中按照 1-1 固定关卡流程完成 3 个面包后立刻退出并结算领奖,将单轮时间控制在约 15 秒,且不依赖氪金角色即可运行。

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了两个问题,并给出了一些整体性的反馈:

  • _run_evict 中的 ROI 和按键常量(例如 select_level_targetclick_roikey_f = 70)目前是硬编码的;建议将它们移到共享的配置/JSON 或具名常量中,这样可以在不修改逻辑代码的前提下复用并调整这些值。
  • 新的 mark_roi.py 工具在脚本中直接内嵌了默认标签和缩放比例处理;如果你计划在其他功能中复用它,建议通过小型配置或预设配置集来参数化这些内容,以避免在新增 ROI 工作流时需要直接改动脚本本身。
提供给 AI Agents 的提示
Please address the comments from this code review:

## Overall Comments
- `_run_evict` 中的 ROI 和按键常量(例如 `select_level_target``click_roi``key_f = 70`)目前是硬编码的;建议将它们移到共享的配置/JSON 或具名常量中,这样可以在不修改逻辑代码的前提下复用并调整这些值。
- 新的 `mark_roi.py` 工具在脚本中直接内嵌了默认标签和缩放比例处理;如果你计划在其他功能中复用它,建议通过小型配置或预设配置集来参数化这些内容,以避免在新增 ROI 工作流时需要直接改动脚本本身。

## Individual Comments

### Comment 1
<location path="tools/mark_roi.py" line_range="23-32" />
<code_context>
+
+
+class RoiMarker:
+    def __init__(self, image_path: Path, labels: list[str], scale: float):
+        self.image_path = image_path
+        self.labels = labels
+        self.scale = scale
+        image = cv2.imread(str(image_path), cv2.IMREAD_COLOR)
+        if image is None:
+            raise FileNotFoundError(f"无法读取图片: {image_path}")
+        self.image = image
+
+        self.display_base = cv2.resize(
+            self.image,
+            None,
</code_context>
<issue_to_address>
**issue (bug_risk):** 验证 `scale`,以避免无效或退化的缩放操作。

来自 CLI 的 `scale` 会被直接传递给 `cv2.resize`,因此像 `--scale 0` 或负数这样的值会导致 OpenCV 报错或产生未定义行为。请对其进行校验(例如强制 `scale > 0`),并在发现非法值时尽早以清晰的错误信息失败,而不是依赖 `cv2.resize` 间接暴露问题。
</issue_to_address>

### Comment 2
<location path="tools/mark_roi.py" line_range="192" />
<code_context>
+            {"label": str(item["label"]), "roi": item["roi"]}
+            for item in self.rois
+        ]
+        output_json.write_text(json.dumps(data, ensure_ascii=False, indent=4) + "\n")
+        cv2.imwrite(str(output_image), self._render())
+
</code_context>
<issue_to_address>
**suggestion (bug_risk):** 建议在写入 JSON 时显式使用 `encoding='utf-8'`。

由于该 JSON 可能包含非 ASCII 标签,显式调用 `write_text(..., encoding="utf-8")` 可以避免依赖平台默认编码,并确保在不同环境下稳定输出 UTF-8。

Suggested implementation:

```python
        data = [
            {"label": str(item["label"]), "roi": item["roi"]}
            for item in self.rois
        ]
        output_json.write_text(
            json.dumps(data, ensure_ascii=False, indent=4) + "\n",
            encoding="utf-8",
        )
        cv2.imwrite(str(output_image), self._render())

```

如果 `json` 尚未在 `tools/mark_roi.py` 顶部导入,请在其他导入语句旁添加 `import json`。
</issue_to_address>

Sourcery 对开源项目免费——如果你觉得我们的代码审查有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,你的反馈将帮助我改进代码审查。
Original comment in English

Hey - I've found 2 issues, and left some high level feedback:

  • The ROI and key-code constants in _run_evict (e.g. select_level_target, click_roi, key_f = 70) are currently hardcoded; consider moving them into a shared config/JSON or named constants so they can be reused and adjusted without touching the logic.
  • The new mark_roi.py tool embeds default labels and scale handling directly in the script; if you plan to reuse it for other features, consider parameterizing these via a small config or preset profiles to avoid needing to modify the script when adding new ROI workflows.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The ROI and key-code constants in `_run_evict` (e.g. `select_level_target`, `click_roi`, `key_f = 70`) are currently hardcoded; consider moving them into a shared config/JSON or named constants so they can be reused and adjusted without touching the logic.
- The new `mark_roi.py` tool embeds default labels and scale handling directly in the script; if you plan to reuse it for other features, consider parameterizing these via a small config or preset profiles to avoid needing to modify the script when adding new ROI workflows.

## Individual Comments

### Comment 1
<location path="tools/mark_roi.py" line_range="23-32" />
<code_context>
+
+
+class RoiMarker:
+    def __init__(self, image_path: Path, labels: list[str], scale: float):
+        self.image_path = image_path
+        self.labels = labels
+        self.scale = scale
+        image = cv2.imread(str(image_path), cv2.IMREAD_COLOR)
+        if image is None:
+            raise FileNotFoundError(f"无法读取图片: {image_path}")
+        self.image = image
+
+        self.display_base = cv2.resize(
+            self.image,
+            None,
</code_context>
<issue_to_address>
**issue (bug_risk):** Validate `scale` to avoid invalid or degenerate resize operations.

`scale` from the CLI is passed directly to `cv2.resize`, so values like `--scale 0` or negatives will cause OpenCV errors or undefined behavior. Please validate (e.g., enforce `scale > 0`) and fail fast with a clear error instead of relying on `cv2.resize` to surface this indirectly.
</issue_to_address>

### Comment 2
<location path="tools/mark_roi.py" line_range="192" />
<code_context>
+            {"label": str(item["label"]), "roi": item["roi"]}
+            for item in self.rois
+        ]
+        output_json.write_text(json.dumps(data, ensure_ascii=False, indent=4) + "\n")
+        cv2.imwrite(str(output_image), self._render())
+
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Consider using `encoding='utf-8'` explicitly when writing JSON.

Since this JSON may include non-ASCII labels, explicitly calling `write_text(..., encoding="utf-8")` will avoid relying on platform defaults and ensure consistent UTF-8 output across environments.

Suggested implementation:

```python
        data = [
            {"label": str(item["label"]), "roi": item["roi"]}
            for item in self.rois
        ]
        output_json.write_text(
            json.dumps(data, ensure_ascii=False, indent=4) + "\n",
            encoding="utf-8",
        )
        cv2.imwrite(str(output_image), self._render())

```

If `json` is not already imported at the top of `tools/mark_roi.py`, add `import json` alongside the other imports.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread tools/mark_roi.py
Comment on lines +23 to +32
def __init__(self, image_path: Path, labels: list[str], scale: float):
self.image_path = image_path
self.labels = labels
self.scale = scale
image = cv2.imread(str(image_path), cv2.IMREAD_COLOR)
if image is None:
raise FileNotFoundError(f"无法读取图片: {image_path}")
self.image = image

self.display_base = cv2.resize(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): 验证 scale,以避免无效或退化的缩放操作。

来自 CLI 的 scale 会被直接传递给 cv2.resize,因此像 --scale 0 或负数这样的值会导致 OpenCV 报错或产生未定义行为。请对其进行校验(例如强制 scale > 0),并在发现非法值时尽早以清晰的错误信息失败,而不是依赖 cv2.resize 间接暴露问题。

Original comment in English

issue (bug_risk): Validate scale to avoid invalid or degenerate resize operations.

scale from the CLI is passed directly to cv2.resize, so values like --scale 0 or negatives will cause OpenCV errors or undefined behavior. Please validate (e.g., enforce scale > 0) and fail fast with a clear error instead of relying on cv2.resize to surface this indirectly.

Comment thread tools/mark_roi.py
{"label": str(item["label"]), "roi": item["roi"]}
for item in self.rois
]
output_json.write_text(json.dumps(data, ensure_ascii=False, indent=4) + "\n")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): 建议在写入 JSON 时显式使用 encoding='utf-8'

由于该 JSON 可能包含非 ASCII 标签,显式调用 write_text(..., encoding="utf-8") 可以避免依赖平台默认编码,并确保在不同环境下稳定输出 UTF-8。

Suggested implementation:

        data = [
            {"label": str(item["label"]), "roi": item["roi"]}
            for item in self.rois
        ]
        output_json.write_text(
            json.dumps(data, ensure_ascii=False, indent=4) + "\n",
            encoding="utf-8",
        )
        cv2.imwrite(str(output_image), self._render())

如果 json 尚未在 tools/mark_roi.py 顶部导入,请在其他导入语句旁添加 import json

Original comment in English

suggestion (bug_risk): Consider using encoding='utf-8' explicitly when writing JSON.

Since this JSON may include non-ASCII labels, explicitly calling write_text(..., encoding="utf-8") will avoid relying on platform defaults and ensure consistent UTF-8 output across environments.

Suggested implementation:

        data = [
            {"label": str(item["label"]), "roi": item["roi"]}
            for item in self.rois
        ]
        output_json.write_text(
            json.dumps(data, ensure_ascii=False, indent=4) + "\n",
            encoding="utf-8",
        )
        cv2.imwrite(str(output_image), self._render())

If json is not already imported at the top of tools/mark_roi.py, add import json alongside the other imports.

1bananachicken pushed a commit that referenced this pull request Jun 12, 2026
* feat(make_coffee): 增加做咖啡平民版
平民版做咖啡1-1,无需白藏娜娜莉
优化做咖啡入口逻辑,在店长特供对话附近可进入界面.
Refs: #128

* fix: 去除冗余引用

* fix: 去除冗余引用并显式捕获错误

* fix: 修改PrintT传入正确参数
XHLinLin pushed a commit to XHLinLin/MaaNTE-LinLin that referenced this pull request Jun 15, 2026
* feat(make_coffee): 增加做咖啡平民版
平民版做咖啡1-1,无需白藏娜娜莉
优化做咖啡入口逻辑,在店长特供对话附近可进入界面.
Refs: 1bananachicken#128

* fix: 去除冗余引用

* fix: 去除冗余引用并显式捕获错误

* fix: 修改PrintT传入正确参数
XHLinLin pushed a commit to XHLinLin/MaaNTE-LinLin that referenced this pull request Jun 15, 2026
* feat(make_coffee): 增加做咖啡平民版
平民版做咖啡1-1,无需白藏娜娜莉
优化做咖啡入口逻辑,在店长特供对话附近可进入界面.
Refs: 1bananachicken#128

* fix: 去除冗余引用

* fix: 去除冗余引用并显式捕获错误

* fix: 修改PrintT传入正确参数
lisadnsess pushed a commit to lisadnsess/MaaNTE that referenced this pull request Jun 22, 2026
* feat(make_coffee): 增加做咖啡平民版
平民版做咖啡1-1,无需白藏娜娜莉
优化做咖啡入口逻辑,在店长特供对话附近可进入界面.
Refs: 1bananachicken#128

* fix: 去除冗余引用

* fix: 去除冗余引用并显式捕获错误

* fix: 修改PrintT传入正确参数
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

增加咖啡1-1关卡无限刷每周都市活力功能

1 participant