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

View File

@ -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<struct DLC_entry> DLCs;
std::vector<struct Mod_entry> mods;
std::map<AppId_t, std::string> app_paths;
std::map<std::string, Leaderboard_config> leaderboards;
std::map<std::string, Stat_config> 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<uint64_t> auto_accept_overlay_invites_friends{};
bool unlockAllDLCs = true;
bool offline = false;
std::vector<struct DLC_entry> DLCs{};
std::vector<struct Mod_entry> mods{};
std::map<AppId_t, std::string> app_paths{};
std::map<std::string, Leaderboard_config> leaderboards{};
std::map<std::string, Stat_config> 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<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; }
std::vector<DepotId_t> depots{};
//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;
std::set<IP_PORT> 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<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
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<uint64_t> auto_accept_overlay_invites_friends{};
//app build id
int build_id = 10;
//supported languages
std::set<std::string> 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;
//App Install paths
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;
// can use GC token for generation
bool use_gc_token = false;
//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();
//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
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

View File

@ -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<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);
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<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 last = images.size() + 1;

View File

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

View File

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

View File

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

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