diff --git a/src/frontend-common/cheevos.cpp b/src/frontend-common/cheevos.cpp index 674a7b1c2..45d5d877f 100644 --- a/src/frontend-common/cheevos.cpp +++ b/src/frontend-common/cheevos.cpp @@ -45,6 +45,7 @@ static bool ActivateAchievement(Achievement* achievement); static void DeactivateAchievement(Achievement* achievement); static void SendPing(); static void SendPlaying(); +static void UpdateRichPresence(); /// Uses a temporarily (second) CD image to resolve the hash. static void GameChanged(); @@ -306,6 +307,8 @@ void Update() if (!s_test_mode) { + UpdateRichPresence(); + const s32 ping_frequency = s_rich_presence_enabled ? RICH_PRESENCE_PING_FREQUENCY : NO_RICH_PRESENCE_PING_FREQUENCY; if (static_cast(s_last_ping_time.GetTimeSeconds()) >= ping_frequency) @@ -633,6 +636,7 @@ static void GetUserUnlocksCallback(s32 status_code, const FrontendCommon::HTTPDo ActivateLockedAchievements(); DisplayAchievementSummary(); SendPlaying(); + UpdateRichPresence(); SendPing(); GetHostInterface()->OnAchievementsRefreshed(); } @@ -1045,6 +1049,9 @@ void SendPlaying() static void UpdateRichPresence() { + if (!s_has_rich_presence) + return; + char buffer[512]; int res = rc_runtime_get_richpresence(&s_rcheevos_runtime, buffer, sizeof(buffer), CheevosPeek, nullptr, nullptr); if (res <= 0) @@ -1076,9 +1083,6 @@ void SendPing() if (!HasActiveGame()) return; - if (s_has_rich_presence) - UpdateRichPresence(); - char url[512]; char post_data[512]; int res = rc_url_ping(url, sizeof(url), post_data, sizeof(post_data), s_username.c_str(), s_login_token.c_str(), diff --git a/src/frontend-common/common_host_interface.cpp b/src/frontend-common/common_host_interface.cpp index 4f0a85d36..fddcec324 100644 --- a/src/frontend-common/common_host_interface.cpp +++ b/src/frontend-common/common_host_interface.cpp @@ -1028,7 +1028,7 @@ void CommonHostInterface::OnRunningGameChanged(const std::string& path, CDImage* } #ifdef WITH_DISCORD_PRESENCE - UpdateDiscordPresence(); + UpdateDiscordPresence(false); #endif #ifdef WITH_CHEEVOS @@ -3764,7 +3764,7 @@ void CommonHostInterface::InitializeDiscordPresence() Discord_Initialize("705325712680288296", &handlers, 0, nullptr); m_discord_presence_active = true; - UpdateDiscordPresence(); + UpdateDiscordPresence(false); } void CommonHostInterface::ShutdownDiscordPresence() @@ -3775,13 +3775,31 @@ void CommonHostInterface::ShutdownDiscordPresence() Discord_ClearPresence(); Discord_Shutdown(); m_discord_presence_active = false; +#ifdef WITH_CHEEVOS + m_discord_presence_cheevos_string.clear(); +#endif } -void CommonHostInterface::UpdateDiscordPresence() +void CommonHostInterface::UpdateDiscordPresence(bool rich_presence_only) { if (!m_discord_presence_active) return; +#ifdef WITH_CHEEVOS + // Update only if RetroAchievements rich presence has changed + const std::string& new_rich_presence = Cheevos::GetRichPresenceString(); + if (new_rich_presence == m_discord_presence_cheevos_string && rich_presence_only) + { + return; + } + m_discord_presence_cheevos_string = new_rich_presence; +#else + if (rich_presence_only) + { + return; + } +#endif + // https://discord.com/developers/docs/rich-presence/how-to#updating-presence-update-presence-payload-fields DiscordRichPresence rp = {}; rp.largeImageKey = "duckstation_logo"; @@ -3799,6 +3817,22 @@ void CommonHostInterface::UpdateDiscordPresence() details_string.AppendString("No Game Running"); } +#ifdef WITH_CHEEVOS + SmallString state_string; + // Trim to 128 bytes as per Discord-RPC requirements + if (m_discord_presence_cheevos_string.length() >= 128) + { + // 124 characters + 3 dots + null terminator + state_string = m_discord_presence_cheevos_string.substr(0, 124); + state_string.AppendString("..."); + } + else + { + state_string = m_discord_presence_cheevos_string; + } + + rp.state = state_string; +#endif rp.details = details_string; Discord_UpdatePresence(&rp); @@ -3809,6 +3843,8 @@ void CommonHostInterface::PollDiscordPresence() if (!m_discord_presence_active) return; + UpdateDiscordPresence(true); + Discord_RunCallbacks(); } diff --git a/src/frontend-common/common_host_interface.h b/src/frontend-common/common_host_interface.h index fea38c842..e85d6df05 100644 --- a/src/frontend-common/common_host_interface.h +++ b/src/frontend-common/common_host_interface.h @@ -502,7 +502,7 @@ private: void SetDiscordPresenceEnabled(bool enabled); void InitializeDiscordPresence(); void ShutdownDiscordPresence(); - void UpdateDiscordPresence(); + void UpdateDiscordPresence(bool rich_presence_only); void PollDiscordPresence(); #endif @@ -551,5 +551,8 @@ private: // discord rich presence bool m_discord_presence_enabled = false; bool m_discord_presence_active = false; +#ifdef WITH_CHEEVOS + std::string m_discord_presence_cheevos_string; +#endif #endif };