From e133791369e565c954b0aa690708d1838b211630 Mon Sep 17 00:00:00 2001 From: Jocke Date: Wed, 3 Feb 2016 10:28:15 +0100 Subject: [PATCH 01/43] WIP Reliable Message --- include/Engine/Network/Client.h | 2 +- include/Engine/Network/HybridClient.h | 14 ++++++++++++++ include/Engine/Network/TCPClient.h | 7 +++++++ include/Game/Game.h | 2 +- src/Engine/Network/HybridClient.cpp | 12 ++++++++++++ src/Engine/Network/Server.cpp | 2 +- src/Engine/Network/TCPClient.cpp | 0 src/Game/Game.cpp | 2 +- src/Tests/CollisionTest.cpp | 2 +- src/Tests/HealthSystemTest.cpp | 4 ++-- 10 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 include/Engine/Network/HybridClient.h create mode 100644 include/Engine/Network/TCPClient.h create mode 100644 src/Engine/Network/HybridClient.cpp create mode 100644 src/Engine/Network/TCPClient.cpp diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 4f1baa67..4397dd41 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -29,7 +29,7 @@ public: ~Client(); void Start(World* world, EventBroker* eventBroker) override; void Update() override; -private: +protected: // Assio UDP logic boost::asio::ip::udp::endpoint m_ReceiverEndpoint; boost::asio::io_service m_IOService; diff --git a/include/Engine/Network/HybridClient.h b/include/Engine/Network/HybridClient.h new file mode 100644 index 00000000..7573ad87 --- /dev/null +++ b/include/Engine/Network/HybridClient.h @@ -0,0 +1,14 @@ +#ifndef HybridClient_h__ +#define HybridClient_h__ + +#include "Client.h" + + +class HybridClient : public Client +{ +public: + HybridClient(ConfigFile* config); + ~HybridClient(); +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Network/TCPClient.h b/include/Engine/Network/TCPClient.h new file mode 100644 index 00000000..d342641b --- /dev/null +++ b/include/Engine/Network/TCPClient.h @@ -0,0 +1,7 @@ +#ifndef TCPClient_h__ +#define TCPClient_h__ + + + + +#endif \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index fab10a49..ccca080e 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -25,7 +25,7 @@ #include #include "Network/Network.h" #include "Network/Server.h" -#include "Network/Client.h" +#include "Network/HybridClient.h" // Sound #include "Sound/SoundSystem.h" diff --git a/src/Engine/Network/HybridClient.cpp b/src/Engine/Network/HybridClient.cpp new file mode 100644 index 00000000..798ff578 --- /dev/null +++ b/src/Engine/Network/HybridClient.cpp @@ -0,0 +1,12 @@ +#include "Network/HybridClient.h" + + +HybridClient::HybridClient(ConfigFile * config) : Client(config) +{ + +} + +HybridClient::~HybridClient() +{ + +} diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 30676d80..a94acd39 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -271,7 +271,7 @@ void Server::parseOnInputCommand(Packet& packet) 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); + LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); } } } diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index ef51aca6..7ce66710 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -169,7 +169,7 @@ void Game::networkFunction() bool isServer = m_Config->Get("Networking.IsServer", false); if (!isServer) { m_IsClientOrServer = true; - m_ClientOrServer = new Client(m_Config); + m_ClientOrServer = new HybridClient(m_Config); } if (isServer) { m_IsClientOrServer = true; diff --git a/src/Tests/CollisionTest.cpp b/src/Tests/CollisionTest.cpp index 67b6ce19..6cb6c88b 100644 --- a/src/Tests/CollisionTest.cpp +++ b/src/Tests/CollisionTest.cpp @@ -29,7 +29,7 @@ void RayTest(std::string fileName) { Ray ray(glm::vec3(-50, 0, 0), glm::vec3(1, 0, 0)); //using a - here, else we have to init the renderingsystem + //here, else we have to init the renderingsystem ResourceManager::RegisterType("RawModel"); auto unitBox = ResourceManager::Load(fileName); BOOST_REQUIRE(unitBox != nullptr); diff --git a/src/Tests/HealthSystemTest.cpp b/src/Tests/HealthSystemTest.cpp index bdd9ba4b..6540c0e3 100644 --- a/src/Tests/HealthSystemTest.cpp +++ b/src/Tests/HealthSystemTest.cpp @@ -69,8 +69,8 @@ GameHealthSystemTest::GameHealthSystemTest() m_EventBroker->Publish(e3); //damage player with 50 Events::PlayerDamage e; - e.DamageAmount = 50.0f; - e.PlayerDamagedID = healthsID; + // e.DamageAmount = 50.0f; +// e.PlayerDamagedID = healthsID; m_EventBroker->Publish(e); //heal some other player with 40 Events::PlayerHealthPickup e2; From 9232b24a7be77aec148c79309356af2da75bb214 Mon Sep 17 00:00:00 2001 From: Jocke Date: Thu, 4 Feb 2016 15:49:04 +0100 Subject: [PATCH 02/43] WIP Reliable message --- include/Engine/Network/Client.h | 13 +- include/Engine/Network/HybridClient.h | 10 ++ include/Engine/Network/HybridServer.h | 30 ++++ include/Engine/Network/PlayerDefinition.h | 3 + include/Engine/Network/Server.h | 35 ++-- include/Engine/Network/TCPClient.h | 16 ++ include/Engine/Network/TCPServer.h | 37 ++++ include/Game/Game.h | 4 +- src/Engine/Network/Client.cpp | 59 +----- src/Engine/Network/HybridClient.cpp | 56 +++++- src/Engine/Network/HybridServer.cpp | 203 +++++++++++++++++++++ src/Engine/Network/Server.cpp | 208 +--------------------- src/Engine/Network/TCPClient.cpp | 48 +++++ src/Engine/Network/TCPServer.cpp | 148 +++++++++++++++ src/Game/Game.cpp | 4 +- 15 files changed, 580 insertions(+), 294 deletions(-) create mode 100644 include/Engine/Network/HybridServer.h create mode 100644 include/Engine/Network/TCPServer.h create mode 100644 src/Engine/Network/HybridServer.cpp create mode 100644 src/Engine/Network/TCPServer.cpp diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 4397dd41..1c445cac 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -30,11 +30,9 @@ public: void Start(World* world, EventBroker* eventBroker) override; void Update() override; protected: - // Assio UDP logic - boost::asio::ip::udp::endpoint m_ReceiverEndpoint; - boost::asio::io_service m_IOService; - boost::asio::ip::udp::socket m_Socket; - + // Save for children + std::string address; + int port = 0; // Sending message to server logic int bytesRead = -1; char readBuf[INPUTSIZE] = { 0 }; @@ -68,9 +66,8 @@ protected: std::vector m_InputCommandBuffer; // Private member functions - void readFromServer(); - int receive(char* data); - void send(Packet& packet); + virtual void send(Packet& packet) = 0; + virtual void readFromServer() = 0; void connect(); void disconnect(); void parseMessageType(Packet& packet); diff --git a/include/Engine/Network/HybridClient.h b/include/Engine/Network/HybridClient.h index 7573ad87..8c9d1a68 100644 --- a/include/Engine/Network/HybridClient.h +++ b/include/Engine/Network/HybridClient.h @@ -9,6 +9,16 @@ class HybridClient : public Client public: HybridClient(ConfigFile* config); ~HybridClient(); + void Start(World* world, EventBroker* eventBroker); +private: + // Assio UDP logic + boost::asio::ip::udp::endpoint m_ReceiverEndpoint; + boost::asio::io_service m_IOService; + boost::asio::ip::udp::socket m_Socket; + + void readFromServer(); + int receive(char * data); + void send(Packet & packet); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/HybridServer.h b/include/Engine/Network/HybridServer.h new file mode 100644 index 00000000..95a9ffde --- /dev/null +++ b/include/Engine/Network/HybridServer.h @@ -0,0 +1,30 @@ +#ifndef HybridServer_h__ +#define HybridServer_h__ + +#include "Server.h" +#include + +class HybridServer : public Server +{ +public: + HybridServer(); + ~HybridServer(); +private: + // UDP logic + boost::asio::io_service m_IOService; + std::unique_ptr m_Socket; + + 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/PlayerDefinition.h b/include/Engine/Network/PlayerDefinition.h index 863948b3..3a3dd122 100644 --- a/include/Engine/Network/PlayerDefinition.h +++ b/include/Engine/Network/PlayerDefinition.h @@ -2,6 +2,7 @@ #define PlayerDefinition_h__ #include #include "../Core/Entity.h" +#include struct PlayerDefinition { ::EntityID EntityID = EntityID_Invalid; @@ -9,6 +10,8 @@ struct PlayerDefinition { boost::asio::ip::udp::endpoint Endpoint; unsigned int PacketID; std::clock_t StopTime; + // use for tcp connections + boost::shared_ptr TCPSocket; }; #endif diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 11f983a9..2926558f 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -5,7 +5,6 @@ #include #include -#include #include "Network/MessageType.h" #include "Network/PlayerDefinition.h" @@ -18,7 +17,6 @@ #include "Core/EPlayerSpawned.h" #include "Core/EEntityDeleted.h" #include "Core/EComponentDeleted.h" - class Server : public Network { public: @@ -26,12 +24,9 @@ public: ~Server(); void Start(World* m_world, EventBroker *eventBroker) override; void Update() override; -private: - // UDP logic - boost::asio::ip::udp::endpoint m_ReceiverEndpoint; - boost::asio::io_service m_IOService; - boost::asio::ip::udp::socket m_Socket; - +protected: + template + T m_ReceiverEndpoint; // Sending messages to client logic std::map m_ConnectedPlayers; // HACK: Fix INPUTSIZE @@ -41,12 +36,12 @@ private: 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 pingIntervalMs; int snapshotInterval; int checkTimeOutInterval = 100; int m_NextPlayerID = 0; - //Timers std::clock_t m_StartPingTime; @@ -59,10 +54,7 @@ private: PacketID m_PreviousPacketID = 0; // Private member functions - int receive(char* data); - void readFromClients(); - void send(PlayerID player, Packet& packet); - void send(Packet& packet); + //int receive(char* data); void broadcast(Packet& packet); void sendSnapshot(); void addChildrenToPacket(Packet& packet, EntityID entityID); @@ -70,15 +62,18 @@ private: void checkForTimeOuts(); void disconnect(PlayerID playerID); void parseMessageType(Packet& packet); - void parseOnInputCommand(Packet& packet); void parseOnPlayerDamage(Packet& packet); - void parseConnect(Packet& packet); - void parseDisconnect(); - void parseClientPing(); - void parsePing(); void identifyPacketLoss(); void kick(PlayerID player); - PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); + // 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); @@ -88,7 +83,7 @@ private: bool OnEntityDeleted(const Events::EntityDeleted& e); EventRelay m_EComponentDeleted; bool OnComponentDeleted(const Events::ComponentDeleted& e); - void parsePlayerTransform(Packet& packet); + virtual void parsePlayerTransform(Packet& packet) = 0; }; #endif diff --git a/include/Engine/Network/TCPClient.h b/include/Engine/Network/TCPClient.h index d342641b..14415eef 100644 --- a/include/Engine/Network/TCPClient.h +++ b/include/Engine/Network/TCPClient.h @@ -1,7 +1,23 @@ #ifndef TCPClient_h__ #define TCPClient_h__ +#include "Client.h" +class TCPClient : public Client +{ +public: + TCPClient(ConfigFile* config); + ~TCPClient(); + void Start(World* world, EventBroker* eventBroker); +private: + // Assio TCP logic + boost::asio::ip::tcp::endpoint m_Endpoint; + boost::asio::io_service m_IOService; + boost::shared_ptr m_Socket; + void readFromServer(); + int receive(char * data); + void send(Packet & packet); +}; #endif \ No newline at end of file diff --git a/include/Engine/Network/TCPServer.h b/include/Engine/Network/TCPServer.h new file mode 100644 index 00000000..23f6d666 --- /dev/null +++ b/include/Engine/Network/TCPServer.h @@ -0,0 +1,37 @@ +#ifndef TCPServer_h__ +#define TCPServer_h__ + +#include "Server.h" + +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/include/Game/Game.h b/include/Game/Game.h index 85d0190c..060f97f4 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -26,8 +26,10 @@ // Network #include #include "Network/Network.h" -#include "Network/Server.h" +#include "Network/HybridServer.h" #include "Network/HybridClient.h" +#include "Network/TCPClient.h" +#include "Network/TCPServer.h" // Sound #include "Sound/SoundSystem.h" diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 6c43cc8b..6f9519d5 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -1,9 +1,6 @@ #include "Network/Client.h" -using namespace boost::asio::ip; - - -Client::Client(ConfigFile* config) : m_Socket(m_IOService) +Client::Client(ConfigFile* config) { Network::initialize(); @@ -12,13 +9,11 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService) // Init timer m_TimeSinceSentInputs = std::clock(); // Default is local host - std::string address = config->Get("Networking.Address", "127.0.0.1"); - int port = config->Get("Networking.Port", 27666); - m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); + address = config->Get("Networking.Address", "127.0.0.1"); + port = config->Get("Networking.Port", 27666); // Set up network stream m_PlayerName = config->Get("Networking.Name", "Raptorcopter"); m_SendInputIntervalMs = config->Get("Networking.SendInputIntervalMs", 33); - } Client::~Client() @@ -33,8 +28,6 @@ void Client::Start(World* world, EventBroker* eventBroker) EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned); - - m_Socket.connect(m_ReceiverEndpoint); LOG_INFO("I am client. BIP BOP"); } @@ -54,17 +47,6 @@ void Client::Update() Network::Update(); } -void Client::readFromServer() -{ - while (m_Socket.available()) { - bytesRead = receive(readBuf); - if (bytesRead > 0) { - Packet packet(readBuf, bytesRead); - parseMessageType(packet); - } - } -} - void Client::parseMessageType(Packet& packet) { int messageType = packet.ReadPrimitive(); @@ -258,40 +240,6 @@ void Client::parseSnapshot(Packet& packet) } } -int Client::receive(char* data) -{ - boost::system::error_code error; - - int bytesReceived = m_Socket.receive_from(boost - ::asio::buffer((void*)data, INPUTSIZE), - m_ReceiverEndpoint, - 0, 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 Client::send(Packet& packet) -{ - m_Socket.send_to(boost::asio::buffer( - packet.Data(), - packet.Size()), - m_ReceiverEndpoint, 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - m_NetworkData.AmountOfMessagesSent++; - } -} - void Client::connect() { Packet packet(MessageType::Connect, m_SendPacketID); @@ -457,7 +405,6 @@ void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID client { m_ServerIDToClientID.insert(std::make_pair(serverEntityID, clientEntityID)); m_ClientIDToServerID.insert(std::make_pair(clientEntityID, serverEntityID)); - } void Client::deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID) diff --git a/src/Engine/Network/HybridClient.cpp b/src/Engine/Network/HybridClient.cpp index 798ff578..fd0b6649 100644 --- a/src/Engine/Network/HybridClient.cpp +++ b/src/Engine/Network/HybridClient.cpp @@ -1,12 +1,64 @@ #include "Network/HybridClient.h" +using namespace boost::asio::ip; -HybridClient::HybridClient(ConfigFile * config) : Client(config) +HybridClient::HybridClient(ConfigFile * config) : Client(config), m_Socket(m_IOService) { - + m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); } HybridClient::~HybridClient() { } + +void HybridClient::Start(World* world, EventBroker* eventBroker) +{ + Client::Start(world, eventBroker); + m_Socket.connect(m_ReceiverEndpoint); +} + +void HybridClient::readFromServer() +{ + while (m_Socket.available()) { + bytesRead = receive(readBuf); + if (bytesRead > 0) { + Packet packet(readBuf, bytesRead); + parseMessageType(packet); + } + } +} + +int HybridClient::receive(char* data) +{ + boost::system::error_code error; + + int bytesReceived = m_Socket.receive_from(boost + ::asio::buffer((void*)data, INPUTSIZE), + m_ReceiverEndpoint, + 0, 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 HybridClient::send(Packet& packet) +{ + m_Socket.send_to(boost::asio::buffer( + packet.Data(), + packet.Size()), + m_ReceiverEndpoint, 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } +} \ No newline at end of file diff --git a/src/Engine/Network/HybridServer.cpp b/src/Engine/Network/HybridServer.cpp new file mode 100644 index 00000000..e4142725 --- /dev/null +++ b/src/Engine/Network/HybridServer.cpp @@ -0,0 +1,203 @@ +#include "Network/HybridServer.h" + +HybridServer::HybridServer() +{ + m_Socket = std::unique_ptr(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666))); + +} + +HybridServer::~HybridServer() +{ } + + +void HybridServer::readFromClients() +{ + while (m_Socket->available()) { + try { + bytesRead = receive(readBuffer); + Packet packet(readBuffer, bytesRead); + parseMessageType(packet); + } catch (const std::exception& err) { + //LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what()); + } + } + std::clock_t currentTime = std::clock(); + // Send snapshot + if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { + sendSnapshot(); + previousSnapshotMessage = currentTime; + } + + // Send pings each + if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { + sendPing(); + previousePingMessage = currentTime; + } + + // Time out logic + if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { + checkForTimeOuts(); + timOutTimer = currentTime; + } +} + +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) { + return; + } + // Create a new player + PlayerDefinition pd; + pd.EntityID = 0; // Overlook this + pd.Endpoint = m_ReceiverEndpoint; + 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()); + + // Send a message to the player that connected + Packet connnectPacket(MessageType::Connect, pd.PacketID); + send(connnectPacket); + + // Send notification that a player has connected + Packet notificationPacket(MessageType::PlayerConnected); + 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 { + int bytesSent = m_Socket->send_to( + boost::asio::buffer(packet.Data(), packet.Size()), + playerDefinition.Endpoint, + 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } + } catch (const boost::system::system_error& e) { + // TODO: Clean up invalid endpoints out of m_ConnectedPlayers later + playerDefinition.Endpoint = boost::asio::ip::udp::endpoint(); + } +} +// Send back to endpoint of received packet +void HybridServer::send(Packet & packet) +{ + m_Socket->send_to( + boost::asio::buffer( + packet.Data(), + packet.Size()), + m_ReceiverEndpoint, + 0); + if (isReadingData) { + // Network Debug data + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + } +} + + +int HybridServer::receive(char * data) +{ + unsigned int length = m_Socket->receive_from( + boost::asio::buffer((void*)data + , INPUTSIZE) + , m_ReceiverEndpoint, 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataReceived += length; + m_NetworkData.DataReceivedThisInterval += length; + m_NetworkData.AmountOfMessagesReceived++; + } + 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/Server.cpp b/src/Engine/Network/Server.cpp index adf14413..37b2e752 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -1,19 +1,16 @@ #include "Network/Server.h" -Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666)) +Server::Server() { Network::initialize(); ConfigFile* config = ResourceManager::Load("Config.ini"); snapshotInterval = 1000 * config->Get("Networking.SnapshotInterval", 0.05); pingIntervalMs = config->Get("Networking.PingIntervalMs", 1000); - } - Server::~Server() { } - void Server::Start(World* world, EventBroker* eventBroker) { m_World = world; @@ -36,41 +33,9 @@ void Server::Update() } -void Server::readFromClients() -{ - while (m_Socket.available()) { - try { - bytesRead = receive(readBuffer); - Packet packet(readBuffer, bytesRead); - parseMessageType(packet); - } catch (const std::exception& err) { - //LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what()); - } - } - std::clock_t currentTime = std::clock(); - // Send snapshot - if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { - sendSnapshot(); - previousSnapshotMessage = currentTime; - } - - // Send pings each - if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { - sendPing(); - previousePingMessage = currentTime; - } - - // Time out logic - if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { - checkForTimeOuts(); - timOutTimer = currentTime; - } -} - void Server::parseMessageType(Packet& packet) { int messageType = packet.ReadPrimitive(); // Read what type off message was sent from server - // Read packet ID m_PreviousPacketID = m_PacketID; // Set previous packet id m_PacketID = packet.ReadPrimitive(); //Read new packet id @@ -103,60 +68,11 @@ void Server::parseMessageType(Packet& packet) } } -int Server::receive(char * data) -{ - unsigned int length = m_Socket.receive_from( - boost::asio::buffer((void*)data - , INPUTSIZE) - , m_ReceiverEndpoint, 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataReceived += length; - m_NetworkData.DataReceivedThisInterval += length; - m_NetworkData.AmountOfMessagesReceived++; - } - return length; -} - -void Server::send(PlayerID player, Packet& packet) -{ - try { - int bytesSent = m_Socket.send_to( - boost::asio::buffer(packet.Data(), packet.Size()), - m_ConnectedPlayers[player].Endpoint, - 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - m_NetworkData.AmountOfMessagesSent++; - } - } catch (const boost::system::system_error& e) { - // TODO: Clean up invalid endpoints out of m_ConnectedPlayers later - m_ConnectedPlayers[player].Endpoint = boost::asio::ip::udp::endpoint(); - } -} - -void Server::send(Packet & packet) -{ - m_Socket.send_to( - boost::asio::buffer( - packet.Data(), - packet.Size()), - m_ReceiverEndpoint, - 0); - if (isReadingData) { - // Network Debug data - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - } -} - void Server::broadcast(Packet& packet) { for (auto& kv : m_ConnectedPlayers) { packet.ChangePacketID(kv.second.PacketID); - send(kv.first, packet); + send(packet, kv.second); } } @@ -259,24 +175,6 @@ void Server::disconnect(PlayerID playerID) m_ConnectedPlayers.erase(playerID); } -void Server::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 Server::parseOnPlayerDamage(Packet & packet) { Events::PlayerDamage e; @@ -286,75 +184,6 @@ void Server::parseOnPlayerDamage(Packet & packet) //LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str()); } -void Server::parseConnect(Packet& packet) -{ - LOG_INFO("Parsing connections"); - // Check if player is already connected - if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) { - return; - } - for (auto& kv : m_ConnectedPlayers) { - if (kv.second.Endpoint.address() == m_ReceiverEndpoint.address() && - kv.second.Endpoint.port() == m_ReceiverEndpoint.port()) { - // Already connected - return; - } - } - // Create a new player - PlayerDefinition pd; - pd.EntityID = 0; // Overlook this - pd.Endpoint = m_ReceiverEndpoint; - 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()); - - // Send a message to the player that connected - Packet connnectPacket(MessageType::Connect, pd.PacketID); - 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.Endpoint.address() == m_ReceiverEndpoint.address() && - kv.second.Endpoint.port() == m_ReceiverEndpoint.port()) { - disconnect(kv.first); - break; - } - } -} - -void Server::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 Server::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 Server::identifyPacketLoss() { // if no packets lost, difference should be equal to 1 @@ -371,17 +200,6 @@ void Server::kick(PlayerID player) send(packet); } -PlayerID Server::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; -} - bool Server::OnInputCommand(const Events::InputCommand & e) { //LOG_DEBUG("Server::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); @@ -408,7 +226,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); - send(e.PlayerID, packet); + send(packet, m_ConnectedPlayers[e.PlayerID]); return false; } @@ -432,23 +250,3 @@ bool Server::OnComponentDeleted(const Events::ComponentDeleted & e) } return false; } - -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(m_ReceiverEndpoint); - EntityWrapper player(m_World, m_ConnectedPlayers.at(playerID).EntityID); - - if (player.Valid()) { - player["Transform"]["Position"] = position; - player["Transform"]["Orientation"] = orientation; - } -} diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp index e69de29b..d4909f56 100644 --- a/src/Engine/Network/TCPClient.cpp +++ b/src/Engine/Network/TCPClient.cpp @@ -0,0 +1,48 @@ +#include "Network/TCPClient.h" + +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)); +} + +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) { + m_Socket->close(); + m_Socket->connect(m_Endpoint,error); + LOG_INFO(error.message().c_str()); + } +} + +void TCPClient::readFromServer() +{ + +} + +int TCPClient::receive(char * data) +{ + return 0; +} + +void TCPClient::send(Packet & packet) +{ + m_Socket->send(boost::asio::buffer( + packet.Data(), + packet.Size())); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } +} diff --git a/src/Engine/Network/TCPServer.cpp b/src/Engine/Network/TCPServer.cpp new file mode 100644 index 00000000..930e7913 --- /dev/null +++ b/src/Engine/Network/TCPServer.cpp @@ -0,0 +1,148 @@ +#include "Network/TCPServer.h" +using namespace boost::asio::ip; + +TCPServer::TCPServer() +{ + acceptor = std::unique_ptr(new tcp::acceptor(m_IOService, tcp::endpoint(tcp::v4(), 27666))); +} + +TCPServer::~TCPServer() +{ + +} + +void TCPServer::Start(World* world, EventBroker* eventBroker) +{ + Server::Start(world, eventBroker); +} + +void TCPServer::readFromClients() +{ + acceptNewConnections(); + for (auto& kv : m_ConnectedPlayers) { + while (kv.second.TCPSocket->available()) { + try { + bytesRead = receive(readBuffer, *kv.second.TCPSocket); + lastReceivedSocket = kv.second.TCPSocket; + Packet packet(readBuffer, bytesRead); + parseMessageType(packet); + } catch (const std::exception& err) { + //LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what()); + } + } + } + + std::clock_t currentTime = std::clock(); + // Send snapshot + if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { + sendSnapshot(); + previousSnapshotMessage = currentTime; + } + + // Send pings each + if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { + sendPing(); + previousePingMessage = currentTime; + } + + // Time out logic + if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { + checkForTimeOuts(); + timOutTimer = currentTime; + } +} + +void TCPServer::acceptNewConnections() +{ + boost::shared_ptr newSocket = boost::shared_ptr(new tcp::socket(m_IOService)); + m_IOService.poll(); + acceptor->async_accept(*newSocket, + boost::bind(&TCPServer::handle_accept, this, newSocket, + boost::asio::placeholders::error)); +} + +void TCPServer::handle_accept(boost::shared_ptr socket, const boost::system::error_code& error) +{ + if (!error) { + // Add tcp socket to connections + PlayerDefinition pd; + pd.StopTime = std::clock(); + pd.TCPSocket = socket; + m_ConnectedPlayers[m_NextPlayerID++] = pd; + } +} +void TCPServer::parseClientPing() +{ + +} +void TCPServer::parsePing() +{ + +} +void TCPServer::parseDisconnect() +{ + +} +void TCPServer::parseConnect(Packet & packet) +{ + +} +void TCPServer::parseOnInputCommand(Packet & packet) +{ + +} +void TCPServer::parsePlayerTransform(Packet & packet) +{ + +} +void TCPServer::send(Packet & packet, PlayerDefinition & playerDefinition) +{ + try { + int bytesSent = playerDefinition.TCPSocket->send( + boost::asio::buffer(packet.Data(), packet.Size()), + 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } + } catch (const boost::system::system_error& e) { + // TODO: Clean up invalid endpoints out of m_ConnectedPlayers later + playerDefinition.Endpoint = boost::asio::ip::udp::endpoint(); + } +} + +void TCPServer::send(Packet & packet) +{ + lastReceivedSocket->send( + boost::asio::buffer( + packet.Data(), + packet.Size()), + 0); + if (isReadingData) { + // Network Debug data + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + } +} + +//boost::shared_ptr socket +int TCPServer::receive(char * data,boost::asio::ip::tcp::socket& socket) +{ + unsigned int length = socket.read_some( + boost::asio::buffer((void*)data, INPUTSIZE)); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataReceived += length; + m_NetworkData.DataReceivedThisInterval += length; + m_NetworkData.AmountOfMessagesReceived++; + } + return length; + +} + +PlayerID TCPServer::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) +{ + return PlayerID(); +} \ No newline at end of file diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index c26510ec..969fa46c 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -181,11 +181,11 @@ void Game::networkFunction() bool isServer = m_Config->Get("Networking.IsServer", false); if (!isServer) { m_IsClientOrServer = true; - m_ClientOrServer = new HybridClient(m_Config); + m_ClientOrServer = new TCPClient(m_Config); } if (isServer) { m_IsClientOrServer = true; - m_ClientOrServer = new Server(); + m_ClientOrServer = new TCPServer(); } m_ClientOrServer->Start(m_World, m_EventBroker); From 88d7b79cd32f60a91c12ec413cf99b31da453700 Mon Sep 17 00:00:00 2001 From: Jocke Date: Fri, 5 Feb 2016 18:30:31 +0100 Subject: [PATCH 03/43] TCP and UDP Client are working for 1 connected player, more players are not tested yet --- include/Engine/Network/Client.h | 4 +- include/Engine/Network/HybridClient.h | 1 + include/Engine/Network/HybridServer.h | 7 +- include/Engine/Network/Network.h | 2 +- include/Engine/Network/Packet.h | 2 + include/Engine/Network/PlayerDefinition.h | 2 + include/Engine/Network/Server.h | 18 ++-- include/Engine/Network/TCPClient.h | 1 + include/Engine/Network/TCPServer.h | 11 --- src/Engine/Network/Client.cpp | 16 ++-- src/Engine/Network/HybridClient.cpp | 14 ++- src/Engine/Network/HybridServer.cpp | 93 ++----------------- src/Engine/Network/Packet.cpp | 9 +- src/Engine/Network/Server.cpp | 103 ++++++++++++++++++++-- src/Engine/Network/TCPClient.cpp | 61 ++++++++++--- src/Engine/Network/TCPServer.cpp | 85 ++++++++++-------- src/Game/Game.cpp | 6 +- 17 files changed, 253 insertions(+), 182 deletions(-) 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); From ba9419b342918301fc1d521bd6ef9faa8b9fef69 Mon Sep 17 00:00:00 2001 From: Jocke Date: Mon, 8 Feb 2016 14:32:00 +0100 Subject: [PATCH 04/43] Moved UDP logic from Hybrid server/client to UDP server/client. fixed bug in Server::CheckForTimeOuts. --- include/Engine/Network/HybridClient.h | 16 +--- include/Engine/Network/HybridServer.h | 15 +--- include/Engine/Network/TCPClient.h | 3 +- include/Engine/Network/TCPServer.h | 6 +- include/Engine/Network/UDPClient.h | 24 +++++ include/Engine/Network/UDPServer.h | 25 ++++++ include/Game/Game.h | 5 ++ src/Engine/Network/Client.cpp | 3 +- src/Engine/Network/HybridClient.cpp | 66 +------------- src/Engine/Network/HybridServer.cpp | 117 +----------------------- src/Engine/Network/Server.cpp | 7 +- src/Engine/Network/TCPClient.cpp | 15 ++-- src/Engine/Network/TCPServer.cpp | 2 - src/Engine/Network/UDPClient.cpp | 66 ++++++++++++++ src/Engine/Network/UDPServer.cpp | 123 ++++++++++++++++++++++++++ src/Game/Game.cpp | 8 +- 16 files changed, 271 insertions(+), 230 deletions(-) create mode 100644 include/Engine/Network/UDPClient.h create mode 100644 include/Engine/Network/UDPServer.h create mode 100644 src/Engine/Network/UDPClient.cpp create mode 100644 src/Engine/Network/UDPServer.cpp diff --git a/include/Engine/Network/HybridClient.h b/include/Engine/Network/HybridClient.h index fb2777d4..8d96bf6e 100644 --- a/include/Engine/Network/HybridClient.h +++ b/include/Engine/Network/HybridClient.h @@ -1,25 +1,13 @@ #ifndef HybridClient_h__ #define HybridClient_h__ -#include "Client.h" - - -class HybridClient : public Client +class HybridClient { public: - HybridClient(ConfigFile* config); + HybridClient(); ~HybridClient(); - void Start(World* world, EventBroker* eventBroker); private: - // Assio UDP logic - boost::asio::ip::udp::endpoint m_ReceiverEndpoint; - 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); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/HybridServer.h b/include/Engine/Network/HybridServer.h index f12dc660..48d6fe63 100644 --- a/include/Engine/Network/HybridServer.h +++ b/include/Engine/Network/HybridServer.h @@ -1,25 +1,12 @@ #ifndef HybridServer_h__ #define HybridServer_h__ -#include "Server.h" -#include - -class HybridServer : public Server +class HybridServer { public: HybridServer(); ~HybridServer(); private: - // UDP logic - boost::asio::io_service m_IOService; - std::unique_ptr m_Socket; - boost::asio::ip::udp::endpoint m_ReceiverEndpoint; - - void readFromClients(); - void parseConnect(Packet & packet); - void send(Packet & packet, PlayerDefinition & playerDefinition); - void send(Packet & packet); - int receive(char * data); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/TCPClient.h b/include/Engine/Network/TCPClient.h index e90e049c..b16d541d 100644 --- a/include/Engine/Network/TCPClient.h +++ b/include/Engine/Network/TCPClient.h @@ -8,12 +8,11 @@ class TCPClient : public Client public: TCPClient(ConfigFile* config); ~TCPClient(); - void Start(World* world, EventBroker* eventBroker); private: // Assio TCP logic boost::asio::ip::tcp::endpoint m_Endpoint; boost::asio::io_service m_IOService; - boost::shared_ptr m_Socket; + std::unique_ptr m_Socket; void connect(); void readFromServer(); diff --git a/include/Engine/Network/TCPServer.h b/include/Engine/Network/TCPServer.h index 61e40639..6c52d10d 100644 --- a/include/Engine/Network/TCPServer.h +++ b/include/Engine/Network/TCPServer.h @@ -13,14 +13,14 @@ private: boost::asio::io_service m_IOService; std::unique_ptr acceptor; boost::shared_ptr lastReceivedSocket; - - void readFromClients(); + void acceptNewConnections(); void handle_accept(boost::shared_ptr socket, const boost::system::error_code & error); + void readFromClients(); + int receive(char * data, boost::asio::ip::tcp::socket& socket); void parseConnect(Packet & packet); void send(Packet & packet, PlayerDefinition & playerDefinition); void send(Packet & packet); - int receive(char * data, boost::asio::ip::tcp::socket& socket); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/UDPClient.h b/include/Engine/Network/UDPClient.h new file mode 100644 index 00000000..abe34b3a --- /dev/null +++ b/include/Engine/Network/UDPClient.h @@ -0,0 +1,24 @@ +#ifndef UDPClient_h__ +#define UDPClient_h__ + +#include "Client.h" + + +class UDPClient : public Client +{ +public: + UDPClient(ConfigFile* config); + ~UDPClient(); +private: + // Assio UDP logic + boost::asio::io_service m_IOService; + boost::asio::ip::udp::endpoint m_ReceiverEndpoint; + boost::asio::ip::udp::socket m_Socket; + + void connect(); + void readFromServer(); + int receive(char * data); + void send(Packet & packet); +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Network/UDPServer.h b/include/Engine/Network/UDPServer.h new file mode 100644 index 00000000..22c8c3e3 --- /dev/null +++ b/include/Engine/Network/UDPServer.h @@ -0,0 +1,25 @@ +#ifndef UDPServer_h__ +#define UDPServer_h__ + +#include "Server.h" +#include + +class UDPServer : public Server +{ +public: + UDPServer(); + ~UDPServer(); +private: + // UDP logic + boost::asio::io_service m_IOService; + boost::asio::ip::udp::endpoint m_ReceiverEndpoint; + std::unique_ptr m_Socket; + + void readFromClients(); + int receive(char * data); + void parseConnect(Packet & packet); + void send(Packet & packet, PlayerDefinition & playerDefinition); + void send(Packet & packet); +}; + +#endif \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index 060f97f4..4faf6bbf 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -26,10 +26,15 @@ // Network #include #include "Network/Network.h" +// Hybrid #include "Network/HybridServer.h" #include "Network/HybridClient.h" +// TCP #include "Network/TCPClient.h" #include "Network/TCPServer.h" +// UDP +#include "Network/UDPServer.h" +#include "Network/UDPClient.h" // Sound #include "Sound/SoundSystem.h" diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 13efad40..c7a8f0e6 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -17,7 +17,8 @@ Client::Client(ConfigFile* config) } Client::~Client() -{ } +{ +} void Client::Start(World* world, EventBroker* eventBroker) { diff --git a/src/Engine/Network/HybridClient.cpp b/src/Engine/Network/HybridClient.cpp index eabe109b..4200e8e3 100644 --- a/src/Engine/Network/HybridClient.cpp +++ b/src/Engine/Network/HybridClient.cpp @@ -1,72 +1,10 @@ #include "Network/HybridClient.h" -using namespace boost::asio::ip; -HybridClient::HybridClient(ConfigFile * config) : Client(config), m_Socket(m_IOService) -{ - m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); +HybridClient::HybridClient() +{ } HybridClient::~HybridClient() -{ - -} - -void HybridClient::Start(World* world, EventBroker* eventBroker) -{ - Client::Start(world, eventBroker); - m_Socket.connect(m_ReceiverEndpoint); -} - -void HybridClient::readFromServer() { - while (m_Socket.available()) { - bytesRead = receive(readBuffer); - if (bytesRead > 0) { - Packet packet(readBuffer, bytesRead); - parseMessageType(packet); - } - } -} - -int HybridClient::receive(char* data) -{ - boost::system::error_code error; - - int bytesReceived = m_Socket.receive_from(boost - ::asio::buffer((void*)data, BUFFERSIZE), - m_ReceiverEndpoint, - 0, 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 HybridClient::send(Packet& packet) -{ - m_Socket.send_to(boost::asio::buffer( - packet.Data(), - packet.Size()), - m_ReceiverEndpoint, 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataSent += packet.Size(); - 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 6c22bab7..bfcdaee0 100644 --- a/src/Engine/Network/HybridServer.cpp +++ b/src/Engine/Network/HybridServer.cpp @@ -2,123 +2,8 @@ HybridServer::HybridServer() { - m_Socket = std::unique_ptr(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666))); - } HybridServer::~HybridServer() -{ } - - -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) { - //LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what()); - } - } - std::clock_t currentTime = std::clock(); - // Send snapshot - if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { - sendSnapshot(); - previousSnapshotMessage = currentTime; - } - - // Send pings each - if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { - sendPing(); - previousePingMessage = currentTime; - } - - // Time out logic - if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { - checkForTimeOuts(); - timOutTimer = currentTime; - } -} - -void HybridServer::parseConnect(Packet& packet) -{ - LOG_INFO("Parsing connections"); - // Check if player is already connected - 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(); - m_ConnectedPlayers[m_NextPlayerID++] = pd; - LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str()); - - // Send a message to the player that connected - Packet connnectPacket(MessageType::Connect, pd.PacketID); - send(connnectPacket); - - // Send notification that a player has connected - Packet notificationPacket(MessageType::PlayerConnected); - broadcast(notificationPacket); -} - -void HybridServer::send(Packet& packet, PlayerDefinition & playerDefinition) -{ - try { - int bytesSent = m_Socket->send_to( - boost::asio::buffer(packet.Data(), packet.Size()), - playerDefinition.Endpoint, - 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - m_NetworkData.AmountOfMessagesSent++; - } - } catch (const boost::system::system_error& e) { - // TODO: Clean up invalid endpoints out of m_ConnectedPlayers later - playerDefinition.Endpoint = boost::asio::ip::udp::endpoint(); - } -} -// Send back to endpoint of received packet -void HybridServer::send(Packet & packet) -{ - m_Socket->send_to( - boost::asio::buffer( - packet.Data(), - packet.Size()), - m_ReceiverEndpoint, - 0); - if (isReadingData) { - // Network Debug data - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - } -} - - -int HybridServer::receive(char * data) -{ - unsigned int length = m_Socket->receive_from( - boost::asio::buffer((void*)data - , BUFFERSIZE) - , m_ReceiverEndpoint, 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataReceived += length; - m_NetworkData.DataReceivedThisInterval += length; - m_NetworkData.AmountOfMessagesReceived++; - } - return length; -} - - +} \ No newline at end of file diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 55f59a03..344efba6 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -9,7 +9,6 @@ Server::Server() } Server::~Server() { - } void Server::Start(World* world, EventBroker* eventBroker) { @@ -154,16 +153,20 @@ void Server::checkForTimeOuts() int startPing = 1000 * m_StartPingTime / static_cast(CLOCKS_PER_SEC); + std::vector playersToRemove; 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!", kv.second.Name); - disconnect(kv.first); + playersToRemove.push_back(kv.first); } } } + for (size_t i = 0; i < playersToRemove.size(); i++) { + disconnect(playersToRemove.at(i)); + } } void Server::parseDisconnect() diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp index 3d7261b7..545db491 100644 --- a/src/Engine/Network/TCPClient.cpp +++ b/src/Engine/Network/TCPClient.cpp @@ -5,7 +5,7 @@ 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_Endpoint)); + m_Socket = std::unique_ptr(new tcp::socket(m_IOService, m_Endpoint)); tcp::no_delay option(true); m_Socket->set_option(option); } @@ -15,10 +15,6 @@ TCPClient::~TCPClient() } -void TCPClient::Start(World * world, EventBroker * eventBroker) -{ - Client::Start(world, eventBroker); -} void TCPClient::connect() { if (!m_IsConnected) { @@ -34,7 +30,7 @@ void TCPClient::connect() } } } -// TODO FIX CRASH TCP CLIENT SEVER DISCONNECTS FIRST + void TCPClient::readFromServer() { while (m_Socket->available()) { @@ -50,14 +46,14 @@ int TCPClient::receive(char * data) // Read size of packet int bytesReceived = m_Socket->read_some(boost ::asio::buffer((void*)data, sizeof(int)), - error); + 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); + error); // Network Debug data if (isReadingData) { m_NetworkData.TotalDataReceived += bytesReceived; @@ -73,9 +69,10 @@ int TCPClient::receive(char * data) void TCPClient::send(Packet & packet) { packet.UpdateSize(); + boost::system::error_code error; m_Socket->send(boost::asio::buffer( packet.Data(), - packet.Size())); + packet.Size()), 0, error); // Network Debug data if (isReadingData) { m_NetworkData.TotalDataSent += packet.Size(); diff --git a/src/Engine/Network/TCPServer.cpp b/src/Engine/Network/TCPServer.cpp index caf37ee8..d523bf47 100644 --- a/src/Engine/Network/TCPServer.cpp +++ b/src/Engine/Network/TCPServer.cpp @@ -8,7 +8,6 @@ TCPServer::TCPServer() TCPServer::~TCPServer() { - } void TCPServer::readFromClients() @@ -135,7 +134,6 @@ void TCPServer::send(Packet & packet) } } -//boost::shared_ptr socket int TCPServer::receive(char * data, boost::asio::ip::tcp::socket& socket) { boost::system::error_code error; diff --git a/src/Engine/Network/UDPClient.cpp b/src/Engine/Network/UDPClient.cpp new file mode 100644 index 00000000..26e895d5 --- /dev/null +++ b/src/Engine/Network/UDPClient.cpp @@ -0,0 +1,66 @@ +#include "Network/UDPClient.h" + +using namespace boost::asio::ip; + +UDPClient::UDPClient(ConfigFile * config) : Client(config), m_Socket(m_IOService) +{ + m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); + m_Socket.connect(m_ReceiverEndpoint); +} + +UDPClient::~UDPClient() +{ +} + +void UDPClient::readFromServer() +{ + while (m_Socket.available()) { + bytesRead = receive(readBuffer); + if (bytesRead > 0) { + Packet packet(readBuffer, bytesRead); + parseMessageType(packet); + } + } +} + +int UDPClient::receive(char* data) +{ + boost::system::error_code error; + + int bytesReceived = m_Socket.receive_from(boost + ::asio::buffer((void*)data, BUFFERSIZE), + m_ReceiverEndpoint, + 0, 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 UDPClient::send(Packet& packet) +{ + m_Socket.send_to(boost::asio::buffer( + packet.Data(), + packet.Size()), + m_ReceiverEndpoint, 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } +} + +void UDPClient::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/UDPServer.cpp b/src/Engine/Network/UDPServer.cpp new file mode 100644 index 00000000..1e62c10a --- /dev/null +++ b/src/Engine/Network/UDPServer.cpp @@ -0,0 +1,123 @@ +#include "Network/UDPServer.h" + +UDPServer::UDPServer() +{ + m_Socket = std::unique_ptr(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666))); +} + +UDPServer::~UDPServer() +{ +} + +void UDPServer::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) { + //LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what()); + } + } + std::clock_t currentTime = std::clock(); + // Send snapshot + if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { + sendSnapshot(); + previousSnapshotMessage = currentTime; + } + + // Send pings each + if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { + sendPing(); + previousePingMessage = currentTime; + } + + // Time out logic + if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { + checkForTimeOuts(); + timOutTimer = currentTime; + } +} + +void UDPServer::parseConnect(Packet& packet) +{ + LOG_INFO("Parsing connections"); + // Check if player is already connected + 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(); + m_ConnectedPlayers[m_NextPlayerID++] = pd; + LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str()); + + // Send a message to the player that connected + Packet connnectPacket(MessageType::Connect, pd.PacketID); + send(connnectPacket); + + // Send notification that a player has connected + Packet notificationPacket(MessageType::PlayerConnected); + broadcast(notificationPacket); +} + +void UDPServer::send(Packet& packet, PlayerDefinition & playerDefinition) +{ + try { + int bytesSent = m_Socket->send_to( + boost::asio::buffer(packet.Data(), packet.Size()), + playerDefinition.Endpoint, + 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } + } catch (const boost::system::system_error& e) { + // TODO: Clean up invalid endpoints out of m_ConnectedPlayers later + playerDefinition.Endpoint = boost::asio::ip::udp::endpoint(); + } +} +// Send back to endpoint of received packet +void UDPServer::send(Packet & packet) +{ + m_Socket->send_to( + boost::asio::buffer( + packet.Data(), + packet.Size()), + m_ReceiverEndpoint, + 0); + if (isReadingData) { + // Network Debug data + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + } +} + + +int UDPServer::receive(char * data) +{ + unsigned int length = m_Socket->receive_from( + boost::asio::buffer((void*)data + , BUFFERSIZE) + , m_ReceiverEndpoint, 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataReceived += length; + m_NetworkData.DataReceivedThisInterval += length; + m_NetworkData.AmountOfMessagesReceived++; + } + return length; +} + + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index a2bde7cb..ccbf79c9 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -181,13 +181,15 @@ void Game::networkFunction() bool isServer = m_Config->Get("Networking.IsServer", false); if (!isServer) { m_IsClientOrServer = true; + m_ClientOrServer = new UDPClient(m_Config); //m_ClientOrServer = new TCPClient(m_Config); - m_ClientOrServer = new HybridClient(m_Config); + //m_ClientOrServer = new HybridClient(m_Config); } if (isServer) { m_IsClientOrServer = true; - //m_ClientOrServer = new TCPServer(); - m_ClientOrServer = new HybridServer(); + m_ClientOrServer = new UDPServer(); + // m_ClientOrServer = new TCPServer(); + //m_ClientOrServer = new HybridServer(); } m_ClientOrServer->Start(m_World, m_EventBroker); From fccd8c64e789803aab305203137da46e3af6871d Mon Sep 17 00:00:00 2001 From: Jocke Date: Tue, 9 Feb 2016 11:43:16 +0100 Subject: [PATCH 05/43] WIP Clients are working properly, servers are not. --- include/Engine/Network/Client.h | 11 ++-- include/Engine/Network/MessageType.h | 3 +- include/Engine/Network/Network.h | 2 + include/Engine/Network/NetworkClient.h | 21 ++++++++ include/Engine/Network/NetworkServer.h | 20 +++++++ include/Engine/Network/Packet.h | 5 ++ include/Engine/Network/TCPClient.h | 25 ++++++--- include/Engine/Network/UDPClient.h | 27 ++++++---- include/Game/Game.h | 4 ++ src/Engine/Network/Client.cpp | 33 +++++++----- src/Engine/Network/Network.cpp | 15 ++++++ src/Engine/Network/NetworkClient.cpp | 0 src/Engine/Network/Packet.cpp | 41 +++++++++++---- src/Engine/Network/Server.cpp | 21 ++++++-- src/Engine/Network/TCPClient.cpp | 66 ++++++++++++----------- src/Engine/Network/TCPServer.cpp | 24 +-------- src/Engine/Network/UDPClient.cpp | 72 ++++++++++++++------------ src/Engine/Network/UDPServer.cpp | 21 +------- src/Game/Game.cpp | 32 ++++++++---- 19 files changed, 277 insertions(+), 166 deletions(-) create mode 100644 include/Engine/Network/NetworkClient.h create mode 100644 include/Engine/Network/NetworkServer.h create mode 100644 src/Engine/Network/NetworkClient.cpp diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 5259504b..0c9608ff 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -13,6 +13,8 @@ #include "Network/Network.h" #include "Network/MessageType.h" #include "Network/PlayerDefinition.h" +#include "Network/UDPClient.h" +#include "Network/TCPClient.h" #include "Network/SnapshotDefinitions.h" #include "Core/World.h" #include "Core/EventBroker.h" @@ -35,7 +37,6 @@ protected: int port = 0; // Sending message to server logic int bytesRead = -1; - char readBuffer[BUFFERSIZE] = { 0 }; // Packet loss logic PacketID m_PacketID = 0; @@ -66,9 +67,6 @@ protected: std::vector m_InputCommandBuffer; // Private member functions - virtual void send(Packet& packet) = 0; - virtual void readFromServer() = 0; - virtual void connect() = 0; void disconnect(); void parseMessageType(Packet& packet); void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType); @@ -103,6 +101,11 @@ protected: bool OnPlayerDamage(const Events::PlayerDamage& e); EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(const Events::PlayerSpawned& e); + +private: + //UDPClient m_UDPClient; + //TCPClient m_TCPClient; + TCPClient m_UDPClient; }; #endif diff --git a/include/Engine/Network/MessageType.h b/include/Engine/Network/MessageType.h index 85f22649..a72f054e 100644 --- a/include/Engine/Network/MessageType.h +++ b/include/Engine/Network/MessageType.h @@ -18,7 +18,8 @@ enum class MessageType OnPlayerSpawned, EntityDeleted, ComponentDeleted, - PlayerTransform + PlayerTransform, + Invalid }; #endif diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index caf55f13..7f292b1a 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -30,6 +30,8 @@ protected: std::clock_t m_SaveDataTimer; unsigned int m_MaxConnections; unsigned int m_TimeoutMs; + void logSentData(int bytesSent); + void logReceivedData(int bytesReceived); void saveToFile(); void updateNetworkData(); void initialize(); diff --git a/include/Engine/Network/NetworkClient.h b/include/Engine/Network/NetworkClient.h new file mode 100644 index 00000000..4c623209 --- /dev/null +++ b/include/Engine/Network/NetworkClient.h @@ -0,0 +1,21 @@ +#ifndef NetworkClient_h__ +#define NetworkClient_h__ + +#include "Network/Packet.h" +#define BUFFERSIZE 32000 +typedef unsigned int PlayerID; +typedef unsigned int PacketID; + +class NetworkClient +{ +public: + virtual void Connect(std::string playerName, std::string address, int port) = 0; + virtual void Disconnect() = 0; + virtual void Receive(Packet& packet) = 0; + virtual void Send(Packet & packet) = 0; + virtual bool IsSocketAvailable() = 0; +protected: + char m_ReadBuffer[BUFFERSIZE] = { 0 }; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Network/NetworkServer.h b/include/Engine/Network/NetworkServer.h new file mode 100644 index 00000000..1586693d --- /dev/null +++ b/include/Engine/Network/NetworkServer.h @@ -0,0 +1,20 @@ +#ifndef NetworkServer_h__ +#define NetworkServer_h__ + +#include "Network/Packet.h" +#define BUFFERSIZE 32000 +typedef unsigned int PlayerID; +typedef unsigned int PacketID; + +class NetworkServer +{ +//public: +// virtual void Connect(std::string playerName, std::string address, int port) = 0; +// virtual void Disconnect() = 0; +// virtual Packet Receive() = 0; +// virtual void Send(Packet & packet) = 0; +//protected: +// char m_ReadBuffer[BUFFERSIZE] = { 0 }; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Network/Packet.h b/include/Engine/Network/Packet.h index b7e774c2..e88747b8 100644 --- a/include/Engine/Network/Packet.h +++ b/include/Engine/Network/Packet.h @@ -49,12 +49,15 @@ public: void WriteData(char* data, int sizeOfData); // Pops the first element as if it was a string. std::string ReadString(); + // Construct a packet + void ReconstructFromData(char* data, int SizeOfData); // Update size of packet variable in header void UpdateSize(); char* ReadData(int SizeOfData); void ChangePacketID(unsigned int& packetID); int Size() { return m_Offset; }; char* Data() { return m_Data; }; + MessageType GetMessageType() { return m_MessageType; }; unsigned int DataReadSize() { return m_ReturnDataOffset; } unsigned int MaxSize() { return m_MaxPacketSize; } unsigned int HeaderSize() { return m_HeaderSize; } @@ -65,7 +68,9 @@ private: int m_Offset = 0; unsigned int m_MaxPacketSize = 512; unsigned int m_HeaderSize = 0; + MessageType m_MessageType = MessageType::Invalid; void resizeData(); + void resizeData(int size); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/TCPClient.h b/include/Engine/Network/TCPClient.h index b16d541d..ff10b63a 100644 --- a/include/Engine/Network/TCPClient.h +++ b/include/Engine/Network/TCPClient.h @@ -1,23 +1,32 @@ #ifndef TCPClient_h__ #define TCPClient_h__ -#include "Client.h" +#include +#include "NetworkClient.h" -class TCPClient : public Client +class TCPClient : public NetworkClient { public: - TCPClient(ConfigFile* config); + TCPClient(); ~TCPClient(); + + void Connect(std::string playerName, std::string address, int port); + void Disconnect(); + void Receive(Packet& packet); + void Send(Packet & packet); + bool IsSocketAvailable(); private: + // Assio UDP logic + //boost::asio::io_service m_IOService; + //boost::asio::ip::udp::endpoint m_ReceiverEndpoint; + //boost::shared_ptr m_Socket; // Assio TCP logic boost::asio::ip::tcp::endpoint m_Endpoint; boost::asio::io_service m_IOService; std::unique_ptr m_Socket; - - void connect(); - void readFromServer(); - int receive(char * data); - void send(Packet & packet); + int readBuffer(char* data); + PacketID m_SendPacketID = 0; + bool m_IsConnected = false; }; #endif \ No newline at end of file diff --git a/include/Engine/Network/UDPClient.h b/include/Engine/Network/UDPClient.h index abe34b3a..ca369f6b 100644 --- a/include/Engine/Network/UDPClient.h +++ b/include/Engine/Network/UDPClient.h @@ -1,24 +1,31 @@ #ifndef UDPClient_h__ #define UDPClient_h__ -#include "Client.h" +#include +#include "Network/NetworkClient.h" +//virtual void Connect(std::string address, int port) = 0; +//virtual int Receive(char * data) = 0; +//virtual void Send(Packet & packet) = 0; +//virtual void Disconnect() = 0; - -class UDPClient : public Client +class UDPClient : public NetworkClient { public: - UDPClient(ConfigFile* config); + UDPClient(); ~UDPClient(); + + void Connect(std::string playerName, std::string address, int port); + void Disconnect(); + void Receive(Packet& packet); + void Send(Packet & packet); + bool IsSocketAvailable(); private: // Assio UDP logic boost::asio::io_service m_IOService; boost::asio::ip::udp::endpoint m_ReceiverEndpoint; - boost::asio::ip::udp::socket m_Socket; - - void connect(); - void readFromServer(); - int receive(char * data); - void send(Packet & packet); + boost::shared_ptr m_Socket; + int readBuffer(char* data); + PacketID m_SendPacketID = 0; }; #endif \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index 4faf6bbf..54b8c753 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -26,6 +26,8 @@ // Network #include #include "Network/Network.h" +// Client +#include "Network/Client.h" // Hybrid #include "Network/HybridServer.h" #include "Network/HybridClient.h" @@ -68,7 +70,9 @@ private: // Network methods void networkFunction(); Network* m_ClientOrServer; + std::unique_ptr m_Client; bool m_IsClientOrServer = false; + bool m_IsServer = false; // Sound SoundSystem* m_SoundSystem; diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index c7a8f0e6..eaacac47 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -17,8 +17,7 @@ Client::Client(ConfigFile* config) } Client::~Client() -{ -} +{ } void Client::Start(World* world, EventBroker* eventBroker) { @@ -35,17 +34,23 @@ void Client::Start(World* world, EventBroker* eventBroker) void Client::Update() { m_EventBroker->Process(); - readFromServer(); + while (m_UDPClient.IsSocketAvailable()) { + // Packet will get real data in receive + Packet packet(MessageType::Invalid); + m_UDPClient.Receive(packet); + parseMessageType(packet); + } + if (m_IsConnected) { hasServerTimedOut(); - // Don't sent 1 input in 1 packet, bunch em up. + // Don't send 1 input in 1 packet, bunch em up. if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) { sendInputCommands(); m_TimeSinceSentInputs = std::clock(); } sendLocalPlayerTransform(); } - Network::Update(); + //Network::Update(); } void Client::parseMessageType(Packet& packet) @@ -59,7 +64,7 @@ void Client::parseMessageType(Packet& packet) // Read packet ID m_PreviousPacketID = m_PacketID; // Set previous packet id m_PacketID = packet.ReadPrimitive(); //Read new packet id - identifyPacketLoss(); + //identifyPacketLoss(); switch (static_cast(messageType)) { case MessageType::Connect: @@ -118,7 +123,7 @@ void Client::parsePing() Packet packet(MessageType::Ping, m_SendPacketID); packet.WriteString("Ping recieved"); - send(packet); + m_UDPClient.Send(packet); } void Client::parseKick() @@ -250,14 +255,14 @@ void Client::disconnect() m_PreviousPacketID = 0; m_PacketID = 0; Packet packet(MessageType::Disconnect, m_SendPacketID); - send(packet); + m_UDPClient.Send(packet); } bool Client::OnInputCommand(const Events::InputCommand & e) { if (e.Command == "ConnectToServer") { // Connect for now if (e.Value > 0) { - connect(); + m_UDPClient.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; @@ -280,7 +285,7 @@ bool Client::OnInputCommand(const Events::InputCommand & e) m_SaveDataTimer = std::clock(); } } else { - if (m_IsConnected) { + 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); @@ -294,7 +299,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)); - send(packet); + m_UDPClient.Send(packet); return false; } @@ -322,7 +327,7 @@ void Client::sendLocalPlayerTransform() packet.WritePrimitive(orientation.x); packet.WritePrimitive(orientation.y); packet.WritePrimitive(orientation.z); - send(packet); + m_UDPClient.Send(packet); } void Client::identifyPacketLoss() @@ -365,7 +370,7 @@ void Client::sendInputCommands() packet.WriteString(m_InputCommandBuffer[i].Command); packet.WritePrimitive(m_InputCommandBuffer[i].Value); } - send(packet); + m_UDPClient.Send(packet); m_InputCommandBuffer.clear(); } } @@ -373,7 +378,7 @@ void Client::sendInputCommands() void Client::becomePlayer() { Packet packet = Packet(MessageType::BecomePlayer, m_SendPacketID); - send(packet); + m_UDPClient.Send(packet); } bool Client::clientServerMapsHasEntity(EntityID clientEntityID) diff --git a/src/Engine/Network/Network.cpp b/src/Engine/Network/Network.cpp index f4dcd1a2..db54a12e 100644 --- a/src/Engine/Network/Network.cpp +++ b/src/Engine/Network/Network.cpp @@ -5,6 +5,21 @@ void Network::Update() updateNetworkData(); } +void Network::logSentData(int bytesSent) +{ + +} + +void Network::logReceivedData(int bytesReceived) +{ + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataReceived += bytesReceived; + m_NetworkData.DataReceivedThisInterval += bytesReceived; + m_NetworkData.AmountOfMessagesReceived++; + } +} + void Network::saveToFile() { std::ofstream outfile; diff --git a/src/Engine/Network/NetworkClient.cpp b/src/Engine/Network/NetworkClient.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/Engine/Network/Packet.cpp b/src/Engine/Network/Packet.cpp index 28622611..06c81b8f 100644 --- a/src/Engine/Network/Packet.cpp +++ b/src/Engine/Network/Packet.cpp @@ -37,6 +37,7 @@ void Packet::Init(MessageType type, unsigned int & packetID) // allocate memory for size of packet(only used in tcp) Packet::WritePrimitive(0); // Add message type + m_MessageType = type; int messageType = static_cast(type); Packet::WritePrimitive(messageType); Packet::WritePrimitive(packetID); @@ -58,9 +59,12 @@ void Packet::WriteString(const std::string& str) void Packet::WriteData(char * data, int sizeOfData) { + if (m_Offset + sizeOfData > m_MaxPacketSize) { //LOG_WARNING("Packet::WriteData(): Data size in packet exceeded maximum packet size. New size is %i bytes\n", m_MaxPacketSize*2); - resizeData(); + while (m_Offset + sizeOfData > m_MaxPacketSize) { + resizeData(); + } } memcpy(m_Data + m_Offset, data, sizeOfData); m_Offset += sizeOfData; @@ -78,19 +82,34 @@ std::string Packet::ReadString() return returnValue; } +void Packet::ReconstructFromData(char * data, int sizeOfData) +{ + if (sizeOfData > m_MaxPacketSize) { + // Delete our data + delete[] m_Data; + // Set new max size + m_MaxPacketSize = sizeOfData; + m_Data = new char[m_MaxPacketSize]; + // while we resized the old data container. + } + memcpy(m_Data, data, sizeOfData); + m_Offset = sizeOfData; + +} + void Packet::UpdateSize() -{ +{ memcpy(m_Data, &m_Offset, sizeof(int)); } -char * Packet::ReadData(int SizeOfData) +char * Packet::ReadData(int sizeOfData) { - if (m_Offset < m_ReturnDataOffset + SizeOfData) { + if (m_Offset < m_ReturnDataOffset + sizeOfData) { //LOG_WARNING("packet ReadData(): Oh no! You are trying to remove things outside my memory kingdom"); return nullptr; } unsigned int oldReturnDataOffset = m_ReturnDataOffset; - m_ReturnDataOffset += SizeOfData; + m_ReturnDataOffset += sizeOfData; return (m_Data + oldReturnDataOffset); } @@ -103,20 +122,24 @@ void Packet::ChangePacketID(unsigned int & packetID) void Packet::resizeData() { + resizeData(m_MaxPacketSize * 2); +} +void Packet::resizeData(int size) +{ // Allocate memory to store our data in char* holdData = new char[m_MaxPacketSize]; // Copy our data to the newly allocated memory memcpy(holdData, m_Data, m_Offset); // Increase max packet size - m_MaxPacketSize = m_MaxPacketSize * 2; + m_MaxPacketSize = size; // Delete our data - delete m_Data; - // Allocate twice the memory we had before + delete[] m_Data; + // Allocate memory m_Data = new char[m_MaxPacketSize]; // Copy our data to new location memcpy(m_Data, holdData, m_Offset); // Delete the memory allocated to hold our data // while we resized the old data container. - delete holdData; + delete[] holdData; } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 344efba6..fa0f1a1a 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -8,8 +8,7 @@ Server::Server() pingIntervalMs = config->Get("Networking.PingIntervalMs", 1000); } Server::~Server() -{ -} +{ } void Server::Start(World* world, EventBroker* eventBroker) { m_World = world; @@ -25,11 +24,27 @@ void Server::Start(World* world, EventBroker* eventBroker) void Server::Update() { readFromClients(); + + std::clock_t currentTime = std::clock(); + // Send snapshot + if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { + sendSnapshot(); + previousSnapshotMessage = currentTime; + } + // Send pings each + if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { + sendPing(); + previousePingMessage = currentTime; + } + // Time out logic + if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { + checkForTimeOuts(); + timOutTimer = currentTime; + } m_EventBroker->Process(); if (isReadingData) { Network::Update(); } - } void Server::parseMessageType(Packet& packet) diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp index 545db491..42f724d0 100644 --- a/src/Engine/Network/TCPClient.cpp +++ b/src/Engine/Network/TCPClient.cpp @@ -2,46 +2,55 @@ using namespace boost::asio::ip; -TCPClient::TCPClient(ConfigFile * config) : Client(config) +TCPClient::TCPClient() { - m_Endpoint = tcp::endpoint(boost::asio::ip::address::from_string(address), port); - m_Socket = std::unique_ptr(new tcp::socket(m_IOService, m_Endpoint)); - tcp::no_delay option(true); - m_Socket->set_option(option); } TCPClient::~TCPClient() { - } -void TCPClient::connect() +void TCPClient::Connect(std::string playerName, std::string address, int port) { + if (m_Socket) { + return; + } if (!m_IsConnected) { boost::system::error_code error = boost::asio::error::host_not_found; + m_Endpoint = tcp::endpoint(boost::asio::ip::address::from_string(address), port); + m_Socket = std::unique_ptr(new tcp::socket(m_IOService, m_Endpoint)); + tcp::no_delay option(true); + m_Socket->set_option(option); m_Socket->close(); m_Socket->connect(m_Endpoint, error); LOG_INFO(error.message().c_str()); if (!error) { + m_IsConnected = true; Packet packet(MessageType::Connect, m_SendPacketID); - packet.WriteString(m_PlayerName); - m_StartPingTime = std::clock(); - send(packet); + packet.WriteString(playerName); + Send(packet); } } } -void TCPClient::readFromServer() +void TCPClient::Disconnect() +{ + +} + +void TCPClient::Receive(Packet& packet) { - while (m_Socket->available()) { - bytesRead = receive(readBuffer); - Packet packet(readBuffer, bytesRead); - parseMessageType(packet); + int bytesRead = readBuffer(m_ReadBuffer); + if (bytesRead > 0) { + packet.ReconstructFromData(m_ReadBuffer, bytesRead); } } -int TCPClient::receive(char * data) -{ +int TCPClient::readBuffer(char* data) +{ + if (!m_Socket) { + return 0; + } boost::system::error_code error; // Read size of packet int bytesReceived = m_Socket->read_some(boost @@ -54,29 +63,26 @@ int TCPClient::receive(char * data) 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) +void TCPClient::Send(Packet & packet) { packet.UpdateSize(); boost::system::error_code error; m_Socket->send(boost::asio::buffer( packet.Data(), packet.Size()), 0, error); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - m_NetworkData.AmountOfMessagesSent++; - } + //Network::logSentData(packet.Size()); } + +bool TCPClient::IsSocketAvailable() +{ + if (!m_Socket) { + return false; + } + return m_Socket->available(); +} \ No newline at end of file diff --git a/src/Engine/Network/TCPServer.cpp b/src/Engine/Network/TCPServer.cpp index d523bf47..09d2ce69 100644 --- a/src/Engine/Network/TCPServer.cpp +++ b/src/Engine/Network/TCPServer.cpp @@ -7,8 +7,7 @@ TCPServer::TCPServer() } TCPServer::~TCPServer() -{ -} +{ } void TCPServer::readFromClients() { @@ -30,25 +29,6 @@ void TCPServer::readFromClients() } } } - - std::clock_t currentTime = std::clock(); - // Send snapshot - if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { - sendSnapshot(); - previousSnapshotMessage = currentTime; - } - - // Send pings each - if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { - sendPing(); - previousePingMessage = currentTime; - } - - // Time out logic - if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { - checkForTimeOuts(); - timOutTimer = currentTime; - } } void TCPServer::acceptNewConnections() @@ -80,7 +60,7 @@ void TCPServer::parseConnect(Packet & packet) LOG_INFO("Parsing connections"); // Check if player is already connected PlayerID playerID = GetPlayerIDFromEndpoint(); - if(playerID = -1){ + if (playerID = -1) { return; } diff --git a/src/Engine/Network/UDPClient.cpp b/src/Engine/Network/UDPClient.cpp index 26e895d5..e5eafc08 100644 --- a/src/Engine/Network/UDPClient.cpp +++ b/src/Engine/Network/UDPClient.cpp @@ -2,65 +2,69 @@ using namespace boost::asio::ip; -UDPClient::UDPClient(ConfigFile * config) : Client(config), m_Socket(m_IOService) -{ - m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); - m_Socket.connect(m_ReceiverEndpoint); +UDPClient::UDPClient() +{ } UDPClient::~UDPClient() -{ +{ } -void UDPClient::readFromServer() +void UDPClient::Connect(std::string playerName, std::string address, int port) { - while (m_Socket.available()) { - bytesRead = receive(readBuffer); - if (bytesRead > 0) { - Packet packet(readBuffer, bytesRead); - parseMessageType(packet); - } + if (m_Socket) { + return; + } + 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() +{ + +} + +void UDPClient::Receive(Packet& packet) +{ + int bytesRead = readBuffer(m_ReadBuffer); + if (bytesRead > 0) { + packet.ReconstructFromData(m_ReadBuffer, bytesRead); } } -int UDPClient::receive(char* data) +int UDPClient::readBuffer(char* data) { + if (!m_Socket) { + return 0; + } boost::system::error_code error; - - int bytesReceived = m_Socket.receive_from(boost + int bytesReceived = m_Socket->receive_from(boost ::asio::buffer((void*)data, BUFFERSIZE), m_ReceiverEndpoint, 0, 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 UDPClient::send(Packet& packet) +void UDPClient::Send(Packet& packet) { - m_Socket.send_to(boost::asio::buffer( + m_Socket->send_to(boost::asio::buffer( packet.Data(), packet.Size()), m_ReceiverEndpoint, 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - m_NetworkData.AmountOfMessagesSent++; - } } -void UDPClient::connect() +bool UDPClient::IsSocketAvailable() { - Packet packet(MessageType::Connect, m_SendPacketID); - packet.WriteString(m_PlayerName); - m_StartPingTime = std::clock(); - send(packet); + if (!m_Socket) { + return false; + } + return m_Socket->available(); } \ No newline at end of file diff --git a/src/Engine/Network/UDPServer.cpp b/src/Engine/Network/UDPServer.cpp index 1e62c10a..41cb436c 100644 --- a/src/Engine/Network/UDPServer.cpp +++ b/src/Engine/Network/UDPServer.cpp @@ -6,8 +6,7 @@ UDPServer::UDPServer() } UDPServer::~UDPServer() -{ -} +{ } void UDPServer::readFromClients() { @@ -22,24 +21,6 @@ void UDPServer::readFromClients() //LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what()); } } - std::clock_t currentTime = std::clock(); - // Send snapshot - if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { - sendSnapshot(); - previousSnapshotMessage = currentTime; - } - - // Send pings each - if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { - sendPing(); - previousePingMessage = currentTime; - } - - // Time out logic - if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { - checkForTimeOuts(); - timOutTimer = currentTime; - } } void UDPServer::parseConnect(Packet& packet) diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index ccbf79c9..931bb9dd 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -43,7 +43,7 @@ Game::Game(int argc, char* argv[]) 0, m_Config->Get("Video.Width", 1280), m_Config->Get("Video.Height", 720) - )); + )); m_Renderer->Initialize(); //m_Renderer->Camera()->SetFOV(glm::radians(m_Config->Get("Video.FOV", 90.f))); m_RenderFrame = new RenderFrame(); @@ -155,7 +155,11 @@ void Game::Tick() // Update network if (m_IsClientOrServer) { - m_ClientOrServer->Update(); + if (m_IsServer) + m_ClientOrServer->Update(); + else if (!m_IsServer) { + m_Client->Update(); + } } // Iterate through systems and update world! m_EventBroker->Process(); @@ -178,19 +182,25 @@ void Game::debugTick(double dt) void Game::networkFunction() { - bool isServer = m_Config->Get("Networking.IsServer", false); - if (!isServer) { + m_IsServer = m_Config->Get("Networking.IsServer", false); + if (!m_IsServer) { m_IsClientOrServer = true; - m_ClientOrServer = new UDPClient(m_Config); - //m_ClientOrServer = new TCPClient(m_Config); - //m_ClientOrServer = new HybridClient(m_Config); + m_Client = std::unique_ptr(new Client(m_Config)); + m_Client->Start(m_World, m_EventBroker); } - if (isServer) { + //if (!isServer) { + // m_IsClientOrServer = true; + // m_ClientOrServer = new UDPClient(m_Config); + // //m_ClientOrServer = new TCPClient(m_Config); + // //m_ClientOrServer = new HybridClient(m_Config); + //} + if (m_IsServer) { m_IsClientOrServer = true; - m_ClientOrServer = new UDPServer(); - // m_ClientOrServer = new TCPServer(); + // m_ClientOrServer = new UDPServer(); + m_ClientOrServer = new TCPServer(); //m_ClientOrServer = new HybridServer(); + m_ClientOrServer->Start(m_World, m_EventBroker); } - m_ClientOrServer->Start(m_World, m_EventBroker); + } \ No newline at end of file From d2ed293183bad8ae6a91b71b2d491ee1e8fc3550 Mon Sep 17 00:00:00 2001 From: Jocke Date: Tue, 9 Feb 2016 19:14:56 +0100 Subject: [PATCH 06/43] Network is now working as udp or tcp. Next step is making the hybrid. --- include/Engine/Network/NetworkServer.h | 28 +++++-- include/Engine/Network/Packet.h | 3 +- include/Engine/Network/Server.h | 22 +++-- include/Engine/Network/TCPServer.h | 24 +++--- include/Engine/Network/UDPServer.h | 22 +++-- include/Game/Game.h | 13 +-- src/Engine/Network/Packet.cpp | 8 +- src/Engine/Network/Server.cpp | 90 ++++++++++++++++++-- src/Engine/Network/TCPClient.cpp | 7 ++ src/Engine/Network/TCPServer.cpp | 109 +++++++++---------------- src/Engine/Network/UDPServer.cpp | 83 +++++-------------- src/Game/Game.cpp | 6 +- 12 files changed, 225 insertions(+), 190 deletions(-) diff --git a/include/Engine/Network/NetworkServer.h b/include/Engine/Network/NetworkServer.h index 1586693d..36544292 100644 --- a/include/Engine/Network/NetworkServer.h +++ b/include/Engine/Network/NetworkServer.h @@ -1,20 +1,32 @@ #ifndef NetworkServer_h__ #define NetworkServer_h__ - +#include #include "Network/Packet.h" +#include "Network/PlayerDefinition.h" #define BUFFERSIZE 32000 typedef unsigned int PlayerID; typedef unsigned int PacketID; class NetworkServer { -//public: -// virtual void Connect(std::string playerName, std::string address, int port) = 0; -// virtual void Disconnect() = 0; -// virtual Packet Receive() = 0; -// virtual void Send(Packet & packet) = 0; -//protected: -// char m_ReadBuffer[BUFFERSIZE] = { 0 }; +public: + virtual void AcceptNewConnections(int& nextPlayerID, std::map& connectedPlayers) = 0; + virtual void Receive(Packet & packet, PlayerDefinition & playerDefinition) = 0; + virtual void Send(Packet & packet, PlayerDefinition & playerDefinition) = 0; + virtual void Send(Packet & packet) = 0; +protected: + char m_ReadBuffer[BUFFERSIZE] = { 0 }; + //void handle_accept(boost::shared_ptr socket, const boost::system::error_code & error); + //void parseConnect(Packet & packet); + //void readFromClients(); + + //public: + // virtual void Connect(std::string playerName, std::string address, int port) = 0; + // virtual void Disconnect() = 0; + // virtual Packet Receive() = 0; + // virtual void Send(Packet & packet) = 0; + //protected: + // char m_ReadBuffer[BUFFERSIZE] = { 0 }; }; #endif \ No newline at end of file diff --git a/include/Engine/Network/Packet.h b/include/Engine/Network/Packet.h index e88747b8..2a370dc6 100644 --- a/include/Engine/Network/Packet.h +++ b/include/Engine/Network/Packet.h @@ -57,7 +57,7 @@ public: void ChangePacketID(unsigned int& packetID); int Size() { return m_Offset; }; char* Data() { return m_Data; }; - MessageType GetMessageType() { return m_MessageType; }; + MessageType GetMessageType(); unsigned int DataReadSize() { return m_ReturnDataOffset; } unsigned int MaxSize() { return m_MaxPacketSize; } unsigned int HeaderSize() { return m_HeaderSize; } @@ -68,7 +68,6 @@ private: int m_Offset = 0; unsigned int m_MaxPacketSize = 512; unsigned int m_HeaderSize = 0; - MessageType m_MessageType = MessageType::Invalid; void resizeData(); void resizeData(int size); }; diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 4ff169d2..0a3c93c8 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -6,6 +6,8 @@ #include +#include "Network/TCPServer.h" +#include "Network/UDPServer.h" #include "Network/MessageType.h" #include "Network/PlayerDefinition.h" #include "Core/World.h" @@ -17,6 +19,7 @@ #include "Core/EPlayerSpawned.h" #include "Core/EEntityDeleted.h" #include "Core/EComponentDeleted.h" + class Server : public Network { public: @@ -49,7 +52,7 @@ protected: // Game logic World* m_World; EventBroker* m_EventBroker; - + // Packet loss logic PacketID m_PacketID = 0; PacketID m_PreviousPacketID = 0; @@ -70,13 +73,15 @@ protected: void parsePlayerTransform(Packet& packet); void parseOnInputCommand(Packet& packet); void parseClientPing(); - void parsePing(); + void parsePing(); + void parseConnect(Packet & packet, PlayerDefinition & pd); + 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; - virtual void parseConnect(Packet& packet) = 0; + //// 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; bool OnInputCommand(const Events::InputCommand& e); @@ -86,6 +91,9 @@ protected: bool OnEntityDeleted(const Events::EntityDeleted& e); EventRelay m_EComponentDeleted; bool OnComponentDeleted(const Events::ComponentDeleted& e); +private: + TCPServer m_TCPServer; + //UDPServer m_UDPServer; }; #endif diff --git a/include/Engine/Network/TCPServer.h b/include/Engine/Network/TCPServer.h index 6c52d10d..b1aa7ce0 100644 --- a/include/Engine/Network/TCPServer.h +++ b/include/Engine/Network/TCPServer.h @@ -1,26 +1,30 @@ #ifndef TCPServer_h__ #define TCPServer_h__ -#include "Server.h" +#include +#include +#include +#include "NetworkServer.h" -class TCPServer : public Server +class TCPServer : public NetworkServer { public: TCPServer(); ~TCPServer(); + void AcceptNewConnections(int& nextPlayerID, std::map& connectedPlayers); + void Receive(Packet & packet, PlayerDefinition & playerDefinition); + void Send(Packet & packet, PlayerDefinition & playerDefinition); + void Send(Packet & packet); private: // TCP logic boost::asio::io_service m_IOService; std::unique_ptr acceptor; boost::shared_ptr lastReceivedSocket; - - void acceptNewConnections(); - void handle_accept(boost::shared_ptr socket, const boost::system::error_code & error); - void readFromClients(); - int receive(char * data, boost::asio::ip::tcp::socket& socket); - void parseConnect(Packet & packet); - void send(Packet & packet, PlayerDefinition & playerDefinition); - void send(Packet & packet); + + void handle_accept(boost::shared_ptr socket, + int& nextPlayerID, std::map& connectedPlayers, + const boost::system::error_code& error); + int readBuffer(char* data, PlayerDefinition& playerDefinition); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/UDPServer.h b/include/Engine/Network/UDPServer.h index 22c8c3e3..7c912a21 100644 --- a/include/Engine/Network/UDPServer.h +++ b/include/Engine/Network/UDPServer.h @@ -1,25 +1,31 @@ #ifndef UDPServer_h__ #define UDPServer_h__ -#include "Server.h" +#include "NetworkServer.h" #include +// +//virtual void AcceptNewConnections() = 0; +//virtual void Receive(Packet & packet, PlayerDefinition & playerDefinition) = 0; +//virtual void Send(Packet & packet, PlayerDefinition & playerDefinition) = 0; +//virtual void Send(Packet & packet) = 0; -class UDPServer : public Server +class UDPServer : public NetworkServer { public: UDPServer(); ~UDPServer(); + void AcceptNewConnections(int& nextPlayerID, std::map& connectedPlayers); + void Receive(Packet & packet, PlayerDefinition & playerDefinition); + //void parseConnect(Packet & packet, PlayerDefinition & playerDefinition); + void Send(Packet & packet, PlayerDefinition & playerDefinition); + void Send(Packet & packet); + bool IsSocketAvailable(); private: // UDP logic boost::asio::io_service m_IOService; boost::asio::ip::udp::endpoint m_ReceiverEndpoint; std::unique_ptr m_Socket; - - void readFromClients(); - int receive(char * data); - void parseConnect(Packet & packet); - void send(Packet & packet, PlayerDefinition & playerDefinition); - void send(Packet & packet); + int readBuffer(char* data); }; #endif \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index 54b8c753..fb03896d 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -28,15 +28,8 @@ #include "Network/Network.h" // Client #include "Network/Client.h" -// Hybrid -#include "Network/HybridServer.h" -#include "Network/HybridClient.h" -// TCP -#include "Network/TCPClient.h" -#include "Network/TCPServer.h" -// UDP -#include "Network/UDPServer.h" -#include "Network/UDPClient.h" +// Server +#include "Network/Server.h" // Sound #include "Sound/SoundSystem.h" @@ -69,8 +62,8 @@ private: // Network methods void networkFunction(); - Network* m_ClientOrServer; std::unique_ptr m_Client; + std::unique_ptr m_Server; bool m_IsClientOrServer = false; bool m_IsServer = false; diff --git a/src/Engine/Network/Packet.cpp b/src/Engine/Network/Packet.cpp index 06c81b8f..c9e8832a 100644 --- a/src/Engine/Network/Packet.cpp +++ b/src/Engine/Network/Packet.cpp @@ -37,7 +37,6 @@ void Packet::Init(MessageType type, unsigned int & packetID) // allocate memory for size of packet(only used in tcp) Packet::WritePrimitive(0); // Add message type - m_MessageType = type; int messageType = static_cast(type); Packet::WritePrimitive(messageType); Packet::WritePrimitive(packetID); @@ -120,6 +119,13 @@ void Packet::ChangePacketID(unsigned int & packetID) memcpy(m_Data + 2*sizeof(int), &packetID, sizeof(int)); } +MessageType Packet::GetMessageType() +{ + MessageType messagType; + memcpy(&messagType, m_Data + sizeof(int), sizeof(int)); + return messagType; +} + void Packet::resizeData() { resizeData(m_MaxPacketSize * 2); diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index fa0f1a1a..de7b6e14 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -23,7 +23,35 @@ void Server::Start(World* world, EventBroker* eventBroker) void Server::Update() { - readFromClients(); + m_TCPServer.AcceptNewConnections(m_NextPlayerID, m_ConnectedPlayers); + PlayerDefinition pd; + 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()) { + // // Packet will get real data in receive + // Packet packet(MessageType::Invalid); + // m_UDPServer.Receive(packet, pd); + // m_Address = pd.Endpoint.address(); + // m_Port = pd.Endpoint.port(); + // if (packet.GetMessageType() == MessageType::Connect) { + // parseConnect(packet, pd); + // } else { + // parseMessageType(packet); + // } + //} std::clock_t currentTime = std::clock(); // Send snapshot @@ -60,7 +88,7 @@ void Server::parseMessageType(Packet& packet) //identifyPacketLoss(); switch (static_cast(messageType)) { case MessageType::Connect: - parseConnect(packet); + //parseConnect(packet); break; case MessageType::Ping: parsePing(); @@ -90,7 +118,7 @@ void Server::broadcast(Packet& packet) { for (auto& kv : m_ConnectedPlayers) { packet.ChangePacketID(kv.second.PacketID); - send(packet, kv.second); + m_TCPServer.Send(packet, kv.second); } } @@ -184,6 +212,56 @@ void Server::checkForTimeOuts() } } +void Server::parseConnect(Packet & packet, PlayerDefinition & pd) +{ + //LOG_INFO("Parsing connections"); + //// Check if player is already connected + //if (GetPlayerIDFromEndpoint() != -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()); + + //// Send a message to the player that connected + //Packet connnectPacket(MessageType::Connect, pd.PacketID); + //m_UDPServer.Send(connnectPacket); + + //// Send notification that a player has connected + //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); @@ -232,7 +310,7 @@ void Server::kick(PlayerID player) { disconnect(player); Packet packet = Packet(MessageType::Kick); - send(packet); + m_TCPServer.Send(packet); } bool Server::OnInputCommand(const Events::InputCommand & e) @@ -261,7 +339,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); - send(packet, m_ConnectedPlayers[e.PlayerID]); + m_TCPServer.Send(packet, m_ConnectedPlayers[e.PlayerID]); return false; } @@ -297,7 +375,7 @@ void Server::parseClientPing() // Return ping Packet packet(MessageType::Ping, m_ConnectedPlayers[player].PacketID); packet.WriteString("Ping received"); - send(packet); + m_TCPServer.Send(packet); } void Server::parsePing() diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp index 42f724d0..69938c38 100644 --- a/src/Engine/Network/TCPClient.cpp +++ b/src/Engine/Network/TCPClient.cpp @@ -13,6 +13,12 @@ TCPClient::~TCPClient() void TCPClient::Connect(std::string playerName, std::string address, int port) { if (m_Socket) { + if (m_IsConnected) { + Packet packet(MessageType::Connect, m_SendPacketID); + packet.WriteString(playerName); + Send(packet); + LOG_INFO("Connect message sent again!"); + } return; } if (!m_IsConnected) { @@ -29,6 +35,7 @@ void TCPClient::Connect(std::string playerName, std::string address, int port) Packet packet(MessageType::Connect, m_SendPacketID); packet.WriteString(playerName); Send(packet); + LOG_INFO("Connect message sent!"); } } } diff --git a/src/Engine/Network/TCPServer.cpp b/src/Engine/Network/TCPServer.cpp index 09d2ce69..105aab9f 100644 --- a/src/Engine/Network/TCPServer.cpp +++ b/src/Engine/Network/TCPServer.cpp @@ -7,42 +7,38 @@ TCPServer::TCPServer() } TCPServer::~TCPServer() -{ } - -void TCPServer::readFromClients() { - acceptNewConnections(); - for (auto& kv : m_ConnectedPlayers) { - while (kv.second.TCPSocket->available()) { - 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) { - //LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what()); - } - } - } } -void TCPServer::acceptNewConnections() +void TCPServer::AcceptNewConnections(int& nextPlayerID, std::map& connectedPlayers) { + //PlayerDefinition pd; + //connectedPlayers[nextPlayerID++] = pd; boost::shared_ptr newSocket = boost::shared_ptr(new tcp::socket(m_IOService)); m_IOService.poll(); acceptor->async_accept(*newSocket, - boost::bind(&TCPServer::handle_accept, this, newSocket, + boost::bind(&TCPServer::handle_accept, this, newSocket, boost::ref(nextPlayerID), boost::ref(connectedPlayers), boost::asio::placeholders::error)); } -void TCPServer::handle_accept(boost::shared_ptr socket, const boost::system::error_code& error) +PlayerID GetPlayerIDFromEndpoint(const std::map& connectedPlayers, + boost::asio::ip::address address, unsigned short port) { - if (!error && GetPlayerIDFromEndpoint() == -1) { + for (auto& kv : connectedPlayers) { + if (kv.second.Address == address && + kv.second.Port == port) { + return kv.first; + } + } + return -1; +} + +void TCPServer::handle_accept(boost::shared_ptr socket, + int& nextPlayerID, std::map& connectedPlayers, + const boost::system::error_code& error) +{ + if (!error && GetPlayerIDFromEndpoint(connectedPlayers, socket->remote_endpoint().address(), + socket->remote_endpoint().port()) == -1) { // Add tcp socket to connections boost::asio::ip::tcp::no_delay option(true); socket->set_option(option); @@ -51,55 +47,24 @@ void TCPServer::handle_accept(boost::shared_ptr socket, const boost pd.TCPSocket = socket; pd.Address = socket.get()->remote_endpoint().address(); pd.Port = socket.get()->remote_endpoint().port(); - m_ConnectedPlayers[m_NextPlayerID++] = pd; + connectedPlayers[nextPlayerID++] = pd; } } -void TCPServer::parseConnect(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); - send(connnectPacket); - - // Send notification that a player has connected - Packet notificationPacket(MessageType::PlayerConnected); - broadcast(notificationPacket); -} - -void TCPServer::send(Packet & packet, PlayerDefinition & playerDefinition) +void TCPServer::Send(Packet & packet, PlayerDefinition & playerDefinition) { try { packet.UpdateSize(); int bytesSent = playerDefinition.TCPSocket->send( boost::asio::buffer(packet.Data(), packet.Size()), 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - m_NetworkData.AmountOfMessagesSent++; - } } catch (const boost::system::system_error& e) { // TODO: Clean up invalid endpoints out of m_ConnectedPlayers later playerDefinition.Endpoint = boost::asio::ip::udp::endpoint(); } } -void TCPServer::send(Packet & packet) +void TCPServer::Send(Packet & packet) { packet.UpdateSize(); lastReceivedSocket->send( @@ -107,33 +72,33 @@ void TCPServer::send(Packet & packet) packet.Data(), packet.Size()), 0); - if (isReadingData) { - // Network Debug data - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); +} + +void TCPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition) +{ + int bytesRead = readBuffer(m_ReadBuffer, playerDefinition); + if (bytesRead > 0) { + packet.ReconstructFromData(m_ReadBuffer, bytesRead); } } -int TCPServer::receive(char * data, boost::asio::ip::tcp::socket& socket) +int TCPServer::readBuffer(char* data, PlayerDefinition & playerDefinition) { + if (!playerDefinition.TCPSocket) { + return 0; + } boost::system::error_code error; // Read size of packet - int bytesReceived = socket.read_some(boost + int bytesReceived = playerDefinition.TCPSocket->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 + bytesReceived += playerDefinition.TCPSocket->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()); } diff --git a/src/Engine/Network/UDPServer.cpp b/src/Engine/Network/UDPServer.cpp index 41cb436c..e0bdf3a2 100644 --- a/src/Engine/Network/UDPServer.cpp +++ b/src/Engine/Network/UDPServer.cpp @@ -6,71 +6,23 @@ UDPServer::UDPServer() } UDPServer::~UDPServer() -{ } - -void UDPServer::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) { - //LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what()); - } - } } -void UDPServer::parseConnect(Packet& packet) -{ - LOG_INFO("Parsing connections"); - // Check if player is already connected - 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(); - m_ConnectedPlayers[m_NextPlayerID++] = pd; - LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str()); - - // Send a message to the player that connected - Packet connnectPacket(MessageType::Connect, pd.PacketID); - send(connnectPacket); - - // Send notification that a player has connected - Packet notificationPacket(MessageType::PlayerConnected); - broadcast(notificationPacket); -} - -void UDPServer::send(Packet& packet, PlayerDefinition & playerDefinition) +void UDPServer::Send(Packet& packet, PlayerDefinition & playerDefinition) { try { int bytesSent = m_Socket->send_to( boost::asio::buffer(packet.Data(), packet.Size()), playerDefinition.Endpoint, 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - m_NetworkData.AmountOfMessagesSent++; - } } catch (const boost::system::system_error& e) { // TODO: Clean up invalid endpoints out of m_ConnectedPlayers later playerDefinition.Endpoint = boost::asio::ip::udp::endpoint(); } } // Send back to endpoint of received packet -void UDPServer::send(Packet & packet) +void UDPServer::Send(Packet & packet) { m_Socket->send_to( boost::asio::buffer( @@ -78,27 +30,32 @@ void UDPServer::send(Packet & packet) packet.Size()), m_ReceiverEndpoint, 0); - if (isReadingData) { - // Network Debug data - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - } } -int UDPServer::receive(char * data) +void UDPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition) +{ + int bytesRead = readBuffer(m_ReadBuffer); + if (bytesRead > 0) { + packet.ReconstructFromData(m_ReadBuffer, bytesRead); + } + playerDefinition.Endpoint = m_ReceiverEndpoint; +} + +bool UDPServer::IsSocketAvailable() +{ + return m_Socket->available(); +} + +int UDPServer::readBuffer(char* data) { unsigned int length = m_Socket->receive_from( boost::asio::buffer((void*)data , BUFFERSIZE) , m_ReceiverEndpoint, 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataReceived += length; - m_NetworkData.DataReceivedThisInterval += length; - m_NetworkData.AmountOfMessagesReceived++; - } return length; } - +void UDPServer::AcceptNewConnections(int& nextPlayerID, std::map& connectedPlayers) +{ +} \ No newline at end of file diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 931bb9dd..9e1bf708 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -156,7 +156,7 @@ void Game::Tick() // Update network if (m_IsClientOrServer) { if (m_IsServer) - m_ClientOrServer->Update(); + m_Server->Update(); else if (!m_IsServer) { m_Client->Update(); } @@ -197,9 +197,9 @@ void Game::networkFunction() if (m_IsServer) { m_IsClientOrServer = true; // m_ClientOrServer = new UDPServer(); - m_ClientOrServer = new TCPServer(); + m_Server = std::unique_ptr(new Server()); //m_ClientOrServer = new HybridServer(); - m_ClientOrServer->Start(m_World, m_EventBroker); + m_Server->Start(m_World, m_EventBroker); } From 2ec30fd2b20e35667954d1417d7748be9111a22a Mon Sep 17 00:00:00 2001 From: Jocke Date: Wed, 10 Feb 2016 11:28:03 +0100 Subject: [PATCH 07/43] Cleaned up code and fixed crash when closing client before server when using udp. --- include/Engine/Network/Client.h | 4 +- include/Engine/Network/NetworkServer.h | 11 -- include/Engine/Network/Server.h | 4 +- include/Engine/Network/TCPClient.h | 4 - include/Engine/Network/UDPClient.h | 4 - include/Engine/Network/UDPServer.h | 6 -- src/Engine/Network/Server.cpp | 133 +++++++++++++------------ src/Engine/Network/TCPClient.cpp | 1 - src/Engine/Network/TCPServer.cpp | 2 - src/Engine/Network/UDPServer.cpp | 12 ++- 10 files changed, 78 insertions(+), 103 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 0c9608ff..ffdf812f 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -103,9 +103,9 @@ protected: bool OnPlayerSpawned(const Events::PlayerSpawned& e); private: - //UDPClient m_UDPClient; + UDPClient m_UDPClient; //TCPClient m_TCPClient; - TCPClient m_UDPClient; + //TCPClient m_UDPClient; }; #endif diff --git a/include/Engine/Network/NetworkServer.h b/include/Engine/Network/NetworkServer.h index 36544292..d6406eab 100644 --- a/include/Engine/Network/NetworkServer.h +++ b/include/Engine/Network/NetworkServer.h @@ -16,17 +16,6 @@ public: virtual void Send(Packet & packet) = 0; protected: char m_ReadBuffer[BUFFERSIZE] = { 0 }; - //void handle_accept(boost::shared_ptr socket, const boost::system::error_code & error); - //void parseConnect(Packet & packet); - //void readFromClients(); - - //public: - // virtual void Connect(std::string playerName, std::string address, int port) = 0; - // virtual void Disconnect() = 0; - // virtual Packet Receive() = 0; - // virtual void Send(Packet & packet) = 0; - //protected: - // char m_ReadBuffer[BUFFERSIZE] = { 0 }; }; #endif \ No newline at end of file diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 0a3c93c8..1b2e6956 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -92,8 +92,8 @@ protected: EventRelay m_EComponentDeleted; bool OnComponentDeleted(const Events::ComponentDeleted& e); private: - TCPServer m_TCPServer; - //UDPServer m_UDPServer; + //TCPServer m_TCPServer; + UDPServer m_UDPServer; }; #endif diff --git a/include/Engine/Network/TCPClient.h b/include/Engine/Network/TCPClient.h index ff10b63a..9f61cca5 100644 --- a/include/Engine/Network/TCPClient.h +++ b/include/Engine/Network/TCPClient.h @@ -16,10 +16,6 @@ public: void Send(Packet & packet); bool IsSocketAvailable(); private: - // Assio UDP logic - //boost::asio::io_service m_IOService; - //boost::asio::ip::udp::endpoint m_ReceiverEndpoint; - //boost::shared_ptr m_Socket; // Assio TCP logic boost::asio::ip::tcp::endpoint m_Endpoint; boost::asio::io_service m_IOService; diff --git a/include/Engine/Network/UDPClient.h b/include/Engine/Network/UDPClient.h index ca369f6b..3a458d3e 100644 --- a/include/Engine/Network/UDPClient.h +++ b/include/Engine/Network/UDPClient.h @@ -3,10 +3,6 @@ #include #include "Network/NetworkClient.h" -//virtual void Connect(std::string address, int port) = 0; -//virtual int Receive(char * data) = 0; -//virtual void Send(Packet & packet) = 0; -//virtual void Disconnect() = 0; class UDPClient : public NetworkClient { diff --git a/include/Engine/Network/UDPServer.h b/include/Engine/Network/UDPServer.h index 7c912a21..246fb333 100644 --- a/include/Engine/Network/UDPServer.h +++ b/include/Engine/Network/UDPServer.h @@ -3,11 +3,6 @@ #include "NetworkServer.h" #include -// -//virtual void AcceptNewConnections() = 0; -//virtual void Receive(Packet & packet, PlayerDefinition & playerDefinition) = 0; -//virtual void Send(Packet & packet, PlayerDefinition & playerDefinition) = 0; -//virtual void Send(Packet & packet) = 0; class UDPServer : public NetworkServer { @@ -16,7 +11,6 @@ public: ~UDPServer(); void AcceptNewConnections(int& nextPlayerID, std::map& connectedPlayers); void Receive(Packet & packet, PlayerDefinition & playerDefinition); - //void parseConnect(Packet & packet, PlayerDefinition & playerDefinition); void Send(Packet & packet, PlayerDefinition & playerDefinition); void Send(Packet & packet); bool IsSocketAvailable(); diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index de7b6e14..d3099e12 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -23,36 +23,37 @@ void Server::Start(World* world, EventBroker* eventBroker) void Server::Update() { - m_TCPServer.AcceptNewConnections(m_NextPlayerID, m_ConnectedPlayers); PlayerDefinition pd; - 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()) { - // // Packet will get real data in receive - // Packet packet(MessageType::Invalid); - // m_UDPServer.Receive(packet, pd); - // m_Address = pd.Endpoint.address(); - // m_Port = pd.Endpoint.port(); - // if (packet.GetMessageType() == MessageType::Connect) { - // parseConnect(packet, pd); - // } else { - // parseMessageType(packet); + + //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()) { + // Packet will get real data in receive + Packet packet(MessageType::Invalid); + m_UDPServer.Receive(packet, pd); + m_Address = pd.Endpoint.address(); + m_Port = pd.Endpoint.port(); + if (packet.GetMessageType() == MessageType::Connect) { + parseConnect(packet, pd); + } else { + parseMessageType(packet); + } + } + std::clock_t currentTime = std::clock(); // Send snapshot if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { @@ -118,7 +119,7 @@ void Server::broadcast(Packet& packet) { for (auto& kv : m_ConnectedPlayers) { packet.ChangePacketID(kv.second.PacketID); - m_TCPServer.Send(packet, kv.second); + m_UDPServer.Send(packet, kv.second); } } @@ -213,54 +214,54 @@ void Server::checkForTimeOuts() } void Server::parseConnect(Packet & packet, PlayerDefinition & pd) -{ - //LOG_INFO("Parsing connections"); - //// Check if player is already connected - //if (GetPlayerIDFromEndpoint() != -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()); - - //// Send a message to the player that connected - //Packet connnectPacket(MessageType::Connect, pd.PacketID); - //m_UDPServer.Send(connnectPacket); - - //// Send notification that a player has connected - //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) { + if (GetPlayerIDFromEndpoint() != -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()); + 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()); // Send a message to the player that connected - Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID); - m_TCPServer.Send(connnectPacket); + Packet connnectPacket(MessageType::Connect, pd.PacketID); + m_UDPServer.Send(connnectPacket); // Send notification that a player has connected Packet notificationPacket(MessageType::PlayerConnected); - //broadcast(notificationPacket); + 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() { @@ -310,7 +311,7 @@ void Server::kick(PlayerID player) { disconnect(player); Packet packet = Packet(MessageType::Kick); - m_TCPServer.Send(packet); + m_UDPServer.Send(packet); } bool Server::OnInputCommand(const Events::InputCommand & e) @@ -339,7 +340,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_TCPServer.Send(packet, m_ConnectedPlayers[e.PlayerID]); + m_UDPServer.Send(packet, m_ConnectedPlayers[e.PlayerID]); return false; } @@ -375,7 +376,7 @@ void Server::parseClientPing() // Return ping Packet packet(MessageType::Ping, m_ConnectedPlayers[player].PacketID); packet.WriteString("Ping received"); - m_TCPServer.Send(packet); + m_UDPServer.Send(packet); } void Server::parsePing() diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp index 69938c38..21bb653f 100644 --- a/src/Engine/Network/TCPClient.cpp +++ b/src/Engine/Network/TCPClient.cpp @@ -83,7 +83,6 @@ void TCPClient::Send(Packet & packet) m_Socket->send(boost::asio::buffer( packet.Data(), packet.Size()), 0, error); - //Network::logSentData(packet.Size()); } bool TCPClient::IsSocketAvailable() diff --git a/src/Engine/Network/TCPServer.cpp b/src/Engine/Network/TCPServer.cpp index 105aab9f..f8da15e2 100644 --- a/src/Engine/Network/TCPServer.cpp +++ b/src/Engine/Network/TCPServer.cpp @@ -12,8 +12,6 @@ TCPServer::~TCPServer() void TCPServer::AcceptNewConnections(int& nextPlayerID, std::map& connectedPlayers) { - //PlayerDefinition pd; - //connectedPlayers[nextPlayerID++] = pd; boost::shared_ptr newSocket = boost::shared_ptr(new tcp::socket(m_IOService)); m_IOService.poll(); acceptor->async_accept(*newSocket, diff --git a/src/Engine/Network/UDPServer.cpp b/src/Engine/Network/UDPServer.cpp index e0bdf3a2..6bf4e466 100644 --- a/src/Engine/Network/UDPServer.cpp +++ b/src/Engine/Network/UDPServer.cpp @@ -6,8 +6,7 @@ UDPServer::UDPServer() } UDPServer::~UDPServer() -{ -} +{ } void UDPServer::Send(Packet& packet, PlayerDefinition & playerDefinition) { @@ -49,13 +48,16 @@ bool UDPServer::IsSocketAvailable() int UDPServer::readBuffer(char* data) { + boost::system::error_code error = boost::asio::error::host_not_found; unsigned int length = m_Socket->receive_from( boost::asio::buffer((void*)data , BUFFERSIZE) - , m_ReceiverEndpoint, 0); + , m_ReceiverEndpoint, 0, error); + if (error) { + LOG_WARNING(error.message().c_str()); + } return length; } void UDPServer::AcceptNewConnections(int& nextPlayerID, std::map& connectedPlayers) -{ -} \ No newline at end of file +{ } \ No newline at end of file From 4f2ad3ad00ab561cb241be49812f757d00416b2b Mon Sep 17 00:00:00 2001 From: Jocke Date: Wed, 10 Feb 2016 16:16:56 +0100 Subject: [PATCH 08/43] 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); From 7cbdc33f840fa53075af983a6e3157baaf3c10bd Mon Sep 17 00:00:00 2001 From: Jocke Date: Wed, 10 Feb 2016 17:39:23 +0100 Subject: [PATCH 09/43] Updated submodules --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 7531e441..1c510a53 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 7531e441fea639076d69c6cf05e3ae8ff7170cf9 +Subproject commit 1c510a53d38b0f443ef141ddb3265a76c394ef7c From 95fa1f4bbd4f1b757e05236d58aec9802a218973 Mon Sep 17 00:00:00 2001 From: Jocke Date: Wed, 10 Feb 2016 20:10:20 +0100 Subject: [PATCH 10/43] Connect Fix for TCP Client --- src/Engine/Network/TCPClient.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp index 21bb653f..703e4cbe 100644 --- a/src/Engine/Network/TCPClient.cpp +++ b/src/Engine/Network/TCPClient.cpp @@ -19,16 +19,25 @@ void TCPClient::Connect(std::string playerName, std::string address, int port) Send(packet); LOG_INFO("Connect message sent again!"); } - return; + else { + boost::system::error_code error = boost::asio::error::host_not_found; + m_Socket->connect(m_Endpoint, error); + if (!error) { + m_IsConnected = true; + Packet packet(MessageType::Connect, m_SendPacketID); + packet.WriteString(playerName); + Send(packet); + LOG_INFO("Connect message sent!"); + } + } } - if (!m_IsConnected) { + else if (!m_IsConnected) { boost::system::error_code error = boost::asio::error::host_not_found; m_Endpoint = tcp::endpoint(boost::asio::ip::address::from_string(address), port); - m_Socket = std::unique_ptr(new tcp::socket(m_IOService, m_Endpoint)); + m_Socket = std::unique_ptr(new tcp::socket(m_IOService)); + m_Socket->connect(m_Endpoint, error); tcp::no_delay option(true); m_Socket->set_option(option); - m_Socket->close(); - m_Socket->connect(m_Endpoint, error); LOG_INFO(error.message().c_str()); if (!error) { m_IsConnected = true; From ec54b1298d0b7d383ae837337ded5eb190705f44 Mon Sep 17 00:00:00 2001 From: Jocke Date: Wed, 10 Feb 2016 21:02:46 +0100 Subject: [PATCH 11/43] Reconnect is now possible. --- include/Engine/Network/TCPServer.h | 1 + src/Engine/Network/Client.cpp | 5 +++-- src/Engine/Network/Server.cpp | 2 ++ src/Engine/Network/TCPClient.cpp | 9 ++++++++- src/Engine/Network/TCPServer.cpp | 5 +++++ 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/include/Engine/Network/TCPServer.h b/include/Engine/Network/TCPServer.h index b1aa7ce0..9cc7646a 100644 --- a/include/Engine/Network/TCPServer.h +++ b/include/Engine/Network/TCPServer.h @@ -15,6 +15,7 @@ public: void Receive(Packet & packet, PlayerDefinition & playerDefinition); void Send(Packet & packet, PlayerDefinition & playerDefinition); void Send(Packet & packet); + void Disconnect(); private: // TCP logic boost::asio::io_service m_IOService; diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 4eaefde2..f7fc956c 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -58,13 +58,14 @@ void Client::Update() } if (m_IsConnected) { - hasServerTimedOut(); // Don't send 1 input in 1 packet, bunch em up. if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) { sendInputCommands(); m_TimeSinceSentInputs = std::clock(); } sendLocalPlayerTransform(); + + m_IsConnected = !hasServerTimedOut(); } //Network::Update(); } @@ -380,7 +381,7 @@ bool Client::hasServerTimedOut() if (timeSincePing > m_TimeoutMs) { // Clear everything and go to menu. LOG_INFO("Server has timed out, returning to menu, Beep Boop."); - m_IsConnected = false; + m_Reliable.Disconnect(); return true; } return false; diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index bc2099bd..0c9af69c 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -302,6 +302,8 @@ void Server::disconnect(PlayerID playerID) e.PlayerID = playerID; m_EventBroker->Publish(e); + m_ConnectedPlayers[playerID].TCPSocket->shutdown(boost::asio::ip::tcp::socket::shutdown_both); + m_ConnectedPlayers[playerID].TCPSocket->close(); m_ConnectedPlayers.erase(playerID); } diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp index 703e4cbe..5c8ccee7 100644 --- a/src/Engine/Network/TCPClient.cpp +++ b/src/Engine/Network/TCPClient.cpp @@ -51,7 +51,10 @@ void TCPClient::Connect(std::string playerName, std::string address, int port) void TCPClient::Disconnect() { - + m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both); + m_Socket->close(); + m_Socket = nullptr; + m_IsConnected = false; } void TCPClient::Receive(Packet& packet) @@ -87,6 +90,10 @@ int TCPClient::readBuffer(char* data) void TCPClient::Send(Packet & packet) { + if (!m_Socket) { + LOG_WARNING("TCPClient::Send: Socket is null"); + return; + } packet.UpdateSize(); boost::system::error_code error; m_Socket->send(boost::asio::buffer( diff --git a/src/Engine/Network/TCPServer.cpp b/src/Engine/Network/TCPServer.cpp index 0b44013d..2bfcde74 100644 --- a/src/Engine/Network/TCPServer.cpp +++ b/src/Engine/Network/TCPServer.cpp @@ -72,6 +72,11 @@ void TCPServer::Send(Packet & packet) 0); } +void TCPServer::Disconnect() +{ + +} + void TCPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition) { int bytesRead = readBuffer(m_ReadBuffer, playerDefinition); From eb244f87c4e773fd2939d24e2141cbeae10b2705 Mon Sep 17 00:00:00 2001 From: Jocke Date: Wed, 10 Feb 2016 23:27:46 +0100 Subject: [PATCH 12/43] Added disconnect functionality and removed some warnings. --- include/Engine/Network/Client.h | 2 +- include/Engine/Network/Packet.h | 2 +- include/Engine/Network/Server.h | 9 +++++---- include/Engine/Network/TCPClient.h | 2 +- src/Engine/Network/Client.cpp | 11 +++++------ src/Engine/Network/Packet.cpp | 2 +- src/Engine/Network/Server.cpp | 13 ++++++++++--- src/Engine/Network/TCPClient.cpp | 9 ++++++--- src/Engine/Network/TCPServer.cpp | 2 +- 9 files changed, 31 insertions(+), 21 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 4ff2ecf8..76bb0470 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -82,7 +82,7 @@ protected: void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void parseSnapshot(Packet& packet); void identifyPacketLoss(); - bool hasServerTimedOut(); + void hasServerTimedOut(); EntityID createPlayer(); void sendInputCommands(); void sendLocalPlayerTransform(); diff --git a/include/Engine/Network/Packet.h b/include/Engine/Network/Packet.h index 694fd703..b688b8c6 100644 --- a/include/Engine/Network/Packet.h +++ b/include/Engine/Network/Packet.h @@ -50,7 +50,7 @@ public: // Pops the first element as if it was a string. std::string ReadString(); // Construct a packet - void ReconstructFromData(char* data, int SizeOfData); + void ReconstructFromData(char* data, size_t SizeOfData); // Update size of packet variable in header void UpdateSize(); char* ReadData(int SizeOfData); diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 308a74ed..ee40b707 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -27,12 +27,16 @@ public: ~Server(); void Start(World* m_world, EventBroker *eventBroker) override; void Update() override; -protected: +private: + // Network channels + TCPServer m_Reliable; + UDPServer m_Unreliable; // 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; + std::vector m_PlayersToDisconnect; // HACK: Fix INPUTSIZE char readBuffer[BUFFERSIZE] = { 0 }; size_t bytesRead = 0; @@ -88,9 +92,6 @@ protected: bool OnEntityDeleted(const Events::EntityDeleted& e); EventRelay m_EComponentDeleted; bool OnComponentDeleted(const Events::ComponentDeleted& e); -private: - TCPServer m_Reliable; - UDPServer m_Unreliable; }; #endif diff --git a/include/Engine/Network/TCPClient.h b/include/Engine/Network/TCPClient.h index 9f61cca5..a666cbbe 100644 --- a/include/Engine/Network/TCPClient.h +++ b/include/Engine/Network/TCPClient.h @@ -20,7 +20,7 @@ private: boost::asio::ip::tcp::endpoint m_Endpoint; boost::asio::io_service m_IOService; std::unique_ptr m_Socket; - int readBuffer(char* data); + size_t readBuffer(char* data); PacketID m_SendPacketID = 0; bool m_IsConnected = false; }; diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index f7fc956c..c5c7596e 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -64,8 +64,8 @@ void Client::Update() m_TimeSinceSentInputs = std::clock(); } sendLocalPlayerTransform(); - - m_IsConnected = !hasServerTimedOut(); + + hasServerTimedOut(); } //Network::Update(); } @@ -290,6 +290,7 @@ void Client::disconnect() m_PacketID = 0; Packet packet(MessageType::Disconnect, m_SendPacketID); m_Reliable.Send(packet); + m_Reliable.Disconnect(); } bool Client::OnInputCommand(const Events::InputCommand & e) @@ -374,17 +375,15 @@ void Client::identifyPacketLoss() } } -bool Client::hasServerTimedOut() +void Client::hasServerTimedOut() { // Time in ms double timeSincePing = 1000 * (std::clock() - m_StartPingTime) / static_cast(CLOCKS_PER_SEC); if (timeSincePing > m_TimeoutMs) { // Clear everything and go to menu. LOG_INFO("Server has timed out, returning to menu, Beep Boop."); - m_Reliable.Disconnect(); - return true; + disconnect(); } - return false; } EntityID Client::createPlayer() diff --git a/src/Engine/Network/Packet.cpp b/src/Engine/Network/Packet.cpp index af8f91c2..475ca673 100644 --- a/src/Engine/Network/Packet.cpp +++ b/src/Engine/Network/Packet.cpp @@ -81,7 +81,7 @@ std::string Packet::ReadString() return returnValue; } -void Packet::ReconstructFromData(char * data, int sizeOfData) +void Packet::ReconstructFromData(char * data, size_t sizeOfData) { if (sizeOfData > m_MaxPacketSize) { // Delete our data diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 0c9af69c..8a0ecd36 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -53,6 +53,11 @@ void Server::Update() parseMessageType(packet); } } + // Check if players have disconnected + for (int i = 0; i < m_PlayersToDisconnect.size(); i++) { + disconnect(m_PlayersToDisconnect.at(i)); + } + m_PlayersToDisconnect.clear(); std::clock_t currentTime = std::clock(); // Send snapshot @@ -74,6 +79,7 @@ void Server::Update() if (isReadingData) { Network::Update(); } + } void Server::parseMessageType(Packet& packet) @@ -249,7 +255,7 @@ void Server::parseTCPConnect(Packet & packet) // 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 // Ska vara till lagd i TCPServer receive @@ -286,7 +292,7 @@ void Server::parseDisconnect() for (auto& kv : m_ConnectedPlayers) { if (kv.second.TCPAddress == m_Address && kv.second.TCPPort == m_Port) { - disconnect(kv.first); + m_PlayersToDisconnect.push_back(kv.first); break; } } @@ -301,10 +307,11 @@ void Server::disconnect(PlayerID playerID) e.Entity = m_ConnectedPlayers.at(playerID).EntityID; e.PlayerID = playerID; m_EventBroker->Publish(e); - + //m_World->DeleteEntity(m_ConnectedPlayers[playerID].EntityID); m_ConnectedPlayers[playerID].TCPSocket->shutdown(boost::asio::ip::tcp::socket::shutdown_both); m_ConnectedPlayers[playerID].TCPSocket->close(); m_ConnectedPlayers.erase(playerID); + // Send disconnect to the other players. } void Server::parseOnPlayerDamage(Packet & packet) diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp index 5c8ccee7..38bac621 100644 --- a/src/Engine/Network/TCPClient.cpp +++ b/src/Engine/Network/TCPClient.cpp @@ -51,6 +51,9 @@ void TCPClient::Connect(std::string playerName, std::string address, int port) void TCPClient::Disconnect() { + if (!m_IsConnected) { + return; + } m_Socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both); m_Socket->close(); m_Socket = nullptr; @@ -59,20 +62,20 @@ void TCPClient::Disconnect() void TCPClient::Receive(Packet& packet) { - int bytesRead = readBuffer(m_ReadBuffer); + size_t bytesRead = readBuffer(m_ReadBuffer); if (bytesRead > 0) { packet.ReconstructFromData(m_ReadBuffer, bytesRead); } } -int TCPClient::readBuffer(char* data) +size_t TCPClient::readBuffer(char* data) { if (!m_Socket) { return 0; } boost::system::error_code error; // Read size of packet - int bytesReceived = m_Socket->read_some(boost + size_t bytesReceived = m_Socket->read_some(boost ::asio::buffer((void*)data, sizeof(int)), error); int sizeOfPacket = 0; diff --git a/src/Engine/Network/TCPServer.cpp b/src/Engine/Network/TCPServer.cpp index 2bfcde74..a449e684 100644 --- a/src/Engine/Network/TCPServer.cpp +++ b/src/Engine/Network/TCPServer.cpp @@ -93,7 +93,7 @@ int TCPServer::readBuffer(char* data, PlayerDefinition & playerDefinition) } boost::system::error_code error; // Read size of packet - int bytesReceived = playerDefinition.TCPSocket->read_some(boost + size_t bytesReceived = playerDefinition.TCPSocket->read_some(boost ::asio::buffer((void*)data, sizeof(int)), error); int sizeOfPacket = 0; From fa2e556ab2d2865ea29c7ef1a4735f845bdbc83c Mon Sep 17 00:00:00 2001 From: Jocke Date: Thu, 11 Feb 2016 14:07:51 +0100 Subject: [PATCH 13/43] fixed some error handling in TCPClient. --- src/Engine/Network/Server.cpp | 2 +- src/Engine/Network/TCPClient.cpp | 16 +++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 8a0ecd36..cc774c2f 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -272,7 +272,7 @@ void Server::parseTCPConnect(Packet & packet) 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); + m_ConnectedPlayers.at(playerID).TCPAddress.to_string().c_str()); // Send a message to the player that connected Packet connnectPacket(MessageType::Connect, m_ConnectedPlayers.at(playerID).PacketID); diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp index 38bac621..df4f3826 100644 --- a/src/Engine/Network/TCPClient.cpp +++ b/src/Engine/Network/TCPClient.cpp @@ -19,17 +19,6 @@ void TCPClient::Connect(std::string playerName, std::string address, int port) Send(packet); LOG_INFO("Connect message sent again!"); } - else { - boost::system::error_code error = boost::asio::error::host_not_found; - m_Socket->connect(m_Endpoint, error); - if (!error) { - m_IsConnected = true; - Packet packet(MessageType::Connect, m_SendPacketID); - packet.WriteString(playerName); - Send(packet); - LOG_INFO("Connect message sent!"); - } - } } else if (!m_IsConnected) { boost::system::error_code error = boost::asio::error::host_not_found; @@ -46,6 +35,11 @@ void TCPClient::Connect(std::string playerName, std::string address, int port) Send(packet); LOG_INFO("Connect message sent!"); } + // If error + else { + m_Socket->close(); + m_Socket = nullptr; + } } } From 49d4a45ef87f86b56b9896f1cdd3250e4ba92086 Mon Sep 17 00:00:00 2001 From: Jocke Date: Thu, 11 Feb 2016 16:27:33 +0100 Subject: [PATCH 14/43] Client crashed when connecting, this was a hot fix. --- src/Engine/Rendering/PickingPass.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index cc9837ff..07440749 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -104,8 +104,11 @@ void PickingPass::Draw(RenderScene& scene) std::vector frameBones; frameBones = modelJob->Skeleton->GetBones(); - glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - + // temp check revise later crashed client when connectiong + // frameBones.size() was 0 // Jocke + if (frameBones.size() > 0) { + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } } } else { m_PickingProgram->Bind(); From fee50ba3b6e0b025c6f0ae4ec17be5153ca1b306 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 11 Feb 2016 21:16:10 +0100 Subject: [PATCH 15/43] Crash fix --- src/Game/Systems/CapturePointHUDSystem.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Game/Systems/CapturePointHUDSystem.cpp b/src/Game/Systems/CapturePointHUDSystem.cpp index 784c7e16..5369b830 100644 --- a/src/Game/Systems/CapturePointHUDSystem.cpp +++ b/src/Game/Systems/CapturePointHUDSystem.cpp @@ -17,6 +17,10 @@ void CapturePointHUDSystem::Update(double dt) auto CapturePointHUDElements = m_World->GetComponents("CapturePointHUD"); auto CapturePoints = m_World->GetComponents("CapturePoint"); + if(!CapturePointHUDElements) { + return; + } + for (auto& cCapturePointHUD : *CapturePointHUDElements) { int HUD_ID = cCapturePointHUD["CapturePointNumber"]; EntityWrapper entityHUD = EntityWrapper(m_World, cCapturePointHUD.EntityID); From afd9e24df64d0c4d7541aee9c327180ee2427fa0 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 11 Feb 2016 21:23:53 +0100 Subject: [PATCH 16/43] Reverted last commit. Also testing to delay OnPlayerSpawn event for clients. No progress... --- include/Engine/Network/Client.h | 2 + src/Engine/Network/Client.cpp | 29 ++++++++++++-- src/Engine/Rendering/PickingPass.cpp | 59 +++++++++++++--------------- 3 files changed, 54 insertions(+), 36 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 7ea63ad8..f2b18eee 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -35,6 +35,8 @@ public: void Connect(std::string address, int port); void Update() override; + std::vector m_PlayerSpawnEvents; + void parseSpawnEvents(); // Save for children std::unique_ptr m_SnapshotFilter = nullptr; diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 7c19d852..d88becdb 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -54,7 +54,6 @@ void Client::Update() parseMessageType(packet); } } - while (m_Reliable.IsSocketAvailable()) { // Packet will get real data in receive Packet packet(MessageType::Invalid); @@ -177,14 +176,35 @@ void Client::parseKick() m_IsConnected = false; } +void Client::parseSpawnEvents() +{ + for (int i = 0; i < m_PlayerSpawnEvents.size(); i++) { + Events::PlayerSpawned e; + e.Player = EntityWrapper(m_World, m_ServerIDToClientID[m_PlayerSpawnEvents[i].Player.ID]); + e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[m_PlayerSpawnEvents[i].Spawner.ID]); + e.PlayerID = -1; + e.PlayerName = m_PlayerSpawnEvents[i].PlayerName; + m_EventBroker->Publish(e); + } + m_PlayerSpawnEvents.clear(); +} + void Client::parsePlayersSpawned(Packet& packet) { + //Events::PlayerSpawned e; + //e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive()]); + //e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive()]); + //e.PlayerID = -1; + //e.PlayerName = packet.ReadString(); + //m_EventBroker->Publish(e); + Events::PlayerSpawned e; - e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive()]); - e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive()]); + e.Player = EntityWrapper(m_World, packet.ReadPrimitive()); + e.Spawner = EntityWrapper(m_World, packet.ReadPrimitive()); e.PlayerID = -1; e.PlayerName = packet.ReadString(); - m_EventBroker->Publish(e); + m_PlayerSpawnEvents.push_back(e); + parseSpawnEvents(); } void Client::parseEntityDeletion(Packet & packet) @@ -322,6 +342,7 @@ void Client::parseSnapshot(Packet& packet) m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID)); } } + // parseSpawnEvents(); } void Client::disconnect() diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 07440749..2a0a8cf8 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -42,22 +42,22 @@ void PickingPass::InitializeShaderPrograms() m_PickingProgram->BindFragDataLocation(0, "TextureFragment"); m_PickingProgram->Link(); - m_PickingSkinnedProgram = ResourceManager::Load("#PickingSkinnedProgram"); + m_PickingSkinnedProgram = ResourceManager::Load("#PickingSkinnedProgram"); - m_PickingSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/PickingSkinned.vert.glsl"))); - m_PickingSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/Picking.frag.glsl"))); - m_PickingSkinnedProgram->Compile(); - m_PickingSkinnedProgram->BindFragDataLocation(0, "TextureFragment"); - m_PickingSkinnedProgram->Link(); + m_PickingSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/PickingSkinned.vert.glsl"))); + m_PickingSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/Picking.frag.glsl"))); + m_PickingSkinnedProgram->Compile(); + m_PickingSkinnedProgram->BindFragDataLocation(0, "TextureFragment"); + m_PickingSkinnedProgram->Link(); } void PickingPass::Draw(RenderScene& scene) { PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle()); - + //TODO: Render: Add code for more jobs than modeljobs. GLuint shaderHandle = m_PickingProgram->GetHandle(); - GLuint shaderSkinnedHandle = m_PickingSkinnedProgram->GetHandle(); + GLuint shaderSkinnedHandle = m_PickingSkinnedProgram->GetHandle(); m_PickingProgram->Bind(); if (scene.ClearDepth) { @@ -92,31 +92,26 @@ void PickingPass::Draw(RenderScene& scene) m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; - if (modelJob->Model->IsSkinned()) - { - m_PickingSkinnedProgram->Bind(); - glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); - glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); + if (modelJob->Model->IsSkinned()) { + m_PickingSkinnedProgram->Bind(); + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); - if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { + if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { std::vector frameBones; frameBones = modelJob->Skeleton->GetBones(); - // temp check revise later crashed client when connectiong - // frameBones.size() was 0 // Jocke - if (frameBones.size() > 0) { - glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } - } - } else { + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } else { m_PickingProgram->Bind(); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); - glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); - } + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); + } glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); @@ -202,7 +197,7 @@ void PickingPass::Draw(RenderScene& scene) m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; - if(modelJob->Model->IsSkinned()) { + if (modelJob->Model->IsSkinned()) { m_PickingSkinnedProgram->Bind(); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); @@ -257,7 +252,7 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->IsSkinned()) { m_PickingSkinnedProgram->Bind(); - + glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); @@ -280,7 +275,7 @@ void PickingPass::Draw(RenderScene& scene) glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); } - + glBindVertexArray(modelJob->Model->VAO); @@ -288,7 +283,7 @@ void PickingPass::Draw(RenderScene& scene) glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); } } - + m_PickingBuffer.Unbind(); GLERROR("PickingPass Error"); From b66e3d36309da8b1dffe736ed37d22848d22525f Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 11 Feb 2016 22:15:47 +0100 Subject: [PATCH 17/43] WIP trying to hot fix --- src/Engine/Network/Client.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index d88becdb..d6aece06 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -178,15 +178,22 @@ void Client::parseKick() void Client::parseSpawnEvents() { + std::vector tempSpawn; for (int i = 0; i < m_PlayerSpawnEvents.size(); i++) { Events::PlayerSpawned e; - e.Player = EntityWrapper(m_World, m_ServerIDToClientID[m_PlayerSpawnEvents[i].Player.ID]); - e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[m_PlayerSpawnEvents[i].Spawner.ID]); + if (!serverClientMapsHasEntity(m_PlayerSpawnEvents.at(i).Player.ID) || + !serverClientMapsHasEntity(m_PlayerSpawnEvents.at(i).Spawner.ID)) { + tempSpawn.push_back(m_PlayerSpawnEvents.at(i)); + continue; + } + e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Player.ID)); + e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Spawner.ID)); e.PlayerID = -1; - e.PlayerName = m_PlayerSpawnEvents[i].PlayerName; + e.PlayerName = m_PlayerSpawnEvents.at(i).PlayerName; m_EventBroker->Publish(e); } - m_PlayerSpawnEvents.clear(); + m_PlayerSpawnEvents = tempSpawn; + // m_PlayerSpawnEvents.clear(); } void Client::parsePlayersSpawned(Packet& packet) From c1860ae383faacdce63f2b374f5c9c645bdbde8b Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 11 Feb 2016 23:38:25 +0100 Subject: [PATCH 18/43] AmmunitionHUD now working --- include/Game/Systems/HealthHUDSystem - Copy.h | 17 ++ .../{PlayerHUDSystem.h => HealthHUDSystem.h} | 6 +- resources/Schema/Components.xsd | 1 + resources/Schema/Components/AmmunitionHUD.xml | 3 + resources/Schema/Components/AmmunitionHUD.xsd | 10 + ...PointHUDGroup => CapturePointHUDGroup.xml} | 0 resources/Schema/Entities/Player.xml | 235 ++++++++++++++++-- resources/Schema/Types/Entity.xsd | 1 + src/Game/Game.cpp | 7 +- ...layerHUDSystem.cpp => HealthHUDSystem.cpp} | 8 +- 10 files changed, 263 insertions(+), 25 deletions(-) create mode 100644 include/Game/Systems/HealthHUDSystem - Copy.h rename include/Game/Systems/{PlayerHUDSystem.h => HealthHUDSystem.h} (57%) create mode 100644 resources/Schema/Components/AmmunitionHUD.xml create mode 100644 resources/Schema/Components/AmmunitionHUD.xsd rename resources/Schema/Entities/{CapturePointHUDGroup => CapturePointHUDGroup.xml} (100%) rename src/Game/Systems/{PlayerHUDSystem.cpp => HealthHUDSystem.cpp} (85%) diff --git a/include/Game/Systems/HealthHUDSystem - Copy.h b/include/Game/Systems/HealthHUDSystem - Copy.h new file mode 100644 index 00000000..b22a85b5 --- /dev/null +++ b/include/Game/Systems/HealthHUDSystem - Copy.h @@ -0,0 +1,17 @@ +#ifndef AmmunitionHUDSystem_h__ +#define AmmunitionHUDSystem_h__ + +#include "../../Engine/Core/System.h" +#include "../../Engine/GLM.h" + +class AmmunitionHUDSystem : public ImpureSystem +{ +public: + AmmunitionHUDSystem(SystemParams params) + : System(params) + { } + + virtual void Update(double dt) override; +}; + +#endif \ No newline at end of file diff --git a/include/Game/Systems/PlayerHUDSystem.h b/include/Game/Systems/HealthHUDSystem.h similarity index 57% rename from include/Game/Systems/PlayerHUDSystem.h rename to include/Game/Systems/HealthHUDSystem.h index 50b6a258..49a40041 100644 --- a/include/Game/Systems/PlayerHUDSystem.h +++ b/include/Game/Systems/HealthHUDSystem.h @@ -3,13 +3,11 @@ #include "../../Engine/Core/System.h" #include "../../Engine/GLM.h" -#include "../../Engine/Rendering/ESetCamera.h" -#include -class PlayerHUDSystem : public ImpureSystem +class HealthHUDSystem : public ImpureSystem { public: - PlayerHUDSystem(SystemParams params) + HealthHUDSystem(SystemParams params) : System(params) { } diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index f950e8c8..2a1b67e0 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -39,4 +39,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/AmmunitionHUD.xml b/resources/Schema/Components/AmmunitionHUD.xml new file mode 100644 index 00000000..63b86150 --- /dev/null +++ b/resources/Schema/Components/AmmunitionHUD.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/Schema/Components/AmmunitionHUD.xsd b/resources/Schema/Components/AmmunitionHUD.xsd new file mode 100644 index 00000000..1a48d8d1 --- /dev/null +++ b/resources/Schema/Components/AmmunitionHUD.xsd @@ -0,0 +1,10 @@ + + + + + + + Hud element for tracking ammunition from parent with AssaultWeapon component. Child with the name "MagazineAmmo" tracks clip ammunition. Child with the name "Ammo" tracks ammo. + + + \ No newline at end of file diff --git a/resources/Schema/Entities/CapturePointHUDGroup b/resources/Schema/Entities/CapturePointHUDGroup.xml similarity index 100% rename from resources/Schema/Entities/CapturePointHUDGroup rename to resources/Schema/Entities/CapturePointHUDGroup.xml diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 4ba23a0d..8a5a4d24 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -12,9 +12,7 @@ - - - + 5 @@ -73,17 +71,17 @@ 1 - + + + Textures/Core/UnitHexagon.png + + - - Models/Core/UnitHexagon.mesh - - - + @@ -101,13 +99,182 @@ + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 2 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 3 + + + 0.80222018197612788 + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 4 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 1 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + Idle - 0.52743271827223559 + 0.14471987707210765 1 @@ -126,8 +293,8 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - - + + @@ -142,6 +309,44 @@ + + + + + + + + + + + + + 32 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + 360 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + @@ -166,7 +371,7 @@ Idle - 0.69666320633760392 + 1.7139414005989018 1 @@ -190,8 +395,8 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - - + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index ffe3421a..3e521007 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -43,6 +43,7 @@ + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 8ee6dbed..cd8abb87 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -17,12 +17,14 @@ #include "Game/Systems/DamageIndicatorSystem.h" #include "Game/Systems/WeaponSystem.h" #include "Rendering/AnimationSystem.h" -#include "Game/Systems/PlayerHUDSystem.h" +#include "Game/Systems/HealthHUDSystem.h" #include "Rendering/BoneAttachmentSystem.h" #include "Game/Systems/LifetimeSystem.h" #include "../Engine/Core/UniformScaleSystem.h" #include "Rendering/AnimationSystem.h" #include "Network/MultiplayerSnapshotFilter.h" +#include "Game/Systems/AmmunitionHUDSystem.h" + Game::Game(int argc, char* argv[]) { @@ -125,6 +127,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); @@ -132,7 +135,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeFrustrumCulling); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); - m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); // Collision and TriggerSystem should update after player. ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel); diff --git a/src/Game/Systems/PlayerHUDSystem.cpp b/src/Game/Systems/HealthHUDSystem.cpp similarity index 85% rename from src/Game/Systems/PlayerHUDSystem.cpp rename to src/Game/Systems/HealthHUDSystem.cpp index 898d8bea..49b2d0c1 100644 --- a/src/Game/Systems/PlayerHUDSystem.cpp +++ b/src/Game/Systems/HealthHUDSystem.cpp @@ -1,6 +1,6 @@ -#include "Game/Systems/PlayerHUDSystem.h" +#include "Game/Systems/HealthHUDSystem.h" -void PlayerHUDSystem::Update(double dt) +void HealthHUDSystem::Update(double dt) { auto healthHUDs = m_World->GetComponents("HealthHUD"); if (healthHUDs == nullptr) { @@ -27,13 +27,13 @@ void PlayerHUDSystem::Update(double dt) s = s + "/"; s = s + std::to_string((int)(double)entityIDParent["Health"]["MaxHealth"]); float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"]; - (glm::vec4&)entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, 1.f); + (glm::vec4&)entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, glm::vec4(entity["Fill"]["Color"]).a); entity["Text"]["Content"] = s; } if(entity.HasComponent("Fill")) { float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"]; - (glm::vec4&)entity["Fill"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, 0.f); + (glm::vec4&)entity["Fill"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, glm::vec4(entity["Fill"]["Color"]).a); (double&)entity["Fill"]["Percentage"] = healthPercentage; } From 30f454e6a44d31de85cfd87b64f701f970bd491a Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 11 Feb 2016 23:50:57 +0100 Subject: [PATCH 19/43] Entity fixes --- resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml | 4 +--- resources/Schema/Types/Entity.xsd | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml b/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml index 8a9f5e5b..3ec16e4e 100644 --- a/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml +++ b/resources/Schema/Entities/PlayerDeathExplosionWithCamera.xml @@ -2,9 +2,7 @@ - - Hold Pos - + 2.5 diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index ffe3421a..b8a863e2 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -43,6 +43,7 @@ + From e24a84c52d87591d58d848a9c229dfc0f73911f1 Mon Sep 17 00:00:00 2001 From: stiffly Date: Thu, 11 Feb 2016 23:52:55 +0100 Subject: [PATCH 20/43] Server now deletes the player on a new player spawn. --- src/Engine/Network/Client.cpp | 5 +++-- src/Game/Systems/PlayerSpawnSystem.cpp | 9 ++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index d6aece06..d75b8412 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -287,7 +287,8 @@ void Client::parseSnapshot(Packet& packet) for (std::size_t i = 0; i < numInputCommands; ++i) { Events::InputCommand e; e.PlayerID = packet.ReadPrimitive(); - e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(packet.ReadPrimitive())); + EntityID player = packet.ReadPrimitive(); + e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(player)); e.Command = packet.ReadString(); e.Value = packet.ReadPrimitive(); m_EventBroker->Publish(e); @@ -349,7 +350,7 @@ void Client::parseSnapshot(Packet& packet) m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID)); } } - // parseSpawnEvents(); + parseSpawnEvents(); } void Client::disconnect() diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 507ed0f5..e2775280 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -71,18 +71,17 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e) bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) { // When a player is actually spawned (since the actual spawning is handled on the server) - if (!IsClient) { - return false; - } - // Check if a player already exists + // Hack should be moved. if (m_PlayerEntities.count(e.PlayerID) != 0) { // TODO: Disallow infinite respawning here if (m_PlayerEntities[e.PlayerID].Valid()) { m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID); } } - + if (!IsClient) { + return false; + } // Store the player for future reference m_PlayerEntities[e.PlayerID] = e.Player; From a36ed76a4e42bf0a4ad116b86b4b8f603fcf3021 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Fri, 12 Feb 2016 00:26:59 +0100 Subject: [PATCH 21/43] AmmunitionHUDSystem now really working --- assets | 2 +- ...DSystem - Copy.h => AmmunitionHUDSystem.h} | 0 resources/Schema/Entities/Player.xml | 17 ++++----- src/Game/Systems/AmmunitionHUDSystem.cpp | 36 +++++++++++++++++++ 4 files changed, 46 insertions(+), 9 deletions(-) rename include/Game/Systems/{HealthHUDSystem - Copy.h => AmmunitionHUDSystem.h} (100%) create mode 100644 src/Game/Systems/AmmunitionHUDSystem.cpp diff --git a/assets b/assets index dfa0fc61..4d36fdce 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit dfa0fc61ab88456f3461779bd7c6ac97d15f6493 +Subproject commit 4d36fdced7007a594a56b7371bb26861876889aa diff --git a/include/Game/Systems/HealthHUDSystem - Copy.h b/include/Game/Systems/AmmunitionHUDSystem.h similarity index 100% rename from include/Game/Systems/HealthHUDSystem - Copy.h rename to include/Game/Systems/AmmunitionHUDSystem.h diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 8a5a4d24..910e440f 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -274,7 +274,7 @@ Idle - 0.14471987707210765 + 1.9901368826444736 1 @@ -293,8 +293,8 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - - + + @@ -313,8 +313,9 @@ - - + + + @@ -371,7 +372,7 @@ Idle - 1.7139414005989018 + 0.22602443705505681 1 @@ -395,8 +396,8 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - - + + diff --git a/src/Game/Systems/AmmunitionHUDSystem.cpp b/src/Game/Systems/AmmunitionHUDSystem.cpp new file mode 100644 index 00000000..c9d87072 --- /dev/null +++ b/src/Game/Systems/AmmunitionHUDSystem.cpp @@ -0,0 +1,36 @@ +#include "Game/Systems/AmmunitionHUDSystem.h" + +void AmmunitionHUDSystem::Update(double dt) +{ + //Hud element for tracking ammunition from parent with AssaultWeapon component.Child with the name "MagazineAmmo" tracks clip ammunition.Child with the name "Ammo" tracks ammo. + + auto ammunitionHUDs = m_World->GetComponents("AmmunitionHUD"); + if (ammunitionHUDs == nullptr) { + return; + } + + for (auto& ammunitionHUDComponent : *ammunitionHUDs) { + EntityWrapper entity = EntityWrapper(m_World, ammunitionHUDComponent.EntityID); + + EntityWrapper playerEntity = entity.FirstParentWithComponent("AssaultWeapon"); + + if (!playerEntity.Valid()) { + return; + } + + + EntityWrapper magazineAmmo = entity.FirstChildByName("MagazineAmmo"); + if(magazineAmmo.Valid()) { + if(magazineAmmo.HasComponent("Text")) { + (std::string&)magazineAmmo["Text"]["Content"] = std::to_string((int)playerEntity["AssaultWeapon"]["MagazineAmmo"]); + } + } + + EntityWrapper ammo = entity.FirstChildByName("Ammo"); + if (ammo.Valid()) { + if (ammo.HasComponent("Text")) { + (std::string&)ammo["Text"]["Content"] = std::to_string((int)playerEntity["AssaultWeapon"]["Ammo"]); + } + } + } +} From 3b42f5dbf412e972efbf7f52d27eccf5a49e530f Mon Sep 17 00:00:00 2001 From: Jocke Date: Fri, 12 Feb 2016 01:33:45 +0100 Subject: [PATCH 22/43] Fixed server so it now deletes. --- src/Game/Systems/PlayerSpawnSystem.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index e2775280..108fa502 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -79,11 +79,12 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID); } } + // Store the player for future reference + m_PlayerEntities[e.PlayerID] = e.Player; + if (!IsClient) { return false; } - // Store the player for future reference - m_PlayerEntities[e.PlayerID] = e.Player; // Set the camera to the correct entity EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera"); From 529513331121a9ee0c5598029c490ec782b356c6 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 12 Feb 2016 01:45:54 +0100 Subject: [PATCH 23/43] Hack to sync ammo over network until we have input replaying + Reload effect from all views --- .../Systems/Weapon/AssaultWeaponBehaviour.h | 5 +- .../Schema/Entities/DoubleJumpHexagon.xml | 23 ++-- resources/Schema/Entities/Player.xml | 38 ++++--- ...nReloadEffect.xml => ReloadEffectView.xml} | 9 +- .../Schema/Entities/ReloadEffectWorld.xml | 24 ++++ resources/Schema/Types/Entity.xsd | 1 + src/Engine/Network/Client.cpp | 12 +- src/Engine/Network/Server.cpp | 16 ++- src/Engine/Rendering/RenderSystem.cpp | 7 +- src/Game/Systems/PlayerMovementSystem.cpp | 3 +- .../Systems/Weapon/AssaultWeaponBehaviour.cpp | 104 +++++++++++++----- 11 files changed, 171 insertions(+), 71 deletions(-) rename resources/Schema/Entities/{WeaponReloadEffect.xml => ReloadEffectView.xml} (72%) create mode 100644 resources/Schema/Entities/ReloadEffectWorld.xml diff --git a/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h b/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h index 915854ff..0473cec3 100644 --- a/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h +++ b/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h @@ -1,6 +1,7 @@ #include "Sound/EPlaySoundOnEntity.h" #include "Collision/Collision.h" #include "Rendering/AnimationSystem.h" +#include "Core/ConfigFile.h" #include "WeaponBehaviour.h" #include "../SpawnerSystem.h" #include "Core/EPlayerDamage.h" @@ -19,11 +20,13 @@ public: private: EntityWrapper m_FirstPersonModel; + EntityWrapper m_ThirdPersonModel; // State bool m_Firing = false; bool m_Reloading = false; double m_ReloadTimer = 0.0; - EntityWrapper m_ReloadImpersonator; + EntityWrapper m_FirstPersonReloadImpersonator; + EntityWrapper m_ThirdPersonReloadImpersonator; double m_TimeSinceLastFire = 0.0; EventRelay m_EAnimationComplete; diff --git a/resources/Schema/Entities/DoubleJumpHexagon.xml b/resources/Schema/Entities/DoubleJumpHexagon.xml index c1aaec34..f4596efd 100644 --- a/resources/Schema/Entities/DoubleJumpHexagon.xml +++ b/resources/Schema/Entities/DoubleJumpHexagon.xml @@ -2,27 +2,26 @@ - - Models/Effects/JumpEffectHexagon.mesh - - true - - - - - 0.5 true - - + true 0.5 - + true + + Models/Effects/JumpEffectHexagon.mesh + + true + + + + + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 9f8e0955..05dc79e2 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -24,7 +24,7 @@ - + @@ -138,8 +138,8 @@ true - - + + @@ -154,17 +154,17 @@ + + + + Schema/Entities/ReloadEffectView.xml + + + + + - - - - Schema/Entities/WeaponReloadEffect.xml - - - - - @@ -209,11 +209,10 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - false - - + + @@ -228,6 +227,15 @@ + + + + Schema/Entities/ReloadEffectWorld.xml + + + + + diff --git a/resources/Schema/Entities/WeaponReloadEffect.xml b/resources/Schema/Entities/ReloadEffectView.xml similarity index 72% rename from resources/Schema/Entities/WeaponReloadEffect.xml rename to resources/Schema/Entities/ReloadEffectView.xml index 3099b405..ca7e6e1a 100644 --- a/resources/Schema/Entities/WeaponReloadEffect.xml +++ b/resources/Schema/Entities/ReloadEffectView.xml @@ -2,9 +2,6 @@ - - R_Arm_Weapon_Joint - 2 @@ -18,12 +15,8 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - true - - - - + diff --git a/resources/Schema/Entities/ReloadEffectWorld.xml b/resources/Schema/Entities/ReloadEffectWorld.xml new file mode 100644 index 00000000..97236897 --- /dev/null +++ b/resources/Schema/Entities/ReloadEffectWorld.xml @@ -0,0 +1,24 @@ + + + + + + 2 + + + true + + + true + + true + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + + + + + + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index b8a863e2..42b5d030 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -44,6 +44,7 @@ + diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index b03aad07..b0c8697f 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -411,16 +411,26 @@ void Client::sendLocalPlayerTransform() return; } + Packet packet(MessageType::PlayerTransform, m_SendPacketID); + ComponentWrapper cTransform = m_LocalPlayer["Transform"]; glm::vec3& position = cTransform["Position"]; glm::vec3& orientation = cTransform["Orientation"]; - Packet packet(MessageType::PlayerTransform, m_SendPacketID); packet.WritePrimitive(position.x); packet.WritePrimitive(position.y); packet.WritePrimitive(position.z); packet.WritePrimitive(orientation.x); packet.WritePrimitive(orientation.y); packet.WritePrimitive(orientation.z); + + bool hasAssaultWeapon = m_LocalPlayer.HasComponent("AssaultWeapon"); + packet.WritePrimitive(hasAssaultWeapon); + if (hasAssaultWeapon) { + ComponentWrapper cAssaultWeapon = m_LocalPlayer["AssaultWeapon"]; + packet.WritePrimitive((int)cAssaultWeapon["MagazineAmmo"]); + packet.WritePrimitive((int)cAssaultWeapon["Ammo"]); + } + send(packet); } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 1f0b3bc7..a6174f7a 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -288,7 +288,7 @@ void Server::parseOnInputCommand(Packet& packet) e.Value = packet.ReadPrimitive(); m_EventBroker->Publish(e); - if (e.Command == "PrimaryFire") { + if (e.Command == "PrimaryFire" || e.Command == "Reload") { m_InputCommandsToBroadcast.push_back(e); } //LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); @@ -464,11 +464,23 @@ void Server::parsePlayerTransform(Packet& packet) orientation.y = packet.ReadPrimitive(); orientation.z = packet.ReadPrimitive(); + bool hasAssaultWeapon = packet.ReadPrimitive(); + int magazineAmmo; + int ammo; + if (hasAssaultWeapon) { + magazineAmmo = packet.ReadPrimitive(); + ammo = 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; + + if (hasAssaultWeapon) { + player["AssaultWeapon"]["MagazineAmmo"] = magazineAmmo; + player["AssaultWeapon"]["Ammo"] = ammo; + } } } diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 7beb85db..665c4027 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -79,7 +79,6 @@ void RenderSystem::fillSprites(std::list>& jobs, Worl bool RenderSystem::isEntityVisible(EntityWrapper& entity) { - // Only render children of a camera if that camera is currently active if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) { return false; @@ -87,7 +86,11 @@ bool RenderSystem::isEntityVisible(EntityWrapper& entity) // Hide things parented to local player if they have the HiddenFromLocalPlayer component bool outOfBodyExperience = ResourceManager::Load("Config.ini")->Get("Debug.OutOfBodyExperience", false); - if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) && !outOfBodyExperience) { + if ( + (entity.HasComponent("HiddenForLocalPlayer") || entity.FirstParentWithComponent("HiddenForLocalPlayer").Valid()) + && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) + && !outOfBodyExperience + ) { return false; } diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 461c7098..badaf638 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -40,7 +40,8 @@ void PlayerMovementSystem::updateMovementControllers(double dt) EntityWrapper playerModel = player.FirstChildByName("PlayerModel"); if (playerModel.Valid()) { ComponentWrapper cAnimationOffset = playerModel["AnimationOffset"]; - double time = (cameraOrientation.x + glm::half_pi()) / glm::pi(); + float pitch = cameraOrientation.x + 0.2; + double time = (pitch + glm::half_pi()) / glm::pi(); cAnimationOffset["Time"] = time; } } diff --git a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp index 54c3a590..72b98639 100644 --- a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp @@ -4,6 +4,7 @@ AssaultWeaponBehaviour::AssaultWeaponBehaviour(SystemParams systemParams, IRende : WeaponBehaviour(systemParams, renderer, collisionOctree, player) { m_FirstPersonModel = m_Player.FirstChildByName("Hands"); + m_ThirdPersonModel = m_Player.FirstChildByName("PlayerModel"); EVENT_SUBSCRIBE_MEMBER(m_EAnimationComplete, &AssaultWeaponBehaviour::OnAnimationComplete); } @@ -50,9 +51,14 @@ void AssaultWeaponBehaviour::Update(double dt) if (m_Reloading) { m_ReloadTimer -= dt; // Re-enable glow on reload impersonator half-way through the animation - if (m_ReloadTimer <= (double)m_Player["AssaultWeapon"]["ReloadTime"] / 2.0) { - if (m_ReloadImpersonator.Valid()) { - m_ReloadImpersonator["Model"]["GlowMap"] = true; + if (IsClient) { + if (m_ReloadTimer <= (double)m_Player["AssaultWeapon"]["ReloadTime"] / 2.0) { + if (m_FirstPersonReloadImpersonator.Valid()) { + m_FirstPersonReloadImpersonator["Model"]["GlowMap"] = true; + } + if (m_ThirdPersonReloadImpersonator.Valid()) { + m_ThirdPersonReloadImpersonator["Model"]["GlowMap"] = true; + } } } if (m_ReloadTimer <= 0) { @@ -69,14 +75,18 @@ void AssaultWeaponBehaviour::Update(double dt) } if (!m_Firing && !m_Reloading) { - playIdleAnimation(); + if (IsClient) { + playIdleAnimation(); + } } // Disable glow map on weapon if it's out of ammo // Make real first person weapon model visible again - EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel"); - if (firstPersonWeaponModel.Valid()) { - firstPersonWeaponModel["Model"]["GlowMap"] = hasAmmo(); + if (IsClient) { + EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel"); + if (firstPersonWeaponModel.Valid()) { + firstPersonWeaponModel["Model"]["GlowMap"] = hasAmmo(); + } } } @@ -121,16 +131,19 @@ void AssaultWeaponBehaviour::fireRound() // Fire magAmmo -= 1; - spawnTracer(); - playSound(); - viewPunch(); - playShootAnimation(); - bool hit = shoot(cAssaultWeapon["BaseDamage"]); - if (hit) { - showHitMarker(); - } - m_TimeSinceLastFire = 0.0; + + // Effects + if (IsClient) { + spawnTracer(); + playSound(); + viewPunch(); + playShootAnimation(); + bool hit = shoot(cAssaultWeapon["BaseDamage"]); + if (hit) { + showHitMarker(); + } + } } void AssaultWeaponBehaviour::spawnTracer() @@ -140,7 +153,8 @@ void AssaultWeaponBehaviour::spawnTracer() } EntityWrapper spawner; - if (m_Player == LocalPlayer) { + bool outOfBodyExperience = ResourceManager::Load("Config.ini")->Get("Debug.OutOfBodyExperience", false); + if (m_Player == LocalPlayer && !outOfBodyExperience) { spawner = m_Player.FirstChildByName("WeaponMuzzle"); } else { spawner = m_Player.FirstChildByName("ThirdPersonWeaponMuzzle"); @@ -206,7 +220,13 @@ void AssaultWeaponBehaviour::finishReload() // Make real first person weapon model visible again EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel"); - firstPersonWeaponModel["Model"]["Visible"] = true; + if (firstPersonWeaponModel.Valid()) { + firstPersonWeaponModel["Model"]["Visible"] = true; + } + EntityWrapper thirdPersonWeaponModel = m_Player.FirstChildByName("ThirdPersonWeaponModel"); + if (thirdPersonWeaponModel.Valid()) { + thirdPersonWeaponModel["Model"]["Visible"] = true; + } m_Reloading = false; } @@ -259,19 +279,45 @@ void AssaultWeaponBehaviour::playIdleAnimation() void AssaultWeaponBehaviour::playReloadAnimation() { // Play animation - ComponentWrapper cAnimation = m_FirstPersonModel["Animation"]; - cAnimation["AnimationName1"] = "ReloadSwitch"; - cAnimation["Weight1"] = 1.0; - cAnimation["Time1"] = 0.0; - cAnimation["Speed1"] = 0.5; - cAnimation["Loop1"] = true; + // First person + if (IsClient) + { + ComponentWrapper cAnimation = m_FirstPersonModel["Animation"]; + cAnimation["AnimationName1"] = "ReloadSwitch"; + cAnimation["Weight1"] = 1.0; + cAnimation["Time1"] = 0.0; + cAnimation["Speed1"] = 0.5; + cAnimation["Loop1"] = true; + } + // TODO: Third person + //{ + // ComponentWrapper cAnimation = m_ThirdPersonModel["Animation"]; + // cAnimation["AnimationName1"] = "ReloadSwitch"; + // cAnimation["Weight1"] = 1.0; + // cAnimation["Time1"] = 0.0; + // cAnimation["Speed1"] = 0.5; + // cAnimation["Loop1"] = true; + //} // Hide weapon model and spawn the exploding version - EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel"); - EntityWrapper reloadSpawner = m_Player.FirstChildByName("FirstPersonReloadSpawner"); - m_ReloadImpersonator = SpawnerSystem::Spawn(reloadSpawner, reloadSpawner); - firstPersonWeaponModel["Model"].Copy(m_ReloadImpersonator["Model"]); - firstPersonWeaponModel["Model"]["Visible"] = false; + { + EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel"); + EntityWrapper reloadSpawner = m_Player.FirstChildByName("FirstPersonReloadSpawner"); + if (IsClient) { + m_FirstPersonReloadImpersonator = SpawnerSystem::Spawn(reloadSpawner, reloadSpawner); + firstPersonWeaponModel["Model"].Copy(m_FirstPersonReloadImpersonator["Model"]); + } + firstPersonWeaponModel["Model"]["Visible"] = false; + } + { + EntityWrapper thirdPersonWeaponModel = m_Player.FirstChildByName("ThirdPersonWeaponModel"); + EntityWrapper reloadSpawner = m_Player.FirstChildByName("ThirdPersonReloadSpawner"); + if (IsClient) { + m_ThirdPersonReloadImpersonator = SpawnerSystem::Spawn(reloadSpawner, reloadSpawner); + thirdPersonWeaponModel["Model"].Copy(m_ThirdPersonReloadImpersonator["Model"]); + } + thirdPersonWeaponModel["Model"]["Visible"] = false; + } } bool AssaultWeaponBehaviour::shoot(double damage) From fb5164221f8ec45b191c6395dfcfcc35a48e863c Mon Sep 17 00:00:00 2001 From: viktorljung Date: Fri, 12 Feb 2016 01:57:53 +0100 Subject: [PATCH 24/43] HealthHUD redesigned --- assets | 2 +- resources/Schema/Entities/AmmoHUD | 98 +++++++++++++++++++++++++++ resources/Schema/Entities/Player.xml | 99 +++++++++++++++++++--------- resources/Schema/Entities/temp | 38 +++++++++++ src/Engine/Rendering/Renderer.cpp | 1 + src/Game/Systems/HealthHUDSystem.cpp | 2 +- 6 files changed, 208 insertions(+), 32 deletions(-) create mode 100644 resources/Schema/Entities/AmmoHUD create mode 100644 resources/Schema/Entities/temp diff --git a/assets b/assets index 4d36fdce..0fd6b66b 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 4d36fdced7007a594a56b7371bb26861876889aa +Subproject commit 0fd6b66b599ab98a441f91d5cc53c603009f488c diff --git a/resources/Schema/Entities/AmmoHUD b/resources/Schema/Entities/AmmoHUD new file mode 100644 index 00000000..6cdb6568 --- /dev/null +++ b/resources/Schema/Entities/AmmoHUD @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + + + + 0 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + 360 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + + + + + + + + 0 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + 360 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 39e7331f..30ae942e 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -76,14 +76,14 @@ - Textures/Core/UnitHexagon.png - + Textures/HealthHUD3.png + - - - + + + @@ -279,13 +279,33 @@ + + + + 1 + + + + + 100/100 + Fonts/DroidSans.ttf,64 + + + + + + + + + + Idle - 0.1719161089749548 + 1.1017089512865343 1 @@ -305,8 +325,8 @@ true - - + + @@ -327,36 +347,55 @@ - - + - - 32 - Fonts/DroidSans.ttf,64 - - + + Textures/Core/UnitHexagon.png + + - + + - + - - 360 - Fonts/DroidSans.ttf,64 - - - - - - + - + + + + + 32 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + 360 + Fonts/DroidSans.ttf,64 + + + + + + + + + + @@ -393,7 +432,7 @@ Idle - 1.8038469763698401 + 1.5336333336960681 1 @@ -418,8 +457,8 @@ false - - + + diff --git a/resources/Schema/Entities/temp b/resources/Schema/Entities/temp new file mode 100644 index 00000000..baf4ce61 --- /dev/null +++ b/resources/Schema/Entities/temp @@ -0,0 +1,38 @@ + + + + + + + + + + + + 0 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + 360 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 173ddb2b..be84160c 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -168,6 +168,7 @@ void Renderer::SortRenderJobsByDepth(RenderScene &scene) //Sort all forward jobs so transparency is good. scene.Jobs.TransparentObjects.sort(Renderer::DepthSort); scene.Jobs.SpriteJob.sort(Renderer::DepthSort); + scene.Jobs.Text.sort(Renderer::DepthSort); } void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) diff --git a/src/Game/Systems/HealthHUDSystem.cpp b/src/Game/Systems/HealthHUDSystem.cpp index 49b2d0c1..b35bce12 100644 --- a/src/Game/Systems/HealthHUDSystem.cpp +++ b/src/Game/Systems/HealthHUDSystem.cpp @@ -27,7 +27,7 @@ void HealthHUDSystem::Update(double dt) s = s + "/"; s = s + std::to_string((int)(double)entityIDParent["Health"]["MaxHealth"]); float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"]; - (glm::vec4&)entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, glm::vec4(entity["Fill"]["Color"]).a); + (glm::vec4&)entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, glm::vec4(entity["Text"]["Color"]).a); entity["Text"]["Content"] = s; } From 021c4e36d75567a8cf36a860767bea666ad6ad03 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Fri, 12 Feb 2016 02:08:24 +0100 Subject: [PATCH 25/43] New HUD XML files --- resources/Schema/Entities/AmmunitionHUD.xml | 62 +++++++++++++ .../Schema/Entities/CapturePointHUDGroup.xml | 5 +- resources/Schema/Entities/HealthHUD.xml | 50 ++++++++++ resources/Schema/Entities/Player.xml | 93 ++++++++++--------- 4 files changed, 165 insertions(+), 45 deletions(-) create mode 100644 resources/Schema/Entities/AmmunitionHUD.xml create mode 100644 resources/Schema/Entities/HealthHUD.xml diff --git a/resources/Schema/Entities/AmmunitionHUD.xml b/resources/Schema/Entities/AmmunitionHUD.xml new file mode 100644 index 00000000..2eaf2753 --- /dev/null +++ b/resources/Schema/Entities/AmmunitionHUD.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + + + + 32 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + 360 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/CapturePointHUDGroup.xml b/resources/Schema/Entities/CapturePointHUDGroup.xml index 9dce0ffb..d35e1bde 100644 --- a/resources/Schema/Entities/CapturePointHUDGroup.xml +++ b/resources/Schema/Entities/CapturePointHUDGroup.xml @@ -1,9 +1,10 @@ - + - + + diff --git a/resources/Schema/Entities/HealthHUD.xml b/resources/Schema/Entities/HealthHUD.xml new file mode 100644 index 00000000..ec781d8f --- /dev/null +++ b/resources/Schema/Entities/HealthHUD.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + 1 + + + + + 100/100 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + 1 + + + + Textures/HealthHUD3.png + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 30ae942e..b34669ca 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -69,25 +69,6 @@ - - - - 1 - - - - Textures/HealthHUD3.png - - - - - - - - - - - @@ -279,25 +260,51 @@ - + - - 1 - - - - - 100/100 - Fonts/DroidSans.ttf,64 - - - - - - - + - + + + + + 1 + + + + + 100/100 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + 1 + + + + Textures/HealthHUD3.png + + + + + + + + + + + + @@ -305,7 +312,7 @@ Idle - 1.1017089512865343 + 0.24990652025910975 1 @@ -325,8 +332,8 @@ true - - + + @@ -363,7 +370,7 @@ - + @@ -432,7 +439,7 @@ Idle - 1.5336333336960681 + 1.6484966474501377 1 @@ -457,8 +464,8 @@ false - - + + From 71533b52aed61273516fab17a873860c1e25cf25 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 12 Feb 2016 02:10:42 +0100 Subject: [PATCH 26/43] Map fix --- resources/Schema/Entities/NewMap.xml | 76 ++++- resources/Schema/Entities/PlayerRed.xml | 272 ++++++++++++++++++ resources/Schema/Entities/RayRed.xml | 6 +- .../Systems/Weapon/AssaultWeaponBehaviour.cpp | 3 + 4 files changed, 349 insertions(+), 8 deletions(-) create mode 100644 resources/Schema/Entities/PlayerRed.xml diff --git a/resources/Schema/Entities/NewMap.xml b/resources/Schema/Entities/NewMap.xml index f4c768f0..1ae09247 100644 --- a/resources/Schema/Entities/NewMap.xml +++ b/resources/Schema/Entities/NewMap.xml @@ -3365,7 +3365,7 @@ Models/Core/UnitCylinder.mesh - + true @@ -3401,7 +3401,7 @@ Models/Core/UnitCylinder.mesh - + true @@ -3465,7 +3465,7 @@ Models/Core/UnitCylinder.mesh - + true @@ -3500,7 +3500,7 @@ Models/Core/UnitCylinder.mesh - + true @@ -3618,7 +3618,7 @@ - Schema/Entities/Player.xml + Schema/Entities/PlayerRed.xml @@ -3829,6 +3829,72 @@ + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + diff --git a/resources/Schema/Entities/PlayerRed.xml b/resources/Schema/Entities/PlayerRed.xml new file mode 100644 index 00000000..ae11fa00 --- /dev/null +++ b/resources/Schema/Entities/PlayerRed.xml @@ -0,0 +1,272 @@ + + + + + + + + + + 600 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,100 + + + + + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + + + + + + + + 1 + + + + + Models/Core/UnitHexagon.mesh + + + + + + + + + + + + + + Textures/Weapons/Crosshair/SmallThickHoleDot.png + false + + + + + + + + + + + + Schema/Entities/HitMarker.xml + + + + + + + + + + + Idle + 0.1719161089749548 + 1 + + + Models/Characters/Assault/FirstPerson.mesh + true + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Red/AssaultWeaponRed.mesh + true + + + + + + + + + + + Schema/Entities/RayRed.xml + + + + + + + + + + + Schema/Entities/ReloadEffectView.xml + + + + + + + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + Idle + 1.8038469763698401 + 1 + + + AimRifle + + + + + Models/Characters/Assault/AssaultAnimations.mesh + + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Red/AssaultWeaponRed.mesh + + + + + + + + + + + Schema/Entities/RayRed.xml + + + + + + + + + + + Schema/Entities/ReloadEffectWorld.xml + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + diff --git a/resources/Schema/Entities/RayRed.xml b/resources/Schema/Entities/RayRed.xml index 11a9b077..0a20f148 100644 --- a/resources/Schema/Entities/RayRed.xml +++ b/resources/Schema/Entities/RayRed.xml @@ -6,12 +6,12 @@ 0.25 - Models/Weapons/CylinderBullet.mesh - + Models/Effects/CylinderShot.mesh + true - + diff --git a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp index 72b98639..706adaa0 100644 --- a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp @@ -348,6 +348,9 @@ bool AssaultWeaponBehaviour::shoot(double damage) } EntityWrapper victim(m_World, pickData.Entity); + if (!victim.Valid()) { + return false; + } // Don't let us shoot ourselves in the foot if (victim == LocalPlayer) { From 1dc37565334e1745e80e5dfe5718d645188ce0e2 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 12 Feb 2016 02:23:13 +0100 Subject: [PATCH 27/43] Fixed respawn crash when a player died that had never spawned --- src/Game/Systems/PlayerSpawnSystem.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index ac0ecdf3..e43cee13 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -175,8 +175,15 @@ bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e) if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Spectator")) { return false; } + + if (m_PlayerIDs.count(e.Player.ID) == 0) { + return false; + } + SpawnRequest req; req.PlayerID = m_PlayerIDs.at(e.Player.ID); req.Team = cTeam["Team"]; m_SpawnRequests.push_back(req); + + return true; } From 987dafb44aa0c24fb7f2814291dfaceae9611f9d Mon Sep 17 00:00:00 2001 From: viktorljung Date: Fri, 12 Feb 2016 02:38:11 +0100 Subject: [PATCH 28/43] Fixed Health text color --- src/Game/Systems/HealthHUDSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Game/Systems/HealthHUDSystem.cpp b/src/Game/Systems/HealthHUDSystem.cpp index b35bce12..74258d6e 100644 --- a/src/Game/Systems/HealthHUDSystem.cpp +++ b/src/Game/Systems/HealthHUDSystem.cpp @@ -27,7 +27,7 @@ void HealthHUDSystem::Update(double dt) s = s + "/"; s = s + std::to_string((int)(double)entityIDParent["Health"]["MaxHealth"]); float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"]; - (glm::vec4&)entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, glm::vec4(entity["Text"]["Color"]).a); + //(glm::vec4&)entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, glm::vec4(entity["Text"]["Color"]).a); entity["Text"]["Content"] = s; } From a54156fab3513ec3334d540f96262c6b5e997dfe Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 12 Feb 2016 02:46:16 +0100 Subject: [PATCH 29/43] Added HUD elements to player --- resources/Schema/Entities/Player.xml | 305 ++++++++++++++++++++++++--- 1 file changed, 279 insertions(+), 26 deletions(-) diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 05dc79e2..54d95e83 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -23,9 +23,7 @@ - - - + @@ -71,25 +69,6 @@ - - - - 1 - - - - - Models/Core/UnitHexagon.mesh - - - - - - - - - - @@ -112,6 +91,221 @@ + + + + + + + + + 1 + + + + + 100/100 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + 1 + + + + Textures/HealthHUD3.png + + + + + + + + + + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 2 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 3 + + + 0.80222018197612788 + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 4 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 1 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + @@ -138,8 +332,8 @@ true - - + + @@ -163,6 +357,64 @@ + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + + + + 32 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + 360 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + @@ -198,6 +450,7 @@ Models/Characters/Assault/AssaultAnimations.mesh + false @@ -211,8 +464,8 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - - + + From b5e372896f00f84f13e7b87405c75bcdefe1cd63 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 12 Feb 2016 02:46:42 +0100 Subject: [PATCH 30/43] Added spawner? --- resources/Schema/Entities/NewMap.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/Schema/Entities/NewMap.xml b/resources/Schema/Entities/NewMap.xml index a74b7ef2..7d1f47ca 100644 --- a/resources/Schema/Entities/NewMap.xml +++ b/resources/Schema/Entities/NewMap.xml @@ -4986,11 +4986,6 @@ - - - - - @@ -5004,7 +4999,7 @@ - + @@ -5053,6 +5048,11 @@ + + + + + From 215b1b1aa4bb6deaf978ed2255643142886e4697 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Fri, 12 Feb 2016 03:32:42 +0100 Subject: [PATCH 31/43] On crash, takes minidump, then show MessageBox, and exit app. --- include/Game/MiniDump.h | 8 +++ src/Game/MiniDump.cpp | 106 ++++++++++++++++++++++++++++++++++++++++ src/Game/main.cpp | 22 +++++++-- 3 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 include/Game/MiniDump.h create mode 100644 src/Game/MiniDump.cpp diff --git a/include/Game/MiniDump.h b/include/Game/MiniDump.h new file mode 100644 index 00000000..4ad4548d --- /dev/null +++ b/include/Game/MiniDump.h @@ -0,0 +1,8 @@ +#ifndef MiniDump_h__ +#define MiniDump_h__ + +#include + +void WINAPI Create_Dump(PEXCEPTION_POINTERS pException, BOOL File_Flag, BOOL Show_Flag); + +#endif diff --git a/src/Game/MiniDump.cpp b/src/Game/MiniDump.cpp new file mode 100644 index 00000000..0547e54e --- /dev/null +++ b/src/Game/MiniDump.cpp @@ -0,0 +1,106 @@ +/* + Author: Vladimir Sedach. + + Purpose: demo of Call Stack creation by our own means, + and with MiniDumpWriteDump() function of DbgHelp.dll. +*/ + +#include + +#include +#include +//#include "dbghelp.h" + +//#define DEBUG_DPRINTF 1 //allow d() +//#include "wfun.h" + +#pragma optimize("y", off) //generate stack frame pointers for all functions - same as /Oy- in the project +#pragma warning(disable: 4200) //nonstandard extension used : zero-sized array in struct/union +#pragma warning(disable: 4100) //unreferenced formal parameter + +// In case you don't have dbghelp.h. +#ifndef _DBGHELP_ + +typedef struct _MINIDUMP_EXCEPTION_INFORMATION { + DWORD ThreadId; + PEXCEPTION_POINTERS ExceptionPointers; + BOOL ClientPointers; +} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; + +typedef enum _MINIDUMP_TYPE { + MiniDumpNormal = 0x00000000, + MiniDumpWithDataSegs = 0x00000001, +} MINIDUMP_TYPE; + +typedef BOOL (WINAPI * MINIDUMP_WRITE_DUMP)( + IN HANDLE hProcess, + IN DWORD ProcessId, + IN HANDLE hFile, + IN MINIDUMP_TYPE DumpType, + IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL + IN PVOID UserStreamParam, OPTIONAL + IN PVOID CallbackParam OPTIONAL + ); + +#else + +typedef BOOL (WINAPI * MINIDUMP_WRITE_DUMP)( + IN HANDLE hProcess, + IN DWORD ProcessId, + IN HANDLE hFile, + IN MINIDUMP_TYPE DumpType, + IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL + IN PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL + IN PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL + ); +#endif //#ifndef _DBGHELP_ + +HMODULE hDbgHelp; +MINIDUMP_WRITE_DUMP MiniDumpWriteDump_; + +// Tool Help functions. +typedef HANDLE (WINAPI * CREATE_TOOL_HELP32_SNAPSHOT)(DWORD dwFlags, DWORD th32ProcessID); + +//************************************************************************************* +void WINAPI Create_Dump(PEXCEPTION_POINTERS pException, BOOL File_Flag, BOOL Show_Flag) +//************************************************************************************* +// Create dump. +// pException can be either GetExceptionInformation() or NULL. +// If File_Flag = TRUE - write dump files (.dmz and .dmp) with the name of the current process. +// If Show_Flag = TRUE - show message with Get_Exception_Info() dump. +{ + // Try to get MiniDumpWriteDump() address. + hDbgHelp = LoadLibrary("DBGHELP.DLL"); + MiniDumpWriteDump_ = (MINIDUMP_WRITE_DUMP)GetProcAddress(hDbgHelp, "MiniDumpWriteDump"); + + // If MiniDumpWriteDump() of DbgHelp.dll available. + if (MiniDumpWriteDump_) + { + HANDLE hDump_File; + CHAR Dump_Path[MAX_PATH]; + + GetModuleFileName(NULL, Dump_Path, sizeof(Dump_Path)); //path of current process + + MINIDUMP_EXCEPTION_INFORMATION M; + + M.ThreadId = GetCurrentThreadId(); + M.ExceptionPointers = pException; + M.ClientPointers = 0; + + lstrcpy(Dump_Path + lstrlen(Dump_Path) - 3, "dmp"); + + hDump_File = CreateFile(Dump_Path, + GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + MiniDumpWriteDump_(GetCurrentProcess(), GetCurrentProcessId(), hDump_File, + MiniDumpNormal, (pException) ? &M : NULL, NULL, NULL); + + CloseHandle(hDump_File); + + std::cout << "Memory dumped to: \"" << Dump_Path << "\""; + MessageBox(NULL, ("Application crashed, memory dumped to: " + std::string(Dump_Path)).c_str(), "MiniDump", MB_ICONHAND | MB_OK); + } else { + MessageBox(NULL, "Application crashed, memory dump failed.", "MiniDump", MB_ICONHAND | MB_OK); + } +} + diff --git a/src/Game/main.cpp b/src/Game/main.cpp index 613165dd..dd2a5a84 100644 --- a/src/Game/main.cpp +++ b/src/Game/main.cpp @@ -1,11 +1,25 @@ #include "Game.h" +#include "MiniDump.h" + +LONG WINAPI CrashHandler(EXCEPTION_POINTERS* pException); int main(int argc, char* argv[]) { - Game game(argc, argv); - while (game.Running()) { - game.Tick(); - } + ::SetUnhandledExceptionFilter(CrashHandler); + + Game game(argc, argv); + while (game.Running()) { + game.Tick(); + } return 0; +} + +LONG WINAPI CrashHandler(EXCEPTION_POINTERS* pException) +{ + //Take minidump. path should be bin/TacticalZ.dmp + //Then show MessageBox, and exit application. + Create_Dump(pException, 1, 1); + + return EXCEPTION_EXECUTE_HANDLER;// EXCEPTION_CONTINUE_SEARCH } \ No newline at end of file From 787eecce26917e917f5aed99bfdf46b87541b335 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 12 Feb 2016 04:03:22 +0100 Subject: [PATCH 32/43] WIP --- include/Engine/Network/Server.h | 1 + src/Engine/Network/Server.cpp | 30 +++++++++++++++++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index f16c6c16..fbba5340 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -89,6 +89,7 @@ private: EventRelay m_EComponentDeleted; bool OnComponentDeleted(const Events::ComponentDeleted& e); void parsePlayerTransform(Packet& packet); + bool shouldSendToClient(EntityWrapper childEntity); }; #endif diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index a6174f7a..ff6e0433 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -185,11 +185,18 @@ void Server::addInputCommandsToPacket(Packet& packet) void Server::addChildrenToPacket(Packet & packet, EntityID entityID) { + // HACK: Only sync players for now, since the map turned out to be TOO LARGE to send in one snapshot and Simon's computer shits itself + EntityWrapper entity(m_World, entityID); + if (entityID != EntityID_Invalid && !shouldSendToClient(entity)) { + return; + } + auto itPair = m_World->GetChildren(entityID); std::unordered_map worldComponentPools = m_World->GetComponentPools(); // Loop through every child for (auto it = itPair.first; it != itPair.second; it++) { EntityID childEntityID = it->second; + // Write EntityID and parentsID and Entity name packet.WritePrimitive(childEntityID); packet.WritePrimitive(entityID); @@ -435,9 +442,11 @@ bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e) bool Server::OnEntityDeleted(const Events::EntityDeleted & e) { if (!e.Cascaded) { - Packet packet = Packet(MessageType::EntityDeleted); - packet.WritePrimitive(e.DeletedEntity); - broadcast(packet); + if (shouldSendToClient(EntityWrapper(m_World, e.DeletedEntity))) { + Packet packet = Packet(MessageType::EntityDeleted); + packet.WritePrimitive(e.DeletedEntity); + broadcast(packet); + } } return false; } @@ -445,10 +454,12 @@ bool Server::OnEntityDeleted(const Events::EntityDeleted & e) bool Server::OnComponentDeleted(const Events::ComponentDeleted & e) { if (!e.Cascaded) { - Packet packet = Packet(MessageType::ComponentDeleted); - packet.WritePrimitive(e.Entity); - packet.WriteString(e.ComponentType); - broadcast(packet); + if (shouldSendToClient(EntityWrapper(m_World, e.Entity))) { + Packet packet = Packet(MessageType::ComponentDeleted); + packet.WritePrimitive(e.Entity); + packet.WriteString(e.ComponentType); + broadcast(packet); + } } return false; } @@ -484,3 +495,8 @@ void Server::parsePlayerTransform(Packet& packet) } } } + +bool Server::shouldSendToClient(EntityWrapper childEntity) +{ + return childEntity.HasComponent("Player") || childEntity.FirstParentWithComponent("Player").Valid(); +} From 422bedb844c6f3dbbe18e4304270b2502cff95d3 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Fri, 12 Feb 2016 04:22:11 +0100 Subject: [PATCH 33/43] MiniDump name now depends on time e.g. TacticalZ Fri 04-20-49. --- src/Game/MiniDump.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Game/MiniDump.cpp b/src/Game/MiniDump.cpp index 0547e54e..bd8ee2de 100644 --- a/src/Game/MiniDump.cpp +++ b/src/Game/MiniDump.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -80,25 +81,28 @@ void WINAPI Create_Dump(PEXCEPTION_POINTERS pException, BOOL File_Flag, BOOL Sho CHAR Dump_Path[MAX_PATH]; GetModuleFileName(NULL, Dump_Path, sizeof(Dump_Path)); //path of current process + std::time_t t = std::time(NULL); + char tStr[16]; + std::strftime(tStr, 32, " %a %H-%M-%S", std::localtime(&t)); + std::string time(tStr); + std::string path(Dump_Path); + path = path.substr(0, path.length() - 4); + path += time + ".dmp"; MINIDUMP_EXCEPTION_INFORMATION M; - M.ThreadId = GetCurrentThreadId(); M.ExceptionPointers = pException; M.ClientPointers = 0; - lstrcpy(Dump_Path + lstrlen(Dump_Path) - 3, "dmp"); - - hDump_File = CreateFile(Dump_Path, - GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + hDump_File = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); MiniDumpWriteDump_(GetCurrentProcess(), GetCurrentProcessId(), hDump_File, MiniDumpNormal, (pException) ? &M : NULL, NULL, NULL); CloseHandle(hDump_File); - std::cout << "Memory dumped to: \"" << Dump_Path << "\""; - MessageBox(NULL, ("Application crashed, memory dumped to: " + std::string(Dump_Path)).c_str(), "MiniDump", MB_ICONHAND | MB_OK); + std::cout << "Memory dumped to: \"" << path.c_str() << "\""; + MessageBox(NULL, ("Application crashed, memory dumped to: " + path).c_str(), "MiniDump", MB_ICONHAND | MB_OK); } else { MessageBox(NULL, "Application crashed, memory dump failed.", "MiniDump", MB_ICONHAND | MB_OK); } From a8a3366e8a424b4fb56265ae57ba1f7025907fff Mon Sep 17 00:00:00 2001 From: Tleety Date: Fri, 12 Feb 2016 05:17:09 +0100 Subject: [PATCH 34/43] Hopeless attempts to fix network bugs --- resources/DefaultConfig.ini | 2 +- src/Engine/Network/Server.cpp | 2 +- src/Game/Systems/CapturePointSystem.cpp | 12 +++++++++--- src/Game/Systems/PlayerMovementSystem.cpp | 20 +++++++++++--------- src/Game/Systems/SoundSystem.cpp | 20 +++++++++++++------- 5 files changed, 35 insertions(+), 21 deletions(-) diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index 9c6dfd8f..60ee4823 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -23,7 +23,7 @@ StartNetwork=false IsServer=false Name=Bob Address=127.0.0.1 -Port=13 +Port=27666 MaxConnections=8 SnapshotInterval=0.05 SendInputIntervalMs=33 diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index ff6e0433..bb2115de 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -187,7 +187,7 @@ void Server::addChildrenToPacket(Packet & packet, EntityID entityID) { // HACK: Only sync players for now, since the map turned out to be TOO LARGE to send in one snapshot and Simon's computer shits itself EntityWrapper entity(m_World, entityID); - if (entityID != EntityID_Invalid && !shouldSendToClient(entity)) { + if (!entity.Valid() || !shouldSendToClient(entity)) { return; } diff --git a/src/Game/Systems/CapturePointSystem.cpp b/src/Game/Systems/CapturePointSystem.cpp index f938ecd0..5fdd74cd 100644 --- a/src/Game/Systems/CapturePointSystem.cpp +++ b/src/Game/Systems/CapturePointSystem.cpp @@ -6,15 +6,21 @@ CapturePointSystem::CapturePointSystem(SystemParams params) , PureSystem("CapturePoint") { //subscribe/listenTo playerdamage,healthpickup events (using the eventBroker) - EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch); - EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave); - EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured); + if (IsClient) { + EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch); + EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave); + EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured); + } } //here all capturepoints will update their component //NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, ComponentWrapper& cCapturePoint, double dt) { + if (!IsClient) { + return; + } + if (m_WinnerWasFound) { return; } diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index badaf638..9bf1d25e 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -114,15 +114,17 @@ void PlayerMovementSystem::updateMovementControllers(double dt) if (isOnGround) { controller->SetDoubleJumping(false); } else { - //put a hexagon at the players feet - auto hexagonEffect = ResourceManager::Load("Schema/Entities/DoubleJumpHexagon.xml"); - EntityFileParser parser(hexagonEffect); - EntityID hexagonEffectID = parser.MergeEntities(m_World); - EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID); - hexagonEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"]; - controller->SetDoubleJumping(true); - Events::DoubleJump e; - m_EventBroker->Publish(e); + if (IsClient) { + //put a hexagon at the players feet + auto hexagonEffect = ResourceManager::Load("Schema/Entities/DoubleJumpHexagon.xml"); + EntityFileParser parser(hexagonEffect); + EntityID hexagonEffectID = parser.MergeEntities(m_World); + EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID); + hexagonEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"]; + controller->SetDoubleJumping(true); + Events::DoubleJump e; + m_EventBroker->Publish(e); + } } velocity.y = 4.f; } diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index 59fd4a7f..7101311d 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -6,13 +6,15 @@ SoundSystem::SoundSystem(SystemParams params) { ConfigFile* config = ResourceManager::Load("Config.ini"); m_Announcer = ResourceManager::Load("Config.ini")->Get("Sound.Announcer", "female"); - EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); - EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &SoundSystem::OnInputCommand); - EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundSystem::OnDoubleJump); - EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &SoundSystem::OnDashAbility); - EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage); - EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured); - EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch); + if (IsClient) { + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); + EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &SoundSystem::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundSystem::OnDoubleJump); + EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &SoundSystem::OnDashAbility); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage); + EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured); + EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch); + } } void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) @@ -20,6 +22,10 @@ void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComp void SoundSystem::Update(double dt) { + if (!IsClient) { + return; + } + // Temp for play test. if (m_DrumsIsPlaying) { m_DrumsIsPlaying = !drumTimer(dt); From 60b2c9bc9b256bc498571bd984d364d074abef5c Mon Sep 17 00:00:00 2001 From: viktorljung Date: Fri, 12 Feb 2016 05:41:05 +0100 Subject: [PATCH 35/43] KillFeed --- include/Game/Systems/KillFeedSystem.h | 39 + resources/Schema/Components.xsd | 1 + resources/Schema/Components/KillFeed.xml | 3 + resources/Schema/Components/KillFeed.xsd | 9 + resources/Schema/Components/Text.xml | 2 +- resources/Schema/Entities/DeadGirl.xlm | 255 +++++ resources/Schema/Entities/DeadGirls.xml | 1137 ++++++++++++++++++++++ resources/Schema/Entities/Player.xml | 66 +- resources/Schema/Types/Entity.xsd | 1 + src/Game/Game.cpp | 2 + src/Game/Systems/KillFeedSystem.cpp | 74 ++ src/Game/Systems/PlayerSpawnSystem.cpp | 11 +- 12 files changed, 1589 insertions(+), 11 deletions(-) create mode 100644 include/Game/Systems/KillFeedSystem.h create mode 100644 resources/Schema/Components/KillFeed.xml create mode 100644 resources/Schema/Components/KillFeed.xsd create mode 100644 resources/Schema/Entities/DeadGirl.xlm create mode 100644 resources/Schema/Entities/DeadGirls.xml create mode 100644 src/Game/Systems/KillFeedSystem.cpp diff --git a/include/Game/Systems/KillFeedSystem.h b/include/Game/Systems/KillFeedSystem.h new file mode 100644 index 00000000..31423999 --- /dev/null +++ b/include/Game/Systems/KillFeedSystem.h @@ -0,0 +1,39 @@ +#ifndef KillFeedSystem_h__ +#define KillFeedSystem_h__ + +#include "../../Engine/Core/System.h" +#include "../../Engine/GLM.h" +#include "Core/EPlayerDeath.h" + +class KillFeedSystem : public ImpureSystem +{ +public: + KillFeedSystem(SystemParams params) + : System(params) + { + EVENT_SUBSCRIBE_MEMBER(m_EPlayerDeath, &KillFeedSystem::OnPlayerDeath); + + } + + virtual void Update(double dt) override; + +private: + + + + + EventRelay m_EPlayerDeath; + bool KillFeedSystem::OnPlayerDeath(Events::PlayerDeath& e); + + struct KillFeedInfo + { + std::string Content; + glm::vec4 Color; + float TimeToLive = 5.f; + }; + + std::list m_DeathQueue; + +}; + +#endif \ No newline at end of file diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index ee4d7424..61e49ae3 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -41,4 +41,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/KillFeed.xml b/resources/Schema/Components/KillFeed.xml new file mode 100644 index 00000000..558d4983 --- /dev/null +++ b/resources/Schema/Components/KillFeed.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/Schema/Components/KillFeed.xsd b/resources/Schema/Components/KillFeed.xsd new file mode 100644 index 00000000..fedce9fb --- /dev/null +++ b/resources/Schema/Components/KillFeed.xsd @@ -0,0 +1,9 @@ + + + + + + HUD element for tracking the 3 last kills, printed on the children with the names "KillFeed1", "KillFeed2", "KillFeed3" + + + \ No newline at end of file diff --git a/resources/Schema/Components/Text.xml b/resources/Schema/Components/Text.xml index 9ca629d1..d38d3961 100644 --- a/resources/Schema/Components/Text.xml +++ b/resources/Schema/Components/Text.xml @@ -1,6 +1,6 @@ - Text + true diff --git a/resources/Schema/Entities/DeadGirl.xlm b/resources/Schema/Entities/DeadGirl.xlm new file mode 100644 index 00000000..90a0411d --- /dev/null +++ b/resources/Schema/Entities/DeadGirl.xlm @@ -0,0 +1,255 @@ + + + + + + + + + + 600 + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,100 + + + + + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + + + + + + + + 1 + + + + + Models/Core/UnitHexagon.mesh + + + + + + + + + + + + + + Textures/Weapons/Crosshair/SmallThickHoleDot.png + false + + + + + + + + + + + + + + Idle + 0.28963486380924053 + 1 + + + Models/Characters/Assault/FirstPerson.mesh + true + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + true + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + + + + Schema/Entities/WeaponReloadEffect.xml + + + + + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + Idle + 0.42156525436696768 + 1 + + + AimRifle + + + + + Models/Characters/Assault/AssaultAnimations.mesh + + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + false + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + diff --git a/resources/Schema/Entities/DeadGirls.xml b/resources/Schema/Entities/DeadGirls.xml new file mode 100644 index 00000000..2b004c34 --- /dev/null +++ b/resources/Schema/Entities/DeadGirls.xml @@ -0,0 +1,1137 @@ + + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + + + + + sModels/Widgets/Lights/DirectionalLightWidget.mesh + + + + + + + + + + + + + Models/Test/ObstacleCourse.mesh + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + + + + + + + 600 + + + + + 1 + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,100 + + + + + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + + + + + + + + 0.0099999997764825821 + + + + + Models/Core/UnitHexagon.mesh + + + + + + + + + + + + + + Textures/Weapons/Crosshair/SmallThickHoleDot.png + false + + + + + + + + + + + + + + Idle + 1.9484546004984589 + 1 + + + Models/Characters/Assault/FirstPerson.mesh + true + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + true + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + + + + Schema/Entities/WeaponReloadEffect.xml + + + + + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + Idle + 0.83038427580044871 + 1 + + + AimRifle + + + + + Models/Characters/Assault/AssaultAnimations.mesh + + + + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + false + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + + + + + + 600 + + + + + 1 + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,100 + + + + + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + + + + + + + + 0.0099999997764825821 + + + + + Models/Core/UnitHexagon.mesh + + + + + + + + + + + + + + Textures/Weapons/Crosshair/SmallThickHoleDot.png + false + + + + + + + + + + + + + + Idle + 1.6865388023565906 + 1 + + + Models/Characters/Assault/FirstPerson.mesh + true + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + true + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + + + + Schema/Entities/WeaponReloadEffect.xml + + + + + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + Idle + 0.71846833460743298 + 1 + + + AimRifle + + + + + Models/Characters/Assault/AssaultAnimations.mesh + + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + false + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + + + + + + 600 + + + + + 1 + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,100 + + + + + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + + + + + + + + 0.0099999997764825821 + + + + + Models/Core/UnitHexagon.mesh + + + + + + + + + + + + + + Textures/Weapons/Crosshair/SmallThickHoleDot.png + false + + + + + + + + + + + + + + Idle + 1.4291906531606173 + 1 + + + Models/Characters/Assault/FirstPerson.mesh + true + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + true + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + + + + Schema/Entities/WeaponReloadEffect.xml + + + + + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + Idle + 0.34445363000679663 + 1 + + + AimRifle + + + + + Models/Characters/Assault/AssaultAnimations.mesh + + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + false + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + + + + + + 600 + + + + + 1 + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,100 + + + + + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + + + + + + + + 0.0099999997764825821 + + + + + Models/Core/UnitHexagon.mesh + + + + + + + + + + + + + + Textures/Weapons/Crosshair/SmallThickHoleDot.png + false + + + + + + + + + + + + + + Idle + 0.94316388255725769 + 1 + + + Models/Characters/Assault/FirstPerson.mesh + true + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + true + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + + + + Schema/Entities/WeaponReloadEffect.xml + + + + + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + Idle + 1.7750936055429634 + 1 + + + AimRifle + + + + + Models/Characters/Assault/AssaultAnimations.mesh + + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + false + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index b34669ca..d2063814 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -306,13 +306,67 @@ + + + + + + + + + + + + + + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + Idle - 0.24990652025910975 + 1.6050530664521858 1 @@ -332,8 +386,8 @@ true - - + + @@ -439,7 +493,7 @@ Idle - 1.6484966474501377 + 1.620305457513453 1 @@ -464,8 +518,8 @@ false - - + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 3e521007..3e45cca0 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -44,6 +44,7 @@ + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index e7e1eb48..49b1a963 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -25,6 +25,7 @@ #include "Rendering/AnimationSystem.h" #include "Network/MultiplayerSnapshotFilter.h" #include "Game/Systems/AmmunitionHUDSystem.h" +#include "Game/Systems/KillFeedSystem.h" Game::Game(int argc, char* argv[]) @@ -130,6 +131,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); diff --git a/src/Game/Systems/KillFeedSystem.cpp b/src/Game/Systems/KillFeedSystem.cpp new file mode 100644 index 00000000..373b1ff5 --- /dev/null +++ b/src/Game/Systems/KillFeedSystem.cpp @@ -0,0 +1,74 @@ +#include "Game/Systems/KillFeedSystem.h" + +void KillFeedSystem::Update(double dt) +{ + auto killFeeds = m_World->GetComponents("KillFeed"); + if (killFeeds == nullptr) { + return; + } + + for (auto& killFeedComponent : *killFeeds) { + EntityWrapper entity = EntityWrapper(m_World, killFeedComponent.EntityID); + + for (int i = 1; i <= 3; i++) { + EntityWrapper child = entity.FirstChildByName("KillFeed" + std::to_string(i)); + if (child.HasComponent("Text")) { + (std::string&)child["Text"]["Content"] = ""; + } + } + + + + + int feedIndex = 1; + for (auto it = m_DeathQueue.begin(); it != m_DeathQueue.end(); ) { + bool remove = false; + + EntityWrapper child = entity.FirstChildByName("KillFeed" + std::to_string(feedIndex)); + + if (child.HasComponent("Text")) { + (std::string&)child["Text"]["Content"] = (*it).Content; + (glm::vec4&)child["Text"]["Color"] = (*it).Color; + + (*it).TimeToLive -= dt; + + if ((*it).TimeToLive <= 0.f) { + (std::string&)child["Text"]["Content"] = ""; + (glm::vec4&)child["Text"]["Color"] = (*it).Color; + remove = true; + } + } + feedIndex++; + if(feedIndex > 3) { + break; + } + + if(remove) { + it = m_DeathQueue.erase(it); + } else { + it++; + } + } + } +} + +bool KillFeedSystem::OnPlayerDeath(Events::PlayerDeath& e) +{ + KillFeedInfo kfInfo; + + if (e.Player.HasComponent("Team")) { + int red = e.Player["Team"].Enum("Team", "Red"); + int blue = e.Player["Team"].Enum("Team", "Blue"); + + if ((int)e.Player["Team"]["Team"] == red) { + kfInfo.Content = "Blue Player killed Red Player"; + kfInfo.Color = glm::vec4(0.f, 0.2f, 1.f, 0.8f); + m_DeathQueue.push_back(kfInfo); + } else if ((int)e.Player["Team"]["Team"] == blue) { + kfInfo.Content = "Red Player killed blue Player"; + kfInfo.Color = glm::vec4(1.f, 0.f, 0.f, 0.8f); + m_DeathQueue.push_back(kfInfo); + } + } + return true; +} diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index ac0ecdf3..c92585ba 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -175,8 +175,11 @@ bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e) if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Spectator")) { return false; } - SpawnRequest req; - req.PlayerID = m_PlayerIDs.at(e.Player.ID); - req.Team = cTeam["Team"]; - m_SpawnRequests.push_back(req); + + if (m_PlayerIDs.find(e.Player.ID) != m_PlayerIDs.end()) { + SpawnRequest req; + req.PlayerID = m_PlayerIDs.at(e.Player.ID); + req.Team = cTeam["Team"]; + m_SpawnRequests.push_back(req); + } } From f146971db0ce9af7e1287a0eadb6d8ebc5635821 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Fri, 12 Feb 2016 05:45:17 +0100 Subject: [PATCH 36/43] Fixed size --- src/Game/Systems/KillFeedSystem.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Game/Systems/KillFeedSystem.cpp b/src/Game/Systems/KillFeedSystem.cpp index 373b1ff5..8a16d708 100644 --- a/src/Game/Systems/KillFeedSystem.cpp +++ b/src/Game/Systems/KillFeedSystem.cpp @@ -70,5 +70,11 @@ bool KillFeedSystem::OnPlayerDeath(Events::PlayerDeath& e) m_DeathQueue.push_back(kfInfo); } } + + + if(m_DeathQueue.size() > 3) { + m_DeathQueue.pop_front(); + } + return true; } From 1e042445907e5ef58a6af879be6897c233976187 Mon Sep 17 00:00:00 2001 From: Tleety Date: Fri, 12 Feb 2016 06:00:42 +0100 Subject: [PATCH 37/43] Fixed network bug sorta --- src/Engine/Network/Client.cpp | 7 +++---- src/Engine/Network/Server.cpp | 21 +++++++++------------ 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 020e0cb7..10af98b7 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -181,14 +181,13 @@ void Client::parseSpawnEvents() std::vector tempSpawn; for (int i = 0; i < m_PlayerSpawnEvents.size(); i++) { Events::PlayerSpawned e; - if (!serverClientMapsHasEntity(m_PlayerSpawnEvents.at(i).Player.ID) || - !serverClientMapsHasEntity(m_PlayerSpawnEvents.at(i).Spawner.ID)) { + if (!serverClientMapsHasEntity(m_PlayerSpawnEvents.at(i).Player.ID)) { tempSpawn.push_back(m_PlayerSpawnEvents.at(i)); continue; } e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Player.ID)); - e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Spawner.ID)); - e.PlayerID = -1; + //e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID.at(m_PlayerSpawnEvents.at(i).Spawner.ID)); + e.PlayerID = -1; e.PlayerName = m_PlayerSpawnEvents.at(i).PlayerName; m_EventBroker->Publish(e); } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 1500377a..7bb2722c 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -165,17 +165,16 @@ void Server::addInputCommandsToPacket(Packet& packet) void Server::addChildrenToPacket(Packet & packet, EntityID entityID) { - // HACK: Only sync players for now, since the map turned out to be TOO LARGE to send in one snapshot and Simon's computer shits itself - EntityWrapper entity(m_World, entityID); - if (!entity.Valid() || !shouldSendToClient(entity)) { - return; - } - auto itPair = m_World->GetChildren(entityID); std::unordered_map worldComponentPools = m_World->GetComponentPools(); // Loop through every child for (auto it = itPair.first; it != itPair.second; it++) { EntityID childEntityID = it->second; + // HACK: Only sync players for now, since the map turned out to be TOO LARGE to send in one snapshot and Simon's computer shits itself + EntityWrapper childEntity(m_World, childEntityID); + if (!shouldSendToClient(childEntity)) { + continue; + } // Write EntityID and parentsID and Entity name packet.WritePrimitive(childEntityID); @@ -398,11 +397,9 @@ bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e) bool Server::OnEntityDeleted(const Events::EntityDeleted & e) { if (!e.Cascaded) { - if (shouldSendToClient(EntityWrapper(m_World, e.DeletedEntity))) { - Packet packet = Packet(MessageType::EntityDeleted); - packet.WritePrimitive(e.DeletedEntity); - reliableBroadcast(packet); - } + Packet packet = Packet(MessageType::EntityDeleted); + packet.WritePrimitive(e.DeletedEntity); + reliableBroadcast(packet); } return false; } @@ -458,7 +455,7 @@ void Server::parseOnInputCommand(Packet& packet) e.Player = EntityWrapper(m_World, m_ConnectedPlayers.at(player).EntityID); e.Value = packet.ReadPrimitive(); m_EventBroker->Publish(e); - if (e.Command == "PrimaryFire") { + if (e.Command == "PrimaryFire" || e.Command == "Reload") { m_InputCommandsToBroadcast.push_back(e); } //LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); From 2e5ee633cea4c47d305bc18d477ea16b5193e06b Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 12 Feb 2016 06:10:20 +0100 Subject: [PATCH 38/43] Fixed bug when client would recieve input command from an entity that the client didn't know about --- src/Engine/Network/Client.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 10af98b7..8de62cb5 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -287,10 +287,14 @@ void Client::parseSnapshot(Packet& packet) Events::InputCommand e; e.PlayerID = packet.ReadPrimitive(); EntityID player = packet.ReadPrimitive(); - e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(player)); - e.Command = packet.ReadString(); - e.Value = packet.ReadPrimitive(); - m_EventBroker->Publish(e); + std::string command = packet.ReadString(); + float value = packet.ReadPrimitive(); + if (m_ServerIDToClientID.find(player) != m_ServerIDToClientID.end()) { + e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(player)); + e.Command = command; + e.Value = value; + m_EventBroker->Publish(e); + } } // Read world state From cc422cf73ab6d72378641d74bca647c838910c9a Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 12 Feb 2016 06:30:19 +0100 Subject: [PATCH 39/43] Fixed PlayerDeath being fired multiple times per frame on the server, causing multiple spawns and other weirdness --- src/Game/Systems/HealthSystem.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 0fc113b9..719f6c9f 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -10,8 +10,15 @@ HealthSystem::HealthSystem(SystemParams params) EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &HealthSystem::OnInputCommand); } -void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) +void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cHealth, double dt) { + double& health = cHealth["Health"]; + if (health <= 0.0) { + Events::PlayerDeath ePlayerDeath; + ePlayerDeath.Player = entity; + m_EventBroker->Publish(ePlayerDeath); + //Note: we will delete the entity in PlayerDeathSystem + } } bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) @@ -20,13 +27,6 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) double& health = cHealth["Health"]; health -= e.Damage; - if (health <= 0.0) { - Events::PlayerDeath ePlayerDeath; - ePlayerDeath.Player = e.Victim; - m_EventBroker->Publish(ePlayerDeath); - //Note: we will delete the entity in PlayerDeathSystem - } - return true; } From bb66f95d4375bd576b47562675bc3dde03049a51 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 12 Feb 2016 07:03:14 +0100 Subject: [PATCH 40/43] Enabled server broadcasting PlayerDamage events to other players to make damage indicators work --- include/Engine/Network/Client.h | 2 +- include/Engine/Network/Server.h | 4 +++- src/Engine/Network/Client.cpp | 22 +++++++++++++++++++++- src/Engine/Network/Server.cpp | 13 ++++++++++++- src/Game/Systems/DamageIndicatorSystem.cpp | 7 +++++-- src/Game/Systems/HealthSystem.cpp | 4 ++++ 6 files changed, 46 insertions(+), 6 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index f2b18eee..978c9b65 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -109,7 +109,7 @@ public: bool OnPlayerDamage(const Events::PlayerDamage& e); EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(const Events::PlayerSpawned& e); - + void parsePlayerDamage(Packet& packet); private: UDPClient m_Unreliable; TCPClient m_Reliable; diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 8a1ee514..b37bffab 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -81,6 +81,7 @@ private: void parseUDPConnect(Packet & packet); void parseTCPConnect(Packet & packet); void parseDisconnect(); + bool shouldSendToClient(EntityWrapper childEntity); // Debug event EventRelay m_EInputCommand; @@ -91,7 +92,8 @@ private: bool OnEntityDeleted(const Events::EntityDeleted& e); EventRelay m_EComponentDeleted; bool OnComponentDeleted(const Events::ComponentDeleted& e); - bool shouldSendToClient(EntityWrapper childEntity); + EventRelay m_EPlayerDamage; + bool OnPlayerDamage(const Events::PlayerDamage& e); }; #endif diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 8de62cb5..43ad8dfb 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -119,6 +119,9 @@ void Client::parseMessageType(Packet& packet) case MessageType::ComponentDeleted: parseComponentDeletion(packet); break; + case MessageType::OnPlayerDamage: + parsePlayerDamage(packet); + break; default: break; } @@ -409,12 +412,17 @@ bool Client::OnInputCommand(const Events::InputCommand & e) bool Client::OnPlayerDamage(const Events::PlayerDamage & e) { + if (e.Inflictor != m_LocalPlayer) { + return false; + } + Packet packet(MessageType::OnPlayerDamage, m_SendPacketID); packet.WritePrimitive(m_ClientIDToServerID.at(e.Inflictor.ID)); packet.WritePrimitive(m_ClientIDToServerID.at(e.Victim.ID)); packet.WritePrimitive(e.Damage); m_Reliable.Send(packet); - return false; + + return true; } bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e) @@ -425,6 +433,18 @@ bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e) return true; } +void Client::parsePlayerDamage(Packet& packet) +{ + Events::PlayerDamage e; + e.Inflictor = EntityWrapper(m_World, m_ServerIDToClientID.at(packet.ReadPrimitive())); + e.Victim = EntityWrapper(m_World, m_ServerIDToClientID.at(packet.ReadPrimitive())); + e.Damage = packet.ReadPrimitive(); + // Don't rebroadcast our own player damage events or we'll have an infinite loop! + if (e.Inflictor != m_LocalPlayer) { + m_EventBroker->Publish(e); + } +} + void Client::sendLocalPlayerTransform() { if (!m_LocalPlayer.Valid()) { diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 7bb2722c..233fecbd 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -11,6 +11,7 @@ Server::Server(World* world, EventBroker* eventBroker, int port) EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted); EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Server::OnPlayerDamage); // Bind if (port == 0) { @@ -411,12 +412,22 @@ bool Server::OnComponentDeleted(const Events::ComponentDeleted & e) Packet packet = Packet(MessageType::ComponentDeleted); packet.WritePrimitive(e.Entity); packet.WriteString(e.ComponentType); - reliableBroadcast(packet); + reliableBroadcast(packet); } } return false; } +bool Server::OnPlayerDamage(const Events::PlayerDamage& e) +{ + Packet packet(MessageType::OnPlayerDamage); + packet.WritePrimitive(e.Inflictor.ID); + packet.WritePrimitive(e.Victim.ID); + packet.WritePrimitive(e.Damage); + reliableBroadcast(packet); + + return false; +} void Server::parseClientPing() { diff --git a/src/Game/Systems/DamageIndicatorSystem.cpp b/src/Game/Systems/DamageIndicatorSystem.cpp index 8d586ac1..09db268c 100644 --- a/src/Game/Systems/DamageIndicatorSystem.cpp +++ b/src/Game/Systems/DamageIndicatorSystem.cpp @@ -18,12 +18,15 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e) return false; } - if (e.Victim != LocalPlayer) { + //if (e.Victim != LocalPlayer) { + // return false; + //} + if (e.Victim != LocalPlayer && !e.Victim.IsChildOf(LocalPlayer)) { return false; } if (!e.Inflictor.Valid() || !e.Victim.Valid()) { - return false; + return false; } //grab players direction diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 719f6c9f..b21c1352 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -23,6 +23,10 @@ void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cHea bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) { + if (!IsServer) { + return false; + } + ComponentWrapper cHealth = e.Victim["Health"]; double& health = cHealth["Health"]; health -= e.Damage; From 78e318c032a9c47455fd2d55e0fad760b0f1a038 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 12 Feb 2016 07:14:36 +0100 Subject: [PATCH 41/43] Proper snapshot filtering --- src/Game/Network/MultiplayerSnapshotFilter.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Game/Network/MultiplayerSnapshotFilter.cpp b/src/Game/Network/MultiplayerSnapshotFilter.cpp index 65d40189..52255ed3 100644 --- a/src/Game/Network/MultiplayerSnapshotFilter.cpp +++ b/src/Game/Network/MultiplayerSnapshotFilter.cpp @@ -9,7 +9,15 @@ MultiplayerSnapshotFilter::MultiplayerSnapshotFilter(EventBroker* eventBroker) bool MultiplayerSnapshotFilter::FilterComponent(EntityWrapper entity, SharedComponentWrapper& component) { if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) { - return false; + if ( + component.Info.Name == "Transform" + || component.Info.Name == "Physics" + || component.Info.Name == "AssaultWeapon" + || component.Info.Name == "Animation" + || component.Info.Name == "AnimationOffset" + ) { + return false; + } } if (component.Info.Name == "Physics") { From b48d491ad780382ef1b7b8b38889b098ac2cf44a Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 12 Feb 2016 07:45:51 +0100 Subject: [PATCH 42/43] Complete blue and red player entities --- include/Game/Systems/HealthSystem.h | 7 +- resources/Schema/Entities/Player.xml | 16 +- resources/Schema/Entities/PlayerRed.xml | 366 ++++++++++++++++-- .../Schema/Entities/ReloadEffectViewRed.xml | 24 ++ .../Schema/Entities/ReloadEffectWorld.xml | 3 +- .../Schema/Entities/ReloadEffectWorldRed.xml | 25 ++ src/Game/Systems/HealthSystem.cpp | 3 +- 7 files changed, 401 insertions(+), 43 deletions(-) create mode 100644 resources/Schema/Entities/ReloadEffectViewRed.xml create mode 100644 resources/Schema/Entities/ReloadEffectWorldRed.xml diff --git a/include/Game/Systems/HealthSystem.h b/include/Game/Systems/HealthSystem.h index 21a52330..56f2f838 100644 --- a/include/Game/Systems/HealthSystem.h +++ b/include/Game/Systems/HealthSystem.h @@ -9,7 +9,8 @@ #include "Core/EPlayerDamage.h" #include "Core/EPlayerHealthPickup.h" #include "Core/EPlayerDeath.h" -#include "../Engine/Input/EInputCommand.h" +#include "Core/ConfigFile.h" +#include "Input/EInputCommand.h" #include #include @@ -24,6 +25,8 @@ public: virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override; private: + bool m_NetworkEnabled; + //methods which will take care of specific events EventRelay m_EPlayerDamage; bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e); @@ -34,7 +37,7 @@ private: //vector which will keep track of health changes std::vector> m_DeltaHealthVector; - + }; #endif \ No newline at end of file diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 125bd571..1d72189e 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -23,7 +23,9 @@ - + + + @@ -106,7 +108,7 @@ 100/100 Fonts/DroidSans.ttf,64 - + @@ -120,7 +122,7 @@ 1 - + Textures/HealthHUD3.png @@ -310,15 +312,14 @@ - - + + - Fonts/DroidSans.ttf,64 @@ -331,7 +332,6 @@ - Fonts/DroidSans.ttf,64 @@ -346,7 +346,6 @@ - Fonts/DroidSans.ttf,64 @@ -371,6 +370,7 @@ Models/Characters/Assault/FirstPerson.mesh + true diff --git a/resources/Schema/Entities/PlayerRed.xml b/resources/Schema/Entities/PlayerRed.xml index ae11fa00..3031f27b 100644 --- a/resources/Schema/Entities/PlayerRed.xml +++ b/resources/Schema/Entities/PlayerRed.xml @@ -23,9 +23,7 @@ - - - + @@ -71,25 +69,6 @@ - - - - 1 - - - - - Models/Core/UnitHexagon.mesh - - - - - - - - - - @@ -112,17 +91,284 @@ + + + + + + + + + 1 + + + + + 100/100 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + 1 + + + + Textures/HealthHUD3.png + + + + + + + + + + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 2 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 3 + + + 0.80222018197612788 + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 4 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 1 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + Idle - 0.1719161089749548 + 1.6050530664521858 1 Models/Characters/Assault/FirstPerson.mesh + true @@ -138,8 +384,8 @@ true - - + + @@ -157,12 +403,70 @@ - Schema/Entities/ReloadEffectView.xml + Schema/Entities/ReloadEffectViewRed.xml + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + + + + 32 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + 360 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + @@ -187,7 +491,7 @@ Idle - 1.8038469763698401 + 1.620305457513453 1 @@ -197,7 +501,7 @@ Models/Characters/Assault/AssaultAnimations.mesh - + @@ -211,8 +515,8 @@ Models/Weapons/Red/AssaultWeaponRed.mesh - - + + @@ -230,7 +534,7 @@ - Schema/Entities/ReloadEffectWorld.xml + Schema/Entities/ReloadEffectWorldRed.xml diff --git a/resources/Schema/Entities/ReloadEffectViewRed.xml b/resources/Schema/Entities/ReloadEffectViewRed.xml new file mode 100644 index 00000000..56b9d140 --- /dev/null +++ b/resources/Schema/Entities/ReloadEffectViewRed.xml @@ -0,0 +1,24 @@ + + + + + + 2 + + + true + + + true + + true + + + Models/Weapons/Red/AssaultWeaponRed.mesh + + + + + + + diff --git a/resources/Schema/Entities/ReloadEffectWorld.xml b/resources/Schema/Entities/ReloadEffectWorld.xml index 97236897..ae6d3a3e 100644 --- a/resources/Schema/Entities/ReloadEffectWorld.xml +++ b/resources/Schema/Entities/ReloadEffectWorld.xml @@ -10,11 +10,12 @@ true - + true Models/Weapons/Blue/AssaultWeaponBlue.mesh + true diff --git a/resources/Schema/Entities/ReloadEffectWorldRed.xml b/resources/Schema/Entities/ReloadEffectWorldRed.xml new file mode 100644 index 00000000..55c37389 --- /dev/null +++ b/resources/Schema/Entities/ReloadEffectWorldRed.xml @@ -0,0 +1,25 @@ + + + + + + 2 + + + true + + + true + + true + + + Models/Weapons/Red/AssaultWeaponRed.mesh + true + + + + + + + diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index b21c1352..eac7bf2d 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -8,6 +8,7 @@ HealthSystem::HealthSystem(SystemParams params) EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &HealthSystem::OnPlayerDamaged); EVENT_SUBSCRIBE_MEMBER(m_EPlayerHealthPickup, &HealthSystem::OnPlayerHealthPickup); EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &HealthSystem::OnInputCommand); + m_NetworkEnabled = ResourceManager::Load("Config.ini")->Get("Networking.StartNetwork", false); } void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cHealth, double dt) @@ -23,7 +24,7 @@ void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cHea bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) { - if (!IsServer) { + if (!IsServer && m_NetworkEnabled) { return false; } From eb7b22c7578ae8f63a7b1b10b3c53eafa6b5c074 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 12 Feb 2016 07:48:26 +0100 Subject: [PATCH 43/43] Latest assets --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 078e014f..8d180f2a 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 078e014f3d24a100c4cb544ac6807aa2b54149b2 +Subproject commit 8d180f2a54154191587107e6569bbae0a049be46