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

Hello KSP Launcher v1.4.0

发布说明

v1.4.0 — 飞船管理、渐进式模组选择与 UI 性能(2026-09-18)

本版本为实例和存档新增了完整的飞船(.craft)管理器,支持拖放导入;使推荐/建议对话框变为渐进式且按模块处理;通过懒加载加速实例详情页;并让模组列表按实例持久化其视图状态。

飞船管理(实例与存档)

新的飞船管理器可为任意实例和任意存档列出、查看并导入 .craft 文件,布局仿照存档管理器的标签页放置方式。

  • 实例飞船管理器(shiptabpage.{h,cpp},新增)—— 一个 QTabWidget,含 VAB / SPH 标签页,列出 .craft 文件(自动排除 .loadmeta、.craft.original 等);每行显示飞船名称(去掉 .craft)和游戏版本(从 version = X.Y.Z 解析,缺失时显示“未知”)。
  • 飞船详情(列表内第二页)—— 点击一行会打开名称(ship = XXX)、游戏版本和只读描述(description = XXX),右侧显示来自 Ships/@thumbs/VAB|SPH 的匹配缩略图(缺失时使用火箭 SVG 回退图)。
  • 解析(instancemanager_ships.cpp)—— listCraftFiles(按文件名排序,仅 .craft)、loadCraftInfo(只读 ship/version/description,名称回退到文件名)、getShipThumbPath(png/jpg)、moveCraftToTrash。
  • 入口点—— 实例详情侧边栏新增“飞船管理”第 5 个标签页(showSection(5),rocket.svg);存档详情页新增“飞船管理”第 3 个标签页,通过可设置的基路径(setShipsBase)复用同一个 ShipTabPage,该路径会自动定位到 instanceRoot/saves/saveName/Ships/VAB|SPH。
  • 导入飞船—— 列表工具栏新增“导入飞船”按钮(download.svg);可通过 QFileDialog(多选)导入,或直接将 .craft 拖放到 VAB/SPH 标签页;导入到当前标签页的文件夹;名称冲突不区分大小写,会弹出“覆盖飞船”确认(是 = 覆盖 / 否 = 跳过 / 取消 = 中止剩余操作),并保留目标原有大小写。
  • 删除到回收站—— 每行现在都有垃圾桶按钮(存档列表中旧的装饰性箭头也一并替换);删除操作在 Windows 上将 .craft / 存档文件夹移至系统回收站(SHFileOperation(FO_DELETE + FOF_ALLOWUNDO)),其他平台则永久删除。
  • 翻译/测试—— 新的 ShipTabPage 字符串已全部翻译为 en_US(0 个未完成);test_launcher 新增 TestShips(顶层键解析、嵌套键不会覆盖、名称回退、列表过滤、缩略图定位)。导入/回收站流程没有自动化测试(它们依赖模态对话框和实例路径,符合项目惯例)。

渐进式、按模块的推荐/建议对话框

现在安装模块时,会逐个模块解析并询问其推荐/建议,而不是将所有内容聚合成一个巨大列表。

  • 收集(relationshipresolver.{h,cpp}、ckan.{h,cpp})—— 新增 collectOptionalFor(parent, curInstallSet, wantRecommends),仅收集单个父模块自身的 Recommends/Suggests 候选项,跳过已安装/已选择/冲突项,且不自动级联。旧的全量聚合不再用于弹窗。
  • 安装流程(installservice.cpp resolveInstallSet)—— 两阶段渐进式解析:
    • 阶段 1(推荐)—— 对每个显式安装的模块,一次显示一个推荐对话框;将选择合并到安装集,并将新添加的模块加入队列(FIFO),直到没有新模块出现。
    • 阶段 2(建议)—— 对每个显式模块显示一个建议对话框;如果新选择的模块的推荐未在阶段 1 显示,则先询问这些推荐,再询问其建议。
    • 每个模块只安装一次(按标识符去重);没有候选项的模块静默跳过;每个对话框标题标明其来源父模块。
  • 选择对话框(moddecision.{h,cpp})—— askOptionalModules 新增了一个 Trak-a-dock 风格的“全选 / 全不选”切换按钮,会根据当前状态翻转,并新增 parentName 上下文标题。取消按钮已移除——唯一退出方式是“安装所选”;放弃安装会返回模组管理。
  • 测试—— test_libckan 新增 collectOptionalNoCascade(按模块、不级联、无交叉污染)和 collectOptionalSkipsInstalledAndSelected。全部通过。

模组管理 UI(分隔条与按实例状态)

  • 可拖动的列表/详情分隔条(modstabpage.cpp、configmanager.{h,cpp})—— 一个垂直 QSplitter(modSplitter)位于模组表格和 4 个详情标签页(元数据/文件/关系/版本)之间;拖动可调整列表高度(列表保持在上方,详情标签页下移)。初始为 3:2 分割,两个窗格均不可折叠;底部操作栏保持原位。顶部窗格高度持久化到 HKSPL.json(modSplitterTopHeight,全局),以 250ms 防抖保存;在首次 showEvent 中按分隔条的实际高度精确应用。
  • 按实例列表状态(configmanager.{h,cpp}、modstabpage.cpp)—— 每个实例的模组列表在实例切换/重启后恢复精确视图:搜索文本、状态过滤(全部/已安装/可升级/未安装)、标签过滤、详情标签页索引、排序列+顺序、垂直滚动位置和所选模块。变更时保存(300ms 防抖;切换实例前刷新)到专用 modListViewState 区段,以实例 id 为键。在异步列表加载后恢复(restoreListStateAfterLoad),并用 m_restorePending 标志区分首次进入加载与同实例刷新。

实例详情页——懒加载

进入实例管理不再预先加载所有内容;每个次级标签页仅在进入时获取其数据。

  • instancedetailpage.cpp 的 showSection——模组管理标签页触发 prepareMods()(异步索引 + DLL 扫描),存档标签页触发 loadSaves(),飞船标签页触发 loadShips()。页面打开在“游戏设置”上,前期不执行繁重工作。
  • 模组标签页(modstabpage.{h,cpp})—— setInstance 仅记录实例,setTabActive(true) 在每次进入时重新准备模组。
  • 存档标签页(savestabpage.{h,cpp})—— loadSaves() 在 QtConcurrent::run 后台线程中运行,遍历目录并逐文件解析 persistent.sfs,通过 QFutureWatcher 填充列表(带有“正在加载存档...”占位符);删除后刷新复用同一异步路径。
  • 飞船标签页(shiptabpage.{h,cpp})—— loadShips() 在后台线程中解析 VAB + SPH,并通过 watcher 填充;行构建被拆分为 addShipRow。
  • 线程安全—— InstanceManager::listSaves/loadSaveInfo/listCraftFiles/loadCraftInfo 是纯文件读取,没有共享可变状态,可安全地在主线程之外调用。

崩溃日志对话框——上下文与一键日志打包

  • 上下文窗口(playerloganalyzer.{h,cpp})—— analyzePlayerLog 新增 context 字段;extractPlayerLogContext 取关键错误行(崩溃标记 Caught fatal signal / OOM),并从该处向上回溯最多 40 行(kContextLeadingLines),再取到日志末尾。
  • 对话框(mainwindow.cpp 的 maybeShowCrashAnalysis)—— 一个只读、可选择的 QPlainTextEdit(最小高度 240px)现在会在消息框中粘贴错误上下文,并新增“保存日志”按钮。
  • 一键打包(mainwindow.{h,cpp} 的 packLogToZip)—— 将整个 Player.log 流式写入 zip(使用 miniz 回调,绝不把数百 MB 的日志加载到内存),保存到启动器旁边,命名为 <cleaned-instance>-<id8>_<yyMMdd_HHmmss>.zip;非法文件名字符替换为下划线。成功时显示完整路径;失败时发出警告,且不会留下不完整的 zip。
  • 测试—— test_launcher 新增三个 extractPlayerLogContext 用例(≥40 行回溯起点、短日志头部起点、无崩溃返回空)。

UI 润色

  • 次级侧边栏对齐—— 实例详情和存档详情的次级菜单现在作为左列贯穿整个窗口高度,宽度统一为 220px,与主页侧边栏一致(返回/标题栏移入内容区域顶部)。

技术栈

  • 框架:Qt 6(Widgets、Svg、Network、Concurrent)
  • 语言:C++17
  • 构建:CMake ≥ 3.16;Qt 6.11
  • 测试:test_libckan + test_launcher(全部通过)

0 条评论

请 登录 后发表评论

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