Luanti 5.18.0-dev
Loading...
Searching...
No Matches
clientiface.h
Go to the documentation of this file.
1// Luanti
2// SPDX-License-Identifier: LGPL-2.1-or-later
3// Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5#pragma once
6
7#include "irr_v3d.h" // for irrlicht datatypes
8
9#include "network/address.h"
10#include "network/networkprotocol.h" // session_t
12#include "clientdynamicinfo.h"
13#include "constants.h" // PEER_ID_INEXISTENT
14
15#include <memory>
16#include <mutex>
17#include <set>
18#include <string>
19#include <unordered_map>
20#include <unordered_set>
21#include <vector>
22
23class EmergeManager;
24class MapBlock;
25class NetworkPacket;
26struct PointedThing;
28
29/*
30 * State Transitions
31
32 Start
33 (peer connect)
34 |
35 v
36 /-----------------\
37 | |
38 | Created |
39 | |
40 \-----------------/
41 | depending on the incoming packet
42 ----------------------------------------
43 v
44 +-----------------------------+
45 |IN: |
46 | TOSERVER_INIT |
47 +-----------------------------+
48 | invalid playername
49 | or denied by mod
50 v
51 +-----------------------------+
52 |OUT: |
53 | TOCLIENT_HELLO |
54 +-----------------------------+
55 |
56 |
57 v
58 /-----------------\ /-----------------\
59 | | | |
60 | AwaitingInit2 |<--------- | HelloSent |
61 | | | | |
62 \-----------------/ | \-----------------/
63 | | |
64+-----------------------------+ | *-----------------------------* Auth fails
65|IN: | | |Authentication, depending on |------------------
66| TOSERVER_INIT2 | | | packet sent by client | |
67+-----------------------------+ | *-----------------------------* |
68 | | | |
69 | | | Authentication |
70 v | | successful |
71 /-----------------\ | v |
72 | | | +-----------------------------+ |
73 | InitDone | | |OUT: | |
74 | | | | TOCLIENT_AUTH_ACCEPT | |
75 \-----------------/ | +-----------------------------+ |
76 | | | |
77+-----------------------------+ --------------------- |
78|OUT: | |
79| TOCLIENT_MOVEMENT | |
80| TOCLIENT_ITEMDEF | |
81| TOCLIENT_NODEDEF | |
82| TOCLIENT_ANNOUNCE_MEDIA | |
83| TOCLIENT_DETACHED_INVENTORY | |
84| TOCLIENT_TIME_OF_DAY | |
85+-----------------------------+ |
86 | |
87 | |
88 | ----------------------------- |
89 v | | |
90 /-----------------\ v |
91 | | +-----------------------------+ |
92 | DefinitionsSent | |IN: | |
93 | | | TOSERVER_REQUEST_MEDIA | |
94 \-----------------/ | | |
95 | +-----------------------------+ |
96 | ^ | |
97 | ----------------------------- |
98 v v
99+-----------------------------+ --------------------------------+
100|IN: | | ^
101| TOSERVER_CLIENT_READY | v |
102+-----------------------------+ +------------------------+ |
103 | |OUT: | |
104 v | TOCLIENT_ACCESS_DENIED | |
105+-----------------------------+ +------------------------+ |
106|OUT: | | |
107| TOCLIENT_MOVE_PLAYER | v |
108| TOCLIENT_PRIVILEGES | /-----------------\ |
109| TOCLIENT_INVENTORY_FORMSPEC | | | |
110| UpdateCrafting | | Denied | |
111| TOCLIENT_INVENTORY | | | |
112| TOCLIENT_HP (opt) | \-----------------/ |
113| TOCLIENT_BREATH | |
114| TOCLIENT_DEATHSCREEN_LEGACY | |
115+-----------------------------+ |
116 | |
117 v |
118 /-----------------\ async mod action (ban, kick) |
119 | |---------------------------------------------------------------
120 ---->| Active |
121 | | |----------------------------------------------
122 | \-----------------/ timeout v
123 | | | +-----------------------------+
124 | | | |OUT: |
125 | | | | TOCLIENT_DISCONNECT |
126 | | | +-----------------------------+
127 | | | |
128 | | v v
129 | | +-----------------------------+ /-----------------\
130 | | |IN: | | |
131 | | | TOSERVER_DISCONNECT |------------------->| Disconnecting |
132 | | +-----------------------------+ | |
133 | | \-----------------/
134 | | any auth packet which was
135 | | allowed in TOCLIENT_AUTH_ACCEPT
136 | v
137 | *-----------------------------* Auth +-------------------------------+
138 | |Authentication, depending on | succeeds |OUT: |
139 | | packet sent by client |---------->| TOCLIENT_ACCEPT_SUDO_MODE |
140 | *-----------------------------* +-------------------------------+
141 | | |
142 | | Auth fails /-----------------\
143 | v | |
144 | +-------------------------------+ | SudoMode |
145 | |OUT: | | |
146 | | TOCLIENT_DENY_SUDO_MODE | \-----------------/
147 | +-------------------------------+ |
148 | | v
149 | | +-----------------------------+
150 | | sets password accordingly |IN: |
151 -------------------+-------------------------------| TOSERVER_FIRST_SRP |
152 +-----------------------------+
153
154*/
155namespace con {
156 class IConnection;
157}
158
159
160// Also make sure to update the ClientInterface::statenames
161// array when modifying these enums
162
176
189
190/*
191 Used for queueing and sorting block transfers in containers
192
193 Lower priority number means higher priority.
194*/
196{
197 PrioritySortedBlockTransfer(float a_priority, const v3s16 &a_pos, session_t a_peer_id)
198 {
199 priority = a_priority;
200 pos = a_pos;
201 peer_id = a_peer_id;
202 }
204 {
205 return priority < other.priority;
206 }
207 float priority;
210};
211
213{
214public:
215 // peer_id=0 means this client has no associated peer
216 // NOTE: If client is made allowed to exist while peer doesn't,
217 // this has to be set to 0 when there is no peer.
218 // Also, the client must be moved to some other container.
220 // The serialization version to use with the client
222 //
224
225 /* Authentication information */
226 std::string enc_pwd = "";
229 void *auth_data = nullptr;
231
232 void resetChosenMech();
233
235 { return allowed_auth_mechs & mech; }
236
237 void setEncryptedPassword(const std::string& pwd);
238
239 RemoteClient();
240 ~RemoteClient() = default;
241
242 /*
243 Finds block that should be sent next to the client.
244 Environment should be locked when this is called.
245 dtime is used for resetting send radius at slow interval
246 */
248 float dtime, std::vector<PrioritySortedBlockTransfer> &dest);
249
250 void GotBlock(v3s16 p);
251
252 void SentBlock(v3s16 p);
253
254 void SetBlockNotSent(v3s16 p, bool low_priority = false);
255 void SetBlocksNotSent(const std::vector<v3s16> &blocks, bool low_priority = false);
256
268 const PointedThing &pointed, bool prediction_success);
269
270 u32 getSendingCount() const { return m_blocks_sending.size(); }
271
272 bool isBlockSent(v3s16 p) const
273 {
274 return m_blocks_sent.find(p) != m_blocks_sent.end();
275 }
276
277 bool markMediaSent(const std::string &name) {
278 auto insert_result = m_media_sent.emplace(name);
279 return insert_result.second; // true = was inserted
280 }
281
282 void PrintInfo(std::ostream &o)
283 {
284 o << "RemoteClient " << peer_id << ": "
285 <<"blocks_sent=" << m_blocks_sent.size()
286 <<", blocks_sending=" << m_blocks_sending.size()
287 <<", nearest_unsent_d=" << m_nearest_unsent_d
288 <<", map_send_completion_timer=" << (int)(m_map_send_completion_timer + 0.5f)
289 <<", excess_gotblocks=" << m_excess_gotblocks;
291 }
292
293 // Time from last placing or removing blocks
295
296 /*
297 List of active objects that the client knows of.
298 */
299 std::set<u16> m_known_objects;
300
301 ClientState getState() const { return m_state; }
302
303 const std::string &getName() const { return m_name; }
304
305 void setName(const std::string &name) { m_name = name; }
306
307 /* update internal client state */
308 void notifyEvent(ClientStateEvent event);
309
310 /* set expected serialization version */
313
316
317 /* get uptime */
318 u64 uptime() const;
319
320 /* set version information */
321 void setVersionInfo(u8 major, u8 minor, u8 patch, const std::string &full);
322
323 /* read version information */
324 u8 getMajor() const { return m_version_major; }
325 u8 getMinor() const { return m_version_minor; }
326 u8 getPatch() const { return m_version_patch; }
327 const std::string &getFullVer() const { return m_full_version; }
328
329 void setLangCode(const std::string &code);
330 const std::string &getLangCode() const { return m_lang_code; }
331
332 void setCachedAddress(const Address &addr) { m_addr = addr; }
333 const Address &getAddress() const { return m_addr; }
334
335 void setDynamicInfo(const ClientDynamicInfo &info) { m_dynamic_info = info; }
337
338private:
339 // Version is stored in here after INIT before INIT2
341
342 /* current state of client */
344
345 // Cached here so retrieval doesn't have to go to connection API
347
348 // Client-sent language code
349 std::string m_lang_code;
350
351 // Client-sent dynamic info
353
354 /*
355 Blocks that have been sent to client.
356 - These don't have to be sent again.
357 - A block is cleared from here when client says it has
358 deleted it from it's memory
359
360 List of block positions.
361 No MapBlock* is stored here because the blocks can get deleted.
362 */
363 std::unordered_set<v3s16> m_blocks_sent;
364
365 /*
366 Cache of blocks that have been occlusion culled at the current distance.
367 As GetNextBlocks traverses the same distance multiple times, this saves
368 significant CPU time.
369 */
370 std::unordered_set<v3s16> m_blocks_occ;
371
375
382 const bool m_occ_cull;
383
384 /*
385 Set of media files the client has already requested
386 We won't send the same file twice to avoid bandwidth consumption attacks.
387 */
388 std::unordered_set<std::string> m_media_sent;
389
390 /*
391 Blocks that are currently on the line.
392 This is used for throttling the sending of blocks.
393 - The size of this list is limited to some value
394 Block is added when it is sent with BLOCKDATA.
395 Block is removed when GOTBLOCKS is received.
396 */
397 std::unordered_set<v3s16> m_blocks_sending;
398
399 /*
400 Count of excess GotBlocks().
401 There is an excess amount because the client sometimes
402 gets a block so late that the server sends it again,
403 and the client then sends two GOTBLOCKs.
404 This is reset by PrintInfo()
405 */
407
408 // CPU usage optimization
410
411 // measure how long it takes the server to send the complete map
413
414 /*
415 name of player using this client
416 */
417 std::string m_name = "";
418
419 /*
420 client information
421 */
425
426 std::string m_full_version = "unknown";
427
428 /*
429 time this client was created
430 */
432};
433
434typedef std::unordered_map<u16, RemoteClient*> RemoteClientMap;
435
437public:
438
439 friend class Server;
440
441 ClientInterface(const std::shared_ptr<con::IConnection> &con);
443
444 /* run sync step */
445 void step(float dtime);
446
447 /* get list of active client id's */
448 std::vector<session_t> getClientIDs(ClientState min_state=CS_Active);
449
450 /* mark blocks as not sent on all active clients */
451 void markBlocksNotSent(const std::vector<v3s16> &positions, bool low_priority = false);
452
453 /* verify if server user limit was reached */
454 bool isUserLimitReached();
455
456 /* get list of client player names */
457 const std::vector<std::string> &getPlayerNames() const { return m_clients_names; }
458
459 /* send to one client */
460 void send(session_t peer_id, NetworkPacket *pkt);
461
462 /* send to one client, deviating from the standard params */
463 void sendCustom(session_t peer_id, u8 channel, NetworkPacket *pkt, bool reliable);
464
465 /* send to all clients */
466 void sendToAll(NetworkPacket *pkt, ClientState state_min = CS_Active);
467
468 /* delete a client */
469 void DeleteClient(session_t peer_id);
470
471 /* create client */
472 void CreateClient(session_t peer_id);
473
474 /* get a client by peer_id */
476
477 /* get client by peer_id (make sure you have list lock before!*/
479
480 /* get state of client by id*/
482
483 /* get protocol version of client */
484 u16 getProtocolVersion(session_t peer_id);
485
486 /* event to update client state */
487 void event(session_t peer_id, ClientStateEvent event);
488
489 /* Set environment. Do not call this function if environment is already set */
491 {
492 assert(m_env == NULL); // pre-condition
493 m_env = env;
494 }
495
496 static const char *state2Name(ClientState state);
497
498protected:
499 class AutoLock {
500 public:
502
503 private:
505 };
506
508
509private:
510 /* update internal player list */
511 void UpdatePlayerList();
512
513 // Connection
514 std::shared_ptr<con::IConnection> m_con;
515
516 // FIXME?: as far as I can tell this lock is pointless because only the server
517 // thread ever touches the clients. Consider how getClientNoEx() returns
518 // a raw pointer too.
519 std::recursive_mutex m_clients_mutex;
520 // Connected clients (behind the mutex)
522 std::vector<std::string> m_clients_names; // for announcing to server list
523
524 // Environment
526
529
530 static const char *statenames[];
531
532 // Note that this puts a fixed timeout on the init & auth phase for a client.
533 // (lingering is enforced until CS_InitDone)
534 static constexpr int LINGER_TIMEOUT = 12;
535};
Definition address.h:27
RecursiveMutexAutoLock m_lock
Definition clientiface.h:504
AutoLock(ClientInterface &iface)
Definition clientiface.h:501
float m_check_linger_timer
Definition clientiface.h:528
RemoteClientMap & getClientList()
Definition clientiface.h:507
~ClientInterface()
Definition clientiface.cpp:678
std::shared_ptr< con::IConnection > m_con
Definition clientiface.h:514
void CreateClient(session_t peer_id)
Definition clientiface.cpp:877
static const char * state2Name(ClientState state)
Definition clientiface.cpp:53
ClientState getClientState(session_t peer_id)
Definition clientiface.cpp:835
std::vector< std::string > m_clients_names
Definition clientiface.h:522
void send(session_t peer_id, NetworkPacket *pkt)
Definition clientiface.cpp:785
RemoteClient * getClientNoEx(session_t peer_id, ClientState state_min=CS_Active)
Definition clientiface.cpp:813
void event(session_t peer_id, ClientStateEvent event)
Definition clientiface.cpp:892
const std::vector< std::string > & getPlayerNames() const
Definition clientiface.h:457
std::vector< session_t > getClientIDs(ClientState min_state=CS_Active)
Definition clientiface.cpp:693
u16 getProtocolVersion(session_t peer_id)
Definition clientiface.cpp:914
void setEnv(ServerEnvironment *env)
Definition clientiface.h:490
ServerEnvironment * m_env
Definition clientiface.h:525
std::recursive_mutex m_clients_mutex
Definition clientiface.h:519
float m_print_info_timer
Definition clientiface.h:527
RemoteClient * lockedGetClientNoEx(session_t peer_id, ClientState state_min=CS_Active)
Definition clientiface.cpp:820
void DeleteClient(session_t peer_id)
Definition clientiface.cpp:847
bool isUserLimitReached()
Definition clientiface.cpp:715
static constexpr int LINGER_TIMEOUT
Definition clientiface.h:534
friend class Server
Definition clientiface.h:439
void step(float dtime)
Definition clientiface.cpp:721
void UpdatePlayerList()
Definition clientiface.cpp:755
void sendCustom(session_t peer_id, u8 channel, NetworkPacket *pkt, bool reliable)
Definition clientiface.cpp:793
void markBlocksNotSent(const std::vector< v3s16 > &positions, bool low_priority=false)
Definition clientiface.cpp:706
void sendToAll(NetworkPacket *pkt, ClientState state_min=CS_Active)
Definition clientiface.cpp:802
ClientInterface(const std::shared_ptr< con::IConnection > &con)
Definition clientiface.cpp:670
RemoteClientMap m_clients
Definition clientiface.h:521
static const char * statenames[]
Definition clientiface.h:40
Definition emerge.h:116
Definition mapblock.h:58
Definition networkpacket.h:16
Definition clientiface.h:213
void confirmSerializationVersion()
Definition clientiface.h:314
const Address & getAddress() const
Definition clientiface.h:333
bool isMechAllowed(AuthMechanism mech)
Definition clientiface.h:234
u8 getMinor() const
Definition clientiface.h:325
void setPendingSerializationVersion(u8 version)
Definition clientiface.h:311
const s16 m_block_optimize_distance
Definition clientiface.h:379
u8 m_version_major
Definition clientiface.h:422
void GetNextBlocks(ServerEnvironment *env, EmergeManager *emerge, float dtime, std::vector< PrioritySortedBlockTransfer > &dest)
Definition clientiface.cpp:83
void setDynamicInfo(const ClientDynamicInfo &info)
Definition clientiface.h:335
const s16 m_max_gen_distance
Definition clientiface.h:381
u8 getMajor() const
Definition clientiface.h:324
void PrintInfo(std::ostream &o)
Definition clientiface.h:282
u32 getSendingCount() const
Definition clientiface.h:270
std::string enc_pwd
Definition clientiface.h:226
std::string m_full_version
Definition clientiface.h:426
const s16 m_block_cull_optimize_distance
Definition clientiface.h:380
ClientState m_state
Definition clientiface.h:343
void SetBlockNotSent(v3s16 p, bool low_priority=false)
Definition clientiface.cpp:426
ClientDynamicInfo m_dynamic_info
Definition clientiface.h:352
v3s16 m_last_center
Definition clientiface.h:373
const std::string & getName() const
Definition clientiface.h:303
u32 allowed_auth_mechs
Definition clientiface.h:230
const s16 m_max_send_distance
Definition clientiface.h:378
std::unordered_set< v3s16 > m_blocks_occ
Definition clientiface.h:370
s16 m_nearest_unsent_d
Definition clientiface.h:372
void setName(const std::string &name)
Definition clientiface.h:305
void setCachedAddress(const Address &addr)
Definition clientiface.h:332
std::string m_lang_code
Definition clientiface.h:349
void setVersionInfo(u8 major, u8 minor, u8 patch, const std::string &full)
Definition clientiface.cpp:657
void * auth_data
Definition clientiface.h:229
bool create_player_on_auth_success
Definition clientiface.h:227
std::unordered_set< v3s16 > m_blocks_sending
Definition clientiface.h:397
u8 m_version_minor
Definition clientiface.h:423
u8 m_version_patch
Definition clientiface.h:424
const ClientDynamicInfo & getDynamicInfo() const
Definition clientiface.h:336
float m_map_send_completion_timer
Definition clientiface.h:412
const float m_min_time_from_building
Definition clientiface.h:377
u32 m_excess_gotblocks
Definition clientiface.h:406
bool markMediaSent(const std::string &name)
Definition clientiface.h:277
RemoteClient()
Definition clientiface.cpp:58
const u64 m_connection_time
Definition clientiface.h:431
const std::string & getLangCode() const
Definition clientiface.h:330
u8 m_pending_serialization_version
Definition clientiface.h:340
float m_time_from_building
Definition clientiface.h:294
session_t peer_id
Definition clientiface.h:219
void SentBlock(v3s16 p)
Definition clientiface.cpp:419
u16 net_proto_version
Definition clientiface.h:223
ClientState getState() const
Definition clientiface.h:301
std::unordered_set< v3s16 > m_blocks_sent
Definition clientiface.h:363
void resetChosenMech()
Definition clientiface.cpp:635
void setEncryptedPassword(const std::string &pwd)
Definition clientiface.cpp:644
void fixupNodePrediction(InteractAction action, const PointedThing &pointed, bool prediction_success)
Trigger block sending to undo client-side predicted node changes.
Definition clientiface.cpp:458
~RemoteClient()=default
u8 serialization_version
Definition clientiface.h:221
const std::string & getFullVer() const
Definition clientiface.h:327
bool isBlockSent(v3s16 p) const
Definition clientiface.h:272
std::set< u16 > m_known_objects
Definition clientiface.h:299
Address m_addr
Definition clientiface.h:346
v3f m_last_camera_dir
Definition clientiface.h:374
u8 getPatch() const
Definition clientiface.h:326
void GotBlock(v3s16 p)
Definition clientiface.cpp:408
void setLangCode(const std::string &code)
Definition clientiface.cpp:665
std::string m_name
Definition clientiface.h:417
void notifyEvent(ClientStateEvent event)
Definition clientiface.cpp:486
const u16 m_max_simul_sends
Definition clientiface.h:376
void SetBlocksNotSent(const std::vector< v3s16 > &blocks, bool low_priority=false)
Definition clientiface.cpp:451
u64 uptime() const
Definition clientiface.cpp:652
std::unordered_set< std::string > m_media_sent
Definition clientiface.h:388
const bool m_occ_cull
Definition clientiface.h:382
AuthMechanism chosen_mech
Definition clientiface.h:228
float m_nothing_to_send_pause_timer
Definition clientiface.h:409
Definition serverenvironment.h:113
ClientState
Definition clientiface.h:164
@ CS_HelloSent
Definition clientiface.h:169
@ CS_Disconnecting
Definition clientiface.h:166
@ CS_Denied
Definition clientiface.h:167
@ CS_Active
Definition clientiface.h:173
@ CS_DefinitionsSent
Definition clientiface.h:172
@ CS_AwaitingInit2
Definition clientiface.h:170
@ CS_Created
Definition clientiface.h:168
@ CS_SudoMode
Definition clientiface.h:174
@ CS_InitDone
Definition clientiface.h:171
@ CS_Invalid
Definition clientiface.h:165
ClientStateEvent
Definition clientiface.h:178
@ CSE_SetClientReady
Definition clientiface.h:184
@ CSE_AuthAccept
Definition clientiface.h:180
@ CSE_SetDefinitionsSent
Definition clientiface.h:183
@ CSE_Hello
Definition clientiface.h:179
@ CSE_GotInit2
Definition clientiface.h:181
@ CSE_SudoLeave
Definition clientiface.h:186
@ CSE_SudoSuccess
Definition clientiface.h:185
@ CSE_Disconnect
Definition clientiface.h:187
@ CSE_SetDenied
Definition clientiface.h:182
std::unordered_map< u16, RemoteClient * > RemoteClientMap
Definition clientiface.h:434
#define PEER_ID_INEXISTENT
Definition constants.h:19
core::vector3d< s16 > v3s16
Definition irr_v3d.h:13
core::vector3df v3f
Definition irr_v3d.h:11
std::lock_guard< std::recursive_mutex > RecursiveMutexAutoLock
Definition mutex_auto_lock.h:33
Definition client.h:64
InteractAction
Definition networkprotocol.h:981
AuthMechanism
Definition networkprotocol.h:927
@ AUTH_MECHANISM_NONE
Definition networkprotocol.h:929
u16 session_t
Definition networkprotocol.h:27
Definition clientdynamicinfo.h:12
An active object or node which is selected by a ray on the map.
Definition pointedthing.h:22
bool operator<(const PrioritySortedBlockTransfer &other) const
Definition clientiface.h:203
float priority
Definition clientiface.h:207
PrioritySortedBlockTransfer(float a_priority, const v3s16 &a_pos, session_t a_peer_id)
Definition clientiface.h:197
v3s16 pos
Definition clientiface.h:208
session_t peer_id
Definition clientiface.h:209
static std::string p(std::string path)
Definition test_filesys.cpp:73