From dc95076faa2a597c33252fa29a9dc93329d97be6 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Fri, 2 Apr 2021 23:42:22 -0400 Subject: [PATCH] Achievement names are now treated as case insensitive. This should fix achievements in a few games. --- dll/steam_user_stats.h | 77 ++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/dll/steam_user_stats.h b/dll/steam_user_stats.h index 7de7923c..a35d3a03 100644 --- a/dll/steam_user_stats.h +++ b/dll/steam_user_stats.h @@ -66,6 +66,17 @@ unsigned int find_leaderboard(std::string name) return 0; } +nlohmann::detail::iter_impl defined_achievements_find(std::string key) +{ + return std::find_if(defined_achievements.begin(), defined_achievements.end(), [key](nlohmann::json& item) { + std::string name = static_cast(item["name"]); + return key.size() == name.size() && std::equal(name.begin(), name.end(), key.begin(), + [](char a, char b) { + return tolower(a) == tolower(b); + }); + }); +} + void load_achievements_db() { std::string file_path = Local_Storage::get_game_settings_path() + achievements_user_file; @@ -227,10 +238,10 @@ bool GetAchievement( const char *pchName, bool *pbAchieved ) std::lock_guard lock(global_mutex); try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName]( nlohmann::json &item ) { - return item["name"].get() == pchName; - }); - auto ach = user_achievements.find(pchName); + auto it = defined_achievements_find(pchName); + std::string pch_name = it->value("name", std::string()); + + auto ach = user_achievements.find(pch_name); if (it != defined_achievements.end() && ach != user_achievements.end()) { if(pbAchieved != nullptr) *pbAchieved = (*ach)["earned"]; return true; @@ -249,13 +260,13 @@ bool SetAchievement( const char *pchName ) std::lock_guard lock(global_mutex); try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return item["name"].get() == pchName; - }); + auto it = defined_achievements_find(pchName); + std::string pch_name = it->value("name", std::string()); + if (it != defined_achievements.end()) { - if (user_achievements.find(pchName) == user_achievements.end() || user_achievements[pchName].value("earned", false) == false) { - user_achievements[pchName]["earned"] = true; - user_achievements[pchName]["earned_time"] = std::chrono::duration_cast>(std::chrono::system_clock::now().time_since_epoch()).count(); + if (user_achievements.find(pch_name) == user_achievements.end() || user_achievements[pch_name].value("earned", false) == false) { + user_achievements[pch_name]["earned"] = true; + user_achievements[pch_name]["earned_time"] = std::chrono::duration_cast>(std::chrono::system_clock::now().time_since_epoch()).count(); #ifdef EMU_OVERLAY overlay->AddAchievementNotification(it.value()); #endif @@ -276,12 +287,12 @@ bool ClearAchievement( const char *pchName ) std::lock_guard lock(global_mutex); try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return static_cast(item["name"]) == pchName; - }); + auto it = defined_achievements_find(pchName); + std::string pch_name = it->value("name", std::string()); + if (it != defined_achievements.end()) { - user_achievements[pchName]["earned"] = false; - user_achievements[pchName]["earned_time"] = static_cast(0); + user_achievements[pch_name]["earned"] = false; + user_achievements[pch_name]["earned_time"] = static_cast(0); save_achievements(); return true; } @@ -301,10 +312,10 @@ bool GetAchievementAndUnlockTime( const char *pchName, bool *pbAchieved, uint32 std::lock_guard lock(global_mutex); try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return static_cast(item["name"]) == pchName; - }); - auto ach = user_achievements.find(pchName); + auto it = defined_achievements_find(pchName); + std::string pch_name = it->value("name", std::string()); + + auto ach = user_achievements.find(pch_name); if (it != defined_achievements.end() && ach != user_achievements.end()) { if(pbAchieved != nullptr) *pbAchieved = (*ach)["earned"]; if(punUnlockTime != nullptr) *punUnlockTime = (*ach)["earned_time"]; @@ -367,9 +378,7 @@ const char * GetAchievementDisplayAttribute( const char *pchName, const char *pc if (strcmp (pchKey, "name") == 0) { try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return static_cast(item["name"]) == pchName; - }); + auto it = defined_achievements_find(pchName); if (it != defined_achievements.end()) { return it.value()["displayName"].get_ptr()->c_str(); } @@ -378,9 +387,7 @@ const char * GetAchievementDisplayAttribute( const char *pchName, const char *pc if (strcmp (pchKey, "desc") == 0) { try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return static_cast(item["name"]) == pchName; - }); + auto it = defined_achievements_find(pchName); if (it != defined_achievements.end()) { return it.value()["description"].get_ptr()->c_str(); } @@ -389,9 +396,7 @@ const char * GetAchievementDisplayAttribute( const char *pchName, const char *pc if (strcmp (pchKey, "hidden") == 0) { try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return static_cast(item["name"]) == pchName; - }); + auto it = defined_achievements_find(pchName); if (it != defined_achievements.end()) { return it.value()["hidden"].get_ptr()->c_str(); } @@ -406,15 +411,15 @@ const char * GetAchievementDisplayAttribute( const char *pchName, const char *pc // Calling this w/ N out of N progress will NOT set the achievement, the game must still do that. bool IndicateAchievementProgress( const char *pchName, uint32 nCurProgress, uint32 nMaxProgress ) { - PRINT_DEBUG("IndicateAchievementProgress\n"); + PRINT_DEBUG("IndicateAchievementProgress %s\n", pchName); if (pchName == nullptr) return false; std::lock_guard lock(global_mutex); try { - auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { - return static_cast(item["name"]) == pchName; - }); - auto ach = user_achievements.find(pchName); + auto it = defined_achievements_find(pchName); + std::string pch_name = it->value("name", std::string()); + + auto ach = user_achievements.find(pch_name); if (it != defined_achievements.end()) { bool achieved = false; if ( ach != user_achievements.end()) { @@ -424,14 +429,14 @@ bool IndicateAchievementProgress( const char *pchName, uint32 nCurProgress, uint UserAchievementStored_t data = {}; data.m_nGameID = settings->get_local_game_id().ToUint64(); data.m_bGroupAchievement = false; - strncpy(data.m_rgchAchievementName, pchName, k_cchStatNameMax); + strncpy(data.m_rgchAchievementName, pch_name.c_str(), k_cchStatNameMax); if (achieved) { data.m_nCurProgress = 0; data.m_nMaxProgress = 0; } else { - user_achievements[pchName]["progress"] = nCurProgress; - user_achievements[pchName]["max_progress"] = nMaxProgress; + user_achievements[pch_name]["progress"] = nCurProgress; + user_achievements[pch_name]["max_progress"] = nMaxProgress; data.m_nCurProgress = nCurProgress; data.m_nMaxProgress = nMaxProgress; }