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