add a new option save_only_higher_stat_achievement_progress and enable it by default toa void progress spam from stats which are tied to an achievement

This commit is contained in:
otavepto 2024-06-23 00:35:57 +03:00
parent ace1a591e5
commit 6ee0628750
5 changed files with 61 additions and 9 deletions

View File

@ -232,6 +232,10 @@ public:
// allow stats not defined by the user?
bool allow_unknown_stats = false;
// when a stat that's tied to an achievement gets a new value, should the emu save that progress only if it's higher?
// the stat itself is always saved regardless of that flag, obly affects the achievement progress
bool save_only_higher_stat_achievement_progress = true;
// bypass to make SetAchievement() always return true, prevent some games from breaking
bool achievement_bypass = false;

View File

@ -45,10 +45,10 @@ struct Steam_Leaderboard {
};
struct achievement_trigger {
std::string name{};
std::string name{}; // defined achievement name
std::string value_operation{};
std::string min_value{};
std::string max_value{};
std::string min_value{}; // min progress
std::string max_value{}; // max progress
bool should_unlock_ach(float stat) const;
bool should_unlock_ach(int32 stat) const;

View File

@ -1290,6 +1290,9 @@ static void parse_simple_features(class Settings *settings_client, class Setting
settings_client->allow_unknown_stats = ini.GetBoolValue("main::general", "allow_unknown_stats", settings_client->allow_unknown_stats);
settings_server->allow_unknown_stats = ini.GetBoolValue("main::general", "allow_unknown_stats", settings_server->allow_unknown_stats);
settings_client->save_only_higher_stat_achievement_progress = ini.GetBoolValue("main::general", "save_only_higher_stat_achievement_progress", settings_client->save_only_higher_stat_achievement_progress);
settings_server->save_only_higher_stat_achievement_progress = ini.GetBoolValue("main::general", "save_only_higher_stat_achievement_progress", settings_server->save_only_higher_stat_achievement_progress);
settings_client->immediate_gameserver_stats = ini.GetBoolValue("main::general", "immediate_gameserver_stats", settings_client->immediate_gameserver_stats);
settings_server->immediate_gameserver_stats = ini.GetBoolValue("main::general", "immediate_gameserver_stats", settings_server->immediate_gameserver_stats);

View File

@ -447,7 +447,7 @@ Steam_User_Stats::InternalSetResult<int32> Steam_User_Stats::set_stat_internal(
result.current_val = nData;
auto cached_stat = stats_cache_int.find(stat_name);
if (cached_stat != stats_cache_int.end()) {
if (stats_cache_int.end() != cached_stat) {
if (cached_stat->second == nData) {
result.success = true;
return result;
@ -461,7 +461,26 @@ Steam_User_Stats::InternalSetResult<int32> Steam_User_Stats::set_stat_internal(
set_achievement_internal(t.name.c_str());
}
if (t.should_indicate_progress(nData)) {
IndicateAchievementProgress(t.name.c_str(), nData, std::stoi(t.max_value));
bool indicate_progress = true;
// appid 1482380 needs that otherwise it will spam progress indications while driving
if (settings->save_only_higher_stat_achievement_progress) {
try {
auto user_ach_it = user_achievements.find(t.name);
if (user_achievements.end() != user_ach_it) {
auto user_progress_it = user_ach_it->find("progress");
if (user_ach_it->end() != user_progress_it) {
int32 user_progress = *user_progress_it;
if (nData <= user_progress) {
indicate_progress = false;
}
}
}
} catch(...){}
}
if (indicate_progress) {
IndicateAchievementProgress(t.name.c_str(), nData, std::stoi(t.max_value));
}
}
}
}
@ -502,7 +521,7 @@ Steam_User_Stats::InternalSetResult<std::pair<GameServerStats_Messages::StatInfo
result.current_val.second = fData;
auto cached_stat = stats_cache_float.find(stat_name);
if (cached_stat != stats_cache_float.end()) {
if (stats_cache_float.end() != cached_stat) {
if (cached_stat->second == fData) {
result.success = true;
return result;
@ -516,7 +535,26 @@ Steam_User_Stats::InternalSetResult<std::pair<GameServerStats_Messages::StatInfo
set_achievement_internal(t.name.c_str());
}
if (t.should_indicate_progress(fData)) {
IndicateAchievementProgress(t.name.c_str(), fData, std::stof(t.max_value));
bool indicate_progress = true;
// appid 1482380 needs that otherwise it will spam progress indications while driving
if (settings->save_only_higher_stat_achievement_progress) {
try {
auto user_ach_it = user_achievements.find(t.name);
if (user_achievements.end() != user_ach_it) {
auto user_progress_it = user_ach_it->find("progress");
if (user_ach_it->end() != user_progress_it) {
float user_progress = *user_progress_it;
if (fData <= user_progress) {
indicate_progress = false;
}
}
}
} catch(...){}
}
if (indicate_progress) {
IndicateAchievementProgress(t.name.c_str(), (uint32)fData, (uint32)std::stof(t.max_value));
}
}
}
}
@ -1353,10 +1391,10 @@ bool Steam_User_Stats::GetUserAchievementAndUnlockTime( CSteamID steamIDUser, co
// Reset stats
bool Steam_User_Stats::ResetAllStats( bool bAchievementsToo )
{
PRINT_DEBUG_ENTRY();
PRINT_DEBUG("bAchievementsToo = %i", (int)bAchievementsToo);
std::lock_guard<std::recursive_mutex> lock(global_mutex);
clear_stats_internal();
clear_stats_internal(); // this will save stats to disk if necessary
if (!settings->disable_sharing_stats_with_gameserver) {
for (const auto &stat : settings->getStats()) {
std::string stat_name(common_helpers::ascii_to_lowercase(stat.first));

View File

@ -18,6 +18,13 @@ disable_leaderboards_create_unknown=0
# set this to 1 to allow unknown stats
# default=0
allow_unknown_stats=0
# whenever a game updates a stat which is tied to an achievement progress, the emu will save that progress immediately
# but some games will update the stat very frequently (with lower & higher values) resulting in a spam of disk writes or overlay notifications
# set this to 0 to save any stat achievement progress value (higher or lower)
# this has no impact on the stat itself, only the achievement progress of a stat which is tied to an achievement
# also has no impact on the functions which directly change stats, achievements, or achievements progress
# default=1
save_only_higher_stat_achievement_progress=1
# synchronize user stats/achievements with game servers as soon as possible instead of caching them until the next call to `Steam_RunCallbacks()`
# not recommended
immediate_gameserver_stats=0