From 4f2ad3ad00ab561cb241be49812f757d00416b2b Mon Sep 17 00:00:00 2001 From: Jocke Date: Wed, 10 Feb 2016 16:16:56 +0100 Subject: [PATCH] Reliable message should now be working, further testing is to be done. --- include/Engine/Network/Client.h | 8 +- include/Engine/Network/PlayerDefinition.h | 4 +- include/Engine/Network/Server.h | 13 +- src/Engine/Network/Client.cpp | 62 ++++++-- src/Engine/Network/Packet.cpp | 7 +- src/Engine/Network/Server.cpp | 165 ++++++++++++---------- src/Engine/Network/TCPServer.cpp | 9 +- src/Engine/Network/UDPClient.cpp | 4 - src/Engine/Network/UDPServer.cpp | 1 - 9 files changed, 160 insertions(+), 113 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index ffdf812f..d1530b0e 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -70,7 +70,8 @@ protected: void disconnect(); void parseMessageType(Packet& packet); void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType); - void parseConnect(Packet& packet); + void parseUDPConnect(Packet& packet); + void parseTCPConnect(Packet& packet); void parsePlayerConnected(Packet& packet); void parsePing(); void parseKick(); @@ -103,9 +104,8 @@ protected: bool OnPlayerSpawned(const Events::PlayerSpawned& e); private: - UDPClient m_UDPClient; - //TCPClient m_TCPClient; - //TCPClient m_UDPClient; + UDPClient m_Unreliable; + TCPClient m_Reliable; }; #endif diff --git a/include/Engine/Network/PlayerDefinition.h b/include/Engine/Network/PlayerDefinition.h index e4c3e5c5..afd5d889 100644 --- a/include/Engine/Network/PlayerDefinition.h +++ b/include/Engine/Network/PlayerDefinition.h @@ -10,8 +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; + boost::asio::ip::address TCPAddress; + unsigned short TCPPort; // use for tcp connections boost::shared_ptr TCPSocket; }; diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 1b2e6956..7386e43d 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -59,7 +59,8 @@ protected: // Private member functions //int receive(char* data); - void broadcast(Packet& packet); + void reliableBroadcast(Packet& packet); + void unreliableBroadcast(Packet& packet); void sendSnapshot(); void addChildrenToPacket(Packet& packet, EntityID entityID); void sendPing(); @@ -74,13 +75,9 @@ protected: void parseOnInputCommand(Packet& packet); void parseClientPing(); void parsePing(); - void parseConnect(Packet & packet, PlayerDefinition & pd); + void parseUDPConnect(Packet & packet); void parseTCPConnect(Packet & packet); void parseDisconnect(); - //// Pure virtual functions - //virtual void readFromClients() = 0; - //virtual void send(Packet& packet, PlayerDefinition & playerDefinition) = 0; - //virtual void send(Packet& packet) = 0; // Debug event EventRelay m_EInputCommand; @@ -92,8 +89,8 @@ protected: EventRelay m_EComponentDeleted; bool OnComponentDeleted(const Events::ComponentDeleted& e); private: - //TCPServer m_TCPServer; - UDPServer m_UDPServer; + TCPServer m_Reliable; + UDPServer m_Unreliable; }; #endif diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index eaacac47..ba528f27 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -34,11 +34,27 @@ void Client::Start(World* world, EventBroker* eventBroker) void Client::Update() { m_EventBroker->Process(); - while (m_UDPClient.IsSocketAvailable()) { + while (m_Unreliable.IsSocketAvailable()) { // Packet will get real data in receive Packet packet(MessageType::Invalid); - m_UDPClient.Receive(packet); - parseMessageType(packet); + m_Unreliable.Receive(packet); + if (packet.GetMessageType() == MessageType::Connect) { + parseUDPConnect(packet); + } else { + parseMessageType(packet); + } + } + + while (m_Reliable.IsSocketAvailable()) { + // Packet will get real data in receive + Packet packet(MessageType::Invalid); + m_Reliable.Receive(packet); + if (packet.GetMessageType() == MessageType::Connect) { + parseTCPConnect(packet); + } else { + parseMessageType(packet); + } + } if (m_IsConnected) { @@ -67,9 +83,6 @@ void Client::parseMessageType(Packet& packet) //identifyPacketLoss(); switch (static_cast(messageType)) { - case MessageType::Connect: - parseConnect(packet); - break; case MessageType::Ping: parsePing(); break; @@ -100,12 +113,32 @@ void Client::parseMessageType(Packet& packet) } } -void Client::parseConnect(Packet& packet) +void Client::parseUDPConnect(Packet& packet) { // Map ServerEntityID and your PlayerID LOG_INFO("I be connected PogChamp"); } +void Client::parseTCPConnect(Packet& packet) +{ + LOG_INFO("Received TCP connect from server"); + // Pop size of message int + packet.ReadPrimitive(); + int messageType = packet.ReadPrimitive(); + // Read packet ID + m_PreviousPacketID = m_PacketID; // Set previous packet id + m_PacketID = packet.ReadPrimitive(); //Read new packet id + // parse player id and other stuff + m_PlayerID = packet.ReadPrimitive(); + m_PlayerID = packet.ReadPrimitive(); + LOG_INFO("A Player connected"); + Packet UnreliablePacket(MessageType::Connect, m_SendPacketID); + // Add player id and other stuff + packet.WritePrimitive(m_PlayerID); + m_Unreliable.Send(packet); + LOG_INFO("Sent UDP Connect Server"); +} + void Client::parsePlayerConnected(Packet & packet) { // Map ServerEntityID and other player's PlayerID @@ -123,7 +156,7 @@ void Client::parsePing() Packet packet(MessageType::Ping, m_SendPacketID); packet.WriteString("Ping recieved"); - m_UDPClient.Send(packet); + m_Reliable.Send(packet); } void Client::parseKick() @@ -255,14 +288,15 @@ void Client::disconnect() m_PreviousPacketID = 0; m_PacketID = 0; Packet packet(MessageType::Disconnect, m_SendPacketID); - m_UDPClient.Send(packet); + m_Reliable.Send(packet); } bool Client::OnInputCommand(const Events::InputCommand & e) { if (e.Command == "ConnectToServer") { // Connect for now if (e.Value > 0) { - m_UDPClient.Connect(m_PlayerName, address, port); + m_Reliable.Connect(m_PlayerName, address, port); + m_Unreliable.Connect(m_PlayerName, address, port); } //LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); return true; @@ -299,7 +333,7 @@ bool Client::OnPlayerDamage(const Events::PlayerDamage & e) Packet packet(MessageType::OnPlayerDamage, m_SendPacketID); packet.WritePrimitive(e.Damage); packet.WritePrimitive(m_ClientIDToServerID.at(e.Player.ID)); - m_UDPClient.Send(packet); + m_Reliable.Send(packet); return false; } @@ -327,7 +361,7 @@ void Client::sendLocalPlayerTransform() packet.WritePrimitive(orientation.x); packet.WritePrimitive(orientation.y); packet.WritePrimitive(orientation.z); - m_UDPClient.Send(packet); + m_Unreliable.Send(packet); } void Client::identifyPacketLoss() @@ -370,7 +404,7 @@ void Client::sendInputCommands() packet.WriteString(m_InputCommandBuffer[i].Command); packet.WritePrimitive(m_InputCommandBuffer[i].Value); } - m_UDPClient.Send(packet); + m_Reliable.Send(packet); m_InputCommandBuffer.clear(); } } @@ -378,7 +412,7 @@ void Client::sendInputCommands() void Client::becomePlayer() { Packet packet = Packet(MessageType::BecomePlayer, m_SendPacketID); - m_UDPClient.Send(packet); + m_Reliable.Send(packet); } bool Client::clientServerMapsHasEntity(EntityID clientEntityID) diff --git a/src/Engine/Network/Packet.cpp b/src/Engine/Network/Packet.cpp index c9e8832a..c99390bb 100644 --- a/src/Engine/Network/Packet.cpp +++ b/src/Engine/Network/Packet.cpp @@ -35,11 +35,11 @@ void Packet::Init(MessageType type, unsigned int & packetID) m_Offset = 0; // Create message header // allocate memory for size of packet(only used in tcp) - Packet::WritePrimitive(0); + WritePrimitive(0); // Add message type int messageType = static_cast(type); - Packet::WritePrimitive(messageType); - Packet::WritePrimitive(packetID); + WritePrimitive(messageType); + WritePrimitive(packetID); packetID++; m_HeaderSize = m_Offset; } @@ -98,6 +98,7 @@ void Packet::ReconstructFromData(char * data, int sizeOfData) void Packet::UpdateSize() { + int whatisoffset = m_Offset; memcpy(m_Data, &m_Offset, sizeof(int)); } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index d3099e12..406abfb7 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -24,31 +24,31 @@ void Server::Start(World* world, EventBroker* eventBroker) void Server::Update() { PlayerDefinition pd; - - //m_TCPServer.AcceptNewConnections(m_NextPlayerID, m_ConnectedPlayers); - //for (auto& kv : m_ConnectedPlayers) { - // while (kv.second.TCPSocket->available()) { - // // Packet will get real data in receive - // Packet packet(MessageType::Invalid); - // m_TCPServer.Receive(packet, kv.second); - // m_Address = kv.second.TCPSocket->remote_endpoint().address(); - // m_Port = kv.second.TCPSocket->remote_endpoint().port(); - // if (packet.GetMessageType() == MessageType::Connect) { - // parseTCPConnect(packet); - // } else { - // parseMessageType(packet); - // } - // } - //} - while (m_UDPServer.IsSocketAvailable()) { + m_Reliable.AcceptNewConnections(m_NextPlayerID, m_ConnectedPlayers); + for (auto& kv : m_ConnectedPlayers) { + while (kv.second.TCPSocket->available()) { + // Packet will get real data in receive + Packet packet(MessageType::Invalid); + m_Reliable.Receive(packet, kv.second); + m_Address = kv.second.TCPSocket->remote_endpoint().address(); + m_Port = kv.second.TCPSocket->remote_endpoint().port(); + if (packet.GetMessageType() == MessageType::Connect) { + parseTCPConnect(packet); + } else { + parseMessageType(packet); + } + } + } + + while (m_Unreliable.IsSocketAvailable()) { // Packet will get real data in receive Packet packet(MessageType::Invalid); - m_UDPServer.Receive(packet, pd); + m_Unreliable.Receive(packet, pd); m_Address = pd.Endpoint.address(); m_Port = pd.Endpoint.port(); if (packet.GetMessageType() == MessageType::Connect) { - parseConnect(packet, pd); + parseUDPConnect(packet); } else { parseMessageType(packet); } @@ -115,11 +115,19 @@ void Server::parseMessageType(Packet& packet) } } -void Server::broadcast(Packet& packet) +void Server::reliableBroadcast(Packet& packet) { for (auto& kv : m_ConnectedPlayers) { packet.ChangePacketID(kv.second.PacketID); - m_UDPServer.Send(packet, kv.second); + m_Reliable.Send(packet, kv.second); + } +} + +void Server::unreliableBroadcast(Packet& packet) +{ + for (auto& kv : m_ConnectedPlayers) { + packet.ChangePacketID(kv.second.PacketID); + m_Unreliable.Send(packet, kv.second); } } @@ -128,7 +136,7 @@ void Server::sendSnapshot() { Packet packet(MessageType::Snapshot); addChildrenToPacket(packet, EntityID_Invalid); - broadcast(packet); + unreliableBroadcast(packet); } void Server::addChildrenToPacket(Packet & packet, EntityID entityID) @@ -189,7 +197,7 @@ void Server::sendPing() // Time message m_StartPingTime = std::clock(); // Send message - broadcast(packet); + reliableBroadcast(packet); } void Server::checkForTimeOuts() @@ -199,7 +207,7 @@ void Server::checkForTimeOuts() std::vector playersToRemove; for (auto& kv : m_ConnectedPlayers) { - if (kv.second.Address != boost::asio::ip::address()) { + if (kv.second.TCPAddress != boost::asio::ip::address()) { int stopPing = 1000 * kv.second.StopTime / static_cast(CLOCKS_PER_SEC); if (startPing > stopPing + m_TimeoutMs) { @@ -213,63 +221,71 @@ void Server::checkForTimeOuts() } } -void Server::parseConnect(Packet & packet, PlayerDefinition & pd) +void Server::parseUDPConnect(Packet & packet) { + // Pop size of message int + packet.ReadPrimitive(); + int messageType = packet.ReadPrimitive(); + // Read packet ID + m_PreviousPacketID = m_PacketID; // Set previous packet id + m_PacketID = packet.ReadPrimitive(); //Read new packet id + // parse player id and other stuff + PlayerID playerID = packet.ReadPrimitive(); + // Do something here? + boost::asio::ip::udp::endpoint endpoint(m_Address, m_Port); + m_ConnectedPlayers.at(playerID).Endpoint = endpoint; + LOG_INFO("parseUDPConnect: Spectator \"%s\" connected on IP: %s", m_ConnectedPlayers.at(playerID).Name.c_str(), m_ConnectedPlayers.at(playerID).Endpoint.address().to_string().c_str()); + // Send a message to the player that connected + Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID); + m_Unreliable.Send(connnectPacket); + LOG_INFO("UDP Connect sent to client"); +} + +void Server::parseTCPConnect(Packet & packet) +{ + // Pop size of message int + packet.ReadPrimitive(); + int messageType = packet.ReadPrimitive(); + // Read packet ID + m_PreviousPacketID = m_PacketID; // Set previous packet id + m_PacketID = packet.ReadPrimitive(); //Read new packet id + LOG_INFO("Parsing connections"); // Check if player is already connected - if (GetPlayerIDFromEndpoint() != -1) { + // Ska vara till lagd i TCPServer receive + PlayerID playerID = GetPlayerIDFromEndpoint(); + if (playerID == -1) { return; } // Create a new player - pd.EntityID = 0; // Overlook this - pd.Address = pd.Endpoint.address(); - pd.Port = pd.Endpoint.port(); - pd.Name = packet.ReadString(); - pd.PacketID = 0; - pd.StopTime = std::clock(); - m_ConnectedPlayers[m_NextPlayerID++] = pd; - LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str()); + 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(); + m_ConnectedPlayers.at(playerID).TCPAddress = m_Address; + m_ConnectedPlayers.at(playerID).TCPPort = m_Port; + + LOG_INFO("parseTCPConnect: Spectator \"%s\" connected on IP: %s", m_ConnectedPlayers.at(playerID).Name.c_str(), + m_ConnectedPlayers.at(playerID).TCPAddress); // Send a message to the player that connected - Packet connnectPacket(MessageType::Connect, pd.PacketID); - m_UDPServer.Send(connnectPacket); + Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID); + // Write playerID to packet + connnectPacket.WritePrimitive(playerID); + m_Reliable.Send(connnectPacket); // Send notification that a player has connected - Packet notificationPacket(MessageType::PlayerConnected); - broadcast(notificationPacket); + //Packet notificationPacket(MessageType::PlayerConnected); + //broadcast(notificationPacket); } -// -//void Server::parseTCPConnect(Packet & packet) -//{ -// LOG_INFO("Parsing connections"); -// // Check if player is already connected -// PlayerID playerID = GetPlayerIDFromEndpoint(); -// if (playerID = -1) { -// return; -// } -// // 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()); -// -// // Send a message to the player that connected -// Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID); -// m_TCPServer.Send(connnectPacket); -// -// // Send notification that a player has connected -// Packet notificationPacket(MessageType::PlayerConnected); -// //broadcast(notificationPacket); -//} 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) { + if (kv.second.TCPAddress == m_Address && + kv.second.TCPPort == m_Port) { disconnect(kv.first); break; } @@ -311,7 +327,7 @@ void Server::kick(PlayerID player) { disconnect(player); Packet packet = Packet(MessageType::Kick); - m_UDPServer.Send(packet); + m_Reliable.Send(packet); } bool Server::OnInputCommand(const Events::InputCommand & e) @@ -340,7 +356,7 @@ bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e) packet.WritePrimitive(e.Spawner.ID); // We don't send PlayerID here because it will always be set to -1 packet.WriteString(m_ConnectedPlayers[e.PlayerID].Name); - m_UDPServer.Send(packet, m_ConnectedPlayers[e.PlayerID]); + m_Reliable.Send(packet, m_ConnectedPlayers[e.PlayerID]); return false; } @@ -349,7 +365,7 @@ bool Server::OnEntityDeleted(const Events::EntityDeleted & e) if (!e.Cascaded) { Packet packet = Packet(MessageType::EntityDeleted); packet.WritePrimitive(e.DeletedEntity); - broadcast(packet); + reliableBroadcast(packet); } return false; } @@ -360,7 +376,7 @@ bool Server::OnComponentDeleted(const Events::ComponentDeleted & e) Packet packet = Packet(MessageType::ComponentDeleted); packet.WritePrimitive(e.Entity); packet.WriteString(e.ComponentType); - broadcast(packet); + reliableBroadcast(packet); } return false; } @@ -376,14 +392,14 @@ void Server::parseClientPing() // Return ping Packet packet(MessageType::Ping, m_ConnectedPlayers[player].PacketID); packet.WriteString("Ping received"); - m_UDPServer.Send(packet); + m_Reliable.Send(packet); } void Server::parsePing() { for (auto& kv : m_ConnectedPlayers) { - if (kv.second.Address == m_Address && - kv.second.Port == m_Port) { + if (kv.second.TCPAddress == m_Address && + kv.second.TCPPort == m_Port) { kv.second.StopTime = std::clock(); break; } @@ -430,9 +446,12 @@ void Server::parsePlayerTransform(Packet& packet) PlayerID Server::GetPlayerIDFromEndpoint() { + // check both tcp and udp connection for (auto& kv : m_ConnectedPlayers) { - if (kv.second.Address == m_Address && - kv.second.Port == m_Port) { + if ((kv.second.TCPAddress == m_Address + && kv.second.TCPPort == m_Port) + || (kv.second.Endpoint.address() == m_Address + && kv.second.Endpoint.port() == m_Port)) { return kv.first; } } diff --git a/src/Engine/Network/TCPServer.cpp b/src/Engine/Network/TCPServer.cpp index f8da15e2..0b44013d 100644 --- a/src/Engine/Network/TCPServer.cpp +++ b/src/Engine/Network/TCPServer.cpp @@ -23,8 +23,8 @@ PlayerID GetPlayerIDFromEndpoint(const std::map& con boost::asio::ip::address address, unsigned short port) { for (auto& kv : connectedPlayers) { - if (kv.second.Address == address && - kv.second.Port == port) { + if (kv.second.TCPAddress == address && + kv.second.TCPPort == port) { return kv.first; } } @@ -43,8 +43,8 @@ void TCPServer::handle_accept(boost::shared_ptr socket, PlayerDefinition pd; pd.StopTime = std::clock(); pd.TCPSocket = socket; - pd.Address = socket.get()->remote_endpoint().address(); - pd.Port = socket.get()->remote_endpoint().port(); + pd.TCPAddress = socket.get()->remote_endpoint().address(); + pd.TCPPort = socket.get()->remote_endpoint().port(); connectedPlayers[nextPlayerID++] = pd; } } @@ -78,6 +78,7 @@ void TCPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition) if (bytesRead > 0) { packet.ReconstructFromData(m_ReadBuffer, bytesRead); } + lastReceivedSocket = playerDefinition.TCPSocket; } int TCPServer::readBuffer(char* data, PlayerDefinition & playerDefinition) diff --git a/src/Engine/Network/UDPClient.cpp b/src/Engine/Network/UDPClient.cpp index e5eafc08..c76de084 100644 --- a/src/Engine/Network/UDPClient.cpp +++ b/src/Engine/Network/UDPClient.cpp @@ -18,10 +18,6 @@ void UDPClient::Connect(std::string playerName, std::string address, int port) m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); m_Socket = boost::shared_ptr(new boost::asio::ip::udp::socket(m_IOService)); m_Socket->connect(m_ReceiverEndpoint); - - Packet packet(MessageType::Connect, m_SendPacketID); - packet.WriteString(playerName); - Send(packet); } void UDPClient::Disconnect() diff --git a/src/Engine/Network/UDPServer.cpp b/src/Engine/Network/UDPServer.cpp index 6bf4e466..4b0a08ba 100644 --- a/src/Engine/Network/UDPServer.cpp +++ b/src/Engine/Network/UDPServer.cpp @@ -31,7 +31,6 @@ void UDPServer::Send(Packet & packet) 0); } - void UDPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition) { int bytesRead = readBuffer(m_ReadBuffer);