diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8a4e680b3..4892aa4cc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,7 @@ jobs: - Release steps: - name: Check out files - uses: actions/checkout@v3.3.0 + uses: actions/checkout@v3.5.2 with: submodules: true fetch-depth: 0 @@ -105,7 +105,7 @@ jobs: path: data - name: Install SSH key - uses: shimataro/ssh-key-action@v2.5.0 + uses: shimataro/ssh-key-action@v2.5.1 with: key: ${{ secrets.BOIII_MASTER_SSH_PRIVATE_KEY }} known_hosts: "just-a-placeholder-so-we-dont-get-errors" diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 919315262..26c31a330 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -25,6 +25,8 @@ namespace auth { namespace { + const game::dvar_t* password; + std::array client_xuids{}; std::string get_hdd_serial() @@ -106,6 +108,11 @@ namespace auth std::string serialize_connect_data(const char* data, const int length) { utils::byte_buffer buffer{}; + buffer.write_string(get_key().serialize(PK_PUBLIC)); + + const std::string challenge(reinterpret_cast(0x15A8A7F10_g), 32); + buffer.write_string(utils::cryptography::ecc::sign_message(get_key(), challenge)); + profile_infos::get_profile_info().value_or(profile_infos::profile_info{}).serialize(buffer); buffer.write_string(data, static_cast(length)); @@ -210,6 +217,24 @@ namespace auth void dispatch_connect_packet(const game::netadr_t& target, const std::string& data) { utils::byte_buffer buffer(data); + + utils::cryptography::ecc::key key{}; + key.deserialize(buffer.read_string()); + + std::string challenge{}; + challenge.resize(32); + + const auto get_challenge = reinterpret_cast(game::select( + 0x1412E15E0, 0x14016DDC0)); + get_challenge(&target, challenge.data(), challenge.size()); + + if (!utils::cryptography::ecc::verify_message(key, challenge, buffer.read_string()) && target.type != + game::NA_LOOPBACK) + { + network::send(target, "error", "Bad signature"); + return; + } + const profile_infos::profile_info info(buffer); const auto connect_data = buffer.read_string(); @@ -224,6 +249,11 @@ namespace auth const utils::info_string info_string(params[1]); const auto xuid = strtoull(info_string.get("xuid").data(), nullptr, 16); + if (xuid != key.get_hash()) + { + network::send(target, "error", "Bad XUID"); + return; + } profile_infos::add_and_distribute_profile_info(target, xuid, info); @@ -324,6 +354,22 @@ namespace auth } } + void info_set_value_for_key_stub(char* s, const char* key, const char* value) + { + game::Info_SetValueForKey(s, key, value); + + if (password && *password->current.value.string) + { + game::Info_SetValueForKey(s, "password", password->current.value.string); + } + + const auto* clan_abbrev = game::LiveStats_GetClanTagText(0); + if (*clan_abbrev) + { + game::Info_SetValueForKey(s, "clanAbbrev", clan_abbrev); + } + } + struct component final : generic_component { void post_unpack() override @@ -336,6 +382,11 @@ namespace auth // Intercept SV_DirectConnect in SV_AddTestClient utils::hook::call(game::select(0x1422490DC, 0x14052E582), direct_connect_bots_stub); + scheduler::once([] + { + password = game::register_dvar_string("password", "", game::DVAR_USERINFO, "password"); + }, scheduler::pipeline::main); + // Patch steam id bit check std::vector> patches{}; const auto p = [&patches](const size_t a, const size_t b) @@ -383,6 +434,8 @@ namespace auth utils::hook::call(0x14134BF7D_g, send_connect_data_stub); + utils::hook::call(0x14134BEFE_g, info_set_value_for_key_stub); + // Fix crash utils::hook::set(0x14134B970_g, 0xC3); } diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index 568551785..584bbd5db 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -274,6 +274,7 @@ namespace console if (!game::is_server()) { utils::hook::set(0x14133D2FE_g, 0xEB); // Always enable ingame console + utils::hook::jump(0x141344E44_g, 0x141344E2E_g); // Remove the need to type '\' or '/' to send a console command if (utils::nt::is_wine() && !utils::flags::has_flag("console")) { diff --git a/src/client/component/dvars_patches.cpp b/src/client/component/dvars_patches.cpp index e9a01a17a..f945c18dc 100644 --- a/src/client/component/dvars_patches.cpp +++ b/src/client/component/dvars_patches.cpp @@ -13,7 +13,7 @@ namespace dvars_patches { void patch_dvars() { - game::register_sessionmode_dvar_bool("com_pauseSupported", !game::is_server(), game::DVAR_SERVERINFO, "Whether is pause is ever supported by the game mode"); + (void)game::register_sessionmode_dvar_bool("com_pauseSupported", !game::is_server(), game::DVAR_SERVERINFO, "Whether is pause is ever supported by the game mode"); } void patch_flags() diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 4371a17ab..8b90b78ef 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -304,28 +304,33 @@ namespace network { scheduler::loop(game::fragment_handler::clean, scheduler::async, 5s); - utils::hook::nop(game::select(0x1423322B6, 0x140596DF6), 4); // don't increment data pointer to optionally skip socket byte - utils::hook::call(game::select(0x142332283, 0x140596DC3), read_socket_byte_stub); + utils::hook::nop(game::select(0x1423322B6, 0x140596DF6), 4); + // optionally read socket byte - utils::hook::call(game::select(0x1423322C1, 0x140596E01), verify_checksum_stub); + utils::hook::call(game::select(0x142332283, 0x140596DC3), read_socket_byte_stub); + // skip checksum verification - utils::hook::set(game::select(0x14233249E, 0x140596F2E), 0); // don't add checksum to packet + utils::hook::call(game::select(0x1423322C1, 0x140596E01), verify_checksum_stub); + + // don't add checksum to packet + utils::hook::set(game::select(0x14233249E, 0x140596F2E), 0); // Recreate NET_SendPacket to increase max packet size //utils::hook::jump(game::select(0x1423323B0, 0x140596E40), net_sendpacket_stub); - utils::hook::set(game::select(0x14134C6E0, 0x14018E574), 5); // set initial connection state to challenging + utils::hook::set(game::select(0x14134C6E0, 0x14018E574), 4); // intercept command handling utils::hook::call(game::select(0x14134D146, 0x14018EED0), utils::hook::assemble(handle_command_stub)); - utils::hook::set(game::select(0x14224DEAD, 0x1405315F9), 0xEB); // don't kick clients without dw handle + utils::hook::set(game::select(0x14224DEAD, 0x1405315F9), 0xEB); // Skip DW stuff in NetAdr_ToString utils::hook::set(game::select(0x142172EF2, 0x140515881), 0xEB); + // NA_IP -> NA_RAWIP in NetAdr_ToString utils::hook::set(game::select(0x142172ED4, 0x140515864), game::NA_RAWIP); diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index c442fa835..662ccf971 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -2,10 +2,8 @@ #include "loader/component_loader.hpp" #include -#include #include "network.hpp" -#include "scheduler.hpp" #include @@ -46,6 +44,12 @@ namespace patches { void post_unpack() override { + // print hexadecimal xuids in status command + utils::hook::copy_string(game::select(0x143050560, 0x140E85B00), "%12llx "); + + // print hexadecimal xuids in chat game log command + utils::hook::set(game::select(0x142FD9362, 0x140E16FA2), 'x'); + // don't make script errors fatal error utils::hook::call(game::select(0x1412CAC4D, 0x140158EB2), script_errors_stub); @@ -56,11 +60,6 @@ namespace patches // make sure client's reliableAck are not negative sv_execute_client_messages_hook.create(game::select(0x14224A460, 0x14052F840), sv_execute_client_messages_stub); - - scheduler::once([] - { - game::register_dvar_string("password", "", game::DVAR_USERINFO, "password"); - }, scheduler::pipeline::main); } }; } diff --git a/src/client/component/rcon.cpp b/src/client/component/rcon.cpp index 4fd67a4e4..0418254a8 100644 --- a/src/client/component/rcon.cpp +++ b/src/client/component/rcon.cpp @@ -7,7 +7,6 @@ #include "scheduler.hpp" #include -#include #include @@ -15,9 +14,13 @@ namespace rcon { namespace { + const game::dvar_t* rcon_timeout; + + std::unordered_map rate_limit_map; + std::optional get_and_validate_rcon_command(const std::string& data) { - const command::params params{data.data()}; + const command::params params{data}; if (params.size() <= 1) { @@ -52,8 +55,45 @@ namespace rcon network::send(target, "print", console_buffer); } + bool rate_limit_check(const game::netadr_t& address, const int time) + { + const auto last_time = rate_limit_map[address]; + + if (last_time && (time - last_time) < rcon_timeout->current.value.integer) + { + return false; // Flooding + } + + rate_limit_map[address] = time; + return true; + } + + void rate_limit_cleanup(const int time) + { + for (auto i = rate_limit_map.begin(); i != rate_limit_map.end();) + { + // No longer at risk of flooding, remove + if ((time - i->second) > rcon_timeout->current.value.integer) + { + i = rate_limit_map.erase(i); + } + else + { + ++i; + } + } + } + void rcon_handler(const game::netadr_t& target, const network::data_view& data) { + const auto time = game::Sys_Milliseconds(); + if (!rate_limit_check(target, time)) + { + return; + } + + rate_limit_cleanup(time); + auto str_data = std::string(reinterpret_cast(data.data()), data.size()); scheduler::once([target, s = std::move(str_data)] { @@ -67,6 +107,8 @@ namespace rcon void post_unpack() override { network::on("rcon", rcon_handler); + + rcon_timeout = game::register_dvar_int("rcon_timeout", 500, 100, 10000, game::DVAR_NONE, ""); } }; } diff --git a/src/client/component/server_list.cpp b/src/client/component/server_list.cpp index e21a5fc9d..46199570e 100644 --- a/src/client/component/server_list.cpp +++ b/src/client/component/server_list.cpp @@ -143,20 +143,20 @@ namespace server_list void request_servers(callback callback) { master_state.access([&callback](state& s) + { + game::netadr_t addr{}; + if (!get_master_server(addr)) { - game::netadr_t addr{}; - if (!get_master_server(addr)) - { - return; - } + return; + } - s.requesting = true; - s.address = addr; - s.callback = std::move(callback); - s.query_start = std::chrono::high_resolution_clock::now(); + s.requesting = true; + s.address = addr; + s.callback = std::move(callback); + s.query_start = std::chrono::high_resolution_clock::now(); - network::send(s.address, "getservers", utils::string::va("T7 %i full empty", PROTOCOL)); - }); + network::send(s.address, "getservers", utils::string::va("T7 %i full empty", PROTOCOL)); + }); } void add_favorite_server(game::netadr_t addr) @@ -194,33 +194,33 @@ namespace server_list void post_unpack() override { network::on("getServersResponse", [](const game::netadr_t& target, const network::data_view& data) + { + master_state.access([&](state& s) { - master_state.access([&](state& s) - { - handle_server_list_response(target, data, s); - }); + handle_server_list_response(target, data, s); }); + }); scheduler::loop([] + { + master_state.access([](state& s) { - master_state.access([](state& s) - { - if (!s.requesting) - { - return; - } - - const auto now = std::chrono::high_resolution_clock::now(); - if ((now - s.query_start) < 2s) - { - return; - } - - s.requesting = false; - s.callback(false, {}); - s.callback = {}; - }); - }, scheduler::async, 200ms); + if (!s.requesting) + { + return; + } + + const auto now = std::chrono::high_resolution_clock::now(); + if ((now - s.query_start) < 2s) + { + return; + } + + s.requesting = false; + s.callback(false, {}); + s.callback = {}; + }); + }, scheduler::async, 200ms); lua_serverinfo_to_table_hook.create(0x141F1FD10_g, lua_serverinfo_to_table_stub); @@ -233,10 +233,10 @@ namespace server_list void pre_destroy() override { master_state.access([](state& s) - { - s.requesting = false; - s.callback = {}; - }); + { + s.requesting = false; + s.callback = {}; + }); } }; } diff --git a/src/client/component/workshop.cpp b/src/client/component/workshop.cpp index 29a00a6bf..8e61d906c 100644 --- a/src/client/component/workshop.cpp +++ b/src/client/component/workshop.cpp @@ -3,6 +3,8 @@ #include "workshop.hpp" #include "game/game.hpp" +#include "game/utils.hpp" +#include "command.hpp" #include #include @@ -12,6 +14,8 @@ namespace workshop { namespace { + const game::dvar_t* enable_zone_folder; + utils::hook::detour setup_server_map_hook; utils::hook::detour load_usermap_hook; @@ -141,10 +145,69 @@ namespace workshop return utils::hook::invoke(0x1420D6380_g, type, pub_id.data(), a3); } + + void override_path_mods_stub(utils::hook::assembler& a) + { + const auto new_path = a.newLabel(); + const auto default_path = a.newLabel(); + const auto original_func = a.newLabel(); + + a.pushad64(); + a.mov(rax, qword_ptr(reinterpret_cast(&enable_zone_folder))); + a.test(rax, rax); + a.jz(new_path); + + a.cmp(byte_ptr(rax, 0x28), 0); + a.je(new_path); + + a.bind(default_path); + a.popad64(); + a.mov(rcx, "%s/%s/%s/zone"); + a.jmp(original_func); + + a.bind(new_path); + a.popad64(); + a.mov(rcx, "%s/%s/%s"); + + a.bind(original_func); + a.jmp(game::select(0x1420D6AA0, 0x1404E2930)); + } + + void override_path_usercontent_stub(utils::hook::assembler& a) + { + const auto new_path = a.newLabel(); + const auto default_path = a.newLabel(); + const auto original_func = a.newLabel(); + + a.pushad64(); + a.mov(rax, qword_ptr(reinterpret_cast(&enable_zone_folder))); + a.test(rax, rax); + a.jz(new_path); + + a.cmp(byte_ptr(rax, 0x28), 0); + a.je(new_path); + + a.bind(default_path); + a.popad64(); + a.mov(rcx, "%s/%s/zone"); + a.jmp(original_func); + + a.bind(new_path); + a.popad64(); + a.mov(rcx, "%s/%s"); + + a.bind(original_func); + a.jmp(game::select(0x1420D6574, 0x1404E24A4)); + } } std::string get_mod_resized_name(const std::string& dir_name) { + if (dir_name == "usermaps" || dir_name.empty()) + { + return dir_name; + } + std::string result = dir_name; for (unsigned int i = 0; i < *game::modsCount; ++i) @@ -188,7 +251,7 @@ namespace workshop std::string get_mod_publisher_id(const std::string& dir_name) { - if (dir_name == "usermaps") + if (dir_name == "usermaps" || dir_name.empty()) { return dir_name; } @@ -259,10 +322,15 @@ namespace workshop public: void post_unpack() override { - // %s/%s/%s/zone -> %s/%s/%s - utils::hook::set(game::select(0x14303E8D8, 0x140E73BB8), 0); - // %s/%s/zone -> %s/%s - utils::hook::set(game::select(0x14303E7AD, 0x140E73AD5), 0); + command::add("userContentReload", [](const command::params& params) + { + game::reloadUserContent(); + }); + + enable_zone_folder = game::register_dvar_bool("enable_zone_folder", false, game::DVAR_ARCHIVE, "Load custom zones from the zone folder within the usermaps/mods folder"); + + utils::hook::jump(game::select(0x1420D6A99, 0x1404E2929), utils::hook::assemble(override_path_mods_stub)); + utils::hook::jump(game::select(0x1420D656D, 0x1404E249D), utils::hook::assemble(override_path_usercontent_stub)); load_usermap_hook.create(game::select(0x1420D5700, 0x1404E18B0), load_usermap_stub); utils::hook::call(game::select(0x1420D67F5, 0x1404E25F2), load_usermap_content_stub); diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 2f72549a0..883c243b0 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1,6 +1,6 @@ #pragma once -#define PROTOCOL 5 +#define PROTOCOL 6 #define SUB_PROTOCOL 1 #ifdef __cplusplus diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index c938ac18f..a0513a45b 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -83,8 +83,12 @@ namespace game // Live WEAK symbol Live_GetConnectivityInformation{0x141E0C380}; + // LiveStats + WEAK symbol LiveStats_GetClanTagText{0x141E9CE20}; + // Info WEAK symbol Info_ValueForKey{0x1422E87B0}; + WEAK symbol Info_SetValueForKey{0x1422E8410}; // MSG WEAK symbol MSG_ReadByte{0x142155450, 0x14050D1B0}; @@ -97,7 +101,7 @@ namespace game WEAK symbol NET_StringToAdr{0x142172780, 0x140515110}; // Sys - WEAK symbol Sys_Milliseconds{0x142332870}; + WEAK symbol Sys_Milliseconds{0x142332870, 0x1405972F0}; WEAK symbol Sys_ShowConsole{0x1423333C0, 0x140597E40}; WEAK symbol Sys_GetTLS{0x1421837B0, 0x140525EB0}; WEAK symbol Sys_IsDatabaseReady{0x142183A60}; @@ -107,6 +111,7 @@ namespace game WEAK symbol isModLoaded{0x1420D5020}; WEAK symbol loadMod{0x1420D6930}; + WEAK symbol reloadUserContent{0x1420D66C0, 0x1404E25C0}; // Dvar WEAK symbol Dvar_IsSessionModeBaseDvar{0x1422C23A0, 0x140576890}; @@ -123,6 +128,10 @@ namespace game const char* description)> Dvar_RegisterBool{ 0x1422D0900, 0x14057B500 }; + WEAK symbol Dvar_RegisterInt{ + 0x0, 0x14057B7B0 + }; WEAK symbol Dvar_RegisterFloat{ 0x0, 0x14057B6B0 @@ -151,7 +160,7 @@ namespace game WEAK symbol UI_CoD_Init{0x141F29010, 0x1404A0A50}; WEAK symbol UI_CoD_LobbyUI_Init{0x141F2BD80, 0x1404A1F50}; WEAK symbol UI_CoD_Shutdown{0x141F32E10, 0x0}; - WEAK symbol UI_AddMenu{0x1427018F0, 0x0}; + WEAK symbol UI_AddMenu{0x1427018F0, 0x0}; WEAK symbol UI_CoD_GetRootNameForController{0x141F28940, 0x0}; WEAK symbol Lua_CoD_LoadLuaFile{0x141F11A20, 0x0}; WEAK symbol CG_LUIHUDRestart{0x140F7E970}; diff --git a/src/client/game/utils.cpp b/src/client/game/utils.cpp index c61a4350f..4f6fb99ad 100644 --- a/src/client/game/utils.cpp +++ b/src/client/game/utils.cpp @@ -45,7 +45,7 @@ namespace game return dvar->current.value.enabled; } - const dvar_t* register_sessionmode_dvar_bool(const char* dvar_name, const bool value, const int flags, + const dvar_t* register_sessionmode_dvar_bool(const char* dvar_name, const bool value, const unsigned int flags, const char* description, const eModes mode) { const auto hash = Dvar_GenerateHash(dvar_name); @@ -71,7 +71,7 @@ namespace game return registered_dvar; } - const dvar_t* register_dvar_bool(const char* dvar_name, const bool value, const int flags, const char* description) + const dvar_t* register_dvar_bool(const char* dvar_name, const bool value, const unsigned int flags, const char* description) { const auto hash = Dvar_GenerateHash(dvar_name); auto* registered_dvar = Dvar_RegisterBool(hash, dvar_name, value, flags, description); @@ -84,7 +84,21 @@ namespace game return registered_dvar; } - const dvar_t* register_dvar_float(const char* dvar_name, float value, float min, float max, const int flags, + const dvar_t* register_dvar_int(const char* dvar_name, int value, int min, int max, const unsigned int flags, + const char* description) + { + const auto hash = Dvar_GenerateHash(dvar_name); + auto* registered_dvar = Dvar_RegisterInt(hash, dvar_name, value, min, max, flags, description); + + if (registered_dvar) + { + registered_dvar->debugName = dvar_name; + } + + return registered_dvar; + } + + const dvar_t* register_dvar_float(const char* dvar_name, float value, float min, float max, const unsigned int flags, const char* description) { const auto hash = Dvar_GenerateHash(dvar_name); @@ -98,7 +112,7 @@ namespace game return registered_dvar; } - const dvar_t* register_dvar_string(const char* dvar_name, const char* value, const int flags, + const dvar_t* register_dvar_string(const char* dvar_name, const char* value, const unsigned int flags, const char* description) { const auto hash = Dvar_GenerateHash(dvar_name); @@ -112,7 +126,7 @@ namespace game return registered_dvar; } - void dvar_add_flags(const char* dvar_name, const dvarFlags_e flags) + void dvar_add_flags(const char* dvar_name, const unsigned int flags) { auto* dvar = Dvar_FindVar(dvar_name); @@ -132,7 +146,7 @@ namespace game dvar_to_change->flags |= flags; } - void dvar_set_flags(const char* dvar_name, const dvarFlags_e flags) + void dvar_set_flags(const char* dvar_name, const unsigned int flags) { auto* dvar = Dvar_FindVar(dvar_name); diff --git a/src/client/game/utils.hpp b/src/client/game/utils.hpp index 5bbc78c0c..c211f2869 100644 --- a/src/client/game/utils.hpp +++ b/src/client/game/utils.hpp @@ -4,20 +4,21 @@ namespace game { - std::string get_dvar_string(const char* dvar_name); - int get_dvar_int(const char* dvar_name); - bool get_dvar_bool(const char* dvar_name); + [[nodiscard]] std::string get_dvar_string(const char* dvar_name); + [[nodiscard]] int get_dvar_int(const char* dvar_name); + [[nodiscard]] bool get_dvar_bool(const char* dvar_name); - const dvar_t* register_dvar_bool(const char* dvar_name, bool value, int flags, const char* description); - const dvar_t* register_dvar_float(const char* dvar_name, float value, float min, float max, const int flags, const char* description); - const dvar_t* register_sessionmode_dvar_bool(const char* dvar_name, bool value, int flags, const char* description, eModes mode = MODE_COUNT); - const dvar_t* register_dvar_string(const char* dvar_name, const char* value, int flags, const char* description); + [[nodiscard]] const dvar_t* register_dvar_bool(const char* dvar_name, bool value, unsigned int flags, const char* description); + [[nodiscard]] const dvar_t* register_dvar_int(const char* dvar_name, int value, int min, int max, unsigned int flags, const char* description); + [[nodiscard]] const dvar_t* register_dvar_float(const char* dvar_name, float value, float min, float max, unsigned int flags, const char* description); + [[nodiscard]] const dvar_t* register_sessionmode_dvar_bool(const char* dvar_name, bool value, unsigned int flags, const char* description, eModes mode = MODE_COUNT); + [[nodiscard]] const dvar_t* register_dvar_string(const char* dvar_name, const char* value, unsigned int flags, const char* description); - void dvar_add_flags(const char* dvar, dvarFlags_e flags); - void dvar_set_flags(const char* dvar_name, dvarFlags_e flags); + void dvar_add_flags(const char* dvar, unsigned int flags); + void dvar_set_flags(const char* dvar_name, unsigned int flags); - bool is_server_running(); - size_t get_max_client_count(); + [[nodiscard]] bool is_server_running(); + [[nodiscard]] size_t get_max_client_count(); void foreach_client(const std::function& callback); void foreach_client(const std::function& callback); diff --git a/src/client/steam/interfaces/matchmaking.cpp b/src/client/steam/interfaces/matchmaking.cpp index 298ab8fe7..5744fa256 100644 --- a/src/client/steam/interfaces/matchmaking.cpp +++ b/src/client/steam/interfaces/matchmaking.cpp @@ -1,237 +1,237 @@ -#include +#include #include "../steam.hpp" #include "component/network.hpp" -#include "component/server_list.hpp" - -namespace steam -{ - int matchmaking::GetFavoriteGameCount() - { - return 0; - } - - bool matchmaking::GetFavoriteGame(int iGame, unsigned int* pnAppID, unsigned int* pnIP, unsigned short* pnConnPort, - unsigned short* pnQueryPort, unsigned int* punFlags, - unsigned int* pRTime32LastPlayedOnServer) - { - return false; - } - - int matchmaking::AddFavoriteGame(unsigned int nAppID, unsigned int nIP, unsigned short nConnPort, - unsigned short nQueryPort, unsigned int unFlags, - unsigned int rTime32LastPlayedOnServer) +#include "component/server_list.hpp" + +namespace steam +{ + int matchmaking::GetFavoriteGameCount() + { + return 0; + } + + bool matchmaking::GetFavoriteGame(int iGame, unsigned int* pnAppID, unsigned int* pnIP, unsigned short* pnConnPort, + unsigned short* pnQueryPort, unsigned int* punFlags, + unsigned int* pRTime32LastPlayedOnServer) + { + return false; + } + + int matchmaking::AddFavoriteGame(unsigned int nAppID, unsigned int nIP, unsigned short nConnPort, + unsigned short nQueryPort, unsigned int unFlags, + unsigned int rTime32LastPlayedOnServer) { auto addr = network::address_from_ip(htonl(nIP), nConnPort); - server_list::add_favorite_server(addr); - return 0; - } - - bool matchmaking::RemoveFavoriteGame(unsigned int nAppID, unsigned int nIP, unsigned short nConnPort, - unsigned short nQueryPort, unsigned int unFlags) + server_list::add_favorite_server(addr); + return 0; + } + + bool matchmaking::RemoveFavoriteGame(unsigned int nAppID, unsigned int nIP, unsigned short nConnPort, + unsigned short nQueryPort, unsigned int unFlags) { auto addr = network::address_from_ip(htonl(nIP), nConnPort); - server_list::remove_favorite_server(addr); - return false; - } - - unsigned long long matchmaking::RequestLobbyList() - { - return 0; - } - - void matchmaking::AddRequestLobbyListStringFilter(const char* pchKeyToMatch, const char* pchValueToMatch, - int eComparisonType) - { - } - - void matchmaking::AddRequestLobbyListNumericalFilter(const char* pchKeyToMatch, int nValueToMatch, - int eComparisonType) - { - } - - void matchmaking::AddRequestLobbyListNearValueFilter(const char* pchKeyToMatch, int nValueToBeCloseTo) - { - } - - void matchmaking::AddRequestLobbyListFilterSlotsAvailable(int nSlotsAvailable) - { - } - - void matchmaking::AddRequestLobbyListDistanceFilter(int eLobbyDistanceFilter) - { - } - - void matchmaking::AddRequestLobbyListResultCountFilter(int cMaxResults) - { - } - - void matchmaking::AddRequestLobbyListCompatibleMembersFilter(steam_id steamID) - { - } - - steam_id matchmaking::GetLobbyByIndex(int iLobby) - { - steam_id id; - - id.raw.account_id = SteamUser()->GetSteamID().raw.account_id; - id.raw.universe = 1; - id.raw.account_type = 8; - id.raw.account_instance = 0x40000; - - return id; - } - - unsigned long long matchmaking::CreateLobby(int eLobbyType, int cMaxMembers) - { - const auto result = callbacks::register_call(); - auto retvals = static_cast(calloc(1, sizeof(lobby_created))); - //::Utils::Memory::AllocateArray(); - steam_id id; - - id.raw.account_id = SteamUser()->GetSteamID().raw.account_id; - id.raw.universe = 1; - id.raw.account_type = 8; - id.raw.account_instance = 0x40000; - - retvals->m_e_result = 1; - retvals->m_ul_steam_id_lobby = id; - - callbacks::return_call(retvals, sizeof(lobby_created), lobby_created::callback_id, result); - - matchmaking::JoinLobby(id); - - return result; - } - - unsigned long long matchmaking::JoinLobby(steam_id steamIDLobby) - { - const auto result = callbacks::register_call(); - auto* retvals = static_cast(calloc(1, sizeof(lobby_enter))); - //::Utils::Memory::AllocateArray(); - retvals->m_b_locked = false; - retvals->m_e_chat_room_enter_response = 1; - retvals->m_rgf_chat_permissions = 0xFFFFFFFF; - retvals->m_ul_steam_id_lobby = steamIDLobby; - - callbacks::return_call(retvals, sizeof(lobby_enter), lobby_enter::callback_id, result); - - return result; - } - - void matchmaking::LeaveLobby(steam_id steamIDLobby) - { - } - - bool matchmaking::InviteUserToLobby(steam_id steamIDLobby, steam_id steamIDInvitee) - { - return true; - } - - int matchmaking::GetNumLobbyMembers(steam_id steamIDLobby) - { - return 1; - } - - steam_id matchmaking::GetLobbyMemberByIndex(steam_id steamIDLobby, int iMember) - { - return SteamUser()->GetSteamID(); - } - - const char* matchmaking::GetLobbyData(steam_id steamIDLobby, const char* pchKey) - { - return ""; - } - - bool matchmaking::SetLobbyData(steam_id steamIDLobby, const char* pchKey, const char* pchValue) - { - return true; - } - - int matchmaking::GetLobbyDataCount(steam_id steamIDLobby) - { - return 0; - } - - bool matchmaking::GetLobbyDataByIndex(steam_id steamIDLobby, int iLobbyData, char* pchKey, int cchKeyBufferSize, - char* pchValue, int cchValueBufferSize) - { - return true; - } - - bool matchmaking::DeleteLobbyData(steam_id steamIDLobby, const char* pchKey) - { - return true; - } - - const char* matchmaking::GetLobbyMemberData(steam_id steamIDLobby, steam_id steamIDUser, const char* pchKey) - { - return ""; - } - - void matchmaking::SetLobbyMemberData(steam_id steamIDLobby, const char* pchKey, const char* pchValue) - { - } - - bool matchmaking::SendLobbyChatMsg(steam_id steamIDLobby, const void* pvMsgBody, int cubMsgBody) - { - return true; - } - - int matchmaking::GetLobbyChatEntry(steam_id steamIDLobby, int iChatID, steam_id* pSteamIDUser, void* pvData, - int cubData, int* peChatEntryType) - { - return 0; - } - - bool matchmaking::RequestLobbyData(steam_id steamIDLobby) - { - return true; - } - - void matchmaking::SetLobbyGameServer(steam_id steamIDLobby, unsigned int unGameServerIP, - unsigned short unGameServerPort, steam_id steamIDGameServer) - { - } - - bool matchmaking::GetLobbyGameServer(steam_id steamIDLobby, unsigned int* punGameServerIP, - unsigned short* punGameServerPort, steam_id* psteamIDGameServer) - { - return true; - } - - bool matchmaking::SetLobbyMemberLimit(steam_id steamIDLobby, int cMaxMembers) - { - return true; - } - - int matchmaking::GetLobbyMemberLimit(steam_id steamIDLobby) - { - return 0; - } - - bool matchmaking::SetLobbyType(steam_id steamIDLobby, int eLobbyType) - { - return true; - } - - bool matchmaking::SetLobbyJoinable(steam_id steamIDLobby, bool bLobbyJoinable) - { - return true; - } - - steam_id matchmaking::GetLobbyOwner(steam_id steamIDLobby) - { - return SteamUser()->GetSteamID(); - } - - bool matchmaking::SetLobbyOwner(steam_id steamIDLobby, steam_id steamIDNewOwner) - { - return true; - } - - bool matchmaking::SetLinkedLobby(steam_id steamIDLobby, steam_id steamIDLobby2) - { - return true; - } -} + server_list::remove_favorite_server(addr); + return false; + } + + unsigned long long matchmaking::RequestLobbyList() + { + return 0; + } + + void matchmaking::AddRequestLobbyListStringFilter(const char* pchKeyToMatch, const char* pchValueToMatch, + int eComparisonType) + { + } + + void matchmaking::AddRequestLobbyListNumericalFilter(const char* pchKeyToMatch, int nValueToMatch, + int eComparisonType) + { + } + + void matchmaking::AddRequestLobbyListNearValueFilter(const char* pchKeyToMatch, int nValueToBeCloseTo) + { + } + + void matchmaking::AddRequestLobbyListFilterSlotsAvailable(int nSlotsAvailable) + { + } + + void matchmaking::AddRequestLobbyListDistanceFilter(int eLobbyDistanceFilter) + { + } + + void matchmaking::AddRequestLobbyListResultCountFilter(int cMaxResults) + { + } + + void matchmaking::AddRequestLobbyListCompatibleMembersFilter(steam_id steamID) + { + } + + steam_id matchmaking::GetLobbyByIndex(int iLobby) + { + steam_id id; + + id.raw.account_id = SteamUser()->GetSteamID().raw.account_id; + id.raw.universe = 1; + id.raw.account_type = 8; + id.raw.account_instance = 0x40000; + + return id; + } + + unsigned long long matchmaking::CreateLobby(int eLobbyType, int cMaxMembers) + { + const auto result = callbacks::register_call(); + auto retvals = static_cast(calloc(1, sizeof(lobby_created))); + //::Utils::Memory::AllocateArray(); + steam_id id; + + id.raw.account_id = SteamUser()->GetSteamID().raw.account_id; + id.raw.universe = 1; + id.raw.account_type = 8; + id.raw.account_instance = 0x40000; + + retvals->m_e_result = 1; + retvals->m_ul_steam_id_lobby = id; + + callbacks::return_call(retvals, sizeof(lobby_created), lobby_created::callback_id, result); + + matchmaking::JoinLobby(id); + + return result; + } + + unsigned long long matchmaking::JoinLobby(steam_id steamIDLobby) + { + const auto result = callbacks::register_call(); + auto* retvals = static_cast(calloc(1, sizeof(lobby_enter))); + //::Utils::Memory::AllocateArray(); + retvals->m_b_locked = false; + retvals->m_e_chat_room_enter_response = 1; + retvals->m_rgf_chat_permissions = 0xFFFFFFFF; + retvals->m_ul_steam_id_lobby = steamIDLobby; + + callbacks::return_call(retvals, sizeof(lobby_enter), lobby_enter::callback_id, result); + + return result; + } + + void matchmaking::LeaveLobby(steam_id steamIDLobby) + { + } + + bool matchmaking::InviteUserToLobby(steam_id steamIDLobby, steam_id steamIDInvitee) + { + return true; + } + + int matchmaking::GetNumLobbyMembers(steam_id steamIDLobby) + { + return 1; + } + + steam_id matchmaking::GetLobbyMemberByIndex(steam_id steamIDLobby, int iMember) + { + return SteamUser()->GetSteamID(); + } + + const char* matchmaking::GetLobbyData(steam_id steamIDLobby, const char* pchKey) + { + return ""; + } + + bool matchmaking::SetLobbyData(steam_id steamIDLobby, const char* pchKey, const char* pchValue) + { + return true; + } + + int matchmaking::GetLobbyDataCount(steam_id steamIDLobby) + { + return 0; + } + + bool matchmaking::GetLobbyDataByIndex(steam_id steamIDLobby, int iLobbyData, char* pchKey, int cchKeyBufferSize, + char* pchValue, int cchValueBufferSize) + { + return true; + } + + bool matchmaking::DeleteLobbyData(steam_id steamIDLobby, const char* pchKey) + { + return true; + } + + const char* matchmaking::GetLobbyMemberData(steam_id steamIDLobby, steam_id steamIDUser, const char* pchKey) + { + return ""; + } + + void matchmaking::SetLobbyMemberData(steam_id steamIDLobby, const char* pchKey, const char* pchValue) + { + } + + bool matchmaking::SendLobbyChatMsg(steam_id steamIDLobby, const void* pvMsgBody, int cubMsgBody) + { + return true; + } + + int matchmaking::GetLobbyChatEntry(steam_id steamIDLobby, int iChatID, steam_id* pSteamIDUser, void* pvData, + int cubData, int* peChatEntryType) + { + return 0; + } + + bool matchmaking::RequestLobbyData(steam_id steamIDLobby) + { + return true; + } + + void matchmaking::SetLobbyGameServer(steam_id steamIDLobby, unsigned int unGameServerIP, + unsigned short unGameServerPort, steam_id steamIDGameServer) + { + } + + bool matchmaking::GetLobbyGameServer(steam_id steamIDLobby, unsigned int* punGameServerIP, + unsigned short* punGameServerPort, steam_id* psteamIDGameServer) + { + return true; + } + + bool matchmaking::SetLobbyMemberLimit(steam_id steamIDLobby, int cMaxMembers) + { + return true; + } + + int matchmaking::GetLobbyMemberLimit(steam_id steamIDLobby) + { + return 0; + } + + bool matchmaking::SetLobbyType(steam_id steamIDLobby, int eLobbyType) + { + return true; + } + + bool matchmaking::SetLobbyJoinable(steam_id steamIDLobby, bool bLobbyJoinable) + { + return true; + } + + steam_id matchmaking::GetLobbyOwner(steam_id steamIDLobby) + { + return SteamUser()->GetSteamID(); + } + + bool matchmaking::SetLobbyOwner(steam_id steamIDLobby, steam_id steamIDNewOwner) + { + return true; + } + + bool matchmaking::SetLinkedLobby(steam_id steamIDLobby, steam_id steamIDLobby2) + { + return true; + } +} diff --git a/src/client/steam/interfaces/matchmaking_servers.cpp b/src/client/steam/interfaces/matchmaking_servers.cpp index cb39d9394..c259a87ab 100644 --- a/src/client/steam/interfaces/matchmaking_servers.cpp +++ b/src/client/steam/interfaces/matchmaking_servers.cpp @@ -305,7 +305,8 @@ namespace steam auto& servers_list = hRequest == favorites_request ? favorites_servers : internet_servers; static thread_local gameserveritem_t server_item{}; - return servers_list.access([iServer](const servers& s) -> gameserveritem_t* { + return servers_list.access([iServer](const servers& s) -> gameserveritem_t* + { if (iServer < 0 || static_cast(iServer) >= s.size()) { return nullptr; @@ -378,17 +379,17 @@ namespace steam party::query_server( addr, [response](const bool success, const game::netadr_t& host, const ::utils::info_string& info, const uint32_t ping) + { + if (success) { - if (success) - { - auto server_item = create_server_item(host, info, ping, success); - response->ServerResponded(server_item); - } - else - { - response->ServerFailedToRespond(); - } - }); + auto server_item = create_server_item(host, info, ping, success); + response->ServerResponded(server_item); + } + else + { + response->ServerFailedToRespond(); + } + }); return reinterpret_cast(static_cast(7 + rand())); } diff --git a/src/common/utils/cryptography.cpp b/src/common/utils/cryptography.cpp index 824cb9a7e..5c5c1a8f4 100644 --- a/src/common/utils/cryptography.cpp +++ b/src/common/utils/cryptography.cpp @@ -1,5 +1,8 @@ #include "string.hpp" #include "cryptography.hpp" + +#include + #include "nt.hpp" #include "finally.hpp" @@ -116,11 +119,18 @@ namespace utils::cryptography int i[4]; // uninitialized data auto* i_ptr = &i; - this->add_entropy(reinterpret_cast(&i), sizeof(i)); - this->add_entropy(reinterpret_cast(&i_ptr), sizeof(i_ptr)); + this->add_entropy(&i, sizeof(i)); + this->add_entropy(&i_ptr, sizeof(i_ptr)); auto t = time(nullptr); - this->add_entropy(reinterpret_cast(&t), sizeof(t)); + this->add_entropy(&t, sizeof(t)); + + std::random_device rd{}; + for (auto j = 0; j < 4; ++j) + { + const auto x = rd(); + this->add_entropy(&x, sizeof(x)); + } } };