Skip to content

feat & enhance: 完善 TrackCamouflage 解锁条件、谱师伪装与封面加载 - #151

Merged
clansty merged 3 commits into
MuNET-OSS:mainfrom
Starrah:camouflage-enhance
Sep 20, 2026
Merged

clansty merged 3 commits into
MuNET-OSS:mainfrom
Starrah:camouflage-enhance

Conversation

@Starrah

@Starrah Starrah commented Sep 19, 2026 •

Copy link
Copy Markdown
Collaborator
  • 新增 UnlockScore:将解除伪装的条件改为,只有玩家的达成率达标后才解除伪装(默认为0,即只要所有玩家都有成绩,不管高低,就解除伪装);
  • 优化 NoteDesigner/HideNoteDesigner 的行为;
  • 优化伪装封面文件查找的逻辑,并重写中英配置说明。

Review in cubic

Sourcery 摘要

增强轨道伪装的配置与加载功能,同时使伪装移除取决于玩家的成就阈值。

新功能:

  • 添加用于移除轨道伪装的可配置成就阈值,包括永久保留伪装的支持。
  • 支持通过 TOML 配置伪装或隐藏音符设计者信息。
  • 改进伪装外套的发现功能,支持 JPG/PNG 格式验证和加载诊断。

增强:

  • 明确并扩展关于伪装元数据、解锁行为和外套要求的英文与中文配置说明。
Original summary in English

Sourcery 总结

增强轨道伪装的配置与加载功能,同时使伪装移除依赖于可配置的成就阈值。

新功能:

  • 添加可配置的成就阈值,用于移除轨道伪装,并支持永久保持启用的伪装。
  • 支持在伪装元数据中配置伪装的音符设计者信息,或隐藏音符设计者信息。

错误修复:

  • 改进伪装外套的发现逻辑:验证支持的图像格式,并报告缺失或成功加载的外套文件。

增强功能:

  • 明确并扩展有关伪装元数据、解锁行为和外套要求的英文与中文配置指南。
Original summary in English

Sourcery 总结

增强曲目伪装的配置与加载功能,同时使伪装移除取决于可配置的玩家成就阈值。

新功能:

  • 添加用于移除曲目伪装的可配置成就阈值,并支持让伪装永久保持启用。
  • 支持配置伪装元数据中的谱面设计者,或隐藏谱面设计者信息。

错误修复:

  • 通过验证受支持的图像格式,并报告缺失或成功加载的封面文件,改进伪装封面的发现功能。

增强功能:

  • 明确并扩展有关伪装元数据、解锁行为和封面要求的英文及中文配置指南。
Original summary in English

Summary by Sourcery

Enhance track camouflage configuration and loading while making camouflage removal depend on configurable player achievement thresholds.

New Features:

  • Add configurable achievement thresholds for removing track camouflage, including support for camouflage that remains enabled indefinitely.
  • Support configuring disguised note designers or hiding note designer information in camouflage metadata.

Bug Fixes:

  • Improve camouflage jacket discovery by validating supported image formats and reporting missing or successfully loaded jacket files.

Enhancements:

  • Clarify and expand the English and Chinese configuration guidance for camouflage metadata, unlock behavior, and jacket requirements.

新增 UnlockScore:将解除伪装的条件改为,只有玩家的达成率达标后才解除伪装(默认为0,即与原来的行为相同,只要有成绩就解除伪装);
优化 NoteDesigner/HideNoteDesigner 的行为;
优化伪装封面文件查找的逻辑,并重写中英配置说明。
@sourcery-ai

sourcery-ai Bot commented Sep 19, 2026 •

Copy link
Copy Markdown

审查者指南

通过引入可配置的成就解锁阈值、明确音符设计者的隐藏语义,并增强外套文件发现和诊断功能来改进 TrackCamouflage,同时更新英文和中文配置文档。

TrackCamouflage 解锁评估时序图

sequenceDiagram
    participant TrackCamouflage
    participant UserDataManager
    participant PlayerData
    participant ScoreDic

    TrackCamouflage->>UserDataManager: GetUserData(i)
    UserDataManager-->>TrackCamouflage: PlayerData
    TrackCamouflage->>PlayerData: ScoreDic[j]
    PlayerData-->>TrackCamouflage: UserScore
    TrackCamouflage->>TrackCamouflage: CamouflageCheck(musicID)
    alt Every entered player reaches UnlockScore
        TrackCamouflage-->>TrackCamouflage: return false
    else Any entered player is below UnlockScore
        TrackCamouflage-->>TrackCamouflage: return true
    end
Loading

伪装外套发现流程图

flowchart TD
    A[Initialize] --> B[GetFiles for TOML definitions]
    B --> C[GetFiles for *_jacket.*]
    C --> D[Filter by music ID and AllowedImageExts]
    D --> E{Jacket found?}
    E -- Yes --> F[LoadJacketTexture]
    E -- No --> G[Log missing jacket]
    F --> H[Log loaded jacket file]
Loading

文件级变更

变更 详细信息 文件
在默认保留现有游玩记录行为的同时,增加基于分数阈值的伪装解锁功能。
  • 解析可选的 UnlockScore,默认值为 0。
  • 检查每位已登录玩家的六个难度分数记录,并且仅当所有玩家的分数都达到阈值时移除伪装。
  • 保留 AlwaysShowCamouflage 作为绕过解锁检查的覆盖选项。
AquaMai.Mods/Fancy/TrackCamouflage.cs
优化音符设计者的隐藏和回退行为。
  • 允许显式设置 NoteDesigner 覆盖值。
  • 支持 HideNoteDesigner:未提供覆盖值时显示 "-",否则保留真实设计者。
  • 记录新增 TOML 字段及其优先级。
AquaMai.Mods/Fancy/TrackCamouflage.cs
改进外套文件的发现、验证和诊断功能。
  • 预先收集外套候选文件,根据数字音乐 ID 和支持的图像扩展名进行筛选,并加载第一个可用匹配项。
  • 记录缺失以及成功加载的外套文件。
  • 记录 jpg/png 和直接加载图像的要求。
AquaMai.Mods/Fancy/TrackCamouflage.cs

提示和命令

与 Sourcery 交互

  • 触发新的审查: 在拉取请求中评论 @sourcery-ai review。
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 根据审查评论生成 GitHub issue: 回复审查评论,请 Sourcery 根据该评论创建 issue。你也可以使用 @sourcery-ai issue 回复审查评论,以根据该评论创建 issue。
  • 生成拉取请求标题: 在拉取请求标题的任意位置写入 @sourcery-ai,即可随时生成标题。你也可以在拉取请求中评论 @sourcery-ai title,以随时生成或重新生成标题。
  • 生成拉取请求摘要: 在拉取请求正文中任意位置写入 @sourcery-ai summary,即可在指定位置随时生成 PR 摘要。你也可以在拉取请求中评论 @sourcery-ai summary,以随时生成或重新生成摘要。
  • 生成审查者指南: 在拉取请求中评论 @sourcery-ai guide,即可随时生成或重新生成审查者指南。
  • 解决所有 Sourcery 评论: 在拉取请求中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理了所有评论且不想再看到它们,这项功能会很有用。
  • 忽略所有 Sourcery 审查: 在拉取请求中评论 @sourcery-ai dismiss,即可忽略所有现有的 Sourcery 审查。如果你想使用新的审查重新开始,这项功能尤其有用——别忘了评论 @sourcery-ai review 来触发新的审查!

自定义你的使用体验

访问你的仪表板以:

  • 启用或禁用审查功能,例如 Sourcery 生成的拉取请求摘要、审查者指南及其他功能。
  • 更改审查语言。
  • 添加、删除或编辑自定义审查说明。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

Enhances TrackCamouflage by introducing configurable achievement thresholds for unlocking, clarifying note-designer masking semantics, and making jacket-file discovery and diagnostics more robust, with updated English and Chinese configuration documentation.

Sequence diagram for TrackCamouflage unlock evaluation

sequenceDiagram
    participant TrackCamouflage
    participant UserDataManager
    participant PlayerData
    participant ScoreDic

    TrackCamouflage->>UserDataManager: GetUserData(i)
    UserDataManager-->>TrackCamouflage: PlayerData
    TrackCamouflage->>PlayerData: ScoreDic[j]
    PlayerData-->>TrackCamouflage: UserScore
    TrackCamouflage->>TrackCamouflage: CamouflageCheck(musicID)
    alt Every entered player reaches UnlockScore
        TrackCamouflage-->>TrackCamouflage: return false
    else Any entered player is below UnlockScore
        TrackCamouflage-->>TrackCamouflage: return true
    end
Loading

Flow diagram for camouflage jacket discovery

flowchart TD
    A[Initialize] --> B[GetFiles for TOML definitions]
    B --> C[GetFiles for *_jacket.*]
    C --> D[Filter by music ID and AllowedImageExts]
    D --> E{Jacket found?}
    E -- Yes --> F[LoadJacketTexture]
    E -- No --> G[Log missing jacket]
    F --> H[Log loaded jacket file]
Loading

File-Level Changes

Change Details Files
Add score-threshold-based camouflage unlocking while preserving the existing play-record behavior by default.
  • Parse optional UnlockScore with a default of 0.
  • Check each logged-in player’s six difficulty score records and remove camouflage only when every player has a score meeting the threshold.
  • Keep AlwaysShowCamouflage as an override that bypasses unlock checks.
AquaMai.Mods/Fancy/TrackCamouflage.cs
Refine note-designer masking and fallback behavior.
  • Allow an explicit NoteDesigner override.
  • Support HideNoteDesigner to display "-" when no override is supplied, otherwise preserve the real designer.
  • Document the new TOML fields and their precedence.
AquaMai.Mods/Fancy/TrackCamouflage.cs
Improve jacket discovery, validation, and diagnostics.
  • Pre-collect jacket candidates, filter them by numeric music ID and supported image extensions, and load the first usable match.
  • Log missing and successfully loaded jacket files.
  • Document the jpg/png and direct-image-loading requirements.
AquaMai.Mods/Fancy/TrackCamouflage.cs

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

Choose a reason for hiding this comment

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

你好——我发现了 1 个问题

面向 AI 代理的提示
请处理本次代码审查中的评论:

## 个别评论

### 评论 1
<location path="AquaMai.Mods/Fancy/TrackCamouflage.cs" line_range="106-108" />
<code_context>

-            var jacketFiles = Directory.GetFiles(resolvedDir, $"{musicID}_jacket.*", SearchOption.TopDirectoryOnly);
+            // 根据当前正在处理的歌曲的ID,从allJacketFiles中筛选出匹配的jacket
+            var jacketFiles = allJacketFiles.Where(
+                s => int.TryParse(s.Split('_')[0], out var res) && res == musicID && 
+                     AllowedImageExts.Contains(Path.GetExtension(s).ToLowerInvariant())).ToList();
+            
+            if (jacketFiles.Count == 0)
</code_context>
<issue_to_address>
**问题 (bug_risk):** 当解析出的伪装目录或其父路径包含下划线时,有效的 jacket 文件会被拒绝,因为 `s.Split('_')[0]` 应用于完整路径而不是文件名,因此无法解析音乐 ID。该筛选器还会接受 `123_jacket_backup.jpg` 这样的文件名,并可能加载该文件,而不是精确的 `<Music ID>_jacket` 文件。

**触发条件:** 当 `CamouflageDir` 解析为包含 `_` 的路径,或存在多个名称相似的 jacket 文件时。

**建议修复:** 在解析前提取 `Path.GetFileName(s)`,并要求文件名精确匹配 `$"{musicID}_jacket"`,同时使用允许的扩展名。

```suggestion
            var jacketFiles = allJacketFiles.Where(
                s =>
                {
                    var fileName = Path.GetFileName(s);
                    return Path.GetFileNameWithoutExtension(fileName) == $"{musicID}_jacket" &&
                           AllowedImageExts.Contains(Path.GetExtension(fileName).ToLowerInvariant());
                }).ToList();
```
</issue_to_address>

Sourcery 评估

等待批准。 请先处理 1 个发现的问题。

阻塞性发现:AquaMai.Mods/Fancy/TrackCamouflage.cs:108


Sourcery 对开源项目免费——如果您喜欢我们的评审,请考虑分享 ✨
Original comment in English

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="AquaMai.Mods/Fancy/TrackCamouflage.cs" line_range="106-108" />
<code_context>

-            var jacketFiles = Directory.GetFiles(resolvedDir, $"{musicID}_jacket.*", SearchOption.TopDirectoryOnly);
+            // 根据当前正在处理的歌曲的ID,从allJacketFiles中筛选出匹配的jacket
+            var jacketFiles = allJacketFiles.Where(
+                s => int.TryParse(s.Split('_')[0], out var res) && res == musicID && 
+                     AllowedImageExts.Contains(Path.GetExtension(s).ToLowerInvariant())).ToList();
+            
+            if (jacketFiles.Count == 0)
</code_context>
<issue_to_address>
**issue (bug_risk):** Valid jacket files are rejected when the resolved camouflage directory or its parent path contains an underscore, because `s.Split('_')[0]` is applied to the full path rather than the filename and therefore cannot parse the music ID. The filter also accepts names such as `123_jacket_backup.jpg` and can load that file instead of the exact `<Music ID>_jacket` file.

**Triggers:** When `CamouflageDir` resolves to a path containing `_`, or when multiple similarly named jacket files are present.

**Suggested fix:** Extract `Path.GetFileName(s)` before parsing and require an exact filename such as `$"{musicID}_jacket"` plus an allowed extension.

```suggestion
            var jacketFiles = allJacketFiles.Where(
                s =>
                {
                    var fileName = Path.GetFileName(s);
                    return Path.GetFileNameWithoutExtension(fileName) == $"{musicID}_jacket" &&
                           AllowedImageExts.Contains(Path.GetExtension(fileName).ToLowerInvariant());
                }).ToList();
```
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: AquaMai.Mods/Fancy/TrackCamouflage.cs:108


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread AquaMai.Mods/Fancy/TrackCamouflage.cs

@cubic-dev-ai cubic-dev-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.

All reported issues were addressed across 1 file

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread AquaMai.Mods/Fancy/TrackCamouflage.cs
Comment thread AquaMai.Mods/Fancy/TrackCamouflage.cs Outdated
Comment thread AquaMai.Mods/Fancy/TrackCamouflage.cs

@cubic-dev-ai cubic-dev-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.

All reported issues were addressed

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread AquaMai.Mods/Fancy/TrackCamouflage.cs
Comment thread AquaMai.Mods/Fancy/TrackCamouflage.cs Outdated
Comment thread AquaMai.Mods/Fancy/TrackCamouflage.cs

@cubic-dev-ai cubic-dev-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.

All reported issues were addressed across 1 file (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread AquaMai.Mods/Fancy/TrackCamouflage.cs
@clansty
clansty merged commit 4732cda into MuNET-OSS:main Sep 20, 2026
5 checks passed
@Starrah
Starrah deleted the camouflage-enhance branch September 20, 2026 17:52
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.

2 participants