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