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