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