diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index ce71b1b1..24b59b59 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -25,25 +25,6 @@ public: void Update(); void Close(); private: - void ReadFromServer(); - void SendSnapshotToServer(); - - int Receive(char* data, size_t length); - void Send(Package& message); - void Connect(); - void Disconnect(); - void Ping(); - void MoveMessageHead(char*& data, size_t& length, size_t stepSize); - void ParseMessageType(Package& package); - void ParseEventMessage(Package& package); - void ParseConnect(Package& package); - void ParsePing(); - void ParseServerPing(); - void ParseSnapshot(Package& package); - void CreateNewPlayer(int i); - void IdentifyPacketLoss(); - bool IsConnected(); - // UDP logic boost::asio::ip::udp::endpoint m_ReceiverEndpoint; boost::asio::io_service m_IOService; @@ -75,6 +56,26 @@ private: EventBroker* m_EventBroker; EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand &e); + + void ReadFromServer(); + void SendSnapshotToServer(); + + int Receive(char* data, size_t length); + void Send(Package& message); + void Connect(); + void Disconnect(); + void Ping(); + void MoveMessageHead(char*& data, size_t& length, size_t stepSize); + void ParseMessageType(Package& package); + void ParseEventMessage(Package& package); + void ParseConnect(Package& package); + void ParsePing(); + void ParseServerPing(); + void ParseSnapshot(Package& package); + void CreateNewPlayer(int i); + void IdentifyPacketLoss(); + bool IsConnected(); + }; #endif diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 65a69bba..eb625b0d 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -4,8 +4,6 @@ #include #include -#include -#include #include #include "Network/MessageType.h" @@ -13,7 +11,6 @@ #include "Network/PlayerDefinition.h" #include "Core/World.h" #include "Core/EventBroker.h" -#include "Game/ECreatePlayer.h" #include "Network/Network.h" class Server : public Network @@ -26,32 +23,33 @@ public: void Close(); private: - // udp stuff + // UDP logic boost::asio::ip::udp::endpoint m_ReceiverEndpoint; boost::asio::io_service m_IOService; boost::asio::ip::udp::socket m_Socket; PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS]; + //Timers std::clock_t m_StartPingTime; std::clock_t m_StopTimes[8]; + // Game logic World* m_World; EventBroker* m_EventBroker; - // size = players to create, stores playerID + // size = ammount of players to create, stores playerID's std::vector m_PlayersToCreate; + // Packet loss logic unsigned int m_PacketID; unsigned int m_PreviousPacketID; unsigned int m_SendPacketID; + // Close logic bool m_ThreadIsRunning = true; - // Threaded - void DisplayLoop(); - void ReadFromClients(); - void InputLoop(); // Network functions int Receive(char* data, size_t length); + void ReadFromClients(); void Send(Package& package, int playerID); void Send(Package& package); void MoveMessageHead(char*& data, size_t& length, size_t stepSize); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index dd0a02bb..bc727e49 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -26,14 +26,15 @@ void Client::Start(World* world, EventBroker* eventBroker) // Subscribe to events m_EInputCommand = decltype(m_EInputCommand)(std::bind(&Client::OnInputCommand, this, std::placeholders::_1)); m_EventBroker->Subscribe(m_EInputCommand); - std::cout << "Please enter you name: "; + + LOG_INFO("Please enter your name: "); std::cin >> m_PlayerName; while (m_PlayerName.size() > 7) { - std::cout << "Please enter you name(No longer than 7 characters): "; + LOG_INFO("Please enter your name (No longer than 7 characters):"); std::cin >> m_PlayerName; } m_Socket.connect(m_ReceiverEndpoint); - std::cout << "I am client. BIP BOP\n"; + LOG_INFO("I am client. BIP BOP"); ReadFromServer(); } @@ -170,13 +171,13 @@ void Client::ParseMessageType(Package& package) void Client::ParseConnect(Package& package) { m_PlayerID = package.PopFrontPrimitive(); - std::cout << m_PacketID << ": I am player: " << m_PlayerID << std::endl; + LOG_INFO("%i: I am player: %i", m_PacketID, m_PlayerID); } void Client::ParsePing() { m_DurationOfPingTime = 1000 * (std::clock() - m_StartPingTime) / static_cast(CLOCKS_PER_SEC); - std::cout << m_PacketID << ": response time with ctime(ms): " << m_DurationOfPingTime << std::endl; + LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime); } void Client::ParseServerPing() @@ -184,7 +185,6 @@ void Client::ParseServerPing() Package message(MessageType::ServerPing, m_SendPacketID); message.AddString("Ping recieved"); Send(message); - //std::cout << "Parsing ping." << std::endl; } void Client::ParseEventMessage(Package& package) @@ -196,13 +196,12 @@ void Client::ParseEventMessage(Package& package) // Sett Player name m_PlayerDefinitions[Id].Name = command.erase(0, 7); } else { - std::cout << m_PacketID << ": Event message: " << command << std::endl; + LOG_INFO("%i: Event message: %s", m_PacketID, command); } } void Client::ParseSnapshot(Package& package) { - //std::cout << m_PacketID << ": Parsing incoming snapshot." << std::endl; std::string tempName; for (size_t i = 0; i < MAXCONNECTIONS; i++) { // We're checking for empty name for now. This might not be the best way, @@ -224,16 +223,8 @@ void Client::ParseSnapshot(Package& package) break; } if (m_PlayerDefinitions[i].EntityID != -1) { - // Read position data - //glm::vec3 playerPos; - //playerPos.x = package.PopFrontPrimitive(); - //playerPos.y = package.PopFrontPrimitive(); - //playerPos.z = package.PopFrontPrimitive(); - - // Move player to server position - //m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform")["Position"] = playerPos; int dataSize = m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform").Info.Meta.Stride; memcpy(m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform").Data, package.PopData(dataSize), dataSize); } @@ -250,7 +241,7 @@ int Client::Receive(char* data, size_t length) 0, error); if (error) { - std::cout << "ReadFromServer crashed: " << error.message(); + LOG_ERROR("ReadFromServer: %s", error.message()); } return bytesReceived; @@ -295,13 +286,15 @@ void Client::MoveMessageHead(char*& data, size_t& length, size_t stepSize) bool Client::OnInputCommand(const Events::InputCommand & e) { - if (m_PlayerID != -1) { + if (IsConnected()) { ComponentWrapper& player = m_World->GetComponent(m_PlayerDefinitions[m_PlayerID].EntityID, "Player"); if (e.Command == "Forward") { if (e.Value > 0) { (bool&)player["Forward"] = true; + (bool&)player["Back"] = false; } else if (e.Value < 0) { (bool&)player["Back"] = true; + (bool&)player["Forward"] = false; } else { (bool&)player["Forward"] = false; (bool&)player["Back"] = false; @@ -310,8 +303,10 @@ bool Client::OnInputCommand(const Events::InputCommand & e) if (e.Command == "Right") { if (e.Value > 0) { (bool&)player["Right"] = true; + (bool&)player["Left"] = false; } else if (e.Value < 0) { (bool&)player["Left"] = true; + (bool&)player["Right"] = false; } else { (bool&)player["Left"] = false; (bool&)player["Right"] = false; diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index d1d0c4c7..e66c0680 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -14,15 +14,9 @@ void Server::Start(World* world, EventBroker* eventBroker) for (size_t i = 0; i < MAXCONNECTIONS; i++) { m_StopTimes[i] = std::clock(); } - boost::thread_group threads; + LOG_INFO("I am Server. BIP BOP\n"); - std::cout << "I am Server. BIP BOP\n"; - - threads.create_thread(boost::bind(&Server::DisplayLoop, this)); - threads.create_thread(boost::bind(&Server::ReadFromClients, this)); - threads.create_thread(boost::bind(&Server::InputLoop, this)); - - threads.join_all(); + ReadFromClients(); } void Server::Update() @@ -46,45 +40,35 @@ void Server::Close() m_ThreadIsRunning = false; } -void Server::DisplayLoop() -{ - -} - void Server::ReadFromClients() { - char readBuf[1024] = { 0 }; + char readBuffer[1024] = { 0 }; int bytesRead = 0; // time for previouse message std::clock_t previousePingMessage = std::clock(); std::clock_t previousSnapshotMessage = std::clock(); std::clock_t timOutTimer = std::clock(); // How often we send messages (milliseconds) - int intervallMs = 1000; + int intervalMs = 1000; int snapshotInterval = 50; - int timeToCheckTimeOutTime = 100; + int checkTimeOutInterval = 100; while (m_ThreadIsRunning) { // m_ThreadIsRunning might be unnecessary but the // program crashed if it executed m_Socket.available() // when closing the program. - // If available message -> Socket.available() = true if (m_ThreadIsRunning && m_Socket.available()) { try { - bytesRead = Receive(readBuf, INPUTSIZE); - Package package(readBuf, bytesRead); + bytesRead = Receive(readBuffer, INPUTSIZE); + Package package(readBuffer, bytesRead); ParseMessageType(package); } catch (const std::exception& err) { - // To not spam "socket closed messages" - //if (std::string(err.what()).find("forcefully closed") != std::string::npos) { - std::cout << m_PacketID << ": Read from client crashed: " << err.what(); - //} + LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what()); } } std::clock_t currentTime = std::clock(); - // int tempTestRemovePlz = (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC); // Send snapshot if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { SendSnapshot(); @@ -92,44 +76,19 @@ void Server::ReadFromClients() } // Send pings each - if (intervallMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { + if (intervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { SendPing(); previousePingMessage = currentTime; } // Time out logic - if (timeToCheckTimeOutTime < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { + if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { CheckForTimeOuts(); timOutTimer = currentTime; } } } -void Server::InputLoop() -{ - char inputBuffer[INPUTSIZE] = { 0 }; - std::string inputMessage; - - while (m_ThreadIsRunning) { - std::cin.getline(inputBuffer, INPUTSIZE); - inputMessage = (std::string)inputBuffer; - - if (!inputMessage.empty()) { - try { - // Broadcast message typed in console - Broadcast(inputMessage); - - } catch (const std::exception& err) { - std::cout << m_PacketID << ": Read from WriteLoop crashed: " << err.what(); - } - } - if (inputMessage.find("exit") != std::string::npos) - exit(1); - inputMessage.clear(); - memset(inputBuffer, 0, INPUTSIZE); - } -} - void Server::ParseMessageType(Package& package) { int messageType = package.PopFrontPrimitive(); // Read what type off message was sent from server @@ -137,7 +96,7 @@ void Server::ParseMessageType(Package& package) // Read packet ID m_PreviousPacketID = m_PacketID; // Set previous packet id m_PacketID = package.PopFrontPrimitive(); //Read new packet id - //IdentifyPacketLoss(); + IdentifyPacketLoss(); switch (static_cast(messageType)) { case MessageType::Connect: ParseConnect(package); @@ -221,22 +180,16 @@ void Server::SendSnapshot() { Package package(MessageType::Snapshot, m_SendPacketID); for (size_t i = 0; i < MAXCONNECTIONS; i++) { - + // Send an empty name if there is no player connected on this position. package.AddString(m_PlayerDefinitions[i].Name); 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"]; - ////glm::vec3 playerPos = glm::vec3(1.0f); - //package.AddPrimitive(playerPos.x); - //package.AddPrimitive(playerPos.y); - //package.AddPrimitive(playerPos.z); + // Pack transfrom component into data package auto transform = m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform"); - package.AddData(transform.Data, transform.Info.Meta.Stride); + package.AddData(transform.Data, transform.Info.Meta.Stride); } Broadcast(package); } @@ -245,9 +198,10 @@ void Server::SendPing() { // Prints connected players ping for (size_t i = 0; i < MAXCONNECTIONS; i++) { - if (m_PlayerDefinitions[i].Endpoint.address() != boost::asio::ip::address()) - std::cout << m_PacketID << ": Player " << i << "'s ping: " << 1000 * (m_StopTimes[i] - m_StartPingTime) - / static_cast(CLOCKS_PER_SEC) << std::endl; + if (m_PlayerDefinitions[i].Endpoint.address() != boost::asio::ip::address()) { + int ping = 1000 * (m_StopTimes[i] - m_StartPingTime) / static_cast(CLOCKS_PER_SEC); + LOG_INFO("%i: Player %i's ping: %i", m_PacketID, i, ping); + } } // Create ping message @@ -262,15 +216,15 @@ void Server::SendPing() void Server::CheckForTimeOuts() { int timeOutTimeMs = 5000; - int tempStartPing = 1000 * m_StartPingTime + int startPing = 1000 * m_StartPingTime / static_cast(CLOCKS_PER_SEC); for (size_t i = 0; i < MAXCONNECTIONS; i++) { if (m_PlayerDefinitions[i].Endpoint.address() != boost::asio::ip::address()) { - int tempStopPing = 1000 * m_StopTimes[i] + int stopPing = 1000 * m_StopTimes[i] / static_cast(CLOCKS_PER_SEC); - if (tempStartPing > tempStopPing + timeOutTimeMs) { - std::cout << "player " << i << " timed out!" << std::endl; + if (startPing > stopPing + timeOutTimeMs) { + LOG_INFO("Player %i timed out!", i); Disconnect(i); } } @@ -280,7 +234,7 @@ void Server::CheckForTimeOuts() void Server::Disconnect(int i) { Broadcast("A player disconnected"); - std::cout << "Player " << i << " disconnected/Timed out" << std::endl; + LOG_INFO("Player %i disconnected/timed out", i); // Remove enteties and stuff m_PlayerDefinitions[i].Endpoint = boost::asio::ip::udp::endpoint(); @@ -326,7 +280,7 @@ void Server::ParseEvent(Package& package) void Server::ParseConnect(Package& package) { - std::cout << "Parsing connection." << std::endl; + LOG_INFO("Parsing connections"); // Check if player is already connected for (int i = 0; i < MAXCONNECTIONS; i++) { if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address()) { @@ -336,13 +290,6 @@ void Server::ParseConnect(Package& package) for (int i = 0; i < MAXCONNECTIONS; i++) { if (m_PlayerDefinitions[i].Endpoint.address() == boost::asio::ip::address()) { - - //Events::CreatePlayer e; - //e.entityID = (m_PlayerDefinitions[i].EntityID); - //e.modelPath = "Models/Core/UnitSphere.obj"; - //e.world = m_World; - //m_EventBroker->Publish(e); - // Create new player m_PlayersToCreate.push_back(i); @@ -351,8 +298,7 @@ void Server::ParseConnect(Package& package) 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; + LOG_INFO("Player \"%s\" connected on IP: %s", m_PlayerDefinitions[i].Name, m_PlayerDefinitions[i].Endpoint.address().to_string()); Package package(MessageType::Connect, m_SendPacketID); package.AddPrimitive(i); // Player ID @@ -370,7 +316,7 @@ void Server::ParseConnect(Package& package) void Server::ParseDisconnect() { - std::cout << m_PacketID << ":Parsing disconnect. \n"; + LOG_INFO("%i: Parsing disconnect", m_PacketID); for (int i = 0; i < MAXCONNECTIONS; i++) { if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address()) { @@ -382,7 +328,7 @@ void Server::ParseDisconnect() void Server::ParseClientPing() { - std::cout << m_PacketID << ":Parsing ping." << std::endl; + LOG_INFO("%i: Parsing ping", m_PacketID); // Return ping Package package(MessageType::ClientPing, m_SendPacketID); package.AddString("Ping received"); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 6080b8f5..5f583f31 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -137,7 +137,7 @@ void Game::debugTick(double dt) void Game::NetworkFunction() { std::string inputMessage; - std::cout << "Start client or server? (c/s)" << std::endl; + LOG_INFO("Start client or server? (c/s)"); std::cin >> inputMessage; if (inputMessage == "c" || inputMessage == "C") { m_IsClientOrServer = true;