]> git.localhorst.tv Git - blank.git/blobdiff - src/net/Packet.hpp
reorganized client state
[blank.git] / src / net / Packet.hpp
index 0d99fee2992c74c61a1979dfe251813c69e607ca..bd9dd86436a68ff0c08c548b8dd8b2031aa06ee2 100644 (file)
@@ -4,6 +4,7 @@
 #include <cstdint>
 #include <ostream>
 #include <string>
+#include <SDL_net.h>
 
 
 namespace blank {
@@ -14,14 +15,7 @@ struct Packet {
 
        static constexpr std::uint32_t TAG = 0xFB1AB1AF;
 
-       enum Type {
-               PING = 0,
-               LOGIN = 1,
-               JOIN = 2,
-               PART = 3,
-       };
-
-       static const char *Type2String(Type) noexcept;
+       static const char *Type2String(std::uint8_t) noexcept;
 
        struct TControl {
                std::uint16_t seq;
@@ -35,23 +29,91 @@ struct Packet {
                std::uint8_t type;
        } header;
 
-       std::uint8_t payload[500 - sizeof(Header)];
+       static constexpr std::size_t MAX_PAYLOAD_LEN = 500 - sizeof(Header);
 
+       std::uint8_t payload[MAX_PAYLOAD_LEN];
 
-       Type GetType() const noexcept { return Type(header.type); }
 
-       void Tag() noexcept;
+       void Tag() noexcept { header.tag = TAG; }
 
-       std::size_t MakePing() noexcept;
-       std::size_t MakeLogin(const std::string &name) noexcept;
-       std::size_t MakeJoin(const Entity &player, const std::string &world_name) noexcept;
-       std::size_t MakePart() noexcept;
+       void Type(std::uint8_t t) noexcept { header.type = t; }
+       std::uint8_t Type() const noexcept { return header.type; }
+       const char *TypeString() const noexcept { return Type2String(Type()); }
 
-};
 
-inline std::ostream &operator <<(std::ostream &out, Packet::Type t) {
-       return out << Packet::Type2String(t);
-}
+       struct Payload {
+               std::size_t length;
+               std::uint8_t *data;
+
+               template<class T>
+               void Write(const T &, size_t off) noexcept;
+               template<class T>
+               void Read(T &, size_t off) const noexcept;
+
+               void WriteString(const std::string &src, std::size_t off, std::size_t maxlen) noexcept;
+               void ReadString(std::string &dst, std::size_t off, std::size_t maxlen) const noexcept;
+       };
+
+       struct Ping : public Payload {
+               static constexpr std::uint8_t TYPE = 0;
+               static constexpr std::size_t MAX_LEN = 0;
+       };
+
+       struct Login : public Payload {
+               static constexpr std::uint8_t TYPE = 1;
+               static constexpr std::size_t MAX_LEN = 32;
+
+               void WritePlayerName(const std::string &) noexcept;
+               void ReadPlayerName(std::string &) const noexcept;
+       };
+
+       struct Join : public Payload {
+               static constexpr std::uint8_t TYPE = 2;
+               static constexpr std::size_t MAX_LEN = 100;
+
+               void WritePlayer(const Entity &) noexcept;
+               void ReadPlayer(Entity &) const noexcept;
+               void WriteWorldName(const std::string &) noexcept;
+               void ReadWorldName(std::string &) const noexcept;
+       };
+
+       struct Part : public Payload {
+               static constexpr std::uint8_t TYPE = 3;
+               static constexpr std::size_t MAX_LEN = 0;
+       };
+
+
+       template<class PayloadType>
+       PayloadType As() {
+               PayloadType result;
+               result.length = PayloadType::MAX_LEN;
+               result.data = &payload[0];
+               return result;
+       }
+
+       template<class PayloadType>
+       static PayloadType As(const UDPpacket &pack) {
+               PayloadType result;
+               result.length = std::min(pack.len - sizeof(Header), PayloadType::MAX_LEN);
+               result.data = pack.data + sizeof(Header);
+               return result;
+       }
+
+       template<class PayloadType>
+       static PayloadType Make(UDPpacket &udp_pack) {
+               Packet &pack = *reinterpret_cast<Packet *>(udp_pack.data);
+               pack.Tag();
+               pack.Type(PayloadType::TYPE);
+
+               udp_pack.len = sizeof(Header) + PayloadType::TYPE;
+
+               PayloadType result;
+               result.length = PayloadType::MAX_LEN;
+               result.data = pack.payload;
+               return result;
+       }
+
+};
 
 }