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