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
+43
View File
@@ -0,0 +1,43 @@
# msm / msa —— Metin2 文本包装格式(M2)。照 EterGrnLib/RaceManager 复刻。
# m2map/* —— A1 世界渲染的地图格式(SHINSOO-WORLD-RENDERING.md W0)。无 godot 依赖。
add_library(xr_formats STATIC
textscript.cpp # M2 T1: Metin2 文本脚本 token 树解析(.msa / .msm 共用)
msm.cpp # 模型:base gr2 + 发型(RaceDataScript 子集)
msa.cpp # 动作:anim gr2 + duration + accumulation + 事件
m2_tokvec.cpp # W0: LoadMultipleTextData 等价(Start/End 块 → token 向量表)
m2_coord.cpp # W0: Metin2↔Godot 坐标 / 单位 / 区块编号(BACKLOG I5
map_setting.cpp # W0: setting.txt
texture_set.cpp # W0: TextureSet .txt
area_data.cpp # W0: areadata / areaambiencedata / areaproperty
terrain_files.cpp # W0: height.raw / tile.raw / attr.atr / water.wtr
environment.cpp # W0: .msenvGroup/List 文本树)
property.cpp # W0: .prb/.prt/.pre/.prd/.pra + CRC 注册表(BACKLOG E13
asset_resolver.cpp # W0: 虚拟路径 -> 散文件(BACKLOG G7
terrain_mesh.cpp # W1: heightmap -> 顶点/法线/索引 + GetHeight 三角插值
splat.cpp # W2: tile.raw -> 每图层 258x258 alphaRAW_GenerateSplat 端口)
spt.cpp # W4: .spt 嗅探(几何不可读,见文件头注释)
)
add_library(xrender::formats ALIAS xr_formats)
target_include_directories(xr_formats PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(xr_formats PUBLIC xrender::libgr2)
target_compile_features(xr_formats PUBLIC cxx_std_20)
if(BUILD_TESTING)
add_executable(formats_msa_test tests/msa_test.cpp)
target_link_libraries(formats_msa_test PRIVATE xrender::formats)
add_test(NAME formats.msa_loop_data COMMAND formats_msa_test)
add_executable(formats_msm_test tests/msm_test.cpp)
target_link_libraries(formats_msm_test PRIVATE xrender::formats)
add_test(NAME formats.msm_hair COMMAND formats_msm_test)
add_executable(formats_map_test tests/map_formats_test.cpp)
target_link_libraries(formats_map_test PRIVATE xrender::formats)
add_test(NAME formats.map_formats COMMAND formats_map_test)
# 真实 A1 资源路径(可选):设了就跑 live 断言。
if(DEFINED ENV{M2_ASSETS})
set_tests_properties(formats.map_formats PROPERTIES
ENVIRONMENT "M2_ASSETS=$ENV{M2_ASSETS}")
endif()
endif()