diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 5b2070d6..3485736b 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -42,12 +42,17 @@ private: void ParseServerPing(); void ParseSnapshot(char* data, size_t length); void CreateNewPlayer(int i); + void IdentifyPacketLoss(); // udp stuff boost::asio::ip::udp::endpoint m_ReceiverEndpoint; boost::asio::io_service m_IOService; boost::asio::ip::udp::socket m_Socket; + // Packet loss logic + unsigned int m_PacketID = 0; + unsigned int m_PreviousPacketID = 0; + World* m_World; int m_PlayerID = -1; glm::vec2 m_PlayerPositions[MAXCONNECTIONS]; diff --git a/include/Engine/Network/NetworkDefinitions.h b/include/Engine/Network/NetworkDefinitions.h index e9da132f..b9d36226 100644 --- a/include/Engine/Network/NetworkDefinitions.h +++ b/include/Engine/Network/NetworkDefinitions.h @@ -7,6 +7,7 @@ #define BOARDSIZE 16 #define MAXCONNECTIONS 8 #define INPUTSIZE 128 +#define PACKETMODULUS 1000 // How many packets before the number resets typedef boost::shared_ptr socket_ptr; typedef boost::shared_ptr string_ptr; diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 381759d7..3b476d2a 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -32,6 +32,11 @@ private: std::clock_t m_StopTimes[8]; // Game logic World* m_World; + // Packet loss logic + unsigned int m_PacketCounter = 0; + unsigned int m_PacketID = 0; + const unsigned int m_PacketModolus = 1000; + // Close logic bool m_ThreadIsRunning = true; // Threaded diff --git a/include/Game/Game.h b/include/Game/Game.h index 2763b4dd..8ec4a6d8 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -36,8 +36,7 @@ private: RenderQueueFactory* m_RenderQueueFactory; // Network variables boost::thread m_NetworkThread; - Server m_Server; - Client m_Client; + // Network methods void NetworkFunction(); // Network events diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index df418e06..5e9b1fb3 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -7,6 +7,8 @@ Client::Client() : m_Socket(m_IOService) { // Set up network stream m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string("192.168.1.6"), 13); + m_NextSnapshot.inputForward = ""; + m_NextSnapshot.inputRight = ""; } Client::~Client() @@ -72,7 +74,7 @@ void Client::ReadFromServer() void Client::SendToServer() { - if (m_NextSnapshot.inputForward != "") { + if (m_NextSnapshot.inputForward != "" && m_NextSnapshot.inputForward[0] != '\0') { char* dataPackage = new char[INPUTSIZE]; // The package that will be sent to the server, when filled int len = CreateMessage(MessageType::Event, m_NextSnapshot.inputForward, dataPackage); m_Socket.send_to(boost::asio::buffer( @@ -81,7 +83,7 @@ void Client::SendToServer() m_ReceiverEndpoint, 0); delete[] dataPackage; } - if (m_NextSnapshot.inputRight != "") { + if (m_NextSnapshot.inputRight != "" && m_NextSnapshot.inputRight[0] != '\0') { char* dataPackage = new char[INPUTSIZE]; // The package that will be sent to the server, when filled int len = CreateMessage(MessageType::Event, m_NextSnapshot.inputRight, dataPackage); m_Socket.send_to(boost::asio::buffer( @@ -98,6 +100,12 @@ void Client::ParseMessageType(char* data, size_t length) memcpy(&messageType, data, sizeof(int)); // Read what type off message was sent from server MoveMessageHead(data, length, sizeof(int)); // Move the message head to know where to read from + // Read packet ID + m_PreviousPacketID = m_PacketID; + memcpy(&m_PacketID, data, sizeof(int)); + MoveMessageHead(data, length, sizeof(int)); + IdentifyPacketLoss(); + switch (static_cast(messageType)) { case MessageType::Connect: ParseConnect(data, length); @@ -323,4 +331,16 @@ void Client::CreateNewPlayer(int i) ComponentWrapper transform = m_World->AttachComponent(m_PlayerDefinitions[i].EntityID, "Transform"); ComponentWrapper model = m_World->AttachComponent(m_PlayerDefinitions[i].EntityID, "Model"); model["Resource"] = "Models/Core/UnitSphere.obj"; -} \ No newline at end of file +} + +void Client::IdentifyPacketLoss() +{ + // if no packets lost, difference should be equal to 1 + int difference = m_PacketID - m_PreviousPacketID; + if (difference != 1) { + for (int i = m_PreviousPacketID + 1; i < m_PacketID; i++) + { + LOG_INFO("Packet %i was lost...", i); + } + } +} diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 344054f6..235b26ec 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -162,10 +162,15 @@ int Server::CreateMessage(MessageType type, std::string message, char * data) // Message type memcpy(data + offset, &type, sizeof(int)); offset += sizeof(int); + // Packet ID + m_PacketID = m_PacketCounter % 10; + memcpy(data + offset, &m_PacketID, sizeof(int)); + offset += sizeof(int); // Message, add one extra byte for null terminator memcpy(data + offset, message.data(), (lengthOfMessage + 1) * sizeof(char)); offset += (lengthOfMessage + 1) * sizeof(char); + m_PacketCounter++; return offset; } @@ -273,6 +278,9 @@ int Server::CreateHeader(MessageType type, char * data) int offset = 0; memcpy(data, &messageType, sizeof(int)); offset += sizeof(int); + m_PacketID = m_PacketCounter % 10; + memcpy(data + offset, &m_PacketID, sizeof(int)); + offset += sizeof(int); return offset; } @@ -361,6 +369,10 @@ void Server::ParseConnect(char * data, size_t length) offset += sizeof(int); memcpy(temp + offset, &i, sizeof(int)); + memcpy(temp, &m_PacketID, sizeof(int)); + offset += sizeof(int); + m_PacketCounter++; + m_Socket.send_to( boost::asio::buffer(temp, sizeof(int) * 2), m_PlayerDefinitions[i].Endpoint, diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 5722eaf2..affaaa66 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -48,8 +48,8 @@ Game::Game(int argc, char* argv[]) Game::~Game() { // Call before to ensure that thread closes correctly. - m_Client.Close(); - m_Server.Close(); + //m_Client.Close(); + //m_Server.Close(); delete m_FrameStack; delete m_EventBroker; @@ -84,9 +84,11 @@ void Game::NetworkFunction() std::cout << "Start client or server? (c/s)" << std::endl; std::cin >> inputMessage; if (inputMessage == "c" || inputMessage == "C") { + Client m_Client; m_Client.Start(m_World, m_EventBroker); } if (inputMessage == "s" || inputMessage == "S") { + Server m_Server; m_Server.Start(m_World); } } \ No newline at end of file