]> git.lizzy.rs Git - dragonfireclient.git/blob - src/server.h
b52ae02dcf19b90ebe6a98ef54e33c314d247f9a
[dragonfireclient.git] / src / server.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 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 Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser 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 "irr_v3d.h"
25 #include "map.h"
26 #include "hud.h"
27 #include "gamedef.h"
28 #include "serialization.h" // For SER_FMT_VER_INVALID
29 #include "mods.h"
30 #include "inventorymanager.h"
31 #include "subgame.h"
32 #include "rollback_interface.h" // Needed for rollbackRevertActions()
33 #include "util/numeric.h"
34 #include "util/thread.h"
35 #include "environment.h"
36 #include <string>
37 #include <list>
38 #include <map>
39 #include <vector>
40
41 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
42
43 class IWritableItemDefManager;
44 class IWritableNodeDefManager;
45 class IWritableCraftDefManager;
46 class BanManager;
47 class EventManager;
48 class Inventory;
49 class Player;
50 class PlayerSAO;
51 class IRollbackManager;
52 class EmergeManager;
53 class GameScripting;
54 class ServerEnvironment;
55 struct SimpleSoundSpec;
56
57
58 class ServerError : public std::exception
59 {
60 public:
61         ServerError(const std::string &s)
62         {
63                 m_s = "ServerError: ";
64                 m_s += s;
65         }
66         virtual ~ServerError() throw()
67         {}
68         virtual const char * what() const throw()
69         {
70                 return m_s.c_str();
71         }
72         std::string m_s;
73 };
74
75 /*
76         Some random functions
77 */
78 v3f findSpawnPos(ServerMap &map);
79
80
81 class MapEditEventIgnorer
82 {
83 public:
84         MapEditEventIgnorer(bool *flag):
85                 m_flag(flag)
86         {
87                 if(*m_flag == false)
88                         *m_flag = true;
89                 else
90                         m_flag = NULL;
91         }
92
93         ~MapEditEventIgnorer()
94         {
95                 if(m_flag)
96                 {
97                         assert(*m_flag);
98                         *m_flag = false;
99                 }
100         }
101
102 private:
103         bool *m_flag;
104 };
105
106 class MapEditEventAreaIgnorer
107 {
108 public:
109         MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a):
110                 m_ignorevariable(ignorevariable)
111         {
112                 if(m_ignorevariable->getVolume() == 0)
113                         *m_ignorevariable = a;
114                 else
115                         m_ignorevariable = NULL;
116         }
117
118         ~MapEditEventAreaIgnorer()
119         {
120                 if(m_ignorevariable)
121                 {
122                         assert(m_ignorevariable->getVolume() != 0);
123                         *m_ignorevariable = VoxelArea();
124                 }
125         }
126
127 private:
128         VoxelArea *m_ignorevariable;
129 };
130
131 class Server;
132 class ServerThread;
133
134 /*
135         Used for queueing and sorting block transfers in containers
136
137         Lower priority number means higher priority.
138 */
139 struct PrioritySortedBlockTransfer
140 {
141         PrioritySortedBlockTransfer(float a_priority, v3s16 a_pos, u16 a_peer_id)
142         {
143                 priority = a_priority;
144                 pos = a_pos;
145                 peer_id = a_peer_id;
146         }
147         bool operator < (const PrioritySortedBlockTransfer &other) const
148         {
149                 return priority < other.priority;
150         }
151         float priority;
152         v3s16 pos;
153         u16 peer_id;
154 };
155
156 struct MediaRequest
157 {
158         std::string name;
159
160         MediaRequest(const std::string &name_=""):
161                 name(name_)
162         {}
163 };
164
165 struct MediaInfo
166 {
167         std::string path;
168         std::string sha1_digest;
169
170         MediaInfo(const std::string path_="",
171                         const std::string sha1_digest_=""):
172                 path(path_),
173                 sha1_digest(sha1_digest_)
174         {
175         }
176 };
177
178 struct ServerSoundParams
179 {
180         float gain;
181         std::string to_player;
182         enum Type{
183                 SSP_LOCAL=0,
184                 SSP_POSITIONAL=1,
185                 SSP_OBJECT=2
186         } type;
187         v3f pos;
188         u16 object;
189         float max_hear_distance;
190         bool loop;
191
192         ServerSoundParams():
193                 gain(1.0),
194                 to_player(""),
195                 type(SSP_LOCAL),
196                 pos(0,0,0),
197                 object(0),
198                 max_hear_distance(32*BS),
199                 loop(false)
200         {}
201
202         v3f getPos(ServerEnvironment *env, bool *pos_exists) const;
203 };
204
205 struct ServerPlayingSound
206 {
207         ServerSoundParams params;
208         std::set<u16> clients; // peer ids
209 };
210
211 class RemoteClient
212 {
213 public:
214         // peer_id=0 means this client has no associated peer
215         // NOTE: If client is made allowed to exist while peer doesn't,
216         //       this has to be set to 0 when there is no peer.
217         //       Also, the client must be moved to some other container.
218         u16 peer_id;
219         // The serialization version to use with the client
220         u8 serialization_version;
221         //
222         u16 net_proto_version;
223         // Version is stored in here after INIT before INIT2
224         u8 pending_serialization_version;
225
226         bool definitions_sent;
227
228         bool denied;
229
230         RemoteClient():
231                 m_time_from_building(9999),
232                 m_excess_gotblocks(0)
233         {
234                 peer_id = 0;
235                 serialization_version = SER_FMT_VER_INVALID;
236                 net_proto_version = 0;
237                 pending_serialization_version = SER_FMT_VER_INVALID;
238                 definitions_sent = false;
239                 denied = false;
240                 m_nearest_unsent_d = 0;
241                 m_nearest_unsent_reset_timer = 0.0;
242                 m_nothing_to_send_counter = 0;
243                 m_nothing_to_send_pause_timer = 0;
244         }
245         ~RemoteClient()
246         {
247         }
248
249         /*
250                 Finds block that should be sent next to the client.
251                 Environment should be locked when this is called.
252                 dtime is used for resetting send radius at slow interval
253         */
254         void GetNextBlocks(Server *server, float dtime,
255                         std::vector<PrioritySortedBlockTransfer> &dest);
256
257         void GotBlock(v3s16 p);
258
259         void SentBlock(v3s16 p);
260
261         void SetBlockNotSent(v3s16 p);
262         void SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks);
263
264         s32 SendingCount()
265         {
266                 return m_blocks_sending.size();
267         }
268
269         // Increments timeouts and removes timed-out blocks from list
270         // NOTE: This doesn't fix the server-not-sending-block bug
271         //       because it is related to emerging, not sending.
272         //void RunSendingTimeouts(float dtime, float timeout);
273
274         void PrintInfo(std::ostream &o)
275         {
276                 o<<"RemoteClient "<<peer_id<<": "
277                                 <<"m_blocks_sent.size()="<<m_blocks_sent.size()
278                                 <<", m_blocks_sending.size()="<<m_blocks_sending.size()
279                                 <<", m_nearest_unsent_d="<<m_nearest_unsent_d
280                                 <<", m_excess_gotblocks="<<m_excess_gotblocks
281                                 <<std::endl;
282                 m_excess_gotblocks = 0;
283         }
284
285         // Time from last placing or removing blocks
286         float m_time_from_building;
287
288         /*JMutex m_dig_mutex;
289         float m_dig_time_remaining;
290         // -1 = not digging
291         s16 m_dig_tool_item;
292         v3s16 m_dig_position;*/
293
294         /*
295                 List of active objects that the client knows of.
296                 Value is dummy.
297         */
298         std::set<u16> m_known_objects;
299
300 private:
301         /*
302                 Blocks that have been sent to client.
303                 - These don't have to be sent again.
304                 - A block is cleared from here when client says it has
305                   deleted it from it's memory
306
307                 Key is position, value is dummy.
308                 No MapBlock* is stored here because the blocks can get deleted.
309         */
310         std::set<v3s16> m_blocks_sent;
311         s16 m_nearest_unsent_d;
312         v3s16 m_last_center;
313         float m_nearest_unsent_reset_timer;
314
315         /*
316                 Blocks that are currently on the line.
317                 This is used for throttling the sending of blocks.
318                 - The size of this list is limited to some value
319                 Block is added when it is sent with BLOCKDATA.
320                 Block is removed when GOTBLOCKS is received.
321                 Value is time from sending. (not used at the moment)
322         */
323         std::map<v3s16, float> m_blocks_sending;
324
325         /*
326                 Count of excess GotBlocks().
327                 There is an excess amount because the client sometimes
328                 gets a block so late that the server sends it again,
329                 and the client then sends two GOTBLOCKs.
330                 This is resetted by PrintInfo()
331         */
332         u32 m_excess_gotblocks;
333
334         // CPU usage optimization
335         u32 m_nothing_to_send_counter;
336         float m_nothing_to_send_pause_timer;
337 };
338
339 class Server : public con::PeerHandler, public MapEventReceiver,
340                 public InventoryManager, public IGameDef
341 {
342 public:
343         /*
344                 NOTE: Every public method should be thread-safe
345         */
346
347         Server(
348                 const std::string &path_world,
349                 const SubgameSpec &gamespec,
350                 bool simple_singleplayer_mode
351         );
352         ~Server();
353         void start(unsigned short port);
354         void stop();
355         // This is mainly a way to pass the time to the server.
356         // Actual processing is done in an another thread.
357         void step(float dtime);
358         // This is run by ServerThread and does the actual processing
359         void AsyncRunStep();
360         void Receive();
361         void ProcessData(u8 *data, u32 datasize, u16 peer_id);
362
363         // Environment must be locked when called
364         void setTimeOfDay(u32 time);
365
366         bool getShutdownRequested()
367         {
368                 return m_shutdown_requested;
369         }
370
371         /*
372                 Shall be called with the environment locked.
373                 This is accessed by the map, which is inside the environment,
374                 so it shouldn't be a problem.
375         */
376         void onMapEditEvent(MapEditEvent *event);
377
378         /*
379                 Shall be called with the environment and the connection locked.
380         */
381         Inventory* getInventory(const InventoryLocation &loc);
382         void setInventoryModified(const InventoryLocation &loc);
383
384         // Connection must be locked when called
385         std::wstring getStatusString();
386
387         void requestShutdown(void)
388         {
389                 m_shutdown_requested = true;
390         }
391
392         // Returns -1 if failed, sound handle on success
393         // Envlock + conlock
394         s32 playSound(const SimpleSoundSpec &spec, const ServerSoundParams &params);
395         void stopSound(s32 handle);
396
397         // Envlock + conlock
398         std::set<std::string> getPlayerEffectivePrivs(const std::string &name);
399         bool checkPriv(const std::string &name, const std::string &priv);
400         void reportPrivsModified(const std::string &name=""); // ""=all
401         void reportInventoryFormspecModified(const std::string &name);
402
403         void setIpBanned(const std::string &ip, const std::string &name);
404         void unsetIpBanned(const std::string &ip_or_name);
405         std::string getBanDescription(const std::string &ip_or_name);
406
407         Address getPeerAddress(u16 peer_id)
408         {
409                 return m_con.GetPeerAddress(peer_id);
410         }
411
412         // Envlock and conlock should be locked when calling this
413         void notifyPlayer(const char *name, const std::wstring msg, const bool prepend);
414         void notifyPlayers(const std::wstring msg);
415         void spawnParticle(const char *playername,
416                 v3f pos, v3f velocity, v3f acceleration,
417                 float expirationtime, float size,
418                 bool collisiondetection, std::string texture);
419
420         void spawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
421                 float expirationtime, float size,
422                 bool collisiondetection, std::string texture);
423
424         u32 addParticleSpawner(const char *playername,
425                 u16 amount, float spawntime,
426                 v3f minpos, v3f maxpos,
427                 v3f minvel, v3f maxvel,
428                 v3f minacc, v3f maxacc,
429                 float minexptime, float maxexptime,
430                 float minsize, float maxsize,
431                 bool collisiondetection, std::string texture);
432
433         u32 addParticleSpawnerAll(u16 amount, float spawntime,
434                 v3f minpos, v3f maxpos,
435                 v3f minvel, v3f maxvel,
436                 v3f minacc, v3f maxacc,
437                 float minexptime, float maxexptime,
438                 float minsize, float maxsize,
439                 bool collisiondetection, std::string texture);
440
441         void deleteParticleSpawner(const char *playername, u32 id);
442         void deleteParticleSpawnerAll(u32 id);
443
444         // Creates or resets inventory
445         Inventory* createDetachedInventory(const std::string &name);
446
447         // Envlock and conlock should be locked when using scriptapi
448         GameScripting *getScriptIface(){ return m_script; }
449
450         // Envlock should be locked when using the rollback manager
451         IRollbackManager *getRollbackManager(){ return m_rollback; }
452
453         //TODO: determine what (if anything) should be locked to access EmergeManager
454         EmergeManager *getEmergeManager(){ return m_emerge; }
455
456         // actions: time-reversed list
457         // Return value: success/failure
458         bool rollbackRevertActions(const std::list<RollbackAction> &actions,
459                         std::list<std::string> *log);
460
461         // IGameDef interface
462         // Under envlock
463         virtual IItemDefManager* getItemDefManager();
464         virtual INodeDefManager* getNodeDefManager();
465         virtual ICraftDefManager* getCraftDefManager();
466         virtual ITextureSource* getTextureSource();
467         virtual IShaderSource* getShaderSource();
468         virtual u16 allocateUnknownNodeId(const std::string &name);
469         virtual ISoundManager* getSoundManager();
470         virtual MtEventManager* getEventManager();
471         virtual IRollbackReportSink* getRollbackReportSink();
472
473         IWritableItemDefManager* getWritableItemDefManager();
474         IWritableNodeDefManager* getWritableNodeDefManager();
475         IWritableCraftDefManager* getWritableCraftDefManager();
476
477         const ModSpec* getModSpec(const std::string &modname);
478         void getModNames(std::list<std::string> &modlist);
479         std::string getBuiltinLuaPath();
480
481         std::string getWorldPath(){ return m_path_world; }
482
483         bool isSingleplayer(){ return m_simple_singleplayer_mode; }
484
485         void setAsyncFatalError(const std::string &error)
486         {
487                 m_async_fatal_error.set(error);
488         }
489
490         bool showFormspec(const char *name, const std::string &formspec, const std::string &formname);
491         Map & getMap() { return m_env->getMap(); }
492         ServerEnvironment & getEnv() { return *m_env; }
493         
494         u32 hudAdd(Player *player, HudElement *element);
495         bool hudRemove(Player *player, u32 id);
496         bool hudChange(Player *player, u32 id, HudElementStat stat, void *value);
497         bool hudSetFlags(Player *player, u32 flags, u32 mask);
498         bool hudSetHotbarItemcount(Player *player, s32 hotbar_itemcount);
499         void hudSetHotbarImage(Player *player, std::string name);
500         void hudSetHotbarSelectedImage(Player *player, std::string name);
501
502 private:
503
504         // con::PeerHandler implementation.
505         // These queue stuff to be processed by handlePeerChanges().
506         // As of now, these create and remove clients and players.
507         void peerAdded(con::Peer *peer);
508         void deletingPeer(con::Peer *peer, bool timeout);
509
510         /*
511                 Static send methods
512         */
513
514         static void SendMovement(con::Connection &con, u16 peer_id);
515         static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
516         static void SendBreath(con::Connection &con, u16 peer_id, u16 breath);
517         static void SendAccessDenied(con::Connection &con, u16 peer_id,
518                         const std::wstring &reason);
519         static void SendDeathscreen(con::Connection &con, u16 peer_id,
520                         bool set_camera_point_target, v3f camera_point_target);
521         static void SendItemDef(con::Connection &con, u16 peer_id,
522                         IItemDefManager *itemdef, u16 protocol_version);
523         static void SendNodeDef(con::Connection &con, u16 peer_id,
524                         INodeDefManager *nodedef, u16 protocol_version);
525
526         /*
527                 Non-static send methods.
528                 Conlock should be always used.
529                 Envlock usage is documented badly but it's easy to figure out
530                 which ones access the environment.
531         */
532
533         // Envlock and conlock should be locked when calling these
534         void SendInventory(u16 peer_id);
535         void SendChatMessage(u16 peer_id, const std::wstring &message);
536         void BroadcastChatMessage(const std::wstring &message);
537         void SendTimeOfDay(u16 peer_id, u16 time, f32 time_speed);
538         void SendPlayerHP(u16 peer_id);
539         void SendPlayerBreath(u16 peer_id);
540         void SendMovePlayer(u16 peer_id);
541         void SendPlayerPrivileges(u16 peer_id);
542         void SendPlayerInventoryFormspec(u16 peer_id);
543         void SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname);
544         void SendHUDAdd(u16 peer_id, u32 id, HudElement *form);
545         void SendHUDRemove(u16 peer_id, u32 id);
546         void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value);
547         void SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask);
548         void SendHUDSetParam(u16 peer_id, u16 param, const std::string &value);
549
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                         std::list<u16> *far_players=NULL, float far_d_nodes=100);
558         void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
559                         std::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, u16 net_proto_version);
564
565         // Sends blocks to clients (locks env and con on its own)
566         void SendBlocks(float dtime);
567
568         void fillMediaCache();
569         void sendMediaAnnouncement(u16 peer_id);
570         void sendRequestedMedia(u16 peer_id,
571                         const std::list<MediaRequest> &tosend);
572
573         void sendDetachedInventory(const std::string &name, u16 peer_id);
574         void sendDetachedInventoryToAll(const std::string &name);
575         void sendDetachedInventories(u16 peer_id);
576
577         // Adds a ParticleSpawner on peer with peer_id
578         void SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime,
579                 v3f minpos, v3f maxpos,
580                 v3f minvel, v3f maxvel,
581                 v3f minacc, v3f maxacc,
582                 float minexptime, float maxexptime,
583                 float minsize, float maxsize,
584                 bool collisiondetection, std::string texture, u32 id);
585
586         // Adds a ParticleSpawner on all peers
587         void SendAddParticleSpawnerAll(u16 amount, float spawntime,
588                 v3f minpos, v3f maxpos,
589                 v3f minvel, v3f maxvel,
590                 v3f minacc, v3f maxacc,
591                 float minexptime, float maxexptime,
592                 float minsize, float maxsize,
593                 bool collisiondetection, std::string texture, u32 id);
594
595         // Deletes ParticleSpawner on a single client
596         void SendDeleteParticleSpawner(u16 peer_id, u32 id);
597
598         // Deletes ParticleSpawner on all clients
599         void SendDeleteParticleSpawnerAll(u32 id);
600
601         // Spawns particle on single client
602         void SendSpawnParticle(u16 peer_id,
603                 v3f pos, v3f velocity, v3f acceleration,
604                 float expirationtime, float size,
605                 bool collisiondetection, std::string texture);
606
607         // Spawns particle on all clients
608         void SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
609                 float expirationtime, float size,
610                 bool collisiondetection, std::string texture);
611
612         /*
613                 Something random
614         */
615
616         void DiePlayer(u16 peer_id);
617         void RespawnPlayer(u16 peer_id);
618         void DenyAccess(u16 peer_id, const std::wstring &reason);
619
620         enum ClientDeletionReason {
621                 CDR_LEAVE,
622                 CDR_TIMEOUT,
623                 CDR_DENY
624         };
625         void DeleteClient(u16 peer_id, ClientDeletionReason reason);
626
627         void UpdateCrafting(u16 peer_id);
628
629         // When called, connection mutex should be locked
630         RemoteClient* getClient(u16 peer_id);
631         RemoteClient* getClientNoEx(u16 peer_id);
632
633         // When called, environment mutex should be locked
634         std::string getPlayerName(u16 peer_id);
635         PlayerSAO* getPlayerSAO(u16 peer_id);
636
637         /*
638                 Get a player from memory or creates one.
639                 If player is already connected, return NULL
640                 Does not verify/modify auth info and password.
641
642                 Call with env and con locked.
643         */
644         PlayerSAO *emergePlayer(const char *name, u16 peer_id);
645
646         // Locks environment and connection by its own
647         struct PeerChange;
648         void handlePeerChange(PeerChange &c);
649         void handlePeerChanges();
650
651         /*
652                 Variables
653         */
654
655         // World directory
656         std::string m_path_world;
657         // Subgame specification
658         SubgameSpec m_gamespec;
659         // If true, do not allow multiple players and hide some multiplayer
660         // functionality
661         bool m_simple_singleplayer_mode;
662
663         // Thread can set; step() will throw as ServerError
664         MutexedVariable<std::string> m_async_fatal_error;
665
666         // Some timers
667         float m_liquid_transform_timer;
668         float m_liquid_transform_every;
669         float m_print_info_timer;
670         float m_masterserver_timer;
671         float m_objectdata_timer;
672         float m_emergethread_trigger_timer;
673         float m_savemap_timer;
674         IntervalLimiter m_map_timer_and_unload_interval;
675
676         // NOTE: If connection and environment are both to be locked,
677         // environment shall be locked first.
678
679         // Environment
680         ServerEnvironment *m_env;
681         JMutex m_env_mutex;
682
683         // Connection
684         con::Connection m_con;
685         JMutex m_con_mutex;
686         // Connected clients (behind the con mutex)
687         std::map<u16, RemoteClient*> m_clients;
688         std::vector<std::string> m_clients_names; //for announcing masterserver
689
690         // Ban checking
691         BanManager *m_banmanager;
692
693         // Rollback manager (behind m_env_mutex)
694         IRollbackManager *m_rollback;
695         bool m_rollback_sink_enabled;
696         bool m_enable_rollback_recording; // Updated once in a while
697
698         // Emerge manager
699         EmergeManager *m_emerge;
700
701         // Scripting
702         // Envlock and conlock should be locked when using Lua
703         GameScripting *m_script;
704
705         // Item definition manager
706         IWritableItemDefManager *m_itemdef;
707
708         // Node definition manager
709         IWritableNodeDefManager *m_nodedef;
710
711         // Craft definition manager
712         IWritableCraftDefManager *m_craftdef;
713
714         // Event manager
715         EventManager *m_event;
716
717         // Mods
718         std::vector<ModSpec> m_mods;
719
720         /*
721                 Threads
722         */
723
724         // A buffer for time steps
725         // step() increments and AsyncRunStep() run by m_thread reads it.
726         float m_step_dtime;
727         JMutex m_step_dtime_mutex;
728
729         // The server mainly operates in this thread
730         ServerThread *m_thread;
731
732         /*
733                 Time related stuff
734         */
735
736         // Timer for sending time of day over network
737         float m_time_of_day_send_timer;
738         // Uptime of server in seconds
739         MutexedVariable<double> m_uptime;
740
741         /*
742                 Peer change queue.
743                 Queues stuff from peerAdded() and deletingPeer() to
744                 handlePeerChanges()
745         */
746         enum PeerChangeType
747         {
748                 PEER_ADDED,
749                 PEER_REMOVED
750         };
751         struct PeerChange
752         {
753                 PeerChangeType type;
754                 u16 peer_id;
755                 bool timeout;
756         };
757         Queue<PeerChange> m_peer_change_queue;
758
759         /*
760                 Random stuff
761         */
762
763         // Mod parent directory paths
764         std::list<std::string> m_modspaths;
765
766         bool m_shutdown_requested;
767
768         /*
769                 Map edit event queue. Automatically receives all map edits.
770                 The constructor of this class registers us to receive them through
771                 onMapEditEvent
772
773                 NOTE: Should these be moved to actually be members of
774                 ServerEnvironment?
775         */
776
777         /*
778                 Queue of map edits from the environment for sending to the clients
779                 This is behind m_env_mutex
780         */
781         Queue<MapEditEvent*> m_unsent_map_edit_queue;
782         /*
783                 Set to true when the server itself is modifying the map and does
784                 all sending of information by itself.
785                 This is behind m_env_mutex
786         */
787         bool m_ignore_map_edit_events;
788         /*
789                 If a non-empty area, map edit events contained within are left
790                 unsent. Done at map generation time to speed up editing of the
791                 generated area, as it will be sent anyway.
792                 This is behind m_env_mutex
793         */
794         VoxelArea m_ignore_map_edit_events_area;
795         /*
796                 If set to !=0, the incoming MapEditEvents are modified to have
797                 this peed id as the disabled recipient
798                 This is behind m_env_mutex
799         */
800         u16 m_ignore_map_edit_events_peer_id;
801
802         friend class EmergeThread;
803         friend class RemoteClient;
804
805         std::map<std::string,MediaInfo> m_media;
806
807         /*
808                 Sounds
809         */
810         std::map<s32, ServerPlayingSound> m_playing_sounds;
811         s32 m_next_sound_id;
812
813         /*
814                 Detached inventories (behind m_env_mutex)
815         */
816         // key = name
817         std::map<std::string, Inventory*> m_detached_inventories;
818
819         /*
820                 Particles
821         */
822         std::vector<u32> m_particlespawner_ids;
823 };
824
825 /*
826         Runs a simple dedicated server loop.
827
828         Shuts down when run is set to false.
829 */
830 void dedicated_server_loop(Server &server, bool &run);
831
832 #endif
833