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