# mtgodot GDExtension — registers Metin2Model / Metin2AnimPlayer, links libgr2. # libgr2 is added at the top-level CMakeLists (vendored under ../libgr2), so here # we just consume the xrender::libgr2 target. # --- godot-cpp (submodule pinned at 101ae38034304346a46ea9ea84ae156d3e860496) --- # The parent gitlink is the source-of-truth; .gitmodules intentionally has no # moving branch. The selected bundle targets Godot 4.7's extension API. set(GODOTCPP_API_VERSION "4.7" CACHE STRING "Target Godot API version" FORCE) add_subdirectory(godot-cpp) # --- vendored native deps: libsodium / libzstd / miniLZO --- # Built from source (pinned submodules + vendored miniLZO) so the same tree # compiles on the Android NDK and iOS SDK, which have no Homebrew. Exposes the # aliases mt3p::sodium / mt3p::zstd / mt3p::minilzo. See docs/THIRD-PARTY.md. add_subdirectory(third_party) # --- mtnet: Metin2 net protocol core (no godot-cpp dep; libsodium only) --- add_library(mtnet STATIC src/net/secure_cipher.cpp src/net/net_stream.cpp src/net/entity_store.cpp src/net/mark_image.cpp src/net/classic/classic_stream.cpp # MT_PROTOCOL=classic (40250) src/net/classic/classic_parser.cpp src/net/classic/classic_session.cpp src/net/classic/classic_cipher.cpp ) target_include_directories(mtnet PUBLIC src/net) target_link_libraries(mtnet PUBLIC mt3p::sodium mt3p::minilzo mt3p::cryptopp) target_compile_features(mtnet PUBLIC cxx_std_20) # --- mtpack: m2dev-fork asset pack reader/writer (libsodium + zstd) --- add_library(mtpack STATIC src/pack/eterpack.cpp src/pack/pack_mount.cpp src/pack/asset_source.cpp ) target_include_directories(mtpack PUBLIC src/pack) target_link_libraries(mtpack PUBLIC mt3p::sodium mt3p::zstd xrender::formats) target_compile_features(mtpack PUBLIC cxx_std_20) # --- mtproto: item_proto / mob_proto reader (libsodium + LZO) --- add_library(mtproto STATIC src/proto/proto.cpp) target_include_directories(mtproto PUBLIC src/proto) target_link_libraries(mtproto PUBLIC mt3p::sodium mt3p::minilzo) target_compile_features(mtproto PUBLIC cxx_std_20) # Host-only CLIs + tests: they run on the build machine, so skip them entirely # when cross-compiling the extension for a device. set(MT_HOST_BUILD FALSE) if(CMAKE_SYSTEM_NAME STREQUAL CMAKE_HOST_SYSTEM_NAME) set(MT_HOST_BUILD TRUE) endif() if(MT_HOST_BUILD) add_executable(packtool tools/packtool.cpp) target_link_libraries(packtool PRIVATE mtpack) # net_probe: connect to an auth server, run the handshake + CG_LOGIN3, report. add_executable(net_probe tools/net_probe.cpp) target_link_libraries(net_probe PRIVATE mtnet) # net_e2e: full auth -> game -> char list -> select -> PHASE_GAME against a # real server; dumps entities / points / inventory. Live integration check. add_executable(net_e2e tools/net_e2e.cpp) target_link_libraries(net_e2e PRIVATE mtnet) # net_classic_e2e: live 40250 classic handshake -> login -> char select -> PHASE_GAME probe. add_executable(net_classic_e2e tools/net_classic_e2e.cpp) target_link_libraries(net_classic_e2e PRIVATE mtnet) endif() if(BUILD_TESTING AND MT_HOST_BUILD) add_executable(net_cipher_test tests/net_cipher_test.cpp) target_link_libraries(net_cipher_test PRIVATE mtnet) add_test(NAME net.cipher_roundtrip COMMAND $) add_executable(net_loopback_test tests/net_loopback_test.cpp) target_link_libraries(net_loopback_test PRIVATE mtnet) add_test(NAME net.loopback_flow COMMAND $) add_executable(net_entity_test tests/net_entity_test.cpp) target_link_libraries(net_entity_test PRIVATE mtnet) add_test(NAME net.entity_store COMMAND $) # 40250 "classic" backend (MT_PROTOCOL=classic). add_executable(net_classic_wire_test tests/net_classic_wire_test.cpp) target_include_directories(net_classic_wire_test PRIVATE src/net) target_compile_features(net_classic_wire_test PRIVATE cxx_std_20) add_test(NAME net.classic_wire COMMAND $) add_executable(net_classic_stream_test tests/net_classic_stream_test.cpp) target_link_libraries(net_classic_stream_test PRIVATE mtnet) add_test(NAME net.classic_stream COMMAND $) add_executable(net_classic_session_test tests/net_classic_session_test.cpp) target_link_libraries(net_classic_session_test PRIVATE mtnet) add_test(NAME net.classic_session COMMAND $) add_executable(net_classic_cipher_test tests/net_classic_cipher_test.cpp) target_link_libraries(net_classic_cipher_test PRIVATE mtnet) add_test(NAME net.classic_cipher COMMAND $) add_executable(net_classic_encstream_test tests/net_classic_encstream_test.cpp) target_link_libraries(net_classic_encstream_test PRIVATE mtnet) add_test(NAME net.classic_encstream COMMAND $) add_executable(net_classic_mark_test tests/net_classic_mark_test.cpp) target_link_libraries(net_classic_mark_test PRIVATE mtnet) add_test(NAME net.classic_mark COMMAND $) add_executable(net_mark_test tests/net_mark_test.cpp) target_link_libraries(net_mark_test PRIVATE mtnet mt3p::minilzo) add_test(NAME net.guild_mark COMMAND $) add_executable(pack_roundtrip_test tests/pack_roundtrip_test.cpp) target_link_libraries(pack_roundtrip_test PRIVATE mtpack) add_test(NAME pack.roundtrip COMMAND $) add_executable(proto_test tests/proto_test.cpp) target_link_libraries(proto_test PRIVATE mtproto) add_test(NAME proto.item_mob COMMAND $) if(DEFINED ENV{M2_ASSETS}) set_tests_properties(proto.item_mob PROPERTIES ENVIRONMENT "M2_ASSETS=$ENV{M2_ASSETS}") endif() endif() # --- the extension library --- # macOS/Android: SHARED (Godot dlopen()s it). iOS: STATIC — the platform forbids # loading dynamic libraries, so the archive is linked into the app at export time # (see docs/PLATFORMS.md for the remaining F1 export/sign steps). if(CMAKE_SYSTEM_NAME STREQUAL "iOS") set(MT_LIB_KIND STATIC) set(MT_PLAT_TAG "ios") elseif(CMAKE_SYSTEM_NAME STREQUAL "Android") set(MT_LIB_KIND SHARED) set(MT_PLAT_TAG "android") else() set(MT_LIB_KIND SHARED) set(MT_PLAT_TAG "macos") endif() add_library(mtgodot ${MT_LIB_KIND} src/register_types.cpp src/metin2_model.cpp src/metin2_anim.cpp src/metin2_world.cpp src/terrain_splat.cpp src/static_object.cpp src/tree_placeholder.cpp src/environment_builder.cpp src/water_builder.cpp src/gr2_bridge.cpp src/m2_material.cpp src/dxt.cpp src/asset_io.cpp src/texture_util.cpp src/net/m2_client.cpp src/proto/proto_node.cpp ) target_compile_features(mtgodot PRIVATE cxx_std_20) target_link_libraries(mtgodot PRIVATE godot::cpp xrender::libgr2 xrender::formats mtnet mtproto) # Godot's .gdextension expects, per platform: # project/bin/libmtgodot.macos.template_{debug,release}.dylib # project/bin/libmtgodot.ios.template_{debug,release}.a # project/bin/libmtgodot.android.template_{debug,release}..so set(MT_CFG_TAG "$,template_release,template_debug>") if(CMAKE_SYSTEM_NAME STREQUAL "Android") # godot_arch_name-style suffix; OnePlus 13 = arm64. set(MT_ARCH_SUFFIX ".${CMAKE_ANDROID_ARCH_ABI}") string(REPLACE "arm64-v8a" "arm64" MT_ARCH_SUFFIX "${MT_ARCH_SUFFIX}") else() set(MT_ARCH_SUFFIX "") endif() set_target_properties(mtgodot PROPERTIES PREFIX "lib" OUTPUT_NAME "mtgodot.${MT_PLAT_TAG}.${MT_CFG_TAG}${MT_ARCH_SUFFIX}" ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/project/bin" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/project/bin" )