87class FGE_API ProtocolPacket :
public Packet,
public std::enable_shared_from_this<ProtocolPacket>
97 UPDATE_FULL_TIMESTAMP,
98 UPDATE_CORRECTION_LATENCY
103 constexpr explicit Option(
Options option, std::size_t argument = 0) :
112 using IdType = uint16_t;
113 using RealmType = uint16_t;
114 using CounterType = uint16_t;
120 CounterType _counter;
121 CounterType _lastCounter;
124 constexpr static std::size_t HeaderSize =
sizeof(IdType) +
sizeof(RealmType) +
sizeof(CounterType) * 2;
125 constexpr static std::size_t IdPosition = 0;
126 constexpr static std::size_t RealmPosition =
sizeof(IdType);
127 constexpr static std::size_t CounterPosition =
sizeof(IdType) +
sizeof(RealmType);
128 constexpr static std::size_t ReorderedCounterPosition =
sizeof(IdType) +
sizeof(RealmType) +
sizeof(CounterType);
130 inline ProtocolPacket(Packet
const& pck,
132 std::size_t fluxIndex = 0,
133 std::size_t fluxLifetime = 0);
134 inline ProtocolPacket(Packet&& pck,
Identity const&
id, std::size_t fluxIndex = 0, std::size_t fluxLifetime = 0);
135 inline ProtocolPacket(IdType header,
136 RealmType realmId = FGE_NET_DEFAULT_REALM,
137 CounterType countId = 0,
138 CounterType lastCountId = 0);
140 inline ProtocolPacket(Packet
const& r);
141 inline ProtocolPacket(Packet&& r)
noexcept;
143 inline ProtocolPacket(ProtocolPacket
const& r);
144 inline ProtocolPacket(ProtocolPacket&& r)
noexcept;
146 inline ~ProtocolPacket()
override =
default;
148 [[nodiscard]]
inline Packet& packet() noexcept {
return *
this; }
149 [[nodiscard]]
inline Packet const& packet() const noexcept {
return *
this; }
151 [[nodiscard]]
inline bool haveCorrectHeader()
const;
152 [[nodiscard]]
inline bool haveCorrectHeaderSize()
const;
153 [[nodiscard]]
inline std::optional<IdType> retrieveHeaderId()
const;
154 [[nodiscard]]
inline std::optional<IdType> retrieveFlags()
const;
155 [[nodiscard]]
inline std::optional<IdType> retrieveFullHeaderId()
const;
156 [[nodiscard]]
inline std::optional<RealmType> retrieveRealm()
const;
157 [[nodiscard]]
inline std::optional<CounterType> retrieveCounter()
const;
158 [[nodiscard]]
inline std::optional<CounterType> retrieveReorderedCounter()
const;
159 [[nodiscard]]
inline std::optional<Header> retrieveHeader()
const;
161 [[nodiscard]]
inline bool isFragmented()
const;
163 inline ProtocolPacket& setHeader(Header
const& header);
164 inline ProtocolPacket& setHeaderId(IdType
id);
166 inline ProtocolPacket& setFlags(IdType flags);
167 inline ProtocolPacket& addFlags(IdType flags);
168 inline ProtocolPacket& removeFlags(IdType flags);
169 [[nodiscard]]
inline bool checkFlags(IdType flags)
const;
170 inline ProtocolPacket& doNotDiscard();
171 inline ProtocolPacket& doNotReorder();
172 inline ProtocolPacket& doNotFragment();
174 inline ProtocolPacket& setRealm(RealmType realm);
175 inline ProtocolPacket& setCounter(CounterType counter);
176 inline ProtocolPacket& setReorderedCounter(CounterType counter);
178 inline void setTimestamp(Timestamp timestamp);
179 [[nodiscard]]
inline Timestamp getTimeStamp()
const;
180 [[nodiscard]]
inline Identity
const& getIdentity()
const;
182 [[nodiscard]]
inline std::vector<Option>
const& options()
const;
183 [[nodiscard]]
inline std::vector<Option>& options();
185 [[nodiscard]]
bool compress(
Compressor& compressor);
186 [[nodiscard]]
bool decompress(
Compressor& compressor);
188 inline void markForEncryption();
189 inline void unmarkForEncryption();
190 [[nodiscard]]
inline bool isMarkedForEncryption()
const;
192 inline void markAsLocallyReordered();
193 inline void unmarkAsLocallyReordered();
194 [[nodiscard]]
inline bool isMarkedAsLocallyReordered()
const;
196 inline void markAsCached();
197 inline void unmarkAsCached();
198 [[nodiscard]]
inline bool isMarkedAsCached()
const;
227 inline std::size_t getFluxIndex()
const;
228 inline std::size_t bumpFluxIndex(std::size_t fluxSize);
230 [[nodiscard]] std::vector<std::unique_ptr<ProtocolPacket>> fragment(uint16_t mtu)
const;
236 std::size_t g_fluxIndex{0};
237 std::size_t g_fluxLifetime{0};
239 bool g_markedForEncryption{
false};
240 bool g_markedAsLocallyReordered{
false};
241 bool g_markedAsCached{
false};
243 std::vector<Option> g_options;
289class PacketDefragmentation
292 PacketDefragmentation() =
default;
293 PacketDefragmentation(PacketDefragmentation
const& r) =
delete;
294 PacketDefragmentation(PacketDefragmentation&& r)
noexcept =
default;
295 ~PacketDefragmentation() =
default;
297 PacketDefragmentation& operator=(PacketDefragmentation
const& r) =
delete;
298 PacketDefragmentation& operator=(PacketDefragmentation&& r)
noexcept =
default;
309 ProtocolPacket::RealmType _id;
314 [[nodiscard]]
Result process(ReceivedPacketPtr&& packet);
315 [[nodiscard]] ReceivedPacketPtr retrieve(ProtocolPacket::RealmType
id,
Identity const& client);
320 Data(ProtocolPacket::RealmType
id, ProtocolPacket::CounterType total) :
326 ProtocolPacket::RealmType _id;
327 decltype(InternalFragmentedPacketData::_fragmentTotal) _count;
328 std::vector<ReceivedPacketPtr> _fragments;
330 std::vector<Data> g_data;
340class FGE_API PacketReorderer
348 WAITING_NEXT_COUNTER,
352 PacketReorderer() =
default;
353 PacketReorderer(PacketReorderer
const& r) =
delete;
354 PacketReorderer(PacketReorderer&& r)
noexcept =
default;
355 ~PacketReorderer() =
default;
357 PacketReorderer& operator=(PacketReorderer
const& r) =
delete;
358 PacketReorderer& operator=(PacketReorderer&& r)
noexcept =
default;
364 void push(ReceivedPacketPtr&& packet);
366 [[nodiscard]]
static Stats checkStat(ReceivedPacketPtr
const& packet,
Client const& client,
bool ignoreRealm);
367 [[nodiscard]]
static Stats checkStat(ReceivedPacketPtr
const& packet,
368 ProtocolPacket::CounterType peerCounter,
369 ProtocolPacket::CounterType peerReorderedCounter,
370 ProtocolPacket::RealmType peerRealm,
372 [[nodiscard]] std::optional<Stats> checkStat(
Client const& client,
bool ignoreRealm)
const;
373 [[nodiscard]] std::optional<Stats> checkStat(ProtocolPacket::CounterType peerCounter,
374 ProtocolPacket::CounterType peerReorderedCounter,
375 ProtocolPacket::RealmType peerRealm,
376 bool ignoreRealm)
const;
378 [[nodiscard]] ReceivedPacketPtr pop();
380 [[nodiscard]]
bool isEmpty()
const;
381 [[nodiscard]]
bool isForced()
const;
383 void setMaximumSize(std::size_t size);
384 [[nodiscard]] std::size_t getMaximumSize()
const;
389 explicit Data(ReceivedPacketPtr&& packet);
390 Data(Data
const& r) =
delete;
391 Data(Data&& r)
noexcept;
394 Data& operator=(Data
const& r) =
delete;
395 Data& operator=(Data&& r)
noexcept;
397 [[nodiscard]] Stats checkStat(ProtocolPacket::CounterType peerCounter,
398 ProtocolPacket::CounterType peerReorderedCounter,
399 ProtocolPacket::RealmType peerRealm,
400 bool ignoreRealm)
const;
402 ReceivedPacketPtr _packet;
403 ProtocolPacket::CounterType _counter;
404 ProtocolPacket::CounterType _reorderedCounter;
405 ProtocolPacket::RealmType _realm;
409 [[nodiscard]]
constexpr bool operator()(Data
const& l, Data
const& r)
const
411 if (l._realm == r._realm)
413 return l._reorderedCounter > r._reorderedCounter;
415 return l._realm > r._realm;
420 std::priority_queue<Data, std::vector<Data>,
Data::Compare> g_cache;
421 std::size_t g_cacheSize{FGE_NET_DEFAULT_PACKET_REORDERER_CACHE_SIZE};
422 bool g_forceRetrieve{
false};
425class FGE_API PacketCache
430 constexpr Label() =
default;
431 constexpr Label(ProtocolPacket::CounterType counter, ProtocolPacket::RealmType realm) :
436 ProtocolPacket::CounterType _counter{0};
437 ProtocolPacket::RealmType _realm{0};
439 [[nodiscard]]
constexpr bool operator==(Label
const& r)
const
441 return this->_counter == r._counter && this->_realm == r._realm;
446 [[nodiscard]]
inline std::size_t operator()(Label
const& label)
const
448 static_assert(
sizeof(label._counter) ==
sizeof(label._realm) &&
sizeof(label._counter) == 2,
449 "ProtocolPacket::CounterType and ProtocolPacket::RealmType must be 16 bits");
450 return std::hash<std::size_t>()(
static_cast<std::size_t
>(label._counter) << 16 |
451 static_cast<std::size_t
>(label._realm));
457 PacketCache(PacketCache
const& r) =
delete;
458 PacketCache(PacketCache&& r)
noexcept;
459 ~PacketCache() =
default;
461 PacketCache& operator=(PacketCache
const& r) =
delete;
462 PacketCache& operator=(PacketCache&& r)
noexcept;
465 [[nodiscard]]
bool isEmpty()
const;
466 [[nodiscard]]
bool isEnabled()
const;
467 [[nodiscard]]
bool isAlarmed()
const;
468 void enable(
bool enable);
471 void push(TransmitPacketPtr
const& packet);
474 void acknowledgeReception(std::span<Label> labels);
477 bool process(std::chrono::steady_clock::time_point
const& timePoint,
Client& client);
483 explicit Data(TransmitPacketPtr&& packet);
485 Data& operator=(TransmitPacketPtr&& packet);
487 TransmitPacketPtr _packet;
489 std::chrono::steady_clock::time_point _time{};
490 unsigned int _tryCount{0};
493 mutable std::mutex g_mutex;
495 std::vector<Data> g_cache;
498 bool g_enable{
false};