#pragma once #include #include #include // std::linear_congruential_engine #include #include "acio2emu/internal/lz.h" namespace acio2emu { struct Packet { uint8_t node; uint8_t tag; std::vector payload; }; class PacketDecoder { private: Packet packet_ = {}; // order matters, don't change this enum! enum payloadEncoding { byteStuffing, raw, unknown, replace, lz, } encoding_; uint32_t payload_size_ = 0, payload_size_count_ = 0; // payloadEncoding::replace state uint8_t substitute_; // payloadEncoding::lz state detail::InflateTransformer inflate_; // deobfuscation state bool obfuscated_; std::linear_congruential_engine lcg_; enum class readStep { idle, readNode, readTag, readPayloadSize, readPayloadFlags, readReplacementByte, readPayload, readEscaped, } step_ = readStep::idle; void set_step_(readStep s); void reset_(readStep s); int update_payload_size_(uint8_t b); uint8_t deobfuscate_(uint8_t b); public: bool update(uint8_t b); const Packet &packet(); }; bool encode_packet(std::queue &out, uint8_t node, uint8_t tag, const std::vector &payload); }