FastEngine 0.9.5
A multiplayer oriented 2D engine made with Vulkan.
Loading...
Searching...
No Matches
C_client.hpp
1/*
2 * Copyright 2026 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
17#ifndef _FGE_C_CLIENT_HPP_INCLUDED
18#define _FGE_C_CLIENT_HPP_INCLUDED
19
20#include "FastEngine/fge_extern.hpp"
21#include "C_identity.hpp"
22#include "FastEngine/C_event.hpp"
23#include "FastEngine/C_propertyList.hpp"
24#include "FastEngine/network/C_netCommand.hpp"
25#include "FastEngine/network/C_protocol.hpp"
26#include <array>
27#include <atomic>
28#include <chrono>
29#include <deque>
30#include <memory>
31#include <mutex>
32#include <unordered_set>
33
34#define FGE_NET_DEFAULT_LATENCY 20
35#define FGE_NET_CLIENT_TIMESTAMP_MODULO 65536
36#define FGE_NET_BAD_LATENCY std::numeric_limits<fge::net::Latency_ms>::max()
37#define FGE_NET_LATENCY_PLANNER_MEAN 6
38#define FGE_NET_DEFAULT_lOST_PACKET_THRESHOLD 15
39#define FGE_NET_STATUS_DEFAULT_TIMEOUT \
40 std::chrono::milliseconds \
41 { \
42 2000 \
43 }
44#define FGE_NET_STATUS_DEFAULT_CONNECTED_TIMEOUT \
45 std::chrono::milliseconds \
46 { \
47 6000 \
48 }
49#define FGE_NET_STATUS_DEFAULT_STATUS "none"
50
51#define FGE_NET_DEFAULT_RETURN_PACKET_RATE \
52 std::chrono::milliseconds \
53 { \
54 500 \
55 }
56
57namespace fge::net
58{
59
63
64using Timestamp = uint16_t;
65using FullTimestamp = uint64_t;
66using FullTimestampOffset = int64_t;
67using Latency_ms = uint16_t;
68
79class FGE_API OneWayLatencyPlanner
80{
81public:
82 OneWayLatencyPlanner() = default;
83
84 enum Stats : uint8_t
85 {
86 HAVE_EXTERNAL_TIMESTAMP = 1 << 0
87 };
88
94 void pack(TransmitPacketPtr& tPacket);
101 void unpack(ProtocolPacket* packet, Client& client);
102
111 [[nodiscard]] std::optional<FullTimestampOffset> getClockOffset() const;
117 [[nodiscard]] std::optional<Latency_ms> getLatency() const;
125 [[nodiscard]] std::optional<Latency_ms> getOtherSideLatency() const;
156 [[nodiscard]] std::optional<Latency_ms> getRoundTripTime() const;
157
158private:
159 std::optional<Latency_ms> g_latency;
160 std::optional<Latency_ms> g_otherSideLatency;
161
162 std::optional<FullTimestampOffset> g_meanClockOffset;
163 std::array<FullTimestampOffset, FGE_NET_LATENCY_PLANNER_MEAN> g_clockOffsets{};
164 std::size_t g_clockOffsetCount{0};
165
166 std::optional<Latency_ms> g_roundTripTime;
167
168 Timestamp g_externalStoredTimestamp{0};
169 std::underlying_type_t<Stats> g_syncStat{0};
170};
171
173{
174 PacketDefragmentation _defragmentation;
175 PacketCache _cache;
176 PacketReorderer _reorderer;
177 CommandQueue _commands;
178};
179
180class FGE_API ClientStatus
181{
182public:
183 enum class NetworkStatus
184 {
185 UNKNOWN,
186
187 ACKNOWLEDGED,
188 MTU_DISCOVERED,
189 CONNECTED,
190 AUTHENTICATED,
191
192 DISCONNECTED,
193 TIMEOUT,
194 };
195
196 ClientStatus() = default;
197 explicit ClientStatus(std::string_view status, NetworkStatus networkStatus = NetworkStatus::UNKNOWN);
198
199 [[nodiscard]] bool isInEncryptedState() const;
200 [[nodiscard]] bool isDisconnected() const;
201 [[nodiscard]] bool isConnected() const;
202 [[nodiscard]] bool isConnecting() const;
203 [[nodiscard]] bool isAuthenticated() const;
204
205 [[nodiscard]] std::string const& getStatus() const;
206 [[nodiscard]] NetworkStatus getNetworkStatus() const;
207 [[nodiscard]] std::chrono::milliseconds getTimeout() const;
208 [[nodiscard]] std::chrono::milliseconds getRemainingTimeout() const;
209
210 void set(std::string_view status, NetworkStatus networkStatus);
211 void setStatus(std::string_view status);
212 void setNetworkStatus(NetworkStatus networkStatus);
213
214 void setTimeout(std::chrono::milliseconds timeout);
215 void resetTimeout();
216 [[nodiscard]] bool isTimeout() const;
217
218private:
219 std::string g_status{FGE_NET_STATUS_DEFAULT_STATUS};
220 std::atomic<NetworkStatus> g_networkStatus{NetworkStatus::UNKNOWN};
221 std::chrono::milliseconds g_timeout{FGE_NET_STATUS_DEFAULT_TIMEOUT};
222 std::chrono::steady_clock::time_point g_currentTimeout{std::chrono::steady_clock::now()};
223};
224
225struct FGE_API CryptInfo
226{
227 ~CryptInfo();
228
229 void* _ssl{nullptr};
230 void* _rbio{nullptr};
231 void* _wbio{nullptr};
232};
233
238class FGE_API Client
239{
240public:
241 Client();
242 ~Client();
243
244 enum class Targets
245 {
246 PEER,
247 HOST
248 };
249
256 explicit Client(Latency_ms CTOSLatency, Latency_ms STOCLatency);
257
290
313 std::optional<Timestamp> getCorrectorTimestamp() const;
325 std::optional<Latency_ms> getCorrectorLatency() const;
326
338 [[nodiscard]] std::chrono::milliseconds getLastPacketElapsedTime() const;
339 [[nodiscard]] Latency_ms getLastPacketLatency() const;
340
347 static Timestamp getTimestamp_ms(FullTimestamp fullTimestamp);
361 static Latency_ms computeLatency_ms(Timestamp const& sentTimestamp, Timestamp const& receivedTimestamp);
362
380 void pushPacket(TransmitPacketPtr pck);
381 void pushForcedFrontPacket(TransmitPacketPtr pck);
382 [[nodiscard]] bool isReadyToAcceptMorePendingPackets() const;
388 TransmitPacketPtr popPacket();
395 void allowMorePendingPackets(bool allow);
396
397 void disconnect(bool pushDisconnectPacket = true);
398
399 [[nodiscard]] ProtocolPacket::RealmType getCurrentRealm() const;
400 [[nodiscard]] std::chrono::milliseconds getLastRealmChangeElapsedTime() const;
401 void setCurrentRealm(ProtocolPacket::RealmType realm);
402 ProtocolPacket::RealmType advanceCurrentRealm();
403
404 [[nodiscard]] ProtocolPacket::CounterType getPacketCounter(Targets target) const;
405 ProtocolPacket::CounterType advancePacketCounter(Targets target);
406 void setPacketCounter(Targets target, ProtocolPacket::CounterType count);
407
408 [[nodiscard]] ProtocolPacket::CounterType getReorderedPacketCounter(Targets target) const;
409 ProtocolPacket::CounterType advanceReorderedPacketCounter(Targets target);
410 void setReorderedPacketCounter(Targets target, ProtocolPacket::CounterType count);
411
412 void resetAllCounters();
413
414 void acknowledgeReception(ReceivedPacketPtr const& packet);
415 [[nodiscard]] std::unordered_set<PacketCache::Label, PacketCache::Label::Hash> const& getAcknowledgedList() const;
416 void clearAcknowledgedList();
417
418 void clearLostPacketCount();
419 uint32_t advanceLostPacketCount();
420 void setLostPacketThreshold(uint32_t threshold);
421 [[nodiscard]] uint32_t getLostPacketThreshold() const;
422 [[nodiscard]] uint32_t getLostPacketCount() const;
423
424 [[nodiscard]] ClientStatus const& getStatus() const;
425 [[nodiscard]] ClientStatus& getStatus();
426
427 [[nodiscard]] CryptInfo const& getCryptInfo() const;
428 [[nodiscard]] CryptInfo& getCryptInfo();
429
430 [[nodiscard]] uint16_t getMTU() const;
431 void setMTU(uint16_t mtu);
432
433 void setPacketReturnRate(std::chrono::milliseconds rate);
434 [[nodiscard]] std::chrono::milliseconds getPacketReturnRate() const;
435
436 CallbackHandler<Client&> _onThresholdLostPacket;
437
442 bool _mtuFinalizedFlag{false};
443
444private:
445 mutable std::optional<Timestamp> g_correctorTimestamp;
446 Latency_ms g_CTOSLatency_ms;
447 Latency_ms g_STOCLatency_ms;
448 std::chrono::steady_clock::time_point g_lastPacketTimePoint;
449
450 std::deque<TransmitPacketPtr> g_pendingTransmitPackets;
451 mutable std::recursive_mutex g_mutex;
452
453 std::chrono::steady_clock::time_point g_lastRealmChangeTimePoint;
454 ProtocolPacket::RealmType g_currentRealm{FGE_NET_DEFAULT_REALM};
455
456 ProtocolPacket::CounterType g_hostPacketCounter{0};
457 ProtocolPacket::CounterType g_hostReorderedPacketCounter{0};
458 ProtocolPacket::CounterType g_peerPacketCounter{0};
459 ProtocolPacket::CounterType g_peerReorderedPacketCounter{0};
460
461 std::unordered_set<PacketCache::Label, PacketCache::Label::Hash> g_acknowledgedPackets;
462 uint32_t g_lostPacketCount{0};
463 uint32_t g_lostPacketThreshold{FGE_NET_DEFAULT_lOST_PACKET_THRESHOLD};
464
465 std::chrono::milliseconds g_returnPacketRate{FGE_NET_DEFAULT_RETURN_PACKET_RATE};
466
467 uint16_t g_mtu{0};
468
469 ClientStatus g_status;
470 CryptInfo g_cryptInfo;
471
472 bool g_allowMorePackets{true};
473};
474
478
479} // namespace fge::net
480
481#endif // _FGE_C_CLIENT_HPP_INCLUDED
This class is used to handle callbacks in a safe way.
Definition C_callback.hpp:244
This class is a wrapper for SDL events.
Definition C_event.hpp:59
A class that map a string to a Property.
Definition C_propertyList.hpp:35
Definition C_client.hpp:181
Class that represent the identity of a client.
Definition C_client.hpp:239
void resetLastPacketTimePoint()
Reset the time point for limiting the packets sending frequency.
Latency_ms getPing_ms() const
Compute the ping.
Client(Latency_ms CTOSLatency, Latency_ms STOCLatency)
Constructor with default latencies.
OneWayLatencyPlanner _latencyPlanner
A latency planner that will help latency calculation.
Definition C_client.hpp:440
void pushPacket(TransmitPacketPtr pck)
Add a Packet to the queue.
void clearPackets()
Clear the packet queue.
std::chrono::milliseconds getLastPacketElapsedTime() const
Get the delta time between the last sent packet and the current time.
void setCorrectorTimestamp(Timestamp timestamp)
Set the corrector timestamp.
bool _mtuFinalizedFlag
A flag that indicate if the MTU has been finalized from the remote side.
Definition C_client.hpp:442
PropertyList _data
Some user-defined client properties.
Definition C_client.hpp:439
Event _event
Optional client-side event that can be synchronized with the server.
Definition C_client.hpp:438
std::optional< Timestamp > getCorrectorTimestamp() const
Get the corrector timestamp.
static Timestamp getTimestamp_ms()
Get a modulated timestamp of the current time.
Latency_ms getSTOCLatency_ms() const
Get the "Server To Client" latency.
std::optional< Latency_ms > getCorrectorLatency() const
Compute the corrector latency.
ClientContext _context
The client context containing utility classes for server/client networking.
Definition C_client.hpp:441
bool isPendingPacketsEmpty() const
Check if the packet queue is empty.
static FullTimestamp getFullTimestamp_ms()
Get a timestamp of the current time.
void setCTOSLatency_ms(Latency_ms latency)
Set the "Client To Server" latency.
TransmitPacketPtr popPacket()
Pop a packet from the queue.
Latency_ms getCTOSLatency_ms() const
Get the "Client To Server" latency.
void setSTOCLatency_ms(Latency_ms latency)
Set the "Server To Client" latency.
static Latency_ms computeLatency_ms(Timestamp const &sentTimestamp, Timestamp const &receivedTimestamp)
Compute the latency for the client->server / server->client with the given timestamps.
A helper class that measure latency between client/server.
Definition C_client.hpp:80
std::optional< FullTimestampOffset > getClockOffset() const
Retrieve the clock offset.
std::optional< Latency_ms > getRoundTripTime() const
Retrieve the RTT (Round Trip Time).
std::optional< Latency_ms > getLatency() const
Retrieve the latency.
void pack(TransmitPacketPtr &tPacket)
Pack the required data by the planner to the client/server.
void unpack(ProtocolPacket *packet, Client &client)
Unpack the data received by another client/server planner.
std::optional< Latency_ms > getOtherSideLatency() const
Retrieve the other side latency.
Definition C_protocol.hpp:426
Definition C_protocol.hpp:290
A packet reorderer.
Definition C_protocol.hpp:341
A special inheritance of Packet with a predefined communication protocol.
Definition C_protocol.hpp:88
int64_t FullTimestampOffset
An timestamp offset.
Definition C_client.hpp:66
uint64_t FullTimestamp
An timestamp represent current time in milliseconds.
Definition C_client.hpp:65
uint16_t Timestamp
An timestamp represent modulated current time in milliseconds.
Definition C_client.hpp:64
uint16_t Latency_ms
An latency represent the latency of the client->server / server->client connection.
Definition C_client.hpp:67
Definition C_client.hpp:173
Definition C_client.hpp:226