From c456f521e93293598d3b59d57e886f1c0fbe864f Mon Sep 17 00:00:00 2001 From: collecting Date: Thu, 2 Oct 2025 23:58:53 +0000 Subject: [PATCH 1/2] fix: Discord Rich Presence Timer --- src/citron/discord_impl.cpp | 42 +++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/citron/discord_impl.cpp b/src/citron/discord_impl.cpp index 225128f56..9fbe680da 100644 --- a/src/citron/discord_impl.cpp +++ b/src/citron/discord_impl.cpp @@ -39,8 +39,13 @@ namespace DiscordRPC { Discord_Initialize("1361252452329848892", &handlers, 1, nullptr); - discord_thread_running = true; - discord_thread = std::thread(&DiscordImpl::ThreadRun, this); + // Initialize the timer for the first state (being in the menu). + current_state_start_time = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + was_powered_on = false; // Start in the "off" state. + + discord_thread_running = true; + discord_thread = std::thread(&DiscordImpl::ThreadRun, this); } DiscordImpl::~DiscordImpl() { @@ -61,9 +66,6 @@ namespace DiscordRPC { void DiscordImpl::UpdateGameStatus(bool use_default) { const std::string default_text = "Citron Is A Homebrew Emulator For The Nintendo Switch"; const std::string default_image = "citron_logo"; - s64 start_time = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count(); DiscordRichPresence presence{}; if (!use_default && !game_title_id.empty()) { @@ -79,15 +81,23 @@ namespace DiscordRPC { presence.smallImageText = default_text.c_str(); presence.details = game_title.c_str(); presence.state = "Currently in game"; - presence.startTimestamp = start_time; + presence.startTimestamp = current_state_start_time; // Use the state-based timer Discord_UpdatePresence(&presence); } void DiscordImpl::Update() { - const std::string default_text = "Citron Is A Homebrew Emulator For The Nintendo Switch"; - const std::string default_image = "citron_logo"; + const bool is_powered_on = system.IsPoweredOn(); - if (system.IsPoweredOn()) { + if (is_powered_on != was_powered_on) { + // State changed! Reset the timer + current_state_start_time = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + // Update the state tracker. + was_powered_on = is_powered_on; + } + + if (is_powered_on) { + // Game is running. system.GetAppLoader().ReadTitle(game_title); system.GetAppLoader().ReadProgramId(program_id); game_title_id = fmt::format("{:016X}", program_id); @@ -96,7 +106,7 @@ namespace DiscordRPC { QNetworkRequest request; request.setUrl(QUrl(QString::fromStdString( fmt::format("https://tinfoil.media/ti/{}/256/256", game_title_id)))); - request.setTransferTimeout(5000); // 5 second timeout + request.setTransferTimeout(5000); QNetworkReply* reply = manager.head(request); QEventLoop request_event_loop; QObject::connect(reply, &QNetworkReply::finished, &request_event_loop, &QEventLoop::quit); @@ -105,21 +115,21 @@ namespace DiscordRPC { UpdateGameStatus(reply->error() != QNetworkReply::NoError); reply->deleteLater(); } else { - s64 start_time = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count(); + // Game is NOT running (in menus). + const std::string default_text = "Citron Is A Homebrew Emulator For The Nintendo Switch"; + const std::string default_image = "citron_logo"; DiscordRichPresence presence{}; presence.largeImageKey = default_image.c_str(); presence.largeImageText = default_text.c_str(); - presence.details = "Currently not in game"; - presence.startTimestamp = start_time; + presence.details = "In the Menus"; + presence.startTimestamp = current_state_start_time; // Use the state-based timer Discord_UpdatePresence(&presence); } } void DiscordImpl::ThreadRun() { while (discord_thread_running) { - Update(); // This is the line that was likely missing. + Update(); Discord_RunCallbacks(); std::this_thread::sleep_for(std::chrono::seconds(15)); } From 2d20ffeb06a1bc77910133a7b4c5d95beb54d30f Mon Sep 17 00:00:00 2001 From: collecting Date: Thu, 2 Oct 2025 23:59:25 +0000 Subject: [PATCH 2/2] fix: Discord Presence Timer --- src/citron/discord_impl.h | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/citron/discord_impl.h b/src/citron/discord_impl.h index ec834b438..09ae5c0db 100644 --- a/src/citron/discord_impl.h +++ b/src/citron/discord_impl.h @@ -4,8 +4,8 @@ #pragma once - #include +#include #include #include "citron/discord.h" @@ -15,15 +15,14 @@ namespace Core { namespace DiscordRPC { - class DiscordImpl: public DiscordInterface { + class DiscordImpl : public DiscordInterface { public: - DiscordImpl(Core::System & system_); + DiscordImpl(Core::System& system_); ~DiscordImpl() override; void Pause() override; void Update() override; - // FIX: Add the function and members for the background thread void ThreadRun(); std::thread discord_thread; std::atomic discord_thread_running; @@ -31,13 +30,17 @@ namespace DiscordRPC { private: void UpdateGameStatus(bool use_default); - std::string game_url {}; - std::string game_title {}; - std::string game_title_id {}; + std::string game_url{}; + std::string game_title{}; + std::string game_title_id{}; std::string cached_url; - Core::System & system; + Core::System& system; u64 program_id = 0; + + s64 current_state_start_time = 0; + + bool was_powered_on = false; }; } // namespace DiscordRPC