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