implement server network -> client network communication

This commit is contained in:
Lion Kortlepel 2024-03-10 15:25:48 +01:00
parent 72a5e7c5b1
commit e836ad5133
No known key found for this signature in database
GPG Key ID: 4322FF2B4C71259B
5 changed files with 121 additions and 21 deletions

@ -1 +1 @@
Subproject commit 18ab3b96d9706dc402670052c05e8ad7c0c63c03
Subproject commit 74b4eee8fe2a2ca5b955347eaa2b54248bcbb456

View File

@ -4,6 +4,8 @@
#include "Http.h"
#include "Identity.h"
#include "Launcher.h"
#include "Transport.h"
#include "Util.h"
#include <boost/asio/socket_base.hpp>
#include <nlohmann/json.hpp>
@ -297,6 +299,7 @@ void ClientNetwork::handle_browsing(bmp::ClientPacket& packet) {
});
} else {
spdlog::info("Connected to server!");
start_server_identification();
}
} catch (const std::exception& e) {
spdlog::error("Failed to read json for purpose 0x{:x}: {}", uint16_t(packet.purpose), e.what());
@ -370,7 +373,7 @@ void ClientNetwork::client_tcp_read(std::function<void(bmp::ClientPacket&&)> han
m_tmp_packet.raw_data.resize(hdr.data_size);
m_tmp_packet.purpose = hdr.purpose;
m_tmp_packet.flags = hdr.flags;
spdlog::debug("Got header: purpose: 0x{:x}, flags: 0x{:x}, pid: {}, vid: {}, size: {}",
spdlog::trace("Got header: purpose: 0x{:x}, flags: 0x{:x}, pid: {}, vid: {}, size: {}",
uint16_t(m_tmp_packet.purpose),
uint8_t(m_tmp_packet.flags),
m_tmp_packet.pid, m_tmp_packet.vid,
@ -401,7 +404,7 @@ void ClientNetwork::client_tcp_write(bmp::ClientPacket&& packet, std::function<v
};
boost::asio::async_write(m_game_socket, buffers,
[this, header_data, owned_packet, handler](auto ec, auto size) {
spdlog::debug("Wrote {} bytes for 0x{:x}", size, int(owned_packet->purpose));
spdlog::trace("Wrote {} bytes for 0x{:x}", size, int(owned_packet->purpose));
if (handler) {
handler(ec);
} else {
@ -453,27 +456,80 @@ Result<std::vector<uint8_t>, std::string> ClientNetwork::load_server_list() noex
}
void ClientNetwork::handle_server_packet(bmp::Packet&& packet) {
post(m_io, [packet, this] {
spdlog::info("HELLO WORLD: {}", m_listen_port);
switch (packet.purpose) {
case bmp::Invalid:
break;
case bmp::ProtocolVersion:
case bmp::ProtocolVersionOk:
case bmp::ProtocolVersionBad:
client_tcp_write(bmp::ClientPacket {
.purpose = bmp::ClientPurpose::ConnectError,
.raw_data = json_to_vec({ "message", "Server is outdated or too new - protocol is incompatible. Please try a different server and make sure your Launcher and Mod are up-to-date." }),
});
start_browsing();
break;
case bmp::ProtocolVersionOk:
start_server_authentication();
break;
case bmp::AuthOk:
uint32_t player_id;
bmp::deserialize(player_id, packet.get_readable_data());
client_tcp_write(bmp::ClientPacket {
.purpose = bmp::ClientPurpose::AuthenticationOk,
.raw_data = json_to_vec({ "pid", player_id }),
});
start_server_mod_download();
break;
case bmp::AuthFailed:
client_tcp_write(bmp::ClientPacket {
.purpose = bmp::ClientPurpose::AuthenticationError,
.raw_data = json_to_vec(
{ "message",
std::string(
packet.get_readable_data().begin(),
packet.get_readable_data().end()) }),
});
start_browsing();
break;
case bmp::PlayerRejected:
client_tcp_write(bmp::ClientPacket {
.purpose = bmp::ClientPurpose::PlayerRejected,
.raw_data = json_to_vec(
{ "message",
std::string(
packet.get_readable_data().begin(),
packet.get_readable_data().end()) }),
});
start_browsing();
break;
case bmp::ModsInfo:
client_tcp_write(bmp::ClientPacket {
.purpose = bmp::ClientPurpose::ModSyncStatus,
.raw_data = json_to_vec(json::array()), // TODO: send more here i guess
});
spdlog::debug("Mod stuff not implemented, skipping to session setup");
break;
case bmp::MapInfo: {
auto data = packet.get_readable_data();
auto map = std::string(data.begin(), data.end());
spdlog::debug("Map: '{}'", map);
client_tcp_write(bmp::ClientPacket {
.purpose = bmp::ClientPurpose::MapInfo,
.raw_data = json_to_vec({ "map", map }),
});
start_server_session_setup();
} break;
case bmp::PlayersVehiclesInfo:
client_tcp_write(bmp::ClientPacket {
.purpose = bmp::ClientPurpose::PlayersAndVehiclesInfo,
.raw_data = packet.get_readable_data(),
});
start_server_playing();
break;
case bmp::ClientInfo:
case bmp::ServerInfo:
case bmp::PlayerPublicKey:
case bmp::AuthOk:
case bmp::AuthFailed:
case bmp::PlayerRejected:
case bmp::StartUDP:
case bmp::ModsInfo:
case bmp::MapInfo:
case bmp::ModRequest:
case bmp::ModResponse:
case bmp::ModRequestInvalid:
case bmp::ModsSyncDone:
case bmp::PlayersVehiclesInfo:
case bmp::SessionReady:
case bmp::Ping:
case bmp::VehicleSpawn:
@ -502,6 +558,9 @@ void ClientNetwork::handle_server_packet(bmp::Packet&& packet) {
case bmp::StateChangePlaying:
case bmp::StateChangeLeaving:
break;
case bmp::Invalid:
case bmp::ProtocolVersion:
break;
}
});
}
@ -521,3 +580,37 @@ void ClientNetwork::handle_accept(boost::system::error_code ec) {
}
// TODO: We should probably accept() again somewhere once the game disconnected
}
void ClientNetwork::start_server_identification() {
client_tcp_write(bmp::ClientPacket {
.purpose = bmp::ClientPurpose::StateChangeServerIdentification,
});
m_client_state = bmp::ClientState::ServerIdentification;
}
void ClientNetwork::start_server_authentication() {
client_tcp_write(bmp::ClientPacket {
.purpose = bmp::ClientPurpose::StateChangeServerAuthentication,
});
m_client_state = bmp::ClientState::ServerAuthentication;
}
void ClientNetwork::start_server_mod_download() {
client_tcp_write(bmp::ClientPacket {
.purpose = bmp::ClientPurpose::StateChangeServerModDownload,
});
m_client_state = bmp::ClientState::ServerModDownload;
}
void ClientNetwork::start_server_session_setup() {
client_tcp_write(bmp::ClientPacket {
.purpose = bmp::ClientPurpose::StateChangeServerSessionSetup,
});
m_client_state = bmp::ClientState::ServerSessionSetup;
}
void ClientNetwork::start_server_playing() {
client_tcp_write(bmp::ClientPacket {
.purpose = bmp::ClientPurpose::StateChangeServerPlaying,
});
m_client_state = bmp::ClientState::ServerPlaying;
}

View File

@ -48,6 +48,11 @@ private:
void start_login();
void start_quick_join();
void start_browsing();
void start_server_identification();
void start_server_authentication();
void start_server_mod_download();
void start_server_session_setup();
void start_server_playing();
Result<std::vector<uint8_t>, std::string> load_server_list() noexcept;

View File

@ -53,7 +53,7 @@ void ServerNetwork::run() {
m_io.run();
}
void ServerNetwork::handle_packet(const bmp::Packet& packet) {
void ServerNetwork::handle_packet(bmp::Packet&& packet) {
// handle ping immediately
if (m_state > bmp::State::Identification && packet.purpose == bmp::Purpose::Ping) {
tcp_write(bmp::Packet {
@ -83,6 +83,8 @@ void ServerNetwork::handle_packet(const bmp::Packet& packet) {
case bmp::State::Leaving:
break;
}
launcher.client_network->handle_server_packet(std::move(packet));
}
void ServerNetwork::handle_mod_download(const bmp::Packet& packet) {
@ -263,7 +265,7 @@ void ServerNetwork::tcp_write(bmp::Packet&& packet, std::function<void(boost::sy
};
boost::asio::async_write(m_tcp_socket, buffers,
[this, header_data, owned_packet, handler](auto ec, auto size) {
spdlog::debug("Wrote {} bytes for 0x{:x} to server", size, int(owned_packet->purpose));
spdlog::trace("Wrote {} bytes for 0x{:x} to server", size, int(owned_packet->purpose));
if (handler) {
handler(ec);
} else {
@ -271,7 +273,7 @@ void ServerNetwork::tcp_write(bmp::Packet&& packet, std::function<void(boost::sy
spdlog::error("Failed to send packet of type 0x{:x} to server", int(owned_packet->purpose));
} else {
// ok!
spdlog::debug("Sent packet of type 0x{:x} to server", int(owned_packet->purpose));
spdlog::trace("Sent packet of type 0x{:x} to server", int(owned_packet->purpose));
}
}
});
@ -303,7 +305,7 @@ void ServerNetwork::udp_write(bmp::Packet& packet) {
if (ec) {
spdlog::error("Failed to UDP write to server: {}", ec.message());
} else {
spdlog::info("Wrote {} bytes to server via UDP", size);
spdlog::trace("Wrote {} bytes to server via UDP", size);
}
});
}
@ -340,7 +342,7 @@ void ServerNetwork::handle_playing(const bmp::Packet& packet) {
void ServerNetwork::start_tcp_read() {
tcp_read([this](auto&& packet) {
spdlog::debug("Got packet 0x{:x} from server", int(packet.purpose));
handle_packet(packet);
handle_packet(std::move(packet));
start_tcp_read();
});
}
@ -348,7 +350,7 @@ void ServerNetwork::start_tcp_read() {
void ServerNetwork::start_udp_read() {
udp_read([this](auto&& ep, auto&& packet) {
spdlog::debug("Got packet 0x{:x} from server via UDP", int(packet.purpose));
handle_packet(packet);
handle_packet(std::move(packet));
start_udp_read();
});
}

View File

@ -32,7 +32,7 @@ private:
/// Sends a packet to the specified UDP endpoint via the UDP socket.
void udp_write(bmp::Packet& packet);
void handle_packet(const bmp::Packet& packet);
void handle_packet(bmp::Packet&& packet);
void handle_identification(const bmp::Packet& packet);
void handle_authentication(const bmp::Packet& packet);
void handle_mod_download(const bmp::Packet& packet);