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