FastEngine 0.9.3
A multiplayer oriented 2D engine made with Vulkan.
Loading...
Searching...
No Matches
C_server.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_SERVER_HPP_INCLUDED
18#define _FGE_C_SERVER_HPP_INCLUDED
19
20#include "FastEngine/fge_extern.hpp"
21#include "C_socket.hpp"
22#include "FastEngine/network/C_clientList.hpp"
23#include "FastEngine/network/C_packet.hpp"
24#include "FastEngine/network/C_packetBZ2.hpp"
25#include "FastEngine/network/C_packetLZ4.hpp"
26#include "FastEngine/network/C_protocol.hpp"
27#include <condition_variable>
28#include <memory>
29#include <mutex>
30#include <queue>
31#include <thread>
32
33#if defined(FGE_ENABLE_SERVER_NETWORK_RANDOM_LOST) || defined(FGE_ENABLE_CLIENT_NETWORK_RANDOM_LOST)
34 #include "FastEngine/C_random.hpp"
35#endif
36
37#define FGE_SERVER_DEFAULT_MAXPACKET 200
38#define FGE_SERVER_MAX_TIME_DIFFERENCE_REALM \
39 std::chrono::milliseconds \
40 { \
41 2000 \
42 }
43
44namespace fge::net
45{
46
47class ServerSideNetUdp;
48class ClientSideNetUdp;
49
59{
60public:
61 inline FluxPacket(Packet const& pck, Identity const& id, std::size_t fluxIndex = 0, std::size_t fluxCount = 0);
62 inline FluxPacket(Packet&& pck, Identity const& id, std::size_t fluxIndex = 0, std::size_t fluxCount = 0);
63
64 ~FluxPacket() override = default;
65
66 [[nodiscard]] inline Timestamp getTimeStamp() const;
67 [[nodiscard]] inline Identity const& getIdentity() const;
68
69private:
70 friend class ServerSideNetUdp;
71 friend class ClientSideNetUdp;
72
73 Identity g_id;
74 Timestamp g_timestamp;
75
76 std::size_t g_fluxIndex;
77 std::size_t g_fluxCount;
78};
79using FluxPacketPtr = std::unique_ptr<FluxPacket>;
80
81enum class FluxProcessResults
82{
83 RETRIEVABLE,
84 BAD_REALM,
85 BAD_REORDER,
86 NOT_RETRIEVABLE
87};
88
100class FGE_API NetFluxUdp
101{
102public:
103 NetFluxUdp() = default;
104 NetFluxUdp(NetFluxUdp const& r) = delete;
105 NetFluxUdp(NetFluxUdp&& r) noexcept = delete;
106 virtual ~NetFluxUdp();
107
108 NetFluxUdp& operator=(NetFluxUdp const& r) = delete;
109 NetFluxUdp& operator=(NetFluxUdp&& r) noexcept = delete;
110
111 void clearPackets();
112 [[nodiscard]] FluxPacketPtr popNextPacket();
113
114 [[nodiscard]] std::size_t getPacketsSize() const;
115 [[nodiscard]] bool isEmpty() const;
116
117 void setMaxPackets(std::size_t n);
118 [[nodiscard]] std::size_t getMaxPackets() const;
119
120protected:
121 bool pushPacket(FluxPacketPtr&& fluxPck);
122 void forcePushPacket(FluxPacketPtr fluxPck);
123 void forcePushPacketFront(FluxPacketPtr fluxPck);
124 [[nodiscard]] FluxProcessResults processReorder(Client& client,
125 FluxPacketPtr& refFluxPacket,
126 ProtocolPacket::CountId currentCountId,
127 bool ignoreRealm);
128
129 mutable std::mutex _g_mutexFlux;
130 std::deque<FluxPacketPtr> _g_packets;
131 std::size_t _g_remainingPackets{0};
132
133private:
134 std::size_t g_maxPackets = FGE_SERVER_DEFAULT_MAXPACKET;
135
136 friend class ServerSideNetUdp;
137};
138
139class FGE_API ServerNetFluxUdp : public NetFluxUdp
140{
141public:
142 explicit ServerNetFluxUdp(ServerSideNetUdp& server) :
143 NetFluxUdp(),
144 g_server(&server)
145 {}
146 ~ServerNetFluxUdp() override = default;
147
148 [[nodiscard]] FluxProcessResults
149 process(ClientSharedPtr& refClient, FluxPacketPtr& refFluxPacket, bool allowUnknownClient);
150
151 ClientList _clients;
152
154
155private:
156 [[nodiscard]] bool verifyRealm(ClientSharedPtr const& refClient, FluxPacketPtr const& refFluxPacket);
157
158 ServerSideNetUdp* g_server{nullptr};
159};
160
174class FGE_API ServerSideNetUdp
175{
176public:
177 explicit ServerSideNetUdp(IpAddress::Types addressType = IpAddress::Types::Ipv4);
178 ServerSideNetUdp(ServerSideNetUdp const& r) = delete;
179 ServerSideNetUdp(ServerSideNetUdp&& r) noexcept = delete;
181
182 ServerSideNetUdp& operator=(ServerSideNetUdp const& r) = delete;
183 ServerSideNetUdp& operator=(ServerSideNetUdp&& r) noexcept = delete;
184
185 template<class TPacket = Packet>
186 [[nodiscard]] bool
187 start(Port bindPort, IpAddress const& bindIp, IpAddress::Types addressType = IpAddress::Types::None);
188 template<class TPacket = Packet>
189 [[nodiscard]] bool start(IpAddress::Types addressType = IpAddress::Types::None);
190 void stop();
191
207 [[nodiscard]] ServerNetFluxUdp* newFlux();
208
209 [[nodiscard]] ServerNetFluxUdp* getFlux(std::size_t index);
210 [[nodiscard]] ServerNetFluxUdp* getDefaultFlux();
211
212 [[nodiscard]] std::size_t getFluxSize() const;
213
214 [[nodiscard]] IpAddress::Types getAddressType() const;
215
216 void closeFlux(NetFluxUdp* flux);
217 void closeAllFlux();
218
219 void repushPacket(FluxPacketPtr&& fluxPck);
220
229 [[nodiscard]] bool isRunning() const;
230
231 void sendTo(TransmissionPacketPtr& pck, Client const& client, Identity const& id);
232 void sendTo(TransmissionPacketPtr& pck, Identity const& id);
233
234private:
235 template<class TPacket>
236 void threadReception();
237 template<class TPacket>
238 void threadTransmission();
239
240 std::unique_ptr<std::thread> g_threadReception;
241 std::unique_ptr<std::thread> g_threadTransmission;
242
243 std::condition_variable g_transmissionNotifier;
244
245 mutable std::mutex g_mutexServer;
246
247 std::vector<std::unique_ptr<ServerNetFluxUdp>> g_fluxes;
248 ServerNetFluxUdp g_defaultFlux;
249 std::queue<std::pair<TransmissionPacketPtr, Identity>> g_transmissionQueue;
250
251 SocketUdp g_socket;
252 bool g_running;
253};
254
262class FGE_API ClientSideNetUdp : public NetFluxUdp
263{
264public:
265 explicit ClientSideNetUdp(IpAddress::Types addressType = IpAddress::Types::Ipv4);
266 ClientSideNetUdp(ClientSideNetUdp const& r) = delete;
267 ClientSideNetUdp(ClientSideNetUdp&& r) noexcept = delete;
268 ~ClientSideNetUdp() override;
269
270 ClientSideNetUdp& operator=(ClientSideNetUdp const& r) = delete;
271 ClientSideNetUdp& operator=(ClientSideNetUdp&& r) noexcept = delete;
272
273 template<class TPacket = Packet>
274 [[nodiscard]] bool start(Port bindPort,
275 IpAddress const& bindIp,
276 Port connectRemotePort,
277 IpAddress const& connectRemoteAddress,
278 IpAddress::Types addressType = IpAddress::Types::None);
279 void stop();
280
281 void notifyTransmission();
282 [[nodiscard]] bool isRunning() const;
283
284 [[nodiscard]] IpAddress::Types getAddressType() const;
285
286 [[nodiscard]] std::size_t waitForPackets(std::chrono::milliseconds time_ms);
287
288 [[nodiscard]] Identity const& getClientIdentity() const;
289
290 [[nodiscard]] FluxProcessResults process(FluxPacketPtr& refFluxPacket);
291
292 Client _client; //But it is the server :O
293
294private:
295 template<class TPacket>
296 void threadReception();
297 template<class TPacket>
298 void threadTransmission();
299
300 std::unique_ptr<std::thread> g_threadReception;
301 std::unique_ptr<std::thread> g_threadTransmission;
302
303 std::condition_variable g_transmissionNotifier;
304 std::condition_variable g_receptionNotifier;
305
306 SocketUdp g_socket;
307 bool g_running;
308
309 Identity g_clientIdentity;
310};
311
312} // namespace fge::net
313
314#include "C_server.inl"
315
316#endif // _FGE_C_SERVER_HPP_INCLUDED
This class is used to handle callbacks in a safe way.
Definition C_callback.hpp:189
A list of clients used by a server.
Definition C_clientList.hpp:57
A client side network manager.
Definition C_server.hpp:263
Class that represent the identity of a client.
Definition C_client.hpp:246
A received packet from a network flux.
Definition C_server.hpp:59
A class to represent an IP address.
Definition C_ipAddress.hpp:57
A network flux.
Definition C_server.hpp:101
Definition C_packet.hpp:70
A special inheritance of Packet with a predefined communication protocol.
Definition C_protocol.hpp:52
Definition C_server.hpp:140
A server side network manager.
Definition C_server.hpp:175
void notifyTransmission()
Notify the transmission thread.
ServerNetFluxUdp * newFlux()
Create a new flux.
A wrapper for UDP sockets inheriting from Socket.
Definition C_socket.hpp:267
uint16_t Timestamp
An timestamp represent modulated current time in milliseconds.
Definition C_client.hpp:49
A class to represent a client or server identity with an IP address and a port.
Definition C_identity.hpp:31