Metin2 game client (P0–P11) + mobile asset pipeline

Networked client on the existing Godot 4.7 + libgr2 renderer:
- net: m2dev wire protocol (libsodium KX + XChaCha20), auth/select/game
  phases, EntityStore world model, ~all GC/CG headers. char create/delete,
  private shop / mall / cube, SHOP_GC_START_EX, guild, party (+ CG_PARTY_SET_STATE),
  quests, dragon soul, refine, safebox, exchange.
- UI: in-game windows migrated 1:1 from the reference uiscript/root .py —
  char status (/stat), inventory+equipment, select-item ([SELECT_ITEM] quest
  token), system-option + game-option + ESC system menu, private-shop 39-grid,
  party info board, shop tabs, atlas, minimap, quickbar, chat, …
- EterGrnLib polish: GR2 material blend/two-sided, LOD crossfade, motion-event
  dispatch, contact shadow, ray-AABB picking, weapon grip pre-transform.

Portable asset IO (A1) — all extension/libgr2/formats/mtproto reads routed
through godot::FileAccess (res:// PCK works on iOS/Android); standalone-lib
*_path() kept for the non-Godot CTests. AssetResolver + PropertyRegistry
switched to a baked index (bake_asset_index.gd) instead of std::filesystem.

Mobile builds: build-{android,ios}.sh, export-android.sh, pack-assets.sh,
gen-debug-keystore.sh. Assets ship as a zip mounted at runtime by
project/asset_pack.gd (adb push now; HTTP download is a drop-in later).

ctest 10/10, 34 GDScript suites, macOS/iOS/Android all build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013EJxkHiNKS4kybHS3XKyAJ
This commit is contained in:
shen
2026-08-31 20:02:12 +09:00
co-authored by Claude Sonnet 5
parent f4917a2b3b
commit 47baf6c0c6
414 changed files with 69568 additions and 385 deletions
+53
View File
@@ -0,0 +1,53 @@
# Granny 版本判定(oracle T1
## 已知(M0 T2
- 资产由 **Granny Standard Exporter, SDK version 2.4.0.7** 导出(从解压后的 gr2 内嵌串读到)。
- 9166 个 gr2 里 **9155 个文件格式 v6、11 个 v7**magicv6=`GRNFileMV_Old`v7=`GRNFileMV_32Bit_LittleEndian`)。
- libgr2 自研,`bind_pose_self_check` 全量 2013/2017 多骨 skeleton < 1e-3`warrior_cheongrin` 6.1e-5)。
## 候选 runtime
| DLL | 来源 | 状态 |
|---|---|---|
| `granny2_x64.dll` 2.9.12 | 泄露 SDK `lib/win64/` | **先用这个**(SDK 自带、能直接链)。容器 + 组合公式在 2.4–2.11 稳定。 |
| granny2.dll 2.4.x | 需另找(对应 2.4.0.7 exporter 的 runtime | 若 2.9.12 在曲线 / B 样条边界上和 libgr2 分歧且 Blender 仲裁站 libgr2 这边,换这个。 |
| granny2.dll 2.11.x | m2dev-client-src 头文件写的版本 | 兜底候选。 |
## 判定步骤(跑 `oracle probe`
对每个候选 DLL,跑:
```
oracle probe "assets/PC/ymir work/pc/warrior/warrior_cheongrin.gr2"
oracle probe "assets/PC/ymir work/pc/warrior/action/dance_1.gr2"
oracle probe "assets/Zone/ymir work/zone/.../<某静态件>.gr2"
```
AC(选定 DLL 下):
- `warrior_cheongrin.gr2``Skeletons=1``Meshes=5``Animations=0``Models=1`
`Materials=4``Textures=2`、skeleton 0 = 75 骨、骨骼名以 `Bip01` 开头
—— 与 libgr2`gr2dump`**逐字段一致**。
- `dance_1.gr2``Animations=1``Duration≈28.333334``TrackGroups=1`
- 静态件:`Skeletons=0` 或 1、`Meshes≥1`
- 3+ 文件全过;其余候选 DLL 的失败表现记进本表。
## 选定结果 —— ✅ 已跑(2026-08-29
- **选定:`granny2_x64.dll` 2.9.12.0**(泄露 SDK `lib/win64/`)。
- 环境:macOS 26.4 / Apple Silicon / wine-stable 11.0Rosetta/ MinGW-w64 交叉编译(`build-wine.sh`)。
- **`oracle probe` vs `gr2dump` 逐字段一致**
| 文件 | Textures | Materials | Skeletons | Meshes | Models | Animations | skel0 骨骼数 | 骨骼名/父索引 |
|---|---|---|---|---|---|---|---|---|
| `warrior_cheongrin.gr2` | 2=2 | 4=4 | 1=1 | 5=5 | 1=1 | 0=0 | 75=75 | 逐项一致(Bip01…)|
| `assassin.gr2` | 3=3 | 6=6 | 1=1 | 17=17 | 1=1 | 0=0 | 95=95 | 逐项一致(含双 root`assasin_low` + `Bip01`|
| `dance_1.gr2` | — | — | 0 | 0 | 0 | 1=1 | — | Duration 28.333334TrackGroups 1 |
- `FromFileName` 连非法编码的 Korean 路径都逐字节一致(libgr2 读原始字节 = Granny)。
**结论**2.4 导出的资产在 2.9.12 runtime 下 `GrannyGetFileInfo` 完全正常,libgr2 与之逐字段对齐。
容器 + 组合公式在 2.4–2.9 稳定这一假设成立,**不需要换 2.4.x runtime**。
`oracle.exe` + `granny2_x64.dll` 不进仓库(体积 + 版权);`build-wine.sh` 一条命令重建。