1 #ifndef BLANK_NET_PACKET_HPP_
2 #define BLANK_NET_PACKET_HPP_
4 #include "../graphics/glm.hpp"
20 static constexpr std::uint32_t TAG = 0xFB1AB1AF;
22 static const char *Type2String(std::uint8_t) noexcept;
29 // true if this contains an ack for given (remote) seq
30 bool Acks(std::uint16_t) const noexcept;
31 std::uint16_t AckBegin() const noexcept { return ack; }
32 std::uint16_t AckEnd() const noexcept { return ack - std::uint16_t(33); }
39 std::uint8_t reserved1;
40 std::uint8_t reserved2;
41 std::uint8_t reserved3;
44 static constexpr std::size_t MAX_PAYLOAD_LEN = 500 - sizeof(Header);
46 std::uint8_t payload[MAX_PAYLOAD_LEN];
49 void Tag() noexcept { header.tag = TAG; }
51 void Type(std::uint8_t t) noexcept { header.type = t; }
52 std::uint8_t Type() const noexcept { return header.type; }
53 const char *TypeString() const noexcept { return Type2String(Type()); }
60 /// WARNING: do not use these if the data doesn not
61 /// point into a real packet's payload
62 const Packet &GetPacket() const noexcept {
63 return *reinterpret_cast<const Packet *>(data - sizeof(Header));
65 const Header &GetHeader() const noexcept {
66 return GetPacket().header;
68 std::uint16_t Seq() const noexcept {
69 return GetHeader().ctrl.seq;
73 void Write(const T &, size_t off) noexcept;
75 void Read(T &, size_t off) const noexcept;
77 void Write(const glm::quat &, size_t off) noexcept;
78 void Read(glm::quat &, size_t off) const noexcept;
79 void Write(const EntityState &, size_t off) noexcept;
80 void Read(EntityState &, size_t off) const noexcept;
81 void Write(const EntityState &, const glm::ivec3 &, size_t off) noexcept;
82 void Read(EntityState &, const glm::ivec3 &, size_t off) const noexcept;
84 void WriteString(const std::string &src, std::size_t off, std::size_t maxlen) noexcept;
85 void ReadString(std::string &dst, std::size_t off, std::size_t maxlen) const noexcept;
87 void WritePackB(const glm::ivec3 &, size_t off) noexcept;
88 void ReadPackB(glm::ivec3 &, size_t off) const noexcept;
90 void WritePackN(float, size_t off) noexcept;
91 void ReadPackN(float &, size_t off) const noexcept;
92 void WritePackN(const glm::vec3 &, size_t off) noexcept;
93 void ReadPackN(glm::vec3 &, size_t off) const noexcept;
95 void WritePackU(float, size_t off) noexcept;
96 void ReadPackU(float &, size_t off) const noexcept;
97 void WritePackU(const glm::vec3 &, size_t off) noexcept;
98 void ReadPackU(glm::vec3 &, size_t off) const noexcept;
101 struct Ping : public Payload {
102 static constexpr std::uint8_t TYPE = 0;
103 static constexpr std::size_t MAX_LEN = 0;
106 struct Login : public Payload {
107 static constexpr std::uint8_t TYPE = 1;
108 static constexpr std::size_t MAX_LEN = 32;
110 void WritePlayerName(const std::string &) noexcept;
111 void ReadPlayerName(std::string &) const noexcept;
114 struct Join : public Payload {
115 static constexpr std::uint8_t TYPE = 2;
116 static constexpr std::size_t MAX_LEN = 78;
118 void WritePlayer(const Entity &) noexcept;
119 void ReadPlayerID(std::uint32_t &) const noexcept;
120 void ReadPlayerState(EntityState &) const noexcept;
121 void WriteWorldName(const std::string &) noexcept;
122 void ReadWorldName(std::string &) const noexcept;
125 struct Part : public Payload {
126 static constexpr std::uint8_t TYPE = 3;
127 static constexpr std::size_t MAX_LEN = 0;
130 struct PlayerUpdate : public Payload {
131 static constexpr std::uint8_t TYPE = 4;
132 static constexpr std::size_t MAX_LEN = 50;
134 void WritePredictedState(const EntityState &) noexcept;
135 void ReadPredictedState(EntityState &) const noexcept;
136 void WriteMovement(const glm::vec3 &) noexcept;
137 void ReadMovement(glm::vec3 &) const noexcept;
138 void WriteActions(std::uint8_t) noexcept;
139 void ReadActions(std::uint8_t &) const noexcept;
140 void WriteSlot(std::uint8_t) noexcept;
141 void ReadSlot(std::uint8_t &) const noexcept;
144 struct SpawnEntity : public Payload {
145 static constexpr std::uint8_t TYPE = 5;
146 static constexpr std::size_t MAX_LEN = 110;
148 void WriteEntity(const Entity &) noexcept;
149 void ReadEntityID(std::uint32_t &) const noexcept;
150 void ReadModelID(std::uint32_t &) const noexcept;
151 void ReadEntity(Entity &) const noexcept;
154 struct DespawnEntity : public Payload {
155 static constexpr std::uint8_t TYPE = 6;
156 static constexpr std::size_t MAX_LEN = 4;
158 void WriteEntityID(std::uint32_t) noexcept;
159 void ReadEntityID(std::uint32_t &) const noexcept;
162 struct EntityUpdate : public Payload {
163 static constexpr std::uint8_t TYPE = 7;
164 static constexpr std::size_t MAX_LEN = 460;
166 static constexpr std::uint32_t MAX_ENTITIES = 12;
167 static constexpr std::size_t GetSize(std::uint32_t num) noexcept {
168 return 16 + (num * 37);
171 void WriteEntityCount(std::uint32_t) noexcept;
172 void ReadEntityCount(std::uint32_t &) const noexcept;
173 void WriteChunkBase(const glm::ivec3 &) noexcept;
174 void ReadChunkBase(glm::ivec3 &) const noexcept;
176 void WriteEntity(const Entity &, const glm::ivec3 &, std::uint32_t) noexcept;
177 void ReadEntityID(std::uint32_t &, std::uint32_t) const noexcept;
178 void ReadEntityState(EntityState &, const glm::ivec3 &, std::uint32_t) const noexcept;
181 struct PlayerCorrection : public Payload {
182 static constexpr std::uint8_t TYPE = 8;
183 static constexpr std::size_t MAX_LEN = 44;
185 void WritePacketSeq(std::uint16_t) noexcept;
186 void ReadPacketSeq(std::uint16_t &) const noexcept;
187 void WritePlayer(const Entity &) noexcept;
188 void ReadPlayerState(EntityState &) const noexcept;
191 struct ChunkBegin : public Payload {
192 static constexpr std::uint8_t TYPE = 9;
193 static constexpr std::size_t MAX_LEN = 24;
195 void WriteTransmissionId(std::uint32_t) noexcept;
196 void ReadTransmissionId(std::uint32_t &) const noexcept;
197 void WriteFlags(std::uint32_t) noexcept;
198 void ReadFlags(std::uint32_t &) const noexcept;
199 void WriteChunkCoords(const glm::ivec3 &) noexcept;
200 void ReadChunkCoords(glm::ivec3 &) const noexcept;
201 void WriteDataSize(std::uint32_t) noexcept;
202 void ReadDataSize(std::uint32_t &) const noexcept;
205 struct ChunkData : public Payload {
206 static constexpr std::uint8_t TYPE = 10;
207 static constexpr std::size_t MAX_LEN = MAX_PAYLOAD_LEN;
208 static constexpr std::size_t MAX_DATA_LEN = MAX_LEN - 12;
210 static constexpr std::size_t GetSize(std::size_t data_len) noexcept {
211 return data_len + 12;
214 void WriteTransmissionId(std::uint32_t) noexcept;
215 void ReadTransmissionId(std::uint32_t &) const noexcept;
216 void WriteDataOffset(std::uint32_t) noexcept;
217 void ReadDataOffset(std::uint32_t &) const noexcept;
218 void WriteDataSize(std::uint32_t) noexcept;
219 void ReadDataSize(std::uint32_t &) const noexcept;
220 void WriteData(const std::uint8_t *, std::size_t len) noexcept;
221 void ReadData(std::uint8_t *, std::size_t maxlen) const noexcept;
224 struct BlockUpdate : public Payload {
225 static constexpr std::uint8_t TYPE = 11;
226 static constexpr std::size_t MAX_LEN = 484;
228 static constexpr std::uint32_t MAX_BLOCKS = 78;
229 static constexpr std::size_t GetSize(std::uint32_t num) noexcept {
230 return 16 + (num * 6);
233 void WriteChunkCoords(const glm::ivec3 &) noexcept;
234 void ReadChunkCoords(glm::ivec3 &) const noexcept;
235 void WriteBlockCount(std::uint32_t) noexcept;
236 void ReadBlockCount(std::uint32_t &) const noexcept;
238 void WriteIndex(std::uint16_t, std::uint32_t) noexcept;
239 void ReadIndex(std::uint16_t &, std::uint32_t) const noexcept;
240 void WriteBlock(const Block &, std::uint32_t) noexcept;
241 void ReadBlock(Block &, std::uint32_t) const noexcept;
244 struct Message : public Payload {
245 static constexpr std::uint8_t TYPE = 12;
246 static constexpr std::size_t MAX_LEN = 455;
248 static constexpr std::size_t MAX_MESSAGE_LEN = 450;
249 static std::size_t GetSize(const std::string &msg) noexcept {
250 return 5 + std::min(msg.size() + 1, MAX_MESSAGE_LEN);
253 void WriteType(std::uint8_t) noexcept;
254 void ReadType(std::uint8_t &) const noexcept;
255 void WriteReferral(std::uint32_t) noexcept;
256 void ReadReferral(std::uint32_t &) const noexcept;
257 void WriteMessage(const std::string &) noexcept;
258 void ReadMessage(std::string &) const noexcept;
262 template<class PayloadType>
265 result.length = PayloadType::MAX_LEN;
266 result.data = &payload[0];
270 template<class PayloadType>
271 static PayloadType As(const UDPpacket &pack) {
273 result.length = std::min(pack.len - sizeof(Header), PayloadType::MAX_LEN);
274 result.data = pack.data + sizeof(Header);
278 template<class PayloadType>
279 static PayloadType Make(UDPpacket &udp_pack) {
280 Packet &pack = *reinterpret_cast<Packet *>(udp_pack.data);
282 pack.Type(PayloadType::TYPE);
284 udp_pack.len = sizeof(Header) + PayloadType::MAX_LEN;
287 result.length = PayloadType::MAX_LEN;
288 result.data = pack.payload;