diff --git a/dll/dll/steam_user_stats.h b/dll/dll/steam_user_stats.h index 24db2727..5f6e4316 100644 --- a/dll/dll/steam_user_stats.h +++ b/dll/dll/steam_user_stats.h @@ -71,6 +71,7 @@ public ISteamUserStats { public: static constexpr auto achievements_user_file = "achievements.json"; + static constexpr int UNLOADED_ACH_ICON = -1; private: template @@ -94,6 +95,8 @@ private: nlohmann::json defined_achievements{}; nlohmann::json user_achievements{}; std::vector sorted_achievement_names{}; + bool achievements_icons_loaded = false; + std::map stats_cache_int{}; std::map stats_cache_float{}; @@ -109,7 +112,7 @@ private: void load_achievements(); void save_achievements(); - int load_ach_icon(const nlohmann::json &defined_ach, bool achieved); + int load_ach_icon(nlohmann::json &defined_ach, bool achieved); nlohmann::detail::iter_impl defined_achievements_find(const std::string &key); std::string get_value_for_language(const nlohmann::json &json, std::string_view key, std::string_view language); @@ -134,6 +137,7 @@ private: InternalSetResult clear_achievement_internal( const char *pchName ); void send_updated_stats(); + void load_achievements_icons(); void steam_run_callback(); // requests from server diff --git a/dll/steam_user_stats.cpp b/dll/steam_user_stats.cpp index a1774cde..7014b92f 100644 --- a/dll/steam_user_stats.cpp +++ b/dll/steam_user_stats.cpp @@ -126,8 +126,14 @@ void Steam_User_Stats::save_achievements() local_storage->write_json_file("", achievements_user_file, user_achievements); } -int Steam_User_Stats::load_ach_icon(const nlohmann::json &defined_ach, bool achieved) +int Steam_User_Stats::load_ach_icon(nlohmann::json &defined_ach, bool achieved) { + const char *icon_handle_key = achieved ? "icon_handle" : "icon_gray_handle"; + int current_handle = defined_ach.value(icon_handle_key, UNLOADED_ACH_ICON); + if (UNLOADED_ACH_ICON != current_handle) { // already loaded + return current_handle; + } + const char *icon_key = achieved ? "icon" : "icon_gray"; if (!achieved && !defined_ach.contains(icon_key)) { icon_key = "icongray"; // old format @@ -135,22 +141,27 @@ int Steam_User_Stats::load_ach_icon(const nlohmann::json &defined_ach, bool achi std::string icon_filepath = defined_ach.value(icon_key, std::string{}); if (icon_filepath.empty()) { + defined_ach[icon_handle_key] = Settings::INVALID_IMAGE_HANDLE; return Settings::INVALID_IMAGE_HANDLE; } std::string file_path(Local_Storage::get_game_settings_path() + icon_filepath); unsigned int file_size = file_size_(file_path); if (!file_size) { + defined_ach[icon_handle_key] = Settings::INVALID_IMAGE_HANDLE; return Settings::INVALID_IMAGE_HANDLE; } int icon_size = static_cast(settings->overlay_appearance.icon_size); std::string img(Local_Storage::load_image_resized(file_path, "", icon_size)); if (img.empty()) { + defined_ach[icon_handle_key] = Settings::INVALID_IMAGE_HANDLE; return Settings::INVALID_IMAGE_HANDLE; } - return settings->add_image(img, icon_size, icon_size); + int handle = settings->add_image(img, icon_size, icon_size); + defined_ach[icon_handle_key] = handle; + return handle; } nlohmann::detail::iter_impl Steam_User_Stats::defined_achievements_find(const std::string &key) @@ -859,8 +870,8 @@ Steam_User_Stats::Steam_User_Stats(Settings *settings, class Networking *network it["displayName"] = get_value_for_language(it, "displayName", settings->get_language()); it["description"] = get_value_for_language(it, "description", settings->get_language()); - it["icon_handle"] = load_ach_icon(it, true); - it["icon_gray_handle"] = load_ach_icon(it, false); + it["icon_handle"] = UNLOADED_ACH_ICON; + it["icon_gray_handle"] = UNLOADED_ACH_ICON; } //TODO: not sure if the sort is actually case insensitive, ach names seem to be treated by steam as case insensitive so I assume they are. @@ -1203,15 +1214,7 @@ int Steam_User_Stats::get_achievement_icon_handle( const std::string &ach_name, } catch(...) { } if (defined_achievements.end() == it) return Settings::INVALID_IMAGE_HANDLE; - int handle = 0; // bad handle - try { - if (achieved) { - handle = it->value("icon_handle", static_cast(0)); - } else { - handle = it->value("icon_gray_handle", static_cast(0)); - } - } catch (...) {} - + int handle = load_ach_icon(*it, achieved); PRINT_DEBUG("returned handle = %i", handle); return handle; } @@ -2148,9 +2151,26 @@ void Steam_User_Stats::send_updated_stats() ); } +void Steam_User_Stats::load_achievements_icons() +{ + if (achievements_icons_loaded) return; + if (settings->lazy_load_achievements_icons) { + achievements_icons_loaded = true; + return; + } + + for (auto & defined_ach : defined_achievements) { + load_ach_icon(defined_ach, true); + load_ach_icon(defined_ach, false); + } + + achievements_icons_loaded = true; +} + void Steam_User_Stats::steam_run_callback() { send_updated_stats(); + load_achievements_icons(); }