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