]> git.lizzy.rs Git - dragonfireclient.git/blob - src/server.h
Initial Commit
[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" // 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 "serverenvironment.h"
37 #include "clientiface.h"
38 #include "chatmessage.h"
39 #include <string>
40 #include <list>
41 #include <map>
42 #include <vector>
43
44 class ChatEvent;
45 struct ChatEventChat;
46 struct ChatInterface;
47 class IWritableItemDefManager;
48 class NodeDefManager;
49 class IWritableCraftDefManager;
50 class BanManager;
51 class EventManager;
52 class Inventory;
53 class ModChannelMgr;
54 class RemotePlayer;
55 class PlayerSAO;
56 struct PlayerHPChangeReason;
57 class IRollbackManager;
58 struct RollbackAction;
59 class EmergeManager;
60 class ServerScripting;
61 class ServerEnvironment;
62 struct SimpleSoundSpec;
63 struct CloudParams;
64 struct SkyboxParams;
65 struct SunParams;
66 struct MoonParams;
67 struct StarParams;
68 class ServerThread;
69 class ServerModManager;
70
71 enum ClientDeletionReason {
72         CDR_LEAVE,
73         CDR_TIMEOUT,
74         CDR_DENY
75 };
76
77 struct MediaInfo
78 {
79         std::string path;
80         std::string sha1_digest;
81
82         MediaInfo(const std::string &path_="",
83                   const std::string &sha1_digest_=""):
84                 path(path_),
85                 sha1_digest(sha1_digest_)
86         {
87         }
88 };
89
90 struct ServerSoundParams
91 {
92         enum Type {
93                 SSP_LOCAL,
94                 SSP_POSITIONAL,
95                 SSP_OBJECT
96         } type = SSP_LOCAL;
97         float gain = 1.0f;
98         float fade = 0.0f;
99         float pitch = 1.0f;
100         bool loop = false;
101         float max_hear_distance = 32 * BS;
102         v3f pos;
103         u16 object = 0;
104         std::string to_player = "";
105         std::string exclude_player = "";
106
107         v3f getPos(ServerEnvironment *env, bool *pos_exists) const;
108 };
109
110 struct ServerPlayingSound
111 {
112         ServerSoundParams params;
113         SimpleSoundSpec spec;
114         std::unordered_set<session_t> clients; // peer ids
115 };
116
117 class Server : public con::PeerHandler, public MapEventReceiver,
118                 public InventoryManager, public IGameDef
119 {
120 public:
121         /*
122                 NOTE: Every public method should be thread-safe
123         */
124
125         Server(
126                 const std::string &path_world,
127                 const SubgameSpec &gamespec,
128                 bool simple_singleplayer_mode,
129                 Address bind_addr,
130                 bool dedicated,
131                 ChatInterface *iface = nullptr
132         );
133         ~Server();
134         DISABLE_CLASS_COPY(Server);
135
136         void init();
137         void start();
138         void stop();
139         // This is mainly a way to pass the time to the server.
140         // Actual processing is done in an another thread.
141         void step(float dtime);
142         // This is run by ServerThread and does the actual processing
143         void AsyncRunStep(bool initial_step=false);
144         void Receive();
145         PlayerSAO* StageTwoClientInit(session_t peer_id);
146
147         /*
148          * Command Handlers
149          */
150
151         void handleCommand(NetworkPacket* pkt);
152
153         void handleCommand_Null(NetworkPacket* pkt) {};
154         void handleCommand_Deprecated(NetworkPacket* pkt);
155         void handleCommand_Init(NetworkPacket* pkt);
156         void handleCommand_Init2(NetworkPacket* pkt);
157         void handleCommand_ModChannelJoin(NetworkPacket *pkt);
158         void handleCommand_ModChannelLeave(NetworkPacket *pkt);
159         void handleCommand_ModChannelMsg(NetworkPacket *pkt);
160         void handleCommand_RequestMedia(NetworkPacket* pkt);
161         void handleCommand_ClientReady(NetworkPacket* pkt);
162         void handleCommand_GotBlocks(NetworkPacket* pkt);
163         void handleCommand_PlayerPos(NetworkPacket* pkt);
164         void handleCommand_DeletedBlocks(NetworkPacket* pkt);
165         void handleCommand_InventoryAction(NetworkPacket* pkt);
166         void handleCommand_ChatMessage(NetworkPacket* pkt);
167         void handleCommand_Damage(NetworkPacket* pkt);
168         void handleCommand_Password(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.m_value; }
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         void RedirectPeer(session_t peer_id, const std::string address, u16 port);
336         bool getClientConInfo(session_t peer_id, con::rtt_stat_type type, float *retval);
337         bool getClientInfo(session_t peer_id, ClientState *state, u32 *uptime,
338                         u8* ser_vers, u16* prot_vers, u8* major, u8* minor, u8* patch,
339                         std::string* vers_string);
340
341         void printToConsoleOnly(const std::string &text);
342
343         void SendPlayerHPOrDie(PlayerSAO *player, const PlayerHPChangeReason &reason);
344         void SendPlayerBreath(PlayerSAO *sao);
345         void SendInventory(PlayerSAO *playerSAO, bool incremental);
346         void SendMovePlayer(session_t peer_id);
347         void SendPlayerSpeed(session_t peer_id, const v3f &added_vel);
348         void SendPlayerFov(session_t peer_id);
349
350         void sendDetachedInventories(session_t peer_id, bool incremental);
351
352         virtual bool registerModStorage(ModMetadata *storage);
353         virtual void unregisterModStorage(const std::string &name);
354
355         bool joinModChannel(const std::string &channel);
356         bool leaveModChannel(const std::string &channel);
357         bool sendModChannelMessage(const std::string &channel, const std::string &message);
358         ModChannel *getModChannel(const std::string &channel);
359
360         // Send block to specific player only
361         bool SendBlock(session_t peer_id, const v3s16 &blockpos);
362
363         // Bind address
364         Address m_bind_addr;
365
366         // Environment mutex (envlock)
367         std::mutex m_env_mutex;
368
369 private:
370         friend class EmergeThread;
371         friend class RemoteClient;
372         friend class TestServerShutdownState;
373
374         struct ShutdownState {
375                 friend class TestServerShutdownState;
376                 public:
377                         bool is_requested = false;
378                         bool should_reconnect = false;
379                         std::string message;
380
381                         void reset();
382                         void trigger(float delay, const std::string &msg, bool reconnect);
383                         void tick(float dtime, Server *server);
384                         std::wstring getShutdownTimerMessage() const;
385                         bool isTimerRunning() const { return m_timer > 0.0f; }
386                 private:
387                         float m_timer = 0.0f;
388         };
389
390         void SendMovement(session_t peer_id);
391         void SendHP(session_t peer_id, u16 hp);
392         void SendBreath(session_t peer_id, u16 breath);
393         void SendAccessDenied(session_t peer_id, AccessDeniedCode reason,
394                 const std::string &custom_reason, bool reconnect = false);
395         void SendAccessDenied_Legacy(session_t peer_id, const std::wstring &reason);
396         void SendRedirect(session_t peer_id, const std::string address, u16 port);
397         void SendDeathscreen(session_t peer_id, bool set_camera_point_target,
398                 v3f camera_point_target);
399         void SendItemDef(session_t peer_id, IItemDefManager *itemdef, u16 protocol_version);
400         void SendNodeDef(session_t peer_id, const NodeDefManager *nodedef,
401                 u16 protocol_version);
402
403         /* mark blocks not sent for all clients */
404         void SetBlocksNotSent(std::map<v3s16, MapBlock *>& block);
405
406
407         virtual void SendChatMessage(session_t peer_id, const ChatMessage &message);
408         void SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed);
409         void SendPlayerHP(session_t peer_id);
410
411         void SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4],
412                 f32 animation_speed);
413         void SendEyeOffset(session_t peer_id, v3f first, v3f third);
414         void SendPlayerPrivileges(session_t peer_id);
415         void SendPlayerInventoryFormspec(session_t peer_id);
416         void SendPlayerFormspecPrepend(session_t peer_id);
417         void SendShowFormspecMessage(session_t peer_id, const std::string &formspec,
418                 const std::string &formname);
419         void SendHUDAdd(session_t peer_id, u32 id, HudElement *form);
420         void SendHUDRemove(session_t peer_id, u32 id);
421         void SendHUDChange(session_t peer_id, u32 id, HudElementStat stat, void *value);
422         void SendHUDSetFlags(session_t peer_id, u32 flags, u32 mask);
423         void SendHUDSetParam(session_t peer_id, u16 param, const std::string &value);
424         void SendSetSky(session_t peer_id, const SkyboxParams &params);
425         void SendSetSun(session_t peer_id, const SunParams &params);
426         void SendSetMoon(session_t peer_id, const MoonParams &params);
427         void SendSetStars(session_t peer_id, const StarParams &params);
428         void SendCloudParams(session_t peer_id, const CloudParams &params);
429         void SendOverrideDayNightRatio(session_t peer_id, bool do_override, float ratio);
430         void broadcastModChannelMessage(const std::string &channel,
431                         const std::string &message, session_t from_peer);
432
433         /*
434                 Send a node removal/addition event to all clients except ignore_id.
435                 Additionally, if far_players!=NULL, players further away than
436                 far_d_nodes are ignored and their peer_ids are added to far_players
437         */
438         // Envlock and conlock should be locked when calling these
439         void sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players = nullptr,
440                         float far_d_nodes = 100);
441         void sendAddNode(v3s16 p, MapNode n,
442                         std::unordered_set<u16> *far_players = nullptr,
443                         float far_d_nodes = 100, bool remove_metadata = true);
444
445         void sendMetadataChanged(const std::list<v3s16> &meta_updates,
446                         float far_d_nodes = 100);
447
448         // Environment and Connection must be locked when called
449         void SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver, u16 net_proto_version);
450
451         // Sends blocks to clients (locks env and con on its own)
452         void SendBlocks(float dtime);
453
454         void fillMediaCache();
455         void sendMediaAnnouncement(session_t peer_id, const std::string &lang_code);
456         void sendRequestedMedia(session_t peer_id,
457                         const std::vector<std::string> &tosend);
458
459         void sendDetachedInventory(const std::string &name, session_t peer_id);
460
461         // Adds a ParticleSpawner on peer with peer_id (PEER_ID_INEXISTENT == all)
462         void SendAddParticleSpawner(session_t peer_id, u16 protocol_version,
463                 u16 amount, float spawntime,
464                 v3f minpos, v3f maxpos,
465                 v3f minvel, v3f maxvel,
466                 v3f minacc, v3f maxacc,
467                 float minexptime, float maxexptime,
468                 float minsize, float maxsize,
469                 bool collisiondetection, bool collision_removal, bool object_collision,
470                 u16 attached_id,
471                 bool vertical, const std::string &texture, u32 id,
472                 const struct TileAnimationParams &animation, u8 glow);
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                 v3f pos, v3f velocity, v3f acceleration,
479                 float expirationtime, float size,
480                 bool collisiondetection, bool collision_removal, bool object_collision,
481                 bool vertical, const std::string &texture,
482                 const struct TileAnimationParams &animation, u8 glow);
483
484         void SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersao);
485         void SendActiveObjectMessages(session_t peer_id, const std::string &datas,
486                 bool reliable = true);
487         void SendCSMRestrictionFlags(session_t peer_id);
488
489         /*
490                 Something random
491         */
492
493         void DiePlayer(session_t peer_id, const PlayerHPChangeReason &reason);
494         void RespawnPlayer(session_t peer_id);
495         void DeleteClient(session_t peer_id, ClientDeletionReason reason);
496         void UpdateCrafting(RemotePlayer *player);
497         bool checkInteractDistance(RemotePlayer *player, const f32 d, const std::string &what);
498
499         void handleChatInterfaceEvent(ChatEvent *evt);
500
501         // This returns the answer to the sender of wmessage, or "" if there is none
502         std::wstring handleChat(const std::string &name, const std::wstring &wname,
503                 std::wstring wmessage_input,
504                 bool check_shout_priv = false,
505                 RemotePlayer *player = NULL);
506         void handleAdminChat(const ChatEventChat *evt);
507
508         // When called, connection mutex should be locked
509         RemoteClient* getClient(session_t peer_id, ClientState state_min = CS_Active);
510         RemoteClient* getClientNoEx(session_t peer_id, ClientState state_min = CS_Active);
511
512         // When called, environment mutex should be locked
513         std::string getPlayerName(session_t peer_id);
514         PlayerSAO *getPlayerSAO(session_t peer_id);
515
516         /*
517                 Get a player from memory or creates one.
518                 If player is already connected, return NULL
519                 Does not verify/modify auth info and password.
520
521                 Call with env and con locked.
522         */
523         PlayerSAO *emergePlayer(const char *name, session_t peer_id, u16 proto_version);
524
525         void handlePeerChanges();
526
527         /*
528                 Variables
529         */
530         // World directory
531         std::string m_path_world;
532         // Subgame specification
533         SubgameSpec m_gamespec;
534         // If true, do not allow multiple players and hide some multiplayer
535         // functionality
536         bool m_simple_singleplayer_mode;
537         u16 m_max_chatmessage_length;
538         // For "dedicated" server list flag
539         bool m_dedicated;
540
541         // Thread can set; step() will throw as ServerError
542         MutexedVariable<std::string> m_async_fatal_error;
543
544         // Some timers
545         float m_liquid_transform_timer = 0.0f;
546         float m_liquid_transform_every = 1.0f;
547         float m_masterserver_timer = 0.0f;
548         float m_emergethread_trigger_timer = 0.0f;
549         float m_savemap_timer = 0.0f;
550         IntervalLimiter m_map_timer_and_unload_interval;
551
552         // Environment
553         ServerEnvironment *m_env = nullptr;
554
555         // server connection
556         std::shared_ptr<con::Connection> m_con;
557
558         // Ban checking
559         BanManager *m_banmanager = nullptr;
560
561         // Rollback manager (behind m_env_mutex)
562         IRollbackManager *m_rollback = nullptr;
563
564         // Emerge manager
565         EmergeManager *m_emerge = nullptr;
566
567         // Scripting
568         // Envlock and conlock should be locked when using Lua
569         ServerScripting *m_script = nullptr;
570
571         // Item definition manager
572         IWritableItemDefManager *m_itemdef;
573
574         // Node definition manager
575         NodeDefManager *m_nodedef;
576
577         // Craft definition manager
578         IWritableCraftDefManager *m_craftdef;
579
580         // Event manager
581         EventManager *m_event;
582
583         // Mods
584         std::unique_ptr<ServerModManager> m_modmgr;
585
586         /*
587                 Threads
588         */
589         // A buffer for time steps
590         // step() increments and AsyncRunStep() run by m_thread reads it.
591         float m_step_dtime = 0.0f;
592         std::mutex m_step_dtime_mutex;
593
594         // current server step lag counter
595         float m_lag;
596
597         // The server mainly operates in this thread
598         ServerThread *m_thread = nullptr;
599
600         /*
601                 Time related stuff
602         */
603         // Timer for sending time of day over network
604         float m_time_of_day_send_timer = 0.0f;
605         // Uptime of server in seconds
606         MutexedVariable<double> m_uptime;
607
608         /*
609                 Client interface
610         */
611         ClientInterface m_clients;
612
613         /*
614                 Peer change queue.
615                 Queues stuff from peerAdded() and deletingPeer() to
616                 handlePeerChanges()
617         */
618         std::queue<con::PeerChange> m_peer_change_queue;
619
620         std::unordered_map<session_t, std::string> m_formspec_state_data;
621
622         /*
623                 Random stuff
624         */
625
626         ShutdownState m_shutdown_state;
627
628         ChatInterface *m_admin_chat;
629         std::string m_admin_nick;
630
631         /*
632                 Map edit event queue. Automatically receives all map edits.
633                 The constructor of this class registers us to receive them through
634                 onMapEditEvent
635
636                 NOTE: Should these be moved to actually be members of
637                 ServerEnvironment?
638         */
639
640         /*
641                 Queue of map edits from the environment for sending to the clients
642                 This is behind m_env_mutex
643         */
644         std::queue<MapEditEvent*> m_unsent_map_edit_queue;
645         /*
646                 If a non-empty area, map edit events contained within are left
647                 unsent. Done at map generation time to speed up editing of the
648                 generated area, as it will be sent anyway.
649                 This is behind m_env_mutex
650         */
651         VoxelArea m_ignore_map_edit_events_area;
652
653         // media files known to server
654         std::unordered_map<std::string, MediaInfo> m_media;
655
656         /*
657                 Sounds
658         */
659         std::unordered_map<s32, ServerPlayingSound> m_playing_sounds;
660         s32 m_next_sound_id = 0; // positive values only
661         s32 nextSoundId();
662
663         /*
664                 Detached inventories (behind m_env_mutex)
665         */
666         // key = name
667         std::map<std::string, Inventory*> m_detached_inventories;
668         // value = "" (visible to all players) or player name
669         std::map<std::string, std::string> m_detached_inventories_player;
670
671         std::unordered_map<std::string, ModMetadata *> m_mod_storages;
672         float m_mod_storage_save_timer = 10.0f;
673
674         // CSM restrictions byteflag
675         u64 m_csm_restriction_flags = CSMRestrictionFlags::CSM_RF_NONE;
676         u32 m_csm_restriction_noderange = 8;
677
678         // ModChannel manager
679         std::unique_ptr<ModChannelMgr> m_modchannel_mgr;
680 };
681
682 /*
683         Runs a simple dedicated server loop.
684
685         Shuts down when kill is set to true.
686 */
687 void dedicated_server_loop(Server &server, bool &kill);