diff --git a/.clang-format b/.clang-format index 48fe2550..91bd2aa1 100644 --- a/.clang-format +++ b/.clang-format @@ -2,7 +2,7 @@ Language: Cpp BasedOnStyle: LLVM Standard: c++20 -AccessModifierOffset: 0 +AccessModifierOffset: -4 AlignAfterOpenBracket: Align AlignArrayOfStructures: Left AlignConsecutiveMacros: Consecutive diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index b0e45ac8..fe30b97f 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -28,6 +28,7 @@ jobs: uses: mathieudutour/github-tag-action@v6.2 with: github_token: ${{ secrets.GITHUB_TOKEN }} + default_bump: patch dry_run: true - name: Run version bump script diff --git a/Flakkari/Engine/EntityComponentSystem/Entity.hpp b/Flakkari/Engine/EntityComponentSystem/Entity.hpp index 540b0296..6ee6464e 100644 --- a/Flakkari/Engine/EntityComponentSystem/Entity.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Entity.hpp @@ -23,7 +23,7 @@ namespace Flakkari::Engine::ECS { class Registry; class Entity { - public: +public: friend class Registry; explicit Entity(std::size_t id) : _id(id) {} @@ -43,7 +43,7 @@ class Entity { return *this; } - private: +private: std::size_t _id; }; diff --git a/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp b/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp index 94c84bb3..14dc5b5b 100644 --- a/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp +++ b/Flakkari/Engine/EntityComponentSystem/EntityFactory.hpp @@ -27,10 +27,10 @@ namespace Flakkari::Engine::ECS { class EntityFactory { - public: +public: using nl_template = nlohmann::json; - public: +public: /** * @brief Create a Entity From Template object based on a template JSON * diff --git a/Flakkari/Engine/EntityComponentSystem/Registry.hpp b/Flakkari/Engine/EntityComponentSystem/Registry.hpp index 0ce2d577..42aea5db 100644 --- a/Flakkari/Engine/EntityComponentSystem/Registry.hpp +++ b/Flakkari/Engine/EntityComponentSystem/Registry.hpp @@ -30,7 +30,7 @@ namespace Flakkari::Engine::ECS { class Registry { - public: +public: using entity_type = Entity; using EraseFn = std::function; using SystemFn = std::function; @@ -214,7 +214,7 @@ class Registry { */ void run_systems(); - private: +private: std::unordered_map _components; std::unordered_map _eraseFunctions; std::vector _systems; diff --git a/Flakkari/Engine/EntityComponentSystem/SparseArrays.hpp b/Flakkari/Engine/EntityComponentSystem/SparseArrays.hpp index a9f70778..d9d3bb17 100644 --- a/Flakkari/Engine/EntityComponentSystem/SparseArrays.hpp +++ b/Flakkari/Engine/EntityComponentSystem/SparseArrays.hpp @@ -23,7 +23,7 @@ namespace Flakkari::Engine::ECS { template class SparseArrays { - public: +public: using value_type = std::optional; using reference_type = value_type &; using const_reference_type = const value_type &; @@ -32,7 +32,7 @@ template class SparseArrays { using iterator = typename container_type::iterator; using const_iterator = typename container_type::const_iterator; - public: +public: SparseArrays() = default; SparseArrays(const SparseArrays &other) : _data(other._data){}; SparseArrays(SparseArrays &&other) noexcept : _data(std::move(other._data)){}; @@ -185,7 +185,7 @@ template class SparseArrays { return std::distance(_data.begin(), it); } - private: +private: container_type _data; }; diff --git a/Flakkari/Logger/Logger.hpp b/Flakkari/Logger/Logger.hpp index e7dc4815..e90e65f5 100644 --- a/Flakkari/Logger/Logger.hpp +++ b/Flakkari/Logger/Logger.hpp @@ -97,14 +97,14 @@ namespace Flakkari { class Logger { - public: +public: enum class Mode { SILENT, NORMAL, DEBUG }; - public: +public: static void setMode(Mode mode) noexcept; static const std::string get_current_time() noexcept; static const std::string fatal_error_message() noexcept; diff --git a/Flakkari/Network/Address.cpp b/Flakkari/Network/Address.cpp index a7a4813d..cc310737 100644 --- a/Flakkari/Network/Address.cpp +++ b/Flakkari/Network/Address.cpp @@ -189,7 +189,7 @@ constexpr const char *Address::socketTypeToString(SocketType socket_type) Address::operator std::string() const { return std::string(toString().value_or("null") + " (" + socketTypeToString(_socket_type) + ", " + - ipTypeToString(_ip_type) + ", " + std::to_string(getId()) + ")"); + ipTypeToString(_ip_type) + ")"); } std::ostream &operator<<(std::ostream &os, const Address &addr) @@ -199,8 +199,6 @@ std::ostream &operator<<(std::ostream &os, const Address &addr) os << Address::socketTypeToString(addr.getSocketType()); os << ", "; os << Address::ipTypeToString(addr.getIpType()); - os << ", "; - os << addr.getId(); os << ")"; return os; } diff --git a/Flakkari/Network/Address.hpp b/Flakkari/Network/Address.hpp index 817bce49..0fc0fb9e 100644 --- a/Flakkari/Network/Address.hpp +++ b/Flakkari/Network/Address.hpp @@ -38,7 +38,7 @@ namespace Flakkari::Network { class Address { - public: +public: enum class IpType { None, IPv4, // Internet Protocol version 4 @@ -51,7 +51,7 @@ class Address { UDP, // User Datagram Protocol }; - public: +public: /** * @brief Convert IpType to string * @@ -68,12 +68,12 @@ class Address { */ static constexpr const char *socketTypeToString(SocketType socket_type); - public: +public: using address_t = const std::string; using port_t = unsigned short; using id_t = short; - public: +public: Address(address_t &address, port_t port, SocketType socket_type, IpType ip_type); Address(port_t port, SocketType socket_type, IpType ip_type); Address(const sockaddr_in &clientAddr, SocketType socket_type, IpType ip_type); @@ -150,20 +150,6 @@ class Address { */ [[nodiscard]] IpType getIpType() const { return _ip_type; } - /** - * @brief Get the Id object - * - * @return id_t Id - */ - [[nodiscard]] id_t getId() const { return _id; } - - /** - * @brief Set the Id object - * - * @param id Id - */ - void setId(id_t id) { _id = id; } - /** * @brief Convert Address to string (std::string) * @@ -171,12 +157,11 @@ class Address { */ operator std::string() const; - protected: - private: +protected: +private: std::shared_ptr _addrInfo = nullptr; SocketType _socket_type = SocketType::None; IpType _ip_type = IpType::None; - id_t _id = -1; }; /** diff --git a/Flakkari/Network/Buffer.hpp b/Flakkari/Network/Buffer.hpp index ba590de7..8172abf6 100644 --- a/Flakkari/Network/Buffer.hpp +++ b/Flakkari/Network/Buffer.hpp @@ -48,7 +48,7 @@ namespace Flakkari::Network { * @see Flakkari::Network::Socket */ class Buffer : public std::vector { - public: +public: using std::vector::operator=; using std::vector::operator[]; using std::vector::at; @@ -72,10 +72,10 @@ class Buffer : public std::vector { using std::vector::resize; using std::vector::swap; - public: +public: using std::vector::vector; - public: +public: /** * @brief Construct a new Buffer object * @@ -238,8 +238,8 @@ class Buffer : public std::vector { */ Buffer operator-=(const Buffer &otherBuffer); - protected: - private: +protected: +private: }; /** diff --git a/Flakkari/Network/IOMultiplexer.cpp b/Flakkari/Network/IOMultiplexer.cpp index db7ad521..3eccea0a 100644 --- a/Flakkari/Network/IOMultiplexer.cpp +++ b/Flakkari/Network/IOMultiplexer.cpp @@ -16,10 +16,7 @@ namespace Flakkari::Network { PSELECT::PSELECT(FileDescriptor fileDescriptor, long int seconds, long int microseconds) { if (fileDescriptor == -1) - { - FLAKKARI_LOG_ERROR("Socket is -1"); throw std::runtime_error("Socket is -1"); - } FD_ZERO(&_fds); _maxFd = fileDescriptor; @@ -43,6 +40,7 @@ void PSELECT::addSocket(FileDescriptor socket) throw std::runtime_error("Socket is -1"); if (socket > FD_SETSIZE) throw std::runtime_error("Index out of range"); + FD_SET(socket, &_fds); if (socket > _maxFd) _maxFd = socket; @@ -55,6 +53,7 @@ void PSELECT::removeSocket(FileDescriptor socket) throw std::runtime_error("Socket is -1"); if (socket > _maxFd) throw std::runtime_error("Index out of range"); + FD_CLR(socket, &_fds); _sockets.erase(std::remove(_sockets.begin(), _sockets.end(), socket), _sockets.end()); _maxFd = *std::max_element(_sockets.begin(), _sockets.end()); @@ -78,6 +77,7 @@ bool PSELECT::isReady(FileDescriptor socket) throw std::runtime_error("Socket is -1"); if (socket > _maxFd) throw std::runtime_error("Index out of range"); + return FD_ISSET(socket, &_fds); } @@ -90,13 +90,11 @@ bool PSELECT::skipableError() { return errno == EINTR || errno == EAGAIN || errn PPOLL::PPOLL(FileDescriptor fileDescriptor, event_t events, long int seconds, long int microseconds) { if (fileDescriptor == -1) - { - FLAKKARI_LOG_ERROR("Socket is -1"); throw std::runtime_error("Socket is -1"); - } if (_pollfds.size() < std::size_t(fileDescriptor)) _pollfds.resize(fileDescriptor + 1); + _pollfds[fileDescriptor] = pollfd{fileDescriptor, events, 0}; _timeout.tv_sec = seconds; @@ -115,6 +113,7 @@ void PPOLL::addSocket(FileDescriptor socket) throw std::runtime_error("Socket is -1"); if (_pollfds.size() < std::size_t(socket)) _pollfds.resize(socket + 1); + _pollfds[socket] = pollfd{socket, POLLIN | POLLPRI, 0}; } @@ -124,6 +123,7 @@ void PPOLL::addSocket(FileDescriptor socket, event_t events) throw std::runtime_error("Socket is -1"); if (_pollfds.size() < std::size_t(socket)) _pollfds.resize(socket + 1); + _pollfds[socket] = pollfd{socket, events, 0}; } @@ -152,6 +152,7 @@ pollfd &PPOLL::operator[](std::size_t index) { if (_pollfds.size() < index) throw std::runtime_error("Index out of range"); + return _pollfds[index]; } @@ -161,6 +162,7 @@ pollfd &PPOLL::operator[](FileDescriptor socket) throw std::runtime_error("Socket is -1"); if (_pollfds.size() < std::size_t(socket)) throw std::runtime_error("Index out of range"); + return _pollfds[socket]; } @@ -168,6 +170,7 @@ bool PPOLL::isReady(pollfd fd) { if (fd.fd == -1) throw std::runtime_error("Socket is -1"); + return fd.revents & (POLLIN | POLLPRI); } @@ -179,6 +182,7 @@ bool PPOLL::isReady(FileDescriptor socket) throw std::runtime_error("Index out of range"); if (_pollfds[socket].revents & (POLLIN | POLLPRI)) return true; + return false; } @@ -191,7 +195,7 @@ bool PPOLL::skipableError() { return errno == EINTR || errno == EAGAIN || errno WSA::WSA(FileDescriptor socket, int seconds, int microseconds) { if (socket == -1) - FLAKKARI_LOG_FATAL("Socket is -1"); + throw std::runtime_error("Socket is -1"); _sockets.reserve(MAX_POLLFD); _fdArray.reserve(MAX_POLLFD); diff --git a/Flakkari/Network/IOMultiplexer.hpp b/Flakkari/Network/IOMultiplexer.hpp index c85ed3ca..d96a2f7b 100644 --- a/Flakkari/Network/IOMultiplexer.hpp +++ b/Flakkari/Network/IOMultiplexer.hpp @@ -67,10 +67,10 @@ namespace Flakkari::Network { * @endcode */ class PSELECT { - public: +public: using FileDescriptor = int; - public: +public: PSELECT(FileDescriptor fileDescriptorn, long int seconds = 1, long int microseconds = 0); PSELECT(long int seconds = 1, long int microseconds = 0); ~PSELECT() = default; @@ -118,8 +118,8 @@ class PSELECT { */ [[nodiscard]] bool skipableError(); - protected: - private: +protected: +private: fd_set _fds; std::vector _sockets; FileDescriptor _maxFd = 0; @@ -164,14 +164,14 @@ class PSELECT { * @endcode */ class PPOLL { - public: +public: using FileDescriptor = int; using pollfd = struct pollfd; using event_t = short int; using revents_t = short int; using nfds_t = unsigned long int; - public: +public: PPOLL(FileDescriptor fileDescriptor, event_t events, long int seconds = 1, long int microseconds = 0); PPOLL(long int seconds = 1, long int microseconds = 0); ~PPOLL() = default; @@ -239,8 +239,8 @@ class PPOLL { */ [[nodiscard]] bool skipableError(); - protected: - private: +protected: +private: std::vector _pollfds; struct timespec _timeout = {0, 0}; }; @@ -278,10 +278,10 @@ class PPOLL { * @endcode */ class WSA { - public: +public: using FileDescriptor = SOCKET; - public: +public: /** * @brief Construct a new WSA object with a timeout of 1 second by default * @@ -334,8 +334,8 @@ class WSA { */ [[nodiscard]] bool skipableError(); - protected: - private: +protected: +private: std::vector _sockets; std::vector _fdArray; std::vector _freeSpace; diff --git a/Flakkari/Network/Network.cpp b/Flakkari/Network/Network.cpp index 509186a6..1f153924 100644 --- a/Flakkari/Network/Network.cpp +++ b/Flakkari/Network/Network.cpp @@ -17,7 +17,7 @@ void init() WSADATA WSAData; if (::WSAStartup(MAKEWORD(2, 2), &WSAData) != NO_ERROR) - FLAKKARI_LOG_FATAL("WSAStartup failed"); + throw std::runtime_error("WSAStartup failed"); #endif } diff --git a/Flakkari/Network/PacketQueue.hpp b/Flakkari/Network/PacketQueue.hpp index 54532174..d38bbd58 100644 --- a/Flakkari/Network/PacketQueue.hpp +++ b/Flakkari/Network/PacketQueue.hpp @@ -23,12 +23,12 @@ namespace Flakkari::Network { template class PacketQueue { - public: +public: PacketQueue() = default; PacketQueue(const PacketQueue &) = delete; virtual ~PacketQueue() { clear(); } - public: +public: const T &front() { std::scoped_lock lock(_mutex); @@ -87,8 +87,8 @@ template class PacketQueue { _queue.clear(); } - protected: - private: +protected: +private: std::mutex _mutex; std::deque _queue; }; diff --git a/Flakkari/Network/Serializer.hpp b/Flakkari/Network/Serializer.hpp index 294a428c..69c7a010 100644 --- a/Flakkari/Network/Serializer.hpp +++ b/Flakkari/Network/Serializer.hpp @@ -27,7 +27,7 @@ namespace Flakkari::Network { * in the Flakkari/Protocol/Component.hpp file. */ class Serializer { - public: +public: /** * @brief Serialize an object into a buffer. * diff --git a/Flakkari/Network/Socket.cpp b/Flakkari/Network/Socket.cpp index 71376445..bdd58384 100644 --- a/Flakkari/Network/Socket.cpp +++ b/Flakkari/Network/Socket.cpp @@ -26,20 +26,14 @@ void Socket::create(const std::shared_ptr
&address) _socket = ::socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if (_socket == INVALID_SOCKET) - { - FLAKKARI_LOG_FATAL("Failed to create socket, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to create socket, error: " + STD_ERROR); #if __APPLE__ int optval = 1; ::setsockopt(_socket, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)); #elif __linux__ if (::setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, "\001", 4)) - { - FLAKKARI_LOG_FATAL("Failed to set socket to reuse address and port, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to set socket to reuse address and port, error: " + STD_ERROR); #endif } @@ -51,19 +45,13 @@ void Socket::create(socket_t socket, const std::shared_ptr
&address) #if _WIN32 u_long mode = 1; if (::ioctlsocket(_socket, FIONBIO, &mode) != NO_ERROR) - { - FLAKKARI_LOG_FATAL("Failed to set socket to non-blocking, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to set socket to non-blocking, error: " + STD_ERROR); #elif __APPLE__ int optval = 1; ::setsockopt(_socket, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)); #elif __linux__ if (::setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, "\001", 4)) - { - FLAKKARI_LOG_FATAL("Failed to set socket to reuse address and port, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to set socket to reuse address and port, error: " + STD_ERROR); #endif } @@ -82,20 +70,14 @@ void Socket::create(const Address &address) _socket = ::socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if (_socket == INVALID_SOCKET) - { - FLAKKARI_LOG_FATAL("Failed to create socket, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to create socket, error: " + STD_ERROR); #if __APPLE__ int optval = 1; ::setsockopt(_socket, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)); #elif __linux__ if (::setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, "\001", 4)) - { - FLAKKARI_LOG_FATAL("Failed to set socket to reuse address and port, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to set socket to reuse address and port, error: " + STD_ERROR); #endif } @@ -114,20 +96,14 @@ void Socket::create(ip_t address, port_t port, Address::IpType ip_type, Address: _socket = ::socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if (_socket == INVALID_SOCKET) - { - FLAKKARI_LOG_FATAL("Failed to create socket, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to create socket, error: " + STD_ERROR); #if __APPLE__ int optval = 1; ::setsockopt(_socket, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)); #elif __linux__ if (::setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, "\001", 4)) - { - FLAKKARI_LOG_FATAL("Failed to set socket to reuse address and port, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to set socket to reuse address and port, error: " + STD_ERROR); #endif } @@ -141,19 +117,13 @@ void Socket::bind() return FLAKKARI_LOG_ERROR("Address is nullptr"), void(); if (::bind(_socket, addr->ai_addr, (int) addr->ai_addrlen) == SOCKET_ERROR) - { - FLAKKARI_LOG_FATAL("Failed to bind socket, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to bind socket, error: " + STD_ERROR); } void Socket::listen(int backlog) { if (::listen(_socket, backlog) == SOCKET_ERROR) - { - FLAKKARI_LOG_FATAL("Failed to listen on socket, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to listen on socket, error: " + STD_ERROR); } void Socket::connect() @@ -164,40 +134,25 @@ void Socket::connect() return FLAKKARI_LOG_ERROR("Address is nullptr"), void(); if (::connect(_socket, addr->ai_addr, (int) addr->ai_addrlen) == SOCKET_ERROR) - { - FLAKKARI_LOG_FATAL("Failed to connect socket, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to connect socket, error: " + STD_ERROR); } void Socket::disconnect() { #if _WIN32 if (::shutdown(_socket, SD_BOTH) == SOCKET_ERROR) - { - FLAKKARI_LOG_FATAL("Failed to disconnect socket, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to disconnect socket, error: " + STD_ERROR); #else if (::shutdown(_socket, SHUT_RDWR) == SOCKET_ERROR) - { - FLAKKARI_LOG_FATAL("Failed to disconnect socket, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to disconnect socket, error: " + STD_ERROR); #endif #ifdef _WIN32 if (::closesocket(_socket) == SOCKET_ERROR) - { - FLAKKARI_LOG_FATAL("Failed to close socket, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to close socket, error: " + STD_ERROR); #else if (::close(_socket) == SOCKET_ERROR) - { - FLAKKARI_LOG_FATAL("Failed to close socket, error: " + STD_ERROR); - return; - } + throw std::runtime_error("Failed to close socket, error: " + STD_ERROR); #endif #ifdef _WIN32 @@ -214,10 +169,7 @@ std::shared_ptr Socket::accept() SOCKET clientSocket = ::accept(_socket, (struct sockaddr *) &clientAddr, &clientAddrLen); if (clientSocket == INVALID_SOCKET) - { - FLAKKARI_LOG_FATAL("Failed to accept socket, error: " + STD_ERROR); - return nullptr; - } + throw std::runtime_error("Failed to accept socket, error: " + STD_ERROR); auto _ip_type = (clientAddr.ss_family == AF_INET) ? Address::IpType::IPv4 : (clientAddr.ss_family == AF_INET6) ? Address::IpType::IPv6 : diff --git a/Flakkari/Network/Socket.hpp b/Flakkari/Network/Socket.hpp index ae1c8a51..dc9f3e68 100644 --- a/Flakkari/Network/Socket.hpp +++ b/Flakkari/Network/Socket.hpp @@ -122,12 +122,12 @@ namespace Flakkari::Network { * @endcode */ class Socket { - public: +public: using port_t = Address::port_t; using ip_t = const std::string &; using socket_t = SOCKET; - public: +public: Socket() = default; Socket(const Socket &) = delete; Socket(Socket &&) = delete; @@ -292,8 +292,8 @@ class Socket { */ operator std::string() const; - protected: - private: +protected: +private: std::mutex _mutex; socket_t _socket; std::shared_ptr
_address = nullptr; diff --git a/Flakkari/Protocol/Commands.hpp b/Flakkari/Protocol/Commands.hpp index 3d70f59c..1c7de83b 100644 --- a/Flakkari/Protocol/Commands.hpp +++ b/Flakkari/Protocol/Commands.hpp @@ -116,7 +116,7 @@ enum class CommandId : uint8_t { static_assert(static_cast(CommandId::MAX_COMMAND_ID) <= 0xFF, "CommandId is too big"); class Commands final { - public: +public: static std::string command_to_string(CommandId id) { switch (id) diff --git a/Flakkari/Protocol/Components.hpp b/Flakkari/Protocol/Components.hpp index aa2c344a..64e225ef 100644 --- a/Flakkari/Protocol/Components.hpp +++ b/Flakkari/Protocol/Components.hpp @@ -50,7 +50,7 @@ enum class ComponentId : uint8_t { static_assert(static_cast(ComponentId::MAX_COMPONENT) <= 30, "ComponentId::MAX_COMPONENT is too big"); class Components final { - public: +public: static std::string component_to_string(ComponentId id) { switch (id) diff --git a/Flakkari/Protocol/Header.hpp b/Flakkari/Protocol/Header.hpp index a5eeae71..526bffae 100644 --- a/Flakkari/Protocol/Header.hpp +++ b/Flakkari/Protocol/Header.hpp @@ -37,7 +37,8 @@ using ulong = unsigned long; // 64 bits (max: 18446744073709551615) * */ enum class ApiVersion : byte { - V_0, + V_0 = 0, + V_1 = 1, MAX_VERSION }; diff --git a/Flakkari/Protocol/Packet.hpp b/Flakkari/Protocol/Packet.hpp index 96e79a64..38866b46 100644 --- a/Flakkari/Protocol/Packet.hpp +++ b/Flakkari/Protocol/Packet.hpp @@ -24,6 +24,7 @@ #include "Components.hpp" #include "Events.hpp" #include "Header.hpp" +#include "Logger/Logger.hpp" #include @@ -87,7 +88,7 @@ template struct Packet { const byte *dataBytes = reinterpret_cast(&data); packet.payload.insert(packet.payload.end(), dataBytes, dataBytes + sizeof(data)); - packet.header._contentLength += (ushort) packet.payload.size() + (ushort) sizeof(data); + packet.header._contentLength += (ushort) sizeof(data); return packet; } @@ -118,25 +119,18 @@ template struct Packet { return packet; } + /** + * @brief Inject a string into the packet. + * + * @param str The string to inject. + */ void injectString(std::string str) { int intValue = (int) str.size(); const byte *dataBytes = reinterpret_cast(&intValue); payload.insert(payload.end(), dataBytes, dataBytes + sizeof(intValue)); payload += str; - header._contentLength += (ushort) payload.size() + (ushort) sizeof(intValue); - } - - std::string extractString() - { - std::string str; - int intValue; - std::memcpy(&intValue, payload.data(), sizeof(intValue)); - payload.erase(payload.begin(), payload.begin() + sizeof(intValue)); - str = std::string((const char *) payload.data(), intValue); - payload.erase(payload.begin(), payload.begin() + intValue); - header._contentLength -= (ushort) sizeof(intValue) + (ushort) intValue; - return str; + header._contentLength += (ushort) str.size() + (ushort) sizeof(intValue); } /** @@ -162,12 +156,16 @@ template struct Packet { [[nodiscard]] bool deserialize(const Network::Buffer &buffer) { if (buffer.size() < sizeof(header)) - return false; + return FLAKKARI_LOG_WARNING("Buffer is too small to deserialize a packet."), false; std::memcpy(&header, buffer.data(), sizeof(header)); if (header._priority >= Priority::MAX_PRIORITY) - return false; + return FLAKKARI_LOG_WARNING("Priority is too big (" + std::to_string((int) header._priority) + ")"), false; if (header._apiVersion >= ApiVersion::MAX_VERSION) - return false; + return FLAKKARI_LOG_WARNING("ApiVersion is too big (" + std::to_string((int) header._apiVersion) + ")"), + false; + 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)) return false; payload = buffer.extractData(sizeof(header), header._contentLength); diff --git a/Flakkari/Protocol/PacketFactory.hpp b/Flakkari/Protocol/PacketFactory.hpp index fa37760a..d866a0b9 100644 --- a/Flakkari/Protocol/PacketFactory.hpp +++ b/Flakkari/Protocol/PacketFactory.hpp @@ -25,7 +25,7 @@ namespace Flakkari::Protocol { class PacketFactory { - public: +public: // /** // * @brief Add all the commons components of an entity to a packet. // * diff --git a/Flakkari/Server/Client/Client.cpp b/Flakkari/Server/Client/Client.cpp index a6bb0f3e..79c6c21b 100644 --- a/Flakkari/Server/Client/Client.cpp +++ b/Flakkari/Server/Client/Client.cpp @@ -11,17 +11,15 @@ namespace Flakkari { -Client::Client(const std::shared_ptr &address, const std::string &name) +Client::Client(const std::shared_ptr &address, const std::string &name, + Protocol::ApiVersion apiVersion) : _address(address), _gameName(name), _name(address->toString().value_or("")) { + _apiVersion = apiVersion; _lastActivity = std::chrono::steady_clock::now(); } -Client::~Client() -{ - _isConnected = false; - _address->setId(-1); -} +Client::~Client() { _isConnected = false; } bool Client::isConnected(float timeout) { @@ -37,7 +35,7 @@ void Client::addPacketToHistory(const Network::Buffer &packet) { if (_packetHistory.size() >= _maxPacketHistory) _packetHistory.erase(_packetHistory.begin()); - _packetHistory.push_back(packet); + _packetHistory.emplace_back(packet); } bool Client::incrementWarningCount() @@ -46,4 +44,10 @@ bool Client::incrementWarningCount() return _warningCount >= _maxWarningCount; } +void Client::addPacketToQueue(const Protocol::Packet &packet) +{ + _apiVersion = packet.header._apiVersion; + _receiveQueue.push_back(packet); +} + } /* namespace Flakkari */ diff --git a/Flakkari/Server/Client/Client.hpp b/Flakkari/Server/Client/Client.hpp index 8b6f21da..797a0d1b 100644 --- a/Flakkari/Server/Client/Client.hpp +++ b/Flakkari/Server/Client/Client.hpp @@ -40,14 +40,15 @@ namespace Flakkari { * @see Network::Address */ class Client { - public: +public: /** * @brief Construct a new Client object * * @param address The client's address * @param name The Game's name + * @param apiVersion The API version used by the client */ - Client(const std::shared_ptr &address, const std::string &name); + Client(const std::shared_ptr &address, const std::string &name, Protocol::ApiVersion apiVersion); ~Client(); /** @@ -80,6 +81,14 @@ class Client { */ bool incrementWarningCount(); + /** + * @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); + /** * @brief Get the client's address * @@ -95,8 +104,6 @@ class Client { [[nodiscard]] Engine::ECS::Entity getEntity() const { return _entity; } void setEntity(Engine::ECS::Entity entity) { _entity = entity; } - [[nodiscard]] short getId() const { return _address->getId(); } - [[nodiscard]] std::string getSceneName() const { return _sceneName; } void setSceneName(std::string sceneName) { _sceneName = sceneName; } @@ -112,8 +119,14 @@ class Client { [[nodiscard]] unsigned short getMaxPacketHistory() const { return _maxPacketHistory; } - protected: - private: + [[nodiscard]] Protocol::ApiVersion getApiVersion() const { return _apiVersion; } + + [[nodiscard]] Network::PacketQueue> &getReceiveQueue() + { + return _receiveQueue; + } + +private: std::chrono::steady_clock::time_point _lastActivity; std::shared_ptr _address; Engine::ECS::Entity _entity; @@ -121,11 +134,11 @@ class Client { std::string _gameName; bool _isConnected = true; std::string _name; + Protocol::ApiVersion _apiVersion; unsigned short _warningCount = 0; unsigned short _maxWarningCount = 5; unsigned short _maxPacketHistory = 10; - public: std::vector _packetHistory; Network::PacketQueue> _sendQueue; Network::PacketQueue> _receiveQueue; diff --git a/Flakkari/Server/Client/ClientManager.cpp b/Flakkari/Server/Client/ClientManager.cpp index d05cca4a..7613b4e9 100644 --- a/Flakkari/Server/Client/ClientManager.cpp +++ b/Flakkari/Server/Client/ClientManager.cpp @@ -14,64 +14,51 @@ namespace Flakkari { -bool ClientManager::addClient(const std::shared_ptr &client, Network::Buffer &buffer) +std::optional>> +ClientManager::addClient(const std::shared_ptr &client, Network::Buffer &buffer) { if (this->isBanned(client)) { FLAKKARI_LOG_LOG("Client " + client->toString().value_or("Unknown") + " tried to connect but is banned"); - return false; + return std::nullopt; } - if (_clients.find(client->toString().value_or("")) != _clients.end()) - return _clients[client->toString().value_or("")]->keepAlive(), true; + auto clientString = client->toString().value_or(""); + + if (_clients.find(clientString) != _clients.end()) + { + _clients[clientString]->keepAlive(); + return std::make_pair("", nullptr); + } Protocol::Packet packet; if (!packet.deserialize(buffer)) { FLAKKARI_LOG_WARNING("Client " + client->toString().value_or("Unknown") + " sent an invalid packet"); _bannedClients.push_back(client->getIp().value()); - return false; + return std::nullopt; } if (packet.header._commandId != Protocol::CommandId::REQ_CONNECT) { FLAKKARI_LOG_WARNING("Client " + client->toString().value_or("Unknown") + " sent an invalid packet"); - return false; + _bannedClients.push_back(client->getIp().value()); + return std::nullopt; } - std::string name = packet.extractString(); - _clients[client->toString().value_or("")] = std::make_shared(client, name); + std::string gameName = std::string((const char *) packet.payload.getData(), packet.payload.getSize()); + auto apiVersion = packet.header._apiVersion; + _clients[clientString] = std::make_shared(client, gameName, apiVersion); - FLAKKARI_LOG_LOG("Client " + client->toString().value_or("Unknown") + " connected"); - GameManager::GetInstance().addClientToGame(name, _clients[client->toString().value_or("")]); - GameManager::UnlockInstance(); - return true; + return std::make_pair(gameName, _clients[clientString]); } -void ClientManager::removeClient(const std::shared_ptr &client) +void ClientManager::removeClient(const std::string &clientName) { - if (_clients.find(client->toString().value_or("")) == _clients.end()) - return; - - auto _client = _clients[client->toString().value_or("")]; - - GameManager::GetInstance().removeClientFromGame(_client->getGameName(), _client); - GameManager::UnlockInstance(); - _clients.erase(client->toString().value_or("")); -} - -void ClientManager::banClient(const std::shared_ptr &client) -{ - if (_clients.find(client->toString().value_or("")) == _clients.end()) + if (_clients.find(clientName) == _clients.end()) return; - _bannedClients.push_back(client->getIp().value()); - - FLAKKARI_LOG_LOG("Client " + client->toString().value_or("Unknown") + " banned"); - auto _client = _clients[client->toString().value_or("")]; - GameManager::GetInstance().removeClientFromGame(_client->getGameName(), _client); - GameManager::UnlockInstance(); - _clients.erase(client->toString().value_or("")); + _clients.erase(clientName); } bool ClientManager::isBanned(const std::shared_ptr &client) @@ -96,7 +83,7 @@ void ClientManager::checkInactiveClients() } } -void ClientManager::sendPacketToClient(std::shared_ptr client, const Network::Buffer &packet) +void ClientManager::sendPacketToClient(const std::shared_ptr &client, const Network::Buffer &packet) { std::thread([this, client, packet] { _socket->sendTo(client, packet); }).detach(); } @@ -124,8 +111,8 @@ void ClientManager::sendPacketToAllClientsExcept(const std::shared_ptr &client, - const Network::Buffer &buffer) +std::optional>> +ClientManager::receivePacketFromClient(const std::shared_ptr &client, const Network::Buffer &buffer) { auto clientName = client->toString().value_or(""); auto ip = client->getIp().value_or(""); @@ -133,33 +120,32 @@ void ClientManager::receivePacketFromClient(const std::shared_ptr packet; if (packet.deserialize(buffer)) { FLAKKARI_LOG_LOG("Client " + clientName + " sent a valid packet: " + packet.to_string()); - tmp_client->_receiveQueue.push_back(packet); - return; + tmp_client->addPacketToQueue(packet); + return std::nullopt; } FLAKKARI_LOG_WARNING("Client " + clientName + " sent an invalid packet"); if (!tmp_client->incrementWarningCount()) - return; + return std::nullopt; FLAKKARI_LOG_LOG("Client " + clientName + " has been banned"); _bannedClients.push_back(ip); FLAKKARI_LOG_LOG("Client " + clientName + " banned"); - GameManager::GetInstance().removeClientFromGame(tmp_client->getGameName(), tmp_client); - GameManager::UnlockInstance(); _clients.erase(clientName); + return std::make_pair(tmp_client->getGameName(), tmp_client); } std::shared_ptr ClientManager::getClient(const std::shared_ptr &client) diff --git a/Flakkari/Server/Client/ClientManager.hpp b/Flakkari/Server/Client/ClientManager.hpp index ea745ea4..e3d1ef02 100644 --- a/Flakkari/Server/Client/ClientManager.hpp +++ b/Flakkari/Server/Client/ClientManager.hpp @@ -49,14 +49,14 @@ namespace Flakkari { * @endcode */ class ClientManager : public Singleton { - private: +private: std::unordered_map> _clients; std::vector _bannedClients; std::shared_ptr _socket; using id_t = short; - public: +public: /** * @brief Construct a new ClientManager object * @@ -74,22 +74,19 @@ class ClientManager : public Singleton { * @brief Add a client to the client manager or update the last activity of the client * * @param client The client's address + * @param buffer The packet received from the client + * @return std::optional> + * The client's name and the client object */ - bool addClient(const std::shared_ptr &client, Network::Buffer &buffer); + std::optional>> + addClient(const std::shared_ptr &client, Network::Buffer &buffer); /** * @brief Remove a client from the client manager * - * @param client The client's address - */ - void removeClient(const std::shared_ptr &client); - - /** - * @brief Ban a client from the server - * - * @param client The client's address + * @param client The client's name */ - void banClient(const std::shared_ptr &client); + void removeClient(const std::string &client); /** * @brief Check if a client is banned @@ -117,7 +114,7 @@ class ClientManager : public Singleton { * @param client The client's address * @param packet The packet to send */ - void sendPacketToClient(std::shared_ptr client, const Network::Buffer &packet); + void sendPacketToClient(const std::shared_ptr &client, const Network::Buffer &packet); /** * @brief Send a packet to all clients @@ -139,8 +136,11 @@ class ClientManager : public Singleton { * * @param client The client's address * @param packet The packet received + * @return std::optional> + * The client's name and the client object */ - void receivePacketFromClient(const std::shared_ptr &client, const Network::Buffer &packet); + std::optional>> + receivePacketFromClient(const std::shared_ptr &client, const Network::Buffer &packet); /** * @brief Get the Client object diff --git a/Flakkari/Server/Game/Game.cpp b/Flakkari/Server/Game/Game.cpp index d048f716..e36334e1 100644 --- a/Flakkari/Server/Game/Game.cpp +++ b/Flakkari/Server/Game/Game.cpp @@ -30,6 +30,7 @@ void Game::sendAllEntities(const std::string &sceneName, std::shared_ptr 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); @@ -46,7 +47,10 @@ Game::Game(const std::string &name, std::shared_ptr config) _time = std::chrono::steady_clock::now(); if ((*_config)["scenes"].empty()) - throw std::runtime_error("Game: no scenes found"); + { + FLAKKARI_LOG_ERROR("Game: no scenes found"); + return; + } loadScene((*_config)["startGame"]); ResourceManager::GetInstance().addScene(config, (*_config)["startGame"]); @@ -215,7 +219,7 @@ void Game::loadScene(const std::string &sceneName) } } -void Game::sendOnSameScene(const std::string &sceneName, const Network::Buffer &message) +void Game::sendOnSameScene(const std::string &sceneName, Protocol::Packet &packet) { for (auto &player : _players) { @@ -226,12 +230,14 @@ void Game::sendOnSameScene(const std::string &sceneName, const Network::Buffer & if (player->getSceneName() != sceneName) continue; - ClientManager::GetInstance().sendPacketToClient(player->getAddress(), message); + packet.header._apiVersion = player->getApiVersion(); + + ClientManager::GetInstance().sendPacketToClient(player->getAddress(), packet.serialize()); ClientManager::UnlockInstance(); } } -void Game::sendOnSameSceneExcept(const std::string &sceneName, const Network::Buffer &message, +void Game::sendOnSameSceneExcept(const std::string &sceneName, Protocol::Packet &packet, std::shared_ptr except) { for (auto &player : _players) @@ -245,7 +251,9 @@ void Game::sendOnSameSceneExcept(const std::string &sceneName, const Network::Bu if (player == except) continue; - ClientManager::GetInstance().sendPacketToClient(player->getAddress(), message); + packet.header._apiVersion = player->getApiVersion(); + + ClientManager::GetInstance().sendPacketToClient(player->getAddress(), packet.serialize()); ClientManager::UnlockInstance(); } } @@ -259,7 +267,7 @@ void Game::checkDisconnect() Protocol::Packet packet; packet.header._commandId = Protocol::CommandId::REQ_DISCONNECT; packet << player->getEntity(); - sendOnSameScene(player->getSceneName(), packet.serialize()); + sendOnSameScene(player->getSceneName(), packet); _scenes[player->getSceneName()].kill_entity(player->getEntity()); removePlayer(player); } @@ -288,7 +296,7 @@ void Game::sendUpdatePosition(std::shared_ptr player, Engine::ECS::Compo 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) + ")" + ">"); - sendOnSameScene(player->getSceneName(), packet.serialize()); + sendOnSameScene(player->getSceneName(), packet); } void Game::handleEvent(std::shared_ptr player, Protocol::Packet packet) @@ -380,7 +388,7 @@ void Game::handleEvent(std::shared_ptr player, Protocol::PacketgetSceneName()); shootPacket << player->getEntity(); // create a bullet with player as parent - sendOnSameScene(player->getSceneName(), shootPacket.serialize()); + sendOnSameScene(player->getSceneName(), shootPacket); } return; } @@ -392,7 +400,7 @@ void Game::updateIncomingPackets(unsigned char maxMessagePerFrame) { if (!player->isConnected()) continue; - auto &packets = player->_receiveQueue; + auto &packets = player->getReceiveQueue(); auto messageCount = maxMessagePerFrame; while (!packets.empty() && messageCount > 0) @@ -403,6 +411,15 @@ void Game::updateIncomingPackets(unsigned char maxMessagePerFrame) if (packet.header._commandId == Protocol::CommandId::REQ_USER_UPDATE) handleEvent(player, packet); + + 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(); + } } } } @@ -471,20 +488,22 @@ bool Game::addPlayer(std::shared_ptr player) Protocol::Packet packet; packet.header._commandId = Protocol::CommandId::REP_CONNECT; + packet.header._apiVersion = player->getApiVersion(); packet << newEntity; packet.injectString(sceneGame); packet.injectString(player->getName().value_or("")); packet.injectString(p_Template); ClientManager::GetInstance().sendPacketToClient(address, packet.serialize()); - ClientManager::DestroyInstance(); + ClientManager::UnlockInstance(); Protocol::Packet packet2; packet2.header._commandId = Protocol::CommandId::REQ_ENTITY_SPAWN; + packet2.header._apiVersion = packet.header._apiVersion; packet2 << newEntity; packet2.injectString(sceneGame); packet2.injectString(p_Template); - sendOnSameSceneExcept(sceneGame, packet2.serialize(), player); + sendOnSameSceneExcept(sceneGame, packet2, player); return true; } @@ -503,7 +522,7 @@ bool Game::removePlayer(std::shared_ptr player) packet.header._commandId = Protocol::CommandId::REQ_ENTITY_DESTROY; packet << entity; - sendOnSameScene(sceneGame, packet.serialize()); + sendOnSameScene(sceneGame, packet); registry.kill_entity(entity); _players.erase(it); diff --git a/Flakkari/Server/Game/Game.hpp b/Flakkari/Server/Game/Game.hpp index 440e8d66..a17679df 100644 --- a/Flakkari/Server/Game/Game.hpp +++ b/Flakkari/Server/Game/Game.hpp @@ -42,10 +42,10 @@ using nl_template = using nl_component = nlohmann::json; class Game { - public: +public: friend class Client; - public: // Constructors/Destructors +public: // Constructors/Destructors /** * @brief Construct a new Game object and load the config file * of the game. @@ -56,7 +56,7 @@ class Game { Game(const std::string &name, std::shared_ptr config); ~Game(); - public: // Loaders +public: // Loaders /** * @brief Add all the systems of the game to the registry. * @@ -91,11 +91,11 @@ class Game { */ void loadScene(const std::string &name); - public: // Actions +public: // Actions void sendAllEntities(const std::string &sceneName, std::shared_ptr player); - void sendOnSameScene(const std::string &sceneName, const Network::Buffer &message); + void sendOnSameScene(const std::string &sceneName, Protocol::Packet &packet); - void sendOnSameSceneExcept(const std::string &sceneName, const Network::Buffer &message, + void sendOnSameSceneExcept(const std::string &sceneName, Protocol::Packet &packet, std::shared_ptr except); /** @@ -175,7 +175,7 @@ class Game { */ [[nodiscard]] bool isRunning() const; - public: // Getters +public: // Getters /** * @brief Get the Name object (name of the game). * @@ -190,8 +190,8 @@ class Game { */ [[nodiscard]] std::vector> getPlayers() const; - protected: - private: +protected: +private: bool _running = false; // Is the game running std::thread _thread; // Thread of the game std::string _name; // Name of the game diff --git a/Flakkari/Server/Game/GameManager.cpp b/Flakkari/Server/Game/GameManager.cpp index dd1bce8a..f1c38285 100644 --- a/Flakkari/Server/Game/GameManager.cpp +++ b/Flakkari/Server/Game/GameManager.cpp @@ -19,7 +19,7 @@ namespace Flakkari { GameManager::GameManager(const std::string &gameDir) : _game_dir(gameDir) { if (_game_dir.empty()) - FLAKKARI_LOG_FATAL("No game directory set: please set \"FLAKKARI_GAME_DIR\" environment variable"); + throw std::runtime_error("No game directory set: please download games in the Games folder"); for (const auto &entry : std::filesystem::directory_iterator(_game_dir)) { @@ -108,18 +108,17 @@ void GameManager::listGames() FLAKKARI_LOG_INFO(gamesList); } -void GameManager::addClientToGame(const std::string &gameName, std::shared_ptr &client) +bool GameManager::addClientToGame(const std::string &gameName, std::shared_ptr client) { if (_gamesStore.find(gameName) == _gamesStore.end()) - { - FLAKKARI_LOG_ERROR("game not found"); - client.reset(); - return; - } + return FLAKKARI_LOG_ERROR("game not found"), false; auto &gameStore = _gamesStore[gameName]; auto &gameInstance = _gamesInstances[gameName]; + if (gameStore->at("online").get() == false) + return FLAKKARI_LOG_ERROR("game \"" + gameName + "\" is'nt an online game"), false; + auto minPlayers = gameStore->at("minPlayers").get(); auto maxPlayers = gameStore->at("maxPlayers").get(); auto maxInstances = gameStore->at("maxInstances").get(); @@ -135,7 +134,7 @@ void GameManager::addClientToGame(const std::string &gameName, std::shared_ptr(gameName, gameStore)); FLAKKARI_LOG_INFO("game \"" + gameName + "\" created"); @@ -148,9 +147,10 @@ void GameManager::addClientToGame(const std::string &gameName, std::shared_ptrstart(); if (lobby == "OpenWorld" && !gameInstance.back()->isRunning()) gameInstance.back()->start(); - return; + return true; } FLAKKARI_LOG_ERROR("could not add client \"" + STR_ADDRESS + "\" to game \"" + gameName + "\""); + return false; } void GameManager::removeClientFromGame(const std::string &gameName, const std::shared_ptr &client) diff --git a/Flakkari/Server/Game/GameManager.hpp b/Flakkari/Server/Game/GameManager.hpp index 9a53bec0..3a3368ad 100644 --- a/Flakkari/Server/Game/GameManager.hpp +++ b/Flakkari/Server/Game/GameManager.hpp @@ -32,14 +32,14 @@ namespace Flakkari { class GameManager : public Singleton { - private: +private: std::unordered_map> /*waitingClients*/> _waitingClients; std::unordered_map> /*gamesInstances*/> _gamesInstances; std::unordered_map /*data*/> _gamesStore; std::string _game_dir; - public: +public: /** * @brief Construct a new GameManager object and load all games * already present in the Games folder @@ -94,8 +94,10 @@ class GameManager : public Singleton { * * @param gameName Game to add the client to * @param client Client to add to the game + * @return true Client added to the game + * @return false Client not added to the game */ - void addClientToGame(const std::string &gameName, std::shared_ptr &client); + [[nodiscard]] bool addClientToGame(const std::string &gameName, std::shared_ptr client); /** * @brief Remove a client from a game @@ -112,7 +114,7 @@ class GameManager : public Singleton { * @param client Client to get the index of * @return int Index of the client in the waiting queue */ - int getIndexInWaitingQueue(const std::string &gameName, const std::shared_ptr &client); + [[nodiscard]] int getIndexInWaitingQueue(const std::string &gameName, const std::shared_ptr &client); }; } /* namespace Flakkari */ diff --git a/Flakkari/Server/Game/ResourceManager.hpp b/Flakkari/Server/Game/ResourceManager.hpp index ae127deb..2293904c 100644 --- a/Flakkari/Server/Game/ResourceManager.hpp +++ b/Flakkari/Server/Game/ResourceManager.hpp @@ -50,14 +50,14 @@ namespace Flakkari { * TODO: add a way to load multiple config files cause multiple scenes could be used for multiple windows */ class ResourceManager : public Singleton { - private: +private: using nl_template = nlohmann::json; - private: +private: std::map>> _templates; - public: +public: explicit ResourceManager() = default; ~ResourceManager() = default; diff --git a/Flakkari/Server/Internals/CommandManager.hpp b/Flakkari/Server/Internals/CommandManager.hpp index 30ddd483..adea69d3 100644 --- a/Flakkari/Server/Internals/CommandManager.hpp +++ b/Flakkari/Server/Internals/CommandManager.hpp @@ -28,14 +28,14 @@ namespace Flakkari::Internals { class CommandManager { - public: +public: static std::regex PASSWORD_REGEX; static std::regex ADD_GAME_REGEX; static std::regex UPDATE_GAME_REGEX; static std::regex REMOVE_GAME_REGEX; static bool _unlocked; - public: +public: /** * @brief Handle a command from the admin user and execute it. * @@ -44,7 +44,7 @@ class CommandManager { */ static void handleCommand(); - private: +private: /** * @brief Handle a command from the admin user and execute it. * diff --git a/Flakkari/Server/UDPServer.cpp b/Flakkari/Server/UDPServer.cpp index 1eaec131..e36e672b 100644 --- a/Flakkari/Server/UDPServer.cpp +++ b/Flakkari/Server/UDPServer.cpp @@ -62,13 +62,33 @@ bool UDPServer::handleInput(int fd) void UDPServer::handlePacket() { auto packet = _socket->receiveFrom(); - auto &instance = ClientManager::GetInstance(); + auto resultAddClient = ClientManager::GetInstance().addClient(packet->first, packet->second); + ClientManager::UnlockInstance(); + if (!resultAddClient.has_value()) + return; + + if (!resultAddClient->first.empty()) + { + bool result = GameManager::GetInstance().addClientToGame(resultAddClient->first, resultAddClient->second); + GameManager::UnlockInstance(); + if (!result) + { + ClientManager::GetInstance().removeClient(packet->first->toString().value_or("")); + ClientManager::UnlockInstance(); + } + } - bool result = instance.addClient(packet->first, packet->second); - instance.checkInactiveClients(); - if (result) - instance.receivePacketFromClient(packet->first, packet->second); + ClientManager::GetInstance().checkInactiveClients(); ClientManager::UnlockInstance(); + if (resultAddClient->first.empty()) + { + auto resultRecvClient = ClientManager::GetInstance().receivePacketFromClient(packet->first, packet->second); + ClientManager::UnlockInstance(); + if (!resultRecvClient.has_value()) + return; + GameManager::GetInstance().removeClientFromGame(resultRecvClient->first, resultRecvClient->second); + GameManager::UnlockInstance(); + } } void UDPServer::run() diff --git a/Flakkari/Server/UDPServer.hpp b/Flakkari/Server/UDPServer.hpp index ffd265a2..8f35e49a 100644 --- a/Flakkari/Server/UDPServer.hpp +++ b/Flakkari/Server/UDPServer.hpp @@ -53,7 +53,7 @@ namespace Flakkari { * @endcode */ class UDPServer { - public: +public: /** * @brief Construct a new UDPServer object * @@ -72,7 +72,7 @@ class UDPServer { */ void run(); - private: +private: /** * @brief Handle the timeout of the server (check for inactive clients) * @@ -97,7 +97,7 @@ class UDPServer { */ void handlePacket(); - private: +private: std::shared_ptr _socket; std::unique_ptr _io; }; diff --git a/docs/examples/TCPServer.cpp b/docs/examples/TCPServer.cpp index 293a09cd..7ec6b7f3 100644 --- a/docs/examples/TCPServer.cpp +++ b/docs/examples/TCPServer.cpp @@ -29,7 +29,7 @@ namespace Flakkari { class TCPServer { - public: +public: TCPServer(std::string ip = "localhost", std::size_t port = 8080) : _io(std::make_unique()) { Network::init(); @@ -75,8 +75,8 @@ class TCPServer { return 0; } - protected: - private: +protected: +private: Network::Socket _socket; std::unique_ptr _io; }; diff --git a/docs/examples/UDPClient.hpp b/docs/examples/UDPClient.hpp index 97da5dbd..23afd45f 100644 --- a/docs/examples/UDPClient.hpp +++ b/docs/examples/UDPClient.hpp @@ -24,7 +24,7 @@ namespace Flakkari { class UDPClient { - public: +public: UDPClient(std::string ip = "localhost", unsigned short port = 8080) : _io(std::make_unique()) { Network::init(); @@ -69,8 +69,8 @@ class UDPClient { return 0; } - protected: - private: +protected: +private: Network::Socket _socket; std::unique_ptr _io; }; diff --git a/docs/examples/UDPServer.hpp b/docs/examples/UDPServer.hpp index 3452c8e1..9a5bced8 100644 --- a/docs/examples/UDPServer.hpp +++ b/docs/examples/UDPServer.hpp @@ -29,7 +29,7 @@ namespace Flakkari { class UDPServer { - public: +public: UDPServer(std::string ip, unsigned short port) : _io(std::make_unique()) { Network::init(); @@ -74,8 +74,8 @@ class UDPServer { return 0; } - protected: - private: +protected: +private: Network::Socket _socket; std::unique_ptr _io; };