diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index c1b7e92c58..b1b63726b3 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -22,6 +22,7 @@ #include "Core/PowerPC/MMU.h" #include "Core/System.h" #include "DiscIO/Blob.h" +#include "UICommon/DiscordPresence.h" #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/VideoEvents.h" @@ -227,6 +228,8 @@ void AchievementManager::DoFrame() m_last_rp_time = current_time; rc_client_get_rich_presence_message(m_client, m_rich_presence.data(), RP_SIZE); m_update_callback(UpdatedItems{.rich_presence = true}); + if (Config::Get(Config::RA_DISCORD_PRESENCE_ENABLED)) + Discord::UpdateDiscordPresence(); } } diff --git a/Source/Core/Core/Config/AchievementSettings.cpp b/Source/Core/Core/Config/AchievementSettings.cpp index 38a5bb6166..1e20729bdd 100644 --- a/Source/Core/Core/Config/AchievementSettings.cpp +++ b/Source/Core/Core/Config/AchievementSettings.cpp @@ -22,6 +22,8 @@ const Info RA_UNOFFICIAL_ENABLED{{System::Achievements, "Achievements", "U const Info RA_ENCORE_ENABLED{{System::Achievements, "Achievements", "EncoreEnabled"}, false}; const Info RA_SPECTATOR_ENABLED{{System::Achievements, "Achievements", "SpectatorEnabled"}, false}; +const Info RA_DISCORD_PRESENCE_ENABLED{ + {System::Achievements, "Achievements", "DiscordPresenceEnabled"}, false}; const Info RA_PROGRESS_ENABLED{{System::Achievements, "Achievements", "ProgressEnabled"}, false}; const Info RA_BADGES_ENABLED{{System::Achievements, "Achievements", "BadgesEnabled"}, false}; diff --git a/Source/Core/Core/Config/AchievementSettings.h b/Source/Core/Core/Config/AchievementSettings.h index e448054214..ae2ecbc8b6 100644 --- a/Source/Core/Core/Config/AchievementSettings.h +++ b/Source/Core/Core/Config/AchievementSettings.h @@ -18,6 +18,7 @@ extern const Info RA_HARDCORE_ENABLED; extern const Info RA_UNOFFICIAL_ENABLED; extern const Info RA_ENCORE_ENABLED; extern const Info RA_SPECTATOR_ENABLED; +extern const Info RA_DISCORD_PRESENCE_ENABLED; extern const Info RA_PROGRESS_ENABLED; extern const Info RA_BADGES_ENABLED; } // namespace Config diff --git a/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp b/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp index 807f321bff..62f6a1e0cb 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp @@ -13,9 +13,11 @@ #include "Core/Config/AchievementSettings.h" #include "Core/Config/FreeLookSettings.h" #include "Core/Config/MainSettings.h" +#include "Core/Config/UISettings.h" #include "Core/Core.h" #include "Core/Movie.h" #include "Core/System.h" +#include "UICommon/DiscordPresence.h" #include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h" #include "DolphinQt/Config/ToolTipControls/ToolTipCheckBox.h" @@ -94,6 +96,10 @@ void AchievementSettingsWidget::CreateLayout() "submitted to the server.

If this is on at game launch, it will not be turned off " "until game close, because a RetroAchievements session will not be created.

If " "this is off at game launch, it can be toggled freely while the game is running.")); + m_common_discord_presence_enabled_input = new ToolTipCheckBox(tr("Enable Discord Presence")); + m_common_discord_presence_enabled_input->SetDescription( + tr("Use RetroAchievements rich presence in your Discord status.

Show Current Game on " + "Discord must be enabled.")); m_common_progress_enabled_input = new ToolTipCheckBox(tr("Enable Progress Notifications")); m_common_progress_enabled_input->SetDescription( tr("Enable progress notifications on achievements.

Displays a brief popup message " @@ -119,6 +125,9 @@ void AchievementSettingsWidget::CreateLayout() m_common_layout->addWidget(m_common_encore_enabled_input); m_common_layout->addWidget(m_common_spectator_enabled_input); m_common_layout->addWidget(new QLabel(tr("Display Settings"))); +#ifdef USE_DISCORD_PRESENCE + m_common_layout->addWidget(m_common_discord_presence_enabled_input); +#endif // USE_DISCORD_PRESENCE m_common_layout->addWidget(m_common_progress_enabled_input); m_common_layout->addWidget(m_common_badges_enabled_input); @@ -140,6 +149,8 @@ void AchievementSettingsWidget::ConnectWidgets() &AchievementSettingsWidget::ToggleEncore); connect(m_common_spectator_enabled_input, &QCheckBox::toggled, this, &AchievementSettingsWidget::ToggleSpectator); + connect(m_common_discord_presence_enabled_input, &QCheckBox::toggled, this, + &AchievementSettingsWidget::ToggleDiscordPresence); connect(m_common_progress_enabled_input, &QCheckBox::toggled, this, &AchievementSettingsWidget::ToggleProgress); connect(m_common_badges_enabled_input, &QCheckBox::toggled, this, @@ -195,6 +206,11 @@ void AchievementSettingsWidget::LoadSettings() ->setChecked(Config::Get(Config::RA_SPECTATOR_ENABLED)); SignalBlocking(m_common_spectator_enabled_input)->setEnabled(enabled); + SignalBlocking(m_common_discord_presence_enabled_input) + ->setChecked(Config::Get(Config::RA_DISCORD_PRESENCE_ENABLED)); + SignalBlocking(m_common_discord_presence_enabled_input) + ->setEnabled(enabled && Config::Get(Config::MAIN_USE_DISCORD_PRESENCE)); + SignalBlocking(m_common_progress_enabled_input) ->setChecked(Config::Get(Config::RA_PROGRESS_ENABLED)); SignalBlocking(m_common_progress_enabled_input)->setEnabled(enabled); @@ -215,6 +231,8 @@ void AchievementSettingsWidget::SaveSettings() Config::SetBaseOrCurrent(Config::RA_ENCORE_ENABLED, m_common_encore_enabled_input->isChecked()); Config::SetBaseOrCurrent(Config::RA_SPECTATOR_ENABLED, m_common_spectator_enabled_input->isChecked()); + Config::SetBaseOrCurrent(Config::RA_DISCORD_PRESENCE_ENABLED, + m_common_discord_presence_enabled_input->isChecked()); Config::SetBaseOrCurrent(Config::RA_PROGRESS_ENABLED, m_common_progress_enabled_input->isChecked()); Config::SetBaseOrCurrent(Config::RA_BADGES_ENABLED, m_common_badges_enabled_input->isChecked()); @@ -279,6 +297,12 @@ void AchievementSettingsWidget::ToggleSpectator() AchievementManager::GetInstance().SetSpectatorMode(); } +void AchievementSettingsWidget::ToggleDiscordPresence() +{ + SaveSettings(); + Discord::UpdateDiscordPresence(); +} + void AchievementSettingsWidget::ToggleProgress() { SaveSettings(); diff --git a/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.h b/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.h index 68ba658b8f..b8e848c2d1 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.h +++ b/Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.h @@ -36,6 +36,7 @@ private: void ToggleUnofficial(); void ToggleEncore(); void ToggleSpectator(); + void ToggleDiscordPresence(); void ToggleProgress(); void ToggleBadges(); @@ -53,6 +54,7 @@ private: ToolTipCheckBox* m_common_unofficial_enabled_input; ToolTipCheckBox* m_common_encore_enabled_input; ToolTipCheckBox* m_common_spectator_enabled_input; + ToolTipCheckBox* m_common_discord_presence_enabled_input; ToolTipCheckBox* m_common_progress_enabled_input; ToolTipCheckBox* m_common_badges_enabled_input; }; diff --git a/Source/Core/DolphinQt/Settings/GeneralPane.cpp b/Source/Core/DolphinQt/Settings/GeneralPane.cpp index 114a5846a8..fcc4a79ebf 100644 --- a/Source/Core/DolphinQt/Settings/GeneralPane.cpp +++ b/Source/Core/DolphinQt/Settings/GeneralPane.cpp @@ -351,6 +351,9 @@ void GeneralPane::OnSaveConfig() #ifdef USE_DISCORD_PRESENCE Discord::SetDiscordPresenceEnabled(m_checkbox_discord_presence->isChecked()); +#ifdef USE_RETRO_ACHIEVEMENTS + emit Settings::Instance().ConfigChanged(); +#endif // USE_RETRO_ACHIEVEMENTS #endif #if defined(USE_ANALYTICS) && USE_ANALYTICS diff --git a/Source/Core/UICommon/DiscordPresence.cpp b/Source/Core/UICommon/DiscordPresence.cpp index eadc229054..67870999aa 100644 --- a/Source/Core/UICommon/DiscordPresence.cpp +++ b/Source/Core/UICommon/DiscordPresence.cpp @@ -21,6 +21,8 @@ #include "Common/HttpRequest.h" #include "Common/StringUtil.h" +#include "Core/AchievementManager.h" +#include "Core/Config/AchievementSettings.h" #include "Core/System.h" #endif @@ -34,6 +36,9 @@ namespace { Handler* event_handler = nullptr; const char* username = ""; +static int64_t s_start_timestamp = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count(); void HandleDiscordReady(const DiscordUser* user) { @@ -195,7 +200,7 @@ bool UpdateDiscordPresenceRaw(const std::string& details, const std::string& sta } void UpdateDiscordPresence(int party_size, SecretType type, const std::string& secret, - const std::string& current_game) + const std::string& current_game, bool reset_timer) { #ifdef USE_DISCORD_PRESENCE if (!Config::Get(Config::MAIN_USE_DISCORD_PRESENCE)) @@ -224,10 +229,17 @@ void UpdateDiscordPresence(int party_size, SecretType type, const std::string& s discord_presence.smallImageText = "Dolphin is an emulator for the GameCube and the Wii."; } discord_presence.details = title.empty() ? "Not in-game" : title.c_str(); - discord_presence.startTimestamp = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count(); + if (reset_timer) + { + s_start_timestamp = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + } + discord_presence.startTimestamp = s_start_timestamp; +#ifdef USE_RETRO_ACHIEVEMENTS + std::string state_string; +#endif // USE_RETRO_ACHIEVEMENTS if (party_size > 0) { if (party_size < 4) @@ -244,6 +256,19 @@ void UpdateDiscordPresence(int party_size, SecretType type, const std::string& s // Note: joining still works without partyMax } } +#ifdef USE_RETRO_ACHIEVEMENTS + else if (Config::Get(Config::RA_ENABLED) && Config::Get(Config::RA_DISCORD_PRESENCE_ENABLED)) + { + state_string = AchievementManager::GetInstance().GetRichPresence().data(); + if (state_string.length() >= 128) + { + // 124 characters + 3 dots + null terminator - thanks to Stenzek for format + state_string.resize(124); + state_string += "..."; + } + discord_presence.state = state_string.c_str(); + } +#endif // USE_RETRO_ACHIEVEMENTS std::string party_id; std::string secret_final; diff --git a/Source/Core/UICommon/DiscordPresence.h b/Source/Core/UICommon/DiscordPresence.h index 67da5fd11e..4e628337d8 100644 --- a/Source/Core/UICommon/DiscordPresence.h +++ b/Source/Core/UICommon/DiscordPresence.h @@ -39,7 +39,8 @@ bool UpdateDiscordPresenceRaw(const std::string& details = {}, const std::string const int64_t start_timestamp = 0, const int64_t end_timestamp = 0, const int party_size = 0, const int party_max = 0); void UpdateDiscordPresence(int party_size = 0, SecretType type = SecretType::Empty, - const std::string& secret = {}, const std::string& current_game = {}); + const std::string& secret = {}, const std::string& current_game = {}, + const bool reset_timer = false); std::string CreateSecretFromIPAddress(const std::string& ip_address, int port); void Shutdown(); void SetDiscordPresenceEnabled(bool enabled);