diff options
author | Erik Kundiman <erik@megapahit.org> | 2025-07-12 21:49:15 +0800 |
---|---|---|
committer | Erik Kundiman <erik@megapahit.org> | 2025-07-12 21:49:15 +0800 |
commit | 74b0178b7b4d672c7f6b317102b0ecd26f1ea033 (patch) | |
tree | 64f0f01a6b47b534c42d7f4b085b8724e639937a | |
parent | b1d2961edb593393da5ae88e275be7bb2568969b (diff) |
Download DiscordSocialSdk-1.4.9649.zip
https://discord.com/developers/applications/1393451183741599796/social-sdk/downloads
to your ~/Downloads folder.
Add -DUSE_DISCORD:BOOL=ON to your cmake line.
The authorisation is triggered by selecting Help > Discord Social.
It seems that the user will need to do this every time they want Rich
Presence support on the viewer while using Discord.
The Discord app is still set to be a public client in the OAuth2 tab,
I'm going to try to make it work with the app set to be a confidential
client, next.
All Discord-related code are contained within one file, llstartup.cpp,
and other classes access it through some opaque layer, static functions,
otherwise we'd get these "duplicate symbol" linking errors.
-rw-r--r-- | indra/cmake/CMakeLists.txt | 1 | ||||
-rw-r--r-- | indra/cmake/Discord.cmake | 45 | ||||
-rw-r--r-- | indra/newview/CMakeLists.txt | 7 | ||||
-rw-r--r-- | indra/newview/FixBundle.cmake.in | 1 | ||||
-rw-r--r-- | indra/newview/FixPackage.cmake.in | 1 | ||||
-rw-r--r-- | indra/newview/ViewerInstall.cmake | 13 | ||||
-rw-r--r-- | indra/newview/llappviewer.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llstartup.cpp | 45 | ||||
-rw-r--r-- | indra/newview/llstartup.h | 6 | ||||
-rw-r--r-- | indra/newview/llviewermenu.cpp | 10 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_about.xml | 2 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_login.xml | 7 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_viewer.xml | 7 |
13 files changed, 149 insertions, 0 deletions
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 5525ac9f24..a77e0fca06 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -19,6 +19,7 @@ set(cmake_SOURCE_FILES Copy3rdPartyLibs.cmake DBusGlib.cmake DeploySharedLibs.cmake + Discord.cmake DragDrop.cmake EXPAT.cmake FindAutobuild.cmake diff --git a/indra/cmake/Discord.cmake b/indra/cmake/Discord.cmake new file mode 100644 index 0000000000..52c0765ae7 --- /dev/null +++ b/indra/cmake/Discord.cmake @@ -0,0 +1,45 @@ +include(Prebuilt) + +add_library(ll::discord INTERFACE IMPORTED) +target_compile_definitions(ll::discord INTERFACE LL_DISCORD=1) + +if (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/discord_installed OR NOT ${discord_installed} EQUAL 0) + file(ARCHIVE_EXTRACT + INPUT $ENV{HOME}/Downloads/DiscordSocialSdk-1.4.9649.zip + DESTINATION ${CMAKE_BINARY_DIR} + ) + file( + COPY + ${CMAKE_BINARY_DIR}/discord_social_sdk/include/cdiscord.h + ${CMAKE_BINARY_DIR}/discord_social_sdk/include/discordpp.h + DESTINATION ${LIBS_PREBUILT_DIR}/include + ) + if (WINDOWS) + file( + COPY ${CMAKE_BINARY_DIR}/discord_social_sdk/bin/release/discord_partner_sdk.dll + DESTINATION ${LIBS_PREBUILT_DIR}/bin/release + ) + set(LIBRARY_EXTENSION lib) + else () + set(LIBRARY_PREFIX lib) + set(LIBRARY_EXTENSION so) + endif () + if (DARWIN) + execute_process( + COMMAND lipo + libdiscord_partner_sdk.dylib + -thin ${CMAKE_OSX_ARCHITECTURES} + -output ${ARCH_PREBUILT_DIRS_RELEASE}/libdiscord_partner_sdk.dylib + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/discord_social_sdk/lib/release + ) + else () + file( + COPY ${CMAKE_BINARY_DIR}/discord_social_sdk/lib/release/${LIBRARY_PREFIX}discord_partner_sdk.${LIBRARY_EXTENSION} + DESTINATION ${ARCH_PREBUILT_DIRS_RELEASE} + ) + endif () + file(WRITE ${PREBUILD_TRACKING_DIR}/discord_installed "0") +endif () + +target_include_directories(ll::discord SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) +target_link_libraries(ll::discord INTERFACE discord_partner_sdk) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5e9a59a0e5..7f509d38de 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -15,6 +15,9 @@ include(CMakeCopyIfDifferent) include(CubemapToEquirectangularJS) #include(DBusGlib) include(DragDrop) +if (USE_DISCORD) + include(Discord) +endif () include(EXPAT) include(Hunspell) include(JPEGEncoderBasic) @@ -2141,6 +2144,10 @@ if (ENABLE_MEDIA_PLUGINS) endif () endif () +if (USE_DISCORD) + target_link_libraries(${VIEWER_BINARY_NAME} ll::discord ) +endif () + if( TARGET ll::intel_memops ) target_link_libraries(${VIEWER_BINARY_NAME} ll::intel_memops ) endif() diff --git a/indra/newview/FixBundle.cmake.in b/indra/newview/FixBundle.cmake.in index 829c19e5e4..1d460a9b45 100644 --- a/indra/newview/FixBundle.cmake.in +++ b/indra/newview/FixBundle.cmake.in @@ -293,6 +293,7 @@ execute_process( Frameworks/libbrotlicommon.1.1.0.dylib Frameworks/libbrotlidec.1.1.0.dylib Frameworks/libbz2.1.0.8.dylib + Frameworks/libdiscord_partner_sdk.dylib Frameworks/libexpat.1.10.0.dylib Frameworks/libfreetype.6.dylib Frameworks/libhunspell-1.7.0.dylib diff --git a/indra/newview/FixPackage.cmake.in b/indra/newview/FixPackage.cmake.in index 49f7b75b4d..23d52a9ef9 100644 --- a/indra/newview/FixPackage.cmake.in +++ b/indra/newview/FixPackage.cmake.in @@ -293,6 +293,7 @@ execute_process( Frameworks/libbrotlicommon.1.1.0.dylib Frameworks/libbrotlidec.1.1.0.dylib Frameworks/libbz2.1.0.8.dylib + Frameworks/libdiscord_partner_sdk.dylib Frameworks/libexpat.1.10.0.dylib Frameworks/libfreetype.6.dylib Frameworks/libhunspell-1.7.0.dylib diff --git a/indra/newview/ViewerInstall.cmake b/indra/newview/ViewerInstall.cmake index 343c3fb9c7..aaa0c21fa5 100644 --- a/indra/newview/ViewerInstall.cmake +++ b/indra/newview/ViewerInstall.cmake @@ -169,6 +169,13 @@ elseif (WINDOWS) DESTINATION . ) + if (USE_DISCORD) + install( + PROGRAMS ${LIBS_PREBUILT_DIR}/bin/release/discord_partner_sdk.dll + DESTINATION . + ) + endif () + install( PROGRAMS ${prefix_result}/../bin/boost_context-vc143-mt-${BOOST_PLATFORM}-1_88.dll @@ -193,6 +200,12 @@ if (LINUX) else () set(_LIB lib) endif () + if (USE_DISCORD) + install( + FILES ${ARCH_PREBUILT_DIRS_RELEASE}/libdiscord_partner_sdk.so + DESTINATION ${_LIB} + ) + endif () if (USE_FMODSTUDIO) install(FILES ${ARCH_PREBUILT_DIRS_RELEASE}/libfmod.so diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d9596164eb..419d2cb842 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1348,6 +1348,10 @@ bool LLAppViewer::doFrame() U64 fpsLimitSleepFor = 0; TimePoint fpsLimitFrameStartTime = std::chrono::steady_clock::now(); +#ifdef LL_DISCORD + LLStartUp::runDiscordCallbacks(); +#endif + LL_RECORD_BLOCK_TIME(FTM_FRAME); { // and now adjust the visuals from previous frame. diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 3450792d30..834b99555e 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -217,6 +217,11 @@ #include "fsfloatersearch.h" +#ifdef LL_DISCORD +#define DISCORDPP_IMPLEMENTATION +#include <discordpp.h> +static std::shared_ptr<discordpp::Client> gDiscordClient; +#endif // // exported globals @@ -752,6 +757,17 @@ bool idle_startup() LL_WARNS("AppInit") << "Unreliable timers detected (may be bad PCI chipset)!!" << LL_ENDL; } +#ifdef LL_DISCORD + gDiscordClient = std::make_shared<discordpp::Client>(); + gDiscordClient->SetStatusChangedCallback([](discordpp::Client::Status status, discordpp::Client::Error, int32_t) { + if (status == discordpp::Client::Status::Ready) { + discordpp::Activity activity; + activity.SetType(discordpp::ActivityTypes::Playing); + gDiscordClient->UpdateRichPresence(activity, [](discordpp::ClientResult) {}); + } + }); +#endif + // // Log on to system // @@ -3431,6 +3447,35 @@ bool LLStartUp::startLLProxy() return proxy_ok; } +#ifdef LL_DISCORD + +void LLStartUp::runDiscordCallbacks() +{ + discordpp::RunCallbacks(); +} + +void LLStartUp::handleDiscordSocial() +{ + static const uint64_t DISCORD_APPLICATION_ID = 1393451183741599796; + discordpp::AuthorizationArgs discordAuthArgs{}; + discordAuthArgs.SetClientId(DISCORD_APPLICATION_ID); + discordAuthArgs.SetScopes(discordpp::Client::GetDefaultPresenceScopes()); + auto discordCodeVerifier = gDiscordClient->CreateAuthorizationCodeVerifier(); + discordAuthArgs.SetCodeChallenge(discordCodeVerifier.Challenge()); + gDiscordClient->Authorize(discordAuthArgs, [discordCodeVerifier](auto result, auto code, auto redirectUri) { + if (result.Successful()) { + gDiscordClient->GetToken(DISCORD_APPLICATION_ID, code, discordCodeVerifier.Verifier(), redirectUri, [](discordpp::ClientResult result, std::string accessToken, std::string, discordpp::AuthorizationTokenType, int32_t, std::string) { + gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, accessToken, [](discordpp::ClientResult result) { + if (result.Successful()) + gDiscordClient->Connect(); + }); + }); + } + }); +} + +#endif + bool login_alert_done(const LLSD& notification, const LLSD& response) { LLPanelLogin::giveFocus(); diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index a827fbc487..cf1d38bb18 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -128,6 +128,12 @@ public: static bool startLLProxy(); // Initialize the SOCKS 5 proxy static LLViewerStats::PhaseMap& getPhases() { return *sPhases; } + +#ifdef LL_DISCORD + static void runDiscordCallbacks(); + static void handleDiscordSocial(); +#endif + private: friend class LLStartupListener; static LLSLURL sStartSLURL; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c3bb8ef4c4..4383fc87e5 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -8942,6 +8942,13 @@ void handle_report_bug(const LLSD& param) LLWeb::loadURLExternal(url); } +#ifdef LL_DISCORD +void handle_discord_social(const LLSD& param) +{ + LLStartUp::handleDiscordSocial(); +} +#endif + void handle_buy_currency_test() { std::string url = @@ -9920,6 +9927,9 @@ void initialize_menus() commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2)); // this one opens the Web Content floater commit.add("Advanced.ShowURL", boost::bind(&handle_show_url, _2)); commit.add("Advanced.ReportBug", boost::bind(&handle_report_bug, _2)); +#ifdef LL_DISCORD + commit.add("Advanced.DiscordSocial", boost::bind(&handle_discord_social, _2)); +#endif view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest"); view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr"); view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory"); diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index a251b3c5c5..8b92b83472 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -206,6 +206,8 @@ Collada DOM Copyright 2006 Sony Computer Entertainment Inc. cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) +Discord Social SDK Copyright (c) 2025, Discord, Inc. + expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 5fff9b7bc0..04514e8a52 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -110,6 +110,13 @@ </menu_item_call> <menu_item_separator/> <menu_item_call + label="Discord Social" + name="Discord Social"> + <menu_item_call.on_click + function="Advanced.DiscordSocial"/> + </menu_item_call> + <menu_item_separator/> + <menu_item_call label="About [APP_NAME]" name="About Second Life"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 1ec59bf2eb..56261ce874 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1818,6 +1818,13 @@ function="World.EnvPreset" </menu_item_call> <menu_item_separator/> + <menu_item_call + label="Discord Social" + name="Discord Social"> + <menu_item_call.on_click + function="Advanced.DiscordSocial"/> + </menu_item_call> + <menu_item_separator/> <menu_item_call label="Bumps, Pushes & Hits" name="Bumps, Pushes &amp; Hits"> |