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