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