Repository navigation
Releases: LifeSci-Craft/MCDR-ModUpdateChecker
Releases · LifeSci-Craft/MCDR-ModUpdateChecker
Release list
v1.6.2
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
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
这一版把 .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
命令更好敲、列表不再丢东西、提醒按颜色分好类。
新增
- 名字可以只打一半:
!!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
一次处理一批:!!muc download all / !!muc install all;自动下载完成时会专门说一声。
新增
download all/install all:一条命令、一次确认,处理所有「有更新待下载」或「已下载待安装」的 Mod,与单个形式走同一套两步流程。几条规则:all是保留字,永远指「全部」;没有可下载文件的更新会被数出来,不会被悄悄丢掉;批量确认核对的是「哪些 Mod」而不只是数量,两条命令之间集合变了整条作废;install all底层依旧逐条授权;下载失败的那些会被点名。- 下载完成会专门通知:一次检查里真的抓到了新文件时,控制台多一行「下载完成:N 个新版本已就绪(X MB)」并给出下一步,游戏内权限足够的管理员会在同一时刻收到同样的话;没真下到东西就不发。这一条不受
report.in_game控制(那项管的是「有更新了」的广播)。
内部整理
- 修一条测试的顺序依赖:
entry_envfixture 自己钉住语言,不再依赖前面某个测试设过中文。 - 新增测试:源码行末必须统一 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
游戏内的界面统一成一套,编号不再有多余的空格,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
补丁版,没有破坏性变更。配置文件被创建、被补全,现在都有一行控制台记录。
新增
- 配置文件的三种状态各有一行日志:文件不存在 →
配置文件不存在,已按默认值创建:<路径>(共 N 个选项);文件缺选项 →配置文件缺少 N 个选项,已按默认值补上:…(<路径>);该补没补上 → 降级为警告,同样带上路径与选项名。 !!modupdate status增加一行「配置文件」:显示插件实际读写的完整路径。
验证
- 测试 607 项全部通过。
- 真实 MCDR 矩阵新增两项端到端断言:
config_healed(配置文件真的被补全)与config_reported(控制台真的报了补了什么),五版本逐项一致,共 38 项检查。 - 测试里的
_FakeServer.load_config_simple升级为像 MCDR 一样真的读写文件。
Mod Update Checker v1.2.0
四处用户报上来的问题:三处是真 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
一次「把白干的活去掉」的清理。用起来没有任何变化:配置项、命令、报告格式、状态判定都与 v1.1.0 一致。
变更
- 每次扫描不再计算没人读的 SHA-512:识别靠 SHA-1,本地那份 SHA-512 没有任何代码读过。实测 240 MiB(120 个 jar,页缓存热)的扫描耗时从 0.54
0.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
两项新功能、两条新提醒,以及若干「文档说的和代码做的不一致」的清理。配置项和命令向后兼容,新东西默认按最不打扰的方式工作。
新增
- 自己编译的 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、包内代码可编译。