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