#include #include #include #include #include #include namespace blitz { namespace protocol { namespace PacketSerializer { #define DeclarePacket(PacketName, ...) \ void Visit(const packets::PacketName& a_Packet) override { \ const auto& packetData = a_Packet.m_Data; \ SerializePacketData(packetData); \ } \ \ void SerializePacketData(const packets::PacketName::PacketDataType& a_Packet); class Serializer : public PacketVisitor { private: ByteBuffer& m_Buffer; public: Serializer(ByteBuffer& a_Buffer) : m_Buffer(a_Buffer) {} void Serialize(const Packet& a_Packet) { m_Buffer << static_cast(a_Packet.GetType()); Check(a_Packet); } DeclareAllPacket() }; #undef DeclarePacket #define DeclarePacket(PacketName, ...) \ void Visit(const packets::PacketName& a_Packet) override { \ auto packetPtr = PacketFactory::CreatePacket(); \ auto& packetData = packetPtr->m_Data; \ \ DeserializePacketData(packetData); \ \ m_Packet = std::move(packetPtr); \ } \ \ void DeserializePacketData(packets::PacketName::PacketDataType& a_Packet); class Deserializer : public PacketVisitor { private: ByteBuffer& m_Buffer; PacketPtr m_Packet; public: Deserializer(ByteBuffer&& a_Buffer) : m_Buffer(a_Buffer) {} bool Deserialize(const PacketPtr& a_Packet) { try { Check(*a_Packet.get()); } catch (std::exception& e) { return false; } return true; } PacketPtr& GetPacket() { return m_Packet; } DeclareAllPacket() }; godot::PackedByteArray Serialize(const Packet& a_Packet) { ByteBuffer stream; Serializer serializer(stream); serializer.Serialize(a_Packet); return stream.GetByteArray(); } std::unique_ptr Deserialize(godot::PackedByteArray& a_Data) { ByteBuffer stream(std::move(a_Data)); PacketID packetId; stream >> packetId; if (packetId >= static_cast(PacketType::PACKET_COUNT)) return nullptr; PacketType packetType = PacketType(packetId); // for double-dispatch const PacketPtr& emptyPacket = PacketFactory::CreateReadOnlyPacket(packetType); Deserializer deserializer(std::move(stream)); if (deserializer.Deserialize(emptyPacket)) { PacketPtr packet = std::move(deserializer.GetPacket()); return packet; } return nullptr; } //--------------------------------------------- // Packet serializer implementation //---------------------------------------------- void Serializer::SerializePacketData(const data::PlayerLogin& a_Packet) { m_Buffer << a_Packet.m_PlayerName; } void Deserializer::DeserializePacketData(data::PlayerLogin& a_Packet) { m_Buffer >> a_Packet.m_PlayerName; } void Serializer::SerializePacketData(const data::UpdateHealth& a_Packet) { m_Buffer << a_Packet.m_NewHealth; } void Deserializer::DeserializePacketData(data::UpdateHealth& a_Packet) { m_Buffer >> a_Packet.m_NewHealth; } void Serializer::SerializePacketData(const data::LoggingSuccess& a_Packet) { m_Buffer << a_Packet.m_PlayerId; } void Deserializer::DeserializePacketData(data::LoggingSuccess& a_Packet) { m_Buffer >> a_Packet.m_PlayerId; } void Serializer::SerializePacketData(const data::PlayerDeath& a_Packet) {} void Deserializer::DeserializePacketData(data::PlayerDeath& a_Packet) {} void Serializer::SerializePacketData(const data::PlayerJoin& a_Packet) { m_Buffer << a_Packet.m_Player; } void Deserializer::DeserializePacketData(data::PlayerJoin& a_Packet) { m_Buffer >> a_Packet.m_Player; } void Serializer::SerializePacketData(const data::PlayerLeave& a_Packet) { m_Buffer << a_Packet.m_PlayerId; } void Deserializer::DeserializePacketData(data::PlayerLeave& a_Packet) { m_Buffer >> a_Packet.m_PlayerId; } void Serializer::SerializePacketData(const data::PlayerList& a_Packet) { m_Buffer << a_Packet.m_Players; // m_Buffer << static_cast(a_Packet.m_Players.size()); // for (auto player : a_Packet.m_Players) { // m_Buffer << player.m_PlayerId << player.m_PlayerName; // } } void Deserializer::DeserializePacketData(data::PlayerList& a_Packet) { m_Buffer >> a_Packet.m_Players; // std::uint8_t playerCount; // m_Buffer >> playerCount; // for (std::uint8_t i = 0; i < playerCount; i++) { // PlayerInfo player; // m_Buffer >> player.m_PlayerId >> player.m_PlayerName; // a_Packet.m_Players.push_back(player); // } } void Serializer::SerializePacketData(const data::PlayerStats& a_Packet) {} void Deserializer::DeserializePacketData(data::PlayerStats& a_Packet) {} void Serializer::SerializePacketData(const data::ServerConfig& a_Packet) {} void Deserializer::DeserializePacketData(data::ServerConfig& a_Packet) {} void Serializer::SerializePacketData(const data::ServerTps& a_Packet) {} void Deserializer::DeserializePacketData(data::ServerTps& a_Packet) {} void Serializer::SerializePacketData(const data::UpdateGameState& a_Packet) {} void Deserializer::DeserializePacketData(data::UpdateGameState& a_Packet) {} void Serializer::SerializePacketData(const data::KeepAlive& a_Packet) { m_Buffer << a_Packet.m_KeepAliveId; } void Deserializer::DeserializePacketData(data::KeepAlive& a_Packet) { m_Buffer >> a_Packet.m_KeepAliveId; } void Serializer::SerializePacketData(const data::Disconnect& a_Packet) {} void Deserializer::DeserializePacketData(data::Disconnect& a_Packet) {} void Serializer::SerializePacketData(const data::ChatMessage& a_Packet) { m_Buffer << a_Packet.m_Text; } void Deserializer::DeserializePacketData(data::ChatMessage& a_Packet) { m_Buffer >> a_Packet.m_Text; } void Serializer::SerializePacketData(const data::PlayerPositionAndRotation& a_Packet) { m_Buffer << a_Packet.m_Player << a_Packet.m_Position << a_Packet.m_Rotation; } void Deserializer::DeserializePacketData(data::PlayerPositionAndRotation& a_Packet) { m_Buffer >> a_Packet.m_Player >> a_Packet.m_Position >> a_Packet.m_Rotation; } void Serializer::SerializePacketData(const data::PlayerShoot& a_Packet) {} void Deserializer::DeserializePacketData(data::PlayerShoot& a_Packet) {} } // namespace PacketSerializer } // namespace protocol } // namespace blitz