Prepare profile info distribution

This commit is contained in:
momo5502 2023-04-06 22:04:20 +02:00
parent 70ea07fd90
commit c569ed5d8d
7 changed files with 116 additions and 62 deletions

View File

@ -4,6 +4,7 @@
#include "auth.hpp"
#include "command.hpp"
#include "network.hpp"
#include "profile_infos.hpp"
#include <game/game.hpp>
@ -15,6 +16,7 @@
#include <utils/info_string.hpp>
#include <utils/cryptography.hpp>
namespace auth
{
namespace
@ -95,10 +97,10 @@ namespace auth
return !is_first;
}
std::string serialize_connect_data(const std::vector<char>& data)
std::string serialize_connect_data(const char* data, const int length)
{
utils::byte_buffer buffer{};
buffer.write_vector(data);
buffer.write_string(data, static_cast<size_t>(length));
return buffer.move_buffer();
}
@ -110,12 +112,9 @@ namespace auth
const auto is_connect_sequence = len >= 7 && strncmp("connect", data, 7) == 0;
if (is_connect_sequence)
{
std::vector<char> connect_data{};
connect_data.assign(data, data + len);
buffer.append("connect");
buffer.push_back(' ');
buffer.append(serialize_connect_data(connect_data));
buffer.append(serialize_connect_data(data, len));
data = buffer.data();
len = static_cast<int>(buffer.size());
@ -126,10 +125,24 @@ namespace auth
void handle_connect_packet(const game::netadr_t& target, const network::data_view& data)
{
utils::byte_buffer buffer(data);
// TODO: SV running?
const auto text = buffer.read_vector<char>();
command::params_sv params(std::string(text.data(), text.size()));
utils::byte_buffer buffer(data);
profile_infos::profile_info info(buffer);
const auto connect_data = buffer.read_string();
const command::params_sv params(connect_data);
if (params.size() != 2)
{
return;
}
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();
game::SV_DirectConnect(target);
}

View File

@ -3,6 +3,7 @@
#include "profile_infos.hpp"
#include "network.hpp"
#include "party.hpp"
#include <utils/nt.hpp>
#include <utils/properties.hpp>
@ -29,7 +30,7 @@ namespace profile_infos
profile_info info{};
constexpr auto version_size = sizeof(info.version);
if(data.size() < sizeof(version_size))
if (data.size() < sizeof(version_size))
{
return {};
}
@ -37,10 +38,40 @@ namespace profile_infos
memcpy(&info.version, data.data(), version_size);
info.ddl.assign(data.begin() + version_size, data.end());
return { std::move(info) };
return {std::move(info)};
}
}
profile_info::profile_info(utils::byte_buffer& buffer)
{
this->version = buffer.read<int32_t>();
this->ddl = buffer.read_string();
}
void profile_info::serialize(utils::byte_buffer& buffer) const
{
buffer.write(this->version);
buffer.write_string(this->ddl);
}
void add_profile_info(const uint64_t user_id, profile_info info)
{
if (user_id == steam::SteamUser()->GetSteamID().bits)
{
return;
}
profile_mapping.access([&](profile_map& profiles)
{
profiles[user_id] = std::move(info);
});
}
void distribute_profile_infos()
{
// TODO
}
std::optional<profile_info> get_profile_info(uint64_t user_id)
{
if (user_id == steam::SteamUser()->GetSteamID().bits)
@ -73,17 +104,23 @@ namespace profile_infos
utils::io::write_file("players/user/profile_info", data);
}
struct component final : generic_component
struct component final : client_component
{
void post_load() override
{
}
void post_unpack() override
{
/*network::on("profileInfo", [](const game::netadr_t& server, const network::data_view& data)
network::on("profileInfo", [](const game::netadr_t& server, const network::data_view& data)
{
});*/
if (party::get_connected_server() != server)
{
return;
}
utils::byte_buffer buffer(data);
const auto user_id = buffer.read<uint64_t>();
const profile_info info(buffer);
add_profile_info(user_id, info);
});
}
};
}

View File

@ -1,13 +1,23 @@
#pragma once
#include <utils/byte_buffer.hpp>
namespace profile_infos
{
struct profile_info
{
int32_t version;
std::string ddl;
int32_t version{3};
std::string ddl{};
profile_info() = default;
profile_info(utils::byte_buffer& buffer);
void serialize(utils::byte_buffer& buffer) const;
};
void add_profile_info(uint64_t user_id, profile_info info);
void distribute_profile_infos();
std::optional<profile_info> get_profile_info(uint64_t user_id);
void update_profile_info(const profile_info& info);
}

View File

@ -41,37 +41,6 @@ namespace utils
this->offset_ += length;
}
std::string byte_buffer::read_string()
{
std::string result{};
while (true)
{
const auto b = this->read<char>();
if (!b)
{
break;
}
result.push_back(b);
}
return result;
}
std::string byte_buffer::read_string(const size_t length)
{
std::string result{};
result.reserve(length);
for (size_t i = 0; i < length; ++i)
{
result.push_back(this->read<char>());
}
return result;
}
std::vector<uint8_t> byte_buffer::read_data(const size_t length)
{
std::vector<uint8_t> result{};

View File

@ -20,15 +20,20 @@ namespace utils
void write(const void* buffer, size_t length);
void write(const std::string& string, const bool null_terminate = false)
void write_string(const char* str, const size_t length)
{
const size_t addend = null_terminate ? 1 : 0;
this->write(string.data(), string.size() + addend);
this->write<uint32_t>(static_cast<uint32_t>(length));
this->write(str, length);
}
void write_string(const std::string& string)
void write_string(const std::string& str)
{
this->write(string, true);
this->write_string(str.data(), str.size());
}
void write_string(const char* str)
{
this->write_string(str, strlen(str));
}
template <typename T>
@ -46,7 +51,7 @@ namespace utils
template <typename T>
void write_vector(const std::vector<T>& vec)
{
this->write<uint32_t>(static_cast<uint32_t>(vec.size()));
this->write(static_cast<uint32_t>(vec.size()));
this->write(vec);
}
@ -74,7 +79,7 @@ namespace utils
std::vector<T> read_vector()
{
std::vector<T> result{};
const auto size = read<uint32_t>();
const auto size = this->read<uint32_t>();
const auto totalSize = size * sizeof(T);
if (this->offset_ + totalSize > this->buffer_.size())
@ -88,8 +93,22 @@ namespace utils
return result;
}
std::string read_string();
std::string read_string(size_t length);
std::string read_string()
{
std::string result{};
const auto size = this->read<uint32_t>();
if (this->offset_ + size > this->buffer_.size())
{
throw std::runtime_error("Out of bounds read from byte buffer");
}
result.resize(size);
this->read(result.data(), size);
return result;
}
std::vector<uint8_t> read_data(size_t length);
private:

View File

@ -8,6 +8,11 @@ namespace utils
this->parse(buffer);
}
info_string::info_string(const char* buffer)
: info_string(std::string{buffer})
{
}
info_string::info_string(const std::string_view& buffer)
: info_string(std::string{buffer})
{

View File

@ -9,8 +9,9 @@ namespace utils
{
public:
info_string() = default;
info_string(const std::string& buffer);
info_string(const std::string_view& buffer);
explicit info_string(const std::string& buffer);
explicit info_string(const char* buffer);
explicit info_string(const std::string_view& buffer);
info_string(const std::basic_string_view<uint8_t>& buffer);
void set(const std::string& key, const std::string& value);