☰
Lumafly 源码级解析:跨平台《空洞骑士》Mod 管理器的功能特性、工作原理与使用指南
2026/10/16 6:46:33 网站建设 项目流程
  • 桌面应用
  • 游戏开发

【免费下载链接】Lumafly

A cross platform mod manager for Hollow Knight written in Avalonia.

项目地址:https://gitcode.com/gh_mirrors/lu/Lumafly
点击查看免费下载

Lumafly 是一款基于 Avalonia 开发的跨平台《空洞骑士》(Hollow Knight) 模组管理器,支持 Windows、macOS 与 Linux,并内置了英、西、葡、法、中、日、俄、波等语言界面。本文以仓库根目录的 README.md 为主线,结合 Lumafly 主工程源码与 Lumafly.Tests 测试用例,系统讲解它的安装使用、六大核心能力,以及"下载校验—安装切换—状态持久化—Modpack 分享"背后的完整实现链路。读完本文,你将既能独立完成从安装到管理 Mod 的全流程操作,也能理解其 modlinks 数据源、API 切换、URL Scheme 命令等底层机制,为二次开发或定制部署打下基础。

Lumafly 是什么:从 Scarab+ 到跨平台 Mod 管理器

按 README 的定位,Lumafly 是一个跨平台的《空洞骑士》Mod 管理器,前身是Scarab+(继承自早期 Scarab 项目),目前界面已完全本地化。README 明确列出的本地化语言为英语、西班牙语、葡萄牙语、法语、中文、日语、俄语与波兰语;而在源码层面,SupportedLanguages.cs 中的枚举还额外包含荷兰语(nl)与意大利语(it),即共支持 10 种语言,对应的本地化资源文件位于 Localizations 目录(含Resources.zh.resx等)。

从工程结构看(Lumafly.csproj),它基于:

  • Avalonia 11.0.4+ Skia + Fluent 主题,实现跨平台 UI;
  • .NET 7(TargetFramework为net7.0,OutputType为WinExe);
  • ReactiveUI / PropertyChanged.SourceGenerator驱动 MVVM 视图模型;
  • Mono.Cecil读取程序集元数据、HPackage.Net处理 Modpack 分享格式、NetSparkleUpdater负责 Windows 端自更新。

Program.cs 是启动入口:先完成日志初始化与语言探测,随后注册scarab://URL Scheme 处理器、注册 SIGTERM/SIGINT 信号处理,最后以经典桌面生命周期启动 Avalonia 应用。日志文件ModInstaller.log会写入配置目录,超过 5 MB 时自动归档,崩溃信息另存为ModInstaller_Error_*.log。

快速上手:从下载到进入游戏

README 的 Usage 一节给出了完整的用户操作路径,这也是每个玩家的标准使用流程:

  1. 下载安装:从官方下载页获取最新版本(或从 Releases 页面手动下载)。
  2. 搜索并安装:在 Mod 列表中搜索并下载你喜欢的 Mod。
  3. 进入游戏:安装完成后,Mod 会出现在游戏标题界面的左上角。
  4. 开关与更新:通过开关按钮启用/禁用某个 Mod 对游戏的影响;过期的 Mod 会显示橙色更新按钮,点击即可更新。
  5. 离线使用:无法联网时,可以以离线模式启动 Lumafly,此时仍可开关已安装的 Mod 与 Modding API。

需要补充的是,"Mod 出现在标题界面左上角"这一行为源自《空洞骑士》Modding API 的加载机制——Lumafly 只是负责把 Mod 文件放置到游戏目录并维护启用状态,真正让 Mod 生效的是游戏进程内加载的 API。

核心功能总览:README Features 完整解读

README 的 Features 一节定义了 Lumafly 的六大核心能力,下面逐条展开,并结合源码说明其实现方式。

1. 自动安装 Modding API,随时切换原版/Mod 版

Lumafly 会自动下载并安装 Mod 加载所必需的Modding API,并提供Toggle API按钮在"Mod 版游戏"与"原版游戏"之间切换。

实现上,ModDatabase.cs 会从官方 modlinks 拉取ApiLinks.xml,得到 API 的下载地址、版本号与 SHA256 哈希;Installer.cs 中的InstallApi/ToggleApi则负责实际安装与切换。切换的关键是游戏目录下三个文件名的"轮换":

  • Assembly-CSharp.dll—— 当前生效的程序集;
  • Assembly-CSharp.dll.v—— 备份的原版程序集(vanilla);
  • Assembly-CSharp.dll.m—— 备份的 Mod 版程序集(modded)。

ToggleApi的底层逻辑(Installer.cs)就是在这三个文件之间做文件移动:启用 API 时把原版Current移到.v、再从.m恢复 Mod 版;关闭 API 时反向操作。首次安装 API 时还会用FetchVanillaAssemblyLink按操作系统(Windows/macOS/Linux)下载对应的原版程序集备份,确保之后可以无损切回原版。

2. 搜索官方 modlinks 中的 300+ Mod

README 声称官方 modlinks 中收录了300 多个 Mod,Lumafly 提供统一的搜索、浏览入口。数据侧,ModDatabase每次启动都会抓取ModLinks.xml与ApiLinks.xml两个清单文件(请求超时 30 秒,失败自动回退到 jsdelivr CDN 镜像)。ModLinks.xml中每个<Manifest>条目被反序列化为 ModLinks.cs 中的Manifest记录,包含名称、版本、三个平台的下载链接与 SHA256、依赖、描述、标签、集成、作者等字段。

测试用例 DatabaseTest.cs 直接用一段内嵌的ModLinks.xml/ApiLinks.xml验证了这套反序列化逻辑:它断言QoL这个 Mod 的版本、依赖(Vasi)、下载链接等字段均被正确解析,且 API 版本号被正确读取为 63。这也是理解 modlinks 数据格式最直接的示例。

3. Modpack 分组与分享命令

Lumafly 允许把一组 Mod 打包成Modpack(配置文件/合集)并分享。本地实现位于 PackManager.cs:每个 Modpack 对应游戏目录下的一个文件夹,内含packMods.json清单(packInfoFileName常量)。支持叠加加载(additive,把包内 Mod 合并进当前列表)与独占加载(exclusive,清空现有 Mods 目录后整体替换),加载前会先把旧 Mod 目录缓存到Temp_Mods_Storage,失败时自动回滚。

分享则通过 URL Scheme 命令(README 指向的 Commands 文档)完成:把包转换为HPackageJSON 格式后上传到在线文本存储(实现为 PastebinTextStorage.cs),得到一个分享码,其他人用scarab://modpack/<code>即可导入。此外还支持把包导出为.zip文件。

4. 展示最近更新/新发布的 Mod

README 提到 Lumafly 能"Display mods that were recently updated or released"。这由 ModLinksChanges.cs 实现:它从静态资源仓库的ModlinksChanges.json获取"本周/本月新增与更新"的 Mod 名单,再结合上次使用的ModLinks.xml与当前清单做差量对比,得出"今天的改动",最终在界面上标记ModChangeState.New / Updated(枚举见 ModChangeState.cs)并按其排序权重展示。

5. 一站式管理:下载、更新、设置、Readme、报 Bug

单个 Mod 的详情操作非常完整,全部集中在 ModItem.cs 的ModItem模型上:

  • OnInstall/OnUpdate/Uninstall:安装、更新、卸载;
  • OpenSettingsFile:直接打开该 Mod 的*.GlobalSettings.json配置文件(由 GlobalSettingsFinder.cs 在存档目录中定位,必要时会用 Mono.Cecil 反查 Mod 程序集中的类名,以匹配Modding.Mod、SFCore、Satchel等基类);
  • OpenReadme/OpenReleaseNotes:弹出窗口查看 Readme 与更新日志;
  • ReportBug:跳转到该 Mod 的 Issues 页面。

6. 手动安装非 modlinks 的 Mod

modlinks 之外的第三方 Mod 通过"手动安装"入口支持。这类 Mod 在源码中以NotInModLinksState(见 ModState.cs)标识,ModlinksMod字段区分"官方清单里有同名项但本地装的是自定义版本"与"完全自定义的 Mod"两种情况;列表中对它们会显示"not from official modlinks"的说明。

配置系统:HKInstallerSettings.json 全参数说明

Lumafly 的配置持久化在 Settings.cs 中定义,配置文件位于系统应用数据目录下的HKModInstaller文件夹(Windows 为%APPDATA%,Linux 为~/.config,macOS 为~/Library/Application Support),文件名是HKInstallerSettings.json,采用缩进 JSON 序列化。常用配置项如下表:

配置项类型 / 默认值说明
ManagedFolder字符串《空洞骑士》游戏安装目录(即Managed目录所在位置)
AutoRemoveUnusedDepsNever(默认)/Ask/Always是否自动移除卸载后不再被依赖的 Mod(AutoRemoveUnusedDepsOptions.cs)
WarnBeforeRemovingDependents布尔,默认true移除某 Mod 前是否警告其依赖方
UseCustomModlinks布尔,默认false是否使用自定义 modlinks 数据源
CustomModlinksUri字符串,默认空自定义 modlinks 的地址
UseGithubMirror布尔,默认false是否通过 GitHub 镜像下载
GithubMirrorFormat字符串,默认空镜像 URL 模板
PreferredLanguage可空枚举,默认自动探测首选语言(取值为 SupportedLanguages.cs 的 10 种语言之一)
LowStorageMode布尔,默认false低存储模式:不缓存下载的 Mod 压缩包
RequiresWorkaroundClient布尔是否强制使用 IPv4 专用 HTTP 客户端(网络兼容性开关)

Settings.Load()在 JSON 损坏时会静默回退为空配置而不是崩溃。此外,Program.cs 的SetPreferredLanguage会优先读取该配置,否则跟随系统区域语言,再次兜底为英语。

游戏目录的自动定位同样在Settings中完成:先遍历内置的静态路径列表(Steam / Xbox / GOG 的常见安装路径),再检查用户主目录下的 Linux(含 Flatpak)与 macOS 路径,最后在 Windows 上读取注册表(Valve Steam 的libraryfolders.vdf与 GOG 注册表键)来定位游戏库。也就是说,即使玩家把游戏装到了非默认位置,Lumafly 也能大概率自动找到。

安装、更新与卸载的实现原理

Installer是操作游戏目录的核心服务(Installer.cs),安装流程可以概括为:

  1. 确保 Modding API 已安装(递归调用InstallApi);
  2. 通过信号量(SemaphoreSlim)串行化安装操作;
  3. 递归处理依赖:_Install会遍历mod.Dependencies,先装好每个依赖及其传递依赖;
  4. 下载 Mod 文件(支持进度回调),下载前优先命中本地缓存(CacheFolder下的HKInstallerCache);
  5. 用 manifest 中声明的SHA256 哈希做完整性校验,不匹配则抛HashMismatchException并中止;
  6. 按文件类型落盘:.zip解压(解压过程会做路径穿越防护,file_dest.StartsWith(dest_dir_path)检查防止恶意压缩包逃逸出目录),.dll直接写入Mods/<ModName>/;
  7. 更新内存状态并写入持久化文件。

更新(OnUpdate)本质是带clearDlls标志的重装:先清空 Mod 文件夹中的旧 DLL 再放置新文件,避免残留旧程序集;卸载(_Uninstall)则直接删除对应目录,并把NotInModLinksState的 Mod 从列表移除。

状态模型是理解 UI 的关键。ModState.cs 定义了三种状态:

  • NotInstalledState:未安装;
  • InstalledState:已安装(含Enabled启用、Version本地版本、Updated是否最新、Pinned置顶);
  • NotInModLinksState:已安装但不在官方清单中(区分ModlinksMod)。

当清单版本与本地版本一致时Updated=true,否则UpdateAvailable为真,界面上就会显示橙色更新按钮。

开关 Mod 与 API:目录搬运与文件轮换

启用/禁用 Mod 的实现非常朴素且可靠:整体移动文件夹。_Toggle(Installer.cs)把 Mod 目录在Mods(启用)与Disabled(禁用)两个目录之间移动——游戏只加载Mods目录下的内容,因此禁用不会丢失任何文件,可以随时切回。

值得注意的两个细节:

  • 启用时自动带起依赖:Toggle在启用某 Mod 前,会先递归启用它的所有依赖(源码注释明确说明这是为了避免"启用后因缺少依赖而失效");
  • 目标目录冲突保护:如果目标目录已存在同名文件夹,会弹窗询问用户是否删除冲突项。

API 的开关则使用前面提到的.v/.m/Current三文件轮换,且由独立的_modToggleSemaphore保护,避免与 Mod 切换并发冲突。

已安装状态持久化与自恢复

InstalledMods.cs 负责把"已安装哪些 Mod、启用状态如何、API 状态如何"持久化为配置文件目录下的InstalledMods.json。它有两个值得称道的健壮性设计:

  1. 损坏自恢复:JSON 损坏或首次安装时,会扫描Mods/Disabled目录重建状态,版本未知的 Mod 标记为"过期"(Updated=false)并提示更新;
  2. 目录状态对账:每次加载都会把磁盘目录与记录状态做对比——玩家手动移动、删除文件夹后,状态记录会被自动修正(源码中enabled state mismatch, fixing!与Removing missing mod的 Trace 日志即出自此处)。

ModSourceTest.cs(ModSourceTest.cs)用内存文件系统验证了"记录安装状态 → 从 manifest 判断是否过期 → 记录卸载"的完整闭环,是对这套持久化逻辑的直接测试佐证。

Modpack 机制:分组、导入导出与分享

PackManager 是 Modpack 功能的核心(PackManager.cs),核心机制包括:

  • 保存:SavePack把当前Mods目录(排除Disabled)复制到ManagedFolder/<包名>/,并写入packMods.json(含名称、描述、作者与启用状态的 Mod 清单);
  • 加载:LoadPack区分叠加与独占两种模式,加载前用CacheOldModsFolder备份当前 Mods 目录,任何一步失败都会RevertToPreviousModsFolder完整还原;
  • 导出:SavePackToZip借助系统保存对话框把包目录压缩为.zip;
  • 导入/分享:ConvertToHPackage用 HPackage.Net 把包序列化为 Hollow Knight 标准包格式 JSON,上传在线文本存储后得到SharingCode;ImportPack则反向解析分享码导入,重名包会被拒绝。

Pack模型定义在 Pack.cs,IsSame/DeepCopy用于编辑后判断是否发生变化。加载包前还会检测游戏进程(hollow_knight)是否在运行,必要时提醒用户关闭游戏。

URL Scheme 命令:远程控制与分享的通道

README 中提到的 "commands" 即scarab://自定义协议。注册与解析在 UrlSchemeHandler.cs:Windows 上写注册表HKEY_CURRENT_USER\SOFTWARE\Classes\scarab,Linux 上生成scarab.desktop桌面条目(x-scheme-handler/scarab),macOS 则在编译期写入Info.plist(见 Scripts/Lumafly.app/Contents/Info.plist)。

支持的命令(枚举定义见 UrlSchemeCommands.cs)如下:

命令用途
download下载一个或多个 Mod,格式为scarab://download/名称:'链接'/名称2:'链接2'
reset重置已安装状态
forceUpdateAll强制更新全部 Mod
customModLinks切换并使用自定义 modlinks
useOfficialModLinks切回官方 modlinks
removeAllModsGlobalSettings清空所有 Mod 的全局设置文件
removeGlobalSettings移除指定 Mod 的全局设置文件
launch启动游戏
modpack导入某个分享码对应的 Modpack
location定位/指定游戏目录

download命令的解析器ParseDownloadCommand会对名称做非法字符校验、对链接做 URI 合法性校验,非法输入直接拒绝解析;非scarab://前缀或未知命令会弹出警告框。ModItem.Share()方法会把单个 Mod 编码进分享链接,与 modpack 分享形成闭环。

“最近更新”与反向依赖搜索

  • 最近更新:由ModLinksChanges服务完成(详见上文功能 4),其IsLoaded三态布尔(null未加载 /true成功 /false失败)确保数据异常时界面不做无意义的展示;离线模式或使用自定义 modlinks 时该功能自动关闭。
  • 反向依赖搜索:ReverseDependencySearch.cs 提供三类查询:GetAllDependentAndIntegratedMods(依赖方 + 集成方)、GetAllIntegratedMods(仅集成方)、GetAllEnabledDependents(仅已启用的依赖方),且依赖关系支持传递(递归判断)。这与 UI 中的SearchType(Normal / DependencyAndIntegration / Integration,见 SearchType.cs)以及ModFilterState(All / Installed / Enabled / OutOfDate / WhatsNew,见 ModFilerState.cs)筛选器配合,能快速回答"卸载这个 Mod 会影响谁"、"哪些 Mod 集成了这个 Mod"等实际问题。

本地化与字体

本地化采用 Avalonia 标准的.resx资源机制(Lumafly.csproj 中把所有Localizations\*.resx设为嵌入资源),翻译工作通过 Crowdin 平台协作完成(README Contributions 一节有说明)。Program.cs 还针对不同语言做了字体覆盖:中文使用内嵌的 Noto Sans SC、其余语言使用 Noto Sans(字体文件位于 Assets/Fonts),确保 CJK 字符渲染正常。

网络容错与离线模式

  • 离线模式:LumaflyMode枚举(LumaflyMode.cs)区分Online/Offline。离线启动时不拉取任何在线数据,仅基于本地InstalledMods.json与已下载缓存工作,仍可开关 Mod 与 API——这正是 README 描述的离线能力。
  • IPv4 回退客户端:WorkaroundHttpClient.cs 针对 .NET 默认双栈 socket 在某些网络/驱动下走 IPv6 失败的问题,提供了强制 IPv4 连接的替代客户端;RequiresWorkaroundClient为 true 时全程使用,否则先试常规客户端、超时再回退(HttpSetting.OnlyWorkaround / TryBoth)。

自更新机制

AppUpdater.cs 负责应用自更新:Windows 端基于 NetSparkleUpdater 读取 appcast.xml(仓库根目录,当前最新条目为 v3.3.0.0),支持自动下载安装、重启后替换;非 Windows 平台改为手动检查 GitHub Releases 的tag_name版本号,高于本地版本时提示用户跳转下载。更新信息(发布说明、下载链接、变更日志)通过静态资源仓库的UpdateLinks.json动态下发,无需发版即可调整。

测试保障

仓库自带的 Lumafly.Tests 覆盖了最关键的两条链路:

  • DatabaseTest.cs:验证ModLinks.xml/ApiLinks.xml的 XML 反序列化、ModDatabase的 Item 构建以及三种状态(未安装 / 已安装 / 过期)的判定;
  • ModSourceTest.cs:验证InstalledMods的持久化读写与"版本一致即最新"逻辑。

它们使用System.IO.Abstractions.TestingHelpers的内存文件系统,可在无真实游戏目录的情况下运行,也间接证明了核心逻辑与具体文件系统解耦。

参与贡献与社区生态

按 README 的 Contributions 说明:功能建议与 Bug 请走 Issues 页面;想参与开发可关注 enhancement 标签下的待办功能;本地化翻译请通过 Crowdin 平台提交。README 的 Credits 部分同时列出了项目渊源——基于 fifty-six 的 Scarab 开发,以及来自社区的多语言译者与美术作者。

结语

从 README 的六项核心特性出发,本文结合仓库源码把 Lumafly 拆解为一条清晰的实现主线:modlinks 数据源驱动内容、Installer 负责文件级安装与切换、InstalledMods 持久化状态、PackManager 支持批量管理、URL Scheme 打通远程分享、离线模式兜底断网场景。无论你是普通玩家想正确安装和使用它,还是开发者想为《空洞骑士》生态贡献一个 Mod 管理器插件或定制版本,都可以从 README.md 起步,再按本文给出的源码路径逐层深入。

  • 桌面应用
  • 游戏开发

【免费下载链接】Lumafly

A cross platform mod manager for Hollow Knight written in Avalonia.

项目地址:https://gitcode.com/gh_mirrors/lu/Lumafly
点击查看免费下载

相关推荐

上一篇:SPT-AKI存档编辑器终极指南:如何快速掌握你的塔科夫单机版游戏进度
下一篇:LX Music 桌面版:聚合五平台音乐搜索与批量下载的上手指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询