#include "network/network.h" #include "network/message.h" #include "Logs.h" #include "sn_utils.h" #include "Timer.h" #include "application.h" network::connection::connection(bool client) { is_client = client; } void network::connection::connected() { WriteLog("net: socket connected", logtype::net); if (is_client) { std::shared_ptr hello = std::make_shared(message::CONNECT_REQUEST); send_message(hello); } } void network::connection::message_received(std::shared_ptr &msg) { if (msg->type == message::TYPE_MAX) { disconnect(); return; } if (msg->type == message::CONNECT_REQUEST) { std::shared_ptr reply = std::make_shared(); reply->seed = Global.random_seed; WriteLog("client accepted", logtype::net); send_message(reply); } else if (msg->type == message::CONNECT_ACCEPT) { auto cmd = std::dynamic_pointer_cast(msg); WriteLog("accept received", logtype::net); Global.random_seed = cmd->seed; Global.random_engine.seed(Global.random_seed); } else if (msg->type == message::CLIENT_COMMAND) { auto cmd = std::dynamic_pointer_cast(msg); for (auto const &kv : cmd->commands) client_commands_queue.emplace(kv); } else if (msg->type == message::STEP_INFO) { auto delta = std::dynamic_pointer_cast(msg); auto now = std::chrono::high_resolution_clock::now(); delta_queue.push(std::make_pair(now, delta)); } } std::tuple network::connection::get_next_delta() { if (delta_queue.empty()) { return std::tuple(0.0, 0.0, command_queue::commands_map()); } ///auto now = std::chrono::high_resolution_clock::now(); //double last_frame = std::chrono::duration_cast(now - last_time).count(); //last_time = now; //accum += last_frame; auto entry = delta_queue.front(); //if (accum > remote_dt) { //accum -= remote_dt; delta_queue.pop(); return std::make_tuple(entry.second->dt, entry.second->sync, entry.second->commands); //} //else { //return 0.0; //} } command_queue::commands_map network::connection::pop_commands() { command_queue::commands_map map(client_commands_queue); client_commands_queue.clear(); return map; } void network::connection::data_received(std::string &buffer) { std::istringstream body(buffer); std::shared_ptr msg = deserialize_message(body); message_received(msg); } void network::connection::send_message(std::shared_ptr msg) { std::ostringstream stream; sn_utils::ls_uint32(stream, 0x37305545); sn_utils::ls_uint32(stream, msg->get_size()); sn_utils::ls_uint16(stream, (uint16_t)msg->type); msg->serialize(stream); stream.flush(); std::shared_ptr buf = std::make_shared(stream.str()); send_data(buf); } network::server::server() { recorder.open("recorder.bin", std::ios::trunc | std::ios::out | std::ios::binary); } void network::server::push_delta(double dt, double sync, command_queue::commands_map commands) { if (dt == 0.0 && commands.empty()) return; std::shared_ptr msg = std::make_shared(); msg->dt = dt; msg->sync = sync; msg->commands = commands; sn_utils::ls_uint32(recorder, 0x37305545); sn_utils::ls_uint32(recorder, msg->get_size()); sn_utils::ls_uint16(recorder, (uint16_t)msg->type); msg->serialize(recorder); recorder.flush(); for (auto c : clients) c->send_message(msg); } command_queue::commands_map network::server::pop_commands() { command_queue::commands_map map; for (auto c : clients) { command_queue::commands_map cmap = c->pop_commands(); for (auto const &kv : cmap) { auto lookup = map.emplace(kv.first, command_queue::commanddata_sequence()); for (command_data const &data : kv.second) lookup.first->second.emplace_back(data); } } return map; } std::tuple network::client::get_next_delta() { return conn->get_next_delta(); } void network::client::send_commands(command_queue::commands_map commands) { if (commands.empty()) return; std::shared_ptr msg = std::make_shared(); msg->commands = commands; conn->send_message(msg); }