]> git.lizzy.rs Git - minetest.git/blob - src/server.h
Random Lua tweaks/fixes
[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 {
371 public:
372         /*
373                 NOTE: Every public method should be thread-safe
374         */
375
376         Server(
377                 std::string mapsavedir,
378                 std::string configpath
379         );
380         ~Server();
381         void start(unsigned short port);
382         void stop();
383         // This is mainly a way to pass the time to the server.
384         // Actual processing is done in an another thread.
385         void step(float dtime);
386         // This is run by ServerThread and does the actual processing
387         void AsyncRunStep();
388         void Receive();
389         void ProcessData(u8 *data, u32 datasize, u16 peer_id);
390
391         core::list<PlayerInfo> getPlayerInfo();
392
393         /*u32 getDayNightRatio()
394         {
395                 return time_to_daynight_ratio(m_time_of_day.get());
396         }*/
397         
398         // Environment must be locked when called
399         void setTimeOfDay(u32 time)
400         {
401                 m_env->setTimeOfDay(time);
402                 m_time_of_day_send_timer = 0;
403         }
404
405         bool getShutdownRequested()
406         {
407                 return m_shutdown_requested;
408         }
409         
410         /*
411                 Shall be called with the environment locked.
412                 This is accessed by the map, which is inside the environment,
413                 so it shouldn't be a problem.
414         */
415         void onMapEditEvent(MapEditEvent *event);
416
417         /*
418                 Shall be called with the environment and the connection locked.
419         */
420         Inventory* getInventory(InventoryContext *c, std::string id);
421         void inventoryModified(InventoryContext *c, std::string id);
422
423         // Connection must be locked when called
424         std::wstring getStatusString();
425
426         void requestShutdown(void)
427         {
428                 m_shutdown_requested = true;
429         }
430
431
432         // Envlock and conlock should be locked when calling this
433         void SendMovePlayer(Player *player);
434         
435         u64 getPlayerAuthPrivs(const std::string &name)
436         {
437                 try{
438                         return m_authmanager.getPrivs(name);
439                 }
440                 catch(AuthNotFoundException &e)
441                 {
442                         dstream<<"WARNING: Auth not found for "<<name<<std::endl;
443                         return 0;
444                 }
445         }
446
447         void setPlayerAuthPrivs(const std::string &name, u64 privs)
448         {
449                 try{
450                         return m_authmanager.setPrivs(name, privs);
451                 }
452                 catch(AuthNotFoundException &e)
453                 {
454                         dstream<<"WARNING: Auth not found for "<<name<<std::endl;
455                 }
456         }
457         
458         // Saves g_settings to configpath given at initialization
459         void saveConfig();
460
461         void setIpBanned(const std::string &ip, const std::string &name)
462         {
463                 m_banmanager.add(ip, name);
464                 return;
465         }
466
467         void unsetIpBanned(const std::string &ip_or_name)
468         {
469                 m_banmanager.remove(ip_or_name);
470                 return;
471         }
472
473         std::string getBanDescription(const std::string &ip_or_name)
474         {
475                 return m_banmanager.getBanDescription(ip_or_name);
476         }
477
478         Address getPeerAddress(u16 peer_id)
479         {
480                 return m_con.GetPeerAddress(peer_id);
481         }
482         
483         // Envlock and conlock should be locked when calling this
484         void notifyPlayer(const char *name, const std::wstring msg);
485         void notifyPlayers(const std::wstring msg);
486         
487         // Envlock and conlock should be locked when using Lua
488         lua_State *getLua(){ return m_lua; }
489         
490         // IGameDef interface
491         // Under envlock
492         virtual IToolDefManager* getToolDefManager();
493         virtual INodeDefManager* getNodeDefManager();
494         virtual ICraftDefManager* getCraftDefManager();
495         virtual ITextureSource* getTextureSource();
496         virtual u16 allocateUnknownNodeId(const std::string &name);
497         
498         IWritableToolDefManager* getWritableToolDefManager();
499         IWritableNodeDefManager* getWritableNodeDefManager();
500         IWritableCraftDefManager* getWritableCraftDefManager();
501
502 private:
503
504         // con::PeerHandler implementation.
505         // These queue stuff to be processed by handlePeerChanges().
506         // As of now, these create and remove clients and players.
507         void peerAdded(con::Peer *peer);
508         void deletingPeer(con::Peer *peer, bool timeout);
509         
510         /*
511                 Static send methods
512         */
513         
514         static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
515         static void SendAccessDenied(con::Connection &con, u16 peer_id,
516                         const std::wstring &reason);
517         static void SendDeathscreen(con::Connection &con, u16 peer_id,
518                         bool set_camera_point_target, v3f camera_point_target);
519         static void SendToolDef(con::Connection &con, u16 peer_id,
520                         IToolDefManager *tooldef);
521         static void SendNodeDef(con::Connection &con, u16 peer_id,
522                         INodeDefManager *nodedef);
523         
524         /*
525                 Non-static send methods.
526                 Conlock should be always used.
527                 Envlock usage is documented badly but it's easy to figure out
528                 which ones access the environment.
529         */
530
531         // Envlock and conlock should be locked when calling these
532         void SendObjectData(float dtime);
533         void SendPlayerInfos();
534         void SendInventory(u16 peer_id);
535         // send wielded item info about player to all
536         void SendWieldedItem(const Player *player);
537         // send wielded item info about all players to all players
538         void SendPlayerItems();
539         void SendChatMessage(u16 peer_id, const std::wstring &message);
540         void BroadcastChatMessage(const std::wstring &message);
541         void SendPlayerHP(Player *player);
542         /*
543                 Send a node removal/addition event to all clients except ignore_id.
544                 Additionally, if far_players!=NULL, players further away than
545                 far_d_nodes are ignored and their peer_ids are added to far_players
546         */
547         // Envlock and conlock should be locked when calling these
548         void sendRemoveNode(v3s16 p, u16 ignore_id=0,
549                         core::list<u16> *far_players=NULL, float far_d_nodes=100);
550         void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
551                         core::list<u16> *far_players=NULL, float far_d_nodes=100);
552         void setBlockNotSent(v3s16 p);
553         
554         // Environment and Connection must be locked when called
555         void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
556         
557         // Sends blocks to clients (locks env and con on its own)
558         void SendBlocks(float dtime);
559         
560         void SendTextures(u16 peer_id);
561
562         /*
563                 Something random
564         */
565         
566         void HandlePlayerHP(Player *player, s16 damage);
567         void RespawnPlayer(Player *player);
568         
569         void UpdateCrafting(u16 peer_id);
570         
571         // When called, connection mutex should be locked
572         RemoteClient* getClient(u16 peer_id);
573         
574         // When called, environment mutex should be locked
575         std::string getPlayerName(u16 peer_id)
576         {
577                 Player *player = m_env->getPlayer(peer_id);
578                 if(player == NULL)
579                         return "[id="+itos(peer_id);
580                 return player->getName();
581         }
582
583         /*
584                 Get a player from memory or creates one.
585                 If player is already connected, return NULL
586                 The password is not checked here - it is only used to
587                 set the password if a new player is created.
588
589                 Call with env and con locked.
590         */
591         Player *emergePlayer(const char *name, const char *password, u16 peer_id);
592         
593         // Locks environment and connection by its own
594         struct PeerChange;
595         void handlePeerChange(PeerChange &c);
596         void handlePeerChanges();
597
598         u64 getPlayerPrivs(Player *player);
599
600         /*
601                 Variables
602         */
603         
604         // Some timers
605         float m_liquid_transform_timer;
606         float m_print_info_timer;
607         float m_objectdata_timer;
608         float m_emergethread_trigger_timer;
609         float m_savemap_timer;
610         IntervalLimiter m_map_timer_and_unload_interval;
611         
612         // NOTE: If connection and environment are both to be locked,
613         // environment shall be locked first.
614
615         // Environment
616         ServerEnvironment *m_env;
617         JMutex m_env_mutex;
618         
619         // Connection
620         con::Connection m_con;
621         JMutex m_con_mutex;
622         // Connected clients (behind the con mutex)
623         core::map<u16, RemoteClient*> m_clients;
624
625         // User authentication
626         AuthManager m_authmanager;
627
628         // Bann checking
629         BanManager m_banmanager;
630
631         // Scripting
632         // Envlock and conlock should be locked when using Lua
633         lua_State *m_lua;
634
635         // Tool definition manager
636         IWritableToolDefManager *m_toolmgr;
637         
638         // Node definition manager
639         IWritableNodeDefManager *m_nodedef;
640         
641         // Craft definition manager
642         IWritableCraftDefManager *m_craftdef;
643         
644         /*
645                 Threads
646         */
647         
648         // A buffer for time steps
649         // step() increments and AsyncRunStep() run by m_thread reads it.
650         float m_step_dtime;
651         JMutex m_step_dtime_mutex;
652
653         // The server mainly operates in this thread
654         ServerThread m_thread;
655         // This thread fetches and generates map
656         EmergeThread m_emergethread;
657         // Queue of block coordinates to be processed by the emerge thread
658         BlockEmergeQueue m_emerge_queue;
659         
660         /*
661                 Time related stuff
662         */
663
664         // 0-23999
665         //MutexedVariable<u32> m_time_of_day;
666         // Used to buffer dtime for adding to m_time_of_day
667         float m_time_counter;
668         // Timer for sending time of day over network
669         float m_time_of_day_send_timer;
670         // Uptime of server in seconds
671         MutexedVariable<double> m_uptime;
672         
673         /*
674                 Peer change queue.
675                 Queues stuff from peerAdded() and deletingPeer() to
676                 handlePeerChanges()
677         */
678         enum PeerChangeType
679         {
680                 PEER_ADDED,
681                 PEER_REMOVED
682         };
683         struct PeerChange
684         {
685                 PeerChangeType type;
686                 u16 peer_id;
687                 bool timeout;
688         };
689         Queue<PeerChange> m_peer_change_queue;
690
691         /*
692                 Random stuff
693         */
694
695         // Map directory
696         std::string m_mapsavedir;
697
698         // Configuration path ("" = no configuration file)
699         std::string m_configpath;
700         
701         // Mod parent directory paths
702         core::list<std::string> m_modspaths;
703
704         bool m_shutdown_requested;
705         
706         /*
707                 Map edit event queue. Automatically receives all map edits.
708                 The constructor of this class registers us to receive them through
709                 onMapEditEvent
710
711                 NOTE: Should these be moved to actually be members of
712                 ServerEnvironment?
713         */
714
715         /*
716                 Queue of map edits from the environment for sending to the clients
717                 This is behind m_env_mutex
718         */
719         Queue<MapEditEvent*> m_unsent_map_edit_queue;
720         /*
721                 Set to true when the server itself is modifying the map and does
722                 all sending of information by itself.
723                 This is behind m_env_mutex
724         */
725         bool m_ignore_map_edit_events;
726         /*
727                 If set to !=0, the incoming MapEditEvents are modified to have
728                 this peed id as the disabled recipient
729                 This is behind m_env_mutex
730         */
731         u16 m_ignore_map_edit_events_peer_id;
732
733         friend class EmergeThread;
734         friend class RemoteClient;
735 };
736
737 /*
738         Runs a simple dedicated server loop.
739
740         Shuts down when run is set to false.
741 */
742 void dedicated_server_loop(Server &server, bool &run);
743
744 #endif
745