diff --git a/Common/UI/IconCache.cpp b/Common/UI/IconCache.cpp index 598aad75aa..0262cd9910 100644 --- a/Common/UI/IconCache.cpp +++ b/Common/UI/IconCache.cpp @@ -14,6 +14,9 @@ #define MAX_RUNTIME_CACHE_SIZE (1024 * 1024 * 4) #define MAX_SAVED_CACHE_SIZE (1024 * 1024 * 1) +// Seconds before MarkPending accepts a key whose download failed. +constexpr double FAILED_RETRY_DELAY = 30.0; + constexpr uint32_t ICON_CACHE_MAGIC = MK_FOURCC("pICN"); IconCache g_iconCache; @@ -127,6 +130,7 @@ void IconCache::ClearData() { ClearTextures(); std::unique_lock lock(lock_); cache_.clear(); + failed_.clear(); } void IconCache::FrameUpdate() { @@ -231,10 +235,26 @@ bool IconCache::MarkPending(std::string_view key) { if (pending_.find(key) != pending_.end()) { return false; } + auto failedIter = failed_.find(key); + if (failedIter != failed_.end()) { + if (time_now_d() < failedIter->second + FAILED_RETRY_DELAY) { + return false; + } + failed_.erase(failedIter); + } pending_.emplace(key); return true; } +void IconCache::MarkFailed(std::string_view key) { + std::unique_lock lock(lock_); + auto iter = pending_.find(key); + if (iter != pending_.end()) { + pending_.erase(iter); + } + failed_[std::string(key)] = time_now_d(); +} + void IconCache::CancelPending(std::string_view key) { std::unique_lock lock(lock_); auto iter = pending_.find(key); diff --git a/Common/UI/IconCache.h b/Common/UI/IconCache.h index e631f77ca6..1b22e9ba0f 100644 --- a/Common/UI/IconCache.h +++ b/Common/UI/IconCache.h @@ -37,6 +37,8 @@ public: // It's okay to call these from any thread. bool MarkPending(std::string_view key); // returns false if already pending or loaded void CancelPending(std::string_view key); + // Like CancelPending, but MarkPending refuses the key for a while, so a failing download isn't retried every frame. + void MarkFailed(std::string_view key); bool InsertIcon(std::string_view key, IconFormat format, std::string &&pngData); bool GetDimensions(std::string_view key, int *width, int *height); bool Contains(std::string_view key); @@ -65,6 +67,7 @@ private: std::map> cache_; std::set> pending_; + std::map> failed_; // key -> time of failure std::mutex lock_; diff --git a/Core/RetroAchievements.cpp b/Core/RetroAchievements.cpp index 5519b25ee4..e0aa262d6a 100644 --- a/Core/RetroAchievements.cpp +++ b/Core/RetroAchievements.cpp @@ -351,11 +351,11 @@ static void event_handler_callback(const rc_client_event_t *event, rc_client_t * const rc_client_game_t *gameInfo = rc_client_get_game_info(g_rcClient); std::string setTitle = gameInfo->title; - std::string badgeUrl = gameInfo->badge_url; + std::string badgeUrl = http::RemoveHttpsIfNeeded(gameInfo->badge_url); if (event->type == RC_CLIENT_EVENT_SUBSET_COMPLETED) { const rc_client_subset_t *subset = event->subset; setTitle = subset->title; - badgeUrl = subset->badge_url; + badgeUrl = http::RemoveHttpsIfNeeded(subset->badge_url); } DownloadImageIfMissing(badgeUrl); @@ -964,10 +964,15 @@ void DownloadImageIfMissing(std::string_view url) { if (g_iconCache.MarkPending(url)) { INFO_LOG(Log::Achievements, "Downloading image: %.*s", STR_VIEW(url)); g_DownloadManager.StartDownload(url, Path(), http::RequestFlags::Default, nullptr, "", [](http::Request &download) { - if (download.ResultCode() != 200) - return; std::string data; - download.buffer().TakeAll(&data); + if (download.ResultCode() == 200) { + download.buffer().TakeAll(&data); + } + if (data.empty()) { + WARN_LOG(Log::Achievements, "Failed to download image (%d): %s", download.ResultCode(), download.url().c_str()); + g_iconCache.MarkFailed(download.url()); + return; + } g_iconCache.InsertIcon(download.url(), IconFormat::PNG, std::move(data)); }); } diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index 2b64b1f191..30dfe8ab98 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -494,6 +494,8 @@ bool System_GetPropertyBool(SystemProperty prop) { } case SYSPROP_DEBUGGER_PRESENT: return IsDebuggerPresent(); + case SYSPROP_SUPPORTS_HTTPS: + return !g_Config.bDisableHTTPS; case SYSPROP_OK_BUTTON_LEFT: return true; case SYSPROP_CAN_GET_FREE_SPACE_FAST: