diff --git a/dll/dll/auth.h b/dll/dll/auth.h index fb3289f2..b5bffd8f 100644 --- a/dll/dll/auth.h +++ b/dll/dll/auth.h @@ -165,7 +165,7 @@ static std::vector sign_auth_data(const std::string &private_key_conten #ifndef EMU_RELEASE_BUILD // we nedd a live object until the printf does its job, hence this special handling - auto str = uint8_vector_to_hex_string(signature); + auto str = common_helpers::uint8_vector_to_hex_string(signature); PRINT_DEBUG("sign_auth_data final signature [%zu bytes]:\n %s\n", signature.size(), str.c_str()); #endif @@ -296,7 +296,7 @@ public: #ifndef EMU_RELEASE_BUILD // we nedd a live object until the printf does its job, hence this special handling - auto str = uint8_vector_to_hex_string(buffer); + auto str = common_helpers::uint8_vector_to_hex_string(buffer); PRINT_DEBUG("AUTH::AppTicketGC::SER final data [%zu bytes]:\n %s\n", buffer.size(), str.c_str()); #endif @@ -407,7 +407,7 @@ struct AppTicket { #ifndef EMU_RELEASE_BUILD { // we nedd a live object until the printf does its job, hence this special handling - auto str = uint8_vector_to_hex_string(buffer); + auto str = common_helpers::uint8_vector_to_hex_string(buffer); PRINT_DEBUG("AUTH::AppTicket::SER (before licenses + DLCs):\n %s\n", str.c_str()); } #endif @@ -460,7 +460,7 @@ struct AppTicket { #ifndef EMU_RELEASE_BUILD { // we nedd a live object until the printf does its job, hence this special handling - auto str = uint8_vector_to_hex_string(buffer); + auto str = common_helpers::uint8_vector_to_hex_string(buffer); PRINT_DEBUG("AUTH::AppTicket::SER final data [%zu bytes]:\n %s\n", buffer.size(), str.c_str()); } #endif @@ -602,7 +602,7 @@ struct Auth_Data { #ifndef EMU_RELEASE_BUILD { // we nedd a live object until the printf does its job, hence this special handling - auto str = uint8_vector_to_hex_string(buffer); + auto str = common_helpers::uint8_vector_to_hex_string(buffer); PRINT_DEBUG("AUTH::Auth_Data::SER final data (before signature) [%zu bytes]:\n %s\n", buffer.size(), str.c_str()); } #endif @@ -615,7 +615,7 @@ struct Auth_Data { #ifndef EMU_RELEASE_BUILD { // we nedd a live object until the printf does its job, hence this special handling - auto str = uint8_vector_to_hex_string(buffer); + auto str = common_helpers::uint8_vector_to_hex_string(buffer); PRINT_DEBUG("AUTH::Auth_Data::SER final data (after signature) [%zu bytes]:\n %s\n", buffer.size(), str.c_str()); } #endif diff --git a/dll/dll/common_includes.h b/dll/dll/common_includes.h index 9aa15ed2..4a9c1d81 100644 --- a/dll/dll/common_includes.h +++ b/dll/dll/common_includes.h @@ -167,8 +167,6 @@ static inline void reset_LastError() #include "utfcpp/utf8.h" #include "controller/gamepad.h" -constexpr const char * const whitespaces = " \t\r\n"; - // common includes #include "common_helpers/common_helpers.hpp" @@ -215,56 +213,6 @@ constexpr const char * const whitespaces = " \t\r\n"; #define PRINT_DEBUG(...) #endif // EMU_RELEASE_BUILD -static inline std::string ascii_to_lowercase(std::string data) { - std::transform(data.begin(), data.end(), data.begin(), - [](unsigned char c){ return std::tolower(c); }); - return data; -} - -static inline void thisThreadYieldFor(std::chrono::microseconds u) -{ - PRINT_DEBUG("Thread is waiting for %lld us\n", (long long int)u.count()); - const auto start = std::chrono::high_resolution_clock::now(); - const auto end = start + u; - do - { - std::this_thread::yield(); - } - while (std::chrono::high_resolution_clock::now() < end); - PRINT_DEBUG("Thread finished waiting\n"); -} - -static std::string uint8_vector_to_hex_string(const std::vector& v) -{ - std::string result{}; - result.reserve(v.size() * 2); // two digits per character - - static constexpr const char hex[] = "0123456789ABCDEF"; - - for (uint8_t c : v) - { - result.push_back(hex[c / 16]); - result.push_back(hex[c % 16]); - } - - return result; -} - -static inline void consume_bom(std::ifstream &input) -{ - if (!input.is_open()) return; - - auto pos = input.tellg(); - int bom[3]{}; - bom[0] = input.get(); - bom[1] = input.get(); - bom[2] = input.get(); - if (bom[0] != 0xEF || bom[1] != 0xBB || bom[2] != 0xBF) { - input.clear(); - input.seekg(pos, std::ios::beg); - } -} - // Emulator includes // add them here after the inline functions definitions #include "net.pb.h" diff --git a/dll/dll/settings.h b/dll/dll/settings.h index 0d13e15f..4c8a619e 100644 --- a/dll/dll/settings.h +++ b/dll/dll/settings.h @@ -237,7 +237,7 @@ public: //stats std::map getStats() { return stats; } - void setStatDefiniton(std::string name, struct Stat_config stat_config) {stats[ascii_to_lowercase(name)] = stat_config; } + 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; diff --git a/dll/dll/steam_networking.h b/dll/dll/steam_networking.h index a5da8393..d6d36fdd 100644 --- a/dll/dll/steam_networking.h +++ b/dll/dll/steam_networking.h @@ -911,7 +911,7 @@ void Callback(Common_Message *msg) "Steam_Networking: got msg from: " "%" PRIu64 " to: " "%" PRIu64 " size %zu type %u | messages %p: %zu\n", msg->source_id(), msg->dest_id(), msg->network().data().size(), msg->network().type(), &messages, messages.size() ); - PRINT_DEBUG("Steam_Networking msg data: '%s'\n", uint8_vector_to_hex_string( std::vector(msg->network().data().begin(), msg->network().data().end()) ).c_str()); + PRINT_DEBUG("Steam_Networking msg data: '%s'\n", common_helpers::uint8_vector_to_hex_string( std::vector(msg->network().data().begin(), msg->network().data().end()) ).c_str()); #endif if (msg->network().type() == Network_pb::DATA) { diff --git a/dll/dll/steam_user_stats.h b/dll/dll/steam_user_stats.h index 4f712f11..b43084dc 100644 --- a/dll/dll/steam_user_stats.h +++ b/dll/dll/steam_user_stats.h @@ -142,7 +142,7 @@ void save_leaderboard_score(Steam_Leaderboard *leaderboard) output.push_back(s); } - std::string leaderboard_name = ascii_to_lowercase(leaderboard->name); + std::string leaderboard_name = common_helpers::ascii_to_lowercase(leaderboard->name); local_storage->store_data(Local_Storage::leaderboard_storage_folder, leaderboard_name, (char* )output.data(), sizeof(uint32_t) * output.size()); } @@ -150,7 +150,7 @@ std::vector load_leaderboard_scores(std::string name) { std::vector out; - std::string leaderboard_name = ascii_to_lowercase(name); + std::string leaderboard_name = common_helpers::ascii_to_lowercase(name); unsigned size = local_storage->file_size(Local_Storage::leaderboard_storage_folder, leaderboard_name); if (size == 0 || (size % sizeof(uint32_t)) != 0) return out; @@ -254,7 +254,7 @@ Steam_User_Stats(Settings *settings, Local_Storage *local_storage, class SteamCa achievement_trigger trig; trig.name = name; trig.value_operation = static_cast(it["progress"]["value"]["operation"]); - std::string stat_name = ascii_to_lowercase(static_cast(it["progress"]["value"]["operand1"])); + std::string stat_name = common_helpers::ascii_to_lowercase(static_cast(it["progress"]["value"]["operand1"])); trig.min_value = static_cast(it["progress"]["min_val"]); trig.max_value = static_cast(it["progress"]["max_val"]); achievement_stat_trigger[stat_name].push_back(trig); @@ -299,7 +299,7 @@ bool GetStat( const char *pchName, int32 *pData ) std::lock_guard lock(global_mutex); if (!pchName || !pData) return false; - std::string stat_name = ascii_to_lowercase(pchName); + std::string stat_name = common_helpers::ascii_to_lowercase(pchName); auto stats_config = settings->getStats(); auto stats_data = stats_config.find(stat_name); @@ -331,7 +331,7 @@ bool GetStat( const char *pchName, float *pData ) std::lock_guard lock(global_mutex); if (!pchName || !pData) return false; - std::string stat_name = ascii_to_lowercase(pchName); + std::string stat_name = common_helpers::ascii_to_lowercase(pchName); auto stats_config = settings->getStats(); auto stats_data = stats_config.find(stat_name); @@ -365,7 +365,7 @@ bool SetStat( const char *pchName, int32 nData ) std::lock_guard lock(global_mutex); if (!pchName) return false; - std::string stat_name = ascii_to_lowercase(pchName); + std::string stat_name = common_helpers::ascii_to_lowercase(pchName); auto stats_config = settings->getStats(); auto stats_data = stats_config.find(stat_name); @@ -400,7 +400,7 @@ bool SetStat( const char *pchName, float fData ) std::lock_guard lock(global_mutex); if (!pchName) return false; - std::string stat_name = ascii_to_lowercase(pchName); + std::string stat_name = common_helpers::ascii_to_lowercase(pchName); auto stats_config = settings->getStats(); auto stats_data = stats_config.find(stat_name); @@ -435,7 +435,7 @@ bool UpdateAvgRateStat( const char *pchName, float flCountThisSession, double dS std::lock_guard lock(global_mutex); if (!pchName) return false; - std::string stat_name = ascii_to_lowercase(pchName); + std::string stat_name = common_helpers::ascii_to_lowercase(pchName); auto stats_config = settings->getStats(); auto stats_data = stats_config.find(stat_name); diff --git a/dll/settings_parser.cpp b/dll/settings_parser.cpp index 4a4a1d00..81e2ee8c 100644 --- a/dll/settings_parser.cpp +++ b/dll/settings_parser.cpp @@ -21,7 +21,7 @@ static void load_custom_broadcasts(std::string broadcasts_filepath, std::set, std::string>> button_pairs; for( std::string line; getline( input, line ); ) { @@ -464,7 +462,7 @@ std::set parse_supported_languages(class Local_Storage *local_stora std::string first_language; if (input.is_open()) { - consume_bom(input); + common_helpers::consume_bom(input); for( std::string line; getline( input, line ); ) { if (!line.empty() && line[line.length()-1] == '\n') { line.pop_back(); @@ -500,7 +498,7 @@ static void parse_dlc(class Settings *settings_client, Settings *settings_server std::string dlc_config_path = Local_Storage::get_game_settings_path() + "DLC.txt"; std::ifstream input( utf8_decode(dlc_config_path) ); if (input.is_open()) { - consume_bom(input); + common_helpers::consume_bom(input); settings_client->unlockAllDLC(false); settings_server->unlockAllDLC(false); PRINT_DEBUG("Locking all DLC\n"); @@ -545,7 +543,7 @@ static void parse_app_paths(class Settings *settings_client, Settings *settings_ std::ifstream input( utf8_decode(dlc_config_path) ); if (input.is_open()) { - consume_bom(input); + common_helpers::consume_bom(input); for( std::string line; getline( input, line ); ) { if (!line.empty() && line[line.length()-1] == '\n') { line.pop_back(); @@ -582,7 +580,7 @@ static void parse_leaderboards(class Settings *settings_client, Settings *settin std::string dlc_config_path = Local_Storage::get_game_settings_path() + "leaderboards.txt"; std::ifstream input( utf8_decode(dlc_config_path) ); if (input.is_open()) { - consume_bom(input); + common_helpers::consume_bom(input); settings_client->setCreateUnknownLeaderboards(false); settings_server->setCreateUnknownLeaderboards(false); @@ -627,7 +625,7 @@ static void parse_stats(class Settings *settings_client, Settings *settings_serv std::string stats_config_path = Local_Storage::get_game_settings_path() + "stats.txt"; std::ifstream input( utf8_decode(stats_config_path) ); if (input.is_open()) { - consume_bom(input); + common_helpers::consume_bom(input); for( std::string line; getline( input, line ); ) { if (!line.empty() && line[line.length()-1] == '\n') { line.pop_back(); @@ -695,7 +693,7 @@ static void parse_depots(class Settings *settings_client, Settings *settings_ser std::string depots_config_path = Local_Storage::get_game_settings_path() + "depots.txt"; std::ifstream input( utf8_decode(depots_config_path) ); if (input.is_open()) { - consume_bom(input); + common_helpers::consume_bom(input); for( std::string line; getline( input, line ); ) { if (!line.empty() && line[line.length()-1] == '\n') { line.pop_back(); @@ -722,7 +720,7 @@ static void parse_subscribed_groups(class Settings *settings_client, Settings *s std::string depots_config_path = Local_Storage::get_game_settings_path() + "subscribed_groups.txt"; std::ifstream input( utf8_decode(depots_config_path) ); if (input.is_open()) { - consume_bom(input); + common_helpers::consume_bom(input); for( std::string line; getline( input, line ); ) { if (!line.empty() && line[line.length()-1] == '\n') { line.pop_back(); @@ -752,7 +750,7 @@ static void parse_installed_app_Ids(class Settings *settings_client, Settings *s settings_client->assume_any_app_installed = false; settings_server->assume_any_app_installed = false; PRINT_DEBUG("Limiting/Locking installed apps\n"); - consume_bom(input); + common_helpers::consume_bom(input); for( std::string line; getline( input, line ); ) { if (!line.empty() && line[line.length()-1] == '\n') { line.pop_back(); @@ -783,16 +781,10 @@ static void parse_force_branch_name(class Settings *settings_client, Settings *s std::string installed_apps_list_path = Local_Storage::get_game_settings_path() + "force_branch_name.txt"; std::ifstream input( utf8_decode(installed_apps_list_path) ); if (input.is_open()) { - consume_bom(input); + common_helpers::consume_bom(input); std::string line; getline( input, line ); - - size_t start = line.find_first_not_of(whitespaces); - size_t end = line.find_last_not_of(whitespaces); - line = start == end - ? std::string() - : line.substr(start, end - start + 1); - + line = common_helpers::string_strip(line); if (!line.empty()) { settings_client->current_branch_name = line; settings_server->current_branch_name = line; @@ -1072,16 +1064,10 @@ static void parse_crash_printer_location() std::string installed_apps_list_path = Local_Storage::get_game_settings_path() + "crash_printer_location.txt"; std::ifstream input( utf8_decode(installed_apps_list_path) ); if (input.is_open()) { - consume_bom(input); + common_helpers::consume_bom(input); std::string line; std::getline( input, line ); - - size_t start = line.find_first_not_of(whitespaces); - size_t end = line.find_last_not_of(whitespaces); - line = start == end - ? std::string() - : line.substr(start, end - start + 1); - + line = common_helpers::string_strip(line); if (!line.empty()) { auto crash_path = utf8_decode(get_full_program_path() + line); if (crash_printer::init(crash_path)) { @@ -1100,15 +1086,9 @@ static void parse_auto_accept_invite(class Settings *settings_client, Settings * std::ifstream input( utf8_decode(auto_accept_list_path) ); if (input.is_open()) { bool accept_any_invite = true; - consume_bom(input); + common_helpers::consume_bom(input); for( std::string line; getline( input, line ); ) { - - size_t start = line.find_first_not_of(whitespaces); - size_t end = line.find_last_not_of(whitespaces); - line = start == end - ? std::string() - : line.substr(start, end - start + 1); - + line = common_helpers::string_strip(line); if (!line.empty()) { accept_any_invite = false; try { @@ -1137,16 +1117,10 @@ static void parse_ip_country(class Settings *settings_client, Settings *settings std::string setting_file = Local_Storage::get_game_settings_path() + "ip_country.txt"; std::ifstream input( utf8_decode(setting_file) ); if (input.is_open()) { - consume_bom(input); + common_helpers::consume_bom(input); std::string line{}; std::getline( input, line ); - - size_t start = line.find_first_not_of(whitespaces); - size_t end = line.find_last_not_of(whitespaces); - line = start == end - ? std::string() - : line.substr(start, end - start + 1); - + 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); }); @@ -1164,15 +1138,10 @@ static void parse_overlay_hook_delay_sec(class Settings *settings_client, Settin std::ifstream input( utf8_decode(auto_accept_list_path) ); if (input.is_open()) { bool accept_any_invite = true; - consume_bom(input); + common_helpers::consume_bom(input); std::string line{}; std::getline( input, line ); - size_t start = line.find_first_not_of(whitespaces); - size_t end = line.find_last_not_of(whitespaces); - line = start == end - ? std::string() - : line.substr(start, end - start + 1); - + line = common_helpers::string_strip(line); if (!line.empty()) { try { auto delay_sec = std::stoi(line); diff --git a/helpers/common_helpers.cpp b/helpers/common_helpers.cpp index 153539b8..5d0140e5 100644 --- a/helpers/common_helpers.cpp +++ b/helpers/common_helpers.cpp @@ -2,6 +2,7 @@ #include #include #include +#include static bool create_dir_impl(std::filesystem::path &dirpath) { @@ -106,6 +107,71 @@ bool common_helpers::ends_with_i(const std::wstring &target, const std::wstring } +std::string common_helpers::string_strip(const std::string& str) +{ + static constexpr const char whitespaces[] = " \t\r\n"; + + size_t start = str.find_first_not_of(whitespaces); + size_t end = str.find_last_not_of(whitespaces); + + if (start == std::string::npos) return {}; + + if (start == end) { + auto c = str[start]; + for (auto c_white = whitespaces; *c_white; ++c_white) { + if (c == *c_white) return {}; + } + } + + return str.substr(start, end - start + 1); +} + +std::string common_helpers::uint8_vector_to_hex_string(const std::vector& v) +{ + std::string result{}; + result.reserve(v.size() * 2); // two digits per character + + static constexpr const char hex[] = "0123456789ABCDEF"; + + for (uint8_t c : v) + { + result.push_back(hex[c / 16]); + result.push_back(hex[c % 16]); + } + + return result; +} + +std::string common_helpers::ascii_to_lowercase(std::string data) { + std::transform(data.begin(), data.end(), data.begin(), + [](unsigned char c){ return std::tolower(c); }); + return data; +} + +void common_helpers::thisThreadYieldFor(std::chrono::microseconds u) +{ + const auto start = std::chrono::high_resolution_clock::now(); + const auto end = start + u; + do { + std::this_thread::yield(); + } while (std::chrono::high_resolution_clock::now() < end); +} + +void common_helpers::consume_bom(std::ifstream &input) +{ + if (!input.is_open()) return; + + auto pos = input.tellg(); + int bom[3]{}; + bom[0] = input.get(); + bom[1] = input.get(); + bom[2] = input.get(); + if (bom[0] != 0xEF || bom[1] != 0xBB || bom[2] != 0xBF) { + input.clear(); + input.seekg(pos, std::ios::beg); + } +} + std::string common_helpers::to_lower(std::string str) { std::string _str(str.size(), '\0'); diff --git a/helpers/common_helpers/common_helpers.hpp b/helpers/common_helpers/common_helpers.hpp index b4c2ec04..b763b148 100644 --- a/helpers/common_helpers/common_helpers.hpp +++ b/helpers/common_helpers/common_helpers.hpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace common_helpers { @@ -24,6 +25,16 @@ bool ends_with_i(const std::string &target, const std::string &query); bool ends_with_i(const std::wstring &target, const std::wstring &query); +std::string string_strip(const std::string& str); + +std::string uint8_vector_to_hex_string(const std::vector& v); + +std::string ascii_to_lowercase(std::string data); + +void thisThreadYieldFor(std::chrono::microseconds u); + +void consume_bom(std::ifstream &input); + std::string to_lower(std::string str); std::wstring to_lower(std::wstring wstr);