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