FastEngine 0.9.3
A multiplayer oriented 2D engine made with Vulkan.
Loading...
Searching...
No Matches
C_client.hpp
1/*
2 * Copyright 2024 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 "C_packet.hpp"
23#include "FastEngine/C_event.hpp"
24#include "FastEngine/C_propertyList.hpp"
25#include "FastEngine/network/C_protocol.hpp"
26#include <array>
27#include <chrono>
28#include <memory>
29#include <mutex>
30#include <queue>
31#include <vector>
32
33#define FGE_NET_BAD_SKEY 0
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
40namespace fge::net
41{
42
47using Skey = uint32_t;
48
49using Timestamp = uint16_t;
50using FullTimestamp = uint64_t;
51using FullTimestampOffset = int64_t;
52using Latency_ms = uint16_t;
53
54class FluxPacket;
55class Client;
56
66class FGE_API TransmissionPacket
67{
68public:
73 enum class Options
74 {
75 UPDATE_TIMESTAMP,
76 UPDATE_FULL_TIMESTAMP,
77 UPDATE_CORRECTION_LATENCY
78 };
79
80 struct Option
81 {
82 constexpr explicit Option(Options option, std::size_t argument = 0) :
83 _option(option),
84 _argument(argument)
85 {}
86
88 std::size_t _argument;
89 };
90
91 [[nodiscard]] static inline std::shared_ptr<TransmissionPacket>
92 create(ProtocolPacket::Header header = FGE_NET_BAD_HEADERID);
93 [[nodiscard]] static inline std::shared_ptr<TransmissionPacket> create(Packet&& packet);
94
95 TransmissionPacket(TransmissionPacket const& r) = delete;
96 TransmissionPacket(TransmissionPacket&& r) noexcept = delete;
97 ~TransmissionPacket() = default;
98
99 TransmissionPacket& operator=(TransmissionPacket const& r) = delete;
100 TransmissionPacket& operator=(TransmissionPacket&& r) noexcept = delete;
101
102 [[nodiscard]] inline ProtocolPacket const& packet() const;
103 [[nodiscard]] inline ProtocolPacket& packet();
104 [[nodiscard]] inline std::vector<Option> const& options() const;
105 [[nodiscard]] inline std::vector<Option>& options();
106
107 inline TransmissionPacket& doNotDiscard();
108 inline TransmissionPacket& doNotReorder();
109
117 void applyOptions(Client const& client);
125
126private:
127 inline explicit TransmissionPacket(ProtocolPacket::Header header,
128 ProtocolPacket::Realm realmId,
129 ProtocolPacket::CountId countId);
130 inline explicit TransmissionPacket(ProtocolPacket&& packet);
131
132 ProtocolPacket g_packet;
133 std::vector<Option> g_options;
134};
135
136using TransmissionPacketPtr = std::shared_ptr<TransmissionPacket>;
137
149{
150public:
151 OneWayLatencyPlanner() = default;
152
153 enum Stats : uint8_t
154 {
155 HAVE_EXTERNAL_TIMESTAMP = 1 << 0
156 };
157
163 void pack(TransmissionPacketPtr& tPacket);
170 void unpack(FluxPacket* packet, Client& client);
171
180 [[nodiscard]] std::optional<FullTimestampOffset> getClockOffset() const;
186 [[nodiscard]] std::optional<Latency_ms> getLatency() const;
194 [[nodiscard]] std::optional<Latency_ms> getOtherSideLatency() const;
225 [[nodiscard]] std::optional<Latency_ms> getRoundTripTime() const;
226
227private:
228 std::optional<Latency_ms> g_latency;
229 std::optional<Latency_ms> g_otherSideLatency;
230
231 std::optional<FullTimestampOffset> g_meanClockOffset;
232 std::array<FullTimestampOffset, FGE_NET_LATENCY_PLANNER_MEAN> g_clockOffsets{};
233 std::size_t g_clockOffsetCount{0};
234
235 std::optional<Latency_ms> g_roundTripTime;
236
237 Timestamp g_externalStoredTimestamp{0};
238 std::underlying_type_t<Stats> g_syncStat{0};
239};
240
245class FGE_API Client
246{
247public:
248 Client();
255 explicit Client(Latency_ms CTOSLatency, Latency_ms STOCLatency);
256
268 void setSkey(Skey key);
274 Skey getSkey() const;
275
308
331 std::optional<Timestamp> getCorrectorTimestamp() const;
343 std::optional<Latency_ms> getCorrectorLatency() const;
344
357
364 static Timestamp getTimestamp_ms(FullTimestamp fullTimestamp);
378 static Latency_ms computeLatency_ms(Timestamp const& sentTimestamp, Timestamp const& receivedTimestamp);
379
397 void pushPacket(TransmissionPacketPtr pck);
403 TransmissionPacketPtr popPacket();
410
411 [[nodiscard]] ProtocolPacket::Realm getCurrentRealm() const;
412 [[nodiscard]] std::chrono::milliseconds getLastRealmChangeElapsedTime() const;
413 void setCurrentRealm(ProtocolPacket::Realm realm);
414 ProtocolPacket::Realm advanceCurrentRealm();
415
416 [[nodiscard]] ProtocolPacket::CountId getCurrentPacketCountId() const;
417 ProtocolPacket::CountId advanceCurrentPacketCountId();
418 void setCurrentPacketCountId(ProtocolPacket::CountId countId);
419
420 [[nodiscard]] ProtocolPacket::CountId getClientPacketCountId() const;
421 ProtocolPacket::CountId advanceClientPacketCountId();
422 void setClientPacketCountId(ProtocolPacket::CountId countId);
423
424 [[nodiscard]] PacketReorderer& getPacketReorderer();
425 [[nodiscard]] PacketReorderer const& getPacketReorderer() const;
426
427 void clearLostPacketCount();
428 uint32_t advanceLostPacketCount();
429 void setLostPacketThreshold(uint32_t threshold);
430 [[nodiscard]] uint32_t getLostPacketThreshold() const;
431 [[nodiscard]] uint32_t getLostPacketCount() const;
432
433 CallbackHandler<Client&> _onThresholdLostPacket;
434
438
439private:
440 mutable std::optional<Timestamp> g_correctorTimestamp;
441 Latency_ms g_CTOSLatency_ms;
442 Latency_ms g_STOCLatency_ms;
443 std::chrono::steady_clock::time_point g_lastPacketTimePoint;
444
445 std::queue<TransmissionPacketPtr> g_pendingTransmitPackets;
446 mutable std::recursive_mutex g_mutex;
447
448 Skey g_skey;
449
450 std::chrono::steady_clock::time_point g_lastRealmChangeTimePoint;
451 ProtocolPacket::Realm g_currentRealm;
452 ProtocolPacket::CountId g_currentPacketCountId;
453 ProtocolPacket::CountId g_clientPacketCountId;
454
455 PacketReorderer g_packetReorderer;
456 uint32_t g_lostPacketCount{0};
457 uint32_t g_lostPacketThreshold{FGE_NET_DEFAULT_lOST_PACKET_THRESHOLD};
458};
459
464} // namespace fge::net
465
466#include "C_client.inl"
467
468#endif // _FGE_C_CLIENT_HPP_INCLUDED
This class is used to handle callbacks in a safe way.
Definition C_callback.hpp:189
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
Class that represent the identity of a client.
Definition C_client.hpp:246
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:437
TransmissionPacketPtr popPacket()
Pop a packet from the queue.
void setSkey(Skey key)
Set the session key for this client.
void clearPackets()
Clear the packet queue.
void setCorrectorTimestamp(Timestamp timestamp)
Set the corrector timestamp.
PropertyList _data
Some user-defined client properties.
Definition C_client.hpp:436
Event _event
Optional client-side event that can be synchronized with the server.
Definition C_client.hpp:435
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.
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.
Latency_ms getLastPacketElapsedTime() const
Get the delta time between the last sent packet and the current time.
static Skey GenerateSkey()
Generate a new random session key.
Latency_ms getCTOSLatency_ms() const
Get the "Client To Server" latency.
void setSTOCLatency_ms(Latency_ms latency)
Set the "Server To Client" latency.
void pushPacket(TransmissionPacketPtr pck)
Add a TransmissionPacket to the queue.
static Latency_ms computeLatency_ms(Timestamp const &sentTimestamp, Timestamp const &receivedTimestamp)
Compute the latency for the client->server / server->client with the given timestamps.
Skey getSkey() const
Get the session key for this client.
A received packet from a network flux.
Definition C_server.hpp:59
A helper class that measure latency between client/server.
Definition C_client.hpp:149
std::optional< FullTimestampOffset > getClockOffset() const
Retrieve the clock offset.
void unpack(FluxPacket *packet, Client &client)
Unpack the data received by another client/server planner.
void pack(TransmissionPacketPtr &tPacket)
Pack the required data by the planner to the client/server.
std::optional< Latency_ms > getRoundTripTime() const
Retrieve the RTT (Round Trip Time)
std::optional< Latency_ms > getLatency() const
Retrieve the latency.
std::optional< Latency_ms > getOtherSideLatency() const
Retrieve the other side latency.
A packet reorderer.
Definition C_protocol.hpp:102
Definition C_packet.hpp:70
A special inheritance of Packet with a predefined communication protocol.
Definition C_protocol.hpp:52
A packet with configurable options to transmit via a network thread.
Definition C_client.hpp:67
Options
Options to pass to the network thread when sending a packet.
Definition C_client.hpp:74
void applyOptions(Client const &client)
Apply packet options to the packet.
void applyOptions()
Apply packet options to the packet.
int64_t FullTimestampOffset
An timestamp offset.
Definition C_client.hpp:51
uint64_t FullTimestamp
An timestamp represent current time in milliseconds.
Definition C_client.hpp:50
uint16_t Timestamp
An timestamp represent modulated current time in milliseconds.
Definition C_client.hpp:49
uint16_t Latency_ms
An latency represent the latency of the client->server / server->client connection.
Definition C_client.hpp:52
uint32_t Skey
The session key can be used to identify a client when connecting to a server.
Definition C_client.hpp:47
Definition C_client.hpp:81
std::size_t _argument
The option argument.
Definition C_client.hpp:88
Options _option
The option to send the packet with.
Definition C_client.hpp:87