ServerRemotePlayer implements ServerActiveObject
[oweals/minetest.git] / src / server.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010-2011 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 General Public License as published by
7 the Free Software Foundation; either version 2 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 General Public License for more details.
14
15 You should have received a copy of the GNU 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
20 #ifndef SERVER_HEADER
21 #define SERVER_HEADER
22
23 #include "connection.h"
24 #include "environment.h"
25 #include "common_irrlicht.h"
26 #include <string>
27 #include "porting.h"
28 #include "map.h"
29 #include "inventory.h"
30 #include "auth.h"
31 #include "ban.h"
32 struct LuaState;
33 typedef struct lua_State lua_State;
34
35 /*
36         Some random functions
37 */
38 v3f findSpawnPos(ServerMap &map);
39
40 /*
41         A structure containing the data needed for queueing the fetching
42         of blocks.
43 */
44 struct QueuedBlockEmerge
45 {
46         v3s16 pos;
47         // key = peer_id, value = flags
48         core::map<u16, u8> peer_ids;
49 };
50
51 /*
52         This is a thread-safe class.
53 */
54 class BlockEmergeQueue
55 {
56 public:
57         BlockEmergeQueue()
58         {
59                 m_mutex.Init();
60         }
61
62         ~BlockEmergeQueue()
63         {
64                 JMutexAutoLock lock(m_mutex);
65
66                 core::list<QueuedBlockEmerge*>::Iterator i;
67                 for(i=m_queue.begin(); i!=m_queue.end(); i++)
68                 {
69                         QueuedBlockEmerge *q = *i;
70                         delete q;
71                 }
72         }
73         
74         /*
75                 peer_id=0 adds with nobody to send to
76         */
77         void addBlock(u16 peer_id, v3s16 pos, u8 flags)
78         {
79                 DSTACK(__FUNCTION_NAME);
80         
81                 JMutexAutoLock lock(m_mutex);
82
83                 if(peer_id != 0)
84                 {
85                         /*
86                                 Find if block is already in queue.
87                                 If it is, update the peer to it and quit.
88                         */
89                         core::list<QueuedBlockEmerge*>::Iterator i;
90                         for(i=m_queue.begin(); i!=m_queue.end(); i++)
91                         {
92                                 QueuedBlockEmerge *q = *i;
93                                 if(q->pos == pos)
94                                 {
95                                         q->peer_ids[peer_id] = flags;
96                                         return;
97                                 }
98                         }
99                 }
100                 
101                 /*
102                         Add the block
103                 */
104                 QueuedBlockEmerge *q = new QueuedBlockEmerge;
105                 q->pos = pos;
106                 if(peer_id != 0)
107                         q->peer_ids[peer_id] = flags;
108                 m_queue.push_back(q);
109         }
110
111         // Returned pointer must be deleted
112         // Returns NULL if queue is empty
113         QueuedBlockEmerge * pop()
114         {
115                 JMutexAutoLock lock(m_mutex);
116
117                 core::list<QueuedBlockEmerge*>::Iterator i = m_queue.begin();
118                 if(i == m_queue.end())
119                         return NULL;
120                 QueuedBlockEmerge *q = *i;
121                 m_queue.erase(i);
122                 return q;
123         }
124
125         u32 size()
126         {
127                 JMutexAutoLock lock(m_mutex);
128                 return m_queue.size();
129         }
130         
131         u32 peerItemCount(u16 peer_id)
132         {
133                 JMutexAutoLock lock(m_mutex);
134
135                 u32 count = 0;
136
137                 core::list<QueuedBlockEmerge*>::Iterator i;
138                 for(i=m_queue.begin(); i!=m_queue.end(); i++)
139                 {
140                         QueuedBlockEmerge *q = *i;
141                         if(q->peer_ids.find(peer_id) != NULL)
142                                 count++;
143                 }
144
145                 return count;
146         }
147
148 private:
149         core::list<QueuedBlockEmerge*> m_queue;
150         JMutex m_mutex;
151 };
152
153 class Server;
154
155 class ServerThread : public SimpleThread
156 {
157         Server *m_server;
158
159 public:
160
161         ServerThread(Server *server):
162                 SimpleThread(),
163                 m_server(server)
164         {
165         }
166
167         void * Thread();
168 };
169
170 class EmergeThread : public SimpleThread
171 {
172         Server *m_server;
173
174 public:
175
176         EmergeThread(Server *server):
177                 SimpleThread(),
178                 m_server(server)
179         {
180         }
181
182         void * Thread();
183
184         void trigger()
185         {
186                 setRun(true);
187                 if(IsRunning() == false)
188                 {
189                         Start();
190                 }
191         }
192 };
193
194 struct PlayerInfo
195 {
196         u16 id;
197         char name[PLAYERNAME_SIZE];
198         v3f position;
199         Address address;
200         float avg_rtt;
201
202         PlayerInfo();
203         void PrintLine(std::ostream *s);
204 };
205
206 u32 PIChecksum(core::list<PlayerInfo> &l);
207
208 /*
209         Used for queueing and sorting block transfers in containers
210         
211         Lower priority number means higher priority.
212 */
213 struct PrioritySortedBlockTransfer
214 {
215         PrioritySortedBlockTransfer(float a_priority, v3s16 a_pos, u16 a_peer_id)
216         {
217                 priority = a_priority;
218                 pos = a_pos;
219                 peer_id = a_peer_id;
220         }
221         bool operator < (PrioritySortedBlockTransfer &other)
222         {
223                 return priority < other.priority;
224         }
225         float priority;
226         v3s16 pos;
227         u16 peer_id;
228 };
229
230 class RemoteClient
231 {
232 public:
233         // peer_id=0 means this client has no associated peer
234         // NOTE: If client is made allowed to exist while peer doesn't,
235         //       this has to be set to 0 when there is no peer.
236         //       Also, the client must be moved to some other container.
237         u16 peer_id;
238         // The serialization version to use with the client
239         u8 serialization_version;
240         //
241         u16 net_proto_version;
242         // Version is stored in here after INIT before INIT2
243         u8 pending_serialization_version;
244
245         RemoteClient():
246                 m_time_from_building(9999),
247                 m_excess_gotblocks(0)
248         {
249                 peer_id = 0;
250                 serialization_version = SER_FMT_VER_INVALID;
251                 net_proto_version = 0;
252                 pending_serialization_version = SER_FMT_VER_INVALID;
253                 m_nearest_unsent_d = 0;
254                 m_nearest_unsent_reset_timer = 0.0;
255                 m_nothing_to_send_counter = 0;
256                 m_nothing_to_send_pause_timer = 0;
257         }
258         ~RemoteClient()
259         {
260         }
261         
262         /*
263                 Finds block that should be sent next to the client.
264                 Environment should be locked when this is called.
265                 dtime is used for resetting send radius at slow interval
266         */
267         void GetNextBlocks(Server *server, float dtime,
268                         core::array<PrioritySortedBlockTransfer> &dest);
269
270         /*
271                 Connection and environment should be locked when this is called.
272                 steps() objects of blocks not found in active_blocks, then
273                 adds those blocks to active_blocks
274         */
275         void SendObjectData(
276                         Server *server,
277                         float dtime,
278                         core::map<v3s16, bool> &stepped_blocks
279                 );
280
281         void GotBlock(v3s16 p);
282
283         void SentBlock(v3s16 p);
284
285         void SetBlockNotSent(v3s16 p);
286         void SetBlocksNotSent(core::map<v3s16, MapBlock*> &blocks);
287
288         s32 SendingCount()
289         {
290                 return m_blocks_sending.size();
291         }
292         
293         // Increments timeouts and removes timed-out blocks from list
294         // NOTE: This doesn't fix the server-not-sending-block bug
295         //       because it is related to emerging, not sending.
296         //void RunSendingTimeouts(float dtime, float timeout);
297
298         void PrintInfo(std::ostream &o)
299         {
300                 o<<"RemoteClient "<<peer_id<<": "
301                                 <<"m_blocks_sent.size()="<<m_blocks_sent.size()
302                                 <<", m_blocks_sending.size()="<<m_blocks_sending.size()
303                                 <<", m_nearest_unsent_d="<<m_nearest_unsent_d
304                                 <<", m_excess_gotblocks="<<m_excess_gotblocks
305                                 <<std::endl;
306                 m_excess_gotblocks = 0;
307         }
308
309         // Time from last placing or removing blocks
310         float m_time_from_building;
311         
312         /*JMutex m_dig_mutex;
313         float m_dig_time_remaining;
314         // -1 = not digging
315         s16 m_dig_tool_item;
316         v3s16 m_dig_position;*/
317         
318         /*
319                 List of active objects that the client knows of.
320                 Value is dummy.
321         */
322         core::map<u16, bool> m_known_objects;
323
324 private:
325         /*
326                 Blocks that have been sent to client.
327                 - These don't have to be sent again.
328                 - A block is cleared from here when client says it has
329                   deleted it from it's memory
330                 
331                 Key is position, value is dummy.
332                 No MapBlock* is stored here because the blocks can get deleted.
333         */
334         core::map<v3s16, bool> m_blocks_sent;
335         s16 m_nearest_unsent_d;
336         v3s16 m_last_center;
337         float m_nearest_unsent_reset_timer;
338         
339         /*
340                 Blocks that are currently on the line.
341                 This is used for throttling the sending of blocks.
342                 - The size of this list is limited to some value
343                 Block is added when it is sent with BLOCKDATA.
344                 Block is removed when GOTBLOCKS is received.
345                 Value is time from sending. (not used at the moment)
346         */
347         core::map<v3s16, float> m_blocks_sending;
348
349         /*
350                 Count of excess GotBlocks().
351                 There is an excess amount because the client sometimes
352                 gets a block so late that the server sends it again,
353                 and the client then sends two GOTBLOCKs.
354                 This is resetted by PrintInfo()
355         */
356         u32 m_excess_gotblocks;
357         
358         // CPU usage optimization
359         u32 m_nothing_to_send_counter;
360         float m_nothing_to_send_pause_timer;
361 };
362
363 class Server : public con::PeerHandler, public MapEventReceiver,
364                 public InventoryManager
365 {
366 public:
367         /*
368                 NOTE: Every public method should be thread-safe
369         */
370
371         Server(
372                 std::string mapsavedir,
373                 std::string configpath
374         );
375         ~Server();
376         void start(unsigned short port);
377         void stop();
378         // This is mainly a way to pass the time to the server.
379         // Actual processing is done in an another thread.
380         void step(float dtime);
381         // This is run by ServerThread and does the actual processing
382         void AsyncRunStep();
383         void Receive();
384         void ProcessData(u8 *data, u32 datasize, u16 peer_id);
385
386         core::list<PlayerInfo> getPlayerInfo();
387
388         /*u32 getDayNightRatio()
389         {
390                 return time_to_daynight_ratio(m_time_of_day.get());
391         }*/
392         
393         // Environment must be locked when called
394         void setTimeOfDay(u32 time)
395         {
396                 m_env->setTimeOfDay(time);
397                 m_time_of_day_send_timer = 0;
398         }
399
400         bool getShutdownRequested()
401         {
402                 return m_shutdown_requested;
403         }
404         
405         /*
406                 Shall be called with the environment locked.
407                 This is accessed by the map, which is inside the environment,
408                 so it shouldn't be a problem.
409         */
410         void onMapEditEvent(MapEditEvent *event);
411
412         /*
413                 Shall be called with the environment and the connection locked.
414         */
415         Inventory* getInventory(InventoryContext *c, std::string id);
416         void inventoryModified(InventoryContext *c, std::string id);
417
418         // Connection must be locked when called
419         std::wstring getStatusString();
420
421         void requestShutdown(void)
422         {
423                 m_shutdown_requested = true;
424         }
425
426
427         // Envlock and conlock should be locked when calling this
428         void SendMovePlayer(Player *player);
429         
430         u64 getPlayerAuthPrivs(const std::string &name)
431         {
432                 try{
433                         return m_authmanager.getPrivs(name);
434                 }
435                 catch(AuthNotFoundException &e)
436                 {
437                         dstream<<"WARNING: Auth not found for "<<name<<std::endl;
438                         return 0;
439                 }
440         }
441
442         void setPlayerAuthPrivs(const std::string &name, u64 privs)
443         {
444                 try{
445                         return m_authmanager.setPrivs(name, privs);
446                 }
447                 catch(AuthNotFoundException &e)
448                 {
449                         dstream<<"WARNING: Auth not found for "<<name<<std::endl;
450                 }
451         }
452         
453         // Saves g_settings to configpath given at initialization
454         void saveConfig();
455
456         void setIpBanned(const std::string &ip, const std::string &name)
457         {
458                 m_banmanager.add(ip, name);
459                 return;
460         }
461
462         void unsetIpBanned(const std::string &ip_or_name)
463         {
464                 m_banmanager.remove(ip_or_name);
465                 return;
466         }
467
468         std::string getBanDescription(const std::string &ip_or_name)
469         {
470                 return m_banmanager.getBanDescription(ip_or_name);
471         }
472
473         Address getPeerAddress(u16 peer_id)
474         {
475                 return m_con.GetPeerAddress(peer_id);
476         }
477         
478         // Envlock and conlock should be locked when calling this
479         void notifyPlayer(const char *name, const std::wstring msg);
480         void notifyPlayers(const std::wstring msg);
481         
482         // Envlock and conlock should be locked when using Lua
483         lua_State *getLua(){ return m_lua; }
484
485 private:
486
487         // con::PeerHandler implementation.
488         // These queue stuff to be processed by handlePeerChanges().
489         // As of now, these create and remove clients and players.
490         void peerAdded(con::Peer *peer);
491         void deletingPeer(con::Peer *peer, bool timeout);
492         
493         /*
494                 Static send methods
495         */
496         
497         static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
498         static void SendAccessDenied(con::Connection &con, u16 peer_id,
499                         const std::wstring &reason);
500         static void SendDeathscreen(con::Connection &con, u16 peer_id,
501                         bool set_camera_point_target, v3f camera_point_target);
502         
503         /*
504                 Non-static send methods
505         */
506
507         // Envlock and conlock should be locked when calling these
508         void SendObjectData(float dtime);
509         void SendPlayerInfos();
510         void SendInventory(u16 peer_id);
511         // send wielded item info about player to all
512         void SendWieldedItem(const Player *player);
513         // send wielded item info about all players to all players
514         void SendPlayerItems();
515         void SendChatMessage(u16 peer_id, const std::wstring &message);
516         void BroadcastChatMessage(const std::wstring &message);
517         void SendPlayerHP(Player *player);
518         /*
519                 Send a node removal/addition event to all clients except ignore_id.
520                 Additionally, if far_players!=NULL, players further away than
521                 far_d_nodes are ignored and their peer_ids are added to far_players
522         */
523         // Envlock and conlock should be locked when calling these
524         void sendRemoveNode(v3s16 p, u16 ignore_id=0,
525                         core::list<u16> *far_players=NULL, float far_d_nodes=100);
526         void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
527                         core::list<u16> *far_players=NULL, float far_d_nodes=100);
528         void setBlockNotSent(v3s16 p);
529         
530         // Environment and Connection must be locked when called
531         void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
532         
533         // Sends blocks to clients (locks env and con on its own)
534         void SendBlocks(float dtime);
535
536         /*
537                 Something random
538         */
539         
540         void HandlePlayerHP(Player *player, s16 damage);
541         void RespawnPlayer(Player *player);
542         
543         void UpdateCrafting(u16 peer_id);
544         
545         // When called, connection mutex should be locked
546         RemoteClient* getClient(u16 peer_id);
547         
548         // When called, environment mutex should be locked
549         std::string getPlayerName(u16 peer_id)
550         {
551                 Player *player = m_env->getPlayer(peer_id);
552                 if(player == NULL)
553                         return "[id="+itos(peer_id);
554                 return player->getName();
555         }
556
557         /*
558                 Get a player from memory or creates one.
559                 If player is already connected, return NULL
560                 The password is not checked here - it is only used to
561                 set the password if a new player is created.
562
563                 Call with env and con locked.
564         */
565         Player *emergePlayer(const char *name, const char *password, u16 peer_id);
566         
567         // Locks environment and connection by its own
568         struct PeerChange;
569         void handlePeerChange(PeerChange &c);
570         void handlePeerChanges();
571
572         u64 getPlayerPrivs(Player *player);
573
574         /*
575                 Variables
576         */
577         
578         // Some timers
579         float m_liquid_transform_timer;
580         float m_print_info_timer;
581         float m_objectdata_timer;
582         float m_emergethread_trigger_timer;
583         float m_savemap_timer;
584         IntervalLimiter m_map_timer_and_unload_interval;
585         
586         // NOTE: If connection and environment are both to be locked,
587         // environment shall be locked first.
588
589         // Environment
590         ServerEnvironment *m_env;
591         JMutex m_env_mutex;
592         
593         // Connection
594         con::Connection m_con;
595         JMutex m_con_mutex;
596         // Connected clients (behind the con mutex)
597         core::map<u16, RemoteClient*> m_clients;
598
599         // User authentication
600         AuthManager m_authmanager;
601
602         // Bann checking
603         BanManager m_banmanager;
604
605         // Scripting
606         // Envlock and conlock should be locked when using Lua
607         lua_State *m_lua;
608         
609         /*
610                 Threads
611         */
612         
613         // A buffer for time steps
614         // step() increments and AsyncRunStep() run by m_thread reads it.
615         float m_step_dtime;
616         JMutex m_step_dtime_mutex;
617
618         // The server mainly operates in this thread
619         ServerThread m_thread;
620         // This thread fetches and generates map
621         EmergeThread m_emergethread;
622         // Queue of block coordinates to be processed by the emerge thread
623         BlockEmergeQueue m_emerge_queue;
624         
625         /*
626                 Time related stuff
627         */
628
629         // 0-23999
630         //MutexedVariable<u32> m_time_of_day;
631         // Used to buffer dtime for adding to m_time_of_day
632         float m_time_counter;
633         // Timer for sending time of day over network
634         float m_time_of_day_send_timer;
635         // Uptime of server in seconds
636         MutexedVariable<double> m_uptime;
637         
638         /*
639                 Peer change queue.
640                 Queues stuff from peerAdded() and deletingPeer() to
641                 handlePeerChanges()
642         */
643         enum PeerChangeType
644         {
645                 PEER_ADDED,
646                 PEER_REMOVED
647         };
648         struct PeerChange
649         {
650                 PeerChangeType type;
651                 u16 peer_id;
652                 bool timeout;
653         };
654         Queue<PeerChange> m_peer_change_queue;
655
656         /*
657                 Random stuff
658         */
659
660         // Map directory
661         std::string m_mapsavedir;
662
663         // Configuration path ("" = no configuration file)
664         std::string m_configpath;
665
666         bool m_shutdown_requested;
667         
668         /*
669                 Map edit event queue. Automatically receives all map edits.
670                 The constructor of this class registers us to receive them through
671                 onMapEditEvent
672
673                 NOTE: Should these be moved to actually be members of
674                 ServerEnvironment?
675         */
676
677         /*
678                 Queue of map edits from the environment for sending to the clients
679                 This is behind m_env_mutex
680         */
681         Queue<MapEditEvent*> m_unsent_map_edit_queue;
682         /*
683                 Set to true when the server itself is modifying the map and does
684                 all sending of information by itself.
685                 This is behind m_env_mutex
686         */
687         bool m_ignore_map_edit_events;
688         /*
689                 If set to !=0, the incoming MapEditEvents are modified to have
690                 this peed id as the disabled recipient
691                 This is behind m_env_mutex
692         */
693         u16 m_ignore_map_edit_events_peer_id;
694
695         Profiler *m_profiler;
696
697         friend class EmergeThread;
698         friend class RemoteClient;
699 };
700
701 /*
702         Runs a simple dedicated server loop.
703
704         Shuts down when run is set to false.
705 */
706 void dedicated_server_loop(Server &server, bool &run);
707
708 #endif
709