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()); }
56 std::uint16_t Seq() const noexcept {
57 return reinterpret_cast<const Packet *>(data - sizeof(Header))->header.ctrl.seq;
61 void Write(const T &, size_t off) noexcept;
63 void Read(T &, size_t off) const noexcept;
65 void WriteString(const std::string &src, std::size_t off, std::size_t maxlen) noexcept;
66 void ReadString(std::string &dst, std::size_t off, std::size_t maxlen) const noexcept;
69 struct Ping : public Payload {
70 static constexpr std::uint8_t TYPE = 0;
71 static constexpr std::size_t MAX_LEN = 0;
74 struct Login : public Payload {
75 static constexpr std::uint8_t TYPE = 1;
76 static constexpr std::size_t MAX_LEN = 32;
78 void WritePlayerName(const std::string &) noexcept;
79 void ReadPlayerName(std::string &) const noexcept;
82 struct Join : public Payload {
83 static constexpr std::uint8_t TYPE = 2;
84 static constexpr std::size_t MAX_LEN = 100;
86 void WritePlayer(const Entity &) noexcept;
87 void ReadPlayerID(std::uint32_t &) const noexcept;
88 void ReadPlayer(Entity &) const noexcept;
89 void WriteWorldName(const std::string &) noexcept;
90 void ReadWorldName(std::string &) const noexcept;
93 struct Part : public Payload {
94 static constexpr std::uint8_t TYPE = 3;
95 static constexpr std::size_t MAX_LEN = 0;
98 struct PlayerUpdate : public Payload {
99 static constexpr std::uint8_t TYPE = 4;
100 static constexpr std::size_t MAX_LEN = 64;
102 void WritePlayer(const Entity &) noexcept;
103 void ReadPlayer(Entity &) const noexcept;
106 struct SpawnEntity : public Payload {
107 static constexpr std::uint8_t TYPE = 5;
108 static constexpr std::size_t MAX_LEN = 132;
110 void WriteEntity(const Entity &) noexcept;
111 void ReadEntityID(std::uint32_t &) const noexcept;
112 void ReadSkeletonID(std::uint32_t &) const noexcept;
113 void ReadEntity(Entity &) const noexcept;
116 struct DespawnEntity : public Payload {
117 static constexpr std::uint8_t TYPE = 6;
118 static constexpr std::size_t MAX_LEN = 4;
120 void WriteEntityID(std::uint32_t) noexcept;
121 void ReadEntityID(std::uint32_t &) const noexcept;
124 struct EntityUpdate : public Payload {
125 static constexpr std::uint8_t TYPE = 7;
126 static constexpr std::size_t MAX_LEN = 452;
128 static constexpr std::uint32_t MAX_ENTITIES = 7;
129 static constexpr std::size_t GetSize(std::uint32_t num) noexcept {
130 return 4 + (num * 64);
133 void WriteEntityCount(std::uint32_t) noexcept;
134 void ReadEntityCount(std::uint32_t &) const noexcept;
136 void WriteEntity(const Entity &, std::uint32_t) noexcept;
137 void ReadEntityID(std::uint32_t &, std::uint32_t) const noexcept;
138 void ReadEntity(Entity &, std::uint32_t) const noexcept;
142 template<class PayloadType>
145 result.length = PayloadType::MAX_LEN;
146 result.data = &payload[0];
150 template<class PayloadType>
151 static PayloadType As(const UDPpacket &pack) {
153 result.length = std::min(pack.len - sizeof(Header), PayloadType::MAX_LEN);
154 result.data = pack.data + sizeof(Header);
158 template<class PayloadType>
159 static PayloadType Make(UDPpacket &udp_pack) {
160 Packet &pack = *reinterpret_cast<Packet *>(udp_pack.data);
162 pack.Type(PayloadType::TYPE);
164 udp_pack.len = sizeof(Header) + PayloadType::MAX_LEN;
167 result.length = PayloadType::MAX_LEN;
168 result.data = pack.payload;