]> git.lizzy.rs Git - dragonfireclient.git/blob - src/clientiface.h
Suppress MSVC warning in chat.cpp
[dragonfireclient.git] / src / clientiface.h
1 /*
2 Minetest
3 Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 #ifndef _CLIENTIFACE_H_
20 #define _CLIENTIFACE_H_
21
22 #include "irr_v3d.h"                   // for irrlicht datatypes
23
24 #include "constants.h"
25 #include "serialization.h"             // for SER_FMT_VER_INVALID
26 #include "jthread/jmutex.h"
27
28 #include <list>
29 #include <vector>
30 #include <map>
31 #include <set>
32
33 class MapBlock;
34 class ServerEnvironment;
35 class EmergeManager;
36
37 /*
38  * State Transitions
39
40       Start
41   (peer connect)
42         |
43         v
44       /-----------------\
45       |                 |
46       |    Created      |
47       |                 |
48       \-----------------/
49                |
50                |
51 +-----------------------------+            invalid playername, password
52 |IN:                          |                    or denied by mod
53 | TOSERVER_INIT               |------------------------------
54 +-----------------------------+                             |
55                |                                            |
56                | Auth ok                                    |
57                |                                            |
58 +-----------------------------+                             |
59 |OUT:                         |                             |
60 | TOCLIENT_INIT               |                             |
61 +-----------------------------+                             |
62                |                                            |
63                v                                            |
64       /-----------------\                                   |
65       |                 |                                   |
66       |    InitSent     |                                   |
67       |                 |                                   |
68       \-----------------/                                   +------------------
69                |                                            |                 |
70 +-----------------------------+             +-----------------------------+   |
71 |IN:                          |             |OUT:                         |   |
72 | TOSERVER_INIT2              |             | TOCLIENT_ACCESS_DENIED      |   |
73 +-----------------------------+             +-----------------------------+   |
74                |                                            |                 |
75                v                                            v                 |
76       /-----------------\                           /-----------------\       |
77       |                 |                           |                 |       |
78       |    InitDone     |                           |     Denied      |       |
79       |                 |                           |                 |       |
80       \-----------------/                           \-----------------/       |
81                |                                                              |
82 +-----------------------------+                                               |
83 |OUT:                         |                                               |
84 | TOCLIENT_MOVEMENT           |                                               |
85 | TOCLIENT_ITEMDEF            |                                               |
86 | TOCLIENT_NODEDEF            |                                               |
87 | TOCLIENT_ANNOUNCE_MEDIA     |                                               |
88 | TOCLIENT_DETACHED_INVENTORY |                                               |
89 | TOCLIENT_TIME_OF_DAY        |                                               |
90 +-----------------------------+                                               |
91                |                                                              |
92                |                                                              |
93                |      -----------------------------------                     |
94                v      |                                 |                     |
95       /-----------------\                               v                     |
96       |                 |                   +-----------------------------+   |
97       | DefinitionsSent |                   |IN:                          |   |
98       |                 |                   | TOSERVER_REQUEST_MEDIA      |   |
99       \-----------------/                   | TOSERVER_RECEIVED_MEDIA     |   |
100                |                            +-----------------------------+   |
101                |      ^                                 |                     |
102                |      -----------------------------------                     |
103                |                                                              |
104 +-----------------------------+                                               |
105 |IN:                          |                                               |
106 | TOSERVER_CLIENT_READY       |                                               |
107 +-----------------------------+                                               |
108                |                                                    async     |
109                v                                                  mod action  |
110 +-----------------------------+                                   (ban,kick)  |
111 |OUT:                         |                                               |
112 | TOCLIENT_MOVE_PLAYER        |                                               |
113 | TOCLIENT_PRIVILEGES         |                                               |
114 | TOCLIENT_INVENTORY_FORMSPEC |                                               |
115 | UpdateCrafting              |                                               |
116 | TOCLIENT_INVENTORY          |                                               |
117 | TOCLIENT_HP (opt)           |                                               |
118 | TOCLIENT_BREATH             |                                               |
119 | TOCLIENT_DEATHSCREEN        |                                               |
120 +-----------------------------+                                               |
121               |                                                               |
122               v                                                               |
123       /-----------------\                                                     |
124       |                 |------------------------------------------------------
125       |     Active      |
126       |                 |----------------------------------
127       \-----------------/      timeout                    |
128                |                            +-----------------------------+
129                |                            |OUT:                         |
130                |                            | TOCLIENT_DISCONNECT         |
131                |                            +-----------------------------+
132                |                                          |
133                |                                          v
134 +-----------------------------+                    /-----------------\
135 |IN:                          |                    |                 |
136 | TOSERVER_DISCONNECT         |------------------->|  Disconnecting  |
137 +-----------------------------+                    |                 |
138                                                    \-----------------/
139 */
140 namespace con {
141         class Connection;
142 }
143
144 #define CI_ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0]))
145
146 enum ClientState
147 {
148         CS_Invalid,
149         CS_Disconnecting,
150         CS_Denied,
151         CS_Created,
152         CS_InitSent,
153         CS_InitDone,
154         CS_DefinitionsSent,
155         CS_Active
156 };
157
158 enum ClientStateEvent
159 {
160         CSE_Init,
161         CSE_GotInit2,
162         CSE_SetDenied,
163         CSE_SetDefinitionsSent,
164         CSE_SetClientReady,
165         CSE_Disconnect
166 };
167
168 /*
169         Used for queueing and sorting block transfers in containers
170
171         Lower priority number means higher priority.
172 */
173 struct PrioritySortedBlockTransfer
174 {
175         PrioritySortedBlockTransfer(float a_priority, v3s16 a_pos, u16 a_peer_id)
176         {
177                 priority = a_priority;
178                 pos = a_pos;
179                 peer_id = a_peer_id;
180         }
181         bool operator < (const PrioritySortedBlockTransfer &other) const
182         {
183                 return priority < other.priority;
184         }
185         float priority;
186         v3s16 pos;
187         u16 peer_id;
188 };
189
190 class RemoteClient
191 {
192 public:
193         // peer_id=0 means this client has no associated peer
194         // NOTE: If client is made allowed to exist while peer doesn't,
195         //       this has to be set to 0 when there is no peer.
196         //       Also, the client must be moved to some other container.
197         u16 peer_id;
198         // The serialization version to use with the client
199         u8 serialization_version;
200         //
201         u16 net_proto_version;
202
203         RemoteClient():
204                 peer_id(PEER_ID_INEXISTENT),
205                 serialization_version(SER_FMT_VER_INVALID),
206                 net_proto_version(0),
207                 m_time_from_building(9999),
208                 m_pending_serialization_version(SER_FMT_VER_INVALID),
209                 m_state(CS_Created),
210                 m_nearest_unsent_d(0),
211                 m_nearest_unsent_reset_timer(0.0),
212                 m_excess_gotblocks(0),
213                 m_nothing_to_send_pause_timer(0.0),
214                 m_name(""),
215                 m_version_major(0),
216                 m_version_minor(0),
217                 m_version_patch(0),
218                 m_full_version("unknown"),
219                 m_connection_time(getTime(PRECISION_SECONDS))
220         {
221         }
222         ~RemoteClient()
223         {
224         }
225
226         /*
227                 Finds block that should be sent next to the client.
228                 Environment should be locked when this is called.
229                 dtime is used for resetting send radius at slow interval
230         */
231         void GetNextBlocks(ServerEnvironment *env, EmergeManager* emerge,
232                         float dtime, std::vector<PrioritySortedBlockTransfer> &dest);
233
234         void GotBlock(v3s16 p);
235
236         void SentBlock(v3s16 p);
237
238         void SetBlockNotSent(v3s16 p);
239         void SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks);
240
241         /**
242          * tell client about this block being modified right now.
243          * this information is required to requeue the block in case it's "on wire"
244          * while modification is processed by server
245          * @param p position of modified block
246          */
247         void ResendBlockIfOnWire(v3s16 p);
248
249         s32 SendingCount()
250         {
251                 return m_blocks_sending.size();
252         }
253
254         // Increments timeouts and removes timed-out blocks from list
255         // NOTE: This doesn't fix the server-not-sending-block bug
256         //       because it is related to emerging, not sending.
257         //void RunSendingTimeouts(float dtime, float timeout);
258
259         void PrintInfo(std::ostream &o)
260         {
261                 o<<"RemoteClient "<<peer_id<<": "
262                                 <<"m_blocks_sent.size()="<<m_blocks_sent.size()
263                                 <<", m_blocks_sending.size()="<<m_blocks_sending.size()
264                                 <<", m_nearest_unsent_d="<<m_nearest_unsent_d
265                                 <<", m_excess_gotblocks="<<m_excess_gotblocks
266                                 <<std::endl;
267                 m_excess_gotblocks = 0;
268         }
269
270         // Time from last placing or removing blocks
271         float m_time_from_building;
272
273         /*
274                 List of active objects that the client knows of.
275                 Value is dummy.
276         */
277         std::set<u16> m_known_objects;
278
279         ClientState getState()
280                 { return m_state; }
281
282         std::string getName()
283                 { return m_name; }
284
285         void setName(std::string name)
286                 { m_name = name; }
287
288         /* update internal client state */
289         void notifyEvent(ClientStateEvent event);
290
291         /* set expected serialization version */
292         void setPendingSerializationVersion(u8 version)
293                 { m_pending_serialization_version = version; }
294
295         void confirmSerializationVersion()
296                 { serialization_version = m_pending_serialization_version; }
297
298         /* get uptime */
299         u32 uptime();
300
301
302         /* set version information */
303         void setVersionInfo(u8 major, u8 minor, u8 patch, std::string full) {
304                 m_version_major = major;
305                 m_version_minor = minor;
306                 m_version_patch = patch;
307                 m_full_version = full;
308         }
309
310         /* read version information */
311         u8 getMajor() { return m_version_major; }
312         u8 getMinor() { return m_version_minor; }
313         u8 getPatch() { return m_version_patch; }
314         std::string getVersion() { return m_full_version; }
315 private:
316         // Version is stored in here after INIT before INIT2
317         u8 m_pending_serialization_version;
318
319         /* current state of client */
320         ClientState m_state;
321
322         /*
323                 Blocks that have been sent to client.
324                 - These don't have to be sent again.
325                 - A block is cleared from here when client says it has
326                   deleted it from it's memory
327
328                 Key is position, value is dummy.
329                 No MapBlock* is stored here because the blocks can get deleted.
330         */
331         std::set<v3s16> m_blocks_sent;
332         s16 m_nearest_unsent_d;
333         v3s16 m_last_center;
334         float m_nearest_unsent_reset_timer;
335
336         /*
337                 Blocks that are currently on the line.
338                 This is used for throttling the sending of blocks.
339                 - The size of this list is limited to some value
340                 Block is added when it is sent with BLOCKDATA.
341                 Block is removed when GOTBLOCKS is received.
342                 Value is time from sending. (not used at the moment)
343         */
344         std::map<v3s16, float> m_blocks_sending;
345
346         /*
347                 Count of excess GotBlocks().
348                 There is an excess amount because the client sometimes
349                 gets a block so late that the server sends it again,
350                 and the client then sends two GOTBLOCKs.
351                 This is resetted by PrintInfo()
352         */
353         u32 m_excess_gotblocks;
354
355         // CPU usage optimization
356         float m_nothing_to_send_pause_timer;
357
358         /*
359                 name of player using this client
360         */
361         std::string m_name;
362
363         /*
364                 client information
365          */
366         u8 m_version_major;
367         u8 m_version_minor;
368         u8 m_version_patch;
369
370         std::string m_full_version;
371
372         /*
373                 time this client was created
374          */
375         const u32 m_connection_time;
376 };
377
378 class ClientInterface {
379 public:
380
381         friend class Server;
382
383         ClientInterface(con::Connection* con);
384         ~ClientInterface();
385
386         /* run sync step */
387         void step(float dtime);
388
389         /* get list of active client id's */
390         std::list<u16> getClientIDs(ClientState min_state=CS_Active);
391
392         /* get list of client player names */
393         std::vector<std::string> getPlayerNames();
394
395         /* send message to client */
396         void send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
397
398         /* send to all clients */
399         void sendToAll(u16 channelnum, SharedBuffer<u8> data, bool reliable);
400
401         /* delete a client */
402         void DeleteClient(u16 peer_id);
403
404         /* create client */
405         void CreateClient(u16 peer_id);
406
407         /* get a client by peer_id */
408         RemoteClient* getClientNoEx(u16 peer_id,  ClientState state_min=CS_Active);
409
410         /* get client by peer_id (make sure you have list lock before!*/
411         RemoteClient* lockedGetClientNoEx(u16 peer_id,  ClientState state_min=CS_Active);
412
413         /* get state of client by id*/
414         ClientState getClientState(u16 peer_id);
415
416         /* set client playername */
417         void setPlayerName(u16 peer_id,std::string name);
418
419         /* get protocol version of client */
420         u16 getProtocolVersion(u16 peer_id);
421
422         /* set client version */
423         void setClientVersion(u16 peer_id, u8 major, u8 minor, u8 patch, std::string full);
424
425         /* event to update client state */
426         void event(u16 peer_id, ClientStateEvent event);
427
428         /* set environment */
429         void setEnv(ServerEnvironment* env)
430         { assert(m_env == 0); m_env = env; }
431
432         static std::string state2Name(ClientState state);
433
434 protected:
435         //TODO find way to avoid this functions
436         void Lock()
437                 { m_clients_mutex.Lock(); }
438         void Unlock()
439                 { m_clients_mutex.Unlock(); }
440
441         std::map<u16, RemoteClient*>& getClientList()
442                 { return m_clients; }
443
444 private:
445         /* update internal player list */
446         void UpdatePlayerList();
447
448         // Connection
449         con::Connection* m_con;
450         JMutex m_clients_mutex;
451         // Connected clients (behind the con mutex)
452         std::map<u16, RemoteClient*> m_clients;
453         std::vector<std::string> m_clients_names; //for announcing masterserver
454
455         // Environment
456         ServerEnvironment *m_env;
457         JMutex m_env_mutex;
458
459         float m_print_info_timer;
460         
461         static const char *statenames[];
462 };
463
464 #endif