From 4809a7565c9bba46cf0e3c5c5b482018953c3449 Mon Sep 17 00:00:00 2001 From: otavepto Date: Tue, 26 Mar 2024 23:48:57 +0200 Subject: [PATCH] * separate the config file `disable_leaderboards_create_unknown.txt` * some refactoring --- CHANGELOG.md | 7 +- dll/dll/settings.h | 234 +++++++++--------- dll/dll/steam_user_stats.h | 1 + dll/settings.cpp | 34 ++- dll/settings_parser.cpp | 15 +- dll/steam_gameserverstats.cpp | 2 +- dll/steam_user_stats.cpp | 5 +- ...le_leaderboards_create_unknown.EXAMPLE.txt | 1 + 8 files changed, 172 insertions(+), 127 deletions(-) create mode 100644 post_build/steam_settings.EXAMPLE/disable_leaderboards_create_unknown.EXAMPLE.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index cb091e07..73f33cad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,14 +4,17 @@ - the above command introduced the ability to run without root - 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 -* implemented the missing interface `ISteamGameServerStats`, allowing game servers to exchange user stats with players +* implemented the missing interface `ISteamGameServerStats`, allowing game servers to exchange user stats & achievements with players * 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 dll `GameOverlayRenderer` for the experiemntal steamclient setup, some apps verify the existence of this dll, either on disk, or inside their memory space. **not recommended** to ignore it -* added new function `rmCallbacks()` for the networking, to be able to cleanup callbacks on object destruction +* separate the config file `disable_leaderboards_create_unknown.txt`, previously it was tied to `leaderboards.txt`, + by default the emu will create any unknown leaderboards, you can disable this behavior with this file * added missing example file `disable_lobby_creation.txt` in `steam_settings` folder + updated release `README` +* set the minimum game server latency/ping to 2ms +* added new function `rmCallbacks()` for the networking, to be able to cleanup callbacks on object destruction * for windows build script: prevent permissive language extensions via the compiler flag `/permissive-` * allow overlay invitations to obscure game input to be able to accept/reject the request diff --git a/dll/dll/settings.h b/dll/dll/settings.h index fefad045..ba500081 100644 --- a/dll/dll/settings.h +++ b/dll/dll/settings.h @@ -162,108 +162,28 @@ struct Overlay_Appearance { }; class Settings { - CSteamID steam_id; + CSteamID steam_id; // user id CGameID game_id; - std::string name, language; - CSteamID lobby_id; + std::string name{}; + std::string language{}; // default "english" + CSteamID lobby_id = k_steamIDNil; - bool unlockAllDLCs; - bool offline; - std::vector DLCs; - std::vector mods; - std::map app_paths; - std::map leaderboards; - std::map stats; - bool create_unknown_leaderboards; - uint16 port; - - // whether to auto accept any overlay invites - bool auto_accept_any_overlay_invites = false; - // list of user steam IDs to auto-accept invites from - std::set auto_accept_overlay_invites_friends{}; + bool unlockAllDLCs = true; + bool offline = false; + std::vector DLCs{}; + std::vector mods{}; + std::map app_paths{}; + std::map leaderboards{}; + std::map stats{}; + uint16 port{}; // Listen port, default 47584 public: -#ifdef LOBBY_CONNECT - static const bool is_lobby_connect = true; -#else - static const bool is_lobby_connect = false; -#endif - - static std::string sanitize(const std::string &name); - Settings(CSteamID steam_id, CGameID game_id, const std::string &name, const std::string &language, bool offline); - CSteamID get_local_steam_id(); - CGameID get_local_game_id(); - const char *get_local_name(); - void set_local_name(const char *name); - const char *get_language(); - void set_language(const char *language); - - void set_game_id(CGameID game_id); - void set_lobby(CSteamID lobby_id); - CSteamID get_lobby(); - bool is_offline() {return offline; } - uint16 get_port() {return port;} - void set_port(uint16 port) { this->port = port;} - - //DLC stuff - void unlockAllDLC(bool value); - void addDLC(AppId_t appID, std::string name, bool available); - unsigned int DLCCount(); - bool hasDLC(AppId_t appID); - bool getDLC(unsigned int index, AppId_t &appID, bool &available, std::string &name); - bool allDLCUnlocked() const; - //Depots - std::vector depots; - - //App Install paths - void setAppInstallPath(AppId_t appID, const std::string &path); - std::string getAppInstallPath(AppId_t appID); - - //mod stuff - void addMod(PublishedFileId_t id, const std::string &title, const std::string &path); - void addModDetails(PublishedFileId_t id, const Mod_entry &details); - Mod_entry getMod(PublishedFileId_t id); - bool isModInstalled(PublishedFileId_t id); - std::set modSet(); - - //leaderboards - void setLeaderboard(std::string leaderboard, enum ELeaderboardSortMethod sort_method, enum ELeaderboardDisplayType display_type); - std::map getLeaderboards() { return leaderboards; } - void setCreateUnknownLeaderboards(bool enable) {create_unknown_leaderboards = enable;} - bool createUnknownLeaderboards() { return create_unknown_leaderboards; } + std::vector depots{}; //custom broadcasts - std::set custom_broadcasts; - - //stats - const std::map& getStats() { return stats; } - void setStatDefiniton(std::string name, struct Stat_config stat_config) {stats[common_helpers::ascii_to_lowercase(name)] = stat_config; } - // bypass to make SetAchievement() always return true, prevent some games from breaking - bool achievement_bypass = false; - - //subscribed lobby/group ids - std::set subscribed_groups; - std::vector subscribed_groups_clans; - - //images - std::map images; - int add_image(const std::string &data, uint32 width, uint32 height); - bool disable_account_avatar = false; - - //installed app ids, Steam_Apps::BIsAppInstalled() - std::set installed_app_ids; - bool assume_any_app_installed = true; - bool appIsInstalled(AppId_t appID); - - //is playing on beta branch + current/forced branch name - bool is_beta_branch = false; - std::string current_branch_name = "public"; - - //controller - struct Controller_Settings controller_settings; - std::string glyphs_directory; + std::set custom_broadcasts{}; //networking bool disable_networking = false; @@ -275,6 +195,59 @@ public: bool matchmaking_server_list_always_lan_type = true; bool matchmaking_server_details_via_source_query = false; + //app build id + int build_id = 10; + + //supported languages + std::set supported_languages{}; + + //make lobby creation fail in the matchmaking interface + bool disable_lobby_creation = false; + + // path to local save + std::string local_save{}; + + //steamhttp external download support + bool download_steamhttp_requests = false; + bool force_steamhttp_success = false; + + //steam deck flag + bool steam_deck = false; + + // use new app_ticket auth instead of old one + bool enable_new_app_ticket = false; + // can use GC token for generation + bool use_gc_token = false; + + // bypass to make SetAchievement() always return true, prevent some games from breaking + bool achievement_bypass = false; + + bool disable_account_avatar = false; + + std::map images{}; + + //subscribed lobby/group ids + std::set subscribed_groups{}; + std::vector subscribed_groups_clans{}; + + // get the alpha-2 code from: https://www.iban.com/country-codes + std::string ip_country = "US"; + + //is playing on beta branch + current/forced branch name + bool is_beta_branch = false; + std::string current_branch_name = "public"; + + //controller + struct Controller_Settings controller_settings{}; + std::string glyphs_directory{}; + + //installed app ids, Steam_Apps::BIsAppInstalled() + std::set installed_app_ids{}; + bool assume_any_app_installed = true; + + // allow Steam_User_Stats::FindLeaderboard() to always succeed and create the given unknown leaderboard + bool disable_leaderboards_create_unknown = false; + //overlay bool disable_overlay = false; int overlay_hook_delay_sec = 0; // "Saints Row (2022)" needs a lot of time to initialize, otherwise detection will fail @@ -294,30 +267,65 @@ public: // disable all overlay warnings bool disable_overlay_warning_any = false; Overlay_Appearance overlay_appearance{}; + // whether to auto accept any overlay invites + bool auto_accept_any_overlay_invites = false; + // list of user steam IDs to auto-accept invites from + std::set auto_accept_overlay_invites_friends{}; - //app build id - int build_id = 10; - //supported languages - std::set supported_languages; +#ifdef LOBBY_CONNECT + static const bool is_lobby_connect = true; +#else + static const bool is_lobby_connect = false; +#endif - //make lobby creation fail in the matchmaking interface - bool disable_lobby_creation = false; + static std::string sanitize(const std::string &name); + Settings(CSteamID steam_id, CGameID game_id, const std::string &name, const std::string &language, bool offline); + CSteamID get_local_steam_id(); + CGameID get_local_game_id(); + const char *get_local_name(); + void set_local_name(const char *name); + const char *get_language(); + void set_language(const char *language); - // path to local save - std::string local_save; + void set_game_id(CGameID game_id); + void set_lobby(CSteamID lobby_id); + CSteamID get_lobby(); + bool is_offline(); + uint16 get_port(); + void set_port(uint16 port); - //steamhttp external download support - bool download_steamhttp_requests = false; - bool force_steamhttp_success = false; + //DLC stuff + void unlockAllDLC(bool value); + void addDLC(AppId_t appID, std::string name, bool available); + unsigned int DLCCount(); + bool hasDLC(AppId_t appID); + bool getDLC(unsigned int index, AppId_t &appID, bool &available, std::string &name); + bool allDLCUnlocked() const; - //steam deck flag - bool steam_deck = false; - - // use new app_ticket auth instead of old one - bool enable_new_app_ticket = false; - // can use GC token for generation - bool use_gc_token = false; + //App Install paths + void setAppInstallPath(AppId_t appID, const std::string &path); + std::string getAppInstallPath(AppId_t appID); + + //mod stuff + void addMod(PublishedFileId_t id, const std::string &title, const std::string &path); + void addModDetails(PublishedFileId_t id, const Mod_entry &details); + Mod_entry getMod(PublishedFileId_t id); + bool isModInstalled(PublishedFileId_t id); + std::set modSet(); + + //leaderboards + void setLeaderboard(std::string leaderboard, enum ELeaderboardSortMethod sort_method, enum ELeaderboardDisplayType display_type); + std::map getLeaderboards(); + + //stats + const std::map& getStats(); + void setStatDefiniton(const std::string &name, const struct Stat_config &stat_config); + + //images + int add_image(const std::string &data, uint32 width, uint32 height); + + bool appIsInstalled(AppId_t appID); // overlay auto accept stuff void acceptAnyOverlayInvites(bool value); @@ -325,8 +333,6 @@ public: bool hasOverlayAutoAcceptInviteFromFriend(uint64_t friend_id) const; size_t overlayAutoAcceptInvitesCount() const; - // get the alpha-2 code from: https://www.iban.com/country-codes - std::string ip_country = "US"; }; #endif diff --git a/dll/dll/steam_user_stats.h b/dll/dll/steam_user_stats.h index 0a3a9155..5c585a81 100644 --- a/dll/dll/steam_user_stats.h +++ b/dll/dll/steam_user_stats.h @@ -103,6 +103,7 @@ private: GameServerStats_Messages::AllStats pending_server_updates{}; + // returns a value 1 -> leaderboards.size(), inclusize unsigned int find_leaderboard(std::string name); nlohmann::detail::iter_impl defined_achievements_find(const std::string &key); diff --git a/dll/settings.cpp b/dll/settings.cpp index c9b931f2..91f73c9f 100644 --- a/dll/settings.cpp +++ b/dll/settings.cpp @@ -75,11 +75,8 @@ Settings::Settings(CSteamID steam_id, CGameID game_id, const std::string &name, std::transform(lang.begin(), lang.end(), lang.begin(), ::tolower); lang.erase(std::remove(lang.begin(), lang.end(), ' '), lang.end()); this->language = lang; - this->lobby_id = k_steamIDNil; - this->unlockAllDLCs = true; this->offline = offline; - this->create_unknown_leaderboards = true; } CSteamID Settings::get_local_steam_id() @@ -127,6 +124,21 @@ CSteamID Settings::get_lobby() return this->lobby_id; } +bool Settings::is_offline() +{ + return offline; +} + +uint16 Settings::get_port() +{ + return port; +} + +void Settings::set_port(uint16 port) +{ + this->port = port; +} + void Settings::unlockAllDLC(bool value) { this->unlockAllDLCs = value; @@ -275,6 +287,22 @@ void Settings::setLeaderboard(std::string leaderboard, enum ELeaderboardSortMeth leaderboards[leaderboard] = leader; } +std::map Settings::getLeaderboards() +{ + return leaderboards; +} + +const std::map& Settings::getStats() +{ + return stats; +} + +void Settings::setStatDefiniton(const std::string &name, const struct Stat_config &stat_config) +{ + stats[common_helpers::ascii_to_lowercase(name)] = stat_config; +} + + int Settings::add_image(const std::string &data, uint32 width, uint32 height) { int last = images.size() + 1; diff --git a/dll/settings_parser.cpp b/dll/settings_parser.cpp index 9b62c1e1..7ea402ff 100644 --- a/dll/settings_parser.cpp +++ b/dll/settings_parser.cpp @@ -388,7 +388,7 @@ uint16 parse_listen_port(class Local_Storage *local_storage) char array_port[10] = {}; array_port[0] = '0'; local_storage->get_data_settings("listen_port.txt", array_port, sizeof(array_port) - 1); - uint16 port = std::stoi(array_port); + uint16 port = (uint16)std::stoi(array_port); if (port == 0) { port = DEFAULT_PORT; snprintf(array_port, sizeof(array_port), "%hu", port); @@ -589,8 +589,6 @@ static void parse_leaderboards(class Settings *settings_client, Settings *settin std::ifstream input( utf8_decode(dlc_config_path) ); if (input.is_open()) { common_helpers::consume_bom(input); - settings_client->setCreateUnknownLeaderboards(false); - settings_server->setCreateUnknownLeaderboards(false); for( std::string line; getline( input, line ); ) { if (!line.empty() && line[line.length()-1] == '\n') { @@ -1131,7 +1129,7 @@ static void parse_ip_country(class Settings *settings_client, Settings *settings line = common_helpers::string_strip(line); // ISO 3166-1-alpha-2 format is 2 chars only if (line.size() == 2) { - std::transform(line.begin(), line.end(), line.begin(), [](char c) { return std::toupper(c); }); + std::transform(line.begin(), line.end(), line.begin(), [](char c){ return std::toupper(c); } ); settings_client->ip_country = line; settings_server->ip_country = line; PRINT_DEBUG("Setting IP country to: '%s'\n", line.c_str()); @@ -1239,6 +1237,7 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s bool disable_account_avatar = false; bool achievement_bypass = false; bool is_beta_branch = false; + bool disable_leaderboards_create_unknown = false; bool use_gc_token = false; bool enable_new_app_ticket = false; int build_id = 10; @@ -1284,6 +1283,8 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s disable_source_query = true; } else if (p == "disable_account_avatar.txt") { disable_account_avatar = true; + } else if (p == "disable_leaderboards_create_unknown.txt") { + disable_leaderboards_create_unknown = true; } else if (p == "achievements_bypass.txt") { achievement_bypass = true; } else if (p == "is_beta_branch.txt") { @@ -1354,14 +1355,20 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s settings_server->supported_languages = supported_languages; settings_client->steam_deck = steam_deck_mode; settings_server->steam_deck = steam_deck_mode; + settings_client->download_steamhttp_requests = download_steamhttp_requests; settings_server->download_steamhttp_requests = download_steamhttp_requests; settings_client->force_steamhttp_success = force_steamhttp_success; settings_server->force_steamhttp_success = force_steamhttp_success; + settings_client->achievement_bypass = achievement_bypass; settings_server->achievement_bypass = achievement_bypass; settings_client->is_beta_branch = is_beta_branch; settings_server->is_beta_branch = is_beta_branch; + + settings_client->disable_leaderboards_create_unknown = disable_leaderboards_create_unknown; + settings_server->disable_leaderboards_create_unknown = disable_leaderboards_create_unknown; + 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 bc562af2..3585d292 100644 --- a/dll/steam_gameserverstats.cpp +++ b/dll/steam_gameserverstats.cpp @@ -440,7 +440,7 @@ void Steam_GameServerStats::network_callback_initial_stats(Common_Message *msg) item.steamIDUser == user_steamid; } ); - if (pending_RequestUserStats.end() == it) { // timeout and already removed + if (pending_RequestUserStats.end() == it) { // timeout and already removed PRINT_DEBUG("Steam_GameServerStats::network_callback_initial_stats error got all player stats but pending request timedout and removed\n"); return; } diff --git a/dll/steam_user_stats.cpp b/dll/steam_user_stats.cpp index defbe073..cc4e827a 100644 --- a/dll/steam_user_stats.cpp +++ b/dll/steam_user_stats.cpp @@ -18,7 +18,6 @@ #include "dll/steam_user_stats.h" - unsigned int Steam_User_Stats::find_leaderboard(std::string name) { unsigned index = 1; @@ -1017,10 +1016,10 @@ SteamAPICall_t Steam_User_Stats::FindLeaderboard( const char *pchLeaderboardName if (settings_Leaderboards.count(pchLeaderboardName)) { auto config = settings_Leaderboards[pchLeaderboardName]; return FindOrCreateLeaderboard(pchLeaderboardName, config.sort_method, config.display_type); - } else if (settings->createUnknownLeaderboards()) { + } else if (!settings->disable_leaderboards_create_unknown) { return FindOrCreateLeaderboard(pchLeaderboardName, k_ELeaderboardSortMethodDescending, k_ELeaderboardDisplayTypeNumeric); } else { - LeaderboardFindResult_t data; + LeaderboardFindResult_t data{}; data.m_hSteamLeaderboard = find_leaderboard(pchLeaderboardName);; data.m_bLeaderboardFound = !!data.m_hSteamLeaderboard; return callback_results->addCallResult(data.k_iCallback, &data, sizeof(data)); diff --git a/post_build/steam_settings.EXAMPLE/disable_leaderboards_create_unknown.EXAMPLE.txt b/post_build/steam_settings.EXAMPLE/disable_leaderboards_create_unknown.EXAMPLE.txt new file mode 100644 index 00000000..a1dc16c9 --- /dev/null +++ b/post_build/steam_settings.EXAMPLE/disable_leaderboards_create_unknown.EXAMPLE.txt @@ -0,0 +1 @@ +Rename this file to disable_leaderboards_create_unknown.txt to prevent Steam_User_Stats::FindLeaderboard() from always succeeding and creating the unknown leaderboard \ No newline at end of file