From d1832c1741acef79210cf12a14f856eb1f4b194c Mon Sep 17 00:00:00 2001 From: Jocke Date: Wed, 17 Feb 2016 17:07:17 +0100 Subject: [PATCH] WIP Timestamps --- include/Engine/Input/EInputCommand.h | 2 + include/Engine/Network/Client.h | 15 +++--- include/Engine/Network/Network.h | 4 +- include/Engine/Network/Server.h | 2 +- src/Engine/Network/Client.cpp | 74 +++++++++++++++++++++------- src/Engine/Network/Network.cpp | 2 +- src/Engine/Network/Server.cpp | 15 +++--- src/Game/Game.cpp | 4 +- 8 files changed, 82 insertions(+), 36 deletions(-) diff --git a/include/Engine/Input/EInputCommand.h b/include/Engine/Input/EInputCommand.h index d4608b55..c2565156 100644 --- a/include/Engine/Input/EInputCommand.h +++ b/include/Engine/Input/EInputCommand.h @@ -16,6 +16,8 @@ struct InputCommand : Event std::string Command; /** The value of the command. */ float Value = 0; + /** Timestamp of the command. */ + double TimeStamp = 0; }; } diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 978c9b65..af4aff51 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -33,8 +33,8 @@ public: ~Client(); void Connect(std::string address, int port); - void Update() override; - + void Update(double dt) override; +private: std::vector m_PlayerSpawnEvents; void parseSpawnEvents(); // Save for children @@ -56,13 +56,13 @@ public: bool m_IsConnected = false; EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; // Server Client Lookup map - // Assumes that root node for client and server is EntityID 0. - // Don't Add items to these two maps with insert, use insertIntoServerClientMaps(EntityID, EntityID)!!!! std::unordered_map m_ServerIDToClientID; std::unordered_map m_ClientIDToServerID; // Network logic + UDPClient m_Unreliable; + TCPClient m_Reliable; PlayerDefinition m_PlayerDefinitions[8]; SnapshotDefinitions m_NextSnapshot; double m_DurationOfPingTime; @@ -70,9 +70,9 @@ public: std::clock_t m_TimeSinceSentInputs; unsigned int m_SendInputIntervalMs; std::vector m_InputCommandBuffer; + std::vector m_ReceivedInputCommands; // Private member functions - size_t receive(char* data); void disconnect(); void parseMessageType(Packet& packet); void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID); @@ -88,6 +88,8 @@ public: void parseComponentDeletion(Packet& packet); void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void parseSnapshot(Packet& packet); + void parseOnInputCommand(Packet& packet); + void publishInputCommands(double dt); void identifyPacketLoss(); void hasServerTimedOut(); EntityID createPlayer(); @@ -110,9 +112,6 @@ public: EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(const Events::PlayerSpawned& e); void parsePlayerDamage(Packet& packet); -private: - UDPClient m_Unreliable; - TCPClient m_Reliable; }; #endif diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index b4de053e..3c320b2c 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -22,11 +22,13 @@ public: Network(World* world, EventBroker* eventBroker); virtual ~Network() { }; - virtual void Update() = 0; + virtual void Update(double dt) = 0; protected: World* m_World; EventBroker* m_EventBroker; + // for network + double m_TimeStamp = 0; // For Debug bool isReadingData = false; diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index b37bffab..d71bffac 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -26,7 +26,7 @@ public: Server(World* world, EventBroker* eventBroker, int port); ~Server(); - void Update() override; + void Update(double dt) override; private: // Network channels diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index b595536d..6cb5dc08 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -41,9 +41,11 @@ void Client::Connect(std::string address, int port) } } -void Client::Update() +void Client::Update(double dt) { m_EventBroker->Process(); + m_TimeStamp += dt; + publishInputCommands(dt); while (m_Unreliable.IsSocketAvailable()) { // Packet will get real data in receive Packet packet(MessageType::Invalid); @@ -122,6 +124,9 @@ void Client::parseMessageType(Packet& packet) case MessageType::OnPlayerDamage: parsePlayerDamage(packet); break; + case MessageType::OnInputCommand: + //parsePlayerDamage(packet); + break; default: break; } @@ -284,21 +289,23 @@ void Client::ignoreFields(Packet& packet, const ComponentInfo& componentInfo) void Client::parseSnapshot(Packet& packet) { - // Read input commands - std::size_t numInputCommands = packet.ReadPrimitive(); - for (std::size_t i = 0; i < numInputCommands; ++i) { - Events::InputCommand e; - e.PlayerID = packet.ReadPrimitive(); - EntityID player = packet.ReadPrimitive(); - std::string command = packet.ReadString(); - float value = packet.ReadPrimitive(); - if (m_ServerIDToClientID.find(player) != m_ServerIDToClientID.end()) { - e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(player)); - e.Command = command; - e.Value = value; - m_EventBroker->Publish(e); - } - } + //// Read input commands + //std::size_t numInputCommands = packet.ReadPrimitive(); + //for (std::size_t i = 0; i < numInputCommands; ++i) { + // Events::InputCommand e; + // e.PlayerID = packet.ReadPrimitive(); + // EntityID player = packet.ReadPrimitive(); + // std::string command = packet.ReadString(); + // float value = packet.ReadPrimitive(); + // double timestamp = packet.ReadPrimitive(); + // if (m_ServerIDToClientID.find(player) != m_ServerIDToClientID.end()) { + // e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(player)); + // e.Command = command; + // e.Value = value; + // e.TimeStamp = timestamp; + // m_EventBroker->Publish(e); + // } + //} // Read world state while (packet.DataReadSize() < packet.Size()) { @@ -359,6 +366,36 @@ void Client::parseSnapshot(Packet& packet) parseSpawnEvents(); } + +void Client::parseOnInputCommand(Packet & packet) +{ + while (packet.DataReadSize() < packet.Size()) { + Events::InputCommand e; + e.PlayerID = packet.ReadPrimitive(); + e.Player = EntityWrapper(m_World, packet.ReadPrimitive()); + e.Command = packet.ReadString(); + e.Value = packet.ReadPrimitive(); + e.TimeStamp = packet.ReadPrimitive(); + m_EventBroker->Publish(e); + m_ReceivedInputCommands.push_back(e); + //LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); + } +} + +void Client::publishInputCommands(double dt) +{ + std::vector notPublishedEvents; + for (int i = 0; i < m_ReceivedInputCommands.size(); i++) { + if (m_ReceivedInputCommands.at(i).TimeStamp < m_TimeStamp) { + m_EventBroker->Publish(m_ReceivedInputCommands.at(i).TimeStamp); + } + else { + notPublishedEvents.push_back(m_ReceivedInputCommands.at(i)); + } + } + m_ReceivedInputCommands = notPublishedEvents; +} + void Client::disconnect() { m_IsConnected = false; @@ -402,7 +439,9 @@ bool Client::OnInputCommand(const Events::InputCommand & e) } } else { if (m_IsConnected) { - m_InputCommandBuffer.push_back(e); + Events::InputCommand setTimestamp = e; + setTimestamp.TimeStamp = m_TimeStamp; + m_InputCommandBuffer.push_back(setTimestamp); } //LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); return true; @@ -516,6 +555,7 @@ void Client::sendInputCommands() for (int i = 0; i < m_InputCommandBuffer.size(); i++) { packet.WriteString(m_InputCommandBuffer[i].Command); packet.WritePrimitive(m_InputCommandBuffer[i].Value); + packet.WritePrimitive(m_InputCommandBuffer[i].TimeStamp); } m_Reliable.Send(packet); m_InputCommandBuffer.clear(); diff --git a/src/Engine/Network/Network.cpp b/src/Engine/Network/Network.cpp index 6ce9ef82..6abcf302 100644 --- a/src/Engine/Network/Network.cpp +++ b/src/Engine/Network/Network.cpp @@ -9,7 +9,7 @@ Network::Network(World* world, EventBroker* eventBroker) m_TimeoutMs = config->Get("Networking.TimeoutMs", 20000); } -void Network::Update() +void Network::Update(double dt) { updateNetworkData(); } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 3f59eb0c..f4adad91 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -26,10 +26,11 @@ Server::~Server() } -void Server::Update() +void Server::Update(double dt) { + m_EventBroker->Process(); + m_TimeStamp += dt; PlayerDefinition pd; - m_Reliable.AcceptNewConnections(m_NextPlayerID, m_ConnectedPlayers); for (auto& kv : m_ConnectedPlayers) { while (kv.second.TCPSocket->available()) { @@ -80,9 +81,8 @@ void Server::Update() checkForTimeOuts(); timOutTimer = currentTime; } - m_EventBroker->Process(); if (isReadingData) { - Network::Update(); + Network::Update(dt); } } @@ -145,7 +145,7 @@ void Server::unreliableBroadcast(Packet& packet) void Server::sendSnapshot() { Packet packet(MessageType::Snapshot); - addInputCommandsToPacket(packet); + //addInputCommandsToPacket(packet); addChildrenToPacket(packet, EntityID_Invalid); unreliableBroadcast(packet); } @@ -159,6 +159,7 @@ void Server::addInputCommandsToPacket(Packet& packet) packet.WritePrimitive(m_ConnectedPlayers.at(command.PlayerID).EntityID); packet.WriteString(command.Command); packet.WritePrimitive(command.Value); + packet.WritePrimitive(command.TimeStamp); } m_InputCommandsToBroadcast.clear(); } @@ -465,7 +466,9 @@ void Server::parseOnInputCommand(Packet& packet) e.PlayerID = player; // Set correct player id e.Player = EntityWrapper(m_World, m_ConnectedPlayers.at(player).EntityID); e.Value = packet.ReadPrimitive(); - m_EventBroker->Publish(e); + e.TimeStamp = packet.ReadPrimitive(); + /* m_EventBroker->Publish(e);*/ + if (e.Command == "PrimaryFire" || e.Command == "Reload") { m_InputCommandsToBroadcast.push_back(e); } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 49b1a963..fecea4f8 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -199,10 +199,10 @@ void Game::Tick() // Update network m_EventBroker->Process(); if (m_NetworkClient != nullptr) { - m_NetworkClient->Update(); + m_NetworkClient->Update(dt); } if (m_NetworkServer != nullptr) { - m_NetworkServer->Update(); + m_NetworkServer->Update(dt); } //m_SoundManager->Update(dt);