diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 61fa5ff0..4a16034b 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -39,14 +39,14 @@ private: char readBuf[INPUTSIZE] = { 0 }; // Packet loss logic - unsigned int m_PacketID = 0; - unsigned int m_PreviousPacketID = 0; - unsigned int m_SendPacketID = 0; + PacketID m_PacketID = 0; + PacketID m_PreviousPacketID = 0; + PacketID m_SendPacketID = 0; // Game logic World* m_World; std::string m_PlayerName; - int m_PlayerID = -1; + PlayerID m_PlayerID = -1; EntityID m_ServerEntityID = std::numeric_limits::max(); bool m_IsConnected = false; // Server Client Lookup map @@ -76,6 +76,7 @@ private: void parseConnect(Packet& packet); void parsePlayerConnected(Packet& packet); void parsePing(); + void parseKick(); void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void parseSnapshot(Packet& packet); void identifyPacketLoss(); diff --git a/include/Engine/Network/MessageType.h b/include/Engine/Network/MessageType.h index 8468f2fc..7d8094de 100644 --- a/include/Engine/Network/MessageType.h +++ b/include/Engine/Network/MessageType.h @@ -13,7 +13,8 @@ enum class MessageType OnInputCommand, OnPlayerDamage, PlayerConnected, - BecomePlayer + BecomePlayer, + Kick }; #endif diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 73cb01d3..480ac602 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -13,6 +13,9 @@ #include #define INPUTSIZE 4097 +typedef unsigned int PlayerID; +typedef unsigned int PacketID; +typedef unsigned int UserID; class Network { diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index f1b5691a..cbad08b0 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -51,19 +51,19 @@ private: EventBroker* m_EventBroker; // Packet loss logic - unsigned int m_PacketID = 0; - unsigned int m_PreviousPacketID = 0; + PacketID m_PacketID = 0; + PacketID m_PreviousPacketID = 0; // Private member functions int receive(char* data); void readFromClients(); - void send(Packet& packet, int playerID); + void send(Packet& packet, UserID user); void send(Packet& packet); void broadcast(Packet& packet); void sendSnapshot(); void sendPing(); void checkForTimeOuts(); - void disconnect(int i); + void disconnect(UserID user); void parseMessageType(Packet& packet); void parseOnInputCommand(Packet& packet); void parseOnPlayerDamage(Packet& packet); @@ -73,7 +73,8 @@ private: void parsePing(); void identifyPacketLoss(); void createPlayer(); - int GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); + void kick(PlayerID player); + PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); // Debug event EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand& e); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index fe552fa2..129e0b42 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -89,6 +89,9 @@ void Client::parseMessageType(Packet& packet) break; case MessageType::PlayerConnected: parsePlayerConnected(packet); + case MessageType::Kick: + parseKick(); + break; default: break; } @@ -120,6 +123,12 @@ void Client::parsePing() send(packet); } +void Client::parseKick() +{ + LOG_WARNING("You have been kicked from the server."); + m_IsConnected = false; +} + // Fields with strings will not work right now void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType) { diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 719ca16f..03b9775a 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -118,11 +118,11 @@ int Server::receive(char * data) return length; } -void Server::send(Packet& packet, int userID) +void Server::send(Packet& packet, UserID user) { int bytesSent = m_Socket.send_to( boost::asio::buffer(packet.Data(), packet.Size()), - m_ConnectedUsers[userID].Endpoint, + m_ConnectedUsers[user].Endpoint, 0); // Network Debug data if (isReadingData) { @@ -224,40 +224,40 @@ void Server::checkForTimeOuts() } } -void Server::disconnect(int i) +void Server::disconnect(UserID user) { //broadcast("A player disconnected"); - LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[i].Name.c_str()); + LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[user].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_PlayerDefinitions[i].EntityID; - e.PlayerID = i; + e.Entity = m_PlayerDefinitions[user].EntityID; + e.PlayerID = user; m_EventBroker->Publish(e); - m_PlayerDefinitions[i].Endpoint = boost::asio::ip::udp::endpoint(); - m_PlayerDefinitions[i].EntityID = -1; - m_PlayerDefinitions[i].Name = ""; - m_PlayerDefinitions[i].PacketID = 0; - m_ConnectedUsers.erase(m_ConnectedUsers.begin() + i); + m_PlayerDefinitions[user].Endpoint = boost::asio::ip::udp::endpoint(); + m_PlayerDefinitions[user].EntityID = -1; + m_PlayerDefinitions[user].Name = ""; + m_PlayerDefinitions[user].PacketID = 0; + m_ConnectedUsers.erase(m_ConnectedUsers.begin() + user); } void Server::parseOnInputCommand(Packet& packet) { - int playerID = -1; + PlayerID player = -1; // Check which player it was who sent the message for (int i = 0; i < m_MaxConnections; i++) { // if the player is connected set playerID to the correct PlayerID if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address() && m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) { - playerID = i; + player = i; break; } } - if (playerID != -1) { + if (player != -1) { while (packet.DataReadSize() < packet.Size()) { Events::InputCommand e; e.Command = packet.ReadString(); - e.PlayerID = playerID; // Set correct player id + e.PlayerID = player; // Set correct player id 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); @@ -322,12 +322,12 @@ void Server::parseDisconnect() void Server::parseClientPing() { LOG_INFO("%i: Parsing ping", m_PacketID); - int playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint); - if (playerID == -1) { + PlayerID player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint); + if (player == -1) { return; } // Return ping - Packet packet(MessageType::Ping, m_PlayerDefinitions[playerID].PacketID); + Packet packet(MessageType::Ping, m_PlayerDefinitions[player].PacketID); packet.WriteString("Ping received"); send(packet); } @@ -358,7 +358,7 @@ void Server::createPlayer() LOG_WARNING("Already connected!"); return; } - int userIndex; + UserID userIndex; for (userIndex = 0; userIndex < m_ConnectedUsers.size(); userIndex++) { if (m_ConnectedUsers[userIndex].Endpoint.address() == m_ReceiverEndpoint.address() && m_ConnectedUsers[userIndex].Endpoint.port() == m_ReceiverEndpoint.port()) { @@ -370,7 +370,7 @@ void Server::createPlayer() LOG_WARNING("Not a recognized user!"); return; } - for (int playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) { + for (PlayerID playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) { if (m_PlayerDefinitions[playerIndex].Endpoint.address() == boost::asio::ip::address()) { m_PlayerDefinitions[playerIndex] = m_ConnectedUsers[userIndex]; EntityID entityID = m_World->CreateEntity(); @@ -388,7 +388,14 @@ void Server::createPlayer() } -int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) +void Server::kick(PlayerID player) +{ + disconnect(player); + Packet packet = Packet(MessageType::Kick); + send(packet); +} + +PlayerID Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) { for (int i = 0; i < m_MaxConnections; i++) { if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() && @@ -409,5 +416,9 @@ bool Server::OnInputCommand(const Events::InputCommand & e) isReadingData = !isReadingData; m_SaveDataTimer = std::clock(); } + if (e.Command == "KickPlayer" && e.Value > 0) { + kick(0); + } + return true; }