implement more plumbing between client and server network

This commit is contained in:
Lion Kortlepel 2024-03-03 22:24:35 +01:00
parent 342b3c3075
commit 387bce5033
No known key found for this signature in database
GPG Key ID: 4322FF2B4C71259B
6 changed files with 84 additions and 24 deletions

View File

@ -2,6 +2,7 @@
#include "ClientPacket.h"
#include "ClientTransport.h"
#include "Http.h"
#include "Launcher.h"
#include "Identity.h"
#include <nlohmann/json.hpp>
@ -93,12 +94,12 @@ void ClientNetwork::handle_connection(ip::tcp::socket&& socket) {
}
void ClientNetwork::handle_packet(bmp::ClientPacket& packet) {
spdlog::trace("Got client packet: purpose: 0x{:x}, flags: 0x{:x}, pid: {}, vid: {}, size: {}",
spdlog::debug("Got client packet: purpose: 0x{:x}, flags: 0x{:x}, pid: {}, vid: {}, size: {}",
uint16_t(packet.purpose),
uint8_t(packet.flags),
packet.pid, packet.vid,
packet.get_readable_data().size());
spdlog::trace("Client State: 0x{:x}", int(m_client_state));
spdlog::debug("Client State: 0x{:x}", int(m_client_state));
switch (m_client_state) {
case bmp::ClientIdentification:
@ -147,12 +148,12 @@ void ClientNetwork::handle_client_identification(bmp::ClientPacket& packet) {
disconnect(fmt::format("Incompatible protocol version, expected v{}", "1.x.x"));
return;
}
m_mod_version = Version { uint8_t(mod_version.at(0)), uint8_t(mod_version.at(1)), uint8_t(mod_version.at(2)) };
m_game_version = Version { uint8_t(game_version.at(0)), uint8_t(game_version.at(1)), uint8_t(game_version.at(2)) };
*launcher.mod_version = Version { uint8_t(mod_version.at(0)), uint8_t(mod_version.at(1)), uint8_t(mod_version.at(2)) };
*launcher.game_version = Version { uint8_t(game_version.at(0)), uint8_t(game_version.at(1)), uint8_t(game_version.at(2)) };
spdlog::info("Connected to {} (mod v{}, game v{}, protocol v{}.{}.{}",
impl,
m_mod_version.to_string(),
m_game_version.to_string(),
launcher.mod_version->to_string(),
launcher.game_version->to_string(),
protocol_version.at(0),
protocol_version.at(1), protocol_version.at(2));
} catch (const std::exception& e) {

View File

@ -19,6 +19,8 @@ public:
void run();
private:
void handle_connection(ip::tcp::socket&& socket);
bmp::ClientPacket client_tcp_read();
@ -46,9 +48,6 @@ private:
static std::vector<uint8_t> json_to_vec(const nlohmann::json& json);
static nlohmann::json vec_to_json(const std::vector<uint8_t>& vec);
Version m_mod_version;
Version m_game_version;
Sync<ident::Identity> m_identity {};
uint16_t m_listen_port {};

View File

@ -1,9 +1,11 @@
#include "Launcher.h"
#include "ClientNetwork.h"
#include "Compression.h"
#include "Hashing.h"
#include "Http.h"
#include "Identity.h"
#include "Platform.h"
#include "ServerNetwork.h"
#include "Version.h"
#include <boost/asio.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
@ -30,6 +32,12 @@ Launcher::Launcher() {
}
// try logging in immediately, for later update requests and such stuff
try_auto_login();
client_network = std::make_unique<ClientNetwork>(*this, m_config->port);
m_client_network_thread = boost::scoped_thread<>([&] {
client_network->run();
});
}
/// Sets shared headers for all backend proxy messages
@ -95,7 +103,7 @@ void Launcher::parse_config() {
void Launcher::check_for_updates(int argc, char** argv) {
std::string LatestHash = HTTP::Get(fmt::format("https://backend.beammp.com/sha/launcher?branch={}&pk={}", m_config->branch, identity->PublicKey));
std::string LatestVersion = HTTP::Get(fmt::format("https://backend.beammp.com/version/launcher?branch={}&pk={}", m_config->branch,identity->PublicKey));
std::string LatestVersion = HTTP::Get(fmt::format("https://backend.beammp.com/version/launcher?branch={}&pk={}", m_config->branch, identity->PublicKey));
std::string DownloadURL = fmt::format("https://backend.beammp.com/builds/launcher?download=true"
"&pk={}"
"&branch={}",
@ -284,3 +292,35 @@ void Launcher::try_auto_login() {
}
}
Result<void, std::string> Launcher::start_server_network(const std::string& host, uint16_t port) {
ip::tcp::resolver resolver(m_io);
boost::system::error_code ec;
auto resolved = resolver.resolve(host, std::to_string(port), ec);
if (ec) {
spdlog::error("Failed to resolve '{}': {}", host, ec.message());
return fmt::format("Failed to resolve '{}': {}", host, ec.message());
}
bool connected = false;
for (const auto& addr : resolved) {
try {
server_network = std::make_unique<ServerNetwork>(*this, addr.endpoint());
spdlog::info("Resolved and connected to '[{}]:{}'",
addr.endpoint().address().to_string(),
addr.endpoint().port());
connected = true;
break;
} catch (...) {
// ignore
}
}
if (!connected) {
spdlog::error("Failed to connect to [{}]:{}", host, port);
return fmt::format("Failed to connect to [{}]:{}", host, port);
} else {
m_server_network_thread = boost::scoped_thread<>([&] {
server_network->run();
});
}
return outcome::success();
}

View File

@ -3,6 +3,7 @@
#include "Config.h"
#include "Identity.h"
#include "Sync.h"
#include "Version.h"
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ip/udp.hpp>
#include <boost/thread/scoped_thread.hpp>
@ -11,6 +12,9 @@
#include <string>
#include <thread>
class ClientNetwork;
class ServerNetwork;
class Launcher {
public:
Launcher();
@ -31,6 +35,14 @@ public:
Sync<ident::Identity> identity {};
Result<void, std::string> start_server_network(const std::string& host, uint16_t port);
Sync<Version> mod_version {};
Sync<Version> game_version {};
std::unique_ptr<ClientNetwork> client_network {};
std::unique_ptr<ServerNetwork> server_network {};
private:
/// Thread main function for the http(s) proxy thread.
void proxy_main();

View File

@ -2,6 +2,7 @@
#include "ClientInfo.h"
#include "Identity.h"
#include "ImplementationInfo.h"
#include "Launcher.h"
#include "ProtocolVersion.h"
#include "ServerInfo.h"
#include "Transport.h"
@ -13,6 +14,11 @@ ServerNetwork::ServerNetwork(Launcher& launcher, const ip::tcp::endpoint& ep)
: m_tcp_ep(ep)
, launcher(launcher) {
spdlog::debug("Server network created");
boost::system::error_code ec;
m_tcp_socket.connect(m_tcp_ep, ec);
if (ec) {
throw std::runtime_error(ec.message());
}
}
ServerNetwork::~ServerNetwork() {
@ -20,12 +26,6 @@ ServerNetwork::~ServerNetwork() {
}
void ServerNetwork::run() {
boost::system::error_code ec;
m_tcp_socket.connect(m_tcp_ep, ec);
if (ec) {
spdlog::error("Failed to connect to [{}]:{}: {}", m_tcp_ep.address().to_string(), m_tcp_ep.port(), ec.message());
throw std::runtime_error(ec.message());
}
// start the connection by going to the identification state and sending
// the first packet in the identification protocol (protocol version)
m_state = bmp::State::Identification;
@ -171,11 +171,18 @@ void ServerNetwork::handle_identification(const bmp::Packet& packet) {
.purpose = bmp::Purpose::ClientInfo,
.raw_data = std::vector<uint8_t>(1024),
};
// TODO: Game and mod version
struct bmp::ClientInfo ci {
.program_version = { .major = PRJ_VERSION_MAJOR, .minor = PRJ_VERSION_MINOR, .patch = PRJ_VERSION_PATCH },
.game_version = { .major = 4, .minor = 5, .patch = 6 },
.mod_version = { .major = 1, .minor = 2, .patch = 3 },
.game_version = {
.major = launcher.game_version->major,
.minor = launcher.game_version->minor,
.patch = launcher.game_version->patch,
},
.mod_version = {
.major = launcher.mod_version->major,
.minor = launcher.mod_version->minor,
.patch = launcher.mod_version->patch,
},
.implementation = bmp::ImplementationInfo {
.value = "Official BeamMP Launcher",
},
@ -202,10 +209,10 @@ void ServerNetwork::handle_identification(const bmp::Packet& packet) {
case bmp::Purpose::StateChangeAuthentication: {
spdlog::debug("Starting authentication");
m_state = bmp::State::Authentication;
Identity ident{};
auto ident = launcher.identity.synchronize();
bmp::Packet pubkey_packet {
.purpose = bmp::Purpose::PlayerPublicKey,
.raw_data = std::vector<uint8_t>(ident.PublicKey.begin(), ident.PublicKey.end())
.raw_data = std::vector<uint8_t>(ident->PublicKey.begin(), ident->PublicKey.end())
};
tcp_write(pubkey_packet);
break;
@ -291,4 +298,3 @@ void ServerNetwork::handle_playing(const bmp::Packet& packet) {
break;
}
}

View File

@ -89,9 +89,11 @@ int main(int argc, char** argv) {
launcher.start_game();
}
ClientNetwork cn(4444);
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
cn.run();
//auto _ = launcher.start_server_network("beamcruise.com", 10814);
// old: launcher.start_network();