diff --git a/CMakeLists.txt b/CMakeLists.txt index bc90035..2b99bdf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,22 +1,33 @@ cmake_minimum_required(VERSION 3.24) -project(DingoSDK LANGUAGES CXX) -if(NOT WIN32 OR NOT MSVC OR NOT CMAKE_SIZEOF_VOID_P EQUAL 8) - message(FATAL_ERROR "DingoSDK requires Windows, MSVC and the x64 platform.") +project(DingoSDK LANGUAGES CXX C) +if(WIN32) + if(NOT MSVC OR NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + message(FATAL_ERROR "DingoSDK on Windows requires MSVC and the x64 platform.") + endif() +else() + if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + message(FATAL_ERROR "DingoSDK on Linux requires a 64-bit platform.") + endif() + message(STATUS "Linux build: dedicated server only (launcher/runtime stay Windows-only).") endif() include(cmake/ProjectOptions.cmake) include(cmake/Dependencies.cmake) include(cmake/CustomScriptData.cmake) include(cmake/Core.cmake) -include(cmake/Features.cmake) -include(cmake/UI.cmake) -include(cmake/Runtime.cmake) +if(WIN32) + include(cmake/Features.cmake) + include(cmake/UI.cmake) + include(cmake/Runtime.cmake) +endif() include(cmake/Apps.cmake) -include(cmake/Backtrace.cmake) +if(WIN32) + include(cmake/Backtrace.cmake) +endif() option(DINGOSDK_BUILD_TESTS "Build logging regression tests" OFF) option(DINGOSDK_BUILD_PARK_EDITOR_TESTS "Build park editor regression tests" OFF) -if(DINGOSDK_BUILD_PARK_EDITOR_TESTS) +if(DINGOSDK_BUILD_PARK_EDITOR_TESTS AND WIN32) enable_testing() add_executable(dingosdk_park_editor_tests Extension/Objects/ParkEditor/Test/park_editor_tests.cpp) target_link_libraries(dingosdk_park_editor_tests PRIVATE dingosdk_local_profile) @@ -39,10 +50,49 @@ endif() option(DINGOSDK_BUILD_MULTIPLAYER_TESTS "Build multiplayer protocol regression tests" OFF) if(DINGOSDK_BUILD_MULTIPLAYER_TESTS) enable_testing() - add_executable(dingosdk_voice_tests Extension/Multiplayer/Test/voice_chat_tests.cpp Extension/Multiplayer/Net/protocol.cpp - Extension/Multiplayer/Net/delta_codec.cpp Extension/Multiplayer/Net/wire_codec.cpp) - target_link_libraries(dingosdk_voice_tests PRIVATE dingosdk_lz4 dingosdk_zstd) - add_test(NAME multiplayer_voice COMMAND dingosdk_voice_tests) + if(WIN32) + add_executable(dingosdk_voice_tests Extension/Multiplayer/Test/voice_chat_tests.cpp Extension/Multiplayer/Net/protocol.cpp + Extension/Multiplayer/Net/delta_codec.cpp Extension/Multiplayer/Net/wire_codec.cpp) + target_link_libraries(dingosdk_voice_tests PRIVATE dingosdk_lz4 dingosdk_zstd) + add_test(NAME multiplayer_voice COMMAND dingosdk_voice_tests) + endif() + add_executable(dingosdk_party_tests Extension/Multiplayer/Test/party_tests.cpp Extension/Multiplayer/Session/party_book.cpp) + target_include_directories(dingosdk_party_tests PRIVATE "${PROJECT_SOURCE_DIR}") + add_test(NAME multiplayer_parties COMMAND dingosdk_party_tests) + add_executable(dingosdk_server_activity_tests Server/Test/server_activity_tests.cpp Server/server_activity.cpp + Extension/Throwdowns/throwdown_wire.cpp) + target_include_directories(dingosdk_server_activity_tests PRIVATE "${PROJECT_SOURCE_DIR}") + add_test(NAME server_activity COMMAND dingosdk_server_activity_tests) + add_executable(dingosdk_speed_check_tests Server/Test/speed_check_tests.cpp) + target_include_directories(dingosdk_speed_check_tests PRIVATE "${PROJECT_SOURCE_DIR}") + add_test(NAME server_speed_check COMMAND dingosdk_speed_check_tests) + add_executable(dingosdk_server_config_tests Server/Test/server_config_tests.cpp Server/server_config.cpp + Extension/Multiplayer/Net/protocol.cpp) + target_include_directories(dingosdk_server_config_tests PRIVATE "${PROJECT_SOURCE_DIR}") + if(WIN32) + target_link_libraries(dingosdk_server_config_tests PRIVATE dingosdk_launcher_support dingosdk_world_layer_scan dingosdk_json + dingosdk_lz4 dingosdk_zstd dingosdk_logging) + else() + target_link_libraries(dingosdk_server_config_tests PRIVATE dingosdk_launcher_support dingosdk_world_layer_scan dingosdk_json + dingosdk_lz4 dingosdk_zstd) + endif() + add_test(NAME server_config COMMAND dingosdk_server_config_tests) + add_executable(dingosdk_word_filter_tests Engine/Core/Text/Test/word_filter_tests.cpp) + target_link_libraries(dingosdk_word_filter_tests PRIVATE dingosdk_word_filter) + add_test(NAME word_filter COMMAND dingosdk_word_filter_tests) + add_executable(dingosdk_multiplayer_bandwidth_tests + Extension/Multiplayer/Test/bandwidth_tests.cpp Extension/Multiplayer/Net/protocol.cpp Extension/Multiplayer/Remote/playback_buffers.cpp + Extension/Multiplayer/Net/wire_codec.cpp Extension/Multiplayer/Net/delta_codec.cpp) + target_link_libraries(dingosdk_multiplayer_bandwidth_tests PRIVATE dingosdk_lz4 dingosdk_zstd) + add_test(NAME multiplayer_bandwidth COMMAND dingosdk_multiplayer_bandwidth_tests) + add_executable(dingosdk_multiplayer_lane_tests Extension/Multiplayer/Test/steam_lanes_tests.cpp) + target_include_directories(dingosdk_multiplayer_lane_tests SYSTEM PRIVATE "${PROJECT_SOURCE_DIR}/External/steam_networking") + add_test(NAME multiplayer_lanes COMMAND dingosdk_multiplayer_lane_tests) + add_executable(dingosdk_multiplayer_prediction_tests + Extension/Multiplayer/Test/prediction_tests.cpp Extension/Multiplayer/Net/protocol.cpp Extension/Multiplayer/Remote/playback_buffers.cpp) + add_test(NAME multiplayer_prediction COMMAND dingosdk_multiplayer_prediction_tests) +endif() +if(DINGOSDK_BUILD_MULTIPLAYER_TESTS AND WIN32) if(EXISTS "${PROJECT_SOURCE_DIR}/tests/first_person_spring_tests.cpp") add_executable(dingosdk_first_person_spring_tests tests/first_person_spring_tests.cpp) target_include_directories(dingosdk_first_person_spring_tests PRIVATE "${PROJECT_SOURCE_DIR}") @@ -79,27 +129,11 @@ if(DINGOSDK_BUILD_MULTIPLAYER_TESTS) Extension/Throwdowns/throwdown_wire.cpp) target_link_libraries(dingosdk_multiplayer_tests PRIVATE dingosdk_lz4 dingosdk_zstd dingosdk_logging dingosdk_word_filter) add_test(NAME multiplayer_protocol COMMAND dingosdk_multiplayer_tests) - add_executable(dingosdk_party_tests Extension/Multiplayer/Test/party_tests.cpp Extension/Multiplayer/Session/party_book.cpp) - target_include_directories(dingosdk_party_tests PRIVATE "${PROJECT_SOURCE_DIR}") - add_test(NAME multiplayer_parties COMMAND dingosdk_party_tests) add_executable(dingosdk_throwdown_relay_tests Extension/Throwdowns/Test/throwdown_relay_tests.cpp Extension/Throwdowns/throwdown_relay.cpp Extension/Throwdowns/throwdown_wire.cpp) target_include_directories(dingosdk_throwdown_relay_tests PRIVATE "${PROJECT_SOURCE_DIR}") target_link_libraries(dingosdk_throwdown_relay_tests PRIVATE dingosdk_logging) add_test(NAME throwdown_relay COMMAND dingosdk_throwdown_relay_tests) - add_executable(dingosdk_server_activity_tests Server/Test/server_activity_tests.cpp Server/server_activity.cpp - Extension/Throwdowns/throwdown_wire.cpp) - target_include_directories(dingosdk_server_activity_tests PRIVATE "${PROJECT_SOURCE_DIR}") - add_test(NAME server_activity COMMAND dingosdk_server_activity_tests) - add_executable(dingosdk_speed_check_tests Server/Test/speed_check_tests.cpp) - target_include_directories(dingosdk_speed_check_tests PRIVATE "${PROJECT_SOURCE_DIR}") - add_test(NAME server_speed_check COMMAND dingosdk_speed_check_tests) - add_executable(dingosdk_server_config_tests Server/Test/server_config_tests.cpp Server/server_config.cpp - Extension/Multiplayer/Net/protocol.cpp) - target_include_directories(dingosdk_server_config_tests PRIVATE "${PROJECT_SOURCE_DIR}") - target_link_libraries(dingosdk_server_config_tests PRIVATE dingosdk_launcher_support dingosdk_world_layer_scan dingosdk_json - dingosdk_lz4 dingosdk_zstd dingosdk_logging) - add_test(NAME server_config COMMAND dingosdk_server_config_tests) add_executable(dingosdk_multiplayer_native_tests Extension/Multiplayer/Test/native_layout_tests.cpp Extension/Multiplayer/Net/protocol.cpp) add_test(NAME multiplayer_native_layout COMMAND dingosdk_multiplayer_native_tests) @@ -115,25 +149,11 @@ if(DINGOSDK_BUILD_MULTIPLAYER_TESTS) target_link_libraries(dingosdk_multiplayer_mesh_tests PRIVATE dingosdk_logging dingosdk_launcher_support dingosdk_lz4 dingosdk_zstd bcrypt dingosdk_word_filter) add_test(NAME multiplayer_mesh COMMAND dingosdk_multiplayer_mesh_tests) - add_executable(dingosdk_word_filter_tests Engine/Core/Text/Test/word_filter_tests.cpp) - target_link_libraries(dingosdk_word_filter_tests PRIVATE dingosdk_word_filter) - add_test(NAME word_filter COMMAND dingosdk_word_filter_tests) add_executable(dingosdk_settings_lock_tests Engine/Game/Settings/Test/multiplayer_settings_lock_tests.cpp) target_include_directories(dingosdk_settings_lock_tests PRIVATE "${PROJECT_SOURCE_DIR}") add_test(NAME multiplayer_settings_lock COMMAND dingosdk_settings_lock_tests) add_executable(dingosdk_held_input_tests Extension/UI/Overlay/Test/held_input_tests.cpp) add_test(NAME overlay_held_input COMMAND dingosdk_held_input_tests) - add_executable(dingosdk_multiplayer_bandwidth_tests - Extension/Multiplayer/Test/bandwidth_tests.cpp Extension/Multiplayer/Net/protocol.cpp Extension/Multiplayer/Remote/playback_buffers.cpp - Extension/Multiplayer/Net/wire_codec.cpp Extension/Multiplayer/Net/delta_codec.cpp) - target_link_libraries(dingosdk_multiplayer_bandwidth_tests PRIVATE dingosdk_lz4 dingosdk_zstd) - add_test(NAME multiplayer_bandwidth COMMAND dingosdk_multiplayer_bandwidth_tests) - add_executable(dingosdk_multiplayer_lane_tests Extension/Multiplayer/Test/steam_lanes_tests.cpp) - target_include_directories(dingosdk_multiplayer_lane_tests SYSTEM PRIVATE "${PROJECT_SOURCE_DIR}/External/steam_networking") - add_test(NAME multiplayer_lanes COMMAND dingosdk_multiplayer_lane_tests) - add_executable(dingosdk_multiplayer_prediction_tests - Extension/Multiplayer/Test/prediction_tests.cpp Extension/Multiplayer/Net/protocol.cpp Extension/Multiplayer/Remote/playback_buffers.cpp) - add_test(NAME multiplayer_prediction COMMAND dingosdk_multiplayer_prediction_tests) endif() # The route and logging tests live in the local, untracked tests/ folder. option(DINGOSDK_BUILD_ROUTE_TESTS "Build native route cycle regression tests" OFF) @@ -154,8 +174,10 @@ if(DINGOSDK_BUILD_TESTS AND EXISTS "${PROJECT_SOURCE_DIR}/tests/logging_tests.cp endif() # Header-only game contracts belong to the runtime's subsystem tree. -file(GLOB_RECURSE game_headers CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/Engine/Game/*.h") -target_sources(dingosdk_runtime PRIVATE ${game_headers}) +if(WIN32) + file(GLOB_RECURSE game_headers CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/Engine/Game/*.h") + target_sources(dingosdk_runtime PRIVATE ${game_headers}) +endif() get_property(project_targets DIRECTORY PROPERTY BUILDSYSTEM_TARGETS) foreach(target IN LISTS project_targets) if(NOT target MATCHES "^(dingosdk_imgui|dingosdk_detours|dingosdk_sqlite|dingosdk_lz4|dingosdk_zstd|dingosdk_miniz)$") diff --git a/Engine/Core/Platform/launcher_support.cpp b/Engine/Core/Platform/launcher_support.cpp index 1be6012..d2961e8 100644 --- a/Engine/Core/Platform/launcher_support.cpp +++ b/Engine/Core/Platform/launcher_support.cpp @@ -96,6 +96,8 @@ OverlayKeys overlay_keys() noexcept { return keys; } +#endif // _WIN32 + bool offline_mode() noexcept { #ifdef _WIN32 static const bool offline = [] { @@ -135,7 +137,8 @@ std::uint64_t offline_steam_id() noexcept { char* end{}; const auto parsed = std::strtoull(value, &end, 10); // Individual accounts in the public universe only. - return end && *end == '\0' && (parsed >> 52) == 0x011 ? parsed : fallback; + if (!end || *end != '\0' || (static_cast(parsed) >> 52) != 0x011) return fallback; + return static_cast(parsed); }(); return id; } diff --git a/Engine/Resource/cas_codec.cpp b/Engine/Resource/cas_codec.cpp index 0f285eb..8249df8 100644 --- a/Engine/Resource/cas_codec.cpp +++ b/Engine/Resource/cas_codec.cpp @@ -84,7 +84,7 @@ template Function oodle_function(const std::filesystem::path #else // Linux dedicated servers read pre-exported world-layers.json; Oodle blocks // (game CAS) need the Windows game + oo2core DLL and are unsupported here. -void *oodle(const std::filesystem::path &) { +[[maybe_unused]] void *oodle(const std::filesystem::path &) { throw std::runtime_error("Oodle CAS data is only supported on Windows (export world-layers.json there)"); } template Function oodle_function(const std::filesystem::path&, const char* name) { @@ -127,6 +127,7 @@ std::vector zstd_decode(std::span input, std::size_t std::vector oodle_decode(std::span input, std::size_t size, const std::filesystem::path& gameRoot) { +#ifdef _WIN32 using Function = std::int64_t(__cdecl*)(const void*, std::int64_t, void*, std::int64_t, int, int, int, void*, std::int64_t, void*, void*, void*, std::int64_t, int); const auto decode = oodle_function(gameRoot, "OodleLZ_Decompress"); @@ -136,10 +137,17 @@ std::vector oodle_decode(std::span input, std::size_ nullptr, 0, 3) != static_cast(size)) throw std::runtime_error("Oodle CAS block failed to decode"); return output; +#else + (void)input; + (void)size; + (void)gameRoot; + throw std::runtime_error("Oodle CAS data is only supported on Windows (export world-layers.json there)"); +#endif } std::vector oodle_encode(std::span input, CasCompression compression, int level, const std::filesystem::path& gameRoot) { +#ifdef _WIN32 using Bound = std::int64_t(__cdecl*)(int, std::int64_t); using Compress = std::int64_t(__cdecl*)(int, const void*, std::int64_t, void*, int, void*, void*, void*, void*, std::int64_t); @@ -160,6 +168,13 @@ std::vector oodle_encode(std::span input, CasCompres if (length <= 0 || length > capacity) throw std::runtime_error("Oodle CAS compression failed"); output.resize(static_cast(length)); return output; +#else + (void)input; + (void)compression; + (void)level; + (void)gameRoot; + throw std::runtime_error("Oodle CAS data is only supported on Windows"); +#endif } std::vector read_block(Cursor& cursor, const CasDecodeOptions& options) { diff --git a/Server/steam_server.cpp b/Server/steam_server.cpp index 69d2b14..e2a3fa8 100644 --- a/Server/steam_server.cpp +++ b/Server/steam_server.cpp @@ -163,10 +163,12 @@ bool SteamServer::start(const std::filesystem::path &folder, std::uint16_t port, module_ = dlopen("libsteam_api.so", RTLD_NOW); library = folder / "libsteam_api.so"; } - if (!module_) + if (!module_) { + const char *details = dlerror(); throw std::runtime_error("Cannot load " + library.string() + - ". Put libsteam_api.so (Steamworks SDK) next to the server. " + - (dlerror() ? dlerror() : "")); + ". Put libsteam_api.so (Steamworks SDK) next to the server." + + (details && details[0] ? std::string(" ") + details : "")); + } setenv("SteamAppId", "3354750", 1); setenv("SteamGameId", "3354750", 1); #endif diff --git a/cmake/Apps.cmake b/cmake/Apps.cmake index 2f9b59e..2f420ca 100644 --- a/cmake/Apps.cmake +++ b/cmake/Apps.cmake @@ -1,14 +1,16 @@ -add_executable(dingosdk_launcher WIN32 Launcher/main.cpp Launcher/launch.cpp - Launcher/gui.cpp Launcher/gui_launcher.cpp Launcher/gui_renderer.cpp Launcher/gui_home.cpp - Launcher/gui_settings.cpp Launcher/gui_sign_in.cpp Launcher/gui_mods.cpp Launcher/gui_mods_browse.cpp - Launcher/updater.cpp Launcher/mod_manager.cpp Launcher/thunderstore.cpp) -target_link_libraries(dingosdk_launcher PRIVATE dingosdk_logging dingosdk_content_cache_install dingosdk_world_layer_scan dingosdk_launcher_support dingosdk_initfs - dingosdk_mod_list dingosdk_json dingosdk_miniz dingosdk_imgui winhttp shell32 dwmapi windowscodecs ole32) -set_target_properties(dingosdk_launcher PROPERTIES OUTPUT_NAME "ReSkateLauncher") -dingosdk_version_info(dingosdk_launcher "ReSkate launcher" "ReSkateLauncher.exe" VFT_APP) +if(WIN32) + add_executable(dingosdk_launcher WIN32 Launcher/main.cpp Launcher/launch.cpp + Launcher/gui.cpp Launcher/gui_launcher.cpp Launcher/gui_renderer.cpp Launcher/gui_home.cpp + Launcher/gui_settings.cpp Launcher/gui_sign_in.cpp Launcher/gui_mods.cpp Launcher/gui_mods_browse.cpp + Launcher/updater.cpp Launcher/mod_manager.cpp Launcher/thunderstore.cpp) + target_link_libraries(dingosdk_launcher PRIVATE dingosdk_logging dingosdk_content_cache_install dingosdk_world_layer_scan dingosdk_launcher_support dingosdk_initfs + dingosdk_mod_list dingosdk_json dingosdk_miniz dingosdk_imgui winhttp shell32 dwmapi windowscodecs ole32) + set_target_properties(dingosdk_launcher PROPERTIES OUTPUT_NAME "ReSkateLauncher") + dingosdk_version_info(dingosdk_launcher "ReSkate launcher" "ReSkateLauncher.exe" VFT_APP) +endif() option(DINGOSDK_BUILD_LAUNCHER_TESTS "Build launcher mod manager regression tests" OFF) -if(DINGOSDK_BUILD_LAUNCHER_TESTS) +if(DINGOSDK_BUILD_LAUNCHER_TESTS AND WIN32) enable_testing() add_executable(dingosdk_mod_manager_tests Launcher/Test/mod_manager_tests.cpp Launcher/mod_manager.cpp) target_link_libraries(dingosdk_mod_manager_tests PRIVATE dingosdk_mod_list dingosdk_launcher_support dingosdk_miniz shell32) @@ -44,37 +46,39 @@ if(DINGOSDK_BUILD_LAUNCHER_TESTS) add_test(NAME mod_scoring COMMAND dingosdk_mod_scoring_tests "${DINGOSDK_TEST_GAME_ROOT}") endif() -# Launcher fonts (OFL / Apache, licences beside them) and the background photo, -# embedded when present. A ReSkateLauncher.background.jpg beside the exe -# overrides the photo at runtime. -set(launcher_fonts "${PROJECT_SOURCE_DIR}/External/fonts") -set(launcher_resources - "FONT_HEADING RCDATA \"${launcher_fonts}/Montserrat-ExtraBold.ttf\"\n" - "FONT_BODY RCDATA \"${launcher_fonts}/Montserrat-SemiBold.ttf\"\n" - "FONT_BRUSH RCDATA \"${launcher_fonts}/PermanentMarker-Regular.ttf\"\n") -set(launcher_background "${PROJECT_SOURCE_DIR}/assets/launcher/background.jpg") -if(EXISTS "${launcher_background}") - list(APPEND launcher_resources "LAUNCHER_BACKGROUND RCDATA \"${launcher_background}\"\n") - set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${launcher_background}") -endif() -# Tile icons: the skate tool on MODS, the wheel on SETTINGS. -foreach(tile_icon mods settings) - set(tile_icon_path "${PROJECT_SOURCE_DIR}/assets/launcher/icon_${tile_icon}.png") - if(EXISTS "${tile_icon_path}") - string(TOUPPER "${tile_icon}" tile_icon_name) - list(APPEND launcher_resources "LAUNCHER_ICON_${tile_icon_name} RCDATA \"${tile_icon_path}\"\n") - set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${tile_icon_path}") +if(WIN32) + # Launcher fonts (OFL / Apache, licences beside them) and the background photo, + # embedded when present. A ReSkateLauncher.background.jpg beside the exe + # overrides the photo at runtime. + set(launcher_fonts "${PROJECT_SOURCE_DIR}/External/fonts") + set(launcher_resources + "FONT_HEADING RCDATA \"${launcher_fonts}/Montserrat-ExtraBold.ttf\"\n" + "FONT_BODY RCDATA \"${launcher_fonts}/Montserrat-SemiBold.ttf\"\n" + "FONT_BRUSH RCDATA \"${launcher_fonts}/PermanentMarker-Regular.ttf\"\n") + set(launcher_background "${PROJECT_SOURCE_DIR}/assets/launcher/background.jpg") + if(EXISTS "${launcher_background}") + list(APPEND launcher_resources "LAUNCHER_BACKGROUND RCDATA \"${launcher_background}\"\n") + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${launcher_background}") endif() -endforeach() -# Icon resource 1: the exe's icon in Explorer and the window's icon. -set(launcher_icon "${PROJECT_SOURCE_DIR}/assets/launcher/icon.ico") -if(EXISTS "${launcher_icon}") - list(PREPEND launcher_resources "1 ICON \"${launcher_icon}\"\n") - set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${launcher_icon}") + # Tile icons: the skate tool on MODS, the wheel on SETTINGS. + foreach(tile_icon mods settings) + set(tile_icon_path "${PROJECT_SOURCE_DIR}/assets/launcher/icon_${tile_icon}.png") + if(EXISTS "${tile_icon_path}") + string(TOUPPER "${tile_icon}" tile_icon_name) + list(APPEND launcher_resources "LAUNCHER_ICON_${tile_icon_name} RCDATA \"${tile_icon_path}\"\n") + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${tile_icon_path}") + endif() + endforeach() + # Icon resource 1: the exe's icon in Explorer and the window's icon. + set(launcher_icon "${PROJECT_SOURCE_DIR}/assets/launcher/icon.ico") + if(EXISTS "${launcher_icon}") + list(PREPEND launcher_resources "1 ICON \"${launcher_icon}\"\n") + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${launcher_icon}") + endif() + string(CONCAT launcher_resources ${launcher_resources}) + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/generated/launcher_resources.rc" "${launcher_resources}") + target_sources(dingosdk_launcher PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/generated/launcher_resources.rc") endif() -string(CONCAT launcher_resources ${launcher_resources}) -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/generated/launcher_resources.rc" "${launcher_resources}") -target_sources(dingosdk_launcher PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/generated/launcher_resources.rc") # Off for local builds so a deployed development DLL is never replaced by a release. option(DINGOSDK_LAUNCHER_AUTO_UPDATE "Let the launcher replace itself and ReSkate.dll from the launcher config" OFF) @@ -98,23 +102,33 @@ else() endif() configure_file(cmake/templates/launcher_update_config.h.in generated/launcher_update_config.h @ONLY) -# ReSkateEmotePacker: a folder of pictures and GIFs -> the chat emote pack (emotes.json + -# emotes.png) that ReSkate.dll bakes in from assets/emotes. -add_executable(dingosdk_emote_packer EmotePacker/main.cpp) -target_link_libraries(dingosdk_emote_packer PRIVATE dingosdk_json windowscodecs ole32) -set_target_properties(dingosdk_emote_packer PROPERTIES OUTPUT_NAME "ReSkateEmotePacker") +if(WIN32) + # ReSkateEmotePacker: a folder of pictures and GIFs -> the chat emote pack (emotes.json + + # emotes.png) that ReSkate.dll bakes in from assets/emotes. + add_executable(dingosdk_emote_packer EmotePacker/main.cpp) + target_link_libraries(dingosdk_emote_packer PRIVATE dingosdk_json windowscodecs ole32) + set_target_properties(dingosdk_emote_packer PROPERTIES OUTPUT_NAME "ReSkateEmotePacker") +endif() # ReSkate dedicated server: a headless session host. It runs from its own folder # next to steam_api64.dll and the Steam client files; no game install needed. +# On Linux next to libsteam_api.so; self-update is disabled there (see server_update.cpp). add_executable(dingosdk_server Server/main.cpp Server/server_host.cpp Server/server_party.cpp Extension/Multiplayer/Session/party_book.cpp Server/server_config.cpp Server/steam_server.cpp - Server/server_update.cpp Launcher/updater.cpp + Server/server_update.cpp $<$:Launcher/updater.cpp> Extension/Multiplayer/Steam/steam_transport.cpp Extension/Multiplayer/Net/protocol.cpp Extension/Multiplayer/Net/delta_codec.cpp Extension/Multiplayer/Net/wire_codec.cpp Extension/Multiplayer/Remote/playback_buffers.cpp Extension/Multiplayer/Session/password.cpp Server/server_activity.cpp Server/server_votes.cpp Extension/Throwdowns/throwdown_wire.cpp) target_include_directories(dingosdk_server SYSTEM PRIVATE "${PROJECT_SOURCE_DIR}/External/steam_networking") -target_link_libraries(dingosdk_server PRIVATE dingosdk_launcher_support dingosdk_world_layer_scan dingosdk_json - dingosdk_lz4 dingosdk_zstd dingosdk_logging dingosdk_miniz dingosdk_word_filter winhttp bcrypt winmm) -set_target_properties(dingosdk_server PROPERTIES OUTPUT_NAME "ReSkateServer") -dingosdk_version_info(dingosdk_server "ReSkate dedicated server" "ReSkateServer.exe" VFT_APP) +if(WIN32) + target_link_libraries(dingosdk_server PRIVATE dingosdk_launcher_support dingosdk_world_layer_scan dingosdk_json + dingosdk_lz4 dingosdk_zstd dingosdk_logging dingosdk_miniz dingosdk_word_filter winhttp bcrypt winmm) + set_target_properties(dingosdk_server PROPERTIES OUTPUT_NAME "ReSkateServer") + dingosdk_version_info(dingosdk_server "ReSkate dedicated server" "ReSkateServer.exe" VFT_APP) +else() + find_package(OpenSSL REQUIRED) + target_link_libraries(dingosdk_server PRIVATE dingosdk_launcher_support dingosdk_world_layer_scan dingosdk_json + dingosdk_lz4 dingosdk_zstd dingosdk_miniz dingosdk_word_filter OpenSSL::Crypto dl pthread) + set_target_properties(dingosdk_server PROPERTIES OUTPUT_NAME "ReSkateServer") +endif() diff --git a/cmake/Core.cmake b/cmake/Core.cmake index 629b585..c3143fb 100644 --- a/cmake/Core.cmake +++ b/cmake/Core.cmake @@ -1,17 +1,26 @@ -add_library(dingosdk_hooks STATIC - Engine/Core/Hooks/hooks.cpp) -target_link_libraries(dingosdk_hooks PRIVATE dingosdk_detours) +if(WIN32) + add_library(dingosdk_hooks STATIC + Engine/Core/Hooks/hooks.cpp) + target_link_libraries(dingosdk_hooks PRIVATE dingosdk_detours) +endif() add_library(dingosdk_launcher_support STATIC Engine/Core/Platform/launcher_support.cpp Engine/Core/Platform/launcher_pe.cpp - Engine/Core/Platform/launcher_injection.cpp) + $<$:Engine/Core/Platform/launcher_injection.cpp>) -target_link_libraries(dingosdk_launcher_support PUBLIC bcrypt) +if(WIN32) + target_link_libraries(dingosdk_launcher_support PUBLIC bcrypt) +else() + find_package(OpenSSL REQUIRED) + target_link_libraries(dingosdk_launcher_support PUBLIC OpenSSL::Crypto) +endif() -# Checks that the running game is the supported Skate.exe build. -add_library(dingosdk_supported_build STATIC Engine/Game/Build/image_identity.cpp) -target_link_libraries(dingosdk_supported_build PUBLIC bcrypt) +if(WIN32) + # Checks that the running game is the supported Skate.exe build. + add_library(dingosdk_supported_build STATIC Engine/Game/Build/image_identity.cpp) + target_link_libraries(dingosdk_supported_build PUBLIC bcrypt) +endif() add_library(dingosdk_console_core STATIC Engine/Core/Console/console_core.cpp @@ -33,25 +42,27 @@ add_library(dingosdk_word_filter STATIC Engine/Core/Text/word_filter.cpp) target_include_directories(dingosdk_json SYSTEM PRIVATE External) -add_library(dingosdk_logging STATIC - Engine/Core/Log/logger.cpp - Engine/Core/Log/banner.cpp - Engine/Core/Log/events.cpp - Engine/Core/Log/paths.cpp - Engine/Core/Log/crash.cpp) -target_link_libraries(dingosdk_logging PUBLIC dingosdk_console_core PRIVATE shell32 ole32) -target_include_directories(dingosdk_logging SYSTEM PRIVATE External/spdlog/include External) -target_compile_definitions(dingosdk_logging PRIVATE SPDLOG_USE_STD_FORMAT SPDLOG_WCHAR_FILENAMES) +if(WIN32) + add_library(dingosdk_logging STATIC + Engine/Core/Log/logger.cpp + Engine/Core/Log/banner.cpp + Engine/Core/Log/events.cpp + Engine/Core/Log/paths.cpp + Engine/Core/Log/crash.cpp) + target_link_libraries(dingosdk_logging PUBLIC dingosdk_console_core PRIVATE shell32 ole32) + target_include_directories(dingosdk_logging SYSTEM PRIVATE External/spdlog/include External) + target_compile_definitions(dingosdk_logging PRIVATE SPDLOG_USE_STD_FORMAT SPDLOG_WCHAR_FILENAMES) -# The performance profiler: zones, frame timing, thread CPU use and the stack sampler -# (Engine/Core/Profiling/profiler.h). Shared by the overlay and the runtime. -add_library(dingosdk_profiler STATIC - Engine/Core/Profiling/profiler.cpp - Engine/Core/Profiling/sampler.cpp) -target_link_libraries(dingosdk_profiler PUBLIC dingosdk_logging PRIVATE dbghelp) + # The performance profiler: zones, frame timing, thread CPU use and the stack sampler + # (Engine/Core/Profiling/profiler.h). Shared by the overlay and the runtime. + add_library(dingosdk_profiler STATIC + Engine/Core/Profiling/profiler.cpp + Engine/Core/Profiling/sampler.cpp) + target_link_libraries(dingosdk_profiler PUBLIC dingosdk_logging PRIVATE dbghelp) -add_library(dingosdk_storage STATIC Engine/Core/Storage/save_database.cpp) -target_link_libraries(dingosdk_storage PUBLIC dingosdk_json PRIVATE dingosdk_sqlite) + add_library(dingosdk_storage STATIC Engine/Core/Storage/save_database.cpp) + target_link_libraries(dingosdk_storage PUBLIC dingosdk_json PRIVATE dingosdk_sqlite) +endif() add_library(dingosdk_frostbite STATIC Engine/Resource/binary_io.cpp @@ -70,46 +81,52 @@ target_link_libraries(dingosdk_frostbite PRIVATE dingosdk_lz4 dingosdk_zstd ding add_library(dingosdk_native_db STATIC Engine/Vfs/native_db.cpp) -add_library(dingosdk_initfs STATIC Engine/Vfs/initfs.cpp) -target_link_libraries(dingosdk_initfs PUBLIC dingosdk_launcher_support dingosdk_json PRIVATE dingosdk_native_db bcrypt) +if(WIN32) + add_library(dingosdk_initfs STATIC Engine/Vfs/initfs.cpp) + target_link_libraries(dingosdk_initfs PUBLIC dingosdk_launcher_support dingosdk_json PRIVATE dingosdk_native_db bcrypt) -# The Mods folder list and mods.json writer, without the merge: shared with -# the launcher's mod manager. -add_library(dingosdk_mod_list STATIC Engine/Vfs/mod_list.cpp) -target_link_libraries(dingosdk_mod_list PUBLIC dingosdk_json) + # The Mods folder list and mods.json writer, without the merge: shared with + # the launcher's mod manager. + add_library(dingosdk_mod_list STATIC Engine/Vfs/mod_list.cpp) + target_link_libraries(dingosdk_mod_list PUBLIC dingosdk_json) +endif() # Read access to the installed game's cas archives. add_library(dingosdk_game_archives STATIC Engine/Vfs/game_archives.cpp Engine/Vfs/game_bundles.cpp Engine/Vfs/item_thumbnails.cpp) target_link_libraries(dingosdk_game_archives PUBLIC dingosdk_native_db dingosdk_frostbite) -add_library(dingosdk_mods STATIC - Engine/Vfs/mod_catalog.cpp - Engine/Vfs/mod_merge.cpp - Engine/Vfs/mod_merge_files.cpp - Engine/Vfs/mod_merge_stamp.cpp - Engine/Vfs/mod_merge_cas_store.cpp - Engine/Vfs/mod_merge_combine.cpp - Engine/Vfs/mod_merge_overrides.cpp - Engine/Vfs/mod_merge_grid.cpp - Engine/Vfs/mod_merge_load_screens.cpp - Engine/Vfs/mod_scoring.cpp) -target_link_libraries(dingosdk_mods PUBLIC dingosdk_json dingosdk_mod_list PRIVATE dingosdk_game_archives dingosdk_native_db dingosdk_frostbite shell32 bcrypt) +if(WIN32) + add_library(dingosdk_mods STATIC + Engine/Vfs/mod_catalog.cpp + Engine/Vfs/mod_merge.cpp + Engine/Vfs/mod_merge_files.cpp + Engine/Vfs/mod_merge_stamp.cpp + Engine/Vfs/mod_merge_cas_store.cpp + Engine/Vfs/mod_merge_combine.cpp + Engine/Vfs/mod_merge_overrides.cpp + Engine/Vfs/mod_merge_grid.cpp + Engine/Vfs/mod_merge_load_screens.cpp + Engine/Vfs/mod_scoring.cpp) + target_link_libraries(dingosdk_mods PUBLIC dingosdk_json dingosdk_mod_list PRIVATE dingosdk_game_archives dingosdk_native_db dingosdk_frostbite shell32 bcrypt) -add_library(dingosdk_custom_scripts STATIC Engine/Scripting/custom_scripts.cpp) -target_link_libraries(dingosdk_custom_scripts PUBLIC dingosdk_json PRIVATE dingosdk_initfs) + add_library(dingosdk_custom_scripts STATIC Engine/Scripting/custom_scripts.cpp) + target_link_libraries(dingosdk_custom_scripts PUBLIC dingosdk_json PRIVATE dingosdk_initfs) -# HTTPS downloads shared by the park preview and content cache packs. -add_library(dingosdk_https STATIC Engine/Vfs/https_download.cpp) -target_link_libraries(dingosdk_https PUBLIC winhttp) + # HTTPS downloads shared by the park preview and content cache packs. + add_library(dingosdk_https STATIC Engine/Vfs/https_download.cpp) + target_link_libraries(dingosdk_https PUBLIC winhttp) +endif() # The live game's content cache: the launcher installs it, the runtime reads # catalogues from it (Engine/Vfs/content_cache.h). add_library(dingosdk_content_cache STATIC Engine/Vfs/content_cache.cpp Engine/Vfs/content_catalogs.cpp) target_link_libraries(dingosdk_content_cache PUBLIC dingosdk_json) -add_library(dingosdk_content_cache_install STATIC Engine/Vfs/content_cache_install.cpp) -target_link_libraries(dingosdk_content_cache_install PUBLIC dingosdk_content_cache - PRIVATE dingosdk_launcher_support dingosdk_https dingosdk_miniz) +if(WIN32) + add_library(dingosdk_content_cache_install STATIC Engine/Vfs/content_cache_install.cpp) + target_link_libraries(dingosdk_content_cache_install PUBLIC dingosdk_content_cache + PRIVATE dingosdk_launcher_support dingosdk_https dingosdk_miniz) +endif() # World layers read from the installed level data, cached per game build. add_library(dingosdk_world_layer_scan STATIC Engine/Vfs/world_layer_scan.cpp) target_link_libraries(dingosdk_world_layer_scan PUBLIC dingosdk_json PRIVATE dingosdk_game_archives dingosdk_content_cache) diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 86bfd84..a1dedab 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -1,28 +1,30 @@ -add_library(dingosdk_imgui STATIC - "${PROJECT_SOURCE_DIR}/External/imgui/imgui.cpp" - "${PROJECT_SOURCE_DIR}/External/imgui/imgui_draw.cpp" - "${PROJECT_SOURCE_DIR}/External/imgui/imgui_tables.cpp" - "${PROJECT_SOURCE_DIR}/External/imgui/imgui_widgets.cpp" - "${PROJECT_SOURCE_DIR}/External/imgui/backends/imgui_impl_dx12.cpp" - "${PROJECT_SOURCE_DIR}/External/imgui/backends/imgui_impl_win32.cpp") -target_include_directories(dingosdk_imgui PUBLIC "${PROJECT_SOURCE_DIR}/External/imgui") -target_compile_definitions(dingosdk_imgui PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX UNICODE _UNICODE) -target_link_libraries(dingosdk_imgui PUBLIC d3d12 dxgi d3dcompiler dwmapi) +if(WIN32) + add_library(dingosdk_imgui STATIC + "${PROJECT_SOURCE_DIR}/External/imgui/imgui.cpp" + "${PROJECT_SOURCE_DIR}/External/imgui/imgui_draw.cpp" + "${PROJECT_SOURCE_DIR}/External/imgui/imgui_tables.cpp" + "${PROJECT_SOURCE_DIR}/External/imgui/imgui_widgets.cpp" + "${PROJECT_SOURCE_DIR}/External/imgui/backends/imgui_impl_dx12.cpp" + "${PROJECT_SOURCE_DIR}/External/imgui/backends/imgui_impl_win32.cpp") + target_include_directories(dingosdk_imgui PUBLIC "${PROJECT_SOURCE_DIR}/External/imgui") + target_compile_definitions(dingosdk_imgui PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX UNICODE _UNICODE) + target_link_libraries(dingosdk_imgui PUBLIC d3d12 dxgi d3dcompiler dwmapi) -add_library(dingosdk_detours STATIC - External/detours/src/detours.cpp - External/detours/src/modules.cpp - External/detours/src/disasm.cpp - External/detours/src/image.cpp - External/detours/src/creatwth.cpp - External/detours/src/disolx86.cpp - External/detours/src/disolx64.cpp - External/detours/src/disolia64.cpp - External/detours/src/disolarm.cpp - External/detours/src/disolarm64.cpp) -target_include_directories(dingosdk_detours SYSTEM PUBLIC External/detours/src) -target_compile_definitions(dingosdk_detours PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX) -set_target_properties(dingosdk_imgui dingosdk_detours PROPERTIES FOLDER "Dependencies") + add_library(dingosdk_detours STATIC + External/detours/src/detours.cpp + External/detours/src/modules.cpp + External/detours/src/disasm.cpp + External/detours/src/image.cpp + External/detours/src/creatwth.cpp + External/detours/src/disolx86.cpp + External/detours/src/disolx64.cpp + External/detours/src/disolia64.cpp + External/detours/src/disolarm.cpp + External/detours/src/disolarm64.cpp) + target_include_directories(dingosdk_detours SYSTEM PUBLIC External/detours/src) + target_compile_definitions(dingosdk_detours PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX) + set_target_properties(dingosdk_imgui dingosdk_detours PROPERTIES FOLDER "Dependencies") +endif() enable_language(C) add_library(dingosdk_miniz STATIC External/miniz/miniz.c) diff --git a/cmake/ProjectOptions.cmake b/cmake/ProjectOptions.cmake index e4b12a6..bb2523c 100644 --- a/cmake/ProjectOptions.cmake +++ b/cmake/ProjectOptions.cmake @@ -2,7 +2,9 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +if(MSVC) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +endif() set_property(GLOBAL PROPERTY USE_FOLDERS ON) # Windows version information (Explorer's Details tab) for the shipped binaries. The release @@ -17,6 +19,9 @@ function(dingosdk_version_info target description file_name file_type) if(NOT DINGOSDK_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") message(FATAL_ERROR "DINGOSDK_VERSION must look like 1.2.3, not '${DINGOSDK_VERSION}'") endif() + if(NOT WIN32) + return() + endif() set(version_major ${CMAKE_MATCH_1}) set(version_minor ${CMAKE_MATCH_2}) set(version_patch ${CMAKE_MATCH_3}) @@ -31,8 +36,14 @@ endfunction() function(dingosdk_configure_target target) target_include_directories(${target} PUBLIC "${PROJECT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/generated") - target_compile_definitions(${target} PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX UNICODE _UNICODE) - target_compile_options(${target} PRIVATE /W4 /WX /MP4 /permissive- /EHsc) + if(WIN32) + target_compile_definitions(${target} PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX UNICODE _UNICODE) + endif() + if(MSVC) + target_compile_options(${target} PRIVATE /W4 /WX /MP4 /permissive- /EHsc) + else() + target_compile_options(${target} PRIVATE -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-function -Wno-array-bounds) + endif() if(target STREQUAL "dingosdk_launcher") set_property(TARGET ${target} PROPERTY FOLDER "Apps") elseif(target MATCHES "^dingosdk_runtime$")