FastEngine 0.9.3
A multiplayer oriented 2D engine made with Vulkan.
Loading...
Searching...
No Matches
network_manager.inl
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
17namespace fge::net
18{
19
21{
22 fge::net::Skey buff;
23 if (pck >> buff)
24 {
25 return buff == skey;
26 }
27 return false;
28}
30{
31 fge::net::Skey buff;
32 if (pck >> buff)
33 {
34 return buff;
35 }
36 return FGE_NET_BAD_SKEY;
37}
38
39namespace rules
40{
41
42template<class TValue>
43constexpr ChainedArguments<TValue>::ChainedArguments(fge::net::Packet const& pck, TValue* existingValue) :
44 g_pck(&pck),
45 g_value(existingValue == nullptr ? Value{std::in_place_type<TValue>} : Value{existingValue}),
46 g_error(pck.isValid() ? Error{}
47 : Error{Error::Types::ERR_ALREADY_INVALID, pck.getReadPos(), "already invalid packet",
48 __func__})
49{}
50template<class TValue>
51constexpr ChainedArguments<TValue>::ChainedArguments(fge::net::Packet const& pck, Error&& err, TValue* existingValue) :
52 g_pck(&pck),
53 g_value(existingValue == nullptr ? Value{std::in_place_type<TValue>} : Value{existingValue}),
54 g_error(std::move(err))
55{}
56
57template<class TValue>
59{
60 auto* value = std::holds_alternative<TValue>(this->g_value) ? &std::get<TValue>(this->g_value)
61 : std::get<TValue*>(this->g_value);
62 *this->g_pck >> *value;
63 if (this->g_pck->isValid())
64 {
65 return value;
66 }
67 this->g_error =
68 net::Error{net::Error::Types::ERR_EXTRACT, this->g_pck->getReadPos(), "extraction failed", __func__};
69 return nullptr;
70}
71template<class TValue>
72template<class TPeek>
73constexpr std::optional<TPeek> ChainedArguments<TValue>::peek()
74{
75 auto startReadPos = this->g_pck->getReadPos();
76
77 TPeek value{};
78 *this->g_pck >> value;
79
80 if (this->g_pck->isValid())
81 {
82 this->g_pck->setReadPos(startReadPos);
83 return value;
84 }
85
86 this->g_error = net::Error{net::Error::Types::ERR_EXTRACT, this->g_pck->getReadPos(), "peek failed", __func__};
87 return std::nullopt;
88}
89
90template<class TValue>
92{
93 return *this->g_pck;
94}
95template<class TValue>
96constexpr TValue const& ChainedArguments<TValue>::value() const
97{
98 return std::holds_alternative<TValue>(this->g_value) ? std::get<TValue>(this->g_value)
99 : *std::get<TValue*>(this->g_value);
100}
101template<class TValue>
102constexpr TValue& ChainedArguments<TValue>::value()
103{
104 return std::holds_alternative<TValue>(this->g_value) ? std::get<TValue>(this->g_value)
105 : *std::get<TValue*>(this->g_value);
106}
107
108template<class TValue>
109template<class TInvokable>
110constexpr typename std::invoke_result_t<TInvokable, ChainedArguments<TValue>&>
112{
113 if (this->g_pck->isValid())
114 {
115 return std::invoke(std::forward<TInvokable>(f), *this);
116 }
117 return {*this->g_pck, std::move(this->g_error), nullptr};
118}
119template<class TValue>
120template<class TInvokable, class TIndex>
122ChainedArguments<TValue>::and_for_each(TIndex iStart, TIndex iEnd, TIndex iIncrement, TInvokable&& f)
123{
124 if (!this->g_pck->isValid())
125 {
126 return *this;
127 }
128
129 for (iStart; iStart != iEnd; iStart += iIncrement)
130 {
131 std::optional<Error> err =
132 std::invoke(std::forward<TInvokable>(f), const_cast<ChainedArguments<TValue> const&>(*this), iStart);
133
134 if (err)
135 {
136 this->invalidate(std::move(err.value()));
137 return *this;
138 }
139 }
140 return *this;
141}
142template<class TValue>
143template<class TInvokable, class TIndex>
145ChainedArguments<TValue>::and_for_each(TIndex iStart, TIndex iIncrement, TInvokable&& f)
146{
147 if (!this->g_pck->isValid())
148 {
149 return *this;
150 }
151
152 auto& value = this->value();
153
154 for (; iStart != value; iStart += iIncrement)
155 {
156 std::optional<Error> err =
157 std::invoke(std::forward<TInvokable>(f), const_cast<ChainedArguments<TValue> const&>(*this), iStart);
158
159 if (err)
160 {
161 this->invalidate(std::move(err.value()));
162 return *this;
163 }
164 }
165 return *this;
166}
167template<class TValue>
168template<class TInvokable>
170{
171 if (!this->g_pck->isValid())
172 {
173 return *this;
174 }
175
176 auto& value = this->value();
177
178 for (TValue iIndex = 0; iIndex != value; ++iIndex)
179 {
180 std::optional<Error> err =
181 std::invoke(std::forward<TInvokable>(f), const_cast<ChainedArguments<TValue> const&>(*this), iIndex);
182
183 if (err)
184 {
185 this->invalidate(std::move(err.value()));
186 return *this;
187 }
188 }
189 return *this;
190}
191template<class TValue>
192template<class TInvokable>
193constexpr std::optional<Error> ChainedArguments<TValue>::on_error(TInvokable&& f)
194{
195 if (!this->g_pck->isValid())
196 {
197 std::invoke(std::forward<TInvokable>(f), *this);
198 return this->g_error;
199 }
200 return std::nullopt;
201}
202template<class TValue>
203constexpr std::optional<Error> ChainedArguments<TValue>::end()
204{
205 return this->g_pck->isValid() ? std::nullopt : std::optional<Error>{std::move(this->g_error)};
206}
207template<class TValue>
208constexpr std::optional<Error> ChainedArguments<TValue>::end(std::nullopt_t nullopt) const
209{
210 return std::optional<Error>{nullopt};
211}
212template<class TValue>
213constexpr std::optional<Error> ChainedArguments<TValue>::end(Error&& err) const
214{
215 return std::optional<Error>{std::move(err)};
216}
217
218template<class TValue>
220{
221 if (this->g_pck->isValid())
222 {
223 auto* extractedValue = std::holds_alternative<TValue>(this->g_value) ? &std::get<TValue>(this->g_value)
224 : std::get<TValue*>(this->g_value);
225 if constexpr (std::is_move_assignable_v<TValue>)
226 {
227 value = std::move(*extractedValue);
228 }
229 else
230 {
231 value = *extractedValue;
232 }
233 }
234 return *this;
235}
236template<class TValue>
237template<class TInvokable>
239{
240 if (this->g_pck->isValid())
241 {
242 auto* extractedValue = std::holds_alternative<TValue>(this->g_value) ? &std::get<TValue>(this->g_value)
243 : std::get<TValue*>(this->g_value);
244 std::invoke(std::forward<TInvokable>(f), const_cast<TValue&>(*extractedValue));
245 }
246 return *this;
247}
248
249template<class TValue>
250template<class TNewValue>
252{
253 return ChainedArguments<TNewValue>{*this->g_pck, std::move(this->g_error), existingValue};
254}
255template<class TValue>
256template<class TNewValue>
258{
259 return ChainedArguments<TNewValue>{*this->g_pck, existingValue};
260}
261
262template<class TValue>
264{
265 this->g_error = std::move(err);
266 return *this;
267}
268template<class TValue>
270{
271 this->g_pck->invalidate();
272 this->g_error = std::move(err);
273 return *this;
274}
275
276template<class TValue, ROutputs TOutput>
277constexpr ChainedArguments<TValue> RRange(TValue const& min, TValue const& max, ChainedArguments<TValue>&& args)
278{
279 if (args.packet().isValid())
280 {
281 auto* val = args.extract();
282 if (val != nullptr)
283 {
284 if (!((*val >= min && *val <= max) ^ static_cast<bool>(TOutput)))
285 {
286 args.invalidate(Error{Error::Types::ERR_RULE, args.packet().getReadPos(), "rule failed", __func__});
287 }
288 }
289 }
290 return args;
291}
292
293template<class TValue>
295{
296 if (args.packet().isValid())
297 {
298 auto* val = args.extract();
299 if (val == nullptr)
300 {
301 args.invalidate(Error{Error::Types::ERR_RULE, args.packet().getReadPos(), "rule failed", __func__});
302 }
303 }
304 return args;
305}
306
307template<class TValue, ROutputs TOutput>
309{
310 if (args.packet().isValid())
311 {
312 auto* val = args.extract();
313 if (val != nullptr)
314 {
315 if (!((*val == a) ^ static_cast<bool>(TOutput)))
316 {
317 args.invalidate(Error{Error::Types::ERR_RULE, args.packet().getReadPos(), "rule failed", __func__});
318 }
319 }
320 }
321 return args;
322}
323
324template<class TValue, ROutputs TOutput>
326{
327 if (args.packet().isValid())
328 {
329 auto* val = args.extract();
330 if (val != nullptr)
331 {
332 if (!((*val < less) ^ static_cast<bool>(TOutput)))
333 {
334 args.invalidate(Error{Error::Types::ERR_RULE, args.packet().getReadPos(), "rule failed", __func__});
335 }
336 }
337 }
338 return args;
339}
340
341template<class TValue, ROutputs TOutput>
343{
344 if (args.packet().isValid())
345 {
346 auto* val = args.extract();
347 if (val != nullptr)
348 {
349 if (!((*val <= less) ^ static_cast<bool>(TOutput)))
350 {
351 args.invalidate(Error{Error::Types::ERR_RULE, args.packet().getReadPos(), "rule failed", __func__});
352 }
353 }
354 }
355 return args;
356}
357
358template<class TValue, ROutputs TOutput>
359constexpr ChainedArguments<TValue> RSizeRange(SizeType min, SizeType max, ChainedArguments<TValue>&& args)
360{
361 if (args.packet().isValid())
362 {
363 auto size = args.template peek<fge::net::SizeType>();
364 if (size)
365 {
366 if (!((size >= min && size <= max) ^ static_cast<bool>(TOutput)))
367 {
368 args.invalidate(Error{Error::Types::ERR_RULE, args.packet().getReadPos(), "rule failed", __func__});
369 }
370 }
371 }
372 return args;
373}
374
375template<class TValue, ROutputs TOutput>
377{
378 if (args.packet().isValid())
379 {
380 auto size = args.template peek<fge::net::SizeType>();
381 if (size)
382 {
383 if (!((size == a) ^ static_cast<bool>(TOutput)))
384 {
385 args.invalidate(Error{Error::Types::ERR_RULE, args.packet().getReadPos(), "rule failed", __func__});
386 }
387 }
388 }
389 return args;
390}
391
392template<class TValue, ROutputs TOutput>
394{
395 if (args.packet().isValid())
396 {
397 auto* val = args.extract();
398 if (val != nullptr)
399 {
400 if (!(fge::string::IsValidUtf8String(val) ^ static_cast<bool>(TOutput)))
401 {
402 args.invalidate(Error{Error::Types::ERR_RULE, args.packet().getReadPos(), "rule failed", __func__});
403 }
404 }
405 }
406 return args;
407}
408
409} // namespace rules
410
411} // namespace fge::net
Definition C_packet.hpp:70
This is a wrapper around a Packet and a value for safe extraction.
Definition network_manager.hpp:92
constexpr ChainedArguments< TValue > & invalidate(Error &&err)
Invalidate the packet and set the error.
Definition network_manager.inl:269
FGE_API bool IsValidUtf8String(std::string const &str)
Check if the provided string has valid utf8 encoded chars.
constexpr ChainedArguments< TValue > RRange(TValue const &min, TValue const &max, ChainedArguments< TValue > &&args)
Range rule, check if the value is in the min/max range.
Definition network_manager.inl:277
constexpr ChainedArguments< TValue > RMustValidUtf8(ChainedArguments< TValue > &&args)
Check if the extracted string is a valid UTF8 string.
Definition network_manager.inl:393
constexpr ChainedArguments< TValue > RStrictLess(TValue less, ChainedArguments< TValue > &&args)
Strict less rule, check if the value is strictly lesser than the provided one.
Definition network_manager.inl:325
constexpr ChainedArguments< TValue > RMustEqual(TValue const &a, ChainedArguments< TValue > &&args)
Must equal rule, check if the value is equal to the provided one.
Definition network_manager.inl:308
constexpr ChainedArguments< TValue > RSizeMustEqual(fge::net::SizeType a, ChainedArguments< TValue > &&args)
Size must equal rule, check if the size is equal to the provided one.
Definition network_manager.inl:376
constexpr ChainedArguments< TValue > RSizeRange(SizeType min, SizeType max, ChainedArguments< TValue > &&args)
Size range rule, check if the size is in the min/max range.
Definition network_manager.inl:359
constexpr ChainedArguments< TValue > RValid(ChainedArguments< TValue > &&args)
Valid rule, check if the value is correctly extracted.
Definition network_manager.inl:294
constexpr ChainedArguments< TValue > RLess(TValue less, ChainedArguments< TValue > &&args)
Less rule, check if the value is lesser than the provided one.
Definition network_manager.inl:342
fge::net::Skey GetSkey(fge::net::Packet &pck)
Shortcut function that will extract the skey.
Definition network_manager.inl:29
bool CheckSkey(fge::net::Packet &pck, fge::net::Skey skey)
Shortcut function that will extract and compare the provided skey.
Definition network_manager.inl:20
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_packet.hpp:45