gen_1_21 实测启动成功 + provision 工具
决定性验证:gen_1_21 后端在 1.21.1 上收到 {"event":"ready"}
⇒ 世代分派架构成立:同一套 Python 层,两个独立编译的 Java 后端
运行时发现第 12 处世代差异(编译期看不出):
1.20.x registryAccess 是可变 LayeredRegistryAccess → 事后反射替换
1.21.x registryAccess 是 final RegistryAccess$Frozen → 反射抛
"Can not set final field"
处理:gen_1_21 改为先载注册表 → 经 CommonListenerCookie.receivedRegistries
传入 → 再构造 listener。比 1.20 的反射做法更干净。
新增 mcfold/provision.py(从官方 manifest 装任意版本,版本无关):
- 跳过音频资源:1.21.1 实测 3911 条里跳过 3744 条
- natives 两种形态都认(1.21 起是独立库条目,非 classifiers)
- 实测 1.21.1:274 文件 / 200MB / 32s / 0 失败
This commit is contained in:
@ -54,3 +54,28 @@ Java 编译期绑定签名。实测:
|
||||
⚠️ 教训(本轮踩过):`Reason.LEVEL_LOAD`、`DirectoryValidator.NONE`
|
||||
都是凭印象写出来的、实际不存在的 API;`loadEffect` 的可见性也没验证。
|
||||
**改之前先 `javap`。**
|
||||
|
||||
## 补充:1.21.1 实际运行验证(比编译更强的证据)
|
||||
|
||||
`gen_1_21` 已实测启动成功(stdout 收到 `{"event":"ready"}`)。
|
||||
|
||||
运行期又暴露 1 处「编译期看不出」的差异:
|
||||
|
||||
| # | API | 1.20.x | 1.21+ | 处理 |
|
||||
|---|---|---|---|---|
|
||||
| 12 | `ClientPacketListener.registryAccess` | 可变 `LayeredRegistryAccess`,可事后反射替换 | **`final RegistryAccess$Frozen`**,反射抛 `Can not set final field` | gen_1_21 改为**先载注册表 → 经 `CommonListenerCookie.receivedRegistries` 传入 → 再构造 listener** |
|
||||
|
||||
★ 这条是本轮最有价值的发现:1.21 的 cookie 机制让注册表注入**比 1.20 的反射更干净**。
|
||||
两代的启动顺序因此不同:
|
||||
|
||||
```
|
||||
1.20.x: 构造 listener → 反射替换 registryAccess 字段
|
||||
1.21.x: 先加载注册表 → 构造 cookie(含注册表) → 构造 listener(final 字段一次到位)
|
||||
```
|
||||
|
||||
## provision 的实测发现
|
||||
|
||||
- natives 在 1.21.1 是**独立库条目**(`name` 含 `:natives-linux`),
|
||||
不走老版 `downloads.classifiers` 结构 ⇒ 两种形态都要认。
|
||||
- 跳过音频资源可省 **3744/3911 条**(仅 167 条实际下载),
|
||||
实测 1.21.1 全量 274 文件 / 200MB / 32s,0 失败。
|
||||
|
||||
Reference in New Issue
Block a user