From 7f02e7cf22293d2e25662ba01e35cc133d3911bc Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sat, 16 Nov 2024 23:51:27 -0500 Subject: [PATCH 01/26] feat: add commands management to version 1 of the protocol --- Flakkari/Protocol/Commands.hpp | 99 ++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/Flakkari/Protocol/Commands.hpp b/Flakkari/Protocol/Commands.hpp index 1c7de83b..85fed0cb 100644 --- a/Flakkari/Protocol/Commands.hpp +++ b/Flakkari/Protocol/Commands.hpp @@ -166,6 +166,105 @@ class Commands final { } /* namespace V_0 */ +namespace V_1 { + +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_HEARTBEAT = 4, // Client -> Server [Heartbeat server) (Keep alive)]: (user_id) + REP_HEARTBEAT = 5, // 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 + REQ_USER_UPDATE = 30, // Client -> Server [Update user]: (event_id, state) + REP_USER_UPDATE = 31, // Server -> Client [User updated]: () + REQ_USER_UPDATES = 32, // Client -> Server [Update user multi-events]: (event_id, state|event_id, float) + REP_USER_UPDATES = 33, // Server -> Client [User updated]: () + // 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]: () + MAX_COMMAND_ID +}; + +static_assert(static_cast(CommandId::MAX_COMMAND_ID) <= 0xFF, "CommandId is too big"); + +class Commands final { +public: + static std::string command_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_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_USER_UPDATES: return "REQ_USER_UPDATES"; + case CommandId::REP_USER_UPDATES: return "REP_USER_UPDATES"; + 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_1 */ + } // namespace Flakkari::Protocol #endif /* !COMMANDS_HPP_ */ From 93ec0df9f6b789039795d3544d8d552b7efef751 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 17 Nov 2024 04:51:45 +0000 Subject: [PATCH 02/26] style: apply linter --- Flakkari/Protocol/Commands.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flakkari/Protocol/Commands.hpp b/Flakkari/Protocol/Commands.hpp index 85fed0cb..f6cb0654 100644 --- a/Flakkari/Protocol/Commands.hpp +++ b/Flakkari/Protocol/Commands.hpp @@ -195,8 +195,8 @@ enum class CommandId : uint8_t { 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]: () + REQ_USER_UPDATE = 30, // Client -> Server [Update user]: (event_id, state) + REP_USER_UPDATE = 31, // Server -> Client [User updated]: () REQ_USER_UPDATES = 32, // Client -> Server [Update user multi-events]: (event_id, state|event_id, float) REP_USER_UPDATES = 33, // Server -> Client [User updated]: () // 40 - 49: Chat From 67349e393fe54ef39d2840021d7b61fbf9e1c040 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sat, 16 Nov 2024 23:54:13 -0500 Subject: [PATCH 03/26] feat: add version 1 component IDs and string conversion method --- Flakkari/Protocol/Components.hpp | 69 ++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/Flakkari/Protocol/Components.hpp b/Flakkari/Protocol/Components.hpp index 64e225ef..165fa02f 100644 --- a/Flakkari/Protocol/Components.hpp +++ b/Flakkari/Protocol/Components.hpp @@ -78,6 +78,75 @@ class Components final { } /* namespace V_0 */ +namespace V_1 { + +enum class ComponentId : uint8_t { + // 0 - 9: 2D components + CONTROL = 0, + MOVABLE = 1, + TRANSFORM = 2, + COLLIDER = 3, + RIGIDBODY = 4, + // 10 - 19: 3D components + CONTROL_3D = 10, + MOVABLE_3D = 11, + TRANSFORM_3D = 12, + BOXCOLLIDER = 13, + SPHERECOLLIDER = 14, + RIGIDBODY_3D = 15, + // 20 - 29: Common components + CHILD = 20, + PARENT = 21, + TAG = 22, + SPAWNED = 23, + TEMPLATE = 24, + WEAPON = 25, + LEVEL = 26, + EVOLVE = 27, + HEALTH = 28, + // 30 - 39: Network components + NETWORK_EVENT = 30, + NETWORK_IP = 31, + MAX_COMPONENT +}; + +static_assert(static_cast(ComponentId::MAX_COMPONENT) <= 40, "ComponentId::MAX_COMPONENT is too big"); + +class Components final { +public: + static std::string component_to_string(ComponentId id) + { + switch (id) + { + case ComponentId::CONTROL: return "CONTROL"; + case ComponentId::CONTROL_3D: return "CONTROL_3D"; + case ComponentId::MOVABLE: return "MOVABLE"; + case ComponentId::MOVABLE_3D: return "MOVABLE_3D"; + case ComponentId::TRANSFORM: return "TRANSFORM"; + case ComponentId::TRANSFORM_3D: return "TRANSFORM_3D"; + case ComponentId::COLLIDER: return "COLLIDER"; + case ComponentId::BOXCOLLIDER: return "BOXCOLLIDER"; + case ComponentId::SPHERECOLLIDER: return "SPHERECOLLIDER"; + case ComponentId::RIGIDBODY: return "RIGIDBODY"; + case ComponentId::RIGIDBODY_3D: return "RIGIDBODY_3D"; + case ComponentId::CHILD: return "CHILD"; + case ComponentId::PARENT: return "PARENT"; + case ComponentId::TAG: return "TAG"; + case ComponentId::SPAWNED: return "SPAWNED"; + case ComponentId::TEMPLATE: return "TEMPLATE"; + case ComponentId::WEAPON: return "WEAPON"; + case ComponentId::LEVEL: return "LEVEL"; + case ComponentId::EVOLVE: return "EVOLVE"; + case ComponentId::HEALTH: return "HEALTH"; + case ComponentId::NETWORK_EVENT: return "NETWORK_EVENT"; + case ComponentId::NETWORK_IP: return "NETWORK_IP"; + default: return "UNKNOWN"; + } + } +}; + +} /* namespace V_1 */ + } // namespace Flakkari::Protocol #endif /* !COMPONENTS_HPP_ */ From 8885243fdacd8ccb65fb5139a22738dcdbb8ef2f Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sat, 16 Nov 2024 23:57:51 -0500 Subject: [PATCH 04/26] feat: add event management for version 1 of the protocol --- Flakkari/Protocol/Events.hpp | 39 ++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/Flakkari/Protocol/Events.hpp b/Flakkari/Protocol/Events.hpp index 16fa4d56..bb99af58 100644 --- a/Flakkari/Protocol/Events.hpp +++ b/Flakkari/Protocol/Events.hpp @@ -42,14 +42,49 @@ enum class EventState : uint8_t { LPL_PACKED_START struct Event { - EventId id; - EventState state; + V_0::EventId id; + V_0::EventState state; }; LPL_PACKED_END } /* namespace V_0 */ +namespace V_1 { + +enum class EventId : uint8_t { + MOVE_LEFT = 10, + MOVE_RIGHT = 11, + MOVE_UP = 12, + MOVE_DOWN = 13, + MOVE_FRONT = 14, + MOVE_BACK = 15, + LOOK_LEFT = 16, + LOOK_RIGHT = 17, + LOOK_UP = 18, + LOOK_DOWN = 19, + SHOOT = 20, + MAX_EVENT +}; + +enum class EventState : uint8_t { + NONE = 0, + PRESSED = 1, + RELEASED = 2, + MAX_STATE +}; + +LPL_PACKED_START + +struct Event { + V_1::EventId id; + V_1::EventState state; +}; + +LPL_PACKED_END + +} /* namespace V_1 */ + } // namespace Flakkari::Protocol #endif /* !EVENTS_HPP_ */ From e4c2561f765f1eb057d198cca171b71e50ef6058 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sun, 17 Nov 2024 00:13:25 -0500 Subject: [PATCH 05/26] feat: add header management for protocol version 1 --- Flakkari/Protocol/Header.hpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Flakkari/Protocol/Header.hpp b/Flakkari/Protocol/Header.hpp index 526bffae..539c08c7 100644 --- a/Flakkari/Protocol/Header.hpp +++ b/Flakkari/Protocol/Header.hpp @@ -42,8 +42,6 @@ enum class ApiVersion : byte { MAX_VERSION }; -inline namespace V_0 { - /** * @brief The priority of the message in the queue * @@ -58,6 +56,8 @@ enum class Priority : byte { MAX_PRIORITY = 4 }; +namespace V_0 { + LPL_PACKED_START template struct Header { @@ -74,6 +74,24 @@ LPL_PACKED_END } // namespace V_0 +namespace V_1 { + +LPL_PACKED_START + +template struct Header { + Priority _priority : 4 = Priority::LOW; + ApiVersion _apiVersion : 4 = ApiVersion::V_1; + Id _commandId; + ushort _contentLength = 0; + uint _sequenceNumber = static_cast( + std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) + .count()); +}; + +LPL_PACKED_END + +} // namespace V_1 + } // namespace Flakkari::Protocol #endif /* !HEADER_HPP_ */ From b79b89fc57049fa0c76ad40a4d2839fb6fd2f12a Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sun, 17 Nov 2024 00:16:17 -0500 Subject: [PATCH 06/26] feat: update protocol versioning and event handling for version 0 --- .../EntityComponentSystem/Systems/Systems.cpp | 16 ++++++++-------- Flakkari/Protocol/Commands.hpp | 4 ++-- Flakkari/Protocol/Components.hpp | 4 ++-- Flakkari/Protocol/Events.hpp | 4 ++-- Flakkari/Protocol/Header.hpp | 2 +- Flakkari/Protocol/Packet.hpp | 6 +----- 6 files changed, 16 insertions(+), 20 deletions(-) diff --git a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp index 4b393dc6..6b22fcca 100644 --- a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp +++ b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp @@ -53,24 +53,24 @@ void update_control(Registry &r) if (!net.has_value() || !vel.has_value()) continue; - if (net->events.size() < int(Protocol::EventId::MOVE_UP)) + if (net->events.size() < int(Protocol::V_0::EventId::MOVE_UP)) continue; - if (net->events[int(Protocol::EventId::MOVE_UP)] == int(Protocol::EventState::PRESSED)) + if (net->events[int(Protocol::V_0::EventId::MOVE_UP)] == int(Protocol::V_0::EventState::PRESSED)) vel->_velocity.vec.y = -1; - if (net->events.size() < int(Protocol::EventId::MOVE_DOWN)) + if (net->events.size() < int(Protocol::V_0::EventId::MOVE_DOWN)) continue; - if (net->events[int(Protocol::EventId::MOVE_DOWN)] == int(Protocol::EventState::PRESSED)) + if (net->events[int(Protocol::V_0::EventId::MOVE_DOWN)] == int(Protocol::V_0::EventState::PRESSED)) vel->_velocity.vec.y = 1; - if (net->events.size() < int(Protocol::EventId::MOVE_LEFT)) + if (net->events.size() < int(Protocol::V_0::EventId::MOVE_LEFT)) continue; - if (net->events[int(Protocol::EventId::MOVE_LEFT)] == int(Protocol::EventState::PRESSED)) + if (net->events[int(Protocol::V_0::EventId::MOVE_LEFT)] == int(Protocol::V_0::EventState::PRESSED)) vel->_velocity.vec.x = -1; - if (net->events.size() < int(Protocol::EventId::MOVE_RIGHT)) + if (net->events.size() < int(Protocol::V_0::EventId::MOVE_RIGHT)) continue; - if (net->events[int(Protocol::EventId::MOVE_RIGHT)] == int(Protocol::EventState::PRESSED)) + if (net->events[int(Protocol::V_0::EventId::MOVE_RIGHT)] == int(Protocol::V_0::EventState::PRESSED)) vel->_velocity.vec.x = 1; } } diff --git a/Flakkari/Protocol/Commands.hpp b/Flakkari/Protocol/Commands.hpp index f6cb0654..d0a1f358 100644 --- a/Flakkari/Protocol/Commands.hpp +++ b/Flakkari/Protocol/Commands.hpp @@ -22,7 +22,7 @@ namespace Flakkari::Protocol { -inline namespace V_0 { +namespace V_0 { enum class CommandId : uint8_t { // 0 - 9: System @@ -166,7 +166,7 @@ class Commands final { } /* namespace V_0 */ -namespace V_1 { +inline namespace V_1 { enum class CommandId : uint8_t { // 0 - 9: System diff --git a/Flakkari/Protocol/Components.hpp b/Flakkari/Protocol/Components.hpp index 165fa02f..bb668666 100644 --- a/Flakkari/Protocol/Components.hpp +++ b/Flakkari/Protocol/Components.hpp @@ -22,7 +22,7 @@ namespace Flakkari::Protocol { -inline namespace V_0 { +namespace V_0 { enum class ComponentId : uint8_t { // 0 - 9: 2D components @@ -78,7 +78,7 @@ class Components final { } /* namespace V_0 */ -namespace V_1 { +inline namespace V_1 { enum class ComponentId : uint8_t { // 0 - 9: 2D components diff --git a/Flakkari/Protocol/Events.hpp b/Flakkari/Protocol/Events.hpp index bb99af58..fec3be79 100644 --- a/Flakkari/Protocol/Events.hpp +++ b/Flakkari/Protocol/Events.hpp @@ -21,7 +21,7 @@ namespace Flakkari::Protocol { -inline namespace V_0 { +namespace V_0 { enum class EventId : uint8_t { MOVE_LEFT = 10, @@ -50,7 +50,7 @@ LPL_PACKED_END } /* namespace V_0 */ -namespace V_1 { +inline namespace V_1 { enum class EventId : uint8_t { MOVE_LEFT = 10, diff --git a/Flakkari/Protocol/Header.hpp b/Flakkari/Protocol/Header.hpp index 539c08c7..20686eef 100644 --- a/Flakkari/Protocol/Header.hpp +++ b/Flakkari/Protocol/Header.hpp @@ -74,7 +74,7 @@ LPL_PACKED_END } // namespace V_0 -namespace V_1 { +inline namespace V_1 { LPL_PACKED_START diff --git a/Flakkari/Protocol/Packet.hpp b/Flakkari/Protocol/Packet.hpp index 38866b46..47908f98 100644 --- a/Flakkari/Protocol/Packet.hpp +++ b/Flakkari/Protocol/Packet.hpp @@ -30,10 +30,8 @@ namespace Flakkari::Protocol { -inline namespace V_0 { - /** - * @brief Flakkari Packet v0 (new packet) + * @brief Flakkari Packet v1 (new packet) * * @tparam Id: The type of the command id. * @param header: The header of the packet. @@ -173,8 +171,6 @@ template struct Packet { } }; -} /* namespace V_0 */ - } // namespace Flakkari::Protocol #endif /* !PACKET_HPP_ */ From b4eb1a11dabec564a9ff0e532067ac33816e4923 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Sun, 17 Nov 2024 00:19:34 -0500 Subject: [PATCH 07/26] feat: add method to include 3D components of an entity in a packet --- Flakkari/Protocol/PacketFactory.hpp | 100 ++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/Flakkari/Protocol/PacketFactory.hpp b/Flakkari/Protocol/PacketFactory.hpp index 91cc2c6a..2d5868a2 100644 --- a/Flakkari/Protocol/PacketFactory.hpp +++ b/Flakkari/Protocol/PacketFactory.hpp @@ -245,6 +245,102 @@ class PacketFactory { } } + /** + * @brief Add all the 3D 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 add3dToPacketByEntity(Packet &packet, Engine::ECS::Registry ®istry, Engine::ECS::Entity entity) + { + auto transform = registry.getComponents()[entity]; + + if (transform.has_value()) + { + packet << ComponentId::TRANSFORM_3D; + packet << transform->_position.vec.x; + packet << transform->_position.vec.y; + packet << transform->_position.vec.z; + packet << transform->_rotation.vec.x; + packet << transform->_rotation.vec.y; + packet << transform->_rotation.vec.z; + packet << transform->_scale.vec.x; + packet << transform->_scale.vec.y; + packet << transform->_scale.vec.z; + } + + auto movable = registry.getComponents()[entity]; + + if (movable.has_value()) + { + packet << ComponentId::MOVABLE_3D; + packet << movable->_velocity.vec.x; + packet << movable->_velocity.vec.y; + packet << movable->_velocity.vec.z; + packet << movable->_acceleration.vec.x; + packet << movable->_acceleration.vec.y; + packet << movable->_acceleration.vec.z; + } + + auto control = registry.getComponents()[entity]; + + if (control.has_value()) + { + packet << ComponentId::CONTROL_3D; + packet << control->_move_up; + packet << control->_move_down; + packet << control->_move_left; + packet << control->_move_right; + packet << control->_move_front; + packet << control->_move_back; + packet << control->_look_up; + packet << control->_look_down; + packet << control->_look_left; + packet << control->_look_right; + packet << control->_shoot; + } + + auto boxCollider = registry.getComponents()[entity]; + + if (boxCollider.has_value()) + { + packet << ComponentId::BOXCOLLIDER; + packet << boxCollider->_size.vec.x; + packet << boxCollider->_size.vec.y; + packet << boxCollider->_size.vec.z; + packet << boxCollider->_center.vec.x; + packet << boxCollider->_center.vec.y; + packet << boxCollider->_center.vec.z; + } + + auto sphereCollider = registry.getComponents()[entity]; + + if (sphereCollider.has_value()) + { + packet << ComponentId::SPHERECOLLIDER; + packet << sphereCollider->_center.vec.x; + packet << sphereCollider->_center.vec.y; + packet << sphereCollider->_center.vec.z; + packet << sphereCollider->_radius; + } + + auto rigidbody = registry.getComponents()[entity]; + + if (rigidbody.has_value()) + { + packet << ComponentId::RIGIDBODY_3D; + packet << rigidbody->_mass; + packet << rigidbody->_drag; + packet << rigidbody->_angularDrag; + packet << rigidbody->_useGravity; + packet << rigidbody->_isKinematic; + } + } + + /** * @brief Add all the components of an entity to a packet. * @@ -264,6 +360,10 @@ class PacketFactory { /*_ 2D Components _*/ add2dToPacketByEntity(packet, registry, entity); + + /*_ 3D Components _*/ + + add3dToPacketByEntity(packet, registry, entity); } struct UpdateMovement { From f7d8292f693ed2bad3ec8a4235d8f2cf890bdad6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sun, 17 Nov 2024 05:19:55 +0000 Subject: [PATCH 08/26] style: apply linter --- Flakkari/Protocol/PacketFactory.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Flakkari/Protocol/PacketFactory.hpp b/Flakkari/Protocol/PacketFactory.hpp index 2d5868a2..014d2307 100644 --- a/Flakkari/Protocol/PacketFactory.hpp +++ b/Flakkari/Protocol/PacketFactory.hpp @@ -340,7 +340,6 @@ class PacketFactory { } } - /** * @brief Add all the components of an entity to a packet. * From 74d6b22bc20cdf5a1e826ae5fc3d51f47c9cc97d Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:40:29 -0500 Subject: [PATCH 09/26] feat: add Factory class for entity creation from templates --- CMakeLists.txt | 7 +- .../EntityComponentSystem/EntityFactory.hpp | 315 ------------------ .../Engine/EntityComponentSystem/Factory.cpp | 292 ++++++++++++++++ .../Engine/EntityComponentSystem/Factory.hpp | 66 ++++ 4 files changed, 360 insertions(+), 320 deletions(-) delete mode 100644 Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp create mode 100644 Flakkari/Engine/EntityComponentSystem/Factory.cpp create mode 100644 Flakkari/Engine/EntityComponentSystem/Factory.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ff9cada0..ceff11e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ set(SOURCES Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp Flakkari/Engine/EntityComponentSystem/Registry.cpp + Flakkari/Engine/EntityComponentSystem/Factory.cpp Flakkari/Server/UDPServer.cpp Flakkari/Server/Client/Client.cpp @@ -58,7 +59,7 @@ set(HEADERS Flakkari/Engine/EntityComponentSystem/Entity.hpp Flakkari/Engine/EntityComponentSystem/SparseArrays.hpp Flakkari/Engine/EntityComponentSystem/Registry.hpp - Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp + Flakkari/Engine/EntityComponentSystem/Factory.hpp Flakkari/Server/UDPServer.hpp @@ -269,10 +270,6 @@ add_library(flakkari_network SHARED ${SOURCES_LIB_NETWORK} ${HEADER_LIB_NETWORK} # Include Directories: target_include_directories(flakkari_network PRIVATE ${CMAKE_SOURCE_DIR}/Flakkari) -target_include_directories(flakkari_network PRIVATE ${singleton_SOURCE_DIR}) - -# Link Libraries: -target_link_libraries(flakkari_network PRIVATE nlohmann_json::nlohmann_json) # Install dynamic library: install(TARGETS flakkari_network DESTINATION lib) diff --git a/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp b/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp deleted file mode 100644 index a8d41642..00000000 --- a/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp +++ /dev/null @@ -1,315 +0,0 @@ -/************************************************************************** - * Flakkari Engine Library v0.4.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.4.0 - * @date 2024-01-13 - **************************************************************************/ - -#ifndef FLAKKARI_ENTITYFACTORY_HPP_ -#define FLAKKARI_ENTITYFACTORY_HPP_ - -#include - -#include "Registry.hpp" - -#include "Components/Components2D.hpp" -#include "Components/Components3D.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 == "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; - 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 == "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; - 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; - } - - //*_ 3D Components _*// - - if (componentName == "BoxCollider") - { - registry.registerComponent(); - Engine::ECS::Components::_3D::BoxCollider boxCollider; - boxCollider._size = Engine::Math::Vector3f(componentContent["size"]["x"], componentContent["size"]["y"], - componentContent["size"]["z"]); - boxCollider._center = Engine::Math::Vector3f( - componentContent["center"]["x"], componentContent["center"]["y"], componentContent["center"]["z"]); - registry.add_component(entity, std::move(boxCollider)); - continue; - } - - if (componentName == "3D_Control") - { - registry.registerComponent(); - Engine::ECS::Components::_3D::Control control; - control._move_up = componentContent["move_up"]; - control._move_down = componentContent["move_down"]; - control._move_left = componentContent["move_left"]; - control._move_right = componentContent["move_right"]; - control._move_front = componentContent["move_front"]; - control._move_back = componentContent["move_back"]; - control._look_up = componentContent["look_up"]; - control._look_down = componentContent["look_down"]; - control._look_left = componentContent["look_left"]; - control._look_right = componentContent["look_right"]; - control._shoot = componentContent["shoot"]; - registry.add_component(entity, std::move(control)); - continue; - } - - if (componentName == "3D_Movable") - { - registry.registerComponent(); - Engine::ECS::Components::_3D::Movable movable; - movable._velocity = - Engine::Math::Vector3f(componentContent["velocity"]["x"], componentContent["velocity"]["y"], - componentContent["velocity"]["z"]); - movable._acceleration = - Engine::Math::Vector3f(componentContent["acceleration"]["x"], componentContent["acceleration"]["y"], - componentContent["acceleration"]["z"]); - registry.add_component(entity, std::move(movable)); - continue; - } - - if (componentName == "RigidBody") - { - registry.registerComponent(); - Engine::ECS::Components::_3D::RigidBody rigidBody; - rigidBody._mass = componentContent["mass"]; - rigidBody._drag = componentContent["drag"]; - rigidBody._angularDrag = componentContent["angularDrag"]; - rigidBody._useGravity = componentContent["useGravity"]; - rigidBody._isKinematic = componentContent["isKinematic"]; - registry.add_component(entity, std::move(rigidBody)); - continue; - } - - if (componentName == "SphereCollider") - { - registry.registerComponent(); - Engine::ECS::Components::_3D::SphereCollider sphereCollider; - sphereCollider._center = Engine::Math::Vector3f( - componentContent["center"]["x"], componentContent["center"]["y"], componentContent["center"]["z"]); - sphereCollider._radius = componentContent["radius"]; - registry.add_component(entity, std::move(sphereCollider)); - continue; - } - - if (componentName == "3D_Transform") - { - registry.registerComponent(); - Engine::ECS::Components::_3D::Transform transform; - transform._position = - Engine::Math::Vector3f(componentContent["position"]["x"], componentContent["position"]["y"], - componentContent["position"]["z"]); - transform._rotation = - Engine::Math::Vector3f(componentContent["rotation"]["x"], componentContent["rotation"]["y"], - componentContent["rotation"]["z"]); - transform._scale = Engine::Math::Vector3f( - componentContent["scale"]["x"], componentContent["scale"]["y"], componentContent["scale"]["z"]); - 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 == "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"]); - registry.add_component(entity, std::move(parent)); - 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(); - 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; - } - - 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; - } - } - } -}; - -} // namespace Flakkari::Engine::ECS - -#endif /* !FLAKKARI_ENTITYFACTORY_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Factory.cpp b/Flakkari/Engine/EntityComponentSystem/Factory.cpp new file mode 100644 index 00000000..25af87f4 --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Factory.cpp @@ -0,0 +1,292 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2024-11-17 +** File description: +** Factory +*/ + +#include "Factory.hpp" + +namespace Flakkari::Engine::ECS::Factory { + +Entity createEntityFromTemplate(Registry ®istry, const nl_template &templateJson) +{ + Entity entity = registry.spawn_entity(); + + RegistryEntityByTemplate(registry, entity, templateJson); + + return entity; +} + +static const nl_template &getTemplateByName(const nl_templates &templates, const std::string &name) +{ + for (auto &template_ : templates.items()) + { + if (template_.value().begin().key() == name) + return template_.value().begin().value(); + } + + throw std::runtime_error("Template not found"); +} + +void RegistryEntityByTemplate(Registry ®istry, Entity entity, const nl_template &templateJson, + const nl_templates &templates) +{ + for (auto &component : templateJson.items()) + { + auto componentName = component.key(); + auto componentContent = component.value(); + + //*_ 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; + 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 == "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; + 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; + } + + //*_ 3D Components _*// + + if (componentName == "BoxCollider") + { + registry.registerComponent(); + Engine::ECS::Components::_3D::BoxCollider boxCollider; + boxCollider._size = Engine::Math::Vector3f(componentContent["size"]["x"], componentContent["size"]["y"], + componentContent["size"]["z"]); + boxCollider._center = Engine::Math::Vector3f( + componentContent["center"]["x"], componentContent["center"]["y"], componentContent["center"]["z"]); + registry.add_component(entity, std::move(boxCollider)); + continue; + } + + if (componentName == "3D_Control") + { + registry.registerComponent(); + Engine::ECS::Components::_3D::Control control; + control._move_up = componentContent["move_up"]; + control._move_down = componentContent["move_down"]; + control._move_left = componentContent["move_left"]; + control._move_right = componentContent["move_right"]; + control._move_front = componentContent["move_front"]; + control._move_back = componentContent["move_back"]; + control._look_up = componentContent["look_up"]; + control._look_down = componentContent["look_down"]; + control._look_left = componentContent["look_left"]; + control._look_right = componentContent["look_right"]; + control._shoot = componentContent["shoot"]; + registry.add_component(entity, std::move(control)); + continue; + } + + if (componentName == "3D_Movable") + { + registry.registerComponent(); + Engine::ECS::Components::_3D::Movable movable; + movable._velocity = + Engine::Math::Vector3f(componentContent["velocity"]["x"], componentContent["velocity"]["y"], + componentContent["velocity"]["z"]); + movable._acceleration = + Engine::Math::Vector3f(componentContent["acceleration"]["x"], componentContent["acceleration"]["y"], + componentContent["acceleration"]["z"]); + movable._minSpeed = componentContent["minSpeed"]; + movable._maxSpeed = componentContent["maxSpeed"]; + registry.add_component(entity, std::move(movable)); + continue; + } + + if (componentName == "RigidBody") + { + registry.registerComponent(); + Engine::ECS::Components::_3D::RigidBody rigidBody; + rigidBody._mass = componentContent["mass"]; + rigidBody._drag = componentContent["drag"]; + rigidBody._angularDrag = componentContent["angularDrag"]; + rigidBody._useGravity = componentContent["useGravity"]; + rigidBody._isKinematic = componentContent["isKinematic"]; + registry.add_component(entity, std::move(rigidBody)); + continue; + } + + if (componentName == "SphereCollider") + { + registry.registerComponent(); + Engine::ECS::Components::_3D::SphereCollider sphereCollider; + sphereCollider._center = Engine::Math::Vector3f( + componentContent["center"]["x"], componentContent["center"]["y"], componentContent["center"]["z"]); + sphereCollider._radius = componentContent["radius"]; + registry.add_component(entity, std::move(sphereCollider)); + continue; + } + + if (componentName == "3D_Transform") + { + registry.registerComponent(); + Engine::ECS::Components::_3D::Transform transform; + transform._position = + Engine::Math::Vector3f(componentContent["position"]["x"], componentContent["position"]["y"], + componentContent["position"]["z"]); + transform._rotation = + Engine::Math::Vector3f(componentContent["rotation"]["x"], componentContent["rotation"]["y"], + componentContent["rotation"]["z"]); + transform._scale = Engine::Math::Vector3f(componentContent["scale"]["x"], componentContent["scale"]["y"], + componentContent["scale"]["z"]); + registry.add_component(entity, std::move(transform)); + continue; + } + + //*_ Common Components _*// + + if (componentName == "Child") + { + registry.registerComponent(); + Engine::ECS::Components::Common::Child child(componentContent); + registry.add_component(entity, std::move(child)); + continue; + } + + if (componentName == "Evolve") + { + registry.registerComponent(); + Engine::ECS::Components::Common::Evolve evolve(componentContent); + registry.add_component(entity, std::move(evolve)); + 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); + registry.add_component(entity, std::move(parent)); + 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); + registry.add_component(entity, std::move(spawned)); + continue; + } + + if (componentName == "Tag") + { + registry.registerComponent(); + Engine::ECS::Components::Common::Tag tag(componentContent); + registry.add_component(entity, std::move(tag)); + continue; + } + + if (componentName == "Template") + { + registry.registerComponent(); + Engine::ECS::Components::Common::Template template_(componentContent, + getTemplateByName(templates, componentContent)); + registry.add_component(entity, std::move(template_)); + continue; + } + + if (componentName == "Timer") + { + registry.registerComponent(); + Engine::ECS::Components::Common::Timer timer; + timer.maxTime = componentContent["maxTime"]; + registry.add_component(entity, std::move(timer)); + continue; + } + + if (componentName == "Weapon") + { + registry.registerComponent(); + Engine::ECS::Components::Common::Weapon weapon; + weapon.minDamage = componentContent["minDamage"]; + weapon.maxDamage = componentContent["maxDamage"]; + weapon.chargeMaxTime = componentContent["chargeMaxTime"]; + weapon.fireRate = componentContent["fireRate"]; + weapon.level = componentContent["level"]; + registry.add_component(entity, std::move(weapon)); + continue; + } + } +} + +} // namespace Flakkari::Engine::ECS::Factory diff --git a/Flakkari/Engine/EntityComponentSystem/Factory.hpp b/Flakkari/Engine/EntityComponentSystem/Factory.hpp new file mode 100644 index 00000000..b0ac6310 --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Factory.hpp @@ -0,0 +1,66 @@ +/************************************************************************** + * Flakkari Engine Library v0.4.0 + * + * Flakkari Library is a C++ Library for Network. + * @file Factory.hpp + * @brief Flakkari::Engine::ECS::Factory functions 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.4.0 + * @date 2024-01-13 + **************************************************************************/ + +#ifndef FLAKKARI_ECS_FACTORY_HPP_ +#define FLAKKARI_ECS_FACTORY_HPP_ + +#include + +#include "Registry.hpp" + +#include "Components/Components2D.hpp" +#include "Components/Components3D.hpp" +#include "Components/ComponentsCommon.hpp" + +namespace Flakkari::Engine::ECS::Factory { + +using nl_template = nlohmann::json; +using nl_templates = + nlohmann::basic_json>, void>; + +/** + * @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 + */ +Entity createEntityFromTemplate(Registry ®istry, const nl_template &templateJson); + +/** + * @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 + */ +void RegistryEntityByTemplate(Registry ®istry, Entity entity, const nl_template &templateJson, + const nl_templates &templates = nl_templates()); + +} // namespace Flakkari::Engine::ECS::Factory + +#endif /* !FLAKKARI_ECS_FACTORY_HPP_ */ From 448368b24770b61329792669850f039ff49fccbc Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:41:34 -0500 Subject: [PATCH 10/26] feat: temporary shutdown the workflows --- .github/workflows/build_checker.yml | 1 + .github/workflows/linter.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/build_checker.yml b/.github/workflows/build_checker.yml index 3923b7ab..45a92c18 100644 --- a/.github/workflows/build_checker.yml +++ b/.github/workflows/build_checker.yml @@ -5,6 +5,7 @@ on: branches-ignore: - 'ga-ignore-**' - 'gh-pages' + branches: [master, main] jobs: build_checker_windows: diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index ca8829e6..890a2057 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -5,6 +5,7 @@ on: branches-ignore: - 'ga-ignore-**' - 'gh-pages' + branches: [master, main] permissions: contents: write From 6f0bf1bcc5ba3136752a9b15d8a588f85fdf0a80 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:42:46 -0500 Subject: [PATCH 11/26] feat: add Timer component for ECS entities and update includes --- .../Components/Common/Timer.hpp | 52 +++++++++++++++++++ .../Components/Components3D.hpp | 4 +- .../Components/ComponentsCommon.hpp | 1 + 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 Flakkari/Engine/EntityComponentSystem/Components/Common/Timer.hpp diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Timer.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Timer.hpp new file mode 100644 index 00000000..5b13bc62 --- /dev/null +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Timer.hpp @@ -0,0 +1,52 @@ +/* +** EPITECH PROJECT, 2024 +** Title: Flakkari +** Author: MasterLaplace +** Created: 2024-11-17 +** File description: +** Timer +*/ + +#ifndef Timer_HPP_ +#define Timer_HPP_ + +#include +#include +#include + +#include "config.h.in" + +namespace Flakkari::Engine::ECS::Components::Common { +LPL_PACKED_START + +/** + * @brief Timer component for ECS entities that have a timer attached to them + * + * @details This component is used to store the current time and the maximum time + */ +struct Timer { + std::chrono::steady_clock::time_point lastTime = std::chrono::steady_clock::now(); + float maxTime; + + Timer() : maxTime(0) {} + Timer(bool spawed) : maxTime(spawed) {} + Timer(const Timer &other) : maxTime(other.maxTime) {} + + Timer &operator=(const Timer &other) + { + if (this != &other) + { + lastTime = other.lastTime; + maxTime = other.maxTime; + } + + return *this; + } + + std::size_t size() const { return sizeof(*this); } +}; + +LPL_PACKED_END +} // namespace Flakkari::Engine::ECS::Components::Common + +#endif /* !Timer_HPP_ */ diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Components3D.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Components3D.hpp index 216883ce..f77ccb14 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Components3D.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Components3D.hpp @@ -17,8 +17,8 @@ #define FLAKKARI_COMPONENTS3D_HPP_ #include "3D/BoxCollider.hpp" // Collider component (center, size) -#include "3D/Control.hpp" // Control component (up, down, left, right, shoot) -#include "3D/Movable.hpp" // Movable component (velocity, acceleration) +#include "3D/Control.hpp" // Control component (move_[up, down, left, right, ...], look_[*] shoot) +#include "3D/Movable.hpp" // Movable component (velocity, acceleration, minSpeed, maxSpeed) #include "3D/RigidBody.hpp" // RigidBody component (mass, drag, angularDrag, useGravity, isKinematic) #include "3D/SphereCollider.hpp" // Collider component (center, radius) #include "3D/Transform.hpp" // Transform component (position, rotation, scale) diff --git a/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp b/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp index 930811bc..5c00db04 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/ComponentsCommon.hpp @@ -26,6 +26,7 @@ #include "Common/Spawned.hpp" // Spawned component (spawned) #include "Common/Tag.hpp" // Tag component (tag) #include "Common/Template.hpp" // Template component (name) +#include "Common/Timer.hpp" // Timer component (time) #include "Common/Weapon.hpp" // Weapon component (name) #include "Common/NetworkEvent.hpp" // NetworkEvent component (event) From d23dc05236f8a31538f6a59a4a4b1e504eefa3b9 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:44:10 -0500 Subject: [PATCH 12/26] feat: add minimum and maximum speed properties to Movable and RigidBody components, and adjust the Weapon structure to manage minimum and maximum damage --- .../Components/3D/Control.hpp | 15 +++++++++-- .../Components/3D/Movable.hpp | 14 +++++++--- .../Components/3D/RigidBody.hpp | 1 + .../Components/3D/Transform.hpp | 4 +-- .../Components/Common/Weapon.hpp | 26 +++++++++++++------ Flakkari/Engine/Math/Vector.hpp | 1 + 6 files changed, 45 insertions(+), 16 deletions(-) diff --git a/Flakkari/Engine/EntityComponentSystem/Components/3D/Control.hpp b/Flakkari/Engine/EntityComponentSystem/Components/3D/Control.hpp index 6cfe4fa5..33c39b34 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/3D/Control.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/3D/Control.hpp @@ -30,6 +30,7 @@ LPL_PACKED_START * _look_left: look left (give access to the look left) * _look_right: look right (give access to the look right) * _shoot: shoot (give access to the shoot) + * _padding: padding to align the size of the struct */ struct Control { bool _move_up = false; @@ -43,17 +44,19 @@ struct Control { bool _look_left = false; bool _look_right = false; bool _shoot = false; + uint8_t _padding : 5 = 0; Control() = default; Control(bool m_up, bool m_down, bool m_left, bool m_right, bool m_front, bool m_back, bool l_up, bool l_down, bool l_left, bool l_right, bool s) : _move_up(m_up), _move_down(m_down), _move_left(m_left), _move_right(m_right), _move_front(m_front), - _move_back(m_back), _look_up(l_up), _look_down(l_down), _look_left(l_left), _look_right(l_right), _shoot(s){}; + _move_back(m_back), _look_up(l_up), _look_down(l_down), _look_left(l_left), _look_right(l_right), + _shoot(s) {}; Control(const Control &other) : _move_up(other._move_up), _move_down(other._move_down), _move_left(other._move_left), _move_right(other._move_right), _move_front(other._move_front), _move_back(other._move_back), _look_up(other._look_up), _look_down(other._look_down), _look_left(other._look_left), - _look_right(other._look_right), _shoot(other._shoot){}; + _look_right(other._look_right), _shoot(other._shoot) {}; Control &operator=(const Control &other) { @@ -75,6 +78,14 @@ struct Control { return *this; } + unsigned short toSerialized() + { + return static_cast((_move_up << 0) | (_move_down << 1) | (_move_left << 2) | + (_move_right << 3) | (_move_front << 4) | (_move_back << 5) | + (_look_up << 6) | (_look_down << 7) | (_look_left << 8) | + (_look_right << 9) | (_shoot << 10)); + } + std::size_t size() const { return sizeof(*this); } }; diff --git a/Flakkari/Engine/EntityComponentSystem/Components/3D/Movable.hpp b/Flakkari/Engine/EntityComponentSystem/Components/3D/Movable.hpp index dc48b855..66187557 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/3D/Movable.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/3D/Movable.hpp @@ -21,11 +21,15 @@ LPL_PACKED_START struct Movable { Math::Vector3f _velocity; Math::Vector3f _acceleration; + float _minSpeed; + float _maxSpeed; - Movable() : _velocity(0, 0), _acceleration(0, 0) {} - Movable(const Math::Vector3f &velocity, const Math::Vector3f &acceleration) - : _velocity(velocity), _acceleration(acceleration){}; - Movable(const Movable &other) : _velocity(other._velocity), _acceleration(other._acceleration){}; + Movable() : _velocity(0, 0), _acceleration(0, 0), _minSpeed(0), _maxSpeed(0) {}; + Movable(const Math::Vector3f &velocity, const Math::Vector3f &acceleration, float minSpeed, float maxSpeed) + : _velocity(velocity), _acceleration(acceleration), _minSpeed(minSpeed), _maxSpeed(maxSpeed) {}; + Movable(const Movable &other) + : _velocity(other._velocity), _acceleration(other._acceleration), _minSpeed(other._minSpeed), + _maxSpeed(other._maxSpeed) {}; Movable &operator=(const Movable &other) { @@ -33,6 +37,8 @@ struct Movable { { _velocity = other._velocity; _acceleration = other._acceleration; + _minSpeed = other._minSpeed; + _maxSpeed = other._maxSpeed; } return *this; diff --git a/Flakkari/Engine/EntityComponentSystem/Components/3D/RigidBody.hpp b/Flakkari/Engine/EntityComponentSystem/Components/3D/RigidBody.hpp index 03271c74..474b55ae 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/3D/RigidBody.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/3D/RigidBody.hpp @@ -24,6 +24,7 @@ struct RigidBody { float _angularDrag; bool _useGravity = true; bool _isKinematic = false; + uint8_t padding : 6 = 0; RigidBody() : _mass(0), _drag(0), _angularDrag(0), _useGravity(false), _isKinematic(false){}; RigidBody(const RigidBody &other) diff --git a/Flakkari/Engine/EntityComponentSystem/Components/3D/Transform.hpp b/Flakkari/Engine/EntityComponentSystem/Components/3D/Transform.hpp index 4751216d..4b1868ed 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/3D/Transform.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/3D/Transform.hpp @@ -21,10 +21,10 @@ LPL_PACKED_START struct Transform { Math::Vector3f _position; Math::Vector3f _scale; - Math::Vector3f _rotation; + Math::Quaternion _rotation; Transform() : _position(0, 0, 0), _scale(1, 1, 1), _rotation(0, 0, 0){}; - Transform(const Math::Vector2f &position, const Math::Vector2f &scale, const Math::Vector3f &rotation) + Transform(const Math::Vector3f &position, const Math::Vector3f &scale, const Math::Quaternion &rotation) : _position(position), _scale(scale), _rotation(rotation){}; Transform(const Transform &other) : _position(other._position), _scale(other._scale), _rotation(other._rotation){}; diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Weapon.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Weapon.hpp index d3d01924..fca03252 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Weapon.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Weapon.hpp @@ -26,28 +26,38 @@ LPL_PACKED_START * It is used by the WeaponComponent to handle the firing and reloading logic. * * @param - * damage: The amount of damage dealt by the weapon. + * minDamage: The amount of damage dealt by the weapon. + * maxDamage: The maximum amount of damage dealt by the weapon. + * chargeTime: The time it takes to shoot a charged bullet. + * chargeMaxTime: The maximum time it takes to charge a bullet at max power. + * isCharging: A flag that indicates if the weapon is charging. * 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 { - std::size_t damage; + std::size_t minDamage; + std::size_t maxDamage; + float chargeTime = 0; + float chargeMaxTime; + bool isCharging = false; + float timeSinceLastShot = 0; float fireRate; std::size_t level; Weapon() = default; Weapon(const Weapon &other) = default; - Weapon(std::size_t dmg, float rate, std::size_t lvl) : damage(dmg), fireRate(rate), level(lvl){}; + Weapon(std::size_t min_dmg, std::size_t max_dmg, float chargeMax, float rate, std::size_t lvl) + : minDamage(min_dmg), maxDamage(max_dmg), chargeMaxTime(chargeMax), fireRate(rate), level(lvl) {}; Weapon &operator=(const Weapon &other) { if (this != &other) { - damage = other.damage; + minDamage = other.minDamage; + maxDamage = other.maxDamage; + chargeTime = other.chargeTime; + chargeMaxTime = other.chargeMaxTime; + isCharging = other.isCharging; fireRate = other.fireRate; level = other.level; } diff --git a/Flakkari/Engine/Math/Vector.hpp b/Flakkari/Engine/Math/Vector.hpp index 1e31f8b5..1dcea0d0 100644 --- a/Flakkari/Engine/Math/Vector.hpp +++ b/Flakkari/Engine/Math/Vector.hpp @@ -335,6 +335,7 @@ using Vector4f = Vector; using Vector4d = Vector; using Vector4i = Vector; using Vector4u = Vector; +using Quaternion = Vector4f; using Color = Vector4f; template std::ostream &operator<<(std::ostream &os, const Vector &vector); From 44b34104176c395717caeef1057883b8b53a9284 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:44:54 -0500 Subject: [PATCH 13/26] feat: add content property to Template struct and update constructors and assignment operator --- .../Components/Common/Template.hpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp index 9cff97b1..a6ef316d 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Template.hpp @@ -10,21 +10,26 @@ #ifndef FLAKKARI_TEMPLATE_HPP_ #define FLAKKARI_TEMPLATE_HPP_ +#include #include namespace Flakkari::Engine::ECS::Components::Common { struct Template { std::string name; + nlohmann::json content; - Template() : name("") {} - Template(const std::string &nname) : name(nname) {} - Template(const Template &other) : name(other.name) {} + Template() : name(""), content(nlohmann::json::object()) {} + Template(const std::string &name, const nlohmann::json &content) : name(name), content(content) {} + Template(const Template &other) : name(other.name), content(other.content) {} Template &operator=(const Template &other) { if (this != &other) + { name = other.name; + content = other.content; + } return *this; } From 094f5b4b31b8e8a0770ef8ba503c4caffc2fb168 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:45:53 -0500 Subject: [PATCH 14/26] feat: refactor addCommonsToPacketByEntity to include additional components and improve packet serialization --- Flakkari/Protocol/PacketFactory.hpp | 263 +++++++++++----------------- 1 file changed, 99 insertions(+), 164 deletions(-) diff --git a/Flakkari/Protocol/PacketFactory.hpp b/Flakkari/Protocol/PacketFactory.hpp index 014d2307..b1f4d255 100644 --- a/Flakkari/Protocol/PacketFactory.hpp +++ b/Flakkari/Protocol/PacketFactory.hpp @@ -26,72 +26,99 @@ 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 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()[entity]; + + if (child.has_value()) { + packet << Protocol::ComponentId::CHILD; + packet.injectString(child->name); + } + + auto evolve = registry.getComponents()[entity]; + + if (evolve.has_value()) { + packet << Protocol::ComponentId::EVOLVE; + packet.injectString(evolve->name); + } + + auto health = registry.getComponents()[entity]; + + if (health.has_value()) { + packet << Protocol::ComponentId::HEALTH; + packet << health->currentHealth; + packet << health->maxHealth; + packet << health->shield; + packet << health->maxShield; + } + + auto id = registry.getComponents()[entity]; + + if (id.has_value()) { + packet << Protocol::ComponentId::ID; + packet << id->id; + } + + auto level = registry.getComponents()[entity]; + + if (level.has_value()) { + packet << Protocol::ComponentId::LEVEL; + packet << level->level; + packet.injectString(level->currentWeapon); + packet << level->currentExp; + packet << level->requiredExp; + } + + auto parent = registry.getComponents()[entity]; + + if (parent.has_value()) { + packet << Protocol::ComponentId::PARENT; + packet << parent->entity; + } + + auto tag = registry.getComponents()[entity]; + + if (tag.has_value()) { + packet << Protocol::ComponentId::TAG; + packet.injectString(tag->tag); + } + + auto template_ = registry.getComponents()[entity]; + + if (template_.has_value()) { + packet << Protocol::ComponentId::TEMPLATE; + packet.injectString(template_->name); + } + + auto timer = registry.getComponents()[entity]; + + if (timer.has_value()) { + packet << Protocol::ComponentId::TIMER; + packet << timer->lastTime.time_since_epoch().count(); + packet << timer->maxTime; + } + + auto weapon = registry.getComponents()[entity]; + + if (weapon.has_value()) { + packet << Protocol::ComponentId::WEAPON; + packet << weapon->minDamage; + packet << weapon->maxDamage; + packet << weapon->chargeMaxTime; + packet << weapon->fireRate; + packet << weapon->level; + } + } /** * @brief Add all the 2D components of an entity to a packet. @@ -159,90 +186,6 @@ class PacketFactory { packet << rigidbody->_gravityScale; packet << rigidbody->_isKinematic; } - - auto health = registry.getComponents()[entity]; - - if (health.has_value()) - { - packet << ComponentId::HEALTH; - packet << health->currentHealth; - packet << health->maxHealth; - packet << health->shield; - packet << health->maxShield; - } - - auto weapon = registry.getComponents()[entity]; - - if (weapon.has_value()) - { - packet << ComponentId::WEAPON; - packet << weapon->damage; - packet << weapon->fireRate; - packet << weapon->level; - } - - auto level = registry.getComponents()[entity]; - - if (level.has_value()) - { - packet << ComponentId::LEVEL; - packet << level->level; - packet.injectString(level->currentWeapon); - packet << level->currentExp; - packet << level->requiredExp; - } - - auto spawned = registry.getComponents()[entity]; - - if (spawned.has_value()) - { - packet << ComponentId::SPAWNED; - packet << spawned->has_spawned; - } - - auto networkEvent = registry.getComponents()[entity]; - - if (networkEvent.has_value()) - { - packet << ComponentId::NETWORK_EVENT; - packet << networkEvent->events.size(); - for (auto &event : networkEvent->events) - { - packet << event; - } - } - - auto templateName = registry.getComponents()[entity]; - - if (templateName.has_value()) - { - packet << ComponentId::TEMPLATE; - packet.injectString(templateName->name); - } - - auto parent = registry.getComponents()[entity]; - - if (parent.has_value()) - { - packet << ComponentId::PARENT; - packet << parent->entity; - } - - auto child = registry.getComponents()[entity]; - - if (child.has_value()) - { - packet << ComponentId::CHILD; - packet.injectString(child->name); - } - - auto tag = registry.getComponents()[entity]; - - if (tag.has_value()) - { - packet << ComponentId::TAG; - packet.injectString(tag->tag); - } } /** @@ -267,6 +210,7 @@ class PacketFactory { packet << transform->_rotation.vec.x; packet << transform->_rotation.vec.y; packet << transform->_rotation.vec.z; + packet << transform->_rotation.vec.w; packet << transform->_scale.vec.x; packet << transform->_scale.vec.y; packet << transform->_scale.vec.z; @@ -283,6 +227,8 @@ class PacketFactory { packet << movable->_acceleration.vec.x; packet << movable->_acceleration.vec.y; packet << movable->_acceleration.vec.z; + packet << movable->_minSpeed; + packet << movable->_maxSpeed; } auto control = registry.getComponents()[entity]; @@ -290,17 +236,7 @@ class PacketFactory { if (control.has_value()) { packet << ComponentId::CONTROL_3D; - packet << control->_move_up; - packet << control->_move_down; - packet << control->_move_left; - packet << control->_move_right; - packet << control->_move_front; - packet << control->_move_back; - packet << control->_look_up; - packet << control->_look_down; - packet << control->_look_left; - packet << control->_look_right; - packet << control->_shoot; + packet << control.value().toSerialized(); } auto boxCollider = registry.getComponents()[entity]; @@ -335,8 +271,7 @@ class PacketFactory { packet << rigidbody->_mass; packet << rigidbody->_drag; packet << rigidbody->_angularDrag; - packet << rigidbody->_useGravity; - packet << rigidbody->_isKinematic; + packet << (byte)rigidbody->_useGravity; } } @@ -354,7 +289,7 @@ class PacketFactory { { /*_ Common Components _*/ - // addCommonsToPacketByEntity(packet, registry, entity); + addCommonsToPacketByEntity(packet, registry, entity); /*_ 2D Components _*/ From 498a279de1fe10a551962a9439602de091133b14 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:46:34 -0500 Subject: [PATCH 15/26] feat: reorganise component and event identifiers for greater clarity and consistency --- Flakkari/Protocol/Components.hpp | 33 +++++++++---------- Flakkari/Protocol/Events.hpp | 55 +++++++++++++++++++++----------- 2 files changed, 51 insertions(+), 37 deletions(-) diff --git a/Flakkari/Protocol/Components.hpp b/Flakkari/Protocol/Components.hpp index bb668666..655db7f3 100644 --- a/Flakkari/Protocol/Components.hpp +++ b/Flakkari/Protocol/Components.hpp @@ -96,21 +96,19 @@ enum class ComponentId : uint8_t { RIGIDBODY_3D = 15, // 20 - 29: Common components CHILD = 20, - PARENT = 21, - TAG = 22, - SPAWNED = 23, - TEMPLATE = 24, - WEAPON = 25, - LEVEL = 26, - EVOLVE = 27, - HEALTH = 28, - // 30 - 39: Network components - NETWORK_EVENT = 30, - NETWORK_IP = 31, + EVOLVE = 21, + HEALTH = 22, + ID = 23, + LEVEL = 24, + PARENT = 25, + TAG = 26, + TEMPLATE = 27, + TIMER = 28, + WEAPON = 29, MAX_COMPONENT }; -static_assert(static_cast(ComponentId::MAX_COMPONENT) <= 40, "ComponentId::MAX_COMPONENT is too big"); +static_assert(static_cast(ComponentId::MAX_COMPONENT) <= 30, "ComponentId::MAX_COMPONENT is too big"); class Components final { public: @@ -130,16 +128,15 @@ class Components final { case ComponentId::RIGIDBODY: return "RIGIDBODY"; case ComponentId::RIGIDBODY_3D: return "RIGIDBODY_3D"; case ComponentId::CHILD: return "CHILD"; + case ComponentId::EVOLVE: return "EVOLVE"; + case ComponentId::HEALTH: return "HEALTH"; + case ComponentId::ID: return "ID"; + case ComponentId::LEVEL: return "LEVEL"; case ComponentId::PARENT: return "PARENT"; case ComponentId::TAG: return "TAG"; - case ComponentId::SPAWNED: return "SPAWNED"; case ComponentId::TEMPLATE: return "TEMPLATE"; + case ComponentId::TIMER: return "TIMER"; case ComponentId::WEAPON: return "WEAPON"; - case ComponentId::LEVEL: return "LEVEL"; - case ComponentId::EVOLVE: return "EVOLVE"; - case ComponentId::HEALTH: return "HEALTH"; - case ComponentId::NETWORK_EVENT: return "NETWORK_EVENT"; - case ComponentId::NETWORK_IP: return "NETWORK_IP"; default: return "UNKNOWN"; } } diff --git a/Flakkari/Protocol/Events.hpp b/Flakkari/Protocol/Events.hpp index fec3be79..1b224353 100644 --- a/Flakkari/Protocol/Events.hpp +++ b/Flakkari/Protocol/Events.hpp @@ -24,11 +24,15 @@ namespace Flakkari::Protocol { namespace V_0 { enum class EventId : uint8_t { - MOVE_LEFT = 10, - MOVE_RIGHT = 11, - MOVE_UP = 12, - MOVE_DOWN = 13, - SHOOT = 14, + MOVE_LEFT = 0, + MOVE_RIGHT = 1, + MOVE_UP = 2, + MOVE_DOWN = 3, + SHOOT = 4, + MAX_EVENT +}; + +enum class EventAxisId : uint8_t { MAX_EVENT }; @@ -46,6 +50,10 @@ struct Event { V_0::EventState state; }; +struct EventAxis { + V_0::EventAxisId id; +}; + LPL_PACKED_END } /* namespace V_0 */ @@ -53,24 +61,28 @@ LPL_PACKED_END inline namespace V_1 { enum class EventId : uint8_t { - MOVE_LEFT = 10, - MOVE_RIGHT = 11, - MOVE_UP = 12, - MOVE_DOWN = 13, - MOVE_FRONT = 14, - MOVE_BACK = 15, - LOOK_LEFT = 16, - LOOK_RIGHT = 17, - LOOK_UP = 18, - LOOK_DOWN = 19, - SHOOT = 20, + MOVE_LEFT = 0, + MOVE_RIGHT = 1, + MOVE_UP = 2, + MOVE_DOWN = 3, + MOVE_FRONT = 4, + MOVE_BACK = 5, + SHOOT = 10, + MAX_EVENT +}; + +enum class EventAxisId : uint8_t { + LOOK_LEFT = 1, + LOOK_RIGHT = 2, + LOOK_UP = 3, + LOOK_DOWN = 4, + SHOOT = 5, MAX_EVENT }; enum class EventState : uint8_t { - NONE = 0, - PRESSED = 1, - RELEASED = 2, + PRESSED = 0, + RELEASED = 1, MAX_STATE }; @@ -81,6 +93,11 @@ struct Event { V_1::EventState state; }; +struct EventAxis { + V_1::EventAxisId id; + float value; +}; + LPL_PACKED_END } /* namespace V_1 */ From c90df9ff453bd0909be1d49b0f39b50c7a05197e Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:47:36 -0500 Subject: [PATCH 16/26] feat: implement equality operator and hash function for Entity, update type definitions and header structure for improved clarity and consistency --- .../Engine/EntityComponentSystem/Entity.hpp | 18 +++++++++++++ Flakkari/Protocol/Header.hpp | 26 ++++++++++++++----- Flakkari/Protocol/Packet.hpp | 8 +++--- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/Flakkari/Engine/EntityComponentSystem/Entity.hpp b/Flakkari/Engine/EntityComponentSystem/Entity.hpp index 6ee6464e..f3babb1f 100644 --- a/Flakkari/Engine/EntityComponentSystem/Entity.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Entity.hpp @@ -43,10 +43,28 @@ class Entity { return *this; } + bool operator==(const Entity& other) const { + return _id == other._id; + } + + std::size_t getId() const { return _id; } + private: std::size_t _id; }; } // namespace Flakkari::Engine::ECS +#include + +namespace std { + template <> + struct hash + { + size_t operator()(const Flakkari::Engine::ECS::Entity& entity) const noexcept { + return std::hash()(entity.getId()); + } + }; +} + #endif /* !FLAKKARI_ENTITY_HPP_ */ diff --git a/Flakkari/Protocol/Header.hpp b/Flakkari/Protocol/Header.hpp index 20686eef..ed24e720 100644 --- a/Flakkari/Protocol/Header.hpp +++ b/Flakkari/Protocol/Header.hpp @@ -28,9 +28,9 @@ namespace Flakkari::Protocol { -using ushort = unsigned short; // 16 bits (max: 65535) -using uint = unsigned int; // 32 bits (max: 4294967295) -using ulong = unsigned long; // 64 bits (max: 18446744073709551615) +using ushort = uint16_t; // 16 bits (max: 65535) (2 bytes) +using uint = uint32_t; // 32 bits (max: 4294967295) (4 bytes) +using ulong = uint64_t; // 64 bits (max: 18446744073709551615) (8 bytes) /** * @brief The version of the protocol used @@ -78,14 +78,28 @@ inline namespace V_1 { LPL_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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Priority|Api V.| CommandId | ContentLength | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | SequenceNumber | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ template struct Header { Priority _priority : 4 = Priority::LOW; ApiVersion _apiVersion : 4 = ApiVersion::V_1; Id _commandId; - ushort _contentLength = 0; - uint _sequenceNumber = static_cast( - std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) + uint16_t _contentLength = 0; + uint64_t _sequenceNumber = + static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) .count()); + + std::size_t size() const { return sizeof(*this); } }; LPL_PACKED_END diff --git a/Flakkari/Protocol/Packet.hpp b/Flakkari/Protocol/Packet.hpp index 47908f98..49ac8af7 100644 --- a/Flakkari/Protocol/Packet.hpp +++ b/Flakkari/Protocol/Packet.hpp @@ -153,9 +153,9 @@ template struct Packet { */ [[nodiscard]] bool deserialize(const Network::Buffer &buffer) { - if (buffer.size() < sizeof(header)) + if (buffer.size() < header.size()) return FLAKKARI_LOG_WARNING("Buffer is too small to deserialize a packet."), false; - std::memcpy(&header, buffer.data(), sizeof(header)); + std::memcpy(&header, buffer.data(), header.size()); if (header._priority >= Priority::MAX_PRIORITY) return FLAKKARI_LOG_WARNING("Priority is too big (" + std::to_string((int) header._priority) + ")"), false; if (header._apiVersion >= ApiVersion::MAX_VERSION) @@ -164,9 +164,9 @@ template struct Packet { if (header._commandId >= CommandId::MAX_COMMAND_ID) return FLAKKARI_LOG_WARNING("CommandId is too big (" + std::to_string((int) header._commandId) + ")"), false; - if (header._contentLength > buffer.size() - sizeof(header)) + if (header._contentLength > buffer.size() - header.size()) return false; - payload = buffer.extractData(sizeof(header), header._contentLength); + payload = buffer.extractData(header.size(), header._contentLength); return true; } }; From 56cafd7300b1a2dca15843442f6714b998c499a6 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:49:15 -0500 Subject: [PATCH 17/26] feat: refactor game management logic, update includes, and add isClientWaiting method for improved client handling --- Flakkari/Server/Game/Game.hpp | 13 +++++-------- Flakkari/Server/Game/GameManager.cpp | 12 ++++++++++-- Flakkari/Server/Game/GameManager.hpp | 9 +++++++++ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Flakkari/Server/Game/Game.hpp b/Flakkari/Server/Game/Game.hpp index a17679df..00694ad0 100644 --- a/Flakkari/Server/Game/Game.hpp +++ b/Flakkari/Server/Game/Game.hpp @@ -24,7 +24,7 @@ #include #include -#include "Engine/EntityComponentSystem/EntityFactory.hpp" +#include "Engine/EntityComponentSystem/Factory.hpp" #include "Engine/EntityComponentSystem/Systems/Systems.hpp" #include "Protocol/PacketFactory.hpp" @@ -35,7 +35,8 @@ namespace Flakkari { class Client; -using nl_entity = nlohmann::detail::iteration_proxy>; +using nl_entity = nlohmann::json_abi_v3_11_3::detail::iteration_proxy_value< + nlohmann::json_abi_v3_11_3::detail::iter_impl>; using nl_template = nlohmann::basic_json>, void>; @@ -136,16 +137,12 @@ class Game { void update(); /** - * @brief Start the game. This function is called when the game is - * launched. It will start the game loop. - * + * @brief Start the game. This function is called when the game is launched. It will start the game loop. */ void start(); /** - * @brief Run the game. This function is called when the game is - * started. It will run the game loop. - * + * @brief Run the game. This function is called when the game is started. It will run the game loop. */ void run(); diff --git a/Flakkari/Server/Game/GameManager.cpp b/Flakkari/Server/Game/GameManager.cpp index f1c38285..30ca84cc 100644 --- a/Flakkari/Server/Game/GameManager.cpp +++ b/Flakkari/Server/Game/GameManager.cpp @@ -169,9 +169,9 @@ void GameManager::removeClientFromGame(const std::string &gameName, const std::s if (instance->getPlayers().empty()) { - _gamesInstances[gameName].erase( - std::find(_gamesInstances[gameName].begin(), _gamesInstances[gameName].end(), instance)); + _gamesInstances[gameName].pop_back(); FLAKKARI_LOG_INFO("game \"" + gameName + "\" removed"); + break; } else if (instance->getPlayers().size() > minPlayers) { @@ -193,6 +193,14 @@ void GameManager::removeClientFromGame(const std::string &gameName, const std::s FLAKKARI_LOG_ERROR("could not remove client \"" + STR_ADDRESS + "\" from game \"" + gameName + "\""); } +bool GameManager::isClientWaiting(const std::string &gameName) +{ + if (_gamesStore.find(gameName) == _gamesStore.end()) + return FLAKKARI_LOG_ERROR("game not found"), true; + + return _waitingClients[gameName].empty(); +} + int GameManager::getIndexInWaitingQueue(const std::string &gameName, const std::shared_ptr &client) { if (_gamesStore.find(gameName) == _gamesStore.end()) diff --git a/Flakkari/Server/Game/GameManager.hpp b/Flakkari/Server/Game/GameManager.hpp index 3a3368ad..60ae4a8c 100644 --- a/Flakkari/Server/Game/GameManager.hpp +++ b/Flakkari/Server/Game/GameManager.hpp @@ -107,6 +107,15 @@ class GameManager : public Singleton { */ void removeClientFromGame(const std::string &gameName, const std::shared_ptr &client); + /** + * @brief Get if a player is waiting in the waiting queue of a game + * + * @param gameName Game to check + * @return true No player is waiting + * @return false A player is waiting + */ + [[nodiscard]] bool isClientWaiting(const std::string &gameName); + /** * @brief Get the index of a client in the waiting queue * From 34e4754c72e1a7d93afb90aea958a8bea0fe86e7 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:51:40 -0500 Subject: [PATCH 18/26] feat: refactor game loader methods for improved clarity and consistency in parameter naming and functionality --- Flakkari/Server/Game/Game.cpp | 309 ++++++++-------------------------- Flakkari/Server/Game/Game.hpp | 37 ++-- 2 files changed, 86 insertions(+), 260 deletions(-) diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index 4d83bb77..f660ee48 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -15,31 +15,6 @@ namespace Flakkari { -void Game::sendAllEntities(const std::string &sceneName, std::shared_ptr player) -{ - auto ®istry = _scenes[sceneName]; - - auto &transforms = registry.getComponents(); - - for (Engine::ECS::Entity i(0); i < transforms.size(); ++i) - { - auto &transform = transforms[i]; - - if (!transform.has_value()) - continue; - - Protocol::Packet packet; - packet.header._commandId = Protocol::CommandId::REQ_ENTITY_SPAWN; - packet.header._apiVersion = player->getApiVersion(); - packet << i; - packet.injectString(sceneName); - Protocol::PacketFactory::addComponentsToPacketByEntity(packet, registry, i); - - ClientManager::GetInstance().sendPacketToClient(player->getAddress(), packet.serialize()); - ClientManager::UnlockInstance(); - } -} - Game::Game(const std::string &name, std::shared_ptr config) { _name = name; @@ -64,219 +39,74 @@ Game::~Game() FLAKKARI_LOG_INFO("game \"" + _name + "\" is now stopped"); } -void Game::loadSystems(Engine::ECS::Registry ®istry, const std::string &name) +void Game::loadSystems(Engine::ECS::Registry ®istry, const std::string &sceneName, const std::string &sysName) { - if (name == "position") + if (sysName == "position") registry.add_system([this](Engine::ECS::Registry &r) { Engine::ECS::Systems::_2D::position(r, _deltaTime); }); else if (name == "apply_movable") registry.add_system( [this](Engine::ECS::Registry &r) { Engine::ECS::Systems::_3D::apply_movable(r, _deltaTime); }); - else if (name == "spawn_random_within_skybox") - registry.add_system([](Engine::ECS::Registry &r) { Engine::ECS::Systems::_3D::spawn_random_within_skybox(r); }); - - else if (name == "handle_collisions") - registry.add_system([](Engine::ECS::Registry &r) { Engine::ECS::Systems::_3D::handle_collisions(r); }); -} - -void Game::loadComponents(Engine::ECS::Registry ®istry, const nl_component &components, - Engine::ECS::Entity newEntity) -{ - if (!components.is_object()) - return; - for (auto &component : components.items()) - { - auto componentName = component.key(); - auto componentContent = component.value(); - - //*_ 2D Components _*// - - 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(newEntity, std::move(transform)); - 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(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; - } - - //*_ 3D Components _*// + else if (sysName == "spawn_enemy") + registry.add_system([this, sceneName](Engine::ECS::Registry &r) { + std::string templateName; + Engine::ECS::Entity entity; + if (Engine::ECS::Systems::_3D::spawn_enemy(r, templateName, entity)) + { + Protocol::Packet packet; + packet.header._commandId = Protocol::CommandId::REQ_ENTITY_SPAWN; + packet << entity; + packet.injectString(templateName); - if (componentName == "BoxCollider") - { - registry.registerComponent(); - Engine::ECS::Components::_3D::BoxCollider boxCollider; - boxCollider._size = Engine::Math::Vector3f(componentContent["size"]["x"], componentContent["size"]["y"], - componentContent["size"]["z"]); - boxCollider._center = Engine::Math::Vector3f( - componentContent["center"]["x"], componentContent["center"]["y"], componentContent["center"]["z"]); - registry.add_component(newEntity, std::move(boxCollider)); - continue; - } + Protocol::PacketFactory::addComponentsToPacketByEntity(packet, r, entity); - if (componentName == "3D_Control") - { - registry.registerComponent(); - Engine::ECS::Components::_3D::Control control; - control._move_up = componentContent["move_up"]; - control._move_down = componentContent["move_down"]; - control._move_left = componentContent["move_left"]; - control._move_right = componentContent["move_right"]; - control._move_front = componentContent["move_front"]; - control._move_back = componentContent["move_back"]; - control._look_up = componentContent["look_up"]; - control._look_down = componentContent["look_down"]; - control._look_left = componentContent["look_left"]; - control._look_right = componentContent["look_right"]; - control._shoot = componentContent["shoot"]; - registry.add_component(newEntity, std::move(control)); - continue; - } + this->sendOnSameScene(sceneName, packet); + } + }); - if (componentName == "3D_Movable") - { - registry.registerComponent(); - Engine::ECS::Components::_3D::Movable movable; - movable._velocity = - Engine::Math::Vector3f(componentContent["velocity"]["x"], componentContent["velocity"]["y"], - componentContent["velocity"]["z"]); - movable._acceleration = - Engine::Math::Vector3f(componentContent["acceleration"]["x"], componentContent["acceleration"]["y"], - componentContent["acceleration"]["z"]); - registry.add_component(newEntity, std::move(movable)); - continue; - } + else if (sysName == "spawn_random_within_skybox") + registry.add_system([this, sceneName](Engine::ECS::Registry &r) { + std::vector entities(10); + Engine::ECS::Systems::_3D::spawn_random_within_skybox(r, entities); - if (componentName == "RigidBody") - { - registry.registerComponent(); - Engine::ECS::Components::_3D::RigidBody rigidBody; - rigidBody._mass = componentContent["mass"]; - rigidBody._drag = componentContent["drag"]; - rigidBody._angularDrag = componentContent["angularDrag"]; - rigidBody._useGravity = componentContent["useGravity"]; - rigidBody._isKinematic = componentContent["isKinematic"]; - registry.add_component(newEntity, std::move(rigidBody)); - continue; - } + for (auto &entity : entities) + { + Protocol::Packet packet; + packet.header._commandId = Protocol::CommandId::REQ_ENTITY_UPDATE; + packet << entity; - if (componentName == "SphereCollider") - { - registry.registerComponent(); - Engine::ECS::Components::_3D::SphereCollider sphereCollider; - sphereCollider._center = Engine::Math::Vector3f( - componentContent["center"]["x"], componentContent["center"]["y"], componentContent["center"]["z"]); - sphereCollider._radius = componentContent["radius"]; - registry.add_component(newEntity, std::move(sphereCollider)); - continue; - } + Protocol::PacketFactory::addComponentsToPacketByEntity(packet, r, entity); - if (componentName == "3D_Transform") - { - registry.registerComponent(); - Engine::ECS::Components::_3D::Transform transform; - transform._position = - Engine::Math::Vector3f(componentContent["position"]["x"], componentContent["position"]["y"], - componentContent["position"]["z"]); - transform._rotation = - Engine::Math::Vector3f(componentContent["rotation"]["x"], componentContent["rotation"]["y"], - componentContent["rotation"]["z"]); - transform._scale = Engine::Math::Vector3f(componentContent["scale"]["x"], componentContent["scale"]["y"], - componentContent["scale"]["z"]); - registry.add_component(newEntity, std::move(transform)); - continue; - } + this->sendOnSameScene(sceneName, packet); + } + }); - //*_ Common Components _*// + else if (sysName == "handle_collisions") + registry.add_system([this, sceneName](Engine::ECS::Registry &r) { + std::unordered_map entities; + Engine::ECS::Systems::_3D::handle_collisions(r, entities); - 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)); + for (auto &entity : entities) + { + if (!entity.second) + { + Protocol::Packet packet; + packet.header._commandId = Protocol::CommandId::REQ_ENTITY_DESTROY; + packet << entity.first; + this->sendOnSameScene(sceneName, packet); 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; - } + Protocol::Packet packet; + packet.header._commandId = Protocol::CommandId::REQ_ENTITY_UPDATE; + packet << entity.first; - if (componentName == "Tag") - { - registry.registerComponent(); - Engine::ECS::Components::Common::Tag tag; - tag.tag = componentContent.get().c_str(); - registry.add_component(newEntity, std::move(tag)); - continue; - } + Protocol::PacketFactory::addComponentsToPacketByEntity(packet, r, entity.first); - 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; + this->sendOnSameScene(sceneName, packet); } - - 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; - } - } + }); } void Game::loadEntityFromTemplate(Engine::ECS::Registry ®istry, const nl_entity &entity, @@ -284,16 +114,12 @@ void Game::loadEntityFromTemplate(Engine::ECS::Registry ®istry, const nl_enti { Engine::ECS::Entity newEntity = registry.spawn_entity(); - for (auto &componentInfo : entity.begin().value().items()) - { for (auto &templateInfo : templates.items()) { - if (templateInfo.key() != componentInfo.key()) + if (entity.value() != templateInfo.value().begin().key()) continue; - loadComponents(registry, templateInfo.value(), newEntity); - registry.registerComponent(); - registry.add_component(newEntity, templateInfo.key()); - } + Engine::ECS::Factory::RegistryEntityByTemplate(registry, newEntity, templateInfo.value().begin().value(), + templates); } } @@ -308,10 +134,10 @@ void Game::loadScene(const std::string &sceneName) Engine::ECS::Registry registry; for (auto &system : sceneInfo.value()["systems"].items()) - loadSystems(registry, system.value()); + loadSystems(registry, sceneName, system.value()); for (auto &entity : sceneInfo.value()["entities"].items()) - loadEntityFromTemplate(registry, entity.value().items(), sceneInfo.value()["templates"]); + loadEntityFromTemplate(registry, entity, sceneInfo.value()["templates"]); _scenes[sceneName] = registry; return; @@ -373,30 +199,38 @@ void Game::checkDisconnect() } } -void Game::sendUpdatePosition(std::shared_ptr player, Engine::ECS::Components::_2D::Transform pos, - Engine::ECS::Components::_2D::Movable vel) +void Game::sendUpdatePosition(std::shared_ptr player, Engine::ECS::Components::_3D::Transform pos, + Engine::ECS::Components::_3D::Movable vel) { Protocol::Packet packet; packet.header._commandId = Protocol::CommandId::REQ_ENTITY_MOVED; packet << player->getEntity(); packet << pos._position.vec.x; packet << pos._position.vec.y; - packet << pos._rotation; + packet << pos._position.vec.z; + packet << pos._rotation.vec.x; + packet << pos._rotation.vec.y; + packet << pos._rotation.vec.z; + packet << pos._rotation.vec.w; packet << pos._scale.vec.x; packet << pos._scale.vec.y; + packet << pos._scale.vec.z; packet << vel._velocity.vec.x; packet << vel._velocity.vec.y; + packet << vel._velocity.vec.z; packet << vel._acceleration.vec.x; packet << vel._acceleration.vec.y; + packet << vel._acceleration.vec.z; FLAKKARI_LOG_LOG("packet size: " + std::to_string(packet.size()) + " bytes\n" "packet sent: getEntity()) + ", Pos: (" + std::to_string(pos._position.vec.x) + ", " + - std::to_string(pos._position.vec.y) + ")" + ", Vel: (" + std::to_string(vel._velocity.vec.x) + - ", " + std::to_string(vel._velocity.vec.y) + ")" + ", Acc: (" + - std::to_string(vel._acceleration.vec.x) + ", " + std::to_string(vel._acceleration.vec.y) + ")" + - ">"); + std::to_string(pos._position.vec.y) + ", " + std::to_string(pos._position.vec.z) + ")" + + ", Vel: (" + std::to_string(vel._velocity.vec.x) + ", " + std::to_string(vel._velocity.vec.y) + + ", " + std::to_string(vel._velocity.vec.z) + ")" + ", Acc: (" + + std::to_string(vel._acceleration.vec.x) + ", " + std::to_string(vel._acceleration.vec.y) + ", " + + std::to_string(vel._acceleration.vec.z) + ")" + ">"); sendOnSameScene(player->getSceneName(), packet); } @@ -404,11 +238,10 @@ void Game::handleEvent(std::shared_ptr player, Protocol::PacketgetSceneName(); auto entity = player->getEntity(); - auto ®istry = _scenes[sceneName]; - auto &ctrl = registry.getComponents()[entity]; - auto &vel = registry.getComponents()[entity]; - auto &pos = registry.getComponents()[entity]; - auto &netEvent = registry.getComponents()[entity]; + auto ®istry = _scenes[player->getSceneName()]; + auto &ctrl = registry.getComponents()[entity]; + auto &vel = registry.getComponents()[entity]; + auto &pos = registry.getComponents()[entity]; if (!ctrl.has_value() || !vel.has_value() || !pos.has_value()) return; diff --git a/Flakkari/Server/Game/Game.hpp b/Flakkari/Server/Game/Game.hpp index 00694ad0..c372accb 100644 --- a/Flakkari/Server/Game/Game.hpp +++ b/Flakkari/Server/Game/Game.hpp @@ -62,19 +62,10 @@ class Game { * @brief Add all the systems of the game to the registry. * * @param registry Registry to add the systems to. - * @param name Name of the scene to load. - */ - void loadSystems(Engine::ECS::Registry ®istry, const std::string &name); - - /** - * @brief Add all the components of the game to the registry. - * - * @param registry Registry to add the components to. - * @param componentInfo Info of the components to add. - * @param newEntity Entity to add the components to. + * @param sceneName Name of the scene to load. + * @param sysName Name of the system to load. */ - void loadComponents(Engine::ECS::Registry ®istry, const nl_component &componentInfo, - Engine::ECS::Entity newEntity); + void loadSystems(Engine::ECS::Registry ®istry, const std::string &sceneName, const std::string &sysName); /** * @brief Add all the entities of the game to the registry. @@ -93,7 +84,6 @@ class Game { void loadScene(const std::string &name); public: // Actions - void sendAllEntities(const std::string &sceneName, std::shared_ptr player); void sendOnSameScene(const std::string &sceneName, Protocol::Packet &packet); void sendOnSameSceneExcept(const std::string &sceneName, Protocol::Packet &packet, @@ -112,23 +102,26 @@ class Game { * @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); + void sendUpdatePosition(std::shared_ptr player, Engine::ECS::Components::_3D::Transform pos, + Engine::ECS::Components::_3D::Movable vel); /** - * @brief Handle an event from a player. + * @brief Handle the events from a player. * * @param player Player that sent the event. - * @param packet Packet containing the event. + * @param packet Packet containing the events. */ - void handleEvent(std::shared_ptr player, Protocol::Packet packet); + void handleEvents(std::shared_ptr player, Protocol::Packet packet); /** - * @brief Empty the incoming packets of the players and update the - * game with the new packets. - * + * @brief Empty the incoming packets of the players and update the game with the new packets. + */ + void updateIncomingPackets(unsigned char maxMessagePerFrame = 20); + + /** + * @brief Empty the outcoming packets of the players. */ - void updateIncomingPackets(unsigned char maxMessagePerFrame = 10); + void updateOutcomingPackets(unsigned char maxMessagePerFrame = 20); /** * @brief Update the game. This function is called every frame. From 7461a56b975923d8454553ddac36bda14696c7ae Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:53:13 -0500 Subject: [PATCH 19/26] feat: simplify client management logic and improve packet handling for player connections and removals --- Flakkari/Server/Client/ClientManager.cpp | 5 ++--- Flakkari/Server/Game/Game.cpp | 28 +++++++----------------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/Flakkari/Server/Client/ClientManager.cpp b/Flakkari/Server/Client/ClientManager.cpp index 7613b4e9..d6168666 100644 --- a/Flakkari/Server/Client/ClientManager.cpp +++ b/Flakkari/Server/Client/ClientManager.cpp @@ -75,11 +75,10 @@ void ClientManager::checkInactiveClients() { FLAKKARI_LOG_LOG("Client " + it->first + " disconnected"); it = _clients.erase(it); + continue; } - else - { + ++it; - } } } diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index f660ee48..d1aa7dae 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -403,38 +403,26 @@ bool Game::addPlayer(std::shared_ptr player) auto p_Template = (*_config)["playerTemplate"]; auto player_info = ResourceManager::GetInstance().getTemplateById(_name, sceneGame, p_Template); - loadComponents(registry, player_info.value_or(nullptr), newEntity); + Engine::ECS::Factory::RegistryEntityByTemplate(registry, newEntity, player_info.value()); ResourceManager::UnlockInstance(); - registry.registerComponent(); - registry.add_component( - newEntity, Engine::ECS::Components::Common::NetworkIp(std::string(*address))); - - 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(*address) + "\" added to game \"" + _name + "\""); - // this->sendAllEntities(sceneGame, player); // send all entities to the new player - Protocol::Packet packet; - packet.header._commandId = Protocol::CommandId::REP_CONNECT; packet.header._apiVersion = player->getApiVersion(); + packet.header._commandId = Protocol::CommandId::REP_CONNECT; packet << newEntity; - packet.injectString(sceneGame); - packet.injectString(player->getName().value_or("")); packet.injectString(p_Template); - ClientManager::GetInstance().sendPacketToClient(address, packet.serialize()); - ClientManager::UnlockInstance(); + + player->addPacketToSendQueue(packet); Protocol::Packet packet2; - packet2.header._commandId = Protocol::CommandId::REQ_ENTITY_SPAWN; packet2.header._apiVersion = packet.header._apiVersion; + packet2.header._commandId = Protocol::CommandId::REQ_ENTITY_SPAWN; packet2 << newEntity; - packet2.injectString(sceneGame); packet2.injectString(p_Template); sendOnSameSceneExcept(sceneGame, packet2, player); @@ -456,10 +444,10 @@ bool Game::removePlayer(std::shared_ptr player) packet.header._commandId = Protocol::CommandId::REQ_ENTITY_DESTROY; packet << entity; - sendOnSameScene(sceneGame, packet); - - registry.kill_entity(entity); _players.erase(it); + registry.kill_entity(entity); + + sendOnSameScene(sceneGame, packet); FLAKKARI_LOG_INFO("client \"" + std::string(*player->getAddress()) + "\" removed from game \"" + _name + "\""); return true; } From 2e3b8b125c637bee69cd7b24cf07520464340e54 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:56:54 -0500 Subject: [PATCH 20/26] feat: update system header to include new entity spawning and collision handling functions with improved parameters --- .../EntityComponentSystem/Systems/Systems.cpp | 158 ++++++++++++++---- .../EntityComponentSystem/Systems/Systems.hpp | 33 +++- 2 files changed, 153 insertions(+), 38 deletions(-) diff --git a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp index 6b22fcca..7988e9a0 100644 --- a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp +++ b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp @@ -91,12 +91,12 @@ void apply_movable(Registry &r, float deltaTime) auto &pos = positions[i]; auto &vel = velocities[i]; - if (pos.has_value() && vel.has_value()) - { - pos->_position.vec.x += vel->_velocity.vec.x * vel->_acceleration.vec.x * deltaTime; - pos->_position.vec.y += vel->_velocity.vec.y * vel->_acceleration.vec.y * deltaTime; - pos->_position.vec.z += vel->_velocity.vec.z * vel->_acceleration.vec.z * deltaTime; - } + if (!pos.has_value() || !vel.has_value()) + continue; + + pos->_position.vec.x += vel->_velocity.vec.x * vel->_acceleration.vec.x * deltaTime; + pos->_position.vec.y += vel->_velocity.vec.y * vel->_acceleration.vec.y * deltaTime; + pos->_position.vec.z += vel->_velocity.vec.z * vel->_acceleration.vec.z * deltaTime; } } @@ -105,7 +105,7 @@ static float randomRange(float min, float max) return min + static_cast(rand()) / (static_cast(RAND_MAX / (max - min))); } -void spawn_random_within_skybox(Registry &r) +void spawn_random_within_skybox(Registry &r, std::vector &entities) { if (!r.isRegistered() || !r.isRegistered() || !r.isRegistered()) @@ -113,6 +113,7 @@ void spawn_random_within_skybox(Registry &r) auto &transforms = r.getComponents(); auto &tags = r.getComponents(); + auto &boxcollier = r.getComponents(); auto &spawned = r.getComponents(); float maxRangeX = 0; @@ -123,16 +124,17 @@ void spawn_random_within_skybox(Registry &r) { auto &transform = transforms[i]; auto &tag = tags[i]; + auto &box = boxcollier[i]; - if (transform.has_value() && tag.has_value()) + if (!transform.has_value() || !tag.has_value() || !box.has_value()) + continue; + + if (tag->tag == "Skybox") { - if (tag->tag == "Skybox") - { - maxRangeX = transform->_scale.vec.x / 2; - maxRangeY = transform->_scale.vec.y / 2; - maxRangeZ = transform->_scale.vec.z / 2; - break; - } + maxRangeX = (box->_size.dimension.width * transform->_scale.vec.x) / 2; + maxRangeY = (box->_size.dimension.height * transform->_scale.vec.y) / 2; + maxRangeZ = (box->_size.dimension.depth * transform->_scale.vec.z) / 2; + break; } } @@ -142,28 +144,110 @@ void spawn_random_within_skybox(Registry &r) auto &tag = tags[i]; auto &spawn = spawned[i]; - if (transform.has_value() && tag.has_value() && !spawn.has_value()) + if (!transform.has_value() || !tag.has_value() || !spawn.has_value()) + continue; + + if ((tag->tag == "Player" || tag->tag == "Enemy") && spawn->has_spawned == false) { - if ((tag->tag == "Player" || tag->tag == "Enemy") && spawn->has_spawned == false) - { - transform->_position.vec.x = randomRange(-maxRangeX, maxRangeX); - transform->_position.vec.y = randomRange(-maxRangeY, maxRangeY); - transform->_position.vec.z = randomRange(-maxRangeZ, maxRangeZ); - spawn->has_spawned = true; - } + transform->_position.vec.x = randomRange(-maxRangeX, maxRangeX); + transform->_position.vec.y = randomRange(-maxRangeY, maxRangeY); + transform->_position.vec.z = randomRange(-maxRangeZ, maxRangeZ); + spawn->has_spawned = true; + entities.emplace_back(i); } } } -static void handleDeath(Registry &r, Entity bullet, Entity entity) +static size_t count_entities(Registry &r, const std::string &tag) +{ + if (!r.isRegistered()) + return 0; + + auto &tags = r.getComponents(); + size_t count = 0; + + for (Entity i(0); i < tags.size(); ++i) + { + auto &tagComponent = tags[i]; + + if (!tagComponent.has_value()) + continue; + + if (tagComponent->tag == tag) + count++; + } + + return count; +} + +bool spawn_enemy(Registry &r, std::string &templateName, Entity &entity) +{ + if (!r.isRegistered() || !r.isRegistered() || + !r.isRegistered()) + return false; + + auto &transforms = r.getComponents(); + auto &tags = r.getComponents(); + auto &boxcollier = r.getComponents(); + auto &timers = r.getComponents(); + auto &templates = r.getComponents(); + + float maxRangeX = 0; + float maxRangeY = 0; + float maxRangeZ = 0; + + for (Entity i(0); i < transforms.size() && i < tags.size(); ++i) + { + auto &transform = transforms[i]; + auto &tag = tags[i]; + auto &box = boxcollier[i]; + auto &timer = timers[i]; + auto &template_ = templates[i]; + + if (!transform.has_value() || !tag.has_value() || !box.has_value() || !timer.has_value() || + !template_.has_value()) + continue; + + if (tag->tag != "Skybox") + continue; + + maxRangeX = (box->_size.dimension.width * transform->_scale.vec.x) / 2; + maxRangeY = (box->_size.dimension.height * transform->_scale.vec.y) / 2; + maxRangeZ = (box->_size.dimension.depth * transform->_scale.vec.z) / 2; + + auto now = std::chrono::steady_clock::now(); + auto duration = std::chrono::duration_cast(now - timer->lastTime); + if (duration.count() <= timer->maxTime * 1000) + return false; + + std::cout << "Time since last spawn: " << duration.count() << std::endl; + + timer->lastTime = now; + if (count_entities(r, "Enemy") >= 10) + return false; + + entity = r.spawn_entity(); + templateName = template_->name; + Factory::RegistryEntityByTemplate(r, entity, template_->content); + return true; + } + return false; +} + +static void handleDeath(Registry &r, Entity bullet, Entity entity, std::unordered_map &entities) { auto &health = r.getComponents(entity); auto &weapon = r.getComponents(bullet); - health->currentHealth -= weapon->damage; + health->currentHealth -= weapon->minDamage; + entities[entity] = true; if (health->currentHealth <= 0) - r.kill_entity(entity); - r.kill_entity(bullet); + { + r.kill_entity(entity); // send death event to client + entities[entity] = false; + } + r.kill_entity(bullet); // send destroy event to client + entities[entity] = false; } static bool BoxCollisions(const Components::_3D::Transform &pos1, const Components::_3D::BoxCollider &col1, @@ -243,7 +327,7 @@ static bool outOfSkybox(float maxRangeX, float maxRangeY, float maxRangeZ, const pos._position.vec.y > maxRangeY || pos._position.vec.z < -maxRangeZ || pos._position.vec.z > maxRangeZ; } -void handle_collisions(Registry &r) +void handle_collisions(Registry &r, std::unordered_map &entities) { auto &transforms = r.getComponents(); auto &boxcollider = r.getComponents(); @@ -287,17 +371,22 @@ void handle_collisions(Registry &r) pos1->_position.vec.x = std::max(-maxRangeX, std::min(maxRangeX, pos1->_position.vec.x)); pos1->_position.vec.y = std::max(-maxRangeY, std::min(maxRangeY, pos1->_position.vec.y)); pos1->_position.vec.z = std::max(-maxRangeZ, std::min(maxRangeZ, pos1->_position.vec.z)); + + entities[i] = true; } else if (tag1->tag == "Enemy" && outOfSkybox(maxRangeX, maxRangeY, maxRangeZ, *pos1)) { pos1->_position.vec.x = std::max(-maxRangeX, std::min(maxRangeX, pos1->_position.vec.x)); pos1->_position.vec.y = std::max(-maxRangeY, std::min(maxRangeY, pos1->_position.vec.y)); pos1->_position.vec.z = std::max(-maxRangeZ, std::min(maxRangeZ, pos1->_position.vec.z)); + + entities[i] = true; } else if (tag1->tag == "Bullet" && outOfSkybox(maxRangeX, maxRangeY, maxRangeZ, *pos1)) { r.kill_entity(i); bulletKilled = true; + entities[i] = false; } for (Entity j(i + 1); j < transforms.size() && j < tags.size(); ++j) @@ -331,19 +420,21 @@ void handle_collisions(Registry &r) vel1->_velocity = reflectVelocity(vel1->_velocity, normal); vel2->_velocity = reflectVelocity(vel2->_velocity, normal); } + + entities[i] = true; } } else if (tag2->tag == "Bullet" && tag1->tag == "Enemy" && scol1.has_value() && bcol2.has_value()) { if (r.isRegistered(i) && SphereBoxCollisions(pos1.value(), scol1.value(), pos2.value(), bcol2.value())) - handleDeath(r, j, i); + handleDeath(r, j, i, entities); } else if (tag2->tag == "Bullet" && tag1->tag == "Player" && scol1.has_value() && bcol2.has_value()) { if (r.isRegistered(i) && SphereBoxCollisions(pos1.value(), scol1.value(), pos2.value(), bcol2.value())) - handleDeath(r, j, i); + handleDeath(r, j, i, entities); } else if (bulletKilled) continue; @@ -354,19 +445,22 @@ void handle_collisions(Registry &r) { r.kill_entity(i); r.kill_entity(j); + + entities[i] = false; + entities[j] = false; } } else if (tag1->tag == "Bullet" && tag2->tag == "Enemy" && scol2.has_value() && bcol1.has_value()) { if (r.isRegistered(j) && SphereBoxCollisions(pos2.value(), scol2.value(), pos1.value(), bcol1.value())) - handleDeath(r, i, j); + handleDeath(r, i, j, entities); } else if (tag1->tag == "Bullet" && tag2->tag == "Player" && scol2.has_value() && bcol1.has_value()) { if (r.isRegistered(j) && SphereBoxCollisions(pos2.value(), scol2.value(), pos1.value(), bcol1.value())) - handleDeath(r, i, j); + handleDeath(r, i, j, entities); } } bulletKilled = false; diff --git a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.hpp b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.hpp index 03bcccfd..7f3f8fca 100644 --- a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.hpp @@ -16,10 +16,7 @@ #ifndef FLAKKARI_SYSTEMS_HPP_ #define FLAKKARI_SYSTEMS_HPP_ -#include "../Components/Components2D.hpp" -#include "../Components/Components3D.hpp" -#include "../Components/ComponentsCommon.hpp" -#include "../Registry.hpp" +#include "../Factory.hpp" #include #include @@ -53,15 +50,39 @@ void apply_movable(Registry &r, float deltaTime); * @brief Spawns a random entity within a skybox. * * @param r The registry containing the entities to update. + * @param entities The updated entities. */ -void spawn_random_within_skybox(Registry &r); +void spawn_random_within_skybox(Registry &r, std::vector &entities); + +/** + * @brief Spawns an enemy entity. + * + * @param r The registry containing the entities to update. + * @param templateName The name of the template to use for the enemy entity. + * @param entity The entity to spawn. + * @return true if the enemy was spawned, false otherwise. + */ +bool spawn_enemy(Registry &r, std::string &templateName, Entity &entity); /** * @brief Handles collisions between entities. * * @param r The registry containing the entities to update. + * @param entities The updated entities map. + * + * @details This function will handle collisions between entities. + * It will check if the entities are out of the skybox and resolve the collision. + * It will also check for collisions between entities with a BoxCollider component. + * If a collision is detected, it will resolve the collision. + * + * @details This function will also handle the death of entities. + * If an entity's health reaches 0, it will be killed. + * + * @details The entities map will store the updated or killed entity + * - false means the entity is killed + * - true means the entity was updated */ -void handle_collisions(Registry &r); +void handle_collisions(Registry &r, std::unordered_map &entities); } // namespace Flakkari::Engine::ECS::Systems::_3D From 525f6f98ea48655f3ad2ca931537992cd1adffda Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 15:59:18 -0500 Subject: [PATCH 21/26] feat: rename packet queue methods for clarity and add separate send queue handling in Client class --- Flakkari/Server/Client/Client.cpp | 8 ++++- Flakkari/Server/Client/Client.hpp | 12 ++++++- Flakkari/Server/Client/ClientManager.cpp | 2 +- Flakkari/Server/Game/Game.cpp | 43 ++++++++++++++++++------ 4 files changed, 51 insertions(+), 14 deletions(-) diff --git a/Flakkari/Server/Client/Client.cpp b/Flakkari/Server/Client/Client.cpp index 79c6c21b..6b00719f 100644 --- a/Flakkari/Server/Client/Client.cpp +++ b/Flakkari/Server/Client/Client.cpp @@ -44,10 +44,16 @@ bool Client::incrementWarningCount() return _warningCount >= _maxWarningCount; } -void Client::addPacketToQueue(const Protocol::Packet &packet) +void Client::addPacketToReceiveQueue(const Protocol::Packet &packet) { _apiVersion = packet.header._apiVersion; _receiveQueue.push_back(packet); } +void Client::addPacketToSendQueue(const Protocol::Packet &packet) +{ + _apiVersion = packet.header._apiVersion; + _sendQueue.push_back(packet); +} + } /* namespace Flakkari */ diff --git a/Flakkari/Server/Client/Client.hpp b/Flakkari/Server/Client/Client.hpp index 797a0d1b..cf637e7e 100644 --- a/Flakkari/Server/Client/Client.hpp +++ b/Flakkari/Server/Client/Client.hpp @@ -81,13 +81,21 @@ class Client { */ bool incrementWarningCount(); + /** + * @brief Add a packet to the client's receive queue and set the api version + * used by the client + * + * @param packet The packet to add + */ + void addPacketToReceiveQueue(const Protocol::Packet &packet); + /** * @brief Add a packet to the client's send queue and set the api version * used by the client * * @param packet The packet to add */ - void addPacketToQueue(const Protocol::Packet &packet); + void addPacketToSendQueue(const Protocol::Packet &packet); /** * @brief Get the client's address @@ -126,6 +134,8 @@ class Client { return _receiveQueue; } + [[nodiscard]] Network::PacketQueue> &getSendQueue() { return _sendQueue; } + private: std::chrono::steady_clock::time_point _lastActivity; std::shared_ptr _address; diff --git a/Flakkari/Server/Client/ClientManager.cpp b/Flakkari/Server/Client/ClientManager.cpp index d6168666..0ae2c23f 100644 --- a/Flakkari/Server/Client/ClientManager.cpp +++ b/Flakkari/Server/Client/ClientManager.cpp @@ -130,7 +130,7 @@ ClientManager::receivePacketFromClient(const std::shared_ptr & if (packet.deserialize(buffer)) { FLAKKARI_LOG_LOG("Client " + clientName + " sent a valid packet: " + packet.to_string()); - tmp_client->addPacketToQueue(packet); + tmp_client->addPacketToReceiveQueue(packet); return std::nullopt; } diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index d1aa7dae..acebe639 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -44,7 +44,7 @@ void Game::loadSystems(Engine::ECS::Registry ®istry, const std::string &scene if (sysName == "position") registry.add_system([this](Engine::ECS::Registry &r) { Engine::ECS::Systems::_2D::position(r, _deltaTime); }); - else if (name == "apply_movable") + else if (sysName == "apply_movable") registry.add_system( [this](Engine::ECS::Registry &r) { Engine::ECS::Systems::_3D::apply_movable(r, _deltaTime); }); @@ -158,8 +158,7 @@ void Game::sendOnSameScene(const std::string &sceneName, Protocol::PacketgetApiVersion(); - ClientManager::GetInstance().sendPacketToClient(player->getAddress(), packet.serialize()); - ClientManager::UnlockInstance(); + player->addPacketToSendQueue(packet); } } @@ -179,8 +178,7 @@ void Game::sendOnSameSceneExcept(const std::string &sceneName, Protocol::Packet< packet.header._apiVersion = player->getApiVersion(); - ClientManager::GetInstance().sendPacketToClient(player->getAddress(), packet.serialize()); - ClientManager::UnlockInstance(); + player->addPacketToSendQueue(packet); } } @@ -343,21 +341,44 @@ void Game::updateIncomingPackets(unsigned char maxMessagePerFrame) FLAKKARI_LOG_INFO("packet received: " + packet.to_string()); messageCount--; - if (packet.header._commandId == Protocol::CommandId::REQ_USER_UPDATE) - handleEvent(player, packet); + if (packet.header._commandId == Protocol::CommandId::REQ_USER_UPDATES) + handleEvents(player, packet); - if (packet.header._commandId == Protocol::CommandId::REQ_HEARTBEAT) + else if (packet.header._commandId == Protocol::CommandId::REQ_HEARTBEAT) { Protocol::Packet repPacket; - repPacket.header._commandId = Protocol::CommandId::REP_HEARTBEAT; repPacket.header._apiVersion = packet.header._apiVersion; - ClientManager::GetInstance().sendPacketToClient(player->getAddress(), repPacket.serialize()); - ClientManager::UnlockInstance(); + repPacket.header._commandId = Protocol::CommandId::REP_HEARTBEAT; + + player->addPacketToSendQueue(repPacket); } } } } +void Game::updateOutcomingPackets(unsigned char maxMessagePerFrame) +{ + for (auto &player : _players) + { + if (!player->isConnected()) + continue; + auto &packets = player->getSendQueue(); + auto messageCount = maxMessagePerFrame; + + Network::Buffer buffer; + + while (!packets.empty() && messageCount > 0) + { + auto packet = packets.pop_front(); + messageCount--; + + buffer += packet.serialize(); + ClientManager::GetInstance().sendPacketToClient(player->getAddress(), buffer); + ClientManager::UnlockInstance(); + } + } +} + void Game::update() { auto now = std::chrono::steady_clock::now(); From 7cf56e7246762350a99ac8cc1549e75ed19d2698 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 16:01:33 -0500 Subject: [PATCH 22/26] feat: refactor event handling logic to improve movement and look controls, separating move event processing into a dedicated function --- Flakkari/Server/Game/Game.cpp | 172 ++++++++++++++++++++-------------- 1 file changed, 104 insertions(+), 68 deletions(-) diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index acebe639..8e1c584a 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -232,9 +232,67 @@ void Game::sendUpdatePosition(std::shared_ptr player, Engine::ECS::Compo sendOnSameScene(player->getSceneName(), packet); } -void Game::handleEvent(std::shared_ptr player, Protocol::Packet packet) +static bool handleMoveEvent(Protocol::Event &event, Engine::ECS::Components::_3D::Control &ctrl, + Engine::ECS::Components::_3D::Movable &vel, Engine::ECS::Components::_3D::Transform &pos) +{ + auto setAcceleration = [&](const Engine::Math::Vector3f &acceleration) { + vel._acceleration = pos._rotation * acceleration; + }; + + switch (event.id) + { + //////////////////////////////////////////////////////////////////////////// + //? C# (Unity) + // Math::Vector3f direction = playerCamera.transform.forward * velocity; + // playerCamera.transform.position += direction * Time.deltaTime; + //? C++ (Flakkari) + // vel._acceleration = pos._rotation * Math::Vector3f(0, 0, 1); + // pos._position += vel._velocity * vel._acceleration * _deltaTime; + //////////////////////////////////////////////////////////////////////////// + case Protocol::EventId::MOVE_FRONT: + if (ctrl._move_front) + setAcceleration(event.state == Protocol::EventState::PRESSED ? Engine::Math::Vector3f(0, 0, 1) : + Engine::Math::Vector3f(0, 0, 0)); + return true; + //////////////////////////////////////////////////////////////////////////// + //? C# (Unity) + // Vector3 direction = playerCamera.transform.forward * velocity; + // playerCamera.transform.position += -direction * Time.deltaTime; + //? C++ (Flakkari) + // vel._acceleration = pos._rotation * Math::Vector3f(0, 0, -1); + // pos._position += vel._velocity * vel._acceleration * _deltaTime; + //////////////////////////////////////////////////////////////////////////// + case Protocol::EventId::MOVE_BACK: + if (ctrl._move_back) + setAcceleration(event.state == Protocol::EventState::PRESSED ? Engine::Math::Vector3f(0, 0, -1) : + Engine::Math::Vector3f(0, 0, 0)); + return true; + case Protocol::EventId::MOVE_RIGHT: + if (ctrl._move_right) + vel._acceleration = event.state == Protocol::EventState::PRESSED ? Engine::Math::Vector3f(1, 0, 0) : + Engine::Math::Vector3f(0, 0, 0); + return true; + case Protocol::EventId::MOVE_LEFT: + if (ctrl._move_left) + vel._acceleration = event.state == Protocol::EventState::PRESSED ? Engine::Math::Vector3f(-1, 0, 0) : + Engine::Math::Vector3f(0, 0, 0); + return true; + case Protocol::EventId::MOVE_UP: + if (ctrl._move_up) + vel._acceleration = event.state == Protocol::EventState::PRESSED ? Engine::Math::Vector3f(0, 1, 0) : + Engine::Math::Vector3f(0, 0, 0); + return true; + case Protocol::EventId::MOVE_DOWN: + if (ctrl._move_down) + vel._acceleration = event.state == Protocol::EventState::PRESSED ? Engine::Math::Vector3f(0, -1, 0) : + Engine::Math::Vector3f(0, 0, 0); + return true; + default: return false; + } +} + +void Game::handleEvents(std::shared_ptr player, Protocol::Packet packet) { - auto sceneName = player->getSceneName(); auto entity = player->getEntity(); auto ®istry = _scenes[player->getSceneName()]; auto &ctrl = registry.getComponents()[entity]; @@ -244,85 +302,61 @@ void Game::handleEvent(std::shared_ptr player, Protocol::Packet_up) - { - if (netEvent->events.size() < size_t(event.id)) - netEvent->events.resize(size_t(event.id) + 1); - netEvent->events[size_t(event.id)] = (unsigned short) event.state; + // there is the number of the events in the two first (size of ushort) byte of the payload + uint16_t count_events = *(uint16_t *) packet.payload.data(); + // there is the number of the axis events in the two next (size of ushort) byte of the payload after the events + uint16_t count_axis = + *(uint16_t *) (packet.payload.data() + sizeof(uint16_t) + count_events * sizeof(Protocol::Event)); - FLAKKARI_LOG_INFO("event: " + std::to_string(int(event.id)) + " " + std::to_string(int(event.state))); + // jump to the first event + auto data = packet.payload.data() + sizeof(uint16_t); - if (event.state == Protocol::EventState::PRESSED) - vel->_velocity.vec.y = -1; - if (event.state == Protocol::EventState::RELEASED) - vel->_velocity.vec.y = 0; - sendUpdatePosition(player, pos.value(), vel.value()); - return; - } - if (event.id == Protocol::EventId::MOVE_DOWN && ctrl->_down) + for (uint16_t i = 0; i < count_events; ++i) { - if (netEvent->events.size() < size_t(event.id)) - netEvent->events.resize(size_t(event.id) + 1); - netEvent->events[size_t(event.id)] = (unsigned short) event.state; + Protocol::Event event = *(Protocol::Event *) (data + i * sizeof(Protocol::Event)); - FLAKKARI_LOG_INFO("event: " + std::to_string(int(event.id)) + " " + std::to_string(int(event.state))); - - if (event.state == Protocol::EventState::PRESSED) - vel->_velocity.vec.y = 1; - if (event.state == Protocol::EventState::RELEASED) - vel->_velocity.vec.y = 0; + if (handleMoveEvent(event, ctrl.value(), vel.value(), pos.value())) + { + FLAKKARI_LOG_DEBUG("event: " + std::to_string(int(event.id)) + " " + std::to_string(int(event.state))); sendUpdatePosition(player, pos.value(), vel.value()); - return; + continue; } - if (event.id == Protocol::EventId::MOVE_LEFT && ctrl->_left) - { - if (netEvent->events.size() < size_t(event.id)) - netEvent->events.resize(size_t(event.id) + 1); - netEvent->events[size_t(event.id)] = (unsigned short) event.state; - - FLAKKARI_LOG_INFO("event: " + std::to_string(int(event.id)) + " " + std::to_string(int(event.state))); - + else if (event.id == Protocol::EventId::SHOOT && ctrl->_shoot) + { if (event.state == Protocol::EventState::PRESSED) - vel->_velocity.vec.x = -1; - if (event.state == Protocol::EventState::RELEASED) - vel->_velocity.vec.x = 0; - sendUpdatePosition(player, pos.value(), vel.value()); - return; + {} + else if (event.state == Protocol::EventState::RELEASED) + continue; + } } - if (event.id == Protocol::EventId::MOVE_RIGHT && ctrl->_right) - { - if (netEvent->events.size() < size_t(event.id)) - netEvent->events.resize(size_t(event.id) + 1); - netEvent->events[size_t(event.id)] = (unsigned short) event.state; - FLAKKARI_LOG_INFO("event: " + std::to_string(int(event.id)) + " " + std::to_string(int(event.state))); + // jump to the first axis event + data += count_events * sizeof(Protocol::Event); - if (event.state == Protocol::EventState::PRESSED) - vel->_velocity.vec.x = 1; - if (event.state == Protocol::EventState::RELEASED) - vel->_velocity.vec.x = 0; - sendUpdatePosition(player, pos.value(), vel.value()); - return; - } - if (event.id == Protocol::EventId::SHOOT && ctrl->_shoot) + for (uint16_t i = 0; i < count_axis; ++i) { - if (netEvent->events.size() < size_t(event.id)) - netEvent->events.resize(size_t(event.id) + 1); - netEvent->events[size_t(event.id)] = (unsigned short) event.state; - - FLAKKARI_LOG_INFO("event: " + std::to_string(int(event.id)) + " " + std::to_string(int(event.state))); + Protocol::EventAxis event = *(Protocol::EventAxis *) (data + i * sizeof(Protocol::EventAxis)); - if (event.state == Protocol::EventState::RELEASED) + if (event.id == Protocol::EventAxisId::LOOK_RIGHT && ctrl->_look_right) + { + pos->_rotation.vec.y += event.value * 100 * _deltaTime; + continue; + } + else if (event.id == Protocol::EventAxisId::LOOK_LEFT && ctrl->_look_left) + { + pos->_rotation.vec.y -= event.value * 100 * _deltaTime; + continue; + } + else if (event.id == Protocol::EventAxisId::LOOK_UP && ctrl->_look_up) + { + pos->_rotation.vec.x += event.value * 100 * _deltaTime; + continue; + } + else if (event.id == Protocol::EventAxisId::LOOK_DOWN && ctrl->_look_down) { - Protocol::Packet shootPacket; - shootPacket.header._commandId = Protocol::CommandId::REQ_ENTITY_SHOOT; - shootPacket.injectString(player->getSceneName()); - shootPacket << player->getEntity(); - // create a bullet with player as parent - sendOnSameScene(player->getSceneName(), shootPacket); + pos->_rotation.vec.x -= event.value * 100 * _deltaTime; + continue; } - return; } } @@ -390,7 +424,9 @@ void Game::update() updateIncomingPackets(); for (auto &scene : _scenes) - scene.second.run_systems(); + auto ®istry = scene.second; + + updateOutcomingPackets(); } void Game::start() From 87bed8c4b46a3f621d395ef5418a6e469333f14a Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 16:03:52 -0500 Subject: [PATCH 23/26] feat: remove master and main branch references from workflow configuration files --- .github/workflows/build_checker.yml | 1 - .github/workflows/linter.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/build_checker.yml b/.github/workflows/build_checker.yml index 45a92c18..3923b7ab 100644 --- a/.github/workflows/build_checker.yml +++ b/.github/workflows/build_checker.yml @@ -5,7 +5,6 @@ on: branches-ignore: - 'ga-ignore-**' - 'gh-pages' - branches: [master, main] jobs: build_checker_windows: diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 890a2057..ca8829e6 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -5,7 +5,6 @@ on: branches-ignore: - 'ga-ignore-**' - 'gh-pages' - branches: [master, main] permissions: contents: write From b7d5413ec4b13c2bb52261529f3e373a987e063b Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 16:06:47 -0500 Subject: [PATCH 24/26] feat: add random position spawning for enemies in the ECS --- Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp index 7988e9a0..a20c8201 100644 --- a/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp +++ b/Flakkari/Engine/EntityComponentSystem/Systems/Systems.cpp @@ -229,6 +229,11 @@ bool spawn_enemy(Registry &r, std::string &templateName, Entity &entity) entity = r.spawn_entity(); templateName = template_->name; Factory::RegistryEntityByTemplate(r, entity, template_->content); + + auto &enemyTransform = r.getComponents()[entity]; + enemyTransform->_position.vec.x = randomRange(-maxRangeX, maxRangeX); + enemyTransform->_position.vec.y = randomRange(-maxRangeY, maxRangeY); + enemyTransform->_position.vec.z = randomRange(-maxRangeZ, maxRangeZ); return true; } return false; From 109be24e6bf421f5164a167aefb0e243e722a6b3 Mon Sep 17 00:00:00 2001 From: MasterLaplace Date: Fri, 22 Nov 2024 16:08:16 -0500 Subject: [PATCH 25/26] feat: add system execution in game update loop for improved scene management --- Flakkari/Server/Game/Game.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index 8e1c584a..694b8433 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -424,8 +424,12 @@ void Game::update() updateIncomingPackets(); for (auto &scene : _scenes) + { auto ®istry = scene.second; + registry.run_systems(); + } + updateOutcomingPackets(); } From c16f3faa9d57060465115826d99f02925b14eeeb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 22 Nov 2024 21:08:39 +0000 Subject: [PATCH 26/26] style: apply linter --- .../Components/3D/Control.hpp | 5 +-- .../Components/3D/Movable.hpp | 6 +-- .../Components/Common/Timer.hpp | 2 +- .../Components/Common/Weapon.hpp | 2 +- .../Engine/EntityComponentSystem/Entity.hpp | 17 ++++---- Flakkari/Protocol/Header.hpp | 8 ++-- Flakkari/Protocol/PacketFactory.hpp | 40 ++++++++++++------- Flakkari/Server/Client/ClientManager.cpp | 2 +- Flakkari/Server/Game/Game.cpp | 30 +++++++------- 9 files changed, 59 insertions(+), 53 deletions(-) diff --git a/Flakkari/Engine/EntityComponentSystem/Components/3D/Control.hpp b/Flakkari/Engine/EntityComponentSystem/Components/3D/Control.hpp index 33c39b34..c9f770c2 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/3D/Control.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/3D/Control.hpp @@ -50,13 +50,12 @@ struct Control { Control(bool m_up, bool m_down, bool m_left, bool m_right, bool m_front, bool m_back, bool l_up, bool l_down, bool l_left, bool l_right, bool s) : _move_up(m_up), _move_down(m_down), _move_left(m_left), _move_right(m_right), _move_front(m_front), - _move_back(m_back), _look_up(l_up), _look_down(l_down), _look_left(l_left), _look_right(l_right), - _shoot(s) {}; + _move_back(m_back), _look_up(l_up), _look_down(l_down), _look_left(l_left), _look_right(l_right), _shoot(s){}; Control(const Control &other) : _move_up(other._move_up), _move_down(other._move_down), _move_left(other._move_left), _move_right(other._move_right), _move_front(other._move_front), _move_back(other._move_back), _look_up(other._look_up), _look_down(other._look_down), _look_left(other._look_left), - _look_right(other._look_right), _shoot(other._shoot) {}; + _look_right(other._look_right), _shoot(other._shoot){}; Control &operator=(const Control &other) { diff --git a/Flakkari/Engine/EntityComponentSystem/Components/3D/Movable.hpp b/Flakkari/Engine/EntityComponentSystem/Components/3D/Movable.hpp index 66187557..fbab4e8f 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/3D/Movable.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/3D/Movable.hpp @@ -24,12 +24,12 @@ struct Movable { float _minSpeed; float _maxSpeed; - Movable() : _velocity(0, 0), _acceleration(0, 0), _minSpeed(0), _maxSpeed(0) {}; + Movable() : _velocity(0, 0), _acceleration(0, 0), _minSpeed(0), _maxSpeed(0){}; Movable(const Math::Vector3f &velocity, const Math::Vector3f &acceleration, float minSpeed, float maxSpeed) - : _velocity(velocity), _acceleration(acceleration), _minSpeed(minSpeed), _maxSpeed(maxSpeed) {}; + : _velocity(velocity), _acceleration(acceleration), _minSpeed(minSpeed), _maxSpeed(maxSpeed){}; Movable(const Movable &other) : _velocity(other._velocity), _acceleration(other._acceleration), _minSpeed(other._minSpeed), - _maxSpeed(other._maxSpeed) {}; + _maxSpeed(other._maxSpeed){}; Movable &operator=(const Movable &other) { diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Timer.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Timer.hpp index 5b13bc62..1d354a56 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Timer.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Timer.hpp @@ -10,9 +10,9 @@ #ifndef Timer_HPP_ #define Timer_HPP_ +#include #include #include -#include #include "config.h.in" diff --git a/Flakkari/Engine/EntityComponentSystem/Components/Common/Weapon.hpp b/Flakkari/Engine/EntityComponentSystem/Components/Common/Weapon.hpp index fca03252..197b19d0 100644 --- a/Flakkari/Engine/EntityComponentSystem/Components/Common/Weapon.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Components/Common/Weapon.hpp @@ -47,7 +47,7 @@ struct Weapon { Weapon() = default; Weapon(const Weapon &other) = default; Weapon(std::size_t min_dmg, std::size_t max_dmg, float chargeMax, float rate, std::size_t lvl) - : minDamage(min_dmg), maxDamage(max_dmg), chargeMaxTime(chargeMax), fireRate(rate), level(lvl) {}; + : minDamage(min_dmg), maxDamage(max_dmg), chargeMaxTime(chargeMax), fireRate(rate), level(lvl){}; Weapon &operator=(const Weapon &other) { diff --git a/Flakkari/Engine/EntityComponentSystem/Entity.hpp b/Flakkari/Engine/EntityComponentSystem/Entity.hpp index f3babb1f..263a1fe7 100644 --- a/Flakkari/Engine/EntityComponentSystem/Entity.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Entity.hpp @@ -43,9 +43,7 @@ class Entity { return *this; } - bool operator==(const Entity& other) const { - return _id == other._id; - } + bool operator==(const Entity &other) const { return _id == other._id; } std::size_t getId() const { return _id; } @@ -58,13 +56,12 @@ class Entity { #include namespace std { - template <> - struct hash +template <> struct hash { + size_t operator()(const Flakkari::Engine::ECS::Entity &entity) const noexcept { - size_t operator()(const Flakkari::Engine::ECS::Entity& entity) const noexcept { - return std::hash()(entity.getId()); - } - }; -} + return std::hash()(entity.getId()); + } +}; +} // namespace std #endif /* !FLAKKARI_ENTITY_HPP_ */ diff --git a/Flakkari/Protocol/Header.hpp b/Flakkari/Protocol/Header.hpp index ed24e720..8e31b937 100644 --- a/Flakkari/Protocol/Header.hpp +++ b/Flakkari/Protocol/Header.hpp @@ -29,8 +29,8 @@ namespace Flakkari::Protocol { using ushort = uint16_t; // 16 bits (max: 65535) (2 bytes) -using uint = uint32_t; // 32 bits (max: 4294967295) (4 bytes) -using ulong = uint64_t; // 64 bits (max: 18446744073709551615) (8 bytes) +using uint = uint32_t; // 32 bits (max: 4294967295) (4 bytes) +using ulong = uint64_t; // 64 bits (max: 18446744073709551615) (8 bytes) /** * @brief The version of the protocol used @@ -95,8 +95,8 @@ template struct Header { ApiVersion _apiVersion : 4 = ApiVersion::V_1; Id _commandId; uint16_t _contentLength = 0; - uint64_t _sequenceNumber = - static_cast(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) + uint64_t _sequenceNumber = static_cast( + std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()) .count()); std::size_t size() const { return sizeof(*this); } diff --git a/Flakkari/Protocol/PacketFactory.hpp b/Flakkari/Protocol/PacketFactory.hpp index b1f4d255..d2da0262 100644 --- a/Flakkari/Protocol/PacketFactory.hpp +++ b/Flakkari/Protocol/PacketFactory.hpp @@ -34,27 +34,30 @@ class PacketFactory { * @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 - ) { + template + static void addCommonsToPacketByEntity(Protocol::Packet &packet, Engine::ECS::Registry ®istry, + Engine::ECS::Entity entity) + { auto child = registry.getComponents()[entity]; - if (child.has_value()) { + if (child.has_value()) + { packet << Protocol::ComponentId::CHILD; packet.injectString(child->name); } auto evolve = registry.getComponents()[entity]; - if (evolve.has_value()) { + if (evolve.has_value()) + { packet << Protocol::ComponentId::EVOLVE; packet.injectString(evolve->name); } auto health = registry.getComponents()[entity]; - if (health.has_value()) { + if (health.has_value()) + { packet << Protocol::ComponentId::HEALTH; packet << health->currentHealth; packet << health->maxHealth; @@ -64,14 +67,16 @@ class PacketFactory { auto id = registry.getComponents()[entity]; - if (id.has_value()) { + if (id.has_value()) + { packet << Protocol::ComponentId::ID; packet << id->id; } auto level = registry.getComponents()[entity]; - if (level.has_value()) { + if (level.has_value()) + { packet << Protocol::ComponentId::LEVEL; packet << level->level; packet.injectString(level->currentWeapon); @@ -81,28 +86,32 @@ class PacketFactory { auto parent = registry.getComponents()[entity]; - if (parent.has_value()) { + if (parent.has_value()) + { packet << Protocol::ComponentId::PARENT; packet << parent->entity; } auto tag = registry.getComponents()[entity]; - if (tag.has_value()) { + if (tag.has_value()) + { packet << Protocol::ComponentId::TAG; packet.injectString(tag->tag); } auto template_ = registry.getComponents()[entity]; - if (template_.has_value()) { + if (template_.has_value()) + { packet << Protocol::ComponentId::TEMPLATE; packet.injectString(template_->name); } auto timer = registry.getComponents()[entity]; - if (timer.has_value()) { + if (timer.has_value()) + { packet << Protocol::ComponentId::TIMER; packet << timer->lastTime.time_since_epoch().count(); packet << timer->maxTime; @@ -110,7 +119,8 @@ class PacketFactory { auto weapon = registry.getComponents()[entity]; - if (weapon.has_value()) { + if (weapon.has_value()) + { packet << Protocol::ComponentId::WEAPON; packet << weapon->minDamage; packet << weapon->maxDamage; @@ -271,7 +281,7 @@ class PacketFactory { packet << rigidbody->_mass; packet << rigidbody->_drag; packet << rigidbody->_angularDrag; - packet << (byte)rigidbody->_useGravity; + packet << (byte) rigidbody->_useGravity; } } diff --git a/Flakkari/Server/Client/ClientManager.cpp b/Flakkari/Server/Client/ClientManager.cpp index 0ae2c23f..2ef131d5 100644 --- a/Flakkari/Server/Client/ClientManager.cpp +++ b/Flakkari/Server/Client/ClientManager.cpp @@ -78,7 +78,7 @@ void ClientManager::checkInactiveClients() continue; } - ++it; + ++it; } } diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index 694b8433..bed84004 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -95,8 +95,8 @@ void Game::loadSystems(Engine::ECS::Registry ®istry, const std::string &scene packet.header._commandId = Protocol::CommandId::REQ_ENTITY_DESTROY; packet << entity.first; this->sendOnSameScene(sceneName, packet); - continue; - } + continue; + } Protocol::Packet packet; packet.header._commandId = Protocol::CommandId::REQ_ENTITY_UPDATE; @@ -105,7 +105,7 @@ void Game::loadSystems(Engine::ECS::Registry ®istry, const std::string &scene Protocol::PacketFactory::addComponentsToPacketByEntity(packet, r, entity.first); this->sendOnSameScene(sceneName, packet); - } + } }); } @@ -114,10 +114,10 @@ void Game::loadEntityFromTemplate(Engine::ECS::Registry ®istry, const nl_enti { Engine::ECS::Entity newEntity = registry.spawn_entity(); - for (auto &templateInfo : templates.items()) - { + for (auto &templateInfo : templates.items()) + { if (entity.value() != templateInfo.value().begin().key()) - continue; + continue; Engine::ECS::Factory::RegistryEntityByTemplate(registry, newEntity, templateInfo.value().begin().value(), templates); } @@ -318,13 +318,14 @@ void Game::handleEvents(std::shared_ptr player, Protocol::Packet_shoot) { - if (event.state == Protocol::EventState::PRESSED) - {} + if (event.state == Protocol::EventState::PRESSED) + { + } else if (event.state == Protocol::EventState::RELEASED) continue; } @@ -338,7 +339,7 @@ void Game::handleEvents(std::shared_ptr player, Protocol::Packet_look_right) - { + { pos->_rotation.vec.y += event.value * 100 * _deltaTime; continue; } @@ -346,9 +347,9 @@ void Game::handleEvents(std::shared_ptr player, Protocol::Packet_rotation.vec.y -= event.value * 100 * _deltaTime; continue; - } + } else if (event.id == Protocol::EventAxisId::LOOK_UP && ctrl->_look_up) - { + { pos->_rotation.vec.x += event.value * 100 * _deltaTime; continue; } @@ -408,7 +409,7 @@ void Game::updateOutcomingPackets(unsigned char maxMessagePerFrame) buffer += packet.serialize(); ClientManager::GetInstance().sendPacketToClient(player->getAddress(), buffer); - ClientManager::UnlockInstance(); + ClientManager::UnlockInstance(); } } } @@ -467,7 +468,6 @@ bool Game::addPlayer(std::shared_ptr player) Engine::ECS::Factory::RegistryEntityByTemplate(registry, newEntity, player_info.value()); ResourceManager::UnlockInstance(); - player->setEntity(newEntity); _players.push_back(player); FLAKKARI_LOG_INFO("client \"" + std::string(*address) + "\" added to game \"" + _name + "\"");