diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 22086bce..cc909f66 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -141,8 +141,7 @@ namespace auth const utils::info_string info_string(params[1]); const auto xuid = strtoull(info_string.get("xuid").data(), nullptr, 10); - profile_infos::add_profile_info(xuid, std::move(info)); - profile_infos::distribute_profile_infos(); + profile_infos::add_and_distribute_profile_info(target, xuid, info); game::SV_DirectConnect(target); } diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index be598d14..7a80a301 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -6,6 +6,7 @@ #include "network.hpp" #include "scheduler.hpp" #include "workshop.hpp" +#include "profile_infos.hpp" #include #include @@ -211,6 +212,7 @@ namespace party connect_host = target; } + profile_infos::clear_profile_infos(); query_server(connect_host, handle_connect_query_response); } @@ -314,6 +316,11 @@ namespace party return *reinterpret_cast(address); } + bool is_host(const game::netadr_t& addr) + { + return get_connected_server() == addr || connect_host == addr; + } + struct component final : client_component { void post_unpack() override diff --git a/src/client/component/party.hpp b/src/client/component/party.hpp index 4bca8966..f682a14e 100644 --- a/src/client/component/party.hpp +++ b/src/client/component/party.hpp @@ -9,4 +9,6 @@ namespace party void query_server(const game::netadr_t& host, query_callback callback); game::netadr_t get_connected_server(); + + bool is_host(const game::netadr_t& addr); } diff --git a/src/client/component/profile_infos.cpp b/src/client/component/profile_infos.cpp index 10ea2ad9..576217b1 100644 --- a/src/client/component/profile_infos.cpp +++ b/src/client/component/profile_infos.cpp @@ -12,12 +12,14 @@ #include "../steam/steam.hpp" #include +#include "game/utils.hpp" + namespace profile_infos { namespace { using profile_map = std::unordered_map; - utils::concurrency::container profile_mapping; + utils::concurrency::container profile_mapping{}; std::optional load_profile_info() { @@ -40,6 +42,49 @@ namespace profile_infos return {std::move(info)}; } + + int get_max_client_count() + { + return game::get_dvar_int("com_maxclients"); + } + + void send_profile_info(const game::netadr_t& address, const std::string& buffer) + { + network::send(address, "profileInfo", buffer); + } + + template + void distribute_profile_info(T* client_states, const std::string& buffer) + { + if (!client_states) + { + return; + } + + for (int i = 0; i < get_max_client_count(); ++i) + { + if (client_states[i].client_state > 0) + { + send_profile_info(client_states[i].address, buffer); + } + } + } + + void distribute_profile_info(const uint64_t user_id, const profile_info& info) + { + utils::byte_buffer buffer{}; + buffer.write(user_id); + info.serialize(buffer); + + if (game::is_server()) + { + distribute_profile_info(*game::svs_clients, buffer.get_buffer()); + } + else + { + distribute_profile_info(*game::svs_clients_cl, buffer.get_buffer()); + } + } } profile_info::profile_info(utils::byte_buffer& buffer) @@ -54,26 +99,61 @@ namespace profile_infos buffer.write_string(this->ddl); } - void add_profile_info(const uint64_t user_id, profile_info info) + void add_profile_info(const uint64_t user_id, const profile_info& info) { if (user_id == steam::SteamUser()->GetSteamID().bits) { return; } + printf("Adding profile info: %llX\n", user_id); + profile_mapping.access([&](profile_map& profiles) { - profiles[user_id] = std::move(info); + profiles[user_id] = info; }); } - void distribute_profile_infos() + void distribute_profile_info_to_user(const game::netadr_t& addr, const uint64_t user_id, const profile_info& info) { - // TODO + utils::byte_buffer buffer{}; + buffer.write(user_id); + info.serialize(buffer); + + send_profile_info(addr, buffer.get_buffer()); } - std::optional get_profile_info(uint64_t user_id) + void distribute_profile_infos_to_user(const game::netadr_t& addr) { + profile_mapping.access([&](const profile_map& profiles) + { + for (const auto& entry : profiles) + { + distribute_profile_info_to_user(addr, entry.first, entry.second); + } + }); + } + + void add_and_distribute_profile_info(const game::netadr_t& addr, const uint64_t user_id, const profile_info& info) + { + distribute_profile_infos_to_user(addr); + + add_profile_info(user_id, info); + distribute_profile_info(user_id, info); + } + + void clear_profile_infos() + { + profile_mapping.access([&](profile_map& profiles) + { + profiles = {}; + }); + } + + std::optional get_profile_info(const uint64_t user_id) + { + printf("Requesting profile info: %llX\n", user_id); + if (user_id == steam::SteamUser()->GetSteamID().bits) { return load_profile_info(); @@ -110,7 +190,7 @@ namespace profile_infos { network::on("profileInfo", [](const game::netadr_t& server, const network::data_view& data) { - if (party::get_connected_server() != server) + if (!party::is_host(server)) { return; } diff --git a/src/client/component/profile_infos.hpp b/src/client/component/profile_infos.hpp index f875bf67..a417a545 100644 --- a/src/client/component/profile_infos.hpp +++ b/src/client/component/profile_infos.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include namespace profile_infos @@ -14,9 +15,9 @@ namespace profile_infos void serialize(utils::byte_buffer& buffer) const; }; - void add_profile_info(uint64_t user_id, profile_info info); - - void distribute_profile_infos(); + void add_profile_info(uint64_t user_id, const profile_info& info); + void add_and_distribute_profile_info(const game::netadr_t& addr, uint64_t user_id, const profile_info& info); + void clear_profile_infos(); std::optional get_profile_info(uint64_t user_id); void update_profile_info(const profile_info& info);