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