From 93172e642e154216379f10e7fd753adc9a139c06 Mon Sep 17 00:00:00 2001 From: otavepto Date: Sun, 31 Mar 2024 00:02:02 +0200 Subject: [PATCH] allow disabling the new options via config files --- CHANGELOG.md | 6 ++- dll/dll/settings.h | 5 +++ dll/settings_parser.cpp | 12 ++++++ dll/steam_gameserverstats.cpp | 38 +++++++++++++++---- dll/steam_user_stats.cpp | 31 ++++++++++----- post_build/README.release.md | 18 +++++++++ .../disable_sharing_leaderboards.EXAMPLE.txt | 1 + ..._sharing_stats_with_gameserver.EXAMPLE.txt | 1 + .../generate_emu_config.py | 5 +-- 9 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 post_build/steam_settings.EXAMPLE/disable_sharing_leaderboards.EXAMPLE.txt create mode 100644 post_build/steam_settings.EXAMPLE/disable_sharing_stats_with_gameserver.EXAMPLE.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index f2aa3523..b5fe4bec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,10 @@ - if the script was ran without root, and `-packages_skip` wasn't specified, the script will attempt to detect and use the built-in tool `sudo` if it was available * share leaderboards scores with connected players, adjust players ranks locally, and sort entries as needed by the game, suggested by **[M4RCK5]** - this will only work when people connected on the same network are playing the same game, once they disconnect their leaderboard entry will be lost (no data persistence for other players) -* implemented the missing interface `ISteamGameServerStats`, allowing game servers to exchange user stats & achievements with players + this will only work when people connected on the same network are playing the same game, once they disconnect their leaderboard entry will be lost (no data persistence for other players), also doesn't work well with VPN clients. + could be disabled via `disable_sharing_leaderboards.txt` +* implemented the missing interface `ISteamGameServerStats`, allowing game servers to exchange user stats & achievements with players + could be disabled via `disable_sharing_stats_with_gameserver.txt` * for windows: updated stub drm patterns and added a workaround for older variants, this increases the compatibility, but makes it easier to be detected * new stub/mock dll `GameOverlayRenderer` for the experiemntal steamclient setup, diff --git a/dll/dll/settings.h b/dll/dll/settings.h index 1e4e1f83..ef78cc91 100644 --- a/dll/dll/settings.h +++ b/dll/dll/settings.h @@ -247,6 +247,11 @@ public: // allow Steam_User_Stats::FindLeaderboard() to always succeed and create the given unknown leaderboard bool disable_leaderboards_create_unknown = false; + // don't share leaderboards with other players playing the same game on the same network + bool disable_sharing_leaderboards = false; + + // don't share stats and achievements with the game server + bool disable_sharing_stats_with_gameserver = false; //overlay bool disable_overlay = false; diff --git a/dll/settings_parser.cpp b/dll/settings_parser.cpp index e5563132..8cbd5bb0 100644 --- a/dll/settings_parser.cpp +++ b/dll/settings_parser.cpp @@ -1238,6 +1238,8 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s bool achievement_bypass = false; bool is_beta_branch = false; bool disable_leaderboards_create_unknown = false; + bool disable_sharing_leaderboards = false; + bool disable_sharing_stats_with_gameserver = false; bool use_gc_token = false; bool enable_new_app_ticket = false; int build_id = 10; @@ -1285,6 +1287,10 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s disable_account_avatar = true; } else if (p == "disable_leaderboards_create_unknown.txt") { disable_leaderboards_create_unknown = true; + } else if (p == "disable_sharing_leaderboards.txt") { + disable_sharing_leaderboards = true; + } else if (p == "disable_sharing_stats_with_gameserver.txt") { + disable_sharing_stats_with_gameserver = true; } else if (p == "achievements_bypass.txt") { achievement_bypass = true; } else if (p == "is_beta_branch.txt") { @@ -1369,6 +1375,12 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s settings_client->disable_leaderboards_create_unknown = disable_leaderboards_create_unknown; settings_server->disable_leaderboards_create_unknown = disable_leaderboards_create_unknown; + settings_client->disable_sharing_leaderboards = disable_sharing_leaderboards; + settings_server->disable_sharing_leaderboards = disable_sharing_leaderboards; + + settings_client->disable_sharing_stats_with_gameserver = disable_sharing_stats_with_gameserver; + settings_server->disable_sharing_stats_with_gameserver = disable_sharing_stats_with_gameserver; + settings_client->enable_new_app_ticket = enable_new_app_ticket; settings_server->enable_new_app_ticket = enable_new_app_ticket; settings_client->use_gc_token = use_gc_token; diff --git a/dll/steam_gameserverstats.cpp b/dll/steam_gameserverstats.cpp index c8710403..1c39a7f2 100644 --- a/dll/steam_gameserverstats.cpp +++ b/dll/steam_gameserverstats.cpp @@ -88,18 +88,22 @@ Steam_GameServerStats::Steam_GameServerStats(class Settings *settings, class Net this->callback_results = callback_results; this->callbacks = callbacks; this->run_every_runcb = run_every_runcb; - - this->network->setCallback(CALLBACK_ID_GAMESERVER_STATS, settings->get_local_steam_id(), &Steam_GameServerStats::steam_gameserverstats_network_callback, this); - this->network->setCallback(CALLBACK_ID_USER_STATUS, settings->get_local_steam_id(), &Steam_GameServerStats::steam_gameserverstats_network_low_level, this); - this->run_every_runcb->add(&Steam_GameServerStats::steam_gameserverstats_run_every_runcb, this); + + if (!settings->disable_sharing_stats_with_gameserver) { + this->network->setCallback(CALLBACK_ID_GAMESERVER_STATS, settings->get_local_steam_id(), &Steam_GameServerStats::steam_gameserverstats_network_callback, this); + this->network->setCallback(CALLBACK_ID_USER_STATUS, settings->get_local_steam_id(), &Steam_GameServerStats::steam_gameserverstats_network_low_level, this); + this->run_every_runcb->add(&Steam_GameServerStats::steam_gameserverstats_run_every_runcb, this); + } } Steam_GameServerStats::~Steam_GameServerStats() { - this->network->rmCallback(CALLBACK_ID_GAMESERVER_STATS, settings->get_local_steam_id(), &Steam_GameServerStats::steam_gameserverstats_network_callback, this); - this->network->rmCallback(CALLBACK_ID_USER_STATUS, settings->get_local_steam_id(), &Steam_GameServerStats::steam_gameserverstats_network_low_level, this); - this->run_every_runcb->remove(&Steam_GameServerStats::steam_gameserverstats_run_every_runcb, this); + if (!settings->disable_sharing_stats_with_gameserver) { + this->network->rmCallback(CALLBACK_ID_GAMESERVER_STATS, settings->get_local_steam_id(), &Steam_GameServerStats::steam_gameserverstats_network_callback, this); + this->network->rmCallback(CALLBACK_ID_USER_STATUS, settings->get_local_steam_id(), &Steam_GameServerStats::steam_gameserverstats_network_low_level, this); + this->run_every_runcb->remove(&Steam_GameServerStats::steam_gameserverstats_run_every_runcb, this); + } } @@ -113,6 +117,12 @@ SteamAPICall_t Steam_GameServerStats::RequestUserStats( CSteamID steamIDUser ) { PRINT_DEBUG("Steam_GameServerStats::RequestUserStats %llu\n", (uint64)steamIDUser.ConvertToUint64()); std::lock_guard lock(global_mutex); + if (settings->disable_sharing_stats_with_gameserver) { + GSStatsReceived_t data_bad{}; + data_bad.m_eResult = EResult::k_EResultFail; + data_bad.m_steamIDUser = steamIDUser; + return callback_results->addCallResult(data_bad.k_iCallback, &data_bad, sizeof(data_bad)); + } struct RequestAllStats new_request{}; new_request.created = std::chrono::high_resolution_clock::now(); @@ -145,6 +155,7 @@ bool Steam_GameServerStats::GetUserStat( CSteamID steamIDUser, const char *pchNa { PRINT_DEBUG("Steam_GameServerStats::GetUserStat %llu '%s' %p\n", (uint64)steamIDUser.ConvertToUint64(), pchName, pData); std::lock_guard lock(global_mutex); + if (settings->disable_sharing_stats_with_gameserver) return false; if (!pchName) return false; @@ -160,6 +171,7 @@ bool Steam_GameServerStats::GetUserStat( CSteamID steamIDUser, const char *pchNa { PRINT_DEBUG("Steam_GameServerStats::GetUserStat %llu '%s' %p\n", (uint64)steamIDUser.ConvertToUint64(), pchName, pData); std::lock_guard lock(global_mutex); + if (settings->disable_sharing_stats_with_gameserver) return false; if (!pchName) return false; @@ -175,6 +187,7 @@ bool Steam_GameServerStats::GetUserAchievement( CSteamID steamIDUser, const char { PRINT_DEBUG("Steam_GameServerStats::GetUserAchievement %llu '%s' %p\n", (uint64)steamIDUser.ConvertToUint64(), pchName, pbAchieved); std::lock_guard lock(global_mutex); + if (settings->disable_sharing_stats_with_gameserver) return false; if (!pchName) return false; @@ -194,6 +207,7 @@ bool Steam_GameServerStats::SetUserStat( CSteamID steamIDUser, const char *pchNa { PRINT_DEBUG("Steam_GameServerStats::SetUserStat %llu '%s'=%i\n", (uint64)steamIDUser.ConvertToUint64(), pchName, nData); std::lock_guard lock(global_mutex); + if (settings->disable_sharing_stats_with_gameserver) return false; if (!pchName) return false; @@ -211,6 +225,7 @@ bool Steam_GameServerStats::SetUserStat( CSteamID steamIDUser, const char *pchNa { PRINT_DEBUG("Steam_GameServerStats::SetUserStat %llu '%s'=%f\n", (uint64)steamIDUser.ConvertToUint64(), pchName, fData); std::lock_guard lock(global_mutex); + if (settings->disable_sharing_stats_with_gameserver) return false; if (!pchName) return false; @@ -228,6 +243,7 @@ bool Steam_GameServerStats::UpdateUserAvgRateStat( CSteamID steamIDUser, const c { PRINT_DEBUG("Steam_GameServerStats::UpdateUserAvgRateStat %llu '%s'\n", (uint64)steamIDUser.ConvertToUint64(), pchName); std::lock_guard lock(global_mutex); + if (settings->disable_sharing_stats_with_gameserver) return false; if (!pchName) return false; @@ -258,6 +274,7 @@ bool Steam_GameServerStats::SetUserAchievement( CSteamID steamIDUser, const char { PRINT_DEBUG("Steam_GameServerStats::SetUserAchievement %llu '%s'\n", (uint64)steamIDUser.ConvertToUint64(), pchName); std::lock_guard lock(global_mutex); + if (settings->disable_sharing_stats_with_gameserver) return false; if (!pchName) return false; @@ -274,6 +291,7 @@ bool Steam_GameServerStats::ClearUserAchievement( CSteamID steamIDUser, const ch { PRINT_DEBUG("Steam_GameServerStats::ClearUserAchievement %llu '%s'\n", (uint64)steamIDUser.ConvertToUint64(), pchName); std::lock_guard lock(global_mutex); + if (settings->disable_sharing_stats_with_gameserver) return false; if (!pchName) return false; @@ -299,6 +317,12 @@ SteamAPICall_t Steam_GameServerStats::StoreUserStats( CSteamID steamIDUser ) // it's not necessary to send all data here PRINT_DEBUG("Steam_GameServerStats::StoreUserStats\n"); std::lock_guard lock(global_mutex); + if (settings->disable_sharing_stats_with_gameserver) { + GSStatsStored_t data_bad{}; + data_bad.m_eResult = EResult::k_EResultFail; + data_bad.m_steamIDUser = steamIDUser; + return callback_results->addCallResult(data_bad.k_iCallback, &data_bad, sizeof(data_bad)); + } GSStatsStored_t data{}; diff --git a/dll/steam_user_stats.cpp b/dll/steam_user_stats.cpp index cc9c7ed5..89731711 100644 --- a/dll/steam_user_stats.cpp +++ b/dll/steam_user_stats.cpp @@ -273,6 +273,8 @@ unsigned int Steam_User_Stats::cache_leaderboard_ifneeded(const std::string &nam void Steam_User_Stats::send_my_leaderboard_score(const Steam_Leaderboard &board, const CSteamID *steamid, bool want_scores_back) { + if (settings->disable_sharing_leaderboards) return; + const auto my_entry = board.find_recent_entry(settings->get_local_steam_id()); Leaderboards_Messages::UserScoreEntry *score_entry_msg = nullptr; @@ -306,6 +308,8 @@ void Steam_User_Stats::send_my_leaderboard_score(const Steam_Leaderboard &board, void Steam_User_Stats::request_user_leaderboard_entry(const Steam_Leaderboard &board, const CSteamID &steamid) { + if (settings->disable_sharing_leaderboards) return; + auto board_info_msg = new Leaderboards_Messages::LeaderboardInfo(); board_info_msg->set_allocated_board_name(new std::string(board.name)); board_info_msg->set_sort_method(board.sort_method); @@ -363,7 +367,7 @@ Steam_User_Stats::InternalSetResult Steam_User_Stats::set_stat_internal( if (local_storage->store_data(Local_Storage::stats_storage_folder, stat_name, (char* )&nData, sizeof(nData)) == sizeof(nData)) { stats_cache_int[stat_name] = nData; result.success = true; - result.notify_server = true; + result.notify_server = !settings->disable_sharing_stats_with_gameserver; return result; } @@ -408,7 +412,7 @@ Steam_User_Stats::InternalSetResultstore_data(Local_Storage::stats_storage_folder, stat_name, (char* )&fData, sizeof(fData)) == sizeof(fData)) { stats_cache_float[stat_name] = fData; result.success = true; - result.notify_server = true; + result.notify_server = !settings->disable_sharing_stats_with_gameserver; return result; } @@ -454,7 +458,7 @@ Steam_User_Stats::InternalSetResultstore_data(Local_Storage::stats_storage_folder, stat_name, data, sizeof(data)) == sizeof(data)) { stats_cache_float[stat_name] = average; result.success = true; - result.notify_server = true; + result.notify_server = !settings->disable_sharing_stats_with_gameserver; return result; } @@ -497,7 +501,7 @@ Steam_User_Stats::InternalSetResult Steam_User_Stats::set_achievement_inte save_achievements(); - result.notify_server = true; + result.notify_server = !settings->disable_sharing_stats_with_gameserver; if(!settings->disable_overlay) overlay->AddAchievementNotification(it.value()); @@ -541,7 +545,7 @@ Steam_User_Stats::InternalSetResult Steam_User_Stats::clear_achievement_in user_achievements[pch_name]["earned_time"] = static_cast(0); save_achievements(); - result.notify_server = true; + result.notify_server = !settings->disable_sharing_stats_with_gameserver; } } catch (...) {} @@ -639,16 +643,24 @@ Steam_User_Stats::Steam_User_Stats(Settings *settings, class Networking *network return result.second != rhs.cend() && (result.first == lhs.cend() || std::tolower(*result.first) < std::tolower(*result.second));} ); - this->network->setCallback(CALLBACK_ID_GAMESERVER_STATS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_stats, this); - this->network->setCallback(CALLBACK_ID_LEADERBOARDS_STATS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_leaderboards, this); + if (!settings->disable_sharing_stats_with_gameserver) { + this->network->setCallback(CALLBACK_ID_GAMESERVER_STATS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_stats, this); + } + if (!settings->disable_sharing_leaderboards) { + this->network->setCallback(CALLBACK_ID_LEADERBOARDS_STATS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_leaderboards, this); + } this->network->setCallback(CALLBACK_ID_USER_STATUS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_low_level, this); this->run_every_runcb->add(&Steam_User_Stats::steam_user_stats_run_every_runcb, this); } Steam_User_Stats::~Steam_User_Stats() { - this->network->rmCallback(CALLBACK_ID_GAMESERVER_STATS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_stats, this); - this->network->rmCallback(CALLBACK_ID_LEADERBOARDS_STATS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_leaderboards, this); + if (!settings->disable_sharing_stats_with_gameserver) { + this->network->rmCallback(CALLBACK_ID_GAMESERVER_STATS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_stats, this); + } + if (!settings->disable_sharing_leaderboards) { + this->network->rmCallback(CALLBACK_ID_LEADERBOARDS_STATS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_leaderboards, this); + } this->network->rmCallback(CALLBACK_ID_USER_STATUS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_low_level, this); this->run_every_runcb->remove(&Steam_User_Stats::steam_user_stats_run_every_runcb, this); } @@ -1649,6 +1661,7 @@ bool Steam_User_Stats::GetAchievementProgressLimits( const char *pchName, float void Steam_User_Stats::send_updated_stats() { if (pending_server_updates.user_stats().empty() && pending_server_updates.user_achievements().empty()) return; + if (settings->disable_sharing_stats_with_gameserver) return; auto new_updates_msg = new GameServerStats_Messages::AllStats(pending_server_updates); pending_server_updates.clear_user_stats(); diff --git a/post_build/README.release.md b/post_build/README.release.md index 2d4a1cf5..539b003b 100644 --- a/post_build/README.release.md +++ b/post_build/README.release.md @@ -542,6 +542,24 @@ Check the example file. --- +## Sharing leaderboards scores over LAN: + +By default the emu will mutually share leaderboards scores with people playing the same game on the same network, you can disable this option by adding the config file `disable_sharing_leaderboards.txt` inside your `steam_settings` folder. + +This works best with real LAN, latency from VPN clients might break it. + +Check the example file in the `steam_settings` folder + +--- + +## Sharing stats and achievements with game servers: + +By default the emu will share stats with game servers, you can disable this option by adding the config file `disable_sharing_stats_with_gameserver.txt` inside your `steam_settings` folder, this also disables the interface `ISteamGameServerStats`. + +Check the example file in the `steam_settings` folder + +--- + ## More configurations: Due to the various changes and additions, it became tedious to document everything, so it is recommended to check each example file in the `steam_settings` folder. diff --git a/post_build/steam_settings.EXAMPLE/disable_sharing_leaderboards.EXAMPLE.txt b/post_build/steam_settings.EXAMPLE/disable_sharing_leaderboards.EXAMPLE.txt new file mode 100644 index 00000000..dbcc96ec --- /dev/null +++ b/post_build/steam_settings.EXAMPLE/disable_sharing_leaderboards.EXAMPLE.txt @@ -0,0 +1 @@ +Rename this file to disable_sharing_leaderboards.txt to disable sharing Leaderboards scroes with people playing the same game on the same network \ No newline at end of file diff --git a/post_build/steam_settings.EXAMPLE/disable_sharing_stats_with_gameserver.EXAMPLE.txt b/post_build/steam_settings.EXAMPLE/disable_sharing_stats_with_gameserver.EXAMPLE.txt new file mode 100644 index 00000000..ccef0583 --- /dev/null +++ b/post_build/steam_settings.EXAMPLE/disable_sharing_stats_with_gameserver.EXAMPLE.txt @@ -0,0 +1 @@ +Rename this file to disable_sharing_stats_with_gameserver.txt to prevent sharing stats and achievements with any game server, this also disables the interface ISteamGameServerStats \ No newline at end of file diff --git a/tools/generate_emu_config/generate_emu_config.py b/tools/generate_emu_config/generate_emu_config.py index ffcb501e..8e95ebb0 100644 --- a/tools/generate_emu_config/generate_emu_config.py +++ b/tools/generate_emu_config/generate_emu_config.py @@ -488,9 +488,8 @@ EXTRA_FEATURES: list[tuple[str, str]] = [ ("disable_account_avatar.txt", "disable avatar functionality."), ("disable_networking.txt", "disable all networking functionality."), ("disable_overlay.txt", "disable the overlay."), - ("disable_overlay_achievement_notification.txt", "disable the achievement notifications."), - ("disable_overlay_friend_notification.txt", "disable the friend invite and message notifications."), - ("disable_source_query.txt", "Do not send server details for the server browser. Only works for game servers."), + ("disable_source_query.txt", "do not send server details for the server browser. Only works for game servers."), + ("disable_sharing_leaderboards.txt", "disable sharing leaderboards scroes with people playing the same game on the same network."), ] def disable_all_extra_features(emu_settings_dir : str) -> None: