【免费下载链接】Launcher
This fork of Prism Launcher adds integrated support for Ely.by accounts.
Ely Prism Launcher 是一个基于 Prism Launcher 分支的 Minecraft 启动器,内置 Ely.by 账号支持。它的HttpMetaCache模块是一个本地HTTP 元数据缓存:通过记录 ETag、MD5、文件时间戳等信息,让启动器在下载游戏库文件、材质索引、Mod 整合包清单等资源时自动判断"本地是否已有且仍是最新",从而避免重复下载,省流量、加速启动。
本文将用通俗的方式拆解这套缓存机制的工作原理、目录结构和实际效果。
一、为什么需要元数据缓存?🎮
使用 Minecraft 启动器时,经常需要联网下载的内容包括:
| 内容 | 说明 |
|---|---|
| 游戏版本清单 / libraries | 每次创建或启动实例都可能校验 |
| 资产索引(Asset Indexes) | 材质、模型文件的清单 |
| Forge 旧版依赖库(fmllibs) | 老版本 Forge 实例的公共依赖 |
| Mod 整合包清单 | FTB、Modrinth、Flame、Technic、ATLauncher 等平台的 pack 元数据 |
| 翻译文件、Java 运行环境、新闻源 | 各类辅助资源 |
这些文件大多是低频更新的。如果没有缓存,每次校验都要完整重新下载,网络流量大、速度慢,还可能触发服务端限流(HTTP 429)。HttpMetaCache的作用就是:用极小的元数据记录,换掉整文件的重复传输。
二、HttpMetaCache 是什么?一个"文件护照"系统 🪪
核心实现位于 launcher/net/HttpMetaCache.h 与 launcher/net/HttpMetaCache.cpp。它不缓存文件本身,而是为每个已下载文件颁发一张"护照"——MetaEntry(见 HttpMetaCache.h),记录如下字段:
| 字段 | 含义 |
|---|---|
m_etag | 服务器返回的 ETag,文件内容的"指纹" |
m_md5sum | 本地文件的 MD5 校验值,防止本地被改动 |
m_local_changed_timestamp | 本地文件最后修改时间 |
m_remote_changed_timestamp | 服务器Last-Modified时间 |
m_current_age/m_max_age | 缓存当前年龄 / 允许的最大存活时间 |
m_is_eternal | 是否为"永久有效"条目(如静态索引) |
m_stale | 是否为失效条目(stale),失效则触发重新下载 |
所有护照统一存放在一个名为metacache的 JSON 索引文件中,随启动加载(Load())、随退出保存(SaveNow())。
三、核心流程:三步判断"要不要重新下载" ✅
每次需要某个资源时,启动器会调用resolveEntry做一次"验票"(HttpMetaCache.cpp):
- 查表:索引里有这张护照吗?没有 → 生成一条 stale 条目,走全新下载;
- 验本地:本地文件还在吗?还在就比对修改时间,时间变了就重算 MD5,MD5 不一致(说明文件被动过)→ 作废护照,重新下载;
- 验时效:护照"年龄"超过
max_age吗?超期 → 作废,重新下载。
三步全部通过,这条护照才算"有效",本地文件直接复用,一次网络传输都不用发。
四、条件请求:把"要不要重新下"的问题交给服务器 📡
当条目是 stale(需要校验或刷新)时,下载组件 MetaCacheSink 会在 HTTP 请求里自动带上两个条件请求头:
If-Modified-Since:附带本地记录的远程修改时间;If-None-Match:附带本地记录的 ETag。
如果服务器确认文件没变,会返回HTTP 304 Not Modified——没有正文,只有几十字节的响应头。对启动器来说,这就等于"免费刷新"了一张新护照。
下载真正完成后,finalizeCache(MetaCacheSink.cpp)会从响应头中提取并记录:
ETag与Last-Modified:下次条件请求的凭据;Cache-Control: max-age/Expires:服务器声明的缓存有效期;Age:文件在缓存层已"存活"的时间;- 都没有时,默认有效期为1 周(源码中
MAX_TIME_TO_EXPIRE = 1 * 7 * 24 * 60 * 60,见 MetaCacheSink.cpp)。
新信息写回条目后,调用updateEntry把护照存入索引(HttpMetaCache.cpp)。
五、缓存索引文件长什么样?📄
索引是启动器数据目录下的metacache.json,结构非常直观(由 SaveNow() 生成):
{ "version": "1", "entries": [ { "base": "libraries", "path": "org/lwjgl/lwjgl/3.3.1/lwjgl-3.3.1.jar", "md5sum": "9a8c3f2e...(MD5 摘要)", "etag": "\"abc123\"", "last_changed_timestamp": 1728920000000, "remote_changed_timestamp": "Wed, 11 Oct 2023 09:00:00 GMT", "current_age": 0, "max_age": 604800 } ] }两个值得注意的设计:
- 批量化写入:每次条目变化只调用
SaveEventually()(HttpMetaCache.cpp),启动一个 30 秒的防抖定时器,把密集变更合并成一次落盘,避免频繁写文件; - 失效条目不落盘:stale 条目只存在于内存中,
SaveNow()会直接跳过它们,索引文件始终只保留"活的"护照。
六、哪些资源被纳入了缓存?🗂️
启动器初始化时,Application会通过addBase注册一系列"缓存基地"(Application.cpp):
| base 名称 | 对应目录 | 典型内容 |
|---|---|---|
asset_indexes | assets/indexes | 资产索引文件 |
libraries | libraries | 游戏公共库 jar |
fmllibs | mods/minecraftforge/libs | Forge 旧版依赖 |
general | cache | 通用缓存 |
ATLauncherPacks/FTBPacks/TechnicPacks | cache/... | 各平台整合包清单 |
FlamePacks/FlameMods/ModrinthPacks/ModrinthModpacks | cache/... | Flame、Modrinth 生态资源 |
translations | translations | 多语言翻译包 |
meta | meta | 版本清单等元数据(如 BaseEntity 的版本文件) |
java | cache/java | 自动安装的 Java 运行环境 |
feed | cache/feed | 新闻源 |
也就是说,从创建新实例到更新整合包,几乎每一次网络下载都自动走缓存通道。
七、缓存何时会被清空?🧹
缓存不是"一存永存",有两种清理方式(HttpMetaCache.cpp):
evictAll():清空全部条目并删除对应目录内容,属于彻底重置;softEvict():只清空meta基地的条目(元数据清单),保留本地游戏文件。
一个实际例子:启动器的Pinecone 网络检查在自动切换元数据源(meta 源)时,会调用softEvict再立即保存(PineconeNetworkCheck.cpp)——切换源之后旧清单的 ETag 已不可信,必须重新拉取元数据,但库文件和资源不动,依然免下载。
八、写给普通用户的实用建议 💡
- 首次安装最费流量,之后越来越快:libraries、资产索引、整合包清单首次全量下载后,后续启动、创建同类实例基本零重复传输;
- 想强制刷新元数据:删除启动器数据目录中的
metacache.json(或清空meta目录)即可,下次启动会重建;本地游戏文件本身不受影响; - 网络不稳定时的容错:即使下载中途失败,只要本地已有可用文件,部分任务仍可降级使用本地数据继续(
NetRequest中的AcceptLocalFiles机制,见 NetRequest.cpp); - 多实例共享受益:所有实例共用同一份缓存基地,装的整合包越多,这套元数据缓存省下的流量越可观。
总结
HttpMetaCache用"本地 MD5 + 远程 ETag + 过期时间"三重重校验,把重复下载问题变成了一次几乎零成本的 304 条件请求。它藏在 launcher/net/ 目录背后,却默默影响着每次启动、每次整合包更新的体验——这正是 Ely Prism Launcher 在原版基础上把资源管理做得更细的一环。
【免费下载链接】Launcher
This fork of Prism Launcher adds integrated support for Ely.by accounts.
相关推荐
Terraform AWS Provider 数据源指南:aws_odb_db_servers 查询 Oracle Database@AWS 数据库服务器列表
Terraform AWS Provider 数据源指南:aws_odb_db_servers 查询 Oracle Database@AWS 数据库服务器列表
OneUptime Syslog 摄取指南:通过 HTTPS 将 RFC3164/RFC5424 日志统一接入可观测平台
OneUptime Syslog 摄取指南:通过 HTTPS 将 RFC3164/RFC5424 日志统一接入可观测平台 导读 OneUptime 的 Open
Ely Prism Launcher如何读取存档NBT数据?libnbtplusplus的World管理完全指南
Ely Prism Launcher如何读取存档NBT数据?libnbtplusplus的World管理完全指南 Ely Prism Launcher 是基于
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考