#pragma once #include #include #include #include #include #include namespace ts::connection { class CryptHandler; class CompressionHandler; class AcknowledgeManager; } namespace ts::stats { class ConnectionStatistics; } namespace ts::server::server::udp { struct CommandFragment { uint16_t packet_id{0}; uint16_t packet_generation{0}; uint8_t packet_flags{0}; uint32_t payload_length : 24; pipes::buffer payload{}; CommandFragment() { this->payload_length = 0; } CommandFragment(uint16_t packetId, uint16_t packetGeneration, uint8_t packetFlags, uint32_t payloadLength, pipes::buffer payload) : packet_id{packetId}, packet_generation{packetGeneration}, packet_flags{packetFlags}, payload_length{payloadLength}, payload{std::move(payload)} {} CommandFragment& operator=(const CommandFragment&) = default; CommandFragment(const CommandFragment& other) = default; CommandFragment(CommandFragment&&) = default; }; static_assert(sizeof(CommandFragment) == 8 + sizeof(pipes::buffer)); class PacketDecoder { typedef protocol::PacketRingBuffer command_fragment_buffer_t; typedef std::array command_packet_reassembler; public: typedef std::function callback_decoded_packet_t; PacketDecoder(connection::CryptHandler* /* crypt handler */, connection::CompressionHandler* /* compress handler */, connection::AcknowledgeManager* /* acknowledge handler */); ~PacketDecoder(); void reset(); void decode_incoming_data(const pipes::buffer_view &/* buffer */); [[nodiscard]] inline std::shared_ptr get_statistics() { return this->statistics_; } inline void set_statistics(const std::shared_ptr& stats) { this->statistics_ = stats; } [[nodiscard]] inline bool is_protocol_encrypted() const { return this->protocol_encrypted; } void set_protocol_encrypted(bool flag) { this->protocol_encrypted = flag; } callback_decoded_packet_t callback_decoded_packet{}; private: bool protocol_encrypted{false}; std::shared_ptr statistics_{nullptr}; connection::CryptHandler* crypt_handler_{nullptr}; connection::CompressionHandler* compress_handler_{nullptr}; connection::AcknowledgeManager* acknowledge_handler_{nullptr}; std::array incoming_generation_estimators{}; /* implementation is thread save */ std::recursive_mutex packet_buffer_lock; command_packet_reassembler _command_fragment_buffers; }; }