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