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()); }
57 void Write(const T &, size_t off) noexcept;
59 void Read(T &, size_t off) const noexcept;
61 void WriteString(const std::string &src, std::size_t off, std::size_t maxlen) noexcept;
62 void ReadString(std::string &dst, std::size_t off, std::size_t maxlen) const noexcept;
65 struct Ping : public Payload {
66 static constexpr std::uint8_t TYPE = 0;
67 static constexpr std::size_t MAX_LEN = 0;
70 struct Login : public Payload {
71 static constexpr std::uint8_t TYPE = 1;
72 static constexpr std::size_t MAX_LEN = 32;
74 void WritePlayerName(const std::string &) noexcept;
75 void ReadPlayerName(std::string &) const noexcept;
78 struct Join : public Payload {
79 static constexpr std::uint8_t TYPE = 2;
80 static constexpr std::size_t MAX_LEN = 100;
82 void WritePlayer(const Entity &) noexcept;
83 void ReadPlayerID(std::uint32_t &) const noexcept;
84 void ReadPlayer(Entity &) const noexcept;
85 void WriteWorldName(const std::string &) noexcept;
86 void ReadWorldName(std::string &) const noexcept;
89 struct Part : public Payload {
90 static constexpr std::uint8_t TYPE = 3;
91 static constexpr std::size_t MAX_LEN = 0;
94 struct PlayerUpdate : public Payload {
95 static constexpr std::uint8_t TYPE = 4;
96 static constexpr std::size_t MAX_LEN = 64;
98 void WritePlayer(const Entity &) noexcept;
99 void ReadPlayer(Entity &) const noexcept;
102 struct SpawnEntity : public Payload {
103 static constexpr std::uint8_t TYPE = 5;
104 static constexpr std::size_t MAX_LEN = 132;
106 void WriteEntity(const Entity &) noexcept;
107 void ReadEntityID(std::uint32_t &) const noexcept;
108 void ReadSkeletonID(std::uint32_t &) const noexcept;
109 void ReadEntity(Entity &) const noexcept;
112 struct DespawnEntity : public Payload {
113 static constexpr std::uint8_t TYPE = 6;
114 static constexpr std::size_t MAX_LEN = 4;
116 void WriteEntityID(std::uint32_t) noexcept;
117 void ReadEntityID(std::uint32_t &) const noexcept;
120 struct EntityUpdate : public Payload {
121 static constexpr std::uint8_t TYPE = 7;
122 static constexpr std::size_t MAX_LEN = 452;
124 static constexpr std::uint32_t MAX_ENTITIES = 7;
125 static constexpr std::size_t GetSize(std::uint32_t num) noexcept {
126 return 4 + (num * 64);
129 void WriteEntityCount(std::uint32_t) noexcept;
130 void ReadEntityCount(std::uint32_t &) const noexcept;
132 void WriteEntity(const Entity &, std::uint32_t) noexcept;
133 void ReadEntityID(std::uint32_t &, std::uint32_t) const noexcept;
134 void ReadEntity(Entity &, std::uint32_t) const noexcept;
138 template<class PayloadType>
141 result.length = PayloadType::MAX_LEN;
142 result.data = &payload[0];
146 template<class PayloadType>
147 static PayloadType As(const UDPpacket &pack) {
149 result.length = std::min(pack.len - sizeof(Header), PayloadType::MAX_LEN);
150 result.data = pack.data + sizeof(Header);
154 template<class PayloadType>
155 static PayloadType Make(UDPpacket &udp_pack) {
156 Packet &pack = *reinterpret_cast<Packet *>(udp_pack.data);
158 pack.Type(PayloadType::TYPE);
160 udp_pack.len = sizeof(Header) + PayloadType::MAX_LEN;
163 result.length = PayloadType::MAX_LEN;
164 result.data = pack.payload;