Skip to content

Conversation

@Starrah
Copy link
Contributor

@Starrah Starrah commented Feb 1, 2026

支持前端显示和编辑sortName,编辑的sortName会被自动处理确保符合要求。

PS:动机:我自己写洛天依的中文歌比如《蝴蝶》,然后会被MCM自动生成sortName为コチョウ,有点难绷x 现在我至少可以导入后自己手动改为HUDIE了。

@gemini-code-assist
Copy link

Summary of Changes

Hello @Starrah, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求旨在增强音乐管理功能,允许用户在前端界面直接查看和修改音乐的 sortName 属性。这一改进解决了自动生成 sortName 可能不符合用户预期的问题,通过引入新的API端点和更新前端UI,用户现在可以手动调整排序名称,并且系统会自动确保其格式的合规性。

Highlights

  • 新增SortName编辑功能: 新增了后端API端点 EditMusicSortName,用于编辑音乐的 sortName
  • 前端API与UI更新: 前端API客户端已更新,以支持 sortName 字段的显示和编辑,并集成了新的 EditMusicSortName API。音乐编辑界面现在包含一个 sortName 输入框,允许用户修改音乐的排序名称。
  • SortName自动格式化与UI同步: 后端 MusicXml 模型中,SortName 属性现在可以独立设置,并且其setter会自动对输入值进行格式化处理,确保符合游戏要求。前端会根据后端返回的格式化结果自动更新显示。
  • 多语言支持: 更新了多语言文件,为 sortName 字段及其提示信息提供了本地化文本。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the functionality to display and edit the sortName property for music tracks in the frontend, allowing for manual correction of automatically generated sort names, especially for non-Japanese songs. However, two critical security vulnerabilities have been identified: a Path Traversal vulnerability in the new API endpoint due to unvalidated route parameters, and a potential Denial of Service (application crash) when processing XML files that lack the newly introduced sortName tag. Additionally, the implementation has several areas for improvement, including a NullReferenceException in MusicXml.cs if the sortName XML node is missing, the new API endpoint in MusicController.cs returning an empty string instead of a proper error when music is not found, and a lack of error handling in the frontend's sync function.

Comment on lines 29 to 38
const sync = (key: keyof MusicXmlWithABJacket, method: Function) => async () => {
if (!info.value) return;
info.value!.modified = true;
await method(info.value.id!, info.value.assetDir, (info.value as any)[key]!);
const value = (info.value as any)[key];
const result = (await method(info.value.id!, info.value.assetDir, value)).data;
if (key === "sortName" && typeof result === "string" && result !== value) {
// 如果调用的是sortName接口,且返回的字符串(经过格式化后的实际内容)和传过去的值不同的话,则覆盖之
info.value!.sortName = result;
}
}

Choose a reason for hiding this comment

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

critical

sync 函数目前没有处理API调用失败的情况。如果像 EditMusicSortName 这样的API调用因为找不到资源而返回404错误(如上一个评论建议的),await会抛出异常,导致一个未处理的 promise rejection。这可能会使应用处于不稳定状态。建议在 sync 函数中添加 try-catch 块来优雅地处理这些错误,并向用户显示错误信息。

Suggested change
const sync = (key: keyof MusicXmlWithABJacket, method: Function) => async () => {
if (!info.value) return;
info.value!.modified = true;
await method(info.value.id!, info.value.assetDir, (info.value as any)[key]!);
const value = (info.value as any)[key];
const result = (await method(info.value.id!, info.value.assetDir, value)).data;
if (key === "sortName" && typeof result === "string" && result !== value) {
// 如果调用的是sortName接口,且返回的字符串(经过格式化后的实际内容)和传过去的值不同的话,则覆盖之
info.value!.sortName = result;
}
}
const sync = (key: keyof MusicXmlWithABJacket, method: Function) => async () => {
if (!info.value) return;
info.value!.modified = true;
const value = (info.value as any)[key];
try {
const result = (await method(info.value.id!, info.value.assetDir, value)).data;
if (key === "sortName" && typeof result === "string" && result !== value) {
// 如果调用的是sortName接口,且返回的字符串(经过格式化后的实际内容)和传过去的值不同的话,则覆盖之
info.value!.sortName = result;
}
} catch (e) {
console.error(`Failed to sync ${key}:`, e);
message.error(t('error.unknown'));
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

是不是其实也没啥,在浏览器里unhandled promise rejection本质上和把错误console.error到控制台是一样的,(又不是node, unhandled promise rejection会崩)我是懒得改了

Comment on lines +32 to +42
public string EditMusicSortName(int id, [FromBody] string value, string assetDir)
{
var music = settings.GetMusic(id, assetDir);
if (music != null)
{
music.SortName = value;
return music.SortName; // 因为music.SortName的setter中会对内容做格式化、确保符合要求。所以把转化的结果返回前端供前端更新。
}

return "";
}

Choose a reason for hiding this comment

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

security-high high

The assetDir parameter is directly obtained from the route and used to retrieve music data. This is highly susceptible to a Path Traversal vulnerability, as an attacker could use .. sequences to access or manipulate files outside the intended directory. Additionally, when a music track is not found, the API currently returns an empty string "". This can lead to unexpected frontend behavior, potentially clearing the sortName field. It's more RESTful and robust to return NotFound() (HTTP 404) to clearly indicate that the resource was not found. This change will also require adding a try-catch block in the frontend's sync function to handle API errors.

    public ActionResult<string> EditMusicSortName(int id, [FromBody] string value, string assetDir)
    {
        // TODO: Implement validation for 'assetDir' to prevent Path Traversal vulnerability.
        var music = settings.GetMusic(id, assetDir);
        if (music != null)
        {
            music.SortName = value;
            return music.SortName; // 因为music.SortName的setter中会对内容做格式化、确保符合要求。所以把转化的结果返回前端供前端更新。
        }

        return NotFound();
    }

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 participant