diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 1c445cac..5259504b 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -35,7 +35,7 @@ protected: int port = 0; // Sending message to server logic int bytesRead = -1; - char readBuf[INPUTSIZE] = { 0 }; + char readBuffer[BUFFERSIZE] = { 0 }; // Packet loss logic PacketID m_PacketID = 0; @@ -68,7 +68,7 @@ protected: // Private member functions virtual void send(Packet& packet) = 0; virtual void readFromServer() = 0; - void connect(); + virtual void connect() = 0; void disconnect(); void parseMessageType(Packet& packet); void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType); diff --git a/include/Engine/Network/HybridClient.h b/include/Engine/Network/HybridClient.h index 8c9d1a68..fb2777d4 100644 --- a/include/Engine/Network/HybridClient.h +++ b/include/Engine/Network/HybridClient.h @@ -16,6 +16,7 @@ private: boost::asio::io_service m_IOService; boost::asio::ip::udp::socket m_Socket; + void connect(); void readFromServer(); int receive(char * data); void send(Packet & packet); diff --git a/include/Engine/Network/HybridServer.h b/include/Engine/Network/HybridServer.h index 95a9ffde..f12dc660 100644 --- a/include/Engine/Network/HybridServer.h +++ b/include/Engine/Network/HybridServer.h @@ -13,18 +13,13 @@ private: // UDP logic boost::asio::io_service m_IOService; std::unique_ptr m_Socket; + boost::asio::ip::udp::endpoint m_ReceiverEndpoint; void readFromClients(); - void parseClientPing(); - void parsePing(); - void parseDisconnect(); void parseConnect(Packet & packet); - void parseOnInputCommand(Packet & packet); - void parsePlayerTransform(Packet & packet); void send(Packet & packet, PlayerDefinition & playerDefinition); void send(Packet & packet); int receive(char * data); - PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index e1e64fc1..caf55f13 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -12,7 +12,7 @@ #include #include -#define INPUTSIZE 32000 +#define BUFFERSIZE 32000 typedef unsigned int PlayerID; typedef unsigned int PacketID; diff --git a/include/Engine/Network/Packet.h b/include/Engine/Network/Packet.h index d38ddf58..b7e774c2 100644 --- a/include/Engine/Network/Packet.h +++ b/include/Engine/Network/Packet.h @@ -49,6 +49,8 @@ public: void WriteData(char* data, int sizeOfData); // Pops the first element as if it was a string. std::string ReadString(); + // Update size of packet variable in header + void UpdateSize(); char* ReadData(int SizeOfData); void ChangePacketID(unsigned int& packetID); int Size() { return m_Offset; }; diff --git a/include/Engine/Network/PlayerDefinition.h b/include/Engine/Network/PlayerDefinition.h index 3a3dd122..e4c3e5c5 100644 --- a/include/Engine/Network/PlayerDefinition.h +++ b/include/Engine/Network/PlayerDefinition.h @@ -10,6 +10,8 @@ struct PlayerDefinition { boost::asio::ip::udp::endpoint Endpoint; unsigned int PacketID; std::clock_t StopTime; + boost::asio::ip::address Address; + unsigned short Port; // use for tcp connections boost::shared_ptr TCPSocket; }; diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 2926558f..4ff169d2 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -25,12 +25,13 @@ public: void Start(World* m_world, EventBroker *eventBroker) override; void Update() override; protected: - template - T m_ReceiverEndpoint; + // dont forget to set these in the childrens receive logic + boost::asio::ip::address m_Address; + unsigned short m_Port; // Sending messages to client logic std::map m_ConnectedPlayers; // HACK: Fix INPUTSIZE - char readBuffer[INPUTSIZE] = { 0 }; + char readBuffer[BUFFERSIZE] = { 0 }; int bytesRead = 0; // time for previouse message std::clock_t previousePingMessage = std::clock(); @@ -65,15 +66,17 @@ protected: void parseOnPlayerDamage(Packet& packet); void identifyPacketLoss(); void kick(PlayerID player); + PlayerID GetPlayerIDFromEndpoint(); + void parsePlayerTransform(Packet& packet); + void parseOnInputCommand(Packet& packet); + void parseClientPing(); + void parsePing(); + void parseDisconnect(); // Pure virtual functions - virtual void parseOnInputCommand(Packet& packet) = 0; virtual void readFromClients() = 0; virtual void send(Packet& packet, PlayerDefinition & playerDefinition) = 0; virtual void send(Packet& packet) = 0; virtual void parseConnect(Packet& packet) = 0; - virtual void parseDisconnect() = 0; - virtual void parseClientPing() = 0; - virtual void parsePing() = 0; // Debug event EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand& e); @@ -83,7 +86,6 @@ protected: bool OnEntityDeleted(const Events::EntityDeleted& e); EventRelay m_EComponentDeleted; bool OnComponentDeleted(const Events::ComponentDeleted& e); - virtual void parsePlayerTransform(Packet& packet) = 0; }; #endif diff --git a/include/Engine/Network/TCPClient.h b/include/Engine/Network/TCPClient.h index 14415eef..e90e049c 100644 --- a/include/Engine/Network/TCPClient.h +++ b/include/Engine/Network/TCPClient.h @@ -15,6 +15,7 @@ private: boost::asio::io_service m_IOService; boost::shared_ptr m_Socket; + void connect(); void readFromServer(); int receive(char * data); void send(Packet & packet); diff --git a/include/Engine/Network/TCPServer.h b/include/Engine/Network/TCPServer.h index 23f6d666..61e40639 100644 --- a/include/Engine/Network/TCPServer.h +++ b/include/Engine/Network/TCPServer.h @@ -8,30 +8,19 @@ class TCPServer : public Server public: TCPServer(); ~TCPServer(); - private: // TCP logic - boost::asio::ip::udp::endpoint m_ReceiverEndpoint; boost::asio::io_service m_IOService; std::unique_ptr acceptor; boost::shared_ptr lastReceivedSocket; - void Start(World* world, EventBroker* eventBroker); void readFromClients(); void acceptNewConnections(); void handle_accept(boost::shared_ptr socket, const boost::system::error_code & error); - void parseDisconnect(); void parseConnect(Packet & packet); - ///// Implement method to get which player it was - void parseClientPing(); - void parsePing(); - void parseOnInputCommand(Packet & packet); - void parsePlayerTransform(Packet & packet); - ///////////////////////// void send(Packet & packet, PlayerDefinition & playerDefinition); void send(Packet & packet); int receive(char * data, boost::asio::ip::tcp::socket& socket); - PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); }; #endif \ No newline at end of file diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 6f9519d5..13efad40 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -49,6 +49,9 @@ void Client::Update() void Client::parseMessageType(Packet& packet) { + // Pop packetSize which is used by TCP Client to + // create a packet of the correct size + packet.ReadPrimitive(); int messageType = packet.ReadPrimitive(); if (messageType == -1) return; @@ -240,16 +243,9 @@ void Client::parseSnapshot(Packet& packet) } } -void Client::connect() -{ - Packet packet(MessageType::Connect, m_SendPacketID); - packet.WriteString(m_PlayerName); - m_StartPingTime = std::clock(); - send(packet); -} - void Client::disconnect() { + m_IsConnected = false; m_PreviousPacketID = 0; m_PacketID = 0; Packet packet(MessageType::Disconnect, m_SendPacketID); @@ -283,7 +279,9 @@ bool Client::OnInputCommand(const Events::InputCommand & e) m_SaveDataTimer = std::clock(); } } else { - m_InputCommandBuffer.push_back(e); + if (m_IsConnected) { + m_InputCommandBuffer.push_back(e); + } //LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); return true; } diff --git a/src/Engine/Network/HybridClient.cpp b/src/Engine/Network/HybridClient.cpp index fd0b6649..eabe109b 100644 --- a/src/Engine/Network/HybridClient.cpp +++ b/src/Engine/Network/HybridClient.cpp @@ -21,9 +21,9 @@ void HybridClient::Start(World* world, EventBroker* eventBroker) void HybridClient::readFromServer() { while (m_Socket.available()) { - bytesRead = receive(readBuf); + bytesRead = receive(readBuffer); if (bytesRead > 0) { - Packet packet(readBuf, bytesRead); + Packet packet(readBuffer, bytesRead); parseMessageType(packet); } } @@ -34,7 +34,7 @@ int HybridClient::receive(char* data) boost::system::error_code error; int bytesReceived = m_Socket.receive_from(boost - ::asio::buffer((void*)data, INPUTSIZE), + ::asio::buffer((void*)data, BUFFERSIZE), m_ReceiverEndpoint, 0, error); // Network Debug data @@ -61,4 +61,12 @@ void HybridClient::send(Packet& packet) m_NetworkData.DataSentThisInterval += packet.Size(); m_NetworkData.AmountOfMessagesSent++; } +} + +void HybridClient::connect() +{ + Packet packet(MessageType::Connect, m_SendPacketID); + packet.WriteString(m_PlayerName); + m_StartPingTime = std::clock(); + send(packet); } \ No newline at end of file diff --git a/src/Engine/Network/HybridServer.cpp b/src/Engine/Network/HybridServer.cpp index e4142725..6c22bab7 100644 --- a/src/Engine/Network/HybridServer.cpp +++ b/src/Engine/Network/HybridServer.cpp @@ -15,6 +15,8 @@ void HybridServer::readFromClients() while (m_Socket->available()) { try { bytesRead = receive(readBuffer); + m_Address = m_ReceiverEndpoint.address(); + m_Port = m_ReceiverEndpoint.port(); Packet packet(readBuffer, bytesRead); parseMessageType(packet); } catch (const std::exception& err) { @@ -41,53 +43,19 @@ void HybridServer::readFromClients() } } -void HybridServer::parseClientPing() -{ - LOG_INFO("%i: Parsing ping", m_PacketID); - PlayerID player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint); - if (player == -1) { - return; - } - // Return ping - Packet packet(MessageType::Ping, m_ConnectedPlayers[player].PacketID); - packet.WriteString("Ping received"); - send(packet); -} - -void HybridServer::parsePing() -{ - for (int i = 0; i < m_ConnectedPlayers.size(); i++) { - if (m_ConnectedPlayers[i].Endpoint.address() == m_ReceiverEndpoint.address()) { - m_ConnectedPlayers[i].StopTime = std::clock(); - break; - } - } -} - -void HybridServer::parseDisconnect() -{ - LOG_INFO("%i: Parsing disconnect", m_PacketID); - - for (auto& kv : m_ConnectedPlayers) { - if (kv.second.Endpoint.address() == m_ReceiverEndpoint.address() && - kv.second.Endpoint.port() == m_ReceiverEndpoint.port()) { - disconnect(kv.first); - break; - } - } -} - void HybridServer::parseConnect(Packet& packet) { LOG_INFO("Parsing connections"); // Check if player is already connected - if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) { + if (GetPlayerIDFromEndpoint() != -1) { return; } // Create a new player PlayerDefinition pd; pd.EntityID = 0; // Overlook this pd.Endpoint = m_ReceiverEndpoint; + pd.Address = m_ReceiverEndpoint.address(); + pd.Port = m_ReceiverEndpoint.port(); pd.Name = packet.ReadString(); pd.PacketID = 0; pd.StopTime = std::clock(); @@ -103,44 +71,6 @@ void HybridServer::parseConnect(Packet& packet) broadcast(notificationPacket); } -void HybridServer::parseOnInputCommand(Packet& packet) -{ - PlayerID player = -1; - // Check which player it was who sent the message - player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint); - if (player != -1) { - while (packet.DataReadSize() < packet.Size()) { - Events::InputCommand e; - e.Command = packet.ReadString(); - 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); - LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); - } - } -} - -void HybridServer::parsePlayerTransform(Packet& packet) -{ - glm::vec3 position; - glm::vec3 orientation; - position.x = packet.ReadPrimitive(); - position.y = packet.ReadPrimitive(); - position.z = packet.ReadPrimitive(); - orientation.x = packet.ReadPrimitive(); - orientation.y = packet.ReadPrimitive(); - orientation.z = packet.ReadPrimitive(); - - PlayerID playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint); - EntityWrapper player(m_World, m_ConnectedPlayers.at(playerID).EntityID); - - if (player.Valid()) { - player["Transform"]["Position"] = position; - player["Transform"]["Orientation"] = orientation; - } -} - void HybridServer::send(Packet& packet, PlayerDefinition & playerDefinition) { try { @@ -180,7 +110,7 @@ int HybridServer::receive(char * data) { unsigned int length = m_Socket->receive_from( boost::asio::buffer((void*)data - , INPUTSIZE) + , BUFFERSIZE) , m_ReceiverEndpoint, 0); // Network Debug data if (isReadingData) { @@ -191,13 +121,4 @@ int HybridServer::receive(char * data) return length; } -PlayerID HybridServer::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) -{ - for (auto& kv : m_ConnectedPlayers) { - if (kv.second.Endpoint.address() == endpoint.address() && - kv.second.Endpoint.port() == endpoint.port()) { - return kv.first; - } - } - return -1; -} + diff --git a/src/Engine/Network/Packet.cpp b/src/Engine/Network/Packet.cpp index d40a1b32..28622611 100644 --- a/src/Engine/Network/Packet.cpp +++ b/src/Engine/Network/Packet.cpp @@ -34,6 +34,8 @@ void Packet::Init(MessageType type, unsigned int & packetID) m_ReturnDataOffset = 0; m_Offset = 0; // Create message header + // allocate memory for size of packet(only used in tcp) + Packet::WritePrimitive(0); // Add message type int messageType = static_cast(type); Packet::WritePrimitive(messageType); @@ -76,6 +78,11 @@ std::string Packet::ReadString() return returnValue; } +void Packet::UpdateSize() +{ + memcpy(m_Data, &m_Offset, sizeof(int)); +} + char * Packet::ReadData(int SizeOfData) { if (m_Offset < m_ReturnDataOffset + SizeOfData) { @@ -91,7 +98,7 @@ void Packet::ChangePacketID(unsigned int & packetID) { packetID = packetID + 1; // Overwrite old PacketID - memcpy(m_Data + sizeof(int), &packetID, sizeof(int)); + memcpy(m_Data + 2*sizeof(int), &packetID, sizeof(int)); } void Packet::resizeData() diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 37b2e752..55f59a03 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -35,6 +35,10 @@ void Server::Update() void Server::parseMessageType(Packet& packet) { + // Pop packetSize which is used by TCP Client to + // create a packet of the correct size + packet.ReadPrimitive(); + int messageType = packet.ReadPrimitive(); // Read what type off message was sent from server // Read packet ID m_PreviousPacketID = m_PacketID; // Set previous packet id @@ -150,25 +154,38 @@ void Server::checkForTimeOuts() int startPing = 1000 * m_StartPingTime / static_cast(CLOCKS_PER_SEC); - for (int i = 0; i < m_ConnectedPlayers.size(); i++) { - if (m_ConnectedPlayers[i].Endpoint.address() != boost::asio::ip::address()) { - int stopPing = 1000 * m_ConnectedPlayers[i].StopTime / + for (auto& kv : m_ConnectedPlayers) { + if (kv.second.Address != boost::asio::ip::address()) { + int stopPing = 1000 * kv.second.StopTime / static_cast(CLOCKS_PER_SEC); if (startPing > stopPing + m_TimeoutMs) { - LOG_INFO("User %i timed out!", i); - disconnect(i); + LOG_INFO("User %i timed out!", kv.second.Name); + disconnect(kv.first); } } } } +void Server::parseDisconnect() +{ + LOG_INFO("%i: Parsing disconnect", m_PacketID); + + for (auto& kv : m_ConnectedPlayers) { + if (kv.second.Address == m_Address && + kv.second.Port == m_Port) { + disconnect(kv.first); + break; + } + } +} + void Server::disconnect(PlayerID playerID) { //broadcast("A player disconnected"); LOG_INFO("User %s disconnected/timed out", m_ConnectedPlayers[playerID].Name.c_str()); // Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have) Events::PlayerDisconnected e; - e.Entity = m_ConnectedPlayers[playerID].EntityID; + e.Entity = m_ConnectedPlayers.at(playerID).EntityID; e.PlayerID = playerID; m_EventBroker->Publish(e); @@ -250,3 +267,77 @@ bool Server::OnComponentDeleted(const Events::ComponentDeleted & e) } return false; } + + +void Server::parseClientPing() +{ + LOG_INFO("%i: Parsing ping", m_PacketID); + PlayerID player = GetPlayerIDFromEndpoint(); + if (player == -1) { + return; + } + // Return ping + Packet packet(MessageType::Ping, m_ConnectedPlayers[player].PacketID); + packet.WriteString("Ping received"); + send(packet); +} + +void Server::parsePing() +{ + for (auto& kv : m_ConnectedPlayers) { + if (kv.second.Address == m_Address && + kv.second.Port == m_Port) { + kv.second.StopTime = std::clock(); + break; + } + } +} + +void Server::parseOnInputCommand(Packet& packet) +{ + PlayerID player = -1; + // Check which player it was who sent the message + player = GetPlayerIDFromEndpoint(); + if (player != -1) { + while (packet.DataReadSize() < packet.Size()) { + Events::InputCommand e; + e.Command = packet.ReadString(); + 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); + LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); + } + } +} + +void Server::parsePlayerTransform(Packet& packet) +{ + glm::vec3 position; + glm::vec3 orientation; + position.x = packet.ReadPrimitive(); + position.y = packet.ReadPrimitive(); + position.z = packet.ReadPrimitive(); + orientation.x = packet.ReadPrimitive(); + orientation.y = packet.ReadPrimitive(); + orientation.z = packet.ReadPrimitive(); + + PlayerID playerID = GetPlayerIDFromEndpoint(); + EntityWrapper player(m_World, m_ConnectedPlayers.at(playerID).EntityID); + + if (player.Valid()) { + player["Transform"]["Position"] = position; + player["Transform"]["Orientation"] = orientation; + } +} + +PlayerID Server::GetPlayerIDFromEndpoint() +{ + for (auto& kv : m_ConnectedPlayers) { + if (kv.second.Address == m_Address && + kv.second.Port == m_Port) { + return kv.first; + } + } + return -1; +} \ No newline at end of file diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp index d4909f56..3d7261b7 100644 --- a/src/Engine/Network/TCPClient.cpp +++ b/src/Engine/Network/TCPClient.cpp @@ -3,39 +3,76 @@ using namespace boost::asio::ip; TCPClient::TCPClient(ConfigFile * config) : Client(config) -{ +{ m_Endpoint = tcp::endpoint(boost::asio::ip::address::from_string(address), port); - m_Socket = boost::shared_ptr(new tcp::socket(m_IOService)); + m_Socket = boost::shared_ptr(new tcp::socket(m_IOService, m_Endpoint)); + tcp::no_delay option(true); + m_Socket->set_option(option); } TCPClient::~TCPClient() -{ +{ } void TCPClient::Start(World * world, EventBroker * eventBroker) -{ +{ Client::Start(world, eventBroker); - boost::system::error_code error = boost::asio::error::host_not_found; - while (error) { +} +void TCPClient::connect() +{ + if (!m_IsConnected) { + boost::system::error_code error = boost::asio::error::host_not_found; m_Socket->close(); - m_Socket->connect(m_Endpoint,error); + m_Socket->connect(m_Endpoint, error); LOG_INFO(error.message().c_str()); + if (!error) { + Packet packet(MessageType::Connect, m_SendPacketID); + packet.WriteString(m_PlayerName); + m_StartPingTime = std::clock(); + send(packet); + } } } - +// TODO FIX CRASH TCP CLIENT SEVER DISCONNECTS FIRST void TCPClient::readFromServer() -{ - +{ + while (m_Socket->available()) { + bytesRead = receive(readBuffer); + Packet packet(readBuffer, bytesRead); + parseMessageType(packet); + } } int TCPClient::receive(char * data) { - return 0; + boost::system::error_code error; + // Read size of packet + int bytesReceived = m_Socket->read_some(boost + ::asio::buffer((void*)data, sizeof(int)), + error); + int sizeOfPacket = 0; + memcpy(&sizeOfPacket, data, sizeof(int)); + + // Read the rest of the message + bytesReceived += m_Socket->read_some(boost + ::asio::buffer((void*)(data + bytesReceived), sizeOfPacket - bytesReceived), + error); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataReceived += bytesReceived; + m_NetworkData.DataReceivedThisInterval += bytesReceived; + m_NetworkData.AmountOfMessagesReceived++; + } + if (error) { + //LOG_ERROR("receive: %s", error.message().c_str()); + } + return bytesReceived; } void TCPClient::send(Packet & packet) -{ +{ + packet.UpdateSize(); m_Socket->send(boost::asio::buffer( packet.Data(), packet.Size())); diff --git a/src/Engine/Network/TCPServer.cpp b/src/Engine/Network/TCPServer.cpp index 930e7913..caf37ee8 100644 --- a/src/Engine/Network/TCPServer.cpp +++ b/src/Engine/Network/TCPServer.cpp @@ -11,11 +11,6 @@ TCPServer::~TCPServer() } -void TCPServer::Start(World* world, EventBroker* eventBroker) -{ - Server::Start(world, eventBroker); -} - void TCPServer::readFromClients() { acceptNewConnections(); @@ -24,6 +19,11 @@ void TCPServer::readFromClients() try { bytesRead = receive(readBuffer, *kv.second.TCPSocket); lastReceivedSocket = kv.second.TCPSocket; + // Get logic for mother class + boost::asio::ip::tcp::endpoint remoteEndpoint = kv.second.TCPSocket->remote_endpoint(); + m_Address = remoteEndpoint.address(); + m_Port = remoteEndpoint.port(); + // Recreate packets Packet packet(readBuffer, bytesRead); parseMessageType(packet); } catch (const std::exception& err) { @@ -63,41 +63,48 @@ void TCPServer::acceptNewConnections() void TCPServer::handle_accept(boost::shared_ptr socket, const boost::system::error_code& error) { - if (!error) { + if (!error && GetPlayerIDFromEndpoint() == -1) { // Add tcp socket to connections + boost::asio::ip::tcp::no_delay option(true); + socket->set_option(option); PlayerDefinition pd; pd.StopTime = std::clock(); pd.TCPSocket = socket; + pd.Address = socket.get()->remote_endpoint().address(); + pd.Port = socket.get()->remote_endpoint().port(); m_ConnectedPlayers[m_NextPlayerID++] = pd; } } -void TCPServer::parseClientPing() -{ -} -void TCPServer::parsePing() -{ - -} -void TCPServer::parseDisconnect() -{ - -} void TCPServer::parseConnect(Packet & packet) { + LOG_INFO("Parsing connections"); + // Check if player is already connected + PlayerID playerID = GetPlayerIDFromEndpoint(); + if(playerID = -1){ + return; + } -} -void TCPServer::parseOnInputCommand(Packet & packet) -{ + // Create a new player + m_ConnectedPlayers.at(playerID).EntityID = 0; // Overlook this + m_ConnectedPlayers.at(playerID).Name = packet.ReadString(); + m_ConnectedPlayers.at(playerID).PacketID = 0; + m_ConnectedPlayers.at(playerID).StopTime = std::clock(); + LOG_INFO("Spectator \"%s\" connected on IP: %s", m_ConnectedPlayers.at(playerID).Name.c_str(), m_ConnectedPlayers.at(playerID).Endpoint.address().to_string().c_str()); -} -void TCPServer::parsePlayerTransform(Packet & packet) -{ + // Send a message to the player that connected + Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID); + send(connnectPacket); + // Send notification that a player has connected + Packet notificationPacket(MessageType::PlayerConnected); + broadcast(notificationPacket); } + void TCPServer::send(Packet & packet, PlayerDefinition & playerDefinition) { try { + packet.UpdateSize(); int bytesSent = playerDefinition.TCPSocket->send( boost::asio::buffer(packet.Data(), packet.Size()), 0); @@ -115,6 +122,7 @@ void TCPServer::send(Packet & packet, PlayerDefinition & playerDefinition) void TCPServer::send(Packet & packet) { + packet.UpdateSize(); lastReceivedSocket->send( boost::asio::buffer( packet.Data(), @@ -128,21 +136,28 @@ void TCPServer::send(Packet & packet) } //boost::shared_ptr socket -int TCPServer::receive(char * data,boost::asio::ip::tcp::socket& socket) +int TCPServer::receive(char * data, boost::asio::ip::tcp::socket& socket) { - unsigned int length = socket.read_some( - boost::asio::buffer((void*)data, INPUTSIZE)); + boost::system::error_code error; + // Read size of packet + int bytesReceived = socket.read_some(boost + ::asio::buffer((void*)data, sizeof(int)), + error); + int sizeOfPacket = 0; + memcpy(&sizeOfPacket, data, sizeof(int)); + + // Read the rest of the message + bytesReceived += socket.read_some(boost + ::asio::buffer((void*)(data + bytesReceived), sizeOfPacket - bytesReceived), + error); // Network Debug data if (isReadingData) { - m_NetworkData.TotalDataReceived += length; - m_NetworkData.DataReceivedThisInterval += length; + m_NetworkData.TotalDataReceived += bytesReceived; + m_NetworkData.DataReceivedThisInterval += bytesReceived; m_NetworkData.AmountOfMessagesReceived++; } - return length; - -} - -PlayerID TCPServer::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) -{ - return PlayerID(); + if (error) { + //LOG_ERROR("receive: %s", error.message().c_str()); + } + return bytesReceived; } \ No newline at end of file diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 969fa46c..a2bde7cb 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -181,11 +181,13 @@ void Game::networkFunction() bool isServer = m_Config->Get("Networking.IsServer", false); if (!isServer) { m_IsClientOrServer = true; - m_ClientOrServer = new TCPClient(m_Config); + //m_ClientOrServer = new TCPClient(m_Config); + m_ClientOrServer = new HybridClient(m_Config); } if (isServer) { m_IsClientOrServer = true; - m_ClientOrServer = new TCPServer(); + //m_ClientOrServer = new TCPServer(); + m_ClientOrServer = new HybridServer(); } m_ClientOrServer->Start(m_World, m_EventBroker);