]> git.lizzy.rs Git - dragonfireclient.git/blob - src/server.h
celeron55's sound system initial framework
[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         virtual ISoundManager* getSoundManager();
517         
518         IWritableItemDefManager* getWritableItemDefManager();
519         IWritableNodeDefManager* getWritableNodeDefManager();
520         IWritableCraftDefManager* getWritableCraftDefManager();
521
522         const ModSpec* getModSpec(const std::string &modname);
523         
524         std::string getWorldPath(){ return m_path_world; }
525
526         void setAsyncFatalError(const std::string &error)
527         {
528                 m_async_fatal_error.set(error);
529         }
530
531 private:
532
533         // con::PeerHandler implementation.
534         // These queue stuff to be processed by handlePeerChanges().
535         // As of now, these create and remove clients and players.
536         void peerAdded(con::Peer *peer);
537         void deletingPeer(con::Peer *peer, bool timeout);
538         
539         /*
540                 Static send methods
541         */
542         
543         static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
544         static void SendAccessDenied(con::Connection &con, u16 peer_id,
545                         const std::wstring &reason);
546         static void SendDeathscreen(con::Connection &con, u16 peer_id,
547                         bool set_camera_point_target, v3f camera_point_target);
548         static void SendItemDef(con::Connection &con, u16 peer_id,
549                         IItemDefManager *itemdef);
550         static void SendNodeDef(con::Connection &con, u16 peer_id,
551                         INodeDefManager *nodedef);
552         
553         /*
554                 Non-static send methods.
555                 Conlock should be always used.
556                 Envlock usage is documented badly but it's easy to figure out
557                 which ones access the environment.
558         */
559
560         // Envlock and conlock should be locked when calling these
561         void SendInventory(u16 peer_id);
562         // send wielded item info about player to all
563         void SendWieldedItem(const ServerRemotePlayer *srp);
564         // send wielded item info about all players to all players
565         void SendPlayerItems();
566         void SendChatMessage(u16 peer_id, const std::wstring &message);
567         void BroadcastChatMessage(const std::wstring &message);
568         void SendPlayerHP(Player *player);
569         /*
570                 Send a node removal/addition event to all clients except ignore_id.
571                 Additionally, if far_players!=NULL, players further away than
572                 far_d_nodes are ignored and their peer_ids are added to far_players
573         */
574         // Envlock and conlock should be locked when calling these
575         void sendRemoveNode(v3s16 p, u16 ignore_id=0,
576                         core::list<u16> *far_players=NULL, float far_d_nodes=100);
577         void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
578                         core::list<u16> *far_players=NULL, float far_d_nodes=100);
579         void setBlockNotSent(v3s16 p);
580         
581         // Environment and Connection must be locked when called
582         void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
583         
584         // Sends blocks to clients (locks env and con on its own)
585         void SendBlocks(float dtime);
586         
587         void PrepareTextures();
588
589         void SendTextureAnnouncement(u16 peer_id);
590
591         void SendTexturesRequested(u16 peer_id,core::list<TextureRequest> tosend);
592
593         /*
594                 Something random
595         */
596         
597         void DiePlayer(Player *player);
598         void RespawnPlayer(Player *player);
599         
600         void UpdateCrafting(u16 peer_id);
601         
602         // When called, connection mutex should be locked
603         RemoteClient* getClient(u16 peer_id);
604         
605         // When called, environment mutex should be locked
606         std::string getPlayerName(u16 peer_id)
607         {
608                 Player *player = m_env->getPlayer(peer_id);
609                 if(player == NULL)
610                         return "[id="+itos(peer_id)+"]";
611                 return player->getName();
612         }
613
614         /*
615                 Get a player from memory or creates one.
616                 If player is already connected, return NULL
617                 Does not verify/modify auth info and password.
618
619                 Call with env and con locked.
620         */
621         ServerRemotePlayer *emergePlayer(const char *name, u16 peer_id);
622         
623         // Locks environment and connection by its own
624         struct PeerChange;
625         void handlePeerChange(PeerChange &c);
626         void handlePeerChanges();
627
628         u64 getPlayerPrivs(Player *player);
629
630         /*
631                 Variables
632         */
633         
634         // World directory
635         std::string m_path_world;
636         // Path to user's configuration file ("" = no configuration file)
637         std::string m_path_config;
638         // Subgame specification
639         SubgameSpec m_gamespec;
640         // If true, do not allow multiple players and hide some multiplayer
641         // functionality
642         bool m_simple_singleplayer_mode;
643
644         // Thread can set; step() will throw as ServerError
645         MutexedVariable<std::string> m_async_fatal_error;
646         
647         // Some timers
648         float m_liquid_transform_timer;
649         float m_print_info_timer;
650         float m_objectdata_timer;
651         float m_emergethread_trigger_timer;
652         float m_savemap_timer;
653         IntervalLimiter m_map_timer_and_unload_interval;
654         
655         // NOTE: If connection and environment are both to be locked,
656         // environment shall be locked first.
657
658         // Environment
659         ServerEnvironment *m_env;
660         JMutex m_env_mutex;
661         
662         // Connection
663         con::Connection m_con;
664         JMutex m_con_mutex;
665         // Connected clients (behind the con mutex)
666         core::map<u16, RemoteClient*> m_clients;
667
668         // User authentication
669         AuthManager m_authmanager;
670
671         // Bann checking
672         BanManager m_banmanager;
673
674         // Scripting
675         // Envlock and conlock should be locked when using Lua
676         lua_State *m_lua;
677
678         // Item definition manager
679         IWritableItemDefManager *m_itemdef;
680         
681         // Node definition manager
682         IWritableNodeDefManager *m_nodedef;
683         
684         // Craft definition manager
685         IWritableCraftDefManager *m_craftdef;
686         
687         // Mods
688         core::list<ModSpec> m_mods;
689         
690         /*
691                 Threads
692         */
693         
694         // A buffer for time steps
695         // step() increments and AsyncRunStep() run by m_thread reads it.
696         float m_step_dtime;
697         JMutex m_step_dtime_mutex;
698
699         // The server mainly operates in this thread
700         ServerThread m_thread;
701         // This thread fetches and generates map
702         EmergeThread m_emergethread;
703         // Queue of block coordinates to be processed by the emerge thread
704         BlockEmergeQueue m_emerge_queue;
705         
706         /*
707                 Time related stuff
708         */
709
710         // Timer for sending time of day over network
711         float m_time_of_day_send_timer;
712         // Uptime of server in seconds
713         MutexedVariable<double> m_uptime;
714         
715         /*
716                 Peer change queue.
717                 Queues stuff from peerAdded() and deletingPeer() to
718                 handlePeerChanges()
719         */
720         enum PeerChangeType
721         {
722                 PEER_ADDED,
723                 PEER_REMOVED
724         };
725         struct PeerChange
726         {
727                 PeerChangeType type;
728                 u16 peer_id;
729                 bool timeout;
730         };
731         Queue<PeerChange> m_peer_change_queue;
732
733         /*
734                 Random stuff
735         */
736         
737         // Mod parent directory paths
738         core::list<std::string> m_modspaths;
739
740         bool m_shutdown_requested;
741
742         /*
743                 Map edit event queue. Automatically receives all map edits.
744                 The constructor of this class registers us to receive them through
745                 onMapEditEvent
746
747                 NOTE: Should these be moved to actually be members of
748                 ServerEnvironment?
749         */
750
751         /*
752                 Queue of map edits from the environment for sending to the clients
753                 This is behind m_env_mutex
754         */
755         Queue<MapEditEvent*> m_unsent_map_edit_queue;
756         /*
757                 Set to true when the server itself is modifying the map and does
758                 all sending of information by itself.
759                 This is behind m_env_mutex
760         */
761         bool m_ignore_map_edit_events;
762         /*
763                 If set to !=0, the incoming MapEditEvents are modified to have
764                 this peed id as the disabled recipient
765                 This is behind m_env_mutex
766         */
767         u16 m_ignore_map_edit_events_peer_id;
768
769         friend class EmergeThread;
770         friend class RemoteClient;
771
772         std::map<std::string,TextureInformation> m_Textures;
773 };
774
775 /*
776         Runs a simple dedicated server loop.
777
778         Shuts down when run is set to false.
779 */
780 void dedicated_server_loop(Server &server, bool &run);
781
782 #endif
783