1 #ifndef BLANK_NET_PACKET_HPP_
2 #define BLANK_NET_PACKET_HPP_
16 static constexpr std::uint32_t TAG = 0xFB1AB1AF;
18 static const char *Type2String(std::uint8_t) noexcept;
25 // true if this contains an ack for given (remote) seq
26 bool Acks(std::uint16_t) const noexcept;
27 std::uint16_t AckBegin() const noexcept { return ack; }
28 std::uint16_t AckEnd() const noexcept { return ack + std::uint16_t(33); }
35 std::uint8_t reserved1;
36 std::uint8_t reserved2;
37 std::uint8_t reserved3;
40 static constexpr std::size_t MAX_PAYLOAD_LEN = 500 - sizeof(Header);
42 std::uint8_t payload[MAX_PAYLOAD_LEN];
45 void Tag() noexcept { header.tag = TAG; }
47 void Type(std::uint8_t t) noexcept { header.type = t; }
48 std::uint8_t Type() const noexcept { return header.type; }
49 const char *TypeString() const noexcept { return Type2String(Type()); }
57 void Write(const T &, size_t off) noexcept;
59 void Read(T &, size_t off) const noexcept;
61 void WriteString(const std::string &src, std::size_t off, std::size_t maxlen) noexcept;
62 void ReadString(std::string &dst, std::size_t off, std::size_t maxlen) const noexcept;
65 struct Ping : public Payload {
66 static constexpr std::uint8_t TYPE = 0;
67 static constexpr std::size_t MAX_LEN = 0;
70 struct Login : public Payload {
71 static constexpr std::uint8_t TYPE = 1;
72 static constexpr std::size_t MAX_LEN = 32;
74 void WritePlayerName(const std::string &) noexcept;
75 void ReadPlayerName(std::string &) const noexcept;
78 struct Join : public Payload {
79 static constexpr std::uint8_t TYPE = 2;
80 static constexpr std::size_t MAX_LEN = 100;
82 void WritePlayer(const Entity &) noexcept;
83 void ReadPlayerID(std::uint32_t &) const noexcept;
84 void ReadPlayer(Entity &) const noexcept;
85 void WriteWorldName(const std::string &) noexcept;
86 void ReadWorldName(std::string &) const noexcept;
89 struct Part : public Payload {
90 static constexpr std::uint8_t TYPE = 3;
91 static constexpr std::size_t MAX_LEN = 0;
94 struct PlayerUpdate : public Payload {
95 static constexpr std::uint8_t TYPE = 4;
96 static constexpr std::size_t MAX_LEN = 64;
98 void WritePlayer(const Entity &) noexcept;
99 void ReadPlayer(Entity &) const noexcept;
102 struct SpawnEntity : public Payload {
103 static constexpr std::uint8_t TYPE = 5;
104 static constexpr std::size_t MAX_LEN = 128;
106 void WriteEntity(const Entity &) noexcept;
107 void ReadEntityID(std::uint32_t &) const noexcept;
108 void ReadEntity(Entity &) const noexcept;
111 struct DespawnEntity : public Payload {
112 static constexpr std::uint8_t TYPE = 6;
113 static constexpr std::size_t MAX_LEN = 4;
115 void WriteEntityID(std::uint32_t) noexcept;
116 void ReadEntityID(std::uint32_t &) const noexcept;
119 struct EntityUpdate : public Payload {
120 static constexpr std::uint8_t TYPE = 7;
121 static constexpr std::size_t MAX_LEN = 452;
123 static constexpr std::uint32_t MAX_ENTITIES = 7;
124 static constexpr std::size_t GetSize(std::uint32_t num) noexcept {
125 return 4 + (num * 64);
128 void WriteEntityCount(std::uint32_t) noexcept;
129 void ReadEntityCount(std::uint32_t &) const noexcept;
131 void WriteEntity(const Entity &, std::uint32_t) noexcept;
132 void ReadEntityID(std::uint32_t &, std::uint32_t) const noexcept;
133 void ReadEntity(Entity &, std::uint32_t) const noexcept;
137 template<class PayloadType>
140 result.length = PayloadType::MAX_LEN;
141 result.data = &payload[0];
145 template<class PayloadType>
146 static PayloadType As(const UDPpacket &pack) {
148 result.length = std::min(pack.len - sizeof(Header), PayloadType::MAX_LEN);
149 result.data = pack.data + sizeof(Header);
153 template<class PayloadType>
154 static PayloadType Make(UDPpacket &udp_pack) {
155 Packet &pack = *reinterpret_cast<Packet *>(udp_pack.data);
157 pack.Type(PayloadType::TYPE);
159 udp_pack.len = sizeof(Header) + PayloadType::MAX_LEN;
162 result.length = PayloadType::MAX_LEN;
163 result.data = pack.payload;