]> git.lizzy.rs Git - dragonfireclient.git/blob - src/server.h
fff7f9b6a551ce29996c5fd01e659de8ca0269bb
[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 "network/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 "tileanimation.h" // struct TileAnimationParams
33 #include "util/numeric.h"
34 #include "util/thread.h"
35 #include "util/basic_macros.h"
36 #include "serverenvironment.h"
37 #include "chat_interface.h"
38 #include "clientiface.h"
39 #include "remoteplayer.h"
40 #include "network/networkpacket.h"
41 #include "chatmessage.h"
42 #include <string>
43 #include <list>
44 #include <map>
45 #include <vector>
46
47 class IWritableItemDefManager;
48 class IWritableNodeDefManager;
49 class IWritableCraftDefManager;
50 class BanManager;
51 class EventManager;
52 class Inventory;
53 class PlayerSAO;
54 class IRollbackManager;
55 struct RollbackAction;
56 class EmergeManager;
57 class ServerScripting;
58 class ServerEnvironment;
59 struct SimpleSoundSpec;
60 class ServerThread;
61
62 enum ClientDeletionReason {
63         CDR_LEAVE,
64         CDR_TIMEOUT,
65         CDR_DENY
66 };
67
68 class MapEditEventAreaIgnorer
69 {
70 public:
71         MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a):
72                 m_ignorevariable(ignorevariable)
73         {
74                 if(m_ignorevariable->getVolume() == 0)
75                         *m_ignorevariable = a;
76                 else
77                         m_ignorevariable = NULL;
78         }
79
80         ~MapEditEventAreaIgnorer()
81         {
82                 if(m_ignorevariable)
83                 {
84                         assert(m_ignorevariable->getVolume() != 0);
85                         *m_ignorevariable = VoxelArea();
86                 }
87         }
88
89 private:
90         VoxelArea *m_ignorevariable;
91 };
92
93 struct MediaInfo
94 {
95         std::string path;
96         std::string sha1_digest;
97
98         MediaInfo(const std::string &path_="",
99                   const std::string &sha1_digest_=""):
100                 path(path_),
101                 sha1_digest(sha1_digest_)
102         {
103         }
104 };
105
106 struct ServerSoundParams
107 {
108         enum Type {
109                 SSP_LOCAL,
110                 SSP_POSITIONAL,
111                 SSP_OBJECT
112         } type = SSP_LOCAL;
113         float gain = 1.0f;
114         float fade = 0.0f;
115         float pitch = 1.0f;
116         bool loop = false;
117         float max_hear_distance = 32 * BS;
118         v3f pos;
119         u16 object = 0;
120         std::string to_player = "";
121
122         v3f getPos(ServerEnvironment *env, bool *pos_exists) const;
123 };
124
125 struct ServerPlayingSound
126 {
127         ServerSoundParams params;
128         SimpleSoundSpec spec;
129         std::unordered_set<u16> clients; // peer ids
130 };
131
132 class Server : public con::PeerHandler, public MapEventReceiver,
133                 public InventoryManager, public IGameDef
134 {
135 public:
136         /*
137                 NOTE: Every public method should be thread-safe
138         */
139
140         Server(
141                 const std::string &path_world,
142                 const SubgameSpec &gamespec,
143                 bool simple_singleplayer_mode,
144                 bool ipv6,
145                 bool dedicated,
146                 ChatInterface *iface = nullptr
147         );
148         ~Server();
149         DISABLE_CLASS_COPY(Server);
150
151         void start(Address bind_addr);
152         void stop();
153         // This is mainly a way to pass the time to the server.
154         // Actual processing is done in an another thread.
155         void step(float dtime);
156         // This is run by ServerThread and does the actual processing
157         void AsyncRunStep(bool initial_step=false);
158         void Receive();
159         PlayerSAO* StageTwoClientInit(u16 peer_id);
160
161         /*
162          * Command Handlers
163          */
164
165         void handleCommand(NetworkPacket* pkt);
166
167         void handleCommand_Null(NetworkPacket* pkt) {};
168         void handleCommand_Deprecated(NetworkPacket* pkt);
169         void handleCommand_Init(NetworkPacket* pkt);
170         void handleCommand_Init_Legacy(NetworkPacket* pkt);
171         void handleCommand_Init2(NetworkPacket* pkt);
172         void handleCommand_RequestMedia(NetworkPacket* pkt);
173         void handleCommand_ClientReady(NetworkPacket* pkt);
174         void handleCommand_GotBlocks(NetworkPacket* pkt);
175         void handleCommand_PlayerPos(NetworkPacket* pkt);
176         void handleCommand_DeletedBlocks(NetworkPacket* pkt);
177         void handleCommand_InventoryAction(NetworkPacket* pkt);
178         void handleCommand_ChatMessage(NetworkPacket* pkt);
179         void handleCommand_Damage(NetworkPacket* pkt);
180         void handleCommand_Password(NetworkPacket* pkt);
181         void handleCommand_PlayerItem(NetworkPacket* pkt);
182         void handleCommand_Respawn(NetworkPacket* pkt);
183         void handleCommand_Interact(NetworkPacket* pkt);
184         void handleCommand_RemovedSounds(NetworkPacket* pkt);
185         void handleCommand_NodeMetaFields(NetworkPacket* pkt);
186         void handleCommand_InventoryFields(NetworkPacket* pkt);
187         void handleCommand_FirstSrp(NetworkPacket* pkt);
188         void handleCommand_SrpBytesA(NetworkPacket* pkt);
189         void handleCommand_SrpBytesM(NetworkPacket* pkt);
190
191         void ProcessData(NetworkPacket *pkt);
192
193         void Send(NetworkPacket* pkt);
194
195         // Helper for handleCommand_PlayerPos and handleCommand_Interact
196         void process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
197                 NetworkPacket *pkt);
198
199         // Both setter and getter need no envlock,
200         // can be called freely from threads
201         void setTimeOfDay(u32 time);
202
203         /*
204                 Shall be called with the environment locked.
205                 This is accessed by the map, which is inside the environment,
206                 so it shouldn't be a problem.
207         */
208         void onMapEditEvent(MapEditEvent *event);
209
210         /*
211                 Shall be called with the environment and the connection locked.
212         */
213         Inventory* getInventory(const InventoryLocation &loc);
214         void setInventoryModified(const InventoryLocation &loc, bool playerSend = true);
215
216         // Connection must be locked when called
217         std::wstring getStatusString();
218         inline double getUptime() const { return m_uptime.m_value; }
219
220         // read shutdown state
221         inline bool getShutdownRequested() const { return m_shutdown_requested; }
222
223         // request server to shutdown
224         void requestShutdown(const std::string &msg, bool reconnect, float delay = 0.0f);
225
226         // Returns -1 if failed, sound handle on success
227         // Envlock
228         s32 playSound(const SimpleSoundSpec &spec, const ServerSoundParams &params);
229         void stopSound(s32 handle);
230         void fadeSound(s32 handle, float step, float gain);
231
232         // Envlock
233         std::set<std::string> getPlayerEffectivePrivs(const std::string &name);
234         bool checkPriv(const std::string &name, const std::string &priv);
235         void reportPrivsModified(const std::string &name=""); // ""=all
236         void reportInventoryFormspecModified(const std::string &name);
237
238         void setIpBanned(const std::string &ip, const std::string &name);
239         void unsetIpBanned(const std::string &ip_or_name);
240         std::string getBanDescription(const std::string &ip_or_name);
241
242         void notifyPlayer(const char *name, const std::wstring &msg);
243         void notifyPlayers(const std::wstring &msg);
244         void spawnParticle(const std::string &playername,
245                 v3f pos, v3f velocity, v3f acceleration,
246                 float expirationtime, float size,
247                 bool collisiondetection, bool collision_removal,
248                 bool vertical, const std::string &texture,
249                 const struct TileAnimationParams &animation, u8 glow);
250
251         u32 addParticleSpawner(u16 amount, float spawntime,
252                 v3f minpos, v3f maxpos,
253                 v3f minvel, v3f maxvel,
254                 v3f minacc, v3f maxacc,
255                 float minexptime, float maxexptime,
256                 float minsize, float maxsize,
257                 bool collisiondetection, bool collision_removal,
258                 ServerActiveObject *attached,
259                 bool vertical, const std::string &texture,
260                 const std::string &playername, const struct TileAnimationParams &animation,
261                 u8 glow);
262
263         void deleteParticleSpawner(const std::string &playername, u32 id);
264
265         // Creates or resets inventory
266         Inventory* createDetachedInventory(const std::string &name, const std::string &player="");
267
268         // Envlock and conlock should be locked when using scriptapi
269         ServerScripting *getScriptIface(){ return m_script; }
270
271         // actions: time-reversed list
272         // Return value: success/failure
273         bool rollbackRevertActions(const std::list<RollbackAction> &actions,
274                         std::list<std::string> *log);
275
276         // IGameDef interface
277         // Under envlock
278         virtual IItemDefManager* getItemDefManager();
279         virtual INodeDefManager* getNodeDefManager();
280         virtual ICraftDefManager* getCraftDefManager();
281         virtual u16 allocateUnknownNodeId(const std::string &name);
282         virtual MtEventManager* getEventManager();
283         IRollbackManager *getRollbackManager() { return m_rollback; }
284         virtual EmergeManager *getEmergeManager() { return m_emerge; }
285
286         IWritableItemDefManager* getWritableItemDefManager();
287         IWritableNodeDefManager* getWritableNodeDefManager();
288         IWritableCraftDefManager* getWritableCraftDefManager();
289
290         virtual const std::vector<ModSpec> &getMods() const { return m_mods; }
291         virtual const ModSpec* getModSpec(const std::string &modname) const;
292         void getModNames(std::vector<std::string> &modlist);
293         std::string getBuiltinLuaPath();
294         virtual std::string getWorldPath() const { return m_path_world; }
295         virtual std::string getModStoragePath() const;
296
297         inline bool isSingleplayer()
298                         { return m_simple_singleplayer_mode; }
299
300         inline void setAsyncFatalError(const std::string &error)
301                         { m_async_fatal_error.set(error); }
302
303         bool showFormspec(const char *name, const std::string &formspec, const std::string &formname);
304         Map & getMap() { return m_env->getMap(); }
305         ServerEnvironment & getEnv() { return *m_env; }
306         v3f findSpawnPos();
307
308         u32 hudAdd(RemotePlayer *player, HudElement *element);
309         bool hudRemove(RemotePlayer *player, u32 id);
310         bool hudChange(RemotePlayer *player, u32 id, HudElementStat stat, void *value);
311         bool hudSetFlags(RemotePlayer *player, u32 flags, u32 mask);
312         bool hudSetHotbarItemcount(RemotePlayer *player, s32 hotbar_itemcount);
313         s32 hudGetHotbarItemcount(RemotePlayer *player) const
314                         { return player->getHotbarItemcount(); }
315         void hudSetHotbarImage(RemotePlayer *player, std::string name);
316         std::string hudGetHotbarImage(RemotePlayer *player);
317         void hudSetHotbarSelectedImage(RemotePlayer *player, std::string name);
318         const std::string &hudGetHotbarSelectedImage(RemotePlayer *player) const
319         {
320                 return player->getHotbarSelectedImage();
321         }
322
323         inline Address getPeerAddress(u16 peer_id)
324                         { return m_con.GetPeerAddress(peer_id); }
325
326         bool setLocalPlayerAnimations(RemotePlayer *player, v2s32 animation_frames[4],
327                         f32 frame_speed);
328         bool setPlayerEyeOffset(RemotePlayer *player, v3f first, v3f third);
329
330         bool setSky(RemotePlayer *player, const video::SColor &bgcolor,
331                         const std::string &type, const std::vector<std::string> &params,
332                         bool &clouds);
333         bool setClouds(RemotePlayer *player, float density,
334                         const video::SColor &color_bright,
335                         const video::SColor &color_ambient,
336                         float height,
337                         float thickness,
338                         const v2f &speed);
339
340         bool overrideDayNightRatio(RemotePlayer *player, bool do_override, float brightness);
341
342         /* con::PeerHandler implementation. */
343         void peerAdded(con::Peer *peer);
344         void deletingPeer(con::Peer *peer, bool timeout);
345
346         void DenySudoAccess(u16 peer_id);
347         void DenyAccessVerCompliant(u16 peer_id, u16 proto_ver, AccessDeniedCode reason,
348                 const std::string &str_reason = "", bool reconnect = false);
349         void DenyAccess(u16 peer_id, AccessDeniedCode reason, const std::string &custom_reason="");
350         void acceptAuth(u16 peer_id, bool forSudoMode);
351         void DenyAccess_Legacy(u16 peer_id, const std::wstring &reason);
352         bool getClientConInfo(u16 peer_id, con::rtt_stat_type type,float* retval);
353         bool getClientInfo(u16 peer_id,ClientState* state, u32* uptime,
354                         u8* ser_vers, u16* prot_vers, u8* major, u8* minor, u8* patch,
355                         std::string* vers_string);
356
357         void printToConsoleOnly(const std::string &text);
358
359         void SendPlayerHPOrDie(PlayerSAO *player);
360         void SendPlayerBreath(PlayerSAO *sao);
361         void SendInventory(PlayerSAO* playerSAO);
362         void SendMovePlayer(u16 peer_id);
363
364         virtual bool registerModStorage(ModMetadata *storage);
365         virtual void unregisterModStorage(const std::string &name);
366
367         // Bind address
368         Address m_bind_addr;
369
370         // Environment mutex (envlock)
371         std::mutex m_env_mutex;
372
373 private:
374
375         friend class EmergeThread;
376         friend class RemoteClient;
377
378         void SendMovement(u16 peer_id);
379         void SendHP(u16 peer_id, u8 hp);
380         void SendBreath(u16 peer_id, u16 breath);
381         void SendAccessDenied(u16 peer_id, AccessDeniedCode reason,
382                 const std::string &custom_reason, bool reconnect = false);
383         void SendAccessDenied_Legacy(u16 peer_id, const std::wstring &reason);
384         void SendDeathscreen(u16 peer_id,bool set_camera_point_target, v3f camera_point_target);
385         void SendItemDef(u16 peer_id,IItemDefManager *itemdef, u16 protocol_version);
386         void SendNodeDef(u16 peer_id,INodeDefManager *nodedef, u16 protocol_version);
387
388         /* mark blocks not sent for all clients */
389         void SetBlocksNotSent(std::map<v3s16, MapBlock *>& block);
390
391
392         void SendChatMessage(u16 peer_id, const ChatMessage &message);
393         void SendTimeOfDay(u16 peer_id, u16 time, f32 time_speed);
394         void SendPlayerHP(u16 peer_id);
395
396         void SendLocalPlayerAnimations(u16 peer_id, v2s32 animation_frames[4], f32 animation_speed);
397         void SendEyeOffset(u16 peer_id, v3f first, v3f third);
398         void SendPlayerPrivileges(u16 peer_id);
399         void SendPlayerInventoryFormspec(u16 peer_id);
400         void SendShowFormspecMessage(u16 peer_id, const std::string &formspec, const std::string &formname);
401         void SendHUDAdd(u16 peer_id, u32 id, HudElement *form);
402         void SendHUDRemove(u16 peer_id, u32 id);
403         void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value);
404         void SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask);
405         void SendHUDSetParam(u16 peer_id, u16 param, const std::string &value);
406         void SendSetSky(u16 peer_id, const video::SColor &bgcolor,
407                         const std::string &type, const std::vector<std::string> &params,
408                         bool &clouds);
409         void SendCloudParams(u16 peer_id, float density,
410                         const video::SColor &color_bright,
411                         const video::SColor &color_ambient,
412                         float height,
413                         float thickness,
414                         const v2f &speed);
415         void SendOverrideDayNightRatio(u16 peer_id, bool do_override, float ratio);
416
417         /*
418                 Send a node removal/addition event to all clients except ignore_id.
419                 Additionally, if far_players!=NULL, players further away than
420                 far_d_nodes are ignored and their peer_ids are added to far_players
421         */
422         // Envlock and conlock should be locked when calling these
423         void sendRemoveNode(v3s16 p, u16 ignore_id=0,
424                         std::vector<u16> *far_players=NULL, float far_d_nodes=100);
425         void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
426                         std::vector<u16> *far_players=NULL, float far_d_nodes=100,
427                         bool remove_metadata=true);
428         void setBlockNotSent(v3s16 p);
429
430         // Environment and Connection must be locked when called
431         void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver, u16 net_proto_version);
432
433         // Sends blocks to clients (locks env and con on its own)
434         void SendBlocks(float dtime);
435
436         void fillMediaCache();
437         void sendMediaAnnouncement(u16 peer_id);
438         void sendRequestedMedia(u16 peer_id,
439                         const std::vector<std::string> &tosend);
440
441         void sendDetachedInventory(const std::string &name, u16 peer_id);
442         void sendDetachedInventories(u16 peer_id);
443
444         // Adds a ParticleSpawner on peer with peer_id (PEER_ID_INEXISTENT == all)
445         void SendAddParticleSpawner(u16 peer_id, u16 protocol_version,
446                 u16 amount, float spawntime,
447                 v3f minpos, v3f maxpos,
448                 v3f minvel, v3f maxvel,
449                 v3f minacc, v3f maxacc,
450                 float minexptime, float maxexptime,
451                 float minsize, float maxsize,
452                 bool collisiondetection, bool collision_removal,
453                 u16 attached_id,
454                 bool vertical, const std::string &texture, u32 id,
455                 const struct TileAnimationParams &animation, u8 glow);
456
457         void SendDeleteParticleSpawner(u16 peer_id, u32 id);
458
459         // Spawns particle on peer with peer_id (PEER_ID_INEXISTENT == all)
460         void SendSpawnParticle(u16 peer_id, u16 protocol_version,
461                 v3f pos, v3f velocity, v3f acceleration,
462                 float expirationtime, float size,
463                 bool collisiondetection, bool collision_removal,
464                 bool vertical, const std::string &texture,
465                 const struct TileAnimationParams &animation, u8 glow);
466
467         u32 SendActiveObjectRemoveAdd(u16 peer_id, const std::string &datas);
468         void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true);
469         void SendCSMFlavourLimits(u16 peer_id);
470
471         /*
472                 Something random
473         */
474
475         void DiePlayer(u16 peer_id);
476         void RespawnPlayer(u16 peer_id);
477         void DeleteClient(u16 peer_id, ClientDeletionReason reason);
478         void UpdateCrafting(RemotePlayer *player);
479
480         void handleChatInterfaceEvent(ChatEvent *evt);
481
482         // This returns the answer to the sender of wmessage, or "" if there is none
483         std::wstring handleChat(const std::string &name, const std::wstring &wname,
484                 std::wstring wmessage_input,
485                 bool check_shout_priv = false,
486                 RemotePlayer *player = NULL);
487         void handleAdminChat(const ChatEventChat *evt);
488
489         // When called, connection mutex should be locked
490         RemoteClient* getClient(u16 peer_id,ClientState state_min=CS_Active);
491         RemoteClient* getClientNoEx(u16 peer_id,ClientState state_min=CS_Active);
492
493         // When called, environment mutex should be locked
494         std::string getPlayerName(u16 peer_id);
495         PlayerSAO* getPlayerSAO(u16 peer_id);
496
497         /*
498                 Get a player from memory or creates one.
499                 If player is already connected, return NULL
500                 Does not verify/modify auth info and password.
501
502                 Call with env and con locked.
503         */
504         PlayerSAO *emergePlayer(const char *name, u16 peer_id, u16 proto_version);
505
506         void handlePeerChanges();
507
508         /*
509                 Variables
510         */
511
512         // World directory
513         std::string m_path_world;
514         // Subgame specification
515         SubgameSpec m_gamespec;
516         // If true, do not allow multiple players and hide some multiplayer
517         // functionality
518         bool m_simple_singleplayer_mode;
519         u16 m_max_chatmessage_length;
520         // For "dedicated" server list flag
521         bool m_dedicated;
522
523         // Thread can set; step() will throw as ServerError
524         MutexedVariable<std::string> m_async_fatal_error;
525
526         // Some timers
527         float m_liquid_transform_timer = 0.0f;
528         float m_liquid_transform_every = 1.0f;
529         float m_masterserver_timer = 0.0f;
530         float m_emergethread_trigger_timer = 0.0f;
531         float m_savemap_timer = 0.0f;
532         IntervalLimiter m_map_timer_and_unload_interval;
533
534         // Environment
535         ServerEnvironment *m_env = nullptr;
536
537         // server connection
538         con::Connection m_con;
539
540         // Ban checking
541         BanManager *m_banmanager = nullptr;
542
543         // Rollback manager (behind m_env_mutex)
544         IRollbackManager *m_rollback = nullptr;
545         bool m_enable_rollback_recording = false; // Updated once in a while
546
547         // Emerge manager
548         EmergeManager *m_emerge = nullptr;
549
550         // Scripting
551         // Envlock and conlock should be locked when using Lua
552         ServerScripting *m_script = nullptr;
553
554         // Item definition manager
555         IWritableItemDefManager *m_itemdef;
556
557         // Node definition manager
558         IWritableNodeDefManager *m_nodedef;
559
560         // Craft definition manager
561         IWritableCraftDefManager *m_craftdef;
562
563         // Event manager
564         EventManager *m_event;
565
566         // Mods
567         std::vector<ModSpec> m_mods;
568
569         /*
570                 Threads
571         */
572
573         // A buffer for time steps
574         // step() increments and AsyncRunStep() run by m_thread reads it.
575         float m_step_dtime = 0.0f;
576         std::mutex m_step_dtime_mutex;
577
578         // current server step lag counter
579         float m_lag;
580
581         // The server mainly operates in this thread
582         ServerThread *m_thread = nullptr;
583
584         /*
585                 Time related stuff
586         */
587
588         // Timer for sending time of day over network
589         float m_time_of_day_send_timer = 0.0f;
590         // Uptime of server in seconds
591         MutexedVariable<double> m_uptime;
592         /*
593          Client interface
594          */
595         ClientInterface m_clients;
596
597         /*
598                 Peer change queue.
599                 Queues stuff from peerAdded() and deletingPeer() to
600                 handlePeerChanges()
601         */
602         std::queue<con::PeerChange> m_peer_change_queue;
603
604         /*
605                 Random stuff
606         */
607
608         bool m_shutdown_requested = false;
609         std::string m_shutdown_msg;
610         bool m_shutdown_ask_reconnect = false;
611         float m_shutdown_timer = 0.0f;
612
613         ChatInterface *m_admin_chat;
614         std::string m_admin_nick;
615
616         /*
617                 Map edit event queue. Automatically receives all map edits.
618                 The constructor of this class registers us to receive them through
619                 onMapEditEvent
620
621                 NOTE: Should these be moved to actually be members of
622                 ServerEnvironment?
623         */
624
625         /*
626                 Queue of map edits from the environment for sending to the clients
627                 This is behind m_env_mutex
628         */
629         std::queue<MapEditEvent*> m_unsent_map_edit_queue;
630         /*
631                 Set to true when the server itself is modifying the map and does
632                 all sending of information by itself.
633                 This is behind m_env_mutex
634         */
635         bool m_ignore_map_edit_events = false;
636         /*
637                 If a non-empty area, map edit events contained within are left
638                 unsent. Done at map generation time to speed up editing of the
639                 generated area, as it will be sent anyway.
640                 This is behind m_env_mutex
641         */
642         VoxelArea m_ignore_map_edit_events_area;
643         /*
644                 If set to !=0, the incoming MapEditEvents are modified to have
645                 this peed id as the disabled recipient
646                 This is behind m_env_mutex
647         */
648         u16 m_ignore_map_edit_events_peer_id = 0;
649
650         // media files known to server
651         std::unordered_map<std::string, MediaInfo> m_media;
652
653         /*
654                 Sounds
655         */
656         std::unordered_map<s32, ServerPlayingSound> m_playing_sounds;
657         s32 m_next_sound_id = 0;
658
659         /*
660                 Detached inventories (behind m_env_mutex)
661         */
662         // key = name
663         std::map<std::string, Inventory*> m_detached_inventories;
664         // value = "" (visible to all players) or player name
665         std::map<std::string, std::string> m_detached_inventories_player;
666
667         std::unordered_map<std::string, ModMetadata *> m_mod_storages;
668         float m_mod_storage_save_timer = 10.0f;
669
670         // CSM flavour limits byteflag
671         u64 m_csm_flavour_limits = CSMFlavourLimit::CSM_FL_NONE;
672         u32 m_csm_noderange_limit = 8;
673 };
674
675 /*
676         Runs a simple dedicated server loop.
677
678         Shuts down when kill is set to true.
679 */
680 void dedicated_server_loop(Server &server, bool &kill);
681
682 #endif