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