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_=""):
pathMediaInfo88 		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 
handleCommand_Null(NetworkPacket * pkt)176 	void handleCommand_Null(NetworkPacket* pkt) {};
177 	void handleCommand_Deprecated(NetworkPacket* pkt);
178 	void handleCommand_Init(NetworkPacket* pkt);
179 	void handleCommand_Init2(NetworkPacket* pkt);
180 	void handleCommand_ModChannelJoin(NetworkPacket *pkt);
181 	void handleCommand_ModChannelLeave(NetworkPacket *pkt);
182 	void handleCommand_ModChannelMsg(NetworkPacket *pkt);
183 	void handleCommand_RequestMedia(NetworkPacket* pkt);
184 	void handleCommand_ClientReady(NetworkPacket* pkt);
185 	void handleCommand_GotBlocks(NetworkPacket* pkt);
186 	void handleCommand_PlayerPos(NetworkPacket* pkt);
187 	void handleCommand_DeletedBlocks(NetworkPacket* pkt);
188 	void handleCommand_InventoryAction(NetworkPacket* pkt);
189 	void handleCommand_ChatMessage(NetworkPacket* pkt);
190 	void handleCommand_Damage(NetworkPacket* pkt);
191 	void handleCommand_PlayerItem(NetworkPacket* pkt);
192 	void handleCommand_Respawn(NetworkPacket* pkt);
193 	void handleCommand_Interact(NetworkPacket* pkt);
194 	void handleCommand_RemovedSounds(NetworkPacket* pkt);
195 	void handleCommand_NodeMetaFields(NetworkPacket* pkt);
196 	void handleCommand_InventoryFields(NetworkPacket* pkt);
197 	void handleCommand_FirstSrp(NetworkPacket* pkt);
198 	void handleCommand_SrpBytesA(NetworkPacket* pkt);
199 	void handleCommand_SrpBytesM(NetworkPacket* pkt);
200 
201 	void ProcessData(NetworkPacket *pkt);
202 
203 	void Send(NetworkPacket *pkt);
204 	void Send(session_t peer_id, NetworkPacket *pkt);
205 
206 	// Helper for handleCommand_PlayerPos and handleCommand_Interact
207 	void process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
208 		NetworkPacket *pkt);
209 
210 	// Both setter and getter need no envlock,
211 	// can be called freely from threads
212 	void setTimeOfDay(u32 time);
213 
214 	/*
215 		Shall be called with the environment locked.
216 		This is accessed by the map, which is inside the environment,
217 		so it shouldn't be a problem.
218 	*/
219 	void onMapEditEvent(const MapEditEvent &event);
220 
221 	// Connection must be locked when called
222 	std::string getStatusString();
getUptime()223 	inline double getUptime() const { return m_uptime_counter->get(); }
224 
225 	// read shutdown state
isShutdownRequested()226 	inline bool isShutdownRequested() const { return m_shutdown_state.is_requested; }
227 
228 	// request server to shutdown
229 	void requestShutdown(const std::string &msg, bool reconnect, float delay = 0.0f);
230 
231 	// Returns -1 if failed, sound handle on success
232 	// Envlock
233 	s32 playSound(const SimpleSoundSpec &spec, const ServerSoundParams &params,
234 			bool ephemeral=false);
235 	void stopSound(s32 handle);
236 	void fadeSound(s32 handle, float step, float gain);
237 
238 	// Envlock
239 	std::set<std::string> getPlayerEffectivePrivs(const std::string &name);
240 	bool checkPriv(const std::string &name, const std::string &priv);
241 	void reportPrivsModified(const std::string &name=""); // ""=all
242 	void reportInventoryFormspecModified(const std::string &name);
243 	void reportFormspecPrependModified(const std::string &name);
244 
245 	void setIpBanned(const std::string &ip, const std::string &name);
246 	void unsetIpBanned(const std::string &ip_or_name);
247 	std::string getBanDescription(const std::string &ip_or_name);
248 
249 	void notifyPlayer(const char *name, const std::wstring &msg);
250 	void notifyPlayers(const std::wstring &msg);
251 
252 	void spawnParticle(const std::string &playername,
253 		const ParticleParameters &p);
254 
255 	u32 addParticleSpawner(const ParticleSpawnerParameters &p,
256 		ServerActiveObject *attached, const std::string &playername);
257 
258 	void deleteParticleSpawner(const std::string &playername, u32 id);
259 
260 	bool dynamicAddMedia(const std::string &filepath, std::vector<RemotePlayer*> &sent_to);
261 
getInventoryMgr()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
getScriptIface()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);
getRollbackManager()279 	IRollbackManager *getRollbackManager() { return m_rollback; }
getEmergeManager()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();
getWorldPath()290 	virtual std::string getWorldPath() const { return m_path_world; }
291 	virtual std::string getModStoragePath() const;
292 
isSingleplayer()293 	inline bool isSingleplayer()
294 			{ return m_simple_singleplayer_mode; }
295 
setAsyncFatalError(const std::string & error)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);
getMap()300 	Map & getMap() { return m_env->getMap(); }
getEnv()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;
isTimerRunningShutdownState393 			bool isTimerRunning() const { return m_timer > 0.0f; }
394 		private:
395 			float m_timer = 0.0f;
396 	};
397 
398 	void init();
399 
400 	void SendMovement(session_t peer_id);
401 	void SendHP(session_t peer_id, u16 hp);
402 	void SendBreath(session_t peer_id, u16 breath);
403 	void SendAccessDenied(session_t peer_id, AccessDeniedCode reason,
404 		const std::string &custom_reason, bool reconnect = false);
405 	void SendAccessDenied_Legacy(session_t peer_id, const std::wstring &reason);
406 	void SendDeathscreen(session_t peer_id, bool set_camera_point_target,
407 		v3f camera_point_target);
408 	void SendItemDef(session_t peer_id, IItemDefManager *itemdef, u16 protocol_version);
409 	void SendNodeDef(session_t peer_id, const NodeDefManager *nodedef,
410 		u16 protocol_version);
411 
412 	/* mark blocks not sent for all clients */
413 	void SetBlocksNotSent(std::map<v3s16, MapBlock *>& block);
414 
415 
416 	virtual void SendChatMessage(session_t peer_id, const ChatMessage &message);
417 	void SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed);
418 	void SendPlayerHP(session_t peer_id);
419 
420 	void SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4],
421 		f32 animation_speed);
422 	void SendEyeOffset(session_t peer_id, v3f first, v3f third);
423 	void SendPlayerPrivileges(session_t peer_id);
424 	void SendPlayerInventoryFormspec(session_t peer_id);
425 	void SendPlayerFormspecPrepend(session_t peer_id);
426 	void SendShowFormspecMessage(session_t peer_id, const std::string &formspec,
427 		const std::string &formname);
428 	void SendHUDAdd(session_t peer_id, u32 id, HudElement *form);
429 	void SendHUDRemove(session_t peer_id, u32 id);
430 	void SendHUDChange(session_t peer_id, u32 id, HudElementStat stat, void *value);
431 	void SendHUDSetFlags(session_t peer_id, u32 flags, u32 mask);
432 	void SendHUDSetParam(session_t peer_id, u16 param, const std::string &value);
433 	void SendSetSky(session_t peer_id, const SkyboxParams &params);
434 	void SendSetSun(session_t peer_id, const SunParams &params);
435 	void SendSetMoon(session_t peer_id, const MoonParams &params);
436 	void SendSetStars(session_t peer_id, const StarParams &params);
437 	void SendCloudParams(session_t peer_id, const CloudParams &params);
438 	void SendOverrideDayNightRatio(session_t peer_id, bool do_override, float ratio);
439 	void broadcastModChannelMessage(const std::string &channel,
440 			const std::string &message, session_t from_peer);
441 
442 	/*
443 		Send a node removal/addition event to all clients except ignore_id.
444 		Additionally, if far_players!=NULL, players further away than
445 		far_d_nodes are ignored and their peer_ids are added to far_players
446 	*/
447 	// Envlock and conlock should be locked when calling these
448 	void sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players = nullptr,
449 			float far_d_nodes = 100);
450 	void sendAddNode(v3s16 p, MapNode n,
451 			std::unordered_set<u16> *far_players = nullptr,
452 			float far_d_nodes = 100, bool remove_metadata = true);
453 
454 	void sendMetadataChanged(const std::list<v3s16> &meta_updates,
455 			float far_d_nodes = 100);
456 
457 	// Environment and Connection must be locked when called
458 	void SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver, u16 net_proto_version);
459 
460 	// Sends blocks to clients (locks env and con on its own)
461 	void SendBlocks(float dtime);
462 
463 	bool addMediaFile(const std::string &filename, const std::string &filepath,
464 			std::string *filedata = nullptr, std::string *digest = nullptr);
465 	void fillMediaCache();
466 	void sendMediaAnnouncement(session_t peer_id, const std::string &lang_code);
467 	void sendRequestedMedia(session_t peer_id,
468 			const std::vector<std::string> &tosend);
469 
470 	// Adds a ParticleSpawner on peer with peer_id (PEER_ID_INEXISTENT == all)
471 	void SendAddParticleSpawner(session_t peer_id, u16 protocol_version,
472 		const ParticleSpawnerParameters &p, u16 attached_id, u32 id);
473 
474 	void SendDeleteParticleSpawner(session_t peer_id, u32 id);
475 
476 	// Spawns particle on peer with peer_id (PEER_ID_INEXISTENT == all)
477 	void SendSpawnParticle(session_t peer_id, u16 protocol_version,
478 		const ParticleParameters &p);
479 
480 	void SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersao);
481 	void SendActiveObjectMessages(session_t peer_id, const std::string &datas,
482 		bool reliable = true);
483 	void SendCSMRestrictionFlags(session_t peer_id);
484 
485 	/*
486 		Something random
487 	*/
488 
489 	void DiePlayer(session_t peer_id, const PlayerHPChangeReason &reason);
490 	void RespawnPlayer(session_t peer_id);
491 	void DeleteClient(session_t peer_id, ClientDeletionReason reason);
492 	void UpdateCrafting(RemotePlayer *player);
493 	bool checkInteractDistance(RemotePlayer *player, const f32 d, const std::string &what);
494 
495 	void handleChatInterfaceEvent(ChatEvent *evt);
496 
497 	// This returns the answer to the sender of wmessage, or "" if there is none
498 	std::wstring handleChat(const std::string &name, std::wstring wmessage_input,
499 		bool check_shout_priv = false, RemotePlayer *player = nullptr);
500 	void handleAdminChat(const ChatEventChat *evt);
501 
502 	// When called, connection mutex should be locked
503 	RemoteClient* getClient(session_t peer_id, ClientState state_min = CS_Active);
504 	RemoteClient* getClientNoEx(session_t peer_id, ClientState state_min = CS_Active);
505 
506 	// When called, environment mutex should be locked
507 	std::string getPlayerName(session_t peer_id);
508 	PlayerSAO *getPlayerSAO(session_t peer_id);
509 
510 	/*
511 		Get a player from memory or creates one.
512 		If player is already connected, return NULL
513 		Does not verify/modify auth info and password.
514 
515 		Call with env and con locked.
516 	*/
517 	PlayerSAO *emergePlayer(const char *name, session_t peer_id, u16 proto_version);
518 
519 	void handlePeerChanges();
520 
521 	/*
522 		Variables
523 	*/
524 	// World directory
525 	std::string m_path_world;
526 	// Subgame specification
527 	SubgameSpec m_gamespec;
528 	// If true, do not allow multiple players and hide some multiplayer
529 	// functionality
530 	bool m_simple_singleplayer_mode;
531 	u16 m_max_chatmessage_length;
532 	// For "dedicated" server list flag
533 	bool m_dedicated;
534 	Settings *m_game_settings = nullptr;
535 
536 	// Thread can set; step() will throw as ServerError
537 	MutexedVariable<std::string> m_async_fatal_error;
538 
539 	// Some timers
540 	float m_liquid_transform_timer = 0.0f;
541 	float m_liquid_transform_every = 1.0f;
542 	float m_masterserver_timer = 0.0f;
543 	float m_emergethread_trigger_timer = 0.0f;
544 	float m_savemap_timer = 0.0f;
545 	IntervalLimiter m_map_timer_and_unload_interval;
546 
547 	// Environment
548 	ServerEnvironment *m_env = nullptr;
549 
550 	// Reference to the server map until ServerEnvironment is initialized
551 	// after that this variable must be a nullptr
552 	ServerMap *m_startup_server_map = nullptr;
553 
554 	// server connection
555 	std::shared_ptr<con::Connection> m_con;
556 
557 	// Ban checking
558 	BanManager *m_banmanager = nullptr;
559 
560 	// Rollback manager (behind m_env_mutex)
561 	IRollbackManager *m_rollback = nullptr;
562 
563 	// Emerge manager
564 	EmergeManager *m_emerge = nullptr;
565 
566 	// Scripting
567 	// Envlock and conlock should be locked when using Lua
568 	ServerScripting *m_script = nullptr;
569 
570 	// Item definition manager
571 	IWritableItemDefManager *m_itemdef;
572 
573 	// Node definition manager
574 	NodeDefManager *m_nodedef;
575 
576 	// Craft definition manager
577 	IWritableCraftDefManager *m_craftdef;
578 
579 	// Mods
580 	std::unique_ptr<ServerModManager> m_modmgr;
581 
582 	std::unordered_map<std::string, Translations> server_translations;
583 
584 	/*
585 		Threads
586 	*/
587 	// A buffer for time steps
588 	// step() increments and AsyncRunStep() run by m_thread reads it.
589 	float m_step_dtime = 0.0f;
590 	std::mutex m_step_dtime_mutex;
591 
592 	// The server mainly operates in this thread
593 	ServerThread *m_thread = nullptr;
594 
595 	/*
596 		Time related stuff
597 	*/
598 	// Timer for sending time of day over network
599 	float m_time_of_day_send_timer = 0.0f;
600 
601 	/*
602 	 	Client interface
603 	*/
604 	ClientInterface m_clients;
605 
606 	/*
607 		Peer change queue.
608 		Queues stuff from peerAdded() and deletingPeer() to
609 		handlePeerChanges()
610 	*/
611 	std::queue<con::PeerChange> m_peer_change_queue;
612 
613 	std::unordered_map<session_t, std::string> m_formspec_state_data;
614 
615 	/*
616 		Random stuff
617 	*/
618 
619 	ShutdownState m_shutdown_state;
620 
621 	ChatInterface *m_admin_chat;
622 	std::string m_admin_nick;
623 
624 	// if a mod-error occurs in the on_shutdown callback, the error message will
625 	// be written into this
626 	std::string *const m_on_shutdown_errmsg;
627 
628 	/*
629 		Map edit event queue. Automatically receives all map edits.
630 		The constructor of this class registers us to receive them through
631 		onMapEditEvent
632 
633 		NOTE: Should these be moved to actually be members of
634 		ServerEnvironment?
635 	*/
636 
637 	/*
638 		Queue of map edits from the environment for sending to the clients
639 		This is behind m_env_mutex
640 	*/
641 	std::queue<MapEditEvent*> m_unsent_map_edit_queue;
642 	/*
643 		If a non-empty area, map edit events contained within are left
644 		unsent. Done at map generation time to speed up editing of the
645 		generated area, as it will be sent anyway.
646 		This is behind m_env_mutex
647 	*/
648 	VoxelArea m_ignore_map_edit_events_area;
649 
650 	// media files known to server
651 	std::unordered_map<std::string, MediaInfo> m_media;
652 
653 	/*
654 		Sounds
655 	*/
656 	std::unordered_map<s32, ServerPlayingSound> m_playing_sounds;
657 	s32 m_next_sound_id = 0; // positive values only
658 	s32 nextSoundId();
659 
660 	std::unordered_map<std::string, ModMetadata *> m_mod_storages;
661 	float m_mod_storage_save_timer = 10.0f;
662 
663 	// CSM restrictions byteflag
664 	u64 m_csm_restriction_flags = CSMRestrictionFlags::CSM_RF_NONE;
665 	u32 m_csm_restriction_noderange = 8;
666 
667 	// ModChannel manager
668 	std::unique_ptr<ModChannelMgr> m_modchannel_mgr;
669 
670 	// Inventory manager
671 	std::unique_ptr<ServerInventoryManager> m_inventory_mgr;
672 
673 	// Global server metrics backend
674 	std::unique_ptr<MetricsBackend> m_metrics_backend;
675 
676 	// Server metrics
677 	MetricCounterPtr m_uptime_counter;
678 	MetricGaugePtr m_player_gauge;
679 	MetricGaugePtr m_timeofday_gauge;
680 	// current server step lag
681 	MetricGaugePtr m_lag_gauge;
682 	MetricCounterPtr m_aom_buffer_counter;
683 	MetricCounterPtr m_packet_recv_counter;
684 	MetricCounterPtr m_packet_recv_processed_counter;
685 };
686 
687 /*
688 	Runs a simple dedicated server loop.
689 
690 	Shuts down when kill is set to true.
691 */
692 void dedicated_server_loop(Server &server, bool &kill);
693