From 3bec50abbb8bb4c4166c4e66cab8d21cc22bb6d5 Mon Sep 17 00:00:00 2001 From: Erik Kundiman Date: Thu, 7 Aug 2025 11:00:14 +0800 Subject: Rich Presence w/o requiring access to friends list Thank you Signal Linden for the pointer from https://discord.com/developers/docs/social-sdk/classdiscordpp_1_1Client.html#af0a85e30f2b3d8a0b502fd23744ee58e "Note: On Desktop, rich presence can be set before calling Client::Connect, but it will be cleared if the Client connects. When Client is not connected, this sets the rich presence in the current user's Discord client when available." This lead me to setting the Application ID here https://discord.com/developers/docs/social-sdk/classdiscordpp_1_1Client.html#ad452335c06b28be0406dab824acccc49 in place of setting it on https://discord.com/developers/docs/social-sdk/classdiscordpp_1_1AuthorizationArgs.html which would lead Authorize, GetToken, UpdateToken, Connect, and so on. This means we don't even need the SecAPI saveCredential, loadCredential and deleteCredential parts now. --- indra/newview/llappviewer.cpp | 97 ++++--------------------------------------- 1 file changed, 9 insertions(+), 88 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8dec75e64e..c9bdc29bea 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -5933,100 +5933,21 @@ void LLAppViewer::initDiscordSocial() gDiscordPartyMaxSize = 0; gDiscordTimestampsStart = time(nullptr); gDiscordClient = std::make_shared(); - gDiscordClient->SetStatusChangedCallback([](discordpp::Client::Status status, discordpp::Client::Error, int32_t) { - if (status == discordpp::Client::Status::Ready) - { - updateDiscordActivity(); - } - }); - if (gSavedSettings.getBOOL("EnableDiscord")) - { - auto credential = gSecAPIHandler->loadCredential("Discord"); - if (credential.notNull()) - { - gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, credential->getAuthenticator()["token"].asString(), [](discordpp::ClientResult result) { - if (result.Successful()) - gDiscordClient->Connect(); - else - LL_WARNS("Discord") << result.Error() << LL_ENDL; - }); - } - else - { - LL_WARNS("Discord") << "Integration was enabled, but no credentials. Disabling integration." << LL_ENDL; - gSavedSettings.setBOOL("EnableDiscord", false); - } - } + gDiscordClient->SetApplicationId(1393451183741599796); + updateDiscordActivity(); } -void LLAppViewer::toggleDiscordIntegration(const LLSD& value) +void LLAppViewer::updateDiscordActivity() { - static const uint64_t APPLICATION_ID = 1393451183741599796; - if (value.asBoolean()) - { - discordpp::AuthorizationArgs args{}; - args.SetClientId(APPLICATION_ID); - args.SetScopes(discordpp::Client::GetDefaultPresenceScopes()); - auto codeVerifier = gDiscordClient->CreateAuthorizationCodeVerifier(); - args.SetCodeChallenge(codeVerifier.Challenge()); - gDiscordClient->Authorize(args, [codeVerifier](auto result, auto code, auto redirectUri) { - if (result.Successful()) - { - gDiscordClient->GetToken(APPLICATION_ID, code, codeVerifier.Verifier(), redirectUri, [](discordpp::ClientResult result, std::string accessToken, std::string, discordpp::AuthorizationTokenType, int32_t, std::string) { - if (result.Successful()) - { - gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, accessToken, [accessToken](discordpp::ClientResult result) { - if (result.Successful()) - { - LLSD authenticator = LLSD::emptyMap(); - authenticator["token"] = accessToken; - gSecAPIHandler->saveCredential(gSecAPIHandler->createCredential("Discord", LLSD::emptyMap(), authenticator), true); - gDiscordClient->Connect(); - } - else - { - LL_WARNS("Discord") << result.Error() << LL_ENDL; - } - }); - } - else - { - LL_WARNS("Discord") << result.Error() << LL_ENDL; - } - }); - } - else - { - LL_WARNS("Discord") << result.Error() << LL_ENDL; - gSavedSettings.setBOOL("EnableDiscord", false); - } - }); - } - else + LL_PROFILE_ZONE_SCOPED; + + static LLCachedControl integration_enabled(gSavedSettings, "EnableDiscord", true); + if (!integration_enabled) { - gDiscordClient->Disconnect(); - auto credential = gSecAPIHandler->loadCredential("Discord"); - if (credential.notNull()) - { - gDiscordClient->RevokeToken(APPLICATION_ID, credential->getAuthenticator()["token"].asString(), [](discordpp::ClientResult result) { - if (result.Successful()) - LL_INFOS("Discord") << "Access token successfully revoked." << LL_ENDL; - else - LL_WARNS("Discord") << "No access token to revoke." << LL_ENDL; - }); - auto cred = new LLCredential("Discord"); - gSecAPIHandler->deleteCredential(cred); - } - else - { - LL_WARNS("Discord") << "Credentials are already nonexistent." << LL_ENDL; - } + gDiscordClient->ClearRichPresence(); + return; } -} -void LLAppViewer::updateDiscordActivity() -{ - LL_PROFILE_ZONE_SCOPED; discordpp::Activity activity; activity.SetType(discordpp::ActivityTypes::Playing); discordpp::ActivityTimestamps timestamps; -- cgit v1.2.3 From 2516f0229c84795d8427a2c223ef4081e443c81b Mon Sep 17 00:00:00 2001 From: Erik Kundiman Date: Thu, 7 Aug 2025 11:13:05 +0800 Subject: "Hidden Region" if Discord location sharing is off instead of blank. The coords are hidden too, but the Party numbers are still shown, for consistency with TPVs' implementations. --- indra/newview/llappviewer.cpp | 56 ++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 27 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c9bdc29bea..3e1e07ceae 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -5975,37 +5975,39 @@ void LLAppViewer::updateDiscordActivity() activity.SetDetails(gDiscordActivityDetails); } + auto agent_pos_region = gAgent.getPositionAgent(); + S32 pos_x = S32(agent_pos_region.mV[VX] + 0.5f); + S32 pos_y = S32(agent_pos_region.mV[VY] + 0.5f); + S32 pos_z = S32(agent_pos_region.mV[VZ] + 0.5f); + F32 velocity_mag_sq = gAgent.getVelocity().magVecSquared(); + const F32 FLY_CUTOFF = 6.f; + const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF; + const F32 WALK_CUTOFF = 1.5f; + const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF; + if (velocity_mag_sq > FLY_CUTOFF_SQ) + { + pos_x -= pos_x % 4; + pos_y -= pos_y % 4; + } + else if (velocity_mag_sq > WALK_CUTOFF_SQ) + { + pos_x -= pos_x % 2; + pos_y -= pos_y % 2; + } + + std::string location = "Hidden Region"; static LLCachedControl show_state(gSavedSettings, "ShowDiscordActivityState", false); if (show_state) { - auto agent_pos_region = gAgent.getPositionAgent(); - S32 pos_x = S32(agent_pos_region.mV[VX] + 0.5f); - S32 pos_y = S32(agent_pos_region.mV[VY] + 0.5f); - S32 pos_z = S32(agent_pos_region.mV[VZ] + 0.5f); - F32 velocity_mag_sq = gAgent.getVelocity().magVecSquared(); - const F32 FLY_CUTOFF = 6.f; - const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF; - const F32 WALK_CUTOFF = 1.5f; - const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF; - if (velocity_mag_sq > FLY_CUTOFF_SQ) - { - pos_x -= pos_x % 4; - pos_y -= pos_y % 4; - } - else if (velocity_mag_sq > WALK_CUTOFF_SQ) - { - pos_x -= pos_x % 2; - pos_y -= pos_y % 2; - } - auto location = llformat("%s (%d, %d, %d)", gAgent.getRegion()->getName().c_str(), pos_x, pos_y, pos_z); - activity.SetState(location); - - discordpp::ActivityParty party; - party.SetId(location); - party.SetCurrentSize(gDiscordPartyCurrentSize); - party.SetMaxSize(gDiscordPartyMaxSize); - activity.SetParty(party); + location = llformat("%s (%d, %d, %d)", gAgent.getRegion()->getName().c_str(), pos_x, pos_y, pos_z); } + activity.SetState(location); + + discordpp::ActivityParty party; + party.SetId(location); + party.SetCurrentSize(gDiscordPartyCurrentSize); + party.SetMaxSize(gDiscordPartyMaxSize); + activity.SetParty(party); gDiscordClient->UpdateRichPresence(activity, [](discordpp::ClientResult) {}); } -- cgit v1.2.3