FastEngine 0.9.4
A multiplayer oriented 2D engine made with Vulkan.
Loading...
Searching...
No Matches
C_protocol.inl
1/*
2 * Copyright 2025 Guillaume Guillet
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17namespace fge::net
18{
19inline ProtocolPacket::ProtocolPacket(Packet const& pck,
20 Identity const& id,
21 std::size_t fluxIndex,
22 std::size_t fluxLifetime) :
23 Packet(pck),
24
25 g_identity(id),
26
27 g_fluxIndex(fluxIndex),
28 g_fluxLifetime(fluxLifetime)
29{}
30inline ProtocolPacket::ProtocolPacket(Packet&& pck,
31 Identity const& id,
32 std::size_t fluxIndex,
33 std::size_t fluxLifetime) :
34 Packet(std::move(pck)),
35
36 g_identity(id),
37
38 g_fluxIndex(fluxIndex),
39 g_fluxLifetime(fluxLifetime)
40{}
41inline ProtocolPacket::ProtocolPacket(IdType header, RealmType realmId, CounterType countId, CounterType lastCountId)
42{
43 this->operator<<(header) << realmId << countId << lastCountId;
44}
45
46inline ProtocolPacket::ProtocolPacket(Packet const& r) :
47 Packet(r)
48{}
49inline ProtocolPacket::ProtocolPacket(Packet&& r) noexcept :
50 Packet(std::move(r))
51{}
52
53inline ProtocolPacket::ProtocolPacket(ProtocolPacket const& r) :
54 Packet(r),
55 std::enable_shared_from_this<ProtocolPacket>(r),
56
57 g_identity(r.g_identity),
58 g_timestamp(r.g_timestamp),
59
60 g_fluxIndex(r.g_fluxIndex),
61 g_fluxLifetime(r.g_fluxLifetime),
62
63 g_markedForEncryption(r.g_markedForEncryption),
64 g_markedAsLocallyReordered(r.g_markedAsLocallyReordered),
65 g_markedAsCached(r.g_markedAsCached),
66
67 g_options(r.g_options)
68{}
69inline ProtocolPacket::ProtocolPacket(ProtocolPacket&& r) noexcept :
70 Packet(std::move(r)),
71 std::enable_shared_from_this<ProtocolPacket>(std::move(r)),
72
73 g_identity(r.g_identity),
74 g_timestamp(r.g_timestamp),
75
76 g_fluxIndex(r.g_fluxIndex),
77 g_fluxLifetime(r.g_fluxLifetime),
78
79 g_markedForEncryption(r.g_markedForEncryption),
80 g_markedAsLocallyReordered(r.g_markedAsLocallyReordered),
81 g_markedAsCached(r.g_markedAsCached),
82
83 g_options(std::move(r.g_options))
84{}
85
86inline bool ProtocolPacket::haveCorrectHeader() const
87{
88 if (this->haveCorrectHeaderSize())
89 {
90 IdType headerId;
91 this->unpack(IdPosition, &headerId, sizeof(IdType));
92
93 if ((headerId & ~FGE_NET_HEADER_FLAGS_MASK) == FGE_NET_BAD_ID)
94 {
95 return false;
96 }
97 return true;
98 }
99 return false;
100}
101inline bool ProtocolPacket::haveCorrectHeaderSize() const
102{
103 return this->getDataSize() >= HeaderSize;
104}
105inline std::optional<ProtocolPacket::IdType> ProtocolPacket::retrieveHeaderId() const
106{
107 if (this->haveCorrectHeaderSize())
108 {
109 IdType headerId;
110 this->unpack(IdPosition, &headerId, sizeof(IdType));
111 return headerId & ~FGE_NET_HEADER_FLAGS_MASK;
112 }
113 return std::nullopt;
114}
115inline std::optional<ProtocolPacket::IdType> ProtocolPacket::retrieveFlags() const
116{
117 if (this->haveCorrectHeaderSize())
118 {
119 IdType headerFlags;
120 this->unpack(IdPosition, &headerFlags, sizeof(IdType));
121 return headerFlags & FGE_NET_HEADER_FLAGS_MASK;
122 }
123 return std::nullopt;
124}
125inline std::optional<ProtocolPacket::IdType> ProtocolPacket::retrieveFullHeaderId() const
126{
127 if (this->haveCorrectHeaderSize())
128 {
129 IdType headerId;
130 this->unpack(IdPosition, &headerId, sizeof(IdType));
131 return headerId;
132 }
133 return std::nullopt;
134}
135inline std::optional<ProtocolPacket::RealmType> ProtocolPacket::retrieveRealm() const
136{
137 if (this->haveCorrectHeaderSize())
138 {
139 RealmType realm;
140 this->unpack(RealmPosition, &realm, sizeof(RealmType));
141 return realm;
142 }
143 return std::nullopt;
144}
145inline std::optional<ProtocolPacket::CounterType> ProtocolPacket::retrieveCounter() const
146{
147 if (this->haveCorrectHeaderSize())
148 {
149 CounterType counter;
150 this->unpack(CounterPosition, &counter, sizeof(CounterType));
151 return counter;
152 }
153 return std::nullopt;
154}
155inline std::optional<ProtocolPacket::CounterType> ProtocolPacket::retrieveLastCounter() const
156{
157 if (this->haveCorrectHeaderSize())
158 {
159 CounterType counter;
160 this->unpack(LastCounterPosition, &counter, sizeof(CounterType));
161 return counter;
162 }
163 return std::nullopt;
164}
165inline std::optional<ProtocolPacket::Header> ProtocolPacket::retrieveHeader() const
166{
167 if (this->haveCorrectHeaderSize())
168 {
169 Header header{};
170 this->unpack(IdPosition, &header._id, sizeof(IdType));
171 this->unpack(RealmPosition, &header._realm, sizeof(RealmType));
172 this->unpack(CounterPosition, &header._counter, sizeof(CounterType));
173 this->unpack(LastCounterPosition, &header._lastCounter, sizeof(CounterType));
174 return header;
175 }
176 return std::nullopt;
177}
178inline bool ProtocolPacket::isFragmented() const
179{
180 return this->retrieveHeaderId().value_or(FGE_NET_BAD_ID) == NET_INTERNAL_ID_FRAGMENTED_PACKET;
181}
182
183inline ProtocolPacket& ProtocolPacket::setHeader(Header const& header)
184{
185 if (!this->haveCorrectHeaderSize())
186 {
187 this->append(HeaderSize - this->getDataSize());
188 }
189
190 this->pack(IdPosition, &header._id, sizeof(IdType));
191 this->pack(RealmPosition, &header._realm, sizeof(RealmType));
192 this->pack(CounterPosition, &header._counter, sizeof(CounterType));
193 this->pack(LastCounterPosition, &header._lastCounter, sizeof(CounterType));
194 return *this;
195}
196inline ProtocolPacket& ProtocolPacket::setHeaderId(IdType id)
197{
198 if (this->haveCorrectHeaderSize())
199 {
200 IdType headerFlags;
201 this->unpack(IdPosition, &headerFlags, sizeof(IdType));
202 id = (headerFlags & FGE_NET_HEADER_FLAGS_MASK) | (id & ~FGE_NET_HEADER_FLAGS_MASK);
203 this->pack(IdPosition, &id, sizeof(IdType));
204 }
205 return *this;
206}
207
208inline ProtocolPacket& ProtocolPacket::setFlags(IdType flags)
209{
210 if (this->haveCorrectHeaderSize())
211 {
212 IdType headerId;
213 this->unpack(IdPosition, &headerId, sizeof(IdType));
214 headerId = (headerId & ~FGE_NET_HEADER_FLAGS_MASK) | (flags & FGE_NET_HEADER_FLAGS_MASK);
215 this->pack(IdPosition, &headerId, sizeof(IdType));
216 }
217 return *this;
218}
219inline ProtocolPacket& ProtocolPacket::addFlags(IdType flags)
220{
221 if (this->haveCorrectHeaderSize())
222 {
223 IdType headerId;
224 this->unpack(IdPosition, &headerId, sizeof(IdType));
225 headerId |= flags & FGE_NET_HEADER_FLAGS_MASK;
226 this->pack(IdPosition, &headerId, sizeof(IdType));
227 }
228 return *this;
229}
230inline ProtocolPacket& ProtocolPacket::removeFlags(IdType flags)
231{
232 if (this->haveCorrectHeaderSize())
233 {
234 IdType headerId;
235 this->unpack(IdPosition, &headerId, sizeof(IdType));
236 headerId &= ~(flags & FGE_NET_HEADER_FLAGS_MASK);
237 this->pack(IdPosition, &headerId, sizeof(IdType));
238 }
239 return *this;
240}
241inline bool ProtocolPacket::checkFlags(IdType flags) const
242{
243 if (this->haveCorrectHeaderSize())
244 {
245 IdType headerId;
246 this->unpack(IdPosition, &headerId, sizeof(IdType));
247 return ((headerId & FGE_NET_HEADER_FLAGS_MASK) & (flags & FGE_NET_HEADER_FLAGS_MASK)) > 0;
248 }
249 return false;
250}
251inline ProtocolPacket& ProtocolPacket::doNotDiscard()
252{
253 return this->addFlags(FGE_NET_HEADER_DO_NOT_DISCARD_FLAG);
254}
255inline ProtocolPacket& ProtocolPacket::doNotReorder()
256{
257 return this->addFlags(FGE_NET_HEADER_DO_NOT_REORDER_FLAG);
258}
259inline ProtocolPacket& ProtocolPacket::doNotFragment()
260{
261 return this->addFlags(FGE_NET_HEADER_DO_NOT_FRAGMENT_FLAG);
262}
263
264inline ProtocolPacket& ProtocolPacket::setRealm(RealmType realm)
265{
266 this->pack(RealmPosition, &realm, sizeof(RealmType));
267 return *this;
268}
269inline ProtocolPacket& ProtocolPacket::setCounter(CounterType counter)
270{
271 this->pack(CounterPosition, &counter, sizeof(CounterType));
272 return *this;
273}
274inline ProtocolPacket& ProtocolPacket::setLastReorderedPacketCounter(CounterType counter)
275{
276 this->pack(LastCounterPosition, &counter, sizeof(CounterType));
277 return *this;
278}
279
280inline void ProtocolPacket::setTimestamp(Timestamp timestamp)
281{
282 this->g_timestamp = timestamp;
283}
284inline Timestamp ProtocolPacket::getTimeStamp() const
285{
286 return this->g_timestamp;
287}
288inline Identity const& ProtocolPacket::getIdentity() const
289{
290 return this->g_identity;
291}
292
293inline std::vector<ProtocolPacket::Option> const& ProtocolPacket::options() const
294{
295 return this->g_options;
296}
297inline std::vector<ProtocolPacket::Option>& ProtocolPacket::options()
298{
299 return this->g_options;
300}
301
302inline void ProtocolPacket::markForEncryption()
303{
304 this->g_markedForEncryption = true;
305}
306inline void ProtocolPacket::unmarkForEncryption()
307{
308 this->g_markedForEncryption = false;
309}
310inline bool ProtocolPacket::isMarkedForEncryption() const
311{
312 return this->g_markedForEncryption;
313}
314
315inline void ProtocolPacket::markAsLocallyReordered()
316{
317 this->g_markedAsLocallyReordered = true;
318}
319inline void ProtocolPacket::unmarkAsLocallyReordered()
320{
321 this->g_markedAsLocallyReordered = false;
322}
323inline bool ProtocolPacket::isMarkedAsLocallyReordered() const
324{
325 return this->g_markedAsLocallyReordered;
326}
327
328inline void ProtocolPacket::markAsCached()
329{
330 this->g_markedAsCached = true;
331}
332inline void ProtocolPacket::unmarkAsCached()
333{
334 this->g_markedAsCached = false;
335}
336inline bool ProtocolPacket::isMarkedAsCached() const
337{
338 return this->g_markedAsCached;
339}
340
341inline bool ProtocolPacket::checkFluxLifetime(std::size_t fluxSize)
342{
343 if (++this->g_fluxLifetime >= fluxSize)
344 {
345 return false;
346 }
347 this->g_fluxIndex = (this->g_fluxIndex + 1) % fluxSize;
348 return true;
349}
350inline std::size_t ProtocolPacket::getFluxIndex() const
351{
352 return this->g_fluxIndex;
353}
354inline std::size_t ProtocolPacket::bumpFluxIndex(std::size_t fluxSize)
355{
356 this->g_fluxIndex = (this->g_fluxIndex + 1) % fluxSize;
357 return this->g_fluxIndex;
358}
359
360} // namespace fge::net
Definition C_packet.hpp:52
bool checkFluxLifetime(std::size_t fluxSize)
Check if the flux lifetime is reached.
Definition C_protocol.inl:341
uint16_t Timestamp
An timestamp represent modulated current time in milliseconds.
Definition C_client.hpp:62
A class to represent a client or server identity with an IP address and a port.
Definition C_identity.hpp:31