From c86b7309d44f91824f3f8a2f6941bf6fe9f5c804 Mon Sep 17 00:00:00 2001 From: Silent Date: Sat, 19 Jun 2021 14:13:10 +0200 Subject: [PATCH] Show RetroAchievements rich presence in Discord-RPC --- src/frontend-common/cheevos.cpp | 10 +++-- src/frontend-common/common_host_interface.cpp | 42 +++++++++++++++++-- src/frontend-common/common_host_interface.h | 5 ++- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/frontend-common/cheevos.cpp b/src/frontend-common/cheevos.cpp index 34ac35a22..0a76163e4 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(); @@ -287,6 +288,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) @@ -614,6 +617,7 @@ static void GetUserUnlocksCallback(s32 status_code, const FrontendCommon::HTTPDo ActivateLockedAchievements(); DisplayAchievementSummary(); SendPlaying(); + UpdateRichPresence(); SendPing(); GetHostInterface()->OnAchievementsRefreshed(); } @@ -1022,6 +1026,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) @@ -1053,9 +1060,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 f0e178346..58b0e5666 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 @@ -3763,7 +3763,7 @@ void CommonHostInterface::InitializeDiscordPresence() Discord_Initialize("705325712680288296", &handlers, 0, nullptr); m_discord_presence_active = true; - UpdateDiscordPresence(); + UpdateDiscordPresence(false); } void CommonHostInterface::ShutdownDiscordPresence() @@ -3774,13 +3774,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"; @@ -3798,6 +3816,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); @@ -3808,6 +3842,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 };