Skip to content

Releases: LifeSci-Craft/MCDR-ModUpdateChecker

v1.6.2

Choose a tag to compare

@Pau1am Pau1am released this 15 Oct 08:20
57f2f19

v1.6.2

修复

  • 一个畸形 mod jar 不再让整次检查没有报告:depends.minecraft 写成数字或对象(例如 1.21 忘了引号)时,以前会让检查整体失败、只剩一句 check failed。
  • 下载请求也计入 network.requests_per_minute:以前只有 JSON 请求限速,批量下载不受限。
  • 响应体读到一半断连会重试;深嵌套响应抛出的 RecursionError 归类为上游错误,不再穿透检查流程。
  • 安装成功后会删除已消费的下载文件并清扫下载目录,磁盘占用不再随更新次数单调增长。
  • 并发写同一 JSON 文件不再失败:按目标目录串行化写入并重试改名,缓存与批准状态不再静默丢失。
  • 配置里写错类型会被点名并备份为 config.json.broken.<时间戳>,不再被 MCDR 静默重置为默认值。
  • ResolveCache 只回写自己新增的记录,多个实例不再互相抹掉对方的解析结果。
  • !!muc list ² 这类输入不再让命令静默失败;数值选项范围表补全(network.retries、download.retries、network.cache.ttl_hours、report.reuse_report_minutes)。
  • 版本比较满足传递性,is_prerelease 与之一致:单字母后缀不再被当成预发布标记。
  • download all 也遵守「同一文件不并发下载」;备份名改为原子抢占,不会再覆盖已有备份;.part 临时名唯一。
  • 元数据解压改为分块读并设上限。
  • i18n 不再依赖 Python 3.9+ 的 API,language: auto 在声明的 3.8 下限上不会退化成只有 en_us。
  • 语言文件里让用户设置的键此前写的是缺少 server. 前缀的旧路径,照做的键会被 MCDR 丢掉;现已更正为 server.mc_version。
  • !!muc 与 !!modupdate 两种别名下,屏内提示都指向用户实际输入的那个别名。
  • last_report.json 改为原子写入;reload 后 !!help 的权限等级文案与实际一致。

工具与工程

  • tools/mcdr_matrix.py 固定子进程编码并在中文终端下保住失败证据;tools/probe_upstream.py 接受参数、离线时给出结论而不是回溯。
  • tools/check_python_floor.py 改为检查「模块 + 属性」对,importlib.resources.files 这类问题不会再漏过。
  • CI 增加端到端作业、pip 缓存与固定 action 版本;补英文 README 与徽章。

验证

  • 测试 885 项全部通过(含 2 项真实 MCDR 端到端)。
  • 变异检查 12 条全部被抓。
  • 真实 MCDR 2.13.0 / 2.14.1 / 2.15.0 / 2.15.7 / 2.16.0 五版本矩阵通过,54 项跨版本判据一致。
  • 产物重建与提交件逐字节一致;包内 changelog 只留本节且与版本号一致。

v1.6.1

Choose a tag to compare

@Pau1am Pau1am released this 14 Oct 15:14
fb977b4

CHANGELOG

本插件所有值得一提的变更都记录在此。插件包内也附带同一份 CHANGELOG.md。

格式参考 Keep a Changelog,版本号遵循 语义化版本。

本文件只保留最新一个版本的条目,更早版本的记录见
GitHub Releases。


v1.6.1

这一版是一轮全代码审查的修复轮:下载台账的并发写入、频道开关失效、mods 目录读不到时的误报,
以及十几处「坏了但不出声」的路径。

修复

  • 并发下载不再丢台账。 下载台账以前由多个实例各自把内存快照整份写回,!!muc download 的两个后台线程、命令线程上的 install 与检查线程会互相覆盖(实测 9 条记录被清成 0 条),后果是「关服自动安装已批准的版本」静默失效。现在写入是进程级加锁的重读-合并-写回,JSON 的临时文件名也带上进程与线程号。
  • check.include_beta / check.include_alpha 之前完全不起作用(频道过滤函数没有任何调用者),默认配置下 beta 会被当成可用更新推荐。现在两个开关生效;某个项目在所选频道里没有版本时会回落到更旧的频道,并在报告里说明这次回落。
  • project-map.json 存成 GBK / ANSI 不再让整次检查失败。 以前 UnicodeDecodeError 会穿过映射表的错误处理:!!muc status 整页报错,一次检查以「check failed」收场、一条结论都不产出。
  • 关掉 sources.modrinth 不再污染解析缓存。 以前「没问过」会被写成「确认不存在」,打开 Modrinth 之后这些 jar 在缓存有效期内(默认 24 小时)一次名字搜索都不会发,永久显示为「认不出」。
  • 下载失败不再先删掉旧版本。 旧文件要等新文件就位之后才删,否则新版本 404 时新旧两份都没有,回滚点消失。
  • 游戏版本投票只取下界。 以前区间上界与下界等权计票、平局按字典序取最大者,猜错版本会让每个 Mod 都显示「无适配构建」。
  • mods/ 目录读不到时不再报成「0 个 jar」。 状态页写明目录与原因,检查直接跳过并说明原因——读不到的目录与空目录是两件事。
  • 安装失败不再在 mods/ 留下半截新 jar。 改成同目录临时文件 + 原子替换;万一仍然留下东西,安装结果会点名那个文件。
  • 上游整体不可用时不再对每个 Mod 逐个搜索(以前 12 个 Mod 会发 48 次搜索请求)。
  • 其余收紧:resolve-cache.json 里的坏记录不再让每次检查失败;scan_mods 在目录可 stat 不可列举时返回可解释的结果而不是抛异常;备份名判定改用 fullmatch;台账里的文件名做安全校验(不再接受 ..);加密或损坏的 jar 不再打破 scan_jar 的「不抛异常」承诺;元数据解压加 4 MiB 上限;下载失败文案不再把不重试的失败说成「重试 N 次后失败」。
  • 停服后在途的检查不再覆盖报告;checker 不再在关闭客户端之后继续发请求。

变更

  • !!muc status 改成两段式:命令线程先回一句「正在读取」,扫描与渲染在后台线程完成后整屏给出——页面不再占用 MCDR 唯一的同步执行器线程;同一时间只允许一份状态页在生成。
  • 数值选项超出范围会被钳制并在控制台提示一次(范围写进 README 的配置表;只改内存,不回写管理员写的文件)。
  • !!muc 别名下不再有写死 !!modupdate 的提示行;cleanup.notice_confirm / command.delete.usage / command.delete.disabled_hint 的占位符随之调整(翻译者注意)。
  • 版本识别是从日志或 Mod 元数据推断出来的时候,状态页会多一行说明来源。
  • 版本号 1.6.0 → 1.6.1。

内部整理

  • 新增 tools/mutation_check.py:把每条守卫逐个改坏(在仓库的临时副本里改,工作树不受影响),对应的用例必须失败;没被抓住的守卫与「锚点挪走」分开报告。
  • 新增 tools/check_python_floor.py 与 CI 的 python-floor 作业:每个文件都必须能以 3.8 解析、且不用更新的注解写法或标准库名字。
  • 新增 CI 的 lint 与 mutation 作业;两个 workflow 都补上 permissions、timeout-minutes 与 concurrency。
  • README-dev.md 引用的测量脚本(7 个)连同 bench/README.md 一起进仓库,并新增 tests/test_documented_paths.py 守卫文档里写出的仓库路径确实存在。
  • 入口模块顶部按主题列出段落顺序与拆分计划(未搬迁)。

验证

  • 测试 827 项全部通过(其中 2 项是真实 MCDR 端到端)。
  • 变异检查 12 条全部被抓。
  • 真实 MCDR 2.13.0 / 2.14.1 / 2.15.0 / 2.15.7 / 2.16.0 五版本各跑一遍完整流程,逐项一致。
  • 产物可复现、换行归一、包内无注释与 docstring、包内 changelog 只留本节且与版本号一致。

Mod Update Checker v1.6.0

Choose a tag to compare

@Pau1am Pau1am released this 10 Oct 13:47
47cb8f2

这一版把 .old 备份纳入管理:列表里看得见、可筛选、可删除,但默认一个字节都不删;另有一轮
全代码审查和多处界面修正。

新增

  • .old 备份成为一类状态(old_backup,图标 ⏪):出现在 !!modupdate list(!!modupdate list old_backup 可单独筛出)、!!modupdate info(文件名、大小、留了多久)与 !!modupdate status(几个、共多大、几个超期)。它不参与「共检查 N 个 jar」,也不会被拿去问 Modrinth。
  • 删除旧备份:!!modupdate delete <文件名 / 编号> 删一个、!!modupdate delete all 删全部(不看天数)、!!modupdate cleanup 只删已过期的(默认满 30 天)。三条都先列计划、再由 !!modupdate confirm 确认;第一次敲 cleanup 通常什么都不会删,它会报出现状与两条路(点名删除,或调小 cleanup.max_age_days)。
  • 删除总开关 cleanup.allow_delete(默认关闭):关着时 delete / cleanup 和它们的 confirm 一律被拒,插件不删除 mods/ 里的任何文件;详情页的 [删除此备份] 按钮与状态屏都会说明这一点。
  • 到期提醒 cleanup.enabled(默认关闭,排在总开关之后):发现有过期备份时提醒一次并摆好计划,直接 !!modupdate confirm 即可;不会顶掉正在等待确认的其它操作。

变更

  • 删除的安全规则:delete / cleanup / 确认 / 提醒四处走同一个开关;只认插件自己生成的备份名(<文件名>.jar.old、.jar.old.2 这类),删除时重新核对,要删的集合变了整条计划作废,指向真 Mod 的编号会被拒绝。
  • 列表配色按「一块是什么」定:编号永远黄、名称永远白、[版本] 绿、[详细信息] aqua;状态色 绿 = 已是最新、蓝 = 有更新与待安装、红 = 有问题、其余灰(图标、浮窗第一行、汇总分节标题与通知都用同一张表)。
  • 状态收进 [状态: 图标] 一格:✔ 已是最新、↑ 有新版可下载、↓ 已下载待安装、❌ 无适配构建、✘ 出错、☆ 本地比上游新、? 认不出上游、○ 不是 Mod、⏪ 旧版备份、— 配置里忽略;含义在浮窗第一行(状态名 + 状态色)。图标只取原版字体自带的符号。
  • 版本收进绿色 [版本]:悬停展开(有更新时是红 >>> 绿);控制台与日志照旧印版本数字。
  • 列表行四格对齐:[编号] 名称 [版本] [状态] [详细信息];名称超宽截成 ...(全名在悬停里);补齐按截图实测的字宽模型(i j l t f I 1 记 3/4 个字母、. [ ] 记 1/2、汉字记 2¼;控制台等宽仍按字符数)。完全对齐受字体限制做不到,README 已写明。
  • 每一屏加了与标题栏同宽的收尾线;翻页行改成标题栏样式(到头一侧变灰、点不动)。
  • 悬停与点击:帮助页只留短句、说明文字可点、细节进浮窗;[详细信息] 的浮窗说明它执行 !!modupdate info <Mod 名>;计划里的 confirm 是亮红色按钮(点击只填入输入框,不直接执行)。
  • 文案修正:状态不再一行说两遍;行上的版本注解与状态标签统一((已下载,未安装) 归状态);括号不再套括号;列表末尾悬空的冒号拆开;本地版本更新 改名 本地比上游新;英文状态名收成标签长度;游戏内中文括号统一为半角(71 条)。

修复

  • 备份的年龄以前算错:改名成 .old 会保留原时间戳,升级后会把所有旧备份当成「早已过期」;现在安装时把时间戳刷成它成为备份的那一刻。
  • 删掉的文件不再留在列表里:删除成功后条目会从报告与 last_report.json 一并摘掉。
  • 控制台的列表行重新显示版本号:此前把行形态统一成聊天形态,控制台也印了 [版本] 标签,而终端里没有悬停。
  • 浮窗不再整段溢出:客户端只在空格处断行,中文没有空格,现在全部手工断行(每行 ≤ 32 显示列);list 的状态清单改成一行一个。
  • 缓存文件内容异常不再导致插件启动失败(resolve-cache.json 被写成 [] 之类):!!muc status 的那行日志现在先检查文件形状。

内部整理

  • 一次全代码审查:插件自身的 JSON 统一走原子写;两处重复的下载计数合并为一个函数;备份列表少一次系统调用;删掉一处无用解包;语言文件 304 条逐键核对无孤儿。未改动的都记了理由(README-dev.md)。
  • 渲染路径量过之后,把每行重算的格宽改为按语言缓存(195 µs → 0.8 µs / 10 行);扫描不并行是量过的决定。

验证

  • 测试 725 项全部通过(v1.5.0 是 652 项);27 处注入验证全部被抓到(撤掉一条守卫,对应测试确实失败)。
  • 真实 MCDR 2.13.0 / 2.14.1 / 2.15.0 / 2.15.7 / 2.16.0 五版本各跑一遍完整流程,逐项一致(54 项 required_keys + 2 项附加检查;v1.5.0 是 43 项)。
  • 产物可复现、换行归一、包内无注释与 docstring、包内代码可编译。

Mod Update Checker v1.5.0

Choose a tag to compare

@Pau1am Pau1am released this 08 Oct 13:41
05469bf

命令更好敲、列表不再丢东西、提醒按颜色分好类。

新增

  • 名字可以只打一半:!!modupdate download sod 能对上 Sodium。唯一匹配时直接使用;匹配到多个时列出候选,候选每一条都能点击填入完整命令。MCDR 控制台里可以用 Tab 补全(!!muc download 、!!muc list 、!!muc install 、!!muc info 都支持)。
  • 两条守住不猜的规则:精确匹配永远不会被放宽成前缀匹配;前缀匹配和精确匹配走同一套归一化(大小写、空格、连字符都不计较)。
  • !!modupdate list 翻页:超过一页时不再截断,任何一行都不会丢。游戏内给 [上一页] / [下一页] 按钮,控制台给可直接敲的命令;页码可以手打(!!modupdate list 3、!!modupdate list awaiting_install 2);页码越界时落在最后一页并如实显示;翻页时筛选保留;每一页内部仍是要处理的优先。
  • 只可能在客户端用的依赖不再算「缺依赖」:每个找不到的依赖会拿去问 Modrinth,标记为「不支持服务端」的不计入服务端缺依赖(optional 和没填的照旧提醒)。被排除的那个会在这个 Mod 的详情里留一句说明。

变更

  • !!modupdate / !!muc 不带子命令时改为显示帮助页:原来的「上次检查汇总」搬到 !!modupdate summary。帮助页的用法行也写明「不带子命令就是本页」。
  • 提醒按角色上色:管理员上线提醒、关服安装汇报、下载完成通知不再整片黄:标题白、要动手的行黄、已经做完的灰、提示灰。颜色在句子构造处决定,不是事后按文本猜。

内部整理

  • 列表编号与翻页解耦为 index_page 与 render_index 两个函数,聊天与控制台共用同一套分页算术。
  • 矩阵工具的 tellraw 解析器兼容 MCDR 2.13.0 的序列化形状(裸 list 与对象包 list 都支持),并读取每段文字的颜色。
  • _INDEX_FIXED_LINES 从 6 调到 7(界面多了一行翻页行)。

验证

  • 测试 648 项(v1.4.0 是 627 项)全部通过。
  • 七处新行为都做了注入验证(撤掉之后对应测试确实失败):前缀匹配、翻页只给第一页、越界页码夹到最后一页、客户端专属依赖不排除、裸命令指回汇总、提醒颜色塌回一种、角色表不动而每一行都给同一个角色。
  • 真实 MCDR 2.13.0 / 2.14.1 / 2.15.0 / 2.15.7 / 2.16.0 五版本各跑一遍完整流程,43 项检查逐项一致(v1.4.0 是 41 项)。
  • 产物可复现、换行归一、包内无注释与 docstring、包内代码可编译。

Mod Update Checker v1.4.0

Choose a tag to compare

@Pau1am Pau1am released this 08 Oct 13:30
9602f0e

一次处理一批:!!muc download all / !!muc install all;自动下载完成时会专门说一声。

新增

  • download all / install all:一条命令、一次确认,处理所有「有更新待下载」或「已下载待安装」的 Mod,与单个形式走同一套两步流程。几条规则:all 是保留字,永远指「全部」;没有可下载文件的更新会被数出来,不会被悄悄丢掉;批量确认核对的是「哪些 Mod」而不只是数量,两条命令之间集合变了整条作废;install all 底层依旧逐条授权;下载失败的那些会被点名。
  • 下载完成会专门通知:一次检查里真的抓到了新文件时,控制台多一行「下载完成:N 个新版本已就绪(X MB)」并给出下一步,游戏内权限足够的管理员会在同一时刻收到同样的话;没真下到东西就不发。这一条不受 report.in_game 控制(那项管的是「有更新了」的广播)。

内部整理

  • 修一条测试的顺序依赖:entry_env fixture 自己钉住语言,不再依赖前面某个测试设过中文。
  • 新增测试:源码行末必须统一 LF(.gitattributes 只在提交时归一,「读文件再写回」的脚本会制造 CRLF)。
  • 用于注入验证的两个脚本改用 newline="\n" 写回。

验证

  • 测试 627 项(v1.3.0 是 616 项)全部通过。
  • 五处新行为都做了注入验证(撤掉之后对应测试确实失败):保留字失效、批量集合不再比对、完成通知不接、游戏内那一半去掉、批量安装只装第一个。
  • 真实 MCDR 2.13.0 / 2.14.1 / 2.15.0 / 2.15.7 / 2.16.0 五版本各跑一遍完整流程,40 项检查逐项一致(v1.3.0 是 38 项)。
  • 产物可复现、换行归一、包内无注释与 docstring、包内代码可编译。

Mod Update Checker v1.3.0

Choose a tag to compare

@Pau1am Pau1am released this 08 Oct 13:27
d065011

游戏内的界面统一成一套,编号不再有多余的空格,info 里不再出现两个下载入口。

变更

  • 所有游戏内界面统一:每个界面都以同一段标题栏开头,下面一行服务端上下文,然后是内容。颜色固定五个含义:金色标题栏、aqua 可操作项、白色内容、黄色需要处理的行、灰色其余。此前「按文字猜颜色」的函数删掉了(它把同一件事涂成两种颜色,还会因为一个名叫 a->b 的 Mod 而改色)。
  • !!muc info 里下载只出现一次:去掉直接指向 CDN 文件地址的链接(它绕过了插件下载时的哈希校验),只留按钮,位置不变;文件地址仍在 last_report.json 里,供自动化脚本使用。
  • 游戏内不再出现裸 URL:汇总改给 [详细信息] 按钮(与 list 一致)并显示编号。控制台日志保持原样:那里的 URL 是唯一能到达项目页的方式。

修复

  • 编号不再补空格:[1] 就是 [1],[9] 和 [10] 差一个字符。
  • 汇总里的行序与编号对齐:小节内部与 list 用同一个顺序,不再出现 [2] 排在 [1] 前面。
  • 链接列按显示宽度对齐:中文界面上汉字占两个字符宽,按 len() 补空格会把链接列推得参差不齐。
  • 已是最新的 Mod 不再画假箭头:版本: 0.160.6+26.3 -> 0.160.6+26.3 看起来像发生了一次没发生的变更。

内部整理

  • 删掉两个全库无人调用的渲染函数(render_detail、render_index_body)与 _coloured_line。
  • 测试里的 _FakeServer.load_config_simple 改为真的读写文件。

验证

  • 测试 616 项(v1.2.1 是 607 项)全部通过。新增断言三条:所有界面必须以同一段标题栏开头、游戏内汇总不得出现 URL 且必须带按钮、链接列必须按显示宽度对齐。
  • 真实 MCDR 2.13.0 / 2.14.1 / 2.15.0 / 2.15.7 / 2.16.0 五版本各跑一遍完整流程,逐项一致。
  • 产物可复现、换行归一、包内无注释与 docstring、包内代码可编译。

Mod Update Checker v1.2.1

Choose a tag to compare

@Pau1am Pau1am released this 08 Oct 13:22
78b2145

补丁版,没有破坏性变更。配置文件被创建、被补全,现在都有一行控制台记录。

新增

  • 配置文件的三种状态各有一行日志:文件不存在 → 配置文件不存在,已按默认值创建:<路径>(共 N 个选项);文件缺选项 → 配置文件缺少 N 个选项,已按默认值补上:…(<路径>);该补没补上 → 降级为警告,同样带上路径与选项名。
  • !!modupdate status 增加一行「配置文件」:显示插件实际读写的完整路径。

验证

  • 测试 607 项全部通过。
  • 真实 MCDR 矩阵新增两项端到端断言:config_healed(配置文件真的被补全)与 config_reported(控制台真的报了补了什么),五版本逐项一致,共 38 项检查。
  • 测试里的 _FakeServer.load_config_simple 升级为像 MCDR 一样真的读写文件。

Mod Update Checker v1.2.0

Choose a tag to compare

@Pau1am Pau1am released this 08 Oct 09:26
040acfb

四处用户报上来的问题:三处是真 bug,一处是新功能。

修复

  • 下载一个 Mod 之后,整个列表的编号不再全变:update_available 与 awaiting_install 现在共用同一个名次(名次内部按名字排序),下载不改变名字,编号因此不动。副作用:「有更新待下载」与「已下载待安装」现在混在一起按名字排(此前前者全在前),两批都仍在列表最前。
  • 编号列的补零:7 个 Mod 的清单不再显示 [ 1];宽度按这一页实际会打印的最大编号算,一位数就是 [1],有两位数时才对齐成 [ 1] / [10]。

新增

  • 下载 / 安装 / 详情可以直接填 Mod 名字:编号、Mod 名(大小写、空格、连字符都不计较)、mod id、jar 文件名(带不带 .jar 都行)四种写法都认。先精确匹配再宽松匹配;名字同时匹配到多个 Mod 时会被拒绝并提示改用编号;「编号超出范围」「名字不唯一」「找不到」分开报。
  • 配置文件完整性新增三条测试:Config 的字段与写出的 JSON 必须是同一个集合;每个选项都必须在 README 或开发者文档里出现过;一份缺了选项的配置文件会被补齐并重写,且管理员自己改过的值不受影响。

验证

  • 测试套件 601 项(v1.1.1 是 590 项)全部通过。
  • 四处修复各做了一次注入验证(把修复撤掉,对应的测试确实会失败)。
  • 真实 MCDR 2.13.0 / 2.14.1 / 2.15.0 / 2.15.7 / 2.16.0 五版本各跑一遍完整流程;矩阵顺带抓到了本轮排序改动引起的一处写死前提并修正。
  • 产物可复现、换行归一、包内无注释与 docstring、包内代码可编译。

Mod Update Checker v1.1.1

Choose a tag to compare

@Pau1am Pau1am released this 08 Oct 07:43
64f544d

一次「把白干的活去掉」的清理。用起来没有任何变化:配置项、命令、报告格式、状态判定都与 v1.1.0 一致。

变更

  • 每次扫描不再计算没人读的 SHA-512:识别靠 SHA-1,本地那份 SHA-512 没有任何代码读过。实测 240 MiB(120 个 jar,页缓存热)的扫描耗时从 0.540.62 秒降到 0.300.40 秒,约省下一半时间。
  • !!modupdate status 不再把整个 Mods 目录读一遍:该命令只用文件名,现在走「只要元数据、不读字节」的扫描档;在几百 MB 的整合包上不再有约一秒的卡顿。
  • 两个批量查询合成一个往返:识别一个 Mod 的最后两次请求(取最新适配构建、取项目标题与链接)此前串行,现在并发。

内部整理

  • 两处失败的收集方式从「在 worker 里往报告上追加」改成「把结果和异常当值取回来」,消除一段隐藏的写入顺序竞争。
  • 版本号三处(plugin.json / CHANGELOG / README 样例)由测试核对,并钉住「CHANGELOG 只保留一个版本段」这条规矩。
  • status 的说明补上「本地映射表」一行(README 命令表此前漏了)。

验证

  • 测试套件 590 项(v1.1.0 是 582 项)全部通过。
  • 两条新增的行为断言都做了注入验证(撤掉修复之后它们确实会失败)。
  • 真实 MCDR 2.13.0 / 2.14.1 / 2.15.0 / 2.15.7 / 2.16.0 五版本各跑一遍完整流程。
  • 产物可复现、换行归一、包内无注释与 docstring、包内代码可编译。

Mod Update Checker v1.1.0

Choose a tag to compare

@Pau1am Pau1am released this 08 Oct 07:08
9b81e22

两项新功能、两条新提醒,以及若干「文档说的和代码做的不一致」的清理。配置项和命令向后兼容,新东西默认按最不打扰的方式工作。

新增

  • 自己编译的 Mod 现在能查(sources.manual_map):在 config/mod_update_checker/project-map.json 里写 by_sha1 / by_mod_id 两张表,把自编译、重新打包、改过签名的 jar 指到 Modrinth 项目上。文件只读不写;作为管理员的明确声明,它排在自动名称匹配之前;被它认出来的条目在报告里标为 manual。填错时会明说「引用找不到」,而不是悄悄退回按名字猜;!!modupdate status 显示清单读到几条。
  • 报告会告诉你哪些更新是「刚出现的」:「有更新」一节末尾多一行「其中 N 项是上次检查之后新出现的」。配套修复了 last_report.json 只写不读的问题:report.reuse_report_minutes 的复用窗口现在跨重启有效,判断也从「够不够新」扩成「还算不算数」(Mods 目录、加载器、写死的 server.mc_version 必须与现状一致,否则旧结论作废)。
  • 缺少依赖提醒:某个 Mod 声明的必装依赖在 mods/ 里找不到(只认必装,平台自身已剔除,provides 会被认作满足)。
  • 「Modrinth 标记为不支持服务端」提醒:用 Modrinth 自己的 server_side 字段判断(零额外请求,数据本来就在同一次批量查询里);只有明确写了 unsupported 才报。两条提醒都宁可多报。

内部整理

  • 名称匹配与映射表共用的判断抽成一个方法;报告序列化改为带 format 标记的往返回合;「单个文件名不是路径」的校验抽成共用函数。
  • 修正三处「文档比代码乐观」的说法(解析缓存的真实行为、扫描是否阻塞开服、一处早已废弃的旧配置名),删除一个从未被使用的字段。

验证

  • 测试套件 582 项(v1.0.1 是 504 项)全部通过。
  • 真实 MCDR 2.13.0 / 2.14.1 / 2.15.0 / 2.15.7 / 2.16.0 五版本各跑一遍完整流程。
  • 产物可复现、换行归一、包内无注释与 docstring、包内代码可编译。