Achievement names are now treated as case insensitive.

This should fix achievements in a few games.
This commit is contained in:
Mr_Goldberg 2021-04-02 23:42:22 -04:00
parent 8a5e49251c
commit dc95076faa
No known key found for this signature in database
GPG key ID: 8597D87419DEF278

View file

@ -66,6 +66,17 @@ unsigned int find_leaderboard(std::string name)
return 0; return 0;
} }
nlohmann::detail::iter_impl<nlohmann::json> 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<std::string const&>(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() void load_achievements_db()
{ {
std::string file_path = Local_Storage::get_game_settings_path() + achievements_user_file; 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<std::recursive_mutex> lock(global_mutex); std::lock_guard<std::recursive_mutex> lock(global_mutex);
try { try {
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName]( nlohmann::json &item ) { auto it = defined_achievements_find(pchName);
return item["name"].get<std::string>() == pchName; std::string pch_name = it->value("name", std::string());
});
auto ach = user_achievements.find(pchName); auto ach = user_achievements.find(pch_name);
if (it != defined_achievements.end() && ach != user_achievements.end()) { if (it != defined_achievements.end() && ach != user_achievements.end()) {
if(pbAchieved != nullptr) *pbAchieved = (*ach)["earned"]; if(pbAchieved != nullptr) *pbAchieved = (*ach)["earned"];
return true; return true;
@ -249,13 +260,13 @@ bool SetAchievement( const char *pchName )
std::lock_guard<std::recursive_mutex> lock(global_mutex); std::lock_guard<std::recursive_mutex> lock(global_mutex);
try { try {
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { auto it = defined_achievements_find(pchName);
return item["name"].get<std::string>() == pchName; std::string pch_name = it->value("name", std::string());
});
if (it != defined_achievements.end()) { if (it != defined_achievements.end()) {
if (user_achievements.find(pchName) == user_achievements.end() || user_achievements[pchName].value("earned", false) == false) { if (user_achievements.find(pch_name) == user_achievements.end() || user_achievements[pch_name].value("earned", false) == false) {
user_achievements[pchName]["earned"] = true; user_achievements[pch_name]["earned"] = true;
user_achievements[pchName]["earned_time"] = std::chrono::duration_cast<std::chrono::duration<uint32>>(std::chrono::system_clock::now().time_since_epoch()).count(); user_achievements[pch_name]["earned_time"] = std::chrono::duration_cast<std::chrono::duration<uint32>>(std::chrono::system_clock::now().time_since_epoch()).count();
#ifdef EMU_OVERLAY #ifdef EMU_OVERLAY
overlay->AddAchievementNotification(it.value()); overlay->AddAchievementNotification(it.value());
#endif #endif
@ -276,12 +287,12 @@ bool ClearAchievement( const char *pchName )
std::lock_guard<std::recursive_mutex> lock(global_mutex); std::lock_guard<std::recursive_mutex> lock(global_mutex);
try { try {
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { auto it = defined_achievements_find(pchName);
return static_cast<std::string const&>(item["name"]) == pchName; std::string pch_name = it->value("name", std::string());
});
if (it != defined_achievements.end()) { if (it != defined_achievements.end()) {
user_achievements[pchName]["earned"] = false; user_achievements[pch_name]["earned"] = false;
user_achievements[pchName]["earned_time"] = static_cast<uint32>(0); user_achievements[pch_name]["earned_time"] = static_cast<uint32>(0);
save_achievements(); save_achievements();
return true; return true;
} }
@ -301,10 +312,10 @@ bool GetAchievementAndUnlockTime( const char *pchName, bool *pbAchieved, uint32
std::lock_guard<std::recursive_mutex> lock(global_mutex); std::lock_guard<std::recursive_mutex> lock(global_mutex);
try { try {
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { auto it = defined_achievements_find(pchName);
return static_cast<std::string const&>(item["name"]) == pchName; std::string pch_name = it->value("name", std::string());
});
auto ach = user_achievements.find(pchName); auto ach = user_achievements.find(pch_name);
if (it != defined_achievements.end() && ach != user_achievements.end()) { if (it != defined_achievements.end() && ach != user_achievements.end()) {
if(pbAchieved != nullptr) *pbAchieved = (*ach)["earned"]; if(pbAchieved != nullptr) *pbAchieved = (*ach)["earned"];
if(punUnlockTime != nullptr) *punUnlockTime = (*ach)["earned_time"]; 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) { if (strcmp (pchKey, "name") == 0) {
try { try {
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { auto it = defined_achievements_find(pchName);
return static_cast<std::string const&>(item["name"]) == pchName;
});
if (it != defined_achievements.end()) { if (it != defined_achievements.end()) {
return it.value()["displayName"].get_ptr<std::string*>()->c_str(); return it.value()["displayName"].get_ptr<std::string*>()->c_str();
} }
@ -378,9 +387,7 @@ const char * GetAchievementDisplayAttribute( const char *pchName, const char *pc
if (strcmp (pchKey, "desc") == 0) { if (strcmp (pchKey, "desc") == 0) {
try { try {
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { auto it = defined_achievements_find(pchName);
return static_cast<std::string const&>(item["name"]) == pchName;
});
if (it != defined_achievements.end()) { if (it != defined_achievements.end()) {
return it.value()["description"].get_ptr<std::string*>()->c_str(); return it.value()["description"].get_ptr<std::string*>()->c_str();
} }
@ -389,9 +396,7 @@ const char * GetAchievementDisplayAttribute( const char *pchName, const char *pc
if (strcmp (pchKey, "hidden") == 0) { if (strcmp (pchKey, "hidden") == 0) {
try { try {
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { auto it = defined_achievements_find(pchName);
return static_cast<std::string const&>(item["name"]) == pchName;
});
if (it != defined_achievements.end()) { if (it != defined_achievements.end()) {
return it.value()["hidden"].get_ptr<std::string*>()->c_str(); return it.value()["hidden"].get_ptr<std::string*>()->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. // 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 ) bool IndicateAchievementProgress( const char *pchName, uint32 nCurProgress, uint32 nMaxProgress )
{ {
PRINT_DEBUG("IndicateAchievementProgress\n"); PRINT_DEBUG("IndicateAchievementProgress %s\n", pchName);
if (pchName == nullptr) return false; if (pchName == nullptr) return false;
std::lock_guard<std::recursive_mutex> lock(global_mutex); std::lock_guard<std::recursive_mutex> lock(global_mutex);
try { try {
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) { auto it = defined_achievements_find(pchName);
return static_cast<std::string const&>(item["name"]) == pchName; std::string pch_name = it->value("name", std::string());
});
auto ach = user_achievements.find(pchName); auto ach = user_achievements.find(pch_name);
if (it != defined_achievements.end()) { if (it != defined_achievements.end()) {
bool achieved = false; bool achieved = false;
if ( ach != user_achievements.end()) { if ( ach != user_achievements.end()) {
@ -424,14 +429,14 @@ bool IndicateAchievementProgress( const char *pchName, uint32 nCurProgress, uint
UserAchievementStored_t data = {}; UserAchievementStored_t data = {};
data.m_nGameID = settings->get_local_game_id().ToUint64(); data.m_nGameID = settings->get_local_game_id().ToUint64();
data.m_bGroupAchievement = false; data.m_bGroupAchievement = false;
strncpy(data.m_rgchAchievementName, pchName, k_cchStatNameMax); strncpy(data.m_rgchAchievementName, pch_name.c_str(), k_cchStatNameMax);
if (achieved) { if (achieved) {
data.m_nCurProgress = 0; data.m_nCurProgress = 0;
data.m_nMaxProgress = 0; data.m_nMaxProgress = 0;
} else { } else {
user_achievements[pchName]["progress"] = nCurProgress; user_achievements[pch_name]["progress"] = nCurProgress;
user_achievements[pchName]["max_progress"] = nMaxProgress; user_achievements[pch_name]["max_progress"] = nMaxProgress;
data.m_nCurProgress = nCurProgress; data.m_nCurProgress = nCurProgress;
data.m_nMaxProgress = nMaxProgress; data.m_nMaxProgress = nMaxProgress;
} }