]> git.lizzy.rs Git - dragonfireclient.git/blob - src/server.h
Preserve immortal group for players when damage is disabled
[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::wstring 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);
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, const std::wstring &wname,
499                 std::wstring wmessage_input,
500                 bool check_shout_priv = false,
501                 RemotePlayer *player = NULL);
502         void handleAdminChat(const ChatEventChat *evt);
503
504         // When called, connection mutex should be locked
505         RemoteClient* getClient(session_t peer_id, ClientState state_min = CS_Active);
506         RemoteClient* getClientNoEx(session_t peer_id, ClientState state_min = CS_Active);
507
508         // When called, environment mutex should be locked
509         std::string getPlayerName(session_t peer_id);
510         PlayerSAO *getPlayerSAO(session_t peer_id);
511
512         /*
513                 Get a player from memory or creates one.
514                 If player is already connected, return NULL
515                 Does not verify/modify auth info and password.
516
517                 Call with env and con locked.
518         */
519         PlayerSAO *emergePlayer(const char *name, session_t peer_id, u16 proto_version);
520
521         void handlePeerChanges();
522
523         /*
524                 Variables
525         */
526         // World directory
527         std::string m_path_world;
528         // Subgame specification
529         SubgameSpec m_gamespec;
530         // If true, do not allow multiple players and hide some multiplayer
531         // functionality
532         bool m_simple_singleplayer_mode;
533         u16 m_max_chatmessage_length;
534         // For "dedicated" server list flag
535         bool m_dedicated;
536         Settings *m_game_settings = nullptr;
537
538         // Thread can set; step() will throw as ServerError
539         MutexedVariable<std::string> m_async_fatal_error;
540
541         // Some timers
542         float m_liquid_transform_timer = 0.0f;
543         float m_liquid_transform_every = 1.0f;
544         float m_masterserver_timer = 0.0f;
545         float m_emergethread_trigger_timer = 0.0f;
546         float m_savemap_timer = 0.0f;
547         IntervalLimiter m_map_timer_and_unload_interval;
548
549         // Environment
550         ServerEnvironment *m_env = nullptr;
551
552         // server connection
553         std::shared_ptr<con::Connection> m_con;
554
555         // Ban checking
556         BanManager *m_banmanager = nullptr;
557
558         // Rollback manager (behind m_env_mutex)
559         IRollbackManager *m_rollback = nullptr;
560
561         // Emerge manager
562         EmergeManager *m_emerge = nullptr;
563
564         // Scripting
565         // Envlock and conlock should be locked when using Lua
566         ServerScripting *m_script = nullptr;
567
568         // Item definition manager
569         IWritableItemDefManager *m_itemdef;
570
571         // Node definition manager
572         NodeDefManager *m_nodedef;
573
574         // Craft definition manager
575         IWritableCraftDefManager *m_craftdef;
576
577         // Mods
578         std::unique_ptr<ServerModManager> m_modmgr;
579
580         std::unordered_map<std::string, Translations> server_translations;
581
582         /*
583                 Threads
584         */
585         // A buffer for time steps
586         // step() increments and AsyncRunStep() run by m_thread reads it.
587         float m_step_dtime = 0.0f;
588         std::mutex m_step_dtime_mutex;
589
590         // The server mainly operates in this thread
591         ServerThread *m_thread = nullptr;
592
593         /*
594                 Time related stuff
595         */
596         // Timer for sending time of day over network
597         float m_time_of_day_send_timer = 0.0f;
598
599         /*
600                 Client interface
601         */
602         ClientInterface m_clients;
603
604         /*
605                 Peer change queue.
606                 Queues stuff from peerAdded() and deletingPeer() to
607                 handlePeerChanges()
608         */
609         std::queue<con::PeerChange> m_peer_change_queue;
610
611         std::unordered_map<session_t, std::string> m_formspec_state_data;
612
613         /*
614                 Random stuff
615         */
616
617         ShutdownState m_shutdown_state;
618
619         ChatInterface *m_admin_chat;
620         std::string m_admin_nick;
621
622         // if a mod-error occurs in the on_shutdown callback, the error message will
623         // be written into this
624         std::string *const m_on_shutdown_errmsg;
625
626         /*
627                 Map edit event queue. Automatically receives all map edits.
628                 The constructor of this class registers us to receive them through
629                 onMapEditEvent
630
631                 NOTE: Should these be moved to actually be members of
632                 ServerEnvironment?
633         */
634
635         /*
636                 Queue of map edits from the environment for sending to the clients
637                 This is behind m_env_mutex
638         */
639         std::queue<MapEditEvent*> m_unsent_map_edit_queue;
640         /*
641                 If a non-empty area, map edit events contained within are left
642                 unsent. Done at map generation time to speed up editing of the
643                 generated area, as it will be sent anyway.
644                 This is behind m_env_mutex
645         */
646         VoxelArea m_ignore_map_edit_events_area;
647
648         // media files known to server
649         std::unordered_map<std::string, MediaInfo> m_media;
650
651         /*
652                 Sounds
653         */
654         std::unordered_map<s32, ServerPlayingSound> m_playing_sounds;
655         s32 m_next_sound_id = 0; // positive values only
656         s32 nextSoundId();
657
658         std::unordered_map<std::string, ModMetadata *> m_mod_storages;
659         float m_mod_storage_save_timer = 10.0f;
660
661         // CSM restrictions byteflag
662         u64 m_csm_restriction_flags = CSMRestrictionFlags::CSM_RF_NONE;
663         u32 m_csm_restriction_noderange = 8;
664
665         // ModChannel manager
666         std::unique_ptr<ModChannelMgr> m_modchannel_mgr;
667
668         // Inventory manager
669         std::unique_ptr<ServerInventoryManager> m_inventory_mgr;
670
671         // Global server metrics backend
672         std::unique_ptr<MetricsBackend> m_metrics_backend;
673
674         // Server metrics
675         MetricCounterPtr m_uptime_counter;
676         MetricGaugePtr m_player_gauge;
677         MetricGaugePtr m_timeofday_gauge;
678         // current server step lag
679         MetricGaugePtr m_lag_gauge;
680         MetricCounterPtr m_aom_buffer_counter;
681         MetricCounterPtr m_packet_recv_counter;
682         MetricCounterPtr m_packet_recv_processed_counter;
683 };
684
685 /*
686         Runs a simple dedicated server loop.
687
688         Shuts down when kill is set to true.
689 */
690 void dedicated_server_loop(Server &server, bool &kill);