1 #ifndef BLANK_NET_PACKET_HPP_
2 #define BLANK_NET_PACKET_HPP_
19 static constexpr std::uint32_t TAG = 0xFB1AB1AF;
21 static const char *Type2String(std::uint8_t) noexcept;
28 // true if this contains an ack for given (remote) seq
29 bool Acks(std::uint16_t) const noexcept;
30 std::uint16_t AckBegin() const noexcept { return ack; }
31 std::uint16_t AckEnd() const noexcept { return ack - std::uint16_t(33); }
38 std::uint8_t reserved1;
39 std::uint8_t reserved2;
40 std::uint8_t reserved3;
43 static constexpr std::size_t MAX_PAYLOAD_LEN = 500 - sizeof(Header);
45 std::uint8_t payload[MAX_PAYLOAD_LEN];
48 void Tag() noexcept { header.tag = TAG; }
50 void Type(std::uint8_t t) noexcept { header.type = t; }
51 std::uint8_t Type() const noexcept { return header.type; }
52 const char *TypeString() const noexcept { return Type2String(Type()); }
59 /// WARNING: do not use these if the data doesn not
60 /// point into a real packet's payload
61 const Packet &GetPacket() const noexcept {
62 return *reinterpret_cast<const Packet *>(data - sizeof(Header));
64 const Header &GetHeader() const noexcept {
65 return GetPacket().header;
67 std::uint16_t Seq() const noexcept {
68 return GetHeader().ctrl.seq;
72 void Write(const T &, size_t off) noexcept;
74 void Read(T &, size_t off) const noexcept;
76 void Write(const glm::quat &, size_t off) noexcept;
77 void Read(glm::quat &, size_t off) const noexcept;
78 void Write(const EntityState &, size_t off) noexcept;
79 void Read(EntityState &, size_t off) const noexcept;
80 void Write(const EntityState &, const glm::ivec3 &, size_t off) noexcept;
81 void Read(EntityState &, const glm::ivec3 &, size_t off) const noexcept;
83 void WriteString(const std::string &src, std::size_t off, std::size_t maxlen) noexcept;
84 void ReadString(std::string &dst, std::size_t off, std::size_t maxlen) const noexcept;
86 void WritePackB(const glm::ivec3 &, size_t off) noexcept;
87 void ReadPackB(glm::ivec3 &, size_t off) const noexcept;
89 void WritePackN(float, size_t off) noexcept;
90 void ReadPackN(float &, size_t off) const noexcept;
91 void WritePackN(const glm::vec3 &, size_t off) noexcept;
92 void ReadPackN(glm::vec3 &, size_t off) const noexcept;
94 void WritePackU(float, size_t off) noexcept;
95 void ReadPackU(float &, size_t off) const noexcept;
96 void WritePackU(const glm::vec3 &, size_t off) noexcept;
97 void ReadPackU(glm::vec3 &, size_t off) const noexcept;
100 struct Ping : public Payload {
101 static constexpr std::uint8_t TYPE = 0;
102 static constexpr std::size_t MAX_LEN = 0;
105 struct Login : public Payload {
106 static constexpr std::uint8_t TYPE = 1;
107 static constexpr std::size_t MAX_LEN = 32;
109 void WritePlayerName(const std::string &) noexcept;
110 void ReadPlayerName(std::string &) const noexcept;
113 struct Join : public Payload {
114 static constexpr std::uint8_t TYPE = 2;
115 static constexpr std::size_t MAX_LEN = 86;
117 void WritePlayer(const Entity &) noexcept;
118 void ReadPlayerID(std::uint32_t &) const noexcept;
119 void ReadPlayerState(EntityState &) const noexcept;
120 void WriteWorldName(const std::string &) noexcept;
121 void ReadWorldName(std::string &) const noexcept;
124 struct Part : public Payload {
125 static constexpr std::uint8_t TYPE = 3;
126 static constexpr std::size_t MAX_LEN = 0;
129 struct PlayerUpdate : public Payload {
130 static constexpr std::uint8_t TYPE = 4;
131 static constexpr std::size_t MAX_LEN = 62;
133 void WritePredictedState(const EntityState &) noexcept;
134 void ReadPredictedState(EntityState &) const noexcept;
135 void WriteMovement(const glm::vec3 &) noexcept;
136 void ReadMovement(glm::vec3 &) const noexcept;
137 void WritePitch(float) noexcept;
138 void ReadPitch(float &) const noexcept;
139 void WriteYaw(float) noexcept;
140 void ReadYaw(float &) const noexcept;
141 void WriteActions(std::uint8_t) noexcept;
142 void ReadActions(std::uint8_t &) const noexcept;
143 void WriteSlot(std::uint8_t) noexcept;
144 void ReadSlot(std::uint8_t &) const noexcept;
147 struct SpawnEntity : public Payload {
148 static constexpr std::uint8_t TYPE = 5;
149 static constexpr std::size_t MAX_LEN = 118;
151 void WriteEntity(const Entity &) noexcept;
152 void ReadEntityID(std::uint32_t &) const noexcept;
153 void ReadModelID(std::uint32_t &) const noexcept;
154 void ReadEntity(Entity &) const noexcept;
157 struct DespawnEntity : public Payload {
158 static constexpr std::uint8_t TYPE = 6;
159 static constexpr std::size_t MAX_LEN = 4;
161 void WriteEntityID(std::uint32_t) noexcept;
162 void ReadEntityID(std::uint32_t &) const noexcept;
165 struct EntityUpdate : public Payload {
166 static constexpr std::uint8_t TYPE = 7;
167 static constexpr std::size_t MAX_LEN = 466;
169 static constexpr std::uint32_t MAX_ENTITIES = 10;
170 static constexpr std::size_t GetSize(std::uint32_t num) noexcept {
171 return 16 + (num * 45);
174 void WriteEntityCount(std::uint32_t) noexcept;
175 void ReadEntityCount(std::uint32_t &) const noexcept;
176 void WriteChunkBase(const glm::ivec3 &) noexcept;
177 void ReadChunkBase(glm::ivec3 &) const noexcept;
179 void WriteEntity(const Entity &, const glm::ivec3 &, std::uint32_t) noexcept;
180 void ReadEntityID(std::uint32_t &, std::uint32_t) const noexcept;
181 void ReadEntityState(EntityState &, const glm::ivec3 &, std::uint32_t) const noexcept;
184 struct PlayerCorrection : public Payload {
185 static constexpr std::uint8_t TYPE = 8;
186 static constexpr std::size_t MAX_LEN = 52;
188 void WritePacketSeq(std::uint16_t) noexcept;
189 void ReadPacketSeq(std::uint16_t &) const noexcept;
190 void WritePlayer(const Entity &) noexcept;
191 void ReadPlayerState(EntityState &) const noexcept;
194 struct ChunkBegin : public Payload {
195 static constexpr std::uint8_t TYPE = 9;
196 static constexpr std::size_t MAX_LEN = 24;
198 void WriteTransmissionId(std::uint32_t) noexcept;
199 void ReadTransmissionId(std::uint32_t &) const noexcept;
200 void WriteFlags(std::uint32_t) noexcept;
201 void ReadFlags(std::uint32_t &) const noexcept;
202 void WriteChunkCoords(const glm::ivec3 &) noexcept;
203 void ReadChunkCoords(glm::ivec3 &) const noexcept;
204 void WriteDataSize(std::uint32_t) noexcept;
205 void ReadDataSize(std::uint32_t &) const noexcept;
208 struct ChunkData : public Payload {
209 static constexpr std::uint8_t TYPE = 10;
210 static constexpr std::size_t MAX_LEN = MAX_PAYLOAD_LEN;
211 static constexpr std::size_t MAX_DATA_LEN = MAX_LEN - 12;
213 void WriteTransmissionId(std::uint32_t) noexcept;
214 void ReadTransmissionId(std::uint32_t &) const noexcept;
215 void WriteDataOffset(std::uint32_t) noexcept;
216 void ReadDataOffset(std::uint32_t &) const noexcept;
217 void WriteDataSize(std::uint32_t) noexcept;
218 void ReadDataSize(std::uint32_t &) const noexcept;
219 void WriteData(const std::uint8_t *, std::size_t len) noexcept;
220 void ReadData(std::uint8_t *, std::size_t maxlen) const noexcept;
223 struct BlockUpdate : public Payload {
224 static constexpr std::uint8_t TYPE = 11;
225 static constexpr std::size_t MAX_LEN = 484;
227 static constexpr std::uint32_t MAX_BLOCKS = 78;
228 static constexpr std::size_t GetSize(std::uint32_t num) noexcept {
229 return 16 + (num * 6);
232 void WriteChunkCoords(const glm::ivec3 &) noexcept;
233 void ReadChunkCoords(glm::ivec3 &) const noexcept;
234 void WriteBlockCount(std::uint32_t) noexcept;
235 void ReadBlockCount(std::uint32_t &) const noexcept;
237 void WriteIndex(std::uint16_t, std::uint32_t) noexcept;
238 void ReadIndex(std::uint16_t &, std::uint32_t) const noexcept;
239 void WriteBlock(const Block &, std::uint32_t) noexcept;
240 void ReadBlock(Block &, std::uint32_t) const noexcept;
243 struct Message : public Payload {
244 static constexpr std::uint8_t TYPE = 12;
245 static constexpr std::size_t MAX_LEN = 455;
247 static constexpr std::size_t MAX_MESSAGE_LEN = 450;
248 static std::size_t GetSize(const std::string &msg) noexcept {
249 return 5 + std::min(msg.size() + 1, MAX_MESSAGE_LEN);
252 void WriteType(std::uint8_t) noexcept;
253 void ReadType(std::uint8_t &) const noexcept;
254 void WriteReferral(std::uint32_t) noexcept;
255 void ReadReferral(std::uint32_t &) const noexcept;
256 void WriteMessage(const std::string &) noexcept;
257 void ReadMessage(std::string &) const noexcept;
261 template<class PayloadType>
264 result.length = PayloadType::MAX_LEN;
265 result.data = &payload[0];
269 template<class PayloadType>
270 static PayloadType As(const UDPpacket &pack) {
272 result.length = std::min(pack.len - sizeof(Header), PayloadType::MAX_LEN);
273 result.data = pack.data + sizeof(Header);
277 template<class PayloadType>
278 static PayloadType Make(UDPpacket &udp_pack) {
279 Packet &pack = *reinterpret_cast<Packet *>(udp_pack.data);
281 pack.Type(PayloadType::TYPE);
283 udp_pack.len = sizeof(Header) + PayloadType::MAX_LEN;
286 result.length = PayloadType::MAX_LEN;
287 result.data = pack.payload;