Luanti 5.11.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 "constants.h"
12#include "network/address.h"
13#include "porting.h"
15#include "clientdynamicinfo.h"
16
17#include <list>
18#include <vector>
19#include <set>
20#include <unordered_map>
21#include <unordered_set>
22#include <memory>
23#include <mutex>
24
25class MapBlock;
27class EmergeManager;
28
29/*
30 * State Transitions
31
32 Start
33 (peer connect)
34 |
35 v
36 /-----------------\
37 | |
38 | Created |
39 | |
40 \-----------------/
41 | depending of 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);
255 void SetBlocksNotSent(const std::vector<v3s16> &blocks);
256
264
265 u32 getSendingCount() const { return m_blocks_sending.size(); }
266
267 bool isBlockSent(v3s16 p) const
268 {
269 return m_blocks_sent.find(p) != m_blocks_sent.end();
270 }
271
272 bool markMediaSent(const std::string &name) {
273 auto insert_result = m_media_sent.emplace(name);
274 return insert_result.second; // true = was inserted
275 }
276
277 void PrintInfo(std::ostream &o)
278 {
279 o<<"RemoteClient "<<peer_id<<": "
280 <<"m_blocks_sent.size()="<<m_blocks_sent.size()
281 <<", m_blocks_sending.size()="<<m_blocks_sending.size()
282 <<", m_nearest_unsent_d="<<m_nearest_unsent_d
283 <<", m_excess_gotblocks="<<m_excess_gotblocks
284 <<std::endl;
286 }
287
288 // Time from last placing or removing blocks
290
291 /*
292 List of active objects that the client knows of.
293 */
294 std::set<u16> m_known_objects;
295
296 ClientState getState() const { return m_state; }
297
298 const std::string &getName() const { return m_name; }
299
300 void setName(const std::string &name) { m_name = name; }
301
302 /* update internal client state */
303 void notifyEvent(ClientStateEvent event);
304
305 /* set expected serialization version */
308
311
312 /* get uptime */
313 u64 uptime() const { return porting::getTimeS() - m_connection_time; }
314
315 /* set version information */
316 void setVersionInfo(u8 major, u8 minor, u8 patch, const std::string &full);
317
318 /* read version information */
319 u8 getMajor() const { return m_version_major; }
320 u8 getMinor() const { return m_version_minor; }
321 u8 getPatch() const { return m_version_patch; }
322 const std::string &getFullVer() const { return m_full_version; }
323
324 void setLangCode(const std::string &code);
325 const std::string &getLangCode() const { return m_lang_code; }
326
327 void setCachedAddress(const Address &addr) { m_addr = addr; }
328 const Address &getAddress() const { return m_addr; }
329
330 void setDynamicInfo(const ClientDynamicInfo &info) { m_dynamic_info = info; }
332
333private:
334 // Version is stored in here after INIT before INIT2
336
337 /* current state of client */
339
340 // Cached here so retrieval doesn't have to go to connection API
342
343 // Client-sent language code
344 std::string m_lang_code;
345
346 // Client-sent dynamic info
348
349 /*
350 Blocks that have been sent to client.
351 - These don't have to be sent again.
352 - A block is cleared from here when client says it has
353 deleted it from it's memory
354
355 List of block positions.
356 No MapBlock* is stored here because the blocks can get deleted.
357 */
358 std::unordered_set<v3s16> m_blocks_sent;
359
360 /*
361 Cache of blocks that have been occlusion culled at the current distance.
362 As GetNextBlocks traverses the same distance multiple times, this saves
363 significant CPU time.
364 */
365 std::unordered_set<v3s16> m_blocks_occ;
366
370
377 const bool m_occ_cull;
378
379 /*
380 Set of media files the client has already requested
381 We won't send the same file twice to avoid bandwidth consumption attacks.
382 */
383 std::unordered_set<std::string> m_media_sent;
384
385 /*
386 Blocks that are currently on the line.
387 This is used for throttling the sending of blocks.
388 - The size of this list is limited to some value
389 Block is added when it is sent with BLOCKDATA.
390 Block is removed when GOTBLOCKS is received.
391 Value is time from sending. (not used at the moment)
392 */
393 std::unordered_map<v3s16, float> m_blocks_sending;
394
395 /*
396 Blocks that have been modified since blocks were
397 sent to the client last (getNextBlocks()).
398 This is used to reset the unsent distance, so that
399 modified blocks are resent to the client.
400
401 List of block positions.
402 */
403 std::unordered_set<v3s16> m_blocks_modified;
404
405 /*
406 Count of excess GotBlocks().
407 There is an excess amount because the client sometimes
408 gets a block so late that the server sends it again,
409 and the client then sends two GOTBLOCKs.
410 This is reset by PrintInfo()
411 */
413
414 // CPU usage optimization
416
417 // measure how long it takes the server to send the complete map
419
420 /*
421 name of player using this client
422 */
423 std::string m_name = "";
424
425 /*
426 client information
427 */
431
432 std::string m_full_version = "unknown";
433
434 /*
435 time this client was created
436 */
438};
439
440typedef std::unordered_map<u16, RemoteClient*> RemoteClientMap;
441
443public:
444
445 friend class Server;
446
447 ClientInterface(const std::shared_ptr<con::IConnection> &con);
449
450 /* run sync step */
451 void step(float dtime);
452
453 /* get list of active client id's */
454 std::vector<session_t> getClientIDs(ClientState min_state=CS_Active);
455
456 /* mark blocks as not sent on all active clients */
457 void markBlocksNotSent(const std::vector<v3s16> &positions);
458
459 /* verify is server user limit was reached */
460 bool isUserLimitReached();
461
462 /* get list of client player names */
463 const std::vector<std::string> &getPlayerNames() const { return m_clients_names; }
464
465 /* send to one client */
466 void send(session_t peer_id, NetworkPacket *pkt);
467
468 /* send to one client, deviating from the standard params */
469 void sendCustom(session_t peer_id, u8 channel, NetworkPacket *pkt, bool reliable);
470
471 /* send to all clients */
472 void sendToAll(NetworkPacket *pkt);
473
474 /* delete a client */
475 void DeleteClient(session_t peer_id);
476
477 /* create client */
478 void CreateClient(session_t peer_id);
479
480 /* get a client by peer_id */
482
483 /* get client by peer_id (make sure you have list lock before!*/
485
486 /* get state of client by id*/
488
489 /* set client playername */
490 void setPlayerName(session_t peer_id, const std::string &name);
491
492 /* get protocol version of client */
493 u16 getProtocolVersion(session_t peer_id);
494
495 /* set client version */
496 void setClientVersion(session_t peer_id, u8 major, u8 minor, u8 patch,
497 const std::string &full);
498
499 /* event to update client state */
500 void event(session_t peer_id, ClientStateEvent event);
501
502 /* Set environment. Do not call this function if environment is already set */
504 {
505 assert(m_env == NULL); // pre-condition
506 m_env = env;
507 }
508
509 static std::string state2Name(ClientState state);
510protected:
511 class AutoLock {
512 public:
514
515 private:
517 };
518
520
521private:
522 /* update internal player list */
523 void UpdatePlayerList();
524
525 // Connection
526 std::shared_ptr<con::IConnection> m_con;
527 std::recursive_mutex m_clients_mutex;
528 // Connected clients (behind the con mutex)
530 std::vector<std::string> m_clients_names; //for announcing masterserver
531
532 // Environment
534
537
538 static const char *statenames[];
539
540 static constexpr int LINGER_TIMEOUT = 10;
541};
Definition address.h:28
Definition clientiface.h:511
RecursiveMutexAutoLock m_lock
Definition clientiface.h:516
AutoLock(ClientInterface &iface)
Definition clientiface.h:513
Definition clientiface.h:442
float m_check_linger_timer
Definition clientiface.h:536
RemoteClientMap & getClientList()
Definition clientiface.h:519
~ClientInterface()
Definition clientiface.cpp:647
std::shared_ptr< con::IConnection > m_con
Definition clientiface.h:526
void CreateClient(session_t peer_id)
Definition clientiface.cpp:872
ClientState getClientState(session_t peer_id)
Definition clientiface.cpp:820
std::vector< std::string > m_clients_names
Definition clientiface.h:530
void send(session_t peer_id, NetworkPacket *pkt)
Definition clientiface.cpp:760
static std::string state2Name(ClientState state)
Definition clientiface.cpp:49
RemoteClient * getClientNoEx(session_t peer_id, ClientState state_min=CS_Active)
Definition clientiface.cpp:791
void sendToAll(NetworkPacket *pkt)
Definition clientiface.cpp:777
void event(session_t peer_id, ClientStateEvent event)
Definition clientiface.cpp:887
void markBlocksNotSent(const std::vector< v3s16 > &positions)
Definition clientiface.cpp:675
const std::vector< std::string > & getPlayerNames() const
Definition clientiface.h:463
std::vector< session_t > getClientIDs(ClientState min_state=CS_Active)
Definition clientiface.cpp:662
u16 getProtocolVersion(session_t peer_id)
Definition clientiface.cpp:909
void setEnv(ServerEnvironment *env)
Definition clientiface.h:503
ServerEnvironment * m_env
Definition clientiface.h:533
std::recursive_mutex m_clients_mutex
Definition clientiface.h:527
float m_print_info_timer
Definition clientiface.h:535
RemoteClient * lockedGetClientNoEx(session_t peer_id, ClientState state_min=CS_Active)
Definition clientiface.cpp:806
void setClientVersion(session_t peer_id, u8 major, u8 minor, u8 patch, const std::string &full)
Definition clientiface.cpp:923
void DeleteClient(session_t peer_id)
Definition clientiface.cpp:842
bool isUserLimitReached()
Verify if user limit was reached.
Definition clientiface.cpp:689
static constexpr int LINGER_TIMEOUT
Definition clientiface.h:540
void setPlayerName(session_t peer_id, const std::string &name)
Definition clientiface.cpp:832
void step(float dtime)
Definition clientiface.cpp:694
void UpdatePlayerList()
Definition clientiface.cpp:731
void sendCustom(session_t peer_id, u8 channel, NetworkPacket *pkt, bool reliable)
Definition clientiface.cpp:768
ClientInterface(const std::shared_ptr< con::IConnection > &con)
Definition clientiface.cpp:639
RemoteClientMap m_clients
Definition clientiface.h:529
static const char * statenames[]
Definition clientiface.h:36
Definition emerge.h:117
Definition mapblock.h:58
Definition networkpacket.h:14
Definition clientiface.h:213
void confirmSerializationVersion()
Definition clientiface.h:309
const Address & getAddress() const
Definition clientiface.h:328
bool isMechAllowed(AuthMechanism mech)
Definition clientiface.h:234
u8 getMinor() const
Definition clientiface.h:320
void setPendingSerializationVersion(u8 version)
Definition clientiface.h:306
const s16 m_block_optimize_distance
Definition clientiface.h:374
u8 m_version_major
Definition clientiface.h:428
void GetNextBlocks(ServerEnvironment *env, EmergeManager *emerge, float dtime, std::vector< PrioritySortedBlockTransfer > &dest)
Definition clientiface.cpp:85
void setDynamicInfo(const ClientDynamicInfo &info)
Definition clientiface.h:330
const s16 m_max_gen_distance
Definition clientiface.h:376
void SetBlockNotSent(v3s16 p)
Definition clientiface.cpp:438
u8 getMajor() const
Definition clientiface.h:319
void PrintInfo(std::ostream &o)
Definition clientiface.h:277
u32 getSendingCount() const
Definition clientiface.h:265
std::string enc_pwd
Definition clientiface.h:226
std::string m_full_version
Definition clientiface.h:432
const s16 m_block_cull_optimize_distance
Definition clientiface.h:375
ClientState m_state
Definition clientiface.h:338
void SetBlocksNotSent(const std::vector< v3s16 > &blocks)
Definition clientiface.cpp:448
ClientDynamicInfo m_dynamic_info
Definition clientiface.h:347
v3s16 m_last_center
Definition clientiface.h:368
const std::string & getName() const
Definition clientiface.h:298
u32 allowed_auth_mechs
Definition clientiface.h:230
const s16 m_max_send_distance
Definition clientiface.h:373
std::unordered_set< v3s16 > m_blocks_occ
Definition clientiface.h:365
void ResendBlockIfOnWire(v3s16 p)
tell client about this block being modified right now.
Definition clientiface.cpp:68
s16 m_nearest_unsent_d
Definition clientiface.h:367
void setName(const std::string &name)
Definition clientiface.h:300
void setCachedAddress(const Address &addr)
Definition clientiface.h:327
std::string m_lang_code
Definition clientiface.h:344
void setVersionInfo(u8 major, u8 minor, u8 patch, const std::string &full)
Definition clientiface.cpp:626
void * auth_data
Definition clientiface.h:229
bool create_player_on_auth_success
Definition clientiface.h:227
u8 m_version_minor
Definition clientiface.h:429
u8 m_version_patch
Definition clientiface.h:430
const ClientDynamicInfo & getDynamicInfo() const
Definition clientiface.h:331
float m_map_send_completion_timer
Definition clientiface.h:418
const float m_min_time_from_building
Definition clientiface.h:372
u32 m_excess_gotblocks
Definition clientiface.h:412
bool markMediaSent(const std::string &name)
Definition clientiface.h:272
RemoteClient()
Definition clientiface.cpp:54
const u64 m_connection_time
Definition clientiface.h:437
const std::string & getLangCode() const
Definition clientiface.h:325
u8 m_pending_serialization_version
Definition clientiface.h:335
float m_time_from_building
Definition clientiface.h:289
session_t peer_id
Definition clientiface.h:219
void SentBlock(v3s16 p)
Definition clientiface.cpp:429
u16 net_proto_version
Definition clientiface.h:223
std::unordered_set< v3s16 > m_blocks_modified
Definition clientiface.h:403
ClientState getState() const
Definition clientiface.h:296
std::unordered_set< v3s16 > m_blocks_sent
Definition clientiface.h:358
void resetChosenMech()
Definition clientiface.cpp:609
void setEncryptedPassword(const std::string &pwd)
Definition clientiface.cpp:618
~RemoteClient()=default
u8 serialization_version
Definition clientiface.h:221
const std::string & getFullVer() const
Definition clientiface.h:322
bool isBlockSent(v3s16 p) const
Definition clientiface.h:267
std::set< u16 > m_known_objects
Definition clientiface.h:294
Address m_addr
Definition clientiface.h:341
v3f m_last_camera_dir
Definition clientiface.h:369
u8 getPatch() const
Definition clientiface.h:321
void GotBlock(v3s16 p)
Definition clientiface.cpp:417
void setLangCode(const std::string &code)
Definition clientiface.cpp:634
std::string m_name
Definition clientiface.h:423
void notifyEvent(ClientStateEvent event)
Definition clientiface.cpp:460
const u16 m_max_simul_sends
Definition clientiface.h:371
u64 uptime() const
Definition clientiface.h:313
std::unordered_map< v3s16, float > m_blocks_sending
Definition clientiface.h:393
std::unordered_set< std::string > m_media_sent
Definition clientiface.h:383
const bool m_occ_cull
Definition clientiface.h:377
AuthMechanism chosen_mech
Definition clientiface.h:228
float m_nothing_to_send_pause_timer
Definition clientiface.h:415
Definition serverenvironment.h:219
Definition server.h:166
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:440
#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:59
u64 getTimeS()
Definition porting.h:168
AuthMechanism
Definition networkprotocol.h:888
@ AUTH_MECHANISM_NONE
Definition networkprotocol.h:890
u16 session_t
Definition networkprotocol.h:22
Definition clientdynamicinfo.h:12
Definition clientiface.h:196
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:53