From 58952725e91dad639250ebf70d4ccab47cb64646 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 10 Dec 2015 17:07:18 +0100 Subject: [PATCH] Added class Package to help refactor the code. The code got easier to read. --- include/Engine/Network/Client.h | 1 + include/Engine/Network/NetworkDefinitions.h | 2 + include/Engine/Network/Package.h | 32 ++++++ include/Engine/Network/Server.h | 4 +- src/Engine/Network/Client.cpp | 89 +++++---------- src/Engine/Network/Package.cpp | 24 ++++ src/Engine/Network/Server.cpp | 115 +++++++++----------- 7 files changed, 138 insertions(+), 129 deletions(-) create mode 100644 include/Engine/Network/Package.h create mode 100644 src/Engine/Network/Package.cpp diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 3485736b..26f4489d 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -30,6 +30,7 @@ private: void SendToServer(); int Receive(char* data, size_t length); + void Send(Package& message); int CreateMessage(MessageType type, std::string message, char* data); void Connect(); void Disconnect(); diff --git a/include/Engine/Network/NetworkDefinitions.h b/include/Engine/Network/NetworkDefinitions.h index 4ad32e26..8b2ebadf 100644 --- a/include/Engine/Network/NetworkDefinitions.h +++ b/include/Engine/Network/NetworkDefinitions.h @@ -3,6 +3,8 @@ #include #include +#include "Network/Package.h" + #define BOARDSIZE 16 #define MAXCONNECTIONS 8 diff --git a/include/Engine/Network/Package.h b/include/Engine/Network/Package.h new file mode 100644 index 00000000..949fc05b --- /dev/null +++ b/include/Engine/Network/Package.h @@ -0,0 +1,32 @@ +#ifndef Package_h__ +#define Package_h__ + +#include +#include "Network/MessageType.h" + +// Defines the +class Package +{ +public: + // arg1: Type of message (Connect, Disconnect...) + // arg2: PackageID for identifying packet loss. + Package(MessageType type); + ~Package(); + // Add primitive types like int, float, char... + template + void AddPrimitive(T val) + { + memcpy(m_Data + m_Offset, &val, sizeof(T)); + m_Offset += sizeof(T); + } + void AddString(std::string str); + + int Size() { return m_Offset; }; + char* Data() { return m_Data; }; + +private: + char* m_Data = new char[128]; + int m_Offset = 0; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 3b476d2a..2826684d 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -47,10 +47,12 @@ private: int Receive(char* data, size_t length); + void Send(Package& package, int playerID); + void Send(Package& package); int CreateMessage(MessageType type, std::string message, char * data); void MoveMessageHead(char*& data, size_t& length, size_t stepSize); void Broadcast(std::string message); - void Broadcast(char* data, size_t length); + void Broadcast(Package& package); void SendSnapshot(); void SendPing(); void CheckForTimeOuts(); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 4f397b5b..73b8b823 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -75,22 +75,14 @@ void Client::ReadFromServer() void Client::SendToServer() { 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( - dataPackage, - len), - m_ReceiverEndpoint, 0); - delete[] dataPackage; + Package message(MessageType::Event); + message.AddString(m_NextSnapshot.inputForward); + Send(message); } 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( - dataPackage, - len), - m_ReceiverEndpoint, 0); - delete[] dataPackage; + Package message(MessageType::Event); + message.AddString(m_NextSnapshot.inputRight); + Send(message); } } @@ -146,16 +138,9 @@ void Client::ParsePing() void Client::ParseServerPing() { - char* testMessage = new char[128]; - int testOffset = CreateMessage(MessageType::ServerPing, "Ping recieved", testMessage); - - //std::cout << "Parsing ping." << std::endl; - - m_Socket.send_to(boost::asio::buffer( - testMessage, - testOffset), - m_ReceiverEndpoint, 0); - delete[] testMessage; + Package message(MessageType::ServerPing); + message.AddString("Ping recieved"); + Send(message); } void Client::ParseEventMessage(char* data, size_t length) @@ -223,59 +208,35 @@ int Client::Receive(char* data, size_t length) return bytesReceived; } -int Client::CreateMessage(MessageType type, std::string message, char* data) +void Client::Send(Package& package) { - int lengthOfMessage = 0; - int messageType = static_cast(type); - lengthOfMessage = message.size(); - - int offset = 0; - // Message type - memcpy(data + offset, &messageType, 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); - - return offset; + m_Socket.send_to(boost::asio::buffer( + package.Data(), + package.Size()), + m_ReceiverEndpoint, 0); } void Client::Connect() { - char* dataPackage = new char[INPUTSIZE]; // The package that will be sent to the server, when filled - int length = CreateMessage(MessageType::Connect, m_PlayerName, dataPackage); - m_StartPingTime = std::clock(); - m_Socket.send_to(boost::asio::buffer( - dataPackage, - length), - m_ReceiverEndpoint, 0); - delete[] dataPackage; + Package message(MessageType::Connect); + message.AddString(m_PlayerName); + m_StartPingTime = std::clock(); + Send(message); } void Client::Disconnect() { - char* dataPackage = new char[INPUTSIZE]; // The package that will be sent to the server, when filled - int len = CreateMessage(MessageType::Disconnect, "+Disconnect", dataPackage); - m_Socket.send_to(boost::asio::buffer( - dataPackage, - len), - m_ReceiverEndpoint, 0); - delete[] dataPackage; + Package message(MessageType::Connect); + message.AddString("+Disconnect"); + Send(message); } void Client::Ping() { - char* dataPackage = new char[INPUTSIZE]; - if (GetAsyncKeyState('P')) { // Maybe use previous key here - int length = CreateMessage(MessageType::ClientPing, "Ping", dataPackage); - m_StartPingTime = std::clock(); - m_Socket.send_to(boost::asio::buffer( - dataPackage, - length), - m_ReceiverEndpoint, 0); - } - memset(dataPackage, 0, INPUTSIZE); - delete[] dataPackage; + Package message(MessageType::Connect); + message.AddString("Ping"); + m_StartPingTime = std::clock(); + Send(message); } void Client::MoveMessageHead(char*& data, size_t& length, size_t stepSize) diff --git a/src/Engine/Network/Package.cpp b/src/Engine/Network/Package.cpp new file mode 100644 index 00000000..eb363aac --- /dev/null +++ b/src/Engine/Network/Package.cpp @@ -0,0 +1,24 @@ +#include "Network/Package.h" + +Package::Package(MessageType type) +{ + // Create message header + // Add message type + int messageType = static_cast(type); + memcpy(m_Data, &messageType, sizeof(int)); + m_Offset += sizeof(int); +} + +Package::~Package() +{ + delete[] m_Data; +} + + + +void Package::AddString(std::string str) +{ + // Message, add one extra byte for null terminator + memcpy(m_Data + m_Offset, str.data(), (str.size() + 1) * sizeof(char)); + m_Offset += (str.size() + 1) * sizeof(char); +} diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 2dea57f5..fe851ede 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -154,6 +154,24 @@ int Server::Receive(char * data, size_t length) return length; } +void Server::Send(Package& message, int playerID) +{ + m_Socket.send_to( + boost::asio::buffer(message.Data(), message.Size()), + m_PlayerDefinitions[playerID].Endpoint, + 0); +} + +void Server::Send(Package & package) +{ + m_Socket.send_to( + boost::asio::buffer( + package.Data(), + package.Size()), + m_ReceiverEndpoint, + 0); +} + int Server::CreateMessage(MessageType type, std::string message, char * data) { int lengthOfMessage = 0; @@ -183,55 +201,42 @@ void Server::MoveMessageHead(char *& data, size_t & length, size_t stepSize) void Server::Broadcast(std::string message) { - std::cout << m_PacketID << ": Broadcast: " << message << std::endl; - char* data = new char[128]; - int offset = CreateMessage(MessageType::Event, message, data); + Package package(MessageType::Event); + package.AddPrimitive(12); // Input PackageID here + package.AddString(message); for (int i = 0; i < MAXCONNECTIONS; i++) { if (m_PlayerDefinitions[i].Endpoint.address() != boost::asio::ip::address()) { - m_Socket.send_to( - boost::asio::buffer(data, offset), - m_PlayerDefinitions[i].Endpoint, - 0); + Send(package, i); } } - delete[] data; } -void Server::Broadcast(char * data, size_t length) +void Server::Broadcast(Package& package) { for (int i = 0; i < MAXCONNECTIONS; ++i) { if (m_PlayerDefinitions[i].Endpoint.address() != boost::asio::ip::address()) { - m_Socket.send_to( - boost::asio::buffer(data, length), - m_PlayerDefinitions[i].Endpoint, - 0); + Send(package, i); } } } void Server::SendSnapshot() { - char* data = new char[INPUTSIZE]; - int offset = CreateHeader(MessageType::Snapshot, data); + Package package(MessageType::Snapshot); + package.AddPrimitive(12); // Input PackageID here for (size_t i = 0; i < MAXCONNECTIONS; i++) { if (m_PlayerDefinitions[i].EntityID == -1) { continue; } // Pack player pos into data package glm::vec3 playerPos = m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform")["Position"]; - memcpy(data + offset, &playerPos.x, sizeof(float)); - offset += sizeof(float); - memcpy(data + offset, &playerPos.y, sizeof(float)); - offset += sizeof(float); - memcpy(data + offset, &playerPos.z, sizeof(float)); - offset += sizeof(float); - // +1 for null terminator - // Pack player name into data package - memcpy(data + offset, m_PlayerDefinitions[i].Name.data(), m_PlayerDefinitions[i].Name.size() + 1); - offset += (m_PlayerDefinitions[i].Name.size() + 1) * sizeof(char); + package.AddPrimitive(playerPos.x); + package.AddPrimitive(playerPos.y); + package.AddPrimitive(playerPos.z); + + package.AddString(m_PlayerDefinitions[i].Name); } - Broadcast(data, offset); - delete[] data; + Broadcast(package); } void Server::SendPing() @@ -244,14 +249,13 @@ void Server::SendPing() } // Create ping message - char* data = new char[128]; - int len = CreateMessage(MessageType::ServerPing, "Ping from server", data); - // Time message + Package package(MessageType::ServerPing); + package.AddPrimitive(12); // Input PackageID here + package.AddString("Ping from server"); + // Time message m_StartPingTime = std::clock(); // Send message - Broadcast(data, len); - delete[] data; - + Broadcast(package); } void Server::CheckForTimeOuts() @@ -358,35 +362,23 @@ void Server::ParseConnect(char * data, size_t length) m_PlayerDefinitions[i].Endpoint = m_ReceiverEndpoint; m_PlayerDefinitions[i].Name = std::string(data); + // +1 is the null terminator + MoveMessageHead(data, length, m_PlayerDefinitions[i].Name.size() + 1); m_StopTimes[i] = std::clock(); std::cout << m_PacketID << ": Player \"" << m_PlayerDefinitions[i].Name << "\" connected on IP: " << m_PlayerDefinitions[i].Endpoint.address().to_string() << std::endl; - int offset = 0; - char* temp = new char[sizeof(int) * 2]; - int messagType = 0; - - memcpy(temp, &messagType, sizeof(int)); - 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, - 0); + Package package(MessageType::Connect); + package.AddPrimitive(12); // Input PackageID here + package.AddPrimitive(i); // Player ID + + Send(package, i); // Send notification that a player has connected std::string str = m_PacketID + "Player " + m_PlayerDefinitions[i].Name + " connected on: " + m_PlayerDefinitions[i].Endpoint.address().to_string(); Broadcast(str); - // +1 is the null terminator - MoveMessageHead(data, length, m_PlayerDefinitions[i].Name.size() + 1); - delete[] temp; break; } } @@ -406,18 +398,12 @@ void Server::ParseDisconnect() void Server::ParseClientPing() { - char* testMesssage = new char[128]; - int testOffset = CreateMessage(MessageType::ClientPing, "Ping recieved", testMesssage); - - std::cout << m_PacketID << ":Parsing ping." << std::endl; - // Return ping - m_Socket.send_to( - boost::asio::buffer( - testMesssage, - testOffset), - m_ReceiverEndpoint, - 0); - delete[] testMesssage; + std::cout << m_PacketID << ":Parsing ping." << std::endl; + // Return ping + Package package(MessageType::ClientPing); + package.AddPrimitive(12); // Insert packet ID here + package.AddString("Ping received"); + Send(package); } void Server::ParseServerPing() @@ -430,6 +416,7 @@ void Server::ParseServerPing() } } +// NOT USED void Server::ParseSnapshot(char * data, size_t length) { // Does no logic. Returns snapshot if client request one