中文搜索
Modrinth 和 CurseForge 的搜索索引都是英文的。用户搜"机械动力",索引里根本没有中文,结果是零。这一页讲我们怎么让中文输入也能搜到东西。
只在含中文时才动手
var q = (query ?? "").Trim();
if (q.Length == 0 || !ContainsCjk(q)) return new TranslatedQuery(q, q, null);纯英文(或纯符号)查询原样返回,一次网络都不发。绝大多数用户的搜索词本来就是英文或版本号,走这条路零开销。
中英混输(如"Sodium 钠")也特殊处理:只取拉丁字母那部分,不送机器翻译。机翻会把两种写法叠起来——"Sodium 钠"翻成"Sodium Sodium",反而搜不到。
三级策略:准 → 快 → 万能
① 内置词典。 常见中文译名的硬编码表,零网络、精确命中:
["钠"] = "Sodium",
["光影"] = "Shaders",
["物品管理器"] = "Just Enough Items",
["机械动力"] = "Create",词典放在最前面,是因为它不会翻错。"Create"在机翻眼里可能是"创造",而中文玩家搜"机械动力"时想要的一定是 Create。
② MC 百科。 https://search.mcmod.cn/s?key=钠 的搜索结果条目标题形如「钠 (Sodium)」——括号里的英文就是社区通用英文名。这正是"通过 MC 百科翻译"的含义:拿到的不是机翻产物,而是这个模组的真名。
③ 机器翻译。 词典和百科都收不到的长尾词、描述性短语,走 Google gtx(translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=en&dt=t=),失败再退到 MyMemory(api.mymemory.translated.net/get?q=&langpair=zh-CN|en)。
三步都失败就保持原文搜索——搜索结果为空总比搜到不相干的东西强。每步联网 6 秒超时:翻译是旁路能力,卡住不能拖慢搜索本身。走网络的翻译结果同时写内存和磁盘(search_translation_cache.json),只保留真的翻译过的条目。
模组简介的中文译文
搜索结果里每行都有一句英文简介(Modrinth 的 description / CurseForge 的 summary)。这一句也走翻译,但不是本地机翻,而是取 MCIM 上维护的社区译稿:
POST https://mod.mcimirror.top/translate/modrinth?project_id=P7dR8mSH
POST https://mod.mcimirror.top/translate/curseforge?modId=238222
→ { "translated": "查看物品和配方", "original": "View Items and Recipes" }只在界面语言为中文时启用;原文已含中文就不翻;单次 4 秒超时,同时在途请求上限 4 个。
译文是异步替换的:先显示英文原文,译文到达后就地替换。行是 OneWay 绑定,所以替换不会触发列表重排或闪烁。成功结果落磁盘(mod_summary_cache.json),命中即零网络。
坑:失败不写负缓存
ModSummaryTranslationService 在请求成功但没有译稿时,会把键记进 _misses 集合,本次会话不再问:
if (string.IsNullOrWhiteSpace(translated))
{
lock (_memory) _misses.Add(key);
return null;
}但请求本身失败(超时、镜像不可达)走的是 catch,返回 null,什么都不记:
catch
{
// 镜像不可达 / 该条目没译稿:保留原文,下次进列表再试(不写负缓存)
return null;
}这是刻意的——网络抖动不该让译文永久失效。但代价是:每次滚到那一行都要重新等一个超时。同类问题在社区卡片的文本翻译(CommunityTranslator,走 MyMemory)上更明显,它的超时是 9 秒(NetTimeoutMs = 9000),失败时同样不写任何缓存。
连续失败会让列表明显变慢
MyMemory 在无代理网络下常常超时。一个页面上有十个卡片描述要翻、十个都超时,就是九十秒的等待——虽然每个都是后台并行,UI 上表现为"图标一直转"。
我们的取舍是:宁可多等,也不要把"暂时失败"固化成"永远没有译文"。可行的折中是给失败也加一条带时间戳的负缓存——但目前没做,因为超时路径上拿不准该记的是"这个条目没译文"还是"这个网络不通"。
相关链接
- Modrinth 与 CurseForge —— 搜索索引是英文的根源
- 统一内容库 —— 搜到的资源怎么入库