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