2026年9月12日·发布日志·0 次浏览·10 分钟阅读

Hello KSP Launcher v1.3.0

发行说明

重要提示 / Important Note: 本发行版包含更新器(updater.exe)的更新。如果您仍在使用较早的 v1.2.0 系列版本,由于其自带的老版更新器无法获取到自身的新二进制,自动更新可能无法替换本组件——届时请手动替换 updater.exe。

v1.3.0 — 存档管理重构、更新器自更新与 UI 优化(2026-09-12)

本发行版将存档管理重构为实例详情页的子选项卡,升级备份目录方案以避免冲突,使内置更新器能够自我更新,并优化了自定义标题栏和关于页面。

存档管理现在位于实例详情页内

“存档管理”以前是一个独立的全屏页面(SavesListPage),重复了实例详情侧边栏,并且必须通过 Mod 管理选项卡来路由导出/导入/浏览。现在它是实例详情页的二级选项卡,与游戏设置和 Mod 管理一致。

  • 新增 savestabpage.{h,cpp} — 仅包含存档列表(loadSaves、双击 saveSelected)。对象名 savesTabPage。
  • instancedetailpage.{h,cpp} — 向其 QStackedWidget 添加第 4 个选项卡(存档管理);侧边栏“存档管理”按钮现在调用 showSection(4);showSection 增加了 idx=4 选择和 loadSaves;新增 saveSelected 信号;移除了 savesManageRequested 信号。
  • mainwindow.{h,cpp} — 移除了 SavesListPage 以及 onSavesManageRequested / onSavesNavToDetail / onSavesModpackAction / onBackFromSavesList 路由;InstanceDetailPage::saveSelected 直接连接到 onSaveSelected;onBackFromSaveDetail 返回到实例详情页并停留在存档选项卡。
  • 导出/导入/浏览 — 在存档选项卡内就地触发,复用实例详情侧边栏的 ZIP/CKAN 和浏览菜单(同一个 ModpackController),无需切换选项卡。
  • 移除 saveslistpage.{h,cpp};相应清理了 CMakeLists.txt 和 dark/light.qss 中的 savesListPage 规则。
  • 测试 — 两个测试套件均可构建;UI 已手动验证:存档管理不会导航离开,导出/导入就地打开,从存档详情返回时回到存档选项卡。

备份目录升级(防冲突)

备份以前位于 backups/{instanceName}/{saveName}/*.zip;两个名称相似的实例如果具有相同存档名,可能会互相覆盖备份。现在第一级会附加实例 id 的前 8 个字符(第一个 UUID 段,例如 550e8400):backups/{instanceName-idPrefix}/{saveName}/*.zip。实例 id 全局唯一,并且重命名不会改变它,因此即使显式重命名后,备份仍可定位。

  • 目录计算(instancemanager_backup.cpp getBackupDirForSave)— sanitizeFileName(instanceName) + "-" + instanceId.left(8);存档名层级保持普通名称。空 id 会回退为仅使用实例名,以增强健壮性。
  • 惰性迁移(migrateLegacyBackups)— 两种旧布局(backups/{instanceName}/{saveName} 和更早的单层 backups/{saveName})在访问时迁移;如果目标已存在(名称冲突),则跳过迁移以保持幂等;迁移的 *.zip 文件会被移动,旧目录会被清空。
  • 实例 id 传递 — 与备份相关的 InstanceManager 接口(getBackupDirForSave / listBackups / createBackup / restoreBackup)新增了 instanceId 参数;saveSelected / setSavePath 调用链 savestabpage → instancedetailpage → mainwindow → savedetailpage 会一路传递 id(savestabpage 直接使用 m_instance.id)。
  • 备份 zip 文件命名不变 — saveName[_note]_yyyyMMdd_HHmmss.zip;只有目录层级发生了变化。

内置更新器现在可以自我更新

更新器被排除在自身的保留列表之外(它在清理/移动期间总是跳过 updater.exe),因此无法替换自身。此前发行说明要求 v1.2.0 用户手动替换它。现在,当发行说明正文标记“本发行版附带更新后的内置更新器”时,更新会保留更新包 zip,重新启动后的新启动器会静默替换 updater.exe——无需手动步骤。

  • 检测(updatemanager.{h,cpp} bodyIndicatesUpdaterUpdate)— 匹配发行说明正文中的双语短语(中文“本 Release 含有更新器”或英文“ships an updated built-in updater”);命中后 ReleaseInfo.updaterUpdate=true。
  • 保留 zip(updatemanager.cpp applyUpdate)— 在 Windows 上,如果 updaterUpdate 为真,则向 .updater_update/ 写入 updater_pending 标记(包含 zip 文件名),并向更新器传递 --keep-zip;src/updater/main.cpp 解析 --keep-zip,完成后不再删除 .updater_update 目录。
  • 新启动器替换(main.cpp,启动守卫之后,仅 Windows)— applyPendingUpdaterUpdate 检测 updater_pending → 在保留的 zip 中按 basename 查找 updater.exe(容忍单一顶层发布布局,大小写不敏感)→ 解压到临时文件 → 覆盖应用目录中的 updater.exe → 成功后完全删除 .updater_update。失败时弹出对话框提供“重试 / 忽略”(忽略会调用 cleanupPendingUpdaterUpdate);通常静默且非阻塞。
  • Zip 条目 API(updatemanager.{h,cpp})— findZipEntryByBaseName / extractZipEntry(基于 miniz),用于定位并解压任意深度的更新器条目。
  • 翻译 — 新增 7 个 UI 字符串并完成 en_US 翻译(556 个全部已翻译),.qm 已重建并同步到 dist/translations。
  • 测试 — test_launcher 新增 updaterUpdateBodyDetection 和 zipUpdaterEntry(双语言检测、普通日志无误报、任意深度查找、大小写不敏感、缺失条目、解压内容匹配)。两个 ctest 套件均通过。

自定义标题栏边缘缩放已修复

Qt::FramelessWindowHint 会剥离启用窗口缩放的本地 WS_THICKFRAME 样式,因此无边框窗口无法从其边缘调整大小。

  • 补丁(mainwindow.{h,cpp} applyNativeFrameStyle,仅 Windows)— 保留无边框自定义绘制外观,然后在首次 showEvent 之后以及 toggleMaximize 中,通过 SetWindowLongPtr(GWL_STYLE) 重新添加 WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,并调用 SetWindowPos(SWP_FRAMECHANGED),以便系统重新计算非客户区。刻意不恢复 WS_CAPTION,因此不会出现系统标题栏。
  • 命中测试(WM_NCHITTEST)— 边缘/角落抓取区域从 6px 加宽到 8px,以配合恢复的 WS_THICKFRAME,实现平滑的原生缩放。
  • 结果 — 在保留自定义绘制的无边框标题栏的同时,四条边均可自由、平滑地调整大小。

关于页面条目图标

  • 鸣谢部分 — KSP-CKAN 团队(ckan.png)、Hello Minecraft Launcher 项目(hmcl.png);两个镜像 gh-proxy.com 和 ghfast.top 共用 GitHub 图标(github.png)。
  • 依赖部分 — Qt 6(qt6.png)。
  • 实现 — 4 个 PNG 注册到 resources/resources.qrc;aboutpage.cpp 在其构造函数中加载 QPixmap,并将其作为第 4 个参数传给 makeLinkRow。

完整英文(en_US)本地化

源码包含 548 个 UI 字符串,但 translations/hello_ksp_launcher_en_US.ts 只有 506 个。使用 lupdate 重新提取(build/en_fresh.ts)并比较,以补全近期版本新增的 43 个缺失英文翻译(崩溃日志分析、整合包导入/导出、调试模式、推荐/建议对话框、批量与卸载进度、注册表锁提示、自更新 SHA256 等)。现在全部 548 个字符串都有翻译(lrelease 报告 0 个未完成);现有 506 个未改动。.qm 已重建并同步到 dist/translations。由于英文是默认语言,首次启动现在会显示完整的英文 UI。

技术栈

  • 框架:Qt 6(Widgets、Svg、Network、Concurrent)
  • 语言:C++17
  • 构建:CMake ≥ 3.16;Windows 使用 Qt 自带的 mingw 工具链
  • 测试:test_libckan + test_launcher(全部通过)

完整变更日志:https://github.com/Zhuwenqian/Hello-KSP-Launcher/compare/v1.2.3...v1.3.0

0 条评论

请 登录 后发表评论

还没有评论,快来抢沙发吧