From a2569402f31c1e0b5476e0b163d44f1b4837db2b Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Thu, 11 Jan 2024 02:20:53 +0100 Subject: [PATCH 01/48] fix(Logger): Update Logger.hpp to other platform than linux and Windows --- Flakkari/Logger/Logger.hpp | 39 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/Flakkari/Logger/Logger.hpp b/Flakkari/Logger/Logger.hpp index d0575d0d..a969e554 100644 --- a/Flakkari/Logger/Logger.hpp +++ b/Flakkari/Logger/Logger.hpp @@ -30,25 +30,7 @@ #define STD_ERROR std::string(::strerror(errno)) -#ifdef __linux__ -#define COLOR_RESET "\033[0m" -#define COLOR_RED "\033[31m" -#define COLOR_GREEN "\033[32m" -#define COLOR_YELLOW "\033[33m" -#define COLOR_BLUE "\033[34m" -#define COLOR_MAGENTA "\033[35m" -#define COLOR_CYAN "\033[36m" -#define COLOR_WHITE "\033[37m" -#define COLOR_ORANGE "\033[38;5;208m" -#define COLOR_BRIGHT_RED "\033[91m" -#define COLOR_BRIGHT_GREEN "\033[92m" -#define COLOR_BRIGHT_YELLOW "\033[93m" -#define COLOR_BRIGHT_BLUE "\033[94m" -#define COLOR_BRIGHT_MAGENTA "\033[95m" -#define COLOR_BRIGHT_CYAN "\033[96m" -#define COLOR_BRIGHT_WHITE "\033[97m" - -#elif _WIN32 +#if _WIN32 #include #define COLOR_RESET 7 @@ -67,6 +49,25 @@ #define COLOR_BRIGHT_MAGENTA FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY #define COLOR_BRIGHT_CYAN FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY #define COLOR_BRIGHT_WHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY + +#else + +#define COLOR_RESET "\033[0m" +#define COLOR_RED "\033[31m" +#define COLOR_GREEN "\033[32m" +#define COLOR_YELLOW "\033[33m" +#define COLOR_BLUE "\033[34m" +#define COLOR_MAGENTA "\033[35m" +#define COLOR_CYAN "\033[36m" +#define COLOR_WHITE "\033[37m" +#define COLOR_ORANGE "\033[38;5;208m" +#define COLOR_BRIGHT_RED "\033[91m" +#define COLOR_BRIGHT_GREEN "\033[92m" +#define COLOR_BRIGHT_YELLOW "\033[93m" +#define COLOR_BRIGHT_BLUE "\033[94m" +#define COLOR_BRIGHT_MAGENTA "\033[95m" +#define COLOR_BRIGHT_CYAN "\033[96m" +#define COLOR_BRIGHT_WHITE "\033[97m" #endif namespace Flakkari { From d983ae79b7c2e3a817f8f6b213a5a54ef7e7450d Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Thu, 11 Jan 2024 02:42:06 +0100 Subject: [PATCH 02/48] feat(Network): Add packed.hpp for network structs --- CMakeLists.txt | 3 +++ Flakkari/Network/packed.hpp | 54 +++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 Flakkari/Network/packed.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 210ac7b2..ed4275e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ set(SOURCES set(HEADERS Flakkari/Logger/Logger.hpp + Flakkari/Network/packed.hpp Flakkari/Network/Address.hpp Flakkari/Network/Buffer.hpp Flakkari/Network/Socket.hpp @@ -52,6 +53,7 @@ set(HEADER_LIB_LOGGER ) set(HEADER_LIB_NETWORK + Flakkari/Network/packed.hpp Flakkari/Network/Address.hpp Flakkari/Network/Buffer.hpp Flakkari/Network/Socket.hpp @@ -146,6 +148,7 @@ include(CPack) # Create a dynamic library for the Network components set(SOURCES_LIB_NETWORK Flakkari/Logger/Logger.cpp + Flakkari/Network/packed.hpp Flakkari/Network/Address.cpp Flakkari/Network/Buffer.cpp Flakkari/Network/Socket.cpp diff --git a/Flakkari/Network/packed.hpp b/Flakkari/Network/packed.hpp new file mode 100644 index 00000000..3415b523 --- /dev/null +++ b/Flakkari/Network/packed.hpp @@ -0,0 +1,54 @@ +/************************************************************************** + * Flakkari Library v0.2.0 + * + * Flakkari Library is a C++ Library for Network. + * @file packed.hpp + * @brief packed header. Contains PACKED macros. + * (PACKED_START, PACKED_END, PACKED) + * + * @details PACKED_START and PACKED_END macros are used to pack structs: + * PACKED_<_> macros are used to pack structs: + * PACKED_START struct _ {}; PACKED_END + * PACKED macros are used to pack structs: + * struct _ {} PACKED; + * + * Flakkari Library is under MIT License. + * https://opensource.org/licenses/MIT + * © 2023 @MasterLaplace + * @version 0.2.0 + * @date 2023-01-10 + **************************************************************************/ + + +#ifndef PACKED_HPP_ + #define PACKED_HPP_ + +#ifdef _MSC_VER +#define PACKED_START __pragma(pack(push, 1)) +#define PACKED_END __pragma(pack(pop)) +#else +#define PACKED_START _Pragma("pack(1)") +#define PACKED_END _Pragma("pack()") +#endif + +#if __GNUC__ +#define __PACKED __attribute__((packed)) + +#define PACKED(name, body) \ +do { \ + struct name body __PACKED; \ +} while (0) + +#else + +#define PACKED(name, body) \ +do { \ + PACKED_START \ + struct name \ + body; \ + PACKED_END \ +} while (0) + +#endif + +#endif /* !PACKED_HPP_ */ From aac03c9d5ce53b53255987b2e14d3b6dfa02894f Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Thu, 11 Jan 2024 02:49:47 +0100 Subject: [PATCH 03/48] update(Flakkari): Add packed attribute to structs --- CMakeLists.txt | 6 +++--- .../Components/2D/Movable.hpp | 6 ++++++ .../Components/2D/Transform.hpp | 6 ++++++ .../Components/Common/Child.hpp | 14 ++++++++++++-- .../Components/Common/Parent.hpp | 10 +++++++++- .../Components/Common/Tag.hpp | 14 ++++++++++++-- Flakkari/Engine/EntityComponentSystem/Entity.hpp | 1 + Flakkari/Engine/Math/Vector.hpp | 14 ++++++++------ Flakkari/Network/{packed.hpp => Packed.hpp} | 4 ++-- Flakkari/Protocol/Header.hpp | 11 +++++++---- Flakkari/Protocol/Packet.hpp | 4 ++++ Flakkari/Server/Client/Client.hpp | 5 +++-- 12 files changed, 73 insertions(+), 22 deletions(-) rename Flakkari/Network/{packed.hpp => Packed.hpp} (95%) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed4275e1..70215173 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ set(SOURCES set(HEADERS Flakkari/Logger/Logger.hpp - Flakkari/Network/packed.hpp + Flakkari/Network/Packed.hpp Flakkari/Network/Address.hpp Flakkari/Network/Buffer.hpp Flakkari/Network/Socket.hpp @@ -53,7 +53,7 @@ set(HEADER_LIB_LOGGER ) set(HEADER_LIB_NETWORK - Flakkari/Network/packed.hpp + Flakkari/Network/Packed.hpp Flakkari/Network/Address.hpp Flakkari/Network/Buffer.hpp Flakkari/Network/Socket.hpp @@ -148,7 +148,7 @@ include(CPack) # Create a dynamic library for the Network components set(SOURCES_LIB_NETWORK Flakkari/Logger/Logger.cpp - Flakkari/Network/packed.hpp + Flakkari/Network/Packed.hpp Flakkari/Network/Address.cpp Flakkari/Network/Buffer.cpp Flakkari/Network/Socket.cpp diff --git a/Flakkari/Engine/EntityComponentSystem/Components/2D/Movable.hpp b/Flakkari/Engine/EntityComponentSystem/Components/2D/Movable.hpp index 048e2760..68bbce0e 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/2D/Movable.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/2D/Movable.hpp @@ -13,6 +13,7 @@ #include "../../../Math/Vector.hpp" namespace Flakkari::Engine::ECS::Components::_2D { +PACKED_START struct Movable { Math::Vector2d velocity; // pixels / second @@ -23,8 +24,13 @@ struct Movable { Movable() : velocity(0, 0), acceleration(0, 0) {}; Movable(const Math::Vector2d &velocity, const Math::Vector2d &acceleration) : velocity(velocity), acceleration(acceleration) {}; Movable(const Movable &other) : velocity(other.velocity), acceleration(other.acceleration) {}; + + std::size_t size() const { + return sizeof(*this); + } }; +PACKED_END } // namespace Game::ECS::Components::_2D #endif /* !MOVABLE_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/2D/Transform.hpp b/Flakkari/Engine/EntityComponentSystem/Components/2D/Transform.hpp index 165dc216..58c604ac 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/2D/Transform.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/2D/Transform.hpp @@ -13,6 +13,7 @@ #include "../../../Math/Vector.hpp" namespace Flakkari::Engine::ECS::Components::_2D { +PACKED_START struct Transform { Math::Vector2d position; @@ -22,8 +23,13 @@ struct Transform { Transform() : position(0, 0), scale(1, 1), rotation(0) {}; Transform(const Math::Vector2d &position, const Math::Vector2d &scale, double rotation) : position(position), scale(scale), rotation(rotation) {}; Transform(const Transform &other) : position(other.position), scale(other.scale), rotation(other.rotation) {}; + + std::size_t size() const { + return sizeof(*this); + } }; +PACKED_END } // namespace Game::ECS::Components::_2D #endif /* !TRANSFORM_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Child.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Child.hpp index d7ddc6d6..db47b3d2 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Child.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Child.hpp @@ -11,8 +11,12 @@ #define CHILD_HPP_ #include +#include + +#include "Network/Packed.hpp" namespace Flakkari::Engine::ECS::Components::Common { +PACKED_START /** * @brief Child component for ECS entities that have a child entity attached to them @@ -21,13 +25,19 @@ namespace Flakkari::Engine::ECS::Components::Common { * and attach it to the entity that has this component */ struct Child { - std::string name; + const char *name; Child() : name("") {} - Child(const std::string &name) : name(name) {} + Child(const std::string &nname) : name(nname.c_str()) {} + Child(const char *nname) : name(nname) {} Child(const Child &other) : name(other.name) {} + + std::size_t size() const { + return std::strlen(name); + } }; +PACKED_END } // namespace Flakkari::Engine::ECS::Components::Common #endif /* !CHILD_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Parent.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Parent.hpp index 0e15d141..c865cc6e 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Parent.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Parent.hpp @@ -10,9 +10,12 @@ #ifndef PARENT_HPP_ #define PARENT_HPP_ -#include +#include + +#include "Network/Packed.hpp" namespace Flakkari::Engine::ECS::Components::Common { +PACKED_START /** * @brief Parent component for ECS entities that have a parent entity attached to them @@ -25,8 +28,13 @@ struct Parent { Parent() : entity(0) {} Parent(const std::size_t &entity) : entity(entity) {} Parent(const Parent &other) : entity(other.entity) {} + + std::size_t size() const { + return sizeof(*this); + } }; +PACKED_END } // namespace Flakkari::Engine::ECS::Components::Common #endif /* !PARENT_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Tag.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Tag.hpp index 35f66384..6466946e 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Tag.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Tag.hpp @@ -11,8 +11,12 @@ #define TAG_HPP_ #include +#include + +#include "Network/Packed.hpp" namespace Flakkari::Engine::ECS::Components::Common { +PACKED_START /** * @brief Tag component for ECS entities that have a script attached to them @@ -20,13 +24,19 @@ namespace Flakkari::Engine::ECS::Components::Common { * @details This component is used to store the path to the script that will be executed */ struct Tag { - std::string tag; + const char *tag; Tag() : tag("") {} - Tag(const std::string &tag) : tag(tag) {} + Tag(const std::string &ntag) : tag(ntag.c_str()) {} + Tag(const char *ntag) : tag(ntag) {} Tag(const Tag &other) : tag(other.tag) {} + + std::size_t size() const { + return std::strlen(tag); + } }; +PACKED_END } // namespace Game::ECS::Components::Common #endif /* !TAG_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Entity.hpp b/Flakkari/Engine/EntityComponentSystem/Entity.hpp index 728524b5..d39e583e 100644 --- a/Flakkari/Engine/EntityComponentSystem/Entity.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Entity.hpp @@ -17,6 +17,7 @@ #define ENTITY_HPP_ #include +#include namespace Flakkari::Engine::ECS { diff --git a/Flakkari/Engine/Math/Vector.hpp b/Flakkari/Engine/Math/Vector.hpp index 6a3d0770..ebfcb03c 100644 --- a/Flakkari/Engine/Math/Vector.hpp +++ b/Flakkari/Engine/Math/Vector.hpp @@ -22,38 +22,39 @@ #include #include -namespace Flakkari::Engine::Math { +#include "Network/Packed.hpp" -#define PACKED __attribute__((packed)) +namespace Flakkari::Engine::Math { template struct Vector { +PACKED_START union { struct { Type x; Type y; Type z; Type w; - } PACKED; + }; struct { Type r; Type g; Type b; Type a; - } PACKED; + }; struct { Type width; Type height; Type depth; Type time; - } PACKED; + }; struct { Type dx; Type dy; Type dz; Type _; - } PACKED; + }; Type v[4]; }; @@ -63,6 +64,7 @@ struct Vector { Vector(Type x, Type y) : v{x, y, 0, 1} {}; Vector(Type x) : v{x, 0, 0, 1} {}; Vector(const Vector &other) : v{other.v[0], other.v[1], other.v[2], other.v[3]} {}; +PACKED_END Vector &operator=(const Vector &other) { diff --git a/Flakkari/Network/packed.hpp b/Flakkari/Network/Packed.hpp similarity index 95% rename from Flakkari/Network/packed.hpp rename to Flakkari/Network/Packed.hpp index 3415b523..894ea2e3 100644 --- a/Flakkari/Network/packed.hpp +++ b/Flakkari/Network/Packed.hpp @@ -2,8 +2,8 @@ * Flakkari Library v0.2.0 * * Flakkari Library is a C++ Library for Network. - * @file packed.hpp - * @brief packed header. Contains PACKED macros. + * @file Packed.hpp + * @brief Packed header. Contains PACKED macros. * (PACKED_START, PACKED_END, PACKED) * * @details PACKED_START and PACKED_END macros are used to pack structs: diff --git a/Flakkari/Protocol/Header.hpp b/Flakkari/Protocol/Header.hpp index d2575941..f0991a6e 100644 --- a/Flakkari/Protocol/Header.hpp +++ b/Flakkari/Protocol/Header.hpp @@ -19,11 +19,10 @@ #define PROTOCOL_VERSION 1 -#define PACKED __attribute__((packed)) - -#include "../Network/Buffer.hpp" +#include "../Network/Packed.hpp" #include "Event.hpp" + namespace Flakkari::Protocol::API { using byte = byte_t; // 8 bits (max: 255) @@ -50,6 +49,8 @@ namespace Flakkari::Protocol::API { V_1 = 1 }; + PACKED_START + /** @brief Flakkari Header v1 (new header) * * 0 1 2 3 @@ -117,7 +118,9 @@ namespace Flakkari::Protocol::API { * */ void print(); - } PACKED; + }; + + PACKED_END /** * @brief Overload of the << operator to print the header in the console (for debug) diff --git a/Flakkari/Protocol/Packet.hpp b/Flakkari/Protocol/Packet.hpp index 0d5171d6..ef9addf5 100644 --- a/Flakkari/Protocol/Packet.hpp +++ b/Flakkari/Protocol/Packet.hpp @@ -27,6 +27,8 @@ namespace Flakkari::Protocol::API { inline namespace V_1 { + PACKED_START + /** * @brief Flakkari Packet v1 (new packet) * @@ -75,6 +77,8 @@ namespace Flakkari::Protocol::API { void deleteFragment(Network::Buffer fragment); }; + PACKED_END + void serializeHeader(Header header, Network::Buffer& buffer); void serializeBuffer(Network::Buffer buffer, Network::Buffer& buffer2); diff --git a/Flakkari/Server/Client/Client.hpp b/Flakkari/Server/Client/Client.hpp index 09d9bd92..63c91127 100644 --- a/Flakkari/Server/Client/Client.hpp +++ b/Flakkari/Server/Client/Client.hpp @@ -1,5 +1,5 @@ /************************************************************************** - * Flakkari Library v0.1.0 + * Flakkari Library v0.2.0 * * Flakkari Library is a C++ Library for Network. * @file Client.hpp @@ -9,10 +9,11 @@ * Flakkari Library is under MIT License. * https://opensource.org/licenses/MIT * © 2023 @MasterLaplace - * @version 0.1.0 + * @version 0.2.0 * @date 2023-12-24 **************************************************************************/ + #ifndef CLIENT_HPP_ #define CLIENT_HPP_ From 6c7a003bc7104da743790baeb478cd31b74e8174 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Thu, 11 Jan 2024 02:59:47 +0100 Subject: [PATCH 04/48] feat(Protocol): Add Serializer class for object serialization and deserialization --- CMakeLists.txt | 3 +- Flakkari/Network/Packed.hpp | 16 --------- Flakkari/Network/Serializer.hpp | 64 +++++++++++++++++++++++++++++++++ Flakkari/Protocol/Event.hpp | 2 +- Flakkari/Protocol/Header.cpp | 10 +++--- Flakkari/Protocol/Header.hpp | 13 +++---- Flakkari/Server/UDPServer.cpp | 2 +- 7 files changed, 80 insertions(+), 30 deletions(-) create mode 100644 Flakkari/Network/Serializer.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 70215173..1333798f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ set(HEADERS Flakkari/Network/Address.hpp Flakkari/Network/Buffer.hpp Flakkari/Network/Socket.hpp + Flakkari/Network/Serializer.hpp Flakkari/Network/IOMultiplexer.hpp Flakkari/Protocol/Header.hpp Flakkari/Protocol/Packet.hpp @@ -57,6 +58,7 @@ set(HEADER_LIB_NETWORK Flakkari/Network/Address.hpp Flakkari/Network/Buffer.hpp Flakkari/Network/Socket.hpp + Flakkari/Network/Serializer.hpp Flakkari/Network/IOMultiplexer.hpp ) @@ -148,7 +150,6 @@ include(CPack) # Create a dynamic library for the Network components set(SOURCES_LIB_NETWORK Flakkari/Logger/Logger.cpp - Flakkari/Network/Packed.hpp Flakkari/Network/Address.cpp Flakkari/Network/Buffer.cpp Flakkari/Network/Socket.cpp diff --git a/Flakkari/Network/Packed.hpp b/Flakkari/Network/Packed.hpp index 894ea2e3..6119ef96 100644 --- a/Flakkari/Network/Packed.hpp +++ b/Flakkari/Network/Packed.hpp @@ -33,22 +33,6 @@ #if __GNUC__ #define __PACKED __attribute__((packed)) - -#define PACKED(name, body) \ -do { \ - struct name body __PACKED; \ -} while (0) - -#else - -#define PACKED(name, body) \ -do { \ - PACKED_START \ - struct name \ - body; \ - PACKED_END \ -} while (0) - #endif #endif /* !PACKED_HPP_ */ diff --git a/Flakkari/Network/Serializer.hpp b/Flakkari/Network/Serializer.hpp new file mode 100644 index 00000000..50255833 --- /dev/null +++ b/Flakkari/Network/Serializer.hpp @@ -0,0 +1,64 @@ +/************************************************************************** + * Flakkari Library v0.2.0 + * + * Flakkari Library is a C++ Library for Network. + * @file Serializer.hpp + * @brief Class used to serialize and deserialize objects. (POD types) + * + * Flakkari Library is under MIT License. + * https://opensource.org/licenses/MIT + * © 2023 @MasterLaplace + * @version 0.2.0 + * @date 2023-12-2 + **************************************************************************/ + + +#ifndef SERIALIZER_HPP_ + #define SERIALIZER_HPP_ + +#include "Buffer.hpp" + +namespace Flakkari::Network { + +/** + * @brief Class used to serialize and deserialize objects. + * + * @details This class is used to serialize and deserialize objects. + * It is used to serialize and deserialize especially components + * in the Flakkari/Protocol/Component.hpp file. + */ +class Serializer { +public: + + /** + * @brief Serialize an object into a buffer. + * + * @tparam T The type of the object to serialize. Must be a POD type. (Plain Old Data) + * @param obj The object to serialize. Must be a POD type. (Plain Old Data) + * @return Network::Buffer The serialized object. + */ + template + static Network::Buffer serialize(const T &obj) { + Network::Buffer buffer(sizeof(obj)); + std::copy((byte *)&obj, (byte *)&obj + sizeof(obj), buffer.begin()); + return buffer; + } + + /** + * @brief Deserialize an object from a buffer. + * + * @tparam T The type of the object to deserialize. Must be a POD type. (Plain Old Data) + * @param buffer The buffer to deserialize the object from. + * @return T The deserialized object. Must be a POD type. (Plain Old Data) + */ + template + static T deserialize(const Network::Buffer &buffer) { + T obj; + std::copy(buffer.begin(), buffer.begin() + sizeof(T), (byte *)&obj); + return obj; + } +}; + +} // namespace Flakkari::Network + +#endif /* !SERIALIZER_HPP_ */ diff --git a/Flakkari/Protocol/Event.hpp b/Flakkari/Protocol/Event.hpp index 01f31b03..092dd96b 100644 --- a/Flakkari/Protocol/Event.hpp +++ b/Flakkari/Protocol/Event.hpp @@ -12,7 +12,7 @@ namespace Flakkari::Protocol::API { inline namespace V_1 { - enum class FlakkariEventId { + enum class FlakkariEventId : uint8_t { // 0 - 99: System REQ_CONNECT = 0, // Client -> Server (Connect to server) REP_CONNECT = 1, // Server -> Client (Connection accepted) diff --git a/Flakkari/Protocol/Header.cpp b/Flakkari/Protocol/Header.cpp index 3f2d1d42..25eeb51f 100644 --- a/Flakkari/Protocol/Header.cpp +++ b/Flakkari/Protocol/Header.cpp @@ -19,11 +19,11 @@ inline namespace V_1 { Header::Header( Priority priority, ApiVersion apiVersion, - byte commandId, ushort contentLength//, + FlakkariEventId commandId, ushort contentLength//, // ulong sequenceNumber, ushort checksum ) { - _priority = (byte)priority; - _apiVersion = (byte)apiVersion; + _priority = priority; + _apiVersion = apiVersion; _commandId = commandId; _contentLength = contentLength; // _sequenceNumber = sequenceNumber; @@ -31,8 +31,8 @@ inline namespace V_1 { } Header::Header() { - _priority = 0; - _apiVersion = (byte)ApiVersion::V_1; + _priority = Priority::LOW; + _apiVersion = ApiVersion::V_1; } Network::Buffer Header::toBuffer() diff --git a/Flakkari/Protocol/Header.hpp b/Flakkari/Protocol/Header.hpp index f0991a6e..8da93782 100644 --- a/Flakkari/Protocol/Header.hpp +++ b/Flakkari/Protocol/Header.hpp @@ -19,6 +19,7 @@ #define PROTOCOL_VERSION 1 +#include "../Network/Serializer.hpp" #include "../Network/Packed.hpp" #include "Event.hpp" @@ -38,14 +39,14 @@ namespace Flakkari::Protocol::API { * @note The priority is used to determine the order of the messages in the queue. * The higher the priority, the faster the message will be processed. */ - enum class Priority { + enum class Priority : byte { LOW = 0, MEDIUM = 1, HIGH = 2, CRITICAL = 3 }; - enum class ApiVersion { + enum class ApiVersion : byte { V_1 = 1 }; @@ -82,9 +83,9 @@ namespace Flakkari::Protocol::API { * @endcode */ struct Header { - byte _priority: 4; - byte _apiVersion: 4; - byte _commandId; + Priority _priority: 4; + ApiVersion _apiVersion: 4; + FlakkariEventId _commandId; ushort _contentLength; // ulong _sequenceNumber; // ushort _checksum; @@ -99,7 +100,7 @@ namespace Flakkari::Protocol::API { Header( Priority priority, ApiVersion apiVersion, - byte commandId, ushort contentLength = 0//, + FlakkariEventId commandId, ushort contentLength = 0//, // ulong sequenceNumber = 0, ushort checksum = 0 ); diff --git a/Flakkari/Server/UDPServer.cpp b/Flakkari/Server/UDPServer.cpp index 44ed2836..ca7218ce 100644 --- a/Flakkari/Server/UDPServer.cpp +++ b/Flakkari/Server/UDPServer.cpp @@ -72,7 +72,7 @@ void UDPServer::handlePacket() Protocol::API::Header sendHeader( Protocol::API::Priority::LOW, Protocol::API::ApiVersion::V_1, - int(Protocol::API::FlakkariEventId::REP_ENTITY_SPAWN), + Protocol::API::FlakkariEventId::REP_ENTITY_SPAWN, 0 ); From a470dae1a447447efe4e37b99cbae78779b0ffb4 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Thu, 11 Jan 2024 03:10:42 +0100 Subject: [PATCH 05/48] update(Protocol): Refactor packet content handling --- Flakkari/Network/Packed.hpp | 16 ++++++ Flakkari/Protocol/Packet.cpp | 32 ++++++----- Flakkari/Protocol/Packet.hpp | 108 +++++++++++++++++------------------ Scripts/cpp_norm_checker.py | 2 + 4 files changed, 89 insertions(+), 69 deletions(-) diff --git a/Flakkari/Network/Packed.hpp b/Flakkari/Network/Packed.hpp index 6119ef96..894ea2e3 100644 --- a/Flakkari/Network/Packed.hpp +++ b/Flakkari/Network/Packed.hpp @@ -33,6 +33,22 @@ #if __GNUC__ #define __PACKED __attribute__((packed)) + +#define PACKED(name, body) \ +do { \ + struct name body __PACKED; \ +} while (0) + +#else + +#define PACKED(name, body) \ +do { \ + PACKED_START \ + struct name \ + body; \ + PACKED_END \ +} while (0) + #endif #endif /* !PACKED_HPP_ */ diff --git a/Flakkari/Protocol/Packet.cpp b/Flakkari/Protocol/Packet.cpp index 6c4a2236..3d4a52fe 100644 --- a/Flakkari/Protocol/Packet.cpp +++ b/Flakkari/Protocol/Packet.cpp @@ -15,31 +15,33 @@ namespace Flakkari::Protocol::API { Packet::Packet(Network::Buffer data) { header = Header(data); - content = data.extractData(sizeof(header), header._contentLength); + payload = data.extractData(sizeof(header), header._contentLength); } - Packet::Packet(Header header, Network::Buffer content) - : header(header), content(content) {} + Packet::Packet(Header header, Network::Buffer payload) + : header(header), payload(payload) {} Packet::Packet(Header header) : header(header) {} template - void Packet::addContent(T content) { - this->content += Network::Buffer(content); + void Packet::addContent(T payload) { + this->payload += Network::Buffer(payload); + this->header._contentLength += sizeof(T); } void Packet::addFragment(Network::Buffer fragment) { - this->content += fragment; + this->payload += fragment; this->header._contentLength += fragment.size(); } template - void Packet::deleteContent(T content) { - this->content -= Network::Buffer(content); + void Packet::deleteContent(T payload) { + this->payload -= Network::Buffer(payload); + this->header._contentLength -= sizeof(T); } void Packet::deleteFragment(Network::Buffer fragment) { - this->content -= fragment; + this->payload -= fragment; this->header._contentLength -= fragment.size(); } @@ -47,26 +49,26 @@ namespace Flakkari::Protocol::API { std::copy((byte *) &header, (byte *) &header + sizeof(Header), buffer.begin()); } - void serializeBuffer(Network::Buffer buffer, Network::Buffer& buffer2) { - std::copy(buffer.begin(), buffer.end(), buffer2.begin()); + void serializeBuffer(Network::Buffer buffer, Network::Buffer& dest) { + std::copy(buffer.begin(), buffer.end(), dest.begin()); } void serializePacket(Packet packet, Network::Buffer& buffer) { serializeHeader(packet.header, buffer); - serializeBuffer(packet.content, buffer); + serializeBuffer(packet.payload, buffer); } void deserializeHeader(Network::Buffer buffer, Header& header) { std::copy(buffer.begin(), buffer.begin() + sizeof(Header), (byte *) &header); } - void deserializeBuffer(Network::Buffer buffer, Network::Buffer& buffer2) { - std::copy(buffer.begin(), buffer.end(), buffer2.begin()); + void deserializeBuffer(Network::Buffer buffer, Network::Buffer& dest) { + std::copy(buffer.begin(), buffer.end(), dest.begin()); } void deserializePacket(Network::Buffer buffer, Packet& packet) { deserializeHeader(buffer, packet.header); - deserializeBuffer(buffer, packet.content); + deserializeBuffer(buffer, packet.payload); } } /* namespace V_1 */ diff --git a/Flakkari/Protocol/Packet.hpp b/Flakkari/Protocol/Packet.hpp index ef9addf5..9965d03d 100644 --- a/Flakkari/Protocol/Packet.hpp +++ b/Flakkari/Protocol/Packet.hpp @@ -4,9 +4,9 @@ * Flakkari Library is a C++ Library for Network. * @file Packet.hpp * @brief Flakkari::Protocol::API::Packet class header. This class is used to - * represent a packet. A packet is a header and a content. + * represent a packet. A packet is a header and a payload. * - The header is a Flakkari::Protocol::API::Header object. - * - The content is a Flakkari::Network::Buffer object. + * - The payload is a Flakkari::Network::Buffer object. * * @see Flakkari::Protocol::API::Header * @see Flakkari::Network::Buffer @@ -25,73 +25,73 @@ namespace Flakkari::Protocol::API { - inline namespace V_1 { +inline namespace V_1 { PACKED_START + /** + * @brief Flakkari Packet v1 (new packet) + * + * @param header: The header of the packet. + * @param payload: The payload of the packet. + */ + struct Packet { + Header header; + Network::Buffer payload; + + Packet(Network::Buffer data); + Packet(Header header, Network::Buffer payload); + Packet(Header header); + Packet() = default; + + /** + * @brief Add payload to the packet. + * + * @tparam T The type of the payload to add. + * @param payload The payload to add. + */ + template + void addContent(T payload); + + /** + * @brief Add a fragment to the packet. + * + * @param fragment The fragment to add. + */ + void addFragment(Network::Buffer fragment); + + /** + * @brief Delete payload from the packet. + * + * @tparam T The type of the payload to delete. + * @param payload The payload to delete. + */ + template + void deleteContent(T payload); + /** - * @brief Flakkari Packet v1 (new packet) + * @brief Delete a fragment from the packet. * - * @param header: The header of the packet. - * @param content: The content of the packet. + * @param fragment The fragment to delete. */ - struct Packet { - Header header; - Network::Buffer content; - - Packet(Network::Buffer data); - Packet(Header header, Network::Buffer content); - Packet(Header header); - Packet() = default; - - /** - * @brief Add content to the packet. - * - * @tparam T The type of the content to add. - * @param content The content to add. - */ - template - void addContent(T content); - - /** - * @brief Add a fragment to the packet. - * - * @param fragment The fragment to add. - */ - void addFragment(Network::Buffer fragment); - - /** - * @brief Delete content from the packet. - * - * @tparam T The type of the content to delete. - * @param content The content to delete. - */ - template - void deleteContent(T content); - - /** - * @brief Delete a fragment from the packet. - * - * @param fragment The fragment to delete. - */ - void deleteFragment(Network::Buffer fragment); - }; + void deleteFragment(Network::Buffer fragment); + }; PACKED_END - void serializeHeader(Header header, Network::Buffer& buffer); + void serializeHeader(Header header, Network::Buffer& buffer); - void serializeBuffer(Network::Buffer buffer, Network::Buffer& buffer2); + void serializeBuffer(Network::Buffer buffer, Network::Buffer& buffer2); - void serializePacket(Packet packet, Network::Buffer& buffer); + void serializePacket(Packet packet, Network::Buffer& buffer); - void deserializeHeader(Network::Buffer buffer, Header& header); + void deserializeHeader(Network::Buffer buffer, Header& header); - void deserializeBuffer(Network::Buffer buffer, Network::Buffer& buffer2); + void deserializeBuffer(Network::Buffer buffer, Network::Buffer& buffer2); - void deserializePacket(Network::Buffer buffer, Packet& packet); + void deserializePacket(Network::Buffer buffer, Packet& packet); - } /* namespace V_1 */ +} /* namespace V_1 */ } // namespace Flakkari::Protocol::API diff --git a/Scripts/cpp_norm_checker.py b/Scripts/cpp_norm_checker.py index a043320a..5aac0380 100644 --- a/Scripts/cpp_norm_checker.py +++ b/Scripts/cpp_norm_checker.py @@ -33,6 +33,8 @@ def check_structure_name(self, file_name: str, content: str): matches = re.findall(pattern, content) for struct_name in matches: + if content.find(f" *") != -1 or content.find(f"{{ \\") != -1: + continue if not struct_name[0].isupper(): incorrect_structures.append(struct_name) From c0504f710e794da64e1888b4373d4c8ee64c855e Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Thu, 11 Jan 2024 03:20:11 +0100 Subject: [PATCH 06/48] feat(Components): Add Control component for 2D entities --- .../Components/2D/Control.hpp | 49 +++++++++++++++++++ .../Components/Components2D.hpp | 1 + 2 files changed, 50 insertions(+) create mode 100644 Flakkari/Engine/EntityComponentSystem/Components/2D/Control.hpp diff --git a/Flakkari/Engine/EntityComponentSystem/Components/2D/Control.hpp b/Flakkari/Engine/EntityComponentSystem/Components/2D/Control.hpp new file mode 100644 index 00000000..5e6a7210 --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Components/2D/Control.hpp @@ -0,0 +1,49 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2023-01-11 +** File description: +** Control +*/ + +#ifndef CONTROL_HPP_ +#define CONTROL_HPP_ + +#include "../../../Math/Vector.hpp" + +namespace Flakkari::Engine::ECS::Components::_2D { +PACKED_START + +/** + * @brief Control component for 2D entities (player, enemies, etc...) + * + * @details + * up: move up (give access to the move up) + * down: move down (give access to the move down) + * left: move left (give access to the move left) + * right: move right (give access to the move right) + * shoot: shoot (give access to the shoot) + */ +struct Control { + bool up; + bool down; + bool left; + bool right; + bool shoot; + + Control() : up(false), down(false), left(false), right(false), shoot(false) {}; + Control(bool up, bool down, bool left, bool right, bool shoot) + : up(up), down(down), left(left), right(right), shoot(shoot) {}; + Control(const Control &other) + : up(other.up), down(other.down), left(other.left), right(other.right), shoot(other.shoot) {}; + + std::size_t size() const { + return sizeof(*this); + } +}; + +PACKED_END +} // namespace Flakkari::Engine::ECS::Components::_2D + +#endif /* !CONTROL_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp index a7ced3fd..ee033868 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp @@ -16,6 +16,7 @@ #ifndef COMPONENTS2D_HPP_ #define COMPONENTS2D_HPP_ +#include "2D/Control.hpp" // Control component (up, down, left, right, shoot) #include "2D/Movable.hpp" // Movable component (velocity, angularVelocity, acceleration, angularAcceleration) #include "2D/Transform.hpp" // Transform component (position, rotation, scale) From 4088f9afb2979134539d349667b262df4957d262 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Fri, 12 Jan 2024 14:38:25 +0100 Subject: [PATCH 07/48] update(Components): Update Movable and Transform structs to use float instead of double --- .../EntityComponentSystem/Components/2D/Movable.hpp | 10 +++++----- .../EntityComponentSystem/Components/2D/Transform.hpp | 8 ++++---- Flakkari/Server/Game/Game.cpp | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Flakkari/Engine/EntityComponentSystem/Components/2D/Movable.hpp b/Flakkari/Engine/EntityComponentSystem/Components/2D/Movable.hpp index 68bbce0e..0fc628cd 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/2D/Movable.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/2D/Movable.hpp @@ -16,13 +16,13 @@ namespace Flakkari::Engine::ECS::Components::_2D { PACKED_START struct Movable { - Math::Vector2d velocity; // pixels / second - double angularVelocity; // degrees / second - Math::Vector2d acceleration; // pixels / second^2 - double angularAcceleration; // degrees / second^2 + Math::Vector2f velocity; // pixels / second + float angularVelocity; // degrees / second + Math::Vector2f acceleration; // pixels / second^2 + float angularAcceleration; // degrees / second^2 Movable() : velocity(0, 0), acceleration(0, 0) {}; - Movable(const Math::Vector2d &velocity, const Math::Vector2d &acceleration) : velocity(velocity), acceleration(acceleration) {}; + Movable(const Math::Vector2f &velocity, const Math::Vector2f &acceleration) : velocity(velocity), acceleration(acceleration) {}; Movable(const Movable &other) : velocity(other.velocity), acceleration(other.acceleration) {}; std::size_t size() const { diff --git a/Flakkari/Engine/EntityComponentSystem/Components/2D/Transform.hpp b/Flakkari/Engine/EntityComponentSystem/Components/2D/Transform.hpp index 58c604ac..b20458f8 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/2D/Transform.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/2D/Transform.hpp @@ -16,12 +16,12 @@ namespace Flakkari::Engine::ECS::Components::_2D { PACKED_START struct Transform { - Math::Vector2d position; - Math::Vector2d scale; - double rotation; + Math::Vector2f position; + Math::Vector2f scale; + float rotation; Transform() : position(0, 0), scale(1, 1), rotation(0) {}; - Transform(const Math::Vector2d &position, const Math::Vector2d &scale, double rotation) : position(position), scale(scale), rotation(rotation) {}; + Transform(const Math::Vector2f &position, const Math::Vector2f &scale, float rotation) : position(position), scale(scale), rotation(rotation) {}; Transform(const Transform &other) : position(other.position), scale(other.scale), rotation(other.rotation) {}; std::size_t size() const { diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index 15f6d3ca..aa09e82a 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -47,9 +47,9 @@ void Game::loadComponents(Engine::ECS::Registry ®istry, const nl_component &c if (componentName == "Transform") { registry.registerComponent(); Engine::ECS::Components::_2D::Transform transform; - transform.position = Engine::Math::Vector2d(componentContent["position"]["x"], componentContent["position"]["y"]); + transform.position = Engine::Math::Vector2f(componentContent["position"]["x"], componentContent["position"]["y"]); transform.rotation = componentContent["rotation"]; - transform.scale = Engine::Math::Vector2d(componentContent["scale"]["x"], componentContent["scale"]["y"]); + transform.scale = Engine::Math::Vector2f(componentContent["scale"]["x"], componentContent["scale"]["y"]); registry.add_component(newEntity, std::move(transform)); return; } @@ -57,8 +57,8 @@ void Game::loadComponents(Engine::ECS::Registry ®istry, const nl_component &c if (componentName == "Movable") { registry.registerComponent(); Engine::ECS::Components::_2D::Movable movable; - movable.velocity = Engine::Math::Vector2d(componentContent["velocity"]["x"], componentContent["velocity"]["y"]); - movable.acceleration = Engine::Math::Vector2d(componentContent["acceleration"]["x"], componentContent["acceleration"]["y"]); + movable.velocity = Engine::Math::Vector2f(componentContent["velocity"]["x"], componentContent["velocity"]["y"]); + movable.acceleration = Engine::Math::Vector2f(componentContent["acceleration"]["x"], componentContent["acceleration"]["y"]); registry.add_component(newEntity, std::move(movable)); return; } From c9bf9d426e6f0bc3c8fefcce2358030df4fbed9e Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Fri, 12 Jan 2024 14:45:55 +0100 Subject: [PATCH 08/48] feat(Network): Add getIp() method to Address class --- Flakkari/Network/Address.cpp | 14 +++++++++++++- Flakkari/Network/Address.hpp | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/Flakkari/Network/Address.cpp b/Flakkari/Network/Address.cpp index 4ef24c9f..26a06f87 100644 --- a/Flakkari/Network/Address.cpp +++ b/Flakkari/Network/Address.cpp @@ -116,7 +116,19 @@ std::optional Address::toString() const return {}; } return std::string(host) + ":" + std::string(service); -}; +} + +std::optional Address::getIp() const +{ + if (_addrInfo == nullptr) + return {}; + char host[NI_MAXHOST]; + if (getnameinfo(_addrInfo->ai_addr, _addrInfo->ai_addrlen, host, NI_MAXHOST, nullptr, 0, NI_NUMERICHOST) != 0) { + FLAKKARI_LOG_ERROR("getnameinfo() failed"); + return {}; + } + return std::string(host); +} constexpr const char *Address::ipTypeToString(IpType ip_type) { diff --git a/Flakkari/Network/Address.hpp b/Flakkari/Network/Address.hpp index 9f41b0ec..d8c08730 100644 --- a/Flakkari/Network/Address.hpp +++ b/Flakkari/Network/Address.hpp @@ -99,6 +99,23 @@ class Address { */ [[nodiscard]] sockaddr_in *getSockAddrIn() const { return (sockaddr_in *)_addrInfo->ai_addr; } + /** + * @brief Get the Ip object (std::string) + * + * @return std::optional Ip + * @example "Flakkari/Network/Address.cpp" + * @code + * #include "Address.hpp" + * + * Flakkari::Network::Address address("localhost", 8080, Flakkari::Network::Address::SocketType::TCP, Flakkari::Network::Address::IpType::IPv4); + * std::cout << "Ip: " << address.getIp().value_or("Unknown") << std::endl; + * @endcode + * output: + * @code + * Ip: localhost + */ + [[nodiscard]] std::optional getIp() const; + /** * @brief Get the Port object * From bab0ddbe774a5b4f79a0de904e55235fd070de35 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Fri, 12 Jan 2024 14:47:54 +0100 Subject: [PATCH 09/48] fix(Network): Fix out_of_range exception in Buffer::extractData() --- Flakkari/Network/Buffer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Flakkari/Network/Buffer.cpp b/Flakkari/Network/Buffer.cpp index c3178a34..b1581ce6 100644 --- a/Flakkari/Network/Buffer.cpp +++ b/Flakkari/Network/Buffer.cpp @@ -35,7 +35,10 @@ const byte *Buffer::getData() const { return data(); } -Buffer Buffer::extractData(std::size_t offset, std::size_t length) const { +Buffer Buffer::extractData(std::size_t offset, std::size_t length) const +{ + if (offset + length > size()) + throw std::out_of_range("Buffer::extractData: offset + length > size()"); return Buffer(begin() + offset, begin() + offset + length); } From 2d5f32d7cf56cd12582a5aae2324bfe00ad314c2 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Fri, 12 Jan 2024 14:53:20 +0100 Subject: [PATCH 10/48] fix(Network): Refactor IOMultiplexer classes --- Flakkari/Network/IOMultiplexer.cpp | 46 +++------------ Flakkari/Network/IOMultiplexer.hpp | 94 +++++++++++++----------------- 2 files changed, 49 insertions(+), 91 deletions(-) diff --git a/Flakkari/Network/IOMultiplexer.cpp b/Flakkari/Network/IOMultiplexer.cpp index 03e2caa9..3ec464f9 100644 --- a/Flakkari/Network/IOMultiplexer.cpp +++ b/Flakkari/Network/IOMultiplexer.cpp @@ -26,14 +26,6 @@ PSELECT::PSELECT(int fileDescriptor) _timeout.tv_sec = 1; _timeout.tv_nsec = 0; // 100ms - - // handle ctrl+c or break - sigemptyset(&_sigmask); - sigaddset(&_sigmask, SIGINT); - - struct sigaction sa; - sa.sa_handler = SIG_IGN; - sigaction(SIGINT, &sa, nullptr); } PSELECT::PSELECT() @@ -42,14 +34,6 @@ PSELECT::PSELECT() _timeout.tv_sec = 1; _timeout.tv_nsec = 0; // 100ms - - // handle ctrl+c or break - sigemptyset(&_sigmask); - sigaddset(&_sigmask, SIGINT); - - struct sigaction sa; - sa.sa_handler = SIG_IGN; - sigaction(SIGINT, &sa, nullptr); } void PSELECT::addSocket(FileDescriptor socket) @@ -80,7 +64,13 @@ int PSELECT::wait() FD_ZERO(&_fds); for (auto &fd : _sockets) FD_SET(fd, &_fds); - return ::pselect(_maxFd + 1, &_fds, nullptr, nullptr, &_timeout, &_sigmask); + #if defined(_WIN32) + return ::select(_maxFd + 1, &_fds, nullptr, nullptr, (const timeval *)&_timeout); + #elif defined(__APPLE__) + return ::select(_maxFd + 1, &_fds, nullptr, nullptr, &_timeout); + #else + return ::pselect(_maxFd + 1, &_fds, nullptr, nullptr, &_timeout, nullptr); + #endif } bool PSELECT::isReady(FileDescriptor socket) @@ -109,27 +99,11 @@ PPOLL::PPOLL(int fileDescriptor, event_t events) _timeout.tv_sec = 1; _timeout.tv_nsec = 0;// 100000000; // 100ms - - // handle ctrl+c or break - sigemptyset(&_sigmask); - sigaddset(&_sigmask, SIGINT); - - struct sigaction sa; - sa.sa_handler = SIG_IGN; - sigaction(SIGINT, &sa, nullptr); } PPOLL::PPOLL() { _timeout.tv_sec = 1; _timeout.tv_nsec = 0;// 100000000; // 100ms - - // handle ctrl+c or break - sigemptyset(&_sigmask); - sigaddset(&_sigmask, SIGINT); - - struct sigaction sa; - sa.sa_handler = SIG_IGN; - sigaction(SIGINT, &sa, nullptr); } void PPOLL::addSocket(FileDescriptor socket) @@ -165,7 +139,7 @@ void PPOLL::removeSocket(FileDescriptor socket) int PPOLL::wait() { #ifdef __linux__ - return ppoll(_pollfds.data(), _pollfds.size(), &_timeout, &_sigmask); + return ppoll(_pollfds.data(), _pollfds.size(), &_timeout, nullptr); #elif defined(__APPLE__) return poll(_pollfds.data(), _pollfds.size(), 100); #endif @@ -207,8 +181,4 @@ bool PPOLL::isReady(FileDescriptor socket) #endif -#if defined(_EPOLL_) - -#endif - } // namespace Flakkari::Network diff --git a/Flakkari/Network/IOMultiplexer.hpp b/Flakkari/Network/IOMultiplexer.hpp index fd046e13..e6e35196 100644 --- a/Flakkari/Network/IOMultiplexer.hpp +++ b/Flakkari/Network/IOMultiplexer.hpp @@ -19,7 +19,6 @@ // if im on windows, define all compatible IOMultiplexer #ifdef _WIN32 #define _PSELECT_ - #define _PPOLL_ #define _EPOLL_ #define _KQUEUE_ #define _IO_URING_ @@ -34,29 +33,23 @@ namespace Flakkari::Network { -/** - * @brief IOMultiplexer is an interface for the different I/O multiplexing - * @interface IOMultiplexer - */ -class IOMultiplexer { - public: - using FileDescriptor = int; - - public: - virtual ~IOMultiplexer() = default; - - virtual void addSocket(FileDescriptor socket) = 0; - virtual void removeSocket(FileDescriptor socket) = 0; - virtual int wait() = 0; - virtual bool isReady(FileDescriptor socket) = 0; - -}; - #if defined(_PSELECT_) -#include -#include -#include -#include +#if defined(_WIN32) + #include + #include + #include + #include + + #pragma comment(lib, "Ws2_32.lib") +#elif defined(__APPLE__) + #include + #include + #include +#else + #include + #include + #include +#endif /** * @brief PSELECT is a class that represents a PSELECT @@ -85,7 +78,10 @@ class IOMultiplexer { * } * @endcode */ -class PSELECT : public IOMultiplexer { +class PSELECT { + public: + using FileDescriptor = int; + public: PSELECT(int fileDescriptor); PSELECT(); @@ -96,14 +92,14 @@ class PSELECT : public IOMultiplexer { * * @param socket The socket to add to the list */ - void addSocket(FileDescriptor socket) override; + void addSocket(FileDescriptor socket); /** * @brief Remove a socket from the PSELECT list * * @param socket The socket to remove from the list */ - void removeSocket(FileDescriptor socket) override; + void removeSocket(FileDescriptor socket); /** * @brief Wait for an event to happen on a socket or timeout @@ -112,7 +108,7 @@ class PSELECT : public IOMultiplexer { * @see pselect * @see errno */ - int wait() override; + int wait(); std::vector::iterator begin() { return _sockets.begin(); } std::vector::iterator end() { return _sockets.end(); } @@ -124,7 +120,7 @@ class PSELECT : public IOMultiplexer { * @return true If the socket is ready * @return false If the socket is not ready */ - [[nodiscard]] bool isReady(FileDescriptor socket) override; + [[nodiscard]] bool isReady(FileDescriptor socket); protected: private: @@ -132,13 +128,21 @@ class PSELECT : public IOMultiplexer { std::vector _sockets; FileDescriptor _maxFd = 0; struct timespec _timeout = {0, 0}; - sigset_t _sigmask; }; #endif #if defined(_PPOLL_) -#include -#include +#if defined(_WIN32) + #include + #include + #include + #include + #pragma comment(lib, "Ws2_32.lib") +#elif defined(__APPLE__) + #include +#else + #include +#endif /** * @brief PPOLL is a class that represents a PPOLL @@ -167,8 +171,9 @@ class PSELECT : public IOMultiplexer { * } * @endcode */ -class PPOLL : public IOMultiplexer { +class PPOLL { public: + using FileDescriptor = int; using pollfd = struct pollfd; using event_t = short int; using revents_t = short int; @@ -184,7 +189,7 @@ class PPOLL : public IOMultiplexer { * * @param socket The socket to add to the list */ - void addSocket(FileDescriptor socket) override; + void addSocket(FileDescriptor socket); /** * @brief Add a socket to the PPOLL list with specific events @@ -199,7 +204,7 @@ class PPOLL : public IOMultiplexer { * * @param socket The socket to remove from the list */ - void removeSocket(FileDescriptor socket) override; + void removeSocket(FileDescriptor socket); /** * @brief Wait for an event to happen on a socket or timeout @@ -208,7 +213,7 @@ class PPOLL : public IOMultiplexer { * @see ppoll * @see errno */ - int wait() override; + int wait(); pollfd &operator[](std::size_t index); pollfd &operator[](FileDescriptor socket); @@ -232,32 +237,15 @@ class PPOLL : public IOMultiplexer { * @return true If the socket is ready * @return false If the socket is not ready */ - [[nodiscard]] bool isReady(FileDescriptor socket) override; + [[nodiscard]] bool isReady(FileDescriptor socket); protected: private: std::vector _pollfds; struct timespec _timeout = {0, 0}; - sigset_t _sigmask; }; #endif -#if defined(_EPOLL_) - #if __APPLE__ - #include - #else - #include - #endif -#endif - -#if defined(_KQUEUE_) -#include -#endif - -#if defined(_IO_URING_) -#include -#endif - } // namespace Flakkari::Network #endif /* !IOMULTIPLEXER_HPP_ */ From e55e4de8e188fc74b531bc0b5e3070236c61cd32 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Fri, 12 Jan 2024 14:55:54 +0100 Subject: [PATCH 11/48] fix(Network): Fix socket options for different platforms --- Flakkari/Network/Socket.cpp | 93 ++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 26 deletions(-) diff --git a/Flakkari/Network/Socket.cpp b/Flakkari/Network/Socket.cpp index 5dd4f174..4d511bc7 100644 --- a/Flakkari/Network/Socket.cpp +++ b/Flakkari/Network/Socket.cpp @@ -35,10 +35,15 @@ Socket::Socket(std::shared_ptr
address) return; } + #if __APPLE__ + int optval = 1; + ::setsockopt(_socket, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)); + #elif __linux__ if (::setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, "\001", 4)) { FLAKKARI_LOG_FATAL("Failed to set socket to reuse address and port, error: " + STD_ERROR); return; } + #endif } Socket::Socket(socket_t socket, std::shared_ptr
address) @@ -52,10 +57,18 @@ Socket::Socket(socket_t socket, std::shared_ptr
address) } #endif + #if _WIN32 + u_long mode = 1; + int result = ::ioctlsocket(_socket, FIONBIO, &mode); + #elif __APPLE__ + int optval = 1; + ::setsockopt(_socket, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)); + #elif __linux__ if (::setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, "\001", 4)) { FLAKKARI_LOG_FATAL("Failed to set socket to reuse address and port, error: " + STD_ERROR); return; } + #endif } Socket::Socket(Address address) @@ -82,10 +95,15 @@ Socket::Socket(Address address) return; } + #if __APPLE__ + int optval = 1; + ::setsockopt(_socket, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)); + #elif __linux__ if (::setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, "\001", 4)) { FLAKKARI_LOG_FATAL("Failed to set socket to reuse address and port, error: " + STD_ERROR); return; } + #endif } Socket::Socket(ip_t ip, port_t port, Address::IpType ip_type, Address::SocketType socket_type) @@ -186,18 +204,32 @@ std::shared_ptr Socket::accept() void Socket::send(const Buffer &data, int flags) { - if (::send(_socket, data.getData(), data.getSize(), flags) == SOCKET_ERROR) { - FLAKKARI_LOG_ERROR("Failed to send \"" + std::string(data.begin(), data.end()) + "\" to socket(" + std::to_string(_socket) + "), error: " + STD_ERROR); - return; - } + #ifdef _WIN32 + if (::send(_socket, (const char *)data.getData(), data.getSize(), flags) == SOCKET_ERROR) { + FLAKKARI_LOG_ERROR("Failed to send \"" + std::string(data.begin(), data.end()) + "\" to socket(" + std::to_string(_socket) + "), error: " + STD_ERROR); + return; + } + #else + if (::send(_socket, data.getData(), data.getSize(), flags) == SOCKET_ERROR) { + FLAKKARI_LOG_ERROR("Failed to send \"" + std::string(data.begin(), data.end()) + "\" to socket(" + std::to_string(_socket) + "), error: " + STD_ERROR); + return; + } + #endif } void Socket::send(const Buffer &data, size_t size, int flags) { - if (::send(_socket, data.getData(), size, flags) == SOCKET_ERROR) { - FLAKKARI_LOG_ERROR("Failed to send \"" + std::string(data.begin(), data.end()) + "\" to socket(" + std::to_string(_socket) + "), error: " + STD_ERROR); - return; - } + #ifdef _WIN32 + if (::send(_socket, (const char *)data.getData(), size, flags) == SOCKET_ERROR) { + FLAKKARI_LOG_ERROR("Failed to send \"" + std::string(data.begin(), data.end()) + "\" to socket(" + std::to_string(_socket) + "), error: " + STD_ERROR); + return; + } + #else + if (::send(_socket, data.getData(), size, flags) == SOCKET_ERROR) { + FLAKKARI_LOG_ERROR("Failed to send \"" + std::string(data.begin(), data.end()) + "\" to socket(" + std::to_string(_socket) + "), error: " + STD_ERROR); + return; + } + #endif } void Socket::sendTo(const std::shared_ptr
&address, const Buffer &data, int flags) @@ -207,10 +239,17 @@ void Socket::sendTo(const std::shared_ptr
&address, const Buffer &data, if (addr == nullptr) return FLAKKARI_LOG_ERROR("Address is nullptr"), void(); - if (::sendto(_socket, data.getData(), data.getSize(), flags, addr->ai_addr, addr->ai_addrlen) == SOCKET_ERROR) { - FLAKKARI_LOG_ERROR("Failed to send \"" + std::string(data) + "\" to \"" + address->toString().value_or("No address") + "\", error: " + STD_ERROR); - return; - } + #ifdef _WIN32 + if (::sendto(_socket, (const char *)data.getData(), data.getSize(), flags, addr->ai_addr, addr->ai_addrlen) == SOCKET_ERROR) { + FLAKKARI_LOG_ERROR("Failed to send \"" + std::string(data.begin(), data.end()) + "\" to \"" + address->toString().value_or("No address") + "\", error: " + STD_ERROR); + return; + } + #else + if (::sendto(_socket, data.getData(), data.getSize(), flags, addr->ai_addr, addr->ai_addrlen) == SOCKET_ERROR) { + FLAKKARI_LOG_ERROR("Failed to send \"" + std::string(data) + "\" to \"" + address->toString().value_or("No address") + "\", error: " + STD_ERROR); + return; + } + #endif } void Socket::sendTo(const std::shared_ptr
&address, const byte *data, const size_t &size, int flags) @@ -220,23 +259,25 @@ void Socket::sendTo(const std::shared_ptr
&address, const byte *data, c if (addr == nullptr) return FLAKKARI_LOG_ERROR("Address is nullptr"), void(); - if (::sendto(_socket, data, size, flags, addr->ai_addr, addr->ai_addrlen) == SOCKET_ERROR) { - FLAKKARI_LOG_ERROR( - "Failed to send \"" - + std::string(data, data + size) - + "\" to \"" - + address->toString().value_or("No address") - + "\", error: " + STD_ERROR - ); - return; - } + #if _WIN32 + if (::sendto(_socket, (const char *)data, size, flags, addr->ai_addr, addr->ai_addrlen) == SOCKET_ERROR) { + FLAKKARI_LOG_ERROR("Failed to send \""+ std::string(data, data + size) +"\" to \""+ address->toString().value_or("No address") +"\", error: "+ STD_ERROR); + return; + } + #else + if (::sendto(_socket, data, size, flags, addr->ai_addr, addr->ai_addrlen) == SOCKET_ERROR) { + FLAKKARI_LOG_ERROR("Failed to send \""+ std::string(data, data + size) +"\" to \""+ address->toString().value_or("No address") +"\", error: "+ STD_ERROR + ); + return; + } + #endif } std::optional Socket::receive(size_t size, int flags) { Buffer data(size, 0); - if (::recv(_socket, &data[0], size, flags) == SOCKET_ERROR) { + if (::recv(_socket, (char*)&data[0], size, flags) == SOCKET_ERROR) { FLAKKARI_LOG_ERROR("Failed to receive data from socket(" + std::to_string(_socket) + "), error: " + STD_ERROR); return {}; } @@ -247,7 +288,7 @@ std::optional Socket::receive(int flags) { Buffer data(4096, 0); - if (::recv(_socket, &data[0], 4096, flags) == SOCKET_ERROR) { + if (::recv(_socket, (char*)&data[0], 4096, flags) == SOCKET_ERROR) { FLAKKARI_LOG_ERROR("Failed to receive data from socket(" + std::to_string(_socket) + "), error: " + STD_ERROR); return {}; } @@ -260,7 +301,7 @@ std::optional, Buffer>> Socket::receiveFrom(s sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - if (::recvfrom(_socket, data.data(), size, flags, (sockaddr*)&addr, &addrlen) == SOCKET_ERROR) { + if (::recvfrom(_socket, (char*)data.data(), size, flags, (sockaddr*)&addr, &addrlen) == SOCKET_ERROR) { if (errno == EAGAIN || errno == EWOULDBLOCK) return {}; FLAKKARI_LOG_ERROR("Failed to receive data from \"" + _address->toString().value_or("No address") + "\", error: " + STD_ERROR); @@ -280,7 +321,7 @@ std::optional, Buffer>> Socket::receiveFrom(i sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - if (::recvfrom(_socket, &data[0], 4096, flags, (sockaddr*)&addr, &addrlen) == SOCKET_ERROR) { + if (::recvfrom(_socket, (char*)&data[0], 4096, flags, (sockaddr*)&addr, &addrlen) == SOCKET_ERROR) { if (errno == EAGAIN || errno == EWOULDBLOCK) return {}; FLAKKARI_LOG_ERROR("Failed to receive data from \"" + _address->toString().value_or("No address") + "\", error: " + STD_ERROR); From 3a078e2f4bb0014bfe06a0cacfb11ba407d9b89d Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Fri, 12 Jan 2024 16:19:51 +0100 Subject: [PATCH 12/48] feat(Game): Add ResourceManager class for loading and storing resources --- Flakkari/Server/Game/ResourceManager.cpp | 73 +++++++++++++++ Flakkari/Server/Game/ResourceManager.hpp | 111 +++++++++++++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 Flakkari/Server/Game/ResourceManager.cpp create mode 100644 Flakkari/Server/Game/ResourceManager.hpp diff --git a/Flakkari/Server/Game/ResourceManager.cpp b/Flakkari/Server/Game/ResourceManager.cpp new file mode 100644 index 00000000..afe4aba7 --- /dev/null +++ b/Flakkari/Server/Game/ResourceManager.cpp @@ -0,0 +1,73 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2023-01-12 +** File description: +** ResourceManager +*/ + +#include "ResourceManager.hpp" + +namespace Flakkari { + +std::shared_ptr ResourceManager::_instance = nullptr; +std::mutex ResourceManager::_mutex; + +std::shared_ptr ResourceManager::getInstance() +{ + std::lock_guard lock(_mutex); + if (_instance == nullptr) + _instance = std::make_shared(); + return _instance; +} + +void ResourceManager::addScene(const std::string &configPath, const std::string &scene) +{ + std::lock_guard lock(_mutex); + if (_instance == nullptr) + _instance = std::make_shared(); + _instance->loadConfig(configPath, scene); +} + +void ResourceManager::deleteScene(const std::string &game, const std::string &scene) +{ + std::lock_guard lock(_mutex); + if (_instance == nullptr) + return; + _instance->_templates[game].erase(scene); +} + +std::optional ResourceManager::getTemplateById ( + const std::string &game, const std::string &scene, const std::string &templateId +) { + std::lock_guard lock(_mutex); + if (_instance == nullptr) + return std::nullopt; + return _instance->_templates[game][scene][templateId]; +} + +void ResourceManager::loadConfig(const std::string &configPath, const std::string &scene) +{ + std::ifstream configFile(configPath); + nlohmann::json config; + + if (!configFile.is_open()) + return FLAKKARI_LOG_ERROR("could not open config file \"" + configPath + "\""), void(); + configFile >> config; + + for (auto &_scene : config["scenes"].items()) { + for (auto sceneInfo : _scene.value().items()) { + if (sceneInfo.key() != scene) + continue; + + for (auto &template_ : sceneInfo.value()["templates"].items()) { + for (auto &templateInfo : template_.value().items()) { + _templates[config["title"]][sceneInfo.key()][templateInfo.key()] = templateInfo.value(); + } + } + } + } +} + +} // namespace Engine::Resource diff --git a/Flakkari/Server/Game/ResourceManager.hpp b/Flakkari/Server/Game/ResourceManager.hpp new file mode 100644 index 00000000..9dd18c42 --- /dev/null +++ b/Flakkari/Server/Game/ResourceManager.hpp @@ -0,0 +1,111 @@ +/************************************************************************** + * Flakkari Library v0.2.0 + * + * Flakkari Library is a C++ Library for Network. + * @file ResourceManager.hpp + * @brief This file contains the ResourceManager class. It is used to load + * and store resources (templates). + * + * Flakkari Library is under MIT License. + * https://opensource.org/licenses/MIT + * © 2023 @MasterLaplace + * @version 0.2.0 + * @date 2024-01-12 + **************************************************************************/ + +#ifndef RESOURCEMANAGER_HPP_ +#define RESOURCEMANAGER_HPP_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Logger/Logger.hpp" + +namespace Flakkari { + +/** + * @brief ResourceManager class + * + * This class is used to load and store resources (teemplates) + * It is a singleton, so it can be accessed from anywhere in the code + * It is initialized with a config file path, which contains the paths to the resources + * The config file must be a JSON file, with the following structure: + * + * @example "Games//config.json" + * @code + * ResourceManager::adddScene("Games//config.json", ""); + * auto template = ResourceManager::getTemplateById("", "", ""); + * @endcode + * + * TODO: add a way to unload resources + * TODO: add a way to load multiple config files cause multiple scenes could be used for multiple windows + */ +class ResourceManager { + private: + static std::shared_ptr _instance; + static std::mutex _mutex; + + using nl_template = nlohmann::json_abi_v3_11_3::json; + + public: + std::map>> _templates; + + ResourceManager() = default; + ~ResourceManager() = default; + + public: + ResourceManager(const ResourceManager &) = delete; + ResourceManager(const std::shared_ptr &) = delete; + void operator=(const ResourceManager &) = delete; + void operator=(const std::shared_ptr &) = delete; + + /** + * @brief Get the ResourceManager instance + * + * @param configPath The path to the config file + * @return ResourceManager & The ResourceManager instance + */ + static std::shared_ptr getInstance(); + + /** + * @brief Add a scene to the ResourceManager instance + * + * @param configPath The path to the config file of the game to add + * @param scene The scene to add to the ResourceManager instance + */ + static void addScene(const std::string &configPath, const std::string &scene); + + /** + * @brief Delete a scene from the ResourceManager instance + * + * @param configPath The path to the config file of the game to delete + * @param scene The scene to delete from the ResourceManager instance + */ + static void deleteScene(const std::string &game, const std::string &scene); + + /** + * @brief Get the Template By Id object from the config file of the game + * + * @param game The game to get the template from (name of the file in Games/ folder) + * @param scene The scene to get the template from (name of the file in Games//Scenes/ folder) + * @param templateId The id of the template to get (name of the template in the config file) + * @return std::optional The template if found, std::nullopt otherwise + */ + [[nodiscard]] static std::optional getTemplateById ( + const std::string &game, const std::string &scene, const std::string &templateId + ); + + private: + void loadConfig(const std::string &configPath, const std::string &scene); +}; + +} /* namespace Flakkari */ + +#endif /* !RESOURCEMANAGER_HPP_ */ From 1fc84c9192cbfa8a1fd4f82ecf65ddcb4d589ecc Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Fri, 12 Jan 2024 16:46:19 +0100 Subject: [PATCH 13/48] feat(Network): Add PacketQueue class for storing incoming packets --- CMakeLists.txt | 18 +++++++ Flakkari/Network/PacketQueue.hpp | 92 ++++++++++++++++++++++++++++++++ Flakkari/Server/Game/Game.cpp | 2 +- 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 Flakkari/Network/PacketQueue.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1333798f..dbcf8312 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,46 +6,63 @@ project(R-Type_Server) # Add all your source and headers files: set(SOURCES Flakkari/core.cpp + Flakkari/Logger/Logger.cpp Flakkari/Network/Address.cpp Flakkari/Network/Buffer.cpp Flakkari/Network/Socket.cpp Flakkari/Network/IOMultiplexer.cpp + Flakkari/Protocol/Header.cpp Flakkari/Protocol/Packet.cpp + Flakkari/Engine/Math/Vector.cpp + Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp Flakkari/Engine/EntityComponentSystem/Registry.cpp + Flakkari/Server/UDPServer.cpp Flakkari/Server/Client/Client.cpp Flakkari/Server/Client/ClientManager.cpp + Flakkari/Server/Game/Game.cpp Flakkari/Server/Game/GameManager.cpp + Flakkari/Server/Game/ResourceManager.cpp + Flakkari/Server/Internals/CommandManager.cpp ) set(HEADERS Flakkari/Logger/Logger.hpp + Flakkari/Network/Packed.hpp Flakkari/Network/Address.hpp Flakkari/Network/Buffer.hpp Flakkari/Network/Socket.hpp Flakkari/Network/Serializer.hpp + Flakkari/Network/PacketQueue.hpp Flakkari/Network/IOMultiplexer.hpp + Flakkari/Protocol/Header.hpp Flakkari/Protocol/Packet.hpp + Flakkari/Engine/Math/Vector.hpp + Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp Flakkari/Engine/EntityComponentSystem/Systems/Systems.hpp Flakkari/Engine/EntityComponentSystem/Entity.hpp Flakkari/Engine/EntityComponentSystem/SparseArrays.hpp Flakkari/Engine/EntityComponentSystem/Registry.hpp + Flakkari/Server/UDPServer.hpp Flakkari/Server/Client/Client.hpp Flakkari/Server/Client/ClientManager.hpp + Flakkari/Server/Game/Game.hpp Flakkari/Server/Game/GameManager.hpp + Flakkari/Server/Game/ResourceManager.cpp + Flakkari/Server/Internals/CommandManager.hpp ) @@ -59,6 +76,7 @@ set(HEADER_LIB_NETWORK Flakkari/Network/Buffer.hpp Flakkari/Network/Socket.hpp Flakkari/Network/Serializer.hpp + Flakkari/Network/PacketQueue.hpp Flakkari/Network/IOMultiplexer.hpp ) diff --git a/Flakkari/Network/PacketQueue.hpp b/Flakkari/Network/PacketQueue.hpp new file mode 100644 index 00000000..4aac8e6a --- /dev/null +++ b/Flakkari/Network/PacketQueue.hpp @@ -0,0 +1,92 @@ +/* +/************************************************************************** + * Flakkari Library v0.2.0 + * + * Flakkari Library is a C++ Library for Network. + * @file PacketQueue.hpp + * @brief This file contains the PacketQueue class. It is used to store + * packets in a queue. It is thread safe. It is used by the client + * and the server to store incoming packets. + * + * Flakkari Library is under MIT License. + * https://opensource.org/licenses/MIT + * © 2023 @MasterLaplace + * @version 0.2.0 + * @date 2024-01-12 + **************************************************************************/ + + +#ifndef PACKETQUEUE_HPP_ + #define PACKETQUEUE_HPP_ + +#include +#include + +namespace Flakkari::Network { + +template +class PacketQueue { + public: + PacketQueue() = default; + PacketQueue(const PacketQueue &) = delete; + virtual ~PacketQueue() { clear(); } + + public: + const T &front() { + std::scoped_lock lock(_mutex); + return _queue.front(); + } + + const T &back() { + std::scoped_lock lock(_mutex); + return _queue.back(); + } + + void push_back(const T &value) { + std::scoped_lock lock(_mutex); + _queue.push_back(value); + } + + void push_front(const T &value) { + std::scoped_lock lock(_mutex); + _queue.push_front(value); + } + + T pop_front() { + std::scoped_lock lock(_mutex); + auto value = std::move(_queue.front()); + _queue.pop_front(); + return value; + } + + T pop_back() { + std::scoped_lock lock(_mutex); + auto value = std::move(_queue.back()); + _queue.pop_back(); + return value; + } + + bool empty() { + std::scoped_lock lock(_mutex); + return _queue.empty(); + } + + size_t size() { + std::scoped_lock lock(_mutex); + return _queue.size(); + } + + void clear() { + std::scoped_lock lock(_mutex); + _queue.clear(); + } + + protected: + private: + std::mutex _mutex; + std::deque _queue; +}; + +} // namespace Flakkari::Network + +#endif /* !PACKETQUEUE_HPP_ */ diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index aa09e82a..7b707598 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -8,7 +8,7 @@ */ #include "Game.hpp" -#include "../Client/Client.hpp" +#include "../Client/ClientManager.hpp" namespace Flakkari { From 7e571c3ec3e5fd377a6062e412435dfa8ec43701 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 01:06:35 +0100 Subject: [PATCH 14/48] feat(Network): Add getId() method to Address class and use it in Client class --- Flakkari/Network/Address.cpp | 4 ++++ Flakkari/Network/Address.hpp | 16 ++++++++++++++++ Flakkari/Server/Client/Client.hpp | 2 ++ Flakkari/Server/UDPServer.cpp | 16 ++++++++++------ Flakkari/Server/UDPServer.hpp | 4 ++-- 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Flakkari/Network/Address.cpp b/Flakkari/Network/Address.cpp index 26a06f87..1358a91f 100644 --- a/Flakkari/Network/Address.cpp +++ b/Flakkari/Network/Address.cpp @@ -166,6 +166,8 @@ Address::operator std::string() const + socketTypeToString(_socket_type) + ", " + ipTypeToString(_ip_type) + + ", " + + std::to_string(getId()) + ")" ); } @@ -177,6 +179,8 @@ std::ostream &operator<<(std::ostream &os, const Address &addr) os << Address::socketTypeToString(addr.getSocketType()); os << ", "; os << Address::ipTypeToString(addr.getIpType()); + os << ", "; + os << addr.getId(); os << ")"; return os; } diff --git a/Flakkari/Network/Address.hpp b/Flakkari/Network/Address.hpp index d8c08730..089440f4 100644 --- a/Flakkari/Network/Address.hpp +++ b/Flakkari/Network/Address.hpp @@ -60,6 +60,7 @@ class Address { public: using address_t = const std::string; using port_t = unsigned short; + using id_t = short; public: Address(address_t &address, port_t port, SocketType socket_type, IpType ip_type); @@ -137,6 +138,20 @@ class Address { */ [[nodiscard]] IpType getIpType() const { return _ip_type; } + /** + * @brief Get the Id object + * + * @return id_t Id + */ + [[nodiscard]] id_t getId() const { return _id; } + + /** + * @brief Set the Id object + * + * @param id Id + */ + void setId(id_t id) { _id = id; } + /** * @brief Convert Address to string (std::string) * @@ -149,6 +164,7 @@ class Address { std::shared_ptr _addrInfo = nullptr; SocketType _socket_type = SocketType::None; IpType _ip_type = IpType::None; + id_t _id = -1; }; /** diff --git a/Flakkari/Server/Client/Client.hpp b/Flakkari/Server/Client/Client.hpp index 63c91127..79a3321f 100644 --- a/Flakkari/Server/Client/Client.hpp +++ b/Flakkari/Server/Client/Client.hpp @@ -68,6 +68,8 @@ class Client { */ [[nodiscard]] std::shared_ptr getAddress() const { return _address; } + [[nodiscard]] unsigned int getId() const { return _address->getId(); } + protected: private: std::chrono::steady_clock::time_point _lastActivity; diff --git a/Flakkari/Server/UDPServer.cpp b/Flakkari/Server/UDPServer.cpp index ca7218ce..9d932cd6 100644 --- a/Flakkari/Server/UDPServer.cpp +++ b/Flakkari/Server/UDPServer.cpp @@ -13,22 +13,26 @@ using namespace Flakkari; UDPServer::UDPServer(std::string ip, std::size_t port) : - _socket(Network::Socket( + _socket(std::make_shared( ip, port, Network::Address::IpType::IPv4, Network::Address::SocketType::UDP )) { - FLAKKARI_LOG_INFO(std::string(_socket)); - _socket.bind(); + FLAKKARI_LOG_INFO(std::string(*_socket)); + _socket->bind(); _io = std::make_unique(); - _io->addSocket(_socket.getSocket()); + _io->addSocket(_socket->getSocket()); _io->addSocket(STDIN_FILENO); GameManager::getInstance(); } +UDPServer::~UDPServer() { + FLAKKARI_LOG_INFO("UDPServer is now stopped"); +} + bool UDPServer::handleTimeout(int event) { if (event != 0) @@ -50,7 +54,7 @@ bool UDPServer::handleInput(int fd) void UDPServer::handlePacket() { - auto packet = _socket.receiveFrom(); + auto packet = _socket->receiveFrom(); ClientManager::addClient(packet->first); ClientManager::checkInactiveClients(); @@ -89,7 +93,7 @@ void UDPServer::handlePacket() std::cout << " CommandId: " << (int)sendHeader._commandId << std::endl; std::cout << " ContentLength: " << (int)sendHeader._contentLength << std::endl; - _socket.sendTo(packet->first, buffer); + _socket->sendTo(packet->first, buffer); } void UDPServer::run() diff --git a/Flakkari/Server/UDPServer.hpp b/Flakkari/Server/UDPServer.hpp index fd3fcb7b..65a978cf 100644 --- a/Flakkari/Server/UDPServer.hpp +++ b/Flakkari/Server/UDPServer.hpp @@ -54,7 +54,7 @@ class UDPServer { * @param port The port to bind the server to (default: 8080) */ UDPServer(std::string ip = "localhost", std::size_t port = 8080); - ~UDPServer() = default; + ~UDPServer(); /** * @brief Run the server and wait for incoming packets and clients @@ -90,7 +90,7 @@ class UDPServer { void handlePacket(); private: - Network::Socket _socket; + std::shared_ptr _socket; std::unique_ptr _io; }; From ccf73cfb6f74986a6391286d238fabda43359411 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 01:19:20 +0100 Subject: [PATCH 15/48] feat(Protocol): Add Commands enum class for Flakkari Protocol --- Flakkari/Protocol/Commands.hpp | 118 +++++++++++++++++++++++ Flakkari/Server/Client/ClientManager.hpp | 4 +- 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 Flakkari/Protocol/Commands.hpp diff --git a/Flakkari/Protocol/Commands.hpp b/Flakkari/Protocol/Commands.hpp new file mode 100644 index 00000000..9037db5e --- /dev/null +++ b/Flakkari/Protocol/Commands.hpp @@ -0,0 +1,118 @@ +/************************************************************************** + * Flakkari Library v0.2.0 + * + * Flakkari Library is a C++ Library for Network. + * @file Commands.hpp + * @brief This file contains the Commands enum class. It is used to identify + * the command in the Flakkari Protocol. + * + * @see inspired by the https://en.wikipedia.org/wiki/IPv4 header + * + * Flakkari Library is under MIT License. + * https://opensource.org/licenses/MIT + * © 2023 @MasterLaplace + * @version 0.2.0 + * @date 2024-01-12 + **************************************************************************/ + + +#ifndef COMMANDS_HPP_ + #define COMMANDS_HPP_ + +#include + +namespace Flakkari::Protocol::API { + +inline namespace V_0 { + + enum class CommandId : uint8_t { + // 0 - 9: System + REQ_CONNECT = 0, // Client -> Server [Connect to server]: (username, password game) + REP_CONNECT = 1, // Server -> Client [Connection accepted]: (user_id) + REQ_DISCONNECT = 2, // Client -> Server [Disconnect from server]: (user_id) + REP_DISCONNECT = 3, // Server -> Client [Disconnect accepted]: () + REQ_PING = 4, // Client -> Server [Ping server]: (user_id) + REP_PING = 5, // Server -> Client [Ping accepted]: () + REQ_PONG = 6, // Client -> Server [Pong server]: (user_id) + REP_PONG = 7, // Server -> Client [Pong accepted]: () + REQ_HEARTBEAT = 8, // Client -> Server [Heartbeat server) (Keep alive)]: (user_id) + REP_HEARTBEAT = 9, // Server -> Client [Heartbeat accepted) (Keep alive)]: () + // 10 - 19: Network + REQ_LOGIN = 10, // Client -> Server [Login]: (username, password game) + REP_LOGIN = 11, // Server -> Client [Login accepted]: () + REQ_LOGOUT = 12, // Client -> Server [Logout]: (user_id) + REP_LOGOUT = 13, // Server -> Client [Logout accepted]: () + REQ_REGISTER = 14, // Client -> Server [Register]: (user_id, username, password) + REP_REGISTER = 15, // Server -> Client [Register accepted]: () + // 20 - 29: Game + REQ_ENTITY_SPAWN = 20, // Server -> Client [Spawn entity]: (id)(component (position, rotation, velocity, etc)) + REP_ENTITY_SPAWN = 21, // Client -> Server [Entity spawned]: () + REQ_ENTITY_UPDATE = 22, // Server -> Client [Update entity]: (id)(component (position, rotation, velocity, etc)) + REP_ENTITY_UPDATE = 23, // Client -> Server [Entity updated]: () + REQ_ENTITY_DESTROY = 24, // Server -> Client [Destroy entity]: (id) + REP_ENTITY_DESTROY = 25, // Client -> Server [Entity destroyed]: () + REQ_ENTITY_MOVED = 26, // Server -> Client [Move entity]: (id)(component (position, rotation, velocity, etc)) + REP_ENTITY_MOVED = 27, // Client -> Server [Entity moved]: () + REQ_ENTITY_SHOOT = 28, // Server -> Client [Shoot entity]: (id)(component (position, rotation, velocity, etc)) + REP_ENTITY_SHOOT = 29, // Client -> Server [Entity shot]: () + // 30 - 39: User + // 40 - 49: Chat + // 50 - 59: Matchmaking + REQ_CREATE_ROOM = 50, // Client -> Server [Create room]: (user_id) + REP_CREATE_ROOM = 51, // Server -> Client [Room created]: (room_id) + REQ_JOIN_ROOM = 52, // Client -> Server [Join room]: (user_id, room_id) + REP_JOIN_ROOM = 53, // Server -> Client [Room joined]: () + REQ_LEAVE_ROOM = 54, // Client -> Server [Leave room]: (user_id) + REP_LEAVE_ROOM = 55, // Server -> Client [Room left]: () + REQ_START_GAME = 56, // Client -> Server [Start game]: (user_id) + REP_START_GAME = 57, // Server -> Client [Game started]: () + REQ_END_GAME = 58, // Client -> Server [End game]: (user_id) + REP_END_GAME = 59, // Server -> Client [Game ended]: () + // 60 - 69: Leaderboard + // 70 - 79: Achievement + // 80 - 89: Inventory + // 90 - 99: Store + // 100 - 109: Party + // 110 - 119: Tournament + // 120 - 129: Telemetry + // 130 - 139: Commerce + // 140 - 149: Season + // 150 - 159: PlayerData + // 160 - 169: TitleData + // 170 - 179: Snapshots + // 180 - 189: CloudScript + // 190 - 199: Server-Side CloudScript + // 200 - 209: Shared Group Data + // 210 - 219: Files + // 220 - 229: Party + // 230 - 239: Insights + // 240 - 249: Messaging + // 250 - 259: Multiplayer + // 260 - 269: Server-Side CloudScript + // 270 - 279: PlayStream + // 280 - 289: Advertising + // 290 - 299: Analytics + // 300 - 309: Authentication + // 310 - 319: Profiles + // 320 - 329: Push Notifications + // 330 - 339: Shared Group Data + // 340 - 349: Title-Wide Data Management + // 350 - 359: Characters + // 360 - 369: Friend List + // 370 - 379: Matchmaking + // 380 - 389: Platform Specific + // 390 - 399: Player Data Management + // 400 - 409: Player Item Management + // 410 - 419: Player Profile + // 420 - 429: Title Data Management + // 430 - 439: Title Internal + // 440 - 449: Virtual Currency + // 450 - 459: Player Data Management + // 460 - 469: Player Item Management + }; + +} /* namespace V_0 */ + +} // namespace Flakkari::Protocol::API + +#endif /* !COMMANDS_HPP_ */ diff --git a/Flakkari/Server/Client/ClientManager.hpp b/Flakkari/Server/Client/ClientManager.hpp index d9864058..ac51896a 100644 --- a/Flakkari/Server/Client/ClientManager.hpp +++ b/Flakkari/Server/Client/ClientManager.hpp @@ -48,8 +48,10 @@ class ClientManager { private: static std::shared_ptr _instance; + using id_t = short; + public: - std::unordered_map> _clients; + std::vector _bannedClients; public: ClientManager(const ClientManager &) = delete; From b1e037345c31f08c62061e0519839773bd8ae506 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 01:19:45 +0100 Subject: [PATCH 16/48] feat(Protocol): Add Components enum class for Flakkari Protocol --- Flakkari/Protocol/Components.hpp | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Flakkari/Protocol/Components.hpp diff --git a/Flakkari/Protocol/Components.hpp b/Flakkari/Protocol/Components.hpp new file mode 100644 index 00000000..ce9eab8d --- /dev/null +++ b/Flakkari/Protocol/Components.hpp @@ -0,0 +1,45 @@ +/************************************************************************** + * Flakkari Library v0.2.0 + * + * Flakkari Library is a C++ Library for Network. + * @file Components.hpp + * @brief This file contains the Components enum class. + * It is used to identify the components in the Flakkari Protocol. + * + * @see inspired by the https://en.wikipedia.org/wiki/IPv4 header + * + * Flakkari Library is under MIT License. + * https://opensource.org/licenses/MIT + * © 2023 @MasterLaplace + * @version 0.2.0 + * @date 2024-01-12 + **************************************************************************/ + + +#ifndef COMPONENTS_HPP_ + #define COMPONENTS_HPP_ + +#include + +namespace Flakkari::Protocol::API { + +inline namespace V_0 { + + enum class ComponentId : uint8_t { + // 0 - 9: 2D components + CONTOL = 0, + MOVABLE = 1, + TRANSFORM = 2, + // 10 - 19: Common components + CHILD = 10, + PARENT = 11, + TAG = 12, + ID = 13, + TEMPLATE = 14 + }; + +} /* namespace V_0 */ + +} // namespace Flakkari::Protocol::API + +#endif /* !COMPONENTS_HPP_ */ From fbd12c15c42b948eaef3096f3cd0dd5e4f48deb5 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 01:28:37 +0100 Subject: [PATCH 17/48] refactor(Protocol): Remove unused protocol files --- CMakeLists.txt | 7 +- Flakkari/Protocol/Event.hpp | 85 --------------- Flakkari/Protocol/Header.cpp | 70 ------------ Flakkari/Protocol/Header.hpp | 203 ++++++++--------------------------- Flakkari/Protocol/Packet.cpp | 76 ------------- Flakkari/Protocol/Packet.hpp | 124 ++++++++++++--------- 6 files changed, 124 insertions(+), 441 deletions(-) delete mode 100644 Flakkari/Protocol/Event.hpp delete mode 100644 Flakkari/Protocol/Header.cpp delete mode 100644 Flakkari/Protocol/Packet.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index dbcf8312..85fcbffa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,9 +13,6 @@ set(SOURCES Flakkari/Network/Socket.cpp Flakkari/Network/IOMultiplexer.cpp - Flakkari/Protocol/Header.cpp - Flakkari/Protocol/Packet.cpp - Flakkari/Engine/Math/Vector.cpp Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp @@ -43,6 +40,8 @@ set(HEADERS Flakkari/Network/PacketQueue.hpp Flakkari/Network/IOMultiplexer.hpp + Flakkari/Protocol/Commands.hpp + Flakkari/Protocol/Components.hpp Flakkari/Protocol/Header.hpp Flakkari/Protocol/Packet.hpp @@ -81,6 +80,8 @@ set(HEADER_LIB_NETWORK ) set(HEADER_LIB_PROTOCOL + Flakkari/Protocol/Commands.hpp + Flakkari/Protocol/Components.hpp Flakkari/Protocol/Header.hpp Flakkari/Protocol/Packet.hpp ) diff --git a/Flakkari/Protocol/Event.hpp b/Flakkari/Protocol/Event.hpp deleted file mode 100644 index 092dd96b..00000000 --- a/Flakkari/Protocol/Event.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* -** EPITECH PROJECT, 2023 -** Flakkari -** File description: -** Event -*/ - -#ifndef EVENT_HPP_ -#define EVENT_HPP_ - -namespace Flakkari::Protocol::API { - - inline namespace V_1 { - - enum class FlakkariEventId : uint8_t { - // 0 - 99: System - REQ_CONNECT = 0, // Client -> Server (Connect to server) - REP_CONNECT = 1, // Server -> Client (Connection accepted) - REQ_DISCONNECT = 2, // Client -> Server (Disconnect from server) - REP_DISCONNECT = 3, // Server -> Client (Disconnect accepted) - REQ_HEARTBEAT = 8, // Client -> Server (Heartbeat server) (Keep alive) - REP_HEARTBEAT = 9, // Server -> Client (Heartbeat accepted) (Keep alive) - // 100 - 199: Network - // 200 - 299: Game - REQ_ENTITY_SPAWN = 200, // Client -> Server (Spawn entity) - REP_ENTITY_SPAWN = 201, // Server -> Client (Entity spawned) - REQ_SOUND_PLAY = 202, // Client -> Server (Play sound) - REP_SOUND_PLAY = 203, // Server -> Client (Sound played) - REQ_ENTITY_DESTROY = 204, // Client -> Server (Destroy entity) - REP_ENTITY_DESTROY = 205, // Server -> Client (Entity destroyed) - REQ_ENTITY_MOVED = 206, // Client -> Server (Move entity) - REP_ENTITY_MOVED = 207, // Server -> Client (Entity moved) - REQ_ENTITY_SHOOT = 208, // Client -> Server (Shoot entity) - REP_ENTITY_SHOOT = 209, // Server -> Client (Entity shot) - // 300 - 399: User - // 400 - 499: Chat - // 500 - 599: Matchmaking - // 600 - 699: Leaderboard - // 700 - 799: Achievement - // 800 - 899: Inventory - // 900 - 999: Store - // 1000 - 1099: Party - // 1100 - 1199: Tournament - // 1200 - 1299: Telemetry - // 1300 - 1399: Commerce - // 1400 - 1499: Season - // 1500 - 1599: PlayerData - // 1600 - 1699: TitleData - // 1700 - 1799: Snapshots - // 1800 - 1899: CloudScript - // 1900 - 1999: Server-Side CloudScript - // 2000 - 2099: Shared Group Data - // 2100 - 2199: Files - // 2200 - 2299: Party - // 2300 - 2399: Insights - // 2400 - 2499: Messaging - // 2500 - 2599: Multiplayer - // 2600 - 2699: Server-Side CloudScript - // 2700 - 2799: PlayStream - // 2800 - 2899: Advertising - // 2900 - 2999: Analytics - // 3000 - 3099: Authentication - // 3100 - 3199: Profiles - // 3200 - 3299: Push Notifications - // 3300 - 3399: Shared Group Data - // 3400 - 3499: Title-Wide Data Management - // 3500 - 3599: Characters - // 3600 - 3699: Friend List - // 3700 - 3799: Matchmaking - // 3800 - 3899: Platform Specific - // 3900 - 3999: Player Data Management - // 4000 - 4099: Player Item Management - // 4100 - 4199: Player Profile - // 4200 - 4299: Title Data Management - // 4300 - 4399: Title Internal - // 4400 - 4499: Virtual Currency - // 4500 - 4599: Player Data Management - // 4600 - 4699: Player Item Management - }; - - } /* namespace V_1 */ - -} // namespace Flakkari::Protocol::API - -#endif /* !EVENT_HPP_ */ diff --git a/Flakkari/Protocol/Header.cpp b/Flakkari/Protocol/Header.cpp deleted file mode 100644 index 25eeb51f..00000000 --- a/Flakkari/Protocol/Header.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* -** EPITECH PROJECT, 2023 -** Title: Flakkari -** Author: MasterLaplace -** Created: 2023-12-24 -** File description: -** Header -*/ - -#include "Header.hpp" - -namespace Flakkari::Protocol::API { - -inline namespace V_1 { - - Header::Header(Network::Buffer data) { - *this = *(Header *)data.data(); - } - - Header::Header( - Priority priority, ApiVersion apiVersion, - FlakkariEventId commandId, ushort contentLength//, - // ulong sequenceNumber, ushort checksum - ) { - _priority = priority; - _apiVersion = apiVersion; - _commandId = commandId; - _contentLength = contentLength; - // _sequenceNumber = sequenceNumber; - // _checksum = checksum; - } - - Header::Header() { - _priority = Priority::LOW; - _apiVersion = ApiVersion::V_1; - } - - Network::Buffer Header::toBuffer() - { - Network::Buffer buffer(sizeof(Header)); - std::copy((byte *)this, (byte *)this + sizeof(Header), buffer.begin()); - return buffer; - } - - void Header::print() - { - std::cout << "Header: " << std::endl; - std::cout << " Priority: " << (int)_priority << std::endl; - std::cout << " ApiVersion: " << (int)_apiVersion << std::endl; - std::cout << " CommandId: " << (int)_commandId << std::endl; - std::cout << " ContentLength: " << (int)_contentLength << std::endl; - // std::cout << " SequenceNumber: " << (int)_sequenceNumber << std::endl; - // std::cout << " Checksum: " << (int)_checksum << std::endl; - } - - std::ostream &operator<<(std::ostream &os, const Header &header) - { - os << "Header: " << std::endl; - os << " Priority: " << (int)header._priority << std::endl; - os << " ApiVersion: " << (int)header._apiVersion << std::endl; - os << " CommandId: " << (int)header._commandId << std::endl; - os << " ContentLength: " << (int)header._contentLength << std::endl; - // os << " SequenceNumber: " << (int)header._sequenceNumber << std::endl; - // os << " Checksum: " << (int)header._checksum << std::endl; - return os; - } - -} /* namespace V_1 */ - -} // namespace Flakkari::Protocol::API diff --git a/Flakkari/Protocol/Header.hpp b/Flakkari/Protocol/Header.hpp index 8da93782..ea03c983 100644 --- a/Flakkari/Protocol/Header.hpp +++ b/Flakkari/Protocol/Header.hpp @@ -3,7 +3,8 @@ * * Flakkari Library is a C++ Library for Network. * @file Header.hpp - * @brief This file contains the Header struct. It is used to create a header for the Flakkari Protocol. + * @brief This file contains the Header struct. It is used to create a header + * for the Flakkari Protocol. * * @see inspired by the https://en.wikipedia.org/wiki/IPv4 header * @@ -14,180 +15,64 @@ * @date 2023-12-24 **************************************************************************/ + #ifndef HEADER_HPP_ -#define HEADER_HPP_ + #define HEADER_HPP_ #define PROTOCOL_VERSION 1 -#include "../Network/Serializer.hpp" -#include "../Network/Packed.hpp" -#include "Event.hpp" - +#include "Network/Buffer.hpp" +#include "Network/Packed.hpp" +#include "Commands.hpp" +#include namespace Flakkari::Protocol::API { - using byte = byte_t; // 8 bits (max: 255) - using ushort = unsigned short; // 16 bits (max: 65535) - using uint = unsigned int; // 32 bits (max: 4294967295) - using ulong = unsigned long; // 64 bits (max: 18446744073709551615) - - inline namespace V_1 { +using byte = byte_t; // 8 bits (max: 255) +using ushort = unsigned short; // 16 bits (max: 65535) +using uint = unsigned int; // 32 bits (max: 4294967295) +using ulong = unsigned long; // 64 bits (max: 18446744073709551615) - /** - * @brief The priority of the message in the queue - * - * @note The priority is used to determine the order of the messages in the queue. - * The higher the priority, the faster the message will be processed. - */ +/** + * @brief The version of the protocol used + * + */ +enum class ApiVersion : byte { + V_0, + MAX_VERSION +}; + +inline namespace V_0 { + + /** + * @brief The priority of the message in the queue + * + * @note The priority is used to determine the order of the messages in the queue. + * The higher the priority, the faster the message will be processed. + */ enum class Priority : byte { - LOW = 0, - MEDIUM = 1, - HIGH = 2, - CRITICAL = 3 - }; - - enum class ApiVersion : byte { - V_1 = 1 - }; + LOW = 0, + MEDIUM = 1, + HIGH = 2, + CRITICAL = 3, + MAX_PRIORITY + }; PACKED_START - /** @brief Flakkari Header v1 (new header) - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | PRIO | API v.| Command ID | Content Length | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Sequence Number | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Checksum | - * +-+-+-+-+-+-+-+-+ - * - * @param migration: 4 bits (max 15) - (not used) - * @param priority: 4 bits (max 15) - to determine the priority of the message in the queue - * @param apiVersion: 4 bits (max 15) - to determine the version of the protocol (v1) - * @param commandId: 8 bits (max 255) - to determine the command to execute - * @param contentLength: 16 bits - to determine the length of the content - * @param sequenceNumber: 64 bits - to determine the sequence of the message - * @param checksum: 16 bits - to determine the checksum of the message - * - * @example "Header for a message with a commandId of 1 and a contentLength of 0" - * @code - * Flakkari::Protocol::API::Header header( - * Flakkari::Protocol::API::Priority::LOW, - * Flakkari::Protocol::API::ApiVersion::V_1, - * 1, 0, 0, 0 - * ); - * header.print(); - * @endcode - */ - struct Header { - Priority _priority: 4; - ApiVersion _apiVersion: 4; - FlakkariEventId _commandId; - ushort _contentLength; - // ulong _sequenceNumber; - // ushort _checksum; - - /** - * @brief Construct a new Header object from a buffer - * @see Network::Buffer - * - * @param data the buffer containing the header - */ - Header(Network::Buffer data); - - Header( - Priority priority, ApiVersion apiVersion, - FlakkariEventId commandId, ushort contentLength = 0//, - // ulong sequenceNumber = 0, ushort checksum = 0 - ); - - Header(); - - /** - * @brief Convert the header to a buffer to send it through the network - * @see Network::Buffer - * - * @return Network::Buffer the buffer containing the header - */ - [[nodiscard]] Network::Buffer toBuffer(); - - /** - * @brief Print the header in the console (for debug) - * - */ - void print(); + template + struct Header { + Priority _priority : 4 = Priority::LOW; + ApiVersion _apiVersion : 4 = ApiVersion::V_0; + Id _commandId; + ushort _contentLength; + uint _sequenceNumber = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); }; PACKED_END - /** - * @brief Overload of the << operator to print the header in the console (for debug) - * - * @param os the output stream - * @param header the header to print - * @return std::ostream& the output stream - */ - std::ostream &operator<<(std::ostream &os, const Header &header); - - struct PlayerPacket { - std::uint32_t x; - std::uint32_t y; - std::uint32_t z; - std::uint32_t vx; - std::uint32_t vy; - std::uint32_t vz; - std::uint32_t soundInfo; - std::uint32_t textureInfo; - bool left; - bool right; - bool up; - bool down; - bool jump; - bool shoot; - std::uint32_t tagSize; - Network::Buffer tag; // variable size - - PlayerPacket() { - x = 0; - y = 0; - z = 0; - vx = 0; - vy = 0; - vz = 0; - soundInfo = 0; - textureInfo = 0; - left = false; - right = false; - up = false; - down = false; - jump = false; - shoot = false; - tagSize = 0; - tag = Network::Buffer(); - } - - std::size_t getSize() { - return sizeof(PlayerPacket) - sizeof(tag) + tag.size(); - } - - PlayerPacket(Network::Buffer data) { - std::copy(data.begin(), data.begin() + sizeof(PlayerPacket) - sizeof(tag), (byte *)this); - tag.resize(tagSize); - std::copy(data.begin() + sizeof(PlayerPacket) - sizeof(tag), data.end(), tag.begin()); - } - - [[nodiscard]] Network::Buffer toBuffer() { - Network::Buffer buffer(getSize()); - std::copy((byte *)this, (byte *)this + sizeof(PlayerPacket) - sizeof(tag), buffer.begin()); - std::copy(tag.begin(), tag.end(), buffer.begin() + sizeof(PlayerPacket) - sizeof(tag)); - return buffer; - } - }; - - } /* namespace V_1 */ +} /* namespace V_1 */ } // namespace Flakkari::Protocol::API diff --git a/Flakkari/Protocol/Packet.cpp b/Flakkari/Protocol/Packet.cpp deleted file mode 100644 index 3d4a52fe..00000000 --- a/Flakkari/Protocol/Packet.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* -** EPITECH PROJECT, 2023 -** Title: Flakkari -** Author: MasterLaplace -** Created: 2023-12-24 -** File description: -** Packet -*/ - -#include "Packet.hpp" - -namespace Flakkari::Protocol::API { - - inline namespace V_1 { - - Packet::Packet(Network::Buffer data) { - header = Header(data); - payload = data.extractData(sizeof(header), header._contentLength); - } - - Packet::Packet(Header header, Network::Buffer payload) - : header(header), payload(payload) {} - - Packet::Packet(Header header) : header(header) {} - - template - void Packet::addContent(T payload) { - this->payload += Network::Buffer(payload); - this->header._contentLength += sizeof(T); - } - - void Packet::addFragment(Network::Buffer fragment) { - this->payload += fragment; - this->header._contentLength += fragment.size(); - } - - template - void Packet::deleteContent(T payload) { - this->payload -= Network::Buffer(payload); - this->header._contentLength -= sizeof(T); - } - - void Packet::deleteFragment(Network::Buffer fragment) { - this->payload -= fragment; - this->header._contentLength -= fragment.size(); - } - - void serializeHeader(Header header, Network::Buffer& buffer) { - std::copy((byte *) &header, (byte *) &header + sizeof(Header), buffer.begin()); - } - - void serializeBuffer(Network::Buffer buffer, Network::Buffer& dest) { - std::copy(buffer.begin(), buffer.end(), dest.begin()); - } - - void serializePacket(Packet packet, Network::Buffer& buffer) { - serializeHeader(packet.header, buffer); - serializeBuffer(packet.payload, buffer); - } - - void deserializeHeader(Network::Buffer buffer, Header& header) { - std::copy(buffer.begin(), buffer.begin() + sizeof(Header), (byte *) &header); - } - - void deserializeBuffer(Network::Buffer buffer, Network::Buffer& dest) { - std::copy(buffer.begin(), buffer.end(), dest.begin()); - } - - void deserializePacket(Network::Buffer buffer, Packet& packet) { - deserializeHeader(buffer, packet.header); - deserializeBuffer(buffer, packet.payload); - } - - } /* namespace V_1 */ - -} // namespace Flakkari::Protocol::API diff --git a/Flakkari/Protocol/Packet.hpp b/Flakkari/Protocol/Packet.hpp index 9965d03d..f3771b96 100644 --- a/Flakkari/Protocol/Packet.hpp +++ b/Flakkari/Protocol/Packet.hpp @@ -18,79 +18,107 @@ * @date 2023-12-24 **************************************************************************/ + #ifndef PACKET_HPP_ -#define PACKET_HPP_ + #define PACKET_HPP_ #include "Header.hpp" +#include "Components.hpp" namespace Flakkari::Protocol::API { -inline namespace V_1 { - - PACKED_START +inline namespace V_0 { /** - * @brief Flakkari Packet v1 (new packet) + * @brief Flakkari Packet v0 (new packet) * + * @tparam Id: The type of the command id. * @param header: The header of the packet. * @param payload: The payload of the packet. */ + template struct Packet { - Header header; + Header header; Network::Buffer payload; - Packet(Network::Buffer data); - Packet(Header header, Network::Buffer payload); - Packet(Header header); - Packet() = default; + std::size_t size() const { + return sizeof(header) + payload.size(); + } + + friend std::ostream& operator<<(std::ostream& os, const Packet& packet) + { + os << "Packet"; + return os; + } + + template + friend Packet& operator<<(Packet& packet, const DataType& data) + { + static_assert(std::is_trivially_copyable::value, "DataType must be trivially copyable to be used in a packet."); + static_assert(std::is_standard_layout::value, "DataType must be standard layout to be used in a packet."); + + std::size_t size = packet.payload.size(); + packet.payload.resize(size + sizeof(DataType)); + std::memcpy(packet.payload.data() + size, &data, sizeof(DataType)); + packet.header._contentLength = packet.payload.size(); + return packet; + } + + template + friend Packet& operator>>(Packet& packet, DataType& data) + { + static_assert(std::is_trivially_copyable::value, "DataType must be trivially copyable to be used in a packet."); + static_assert(std::is_standard_layout::value, "DataType must be standard layout to be used in a packet."); + + std::size_t size = packet.payload.size() - sizeof(DataType); + std::memcpy(&data, packet.payload.data() + size, sizeof(DataType)); + packet.payload.resize(size); + packet.header._contentLength = packet.payload.size(); + return packet; + } /** - * @brief Add payload to the packet. + * @brief Serialize the packet into a buffer to be sent over the network. * - * @tparam T The type of the payload to add. - * @param payload The payload to add. + * @return Network::Buffer The buffer containing the serialized packet. */ - template - void addContent(T payload); + Network::Buffer serialize() const + { + Network::Buffer buffer(size()); + std::memcpy(buffer.data(), &header, sizeof(header)); + std::memcpy(buffer.data() + sizeof(header), payload.data(), payload.size()); + return buffer; + } /** - * @brief Add a fragment to the packet. + * @brief Deserialize the buffer into a packet. * - * @param fragment The fragment to add. + * @param buffer The buffer containing the serialized packet. + * @return true The packet has been deserialized successfully. + * @return false The packet has not been deserialized successfully. */ - void addFragment(Network::Buffer fragment); - - /** - * @brief Delete payload from the packet. - * - * @tparam T The type of the payload to delete. - * @param payload The payload to delete. - */ - template - void deleteContent(T payload); - - /** - * @brief Delete a fragment from the packet. - * - * @param fragment The fragment to delete. - */ - void deleteFragment(Network::Buffer fragment); + [[nodiscard]] bool deserialize(Network::Buffer buffer) + { + std::memcpy(&header, buffer.data(), sizeof(header)); + if (header._priority >= Priority::MAX_PRIORITY) + return false; + if (header._apiVersion >= ApiVersion::MAX_VERSION) + return false; + if (header._contentLength > buffer.size() - sizeof(header)) + return false; + payload = buffer.extractData(sizeof(header), header._contentLength); + return true; + } }; - PACKED_END - - void serializeHeader(Header header, Network::Buffer& buffer); - - void serializeBuffer(Network::Buffer buffer, Network::Buffer& buffer2); - - void serializePacket(Packet packet, Network::Buffer& buffer); - - void deserializeHeader(Network::Buffer buffer, Header& header); - - void deserializeBuffer(Network::Buffer buffer, Network::Buffer& buffer2); - - void deserializePacket(Network::Buffer buffer, Packet& packet); - } /* namespace V_1 */ } // namespace Flakkari::Protocol::API From dcca1ed98dfe330529d4fbba0ddf46d794c5c6be Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 01:38:30 +0100 Subject: [PATCH 18/48] fix(Server): Fix packet parsing and update header initialization --- Flakkari/Protocol/Header.hpp | 2 +- Flakkari/Server/UDPServer.cpp | 42 ++++++++++++----------------------- 2 files changed, 15 insertions(+), 29 deletions(-) diff --git a/Flakkari/Protocol/Header.hpp b/Flakkari/Protocol/Header.hpp index ea03c983..b77331f3 100644 --- a/Flakkari/Protocol/Header.hpp +++ b/Flakkari/Protocol/Header.hpp @@ -65,7 +65,7 @@ inline namespace V_0 { Priority _priority : 4 = Priority::LOW; ApiVersion _apiVersion : 4 = ApiVersion::V_0; Id _commandId; - ushort _contentLength; + ushort _contentLength = 0; uint _sequenceNumber = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()).count(); }; diff --git a/Flakkari/Server/UDPServer.cpp b/Flakkari/Server/UDPServer.cpp index 9d932cd6..6d653d94 100644 --- a/Flakkari/Server/UDPServer.cpp +++ b/Flakkari/Server/UDPServer.cpp @@ -59,41 +59,27 @@ void UDPServer::handlePacket() ClientManager::checkInactiveClients(); // parse packet - Protocol::API::Header header; - std::copy(packet->second.begin(), packet->second.begin() + sizeof(header), reinterpret_cast(&header)); - - std::cout << (*packet->first.get()); // Address - std::cout << " : "; - std::cout << packet->second << std::endl; // Buffer + Protocol::API::Packet parsedPacket; + if (parsedPacket.deserialize(packet->second) == false) + FLAKKARI_LOG_WARNING("Invalid packet received"); std::cout << "RECV Header: " << std::endl; - std::cout << " Priority: " << (int)header._priority << std::endl; - std::cout << " ApiVersion: " << (int)header._apiVersion << std::endl; - std::cout << " CommandId: " << (int)header._commandId << std::endl; - std::cout << " ContentLength: " << (int)header._contentLength << std::endl; + std::cout << " Priority: " << (int)parsedPacket.header._priority << std::endl; + std::cout << " ApiVersion: " << (int)parsedPacket.header._apiVersion << std::endl; + std::cout << " CommandId: " << (int)parsedPacket.header._commandId << std::endl; + std::cout << " ContentLength: " << (int)parsedPacket.header._contentLength << std::endl; // send to all clients - Protocol::API::Header sendHeader( - Protocol::API::Priority::LOW, - Protocol::API::ApiVersion::V_1, - Protocol::API::FlakkariEventId::REP_ENTITY_SPAWN, - 0 - ); - - Protocol::API::PlayerPacket playerPacket; - - sendHeader._contentLength = sizeof(playerPacket); - - Network::Buffer buffer(sizeof(sendHeader) + sizeof(playerPacket)); - std::copy(reinterpret_cast(&sendHeader), reinterpret_cast(&sendHeader) + sizeof(sendHeader), buffer.begin()); + Protocol::API::Packet sendHeader; + sendHeader.header._commandId = Protocol::API::CommandId::REP_CONNECT; std::cout << "SEND Header: " << std::endl; - std::cout << " Priority: " << (int)sendHeader._priority << std::endl; - std::cout << " ApiVersion: " << (int)sendHeader._apiVersion << std::endl; - std::cout << " CommandId: " << (int)sendHeader._commandId << std::endl; - std::cout << " ContentLength: " << (int)sendHeader._contentLength << std::endl; + std::cout << " Priority: " << (int)sendHeader.header._priority << std::endl; + std::cout << " ApiVersion: " << (int)sendHeader.header._apiVersion << std::endl; + std::cout << " CommandId: " << (int)sendHeader.header._commandId << std::endl; + std::cout << " ContentLength: " << (int)sendHeader.header._contentLength << std::endl; - _socket->sendTo(packet->first, buffer); + _socket->sendTo(packet->first, sendHeader.serialize()); } void UDPServer::run() From 5ce90dda06e4d297c23061b762b4d226c8428923 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 06:50:10 +0100 Subject: [PATCH 19/48] feat(Common): Add Evolve component to ECS --- .../Components/Common/Evolve.hpp | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Flakkari/Engine/EntityComponentSystem/Components/Common/Evolve.hpp diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Evolve.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Evolve.hpp new file mode 100644 index 00000000..127073f4 --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Evolve.hpp @@ -0,0 +1,43 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2023-01-13 +** File description: +** Evolve +*/ + +#ifndef EVOLVE_HPP_ +#define EVOLVE_HPP_ + +#include +#include + +#include "Network/Packed.hpp" + +namespace Flakkari::Engine::ECS::Components::Common { +PACKED_START + +/** + * @brief Evolve component for ECS entities that can evolve in to another Component + * + * @details This component is used to evolve an entity in to another entity + * based on a template + */ +struct Evolve { + const char *name; + + Evolve() : name("") {} + Evolve(const std::string &nname) : name(nname.c_str()) {} + Evolve(const char *nname) : name(nname) {} + Evolve(const Evolve &other) : name(other.name) {} + + std::size_t size() const { + return std::strlen(name); + } +}; + +PACKED_END +} // namespace Flakkari::Engine::ECS::Components::Common + +#endif /* !EVOLVE_HPP_ */ From 8b00eebaf8a2397f10ecf5d0562208c074d801ca Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 06:51:08 +0100 Subject: [PATCH 20/48] feat(Common): Add Id.hpp to Engine/EntityComponentSystem/Components/Common directory --- .../Components/Common/Id.hpp | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp new file mode 100644 index 00000000..51a6696a --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp @@ -0,0 +1,35 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2023-01-06 +** File description: +** Id +*/ + +#ifndef ID_HPP_ +#define ID_HPP_ + +#include + +#include "Network/Packed.hpp" + +namespace Engine::ECS::Components::Common { +PACKED_START + +struct Id { + std::size_t id; + + Id() : id(0) {} + Id(const Id &other) : id(other.id) {} + Id(std::size_t id) : id(id) {} + + std::size_t size() const { + return sizeof(id); + } +}; + +PACKED_END +} // namespace Engine::ECS::Components::Common + +#endif /* !ID_HPP_ */ From bcf0da4fd7784d2b7d4fbb968523b3523a8a925e Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 06:52:00 +0100 Subject: [PATCH 21/48] feat(Common): Update Id and add Template component --- .../Components/Common/Id.hpp | 2 +- .../Components/Common/Template.hpp | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp index 51a6696a..572937c7 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp @@ -2,7 +2,7 @@ ** EPITECH PROJECT, 2024 ** Title: Flakkari ** Author: MasterLaplace -** Created: 2023-01-06 +** Created: 2024-01-06 ** File description: ** Id */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp new file mode 100644 index 00000000..66c90919 --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp @@ -0,0 +1,36 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2024-01-13 +** File description: +** Template +*/ + +#ifndef TEMPLATE_HPP_ +#define TEMPLATE_HPP_ + +#include +#include + +#include "Network/Packed.hpp" + +namespace Flakkari::Engine::ECS::Components::Common { +PACKED_START + +struct Template { + const char *name; + + Template() : name("") {} + Template(const std::string &nname) : name(nname.c_str()) {} + Template(const char *nname) : name(nname) {} + + std::size_t size() const { + return std::strlen(name); + } +}; + +PACKED_END +} // namespace Flakkari::Engine::ECS::Components::Common + +#endif /* !TEMPLATE_HPP_ */ From 1aedc7a4f60c1b76f1f95b466e0e6319f8372d74 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 06:52:38 +0100 Subject: [PATCH 22/48] update(Components): Add common components --- .../EntityComponentSystem/Components/ComponentsCommon.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp b/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp index ffe439b5..6dc3ef99 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp @@ -16,7 +16,11 @@ #ifndef COMPONENTSCOMMON_HPP_ #define COMPONENTSCOMMON_HPP_ +#include "Common/Child.hpp" // Child component (name) +#include "Common/Evolve.hpp" // Evolve component (name) +#include "Common/Id.hpp" // Id component (id) #include "Common/Parent.hpp" // Parent component (entity) #include "Common/Tag.hpp" // Tag component (tag) +#include "Common/Template.hpp" // Template component (name) #endif /* !COMPONENTSCOMMON_HPP_ */ From b2d1fc3083d6fb6ea876f4c2fa83f5d0fceba045 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 06:58:28 +0100 Subject: [PATCH 23/48] fix(Network): Fix typos and deprecated function in code --- Flakkari/Network/PacketQueue.hpp | 1 - Flakkari/Network/Socket.cpp | 3 +-- Flakkari/Protocol/Components.hpp | 2 +- Flakkari/Protocol/Packet.hpp | 43 +++++++++++++++++++++++++++++++- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/Flakkari/Network/PacketQueue.hpp b/Flakkari/Network/PacketQueue.hpp index 4aac8e6a..d2289c0c 100644 --- a/Flakkari/Network/PacketQueue.hpp +++ b/Flakkari/Network/PacketQueue.hpp @@ -1,4 +1,3 @@ -/* /************************************************************************** * Flakkari Library v0.2.0 * diff --git a/Flakkari/Network/Socket.cpp b/Flakkari/Network/Socket.cpp index 4d511bc7..4ea8220a 100644 --- a/Flakkari/Network/Socket.cpp +++ b/Flakkari/Network/Socket.cpp @@ -266,8 +266,7 @@ void Socket::sendTo(const std::shared_ptr
&address, const byte *data, c } #else if (::sendto(_socket, data, size, flags, addr->ai_addr, addr->ai_addrlen) == SOCKET_ERROR) { - FLAKKARI_LOG_ERROR("Failed to send \""+ std::string(data, data + size) +"\" to \""+ address->toString().value_or("No address") +"\", error: "+ STD_ERROR - ); + FLAKKARI_LOG_ERROR("Failed to send \""+ std::string(data, data + size) +"\" to \""+ address->toString().value_or("No address") +"\", error: "+ STD_ERROR); return; } #endif diff --git a/Flakkari/Protocol/Components.hpp b/Flakkari/Protocol/Components.hpp index ce9eab8d..f1cdf4fa 100644 --- a/Flakkari/Protocol/Components.hpp +++ b/Flakkari/Protocol/Components.hpp @@ -27,7 +27,7 @@ inline namespace V_0 { enum class ComponentId : uint8_t { // 0 - 9: 2D components - CONTOL = 0, + CONTROL = 0, MOVABLE = 1, TRANSFORM = 2, // 10 - 19: Common components diff --git a/Flakkari/Protocol/Packet.hpp b/Flakkari/Protocol/Packet.hpp index f3771b96..fabc1d1d 100644 --- a/Flakkari/Protocol/Packet.hpp +++ b/Flakkari/Protocol/Packet.hpp @@ -59,6 +59,14 @@ inline namespace V_0 { return os; } + /** + * @brief Add data to the packet. + * + * @tparam DataType Type of the data to add. + * @param packet The packet to add the data to. + * @param data The data to add. + * @return Packet& The packet with the data added. + */ template friend Packet& operator<<(Packet& packet, const DataType& data) { @@ -72,6 +80,17 @@ inline namespace V_0 { return packet; } + /** + * @brief Extract data from the packet. + * + * @tparam DataType Type of the data to extract. + * @param packet The packet to extract the data from. + * @param data The data to extract. + * @return Packet& The packet with the data extracted. + * + * @deprecated This function is deprecated. Don't work with std::string. + * Use the other operator>> instead. + */ template friend Packet& operator>>(Packet& packet, DataType& data) { @@ -85,6 +104,28 @@ inline namespace V_0 { return packet; } + /** + * @brief Add data to the packet. + * + * @tparam DataType Type of the data to add. + * @param packet The packet to add the data to. + * @param data The data to add. + * @return Packet& The packet with the data added. + */ + template + friend Packet& operator>>(Packet& packet, std::vector& data) + { + static_assert(std::is_trivially_copyable::value, "DataType must be trivially copyable to be used in a packet."); + static_assert(std::is_standard_layout::value, "DataType must be standard layout to be used in a packet."); + + std::size_t size = packet.payload.size() - sizeof(DataType) * data.size(); + data.resize(packet.payload.size() / sizeof(DataType)); + std::memcpy(data.data(), packet.payload.data() + size, sizeof(DataType) * data.size()); + packet.payload.resize(size); + packet.header._contentLength = packet.payload.size(); + return packet; + } + /** * @brief Serialize the packet into a buffer to be sent over the network. * @@ -105,7 +146,7 @@ inline namespace V_0 { * @return true The packet has been deserialized successfully. * @return false The packet has not been deserialized successfully. */ - [[nodiscard]] bool deserialize(Network::Buffer buffer) + [[nodiscard]] bool deserialize(const Network::Buffer &buffer) { std::memcpy(&header, buffer.data(), sizeof(header)); if (header._priority >= Priority::MAX_PRIORITY) From d264a2aa0bdffec89013677b3df9700cbca4dd5a Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 07:03:13 +0100 Subject: [PATCH 24/48] fix(Game): Fix loading scene in Game constructor --- Flakkari/Server/Game/Game.cpp | 6 +++--- Flakkari/Server/Game/Game.hpp | 22 +++++++++++++++------- Flakkari/Server/Game/ResourceManager.hpp | 2 +- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index 7b707598..2cf2aebb 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -19,7 +19,7 @@ Game::Game(const std::string &name, std::shared_ptr config) _time = std::chrono::steady_clock::now(); if ((*_config)["scenes"].empty()) throw std::runtime_error("Game: no scenes found"); - loadScene((*_config)["startScene"]); + loadScene((*_config)["startGame"]); } Game::~Game() @@ -51,7 +51,7 @@ void Game::loadComponents(Engine::ECS::Registry ®istry, const nl_component &c transform.rotation = componentContent["rotation"]; transform.scale = Engine::Math::Vector2f(componentContent["scale"]["x"], componentContent["scale"]["y"]); registry.add_component(newEntity, std::move(transform)); - return; + continue; } if (componentName == "Movable") { @@ -60,7 +60,7 @@ void Game::loadComponents(Engine::ECS::Registry ®istry, const nl_component &c movable.velocity = Engine::Math::Vector2f(componentContent["velocity"]["x"], componentContent["velocity"]["y"]); movable.acceleration = Engine::Math::Vector2f(componentContent["acceleration"]["x"], componentContent["acceleration"]["y"]); registry.add_component(newEntity, std::move(movable)); - return; + continue; } } } diff --git a/Flakkari/Server/Game/Game.hpp b/Flakkari/Server/Game/Game.hpp index 7ae96eea..ae7826df 100644 --- a/Flakkari/Server/Game/Game.hpp +++ b/Flakkari/Server/Game/Game.hpp @@ -25,19 +25,21 @@ #include #include -#include "Engine/EntityComponentSystem/Registry.hpp" #include "Engine/EntityComponentSystem/Systems/Systems.hpp" namespace Flakkari { class Client; -using nl_entity = nlohmann::json_abi_v3_11_3::detail::iteration_proxy>; -using nl_template = nlohmann::json_abi_v3_11_3::basic_json>, void>; -using nl_component = nlohmann::json_abi_v3_11_3::json ; +using nl_entity = nlohmann::detail::iteration_proxy>; +using nl_template = nlohmann::basic_json>, void>; +using nl_component = nlohmann::json; class Game { public: + friend class Client; + + public: // Constructors/Destructors /** * @brief Construct a new Game object and load the config file * of the game. @@ -48,6 +50,7 @@ class Game { Game(const std::string &name, std::shared_ptr config); ~Game(); + public: // Loaders /** * @brief Add all the systems of the game to the registry. * @@ -63,7 +66,9 @@ class Game { * @param componentInfo Info of the components to add. * @param newEntity Entity to add the components to. */ - void loadComponents(Engine::ECS::Registry ®istry, const nl_component &componentInfo, Engine::ECS::Entity newEntity); + void loadComponents ( + Engine::ECS::Registry ®istry, const nl_component &componentInfo, Engine::ECS::Entity newEntity + ); /** * @brief Add all the entities of the game to the registry. @@ -72,7 +77,9 @@ class Game { * @param entity Entity to add to the registry. * @param templates Templates of the game. */ - void loadEntityFromTemplate(Engine::ECS::Registry ®istry, const nl_entity &entity, const nl_template &templates); + void loadEntityFromTemplate ( + Engine::ECS::Registry ®istry, const nl_entity &entity, const nl_template &templates + ); /** * @brief Load a scene from the game. @@ -117,7 +124,7 @@ class Game { * @return true Player removed successfully * @return false Player not removed */ - [[nodiscard]] bool removePlayer(std::shared_ptr player); + bool removePlayer(std::shared_ptr player); /** * @brief Get if the game is running. @@ -127,6 +134,7 @@ class Game { */ [[nodiscard]] bool isRunning() const; + public: // Getters /** * @brief Get the Name object (name of the game). * diff --git a/Flakkari/Server/Game/ResourceManager.hpp b/Flakkari/Server/Game/ResourceManager.hpp index 9dd18c42..c69a9eba 100644 --- a/Flakkari/Server/Game/ResourceManager.hpp +++ b/Flakkari/Server/Game/ResourceManager.hpp @@ -52,7 +52,7 @@ class ResourceManager { static std::shared_ptr _instance; static std::mutex _mutex; - using nl_template = nlohmann::json_abi_v3_11_3::json; + using nl_template = nlohmann::json; public: std::map>> _templates; From dd34779eeb5705682d354b0c6cd51f970ec0f1f9 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 07:12:53 +0100 Subject: [PATCH 25/48] feat(Protocol): Add PacketFactory class for creating packets from entities --- CMakeLists.txt | 4 +- Flakkari/Protocol/PacketFactory.hpp | 189 ++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 Flakkari/Protocol/PacketFactory.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 85fcbffa..d53c522a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,7 @@ set(HEADERS Flakkari/Protocol/Components.hpp Flakkari/Protocol/Header.hpp Flakkari/Protocol/Packet.hpp + Flakkari/Protocol/PacketFactory.hpp Flakkari/Engine/Math/Vector.hpp @@ -60,7 +61,7 @@ set(HEADERS Flakkari/Server/Game/Game.hpp Flakkari/Server/Game/GameManager.hpp - Flakkari/Server/Game/ResourceManager.cpp + Flakkari/Server/Game/ResourceManager.hpp Flakkari/Server/Internals/CommandManager.hpp ) @@ -84,6 +85,7 @@ set(HEADER_LIB_PROTOCOL Flakkari/Protocol/Components.hpp Flakkari/Protocol/Header.hpp Flakkari/Protocol/Packet.hpp + Flakkari/Protocol/PacketFactory.hpp ) # CMake Modules: diff --git a/Flakkari/Protocol/PacketFactory.hpp b/Flakkari/Protocol/PacketFactory.hpp new file mode 100644 index 00000000..4920a36d --- /dev/null +++ b/Flakkari/Protocol/PacketFactory.hpp @@ -0,0 +1,189 @@ +/************************************************************************** + * Flakkari Library v0.2.0 + * + * Flakkari Library is a C++ Library for Network. + * @file PacketFactory.hpp + * @brief Flakkari::Protocol::PacketFactory class header. This class is used to + * create a packet from an entity. It is used to send an entity to the + * server or to the client. + * + * Flakkari Library is under MIT License. + * https://opensource.org/licenses/MIT + * © 2023 @MasterLaplace + * @version 0.2.0 + * @date 2024-01-13 + **************************************************************************/ + + +#ifndef PACKETFACTORY_HPP_ + #define PACKETFACTORY_HPP_ + +#include "Packet.hpp" + +#include "Engine/EntityComponentSystem/Systems/Systems.hpp" + +namespace Flakkari::Protocol { + +class PacketFactory { +public: + /** + * @brief Add all the commons components of an entity to a packet. + * + * @tparam Id Type of the entity id. + * @param packet Packet to add the components to. + * @param registry Registry to get the components from. + * @param entity Entity to get the components from. + */ + template + static void addCommonsToPacketByEntity ( + Protocol::API::Packet &packet, Engine::ECS::Registry ®istry, Engine::ECS::Entity entity + ) { + auto child = registry.getComponents(); + auto childEntity = child[entity]; + + if (childEntity.has_value()) { + packet << Protocol::API::ComponentId::CHILD; + packet << childEntity->size(); + packet << childEntity->name.c_str(); + } + + auto evolve = registry.getComponents(); + auto evolveEntity = evolve[entity]; + + if (evolveEntity.has_value()) { + packet << Protocol::API::ComponentId::EVOLVE; + packet << evolveEntity->size(); + packet << evolveEntity->name.c_str(); + } + + auto id = registry.getComponents(); + auto idEntity = id[entity]; + + if (idEntity.has_value()) { + packet << Protocol::API::ComponentId::ID; + packet << idEntity->size(); + packet << idEntity->id; + } + + auto parent = registry.getComponents(); + auto parentEntity = parent[entity]; + + if (parentEntity.has_value()) { + packet << Protocol::API::ComponentId::PARENT; + packet << parentEntity->size(); + packet << parentEntity->name.c_str(); + } + + auto tag = registry.getComponents(); + auto tagEntity = tag[entity]; + + if (tagEntity.has_value()) { + packet << Protocol::API::ComponentId::TAG; + packet << tagEntity->size(); + packet << tagEntity->tag.c_str(); + } + + auto name = registry.getComponents(); + auto nameEntity = name[entity]; + + if (nameEntity.has_value()) { + packet << Protocol::API::ComponentId::TEMPLATE; + packet << nameEntity->size(); + packet << nameEntity->name.c_str(); + } + } + + /** + * @brief Add all the 2D components of an entity to a packet. + * + * @tparam Id Type of the entity id. + * @param packet Packet to add the components to. + * @param registry Registry to get the components from. + * @param entity Entity to get the components from. + */ + template + static void add2dToPacketByEntity ( + Protocol::API::Packet &packet, Engine::ECS::Registry ®istry, Engine::ECS::Entity entity + ) { + auto transform = r.getComponents(); + auto pos = transform[entity]; + + if (pos.has_value()) { + packet << Protocol::API::ComponentId::TRANSFORM; + packet << pos->size(); + packet << pos->position.x; + packet << pos->position.y; + packet << pos->rotation; + packet << pos->scale.x; + packet << pos->scale.y; + } + + auto movable = r.getComponents(); + auto vel = movable[entity]; + + if (vel.has_value()) { + packet << Protocol::API::ComponentId::MOVABLE; + packet << vel->size(); + packet << vel->velocity.x; + packet << vel->velocity.y; + packet << vel->acceleration.x; + packet << vel->acceleration.y; + } + + auto control = r.getComponents(); + auto ctrl = control[entity]; + + if (ctrl.has_value()) { + packet << Protocol::API::ComponentId::CONTROL; + packet << ctrl->size(); + packet << ctrl->up; + packet << ctrl->down; + packet << ctrl->left; + packet << ctrl->right; + packet << ctrl->shoot; + } + } + + /** + * @brief Add all the components of an entity to a packet. + * + * @tparam Id Type of the entity id. + * @param packet Packet to add the components to. + * @param registry Registry to get the components from. + * @param entity Entity to get the components from. + */ + template + static void addComponentsToPacketByEntity ( + Protocol::API::Packet &packet, Engine::ECS::Registry ®istry, Engine::ECS::Entity entity + ) { + /*_ Common Components _*/ + + addCommonsToPacketByEntity(packet, registry, entity); + + /*_ 2D Components _*/ + + add2dToPacketByEntity(packet, registry, entity); + } + + /** + * @brief Add requirement information for Command that use components. + * @tparam Id Type of the entity id. + * @param packet Packet to add the components to. + * @param size Size of the packet. + * @param sceneName Name of the scene. + * @param entity Entity to get the components from. + */ + template + static void addInfoToPacket ( + Protocol::API::Packet &packet, std::size_t size, + const std::string &sceneName, Engine::ECS::Entity entity + ) { + packet << size; + packet << sceneName.c_str(); + packet << entity; + } +}; + +} // namespace Flakkari::Protocol + +#endif /* !PACKETFACTORY_HPP_ */ From 03d12eef50619a2af3deacaea1ee24d78e8266a4 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 07:16:27 +0100 Subject: [PATCH 26/48] feat(ECS): Add EntityFactory class to create entities from templates --- CMakeLists.txt | 2 + .../EntityComponentSystem/EntityFactory.hpp | 154 ++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d53c522a..19e5794b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,8 +54,10 @@ set(HEADERS Flakkari/Engine/EntityComponentSystem/Entity.hpp Flakkari/Engine/EntityComponentSystem/SparseArrays.hpp Flakkari/Engine/EntityComponentSystem/Registry.hpp + Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp Flakkari/Server/UDPServer.hpp + Flakkari/Server/Client/Client.hpp Flakkari/Server/Client/ClientManager.hpp diff --git a/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp b/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp new file mode 100644 index 00000000..06b729c6 --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp @@ -0,0 +1,154 @@ +/************************************************************************** + * Flakkari Engine Library v0.2.0 + * + * Flakkari Library is a C++ Library for Network. + * @file EntityFactory.hpp + * @brief Flakkari::Engine::ECS::EntityFactory class header. This class is + * used to create an entity from a template. It is used to create + * entities from the server or from the client. + * + * Flakkari Library is under MIT License. + * https://opensource.org/licenses/MIT + * © 2023 @MasterLaplace + * @version 0.2.0 + * @date 2024-01-13 + **************************************************************************/ + + +#ifndef ENTITYFACTORY_HPP_ + #define ENTITYFACTORY_HPP_ + +#include + +#include "Registry.hpp" + +#include "Components/Components2D.hpp" +#include "Components/ComponentsCommon.hpp" + +namespace Flakkari::Engine::ECS { + +class EntityFactory { +public: + using nl_template = nlohmann::json; + +public: + + /** + * @brief Create a Entity From Template object based on a template JSON + * + * @details This function will create an entity based on the template JSON + * (using the template name) + * + * @see ResourceManager::getTemplateById + * + * @param registry The registry to add the entity to + * @param templateJson The template JSON + * @return Entity The created entity + */ + static Entity createEntityFromTemplate ( + Registry ®istry, const nl_template &templateJson + ) { + Entity entity = registry.spawn_entity(); + + addEntityToRegistryByTemplate(registry, entity, templateJson); + + return entity; + } + + /** + * @brief Add an entity to the registry based on a template JSON + * + * @details This function will add all the components to the entity + * based on the template JSON (using the template name) + * + * @see ResourceManager::getTemplateById + * + * @param registry The registry to add the entity to + * @param entity The entity to add the components to + * @param templateJson The template JSON + */ + static void addEntityToRegistryByTemplate ( + Registry ®istry, Entity entity, const nl_template &templateJson + ) { + for (auto &component : templateJson.items()) + { + auto componentName = component.key(); + auto componentContent = component.value(); + + //*_ 2D Components _*// + + if (componentName == "Control") { + registry.registerComponent(); + Engine::ECS::Components::_2D::Control control; + control.up = componentContent["up"]; + control.down = componentContent["down"]; + control.left = componentContent["left"]; + control.right = componentContent["right"]; + control.shoot = componentContent["shoot"]; + registry.add_component(entity, std::move(control)); + continue; + } + + if (componentName == "Movable") { + registry.registerComponent(); + Engine::ECS::Components::_2D::Movable movable; + movable.velocity = Engine::Math::Vector2f(componentContent["velocity"]["x"], componentContent["velocity"]["y"]); + movable.acceleration = Engine::Math::Vector2f(componentContent["acceleration"]["x"], componentContent["acceleration"]["y"]); + registry.add_component(entity, std::move(movable)); + continue; + } + + if (componentName == "Transform") { + registry.registerComponent(); + Engine::ECS::Components::_2D::Transform transform; + transform.position = Engine::Math::Vector2f(componentContent["position"]["x"], componentContent["position"]["y"]); + transform.rotation = componentContent["rotation"]; + transform.scale = Engine::Math::Vector2f(componentContent["scale"]["x"], componentContent["scale"]["y"]); + registry.add_component(entity, std::move(transform)); + continue; + } + + //*_ Common Components _*// + + if (componentName == "Child") { + registry.registerComponent(); + Engine::ECS::Components::Common::Child child(componentContent["name"]); + registry.add_component(entity, std::move(child)); + continue; + } + + if (componentName == "Evolve") { + registry.registerComponent(); + Engine::ECS::Components::Common::Evolve evolve(componentContent["name"]); + registry.add_component(entity, std::move(evolve)); + continue; + } + + if (componentName == "Parent") { + registry.registerComponent(); + Engine::ECS::Components::Common::Parent parent(componentContent["entity"]); + registry.add_component(entity, std::move(parent)); + continue; + } + + + if (componentName == "Tag") { + registry.registerComponent(); + Engine::ECS::Components::Common::Tag tag(componentContent["tag"]); + registry.add_component(entity, std::move(tag)); + continue; + } + + if (componentName == "Template") { + registry.registerComponent(); + Engine::ECS::Components::Common::Template template_(componentContent["name"]); + registry.add_component(entity, std::move(template_)); + continue; + } + } + } +}; + +} // namespace Flakkari::Engine::ECS + +#endif /* !ENTITYFACTORY_HPP_ */ From 6f61517a9797ea887fa8e673d5553df47f3b33f8 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 07:18:44 +0100 Subject: [PATCH 27/48] feat(Client): Add packet history and warning count to Client class --- Flakkari/Server/Client/Client.cpp | 13 ++++++++ Flakkari/Server/Client/Client.hpp | 50 +++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/Flakkari/Server/Client/Client.cpp b/Flakkari/Server/Client/Client.cpp index 00d0b958..af05631a 100644 --- a/Flakkari/Server/Client/Client.cpp +++ b/Flakkari/Server/Client/Client.cpp @@ -19,6 +19,7 @@ Client::Client(std::shared_ptr address) Client::~Client() { _isConnected = false; + _address->setId(-1); } bool Client::isConnected(float timeout) @@ -32,4 +33,16 @@ void Client::keepAlive() { _lastActivity = std::chrono::steady_clock::now(); } +void Client::addPacketToHistory(Network::Buffer packet) +{ + if (_packetHistory.size() >= _maxPacketHistory) + _packetHistory.erase(_packetHistory.begin()); + _packetHistory.push_back(packet); +} + +bool Client::incrementWarningCount() { + _warningCount++; + return _warningCount >= _maxWarningCount; +} + } /* namespace Flakkari */ diff --git a/Flakkari/Server/Client/Client.hpp b/Flakkari/Server/Client/Client.hpp index 79a3321f..da7c39bf 100644 --- a/Flakkari/Server/Client/Client.hpp +++ b/Flakkari/Server/Client/Client.hpp @@ -15,11 +15,14 @@ #ifndef CLIENT_HPP_ -#define CLIENT_HPP_ + #define CLIENT_HPP_ #include -#include "Network/Address.hpp" +#include "Network/Socket.hpp" +#include "Network/PacketQueue.hpp" +#include "Protocol/Packet.hpp" +#include "Engine/EntityComponentSystem/Entity.hpp" #include "../Game/GameManager.hpp" namespace Flakkari { @@ -61,6 +64,21 @@ class Client { */ void keepAlive(); + /** + * @brief Add a packet to the client's packet history + * + * @param packet The packet to add + */ + void addPacketToHistory(Network::Buffer packet); + + /** + * @brief Increment the warning count of the client + * + * @return true If the client has been disconnected + * @return false If the client has not been disconnected + */ + bool incrementWarningCount(); + /** * @brief Get the client's address * @@ -68,13 +86,39 @@ class Client { */ [[nodiscard]] std::shared_ptr getAddress() const { return _address; } - [[nodiscard]] unsigned int getId() const { return _address->getId(); } + /** + * @brief Get the Entity object + * + * @return Entity The entity of the client + */ + [[nodiscard]] Engine::ECS::Entity getEntity() const { return _entity; } + void setEntity(Engine::ECS::Entity entity) { _entity = entity; } + + [[nodiscard]] short getId() const { return _address->getId(); } + + [[nodiscard]] std::string getSceneName() const { return _sceneName; } + void setSceneName(std::string sceneName) { _sceneName = sceneName; } + + [[nodiscard]] unsigned short getWarningCount() const { return _warningCount; } + + [[nodiscard]] unsigned short getMaxWarningCount() const { return _maxWarningCount; } + + [[nodiscard]] unsigned short getMaxPacketHistory() const { return _maxPacketHistory; } protected: private: std::chrono::steady_clock::time_point _lastActivity; std::shared_ptr _address; + Engine::ECS::Entity _entity; + std::string _sceneName; bool _isConnected = true; + unsigned short _warningCount = 0; + unsigned short _maxWarningCount = 5; + unsigned short _maxPacketHistory = 10; + public: + std::vector _packetHistory; + Network::PacketQueue> _sendQueue; + Network::PacketQueue> _receiveQueue; }; } /* namespace Flakkari */ From e1e47d317131531e58ea0ab6d06c51b0af36f70d Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 17:05:15 +0100 Subject: [PATCH 28/48] feat(Game): Add new functions to Game class and update PacketFactory --- Flakkari/Protocol/PacketFactory.hpp | 42 ++++---- Flakkari/Server/Client/ClientManager.cpp | 127 +++++++++++++++++++++-- Flakkari/Server/Client/ClientManager.hpp | 58 +++++++++-- Flakkari/Server/Game/Game.cpp | 55 ++++++++++ Flakkari/Server/Game/Game.hpp | 21 ++++ Flakkari/Server/UDPServer.cpp | 1 + 6 files changed, 266 insertions(+), 38 deletions(-) diff --git a/Flakkari/Protocol/PacketFactory.hpp b/Flakkari/Protocol/PacketFactory.hpp index 4920a36d..abd7ac22 100644 --- a/Flakkari/Protocol/PacketFactory.hpp +++ b/Flakkari/Protocol/PacketFactory.hpp @@ -44,26 +44,26 @@ class PacketFactory { if (childEntity.has_value()) { packet << Protocol::API::ComponentId::CHILD; packet << childEntity->size(); - packet << childEntity->name.c_str(); + packet << childEntity->name; } - auto evolve = registry.getComponents(); - auto evolveEntity = evolve[entity]; + // auto evolve = registry.getComponents(); + // auto evolveEntity = evolve[entity]; - if (evolveEntity.has_value()) { - packet << Protocol::API::ComponentId::EVOLVE; - packet << evolveEntity->size(); - packet << evolveEntity->name.c_str(); - } + // if (evolveEntity.has_value()) { + // packet << Protocol::API::ComponentId::EVOLVE; + // packet << evolveEntity->size(); + // packet << evolveEntity->name; + // } - auto id = registry.getComponents(); - auto idEntity = id[entity]; + // auto id = registry.getComponents(); + // auto idEntity = id[entity]; - if (idEntity.has_value()) { - packet << Protocol::API::ComponentId::ID; - packet << idEntity->size(); - packet << idEntity->id; - } + // if (idEntity.has_value()) { + // packet << Protocol::API::ComponentId::ID; + // packet << idEntity->size(); + // packet << idEntity->id; + // } auto parent = registry.getComponents(); auto parentEntity = parent[entity]; @@ -71,7 +71,7 @@ class PacketFactory { if (parentEntity.has_value()) { packet << Protocol::API::ComponentId::PARENT; packet << parentEntity->size(); - packet << parentEntity->name.c_str(); + packet << parentEntity->entity; } auto tag = registry.getComponents(); @@ -80,7 +80,7 @@ class PacketFactory { if (tagEntity.has_value()) { packet << Protocol::API::ComponentId::TAG; packet << tagEntity->size(); - packet << tagEntity->tag.c_str(); + packet << tagEntity->tag; } auto name = registry.getComponents(); @@ -89,7 +89,7 @@ class PacketFactory { if (nameEntity.has_value()) { packet << Protocol::API::ComponentId::TEMPLATE; packet << nameEntity->size(); - packet << nameEntity->name.c_str(); + packet << nameEntity->name; } } @@ -105,7 +105,7 @@ class PacketFactory { static void add2dToPacketByEntity ( Protocol::API::Packet &packet, Engine::ECS::Registry ®istry, Engine::ECS::Entity entity ) { - auto transform = r.getComponents(); + auto transform = registry.getComponents(); auto pos = transform[entity]; if (pos.has_value()) { @@ -118,7 +118,7 @@ class PacketFactory { packet << pos->scale.y; } - auto movable = r.getComponents(); + auto movable = registry.getComponents(); auto vel = movable[entity]; if (vel.has_value()) { @@ -130,7 +130,7 @@ class PacketFactory { packet << vel->acceleration.y; } - auto control = r.getComponents(); + auto control = registry.getComponents(); auto ctrl = control[entity]; if (ctrl.has_value()) { diff --git a/Flakkari/Server/Client/ClientManager.cpp b/Flakkari/Server/Client/ClientManager.cpp index 2a32aea6..311bccae 100644 --- a/Flakkari/Server/Client/ClientManager.cpp +++ b/Flakkari/Server/Client/ClientManager.cpp @@ -22,29 +22,64 @@ std::shared_ptr ClientManager::getInstance() return _instance; } +void ClientManager::setSocket(std::shared_ptr socket) { + getInstance()->_socket = socket; +} + void ClientManager::addClient(std::shared_ptr client) { auto &clients = getInstance()->_clients; - if (clients.find(client->toString().value_or("")) == clients.end()) { + + if (ClientManager::isBanned(client)) { + FLAKKARI_LOG_LOG("Client " + client->toString().value_or("Unknown") + " tried to connect but is banned"); + return; + } + + if (clients.find(client->toString().value_or("")) != clients.end()) + return clients[client->toString().value_or("")]->keepAlive(), void(); + clients[client->toString().value_or("")] = std::make_shared(client); FLAKKARI_LOG_LOG("Client " + client->toString().value_or("Unknown") + " connected"); GameManager::addClientToGame("R-Type", clients[client->toString().value_or("")]); - } else - clients[client->toString().value_or("")]->keepAlive(); } void ClientManager::removeClient(std::shared_ptr client) { auto &clients = getInstance()->_clients; - if (clients.find(client->toString().value_or("")) != clients.end()) { + + if (clients.find(client->toString().value_or("")) == clients.end()) + return; + + GameManager::removeClientFromGame("R-Type", clients[client->toString().value_or("")]); + clients.erase(client->toString().value_or("")); +} + +void ClientManager::banClient(std::shared_ptr client) +{ + auto &clients = getInstance()->_clients; + auto &bannedClients = getInstance()->_bannedClients; + + if (clients.find(client->toString().value_or("")) == clients.end()) + return; + + bannedClients.push_back(client->getIp().value()); + + FLAKKARI_LOG_LOG("Client " + client->toString().value_or("Unknown") + " banned"); GameManager::removeClientFromGame("R-Type", clients[client->toString().value_or("")]); clients.erase(client->toString().value_or("")); } + +bool ClientManager::isBanned(std::shared_ptr client) +{ + auto &bannedClients = getInstance()->_bannedClients; + + return std::find(bannedClients.begin(), bannedClients.end(), client->getIp().value_or("")) != bannedClients.end(); } void ClientManager::checkInactiveClients() { auto &clients = getInstance()->_clients; + for (auto it = clients.begin(); it != clients.end();) { if (!it->second->isConnected()) { FLAKKARI_LOG_LOG("Client " + it->first + " disconnected"); @@ -56,20 +91,92 @@ void ClientManager::checkInactiveClients() } } +void ClientManager::sendPacketToClient ( + std::shared_ptr client, const Network::Buffer &packet +) { + auto socket = getInstance()->_socket; + + (void)std::async(std::launch::async, [socket, client, packet] { + socket->sendTo(client, packet); + }); +} + +void ClientManager::sendPacketToAllClients(const Network::Buffer &packet) +{ + auto instance = getInstance(); + auto clients = instance->_clients; + auto socket = instance->_socket; + + for (auto &tmp_client : clients) { + if (tmp_client.second->isConnected()) + socket->sendTo(tmp_client.second->getAddress(), packet); + } +} + +void ClientManager::sendPacketToAllClientsExcept ( + std::shared_ptr client, const Network::Buffer &packet +) { + auto instance = getInstance(); + auto clients = instance->_clients; + auto socket = instance->_socket; + + for (auto &tmp_client : clients) { + if (tmp_client.second->isConnected() && tmp_client.second->getAddress()->toString().value_or("") != client->toString().value_or("")) + socket->sendTo(tmp_client.second->getAddress(), packet); + } +} + +void ClientManager::receivePacketFromClient ( + std::shared_ptr client, const Network::Buffer &buffer +) { + auto &clients = getInstance()->_clients; + auto &bannedClients = getInstance()->_bannedClients; + auto clientName = client->toString().value_or("Unknown"); + + if (std::find(bannedClients.begin(), bannedClients.end(), client->getIp().value_or("")) != bannedClients.end()) { + FLAKKARI_LOG_LOG("Client " + clientName + " tried to connect but is banned"); + return; + } + + if (clients.find(client->toString().value_or("")) == clients.end()) + return; + auto &tmp_client = clients[client->toString().value_or("")]; + + FLAKKARI_LOG_LOG("Client " + clientName + " sent a packet: " + std::string(buffer)); + + Protocol::API::Packet packet; + if (packet.deserialize(buffer)) { + tmp_client->_receiveQueue.push_back(packet); + return; + } + + FLAKKARI_LOG_LOG("Client " + clientName + " sent an invalid packet"); + + if (!tmp_client->incrementWarningCount()) + return; + + FLAKKARI_LOG_LOG("Client " + clientName + " has been banned"); + + bannedClients.push_back(client->getIp().value()); + FLAKKARI_LOG_LOG("Client " + clientName + " banned"); + GameManager::removeClientFromGame("R-Type", tmp_client); + clients.erase(client->toString().value_or("")); +} + std::shared_ptr ClientManager::getClient(std::shared_ptr client) { return getInstance()->_clients[client->toString().value_or("")]; } -std::shared_ptr ClientManager::getClient(std::string ip) { - return getInstance()->_clients[ip]; +std::shared_ptr ClientManager::getClient(std::string id) { + return getInstance()->_clients[id]; } -std::shared_ptr ClientManager::getAddress(std::string ip) { - return getInstance()->_clients[ip]->getAddress(); +std::shared_ptr ClientManager::getAddress(std::string id) { + return getInstance()->_clients[id]->getAddress(); } -std::shared_ptr ClientManager::operator[](std::string ip) { - return _clients[ip]; +std::shared_ptr ClientManager::operator[](std::string id) { + return _clients[id]; } } /* namespace Flakkari */ diff --git a/Flakkari/Server/Client/ClientManager.hpp b/Flakkari/Server/Client/ClientManager.hpp index ac51896a..88e38bd3 100644 --- a/Flakkari/Server/Client/ClientManager.hpp +++ b/Flakkari/Server/Client/ClientManager.hpp @@ -16,7 +16,7 @@ #ifndef CLIENTMANAGER_HPP_ #define CLIENTMANAGER_HPP_ -#include "Network/Address.hpp" +#include "Network/Socket.hpp" #include "Client.hpp" #include @@ -51,7 +51,9 @@ class ClientManager { using id_t = short; public: + std::unordered_map> _clients; std::vector _bannedClients; + std::shared_ptr _socket; public: ClientManager(const ClientManager &) = delete; @@ -71,6 +73,8 @@ class ClientManager { */ ~ClientManager() = default; + static void setSocket(std::shared_ptr socket); + /** * @brief Get the instance of the client manager * @@ -92,6 +96,15 @@ class ClientManager { */ static void removeClient(std::shared_ptr client); + /** + * @brief Ban a client from the server + * + * @param client The client's address + */ + static void banClient(std::shared_ptr client); + + [[nodiscard]] static bool isBanned(std::shared_ptr client); + /** * @brief Check if the clients are still connected to the server * and remove the inactive clients from the client manager @@ -103,6 +116,37 @@ class ClientManager { */ static void checkInactiveClients(); + /** + * @brief Send a packet to a client + * + * @param client The client's address + * @param packet The packet to send + */ + static void sendPacketToClient(std::shared_ptr client, const Network::Buffer &packet); + + /** + * @brief Send a packet to all clients + * + * @param packet The packet to send + */ + static void sendPacketToAllClients(const Network::Buffer &packet); + + /** + * @brief Send a packet to all clients except one + * + * @param client The client's address + * @param packet The packet to send + */ + static void sendPacketToAllClientsExcept(std::shared_ptr client, const Network::Buffer &packet); + + /** + * @brief Receive a packet from a client + * + * @param client The client's address + * @param packet The packet received + */ + static void receivePacketFromClient(std::shared_ptr client, const Network::Buffer &packet); + /** * @brief Get the Client object * @@ -114,26 +158,26 @@ class ClientManager { /** * @brief Get the Client object * - * @param ip The client's ip address and port + * @param id The client's id * @return std::shared_ptr The client object */ - static std::shared_ptr getClient(std::string ip); + static std::shared_ptr getClient(std::string id); /** * @brief Get the Address object * - * @param ip The client's ip address and port + * @param id The client's id * @return std::shared_ptr The client's address */ - static std::shared_ptr getAddress(std::string ip); + static std::shared_ptr getAddress(std::string id); /** * @brief Get the client object from the client manager * - * @param ip The client's ip address and port + * @param id The client's id * @return std::shared_ptr The client object */ - std::shared_ptr operator[](std::string ip); + std::shared_ptr operator[](std::string id); }; } /* namespace Flakkari */ diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index 2cf2aebb..99f92270 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -98,6 +98,51 @@ void Game::loadScene(const std::string &sceneName) } } +void Game::sendOnSameScene(const std::string &sceneName, const Network::Buffer &message) +{ + for (auto &player : _players) { + if (!player || !player->isConnected()) + continue; + if (player->getSceneName() != sceneName) + continue; + ClientManager::sendPacketToClient(player->getAddress(), message); + } +} + +void Game::checkDisconnect() +{ + for (auto &player : _players) { + if (!player || player->isConnected()) + continue; + Protocol::API::Packet packet; + packet.header._commandId = Protocol::API::CommandId::REQ_ENTITY_DESTROY; + packet << player->getSceneName().size(); + packet << player->getSceneName().c_str(); + packet << player->getEntity(); + + sendOnSameScene(player->getSceneName(), packet.serialize()); + + _scenes[player->getSceneName()].kill_entity(player->getEntity()); + removePlayer(player); + } +} + +void Game::updateIncomingPackets(unsigned char maxMessagePerFrame) +{ + for (auto &player : _players) { + if (!player->isConnected()) + continue; + auto &packets = player->_receiveQueue; + auto messageCount = maxMessagePerFrame; + + while (!packets.empty() && messageCount > 0) { + Protocol::API::Packet p; + auto packet = packets.pop_front(); + messageCount--; + } + } +} + void Game::update() { auto now = std::chrono::steady_clock::now(); @@ -111,6 +156,7 @@ void Game::update() void Game::start() { _running = true; + _time = std::chrono::steady_clock::now(); _thread = std::thread(&Game::run, this); FLAKKARI_LOG_INFO("game \"" + _name + "\" is now running"); } @@ -127,6 +173,15 @@ bool Game::addPlayer(std::shared_ptr player) return false; if (_players.size() >= (*_config)["maxPlayers"] || !player->isConnected()) return false; + + auto sceneGame = (*_config)["startGame"]; + auto ®istry = _scenes[sceneGame]; + + player->setSceneName(sceneGame); + + Engine::ECS::Entity newEntity = registry.spawn_entity(); + player->setEntity(newEntity); + _players.push_back(player); FLAKKARI_LOG_INFO("client \""+ std::string(*player->getAddress()) +"\" added to game \""+ _name +"\""); return true; diff --git a/Flakkari/Server/Game/Game.hpp b/Flakkari/Server/Game/Game.hpp index ae7826df..b2e2fb33 100644 --- a/Flakkari/Server/Game/Game.hpp +++ b/Flakkari/Server/Game/Game.hpp @@ -26,6 +26,11 @@ #include #include "Engine/EntityComponentSystem/Systems/Systems.hpp" +#include "Engine/EntityComponentSystem/EntityFactory.hpp" + +#include "Protocol/PacketFactory.hpp" + +#include "ResourceManager.hpp" namespace Flakkari { @@ -88,6 +93,22 @@ class Game { */ void loadScene(const std::string &name); + public: // Actions + void sendOnSameScene(const std::string &sceneName, const Network::Buffer &message); + + /** + * @brief Check if a player is disconnected. + * + */ + void checkDisconnect(); + + /** + * @brief Empty the incoming packets of the players and update the + * game with the new packets. + * + */ + void updateIncomingPackets(unsigned char maxMessagePerFrame = 10); + /** * @brief Update the game. This function is called every frame. * diff --git a/Flakkari/Server/UDPServer.cpp b/Flakkari/Server/UDPServer.cpp index 6d653d94..9848d750 100644 --- a/Flakkari/Server/UDPServer.cpp +++ b/Flakkari/Server/UDPServer.cpp @@ -26,6 +26,7 @@ UDPServer::UDPServer(std::string ip, std::size_t port) : _io->addSocket(_socket->getSocket()); _io->addSocket(STDIN_FILENO); + ClientManager::setSocket(_socket); GameManager::getInstance(); } From dce18a10259d96645d1a2d7b0bf087a41bdaf40b Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 17:16:06 +0100 Subject: [PATCH 29/48] fix(workflows): Update build workflows and add Windows support --- .github/workflows/build_checker_macos.yml | 3 +-- .github/workflows/build_checker_ubuntu.yml | 2 +- .github/workflows/build_checker_windows.yml | 24 +++++++++++++++++++++ .github/workflows/create_release.yml | 24 +++++++++++++++++++++ .gitignore | 1 + CMakeLists.txt | 1 + Flakkari/Server/Client/ClientManager.cpp | 2 ++ Flakkari/Server/Client/ClientManager.hpp | 1 + README.md | 19 +++++++++++----- 9 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/build_checker_windows.yml create mode 100644 .github/workflows/create_release.yml diff --git a/.github/workflows/build_checker_macos.yml b/.github/workflows/build_checker_macos.yml index 5aabb7f7..002a9f4a 100644 --- a/.github/workflows/build_checker_macos.yml +++ b/.github/workflows/build_checker_macos.yml @@ -9,7 +9,7 @@ on: - '*' jobs: - verify-commit-name: + build_checker_macos: runs-on: macos-latest steps: @@ -21,7 +21,6 @@ jobs: brew install cmake brew install ninja - - name: Build run: | mkdir build diff --git a/.github/workflows/build_checker_ubuntu.yml b/.github/workflows/build_checker_ubuntu.yml index ef9db635..5d2ce31f 100644 --- a/.github/workflows/build_checker_ubuntu.yml +++ b/.github/workflows/build_checker_ubuntu.yml @@ -9,7 +9,7 @@ on: - '*' jobs: - verify-commit-name: + build_checker_ubuntu: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/build_checker_windows.yml b/.github/workflows/build_checker_windows.yml new file mode 100644 index 00000000..39e7f582 --- /dev/null +++ b/.github/workflows/build_checker_windows.yml @@ -0,0 +1,24 @@ +name: Build Checker Windows + +on: + push: + branches: + - '*' + pull_request: + branches: + - '*' + +jobs: + build: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - name: Install CMake + run: | + choco install cmake -y + + - name: Configure and Build + run: | + mkdir build && cd build + cmake .. && cmake --build . diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml new file mode 100644 index 00000000..ff4df94d --- /dev/null +++ b/.github/workflows/create_release.yml @@ -0,0 +1,24 @@ +name: Create Release on Tag + +on: + push: + tags: + - 'v*.*.0' + +jobs: + build: + name: Create Release + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Flakkari ${{ github.ref }} + draft: false + prerelease: false diff --git a/.gitignore b/.gitignore index 2dcad2b6..3f9d9528 100644 --- a/.gitignore +++ b/.gitignore @@ -574,3 +574,4 @@ docs/Flakkari/ build/ .Test/ poc/ +Experimental/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 19e5794b..3b3e01aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCES Flakkari/core.cpp Flakkari/Logger/Logger.cpp + Flakkari/Network/Address.cpp Flakkari/Network/Buffer.cpp Flakkari/Network/Socket.cpp diff --git a/Flakkari/Server/Client/ClientManager.cpp b/Flakkari/Server/Client/ClientManager.cpp index 311bccae..fcfb7185 100644 --- a/Flakkari/Server/Client/ClientManager.cpp +++ b/Flakkari/Server/Client/ClientManager.cpp @@ -10,6 +10,8 @@ #include "ClientManager.hpp" #include "../Game/GameManager.hpp" +#include + namespace Flakkari { diff --git a/Flakkari/Server/Client/ClientManager.hpp b/Flakkari/Server/Client/ClientManager.hpp index 88e38bd3..f1386580 100644 --- a/Flakkari/Server/Client/ClientManager.hpp +++ b/Flakkari/Server/Client/ClientManager.hpp @@ -21,6 +21,7 @@ #include #include +#include namespace Flakkari { diff --git a/README.md b/README.md index 69e55f66..8a06d0e4 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,19 @@

🌐 Supported Platforms

- Linux   |   - Windows   |   - MacOS   |   - FreeBSD + Linux   |   + Windows   |   + MacOS   |  

📡 Supported Protocol

@@ -111,7 +120,7 @@ $ docker --version > Docker version 24.0.7, build afdd53b # build docker image -$ docker build -t Flakkari . +$ docker build -t flakkari . # run docker image $ docker run Flakkari -p 4242:4242 From adc8d938352fdd9ff432517af4afc4eb9fe7c95b Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 17:43:24 +0100 Subject: [PATCH 30/48] fix(Components): Refactor component constructors and add new component --- .../EntityComponentSystem/Components/Common/Id.hpp | 2 +- .../Components/Common/Parent.hpp | 1 - .../Components/Common/Template.hpp | 1 + .../Components/Components2D.hpp | 2 ++ Flakkari/Engine/EntityComponentSystem/Registry.hpp | 13 +++++++++++++ Flakkari/Network/Address.cpp | 4 +++- Flakkari/Network/IOMultiplexer.cpp | 2 +- 7 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp index 572937c7..57dc684a 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp @@ -21,8 +21,8 @@ struct Id { std::size_t id; Id() : id(0) {} - Id(const Id &other) : id(other.id) {} Id(std::size_t id) : id(id) {} + Id(const Id &other) : id(other.id) {} std::size_t size() const { return sizeof(id); diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Parent.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Parent.hpp index c865cc6e..243dbbf2 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Parent.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Parent.hpp @@ -28,7 +28,6 @@ struct Parent { Parent() : entity(0) {} Parent(const std::size_t &entity) : entity(entity) {} Parent(const Parent &other) : entity(other.entity) {} - std::size_t size() const { return sizeof(*this); } diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp index 66c90919..4c14ce93 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp @@ -24,6 +24,7 @@ struct Template { Template() : name("") {} Template(const std::string &nname) : name(nname.c_str()) {} Template(const char *nname) : name(nname) {} + Template(const Template &other) : name(other.name) {} std::size_t size() const { return std::strlen(name); diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp index ee033868..21390c62 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp @@ -16,8 +16,10 @@ #ifndef COMPONENTS2D_HPP_ #define COMPONENTS2D_HPP_ +// #include "2D/Collider.hpp" // Collider component (shape, position, rotation, scale) #include "2D/Control.hpp" // Control component (up, down, left, right, shoot) #include "2D/Movable.hpp" // Movable component (velocity, angularVelocity, acceleration, angularAcceleration) +#include "2D/RigidBody.hpp" // RigidBody component (mass, restitution, friction, linearDamping) #include "2D/Transform.hpp" // Transform component (position, rotation, scale) #endif /* !COMPONENTS2D_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Registry.hpp b/Flakkari/Engine/EntityComponentSystem/Registry.hpp index f08caa43..5cdd223c 100644 --- a/Flakkari/Engine/EntityComponentSystem/Registry.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Registry.hpp @@ -111,6 +111,19 @@ class Registry { return getComponents().insert_at(to, std::forward(c)); } + /** + * @brief Get the component from an entity. + * + * @tparam Component The component to get. + * @param to The entity to get the component from. + * @param c The component to get. + * @return SparseArrays::reference_type The component. + */ + template + typename SparseArrays::reference_type add_component(const entity_type &to, const Component &c) { + return getComponents().insert_at(to, c); + } + /** * @brief Get the component from an entity. * diff --git a/Flakkari/Network/Address.cpp b/Flakkari/Network/Address.cpp index 1358a91f..50e13f8f 100644 --- a/Flakkari/Network/Address.cpp +++ b/Flakkari/Network/Address.cpp @@ -92,7 +92,9 @@ Address::Address(const sockaddr_storage &clientAddr, SocketType socket_type, IpT addrinfo *result = nullptr; const char *name = inet_ntoa(((sockaddr_in *)&clientAddr)->sin_addr); - const char *service = std::to_string(ntohs(((sockaddr_in *)&clientAddr)->sin_port)).c_str(); + + const std::string serviceStr = std::to_string(ntohs(((sockaddr_in *)&clientAddr)->sin_port)); + const char *service = serviceStr.c_str(); if (getaddrinfo(name, service, &hints, &result) != 0) { FLAKKARI_LOG_ERROR("getaddrinfo() failed"); diff --git a/Flakkari/Network/IOMultiplexer.cpp b/Flakkari/Network/IOMultiplexer.cpp index 3ec464f9..aaad5147 100644 --- a/Flakkari/Network/IOMultiplexer.cpp +++ b/Flakkari/Network/IOMultiplexer.cpp @@ -67,7 +67,7 @@ int PSELECT::wait() #if defined(_WIN32) return ::select(_maxFd + 1, &_fds, nullptr, nullptr, (const timeval *)&_timeout); #elif defined(__APPLE__) - return ::select(_maxFd + 1, &_fds, nullptr, nullptr, &_timeout); + return ::select(_maxFd + 1, &_fds, nullptr, nullptr, (struct timeval *)&_timeout); #else return ::pselect(_maxFd + 1, &_fds, nullptr, nullptr, &_timeout, nullptr); #endif From 1b43dbc11e1104f2f13bf5b3fd98a63e6dc31d62 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 17:48:35 +0100 Subject: [PATCH 31/48] fix(Components): Remove RigidBody component from Components2D.hpp --- .../Engine/EntityComponentSystem/Components/Components2D.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp index 21390c62..216a987b 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp @@ -19,7 +19,6 @@ // #include "2D/Collider.hpp" // Collider component (shape, position, rotation, scale) #include "2D/Control.hpp" // Control component (up, down, left, right, shoot) #include "2D/Movable.hpp" // Movable component (velocity, angularVelocity, acceleration, angularAcceleration) -#include "2D/RigidBody.hpp" // RigidBody component (mass, restitution, friction, linearDamping) #include "2D/Transform.hpp" // Transform component (position, rotation, scale) #endif /* !COMPONENTS2D_HPP_ */ From a9d8ef77df20f080947bf078dda5a3cf9d59fd24 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 18:05:53 +0100 Subject: [PATCH 32/48] feat(Internals): Update network address handling and password retrieval --- Flakkari/Network/Address.hpp | 10 +++++++++- Flakkari/Server/Internals/CommandManager.cpp | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Flakkari/Network/Address.hpp b/Flakkari/Network/Address.hpp index 089440f4..9a7e31d5 100644 --- a/Flakkari/Network/Address.hpp +++ b/Flakkari/Network/Address.hpp @@ -15,9 +15,17 @@ #ifndef ADDRESS_HPP_ #define ADDRESS_HPP_ -#include +#ifndef _WIN32 || _WIN64 || MSVC || _MSC_VER #include #include +#else +#include +#include + +#pragma comment(lib, "Ws2_32.lib") +#endif + +#include #include #include #include diff --git a/Flakkari/Server/Internals/CommandManager.cpp b/Flakkari/Server/Internals/CommandManager.cpp index 8282321c..0c2303c6 100644 --- a/Flakkari/Server/Internals/CommandManager.cpp +++ b/Flakkari/Server/Internals/CommandManager.cpp @@ -46,7 +46,15 @@ bool CommandManager::handlePasswordCommand(const std::string &input) if (!std::regex_match(input, PASSWORD_REGEX)) return false; - const char *password = std::getenv("FLAKKARI_PASSWORD"); + #ifndef _WIN32 || _WIN64 || MSVC || _MSC_VER + const char *password = std::getenv("FLAKKARI_PASSWORD"); + #else + char *password; + size_t len; + errno_t err = _dupenv_s(&password, &len, "FLAKKARI_PASSWORD"); + if (err) + password = nullptr; + #endif if (password == nullptr || !*password) { FLAKKARI_LOG_WARNING("No password set: please set FLAKKARI_PASSWORD environment variable"); From 4aa1a60dfbb0266070145da4ea3aa73ed94742a6 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 18:10:57 +0100 Subject: [PATCH 33/48] fix(Logger): Refactor Logger.cpp and Packed.hpp --- Flakkari/Logger/Logger.cpp | 2 +- Flakkari/Network/Packed.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Flakkari/Logger/Logger.cpp b/Flakkari/Logger/Logger.cpp index 55df3172..5e60228b 100644 --- a/Flakkari/Logger/Logger.cpp +++ b/Flakkari/Logger/Logger.cpp @@ -30,7 +30,7 @@ const std::string Logger::get_current_time() noexcept } #ifdef _WIN32 -void setColor(int color) { +void setColor(WORD color) noexcept { HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole, color); } diff --git a/Flakkari/Network/Packed.hpp b/Flakkari/Network/Packed.hpp index 894ea2e3..f47cae01 100644 --- a/Flakkari/Network/Packed.hpp +++ b/Flakkari/Network/Packed.hpp @@ -41,7 +41,7 @@ do { \ #else -#define PACKED(name, body) \ +#define __PACKED(name, body)\ do { \ PACKED_START \ struct name \ From d889885b214414350814424a304ea1a1caeec810 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 19:12:40 +0100 Subject: [PATCH 34/48] fix(Network): Fix conditional compilation issue in Address.hpp and CommandManager.cpp --- Flakkari/Network/Address.hpp | 4 ++-- Flakkari/Server/Internals/CommandManager.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Flakkari/Network/Address.hpp b/Flakkari/Network/Address.hpp index 9a7e31d5..2fb828c7 100644 --- a/Flakkari/Network/Address.hpp +++ b/Flakkari/Network/Address.hpp @@ -13,9 +13,9 @@ **************************************************************************/ #ifndef ADDRESS_HPP_ -#define ADDRESS_HPP_ + #define ADDRESS_HPP_ -#ifndef _WIN32 || _WIN64 || MSVC || _MSC_VER +#if !defined(_WIN32) && !defined(_WIN64) || !defined( MSVC) || !defined(_MSC_VER) #include #include #else diff --git a/Flakkari/Server/Internals/CommandManager.cpp b/Flakkari/Server/Internals/CommandManager.cpp index 0c2303c6..0ea571f6 100644 --- a/Flakkari/Server/Internals/CommandManager.cpp +++ b/Flakkari/Server/Internals/CommandManager.cpp @@ -46,7 +46,7 @@ bool CommandManager::handlePasswordCommand(const std::string &input) if (!std::regex_match(input, PASSWORD_REGEX)) return false; - #ifndef _WIN32 || _WIN64 || MSVC || _MSC_VER + #if !defined(_WIN32) && !defined(_WIN64) || !defined( MSVC) || !defined(_MSC_VER) const char *password = std::getenv("FLAKKARI_PASSWORD"); #else char *password; From 5615f4c4e0fcc4f0a216f14c11e17a20259632c1 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 19:57:44 +0100 Subject: [PATCH 35/48] refactor(Client): Refactor packet serialization and deserialization --- Flakkari/Protocol/Packet.hpp | 22 +++++++++++++++++++--- Flakkari/Server/Client/ClientManager.cpp | 20 ++++++++++++-------- Flakkari/Server/Game/Game.cpp | 15 +++++++++++---- Flakkari/Server/UDPServer.cpp | 24 ++---------------------- 4 files changed, 44 insertions(+), 37 deletions(-) diff --git a/Flakkari/Protocol/Packet.hpp b/Flakkari/Protocol/Packet.hpp index fabc1d1d..30aa61b7 100644 --- a/Flakkari/Protocol/Packet.hpp +++ b/Flakkari/Protocol/Packet.hpp @@ -45,14 +45,28 @@ inline namespace V_0 { return sizeof(header) + payload.size(); } + std::string to_string() + { + std::string str = "Packet"; + return str; + } + friend std::ostream& operator<<(std::ostream& os, const Packet& packet) { os << "Packet"; @@ -148,6 +162,8 @@ inline namespace V_0 { */ [[nodiscard]] bool deserialize(const Network::Buffer &buffer) { + if (buffer.size() < sizeof(header)) + return false; std::memcpy(&header, buffer.data(), sizeof(header)); if (header._priority >= Priority::MAX_PRIORITY) return false; diff --git a/Flakkari/Server/Client/ClientManager.cpp b/Flakkari/Server/Client/ClientManager.cpp index fcfb7185..53590390 100644 --- a/Flakkari/Server/Client/ClientManager.cpp +++ b/Flakkari/Server/Client/ClientManager.cpp @@ -121,9 +121,12 @@ void ClientManager::sendPacketToAllClientsExcept ( auto instance = getInstance(); auto clients = instance->_clients; auto socket = instance->_socket; + auto clientKey = client->toString().value_or(""); for (auto &tmp_client : clients) { - if (tmp_client.second->isConnected() && tmp_client.second->getAddress()->toString().value_or("") != client->toString().value_or("")) + auto tmp_clientKey = tmp_client.second->getAddress()->toString().value_or(""); + + if (tmp_client.second->isConnected() && tmp_clientKey != clientKey) socket->sendTo(tmp_client.second->getAddress(), packet); } } @@ -134,25 +137,26 @@ void ClientManager::receivePacketFromClient ( auto &clients = getInstance()->_clients; auto &bannedClients = getInstance()->_bannedClients; auto clientName = client->toString().value_or("Unknown"); + auto ip = client->getIp().value_or(""); + auto clientKey = client->toString().value_or(""); - if (std::find(bannedClients.begin(), bannedClients.end(), client->getIp().value_or("")) != bannedClients.end()) { + if (std::find(bannedClients.begin(), bannedClients.end(), ip) != bannedClients.end()) { FLAKKARI_LOG_LOG("Client " + clientName + " tried to connect but is banned"); return; } - if (clients.find(client->toString().value_or("")) == clients.end()) + if (clients.find(clientKey) == clients.end()) return; - auto &tmp_client = clients[client->toString().value_or("")]; - - FLAKKARI_LOG_LOG("Client " + clientName + " sent a packet: " + std::string(buffer)); + auto &tmp_client = clients[clientKey]; Protocol::API::Packet packet; if (packet.deserialize(buffer)) { + FLAKKARI_LOG_LOG("Client " + clientName + " sent a valid packet: " + packet.to_string()); tmp_client->_receiveQueue.push_back(packet); return; } - FLAKKARI_LOG_LOG("Client " + clientName + " sent an invalid packet"); + FLAKKARI_LOG_WARNING("Client " + clientName + " sent an invalid packet"); if (!tmp_client->incrementWarningCount()) return; @@ -162,7 +166,7 @@ void ClientManager::receivePacketFromClient ( bannedClients.push_back(client->getIp().value()); FLAKKARI_LOG_LOG("Client " + clientName + " banned"); GameManager::removeClientFromGame("R-Type", tmp_client); - clients.erase(client->toString().value_or("")); + clients.erase(clientKey); } std::shared_ptr ClientManager::getClient(std::shared_ptr client) { diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index 99f92270..8a59775a 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -37,8 +37,9 @@ void Game::loadSystems(Engine::ECS::Registry ®istry, const std::string &name) }), void(); } -void Game::loadComponents(Engine::ECS::Registry ®istry, const nl_component &components, Engine::ECS::Entity newEntity) -{ +void Game::loadComponents ( + Engine::ECS::Registry ®istry, const nl_component &components, Engine::ECS::Entity newEntity +) { for (auto &component : components.items()) { auto componentName = component.key(); @@ -65,8 +66,9 @@ void Game::loadComponents(Engine::ECS::Registry ®istry, const nl_component &c } } -void Game::loadEntityFromTemplate(Engine::ECS::Registry ®istry, const nl_entity &entity, const nl_template &templates) -{ +void Game::loadEntityFromTemplate ( + Engine::ECS::Registry ®istry, const nl_entity &entity, const nl_template &templates +) { Engine::ECS::Entity newEntity = registry.spawn_entity(); for (auto &componentInfo : entity.begin().value().items()) { @@ -138,6 +140,7 @@ void Game::updateIncomingPackets(unsigned char maxMessagePerFrame) while (!packets.empty() && messageCount > 0) { Protocol::API::Packet p; auto packet = packets.pop_front(); + FLAKKARI_LOG_INFO("packet received: " + packet.to_string()); messageCount--; } } @@ -149,6 +152,10 @@ void Game::update() _deltaTime = std::chrono::duration_cast>(now - _time).count(); _time = now; + checkDisconnect(); + + updateIncomingPackets(); + for (auto &scene : _scenes) scene.second.run_systems(); } diff --git a/Flakkari/Server/UDPServer.cpp b/Flakkari/Server/UDPServer.cpp index 9848d750..acf9b06c 100644 --- a/Flakkari/Server/UDPServer.cpp +++ b/Flakkari/Server/UDPServer.cpp @@ -59,28 +59,8 @@ void UDPServer::handlePacket() ClientManager::addClient(packet->first); ClientManager::checkInactiveClients(); - // parse packet - Protocol::API::Packet parsedPacket; - if (parsedPacket.deserialize(packet->second) == false) - FLAKKARI_LOG_WARNING("Invalid packet received"); - - std::cout << "RECV Header: " << std::endl; - std::cout << " Priority: " << (int)parsedPacket.header._priority << std::endl; - std::cout << " ApiVersion: " << (int)parsedPacket.header._apiVersion << std::endl; - std::cout << " CommandId: " << (int)parsedPacket.header._commandId << std::endl; - std::cout << " ContentLength: " << (int)parsedPacket.header._contentLength << std::endl; - - // send to all clients - Protocol::API::Packet sendHeader; - sendHeader.header._commandId = Protocol::API::CommandId::REP_CONNECT; - - std::cout << "SEND Header: " << std::endl; - std::cout << " Priority: " << (int)sendHeader.header._priority << std::endl; - std::cout << " ApiVersion: " << (int)sendHeader.header._apiVersion << std::endl; - std::cout << " CommandId: " << (int)sendHeader.header._commandId << std::endl; - std::cout << " ContentLength: " << (int)sendHeader.header._contentLength << std::endl; - - _socket->sendTo(packet->first, sendHeader.serialize()); + ClientManager::receivePacketFromClient(packet->first, packet->second); + ClientManager::sendPacketToClient(packet->first, packet->second); } void UDPServer::run() From 059d494b9b58e363703180a0f124e695213ecf32 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 20:02:01 +0100 Subject: [PATCH 36/48] fix(Network): Fix conditional statements in Address.hpp and CommandManager.cpp --- Flakkari/Network/Address.hpp | 2 +- Flakkari/Server/Internals/CommandManager.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Flakkari/Network/Address.hpp b/Flakkari/Network/Address.hpp index 2fb828c7..0762937f 100644 --- a/Flakkari/Network/Address.hpp +++ b/Flakkari/Network/Address.hpp @@ -15,7 +15,7 @@ #ifndef ADDRESS_HPP_ #define ADDRESS_HPP_ -#if !defined(_WIN32) && !defined(_WIN64) || !defined( MSVC) || !defined(_MSC_VER) +#if !defined(_WIN32) && !defined(_WIN64) && !defined( MSVC) && !defined(_MSC_VER) #include #include #else diff --git a/Flakkari/Server/Internals/CommandManager.cpp b/Flakkari/Server/Internals/CommandManager.cpp index 0ea571f6..5bc4046f 100644 --- a/Flakkari/Server/Internals/CommandManager.cpp +++ b/Flakkari/Server/Internals/CommandManager.cpp @@ -46,7 +46,7 @@ bool CommandManager::handlePasswordCommand(const std::string &input) if (!std::regex_match(input, PASSWORD_REGEX)) return false; - #if !defined(_WIN32) && !defined(_WIN64) || !defined( MSVC) || !defined(_MSC_VER) + #if !defined(_WIN32) && !defined(_WIN64) && !defined( MSVC) && !defined(_MSC_VER) const char *password = std::getenv("FLAKKARI_PASSWORD"); #else char *password; From 4d5146b4028d54ff16efe0da68890e796725d056 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sat, 13 Jan 2024 20:15:50 +0100 Subject: [PATCH 37/48] fix(Logger): Fix time handling and remove unnecessary preprocessor directives --- Flakkari/Logger/Logger.cpp | 16 +++++++++++++--- Flakkari/Network/Address.hpp | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Flakkari/Logger/Logger.cpp b/Flakkari/Logger/Logger.cpp index 5e60228b..61131576 100644 --- a/Flakkari/Logger/Logger.cpp +++ b/Flakkari/Logger/Logger.cpp @@ -21,10 +21,20 @@ void Logger::setMode(Logger::Mode mode) noexcept { const std::string Logger::get_current_time() noexcept { - auto currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - char buffer[80]; - std::strftime(buffer, sizeof(buffer), "[ %Y-%m-%d %H:%M:%S ]", std::localtime(¤tTime)); + struct tm timeInfo; + + #if defined(_WIN32) || defined(_WIN64) + auto currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + + if (localtime_s(&timeInfo, ¤tTime) != 0) + return "localtime_s failed"; + #else + auto currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + timeInfo = *std::localtime(¤tTime); + #endif + + std::strftime(buffer, sizeof(buffer), "[ %Y-%m-%d %H:%M:%S ]", &timeInfo); return std::string(buffer); } diff --git a/Flakkari/Network/Address.hpp b/Flakkari/Network/Address.hpp index 0762937f..de6911a8 100644 --- a/Flakkari/Network/Address.hpp +++ b/Flakkari/Network/Address.hpp @@ -15,7 +15,7 @@ #ifndef ADDRESS_HPP_ #define ADDRESS_HPP_ -#if !defined(_WIN32) && !defined(_WIN64) && !defined( MSVC) && !defined(_MSC_VER) +#if !defined(_WIN32) && !defined(_WIN64) #include #include #else From 31bf98307bb1f307f2f54116dd997930e8fff79b Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sat, 13 Jan 2024 21:02:52 +0100 Subject: [PATCH 38/48] update(ECS): Update include paths in Flakkari codebase --- .../Engine/EntityComponentSystem/Components/2D/Control.hpp | 6 +++--- .../Engine/EntityComponentSystem/Components/2D/Movable.hpp | 6 +++--- .../EntityComponentSystem/Components/2D/Transform.hpp | 6 +++--- .../EntityComponentSystem/Components/Common/Child.hpp | 6 +++--- .../EntityComponentSystem/Components/Common/Evolve.hpp | 6 +++--- .../Engine/EntityComponentSystem/Components/Common/Id.hpp | 6 +++--- .../EntityComponentSystem/Components/Common/Parent.hpp | 6 +++--- .../Engine/EntityComponentSystem/Components/Common/Tag.hpp | 6 +++--- .../EntityComponentSystem/Components/Common/Template.hpp | 6 +++--- .../EntityComponentSystem/Components/Components2D.hpp | 6 +++--- .../EntityComponentSystem/Components/ComponentsCommon.hpp | 6 +++--- Flakkari/Engine/EntityComponentSystem/Entity.hpp | 6 +++--- Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp | 6 +++--- Flakkari/Engine/EntityComponentSystem/Registry.hpp | 6 +++--- Flakkari/Engine/EntityComponentSystem/SparseArrays.hpp | 6 +++--- Flakkari/Engine/EntityComponentSystem/Systems/Systems.hpp | 6 +++--- Flakkari/Engine/Math/Vector.hpp | 6 +++--- Flakkari/Protocol/PacketFactory.hpp | 2 +- 18 files changed, 52 insertions(+), 52 deletions(-) diff --git a/Flakkari/Engine/EntityComponentSystem/Components/2D/Control.hpp b/Flakkari/Engine/EntityComponentSystem/Components/2D/Control.hpp index 5e6a7210..4b697fd2 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/2D/Control.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/2D/Control.hpp @@ -7,8 +7,8 @@ ** Control */ -#ifndef CONTROL_HPP_ -#define CONTROL_HPP_ +#ifndef FLAKKARI_CONTROL_HPP_ +#define FLAKKARI_CONTROL_HPP_ #include "../../../Math/Vector.hpp" @@ -46,4 +46,4 @@ struct Control { PACKED_END } // namespace Flakkari::Engine::ECS::Components::_2D -#endif /* !CONTROL_HPP_ */ +#endif /* !FLAKKARI_CONTROL_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/2D/Movable.hpp b/Flakkari/Engine/EntityComponentSystem/Components/2D/Movable.hpp index 0fc628cd..4f526e83 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/2D/Movable.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/2D/Movable.hpp @@ -7,8 +7,8 @@ ** Movable */ -#ifndef MOVABLE_HPP_ -#define MOVABLE_HPP_ +#ifndef FLAKKARI_MOVABLE_HPP_ +#define FLAKKARI_MOVABLE_HPP_ #include "../../../Math/Vector.hpp" @@ -33,4 +33,4 @@ struct Movable { PACKED_END } // namespace Game::ECS::Components::_2D -#endif /* !MOVABLE_HPP_ */ +#endif /* !FLAKKARI_MOVABLE_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/2D/Transform.hpp b/Flakkari/Engine/EntityComponentSystem/Components/2D/Transform.hpp index b20458f8..f11e1e4b 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/2D/Transform.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/2D/Transform.hpp @@ -7,8 +7,8 @@ ** Transform */ -#ifndef TRANSFORM_HPP_ -#define TRANSFORM_HPP_ +#ifndef FLAKKARI_TRANSFORM_HPP_ +#define FLAKKARI_TRANSFORM_HPP_ #include "../../../Math/Vector.hpp" @@ -32,4 +32,4 @@ struct Transform { PACKED_END } // namespace Game::ECS::Components::_2D -#endif /* !TRANSFORM_HPP_ */ +#endif /* !FLAKKARI_TRANSFORM_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Child.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Child.hpp index db47b3d2..838b8b1f 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Child.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Child.hpp @@ -7,8 +7,8 @@ ** Child */ -#ifndef CHILD_HPP_ -#define CHILD_HPP_ +#ifndef FLAKKARI_CHILD_HPP_ +#define FLAKKARI_CHILD_HPP_ #include #include @@ -40,4 +40,4 @@ struct Child { PACKED_END } // namespace Flakkari::Engine::ECS::Components::Common -#endif /* !CHILD_HPP_ */ +#endif /* !FLAKKARI_CHILD_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Evolve.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Evolve.hpp index 127073f4..1601db97 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Evolve.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Evolve.hpp @@ -7,8 +7,8 @@ ** Evolve */ -#ifndef EVOLVE_HPP_ -#define EVOLVE_HPP_ +#ifndef FLAKKARI_EVOLVE_HPP_ +#define FLAKKARI_EVOLVE_HPP_ #include #include @@ -40,4 +40,4 @@ struct Evolve { PACKED_END } // namespace Flakkari::Engine::ECS::Components::Common -#endif /* !EVOLVE_HPP_ */ +#endif /* !FLAKKARI_EVOLVE_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp index 57dc684a..c037683c 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Id.hpp @@ -7,8 +7,8 @@ ** Id */ -#ifndef ID_HPP_ -#define ID_HPP_ +#ifndef FLAKKARI_ID_HPP_ +#define FLAKKARI_ID_HPP_ #include @@ -32,4 +32,4 @@ struct Id { PACKED_END } // namespace Engine::ECS::Components::Common -#endif /* !ID_HPP_ */ +#endif /* !FLAKKARI_ID_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Parent.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Parent.hpp index 243dbbf2..9cf92aec 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Parent.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Parent.hpp @@ -7,8 +7,8 @@ ** Parent */ -#ifndef PARENT_HPP_ -#define PARENT_HPP_ +#ifndef FLAKKARI_PARENT_HPP_ +#define FLAKKARI_PARENT_HPP_ #include @@ -36,4 +36,4 @@ struct Parent { PACKED_END } // namespace Flakkari::Engine::ECS::Components::Common -#endif /* !PARENT_HPP_ */ +#endif /* !FLAKKARI_PARENT_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Tag.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Tag.hpp index 6466946e..7f631ad4 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Tag.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Tag.hpp @@ -7,8 +7,8 @@ ** Tag */ -#ifndef TAG_HPP_ -#define TAG_HPP_ +#ifndef FLAKKARI_TAG_HPP_ +#define FLAKKARI_TAG_HPP_ #include #include @@ -39,4 +39,4 @@ struct Tag { PACKED_END } // namespace Game::ECS::Components::Common -#endif /* !TAG_HPP_ */ +#endif /* !FLAKKARI_TAG_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp index 4c14ce93..75a9d5ce 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp @@ -7,8 +7,8 @@ ** Template */ -#ifndef TEMPLATE_HPP_ -#define TEMPLATE_HPP_ +#ifndef FLAKKARI_TEMPLATE_HPP_ +#define FLAKKARI_TEMPLATE_HPP_ #include #include @@ -34,4 +34,4 @@ struct Template { PACKED_END } // namespace Flakkari::Engine::ECS::Components::Common -#endif /* !TEMPLATE_HPP_ */ +#endif /* !FLAKKARI_TEMPLATE_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp index 216a987b..aac18bd8 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp @@ -13,12 +13,12 @@ * @date 2023-01-06 **************************************************************************/ -#ifndef COMPONENTS2D_HPP_ -#define COMPONENTS2D_HPP_ +#ifndef FLAKKARI_COMPONENTS2D_HPP_ +#define FLAKKARI_COMPONENTS2D_HPP_ // #include "2D/Collider.hpp" // Collider component (shape, position, rotation, scale) #include "2D/Control.hpp" // Control component (up, down, left, right, shoot) #include "2D/Movable.hpp" // Movable component (velocity, angularVelocity, acceleration, angularAcceleration) #include "2D/Transform.hpp" // Transform component (position, rotation, scale) -#endif /* !COMPONENTS2D_HPP_ */ +#endif /* !FLAKKARI_COMPONENTS2D_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp b/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp index 6dc3ef99..c31659b8 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp @@ -13,8 +13,8 @@ * @date 2023-01-06 **************************************************************************/ -#ifndef COMPONENTSCOMMON_HPP_ -#define COMPONENTSCOMMON_HPP_ +#ifndef FLAKKARI_COMPONENTSCOMMON_HPP_ +#define FLAKKARI_COMPONENTSCOMMON_HPP_ #include "Common/Child.hpp" // Child component (name) #include "Common/Evolve.hpp" // Evolve component (name) @@ -23,4 +23,4 @@ #include "Common/Tag.hpp" // Tag component (tag) #include "Common/Template.hpp" // Template component (name) -#endif /* !COMPONENTSCOMMON_HPP_ */ +#endif /* !FLAKKARI_COMPONENTSCOMMON_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Entity.hpp b/Flakkari/Engine/EntityComponentSystem/Entity.hpp index d39e583e..ee6c1a7d 100644 --- a/Flakkari/Engine/EntityComponentSystem/Entity.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Entity.hpp @@ -13,8 +13,8 @@ **************************************************************************/ -#ifndef ENTITY_HPP_ - #define ENTITY_HPP_ +#ifndef FLAKKARI_ENTITY_HPP_ + #define FLAKKARI_ENTITY_HPP_ #include #include @@ -42,4 +42,4 @@ class Entity { } // namespace Flakkari::Engine::ECS -#endif /* !ENTITY_HPP_ */ +#endif /* !FLAKKARI_ENTITY_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp b/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp index 06b729c6..5f2ddaa0 100644 --- a/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp +++ b/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp @@ -15,8 +15,8 @@ **************************************************************************/ -#ifndef ENTITYFACTORY_HPP_ - #define ENTITYFACTORY_HPP_ +#ifndef FLAKKARI_ENTITYFACTORY_HPP_ + #define FLAKKARI_ENTITYFACTORY_HPP_ #include @@ -151,4 +151,4 @@ class EntityFactory { } // namespace Flakkari::Engine::ECS -#endif /* !ENTITYFACTORY_HPP_ */ +#endif /* !FLAKKARI_ENTITYFACTORY_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Registry.hpp b/Flakkari/Engine/EntityComponentSystem/Registry.hpp index 5cdd223c..538cbebd 100644 --- a/Flakkari/Engine/EntityComponentSystem/Registry.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Registry.hpp @@ -13,8 +13,8 @@ **************************************************************************/ -#ifndef REGISTRY_HPP_ - #define REGISTRY_HPP_ +#ifndef FLAKKARI_REGISTRY_HPP_ + #define FLAKKARI_REGISTRY_HPP_ #include "SparseArrays.hpp" #include "Entity.hpp" @@ -227,4 +227,4 @@ class Registry { } // namespace Flakkari::Engine::ECS -#endif /* !REGISTRY_HPP_ */ +#endif /* !FLAKKARI_REGISTRY_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/SparseArrays.hpp b/Flakkari/Engine/EntityComponentSystem/SparseArrays.hpp index ff534a8b..b12258c3 100644 --- a/Flakkari/Engine/EntityComponentSystem/SparseArrays.hpp +++ b/Flakkari/Engine/EntityComponentSystem/SparseArrays.hpp @@ -13,8 +13,8 @@ **************************************************************************/ -#ifndef SPARSEARRAYS_HPP_ - #define SPARSEARRAYS_HPP_ +#ifndef FLAKKARI_SPARSEARRAYS_HPP_ + #define FLAKKARI_SPARSEARRAYS_HPP_ #include #include @@ -194,4 +194,4 @@ class SparseArrays { } // namespace Flakkari::Engine::ECS -#endif /* !SPARSEARRAYS_HPP_ */ +#endif /* !FLAKKARI_SPARSEARRAYS_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.hpp b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.hpp index c1fea376..de5945c6 100644 --- a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.hpp @@ -13,8 +13,8 @@ * @date 2023-01-06 **************************************************************************/ -#ifndef SYSTEMS_HPP_ -#define SYSTEMS_HPP_ +#ifndef FLAKKARI_SYSTEMS_HPP_ +#define FLAKKARI_SYSTEMS_HPP_ #include "../Registry.hpp" #include "../Components/Components2D.hpp" @@ -37,4 +37,4 @@ void position(Registry &r, float deltaTime); } // namespace Flakkari::Engine::ECS::Systems -#endif /* !SYSTEMS_HPP_ */ +#endif /* !FLAKKARI_SYSTEMS_HPP_ */ diff --git a/Flakkari/Engine/Math/Vector.hpp b/Flakkari/Engine/Math/Vector.hpp index ebfcb03c..4f5dd54f 100644 --- a/Flakkari/Engine/Math/Vector.hpp +++ b/Flakkari/Engine/Math/Vector.hpp @@ -16,8 +16,8 @@ **************************************************************************/ -#ifndef VECTOR_HPP_ - #define VECTOR_HPP_ +#ifndef FLAKKARI_VECTOR_HPP_ + #define FLAKKARI_VECTOR_HPP_ #include #include @@ -354,4 +354,4 @@ std::ostream &operator<<(std::ostream &os, const Vector &vector); } // namespace Flakkari::Engine::Math -#endif /* !VECTOR_HPP_ */ +#endif /* !FLAKKARI_VECTOR_HPP_ */ diff --git a/Flakkari/Protocol/PacketFactory.hpp b/Flakkari/Protocol/PacketFactory.hpp index abd7ac22..0350202b 100644 --- a/Flakkari/Protocol/PacketFactory.hpp +++ b/Flakkari/Protocol/PacketFactory.hpp @@ -20,7 +20,7 @@ #include "Packet.hpp" -#include "Engine/EntityComponentSystem/Systems/Systems.hpp" +#include "Systems/Systems.hpp" namespace Flakkari::Protocol { From f76adb3a7e66ed28a058daec92c83d28f19c285d Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sat, 13 Jan 2024 23:19:26 +0100 Subject: [PATCH 39/48] fix(Protocol): Update include paths in Header.hpp --- Flakkari/Protocol/Header.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flakkari/Protocol/Header.hpp b/Flakkari/Protocol/Header.hpp index b77331f3..52dcdf76 100644 --- a/Flakkari/Protocol/Header.hpp +++ b/Flakkari/Protocol/Header.hpp @@ -21,8 +21,8 @@ #define PROTOCOL_VERSION 1 -#include "Network/Buffer.hpp" -#include "Network/Packed.hpp" +#include "../Network/Buffer.hpp" +#include "../Network/Packed.hpp" #include "Commands.hpp" #include From 9ddcde3af3c2442ac43cddf4dc29d68e60ec9f13 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sun, 14 Jan 2024 06:08:37 +0100 Subject: [PATCH 40/48] refactor(Protocol): Refactor Flakkari::Protocol::API namespace to Flakkari::Protocol --- CMakeLists.txt | 2 ++ Flakkari/Protocol/Commands.hpp | 7 +++++-- Flakkari/Protocol/Components.hpp | 7 ++++--- Flakkari/Protocol/Header.hpp | 4 ++-- Flakkari/Protocol/Packet.hpp | 12 +++++------ Flakkari/Protocol/PacketFactory.hpp | 26 ++++++++++++------------ Flakkari/Server/Client/Client.hpp | 4 ++-- Flakkari/Server/Client/ClientManager.cpp | 2 +- Flakkari/Server/Game/Game.cpp | 6 +++--- docs/RFC.txt | 8 ++++---- 10 files changed, 42 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b3e01aa..204441ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ set(HEADERS Flakkari/Protocol/Commands.hpp Flakkari/Protocol/Components.hpp + Flakkari/Protocol/Events.hpp Flakkari/Protocol/Header.hpp Flakkari/Protocol/Packet.hpp Flakkari/Protocol/PacketFactory.hpp @@ -86,6 +87,7 @@ set(HEADER_LIB_NETWORK set(HEADER_LIB_PROTOCOL Flakkari/Protocol/Commands.hpp Flakkari/Protocol/Components.hpp + Flakkari/Protocol/Events.hpp Flakkari/Protocol/Header.hpp Flakkari/Protocol/Packet.hpp Flakkari/Protocol/PacketFactory.hpp diff --git a/Flakkari/Protocol/Commands.hpp b/Flakkari/Protocol/Commands.hpp index 9037db5e..6062cbb2 100644 --- a/Flakkari/Protocol/Commands.hpp +++ b/Flakkari/Protocol/Commands.hpp @@ -21,7 +21,7 @@ #include -namespace Flakkari::Protocol::API { +namespace Flakkari::Protocol { inline namespace V_0 { @@ -56,6 +56,8 @@ inline namespace V_0 { REQ_ENTITY_SHOOT = 28, // Server -> Client [Shoot entity]: (id)(component (position, rotation, velocity, etc)) REP_ENTITY_SHOOT = 29, // Client -> Server [Entity shot]: () // 30 - 39: User + REQ_USER_UPDATE = 30, // Client -> Server [Update user]: (event_id, state) + REP_USER_UPDATE = 31, // Server -> Client [User updated]: () // 40 - 49: Chat // 50 - 59: Matchmaking REQ_CREATE_ROOM = 50, // Client -> Server [Create room]: (user_id) @@ -109,10 +111,11 @@ inline namespace V_0 { // 440 - 449: Virtual Currency // 450 - 459: Player Data Management // 460 - 469: Player Item Management + MAX_COMMAND_ID }; } /* namespace V_0 */ -} // namespace Flakkari::Protocol::API +} // namespace Flakkari::Protocol #endif /* !COMMANDS_HPP_ */ diff --git a/Flakkari/Protocol/Components.hpp b/Flakkari/Protocol/Components.hpp index f1cdf4fa..0c7fad4c 100644 --- a/Flakkari/Protocol/Components.hpp +++ b/Flakkari/Protocol/Components.hpp @@ -21,7 +21,7 @@ #include -namespace Flakkari::Protocol::API { +namespace Flakkari::Protocol { inline namespace V_0 { @@ -35,11 +35,12 @@ inline namespace V_0 { PARENT = 11, TAG = 12, ID = 13, - TEMPLATE = 14 + TEMPLATE = 14, + MAX_COMPONENT }; } /* namespace V_0 */ -} // namespace Flakkari::Protocol::API +} // namespace Flakkari::Protocol #endif /* !COMPONENTS_HPP_ */ diff --git a/Flakkari/Protocol/Header.hpp b/Flakkari/Protocol/Header.hpp index 52dcdf76..53a3fb79 100644 --- a/Flakkari/Protocol/Header.hpp +++ b/Flakkari/Protocol/Header.hpp @@ -26,7 +26,7 @@ #include "Commands.hpp" #include -namespace Flakkari::Protocol::API { +namespace Flakkari::Protocol { using byte = byte_t; // 8 bits (max: 255) using ushort = unsigned short; // 16 bits (max: 65535) @@ -74,6 +74,6 @@ inline namespace V_0 { } /* namespace V_1 */ -} // namespace Flakkari::Protocol::API +} // namespace Flakkari::Protocol #endif /* !HEADER_HPP_ */ diff --git a/Flakkari/Protocol/Packet.hpp b/Flakkari/Protocol/Packet.hpp index 30aa61b7..524619c9 100644 --- a/Flakkari/Protocol/Packet.hpp +++ b/Flakkari/Protocol/Packet.hpp @@ -3,12 +3,12 @@ * * Flakkari Library is a C++ Library for Network. * @file Packet.hpp - * @brief Flakkari::Protocol::API::Packet class header. This class is used to + * @brief Flakkari::Protocol::Packet class header. This class is used to * represent a packet. A packet is a header and a payload. - * - The header is a Flakkari::Protocol::API::Header object. + * - The header is a Flakkari::Protocol::Header object. * - The payload is a Flakkari::Network::Buffer object. * - * @see Flakkari::Protocol::API::Header + * @see Flakkari::Protocol::Header * @see Flakkari::Network::Buffer * * Flakkari Library is under MIT License. @@ -25,7 +25,7 @@ #include "Header.hpp" #include "Components.hpp" -namespace Flakkari::Protocol::API { +namespace Flakkari::Protocol { inline namespace V_0 { @@ -176,8 +176,8 @@ inline namespace V_0 { } }; -} /* namespace V_1 */ +} /* namespace V_0 */ -} // namespace Flakkari::Protocol::API +} // namespace Flakkari::Protocol #endif /* !PACKET_HPP_ */ diff --git a/Flakkari/Protocol/PacketFactory.hpp b/Flakkari/Protocol/PacketFactory.hpp index 0350202b..ac872940 100644 --- a/Flakkari/Protocol/PacketFactory.hpp +++ b/Flakkari/Protocol/PacketFactory.hpp @@ -36,13 +36,13 @@ class PacketFactory { */ template static void addCommonsToPacketByEntity ( - Protocol::API::Packet &packet, Engine::ECS::Registry ®istry, Engine::ECS::Entity entity + Protocol::Packet &packet, Engine::ECS::Registry ®istry, Engine::ECS::Entity entity ) { auto child = registry.getComponents(); auto childEntity = child[entity]; if (childEntity.has_value()) { - packet << Protocol::API::ComponentId::CHILD; + packet << Protocol::ComponentId::CHILD; packet << childEntity->size(); packet << childEntity->name; } @@ -51,7 +51,7 @@ class PacketFactory { // auto evolveEntity = evolve[entity]; // if (evolveEntity.has_value()) { - // packet << Protocol::API::ComponentId::EVOLVE; + // packet << Protocol::ComponentId::EVOLVE; // packet << evolveEntity->size(); // packet << evolveEntity->name; // } @@ -60,7 +60,7 @@ class PacketFactory { // auto idEntity = id[entity]; // if (idEntity.has_value()) { - // packet << Protocol::API::ComponentId::ID; + // packet << Protocol::ComponentId::ID; // packet << idEntity->size(); // packet << idEntity->id; // } @@ -69,7 +69,7 @@ class PacketFactory { auto parentEntity = parent[entity]; if (parentEntity.has_value()) { - packet << Protocol::API::ComponentId::PARENT; + packet << Protocol::ComponentId::PARENT; packet << parentEntity->size(); packet << parentEntity->entity; } @@ -78,7 +78,7 @@ class PacketFactory { auto tagEntity = tag[entity]; if (tagEntity.has_value()) { - packet << Protocol::API::ComponentId::TAG; + packet << Protocol::ComponentId::TAG; packet << tagEntity->size(); packet << tagEntity->tag; } @@ -87,7 +87,7 @@ class PacketFactory { auto nameEntity = name[entity]; if (nameEntity.has_value()) { - packet << Protocol::API::ComponentId::TEMPLATE; + packet << Protocol::ComponentId::TEMPLATE; packet << nameEntity->size(); packet << nameEntity->name; } @@ -103,13 +103,13 @@ class PacketFactory { */ template static void add2dToPacketByEntity ( - Protocol::API::Packet &packet, Engine::ECS::Registry ®istry, Engine::ECS::Entity entity + Protocol::Packet &packet, Engine::ECS::Registry ®istry, Engine::ECS::Entity entity ) { auto transform = registry.getComponents(); auto pos = transform[entity]; if (pos.has_value()) { - packet << Protocol::API::ComponentId::TRANSFORM; + packet << Protocol::ComponentId::TRANSFORM; packet << pos->size(); packet << pos->position.x; packet << pos->position.y; @@ -122,7 +122,7 @@ class PacketFactory { auto vel = movable[entity]; if (vel.has_value()) { - packet << Protocol::API::ComponentId::MOVABLE; + packet << Protocol::ComponentId::MOVABLE; packet << vel->size(); packet << vel->velocity.x; packet << vel->velocity.y; @@ -134,7 +134,7 @@ class PacketFactory { auto ctrl = control[entity]; if (ctrl.has_value()) { - packet << Protocol::API::ComponentId::CONTROL; + packet << Protocol::ComponentId::CONTROL; packet << ctrl->size(); packet << ctrl->up; packet << ctrl->down; @@ -154,7 +154,7 @@ class PacketFactory { */ template static void addComponentsToPacketByEntity ( - Protocol::API::Packet &packet, Engine::ECS::Registry ®istry, Engine::ECS::Entity entity + Protocol::Packet &packet, Engine::ECS::Registry ®istry, Engine::ECS::Entity entity ) { /*_ Common Components _*/ @@ -175,7 +175,7 @@ class PacketFactory { */ template static void addInfoToPacket ( - Protocol::API::Packet &packet, std::size_t size, + Protocol::Packet &packet, std::size_t size, const std::string &sceneName, Engine::ECS::Entity entity ) { packet << size; diff --git a/Flakkari/Server/Client/Client.hpp b/Flakkari/Server/Client/Client.hpp index da7c39bf..9e7f4237 100644 --- a/Flakkari/Server/Client/Client.hpp +++ b/Flakkari/Server/Client/Client.hpp @@ -117,8 +117,8 @@ class Client { unsigned short _maxPacketHistory = 10; public: std::vector _packetHistory; - Network::PacketQueue> _sendQueue; - Network::PacketQueue> _receiveQueue; + Network::PacketQueue> _sendQueue; + Network::PacketQueue> _receiveQueue; }; } /* namespace Flakkari */ diff --git a/Flakkari/Server/Client/ClientManager.cpp b/Flakkari/Server/Client/ClientManager.cpp index 53590390..abab8477 100644 --- a/Flakkari/Server/Client/ClientManager.cpp +++ b/Flakkari/Server/Client/ClientManager.cpp @@ -149,7 +149,7 @@ void ClientManager::receivePacketFromClient ( return; auto &tmp_client = clients[clientKey]; - Protocol::API::Packet packet; + Protocol::Packet packet; if (packet.deserialize(buffer)) { FLAKKARI_LOG_LOG("Client " + clientName + " sent a valid packet: " + packet.to_string()); tmp_client->_receiveQueue.push_back(packet); diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index 8a59775a..db92067b 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -116,8 +116,8 @@ void Game::checkDisconnect() for (auto &player : _players) { if (!player || player->isConnected()) continue; - Protocol::API::Packet packet; - packet.header._commandId = Protocol::API::CommandId::REQ_ENTITY_DESTROY; + Protocol::Packet packet; + packet.header._commandId = Protocol::CommandId::REQ_ENTITY_DESTROY; packet << player->getSceneName().size(); packet << player->getSceneName().c_str(); packet << player->getEntity(); @@ -138,7 +138,7 @@ void Game::updateIncomingPackets(unsigned char maxMessagePerFrame) auto messageCount = maxMessagePerFrame; while (!packets.empty() && messageCount > 0) { - Protocol::API::Packet p; + Protocol::Packet p; auto packet = packets.pop_front(); FLAKKARI_LOG_INFO("packet received: " + packet.to_string()); messageCount--; diff --git a/docs/RFC.txt b/docs/RFC.txt index 7bf21649..c1edddba 100644 --- a/docs/RFC.txt +++ b/docs/RFC.txt @@ -220,7 +220,7 @@ Table of Contents 3.1 Header Structure - The header structure is defined by the Flakkari::Protocol::API::Header struct + The header structure is defined by the Flakkari::Protocol::Header struct and consists of the following fields: _priority: 4 bits - Represents the priority of the message in the queue @@ -272,9 +272,9 @@ Table of Contents '''cpp - Flakkari::Protocol::API::Header header( - Flakkari::Protocol::API::Priority::LOW, - Flakkari::Protocol::API::ApiVersion::V_1, + Flakkari::Protocol::Header header( + Flakkari::Protocol::Priority::LOW, + Flakkari::Protocol::ApiVersion::V_1, 1, 0 ); From 9c2c0b8c1e597c92dc42f2b3c71dfe29c907f7e5 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sun, 14 Jan 2024 06:08:56 +0100 Subject: [PATCH 41/48] feat(Protocol): Add Events.hpp to Flakkari/Protocol directory --- Flakkari/Protocol/Events.hpp | 47 ++++++++++++++++++++++++++++++++++++ Flakkari/Protocol/Packet.hpp | 1 + 2 files changed, 48 insertions(+) create mode 100644 Flakkari/Protocol/Events.hpp diff --git a/Flakkari/Protocol/Events.hpp b/Flakkari/Protocol/Events.hpp new file mode 100644 index 00000000..eaa2dff0 --- /dev/null +++ b/Flakkari/Protocol/Events.hpp @@ -0,0 +1,47 @@ +/************************************************************************** + * Flakkari Library v0.2.0 + * + * Flakkari Library is a C++ Library for Network. + * @file Events.hpp + * @brief This file contains the EventId enum class. It is used to identify + * the events in the Flakkari Protocol. It is used to send an event + * from the client to the server. + * + * Flakkari Library is under MIT License. + * https://opensource.org/licenses/MIT + * © 2023 @MasterLaplace + * @version 0.2.0 + * @date 2024-01-14 + **************************************************************************/ + + +#ifndef EVENTS_HPP_ + #define EVENTS_HPP_ + +#include + +namespace Flakkari::Protocol { + +inline namespace V_0 { + + enum class EventId : uint8_t { + MOVE_LEFT = 10, + MOVE_RIGHT = 11, + MOVE_UP = 12, + MOVE_DOWN = 13, + SHOOT = 14, + MAX_EVENT + }; + + enum class EventState : uint8_t { + NONE = 0, + PRESSED = 1, + RELEASED = 2, + MAX_STATE + }; + +} /* namespace V_0 */ + +} // namespace Flakkari::Protocol + +#endif /* !EVENTS_HPP_ */ diff --git a/Flakkari/Protocol/Packet.hpp b/Flakkari/Protocol/Packet.hpp index 524619c9..cae6844c 100644 --- a/Flakkari/Protocol/Packet.hpp +++ b/Flakkari/Protocol/Packet.hpp @@ -24,6 +24,7 @@ #include "Header.hpp" #include "Components.hpp" +#include "Events.hpp" namespace Flakkari::Protocol { From 8b32f77b5fa7ee90c60bb8da947d0e2090710e5d Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sun, 14 Jan 2024 07:56:07 +0100 Subject: [PATCH 42/48] update(Game): Add asynchronous start of game instance --- Flakkari/Server/Game/GameManager.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Flakkari/Server/Game/GameManager.cpp b/Flakkari/Server/Game/GameManager.cpp index 95042c5c..3ddba054 100644 --- a/Flakkari/Server/Game/GameManager.cpp +++ b/Flakkari/Server/Game/GameManager.cpp @@ -10,6 +10,8 @@ #include "GameManager.hpp" #include "../Client/Client.hpp" +#include + namespace Flakkari { std::shared_ptr GameManager::_instance = nullptr; @@ -156,9 +158,9 @@ void GameManager::addClientToGame(std::string gameName, std::shared_ptr if (gameInstance.back()->addPlayer(client)) { if (lobby == "Matchmaking" && gameInstance.back()->getPlayers().size() >= minPlayers && !gameInstance.back()->isRunning()) - gameInstance.back()->start(); + (void)std::async(std::launch::async, &Game::start, gameInstance.back()); if (lobby == "OpenWorld" && !gameInstance.back()->isRunning()) - gameInstance.back()->start(); + (void)std::async(std::launch::async, &Game::start, gameInstance.back()); return; } FLAKKARI_LOG_ERROR("could not add client \""+ STR_ADDRESS +"\" to game \"" + gameName + "\""); From ce6d10b9ff1ab7deb8c6c54bf5582e3be246a831 Mon Sep 17 00:00:00 2001 From: Master_Laplace Date: Sun, 14 Jan 2024 08:09:31 +0100 Subject: [PATCH 43/48] update(Flakkari): Update main function to accept command line arguments --- Flakkari/core.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Flakkari/core.cpp b/Flakkari/core.cpp index 4edaa243..f6c40dc1 100644 --- a/Flakkari/core.cpp +++ b/Flakkari/core.cpp @@ -7,14 +7,18 @@ #include "Server/UDPServer.hpp" -int main() +int main(int ac, const char *av[]) { + if (ac != 2) + return FLAKKARI_LOG_FATAL("Usage: ./r-type_server "), 84; try { - Flakkari::UDPServer server("localhost", 8080); + Flakkari::UDPServer server(av[1], 8080); server.run(); } catch (const std::exception &e) { if (std::string(e.what()) != "exit") return FLAKKARI_LOG_FATAL(e.what()), 84; + } catch (...) { + return FLAKKARI_LOG_FATAL("Unknown error"), 84; } return 0; } From d045fe3af01390d1f8c81da27af967c10cb5a99a Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sun, 14 Jan 2024 17:30:31 +0100 Subject: [PATCH 44/48] feat(Components): Add new components: NetworkEvent, Collider, and Spawned --- .../Components/2D/Collider.hpp | 41 +++++++++++++ .../Components/2D/RigidBody.hpp | 44 ++++++++++++++ .../Components/Common/Health.hpp | 43 ++++++++++++++ .../Components/Common/Level.hpp | 51 ++++++++++++++++ .../Components/Common/NetworkEvent.hpp | 31 ++++++++++ .../Components/Common/Spawned.hpp | 41 +++++++++++++ .../Components/Common/Weapon.hpp | 55 +++++++++++++++++ .../Components/Components2D.hpp | 5 +- .../Components/ComponentsCommon.hpp | 9 ++- .../EntityComponentSystem/EntityFactory.hpp | 59 +++++++++++++++++++ 10 files changed, 376 insertions(+), 3 deletions(-) create mode 100644 Flakkari/Engine/EntityComponentSystem/Components/2D/Collider.hpp create mode 100644 Flakkari/Engine/EntityComponentSystem/Components/2D/RigidBody.hpp create mode 100644 Flakkari/Engine/EntityComponentSystem/Components/Common/Health.hpp create mode 100644 Flakkari/Engine/EntityComponentSystem/Components/Common/Level.hpp create mode 100644 Flakkari/Engine/EntityComponentSystem/Components/Common/NetworkEvent.hpp create mode 100644 Flakkari/Engine/EntityComponentSystem/Components/Common/Spawned.hpp create mode 100644 Flakkari/Engine/EntityComponentSystem/Components/Common/Weapon.hpp diff --git a/Flakkari/Engine/EntityComponentSystem/Components/2D/Collider.hpp b/Flakkari/Engine/EntityComponentSystem/Components/2D/Collider.hpp new file mode 100644 index 00000000..1910b406 --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Components/2D/Collider.hpp @@ -0,0 +1,41 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2023-01-14 +** File description: +** Collider +*/ + +#ifndef COLLIDER_HPP_ +#define COLLIDER_HPP_ + +#include +#include "../../../Math/Vector.hpp" + +#include "Network/Packed.hpp" + +namespace Flakkari::Engine::ECS::Components::_2D { +PACKED_START + +/** + * @brief Collider component for ECS entities that have a script attached to them + * + * @details This component is used to store the path to the script that will be executed + */ +struct Collider { + Math::Vector2f _size; + + Collider() : _size() {} + Collider(Math::Vector2f nsize) : _size(nsize) {} + Collider(const Collider &other) : _size(other._size) {} + + std::size_t size() const { + return sizeof(_size); + } +}; + +PACKED_END +} // namespace Flakkari::Engine::ECS::Components::_2D + +#endif /* !COLLIDER_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/2D/RigidBody.hpp b/Flakkari/Engine/EntityComponentSystem/Components/2D/RigidBody.hpp new file mode 100644 index 00000000..c050db8b --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Components/2D/RigidBody.hpp @@ -0,0 +1,44 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2023-01-14 +** File description: +** RigidBody +*/ + +#ifndef RIGIDBODY_HPP_ +#define RIGIDBODY_HPP_ + +#include "../../../Math/Vector.hpp" + +#include "Network/Packed.hpp" + +namespace Flakkari::Engine::ECS::Components::_2D { +PACKED_START + +/** + * @brief RigidBody represent the physical properties of a rigid body in a game engine + * + */ +struct RigidBody { + float mass; + float restitution; + float friction; + float gravityScale; + bool isGravityAffected = true; + bool isKinematic = false; + + RigidBody() : mass(0), restitution(0), friction(0), gravityScale(0), isGravityAffected(false), isKinematic(false) {}; + RigidBody(const RigidBody &other) : mass(other.mass), restitution(other.restitution), friction(other.friction), gravityScale(other.gravityScale), isGravityAffected(other.isGravityAffected), isKinematic(other.isKinematic) {}; + RigidBody(float mass, float restitution, float friction, float gravityScale) : mass(mass), restitution(restitution), friction(friction), gravityScale(gravityScale), isGravityAffected(true), isKinematic(false) {}; + + std::size_t size() const { + return sizeof(*this); + } +}; + +PACKED_END +} // namespace Flakkari::Engine::ECS::Components::_2D + +#endif /* !RIGIDBODY_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Health.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Health.hpp new file mode 100644 index 00000000..148f69a9 --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Health.hpp @@ -0,0 +1,43 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2023-01-14 +** File description: +** Health +*/ + +#ifndef Health_HPP_ +#define Health_HPP_ + +#include + +#include "Network/Packed.hpp" + +namespace Flakkari::Engine::ECS::Components::Common { +PACKED_START + +/** + * @brief Health is a structure that represents the life of an "living object" + * + */ +struct Health { + unsigned int currentHealth; + unsigned int maxHealth = 100; + unsigned int shield = 0; + unsigned int maxShield = 100; + + Health() : currentHealth(100), maxHealth(100), shield(0), maxShield(100) {}; + Health(unsigned int currentHealth, unsigned int maxHealth, unsigned int shield, unsigned int maxShield) : + currentHealth(currentHealth), maxHealth(maxHealth), shield(shield), maxShield(maxShield) {}; + Health(const Health &other) : currentHealth(other.currentHealth), maxHealth(other.maxHealth), shield(other.shield), maxShield(other.maxShield) {}; + + unsigned int size() const { + return sizeof(*this); + } +}; + +PACKED_END +} // namespace Flakkari::Engine::ECS::Components::Common + +#endif /* !Health_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Level.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Level.hpp new file mode 100644 index 00000000..150feae1 --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Level.hpp @@ -0,0 +1,51 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2023-01-14 +** File description: +** Level +*/ + +#ifndef LEVEL_HPP +#define LEVEL_HPP + +#include +#include + +#include "Network/Packed.hpp" + +namespace Flakkari::Engine::ECS::Components::Common { +PACKED_START + +/** + * @brief FontInfo is a structure that holds information about a Font + * + */ +struct Level { + unsigned int level; + const char *currentWeapon; + unsigned int currentExp; + unsigned int requiredExp; + + Level() : level(1), currentWeapon(""), currentExp(0), requiredExp(100) {} + Level(unsigned int level, std::string currentWeapon, unsigned int currentExp, unsigned int requiredExp) + : level(level), + currentWeapon(currentWeapon.c_str()), + currentExp(currentExp), + requiredExp(requiredExp) {} + Level(const Level &other) + : level(other.level), + currentWeapon(other.currentWeapon), + currentExp(other.currentExp), + requiredExp(other.requiredExp) {} + + std::size_t size() const { + return sizeof(level) + std::strlen(currentWeapon) + sizeof(currentExp) + sizeof(requiredExp); + } +}; + +PACKED_END +} // namespace Flakkari::Engine::ECS::Components::Common + +#endif //LEVEL_HPP diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/NetworkEvent.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/NetworkEvent.hpp new file mode 100644 index 00000000..2a19a5f7 --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/NetworkEvent.hpp @@ -0,0 +1,31 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2023-01-14 +** File description: +** NetworkEvent +*/ + +#ifndef NETWORKEVENT_HPP_ +#define NETWORKEVENT_HPP_ + +#include + +namespace Flakkari::Engine::ECS::Components::Common { + + struct NetworkEvent { + std::vector events; + + NetworkEvent() = default; + NetworkEvent(const NetworkEvent &other) : events(other.events) {}; + NetworkEvent(const std::vector &events) : events(events) {}; + + std::size_t size() const { + return events.size() * sizeof(unsigned short); + } + }; + +} /* namespace Flakkari::Engine::ECS::Components::Common */ + +#endif /* !NETWORKEVENT_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Spawned.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Spawned.hpp new file mode 100644 index 00000000..3fc4fdf9 --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Spawned.hpp @@ -0,0 +1,41 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2023-01-14 +** File description: +** Spawned +*/ + +#ifndef SPAWNED_HPP_ +#define SPAWNED_HPP_ + +#include +#include + +#include "Network/Packed.hpp" + +namespace Flakkari::Engine::ECS::Components::Common { +PACKED_START + +/** + * @brief Spawned component for ECS entities that have a script attached to them + * + * @details This component is used to store the path to the script that will be executed + */ +struct Spawned { + bool has_spawned; + + Spawned() : has_spawned(false) {} + Spawned(bool spawed) : has_spawned(spawed) {} + Spawned(const Spawned &other) : has_spawned(other.has_spawned) {} + + std::size_t size() const { + return sizeof(has_spawned); + } +}; + +PACKED_END +} // namespace Flakkari::Engine::ECS::Components::Common + +#endif /* !SPAWNED_HPP_ */ \ No newline at end of file diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Weapon.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Weapon.hpp new file mode 100644 index 00000000..ffef650e --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Weapon.hpp @@ -0,0 +1,55 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2023-01-14 +** File description: +** Weapon +*/ + +#ifndef WEAPON_HPP_ +#define WEAPON_HPP_ + +#include +#include + +#include "Network/Packed.hpp" + +namespace Flakkari::Engine::ECS::Components::Common { +PACKED_START + +/** + * @brief Weapon is a structure that defines the characteristics of a weapon. + * + * @details + * The Weapon structure is used to define the characteristics of a weapon. + * It is used by the WeaponComponent to handle the firing and reloading logic. + * + * @param + * damage: The amount of damage dealt by the weapon. + * fireRate: The rate of fire, shots per second. + * currentAmmo: Current ammunition in the magazine. + * reloadTime: Time it takes to reload the weapon in seconds. + * timeSinceLastShot: Time elapsed since the last shot was fired. + * isReloading: Is the weapon currently reloading. + * maxAmmo: Maximum ammunition the weapon can hold. + */ +struct Weapon { + unsigned int damage; + float fireRate; + unsigned int level; + + Weapon() = default; + Weapon(const Weapon &other) = default; + Weapon(unsigned int dmg, float rate, unsigned int lvl) + : damage(dmg), fireRate(rate), level(lvl){}; + + unsigned int size() const { + return sizeof(*this); + }; +}; + +PACKED_END +} // namespace Flakkari::Engine::ECS::Components::Common + +#endif /* !WEAPON_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp index aac18bd8..499002c3 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Components2D.hpp @@ -4,7 +4,7 @@ * Flakkari Library is a C++ Library for Network. * @file Components2D.hpp * @brief Components2D header. Contains all 2D components. - * (Collider, Movable, RigidBody, Transform) + * (Collider, Control, Movable, RigidBody, Transform) * * Flakkari Library is under MIT License. * https://opensource.org/licenses/MIT @@ -16,9 +16,10 @@ #ifndef FLAKKARI_COMPONENTS2D_HPP_ #define FLAKKARI_COMPONENTS2D_HPP_ -// #include "2D/Collider.hpp" // Collider component (shape, position, rotation, scale) +#include "2D/Collider.hpp" // Collider component (size) #include "2D/Control.hpp" // Control component (up, down, left, right, shoot) #include "2D/Movable.hpp" // Movable component (velocity, angularVelocity, acceleration, angularAcceleration) +#include "2D/RigidBody.hpp" // RigidBody component (mass, inertia, restitution, friction) #include "2D/Transform.hpp" // Transform component (position, rotation, scale) #endif /* !FLAKKARI_COMPONENTS2D_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp b/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp index c31659b8..b1f8d809 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp @@ -4,7 +4,8 @@ * Flakkari Library is a C++ Library for Network. * @file ComponentsCommon.hpp * @brief ComponentsCommon header. Contains all common components. - * (Parent, Tag) + * (Parent, Tag, Id, Template, Child, Evolve, Health, Level, + * Script, Spawned, Weapon) * * Flakkari Library is under MIT License. * https://opensource.org/licenses/MIT @@ -18,9 +19,15 @@ #include "Common/Child.hpp" // Child component (name) #include "Common/Evolve.hpp" // Evolve component (name) +#include "Common/Health.hpp" // Health component (health) #include "Common/Id.hpp" // Id component (id) +#include "Common/Level.hpp" // Level component (level) #include "Common/Parent.hpp" // Parent component (entity) +#include "Common/Spawned.hpp" // Spawned component (spawned) #include "Common/Tag.hpp" // Tag component (tag) #include "Common/Template.hpp" // Template component (name) +#include "Common/Weapon.hpp" // Weapon component (name) + +#include "Common/NetworkEvent.hpp" // NetworkEvent component (event) #endif /* !FLAKKARI_COMPONENTSCOMMON_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp b/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp index 5f2ddaa0..25a05bb5 100644 --- a/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp +++ b/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp @@ -77,6 +77,14 @@ class EntityFactory { //*_ 2D Components _*// + if (componentName == "Collider") { + registry.registerComponent(); + Engine::ECS::Components::_2D::Collider collider; + collider._size = Engine::Math::Vector2f(componentContent["size"]["x"], componentContent["size"]["y"]); + registry.add_component(entity, std::move(collider)); + continue; + } + if (componentName == "Control") { registry.registerComponent(); Engine::ECS::Components::_2D::Control control; @@ -98,6 +106,19 @@ class EntityFactory { continue; } + if (componentName == "RigidBody") { + registry.registerComponent(); + Engine::ECS::Components::_2D::RigidBody rigidBody; + rigidBody.mass = componentContent["mass"]; + rigidBody.restitution = componentContent["restitution"]; + rigidBody.friction = componentContent["friction"]; + rigidBody.gravityScale = componentContent["gravityScale"]; + rigidBody.isGravityAffected = componentContent["isGravityAffected"]; + rigidBody.isKinematic = componentContent["isKinematic"]; + registry.add_component(entity, std::move(rigidBody)); + continue; + } + if (componentName == "Transform") { registry.registerComponent(); Engine::ECS::Components::_2D::Transform transform; @@ -124,6 +145,17 @@ class EntityFactory { continue; } + if (componentName == "Health") { + registry.registerComponent(); + Engine::ECS::Components::Common::Health health; + health.maxHealth = componentContent["maxHealth"]; + health.currentHealth = componentContent["currentHealth"]; + health.maxShield = componentContent["maxShield"]; + health.shield = componentContent["shield"]; + registry.add_component(entity, std::move(health)); + continue; + } + if (componentName == "Parent") { registry.registerComponent(); Engine::ECS::Components::Common::Parent parent(componentContent["entity"]); @@ -131,6 +163,23 @@ class EntityFactory { continue; } + if (componentName == "Level") { + registry.registerComponent(); + Engine::ECS::Components::Common::Level level; + level.level = componentContent["level"]; + level.currentExp = componentContent["currentExp"]; + level.requiredExp = componentContent["requiredExp"]; + level.currentWeapon = componentContent["currentWeapon"].get().c_str(); + registry.add_component(entity, std::move(level)); + continue; + } + + if (componentName == "Spawned") { + registry.registerComponent(); + Engine::ECS::Components::Common::Spawned spawned(componentContent["has_spawned"]); + registry.add_component(entity, std::move(spawned)); + continue; + } if (componentName == "Tag") { registry.registerComponent(); @@ -145,6 +194,16 @@ class EntityFactory { registry.add_component(entity, std::move(template_)); continue; } + + if (componentName == "Weapon") { + registry.registerComponent(); + Engine::ECS::Components::Common::Weapon weapon; + weapon.damage = componentContent["damage"]; + weapon.fireRate = componentContent["fireRate"]; + weapon.level = componentContent["level"]; + registry.add_component(entity, std::move(weapon)); + continue; + } } } }; From 3e127c1bd067b5f459da5f7c9e614ca439204fbf Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sun, 14 Jan 2024 17:32:54 +0100 Subject: [PATCH 45/48] feat(Flakkari): Add game name to Client constructor and handle event from player --- .../EntityComponentSystem/Systems/Systems.cpp | 39 ++++++ Flakkari/Protocol/Events.hpp | 21 +++ Flakkari/Protocol/Packet.hpp | 37 +++--- Flakkari/Protocol/PacketFactory.hpp | 26 +++- Flakkari/Server/Client/Client.cpp | 4 +- Flakkari/Server/Client/Client.hpp | 7 +- Flakkari/Server/Client/ClientManager.cpp | 36 ++++-- Flakkari/Server/Client/ClientManager.hpp | 3 +- Flakkari/Server/Game/Game.cpp | 121 +++++++++++++++++- Flakkari/Server/Game/Game.hpp | 21 +++ Flakkari/Server/UDPServer.cpp | 3 +- 11 files changed, 281 insertions(+), 37 deletions(-) diff --git a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp index b760e848..7deb068c 100644 --- a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp +++ b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp @@ -8,6 +8,7 @@ */ #include "Systems.hpp" +#include "Protocol/Events.hpp" namespace Flakkari::Engine::ECS::Systems { @@ -31,4 +32,42 @@ void position(Registry &r, float deltaTime) } } +void update_control(Registry &r) +{ + if (!r.isRegistered() || !r.isRegistered() + || !r.isRegistered()) + return; + auto& positions = r.getComponents(); + auto& velocities = r.getComponents(); + auto& networkEvent = r.getComponents(); + + for (Entity i(0); i < velocities.size() && i < positions.size(); ++i) { + auto& pos = positions[i]; + auto& vel = velocities[i]; + auto& net = networkEvent[i]; + + if (!net.has_value() || !vel.has_value()) + continue; + if (net->events.size() < int(Protocol::EventId::MOVE_UP)) + continue; + if (net->events[int(Protocol::EventId::MOVE_UP)] == int(Protocol::EventState::PRESSED)) + vel->velocity.dy = -1; + + if (net->events.size() < int(Protocol::EventId::MOVE_DOWN)) + continue; + if (net->events[int(Protocol::EventId::MOVE_DOWN)] == int(Protocol::EventState::PRESSED)) + vel->velocity.dy = 1; + + if (net->events.size() < int(Protocol::EventId::MOVE_LEFT)) + continue; + if (net->events[int(Protocol::EventId::MOVE_LEFT)] == int(Protocol::EventState::PRESSED)) + vel->velocity.dx = -1; + + if (net->events.size() < int(Protocol::EventId::MOVE_RIGHT)) + continue; + if (net->events[int(Protocol::EventId::MOVE_RIGHT)] == int(Protocol::EventState::PRESSED)) + vel->velocity.dx = 1; + } +} + } // namespace Flakkari::Engine::ECS::Systems diff --git a/Flakkari/Protocol/Events.hpp b/Flakkari/Protocol/Events.hpp index eaa2dff0..bca4c937 100644 --- a/Flakkari/Protocol/Events.hpp +++ b/Flakkari/Protocol/Events.hpp @@ -20,6 +20,8 @@ #include +#include "../Network/Packed.hpp" + namespace Flakkari::Protocol { inline namespace V_0 { @@ -40,6 +42,25 @@ inline namespace V_0 { MAX_STATE }; + PACKED_START + + struct Event { + EventId id; + EventState state; + + friend std::ostream& operator<<(std::ostream& os, const Event& event) { + os << "Event"; + return os; + } + + std::string to_string() { + std::string str = "Event"; + return str; + } + }; + + PACKED_END + } /* namespace V_0 */ } // namespace Flakkari::Protocol diff --git a/Flakkari/Protocol/Packet.hpp b/Flakkari/Protocol/Packet.hpp index cae6844c..0353697c 100644 --- a/Flakkari/Protocol/Packet.hpp +++ b/Flakkari/Protocol/Packet.hpp @@ -55,7 +55,7 @@ inline namespace V_0 { + ", SequenceNumber: " + std::to_string(int(header._sequenceNumber)) + ", Payload: " - + std::string(payload) + + std::string((const char*)payload.data(), payload.size()) + ">"; return str; } @@ -119,26 +119,25 @@ inline namespace V_0 { return packet; } - /** - * @brief Add data to the packet. - * - * @tparam DataType Type of the data to add. - * @param packet The packet to add the data to. - * @param data The data to add. - * @return Packet& The packet with the data added. - */ - template - friend Packet& operator>>(Packet& packet, std::vector& data) + void injectString(std::string str) { - static_assert(std::is_trivially_copyable::value, "DataType must be trivially copyable to be used in a packet."); - static_assert(std::is_standard_layout::value, "DataType must be standard layout to be used in a packet."); + int intValue = (int)str.size(); + const byte* dataBytes = reinterpret_cast(&intValue); + payload.insert(payload.end(), dataBytes, dataBytes + sizeof(intValue)); + payload += str; + header._contentLength += payload.size() + sizeof(intValue); + } - std::size_t size = packet.payload.size() - sizeof(DataType) * data.size(); - data.resize(packet.payload.size() / sizeof(DataType)); - std::memcpy(data.data(), packet.payload.data() + size, sizeof(DataType) * data.size()); - packet.payload.resize(size); - packet.header._contentLength = packet.payload.size(); - return packet; + std::string extractString() + { + std::string str; + int intValue; + std::memcpy(&intValue, payload.data(), sizeof(intValue)); + payload.erase(payload.begin(), payload.begin() + sizeof(intValue)); + str = std::string((const char*)payload.data(), intValue); + payload.erase(payload.begin(), payload.begin() + intValue); + header._contentLength -= sizeof(intValue) + intValue; + return str; } /** diff --git a/Flakkari/Protocol/PacketFactory.hpp b/Flakkari/Protocol/PacketFactory.hpp index ac872940..ce911734 100644 --- a/Flakkari/Protocol/PacketFactory.hpp +++ b/Flakkari/Protocol/PacketFactory.hpp @@ -20,7 +20,7 @@ #include "Packet.hpp" -#include "Systems/Systems.hpp" +#include "Engine/EntityComponentSystem/Systems/Systems.hpp" namespace Flakkari::Protocol { @@ -182,6 +182,30 @@ class PacketFactory { packet << sceneName.c_str(); packet << entity; } + + struct UpdateMovement { + Engine::ECS::Entity entity; + Engine::ECS::Components::_2D::Transform pos; + Engine::ECS::Components::_2D::Movable vel; + }; + + template + static void addUpdateMovementToPacket ( + Protocol::Packet &packet, Engine::ECS::Entity entity, + Engine::ECS::Components::_2D::Transform pos, + Engine::ECS::Components::_2D::Movable vel + ) { + packet << entity; + packet << pos.position.x; + packet << pos.position.y; + packet << pos.rotation; + packet << pos.scale.x; + packet << pos.scale.y; + packet << vel.velocity.x; + packet << vel.velocity.y; + packet << vel.acceleration.x; + packet << vel.acceleration.y; + } }; } // namespace Flakkari::Protocol diff --git a/Flakkari/Server/Client/Client.cpp b/Flakkari/Server/Client/Client.cpp index af05631a..f4376ec6 100644 --- a/Flakkari/Server/Client/Client.cpp +++ b/Flakkari/Server/Client/Client.cpp @@ -11,8 +11,8 @@ namespace Flakkari { -Client::Client(std::shared_ptr address) - : _address(address) +Client::Client(std::shared_ptr address, std::string name) + : _address(address), _gameName(name) { _lastActivity = std::chrono::steady_clock::now(); } diff --git a/Flakkari/Server/Client/Client.hpp b/Flakkari/Server/Client/Client.hpp index 9e7f4237..fa705dac 100644 --- a/Flakkari/Server/Client/Client.hpp +++ b/Flakkari/Server/Client/Client.hpp @@ -45,8 +45,9 @@ class Client { * @brief Construct a new Client object * * @param address The client's address + * @param name The Game's name */ - Client(std::shared_ptr address); + Client(std::shared_ptr address, std::string name); ~Client(); /** @@ -99,6 +100,9 @@ class Client { [[nodiscard]] std::string getSceneName() const { return _sceneName; } void setSceneName(std::string sceneName) { _sceneName = sceneName; } + [[nodiscard]] std::string getGameName() const { return _gameName; } + void setGameName(std::string gameName) { _gameName = gameName; } + [[nodiscard]] unsigned short getWarningCount() const { return _warningCount; } [[nodiscard]] unsigned short getMaxWarningCount() const { return _maxWarningCount; } @@ -111,6 +115,7 @@ class Client { std::shared_ptr _address; Engine::ECS::Entity _entity; std::string _sceneName; + std::string _gameName; bool _isConnected = true; unsigned short _warningCount = 0; unsigned short _maxWarningCount = 5; diff --git a/Flakkari/Server/Client/ClientManager.cpp b/Flakkari/Server/Client/ClientManager.cpp index abab8477..da6fca1b 100644 --- a/Flakkari/Server/Client/ClientManager.cpp +++ b/Flakkari/Server/Client/ClientManager.cpp @@ -28,7 +28,7 @@ void ClientManager::setSocket(std::shared_ptr socket) { getInstance()->_socket = socket; } -void ClientManager::addClient(std::shared_ptr client) +void ClientManager::addClient(std::shared_ptr client, Network::Buffer &buffer) { auto &clients = getInstance()->_clients; @@ -40,9 +40,22 @@ void ClientManager::addClient(std::shared_ptr client) if (clients.find(client->toString().value_or("")) != clients.end()) return clients[client->toString().value_or("")]->keepAlive(), void(); - clients[client->toString().value_or("")] = std::make_shared(client); - FLAKKARI_LOG_LOG("Client " + client->toString().value_or("Unknown") + " connected"); - GameManager::addClientToGame("R-Type", clients[client->toString().value_or("")]); + Protocol::Packet packet; + if (!packet.deserialize(buffer)) { + FLAKKARI_LOG_WARNING("Client " + client->toString().value_or("Unknown") + " sent an invalid packet"); + return; + } + + if (packet.header._commandId != Protocol::CommandId::REQ_CONNECT) { + FLAKKARI_LOG_WARNING("Client " + client->toString().value_or("Unknown") + " sent an invalid packet"); + return; + } + + std::string name = packet.extractString(); + clients[client->toString().value_or("")] = std::make_shared(client, name); + + FLAKKARI_LOG_LOG("Client " + client->toString().value_or("Unknown") + " connected"); + GameManager::addClientToGame(name, clients[client->toString().value_or("")]); } void ClientManager::removeClient(std::shared_ptr client) @@ -52,7 +65,9 @@ void ClientManager::removeClient(std::shared_ptr client) if (clients.find(client->toString().value_or("")) == clients.end()) return; - GameManager::removeClientFromGame("R-Type", clients[client->toString().value_or("")]); + auto _client = clients[client->toString().value_or("")]; + + GameManager::removeClientFromGame(_client->getGameName(), _client); clients.erase(client->toString().value_or("")); } @@ -67,9 +82,10 @@ void ClientManager::banClient(std::shared_ptr client) bannedClients.push_back(client->getIp().value()); FLAKKARI_LOG_LOG("Client " + client->toString().value_or("Unknown") + " banned"); - GameManager::removeClientFromGame("R-Type", clients[client->toString().value_or("")]); - clients.erase(client->toString().value_or("")); - } + auto _client = clients[client->toString().value_or("")]; + GameManager::removeClientFromGame(_client->getGameName(), _client); + clients.erase(client->toString().value_or("")); +} bool ClientManager::isBanned(std::shared_ptr client) { @@ -85,7 +101,7 @@ void ClientManager::checkInactiveClients() for (auto it = clients.begin(); it != clients.end();) { if (!it->second->isConnected()) { FLAKKARI_LOG_LOG("Client " + it->first + " disconnected"); - GameManager::removeClientFromGame("R-Type", it->second); + GameManager::removeClientFromGame(it->second->getGameName(), it->second); it = clients.erase(it); } else { ++it; @@ -165,7 +181,7 @@ void ClientManager::receivePacketFromClient ( bannedClients.push_back(client->getIp().value()); FLAKKARI_LOG_LOG("Client " + clientName + " banned"); - GameManager::removeClientFromGame("R-Type", tmp_client); + GameManager::removeClientFromGame(tmp_client->getGameName(), tmp_client); clients.erase(clientKey); } diff --git a/Flakkari/Server/Client/ClientManager.hpp b/Flakkari/Server/Client/ClientManager.hpp index f1386580..771ddc17 100644 --- a/Flakkari/Server/Client/ClientManager.hpp +++ b/Flakkari/Server/Client/ClientManager.hpp @@ -17,6 +17,7 @@ #define CLIENTMANAGER_HPP_ #include "Network/Socket.hpp" +#include "Network/Serializer.hpp" #include "Client.hpp" #include @@ -88,7 +89,7 @@ class ClientManager { * * @param client The client's address */ - static void addClient(std::shared_ptr client); + static void addClient(std::shared_ptr client, Network::Buffer &buffer); /** * @brief Remove a client from the client manager diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index db92067b..17662cdc 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -129,6 +129,123 @@ void Game::checkDisconnect() } } +void Game::sendUpdatePosition ( + std::shared_ptr player, + Engine::ECS::Components::_2D::Transform pos, + Engine::ECS::Components::_2D::Movable vel +) { + Protocol::Packet packet; + packet.header._commandId = Protocol::CommandId::REQ_ENTITY_MOVED; + packet << player->getEntity(); + packet << pos.position.x; + packet << pos.position.y; + packet << pos.rotation; + packet << pos.scale.x; + packet << pos.scale.y; + packet << vel.velocity.x; + packet << vel.velocity.y; + FLAKKARI_LOG_LOG( + "packet sent: getEntity()) + + ", Pos: (" + std::to_string(pos.position.x) + ", " + std::to_string(pos.position.y) + ")" + + ", Vel: (" + std::to_string(vel.velocity.x) + ", " + std::to_string(vel.velocity.y) + ")>" + ); + sendOnSameScene(player->getSceneName(), packet.serialize()); +} + +void Game::handleEvent(std::shared_ptr player, Protocol::Packet packet) +{ + auto sceneName = player->getSceneName(); + auto entity = player->getEntity(); + auto ®istry = _scenes[sceneName]; + auto &control = registry.getComponents(); + auto &velocity = registry.getComponents(); + auto &position = registry.getComponents(); + auto &networkEvent = registry.getComponents(); + auto &ctrl = control[entity]; + auto &vel = velocity[entity]; + auto pos = position[entity]; + auto &netEvent = networkEvent[entity]; + + if (!ctrl.has_value() || !vel.has_value() || !pos.has_value()) + return; + Protocol::Event event = Network::Serializer::deserialize(packet.payload); + if (event.id == Protocol::EventId::MOVE_UP && ctrl->up) { + if (netEvent->events.size() < int(event.id)) + netEvent->events.resize(int(event.id) + 1); + netEvent->events[int(event.id)] = int(event.state); + + FLAKKARI_LOG_INFO("event: " + std::to_string(int(event.id)) + " " + std::to_string(int(event.state))); + + if (event.state == Protocol::EventState::PRESSED) + vel->velocity.dy = -1; + if (event.state == Protocol::EventState::RELEASED) + vel->velocity.dy = 0; + sendUpdatePosition(player, pos.value(), vel.value()); + return; + } + if (event.id == Protocol::EventId::MOVE_DOWN && ctrl->down) { + if (netEvent->events.size() < int(event.id)) + netEvent->events.resize(int(event.id) + 1); + netEvent->events[int(event.id)] = int(event.state); + + FLAKKARI_LOG_INFO("event: " + std::to_string(int(event.id)) + " " + std::to_string(int(event.state))); + + if (event.state == Protocol::EventState::PRESSED) + vel->velocity.dy = 1; + if (event.state == Protocol::EventState::RELEASED) + vel->velocity.dy = 0; + sendUpdatePosition(player, pos.value(), vel.value()); + return; + } + if (event.id == Protocol::EventId::MOVE_LEFT && ctrl->left) { + if (netEvent->events.size() < int(event.id)) + netEvent->events.resize(int(event.id) + 1); + netEvent->events[int(event.id)] = int(event.state); + + FLAKKARI_LOG_INFO("event: " + std::to_string(int(event.id)) + " " + std::to_string(int(event.state))); + + if (event.state == Protocol::EventState::PRESSED) + vel->velocity.dx = -1; + if (event.state == Protocol::EventState::RELEASED) + vel->velocity.dx = 0; + sendUpdatePosition(player, pos.value(), vel.value()); + return; + } + if (event.id == Protocol::EventId::MOVE_RIGHT && ctrl->right) { + if (netEvent->events.size() < int(event.id)) + netEvent->events.resize(int(event.id) + 1); + netEvent->events[int(event.id)] = int(event.state); + + FLAKKARI_LOG_INFO("event: " + std::to_string(int(event.id)) + " " + std::to_string(int(event.state))); + + if (event.state == Protocol::EventState::PRESSED) + vel->velocity.dx = 1; + if (event.state == Protocol::EventState::RELEASED) + vel->velocity.dx = 0; + sendUpdatePosition(player, pos.value(), vel.value()); + return; + } + if (event.id == Protocol::EventId::SHOOT && ctrl->shoot) { + if (netEvent->events.size() < int(event.id)) + netEvent->events.resize(int(event.id) + 1); + netEvent->events[int(event.id)] = int(event.state); + + FLAKKARI_LOG_INFO("event: " + std::to_string(int(event.id)) + " " + std::to_string(int(event.state))); + + if (event.state == Protocol::EventState::RELEASED) { + Protocol::Packet packet; + packet.header._commandId = Protocol::CommandId::REQ_ENTITY_SHOOT; + packet << player->getSceneName().size(); + packet << player->getSceneName().c_str(); + packet << player->getEntity(); + // create a bullet with player as parent + sendOnSameScene(player->getSceneName(), packet.serialize()); + } + return; + } +} + void Game::updateIncomingPackets(unsigned char maxMessagePerFrame) { for (auto &player : _players) { @@ -138,10 +255,12 @@ void Game::updateIncomingPackets(unsigned char maxMessagePerFrame) auto messageCount = maxMessagePerFrame; while (!packets.empty() && messageCount > 0) { - Protocol::Packet p; auto packet = packets.pop_front(); FLAKKARI_LOG_INFO("packet received: " + packet.to_string()); messageCount--; + + if (packet.header._commandId == Protocol::CommandId::REQ_USER_UPDATE) + handleEvent(player, packet); } } } diff --git a/Flakkari/Server/Game/Game.hpp b/Flakkari/Server/Game/Game.hpp index b2e2fb33..317394fe 100644 --- a/Flakkari/Server/Game/Game.hpp +++ b/Flakkari/Server/Game/Game.hpp @@ -102,6 +102,27 @@ class Game { */ void checkDisconnect(); + /** + * @brief Send a packet to a player. + * + * @param player Player to send the packet to. + * @param pos Position of the player. + * @param vel Velocity of the player. + */ + void sendUpdatePosition ( + std::shared_ptr player, + Engine::ECS::Components::_2D::Transform pos, + Engine::ECS::Components::_2D::Movable vel + ); + + /** + * @brief Handle an event from a player. + * + * @param player Player that sent the event. + * @param packet Packet containing the event. + */ + void handleEvent(std::shared_ptr player, Protocol::Packet packet); + /** * @brief Empty the incoming packets of the players and update the * game with the new packets. diff --git a/Flakkari/Server/UDPServer.cpp b/Flakkari/Server/UDPServer.cpp index acf9b06c..eca52386 100644 --- a/Flakkari/Server/UDPServer.cpp +++ b/Flakkari/Server/UDPServer.cpp @@ -56,11 +56,10 @@ bool UDPServer::handleInput(int fd) void UDPServer::handlePacket() { auto packet = _socket->receiveFrom(); - ClientManager::addClient(packet->first); + ClientManager::addClient(packet->first, packet->second); ClientManager::checkInactiveClients(); ClientManager::receivePacketFromClient(packet->first, packet->second); - ClientManager::sendPacketToClient(packet->first, packet->second); } void UDPServer::run() From 16b17c3eb3522a10a7abadf6417096dae5a47c04 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sun, 14 Jan 2024 20:18:31 +0100 Subject: [PATCH 46/48] feat(Protocol): Add new components and update player spawning logic --- .../Components/Common/NetworkEvent.hpp | 30 ++- .../EntityComponentSystem/Systems/Systems.cpp | 7 +- Flakkari/Protocol/Components.hpp | 11 +- Flakkari/Protocol/PacketFactory.hpp | 192 +++++++++++------- Flakkari/Server/Game/Game.cpp | 89 +++++++- 5 files changed, 244 insertions(+), 85 deletions(-) diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/NetworkEvent.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/NetworkEvent.hpp index 2a19a5f7..73152c34 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/NetworkEvent.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/NetworkEvent.hpp @@ -14,17 +14,29 @@ namespace Flakkari::Engine::ECS::Components::Common { - struct NetworkEvent { - std::vector events; +struct NetworkEvent { + std::vector events; - NetworkEvent() = default; - NetworkEvent(const NetworkEvent &other) : events(other.events) {}; - NetworkEvent(const std::vector &events) : events(events) {}; + NetworkEvent() = default; + NetworkEvent(const NetworkEvent &other) : events(other.events) {}; + NetworkEvent(const std::vector &events) : events(events) {}; - std::size_t size() const { - return events.size() * sizeof(unsigned short); - } - }; + std::size_t size() const { + return events.size() * sizeof(unsigned short); + } +}; + +struct NetworkIp { + const char *ip; + + NetworkIp() : ip(0) {} + NetworkIp(std::string ip) : ip(ip.c_str()) {} + NetworkIp(const NetworkIp &other) : ip(other.ip) {} + + std::size_t size() const { + return std::strlen(ip); + } +}; } /* namespace Flakkari::Engine::ECS::Components::Common */ diff --git a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp index 7deb068c..38334dd5 100644 --- a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp +++ b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp @@ -34,15 +34,12 @@ void position(Registry &r, float deltaTime) void update_control(Registry &r) { - if (!r.isRegistered() || !r.isRegistered() - || !r.isRegistered()) + if (!r.isRegistered() || !r.isRegistered()) return; - auto& positions = r.getComponents(); auto& velocities = r.getComponents(); auto& networkEvent = r.getComponents(); - for (Entity i(0); i < velocities.size() && i < positions.size(); ++i) { - auto& pos = positions[i]; + for (Entity i(0); i < velocities.size(); ++i) { auto& vel = velocities[i]; auto& net = networkEvent[i]; diff --git a/Flakkari/Protocol/Components.hpp b/Flakkari/Protocol/Components.hpp index 0c7fad4c..78d000a9 100644 --- a/Flakkari/Protocol/Components.hpp +++ b/Flakkari/Protocol/Components.hpp @@ -30,12 +30,21 @@ inline namespace V_0 { CONTROL = 0, MOVABLE = 1, TRANSFORM = 2, + COLLIDER = 3, + RIGIDBODY = 4, // 10 - 19: Common components CHILD = 10, PARENT = 11, TAG = 12, - ID = 13, + SPAWNED = 13, TEMPLATE = 14, + WEAPON = 15, + LEVEL = 16, + EVOLVE = 17, + HEALTH = 18, + // 20 - 29: Network components + NETWORK_EVENT = 20, + NETWORK_IP = 21, MAX_COMPONENT }; diff --git a/Flakkari/Protocol/PacketFactory.hpp b/Flakkari/Protocol/PacketFactory.hpp index ce911734..52db9340 100644 --- a/Flakkari/Protocol/PacketFactory.hpp +++ b/Flakkari/Protocol/PacketFactory.hpp @@ -26,73 +26,6 @@ namespace Flakkari::Protocol { class PacketFactory { public: - /** - * @brief Add all the commons components of an entity to a packet. - * - * @tparam Id Type of the entity id. - * @param packet Packet to add the components to. - * @param registry Registry to get the components from. - * @param entity Entity to get the components from. - */ - template - static void addCommonsToPacketByEntity ( - Protocol::Packet &packet, Engine::ECS::Registry ®istry, Engine::ECS::Entity entity - ) { - auto child = registry.getComponents(); - auto childEntity = child[entity]; - - if (childEntity.has_value()) { - packet << Protocol::ComponentId::CHILD; - packet << childEntity->size(); - packet << childEntity->name; - } - - // auto evolve = registry.getComponents(); - // auto evolveEntity = evolve[entity]; - - // if (evolveEntity.has_value()) { - // packet << Protocol::ComponentId::EVOLVE; - // packet << evolveEntity->size(); - // packet << evolveEntity->name; - // } - - // auto id = registry.getComponents(); - // auto idEntity = id[entity]; - - // if (idEntity.has_value()) { - // packet << Protocol::ComponentId::ID; - // packet << idEntity->size(); - // packet << idEntity->id; - // } - - auto parent = registry.getComponents(); - auto parentEntity = parent[entity]; - - if (parentEntity.has_value()) { - packet << Protocol::ComponentId::PARENT; - packet << parentEntity->size(); - packet << parentEntity->entity; - } - - auto tag = registry.getComponents(); - auto tagEntity = tag[entity]; - - if (tagEntity.has_value()) { - packet << Protocol::ComponentId::TAG; - packet << tagEntity->size(); - packet << tagEntity->tag; - } - - auto name = registry.getComponents(); - auto nameEntity = name[entity]; - - if (nameEntity.has_value()) { - packet << Protocol::ComponentId::TEMPLATE; - packet << nameEntity->size(); - packet << nameEntity->name; - } - } - /** * @brief Add all the 2D components of an entity to a packet. * @@ -142,6 +75,128 @@ class PacketFactory { packet << ctrl->right; packet << ctrl->shoot; } + + auto collider = registry.getComponents(); + auto col = collider[entity]; + + if (col.has_value()) { + packet << Protocol::ComponentId::COLLIDER; + packet << col->size(); + packet << col->_size.x; + packet << col->_size.y; + } + + auto rigidbody = registry.getComponents(); + auto rb = rigidbody[entity]; + + if (rb.has_value()) { + packet << Protocol::ComponentId::RIGIDBODY; + packet << rb->size(); + packet << rb->mass; + packet << rb->restitution; + packet << rb->friction; + packet << rb->gravityScale; + packet << rb->isKinematic; + } + + auto health = registry.getComponents(); + auto hp = health[entity]; + + if (hp.has_value()) { + packet << Protocol::ComponentId::HEALTH; + packet << hp->size(); + packet << hp->currentHealth; + packet << hp->maxHealth; + packet << hp->shield; + packet << hp->maxShield; + } + + auto weapon = registry.getComponents(); + auto wp = weapon[entity]; + + if (wp.has_value()) { + packet << Protocol::ComponentId::WEAPON; + packet << wp->size(); + packet << wp->damage; + packet << wp->fireRate; + packet << wp->level; + } + + auto level = registry.getComponents(); + auto lvl = level[entity]; + + if (lvl.has_value()) { + packet << Protocol::ComponentId::LEVEL; + packet << lvl->size(); + packet << lvl->level; + packet.injectString(std::string(lvl->currentWeapon)); + packet << lvl->currentExp; + packet << lvl->requiredExp; + } + + auto spawned = registry.getComponents(); + auto sp = spawned[entity]; + + if (sp.has_value()) { + packet << Protocol::ComponentId::SPAWNED; + packet << sp->size(); + packet << sp->has_spawned; + } + + auto networkEvent = registry.getComponents(); + auto netEvent = networkEvent[entity]; + + if (netEvent.has_value()) { + packet << Protocol::ComponentId::NETWORK_EVENT; + packet << netEvent->size(); + packet << netEvent->events.size(); + for (auto &event : netEvent->events) { + packet << event; + } + } + + auto networkIp = registry.getComponents(); + auto ip = networkIp[entity]; + + if (ip.has_value()) { + packet << Protocol::ComponentId::NETWORK_IP; + packet.injectString(std::string(ip->ip)); + } + + auto templateName = registry.getComponents(); + auto name = templateName[entity]; + + if (name.has_value()) { + packet << Protocol::ComponentId::TEMPLATE; + packet.injectString(std::string(name->name)); + } + + auto parent = registry.getComponents(); + auto parentEntity = parent[entity]; + + if (parentEntity.has_value()) { + packet << Protocol::ComponentId::PARENT; + packet << parentEntity->size(); + packet << parentEntity->entity; + } + + auto child = registry.getComponents(); + auto childEntity = child[entity]; + + if (childEntity.has_value()) { + packet << Protocol::ComponentId::CHILD; + packet << childEntity->size(); + packet.injectString(std::string(childEntity->name)); + } + + auto tag = registry.getComponents(); + auto tagEntity = tag[entity]; + + if (tagEntity.has_value()) { + packet << Protocol::ComponentId::TAG; + packet << tagEntity->size(); + packet.injectString(std::string(tagEntity->tag)); + } } /** @@ -178,8 +233,7 @@ class PacketFactory { Protocol::Packet &packet, std::size_t size, const std::string &sceneName, Engine::ECS::Entity entity ) { - packet << size; - packet << sceneName.c_str(); + packet.injectString(sceneName); packet << entity; } diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index 17662cdc..bd8b23d8 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -9,6 +9,9 @@ #include "Game.hpp" #include "../Client/ClientManager.hpp" +#include "ResourceManager.hpp" +#include "Protocol/PacketFactory.hpp" +#include "Engine/EntityComponentSystem/Components/ComponentsCommon.hpp" namespace Flakkari { @@ -63,6 +66,79 @@ void Game::loadComponents ( registry.add_component(newEntity, std::move(movable)); continue; } + + if (componentName == "Control") { + registry.registerComponent(); + Engine::ECS::Components::_2D::Control control; + control.up = componentContent["up"]; + control.down = componentContent["down"]; + control.left = componentContent["left"]; + control.right = componentContent["right"]; + control.shoot = componentContent["shoot"]; + registry.add_component(newEntity, std::move(control)); + continue; + } + + if (componentName == "Collider") { + registry.registerComponent(); + Engine::ECS::Components::_2D::Collider collider; + collider._size = Engine::Math::Vector2f(componentContent["size"]["x"], componentContent["size"]["y"]); + registry.add_component(newEntity, std::move(collider)); + continue; + } + + if (componentName == "Evolve") { + registry.registerComponent(); + Engine::ECS::Components::Common::Evolve evolve; + evolve.name = componentContent["name"].get().c_str(); + registry.add_component(newEntity, std::move(evolve)); + continue; + } + + if (componentName == "Spawned") { + registry.registerComponent(); + Engine::ECS::Components::Common::Spawned spawned; + spawned.has_spawned = componentContent["has_spawned"]; + registry.add_component(newEntity, std::move(spawned)); + continue; + } + + if (componentName == "Tag") { + registry.registerComponent(); + Engine::ECS::Components::Common::Tag tag; + tag.tag = componentContent["tag"].get().c_str(); + registry.add_component(newEntity, std::move(tag)); + continue; + } + + if (componentName == "Template") { + registry.registerComponent(); + Engine::ECS::Components::Common::Template template_; + template_.name = componentContent["name"].get().c_str(); + registry.add_component(newEntity, std::move(template_)); + continue; + } + + if (componentName == "Weapon") { + registry.registerComponent(); + Engine::ECS::Components::Common::Weapon weapon; + weapon.fireRate = componentContent["fireRate"]; + weapon.damage = componentContent["damage"]; + weapon.level = componentContent["level"]; + registry.add_component(newEntity, std::move(weapon)); + continue; + } + + if (componentName == "Health") { + registry.registerComponent(); + Engine::ECS::Components::Common::Health health; + health.maxHealth = componentContent["maxHealth"]; + health.currentHealth = componentContent["currentHealth"]; + health.maxShield = componentContent["maxShield"]; + health.shield = componentContent["shield"]; + registry.add_component(newEntity, std::move(health)); + continue; + } } } @@ -306,10 +382,21 @@ bool Game::addPlayer(std::shared_ptr player) player->setSceneName(sceneGame); Engine::ECS::Entity newEntity = registry.spawn_entity(); - player->setEntity(newEntity); + auto p_Template = (*_config)["playerTemplate"]; + auto player_info = ResourceManager::getTemplateById(_name, sceneGame, p_Template); + player->setEntity(newEntity); _players.push_back(player); FLAKKARI_LOG_INFO("client \""+ std::string(*player->getAddress()) +"\" added to game \""+ _name +"\""); + + Protocol::Packet packet; + packet.header._commandId = Protocol::CommandId::REQ_ENTITY_SPAWN; + + Protocol::PacketFactory::addComponentsToPacketByEntity ( + packet, registry, newEntity + ); + + sendOnSameScene(player->getSceneName(), packet.serialize()); return true; } From 3d329a788dfd2fb4385c7e70ac84f458ae84f1de Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sun, 14 Jan 2024 22:43:16 +0100 Subject: [PATCH 47/48] fix(Game): Add network IP and template components to player entity --- Flakkari/Protocol/PacketFactory.hpp | 2 -- Flakkari/Server/Client/Client.hpp | 2 +- Flakkari/Server/Game/Game.cpp | 23 +++++++++++++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Flakkari/Protocol/PacketFactory.hpp b/Flakkari/Protocol/PacketFactory.hpp index 52db9340..eb3c94b4 100644 --- a/Flakkari/Protocol/PacketFactory.hpp +++ b/Flakkari/Protocol/PacketFactory.hpp @@ -213,8 +213,6 @@ class PacketFactory { ) { /*_ Common Components _*/ - addCommonsToPacketByEntity(packet, registry, entity); - /*_ 2D Components _*/ add2dToPacketByEntity(packet, registry, entity); diff --git a/Flakkari/Server/Client/Client.hpp b/Flakkari/Server/Client/Client.hpp index fa705dac..85699226 100644 --- a/Flakkari/Server/Client/Client.hpp +++ b/Flakkari/Server/Client/Client.hpp @@ -57,7 +57,7 @@ class Client { * @return true If the client is still connected * @return false If the client is not connected anymore */ - [[nodiscard]] bool isConnected(float timeout = 5); + [[nodiscard]] bool isConnected(float timeout = 10); /** * @brief Update the last activity of the client diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index bd8b23d8..187744cb 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -23,6 +23,7 @@ Game::Game(const std::string &name, std::shared_ptr config) if ((*_config)["scenes"].empty()) throw std::runtime_error("Game: no scenes found"); loadScene((*_config)["startGame"]); + ResourceManager::addScene(_name, (*_config)["startGame"]); } Game::~Game() @@ -385,12 +386,34 @@ bool Game::addPlayer(std::shared_ptr player) auto p_Template = (*_config)["playerTemplate"]; auto player_info = ResourceManager::getTemplateById(_name, sceneGame, p_Template); + loadComponents(registry, player_info.value_or(""), newEntity); + + registry.registerComponent(); + registry.add_component ( + newEntity, + Engine::ECS::Components::Common::NetworkIp( + std::string(*player->getAddress()) + ) + ); + + registry.registerComponent(); + registry.add_component ( + newEntity, + Engine::ECS::Components::Common::Template( + std::string(p_Template) + ) + ); + player->setEntity(newEntity); _players.push_back(player); FLAKKARI_LOG_INFO("client \""+ std::string(*player->getAddress()) +"\" added to game \""+ _name +"\""); Protocol::Packet packet; packet.header._commandId = Protocol::CommandId::REQ_ENTITY_SPAWN; + packet.injectString(sceneGame); + packet << newEntity; + packet.injectString(std::string(*player->getAddress())); + packet.injectString(p_Template); Protocol::PacketFactory::addComponentsToPacketByEntity ( packet, registry, newEntity From 5cc41eed3c8229e75a280da65af1fc73e7ea5cc3 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sun, 14 Jan 2024 23:27:55 +0100 Subject: [PATCH 48/48] feat(Protocol): Add CommandId to_string function and injectComponent method --- Flakkari/Protocol/Commands.hpp | 47 ++++++++++++++++++++++++++++++++++ Flakkari/Protocol/Packet.hpp | 10 ++++++++ Flakkari/Server/Game/Game.cpp | 11 ++++---- 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/Flakkari/Protocol/Commands.hpp b/Flakkari/Protocol/Commands.hpp index 6062cbb2..1a736c3d 100644 --- a/Flakkari/Protocol/Commands.hpp +++ b/Flakkari/Protocol/Commands.hpp @@ -114,6 +114,53 @@ inline namespace V_0 { MAX_COMMAND_ID }; + static_assert(static_cast(CommandId::MAX_COMMAND_ID) <= 0xFF, "CommandId is too big"); + + static std::string to_string(CommandId id) + { + switch (id) { + case CommandId::REQ_CONNECT: return "REQ_CONNECT"; + case CommandId::REP_CONNECT: return "REP_CONNECT"; + case CommandId::REQ_DISCONNECT: return "REQ_DISCONNECT"; + case CommandId::REP_DISCONNECT: return "REP_DISCONNECT"; + case CommandId::REQ_PING: return "REQ_PING"; + case CommandId::REP_PING: return "REP_PING"; + case CommandId::REQ_PONG: return "REQ_PONG"; + case CommandId::REP_PONG: return "REP_PONG"; + case CommandId::REQ_HEARTBEAT: return "REQ_HEARTBEAT"; + case CommandId::REP_HEARTBEAT: return "REP_HEARTBEAT"; + case CommandId::REQ_LOGIN: return "REQ_LOGIN"; + case CommandId::REP_LOGIN: return "REP_LOGIN"; + case CommandId::REQ_LOGOUT: return "REQ_LOGOUT"; + case CommandId::REP_LOGOUT: return "REP_LOGOUT"; + case CommandId::REQ_REGISTER: return "REQ_REGISTER"; + case CommandId::REP_REGISTER: return "REP_REGISTER"; + case CommandId::REQ_ENTITY_SPAWN: return "REQ_ENTITY_SPAWN"; + case CommandId::REP_ENTITY_SPAWN: return "REP_ENTITY_SPAWN"; + case CommandId::REQ_ENTITY_UPDATE: return "REQ_ENTITY_UPDATE"; + case CommandId::REP_ENTITY_UPDATE: return "REP_ENTITY_UPDATE"; + case CommandId::REQ_ENTITY_DESTROY: return "REQ_ENTITY_DESTROY"; + case CommandId::REP_ENTITY_DESTROY: return "REP_ENTITY_DESTROY"; + case CommandId::REQ_ENTITY_MOVED: return "REQ_ENTITY_MOVED"; + case CommandId::REP_ENTITY_MOVED: return "REP_ENTITY_MOVED"; + case CommandId::REQ_ENTITY_SHOOT: return "REQ_ENTITY_SHOOT"; + case CommandId::REP_ENTITY_SHOOT: return "REP_ENTITY_SHOOT"; + case CommandId::REQ_USER_UPDATE: return "REQ_USER_UPDATE"; + case CommandId::REP_USER_UPDATE: return "REP_USER_UPDATE"; + case CommandId::REQ_CREATE_ROOM: return "REQ_CREATE_ROOM"; + case CommandId::REP_CREATE_ROOM: return "REP_CREATE_ROOM"; + case CommandId::REQ_JOIN_ROOM: return "REQ_JOIN_ROOM"; + case CommandId::REP_JOIN_ROOM: return "REP_JOIN_ROOM"; + case CommandId::REQ_LEAVE_ROOM: return "REQ_LEAVE_ROOM"; + case CommandId::REP_LEAVE_ROOM: return "REP_LEAVE_ROOM"; + case CommandId::REQ_START_GAME: return "REQ_START_GAME"; + case CommandId::REP_START_GAME: return "REP_START_GAME"; + case CommandId::REQ_END_GAME: return "REQ_END_GAME"; + case CommandId::REP_END_GAME: return "REP_END_GAME"; + default: return "Unknown"; + } + } + } /* namespace V_0 */ } // namespace Flakkari::Protocol diff --git a/Flakkari/Protocol/Packet.hpp b/Flakkari/Protocol/Packet.hpp index 0353697c..801dd116 100644 --- a/Flakkari/Protocol/Packet.hpp +++ b/Flakkari/Protocol/Packet.hpp @@ -74,6 +74,16 @@ inline namespace V_0 { return os; } + template + void injectComponent(T component) + { + int intValue = (int)component.size(); + const byte* dataBytes = reinterpret_cast(&intValue); + payload.insert(payload.end(), dataBytes, dataBytes + sizeof(intValue)); + payload += component; + header._contentLength += payload.size() + sizeof(intValue); + } + /** * @brief Add data to the packet. * diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index 187744cb..746990f7 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -410,15 +410,14 @@ bool Game::addPlayer(std::shared_ptr player) Protocol::Packet packet; packet.header._commandId = Protocol::CommandId::REQ_ENTITY_SPAWN; + std::cout << "entity: " << newEntity << std::endl; + std::cout << "scene: " << sceneGame << std::endl; + std::cout << "address: " << player->getAddress()->toString().value() << std::endl; + std::cout << "template: " << p_Template << std::endl; packet.injectString(sceneGame); - packet << newEntity; - packet.injectString(std::string(*player->getAddress())); + packet.injectString(player->getAddress()->toString().value()); packet.injectString(p_Template); - Protocol::PacketFactory::addComponentsToPacketByEntity ( - packet, registry, newEntity - ); - sendOnSameScene(player->getSceneName(), packet.serialize()); return true; }