1 #ifndef BLANK_NET_PACKET_HPP_
2 #define BLANK_NET_PACKET_HPP_
17 static constexpr std::uint32_t TAG = 0xFB1AB1AF;
19 static const char *Type2String(std::uint8_t) noexcept;
26 // true if this contains an ack for given (remote) seq
27 bool Acks(std::uint16_t) const noexcept;
28 std::uint16_t AckBegin() const noexcept { return ack; }
29 std::uint16_t AckEnd() const noexcept { return ack + std::uint16_t(33); }
36 std::uint8_t reserved1;
37 std::uint8_t reserved2;
38 std::uint8_t reserved3;
41 static constexpr std::size_t MAX_PAYLOAD_LEN = 500 - sizeof(Header);
43 std::uint8_t payload[MAX_PAYLOAD_LEN];
46 void Tag() noexcept { header.tag = TAG; }
48 void Type(std::uint8_t t) noexcept { header.type = t; }
49 std::uint8_t Type() const noexcept { return header.type; }
50 const char *TypeString() const noexcept { return Type2String(Type()); }
57 std::uint16_t Seq() const noexcept {
58 return reinterpret_cast<const Packet *>(data - sizeof(Header))->header.ctrl.seq;
62 void Write(const T &, size_t off) noexcept;
64 void Read(T &, size_t off) const noexcept;
66 void WriteString(const std::string &src, std::size_t off, std::size_t maxlen) noexcept;
67 void ReadString(std::string &dst, std::size_t off, std::size_t maxlen) const noexcept;
70 struct Ping : public Payload {
71 static constexpr std::uint8_t TYPE = 0;
72 static constexpr std::size_t MAX_LEN = 0;
75 struct Login : public Payload {
76 static constexpr std::uint8_t TYPE = 1;
77 static constexpr std::size_t MAX_LEN = 32;
79 void WritePlayerName(const std::string &) noexcept;
80 void ReadPlayerName(std::string &) const noexcept;
83 struct Join : public Payload {
84 static constexpr std::uint8_t TYPE = 2;
85 static constexpr std::size_t MAX_LEN = 100;
87 void WritePlayer(const Entity &) noexcept;
88 void ReadPlayerID(std::uint32_t &) const noexcept;
89 void ReadPlayerState(EntityState &) const noexcept;
90 void WriteWorldName(const std::string &) noexcept;
91 void ReadWorldName(std::string &) const noexcept;
94 struct Part : public Payload {
95 static constexpr std::uint8_t TYPE = 3;
96 static constexpr std::size_t MAX_LEN = 0;
99 struct PlayerUpdate : public Payload {
100 static constexpr std::uint8_t TYPE = 4;
101 static constexpr std::size_t MAX_LEN = 64;
103 void WritePlayer(const Entity &) noexcept;
104 void ReadPlayerState(EntityState &) const noexcept;
107 struct SpawnEntity : public Payload {
108 static constexpr std::uint8_t TYPE = 5;
109 static constexpr std::size_t MAX_LEN = 132;
111 void WriteEntity(const Entity &) noexcept;
112 void ReadEntityID(std::uint32_t &) const noexcept;
113 void ReadSkeletonID(std::uint32_t &) const noexcept;
114 void ReadEntity(Entity &) const noexcept;
117 struct DespawnEntity : public Payload {
118 static constexpr std::uint8_t TYPE = 6;
119 static constexpr std::size_t MAX_LEN = 4;
121 void WriteEntityID(std::uint32_t) noexcept;
122 void ReadEntityID(std::uint32_t &) const noexcept;
125 struct EntityUpdate : public Payload {
126 static constexpr std::uint8_t TYPE = 7;
127 static constexpr std::size_t MAX_LEN = 452;
129 static constexpr std::uint32_t MAX_ENTITIES = 7;
130 static constexpr std::size_t GetSize(std::uint32_t num) noexcept {
131 return 4 + (num * 64);
134 void WriteEntityCount(std::uint32_t) noexcept;
135 void ReadEntityCount(std::uint32_t &) const noexcept;
137 void WriteEntity(const Entity &, std::uint32_t) noexcept;
138 void ReadEntityID(std::uint32_t &, std::uint32_t) const noexcept;
139 void ReadEntityState(EntityState &, std::uint32_t) const noexcept;
142 struct PlayerCorrection : public Payload {
143 static constexpr std::uint8_t TYPE = 8;
144 static constexpr std::size_t MAX_LEN = 66;
146 void WritePacketSeq(std::uint16_t) noexcept;
147 void ReadPacketSeq(std::uint16_t &) const noexcept;
148 void WritePlayer(const Entity &) noexcept;
149 void ReadPlayerState(EntityState &) const noexcept;
153 template<class PayloadType>
156 result.length = PayloadType::MAX_LEN;
157 result.data = &payload[0];
161 template<class PayloadType>
162 static PayloadType As(const UDPpacket &pack) {
164 result.length = std::min(pack.len - sizeof(Header), PayloadType::MAX_LEN);
165 result.data = pack.data + sizeof(Header);
169 template<class PayloadType>
170 static PayloadType Make(UDPpacket &udp_pack) {
171 Packet &pack = *reinterpret_cast<Packet *>(udp_pack.data);
173 pack.Type(PayloadType::TYPE);
175 udp_pack.len = sizeof(Header) + PayloadType::MAX_LEN;
178 result.length = PayloadType::MAX_LEN;
179 result.data = pack.payload;