以前点「发现新版本」,只会弹一句“是否打开下载页”——浏览器跳走,用户还得自己记着下载、解压、找旧 exe 覆盖。把“检查更新”做成了“提醒更新”,最后一步始终卡在手动操作上。
v1.4.0 把这一步补完:客户端可以在程序内下载更新包、校验、退出、替换并自动重启,全程不用打开浏览器。同时把上一版(1.3.1)已完成的 JASS 注入配置交付能力一起带上——1.3.1 没有单独发版,本次一并发布。
这次更新了什么
1. 程序内自动更新(本次核心)
发现新版本时会弹出三个选择:自动更新 / 打开下载页 / 稍后。
选择自动更新后:
- 工具在后台流式下载 ZIP 更新包,进度窗口显示已下载字节数与百分比,可随时取消;
- 下载完成后按服务端给出的 SHA-256 与字节数双重校验,不一致直接丢弃,不会装上一个损坏的包;
- 只从包内解出唯一一个 exe,拒绝路径穿越、拒绝非 Windows 程序文件、限制包与 exe 体积;
- 解出的新版本以
--apply-update模式自举为替换进程,等旧进程完全退出后:先把旧 exe 备份为.exe.bak,再覆盖写入并启动新版本。
失败不会留下半截状态:
- 任一步校验失败、下载中断、替换时文件被占用,都会还原旧 exe 并提示是否改为打开下载页;
.exe.bak保留 7 天,新版本确认可用后自动清理,避免 36 MB 残包长期堆积;- 服务端未配置哈希、或当前不是打包后的 exe(源码运行)时,自动退回“打开下载页”,行为与 1.3.x 一致。
2. 服务端新增更新包校验字段
/admin/download 管理页新增两项:更新包 SHA-256 与更新包字节数。
- 两项可以留空,留空即维持旧行为(只打开下载页);
- 填了就启用程序内更新,客户端会强校验;两项必须同时填写,格式错误会被服务端拒绝;
- 公开接口
/api/download只多返回这两个字段,仍不涉及任何上传数据; - 下线下载入口时,两个字段一并清空。
3. 分发改用 ZIP 更新包
自动更新需要解压,而用户机器上不一定装了 WinRAR。因此安装包改以 ZIP 分发(Python 内置解压,不依赖第三方工具)。RAR 版本仍可继续提供,只是走自动更新的用户需要 ZIP。
4. 一并带上 1.3.1 的 JASS 注入增强
1.3.1 当时未单独发版,内容合并到本版:
- 「导出配置 / 导入配置」:把调好的注入步骤存成 JSON 发给其他作者,导入时先命名、同名可覆盖,兼容旧版字段,且不含地图路径;
- Markdown 报告改为「步骤总览 + 分步详情」,批量命中压成一行;
- 应用成功后自动回到步骤详情并清空旧 diff,保留当前步骤选中;
- 服务端实时诊断流的长文本按换行展示。
怎么升级
第一次升级到 1.4.0 仍需手动一次(旧版本没有自更新能力):
- 先更新服务端(含
sha256/size字段),否则客户端仍只会打开下载页; - 退出正在运行的工具;
- 用 v1.4.0 的 exe 覆盖旧版 exe;
- 保留同目录的
analyzer_config.json、history.db与jass_inject/目录。
从 1.4.0 起,后续版本就可以直接点「自动更新」完成升级。
验证说明
- 全量回归 402 项通过(2 项跳过、2 项预期失败),新增 27 项自更新相关用例:哈希/字节数校验、取消下载、HTTP 失败、路径穿越、多 exe、非 PE 文件、替换成功、替换失败回滚、旧进程不退出、备份保留与过期清理;
- 端到端冒烟:本地 HTTP 提供真实 ZIP,真实 1.4.0 exe 完成「下载 → 校验 → 解压 → helper 替换 → 重启」,
.bak内容为旧版本,退出码 0; - GUI 冒烟:主循环驱动更新进度窗口走完整流程,确认替换成功且只触发一次退出。
下载与反馈
安装包与更新说明见下载页:
https://ca.darksheep.vip/download
遇到问题时,可以在「崩溃诊断」页上传日志获得 6 位上传码,把上传码发给维护者或地图作者。
隐私与数据边界
- 更新过程只下载更新包,不上传任何本机数据;
- 校验在本地完成,不上报下载结果或本机信息;
- 下载的更新包放在系统临时目录,成功替换后由下次启动清理;
- 其余数据范围与 1.3.x 相同,未新增任何采集项。
——萧夜