diff --git a/network/backend/asio.cpp b/network/backend/asio.cpp index 4a7bb5be..99f270df 100644 --- a/network/backend/asio.cpp +++ b/network/backend/asio.cpp @@ -34,6 +34,11 @@ void network::tcp::connection::read_header() void network::tcp::connection::handle_header(const asio::error_code &err, size_t bytes_transferred) { + if (err) { + disconnect(); + return; + } + std::istringstream header(m_header_buffer); if (m_header_buffer.size() != bytes_transferred) { disconnect(); @@ -59,6 +64,11 @@ void network::tcp::connection::handle_header(const asio::error_code &err, size_t void network::tcp::connection::handle_data(const asio::error_code &err, size_t bytes_transferred) { + if (err) { + disconnect(); + return; + } + if (m_body_buffer.size() != bytes_transferred) { disconnect(); return; @@ -132,7 +142,7 @@ network::tcp::server::server(std::shared_ptr buf, asio::io_context void network::tcp::server::accept_conn() { std::shared_ptr conn = std::make_shared(m_acceptor.get_executor().context()); - conn->set_handler(std::bind(&server::handle_message, this, std::ref(*conn.get()), std::placeholders::_1)); + conn->set_handler(std::bind(&server::handle_message, this, conn, std::placeholders::_1)); m_acceptor.async_accept(conn->m_socket, std::bind(&server::handle_accept, this, conn, std::placeholders::_1)); } @@ -146,6 +156,7 @@ void network::tcp::server::handle_accept(std::shared_ptr conn, const } else { + conn->state = connection::DEAD; WriteLog(std::string("net: failed to accept client: " + err.message()), logtype::net); } @@ -155,9 +166,17 @@ void network::tcp::server::handle_accept(std::shared_ptr conn, const // ------------------ network::tcp::client::client(asio::io_context &io_ctx, const std::string &host, uint32_t port) + : host(host), port(port), io_ctx(io_ctx) { +} + +void network::tcp::client::connect() +{ + if (this->conn) + return; + std::shared_ptr conn = std::make_shared(io_ctx, true, messages_counter); - conn->set_handler(std::bind(&client::handle_message, this, std::ref(*conn.get()), std::placeholders::_1)); + conn->set_handler(std::bind(&client::handle_message, this, conn, std::placeholders::_1)); asio::ip::tcp::endpoint endpoint( asio::ip::address::from_string(host), port); @@ -178,5 +197,6 @@ void network::tcp::client::handle_accept(const asio::error_code &err) else { WriteLog(std::string("net: failed to connect: " + err.message()), logtype::net); + conn->state = connection::DEAD; } } diff --git a/network/backend/asio.h b/network/backend/asio.h index a505da03..7bc7a891 100644 --- a/network/backend/asio.h +++ b/network/backend/asio.h @@ -48,6 +48,12 @@ namespace network::tcp { private: void handle_accept(const asio::error_code &err); + asio::io_context &io_ctx; + std::string host; + uint32_t port; + + protected: + virtual void connect() override; public: client(asio::io_context &io_ctx, const std::string &host, uint32_t port); diff --git a/network/manager.cpp b/network/manager.cpp index 4b311c4f..43d9518f 100644 --- a/network/manager.cpp +++ b/network/manager.cpp @@ -33,12 +33,6 @@ void network::server_manager::push_delta(double dt, double sync, const command_q serialize_message(msg, *backbuffer.get()); } -void network::server_manager::update() -{ - for (auto srv : servers) - srv->update(); -} - void network::server_manager::create_server(asio::io_context &ctx, const std::string &host, uint32_t port) { servers.emplace_back(std::make_shared(backbuffer, ctx, host, port)); @@ -51,7 +45,6 @@ network::manager::manager() void network::manager::poll() { io_context.poll(); - servers->update(); } void network::manager::create_server(const std::string &host, uint32_t port) diff --git a/network/manager.h b/network/manager.h index 09feeb24..f1442f81 100644 --- a/network/manager.h +++ b/network/manager.h @@ -18,7 +18,6 @@ namespace network void push_delta(double dt, double sync, const command_queue::commands_map &commands); command_queue::commands_map pop_commands(); void create_server(asio::io_context &ctx, const std::string &host, uint32_t port); - void update(); }; class manager diff --git a/network/network.cpp b/network/network.cpp index aedd00f2..35c004ec 100644 --- a/network/network.cpp +++ b/network/network.cpp @@ -163,14 +163,17 @@ void network::server::push_delta(double dt, double sync, const command_queue::co msg.sync = sync; msg.commands = commands; - for (auto c : clients) - if (c->state == connection::ACTIVE) - c->send_message(msg); -} + for (auto it = clients.begin(); it != clients.end(); ) { + if ((*it)->state == connection::DEAD) { + it = clients.erase(it); + continue; + } -void network::server::update() -{ + if ((*it)->state == connection::ACTIVE) + (*it)->send_message(msg); + it++; + } } command_queue::commands_map network::server::pop_commands() @@ -180,11 +183,11 @@ command_queue::commands_map network::server::pop_commands() return map; } -void network::server::handle_message(connection &conn, const message &msg) +void network::server::handle_message(std::shared_ptr conn, const message &msg) { if (msg.type == message::TYPE_MAX) { - conn.disconnect(); + conn->disconnect(); return; } @@ -193,12 +196,12 @@ void network::server::handle_message(connection &conn, const message &msg) server_hello reply; reply.seed = Global.random_seed; - conn.state = connection::CATCHING_UP; - conn.backbuffer = backbuffer; - conn.backbuffer_pos = 0; - conn.packet_counter = cmd.start_packet; + conn->state = connection::CATCHING_UP; + conn->backbuffer = backbuffer; + conn->backbuffer_pos = 0; + conn->packet_counter = cmd.start_packet; - conn.send_message(reply); + conn->send_message(reply); WriteLog("net: client accepted", logtype::net); } @@ -216,6 +219,14 @@ void network::server::handle_message(connection &conn, const message &msg) std::tuple network::client::get_next_delta() { + if (conn && conn->state == connection::DEAD) { + conn = nullptr; + } + + if (!conn) { + connect(); + } + if (delta_queue.empty()) { return std::tuple(0.0, 0.0, command_queue::commands_map()); @@ -229,8 +240,9 @@ std::tuple network::client::get_nex void network::client::send_commands(command_queue::commands_map commands) { - if (commands.empty()) + if (!conn || conn->state == connection::DEAD || commands.empty()) return; + // eh, maybe queue lost messages request_command msg; msg.commands = commands; @@ -238,11 +250,11 @@ void network::client::send_commands(command_queue::commands_map commands) conn->send_message(msg); } -void network::client::handle_message(connection &conn, const message &msg) +void network::client::handle_message(std::shared_ptr conn, const message &msg) { if (msg.type >= message::TYPE_MAX) { - conn.disconnect(); + conn->disconnect(); return; } @@ -250,7 +262,7 @@ void network::client::handle_message(connection &conn, const message &msg) if (msg.type == message::SERVER_HELLO) { auto cmd = dynamic_cast(msg); - conn.state = connection::ACTIVE; + conn->state = connection::ACTIVE; Global.random_seed = cmd.seed; Global.random_engine.seed(Global.random_seed); diff --git a/network/network.h b/network/network.h index 0e766b0f..584e0440 100644 --- a/network/network.h +++ b/network/network.h @@ -66,7 +66,7 @@ namespace network std::shared_ptr backbuffer; protected: - void handle_message(connection &conn, const message &msg); + void handle_message(std::shared_ptr conn, const message &msg); std::vector> clients; @@ -76,13 +76,13 @@ namespace network server(std::shared_ptr buf); void push_delta(double dt, double sync, const command_queue::commands_map &commands); command_queue::commands_map pop_commands(); - void update(); }; class client { protected: - void handle_message(connection &conn, const message &msg); + virtual void connect() = 0; + void handle_message(std::shared_ptr conn, const message &msg); std::shared_ptr conn; size_t messages_counter = 0;