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