]> git.lizzy.rs Git - dragonfireclient.git/blob - src/server.h
Disable word wrap in vertical texts in main menu
[dragonfireclient.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         // Environment must be locked when called
430         void setTimeOfDay(u32 time)
431         {
432                 m_env->setTimeOfDay(time);
433                 m_time_of_day_send_timer = 0;
434         }
435
436         bool getShutdownRequested()
437         {
438                 return m_shutdown_requested;
439         }
440         
441         /*
442                 Shall be called with the environment locked.
443                 This is accessed by the map, which is inside the environment,
444                 so it shouldn't be a problem.
445         */
446         void onMapEditEvent(MapEditEvent *event);
447
448         /*
449                 Shall be called with the environment and the connection locked.
450         */
451         Inventory* getInventory(const InventoryLocation &loc);
452         std::string getInventoryOwner(const InventoryLocation &loc);
453         void setInventoryModified(const InventoryLocation &loc);
454
455         // Connection must be locked when called
456         std::wstring getStatusString();
457
458         void requestShutdown(void)
459         {
460                 m_shutdown_requested = true;
461         }
462
463         // Envlock and conlock should be locked when calling this
464         void SendMovePlayer(Player *player);
465         
466         // Thread-safe
467         u64 getPlayerAuthPrivs(const std::string &name);
468         void setPlayerAuthPrivs(const std::string &name, u64 privs);
469         u64 getPlayerEffectivePrivs(const std::string &name);
470
471         // Changes a player's password, password must be given as plaintext
472         // If the player doesn't exist, a new entry is added to the auth manager
473         void setPlayerPassword(const std::string &name, const std::wstring &password);
474         
475         // Saves g_settings to configpath given at initialization
476         void saveConfig();
477
478         void setIpBanned(const std::string &ip, const std::string &name)
479         {
480                 m_banmanager.add(ip, name);
481                 return;
482         }
483
484         void unsetIpBanned(const std::string &ip_or_name)
485         {
486                 m_banmanager.remove(ip_or_name);
487                 return;
488         }
489
490         std::string getBanDescription(const std::string &ip_or_name)
491         {
492                 return m_banmanager.getBanDescription(ip_or_name);
493         }
494
495         Address getPeerAddress(u16 peer_id)
496         {
497                 return m_con.GetPeerAddress(peer_id);
498         }
499         
500         // Envlock and conlock should be locked when calling this
501         void notifyPlayer(const char *name, const std::wstring msg);
502         void notifyPlayers(const std::wstring msg);
503
504         void queueBlockEmerge(v3s16 blockpos, bool allow_generate);
505         
506         // Envlock and conlock should be locked when using Lua
507         lua_State *getLua(){ return m_lua; }
508         
509         // IGameDef interface
510         // Under envlock
511         virtual IItemDefManager* getItemDefManager();
512         virtual INodeDefManager* getNodeDefManager();
513         virtual ICraftDefManager* getCraftDefManager();
514         virtual ITextureSource* getTextureSource();
515         virtual u16 allocateUnknownNodeId(const std::string &name);
516         
517         IWritableItemDefManager* getWritableItemDefManager();
518         IWritableNodeDefManager* getWritableNodeDefManager();
519         IWritableCraftDefManager* getWritableCraftDefManager();
520
521         const ModSpec* getModSpec(const std::string &modname);
522         
523         std::string getWorldPath(){ return m_path_world; }
524
525         void setAsyncFatalError(const std::string &error)
526         {
527                 m_async_fatal_error.set(error);
528         }
529
530 private:
531
532         // con::PeerHandler implementation.
533         // These queue stuff to be processed by handlePeerChanges().
534         // As of now, these create and remove clients and players.
535         void peerAdded(con::Peer *peer);
536         void deletingPeer(con::Peer *peer, bool timeout);
537         
538         /*
539                 Static send methods
540         */
541         
542         static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
543         static void SendAccessDenied(con::Connection &con, u16 peer_id,
544                         const std::wstring &reason);
545         static void SendDeathscreen(con::Connection &con, u16 peer_id,
546                         bool set_camera_point_target, v3f camera_point_target);
547         static void SendItemDef(con::Connection &con, u16 peer_id,
548                         IItemDefManager *itemdef);
549         static void SendNodeDef(con::Connection &con, u16 peer_id,
550                         INodeDefManager *nodedef);
551         
552         /*
553                 Non-static send methods.
554                 Conlock should be always used.
555                 Envlock usage is documented badly but it's easy to figure out
556                 which ones access the environment.
557         */
558
559         // Envlock and conlock should be locked when calling these
560         void SendInventory(u16 peer_id);
561         // send wielded item info about player to all
562         void SendWieldedItem(const ServerRemotePlayer *srp);
563         // send wielded item info about all players to all players
564         void SendPlayerItems();
565         void SendChatMessage(u16 peer_id, const std::wstring &message);
566         void BroadcastChatMessage(const std::wstring &message);
567         void SendPlayerHP(Player *player);
568         /*
569                 Send a node removal/addition event to all clients except ignore_id.
570                 Additionally, if far_players!=NULL, players further away than
571                 far_d_nodes are ignored and their peer_ids are added to far_players
572         */
573         // Envlock and conlock should be locked when calling these
574         void sendRemoveNode(v3s16 p, u16 ignore_id=0,
575                         core::list<u16> *far_players=NULL, float far_d_nodes=100);
576         void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
577                         core::list<u16> *far_players=NULL, float far_d_nodes=100);
578         void setBlockNotSent(v3s16 p);
579         
580         // Environment and Connection must be locked when called
581         void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
582         
583         // Sends blocks to clients (locks env and con on its own)
584         void SendBlocks(float dtime);
585         
586         void PrepareTextures();
587
588         void SendTextureAnnouncement(u16 peer_id);
589
590         void SendTexturesRequested(u16 peer_id,core::list<TextureRequest> tosend);
591
592         /*
593                 Something random
594         */
595         
596         void DiePlayer(Player *player);
597         void RespawnPlayer(Player *player);
598         
599         void UpdateCrafting(u16 peer_id);
600         
601         // When called, connection mutex should be locked
602         RemoteClient* getClient(u16 peer_id);
603         
604         // When called, environment mutex should be locked
605         std::string getPlayerName(u16 peer_id)
606         {
607                 Player *player = m_env->getPlayer(peer_id);
608                 if(player == NULL)
609                         return "[id="+itos(peer_id)+"]";
610                 return player->getName();
611         }
612
613         /*
614                 Get a player from memory or creates one.
615                 If player is already connected, return NULL
616                 Does not verify/modify auth info and password.
617
618                 Call with env and con locked.
619         */
620         ServerRemotePlayer *emergePlayer(const char *name, u16 peer_id);
621         
622         // Locks environment and connection by its own
623         struct PeerChange;
624         void handlePeerChange(PeerChange &c);
625         void handlePeerChanges();
626
627         u64 getPlayerPrivs(Player *player);
628
629         /*
630                 Variables
631         */
632         
633         // World directory
634         std::string m_path_world;
635         // Path to user's configuration file ("" = no configuration file)
636         std::string m_path_config;
637         // Subgame specification
638         SubgameSpec m_gamespec;
639         // If true, do not allow multiple players and hide some multiplayer
640         // functionality
641         bool m_simple_singleplayer_mode;
642
643         // Equivalent of /usr/share/minetest/server
644         std::string m_path_share;
645         
646         // Thread can set; step() will throw as ServerError
647         MutexedVariable<std::string> m_async_fatal_error;
648         
649         // Some timers
650         float m_liquid_transform_timer;
651         float m_print_info_timer;
652         float m_objectdata_timer;
653         float m_emergethread_trigger_timer;
654         float m_savemap_timer;
655         IntervalLimiter m_map_timer_and_unload_interval;
656         
657         // NOTE: If connection and environment are both to be locked,
658         // environment shall be locked first.
659
660         // Environment
661         ServerEnvironment *m_env;
662         JMutex m_env_mutex;
663         
664         // Connection
665         con::Connection m_con;
666         JMutex m_con_mutex;
667         // Connected clients (behind the con mutex)
668         core::map<u16, RemoteClient*> m_clients;
669
670         // User authentication
671         AuthManager m_authmanager;
672
673         // Bann checking
674         BanManager m_banmanager;
675
676         // Scripting
677         // Envlock and conlock should be locked when using Lua
678         lua_State *m_lua;
679
680         // Item definition manager
681         IWritableItemDefManager *m_itemdef;
682         
683         // Node definition manager
684         IWritableNodeDefManager *m_nodedef;
685         
686         // Craft definition manager
687         IWritableCraftDefManager *m_craftdef;
688         
689         // Mods
690         core::list<ModSpec> m_mods;
691         
692         /*
693                 Threads
694         */
695         
696         // A buffer for time steps
697         // step() increments and AsyncRunStep() run by m_thread reads it.
698         float m_step_dtime;
699         JMutex m_step_dtime_mutex;
700
701         // The server mainly operates in this thread
702         ServerThread m_thread;
703         // This thread fetches and generates map
704         EmergeThread m_emergethread;
705         // Queue of block coordinates to be processed by the emerge thread
706         BlockEmergeQueue m_emerge_queue;
707         
708         /*
709                 Time related stuff
710         */
711
712         // Timer for sending time of day over network
713         float m_time_of_day_send_timer;
714         // Uptime of server in seconds
715         MutexedVariable<double> m_uptime;
716         
717         /*
718                 Peer change queue.
719                 Queues stuff from peerAdded() and deletingPeer() to
720                 handlePeerChanges()
721         */
722         enum PeerChangeType
723         {
724                 PEER_ADDED,
725                 PEER_REMOVED
726         };
727         struct PeerChange
728         {
729                 PeerChangeType type;
730                 u16 peer_id;
731                 bool timeout;
732         };
733         Queue<PeerChange> m_peer_change_queue;
734
735         /*
736                 Random stuff
737         */
738         
739         // Mod parent directory paths
740         core::list<std::string> m_modspaths;
741
742         bool m_shutdown_requested;
743
744         /*
745                 Map edit event queue. Automatically receives all map edits.
746                 The constructor of this class registers us to receive them through
747                 onMapEditEvent
748
749                 NOTE: Should these be moved to actually be members of
750                 ServerEnvironment?
751         */
752
753         /*
754                 Queue of map edits from the environment for sending to the clients
755                 This is behind m_env_mutex
756         */
757         Queue<MapEditEvent*> m_unsent_map_edit_queue;
758         /*
759                 Set to true when the server itself is modifying the map and does
760                 all sending of information by itself.
761                 This is behind m_env_mutex
762         */
763         bool m_ignore_map_edit_events;
764         /*
765                 If set to !=0, the incoming MapEditEvents are modified to have
766                 this peed id as the disabled recipient
767                 This is behind m_env_mutex
768         */
769         u16 m_ignore_map_edit_events_peer_id;
770
771         friend class EmergeThread;
772         friend class RemoteClient;
773
774         std::map<std::string,TextureInformation> m_Textures;
775 };
776
777 /*
778         Runs a simple dedicated server loop.
779
780         Shuts down when run is set to false.
781 */
782 void dedicated_server_loop(Server &server, bool &run);
783
784 #endif
785