diff options
Diffstat (limited to 'source')
52 files changed, 2214 insertions, 685 deletions
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index f0f767c..6ed5bb5 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,16 +1,31 @@ -cmake_minimum_required(VERSION 3.16) - -# Find CCache -find_program(CCACHE_PATH ccache) -if(CCACHE_PATH) - set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PATH}") - set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PATH}") - message(STATUS "Using CCache") +cmake_minimum_required(VERSION 3.23) + +# Find SCCache or CCache +if (NOT CMAKE_CXX_COMPILER_LAUNCHER MATCHES "ccache") + find_program(SCCACHE_PATH sccache) + if(SCCACHE_PATH) + message(STATUS "Using SCCache at ${SCCACHE_PATH}") + set(CMAKE_C_COMPILER_LAUNCHER ${SCCACHE_PATH}) + set(CMAKE_CXX_COMPILER_LAUNCHER ${SCCACHE_PATH}) + else() + find_program(CCACHE_PATH ccache) + if(CCACHE_PATH) + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PATH}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PATH}") + message(STATUS "Using CCache") + endif() + endif() +endif() + +if(CMAKE_CXX_COMPILER_LAUNCHER MATCHES "ccache") + set(STAR_CCACHE TRUE) + set(STAR_PRECOMPILED_HEADERS FALSE) else() + set(STAR_CCACHE FALSE) + set(STAR_PRECOMPILED_HEADERS TRUE) message(STATUS "Not using CCache") endif() - project(starbound) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../cmake) @@ -299,6 +314,7 @@ elseif(STAR_COMPILER_MSVC) # /fp:fast - Equivalent to -ffast-math # /GS- - Disable buffers security check # /Zi - Generates debugging information without Edit and Continue + # /Z7 - Like the above, but debugging information is stored per-object # /Gy - Use function-level linking # /wd4996 - Disable warnings about unsafe C functions # /wd4351 - Disable warnings about new behavior of default initialization of @@ -317,22 +333,22 @@ elseif(STAR_COMPILER_MSVC) # /wd4624 - Silence implicitly deleted destructor warnings that show up when # using unions in interesting ways. - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP /EHsc /bigobj /wd4996 /wd4351 /wd4800 /wd4244 /wd4305 /wd4267 /wd4456 /wd4503 /wd4250 /wd4624") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17 /MP /EHsc /bigobj /wd4996 /wd4351 /wd4800 /wd4244 /wd4305 /wd4267 /wd4456 /wd4503 /wd4250 /wd4624") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /MP /EHsc /bigobj /wd4996 /wd4351 /wd4800 /wd4244 /wd4305 /wd4267 /wd4456 /wd4503 /wd4250 /wd4624") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /nologo /std:c++17 /MP /EHsc /bigobj /wd4996 /wd4351 /wd4800 /wd4244 /wd4305 /wd4267 /wd4456 /wd4503 /wd4250 /wd4624") if(STAR_ENABLE_STATIC_MSVC_RUNTIME) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MT") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MT") endif() - set(CMAKE_C_FLAGS_DEBUG "/Zi /Od") - set(CMAKE_CXX_FLAGS_DEBUG "/Zi /Od") + set(CMAKE_C_FLAGS_DEBUG "/Z7 /Od") + set(CMAKE_CXX_FLAGS_DEBUG "/Z7 /Od") - set(CMAKE_C_FLAGS_RELWITHASSERTS "/Ox /fp:fast /GA /GS- /Zi /Gy") - set(CMAKE_CXX_FLAGS_RELWITHASSERTS "/Ox /fp:fast /GA /GS- /Zi /Gy") + set(CMAKE_C_FLAGS_RELWITHASSERTS "/Ox /fp:fast /GA /GS- /Z7 /Gy") + set(CMAKE_CXX_FLAGS_RELWITHASSERTS "/Ox /fp:fast /GA /GS- /Z7 /Gy") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "/Ox /fp:fast /GA /GS- /Zi /Gy /DNDEBUG") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/Ox /fp:fast /GA /GS- /Zi /Gy /DNDEBUG") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "/Ox /fp:fast /GA /GS- /Z7 /Gy /DNDEBUG") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/Ox /fp:fast /GA /GS- /Z7 /Gy /DNDEBUG") set(CMAKE_C_FLAGS_RELEASE "/Ox /fp:fast /GA /GS- /Gy /DNDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "/Ox /fp:fast /GA /GS- /Gy /DNDEBUG") @@ -425,6 +441,7 @@ endif() find_package(ZLIB REQUIRED) find_package(PNG REQUIRED) find_package(Freetype REQUIRED) +find_package(Opus CONFIG REQUIRED) find_package(OggVorbis REQUIRED) include_directories(SYSTEM @@ -432,48 +449,45 @@ include_directories(SYSTEM ${OGGVORBIS_INCLUDE_DIR} ) -if(TARGET freetype AND NOT TARGET Freetype::Freetype) - add_library(Freetype::Freetype ALIAS freetype) - message(STATUS "Freetype target name is freetype") -elseif(TARGET Freetype::Freetype AND NOT TARGET freetype) - add_library(freetype ALIAS Freetype::Freetype) - message(STATUS "Freetype target name is Freetype::Freetype") -else() - message(FATAL_ERROR "Could not find Freetype") -endif() - set(STAR_EXT_LIBS ${STAR_EXT_LIBS} ZLIB::ZLIB PNG::PNG - Freetype::Freetype + $<IF:$<TARGET_EXISTS:Freetype::Freetype>,Freetype::Freetype,freetype> + Opus::opus ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY} ${OGG_LIBRARY} - opus # Currently a submodule from extern ) if(STAR_BUILD_GUI) - find_package(SDL2 REQUIRED) - include_directories(SYSTEM ${SDL2_INCLUDE_DIR}) - set(STAR_EXT_GUI_LIBS ${SDL2_LIBRARY}) + find_package(SDL2 CONFIG REQUIRED) + + set(STAR_EXT_GUI_LIBS + $<TARGET_NAME_IF_EXISTS:SDL2::SDL2main> + $<IF:$<TARGET_EXISTS:SDL2::SDL2>,SDL2::SDL2,SDL2::SDL2-static> + ) find_package(OpenGL REQUIRED) find_package(GLEW REQUIRED) - include_directories(SYSTEM ${GLEW_INCLUDE_DIR} ${SDL2_INCLUDE_DIR}) - set(STAR_EXT_GUI_LIBS ${STAR_EXT_GUI_LIBS} ${OPENGL_LIBRARY} ${GLEW_LIBRARY}) + include_directories(SYSTEM ${GLEW_INCLUDE_DIR}) + set(STAR_EXT_GUI_LIBS ${STAR_EXT_GUI_LIBS} + ${OPENGL_LIBRARY} + GLEW::glew_s + ) + + if(STAR_SYSTEM_MACOS) + set(STAR_EXT_GUI_LIBS ${STAR_EXT_GUI_LIBS} "-framework CoreAudio") + endif() if(STAR_ENABLE_STEAM_INTEGRATION) find_package(SteamApi REQUIRED) - include_directories(SYSTEM ${STEAM_API_INCLUDE_DIR}) set(STAR_EXT_GUI_LIBS ${STAR_EXT_GUI_LIBS} ${STEAM_API_LIBRARY}) endif() if(STAR_ENABLE_DISCORD_INTEGRATION) find_package(DiscordApi REQUIRED) - - include_directories(SYSTEM ${DISCORD_API_INCLUDE_DIR}) set(STAR_EXT_GUI_LIBS ${STAR_EXT_GUI_LIBS} ${DISCORD_API_LIBRARY}) endif() endif() diff --git a/source/CMakePresets.json b/source/CMakePresets.json new file mode 100644 index 0000000..8bdbeea --- /dev/null +++ b/source/CMakePresets.json @@ -0,0 +1,123 @@ +{ + "version": 5, + "cmakeMinimumRequired": { + "major": 3, + "minor": 23, + "patch": 0 + }, + "configurePresets": [ + { + "name": "base", + "hidden": true, + "architecture": { "value": "x64", "strategy": "external" }, + "generator": "Ninja", + "toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", + "cacheVariables": { + "CMAKE_INSTALL_PREFIX": "${sourceParentDir}/install", + "VCPKG_OVERLAY_TRIPLETS": "${sourceParentDir}/triplets", + "CMAKE_VERBOSE_MAKEFILE": true, + "BUILD_TESTING": true, + "STAR_ENABLE_STEAM_INTEGRATION": true, + "STAR_ENABLE_DISCORD_INTEGRATION": true + } + }, + { + "inherits": "base", + "name": "windows-release", + "displayName": "Windows x64", + "binaryDir": "${sourceParentDir}/build/windows-release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "VCPKG_TARGET_TRIPLET": "x64-windows-mixed-md", + "CMAKE_MSVC_RUNTIME_LIBRARY": "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL", + "CMAKE_INCLUDE_PATH": "${sourceParentDir}/lib/windows/include", + "CMAKE_LIBRARY_PATH": "${sourceParentDir}/lib/windows" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ "Windows" ] + } + } + }, + { + "inherits": "base", + "name": "linux-release", + "displayName": "Linux x64", + "binaryDir": "${sourceParentDir}/build/linux-release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "VCPKG_TARGET_TRIPLET": "x64-linux-mixed", + "CMAKE_INCLUDE_PATH": "${sourceParentDir}/lib/linux/include", + "CMAKE_LIBRARY_PATH": "${sourceParentDir}/lib/linux" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ "Linux" ] + } + } + }, + { + "inherits": "base", + "name": "macos-release", + "displayName": "macOS x64", + "binaryDir": "${sourceParentDir}/build/macos-release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "VCPKG_TARGET_TRIPLET": "x64-osx-mixed", + "CMAKE_INCLUDE_PATH": "${sourceParentDir}/lib/osx/include", + "CMAKE_LIBRARY_PATH": "${sourceParentDir}/lib/osx/x64;${sourceParentDir}/lib/osx" + } + }, + { + "inherits": "macos-release", + "name": "macos-arm-release", + "displayName": "macOS ARM", + "binaryDir": "${sourceParentDir}/build/macos-arm-release", + "architecture": { "value": "arm64", "strategy": "external" }, + "cacheVariables": { + "VCPKG_TARGET_TRIPLET": "arm64-osx-mixed", + "CMAKE_LIBRARY_PATH": "${sourceParentDir}/lib/osx/arm64;${sourceParentDir}/lib/osx" + } + } + ], + "buildPresets": [ + { + "name": "windows-release", + "configurePreset": "windows-release" + }, + { + "name": "linux-release", + "configurePreset": "linux-release" + }, + { + "name": "macos-release", + "configurePreset": "macos-release" + }, + { + "name": "macos-arm-release", + "configurePreset": "macos-arm-release" + } + ], + "testPresets": [ + { + "name": "windows-release", + "configurePreset": "windows-release", + "filter": { "include": { "label": "NoAssets" } } + }, + { + "name": "linux-release", + "configurePreset": "linux-release", + "filter": { "include": { "label": "NoAssets" } } + }, + { + "name": "macos-release", + "configurePreset": "macos-release", + "filter": { "include": { "label": "NoAssets" } } + }, + { + "name": "macos-arm-release", + "configurePreset": "macos-arm-release", + "filter": { "include": { "label": "NoAssets" } } + } + ] +}
\ No newline at end of file diff --git a/source/CMakeSettings.json b/source/CMakeSettings.json deleted file mode 100644 index 86e0011..0000000 --- a/source/CMakeSettings.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "configurations": [ - { - "name": "x64-RelWithDebInfo", - "generator": "Ninja", - "configurationType": "RelWithDebInfo", - "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${projectDir}\\..\\build", - "installRoot": "${projectDir}\\..\\out\\install\\${name}", - "cmakeCommandArgs": "-DCMAKE_INCLUDE_PATH=\"..\\lib\\windows\\include\" -DCMAKE_LIBRARY_PATH=\"..\\lib\\windows\"", - "variables": [ - { - "name": "STAR_ENABLE_STEAM_INTEGRATION", - "value": "True", - "type": "BOOL" - }, - { - "name": "STAR_ENABLE_DISCORD_INTEGRATION", - "value": "True", - "type": "BOOL" - } - ] - } - ] -}
\ No newline at end of file diff --git a/source/application/CMakeLists.txt b/source/application/CMakeLists.txt index dbaa236..692f2d5 100644 --- a/source/application/CMakeLists.txt +++ b/source/application/CMakeLists.txt @@ -45,8 +45,6 @@ ENDIF () IF (STAR_ENABLE_DISCORD_INTEGRATION) SET (star_application_SOURCES ${star_application_SOURCES} - discord/activity_manager.cpp - discord/application_manager.cpp discord/core.cpp discord/image_manager.cpp discord/lobby_manager.cpp @@ -57,8 +55,15 @@ IF (STAR_ENABLE_DISCORD_INTEGRATION) discord/store_manager.cpp discord/types.cpp discord/user_manager.cpp + discord/voice_manager.cpp + discord/achievement_manager.cpp + discord/activity_manager.cpp + discord/application_manager.cpp ) ENDIF () ADD_LIBRARY (star_application OBJECT ${star_application_SOURCES} ${star_application_HEADERS}) -TARGET_PRECOMPILE_HEADERS (star_application REUSE_FROM star_core)
\ No newline at end of file + +IF(STAR_PRECOMPILED_HEADERS) + TARGET_PRECOMPILE_HEADERS (star_application REUSE_FROM star_core) +ENDIF()
\ No newline at end of file diff --git a/source/application/StarMainApplication_sdl.cpp b/source/application/StarMainApplication_sdl.cpp index b98da46..2130968 100644 --- a/source/application/StarMainApplication_sdl.cpp +++ b/source/application/StarMainApplication_sdl.cpp @@ -7,7 +7,7 @@ #include "StarImage.hpp" #include "StarImageProcessing.hpp" -#include "SDL.h" +#include "SDL2/SDL.h" #include "StarPlatformServices_pc.hpp" namespace Star { diff --git a/source/application/discord/achievement_manager.cpp b/source/application/discord/achievement_manager.cpp new file mode 100644 index 0000000..43a6d4c --- /dev/null +++ b/source/application/discord/achievement_manager.cpp @@ -0,0 +1,99 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "achievement_manager.h" + +#include "core.h" + +#include <cstring> +#include <memory> + +namespace discord { + +class AchievementEvents final { +public: + static void DISCORD_CALLBACK OnUserAchievementUpdate(void* callbackData, + DiscordUserAchievement* userAchievement) + { + auto* core = reinterpret_cast<Core*>(callbackData); + if (!core) { + return; + } + + auto& module = core->AchievementManager(); + module.OnUserAchievementUpdate(*reinterpret_cast<UserAchievement const*>(userAchievement)); + } +}; + +IDiscordAchievementEvents AchievementManager::events_{ + &AchievementEvents::OnUserAchievementUpdate, +}; + +void AchievementManager::SetUserAchievement(Snowflake achievementId, + std::uint8_t percentComplete, + std::function<void(Result)> callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr<std::function<void(Result)>> cb( + reinterpret_cast<std::function<void(Result)>*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast<Result>(result)); + }; + std::unique_ptr<std::function<void(Result)>> cb{}; + cb.reset(new std::function<void(Result)>(std::move(callback))); + internal_->set_user_achievement( + internal_, achievementId, percentComplete, cb.release(), wrapper); +} + +void AchievementManager::FetchUserAchievements(std::function<void(Result)> callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr<std::function<void(Result)>> cb( + reinterpret_cast<std::function<void(Result)>*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast<Result>(result)); + }; + std::unique_ptr<std::function<void(Result)>> cb{}; + cb.reset(new std::function<void(Result)>(std::move(callback))); + internal_->fetch_user_achievements(internal_, cb.release(), wrapper); +} + +void AchievementManager::CountUserAchievements(std::int32_t* count) +{ + if (!count) { + return; + } + + internal_->count_user_achievements(internal_, reinterpret_cast<int32_t*>(count)); +} + +Result AchievementManager::GetUserAchievement(Snowflake userAchievementId, + UserAchievement* userAchievement) +{ + if (!userAchievement) { + return Result::InternalError; + } + + auto result = internal_->get_user_achievement( + internal_, userAchievementId, reinterpret_cast<DiscordUserAchievement*>(userAchievement)); + return static_cast<Result>(result); +} + +Result AchievementManager::GetUserAchievementAt(std::int32_t index, + UserAchievement* userAchievement) +{ + if (!userAchievement) { + return Result::InternalError; + } + + auto result = internal_->get_user_achievement_at( + internal_, index, reinterpret_cast<DiscordUserAchievement*>(userAchievement)); + return static_cast<Result>(result); +} + +} // namespace discord diff --git a/source/application/discord/achievement_manager.h b/source/application/discord/achievement_manager.h new file mode 100644 index 0000000..1f58c8e --- /dev/null +++ b/source/application/discord/achievement_manager.h @@ -0,0 +1,34 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class AchievementManager final { +public: + ~AchievementManager() = default; + + void SetUserAchievement(Snowflake achievementId, + std::uint8_t percentComplete, + std::function<void(Result)> callback); + void FetchUserAchievements(std::function<void(Result)> callback); + void CountUserAchievements(std::int32_t* count); + Result GetUserAchievement(Snowflake userAchievementId, UserAchievement* userAchievement); + Result GetUserAchievementAt(std::int32_t index, UserAchievement* userAchievement); + + Event<UserAchievement const&> OnUserAchievementUpdate; + +private: + friend class Core; + + AchievementManager() = default; + AchievementManager(AchievementManager const& rhs) = delete; + AchievementManager& operator=(AchievementManager const& rhs) = delete; + AchievementManager(AchievementManager&& rhs) = delete; + AchievementManager& operator=(AchievementManager&& rhs) = delete; + + IDiscordAchievementManager* internal_; + static IDiscordAchievementEvents events_; +}; + +} // namespace discord diff --git a/source/application/discord/activity_manager.cpp b/source/application/discord/activity_manager.cpp index b9b6760..3c20074 100644 --- a/source/application/discord/activity_manager.cpp +++ b/source/application/discord/activity_manager.cpp @@ -13,7 +13,7 @@ namespace discord { class ActivityEvents final { public: - static void OnActivityJoin(void* callbackData, char const* secret) + static void DISCORD_CALLBACK OnActivityJoin(void* callbackData, char const* secret) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -24,7 +24,7 @@ public: module.OnActivityJoin(static_cast<const char*>(secret)); } - static void OnActivitySpectate(void* callbackData, char const* secret) + static void DISCORD_CALLBACK OnActivitySpectate(void* callbackData, char const* secret) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -35,7 +35,7 @@ public: module.OnActivitySpectate(static_cast<const char*>(secret)); } - static void OnActivityJoinRequest(void* callbackData, DiscordUser* user) + static void DISCORD_CALLBACK OnActivityJoinRequest(void* callbackData, DiscordUser* user) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -46,10 +46,10 @@ public: module.OnActivityJoinRequest(*reinterpret_cast<User const*>(user)); } - static void OnActivityInvite(void* callbackData, - EDiscordActivityActionType type, - DiscordUser* user, - DiscordActivity* activity) + static void DISCORD_CALLBACK OnActivityInvite(void* callbackData, + EDiscordActivityActionType type, + DiscordUser* user, + DiscordActivity* activity) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { diff --git a/source/application/discord/application_manager.cpp b/source/application/discord/application_manager.cpp index f5a06d3..0e05f3f 100644 --- a/source/application/discord/application_manager.cpp +++ b/source/application/discord/application_manager.cpp @@ -60,4 +60,19 @@ void ApplicationManager::GetOAuth2Token(std::function<void(Result, OAuth2Token c internal_->get_oauth2_token(internal_, cb.release(), wrapper); } +void ApplicationManager::GetTicket(std::function<void(Result, char const*)> callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result, char const* data) -> void { + std::unique_ptr<std::function<void(Result, char const*)>> cb( + reinterpret_cast<std::function<void(Result, char const*)>*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast<Result>(result), static_cast<const char*>(data)); + }; + std::unique_ptr<std::function<void(Result, char const*)>> cb{}; + cb.reset(new std::function<void(Result, char const*)>(std::move(callback))); + internal_->get_ticket(internal_, cb.release(), wrapper); +} + } // namespace discord diff --git a/source/application/discord/application_manager.h b/source/application/discord/application_manager.h index 03b3a8d..ab0e856 100644 --- a/source/application/discord/application_manager.h +++ b/source/application/discord/application_manager.h @@ -12,6 +12,7 @@ public: void GetCurrentLocale(char locale[128]); void GetCurrentBranch(char branch[4096]); void GetOAuth2Token(std::function<void(Result, OAuth2Token const&)> callback); + void GetTicket(std::function<void(Result, char const*)> callback); private: friend class Core; diff --git a/source/application/discord/core.cpp b/source/application/discord/core.cpp index 69a10a1..110c9ef 100644 --- a/source/application/discord/core.cpp +++ b/source/application/discord/core.cpp @@ -29,6 +29,8 @@ Result Core::Create(ClientId clientId, std::uint64_t flags, Core** instance) params.network_events = &NetworkManager::events_; params.overlay_events = &OverlayManager::events_; params.store_events = &StoreManager::events_; + params.voice_events = &VoiceManager::events_; + params.achievement_events = &AchievementManager::events_; auto result = DiscordCreate(DISCORD_VERSION, ¶ms, &((*instance)->internal_)); if (result != DiscordResult_Ok || !(*instance)->internal_) { delete (*instance); @@ -159,4 +161,22 @@ discord::StoreManager& Core::StoreManager() return storeManager_; } +discord::VoiceManager& Core::VoiceManager() +{ + if (!voiceManager_.internal_) { + voiceManager_.internal_ = internal_->get_voice_manager(internal_); + } + + return voiceManager_; +} + +discord::AchievementManager& Core::AchievementManager() +{ + if (!achievementManager_.internal_) { + achievementManager_.internal_ = internal_->get_achievement_manager(internal_); + } + + return achievementManager_; +} + } // namespace discord diff --git a/source/application/discord/core.h b/source/application/discord/core.h index 411e064..8af6fca 100644 --- a/source/application/discord/core.h +++ b/source/application/discord/core.h @@ -11,6 +11,8 @@ #include "overlay_manager.h" #include "storage_manager.h" #include "store_manager.h" +#include "voice_manager.h" +#include "achievement_manager.h" namespace discord { @@ -33,6 +35,8 @@ public: discord::OverlayManager& OverlayManager(); discord::StorageManager& StorageManager(); discord::StoreManager& StoreManager(); + discord::VoiceManager& VoiceManager(); + discord::AchievementManager& AchievementManager(); private: Core() = default; @@ -53,6 +57,8 @@ private: discord::OverlayManager overlayManager_; discord::StorageManager storageManager_; discord::StoreManager storeManager_; + discord::VoiceManager voiceManager_; + discord::AchievementManager achievementManager_; }; } // namespace discord diff --git a/source/application/discord/discord.h b/source/application/discord/discord.h index d604362..c991212 100644 --- a/source/application/discord/discord.h +++ b/source/application/discord/discord.h @@ -12,3 +12,5 @@ #include "overlay_manager.h" #include "storage_manager.h" #include "store_manager.h" +#include "voice_manager.h" +#include "achievement_manager.h" diff --git a/source/application/discord/ffi.h b/source/application/discord/ffi.h index d9835f1..4a21057 100644 --- a/source/application/discord/ffi.h +++ b/source/application/discord/ffi.h @@ -1,6 +1,23 @@ #ifndef _DISCORD_GAME_SDK_H_ #define _DISCORD_GAME_SDK_H_ +#ifdef _WIN32 +#include <Windows.h> +#include <dxgi.h> +#endif + +#ifdef _WIN32 +#ifdef _WIN64 +#define DISCORD_API +#else +#define DISCORD_API __stdcall +#endif +#else +#define DISCORD_API +#endif + +#define DISCORD_CALLBACK DISCORD_API + #ifdef __cplusplus extern "C" { #endif @@ -11,7 +28,7 @@ extern "C" { #include <stdbool.h> #endif -#define DISCORD_VERSION 2 +#define DISCORD_VERSION 3 #define DISCORD_APPLICATION_MANAGER_VERSION 1 #define DISCORD_USER_MANAGER_VERSION 1 #define DISCORD_IMAGE_MANAGER_VERSION 1 @@ -19,41 +36,58 @@ extern "C" { #define DISCORD_RELATIONSHIP_MANAGER_VERSION 1 #define DISCORD_LOBBY_MANAGER_VERSION 1 #define DISCORD_NETWORK_MANAGER_VERSION 1 -#define DISCORD_OVERLAY_MANAGER_VERSION 1 +#define DISCORD_OVERLAY_MANAGER_VERSION 2 #define DISCORD_STORAGE_MANAGER_VERSION 1 #define DISCORD_STORE_MANAGER_VERSION 1 +#define DISCORD_VOICE_MANAGER_VERSION 1 +#define DISCORD_ACHIEVEMENT_MANAGER_VERSION 1 enum EDiscordResult { - DiscordResult_Ok, - DiscordResult_ServiceUnavailable, - DiscordResult_InvalidVersion, - DiscordResult_LockFailed, - DiscordResult_InternalError, - DiscordResult_InvalidPayload, - DiscordResult_InvalidCommand, - DiscordResult_InvalidPermissions, - DiscordResult_NotFetched, - DiscordResult_NotFound, - DiscordResult_Conflict, - DiscordResult_InvalidSecret, - DiscordResult_InvalidJoinSecret, - DiscordResult_NoEligibleActivity, - DiscordResult_InvalidInvite, - DiscordResult_NotAuthenticated, - DiscordResult_InvalidAccessToken, - DiscordResult_ApplicationMismatch, - DiscordResult_InvalidDataUrl, - DiscordResult_InvalidBase64, - DiscordResult_NotFiltered, - DiscordResult_LobbyFull, - DiscordResult_InvalidLobbySecret, - DiscordResult_InvalidFilename, - DiscordResult_InvalidFileSize, - DiscordResult_InvalidEntitlement, - DiscordResult_NotInstalled, - DiscordResult_NotRunning, - DiscordResult_InsufficientBuffer, - DiscordResult_PurchaseCanceled, + DiscordResult_Ok = 0, + DiscordResult_ServiceUnavailable = 1, + DiscordResult_InvalidVersion = 2, + DiscordResult_LockFailed = 3, + DiscordResult_InternalError = 4, + DiscordResult_InvalidPayload = 5, + DiscordResult_InvalidCommand = 6, + DiscordResult_InvalidPermissions = 7, + DiscordResult_NotFetched = 8, + DiscordResult_NotFound = 9, + DiscordResult_Conflict = 10, + DiscordResult_InvalidSecret = 11, + DiscordResult_InvalidJoinSecret = 12, + DiscordResult_NoEligibleActivity = 13, + DiscordResult_InvalidInvite = 14, + DiscordResult_NotAuthenticated = 15, + DiscordResult_InvalidAccessToken = 16, + DiscordResult_ApplicationMismatch = 17, + DiscordResult_InvalidDataUrl = 18, + DiscordResult_InvalidBase64 = 19, + DiscordResult_NotFiltered = 20, + DiscordResult_LobbyFull = 21, + DiscordResult_InvalidLobbySecret = 22, + DiscordResult_InvalidFilename = 23, + DiscordResult_InvalidFileSize = 24, + DiscordResult_InvalidEntitlement = 25, + DiscordResult_NotInstalled = 26, + DiscordResult_NotRunning = 27, + DiscordResult_InsufficientBuffer = 28, + DiscordResult_PurchaseCanceled = 29, + DiscordResult_InvalidGuild = 30, + DiscordResult_InvalidEvent = 31, + DiscordResult_InvalidChannel = 32, + DiscordResult_InvalidOrigin = 33, + DiscordResult_RateLimited = 34, + DiscordResult_OAuth2Error = 35, + DiscordResult_SelectChannelTimeout = 36, + DiscordResult_GetGuildTimeout = 37, + DiscordResult_SelectVoiceForceRequired = 38, + DiscordResult_CaptureShortcutAlreadyListening = 39, + DiscordResult_UnauthorizedForAchievement = 40, + DiscordResult_InvalidGiftCode = 41, + DiscordResult_PurchaseError = 42, + DiscordResult_TransactionAborted = 43, + DiscordResult_DrawingInitFailed = 44, }; enum EDiscordCreateFlags { @@ -68,10 +102,29 @@ enum EDiscordLogLevel { DiscordLogLevel_Debug, }; +enum EDiscordUserFlag { + DiscordUserFlag_Partner = 2, + DiscordUserFlag_HypeSquadEvents = 4, + DiscordUserFlag_HypeSquadHouse1 = 64, + DiscordUserFlag_HypeSquadHouse2 = 128, + DiscordUserFlag_HypeSquadHouse3 = 256, +}; + +enum EDiscordPremiumType { + DiscordPremiumType_None = 0, + DiscordPremiumType_Tier1 = 1, + DiscordPremiumType_Tier2 = 2, +}; + enum EDiscordImageType { DiscordImageType_User, }; +enum EDiscordActivityPartyPrivacy { + DiscordActivityPartyPrivacy_Private = 0, + DiscordActivityPartyPrivacy_Public = 1, +}; + enum EDiscordActivityType { DiscordActivityType_Playing, DiscordActivityType_Streaming, @@ -84,6 +137,12 @@ enum EDiscordActivityActionType { DiscordActivityActionType_Spectate, }; +enum EDiscordActivitySupportedPlatformFlags { + DiscordActivitySupportedPlatformFlags_Desktop = 1, + DiscordActivitySupportedPlatformFlags_Android = 2, + DiscordActivitySupportedPlatformFlags_iOS = 4, +}; + enum EDiscordActivityJoinRequestReply { DiscordActivityJoinRequestReply_No, DiscordActivityJoinRequestReply_Yes, @@ -132,10 +191,26 @@ enum EDiscordLobbySearchDistance { DiscordLobbySearchDistance_Global, }; +enum EDiscordKeyVariant { + DiscordKeyVariant_Normal, + DiscordKeyVariant_Right, + DiscordKeyVariant_Left, +}; + +enum EDiscordMouseButton { + DiscordMouseButton_Left, + DiscordMouseButton_Middle, + DiscordMouseButton_Right, +}; + enum EDiscordEntitlementType { DiscordEntitlementType_Purchase = 1, DiscordEntitlementType_PremiumSubscription, DiscordEntitlementType_DeveloperGift, + DiscordEntitlementType_TestModePurchase, + DiscordEntitlementType_FreePurchase, + DiscordEntitlementType_UserGift, + DiscordEntitlementType_PremiumPurchase, }; enum EDiscordSkuType { @@ -145,6 +220,11 @@ enum EDiscordSkuType { DiscordSkuType_Bundle, }; +enum EDiscordInputModeType { + DiscordInputModeType_VoiceActivity = 0, + DiscordInputModeType_PushToTalk, +}; + typedef int64_t DiscordClientId; typedef int32_t DiscordVersion; typedef int64_t DiscordSnowflake; @@ -158,6 +238,20 @@ typedef char DiscordMetadataKey[256]; typedef char DiscordMetadataValue[4096]; typedef uint64_t DiscordNetworkPeerId; typedef uint8_t DiscordNetworkChannelId; +#ifdef __APPLE__ +typedef void IDXGISwapChain; +#endif +#ifdef __linux__ +typedef void IDXGISwapChain; +#endif +#ifdef __APPLE__ +typedef void MSG; +#endif +#ifdef __linux__ +typedef void MSG; +#endif +typedef char DiscordPath[4096]; +typedef char DiscordDateTime[64]; struct DiscordUser { DiscordUserId id; @@ -204,6 +298,7 @@ struct DiscordPartySize { struct DiscordActivityParty { char id[128]; struct DiscordPartySize size; + enum EDiscordActivityPartyPrivacy privacy; }; struct DiscordActivitySecrets { @@ -223,6 +318,7 @@ struct DiscordActivity { struct DiscordActivityParty party; struct DiscordActivitySecrets secrets; bool instance; + uint32_t supported_platforms; }; struct DiscordPresence { @@ -245,6 +341,21 @@ struct DiscordLobby { bool locked; }; +struct DiscordImeUnderline { + int32_t from; + int32_t to; + uint32_t color; + uint32_t background_color; + bool thick; +}; + +struct DiscordRect { + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +}; + struct DiscordFileStat { char filename[260]; uint64_t size; @@ -269,466 +380,672 @@ struct DiscordSku { struct DiscordSkuPrice price; }; +struct DiscordInputMode { + enum EDiscordInputModeType type; + char shortcut[256]; +}; + +struct DiscordUserAchievement { + DiscordSnowflake user_id; + DiscordSnowflake achievement_id; + uint8_t percent_complete; + DiscordDateTime unlocked_at; +}; + struct IDiscordLobbyTransaction { - enum EDiscordResult (*set_type)(struct IDiscordLobbyTransaction* lobby_transaction, - enum EDiscordLobbyType type); - enum EDiscordResult (*set_owner)(struct IDiscordLobbyTransaction* lobby_transaction, - DiscordUserId owner_id); - enum EDiscordResult (*set_capacity)(struct IDiscordLobbyTransaction* lobby_transaction, - uint32_t capacity); - enum EDiscordResult (*set_metadata)(struct IDiscordLobbyTransaction* lobby_transaction, - DiscordMetadataKey key, - DiscordMetadataValue value); - enum EDiscordResult (*delete_metadata)(struct IDiscordLobbyTransaction* lobby_transaction, - DiscordMetadataKey key); - enum EDiscordResult (*set_locked)(struct IDiscordLobbyTransaction* lobby_transaction, - bool locked); + enum EDiscordResult(DISCORD_API* set_type)(struct IDiscordLobbyTransaction* lobby_transaction, + enum EDiscordLobbyType type); + enum EDiscordResult(DISCORD_API* set_owner)(struct IDiscordLobbyTransaction* lobby_transaction, + DiscordUserId owner_id); + enum EDiscordResult(DISCORD_API* set_capacity)( + struct IDiscordLobbyTransaction* lobby_transaction, + uint32_t capacity); + enum EDiscordResult(DISCORD_API* set_metadata)( + struct IDiscordLobbyTransaction* lobby_transaction, + DiscordMetadataKey key, + DiscordMetadataValue value); + enum EDiscordResult(DISCORD_API* delete_metadata)( + struct IDiscordLobbyTransaction* lobby_transaction, + DiscordMetadataKey key); + enum EDiscordResult(DISCORD_API* set_locked)(struct IDiscordLobbyTransaction* lobby_transaction, + bool locked); }; struct IDiscordLobbyMemberTransaction { - enum EDiscordResult (*set_metadata)( + enum EDiscordResult(DISCORD_API* set_metadata)( struct IDiscordLobbyMemberTransaction* lobby_member_transaction, DiscordMetadataKey key, DiscordMetadataValue value); - enum EDiscordResult (*delete_metadata)( + enum EDiscordResult(DISCORD_API* delete_metadata)( struct IDiscordLobbyMemberTransaction* lobby_member_transaction, DiscordMetadataKey key); }; struct IDiscordLobbySearchQuery { - enum EDiscordResult (*filter)(struct IDiscordLobbySearchQuery* lobby_search_query, - DiscordMetadataKey key, - enum EDiscordLobbySearchComparison comparison, - enum EDiscordLobbySearchCast cast, - DiscordMetadataValue value); - enum EDiscordResult (*sort)(struct IDiscordLobbySearchQuery* lobby_search_query, - DiscordMetadataKey key, - enum EDiscordLobbySearchCast cast, - DiscordMetadataValue value); - enum EDiscordResult (*limit)(struct IDiscordLobbySearchQuery* lobby_search_query, - uint32_t limit); - enum EDiscordResult (*distance)(struct IDiscordLobbySearchQuery* lobby_search_query, - enum EDiscordLobbySearchDistance distance); + enum EDiscordResult(DISCORD_API* filter)(struct IDiscordLobbySearchQuery* lobby_search_query, + DiscordMetadataKey key, + enum EDiscordLobbySearchComparison comparison, + enum EDiscordLobbySearchCast cast, + DiscordMetadataValue value); + enum EDiscordResult(DISCORD_API* sort)(struct IDiscordLobbySearchQuery* lobby_search_query, + DiscordMetadataKey key, + enum EDiscordLobbySearchCast cast, + DiscordMetadataValue value); + enum EDiscordResult(DISCORD_API* limit)(struct IDiscordLobbySearchQuery* lobby_search_query, + uint32_t limit); + enum EDiscordResult(DISCORD_API* distance)(struct IDiscordLobbySearchQuery* lobby_search_query, + enum EDiscordLobbySearchDistance distance); }; typedef void* IDiscordApplicationEvents; struct IDiscordApplicationManager { - void (*validate_or_exit)(struct IDiscordApplicationManager* manager, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*get_current_locale)(struct IDiscordApplicationManager* manager, DiscordLocale* locale); - void (*get_current_branch)(struct IDiscordApplicationManager* manager, DiscordBranch* branch); - void (*get_oauth2_token)(struct IDiscordApplicationManager* manager, - void* callback_data, - void (*callback)(void* callback_data, - enum EDiscordResult result, - struct DiscordOAuth2Token* oauth2_token)); + void(DISCORD_API* validate_or_exit)(struct IDiscordApplicationManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* get_current_locale)(struct IDiscordApplicationManager* manager, + DiscordLocale* locale); + void(DISCORD_API* get_current_branch)(struct IDiscordApplicationManager* manager, + DiscordBranch* branch); + void(DISCORD_API* get_oauth2_token)( + struct IDiscordApplicationManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + struct DiscordOAuth2Token* oauth2_token)); + void(DISCORD_API* get_ticket)(struct IDiscordApplicationManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + const char* data)); }; struct IDiscordUserEvents { - void (*on_current_user_update)(void* event_data); + void(DISCORD_API* on_current_user_update)(void* event_data); }; struct IDiscordUserManager { - enum EDiscordResult (*get_current_user)(struct IDiscordUserManager* manager, - struct DiscordUser* current_user); - void (*get_user)(struct IDiscordUserManager* manager, - DiscordUserId user_id, - void* callback_data, - void (*callback)(void* callback_data, - enum EDiscordResult result, - struct DiscordUser* user)); + enum EDiscordResult(DISCORD_API* get_current_user)(struct IDiscordUserManager* manager, + struct DiscordUser* current_user); + void(DISCORD_API* get_user)(struct IDiscordUserManager* manager, + DiscordUserId user_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + struct DiscordUser* user)); + enum EDiscordResult(DISCORD_API* get_current_user_premium_type)( + struct IDiscordUserManager* manager, + enum EDiscordPremiumType* premium_type); + enum EDiscordResult(DISCORD_API* current_user_has_flag)(struct IDiscordUserManager* manager, + enum EDiscordUserFlag flag, + bool* has_flag); }; typedef void* IDiscordImageEvents; struct IDiscordImageManager { - void (*fetch)(struct IDiscordImageManager* manager, - struct DiscordImageHandle handle, - bool refresh, - void* callback_data, - void (*callback)(void* callback_data, - enum EDiscordResult result, - struct DiscordImageHandle handle_result)); - enum EDiscordResult (*get_dimensions)(struct IDiscordImageManager* manager, - struct DiscordImageHandle handle, - struct DiscordImageDimensions* dimensions); - enum EDiscordResult (*get_data)(struct IDiscordImageManager* manager, - struct DiscordImageHandle handle, - uint8_t* data, - uint32_t data_length); + void(DISCORD_API* fetch)(struct IDiscordImageManager* manager, + struct DiscordImageHandle handle, + bool refresh, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + struct DiscordImageHandle handle_result)); + enum EDiscordResult(DISCORD_API* get_dimensions)(struct IDiscordImageManager* manager, + struct DiscordImageHandle handle, + struct DiscordImageDimensions* dimensions); + enum EDiscordResult(DISCORD_API* get_data)(struct IDiscordImageManager* manager, + struct DiscordImageHandle handle, + uint8_t* data, + uint32_t data_length); }; struct IDiscordActivityEvents { - void (*on_activity_join)(void* event_data, const char* secret); - void (*on_activity_spectate)(void* event_data, const char* secret); - void (*on_activity_join_request)(void* event_data, struct DiscordUser* user); - void (*on_activity_invite)(void* event_data, - enum EDiscordActivityActionType type, - struct DiscordUser* user, - struct DiscordActivity* activity); + void(DISCORD_API* on_activity_join)(void* event_data, const char* secret); + void(DISCORD_API* on_activity_spectate)(void* event_data, const char* secret); + void(DISCORD_API* on_activity_join_request)(void* event_data, struct DiscordUser* user); + void(DISCORD_API* on_activity_invite)(void* event_data, + enum EDiscordActivityActionType type, + struct DiscordUser* user, + struct DiscordActivity* activity); }; struct IDiscordActivityManager { - enum EDiscordResult (*register_command)(struct IDiscordActivityManager* manager, - const char* command); - enum EDiscordResult (*register_steam)(struct IDiscordActivityManager* manager, - uint32_t steam_id); - void (*update_activity)(struct IDiscordActivityManager* manager, - struct DiscordActivity* activity, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*clear_activity)(struct IDiscordActivityManager* manager, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*send_request_reply)(struct IDiscordActivityManager* manager, - DiscordUserId user_id, - enum EDiscordActivityJoinRequestReply reply, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*send_invite)(struct IDiscordActivityManager* manager, - DiscordUserId user_id, - enum EDiscordActivityActionType type, - const char* content, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*accept_invite)(struct IDiscordActivityManager* manager, - DiscordUserId user_id, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* register_command)(struct IDiscordActivityManager* manager, + const char* command); + enum EDiscordResult(DISCORD_API* register_steam)(struct IDiscordActivityManager* manager, + uint32_t steam_id); + void(DISCORD_API* update_activity)(struct IDiscordActivityManager* manager, + struct DiscordActivity* activity, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* clear_activity)(struct IDiscordActivityManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* send_request_reply)(struct IDiscordActivityManager* manager, + DiscordUserId user_id, + enum EDiscordActivityJoinRequestReply reply, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* send_invite)(struct IDiscordActivityManager* manager, + DiscordUserId user_id, + enum EDiscordActivityActionType type, + const char* content, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* accept_invite)(struct IDiscordActivityManager* manager, + DiscordUserId user_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); }; struct IDiscordRelationshipEvents { - void (*on_refresh)(void* event_data); - void (*on_relationship_update)(void* event_data, struct DiscordRelationship* relationship); + void(DISCORD_API* on_refresh)(void* event_data); + void(DISCORD_API* on_relationship_update)(void* event_data, + struct DiscordRelationship* relationship); }; struct IDiscordRelationshipManager { - void (*filter)(struct IDiscordRelationshipManager* manager, - void* filter_data, - bool (*filter)(void* filter_data, struct DiscordRelationship* relationship)); - enum EDiscordResult (*count)(struct IDiscordRelationshipManager* manager, int32_t* count); - enum EDiscordResult (*get)(struct IDiscordRelationshipManager* manager, - DiscordUserId user_id, - struct DiscordRelationship* relationship); - enum EDiscordResult (*get_at)(struct IDiscordRelationshipManager* manager, - uint32_t index, - struct DiscordRelationship* relationship); + void(DISCORD_API* filter)(struct IDiscordRelationshipManager* manager, + void* filter_data, + bool(DISCORD_API* filter)(void* filter_data, + struct DiscordRelationship* relationship)); + enum EDiscordResult(DISCORD_API* count)(struct IDiscordRelationshipManager* manager, + int32_t* count); + enum EDiscordResult(DISCORD_API* get)(struct IDiscordRelationshipManager* manager, + DiscordUserId user_id, + struct DiscordRelationship* relationship); + enum EDiscordResult(DISCORD_API* get_at)(struct IDiscordRelationshipManager* manager, + uint32_t index, + struct DiscordRelationship* relationship); }; struct IDiscordLobbyEvents { - void (*on_lobby_update)(void* event_data, int64_t lobby_id); - void (*on_lobby_delete)(void* event_data, int64_t lobby_id, uint32_t reason); - void (*on_member_connect)(void* event_data, int64_t lobby_id, int64_t user_id); - void (*on_member_update)(void* event_data, int64_t lobby_id, int64_t user_id); - void (*on_member_disconnect)(void* event_data, int64_t lobby_id, int64_t user_id); - void (*on_lobby_message)(void* event_data, - int64_t lobby_id, - int64_t user_id, - uint8_t* data, - uint32_t data_length); - void (*on_speaking)(void* event_data, int64_t lobby_id, int64_t user_id, bool speaking); - void (*on_network_message)(void* event_data, - int64_t lobby_id, - int64_t user_id, - uint8_t channel_id, - uint8_t* data, - uint32_t data_length); + void(DISCORD_API* on_lobby_update)(void* event_data, int64_t lobby_id); + void(DISCORD_API* on_lobby_delete)(void* event_data, int64_t lobby_id, uint32_t reason); + void(DISCORD_API* on_member_connect)(void* event_data, int64_t lobby_id, int64_t user_id); + void(DISCORD_API* on_member_update)(void* event_data, int64_t lobby_id, int64_t user_id); + void(DISCORD_API* on_member_disconnect)(void* event_data, int64_t lobby_id, int64_t user_id); + void(DISCORD_API* on_lobby_message)(void* event_data, + int64_t lobby_id, + int64_t user_id, + uint8_t* data, + uint32_t data_length); + void(DISCORD_API* on_speaking)(void* event_data, + int64_t lobby_id, + int64_t user_id, + bool speaking); + void(DISCORD_API* on_network_message)(void* event_data, + int64_t lobby_id, + int64_t user_id, + uint8_t channel_id, + uint8_t* data, + uint32_t data_length); }; struct IDiscordLobbyManager { - enum EDiscordResult (*get_lobby_create_transaction)( + enum EDiscordResult(DISCORD_API* get_lobby_create_transaction)( struct IDiscordLobbyManager* manager, struct IDiscordLobbyTransaction** transaction); - enum EDiscordResult (*get_lobby_update_transaction)( + enum EDiscordResult(DISCORD_API* get_lobby_update_transaction)( struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, struct IDiscordLobbyTransaction** transaction); - enum EDiscordResult (*get_member_update_transaction)( + enum EDiscordResult(DISCORD_API* get_member_update_transaction)( struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, DiscordUserId user_id, struct IDiscordLobbyMemberTransaction** transaction); - void (*create_lobby)(struct IDiscordLobbyManager* manager, - struct IDiscordLobbyTransaction* transaction, - void* callback_data, - void (*callback)(void* callback_data, - enum EDiscordResult result, - struct DiscordLobby* lobby)); - void (*update_lobby)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - struct IDiscordLobbyTransaction* transaction, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*delete_lobby)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*connect_lobby)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - DiscordLobbySecret secret, - void* callback_data, - void (*callback)(void* callback_data, - enum EDiscordResult result, - struct DiscordLobby* lobby)); - void (*connect_lobby_with_activity_secret)(struct IDiscordLobbyManager* manager, - DiscordLobbySecret activity_secret, - void* callback_data, - void (*callback)(void* callback_data, + void(DISCORD_API* create_lobby)(struct IDiscordLobbyManager* manager, + struct IDiscordLobbyTransaction* transaction, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, enum EDiscordResult result, struct DiscordLobby* lobby)); - void (*disconnect_lobby)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - enum EDiscordResult (*get_lobby)(struct IDiscordLobbyManager* manager, + void(DISCORD_API* update_lobby)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + struct IDiscordLobbyTransaction* transaction, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* delete_lobby)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* connect_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, - struct DiscordLobby* lobby); - enum EDiscordResult (*get_lobby_activity_secret)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - DiscordLobbySecret* secret); - enum EDiscordResult (*get_lobby_metadata_value)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - DiscordMetadataKey key, - DiscordMetadataValue* value); - enum EDiscordResult (*get_lobby_metadata_key)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - int32_t index, - DiscordMetadataKey* key); - enum EDiscordResult (*lobby_metadata_count)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - int32_t* count); - enum EDiscordResult (*member_count)(struct IDiscordLobbyManager* manager, + DiscordLobbySecret secret, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + struct DiscordLobby* lobby)); + void(DISCORD_API* connect_lobby_with_activity_secret)( + struct IDiscordLobbyManager* manager, + DiscordLobbySecret activity_secret, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + struct DiscordLobby* lobby)); + void(DISCORD_API* disconnect_lobby)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, - int32_t* count); - enum EDiscordResult (*get_member_user_id)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - int32_t index, - DiscordUserId* user_id); - enum EDiscordResult (*get_member_user)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - DiscordUserId user_id, - struct DiscordUser* user); - enum EDiscordResult (*get_member_metadata_value)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - DiscordUserId user_id, - DiscordMetadataKey key, - DiscordMetadataValue* value); - enum EDiscordResult (*get_member_metadata_key)(struct IDiscordLobbyManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* get_lobby)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + struct DiscordLobby* lobby); + enum EDiscordResult(DISCORD_API* get_lobby_activity_secret)( + struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordLobbySecret* secret); + enum EDiscordResult(DISCORD_API* get_lobby_metadata_value)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordMetadataKey key, + DiscordMetadataValue* value); + enum EDiscordResult(DISCORD_API* get_lobby_metadata_key)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + int32_t index, + DiscordMetadataKey* key); + enum EDiscordResult(DISCORD_API* lobby_metadata_count)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + int32_t* count); + enum EDiscordResult(DISCORD_API* member_count)(struct IDiscordLobbyManager* manager, DiscordLobbyId lobby_id, - DiscordUserId user_id, + int32_t* count); + enum EDiscordResult(DISCORD_API* get_member_user_id)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + int32_t index, + DiscordUserId* user_id); + enum EDiscordResult(DISCORD_API* get_member_user)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + struct DiscordUser* user); + enum EDiscordResult(DISCORD_API* get_member_metadata_value)( + struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + DiscordMetadataKey key, + DiscordMetadataValue* value); + enum EDiscordResult(DISCORD_API* get_member_metadata_key)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + int32_t index, + DiscordMetadataKey* key); + enum EDiscordResult(DISCORD_API* member_metadata_count)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + int32_t* count); + void(DISCORD_API* update_member)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + struct IDiscordLobbyMemberTransaction* transaction, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* send_lobby_message)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + uint8_t* data, + uint32_t data_length, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* get_search_query)(struct IDiscordLobbyManager* manager, + struct IDiscordLobbySearchQuery** query); + void(DISCORD_API* search)(struct IDiscordLobbyManager* manager, + struct IDiscordLobbySearchQuery* query, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* lobby_count)(struct IDiscordLobbyManager* manager, int32_t* count); + enum EDiscordResult(DISCORD_API* get_lobby_id)(struct IDiscordLobbyManager* manager, int32_t index, - DiscordMetadataKey* key); - enum EDiscordResult (*member_metadata_count)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - DiscordUserId user_id, - int32_t* count); - void (*update_member)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - DiscordUserId user_id, - struct IDiscordLobbyMemberTransaction* transaction, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*send_lobby_message)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - uint8_t* data, - uint32_t data_length, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - enum EDiscordResult (*get_search_query)(struct IDiscordLobbyManager* manager, - struct IDiscordLobbySearchQuery** query); - void (*search)(struct IDiscordLobbyManager* manager, - struct IDiscordLobbySearchQuery* query, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*lobby_count)(struct IDiscordLobbyManager* manager, int32_t* count); - enum EDiscordResult (*get_lobby_id)(struct IDiscordLobbyManager* manager, - int32_t index, - DiscordLobbyId* lobby_id); - void (*connect_voice)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*disconnect_voice)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - enum EDiscordResult (*connect_network)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id); - enum EDiscordResult (*disconnect_network)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id); - enum EDiscordResult (*flush_network)(struct IDiscordLobbyManager* manager); - enum EDiscordResult (*open_network_channel)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - uint8_t channel_id, - bool reliable); - enum EDiscordResult (*send_network_message)(struct IDiscordLobbyManager* manager, - DiscordLobbyId lobby_id, - DiscordUserId user_id, - uint8_t channel_id, - uint8_t* data, - uint32_t data_length); + DiscordLobbyId* lobby_id); + void(DISCORD_API* connect_voice)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* disconnect_voice)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* connect_network)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id); + enum EDiscordResult(DISCORD_API* disconnect_network)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id); + enum EDiscordResult(DISCORD_API* flush_network)(struct IDiscordLobbyManager* manager); + enum EDiscordResult(DISCORD_API* open_network_channel)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + uint8_t channel_id, + bool reliable); + enum EDiscordResult(DISCORD_API* send_network_message)(struct IDiscordLobbyManager* manager, + DiscordLobbyId lobby_id, + DiscordUserId user_id, + uint8_t channel_id, + uint8_t* data, + uint32_t data_length); }; struct IDiscordNetworkEvents { - void (*on_message)(void* event_data, - DiscordNetworkPeerId peer_id, - DiscordNetworkChannelId channel_id, - uint8_t* data, - uint32_t data_length); - void (*on_route_update)(void* event_data, const char* route_data); + void(DISCORD_API* on_message)(void* event_data, + DiscordNetworkPeerId peer_id, + DiscordNetworkChannelId channel_id, + uint8_t* data, + uint32_t data_length); + void(DISCORD_API* on_route_update)(void* event_data, const char* route_data); }; struct IDiscordNetworkManager { - void (*get_peer_id)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId* peer_id); - enum EDiscordResult (*flush)(struct IDiscordNetworkManager* manager); - enum EDiscordResult (*open_peer)(struct IDiscordNetworkManager* manager, - DiscordNetworkPeerId peer_id, - const char* route_data); - enum EDiscordResult (*update_peer)(struct IDiscordNetworkManager* manager, - DiscordNetworkPeerId peer_id, - const char* route_data); - enum EDiscordResult (*close_peer)(struct IDiscordNetworkManager* manager, - DiscordNetworkPeerId peer_id); - enum EDiscordResult (*open_channel)(struct IDiscordNetworkManager* manager, - DiscordNetworkPeerId peer_id, - DiscordNetworkChannelId channel_id, - bool reliable); - enum EDiscordResult (*close_channel)(struct IDiscordNetworkManager* manager, - DiscordNetworkPeerId peer_id, - DiscordNetworkChannelId channel_id); - enum EDiscordResult (*send_message)(struct IDiscordNetworkManager* manager, - DiscordNetworkPeerId peer_id, - DiscordNetworkChannelId channel_id, - uint8_t* data, - uint32_t data_length); + /** + * Get the local peer ID for this process. + */ + void(DISCORD_API* get_peer_id)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId* peer_id); + /** + * Send pending network messages. + */ + enum EDiscordResult(DISCORD_API* flush)(struct IDiscordNetworkManager* manager); + /** + * Open a connection to a remote peer. + */ + enum EDiscordResult(DISCORD_API* open_peer)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId peer_id, + const char* route_data); + /** + * Update the route data for a connected peer. + */ + enum EDiscordResult(DISCORD_API* update_peer)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId peer_id, + const char* route_data); + /** + * Close the connection to a remote peer. + */ + enum EDiscordResult(DISCORD_API* close_peer)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId peer_id); + /** + * Open a message channel to a connected peer. + */ + enum EDiscordResult(DISCORD_API* open_channel)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId peer_id, + DiscordNetworkChannelId channel_id, + bool reliable); + /** + * Close a message channel to a connected peer. + */ + enum EDiscordResult(DISCORD_API* close_channel)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId peer_id, + DiscordNetworkChannelId channel_id); + /** + * Send a message to a connected peer over an opened message channel. + */ + enum EDiscordResult(DISCORD_API* send_message)(struct IDiscordNetworkManager* manager, + DiscordNetworkPeerId peer_id, + DiscordNetworkChannelId channel_id, + uint8_t* data, + uint32_t data_length); }; struct IDiscordOverlayEvents { - void (*on_toggle)(void* event_data, bool locked); + void(DISCORD_API* on_toggle)(void* event_data, bool locked); }; struct IDiscordOverlayManager { - void (*is_enabled)(struct IDiscordOverlayManager* manager, bool* enabled); - void (*is_locked)(struct IDiscordOverlayManager* manager, bool* locked); - void (*set_locked)(struct IDiscordOverlayManager* manager, - bool locked, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*open_activity_invite)(struct IDiscordOverlayManager* manager, - enum EDiscordActivityActionType type, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*open_guild_invite)(struct IDiscordOverlayManager* manager, - const char* code, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); + void(DISCORD_API* is_enabled)(struct IDiscordOverlayManager* manager, bool* enabled); + void(DISCORD_API* is_locked)(struct IDiscordOverlayManager* manager, bool* locked); + void(DISCORD_API* set_locked)(struct IDiscordOverlayManager* manager, + bool locked, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* open_activity_invite)( + struct IDiscordOverlayManager* manager, + enum EDiscordActivityActionType type, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, enum EDiscordResult result)); + void(DISCORD_API* open_guild_invite)(struct IDiscordOverlayManager* manager, + const char* code, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* open_voice_settings)(struct IDiscordOverlayManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* init_drawing_dxgi)(struct IDiscordOverlayManager* manager, + IDXGISwapChain* swapchain, + bool use_message_forwarding); + void(DISCORD_API* on_present)(struct IDiscordOverlayManager* manager); + void(DISCORD_API* forward_message)(struct IDiscordOverlayManager* manager, MSG* message); + void(DISCORD_API* key_event)(struct IDiscordOverlayManager* manager, + bool down, + const char* key_code, + enum EDiscordKeyVariant variant); + void(DISCORD_API* char_event)(struct IDiscordOverlayManager* manager, const char* character); + void(DISCORD_API* mouse_button_event)(struct IDiscordOverlayManager* manager, + uint8_t down, + int32_t click_count, + enum EDiscordMouseButton which, + int32_t x, + int32_t y); + void(DISCORD_API* mouse_motion_event)(struct IDiscordOverlayManager* manager, + int32_t x, + int32_t y); + void(DISCORD_API* ime_commit_text)(struct IDiscordOverlayManager* manager, const char* text); + void(DISCORD_API* ime_set_composition)(struct IDiscordOverlayManager* manager, + const char* text, + struct DiscordImeUnderline* underlines, + uint32_t underlines_length, + int32_t from, + int32_t to); + void(DISCORD_API* ime_cancel_composition)(struct IDiscordOverlayManager* manager); + void(DISCORD_API* set_ime_composition_range_callback)( + struct IDiscordOverlayManager* manager, + void* on_ime_composition_range_changed_data, + void(DISCORD_API* on_ime_composition_range_changed)( + void* on_ime_composition_range_changed_data, + int32_t from, + int32_t to, + struct DiscordRect* bounds, + uint32_t bounds_length)); + void(DISCORD_API* set_ime_selection_bounds_callback)( + struct IDiscordOverlayManager* manager, + void* on_ime_selection_bounds_changed_data, + void(DISCORD_API* on_ime_selection_bounds_changed)(void* on_ime_selection_bounds_changed_data, + struct DiscordRect anchor, + struct DiscordRect focus, + bool is_anchor_first)); + bool(DISCORD_API* is_point_inside_click_zone)(struct IDiscordOverlayManager* manager, + int32_t x, + int32_t y); }; typedef void* IDiscordStorageEvents; struct IDiscordStorageManager { - enum EDiscordResult (*read)(struct IDiscordStorageManager* manager, - const char* name, - uint8_t* data, - uint32_t data_length, - uint32_t* read); - void (*read_async)(struct IDiscordStorageManager* manager, - const char* name, - void* callback_data, - void (*callback)(void* callback_data, - enum EDiscordResult result, - uint8_t* data, - uint32_t data_length)); - void (*read_async_partial)(struct IDiscordStorageManager* manager, - const char* name, - uint64_t offset, - uint64_t length, - void* callback_data, - void (*callback)(void* callback_data, - enum EDiscordResult result, - uint8_t* data, - uint32_t data_length)); - enum EDiscordResult (*write)(struct IDiscordStorageManager* manager, - const char* name, - uint8_t* data, - uint32_t data_length); - void (*write_async)(struct IDiscordStorageManager* manager, - const char* name, - uint8_t* data, - uint32_t data_length, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - enum EDiscordResult (*delete_)(struct IDiscordStorageManager* manager, const char* name); - enum EDiscordResult (*exists)(struct IDiscordStorageManager* manager, + enum EDiscordResult(DISCORD_API* read)(struct IDiscordStorageManager* manager, + const char* name, + uint8_t* data, + uint32_t data_length, + uint32_t* read); + void(DISCORD_API* read_async)(struct IDiscordStorageManager* manager, const char* name, - bool* exists); - void (*count)(struct IDiscordStorageManager* manager, int32_t* count); - enum EDiscordResult (*stat)(struct IDiscordStorageManager* manager, - const char* name, - struct DiscordFileStat* stat); - enum EDiscordResult (*stat_at)(struct IDiscordStorageManager* manager, - int32_t index, - struct DiscordFileStat* stat); + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + uint8_t* data, + uint32_t data_length)); + void(DISCORD_API* read_async_partial)(struct IDiscordStorageManager* manager, + const char* name, + uint64_t offset, + uint64_t length, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result, + uint8_t* data, + uint32_t data_length)); + enum EDiscordResult(DISCORD_API* write)(struct IDiscordStorageManager* manager, + const char* name, + uint8_t* data, + uint32_t data_length); + void(DISCORD_API* write_async)(struct IDiscordStorageManager* manager, + const char* name, + uint8_t* data, + uint32_t data_length, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* delete_)(struct IDiscordStorageManager* manager, + const char* name); + enum EDiscordResult(DISCORD_API* exists)(struct IDiscordStorageManager* manager, + const char* name, + bool* exists); + void(DISCORD_API* count)(struct IDiscordStorageManager* manager, int32_t* count); + enum EDiscordResult(DISCORD_API* stat)(struct IDiscordStorageManager* manager, + const char* name, + struct DiscordFileStat* stat); + enum EDiscordResult(DISCORD_API* stat_at)(struct IDiscordStorageManager* manager, + int32_t index, + struct DiscordFileStat* stat); + enum EDiscordResult(DISCORD_API* get_path)(struct IDiscordStorageManager* manager, + DiscordPath* path); }; struct IDiscordStoreEvents { - void (*on_entitlement_create)(void* event_data, struct DiscordEntitlement* entitlement); - void (*on_entitlement_delete)(void* event_data, struct DiscordEntitlement* entitlement); + void(DISCORD_API* on_entitlement_create)(void* event_data, + struct DiscordEntitlement* entitlement); + void(DISCORD_API* on_entitlement_delete)(void* event_data, + struct DiscordEntitlement* entitlement); }; struct IDiscordStoreManager { - void (*fetch_skus)(struct IDiscordStoreManager* manager, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*count_skus)(struct IDiscordStoreManager* manager, int32_t* count); - enum EDiscordResult (*get_sku)(struct IDiscordStoreManager* manager, - DiscordSnowflake sku_id, - struct DiscordSku* sku); - enum EDiscordResult (*get_sku_at)(struct IDiscordStoreManager* manager, - int32_t index, - struct DiscordSku* sku); - void (*fetch_entitlements)(struct IDiscordStoreManager* manager, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); - void (*count_entitlements)(struct IDiscordStoreManager* manager, int32_t* count); - enum EDiscordResult (*get_entitlement)(struct IDiscordStoreManager* manager, - DiscordSnowflake entitlement_id, - struct DiscordEntitlement* entitlement); - enum EDiscordResult (*get_entitlement_at)(struct IDiscordStoreManager* manager, - int32_t index, - struct DiscordEntitlement* entitlement); - enum EDiscordResult (*has_sku_entitlement)(struct IDiscordStoreManager* manager, - DiscordSnowflake sku_id, - bool* has_entitlement); - void (*start_purchase)(struct IDiscordStoreManager* manager, - DiscordSnowflake sku_id, - void* callback_data, - void (*callback)(void* callback_data, enum EDiscordResult result)); + void(DISCORD_API* fetch_skus)(struct IDiscordStoreManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* count_skus)(struct IDiscordStoreManager* manager, int32_t* count); + enum EDiscordResult(DISCORD_API* get_sku)(struct IDiscordStoreManager* manager, + DiscordSnowflake sku_id, + struct DiscordSku* sku); + enum EDiscordResult(DISCORD_API* get_sku_at)(struct IDiscordStoreManager* manager, + int32_t index, + struct DiscordSku* sku); + void(DISCORD_API* fetch_entitlements)(struct IDiscordStoreManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + void(DISCORD_API* count_entitlements)(struct IDiscordStoreManager* manager, int32_t* count); + enum EDiscordResult(DISCORD_API* get_entitlement)(struct IDiscordStoreManager* manager, + DiscordSnowflake entitlement_id, + struct DiscordEntitlement* entitlement); + enum EDiscordResult(DISCORD_API* get_entitlement_at)(struct IDiscordStoreManager* manager, + int32_t index, + struct DiscordEntitlement* entitlement); + enum EDiscordResult(DISCORD_API* has_sku_entitlement)(struct IDiscordStoreManager* manager, + DiscordSnowflake sku_id, + bool* has_entitlement); + void(DISCORD_API* start_purchase)(struct IDiscordStoreManager* manager, + DiscordSnowflake sku_id, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); +}; + +struct IDiscordVoiceEvents { + void(DISCORD_API* on_settings_update)(void* event_data); +}; + +struct IDiscordVoiceManager { + enum EDiscordResult(DISCORD_API* get_input_mode)(struct IDiscordVoiceManager* manager, + struct DiscordInputMode* input_mode); + void(DISCORD_API* set_input_mode)(struct IDiscordVoiceManager* manager, + struct DiscordInputMode input_mode, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, + enum EDiscordResult result)); + enum EDiscordResult(DISCORD_API* is_self_mute)(struct IDiscordVoiceManager* manager, + bool* mute); + enum EDiscordResult(DISCORD_API* set_self_mute)(struct IDiscordVoiceManager* manager, + bool mute); + enum EDiscordResult(DISCORD_API* is_self_deaf)(struct IDiscordVoiceManager* manager, + bool* deaf); + enum EDiscordResult(DISCORD_API* set_self_deaf)(struct IDiscordVoiceManager* manager, + bool deaf); + enum EDiscordResult(DISCORD_API* is_local_mute)(struct IDiscordVoiceManager* manager, + DiscordSnowflake user_id, + bool* mute); + enum EDiscordResult(DISCORD_API* set_local_mute)(struct IDiscordVoiceManager* manager, + DiscordSnowflake user_id, + bool mute); + enum EDiscordResult(DISCORD_API* get_local_volume)(struct IDiscordVoiceManager* manager, + DiscordSnowflake user_id, + uint8_t* volume); + enum EDiscordResult(DISCORD_API* set_local_volume)(struct IDiscordVoiceManager* manager, + DiscordSnowflake user_id, + uint8_t volume); +}; + +struct IDiscordAchievementEvents { + void(DISCORD_API* on_user_achievement_update)(void* event_data, + struct DiscordUserAchievement* user_achievement); +}; + +struct IDiscordAchievementManager { + void(DISCORD_API* set_user_achievement)( + struct IDiscordAchievementManager* manager, + DiscordSnowflake achievement_id, + uint8_t percent_complete, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, enum EDiscordResult result)); + void(DISCORD_API* fetch_user_achievements)( + struct IDiscordAchievementManager* manager, + void* callback_data, + void(DISCORD_API* callback)(void* callback_data, enum EDiscordResult result)); + void(DISCORD_API* count_user_achievements)(struct IDiscordAchievementManager* manager, + int32_t* count); + enum EDiscordResult(DISCORD_API* get_user_achievement)( + struct IDiscordAchievementManager* manager, + DiscordSnowflake user_achievement_id, + struct DiscordUserAchievement* user_achievement); + enum EDiscordResult(DISCORD_API* get_user_achievement_at)( + struct IDiscordAchievementManager* manager, + int32_t index, + struct DiscordUserAchievement* user_achievement); }; typedef void* IDiscordCoreEvents; struct IDiscordCore { - void (*destroy)(struct IDiscordCore* core); - enum EDiscordResult (*run_callbacks)(struct IDiscordCore* core); - void (*set_log_hook)(struct IDiscordCore* core, - enum EDiscordLogLevel min_level, - void* hook_data, - void (*hook)(void* hook_data, - enum EDiscordLogLevel level, - const char* message)); - struct IDiscordApplicationManager* (*get_application_manager)(struct IDiscordCore* core); - struct IDiscordUserManager* (*get_user_manager)(struct IDiscordCore* core); - struct IDiscordImageManager* (*get_image_manager)(struct IDiscordCore* core); - struct IDiscordActivityManager* (*get_activity_manager)(struct IDiscordCore* core); - struct IDiscordRelationshipManager* (*get_relationship_manager)(struct IDiscordCore* core); - struct IDiscordLobbyManager* (*get_lobby_manager)(struct IDiscordCore* core); - struct IDiscordNetworkManager* (*get_network_manager)(struct IDiscordCore* core); - struct IDiscordOverlayManager* (*get_overlay_manager)(struct IDiscordCore* core); - struct IDiscordStorageManager* (*get_storage_manager)(struct IDiscordCore* core); - struct IDiscordStoreManager* (*get_store_manager)(struct IDiscordCore* core); + void(DISCORD_API* destroy)(struct IDiscordCore* core); + enum EDiscordResult(DISCORD_API* run_callbacks)(struct IDiscordCore* core); + void(DISCORD_API* set_log_hook)(struct IDiscordCore* core, + enum EDiscordLogLevel min_level, + void* hook_data, + void(DISCORD_API* hook)(void* hook_data, + enum EDiscordLogLevel level, + const char* message)); + struct IDiscordApplicationManager*(DISCORD_API* get_application_manager)( + struct IDiscordCore* core); + struct IDiscordUserManager*(DISCORD_API* get_user_manager)(struct IDiscordCore* core); + struct IDiscordImageManager*(DISCORD_API* get_image_manager)(struct IDiscordCore* core); + struct IDiscordActivityManager*(DISCORD_API* get_activity_manager)(struct IDiscordCore* core); + struct IDiscordRelationshipManager*(DISCORD_API* get_relationship_manager)( + struct IDiscordCore* core); + struct IDiscordLobbyManager*(DISCORD_API* get_lobby_manager)(struct IDiscordCore* core); + struct IDiscordNetworkManager*(DISCORD_API* get_network_manager)(struct IDiscordCore* core); + struct IDiscordOverlayManager*(DISCORD_API* get_overlay_manager)(struct IDiscordCore* core); + struct IDiscordStorageManager*(DISCORD_API* get_storage_manager)(struct IDiscordCore* core); + struct IDiscordStoreManager*(DISCORD_API* get_store_manager)(struct IDiscordCore* core); + struct IDiscordVoiceManager*(DISCORD_API* get_voice_manager)(struct IDiscordCore* core); + struct IDiscordAchievementManager*(DISCORD_API* get_achievement_manager)( + struct IDiscordCore* core); }; struct DiscordCreateParams { @@ -756,6 +1073,10 @@ struct DiscordCreateParams { DiscordVersion storage_version; struct IDiscordStoreEvents* store_events; DiscordVersion store_version; + struct IDiscordVoiceEvents* voice_events; + DiscordVersion voice_version; + struct IDiscordAchievementEvents* achievement_events; + DiscordVersion achievement_version; }; #ifdef __cplusplus @@ -777,14 +1098,16 @@ static params->overlay_version = DISCORD_OVERLAY_MANAGER_VERSION; params->storage_version = DISCORD_STORAGE_MANAGER_VERSION; params->store_version = DISCORD_STORE_MANAGER_VERSION; + params->voice_version = DISCORD_VOICE_MANAGER_VERSION; + params->achievement_version = DISCORD_ACHIEVEMENT_MANAGER_VERSION; } -enum EDiscordResult DiscordCreate(DiscordVersion version, - struct DiscordCreateParams* params, - struct IDiscordCore** result); +enum EDiscordResult DISCORD_API DiscordCreate(DiscordVersion version, + struct DiscordCreateParams* params, + struct IDiscordCore** result); #ifdef __cplusplus } #endif -#endif
\ No newline at end of file +#endif diff --git a/source/application/discord/lobby_manager.cpp b/source/application/discord/lobby_manager.cpp index 6bf1a1a..3a95b1a 100644 --- a/source/application/discord/lobby_manager.cpp +++ b/source/application/discord/lobby_manager.cpp @@ -13,7 +13,7 @@ namespace discord { class LobbyEvents final { public: - static void OnLobbyUpdate(void* callbackData, int64_t lobbyId) + static void DISCORD_CALLBACK OnLobbyUpdate(void* callbackData, int64_t lobbyId) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -24,7 +24,7 @@ public: module.OnLobbyUpdate(lobbyId); } - static void OnLobbyDelete(void* callbackData, int64_t lobbyId, uint32_t reason) + static void DISCORD_CALLBACK OnLobbyDelete(void* callbackData, int64_t lobbyId, uint32_t reason) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -35,7 +35,9 @@ public: module.OnLobbyDelete(lobbyId, reason); } - static void OnMemberConnect(void* callbackData, int64_t lobbyId, int64_t userId) + static void DISCORD_CALLBACK OnMemberConnect(void* callbackData, + int64_t lobbyId, + int64_t userId) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -46,7 +48,7 @@ public: module.OnMemberConnect(lobbyId, userId); } - static void OnMemberUpdate(void* callbackData, int64_t lobbyId, int64_t userId) + static void DISCORD_CALLBACK OnMemberUpdate(void* callbackData, int64_t lobbyId, int64_t userId) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -57,7 +59,9 @@ public: module.OnMemberUpdate(lobbyId, userId); } - static void OnMemberDisconnect(void* callbackData, int64_t lobbyId, int64_t userId) + static void DISCORD_CALLBACK OnMemberDisconnect(void* callbackData, + int64_t lobbyId, + int64_t userId) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -68,11 +72,11 @@ public: module.OnMemberDisconnect(lobbyId, userId); } - static void OnLobbyMessage(void* callbackData, - int64_t lobbyId, - int64_t userId, - uint8_t* data, - uint32_t dataLength) + static void DISCORD_CALLBACK OnLobbyMessage(void* callbackData, + int64_t lobbyId, + int64_t userId, + uint8_t* data, + uint32_t dataLength) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -83,7 +87,10 @@ public: module.OnLobbyMessage(lobbyId, userId, data, dataLength); } - static void OnSpeaking(void* callbackData, int64_t lobbyId, int64_t userId, bool speaking) + static void DISCORD_CALLBACK OnSpeaking(void* callbackData, + int64_t lobbyId, + int64_t userId, + bool speaking) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -94,12 +101,12 @@ public: module.OnSpeaking(lobbyId, userId, (speaking != 0)); } - static void OnNetworkMessage(void* callbackData, - int64_t lobbyId, - int64_t userId, - uint8_t channelId, - uint8_t* data, - uint32_t dataLength) + static void DISCORD_CALLBACK OnNetworkMessage(void* callbackData, + int64_t lobbyId, + int64_t userId, + uint8_t channelId, + uint8_t* data, + uint32_t dataLength) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { diff --git a/source/application/discord/network_manager.cpp b/source/application/discord/network_manager.cpp index 97c219e..36031b3 100644 --- a/source/application/discord/network_manager.cpp +++ b/source/application/discord/network_manager.cpp @@ -13,11 +13,11 @@ namespace discord { class NetworkEvents final { public: - static void OnMessage(void* callbackData, - DiscordNetworkPeerId peerId, - DiscordNetworkChannelId channelId, - uint8_t* data, - uint32_t dataLength) + static void DISCORD_CALLBACK OnMessage(void* callbackData, + DiscordNetworkPeerId peerId, + DiscordNetworkChannelId channelId, + uint8_t* data, + uint32_t dataLength) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -28,7 +28,7 @@ public: module.OnMessage(peerId, channelId, data, dataLength); } - static void OnRouteUpdate(void* callbackData, char const* routeData) + static void DISCORD_CALLBACK OnRouteUpdate(void* callbackData, char const* routeData) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { diff --git a/source/application/discord/network_manager.h b/source/application/discord/network_manager.h index 09c9735..e374670 100644 --- a/source/application/discord/network_manager.h +++ b/source/application/discord/network_manager.h @@ -8,13 +8,37 @@ class NetworkManager final { public: ~NetworkManager() = default; + /** + * Get the local peer ID for this process. + */ void GetPeerId(NetworkPeerId* peerId); + /** + * Send pending network messages. + */ Result Flush(); + /** + * Open a connection to a remote peer. + */ Result OpenPeer(NetworkPeerId peerId, char const* routeData); + /** + * Update the route data for a connected peer. + */ Result UpdatePeer(NetworkPeerId peerId, char const* routeData); + /** + * Close the connection to a remote peer. + */ Result ClosePeer(NetworkPeerId peerId); + /** + * Open a message channel to a connected peer. + */ Result OpenChannel(NetworkPeerId peerId, NetworkChannelId channelId, bool reliable); + /** + * Close a message channel to a connected peer. + */ Result CloseChannel(NetworkPeerId peerId, NetworkChannelId channelId); + /** + * Send a message to a connected peer over an opened message channel. + */ Result SendMessage(NetworkPeerId peerId, NetworkChannelId channelId, std::uint8_t* data, diff --git a/source/application/discord/overlay_manager.cpp b/source/application/discord/overlay_manager.cpp index 51ee827..f4b1fba 100644 --- a/source/application/discord/overlay_manager.cpp +++ b/source/application/discord/overlay_manager.cpp @@ -13,7 +13,7 @@ namespace discord { class OverlayEvents final { public: - static void OnToggle(void* callbackData, bool locked) + static void DISCORD_CALLBACK OnToggle(void* callbackData, bool locked) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -94,4 +94,136 @@ void OverlayManager::OpenGuildInvite(char const* code, std::function<void(Result internal_->open_guild_invite(internal_, const_cast<char*>(code), cb.release(), wrapper); } +void OverlayManager::OpenVoiceSettings(std::function<void(Result)> callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr<std::function<void(Result)>> cb( + reinterpret_cast<std::function<void(Result)>*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast<Result>(result)); + }; + std::unique_ptr<std::function<void(Result)>> cb{}; + cb.reset(new std::function<void(Result)>(std::move(callback))); + internal_->open_voice_settings(internal_, cb.release(), wrapper); +} + +Result OverlayManager::InitDrawingDxgi(IDXGISwapChain* swapchain, bool useMessageForwarding) +{ + auto result = + internal_->init_drawing_dxgi(internal_, swapchain, (useMessageForwarding ? 1 : 0)); + return static_cast<Result>(result); +} + +void OverlayManager::OnPresent() +{ + internal_->on_present(internal_); +} + +void OverlayManager::ForwardMessage(MSG* message) +{ + internal_->forward_message(internal_, message); +} + +void OverlayManager::KeyEvent(bool down, char const* keyCode, KeyVariant variant) +{ + internal_->key_event(internal_, + (down ? 1 : 0), + const_cast<char*>(keyCode), + static_cast<EDiscordKeyVariant>(variant)); +} + +void OverlayManager::CharEvent(char const* character) +{ + internal_->char_event(internal_, const_cast<char*>(character)); +} + +void OverlayManager::MouseButtonEvent(std::uint8_t down, + std::int32_t clickCount, + MouseButton which, + std::int32_t x, + std::int32_t y) +{ + internal_->mouse_button_event( + internal_, down, clickCount, static_cast<EDiscordMouseButton>(which), x, y); +} + +void OverlayManager::MouseMotionEvent(std::int32_t x, std::int32_t y) +{ + internal_->mouse_motion_event(internal_, x, y); +} + +void OverlayManager::ImeCommitText(char const* text) +{ + internal_->ime_commit_text(internal_, const_cast<char*>(text)); +} + +void OverlayManager::ImeSetComposition(char const* text, + ImeUnderline* underlines, + std::uint32_t underlinesLength, + std::int32_t from, + std::int32_t to) +{ + internal_->ime_set_composition(internal_, + const_cast<char*>(text), + reinterpret_cast<DiscordImeUnderline*>(underlines), + underlinesLength, + from, + to); +} + +void OverlayManager::ImeCancelComposition() +{ + internal_->ime_cancel_composition(internal_); +} + +void OverlayManager::SetImeCompositionRangeCallback( + std::function<void(std::int32_t, std::int32_t, Rect*, std::uint32_t)> + onImeCompositionRangeChanged) +{ + static auto wrapper = [](void* callbackData, + int32_t from, + int32_t to, + DiscordRect* bounds, + uint32_t boundsLength) -> void { + std::unique_ptr<std::function<void(std::int32_t, std::int32_t, Rect*, std::uint32_t)>> cb( + reinterpret_cast<std::function<void(std::int32_t, std::int32_t, Rect*, std::uint32_t)>*>( + callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(from, to, reinterpret_cast<Rect*>(bounds), boundsLength); + }; + std::unique_ptr<std::function<void(std::int32_t, std::int32_t, Rect*, std::uint32_t)>> cb{}; + cb.reset(new std::function<void(std::int32_t, std::int32_t, Rect*, std::uint32_t)>( + std::move(onImeCompositionRangeChanged))); + internal_->set_ime_composition_range_callback(internal_, cb.release(), wrapper); +} + +void OverlayManager::SetImeSelectionBoundsCallback( + std::function<void(Rect, Rect, bool)> onImeSelectionBoundsChanged) +{ + static auto wrapper = + [](void* callbackData, DiscordRect anchor, DiscordRect focus, bool isAnchorFirst) -> void { + std::unique_ptr<std::function<void(Rect, Rect, bool)>> cb( + reinterpret_cast<std::function<void(Rect, Rect, bool)>*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(*reinterpret_cast<Rect const*>(&anchor), + *reinterpret_cast<Rect const*>(&focus), + (isAnchorFirst != 0)); + }; + std::unique_ptr<std::function<void(Rect, Rect, bool)>> cb{}; + cb.reset(new std::function<void(Rect, Rect, bool)>(std::move(onImeSelectionBoundsChanged))); + internal_->set_ime_selection_bounds_callback(internal_, cb.release(), wrapper); +} + +bool OverlayManager::IsPointInsideClickZone(std::int32_t x, std::int32_t y) +{ + auto result = internal_->is_point_inside_click_zone(internal_, x, y); + return (result != 0); +} + } // namespace discord diff --git a/source/application/discord/overlay_manager.h b/source/application/discord/overlay_manager.h index 4afba0b..5f73a36 100644 --- a/source/application/discord/overlay_manager.h +++ b/source/application/discord/overlay_manager.h @@ -13,6 +13,31 @@ public: void SetLocked(bool locked, std::function<void(Result)> callback); void OpenActivityInvite(ActivityActionType type, std::function<void(Result)> callback); void OpenGuildInvite(char const* code, std::function<void(Result)> callback); + void OpenVoiceSettings(std::function<void(Result)> callback); + Result InitDrawingDxgi(IDXGISwapChain* swapchain, bool useMessageForwarding); + void OnPresent(); + void ForwardMessage(MSG* message); + void KeyEvent(bool down, char const* keyCode, KeyVariant variant); + void CharEvent(char const* character); + void MouseButtonEvent(std::uint8_t down, + std::int32_t clickCount, + MouseButton which, + std::int32_t x, + std::int32_t y); + void MouseMotionEvent(std::int32_t x, std::int32_t y); + void ImeCommitText(char const* text); + void ImeSetComposition(char const* text, + ImeUnderline* underlines, + std::uint32_t underlinesLength, + std::int32_t from, + std::int32_t to); + void ImeCancelComposition(); + void SetImeCompositionRangeCallback( + std::function<void(std::int32_t, std::int32_t, Rect*, std::uint32_t)> + onImeCompositionRangeChanged); + void SetImeSelectionBoundsCallback( + std::function<void(Rect, Rect, bool)> onImeSelectionBoundsChanged); + bool IsPointInsideClickZone(std::int32_t x, std::int32_t y); Event<bool> OnToggle; diff --git a/source/application/discord/relationship_manager.cpp b/source/application/discord/relationship_manager.cpp index 005f2b0..dce874e 100644 --- a/source/application/discord/relationship_manager.cpp +++ b/source/application/discord/relationship_manager.cpp @@ -13,7 +13,7 @@ namespace discord { class RelationshipEvents final { public: - static void OnRefresh(void* callbackData) + static void DISCORD_CALLBACK OnRefresh(void* callbackData) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -24,7 +24,8 @@ public: module.OnRefresh(); } - static void OnRelationshipUpdate(void* callbackData, DiscordRelationship* relationship) + static void DISCORD_CALLBACK OnRelationshipUpdate(void* callbackData, + DiscordRelationship* relationship) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { diff --git a/source/application/discord/storage_manager.cpp b/source/application/discord/storage_manager.cpp index 51fb4c7..fbf9ca7 100644 --- a/source/application/discord/storage_manager.cpp +++ b/source/application/discord/storage_manager.cpp @@ -145,4 +145,14 @@ Result StorageManager::StatAt(std::int32_t index, FileStat* stat) return static_cast<Result>(result); } +Result StorageManager::GetPath(char path[4096]) +{ + if (!path) { + return Result::InternalError; + } + + auto result = internal_->get_path(internal_, reinterpret_cast<DiscordPath*>(path)); + return static_cast<Result>(result); +} + } // namespace discord diff --git a/source/application/discord/storage_manager.h b/source/application/discord/storage_manager.h index cab7868..5d6d17b 100644 --- a/source/application/discord/storage_manager.h +++ b/source/application/discord/storage_manager.h @@ -28,6 +28,7 @@ public: void Count(std::int32_t* count); Result Stat(char const* name, FileStat* stat); Result StatAt(std::int32_t index, FileStat* stat); + Result GetPath(char path[4096]); private: friend class Core; diff --git a/source/application/discord/store_manager.cpp b/source/application/discord/store_manager.cpp index d6bdad1..40c7e65 100644 --- a/source/application/discord/store_manager.cpp +++ b/source/application/discord/store_manager.cpp @@ -13,7 +13,8 @@ namespace discord { class StoreEvents final { public: - static void OnEntitlementCreate(void* callbackData, DiscordEntitlement* entitlement) + static void DISCORD_CALLBACK OnEntitlementCreate(void* callbackData, + DiscordEntitlement* entitlement) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -24,7 +25,8 @@ public: module.OnEntitlementCreate(*reinterpret_cast<Entitlement const*>(entitlement)); } - static void OnEntitlementDelete(void* callbackData, DiscordEntitlement* entitlement) + static void DISCORD_CALLBACK OnEntitlementDelete(void* callbackData, + DiscordEntitlement* entitlement) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { diff --git a/source/application/discord/types.cpp b/source/application/discord/types.cpp index 7e58ad1..b60dded 100644 --- a/source/application/discord/types.cpp +++ b/source/application/discord/types.cpp @@ -249,6 +249,16 @@ PartySize const& ActivityParty::GetSize() const return reinterpret_cast<PartySize const&>(internal_.size); } +void ActivityParty::SetPrivacy(ActivityPartyPrivacy privacy) +{ + internal_.privacy = static_cast<EDiscordActivityPartyPrivacy>(privacy); +} + +ActivityPartyPrivacy ActivityParty::GetPrivacy() const +{ + return static_cast<ActivityPartyPrivacy>(internal_.privacy); +} + void ActivitySecrets::SetMatch(char const* match) { strncpy(internal_.match, match, 128); @@ -385,6 +395,16 @@ bool Activity::GetInstance() const return internal_.instance != 0; } +void Activity::SetSupportedPlatforms(std::uint32_t supportedPlatforms) +{ + internal_.supported_platforms = supportedPlatforms; +} + +std::uint32_t Activity::GetSupportedPlatforms() const +{ + return internal_.supported_platforms; +} + void Presence::SetStatus(Status status) { internal_.status = static_cast<EDiscordStatus>(status); @@ -496,6 +516,96 @@ bool Lobby::GetLocked() const return internal_.locked != 0; } +void ImeUnderline::SetFrom(std::int32_t from) +{ + internal_.from = from; +} + +std::int32_t ImeUnderline::GetFrom() const +{ + return internal_.from; +} + +void ImeUnderline::SetTo(std::int32_t to) +{ + internal_.to = to; +} + +std::int32_t ImeUnderline::GetTo() const +{ + return internal_.to; +} + +void ImeUnderline::SetColor(std::uint32_t color) +{ + internal_.color = color; +} + +std::uint32_t ImeUnderline::GetColor() const +{ + return internal_.color; +} + +void ImeUnderline::SetBackgroundColor(std::uint32_t backgroundColor) +{ + internal_.background_color = backgroundColor; +} + +std::uint32_t ImeUnderline::GetBackgroundColor() const +{ + return internal_.background_color; +} + +void ImeUnderline::SetThick(bool thick) +{ + internal_.thick = thick; +} + +bool ImeUnderline::GetThick() const +{ + return internal_.thick != 0; +} + +void Rect::SetLeft(std::int32_t left) +{ + internal_.left = left; +} + +std::int32_t Rect::GetLeft() const +{ + return internal_.left; +} + +void Rect::SetTop(std::int32_t top) +{ + internal_.top = top; +} + +std::int32_t Rect::GetTop() const +{ + return internal_.top; +} + +void Rect::SetRight(std::int32_t right) +{ + internal_.right = right; +} + +std::int32_t Rect::GetRight() const +{ + return internal_.right; +} + +void Rect::SetBottom(std::int32_t bottom) +{ + internal_.bottom = bottom; +} + +std::int32_t Rect::GetBottom() const +{ + return internal_.bottom; +} + void FileStat::SetFilename(char const* filename) { strncpy(internal_.filename, filename, 260); @@ -619,6 +729,68 @@ SkuPrice const& Sku::GetPrice() const return reinterpret_cast<SkuPrice const&>(internal_.price); } +void InputMode::SetType(InputModeType type) +{ + internal_.type = static_cast<EDiscordInputModeType>(type); +} + +InputModeType InputMode::GetType() const +{ + return static_cast<InputModeType>(internal_.type); +} + +void InputMode::SetShortcut(char const* shortcut) +{ + strncpy(internal_.shortcut, shortcut, 256); + internal_.shortcut[256 - 1] = '\0'; +} + +char const* InputMode::GetShortcut() const +{ + return internal_.shortcut; +} + +void UserAchievement::SetUserId(Snowflake userId) +{ + internal_.user_id = userId; +} + +Snowflake UserAchievement::GetUserId() const +{ + return internal_.user_id; +} + +void UserAchievement::SetAchievementId(Snowflake achievementId) +{ + internal_.achievement_id = achievementId; +} + +Snowflake UserAchievement::GetAchievementId() const +{ + return internal_.achievement_id; +} + +void UserAchievement::SetPercentComplete(std::uint8_t percentComplete) +{ + internal_.percent_complete = percentComplete; +} + +std::uint8_t UserAchievement::GetPercentComplete() const +{ + return internal_.percent_complete; +} + +void UserAchievement::SetUnlockedAt(DateTime unlockedAt) +{ + strncpy(internal_.unlocked_at, unlockedAt, 64); + internal_.unlocked_at[64 - 1] = '\0'; +} + +DateTime UserAchievement::GetUnlockedAt() const +{ + return internal_.unlocked_at; +} + Result LobbyTransaction::SetType(LobbyType type) { auto result = internal_->set_type(internal_, static_cast<EDiscordLobbyType>(type)); diff --git a/source/application/discord/types.h b/source/application/discord/types.h index 5032592..3c97f92 100644 --- a/source/application/discord/types.h +++ b/source/application/discord/types.h @@ -2,40 +2,61 @@ #include "ffi.h" #include "event.h" +#ifdef _WIN32 +#include <Windows.h> +#include <dxgi.h> +#endif + +#include <cstdint> namespace discord { enum class Result { - Ok, - ServiceUnavailable, - InvalidVersion, - LockFailed, - InternalError, - InvalidPayload, - InvalidCommand, - InvalidPermissions, - NotFetched, - NotFound, - Conflict, - InvalidSecret, - InvalidJoinSecret, - NoEligibleActivity, - InvalidInvite, - NotAuthenticated, - InvalidAccessToken, - ApplicationMismatch, - InvalidDataUrl, - InvalidBase64, - NotFiltered, - LobbyFull, - InvalidLobbySecret, - InvalidFilename, - InvalidFileSize, - InvalidEntitlement, - NotInstalled, - NotRunning, - InsufficientBuffer, - PurchaseCanceled, + Ok = 0, + ServiceUnavailable = 1, + InvalidVersion = 2, + LockFailed = 3, + InternalError = 4, + InvalidPayload = 5, + InvalidCommand = 6, + InvalidPermissions = 7, + NotFetched = 8, + NotFound = 9, + Conflict = 10, + InvalidSecret = 11, + InvalidJoinSecret = 12, + NoEligibleActivity = 13, + InvalidInvite = 14, + NotAuthenticated = 15, + InvalidAccessToken = 16, + ApplicationMismatch = 17, + InvalidDataUrl = 18, + InvalidBase64 = 19, + NotFiltered = 20, + LobbyFull = 21, + InvalidLobbySecret = 22, + InvalidFilename = 23, + InvalidFileSize = 24, + InvalidEntitlement = 25, + NotInstalled = 26, + NotRunning = 27, + InsufficientBuffer = 28, + PurchaseCanceled = 29, + InvalidGuild = 30, + InvalidEvent = 31, + InvalidChannel = 32, + InvalidOrigin = 33, + RateLimited = 34, + OAuth2Error = 35, + SelectChannelTimeout = 36, + GetGuildTimeout = 37, + SelectVoiceForceRequired = 38, + CaptureShortcutAlreadyListening = 39, + UnauthorizedForAchievement = 40, + InvalidGiftCode = 41, + PurchaseError = 42, + TransactionAborted = 43, + DrawingInitFailed = 44, }; enum class CreateFlags { @@ -50,10 +71,29 @@ enum class LogLevel { Debug, }; +enum class UserFlag { + Partner = 2, + HypeSquadEvents = 4, + HypeSquadHouse1 = 64, + HypeSquadHouse2 = 128, + HypeSquadHouse3 = 256, +}; + +enum class PremiumType { + None = 0, + Tier1 = 1, + Tier2 = 2, +}; + enum class ImageType { User, }; +enum class ActivityPartyPrivacy { + Private = 0, + Public = 1, +}; + enum class ActivityType { Playing, Streaming, @@ -66,6 +106,12 @@ enum class ActivityActionType { Spectate, }; +enum class ActivitySupportedPlatformFlags { + Desktop = 1, + Android = 2, + iOS = 4, +}; + enum class ActivityJoinRequestReply { No, Yes, @@ -114,10 +160,26 @@ enum class LobbySearchDistance { Global, }; +enum class KeyVariant { + Normal, + Right, + Left, +}; + +enum class MouseButton { + Left, + Middle, + Right, +}; + enum class EntitlementType { Purchase = 1, PremiumSubscription, DeveloperGift, + TestModePurchase, + FreePurchase, + UserGift, + PremiumPurchase, }; enum class SkuType { @@ -127,6 +189,11 @@ enum class SkuType { Bundle, }; +enum class InputModeType { + VoiceActivity = 0, + PushToTalk, +}; + using ClientId = std::int64_t; using Version = std::int32_t; using Snowflake = std::int64_t; @@ -140,6 +207,20 @@ using MetadataKey = char const*; using MetadataValue = char const*; using NetworkPeerId = std::uint64_t; using NetworkChannelId = std::uint8_t; +#ifdef __APPLE__ +using IDXGISwapChain = void; +#endif +#ifdef __linux__ +using IDXGISwapChain = void; +#endif +#ifdef __APPLE__ +using MSG = void; +#endif +#ifdef __linux__ +using MSG = void; +#endif +using Path = char const*; +using DateTime = char const*; class User final { public: @@ -238,6 +319,8 @@ public: char const* GetId() const; PartySize& GetSize(); PartySize const& GetSize() const; + void SetPrivacy(ActivityPartyPrivacy privacy); + ActivityPartyPrivacy GetPrivacy() const; private: DiscordActivityParty internal_; @@ -278,6 +361,8 @@ public: ActivitySecrets const& GetSecrets() const; void SetInstance(bool instance); bool GetInstance() const; + void SetSupportedPlatforms(std::uint32_t supportedPlatforms); + std::uint32_t GetSupportedPlatforms() const; private: DiscordActivity internal_; @@ -326,6 +411,38 @@ private: DiscordLobby internal_; }; +class ImeUnderline final { +public: + void SetFrom(std::int32_t from); + std::int32_t GetFrom() const; + void SetTo(std::int32_t to); + std::int32_t GetTo() const; + void SetColor(std::uint32_t color); + std::uint32_t GetColor() const; + void SetBackgroundColor(std::uint32_t backgroundColor); + std::uint32_t GetBackgroundColor() const; + void SetThick(bool thick); + bool GetThick() const; + +private: + DiscordImeUnderline internal_; +}; + +class Rect final { +public: + void SetLeft(std::int32_t left); + std::int32_t GetLeft() const; + void SetTop(std::int32_t top); + std::int32_t GetTop() const; + void SetRight(std::int32_t right); + std::int32_t GetRight() const; + void SetBottom(std::int32_t bottom); + std::int32_t GetBottom() const; + +private: + DiscordRect internal_; +}; + class FileStat final { public: void SetFilename(char const* filename); @@ -378,6 +495,32 @@ private: DiscordSku internal_; }; +class InputMode final { +public: + void SetType(InputModeType type); + InputModeType GetType() const; + void SetShortcut(char const* shortcut); + char const* GetShortcut() const; + +private: + DiscordInputMode internal_; +}; + +class UserAchievement final { +public: + void SetUserId(Snowflake userId); + Snowflake GetUserId() const; + void SetAchievementId(Snowflake achievementId); + Snowflake GetAchievementId() const; + void SetPercentComplete(std::uint8_t percentComplete); + std::uint8_t GetPercentComplete() const; + void SetUnlockedAt(DateTime unlockedAt); + DateTime GetUnlockedAt() const; + +private: + DiscordUserAchievement internal_; +}; + class LobbyTransaction final { public: Result SetType(LobbyType type); diff --git a/source/application/discord/user_manager.cpp b/source/application/discord/user_manager.cpp index f3ac0e2..ddb6d5c 100644 --- a/source/application/discord/user_manager.cpp +++ b/source/application/discord/user_manager.cpp @@ -13,7 +13,7 @@ namespace discord { class UserEvents final { public: - static void OnCurrentUserUpdate(void* callbackData) + static void DISCORD_CALLBACK OnCurrentUserUpdate(void* callbackData) { auto* core = reinterpret_cast<Core*>(callbackData); if (!core) { @@ -55,4 +55,26 @@ void UserManager::GetUser(UserId userId, std::function<void(Result, User const&) internal_->get_user(internal_, userId, cb.release(), wrapper); } +Result UserManager::GetCurrentUserPremiumType(PremiumType* premiumType) +{ + if (!premiumType) { + return Result::InternalError; + } + + auto result = internal_->get_current_user_premium_type( + internal_, reinterpret_cast<EDiscordPremiumType*>(premiumType)); + return static_cast<Result>(result); +} + +Result UserManager::CurrentUserHasFlag(UserFlag flag, bool* hasFlag) +{ + if (!hasFlag) { + return Result::InternalError; + } + + auto result = internal_->current_user_has_flag( + internal_, static_cast<EDiscordUserFlag>(flag), reinterpret_cast<bool*>(hasFlag)); + return static_cast<Result>(result); +} + } // namespace discord diff --git a/source/application/discord/user_manager.h b/source/application/discord/user_manager.h index 98ed9da..d85de1b 100644 --- a/source/application/discord/user_manager.h +++ b/source/application/discord/user_manager.h @@ -10,6 +10,8 @@ public: Result GetCurrentUser(User* currentUser); void GetUser(UserId userId, std::function<void(Result, User const&)> callback); + Result GetCurrentUserPremiumType(PremiumType* premiumType); + Result CurrentUserHasFlag(UserFlag flag, bool* hasFlag); Event<> OnCurrentUserUpdate; diff --git a/source/application/discord/voice_manager.cpp b/source/application/discord/voice_manager.cpp new file mode 100644 index 0000000..014ceb3 --- /dev/null +++ b/source/application/discord/voice_manager.cpp @@ -0,0 +1,124 @@ +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "voice_manager.h" + +#include "core.h" + +#include <cstring> +#include <memory> + +namespace discord { + +class VoiceEvents final { +public: + static void DISCORD_CALLBACK OnSettingsUpdate(void* callbackData) + { + auto* core = reinterpret_cast<Core*>(callbackData); + if (!core) { + return; + } + + auto& module = core->VoiceManager(); + module.OnSettingsUpdate(); + } +}; + +IDiscordVoiceEvents VoiceManager::events_{ + &VoiceEvents::OnSettingsUpdate, +}; + +Result VoiceManager::GetInputMode(InputMode* inputMode) +{ + if (!inputMode) { + return Result::InternalError; + } + + auto result = + internal_->get_input_mode(internal_, reinterpret_cast<DiscordInputMode*>(inputMode)); + return static_cast<Result>(result); +} + +void VoiceManager::SetInputMode(InputMode inputMode, std::function<void(Result)> callback) +{ + static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { + std::unique_ptr<std::function<void(Result)>> cb( + reinterpret_cast<std::function<void(Result)>*>(callbackData)); + if (!cb || !(*cb)) { + return; + } + (*cb)(static_cast<Result>(result)); + }; + std::unique_ptr<std::function<void(Result)>> cb{}; + cb.reset(new std::function<void(Result)>(std::move(callback))); + internal_->set_input_mode( + internal_, *reinterpret_cast<DiscordInputMode const*>(&inputMode), cb.release(), wrapper); +} + +Result VoiceManager::IsSelfMute(bool* mute) +{ + if (!mute) { + return Result::InternalError; + } + + auto result = internal_->is_self_mute(internal_, reinterpret_cast<bool*>(mute)); + return static_cast<Result>(result); +} + +Result VoiceManager::SetSelfMute(bool mute) +{ + auto result = internal_->set_self_mute(internal_, (mute ? 1 : 0)); + return static_cast<Result>(result); +} + +Result VoiceManager::IsSelfDeaf(bool* deaf) +{ + if (!deaf) { + return Result::InternalError; + } + + auto result = internal_->is_self_deaf(internal_, reinterpret_cast<bool*>(deaf)); + return static_cast<Result>(result); +} + +Result VoiceManager::SetSelfDeaf(bool deaf) +{ + auto result = internal_->set_self_deaf(internal_, (deaf ? 1 : 0)); + return static_cast<Result>(result); +} + +Result VoiceManager::IsLocalMute(Snowflake userId, bool* mute) +{ + if (!mute) { + return Result::InternalError; + } + + auto result = internal_->is_local_mute(internal_, userId, reinterpret_cast<bool*>(mute)); + return static_cast<Result>(result); +} + +Result VoiceManager::SetLocalMute(Snowflake userId, bool mute) +{ + auto result = internal_->set_local_mute(internal_, userId, (mute ? 1 : 0)); + return static_cast<Result>(result); +} + +Result VoiceManager::GetLocalVolume(Snowflake userId, std::uint8_t* volume) +{ + if (!volume) { + return Result::InternalError; + } + + auto result = + internal_->get_local_volume(internal_, userId, reinterpret_cast<uint8_t*>(volume)); + return static_cast<Result>(result); +} + +Result VoiceManager::SetLocalVolume(Snowflake userId, std::uint8_t volume) +{ + auto result = internal_->set_local_volume(internal_, userId, volume); + return static_cast<Result>(result); +} + +} // namespace discord diff --git a/source/application/discord/voice_manager.h b/source/application/discord/voice_manager.h new file mode 100644 index 0000000..95b20e9 --- /dev/null +++ b/source/application/discord/voice_manager.h @@ -0,0 +1,37 @@ +#pragma once + +#include "types.h" + +namespace discord { + +class VoiceManager final { +public: + ~VoiceManager() = default; + + Result GetInputMode(InputMode* inputMode); + void SetInputMode(InputMode inputMode, std::function<void(Result)> callback); + Result IsSelfMute(bool* mute); + Result SetSelfMute(bool mute); + Result IsSelfDeaf(bool* deaf); + Result SetSelfDeaf(bool deaf); + Result IsLocalMute(Snowflake userId, bool* mute); + Result SetLocalMute(Snowflake userId, bool mute); + Result GetLocalVolume(Snowflake userId, std::uint8_t* volume); + Result SetLocalVolume(Snowflake userId, std::uint8_t volume); + + Event<> OnSettingsUpdate; + +private: + friend class Core; + + VoiceManager() = default; + VoiceManager(VoiceManager const& rhs) = delete; + VoiceManager& operator=(VoiceManager const& rhs) = delete; + VoiceManager(VoiceManager&& rhs) = delete; + VoiceManager& operator=(VoiceManager&& rhs) = delete; + + IDiscordVoiceManager* internal_; + static IDiscordVoiceEvents events_; +}; + +} // namespace discord diff --git a/source/base/CMakeLists.txt b/source/base/CMakeLists.txt index d5e0750..712e201 100644 --- a/source/base/CMakeLists.txt +++ b/source/base/CMakeLists.txt @@ -35,4 +35,7 @@ SET (star_base_SOURCES CONFIGURE_FILE (StarVersion.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/StarVersion.cpp) ADD_LIBRARY (star_base OBJECT ${star_base_SOURCES} ${star_base_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/StarVersion.cpp) -TARGET_PRECOMPILE_HEADERS (star_base REUSE_FROM star_core) + +IF(STAR_PRECOMPILED_HEADERS) + TARGET_PRECOMPILE_HEADERS (star_base REUSE_FROM star_core) +ENDIF()
\ No newline at end of file diff --git a/source/base/StarAssets.cpp b/source/base/StarAssets.cpp index b72b446..0b21f5e 100644 --- a/source/base/StarAssets.cpp +++ b/source/base/StarAssets.cpp @@ -86,10 +86,21 @@ Assets::Assets(Settings settings, StringList assetSources) { m_assetSourcePaths.add(sourcePath, source); for (auto const& filename : source->assetPaths()) { - if (filename.endsWith(AssetsPatchSuffix, String::CaseInsensitive)) { - auto targetPatchFile = filename.substr(0, filename.size() - strlen(AssetsPatchSuffix)); - if (auto p = m_files.ptr(targetPatchFile)) - p->patchSources.append({filename, source}); + if (filename.contains(AssetsPatchSuffix, String::CaseInsensitive)) { + if (filename.endsWith(AssetsPatchSuffix, String::CaseInsensitive)) { + auto targetPatchFile = filename.substr(0, filename.size() - strlen(AssetsPatchSuffix)); + if (auto p = m_files.ptr(targetPatchFile)) + p->patchSources.append({filename, source}); + } else { + for (int i = 0; i < 10; i++) { + if (filename.endsWith(AssetsPatchSuffix + toString(i), String::CaseInsensitive)) { + auto targetPatchFile = filename.substr(0, filename.size() - strlen(AssetsPatchSuffix) + 1); + if (auto p = m_files.ptr(targetPatchFile)) + p->patchSources.append({filename, source}); + break; + } + } + } } auto& descriptor = m_files[filename]; descriptor.sourceName = filename; diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index b9a3e1c..0ca0eaf 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -28,5 +28,9 @@ ADD_EXECUTABLE (starbound WIN32 $<TARGET_OBJECTS:star_extern> $<TARGET_OBJECTS:star_core> $<TARGET_OBJECTS:star_base> $<TARGET_OBJECTS:star_game> $<TARGET_OBJECTS:star_application> $<TARGET_OBJECTS:star_rendering> $<TARGET_OBJECTS:star_windowing> $<TARGET_OBJECTS:star_frontend> ${star_client_HEADERS} ${star_client_SOURCES} ${star_client_RESOURCES}) -TARGET_PRECOMPILE_HEADERS (starbound REUSE_FROM star_core) + +IF(STAR_PRECOMPILED_HEADERS) + TARGET_PRECOMPILE_HEADERS (starbound REUSE_FROM star_core) +ENDIF() + TARGET_LINK_LIBRARIES (starbound ${STAR_EXT_LIBS} ${STAR_EXT_GUI_LIBS})
\ No newline at end of file diff --git a/source/core/CMakeLists.txt b/source/core/CMakeLists.txt index ce35500..687b9c5 100644 --- a/source/core/CMakeLists.txt +++ b/source/core/CMakeLists.txt @@ -214,7 +214,10 @@ ELSEIF (STAR_SYSTEM_FAMILY_WINDOWS) ENDIF () ADD_LIBRARY (star_core OBJECT ${star_core_SOURCES} ${star_core_HEADERS}) -TARGET_PRECOMPILE_HEADERS (star_core PUBLIC StarPch.hpp) + +IF(STAR_PRECOMPILED_HEADERS) + TARGET_PRECOMPILE_HEADERS (star_core PUBLIC StarPch.hpp) +ENDIF() IF(STAR_USE_JEMALLOC AND JEMALLOC_IS_PREFIXED) SET_SOURCE_FILES_PROPERTIES(StarMemory.cpp PROPERTIES diff --git a/source/core/StarJson.cpp b/source/core/StarJson.cpp index 3feaf37..3502996 100644 --- a/source/core/StarJson.cpp +++ b/source/core/StarJson.cpp @@ -1035,4 +1035,34 @@ Json jsonMerge(Json const& base, Json const& merger) { } } +bool jsonPartialMatch(Json const& base, Json const& compare) { + if (base == compare) { + return true; + } else { + if (base.type() == Json::Type::Object && compare.type() == Json::Type::Object) { + for (auto const& c : compare.toObject()) { + if (!base.contains(c.first) || !jsonPartialMatch(base.get(c.first), c.second)) + return false; + } + return true; + } + if (base.type() == Json::Type::Array && compare.type() == Json::Type::Array) { + for (auto const& c : compare.toArray()) { + bool similar = false; + for (auto const& b : base.toArray()) { + if (jsonPartialMatch(c, b)) { + similar = true; + break; + } + } + if (!similar) + return false; + } + return true; + } + + return false; + } +} + }
\ No newline at end of file diff --git a/source/core/StarJson.hpp b/source/core/StarJson.hpp index 4aa6f7b..085fd9f 100644 --- a/source/core/StarJson.hpp +++ b/source/core/StarJson.hpp @@ -355,6 +355,14 @@ Json jsonMergeQueryDef(String const& key, Json def, Json const& first, T const&. return def; } +// Compares two JSON values to see if the second is a subset of the first. +// For objects, each key in the second object must exist in the first +// object and the values are recursively compared the same way. For arrays, +// each element in the second array must successfully compare with some +// element of the first array, regardless of order or duplication. +// For all other types, the values must be equal. +bool jsonPartialMatch(Json const& base, Json const& compare); + } template <> struct fmt::formatter<Star::Json> : ostream_formatter {}; diff --git a/source/core/StarJsonPatch.cpp b/source/core/StarJsonPatch.cpp index 49b6749..14505e5 100644 --- a/source/core/StarJsonPatch.cpp +++ b/source/core/StarJsonPatch.cpp @@ -16,6 +16,22 @@ Json jsonPatch(Json const& base, JsonArray const& patch) { } } + +// Returns 0 if not found, index + 1 if found. +size_t findJsonMatch(Json const& searchable, Json const& value, JsonPath::Pointer& pointer) { + if (searchable.isType(Json::Type::Array)) { + auto array = searchable.toArray(); + for (size_t i = 0; i != array.size(); ++i) { + if (jsonPartialMatch(array[i], value)) + return i + 1; + } + } else { + throw JsonPatchException(strf("Search operation failure, value at '{}' is not an array.", pointer.path())); + } + return 0; +} + + namespace JsonPatching { static const StringMap<std::function<Json(Json, Json)>> functionMap = StringMap<std::function<Json(Json, Json)>>{ @@ -25,6 +41,7 @@ namespace JsonPatching { {"replace", std::bind(applyReplaceOperation, _1, _2)}, {"move", std::bind(applyMoveOperation, _1, _2)}, {"copy", std::bind(applyCopyOperation, _1, _2)}, + {"merge", std::bind(applyMergeOperation, _1, _2)}, }; Json applyOperation(Json const& base, Json const& op, Maybe<Json> const& external) { @@ -39,25 +56,34 @@ namespace JsonPatching { } Json applyTestOperation(Json const& base, Json const& op) { - auto path = op.getString("path"); - auto value = op.opt("value"); - auto inverseTest = op.getBool("inverse", false); - + String path = op.getString("path"); auto pointer = JsonPath::Pointer(path); + auto inverseTest = op.getBool("inverse", false); try { - auto testValue = pointer.get(base); - if (!value) { - if (inverseTest) - throw JsonPatchTestFail(strf("Test operation failure, expected {} to be missing.", op.getString("path"))); + if (op.contains("search")) { + auto searchable = pointer.get(base); + auto searchValue = op.get("search"); + bool found = findJsonMatch(searchable, searchValue, pointer); + if (found && inverseTest) + throw JsonPatchTestFail(strf("Test operation failure, expected {} to be missing.", searchValue)); + else if (!found && !inverseTest) + throw JsonPatchTestFail(strf("Test operation failure, could not find {}.", searchValue)); return base; + } else { + auto value = op.opt("value"); + auto testValue = pointer.get(base); + if (!value) { + if (inverseTest) + throw JsonPatchTestFail(strf("Test operation failure, expected {} to be missing.", path)); + return base; + } + + if ((value && (testValue == *value)) ^ inverseTest) + return base; + else + throw JsonPatchTestFail(strf("Test operation failure, expected {} found {}.", value, testValue)); } - - if ((value && (testValue == *value)) ^ inverseTest) { - return base; - } - - throw JsonPatchTestFail(strf("Test operation failure, expected {} found {}.", value, testValue)); } catch (JsonPath::TraversalException& e) { if (inverseTest) return base; @@ -66,31 +92,107 @@ namespace JsonPatching { } Json applyRemoveOperation(Json const& base, Json const& op) { - return JsonPath::Pointer(op.getString("path")).remove(base); + String path = op.getString("path"); + auto pointer = JsonPath::Pointer(path); + + if (op.contains("search")) { + auto searchable = pointer.get(base); + auto searchValue = op.get("search"); + if (size_t index = findJsonMatch(searchable, searchValue, pointer)) + return pointer.add(pointer.remove(base), searchable.eraseIndex(index - 1)); + else + return base; + } else { + return pointer.remove(base); + } } Json applyAddOperation(Json const& base, Json const& op) { - return JsonPath::Pointer(op.getString("path")).add(base, op.get("value")); + String path = op.getString("path"); + auto value = op.get("value"); + auto pointer = JsonPath::Pointer(path); + + if (op.contains("search")) { + auto searchable = pointer.get(base); + auto searchValue = op.get("search"); + if (size_t index = findJsonMatch(searchable, searchValue, pointer)) + return pointer.add(pointer.remove(base), searchable.insert(index - 1, value)); + else + return base; + } else { + return pointer.add(base, value); + } } Json applyReplaceOperation(Json const& base, Json const& op) { + String path = op.getString("path"); + auto value = op.get("value"); auto pointer = JsonPath::Pointer(op.getString("path")); - return pointer.add(pointer.remove(base), op.get("value")); + + if (op.contains("search")) { + auto searchable = pointer.get(base); + auto searchValue = op.get("search"); + if (size_t index = findJsonMatch(searchable, searchValue, pointer)) + return pointer.add(pointer.remove(base), searchable.set(index - 1, value)); + else + return base; + } else { + return pointer.add(pointer.remove(base), value); + } } Json applyMoveOperation(Json const& base, Json const& op) { + String path = op.getString("path"); + auto toPointer = JsonPath::Pointer(path); auto fromPointer = JsonPath::Pointer(op.getString("from")); - auto toPointer = JsonPath::Pointer(op.getString("path")); - Json value = fromPointer.get(base); - return toPointer.add(fromPointer.remove(base), value); + if (op.contains("search")) { + auto searchable = fromPointer.get(base); + auto searchValue = op.get("search"); + if (size_t index = findJsonMatch(searchable, searchValue, fromPointer)) { + auto result = toPointer.add(base, searchable.get(index - 1)); + return fromPointer.add(result, searchable.eraseIndex(index - 1)); + } + else + return base; + } else { + Json value = fromPointer.get(base); + return toPointer.add(fromPointer.remove(base), value); + } } Json applyCopyOperation(Json const& base, Json const& op) { + String path = op.getString("path"); + auto toPointer = JsonPath::Pointer(path); auto fromPointer = JsonPath::Pointer(op.getString("from")); - auto toPointer = JsonPath::Pointer(op.getString("path")); - return toPointer.add(base, fromPointer.get(base)); + if (op.contains("search")) { + auto searchable = fromPointer.get(base); + auto searchValue = op.get("search"); + if (size_t index = findJsonMatch(searchable, searchValue, fromPointer)) + return toPointer.add(base, searchable.get(index - 1)); + else + return base; + } else { + Json value = fromPointer.get(base); + return toPointer.add(base, value); + } + } + + Json applyMergeOperation(Json const& base, Json const& op) { + String path = op.getString("path"); + auto pointer = JsonPath::Pointer(path); + + if (op.contains("search")) { + auto searchable = pointer.get(base); + auto searchValue = op.get("search"); + if (size_t index = findJsonMatch(searchable, searchValue, pointer)) + return pointer.add(pointer.remove(base), searchable.set(index - 1, jsonMerge(searchable.get(index - 1), op.get("value")))); + else + return base; + } else { + return pointer.add(pointer.remove(base), jsonMerge(pointer.get(base), op.get("value"))); + } } } diff --git a/source/core/StarJsonPatch.hpp b/source/core/StarJsonPatch.hpp index 5610cc6..9832543 100644 --- a/source/core/StarJsonPatch.hpp +++ b/source/core/StarJsonPatch.hpp @@ -33,6 +33,9 @@ namespace JsonPatching { // Copies "from" to "path" Json applyCopyOperation(Json const& base, Json const& op); -} + + // Merges "value" at "path" + Json applyMergeOperation(Json const& base, Json const& op); + } } diff --git a/source/extern/CMakeLists.txt b/source/extern/CMakeLists.txt index 624b837..ec74145 100644 --- a/source/extern/CMakeLists.txt +++ b/source/extern/CMakeLists.txt @@ -1,24 +1,5 @@ -set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) -SET (OPUS_INSTALL_PKG_CONFIG_MODULE OFF) -SET (OPUS_INSTALL_CMAKE_CONFIG_MODULE OFF) -SET (OPUS_X86_MAY_HAVE_SSE ON) -SET (OPUS_X86_MAY_HAVE_AVX ON) -SET (OPUS_X86_MAY_HAVE_SSE4_1 ON) -SET (OPUS_ENABLE_FLOAT_API ON) -SET (OPUS_FLOAT_APPROX ON) -SET (OPUS_STACK_PROTECTOR OFF) -SET (OPUS_NONTHREADSAFE_PSEUDOSTACK OFF) -SET (OPUS_USE_ALLOCA ON) -SET (BUILD_TESTING OFF) # Skip Opus tests, these won't build because the tests don't honor OPUS_FLOAT_APPROX. -ADD_SUBDIRECTORY (opus) - -IF (OPUS_NONTHREADSAFE_PSEUDOSTACK) - MESSAGE (FATAL_ERROR "Opus should not be using NONTHREADSAFE_PSEUDOSTACK") -ENDIF () - INCLUDE_DIRECTORIES ( ${STAR_EXTERN_INCLUDES} - opus/include fmt lua ) @@ -89,5 +70,4 @@ SET (star_extern_SOURCES lua/lzio.c ) -ADD_LIBRARY (star_extern OBJECT ${star_extern_SOURCES} ${star_extern_HEADERS}) -TARGET_LINK_LIBRARIES(star_extern PUBLIC opus)
\ No newline at end of file +ADD_LIBRARY (star_extern OBJECT ${star_extern_SOURCES} ${star_extern_HEADERS})
\ No newline at end of file diff --git a/source/extern/opus b/source/extern/opus deleted file mode 160000 -Subproject 9fc8fc4cf432640f284113ba502ee027268b0d9 diff --git a/source/frontend/CMakeLists.txt b/source/frontend/CMakeLists.txt index c213b72..cae2d43 100644 --- a/source/frontend/CMakeLists.txt +++ b/source/frontend/CMakeLists.txt @@ -113,4 +113,7 @@ SET (star_frontend_SOURCES ) ADD_LIBRARY (star_frontend OBJECT ${star_frontend_SOURCES} ${star_frontend_HEADERS}) -TARGET_PRECOMPILE_HEADERS (star_frontend REUSE_FROM star_core)
\ No newline at end of file + +IF(STAR_PRECOMPILED_HEADERS) + TARGET_PRECOMPILE_HEADERS (star_frontend REUSE_FROM star_core) +ENDIF()
\ No newline at end of file diff --git a/source/frontend/StarSongbookInterface.cpp b/source/frontend/StarSongbookInterface.cpp index 8ccb437..cc6a17d 100644 --- a/source/frontend/StarSongbookInterface.cpp +++ b/source/frontend/StarSongbookInterface.cpp @@ -23,21 +23,52 @@ SongbookInterface::SongbookInterface(PlayerPtr player) { dismiss(); }); reader.registerCallback("group", [=](Widget*) {}); + reader.registerCallback("search", [=](Widget*) {}); reader.construct(assets->json("/interface/windowconfig/songbook.config:paneLayout"), this); auto songList = fetchChild<ListWidget>("songs.list"); + auto search = fetchChild<TextBoxWidget>("search")->getText(); - StringList files = assets->scan(".abc"); - sort(files, [](String const& a, String const& b) -> bool { return b.compare(a, String::CaseInsensitive) > 0; }); - for (auto s : files) { + if (m_searchValue != search) + m_searchValue = search; + + m_files = assets->scan(".abc"); + sort(m_files, [](String const& a, String const& b) -> bool { return b.compare(a, String::CaseInsensitive) > 0; }); + for (auto s : m_files) { auto song = s.substr(7, s.length() - (7 + 4)); - auto widget = songList->addItem(); - widget->setData(s); - auto songName = widget->fetchChild<LabelWidget>("songName"); - songName->setText(song); + if (song.contains(m_searchValue, String::CaseInsensitive)) { + auto widget = songList->addItem(); + widget->setData(s); + auto songName = widget->fetchChild<LabelWidget>("songName"); + songName->setText(song); - widget->show(); + widget->show(); + } + } +} + +void SongbookInterface::update(float dt) { + Pane::update(dt); + + auto search = fetchChild<TextBoxWidget>("search")->getText(); + if (m_searchValue != search) { + m_searchValue = search; + + auto songList = fetchChild<ListWidget>("songs.list"); + songList->clear(); + + for (auto s : m_files) { + auto song = s.substr(7, s.length() - (7 + 4)); + if (song.contains(m_searchValue, String::CaseInsensitive)) { + auto widget = songList->addItem(); + widget->setData(s); + auto songName = widget->fetchChild<LabelWidget>("songName"); + songName->setText(song); + + widget->show(); + } + } } } @@ -58,4 +89,4 @@ bool SongbookInterface::play() { return true; } -} +}
\ No newline at end of file diff --git a/source/frontend/StarSongbookInterface.hpp b/source/frontend/StarSongbookInterface.hpp index 47622a4..f8a6cb2 100644 --- a/source/frontend/StarSongbookInterface.hpp +++ b/source/frontend/StarSongbookInterface.hpp @@ -13,8 +13,12 @@ class SongbookInterface : public Pane { public: SongbookInterface(PlayerPtr player); + void update(float dt) override; + private: PlayerPtr m_player; + StringList m_files; + String m_searchValue; bool play(); }; diff --git a/source/frontend/StarVoice.cpp b/source/frontend/StarVoice.cpp index 752a7b4..b2c4695 100644 --- a/source/frontend/StarVoice.cpp +++ b/source/frontend/StarVoice.cpp @@ -6,9 +6,9 @@ #include "StarRoot.hpp" #include "StarLogging.hpp" #include "StarInterpolation.hpp" -#include "opus/include/opus.h" +#include "opus/opus.h" -#include "SDL.h" +#include "SDL2/SDL.h" constexpr int VOICE_SAMPLE_RATE = 48000; constexpr int VOICE_FRAME_SIZE = 960; diff --git a/source/game/CMakeLists.txt b/source/game/CMakeLists.txt index 4886c48..b209acf 100644 --- a/source/game/CMakeLists.txt +++ b/source/game/CMakeLists.txt @@ -507,4 +507,7 @@ SET (star_game_SOURCES ) ADD_LIBRARY (star_game OBJECT ${star_game_SOURCES} ${star_game_HEADERS}) -TARGET_PRECOMPILE_HEADERS (star_game REUSE_FROM star_core)
\ No newline at end of file + +IF(STAR_PRECOMPILED_HEADERS) + TARGET_PRECOMPILE_HEADERS (star_game REUSE_FROM star_core) +ENDIF()
\ No newline at end of file diff --git a/source/game/StarPlayerStorage.cpp b/source/game/StarPlayerStorage.cpp index 72932f1..1946ce2 100644 --- a/source/game/StarPlayerStorage.cpp +++ b/source/game/StarPlayerStorage.cpp @@ -14,7 +14,7 @@ namespace Star { PlayerStorage::PlayerStorage(String const& storageDir) { m_storageDirectory = storageDir; - m_backupDirectory = File::relativeTo(m_storageDirectory, File::convertDirSeparators("backup")); + m_backupDirectory = File::relativeTo(m_storageDirectory, "backup"); if (!File::isDirectory(m_storageDirectory)) { Logger::info("Creating player storage directory"); File::makeDirectory(m_storageDirectory); @@ -257,11 +257,8 @@ void PlayerStorage::backupCycle(Uuid const& uuid) { return File::relativeTo(dir, strf("{}.{}", fileName, extension)); }; - if (!File::isDirectory(m_backupDirectory)) { - Logger::info("Creating player backup directory"); + if (!File::isDirectory(m_backupDirectory)) File::makeDirectory(m_backupDirectory); - return; - } File::backupFileInSequence(path(m_storageDirectory, "player"), path(m_backupDirectory, "player"), playerBackupFileCount, ".bak"); File::backupFileInSequence(path(m_storageDirectory, "shipworld"), path(m_backupDirectory, "shipworld"), playerBackupFileCount, ".bak"); diff --git a/source/game/StarRoot.cpp b/source/game/StarRoot.cpp index efb5e27..3e5f8f8 100644 --- a/source/game/StarRoot.cpp +++ b/source/game/StarRoot.cpp @@ -88,7 +88,11 @@ Root::Root(Settings settings) { if (m_settings.logFile) { String logFile = toStoragePath(*m_settings.logFile); - File::backupFileInSequence(logFile, m_settings.logFileBackups); + String logDirectory = File::relativeTo(m_settings.storageDirectory, "logs"); + if (!File::isDirectory(logDirectory)) + File::makeDirectory(logDirectory); + + File::backupFileInSequence(logFile, File::relativeTo(logDirectory, *m_settings.logFile), m_settings.logFileBackups); Logger::addSink(make_shared<FileLogSink>(logFile, m_settings.logLevel, true)); } Logger::stdoutSink()->setLevel(m_settings.logLevel); @@ -96,7 +100,7 @@ Root::Root(Settings settings) { if (m_settings.quiet) Logger::removeStdoutSink(); - Logger::info("Root: Preparing Root..."); + Logger::info("Root: Preparing..."); m_stopMaintenanceThread = false; m_maintenanceThread = Thread::invoke("Root::maintenanceMain", [this]() { @@ -374,8 +378,9 @@ AssetsConstPtr Root::assets() { return loadMemberFunction<Assets>(m_assets, m_assetsMutex, "Assets", [this]() { StringList assetDirectories = m_settings.assetDirectories; assetDirectories.appendAll(m_modDirectories); + StringList assetSources = scanForAssetSources(assetDirectories, m_settings.assetSources); - auto assets = make_shared<Assets>(m_settings.assetsSettings, scanForAssetSources(assetDirectories)); + auto assets = make_shared<Assets>(m_settings.assetsSettings, assetSources); Logger::info("Assets digest is {}", hexEncode(assets->digest())); return assets; }); @@ -571,7 +576,7 @@ CollectionDatabaseConstPtr Root::collectionDatabase() { return loadMember(m_collectionDatabase, m_collectionDatabaseMutex, "CollectionDatabase"); } -StringList Root::scanForAssetSources(StringList const& directories) { +StringList Root::scanForAssetSources(StringList const& directories, StringList const& manual) { struct AssetSource { String path; Maybe<String> name; @@ -582,6 +587,51 @@ StringList Root::scanForAssetSources(StringList const& directories) { List<shared_ptr<AssetSource>> assetSources; StringMap<shared_ptr<AssetSource>> namedSources; + auto processEntry = [&](String const& sourcePath, bool isDirectory) -> bool { + AssetSourcePtr source; + auto name = File::baseName(sourcePath); + if (name.beginsWith(".") || name.beginsWith("_")) + Logger::info("Root: Skipping hidden '{}' in asset directory", name); + else if (isDirectory) + source = make_shared<DirectoryAssetSource>(sourcePath); + else if (sourcePath.endsWith(".pak")) + source = make_shared<PackedAssetSource>(sourcePath); + else + Logger::warn("Root: Unrecognized file in asset directory '{}', skipping", name); + + if (!source) + return false; + + auto metadata = source->metadata(); + + auto assetSource = make_shared<AssetSource>(); + assetSource->path = sourcePath; + assetSource->name = metadata.maybe("name").apply(mem_fn(&Json::toString)); + assetSource->priority = metadata.value("priority", 0.0f).toFloat(); + assetSource->requires_ = jsonToStringList(metadata.value("requires", JsonArray{})); + assetSource->includes = jsonToStringList(metadata.value("includes", JsonArray{})); + + if (assetSource->name) { + if (auto oldAssetSource = namedSources.value(*assetSource->name)) { + if (oldAssetSource->priority <= assetSource->priority) { + Logger::warn("Root: Overriding duplicate asset source '{}' named '{}' with higher or equal priority source '{}", + oldAssetSource->path, *assetSource->name, assetSource->path); + *oldAssetSource = *assetSource; + } else { + Logger::warn("Root: Skipping duplicate asset source '{}' named '{}', previous source '{}' has higher priority", + assetSource->path, *assetSource->name, oldAssetSource->priority); + } + } else { + namedSources[*assetSource->name] = assetSource; + assetSources.append(std::move(assetSource)); + } + } else { + assetSources.append(std::move(assetSource)); + } + + return true; + }; + // Scan for assets in each given directory, the first-level ordering of asset // sources comes from the scanning order here, and then alphabetically by the // file / directory name @@ -593,51 +643,15 @@ StringList Root::scanForAssetSources(StringList const& directories) { } Logger::info("Root: Scanning for asset sources in directory '{}'", directory); - - for (auto entry : File::dirList(directory, true).sorted()) { - AssetSourcePtr source; - auto fileName = File::relativeTo(directory, entry.first); - if (entry.first.beginsWith(".") || entry.first.beginsWith("_")) - Logger::info("Root: Skipping hidden '{}' in asset directory", entry.first); - else if (entry.second) - source = make_shared<DirectoryAssetSource>(fileName); - else if (entry.first.endsWith(".pak")) - source = make_shared<PackedAssetSource>(fileName); - else - Logger::warn("Root: Unrecognized file in asset directory '{}', skipping", entry.first); - - if (!source) - continue; - - auto metadata = source->metadata(); - - auto assetSource = make_shared<AssetSource>(); - assetSource->path = fileName; - assetSource->name = metadata.maybe("name").apply(mem_fn(&Json::toString)); - assetSource->priority = metadata.value("priority", 0.0f).toFloat(); - assetSource->requires_ = jsonToStringList(metadata.value("requires", JsonArray{})); - assetSource->includes = jsonToStringList(metadata.value("includes", JsonArray{})); - - if (assetSource->name) { - if (auto oldAssetSource = namedSources.value(*assetSource->name)) { - if (oldAssetSource->priority <= assetSource->priority) { - Logger::warn("Root: Overriding duplicate asset source '{}' named '{}' with higher or equal priority source '{}", - oldAssetSource->path, *assetSource->name, assetSource->path); - *oldAssetSource = *assetSource; - } else { - Logger::warn("Root: Skipping duplicate asset source '{}' named '{}', previous source '{}' has higher priority", - assetSource->path, *assetSource->name, oldAssetSource->priority); - } - } else { - namedSources[*assetSource->name] = assetSource; - assetSources.append(std::move(assetSource)); - } - } else { - assetSources.append(std::move(assetSource)); - } - } + for (auto& entry : File::dirList(directory, true).sorted()) + processEntry(File::relativeTo(directory, entry.first), entry.second); } + // Take in any manual asset source paths + + for (auto& path : manual) + processEntry(path, File::isDirectory(path)); + // Then, order asset sources so that lower priority assets come before higher // priority ones diff --git a/source/game/StarRoot.hpp b/source/game/StarRoot.hpp index b60dfca..576fe41 100644 --- a/source/game/StarRoot.hpp +++ b/source/game/StarRoot.hpp @@ -66,6 +66,9 @@ public: // Asset sources are scanned for in the given directories, in order. StringList assetDirectories; + // Just raw asset source paths. + StringList assetSources; + Json defaultConfiguration; // Top-level storage directory under which all game data is saved @@ -179,7 +182,7 @@ public: CollectionDatabaseConstPtr collectionDatabase(); private: - static StringList scanForAssetSources(StringList const& directories); + static StringList scanForAssetSources(StringList const& directories, StringList const& manual = {}); template <typename T, typename... Params> static shared_ptr<T> loadMember(shared_ptr<T>& ptr, Mutex& mutex, char const* name, Params&&... params); template <typename T> diff --git a/source/game/StarRootLoader.cpp b/source/game/StarRootLoader.cpp index f6843f3..f1e005f 100644 --- a/source/game/StarRootLoader.cpp +++ b/source/game/StarRootLoader.cpp @@ -41,8 +41,19 @@ Json const BaseDefaultConfiguration = Json::parseJson(R"JSON( }, "gameServerPort" : 21025, +)JSON" +#ifdef STAR_SYSTEM_WINDOWS + R"JSON( + "gameServerBind" : "*", + "queryServerBind" : "*", + "rconServerBind" : "*", +)JSON" +#else + R"JSON( "gameServerBind" : "::", - +)JSON" +#endif +R"JSON( "serverUsers" : {}, "allowAnonymousConnections" : true, @@ -152,19 +163,11 @@ Root::Settings RootLoader::rootSettingsForOptions(Options const& options) const rootSettings.assetsSettings.pathIgnore = jsonToStringList(assetsSettings.get("pathIgnore")); rootSettings.assetsSettings.digestIgnore = jsonToStringList(assetsSettings.get("digestIgnore")); - rootSettings.assetDirectories = jsonToStringList(bootConfig.get("assetDirectories")); - -#ifdef STAR_SYSTEM_WINDOWS - rootSettings.defaultConfiguration = BaseDefaultConfiguration - .set("gameServerBind", "*") - .set("queryServerBind", "*") - .set("rconServerBind", "*"); -#else - rootSettings.defaultConfiguration = BaseDefaultConfiguration; -#endif + rootSettings.assetDirectories = jsonToStringList(bootConfig.get("assetDirectories", JsonArray())); + rootSettings.assetSources = jsonToStringList(bootConfig.get("assetSources", JsonArray())); rootSettings.defaultConfiguration = jsonMerge( - rootSettings.defaultConfiguration, + BaseDefaultConfiguration, m_defaults.additionalDefaultConfiguration, bootConfig.get("defaultConfiguration", {}) ); @@ -172,7 +175,7 @@ Root::Settings RootLoader::rootSettingsForOptions(Options const& options) const rootSettings.storageDirectory = bootConfig.getString("storageDirectory"); rootSettings.logFile = options.parameters.value("logfile").maybeFirst().orMaybe(m_defaults.logFile); - rootSettings.logFileBackups = bootConfig.getUInt("logFileBackups", 5); + rootSettings.logFileBackups = bootConfig.getUInt("logFileBackups", 10); if (auto ll = options.parameters.value("loglevel").maybeFirst()) rootSettings.logLevel = LogLevelNames.getLeft(*ll); diff --git a/source/rendering/CMakeLists.txt b/source/rendering/CMakeLists.txt index c683daa..401f16e 100644 --- a/source/rendering/CMakeLists.txt +++ b/source/rendering/CMakeLists.txt @@ -33,4 +33,7 @@ SET (star_rendering_SOURCES ) ADD_LIBRARY (star_rendering OBJECT ${star_rendering_SOURCES} ${star_rendering_HEADERS}) -TARGET_PRECOMPILE_HEADERS (star_rendering REUSE_FROM star_core)
\ No newline at end of file + +IF(STAR_PRECOMPILED_HEADERS) + TARGET_PRECOMPILE_HEADERS (star_rendering REUSE_FROM star_core) +ENDIF()
\ No newline at end of file diff --git a/source/server/CMakeLists.txt b/source/server/CMakeLists.txt index 98c1179..697aca3 100644 --- a/source/server/CMakeLists.txt +++ b/source/server/CMakeLists.txt @@ -22,5 +22,9 @@ SET (star_server_SOURCES ADD_EXECUTABLE (starbound_server $<TARGET_OBJECTS:star_extern> $<TARGET_OBJECTS:star_core> $<TARGET_OBJECTS:star_base> $<TARGET_OBJECTS:star_game> ${star_server_HEADERS} ${star_server_SOURCES}) -TARGET_PRECOMPILE_HEADERS (starbound_server REUSE_FROM star_core) + +IF(STAR_PRECOMPILED_HEADERS) + TARGET_PRECOMPILE_HEADERS (starbound_server REUSE_FROM star_core) +ENDIF() + TARGET_LINK_LIBRARIES (starbound_server ${STAR_EXT_LIBS})
\ No newline at end of file diff --git a/source/vcpkg-configuration.json b/source/vcpkg-configuration.json index a11399f..ad33dd2 100644 --- a/source/vcpkg-configuration.json +++ b/source/vcpkg-configuration.json @@ -1,8 +1,8 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg-configuration.schema.json", - "default-registry": { - "kind": "git", - "baseline": "638b1588be3a265a9c7ad5b212cef72a1cad336a", - "repository": "https://github.com/microsoft/vcpkg" - } + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg-configuration.schema.json", + "default-registry": { + "kind": "git", + "baseline": "fba75d09065fcc76a25dcf386b1d00d33f5175af", + "repository": "https://github.com/microsoft/vcpkg" + } }
\ No newline at end of file diff --git a/source/vcpkg.json b/source/vcpkg.json index 7b396a2..1e0942c 100644 --- a/source/vcpkg.json +++ b/source/vcpkg.json @@ -1,11 +1,12 @@ { - "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", - "dependencies": [ - "glew", - "sdl2", - "libvorbis", - "zlib", - "freetype", - "libpng" - ] + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", + "dependencies": [ + "glew", + "sdl2", + "libvorbis", + "zlib", + "freetype", + "libpng", + "opus" + ] }
\ No newline at end of file |