* separate the config file disable_leaderboards_create_unknown.txt

* some refactoring
This commit is contained in:
otavepto 2024-03-26 23:48:57 +02:00
parent af77ce4f5a
commit 4809a7565c
8 changed files with 172 additions and 127 deletions

View File

@ -4,14 +4,17 @@
- the above command introduced the ability to run without root - the above command introduced the ability to run without root
- if the script was ran without root, and `-packages_skip` wasn't specified, - 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 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, * for windows: updated stub drm patterns and added a workaround for older variants,
this increases the compatibility, but makes it easier to be detected this increases the compatibility, but makes it easier to be detected
* new stub dll `GameOverlayRenderer` for the experiemntal steamclient setup, * 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. some apps verify the existence of this dll, either on disk, or inside their memory space.
**not recommended** to ignore it **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` * 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-` * 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 * allow overlay invitations to obscure game input to be able to accept/reject the request

View File

@ -162,108 +162,28 @@ struct Overlay_Appearance {
}; };
class Settings { class Settings {
CSteamID steam_id; CSteamID steam_id; // user id
CGameID game_id; CGameID game_id;
std::string name, language; std::string name{};
CSteamID lobby_id; std::string language{}; // default "english"
CSteamID lobby_id = k_steamIDNil;
bool unlockAllDLCs; bool unlockAllDLCs = true;
bool offline; bool offline = false;
std::vector<struct DLC_entry> DLCs; std::vector<struct DLC_entry> DLCs{};
std::vector<struct Mod_entry> mods; std::vector<struct Mod_entry> mods{};
std::map<AppId_t, std::string> app_paths; std::map<AppId_t, std::string> app_paths{};
std::map<std::string, Leaderboard_config> leaderboards; std::map<std::string, Leaderboard_config> leaderboards{};
std::map<std::string, Stat_config> stats; std::map<std::string, Stat_config> stats{};
bool create_unknown_leaderboards; uint16 port{}; // Listen port, default 47584
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<uint64_t> auto_accept_overlay_invites_friends{};
public: 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 //Depots
std::vector<DepotId_t> depots; std::vector<DepotId_t> 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<PublishedFileId_t> modSet();
//leaderboards
void setLeaderboard(std::string leaderboard, enum ELeaderboardSortMethod sort_method, enum ELeaderboardDisplayType display_type);
std::map<std::string, Leaderboard_config> getLeaderboards() { return leaderboards; }
void setCreateUnknownLeaderboards(bool enable) {create_unknown_leaderboards = enable;}
bool createUnknownLeaderboards() { return create_unknown_leaderboards; }
//custom broadcasts //custom broadcasts
std::set<IP_PORT> custom_broadcasts; std::set<IP_PORT> custom_broadcasts{};
//stats
const std::map<std::string, Stat_config>& 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<uint64> subscribed_groups;
std::vector<Group_Clans> subscribed_groups_clans;
//images
std::map<int, struct Image_Data> 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<AppId_t> 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;
//networking //networking
bool disable_networking = false; bool disable_networking = false;
@ -275,6 +195,59 @@ public:
bool matchmaking_server_list_always_lan_type = true; bool matchmaking_server_list_always_lan_type = true;
bool matchmaking_server_details_via_source_query = false; bool matchmaking_server_details_via_source_query = false;
//app build id
int build_id = 10;
//supported languages
std::set<std::string> 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<int, struct Image_Data> images{};
//subscribed lobby/group ids
std::set<uint64> subscribed_groups{};
std::vector<Group_Clans> 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<AppId_t> 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 //overlay
bool disable_overlay = false; bool disable_overlay = false;
int overlay_hook_delay_sec = 0; // "Saints Row (2022)" needs a lot of time to initialize, otherwise detection will fail 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 // disable all overlay warnings
bool disable_overlay_warning_any = false; bool disable_overlay_warning_any = false;
Overlay_Appearance overlay_appearance{}; 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<uint64_t> auto_accept_overlay_invites_friends{};
//app build id
int build_id = 10;
//supported languages #ifdef LOBBY_CONNECT
std::set<std::string> supported_languages; static const bool is_lobby_connect = true;
#else
static const bool is_lobby_connect = false;
#endif
//make lobby creation fail in the matchmaking interface static std::string sanitize(const std::string &name);
bool disable_lobby_creation = false; 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 void set_game_id(CGameID game_id);
std::string local_save; void set_lobby(CSteamID lobby_id);
CSteamID get_lobby();
bool is_offline();
uint16 get_port();
void set_port(uint16 port);
//steamhttp external download support //DLC stuff
bool download_steamhttp_requests = false; void unlockAllDLC(bool value);
bool force_steamhttp_success = false; 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 //App Install paths
bool steam_deck = false; void setAppInstallPath(AppId_t appID, const std::string &path);
std::string getAppInstallPath(AppId_t appID);
// use new app_ticket auth instead of old one
bool enable_new_app_ticket = false; //mod stuff
// can use GC token for generation void addMod(PublishedFileId_t id, const std::string &title, const std::string &path);
bool use_gc_token = false; void addModDetails(PublishedFileId_t id, const Mod_entry &details);
Mod_entry getMod(PublishedFileId_t id);
bool isModInstalled(PublishedFileId_t id);
std::set<PublishedFileId_t> modSet();
//leaderboards
void setLeaderboard(std::string leaderboard, enum ELeaderboardSortMethod sort_method, enum ELeaderboardDisplayType display_type);
std::map<std::string, Leaderboard_config> getLeaderboards();
//stats
const std::map<std::string, Stat_config>& 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 // overlay auto accept stuff
void acceptAnyOverlayInvites(bool value); void acceptAnyOverlayInvites(bool value);
@ -325,8 +333,6 @@ public:
bool hasOverlayAutoAcceptInviteFromFriend(uint64_t friend_id) const; bool hasOverlayAutoAcceptInviteFromFriend(uint64_t friend_id) const;
size_t overlayAutoAcceptInvitesCount() const; size_t overlayAutoAcceptInvitesCount() const;
// get the alpha-2 code from: https://www.iban.com/country-codes
std::string ip_country = "US";
}; };
#endif #endif

View File

@ -103,6 +103,7 @@ private:
GameServerStats_Messages::AllStats pending_server_updates{}; GameServerStats_Messages::AllStats pending_server_updates{};
// returns a value 1 -> leaderboards.size(), inclusize
unsigned int find_leaderboard(std::string name); unsigned int find_leaderboard(std::string name);
nlohmann::detail::iter_impl<nlohmann::json> defined_achievements_find(const std::string &key); nlohmann::detail::iter_impl<nlohmann::json> defined_achievements_find(const std::string &key);

View File

@ -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); std::transform(lang.begin(), lang.end(), lang.begin(), ::tolower);
lang.erase(std::remove(lang.begin(), lang.end(), ' '), lang.end()); lang.erase(std::remove(lang.begin(), lang.end(), ' '), lang.end());
this->language = lang; this->language = lang;
this->lobby_id = k_steamIDNil;
this->unlockAllDLCs = true;
this->offline = offline; this->offline = offline;
this->create_unknown_leaderboards = true;
} }
CSteamID Settings::get_local_steam_id() CSteamID Settings::get_local_steam_id()
@ -127,6 +124,21 @@ CSteamID Settings::get_lobby()
return this->lobby_id; 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) void Settings::unlockAllDLC(bool value)
{ {
this->unlockAllDLCs = value; this->unlockAllDLCs = value;
@ -275,6 +287,22 @@ void Settings::setLeaderboard(std::string leaderboard, enum ELeaderboardSortMeth
leaderboards[leaderboard] = leader; leaderboards[leaderboard] = leader;
} }
std::map<std::string, Leaderboard_config> Settings::getLeaderboards()
{
return leaderboards;
}
const std::map<std::string, Stat_config>& 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 Settings::add_image(const std::string &data, uint32 width, uint32 height)
{ {
int last = images.size() + 1; int last = images.size() + 1;

View File

@ -388,7 +388,7 @@ uint16 parse_listen_port(class Local_Storage *local_storage)
char array_port[10] = {}; char array_port[10] = {};
array_port[0] = '0'; array_port[0] = '0';
local_storage->get_data_settings("listen_port.txt", array_port, sizeof(array_port) - 1); 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) { if (port == 0) {
port = DEFAULT_PORT; port = DEFAULT_PORT;
snprintf(array_port, sizeof(array_port), "%hu", 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) ); std::ifstream input( utf8_decode(dlc_config_path) );
if (input.is_open()) { if (input.is_open()) {
common_helpers::consume_bom(input); common_helpers::consume_bom(input);
settings_client->setCreateUnknownLeaderboards(false);
settings_server->setCreateUnknownLeaderboards(false);
for( std::string line; getline( input, line ); ) { for( std::string line; getline( input, line ); ) {
if (!line.empty() && line[line.length()-1] == '\n') { 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); line = common_helpers::string_strip(line);
// ISO 3166-1-alpha-2 format is 2 chars only // ISO 3166-1-alpha-2 format is 2 chars only
if (line.size() == 2) { 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_client->ip_country = line;
settings_server->ip_country = line; settings_server->ip_country = line;
PRINT_DEBUG("Setting IP country to: '%s'\n", line.c_str()); 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 disable_account_avatar = false;
bool achievement_bypass = false; bool achievement_bypass = false;
bool is_beta_branch = false; bool is_beta_branch = false;
bool disable_leaderboards_create_unknown = false;
bool use_gc_token = false; bool use_gc_token = false;
bool enable_new_app_ticket = false; bool enable_new_app_ticket = false;
int build_id = 10; int build_id = 10;
@ -1284,6 +1283,8 @@ uint32 create_localstorage_settings(Settings **settings_client_out, Settings **s
disable_source_query = true; disable_source_query = true;
} else if (p == "disable_account_avatar.txt") { } else if (p == "disable_account_avatar.txt") {
disable_account_avatar = true; disable_account_avatar = true;
} else if (p == "disable_leaderboards_create_unknown.txt") {
disable_leaderboards_create_unknown = true;
} else if (p == "achievements_bypass.txt") { } else if (p == "achievements_bypass.txt") {
achievement_bypass = true; achievement_bypass = true;
} else if (p == "is_beta_branch.txt") { } 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_server->supported_languages = supported_languages;
settings_client->steam_deck = steam_deck_mode; settings_client->steam_deck = steam_deck_mode;
settings_server->steam_deck = steam_deck_mode; settings_server->steam_deck = steam_deck_mode;
settings_client->download_steamhttp_requests = download_steamhttp_requests; settings_client->download_steamhttp_requests = download_steamhttp_requests;
settings_server->download_steamhttp_requests = download_steamhttp_requests; settings_server->download_steamhttp_requests = download_steamhttp_requests;
settings_client->force_steamhttp_success = force_steamhttp_success; settings_client->force_steamhttp_success = force_steamhttp_success;
settings_server->force_steamhttp_success = force_steamhttp_success; settings_server->force_steamhttp_success = force_steamhttp_success;
settings_client->achievement_bypass = achievement_bypass; settings_client->achievement_bypass = achievement_bypass;
settings_server->achievement_bypass = achievement_bypass; settings_server->achievement_bypass = achievement_bypass;
settings_client->is_beta_branch = is_beta_branch; settings_client->is_beta_branch = is_beta_branch;
settings_server->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_client->enable_new_app_ticket = enable_new_app_ticket;
settings_server->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; settings_client->use_gc_token = use_gc_token;

View File

@ -440,7 +440,7 @@ void Steam_GameServerStats::network_callback_initial_stats(Common_Message *msg)
item.steamIDUser == user_steamid; 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"); PRINT_DEBUG("Steam_GameServerStats::network_callback_initial_stats error got all player stats but pending request timedout and removed\n");
return; return;
} }

View File

@ -18,7 +18,6 @@
#include "dll/steam_user_stats.h" #include "dll/steam_user_stats.h"
unsigned int Steam_User_Stats::find_leaderboard(std::string name) unsigned int Steam_User_Stats::find_leaderboard(std::string name)
{ {
unsigned index = 1; unsigned index = 1;
@ -1017,10 +1016,10 @@ SteamAPICall_t Steam_User_Stats::FindLeaderboard( const char *pchLeaderboardName
if (settings_Leaderboards.count(pchLeaderboardName)) { if (settings_Leaderboards.count(pchLeaderboardName)) {
auto config = settings_Leaderboards[pchLeaderboardName]; auto config = settings_Leaderboards[pchLeaderboardName];
return FindOrCreateLeaderboard(pchLeaderboardName, config.sort_method, config.display_type); 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); return FindOrCreateLeaderboard(pchLeaderboardName, k_ELeaderboardSortMethodDescending, k_ELeaderboardDisplayTypeNumeric);
} else { } else {
LeaderboardFindResult_t data; LeaderboardFindResult_t data{};
data.m_hSteamLeaderboard = find_leaderboard(pchLeaderboardName);; data.m_hSteamLeaderboard = find_leaderboard(pchLeaderboardName);;
data.m_bLeaderboardFound = !!data.m_hSteamLeaderboard; data.m_bLeaderboardFound = !!data.m_hSteamLeaderboard;
return callback_results->addCallResult(data.k_iCallback, &data, sizeof(data)); return callback_results->addCallResult(data.k_iCallback, &data, sizeof(data));

View File

@ -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