1 #ifndef BLANK_NET_PACKET_HPP_
2 #define BLANK_NET_PACKET_HPP_
18 static constexpr std::uint32_t TAG = 0xFB1AB1AF;
20 static const char *Type2String(std::uint8_t) noexcept;
27 // true if this contains an ack for given (remote) seq
28 bool Acks(std::uint16_t) const noexcept;
29 std::uint16_t AckBegin() const noexcept { return ack; }
30 std::uint16_t AckEnd() const noexcept { return ack - std::uint16_t(33); }
37 std::uint8_t reserved1;
38 std::uint8_t reserved2;
39 std::uint8_t reserved3;
42 static constexpr std::size_t MAX_PAYLOAD_LEN = 500 - sizeof(Header);
44 std::uint8_t payload[MAX_PAYLOAD_LEN];
47 void Tag() noexcept { header.tag = TAG; }
49 void Type(std::uint8_t t) noexcept { header.type = t; }
50 std::uint8_t Type() const noexcept { return header.type; }
51 const char *TypeString() const noexcept { return Type2String(Type()); }
58 /// WARNING: do not use these if the data doesn not
59 /// point into a real packet's payload
60 const Packet &GetPacket() const noexcept {
61 return *reinterpret_cast<const Packet *>(data - sizeof(Header));
63 const Header &GetHeader() const noexcept {
64 return GetPacket().header;
66 std::uint16_t Seq() const noexcept {
67 return GetHeader().ctrl.seq;
71 void Write(const T &, size_t off) noexcept;
73 void Read(T &, size_t off) const noexcept;
75 void WriteString(const std::string &src, std::size_t off, std::size_t maxlen) noexcept;
76 void ReadString(std::string &dst, std::size_t off, std::size_t maxlen) const noexcept;
79 struct Ping : public Payload {
80 static constexpr std::uint8_t TYPE = 0;
81 static constexpr std::size_t MAX_LEN = 0;
84 struct Login : public Payload {
85 static constexpr std::uint8_t TYPE = 1;
86 static constexpr std::size_t MAX_LEN = 32;
88 void WritePlayerName(const std::string &) noexcept;
89 void ReadPlayerName(std::string &) const noexcept;
92 struct Join : public Payload {
93 static constexpr std::uint8_t TYPE = 2;
94 static constexpr std::size_t MAX_LEN = 100;
96 void WritePlayer(const Entity &) noexcept;
97 void ReadPlayerID(std::uint32_t &) const noexcept;
98 void ReadPlayerState(EntityState &) const noexcept;
99 void WriteWorldName(const std::string &) noexcept;
100 void ReadWorldName(std::string &) const noexcept;
103 struct Part : public Payload {
104 static constexpr std::uint8_t TYPE = 3;
105 static constexpr std::size_t MAX_LEN = 0;
108 struct PlayerUpdate : public Payload {
109 static constexpr std::uint8_t TYPE = 4;
110 static constexpr std::size_t MAX_LEN = 64;
112 void WritePlayer(const Entity &) noexcept;
113 void ReadPlayerState(EntityState &) const noexcept;
116 struct SpawnEntity : public Payload {
117 static constexpr std::uint8_t TYPE = 5;
118 static constexpr std::size_t MAX_LEN = 132;
120 void WriteEntity(const Entity &) noexcept;
121 void ReadEntityID(std::uint32_t &) const noexcept;
122 void ReadSkeletonID(std::uint32_t &) const noexcept;
123 void ReadEntity(Entity &) const noexcept;
126 struct DespawnEntity : public Payload {
127 static constexpr std::uint8_t TYPE = 6;
128 static constexpr std::size_t MAX_LEN = 4;
130 void WriteEntityID(std::uint32_t) noexcept;
131 void ReadEntityID(std::uint32_t &) const noexcept;
134 struct EntityUpdate : public Payload {
135 static constexpr std::uint8_t TYPE = 7;
136 static constexpr std::size_t MAX_LEN = 452;
138 static constexpr std::uint32_t MAX_ENTITIES = 7;
139 static constexpr std::size_t GetSize(std::uint32_t num) noexcept {
140 return 4 + (num * 68);
143 void WriteEntityCount(std::uint32_t) noexcept;
144 void ReadEntityCount(std::uint32_t &) const noexcept;
146 void WriteEntity(const Entity &, std::uint32_t) noexcept;
147 void ReadEntityID(std::uint32_t &, std::uint32_t) const noexcept;
148 void ReadEntityState(EntityState &, std::uint32_t) const noexcept;
151 struct PlayerCorrection : public Payload {
152 static constexpr std::uint8_t TYPE = 8;
153 static constexpr std::size_t MAX_LEN = 66;
155 void WritePacketSeq(std::uint16_t) noexcept;
156 void ReadPacketSeq(std::uint16_t &) const noexcept;
157 void WritePlayer(const Entity &) noexcept;
158 void ReadPlayerState(EntityState &) const noexcept;
161 struct ChunkBegin : public Payload {
162 static constexpr std::uint8_t TYPE = 9;
163 static constexpr std::size_t MAX_LEN = 24;
165 void WriteTransmissionId(std::uint32_t) noexcept;
166 void ReadTransmissionId(std::uint32_t &) const noexcept;
167 void WriteFlags(std::uint32_t) noexcept;
168 void ReadFlags(std::uint32_t &) const noexcept;
169 void WriteChunkCoords(const glm::ivec3 &) noexcept;
170 void ReadChunkCoords(glm::ivec3 &) const noexcept;
171 void WriteDataSize(std::uint32_t) noexcept;
172 void ReadDataSize(std::uint32_t &) const noexcept;
175 struct ChunkData : public Payload {
176 static constexpr std::uint8_t TYPE = 10;
177 static constexpr std::size_t MAX_LEN = MAX_PAYLOAD_LEN;
178 static constexpr std::size_t MAX_DATA_LEN = MAX_LEN - 12;
180 void WriteTransmissionId(std::uint32_t) noexcept;
181 void ReadTransmissionId(std::uint32_t &) const noexcept;
182 void WriteDataOffset(std::uint32_t) noexcept;
183 void ReadDataOffset(std::uint32_t &) const noexcept;
184 void WriteDataSize(std::uint32_t) noexcept;
185 void ReadDataSize(std::uint32_t &) const noexcept;
186 void WriteData(const std::uint8_t *, std::size_t len) noexcept;
187 void ReadData(std::uint8_t *, std::size_t maxlen) const noexcept;
191 template<class PayloadType>
194 result.length = PayloadType::MAX_LEN;
195 result.data = &payload[0];
199 template<class PayloadType>
200 static PayloadType As(const UDPpacket &pack) {
202 result.length = std::min(pack.len - sizeof(Header), PayloadType::MAX_LEN);
203 result.data = pack.data + sizeof(Header);
207 template<class PayloadType>
208 static PayloadType Make(UDPpacket &udp_pack) {
209 Packet &pack = *reinterpret_cast<Packet *>(udp_pack.data);
211 pack.Type(PayloadType::TYPE);
213 udp_pack.len = sizeof(Header) + PayloadType::MAX_LEN;
216 result.length = PayloadType::MAX_LEN;
217 result.data = pack.payload;