diff --git a/3rdparty/rcheevos/src/rc_client.c b/3rdparty/rcheevos/src/rc_client.c index db8ab8bccd4b6..fc09c7d346958 100644 --- a/3rdparty/rcheevos/src/rc_client.c +++ b/3rdparty/rcheevos/src/rc_client.c @@ -578,7 +578,13 @@ static int rc_client_get_image_url(char buffer[], size_t buffer_size, int image_ image_request.image_name = image_name; result = rc_api_init_fetch_image_request(&request, &image_request); if (result == RC_OK) - snprintf(buffer, buffer_size, "%s", request.url); + { + const size_t url_length = strlen(request.url); + if (url_length >= buffer_size) + result = RC_INSUFFICIENT_BUFFER; + else + memcpy(buffer, request.url, url_length + 1); + } rc_api_destroy_request(&request); return result; diff --git a/pcsx2/Achievements.cpp b/pcsx2/Achievements.cpp index 299542bdae9dc..0835c2d5071e1 100644 --- a/pcsx2/Achievements.cpp +++ b/pcsx2/Achievements.cpp @@ -66,6 +66,8 @@ namespace Achievements static constexpr float INDICATOR_FADE_IN_TIME = 0.1f; static constexpr float INDICATOR_FADE_OUT_TIME = 0.5f; + static constexpr size_t URL_BUFFER_SIZE = 256; + // Some API calls are really slow. Set a longer timeout. static constexpr float SERVER_CALL_TIMEOUT = 60.0f; @@ -799,7 +801,7 @@ void Achievements::UpdateRichPresence(std::unique_lock& lo if (!s_has_rich_presence || !s_rich_presence_poll_time.ResetIfSecondsPassed(1.0)) return; - char buffer[512]; + char buffer[URL_BUFFER_SIZE]; const size_t res = rc_client_get_rich_presence_message(s_client, buffer, std::size(buffer)); const std::string_view sv(buffer, res); if (s_rich_presence_string == sv) @@ -949,21 +951,21 @@ void Achievements::ClientLoadGameCallback(int result, const char* error_message, // ensure fullscreen UI is ready for notifications MTGS::RunOnGSThread(&ImGuiManager::InitializeFullscreenUI); + char url_buffer[URL_BUFFER_SIZE]; + if (int err = rc_client_game_get_image_url(info, url_buffer, std::size(url_buffer)); err == RC_OK) + { + s_game_icon_url = url_buffer; + } + else + { + ReportRCError(err, "rc_client_game_get_image_url() failed: "); + } + if (const std::string_view badge_name = info->badge_name; !badge_name.empty()) { s_game_icon = Path::Combine(s_image_directory, fmt::format("game_{}.png", info->id)); - if (!FileSystem::FileExists(s_game_icon.c_str())) - { - char buf[512]; - if (int err = rc_client_game_get_image_url(info, buf, std::size(buf)); err == RC_OK) - { - DownloadImage(buf, s_game_icon); - } - else - { - ReportRCError(err, "rc_client_game_get_image_url() failed: "); - } - } + if (!s_game_icon.empty() && !s_game_icon_url.empty() && !FileSystem::FileExists(s_game_icon.c_str())) + DownloadImage(s_game_icon_url, s_game_icon); } UpdateGameSummary(); @@ -1580,7 +1582,7 @@ std::string Achievements::GetAchievementBadgePath(const rc_client_achievement_t* if (!FileSystem::FileExists(path.c_str())) { - char buf[512]; + char buf[URL_BUFFER_SIZE]; const int res = rc_client_achievement_get_image_url(achievement, state, buf, std::size(buf)); if (res == RC_OK) DownloadImage(buf, path); @@ -1608,7 +1610,7 @@ std::string Achievements::GetLeaderboardUserBadgePath(const rc_client_leaderboar if (!FileSystem::FileExists(path.c_str())) { - char buf[512]; + char buf[URL_BUFFER_SIZE]; const int res = rc_client_leaderboard_entry_get_user_image_url(entry, buf, std::size(buf)); if (res == RC_OK) DownloadImage(buf, path); @@ -1782,7 +1784,7 @@ std::string Achievements::GetLoggedInUserBadgePath() badge_path = GetUserBadgePath(user->username); if (!FileSystem::FileExists(badge_path.c_str())) [[unlikely]] { - char url[512]; + char url[URL_BUFFER_SIZE]; const int res = rc_client_user_get_image_url(user, url, std::size(url)); if (res == RC_OK) DownloadImage(url, badge_path); diff --git a/pcsx2/VMManager.cpp b/pcsx2/VMManager.cpp index ec183fb3b2ad9..3788df611716c 100644 --- a/pcsx2/VMManager.cpp +++ b/pcsx2/VMManager.cpp @@ -3632,10 +3632,18 @@ void VMManager::UpdateDiscordPresence(bool update_session_time) rp.details = s_title.empty() ? TRANSLATE("VMManager","No Game Running") : s_title.c_str(); std::string state_string; + + auto lock = Achievements::GetLock(); + if (Achievements::HasRichPresence()) { - state_string = StringUtil::Ellipsise(Achievements::GetRichPresenceString(), 128); - rp.state = state_string.c_str(); + rp.state = (state_string = StringUtil::Ellipsise(Achievements::GetRichPresenceString(), 128)).c_str(); + + if (const std::string& icon_url = Achievements::GetGameIconURL(); !icon_url.empty()) + { + rp.largeImageKey = icon_url.c_str(); + rp.largeImageText = s_title.c_str(); + } } Discord_UpdatePresence(&rp);