From 9f54a085366ffa15f9e4d37f8903fece1d17dcbc Mon Sep 17 00:00:00 2001 From: stiffly Date: Tue, 8 Dec 2015 17:57:01 +0100 Subject: [PATCH] Implemented new version of snapshot for 3D world. Also some cleanup. --- include/Engine/Network/Client.h | 14 +-- include/Engine/Network/PlayerDefinition.h | 4 +- src/Engine/Network/Client.cpp | 133 ++++++---------------- src/Engine/Network/Server.cpp | 11 +- src/Game/Game.cpp | 2 +- 5 files changed, 52 insertions(+), 112 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index b9c1abcc..eb606678 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -11,7 +11,9 @@ #include "Network/MessageType.h" #include "Network/NetworkDefines.h" +#include "Network/PlayerDefinition.h" #include "Network/WinLeakCheck.h" +#include "Core/World.h" #include "Core/EventBroker.h" #include "Core/EKeyDown.h" @@ -21,14 +23,12 @@ class Client public: Client(); ~Client(); - void Start(EventBroker* eventBroker); + void Start(World* world, EventBroker* eventBroker); void Close(); private: // Threaded - void DisplayLoop(); void ReadFromServer(); - void InputLoop(); int Receive(char* data, size_t length); int CreateMessage(MessageType type, std::string message, char* data); @@ -41,19 +41,19 @@ private: void ParsePing(); void ParseServerPing(); void ParseSnapshot(char* data, size_t length); - //void SendInput(); - void SendDebugInput(); - void DrawBoard(); + void CreateNewPlayer(int i); // udp stuff boost::asio::ip::udp::endpoint m_ReceiverEndpoint; boost::asio::io_service m_IOService; boost::asio::ip::udp::socket m_Socket; + World* m_World; int m_PlayerID = -1; char m_GameBoard[BOARDSIZE][BOARDSIZE]; glm::vec2 m_PlayerPositions[MAXCONNECTIONS]; - std::string m_PlayerNames[MAXCONNECTIONS]; + //std::string m_PlayerNames[MAXCONNECTIONS]; + PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS]; std::clock_t m_StartPingTime; double m_DurationOfPingTime; bool m_ShouldDrawGameBoard = true; diff --git a/include/Engine/Network/PlayerDefinition.h b/include/Engine/Network/PlayerDefinition.h index 19c2f341..b35ff463 100644 --- a/include/Engine/Network/PlayerDefinition.h +++ b/include/Engine/Network/PlayerDefinition.h @@ -3,8 +3,8 @@ #include struct PlayerDefinition { - unsigned int EntityID; - std::string Name; + unsigned int EntityID = -1; + std::string Name = ""; boost::asio::ip::udp::endpoint Endpoint; }; diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 9e9e6ed4..d22e4e7c 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -19,10 +19,11 @@ Client::~Client() _CrtDumpMemoryLeaks(); } -void Client::Start(EventBroker* eventBroker) +void Client::Start(World* world, EventBroker* eventBroker) { // Subscribe to events m_EventBroker = eventBroker; + m_World = world; m_EKeyDown = decltype(m_EKeyDown)(std::bind(&Client::OnKeyDown, this, std::placeholders::_1)); m_EventBroker->Subscribe(m_EKeyDown); std::cout << "Please enter you name: "; @@ -34,24 +35,10 @@ void Client::Start(EventBroker* eventBroker) boost::thread_group threads; - for (size_t i = 0; i < BOARDSIZE; i++) { - for (size_t j = 0; j < BOARDSIZE; j++) { - m_GameBoard[j][i] = ' '; - } - } - - for (size_t i = 0; i < MAXCONNECTIONS; i++) { - m_PlayerPositions[i].x = -1; - m_PlayerPositions[i].y = -1; - m_PlayerNames[i] = "X"; - } - m_Socket.connect(m_ReceiverEndpoint); std::cout << "I am client. BIP BOP\n"; - threads.create_thread(boost::bind(&Client::DisplayLoop, this)); threads.create_thread(boost::bind(&Client::ReadFromServer, this)); - //threads.create_thread(boost::bind(&Client::InputLoop, this)); threads.join_all(); } @@ -63,47 +50,6 @@ void Client::Close() m_Socket.close(); } -void Client::InputLoop() -{ - int intervallMs = 33; // ~30 times per second - int commandInterval = 200; // for commands like ping and connect, name might be ambigiuos - std::clock_t previousInputTime = std::clock(); - std::clock_t previousCommandTime = std::clock(); - - while (m_ThreadIsRunning) { - - std::clock_t currentTime = std::clock(); - int testTimeShit = (1000 * (currentTime - previousCommandTime) / (double)CLOCKS_PER_SEC); - if (commandInterval < (1000 * (currentTime - previousCommandTime) / (double)CLOCKS_PER_SEC)) { - SendDebugInput(); - previousCommandTime = currentTime; - } - - int testTimeShit2 = (1000 * (currentTime - previousInputTime) / (double)CLOCKS_PER_SEC); - if (intervallMs < (1000 * (currentTime - previousInputTime) / (double)CLOCKS_PER_SEC)) { - if (m_PlayerID != -1) { - //SendInput(); - } - previousInputTime = currentTime; - } - } -} - -void Client::DisplayLoop() -{ - while (m_ThreadIsRunning) { - // Update gameboard - for (size_t i = 0; i < BOARDSIZE; i++) { - for (size_t j = 0; j < BOARDSIZE; j++) { - m_GameBoard[j][i] = ' '; - } - } - if (m_ShouldDrawGameBoard) - //DrawBoard(); - boost::this_thread::sleep(boost::posix_time::millisec(100)); - } -} - void Client::ReadFromServer() { int bytesRead = -1; @@ -183,7 +129,7 @@ void Client::ParseEventMessage(char* data, size_t length) memcpy(&Id, data, sizeof(int)); MoveMessageHead(data, length, sizeof(int)); // Sett Player name - m_PlayerNames[Id] = command.erase(0, 7); + m_PlayerDefinitions[Id].Name = command.erase(0, 7); } else { std::cout << "Event message: " << std::string(data) << std::endl; @@ -196,40 +142,37 @@ void Client::ParseSnapshot(char* data, size_t length) { std::string tempName; for (size_t i = 0; i < MAXCONNECTIONS; i++) { - memcpy(&m_PlayerPositions[i].x, data, sizeof(float)); + // We're checking for empty name for now. This might not be the best way, + // but it is to avoid sending redundant data. + + // Read position data + glm::vec3 playerPos; + memcpy(&playerPos.x, data, sizeof(float)); MoveMessageHead(data, length, sizeof(float)); - memcpy(&m_PlayerPositions[i].y, data, sizeof(float)); + memcpy(&playerPos.y, data, sizeof(float)); MoveMessageHead(data, length, sizeof(float)); + memcpy(&playerPos.z, data, sizeof(float)); + MoveMessageHead(data, length, sizeof(float)); + tempName = std::string(data); - m_PlayerNames[i] = tempName; // +1 for null terminator MoveMessageHead(data, length, tempName.size() + 1); - } -} -void Client::DrawBoard() -{ - for (size_t i = 0; i < MAXCONNECTIONS; i++) { - if (m_PlayerPositions[i].x != -1 && m_PlayerPositions[i].y != -1) { - m_GameBoard[static_cast(m_PlayerPositions[i].x)][static_cast(m_PlayerPositions[i].y)] = m_PlayerNames[i][0]; + // Apply the position data read to the player entity + // New player connected on the server side + if (m_PlayerDefinitions[i].Name == "" && tempName != "") { + CreateNewPlayer(i); } - } - - system("cls"); - for (size_t i = 0; i < BOARDSIZE; i++) { - std::cout << '_'; - } - - std::cout << std::endl; - for (size_t i = 0; i < BOARDSIZE; i++) { - for (size_t j = 0; j < BOARDSIZE; j++) { - std::cout << m_GameBoard[j][i]; + else if (m_PlayerDefinitions[i].Name != "" && tempName == "") { + // Someone disconnected + // TODO: Insert code here } - std::cout << std::endl; - } - - for (size_t i = 0; i < BOARDSIZE; i++) { - std::cout << "^"; + else { + // Not a connected player + break; + } + m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform")["Position"] = playerPos; + m_PlayerDefinitions[i].Name = tempName; } } @@ -288,22 +231,6 @@ void Client::MoveMessageHead(char*& data, size_t& length, size_t stepSize) length -= stepSize; } -void Client::SendDebugInput() -{ - 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; -} - bool Client::OnKeyDown(const Events::KeyDown& event) { char* dataPackage = new char[INPUTSIZE]; // The package that will be sent to the server, when filled @@ -345,4 +272,12 @@ bool Client::OnKeyDown(const Events::KeyDown& event) memset(dataPackage, 0, INPUTSIZE); delete[] dataPackage; return true; +} + +void Client::CreateNewPlayer(int i) +{ + m_PlayerDefinitions[i].EntityID = m_World->CreateEntity(); + ComponentWrapper transform = m_World->AttachComponent(m_PlayerDefinitions[i].EntityID, "Transform"); + ComponentWrapper model = m_World->AttachComponent(m_PlayerDefinitions[i].EntityID, "Model"); + model["Resource"] = "Models/Core/UnitSphere.obj"; } \ No newline at end of file diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 1fb87cfa..718cb596 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -203,14 +203,19 @@ void Server::Broadcast(char * data, size_t length) void Server::SendSnapshot() { - char* data = new char[128]; + char* data = new char[INPUTSIZE]; int offset = CreateHeader(MessageType::Snapshot, data); for (size_t i = 0; i < MAXCONNECTIONS; i++) { - memcpy(data + offset, &m_PlayerPositions[i].x, sizeof(float)); + // 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, &m_PlayerPositions[i].y, 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); } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 36ef8877..d21e64ea 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -81,7 +81,7 @@ void Game::NetworkFunction() std::cout << "Start client or server? (c/s)" << std::endl; std::cin >> inputMessage; if (inputMessage == "c" || inputMessage == "C") { - m_Client.Start(m_EventBroker); + m_Client.Start(m_World, m_EventBroker); } if (inputMessage == "s" || inputMessage == "S") { m_Server.Start(m_World);