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