From 6962e25042a970f3c7bbd0712317a736446a4525 Mon Sep 17 00:00:00 2001 From: milek7 Date: Wed, 6 Feb 2019 00:03:48 +0100 Subject: [PATCH] network improvements and fixes --- Driver.cpp | 4 ---- Globals.cpp | 31 ++++++++++++++++------------- Globals.h | 13 +++--------- Timer.cpp | 4 ++-- Train.cpp | 1 - application.cpp | 43 ++++++++++++++++++++++++++++------------ application.h | 1 + driveruilayer.cpp | 2 +- network/backend/asio.cpp | 33 ++++++++++++++++++++++++++++++ network/backend/asio.h | 13 ++++++++++++ network/manager.cpp | 31 ++++++++++++++++++++--------- network/manager.h | 9 +++------ network/network.cpp | 9 ++++++++- network/network.h | 18 ++++++++++++++++- scenarioloadermode.cpp | 2 ++ 15 files changed, 152 insertions(+), 62 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index e1139de9..0dc78d53 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -2817,10 +2817,6 @@ bool TController::DecBrake() bool TController::IncSpeed() { // zwiększenie prędkości; zwraca false, jeśli dalej się nie da zwiększać - if( true == tsGuardSignal.is_playing() ) { - // jeśli gada, to nie jedziemy - return false; - } bool OK = true; if( ( iDrivigFlags & moveDoorOpened ) && ( VelDesired > 0.0 ) ) { // to prevent door shuffle on stop diff --git a/Globals.cpp b/Globals.cpp index fea0adbe..0fd5daca 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -715,6 +715,11 @@ global_settings::ConfigParse(cParser &Parser) { Parser >> fpslimit; minframetime = std::chrono::duration(1.0f / fpslimit); } + else if (token == "randomseed") + { + Parser.getTokens(1); + Parser >> Global.random_seed; + } else if (token == "gfx.envmap.enabled") { Parser.getTokens(1); @@ -805,23 +810,21 @@ global_settings::ConfigParse(cParser &Parser) { } else if (token == "network.server") { - Parser.getTokens(1); - Parser >> network_conf.is_server; - if (network_conf.is_server) { - Parser.getTokens(2); - Parser >> network_conf.server_host; - Parser >> network_conf.server_port; - } + Parser.getTokens(2); + + std::string backend; + std::string conf; + Parser >> backend >> conf; + + network_servers.push_back(std::make_pair(backend, conf)); } else if (token == "network.client") { - Parser.getTokens(1); - Parser >> network_conf.is_client; - if (network_conf.is_client) { - Parser.getTokens(2); - Parser >> network_conf.client_host; - Parser >> network_conf.client_port; - } + Parser.getTokens(2); + + network_client.emplace(); + Parser >> network_client->first; + Parser >> network_client->second; } } while ((token != "") && (token != "endconfig")); //(!Parser->EndOfFile) // na koniec trochę zależności diff --git a/Globals.h b/Globals.h index f194f45f..0881ca19 100644 --- a/Globals.h +++ b/Globals.h @@ -29,7 +29,7 @@ struct global_settings { std::mt19937 random_engine; std::mt19937 local_random_engine; bool ready_to_load { false }; - uint32_t random_seed; + uint32_t random_seed = 0; TCamera pCamera; // parametry kamery TCamera pDebugCamera; std::array FreeCameraInit; // pozycje kamery @@ -200,15 +200,8 @@ struct global_settings { bool gfx_shadergamma = false; bool gfx_usegles = false; - struct network_conf_t { - bool is_server = false; - std::string server_host; - uint32_t server_port; - - bool is_client = false; - std::string client_host; - uint32_t client_port; - } network_conf; + std::vector> network_servers; + std::optional> network_client; // methods void LoadIniFile( std::string asFileName ); diff --git a/Timer.cpp b/Timer.cpp index 7ef20f30..478b42d0 100644 --- a/Timer.cpp +++ b/Timer.cpp @@ -77,12 +77,12 @@ void UpdateTimers(bool pause) if (DeltaTime > 1.0) DeltaTime = 1.0; + + fSimulationTime += GetDeltaTime(); } else DeltaTime = 0.0; // wszystko stoi, bo czas nie płynie - fSimulationTime += GetDeltaTime(); - oldCount = count; // Keep track of the time lapse and frame count #if __linux__ diff --git a/Train.cpp b/Train.cpp index 923498b4..8f06cd02 100644 --- a/Train.cpp +++ b/Train.cpp @@ -6915,7 +6915,6 @@ void TTrain::DynamicSet(TDynamicObject *d) void TTrain::MoveToVehicle(TDynamicObject *target) { - ErrorLog("MoveToVehicle"); // > Ra: to nie może być tak robione, to zbytnia proteza jest // indeed, too much hacks... // TODO: cleanup diff --git a/application.cpp b/application.cpp index f4c0c4e5..035b57cc 100644 --- a/application.cpp +++ b/application.cpp @@ -174,8 +174,8 @@ eu07_application::run() { if (m_modes[m_modestack.top()]->is_command_processor()) { // active mode is doing real calculations (e.g. drivermode) - bool nextloop = true; - while (nextloop) + int loop_remaining = MAX_NETWORK_PER_FRAME; + while (--loop_remaining > 0) { command_queue::commands_map commands_to_exec; command_queue::commands_map local_commands = simulation::Commands.pop_intercept_queue(); @@ -207,14 +207,14 @@ eu07_application::run() { m_network->client->send_commands(local_commands); if (delta == 0.0) - nextloop = false; + loop_remaining = -1; } // if we're master else { // just push local commands to execution add_to_dequemap(commands_to_exec, local_commands); - nextloop = false; + loop_remaining = -1; } // send commands to command queue @@ -242,7 +242,8 @@ eu07_application::run() { { // verify sync if (sync != slave_sync) { - WriteLog("net: DESYNC!", logtype::net); + WriteLog("net: desync! calculated: " + std::to_string(sync) + + ", received: " + std::to_string(slave_sync), logtype::net); } // set total delta for rendering code @@ -250,6 +251,17 @@ eu07_application::run() { Timer::set_delta_override(totalDelta); } } + + if (!loop_remaining) { + // loop break forced by counter + float received = m_network->client->get_frame_counter(); + float awaiting = m_network->client->get_awaiting_frames(); + + // TODO: don't meddle with mode progresbar + m_modes[m_modestack.top()]->set_progress(100.0f, 100.0f * (received - awaiting) / received); + } else { + m_modes[m_modestack.top()]->set_progress(0.0f, 0.0f); + } } else { // active mode is loader @@ -714,18 +726,23 @@ eu07_application::init_modes() { } bool eu07_application::init_network() { - if (Global.network_conf.is_server || Global.network_conf.is_client) { + if (!Global.network_servers.empty() || Global.network_client) { + // create network manager m_network.emplace(); } - if (Global.network_conf.is_server) { - m_network->create_server(Global.network_conf.server_host, Global.network_conf.server_port); + for (auto const &pair : Global.network_servers) { + // create all servers + m_network->create_server(pair.first, pair.second); } - if (Global.network_conf.is_client) { - m_network->connect(Global.network_conf.client_host, Global.network_conf.client_port); - } - else { - Global.random_seed = std::random_device{}(); + + if (Global.network_client) { + // create client + m_network->connect(Global.network_client->first, Global.network_client->second); + } else { + // we're simulation master + if (!Global.random_seed) + Global.random_seed = std::random_device{}(); Global.random_engine.seed(Global.random_seed); Global.ready_to_load = true; } diff --git a/application.h b/application.h index e3f43507..24b29903 100644 --- a/application.h +++ b/application.h @@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/. #include "network/manager.h" class eu07_application { + const int MAX_NETWORK_PER_FRAME = 1000; public: // types diff --git a/driveruilayer.cpp b/driveruilayer.cpp index 29a6c937..5e86884b 100644 --- a/driveruilayer.cpp +++ b/driveruilayer.cpp @@ -27,7 +27,7 @@ driver_ui::driver_ui() { push_back( &m_debugpanel ); push_back( &m_transcriptspanel ); - push_back( &m_vehiclelist ); + //push_back( &m_vehiclelist ); push_back( &m_logpanel ); m_logpanel.is_open = false; diff --git a/network/backend/asio.cpp b/network/backend/asio.cpp index 79bca075..3708c24c 100644 --- a/network/backend/asio.cpp +++ b/network/backend/asio.cpp @@ -206,3 +206,36 @@ void network::tcp::client::handle_accept(const asio::error_code &err) conn->disconnect(); } } + +network::tcp::asio_manager::asio_manager() { + backend_list.emplace("tcp", this); +} + +std::shared_ptr network::tcp::asio_manager::create_server(std::shared_ptr backbuffer, const std::string &conf) { + std::istringstream stream(conf); + + std::string host; + std::getline(stream, host, ':'); + + int port; + stream >> port; + + return std::make_shared(backbuffer, io_context, host, port); +} + +std::shared_ptr network::tcp::asio_manager::create_client(const std::string &conf) { + std::istringstream stream(conf); + + std::string host; + std::getline(stream, host, ':'); + + int port; + stream >> port; + + return std::make_shared(io_context, host, port); +} + +void network::tcp::asio_manager::update() { + io_context.restart(); + io_context.poll(); +} diff --git a/network/backend/asio.h b/network/backend/asio.h index 87a524cc..42701b86 100644 --- a/network/backend/asio.h +++ b/network/backend/asio.h @@ -60,4 +60,17 @@ namespace network::tcp public: client(asio::io_context &io_ctx, const std::string &host, uint32_t port); }; + + class asio_manager : public network::backend_manager { + asio::io_context io_context; + + public: + asio_manager(); + + virtual std::shared_ptr create_server(std::shared_ptr, const std::string &conf) override; + virtual std::shared_ptr create_client(const std::string &conf) override; + virtual void update() override; + }; + + asio_manager manager; } diff --git a/network/manager.cpp b/network/manager.cpp index 59eda62d..2a6d5248 100644 --- a/network/manager.cpp +++ b/network/manager.cpp @@ -1,6 +1,5 @@ #include "network/manager.h" #include "simulation.h" -#include "network/backend/asio.h" network::server_manager::server_manager() { @@ -33,9 +32,15 @@ void network::server_manager::push_delta(double dt, double sync, const command_q serialize_message(msg, *backbuffer.get()); } -void network::server_manager::create_server(asio::io_context &ctx, const std::string &host, uint32_t port) +void network::server_manager::create_server(const std::string &backend, const std::string &conf) { - servers.emplace_back(std::make_shared(backbuffer, ctx, host, port)); + auto it = backend_list.find(backend); + if (it == backend_list.end()) { + ErrorLog("net: unknown backend: " + backend); + return; + } + + servers.emplace_back(it->second->create_server(backbuffer, conf)); } network::manager::manager() @@ -44,20 +49,28 @@ network::manager::manager() void network::manager::update() { - io_context.restart(); - io_context.poll(); + for (auto &backend : backend_list) + backend.second->update(); if (client) client->update(); } -void network::manager::create_server(const std::string &host, uint32_t port) +void network::manager::create_server(const std::string &backend, const std::string &conf) { servers.emplace(); - servers->create_server(io_context, host, port); + servers->create_server(backend, conf); } -void network::manager::connect(const std::string &host, uint32_t port) +void network::manager::connect(const std::string &backend, const std::string &conf) { - client = std::make_shared(io_context, host, port); + auto it = backend_list.find(backend); + if (it == backend_list.end()) { + ErrorLog("net: unknown backend: " + backend); + return; + } + + client = it->second->create_client(conf); } + +//std::unordered_map> network::backend_list; diff --git a/network/manager.h b/network/manager.h index 12c1fb60..2e85d483 100644 --- a/network/manager.h +++ b/network/manager.h @@ -1,5 +1,4 @@ #pragma once -#include #include #include "network/network.h" #include "command.h" @@ -17,21 +16,19 @@ 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 create_server(const std::string &backend, const std::string &conf); }; class manager { - asio::io_context io_context; - public: manager(); std::optional servers; std::shared_ptr client; - void create_server(const std::string &host, uint32_t port); - void connect(const std::string &host, uint32_t port); + void create_server(const std::string &backend, const std::string &conf); + void connect(const std::string &backend, const std::string &conf); void update(); }; } diff --git a/network/network.cpp b/network/network.cpp index 268c70fa..7b967fc8 100644 --- a/network/network.cpp +++ b/network/network.cpp @@ -143,7 +143,8 @@ void network::server::handle_message(std::shared_ptr conn, const mes if (msg.type == message::CLIENT_HELLO) { auto cmd = dynamic_cast(msg); - if (cmd.version != 1) { + if (cmd.version != 1 // wrong version + || !Global.ready_to_load) { // not ready yet conn->disconnect(); return; } @@ -227,6 +228,10 @@ void network::client::handle_message(std::shared_ptr conn, const mes Global.random_seed = cmd.seed; Global.random_engine.seed(Global.random_seed); Global.ready_to_load = true; + } else if (Global.random_seed != cmd.seed) { + ErrorLog("net: seed mismatch", logtype::net); + conn->disconnect(); + return; } WriteLog("net: accept received", logtype::net); @@ -241,3 +246,5 @@ void network::client::handle_message(std::shared_ptr conn, const mes } // -------------- + +std::unordered_map network::backend_list; diff --git a/network/network.h b/network/network.h index 9de00a54..87ba9386 100644 --- a/network/network.h +++ b/network/network.h @@ -16,7 +16,7 @@ namespace network friend class client; private: - const int CATCHUP_PACKETS = 100; + const int CATCHUP_PACKETS = 500; /* std::queue< @@ -97,5 +97,21 @@ namespace network void update(); std::tuple get_next_delta(); void send_commands(command_queue::commands_map commands); + int get_frame_counter() { + return resume_frame_counter; + } + int get_awaiting_frames() { + return delta_queue.size(); + } }; + + class backend_manager + { + public: + virtual std::shared_ptr create_server(std::shared_ptr, const std::string &conf) = 0; + virtual std::shared_ptr create_client(const std::string &conf) = 0; + virtual void update() = 0; + }; + + extern std::unordered_map backend_list; } diff --git a/scenarioloadermode.cpp b/scenarioloadermode.cpp index e14de75a..9ec486a6 100644 --- a/scenarioloadermode.cpp +++ b/scenarioloadermode.cpp @@ -40,6 +40,8 @@ scenarioloader_mode::update() { return true; if (!state) { + WriteLog("using simulation seed: " + std::to_string(Global.random_seed), logtype::generic); + WriteLog( "\nLoading scenario \"" + Global.SceneryFile + "\"..." ); timestart = std::chrono::system_clock::now();