]> git.lizzy.rs Git - dragonfireclient.git/blob - src/server.cpp
d6e545498b32a96d487c4516cb0df65bf5dc2bd8
[dragonfireclient.git] / src / server.cpp
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 #include "server.h"
21 #include <iostream>
22 #include <queue>
23 #include <algorithm>
24 #include "network/connection.h"
25 #include "network/networkprotocol.h"
26 #include "network/serveropcodes.h"
27 #include "ban.h"
28 #include "environment.h"
29 #include "map.h"
30 #include "threading/mutex_auto_lock.h"
31 #include "constants.h"
32 #include "voxel.h"
33 #include "config.h"
34 #include "version.h"
35 #include "filesys.h"
36 #include "mapblock.h"
37 #include "server/serveractiveobject.h"
38 #include "settings.h"
39 #include "profiler.h"
40 #include "log.h"
41 #include "scripting_server.h"
42 #include "nodedef.h"
43 #include "itemdef.h"
44 #include "craftdef.h"
45 #include "emerge.h"
46 #include "mapgen/mapgen.h"
47 #include "mapgen/mg_biome.h"
48 #include "content_mapnode.h"
49 #include "content_nodemeta.h"
50 #include "content/mods.h"
51 #include "modchannels.h"
52 #include "serverlist.h"
53 #include "util/string.h"
54 #include "rollback.h"
55 #include "util/serialize.h"
56 #include "util/thread.h"
57 #include "defaultsettings.h"
58 #include "server/mods.h"
59 #include "util/base64.h"
60 #include "util/sha1.h"
61 #include "util/hex.h"
62 #include "database/database.h"
63 #include "chatmessage.h"
64 #include "chat_interface.h"
65 #include "remoteplayer.h"
66 #include "server/player_sao.h"
67 #include "server/serverinventorymgr.h"
68 #include "translation.h"
69
70 class ClientNotFoundException : public BaseException
71 {
72 public:
73         ClientNotFoundException(const char *s):
74                 BaseException(s)
75         {}
76 };
77
78 class ServerThread : public Thread
79 {
80 public:
81
82         ServerThread(Server *server):
83                 Thread("Server"),
84                 m_server(server)
85         {}
86
87         void *run();
88
89 private:
90         Server *m_server;
91 };
92
93 void *ServerThread::run()
94 {
95         BEGIN_DEBUG_EXCEPTION_HANDLER
96
97         /*
98          * The real business of the server happens on the ServerThread.
99          * How this works:
100          * AsyncRunStep() runs an actual server step as soon as enough time has
101          * passed (dedicated_server_loop keeps track of that).
102          * Receive() blocks at least(!) 30ms waiting for a packet (so this loop
103          * doesn't busy wait) and will process any remaining packets.
104          */
105
106         m_server->AsyncRunStep(true);
107
108         while (!stopRequested()) {
109                 try {
110                         m_server->AsyncRunStep();
111
112                         m_server->Receive();
113
114                 } catch (con::PeerNotFoundException &e) {
115                         infostream<<"Server: PeerNotFoundException"<<std::endl;
116                 } catch (ClientNotFoundException &e) {
117                 } catch (con::ConnectionBindFailed &e) {
118                         m_server->setAsyncFatalError(e.what());
119                 } catch (LuaError &e) {
120                         m_server->setAsyncFatalError(
121                                         "ServerThread::run Lua: " + std::string(e.what()));
122                 }
123         }
124
125         END_DEBUG_EXCEPTION_HANDLER
126
127         return nullptr;
128 }
129
130 v3f ServerSoundParams::getPos(ServerEnvironment *env, bool *pos_exists) const
131 {
132         if(pos_exists) *pos_exists = false;
133         switch(type){
134         case SSP_LOCAL:
135                 return v3f(0,0,0);
136         case SSP_POSITIONAL:
137                 if(pos_exists) *pos_exists = true;
138                 return pos;
139         case SSP_OBJECT: {
140                 if(object == 0)
141                         return v3f(0,0,0);
142                 ServerActiveObject *sao = env->getActiveObject(object);
143                 if(!sao)
144                         return v3f(0,0,0);
145                 if(pos_exists) *pos_exists = true;
146                 return sao->getBasePosition(); }
147         }
148         return v3f(0,0,0);
149 }
150
151 void Server::ShutdownState::reset()
152 {
153         m_timer = 0.0f;
154         message.clear();
155         should_reconnect = false;
156         is_requested = false;
157 }
158
159 void Server::ShutdownState::trigger(float delay, const std::string &msg, bool reconnect)
160 {
161         m_timer = delay;
162         message = msg;
163         should_reconnect = reconnect;
164 }
165
166 void Server::ShutdownState::tick(float dtime, Server *server)
167 {
168         if (m_timer <= 0.0f)
169                 return;
170
171         // Timed shutdown
172         static const float shutdown_msg_times[] =
173         {
174                 1, 2, 3, 4, 5, 10, 20, 40, 60, 120, 180, 300, 600, 1200, 1800, 3600
175         };
176
177         // Automated messages
178         if (m_timer < shutdown_msg_times[ARRLEN(shutdown_msg_times) - 1]) {
179                 for (float t : shutdown_msg_times) {
180                         // If shutdown timer matches an automessage, shot it
181                         if (m_timer > t && m_timer - dtime < t) {
182                                 std::wstring periodicMsg = getShutdownTimerMessage();
183
184                                 infostream << wide_to_utf8(periodicMsg).c_str() << std::endl;
185                                 server->SendChatMessage(PEER_ID_INEXISTENT, periodicMsg);
186                                 break;
187                         }
188                 }
189         }
190
191         m_timer -= dtime;
192         if (m_timer < 0.0f) {
193                 m_timer = 0.0f;
194                 is_requested = true;
195         }
196 }
197
198 std::wstring Server::ShutdownState::getShutdownTimerMessage() const
199 {
200         std::wstringstream ws;
201         ws << L"*** Server shutting down in "
202                 << duration_to_string(myround(m_timer)).c_str() << ".";
203         return ws.str();
204 }
205
206 /*
207         Server
208 */
209
210 Server::Server(
211                 const std::string &path_world,
212                 const SubgameSpec &gamespec,
213                 bool simple_singleplayer_mode,
214                 Address bind_addr,
215                 bool dedicated,
216                 ChatInterface *iface
217         ):
218         m_bind_addr(bind_addr),
219         m_path_world(path_world),
220         m_gamespec(gamespec),
221         m_simple_singleplayer_mode(simple_singleplayer_mode),
222         m_dedicated(dedicated),
223         m_async_fatal_error(""),
224         m_con(std::make_shared<con::Connection>(PROTOCOL_ID,
225                         512,
226                         CONNECTION_TIMEOUT,
227                         m_bind_addr.isIPv6(),
228                         this)),
229         m_itemdef(createItemDefManager()),
230         m_nodedef(createNodeDefManager()),
231         m_craftdef(createCraftDefManager()),
232         m_thread(new ServerThread(this)),
233         m_clients(m_con),
234         m_admin_chat(iface),
235         m_modchannel_mgr(new ModChannelMgr())
236 {
237         if (m_path_world.empty())
238                 throw ServerError("Supplied empty world path");
239
240         if (!gamespec.isValid())
241                 throw ServerError("Supplied invalid gamespec");
242
243 #if USE_PROMETHEUS
244         m_metrics_backend = std::unique_ptr<MetricsBackend>(createPrometheusMetricsBackend());
245 #else
246         m_metrics_backend = std::unique_ptr<MetricsBackend>(new MetricsBackend());
247 #endif
248
249         m_uptime_counter = m_metrics_backend->addCounter("minetest_core_server_uptime", "Server uptime (in seconds)");
250         m_player_gauge = m_metrics_backend->addGauge("minetest_core_player_number", "Number of connected players");
251
252         m_timeofday_gauge = m_metrics_backend->addGauge(
253                         "minetest_core_timeofday",
254                         "Time of day value");
255
256         m_lag_gauge = m_metrics_backend->addGauge(
257                         "minetest_core_latency",
258                         "Latency value (in seconds)");
259
260         m_aom_buffer_counter = m_metrics_backend->addCounter(
261                         "minetest_core_aom_generated_count",
262                         "Number of active object messages generated");
263
264         m_packet_recv_counter = m_metrics_backend->addCounter(
265                         "minetest_core_server_packet_recv",
266                         "Processable packets received");
267
268         m_packet_recv_processed_counter = m_metrics_backend->addCounter(
269                         "minetest_core_server_packet_recv_processed",
270                         "Valid received packets processed");
271
272         m_lag_gauge->set(g_settings->getFloat("dedicated_server_step"));
273 }
274
275 Server::~Server()
276 {
277
278         // Send shutdown message
279         SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE,
280                         L"*** Server shutting down"));
281
282         if (m_env) {
283                 MutexAutoLock envlock(m_env_mutex);
284
285                 infostream << "Server: Saving players" << std::endl;
286                 m_env->saveLoadedPlayers();
287
288                 infostream << "Server: Kicking players" << std::endl;
289                 std::string kick_msg;
290                 bool reconnect = false;
291                 if (isShutdownRequested()) {
292                         reconnect = m_shutdown_state.should_reconnect;
293                         kick_msg = m_shutdown_state.message;
294                 }
295                 if (kick_msg.empty()) {
296                         kick_msg = g_settings->get("kick_msg_shutdown");
297                 }
298                 m_env->saveLoadedPlayers(true);
299                 m_env->kickAllPlayers(SERVER_ACCESSDENIED_SHUTDOWN,
300                         kick_msg, reconnect);
301         }
302
303         actionstream << "Server: Shutting down" << std::endl;
304
305         // Do this before stopping the server in case mapgen callbacks need to access
306         // server-controlled resources (like ModStorages). Also do them before
307         // shutdown callbacks since they may modify state that is finalized in a
308         // callback.
309         if (m_emerge)
310                 m_emerge->stopThreads();
311
312         if (m_env) {
313                 MutexAutoLock envlock(m_env_mutex);
314
315                 // Execute script shutdown hooks
316                 infostream << "Executing shutdown hooks" << std::endl;
317                 m_script->on_shutdown();
318
319                 infostream << "Server: Saving environment metadata" << std::endl;
320                 m_env->saveMeta();
321         }
322
323         // Stop threads
324         if (m_thread) {
325                 stop();
326                 delete m_thread;
327         }
328
329         // Delete things in the reverse order of creation
330         delete m_emerge;
331         delete m_env;
332         delete m_rollback;
333         delete m_banmanager;
334         delete m_itemdef;
335         delete m_nodedef;
336         delete m_craftdef;
337
338         // Deinitialize scripting
339         infostream << "Server: Deinitializing scripting" << std::endl;
340         delete m_script;
341
342         while (!m_unsent_map_edit_queue.empty()) {
343                 delete m_unsent_map_edit_queue.front();
344                 m_unsent_map_edit_queue.pop();
345         }
346 }
347
348 void Server::init()
349 {
350         infostream << "Server created for gameid \"" << m_gamespec.id << "\"";
351         if (m_simple_singleplayer_mode)
352                 infostream << " in simple singleplayer mode" << std::endl;
353         else
354                 infostream << std::endl;
355         infostream << "- world:  " << m_path_world << std::endl;
356         infostream << "- game:   " << m_gamespec.path << std::endl;
357
358         // Create world if it doesn't exist
359         if (!loadGameConfAndInitWorld(m_path_world, m_gamespec))
360                 throw ServerError("Failed to initialize world");
361
362         // Create emerge manager
363         m_emerge = new EmergeManager(this);
364
365         // Create ban manager
366         std::string ban_path = m_path_world + DIR_DELIM "ipban.txt";
367         m_banmanager = new BanManager(ban_path);
368
369         m_modmgr = std::unique_ptr<ServerModManager>(new ServerModManager(m_path_world));
370         std::vector<ModSpec> unsatisfied_mods = m_modmgr->getUnsatisfiedMods();
371         // complain about mods with unsatisfied dependencies
372         if (!m_modmgr->isConsistent()) {
373                 m_modmgr->printUnsatisfiedModsError();
374         }
375
376         //lock environment
377         MutexAutoLock envlock(m_env_mutex);
378
379         // Create the Map (loads map_meta.txt, overriding configured mapgen params)
380         ServerMap *servermap = new ServerMap(m_path_world, this, m_emerge, m_metrics_backend.get());
381
382         // Initialize scripting
383         infostream << "Server: Initializing Lua" << std::endl;
384
385         m_script = new ServerScripting(this);
386
387         // Must be created before mod loading because we have some inventory creation
388         m_inventory_mgr = std::unique_ptr<ServerInventoryManager>(new ServerInventoryManager());
389
390         m_script->loadMod(getBuiltinLuaPath() + DIR_DELIM "init.lua", BUILTIN_MOD_NAME);
391
392         m_modmgr->loadMods(m_script);
393
394         // Read Textures and calculate sha1 sums
395         fillMediaCache();
396
397         // Apply item aliases in the node definition manager
398         m_nodedef->updateAliases(m_itemdef);
399
400         // Apply texture overrides from texturepack/override.txt
401         std::vector<std::string> paths;
402         fs::GetRecursiveDirs(paths, g_settings->get("texture_path"));
403         fs::GetRecursiveDirs(paths, m_gamespec.path + DIR_DELIM + "textures");
404         for (const std::string &path : paths) {
405                 TextureOverrideSource override_source(path + DIR_DELIM + "override.txt");
406                 m_nodedef->applyTextureOverrides(override_source.getNodeTileOverrides());
407                 m_itemdef->applyTextureOverrides(override_source.getItemTextureOverrides());
408         }
409
410         m_nodedef->setNodeRegistrationStatus(true);
411
412         // Perform pending node name resolutions
413         m_nodedef->runNodeResolveCallbacks();
414
415         // unmap node names in cross-references
416         m_nodedef->resolveCrossrefs();
417
418         // init the recipe hashes to speed up crafting
419         m_craftdef->initHashes(this);
420
421         // Initialize Environment
422         m_env = new ServerEnvironment(servermap, m_script, this, m_path_world);
423
424         m_inventory_mgr->setEnv(m_env);
425         m_clients.setEnv(m_env);
426
427         if (!servermap->settings_mgr.makeMapgenParams())
428                 FATAL_ERROR("Couldn't create any mapgen type");
429
430         // Initialize mapgens
431         m_emerge->initMapgens(servermap->getMapgenParams());
432
433         if (g_settings->getBool("enable_rollback_recording")) {
434                 // Create rollback manager
435                 m_rollback = new RollbackManager(m_path_world, this);
436         }
437
438         // Give environment reference to scripting api
439         m_script->initializeEnvironment(m_env);
440
441         // Register us to receive map edit events
442         servermap->addEventReceiver(this);
443
444         m_env->loadMeta();
445
446         // Those settings can be overwritten in world.mt, they are
447         // intended to be cached after environment loading.
448         m_liquid_transform_every = g_settings->getFloat("liquid_update");
449         m_max_chatmessage_length = g_settings->getU16("chat_message_max_size");
450         m_csm_restriction_flags = g_settings->getU64("csm_restriction_flags");
451         m_csm_restriction_noderange = g_settings->getU32("csm_restriction_noderange");
452 }
453
454 void Server::start()
455 {
456         init();
457
458         infostream << "Starting server on " << m_bind_addr.serializeString()
459                         << "..." << std::endl;
460
461         // Stop thread if already running
462         m_thread->stop();
463
464         // Initialize connection
465         m_con->SetTimeoutMs(30);
466         m_con->Serve(m_bind_addr);
467
468         // Start thread
469         m_thread->start();
470
471         // ASCII art for the win!
472         std::cerr
473                 << "        .__               __                   __   " << std::endl
474                 << "  _____ |__| ____   _____/  |_  ____   _______/  |_ " << std::endl
475                 << " /     \\|  |/    \\_/ __ \\   __\\/ __ \\ /  ___/\\   __\\" << std::endl
476                 << "|  Y Y  \\  |   |  \\  ___/|  | \\  ___/ \\___ \\  |  |  " << std::endl
477                 << "|__|_|  /__|___|  /\\___  >__|  \\___  >____  > |__|  " << std::endl
478                 << "      \\/        \\/     \\/          \\/     \\/        " << std::endl;
479         actionstream << "World at [" << m_path_world << "]" << std::endl;
480         actionstream << "Server for gameid=\"" << m_gamespec.id
481                         << "\" listening on " << m_bind_addr.serializeString() << ":"
482                         << m_bind_addr.getPort() << "." << std::endl;
483 }
484
485 void Server::stop()
486 {
487         infostream<<"Server: Stopping and waiting threads"<<std::endl;
488
489         // Stop threads (set run=false first so both start stopping)
490         m_thread->stop();
491         //m_emergethread.setRun(false);
492         m_thread->wait();
493         //m_emergethread.stop();
494
495         infostream<<"Server: Threads stopped"<<std::endl;
496 }
497
498 void Server::step(float dtime)
499 {
500         // Limit a bit
501         if (dtime > 2.0)
502                 dtime = 2.0;
503         {
504                 MutexAutoLock lock(m_step_dtime_mutex);
505                 m_step_dtime += dtime;
506         }
507         // Throw if fatal error occurred in thread
508         std::string async_err = m_async_fatal_error.get();
509         if (!async_err.empty()) {
510                 if (!m_simple_singleplayer_mode) {
511                         m_env->kickAllPlayers(SERVER_ACCESSDENIED_CRASH,
512                                 g_settings->get("kick_msg_crash"),
513                                 g_settings->getBool("ask_reconnect_on_crash"));
514                 }
515                 throw ServerError("AsyncErr: " + async_err);
516         }
517 }
518
519 void Server::AsyncRunStep(bool initial_step)
520 {
521
522         float dtime;
523         {
524                 MutexAutoLock lock1(m_step_dtime_mutex);
525                 dtime = m_step_dtime;
526         }
527
528         {
529                 // Send blocks to clients
530                 SendBlocks(dtime);
531         }
532
533         if((dtime < 0.001) && !initial_step)
534                 return;
535
536         ScopeProfiler sp(g_profiler, "Server::AsyncRunStep()", SPT_AVG);
537
538         {
539                 MutexAutoLock lock1(m_step_dtime_mutex);
540                 m_step_dtime -= dtime;
541         }
542
543         /*
544                 Update uptime
545         */
546         m_uptime_counter->increment(dtime);
547
548         handlePeerChanges();
549
550         /*
551                 Update time of day and overall game time
552         */
553         m_env->setTimeOfDaySpeed(g_settings->getFloat("time_speed"));
554
555         /*
556                 Send to clients at constant intervals
557         */
558
559         m_time_of_day_send_timer -= dtime;
560         if (m_time_of_day_send_timer < 0.0) {
561                 m_time_of_day_send_timer = g_settings->getFloat("time_send_interval");
562                 u16 time = m_env->getTimeOfDay();
563                 float time_speed = g_settings->getFloat("time_speed");
564                 SendTimeOfDay(PEER_ID_INEXISTENT, time, time_speed);
565
566                 m_timeofday_gauge->set(time);
567         }
568
569         {
570                 MutexAutoLock lock(m_env_mutex);
571                 // Figure out and report maximum lag to environment
572                 float max_lag = m_env->getMaxLagEstimate();
573                 max_lag *= 0.9998; // Decrease slowly (about half per 5 minutes)
574                 if(dtime > max_lag){
575                         if(dtime > 0.1 && dtime > max_lag * 2.0)
576                                 infostream<<"Server: Maximum lag peaked to "<<dtime
577                                                 <<" s"<<std::endl;
578                         max_lag = dtime;
579                 }
580                 m_env->reportMaxLagEstimate(max_lag);
581                 // Step environment
582                 m_env->step(dtime);
583         }
584
585         static const float map_timer_and_unload_dtime = 2.92;
586         if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime))
587         {
588                 MutexAutoLock lock(m_env_mutex);
589                 // Run Map's timers and unload unused data
590                 ScopeProfiler sp(g_profiler, "Server: map timer and unload");
591                 m_env->getMap().timerUpdate(map_timer_and_unload_dtime,
592                         g_settings->getFloat("server_unload_unused_data_timeout"),
593                         U32_MAX);
594         }
595
596         /*
597                 Listen to the admin chat, if available
598         */
599         if (m_admin_chat) {
600                 if (!m_admin_chat->command_queue.empty()) {
601                         MutexAutoLock lock(m_env_mutex);
602                         while (!m_admin_chat->command_queue.empty()) {
603                                 ChatEvent *evt = m_admin_chat->command_queue.pop_frontNoEx();
604                                 handleChatInterfaceEvent(evt);
605                                 delete evt;
606                         }
607                 }
608                 m_admin_chat->outgoing_queue.push_back(
609                         new ChatEventTimeInfo(m_env->getGameTime(), m_env->getTimeOfDay()));
610         }
611
612         /*
613                 Do background stuff
614         */
615
616         /* Transform liquids */
617         m_liquid_transform_timer += dtime;
618         if(m_liquid_transform_timer >= m_liquid_transform_every)
619         {
620                 m_liquid_transform_timer -= m_liquid_transform_every;
621
622                 MutexAutoLock lock(m_env_mutex);
623
624                 ScopeProfiler sp(g_profiler, "Server: liquid transform");
625
626                 std::map<v3s16, MapBlock*> modified_blocks;
627                 m_env->getMap().transformLiquids(modified_blocks, m_env);
628
629                 /*
630                         Set the modified blocks unsent for all the clients
631                 */
632                 if (!modified_blocks.empty()) {
633                         SetBlocksNotSent(modified_blocks);
634                 }
635         }
636         m_clients.step(dtime);
637
638         m_lag_gauge->increment((m_lag_gauge->get() > dtime ? -1 : 1) * dtime/100);
639 #if USE_CURL
640         // send masterserver announce
641         {
642                 float &counter = m_masterserver_timer;
643                 if (!isSingleplayer() && (!counter || counter >= 300.0) &&
644                                 g_settings->getBool("server_announce")) {
645                         ServerList::sendAnnounce(counter ? ServerList::AA_UPDATE :
646                                                 ServerList::AA_START,
647                                         m_bind_addr.getPort(),
648                                         m_clients.getPlayerNames(),
649                                         m_uptime_counter->get(),
650                                         m_env->getGameTime(),
651                                         m_lag_gauge->get(),
652                                         m_gamespec.id,
653                                         Mapgen::getMapgenName(m_emerge->mgparams->mgtype),
654                                         m_modmgr->getMods(),
655                                         m_dedicated);
656                         counter = 0.01;
657                 }
658                 counter += dtime;
659         }
660 #endif
661
662         /*
663                 Check added and deleted active objects
664         */
665         {
666                 //infostream<<"Server: Checking added and deleted active objects"<<std::endl;
667                 MutexAutoLock envlock(m_env_mutex);
668
669                 m_clients.lock();
670                 const RemoteClientMap &clients = m_clients.getClientList();
671                 ScopeProfiler sp(g_profiler, "Server: update objects within range");
672
673                 m_player_gauge->set(clients.size());
674                 for (const auto &client_it : clients) {
675                         RemoteClient *client = client_it.second;
676
677                         if (client->getState() < CS_DefinitionsSent)
678                                 continue;
679
680                         // This can happen if the client times out somehow
681                         if (!m_env->getPlayer(client->peer_id))
682                                 continue;
683
684                         PlayerSAO *playersao = getPlayerSAO(client->peer_id);
685                         if (!playersao)
686                                 continue;
687
688                         SendActiveObjectRemoveAdd(client, playersao);
689                 }
690                 m_clients.unlock();
691
692                 // Save mod storages if modified
693                 m_mod_storage_save_timer -= dtime;
694                 if (m_mod_storage_save_timer <= 0.0f) {
695                         m_mod_storage_save_timer = g_settings->getFloat("server_map_save_interval");
696                         int n = 0;
697                         for (std::unordered_map<std::string, ModMetadata *>::const_iterator
698                                 it = m_mod_storages.begin(); it != m_mod_storages.end(); ++it) {
699                                 if (it->second->isModified()) {
700                                         it->second->save(getModStoragePath());
701                                         n++;
702                                 }
703                         }
704                         if (n > 0)
705                                 infostream << "Saved " << n << " modified mod storages." << std::endl;
706                 }
707         }
708
709         /*
710                 Send object messages
711         */
712         {
713                 MutexAutoLock envlock(m_env_mutex);
714                 ScopeProfiler sp(g_profiler, "Server: send SAO messages");
715
716                 // Key = object id
717                 // Value = data sent by object
718                 std::unordered_map<u16, std::vector<ActiveObjectMessage>*> buffered_messages;
719
720                 // Get active object messages from environment
721                 for(;;) {
722                         ActiveObjectMessage aom = m_env->getActiveObjectMessage();
723                         if (aom.id == 0)
724                                 break;
725
726                         std::vector<ActiveObjectMessage>* message_list = nullptr;
727                         std::unordered_map<u16, std::vector<ActiveObjectMessage>* >::iterator n;
728                         n = buffered_messages.find(aom.id);
729                         if (n == buffered_messages.end()) {
730                                 message_list = new std::vector<ActiveObjectMessage>;
731                                 buffered_messages[aom.id] = message_list;
732                         }
733                         else {
734                                 message_list = n->second;
735                         }
736                         message_list->push_back(aom);
737                 }
738
739                 m_aom_buffer_counter->increment(buffered_messages.size());
740
741                 m_clients.lock();
742                 const RemoteClientMap &clients = m_clients.getClientList();
743                 // Route data to every client
744                 for (const auto &client_it : clients) {
745                         RemoteClient *client = client_it.second;
746                         PlayerSAO *player = getPlayerSAO(client->peer_id);
747                         std::string reliable_data;
748                         std::string unreliable_data;
749                         // Go through all objects in message buffer
750                         for (const auto &buffered_message : buffered_messages) {
751                                 // If object does not exist or is not known by client, skip it
752                                 u16 id = buffered_message.first;
753                                 ServerActiveObject *sao = m_env->getActiveObject(id);
754                                 if (!sao || client->m_known_objects.find(id) == client->m_known_objects.end())
755                                         continue;
756
757                                 // Get message list of object
758                                 std::vector<ActiveObjectMessage>* list = buffered_message.second;
759                                 // Go through every message
760                                 for (const ActiveObjectMessage &aom : *list) {
761                                         // Send position updates to players who do not see the attachment
762                                         if (aom.datastring[0] == AO_CMD_UPDATE_POSITION) {
763                                                 if (sao->getId() == player->getId())
764                                                         continue;
765
766                                                 // Do not send position updates for attached players
767                                                 // as long the parent is known to the client
768                                                 ServerActiveObject *parent = sao->getParent();
769                                                 if (parent && client->m_known_objects.find(parent->getId()) !=
770                                                                 client->m_known_objects.end())
771                                                         continue;
772                                         }
773                                         // Compose the full new data with header
774                                         std::string new_data;
775                                         // Add object id
776                                         char buf[2];
777                                         writeU16((u8*)&buf[0], aom.id);
778                                         new_data.append(buf, 2);
779                                         // Add data
780                                         new_data += serializeString(aom.datastring);
781                                         // Add data to buffer
782                                         if (aom.reliable)
783                                                 reliable_data += new_data;
784                                         else
785                                                 unreliable_data += new_data;
786                                 }
787                         }
788                         /*
789                                 reliable_data and unreliable_data are now ready.
790                                 Send them.
791                         */
792                         if (!reliable_data.empty()) {
793                                 SendActiveObjectMessages(client->peer_id, reliable_data);
794                         }
795
796                         if (!unreliable_data.empty()) {
797                                 SendActiveObjectMessages(client->peer_id, unreliable_data, false);
798                         }
799                 }
800                 m_clients.unlock();
801
802                 // Clear buffered_messages
803                 for (auto &buffered_message : buffered_messages) {
804                         delete buffered_message.second;
805                 }
806         }
807
808         /*
809                 Send queued-for-sending map edit events.
810         */
811         {
812                 // We will be accessing the environment
813                 MutexAutoLock lock(m_env_mutex);
814
815                 // Don't send too many at a time
816                 //u32 count = 0;
817
818                 // Single change sending is disabled if queue size is not small
819                 bool disable_single_change_sending = false;
820                 if(m_unsent_map_edit_queue.size() >= 4)
821                         disable_single_change_sending = true;
822
823                 int event_count = m_unsent_map_edit_queue.size();
824
825                 // We'll log the amount of each
826                 Profiler prof;
827
828                 std::list<v3s16> node_meta_updates;
829
830                 while (!m_unsent_map_edit_queue.empty()) {
831                         MapEditEvent* event = m_unsent_map_edit_queue.front();
832                         m_unsent_map_edit_queue.pop();
833
834                         // Players far away from the change are stored here.
835                         // Instead of sending the changes, MapBlocks are set not sent
836                         // for them.
837                         std::unordered_set<u16> far_players;
838
839                         switch (event->type) {
840                         case MEET_ADDNODE:
841                         case MEET_SWAPNODE:
842                                 prof.add("MEET_ADDNODE", 1);
843                                 sendAddNode(event->p, event->n, &far_players,
844                                                 disable_single_change_sending ? 5 : 30,
845                                                 event->type == MEET_ADDNODE);
846                                 break;
847                         case MEET_REMOVENODE:
848                                 prof.add("MEET_REMOVENODE", 1);
849                                 sendRemoveNode(event->p, &far_players,
850                                                 disable_single_change_sending ? 5 : 30);
851                                 break;
852                         case MEET_BLOCK_NODE_METADATA_CHANGED: {
853                                 prof.add("MEET_BLOCK_NODE_METADATA_CHANGED", 1);
854                                 if (!event->is_private_change) {
855                                         // Don't send the change yet. Collect them to eliminate dupes.
856                                         node_meta_updates.remove(event->p);
857                                         node_meta_updates.push_back(event->p);
858                                 }
859
860                                 if (MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(
861                                                 getNodeBlockPos(event->p))) {
862                                         block->raiseModified(MOD_STATE_WRITE_NEEDED,
863                                                 MOD_REASON_REPORT_META_CHANGE);
864                                 }
865                                 break;
866                         }
867                         case MEET_OTHER:
868                                 prof.add("MEET_OTHER", 1);
869                                 for (const v3s16 &modified_block : event->modified_blocks) {
870                                         m_clients.markBlockposAsNotSent(modified_block);
871                                 }
872                                 break;
873                         default:
874                                 prof.add("unknown", 1);
875                                 warningstream << "Server: Unknown MapEditEvent "
876                                                 << ((u32)event->type) << std::endl;
877                                 break;
878                         }
879
880                         /*
881                                 Set blocks not sent to far players
882                         */
883                         if (!far_players.empty()) {
884                                 // Convert list format to that wanted by SetBlocksNotSent
885                                 std::map<v3s16, MapBlock*> modified_blocks2;
886                                 for (const v3s16 &modified_block : event->modified_blocks) {
887                                         modified_blocks2[modified_block] =
888                                                         m_env->getMap().getBlockNoCreateNoEx(modified_block);
889                                 }
890
891                                 // Set blocks not sent
892                                 for (const u16 far_player : far_players) {
893                                         if (RemoteClient *client = getClient(far_player))
894                                                 client->SetBlocksNotSent(modified_blocks2);
895                                 }
896                         }
897
898                         delete event;
899                 }
900
901                 if (event_count >= 5) {
902                         infostream << "Server: MapEditEvents:" << std::endl;
903                         prof.print(infostream);
904                 } else if (event_count != 0) {
905                         verbosestream << "Server: MapEditEvents:" << std::endl;
906                         prof.print(verbosestream);
907                 }
908
909                 // Send all metadata updates
910                 if (node_meta_updates.size())
911                         sendMetadataChanged(node_meta_updates);
912         }
913
914         /*
915                 Trigger emergethread (it somehow gets to a non-triggered but
916                 bysy state sometimes)
917         */
918         {
919                 float &counter = m_emergethread_trigger_timer;
920                 counter += dtime;
921                 if (counter >= 2.0) {
922                         counter = 0.0;
923
924                         m_emerge->startThreads();
925                 }
926         }
927
928         // Save map, players and auth stuff
929         {
930                 float &counter = m_savemap_timer;
931                 counter += dtime;
932                 static thread_local const float save_interval =
933                         g_settings->getFloat("server_map_save_interval");
934                 if (counter >= save_interval) {
935                         counter = 0.0;
936                         MutexAutoLock lock(m_env_mutex);
937
938                         ScopeProfiler sp(g_profiler, "Server: map saving (sum)");
939
940                         // Save ban file
941                         if (m_banmanager->isModified()) {
942                                 m_banmanager->save();
943                         }
944
945                         // Save changed parts of map
946                         m_env->getMap().save(MOD_STATE_WRITE_NEEDED);
947
948                         // Save players
949                         m_env->saveLoadedPlayers();
950
951                         // Save environment metadata
952                         m_env->saveMeta();
953                 }
954         }
955
956         m_shutdown_state.tick(dtime, this);
957 }
958
959 void Server::Receive()
960 {
961         NetworkPacket pkt;
962         session_t peer_id;
963         bool first = true;
964         for (;;) {
965                 pkt.clear();
966                 peer_id = 0;
967                 try {
968                         /*
969                                 In the first iteration *wait* for a packet, afterwards process
970                                 all packets that are immediately available (no waiting).
971                         */
972                         if (first) {
973                                 m_con->Receive(&pkt);
974                                 first = false;
975                         } else {
976                                 if (!m_con->TryReceive(&pkt))
977                                         return;
978                         }
979
980                         peer_id = pkt.getPeerId();
981                         m_packet_recv_counter->increment();
982                         ProcessData(&pkt);
983                         m_packet_recv_processed_counter->increment();
984                 } catch (const con::InvalidIncomingDataException &e) {
985                         infostream << "Server::Receive(): InvalidIncomingDataException: what()="
986                                         << e.what() << std::endl;
987                 } catch (const SerializationError &e) {
988                         infostream << "Server::Receive(): SerializationError: what()="
989                                         << e.what() << std::endl;
990                 } catch (const ClientStateError &e) {
991                         errorstream << "ProcessData: peer=" << peer_id << " what()="
992                                          << e.what() << std::endl;
993                         DenyAccess_Legacy(peer_id, L"Your client sent something server didn't expect."
994                                         L"Try reconnecting or updating your client");
995                 } catch (const con::PeerNotFoundException &e) {
996                         // Do nothing
997                 } catch (const con::NoIncomingDataException &e) {
998                         return;
999                 }
1000         }
1001 }
1002
1003 PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
1004 {
1005         std::string playername;
1006         PlayerSAO *playersao = NULL;
1007         m_clients.lock();
1008         try {
1009                 RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone);
1010                 if (client) {
1011                         playername = client->getName();
1012                         playersao = emergePlayer(playername.c_str(), peer_id, client->net_proto_version);
1013                 }
1014         } catch (std::exception &e) {
1015                 m_clients.unlock();
1016                 throw;
1017         }
1018         m_clients.unlock();
1019
1020         RemotePlayer *player = m_env->getPlayer(playername.c_str());
1021
1022         // If failed, cancel
1023         if (!playersao || !player) {
1024                 if (player && player->getPeerId() != PEER_ID_INEXISTENT) {
1025                         actionstream << "Server: Failed to emerge player \"" << playername
1026                                         << "\" (player allocated to an another client)" << std::endl;
1027                         DenyAccess_Legacy(peer_id, L"Another client is connected with this "
1028                                         L"name. If your client closed unexpectedly, try again in "
1029                                         L"a minute.");
1030                 } else {
1031                         errorstream << "Server: " << playername << ": Failed to emerge player"
1032                                         << std::endl;
1033                         DenyAccess_Legacy(peer_id, L"Could not allocate player.");
1034                 }
1035                 return NULL;
1036         }
1037
1038         /*
1039                 Send complete position information
1040         */
1041         SendMovePlayer(peer_id);
1042
1043         // Send privileges
1044         SendPlayerPrivileges(peer_id);
1045
1046         // Send inventory formspec
1047         SendPlayerInventoryFormspec(peer_id);
1048
1049         // Send inventory
1050         SendInventory(playersao, false);
1051
1052         // Send HP or death screen
1053         if (playersao->isDead())
1054                 SendDeathscreen(peer_id, false, v3f(0,0,0));
1055         else
1056                 SendPlayerHPOrDie(playersao,
1057                                 PlayerHPChangeReason(PlayerHPChangeReason::SET_HP));
1058
1059         // Send Breath
1060         SendPlayerBreath(playersao);
1061
1062         /*
1063                 Print out action
1064         */
1065         {
1066                 Address addr = getPeerAddress(player->getPeerId());
1067                 std::string ip_str = addr.serializeString();
1068                 const std::vector<std::string> &names = m_clients.getPlayerNames();
1069
1070                 actionstream << player->getName() << " [" << ip_str << "] joins game. List of players: ";
1071
1072                 for (const std::string &name : names) {
1073                         actionstream << name << " ";
1074                 }
1075
1076                 actionstream << player->getName() <<std::endl;
1077         }
1078         return playersao;
1079 }
1080
1081 inline void Server::handleCommand(NetworkPacket *pkt)
1082 {
1083         const ToServerCommandHandler &opHandle = toServerCommandTable[pkt->getCommand()];
1084         (this->*opHandle.handler)(pkt);
1085 }
1086
1087 void Server::ProcessData(NetworkPacket *pkt)
1088 {
1089         // Environment is locked first.
1090         MutexAutoLock envlock(m_env_mutex);
1091
1092         ScopeProfiler sp(g_profiler, "Server: Process network packet (sum)");
1093         u32 peer_id = pkt->getPeerId();
1094
1095         try {
1096                 Address address = getPeerAddress(peer_id);
1097                 std::string addr_s = address.serializeString();
1098
1099                 if(m_banmanager->isIpBanned(addr_s)) {
1100                         std::string ban_name = m_banmanager->getBanName(addr_s);
1101                         infostream << "Server: A banned client tried to connect from "
1102                                         << addr_s << "; banned name was "
1103                                         << ban_name << std::endl;
1104                         // This actually doesn't seem to transfer to the client
1105                         DenyAccess_Legacy(peer_id, L"Your ip is banned. Banned name was "
1106                                         + utf8_to_wide(ban_name));
1107                         return;
1108                 }
1109         }
1110         catch(con::PeerNotFoundException &e) {
1111                 /*
1112                  * no peer for this packet found
1113                  * most common reason is peer timeout, e.g. peer didn't
1114                  * respond for some time, your server was overloaded or
1115                  * things like that.
1116                  */
1117                 infostream << "Server::ProcessData(): Canceling: peer "
1118                                 << peer_id << " not found" << std::endl;
1119                 return;
1120         }
1121
1122         try {
1123                 ToServerCommand command = (ToServerCommand) pkt->getCommand();
1124
1125                 // Command must be handled into ToServerCommandHandler
1126                 if (command >= TOSERVER_NUM_MSG_TYPES) {
1127                         infostream << "Server: Ignoring unknown command "
1128                                          << command << std::endl;
1129                         return;
1130                 }
1131
1132                 if (toServerCommandTable[command].state == TOSERVER_STATE_NOT_CONNECTED) {
1133                         handleCommand(pkt);
1134                         return;
1135                 }
1136
1137                 u8 peer_ser_ver = getClient(peer_id, CS_InitDone)->serialization_version;
1138
1139                 if(peer_ser_ver == SER_FMT_VER_INVALID) {
1140                         errorstream << "Server::ProcessData(): Cancelling: Peer"
1141                                         " serialization format invalid or not initialized."
1142                                         " Skipping incoming command=" << command << std::endl;
1143                         return;
1144                 }
1145
1146                 /* Handle commands related to client startup */
1147                 if (toServerCommandTable[command].state == TOSERVER_STATE_STARTUP) {
1148                         handleCommand(pkt);
1149                         return;
1150                 }
1151
1152                 if (m_clients.getClientState(peer_id) < CS_Active) {
1153                         if (command == TOSERVER_PLAYERPOS) return;
1154
1155                         errorstream << "Got packet command: " << command << " for peer id "
1156                                         << peer_id << " but client isn't active yet. Dropping packet "
1157                                         << std::endl;
1158                         return;
1159                 }
1160
1161                 handleCommand(pkt);
1162         } catch (SendFailedException &e) {
1163                 errorstream << "Server::ProcessData(): SendFailedException: "
1164                                 << "what=" << e.what()
1165                                 << std::endl;
1166         } catch (PacketError &e) {
1167                 actionstream << "Server::ProcessData(): PacketError: "
1168                                 << "what=" << e.what()
1169                                 << std::endl;
1170         }
1171 }
1172
1173 void Server::setTimeOfDay(u32 time)
1174 {
1175         m_env->setTimeOfDay(time);
1176         m_time_of_day_send_timer = 0;
1177 }
1178
1179 void Server::onMapEditEvent(const MapEditEvent &event)
1180 {
1181         if (m_ignore_map_edit_events_area.contains(event.getArea()))
1182                 return;
1183
1184         m_unsent_map_edit_queue.push(new MapEditEvent(event));
1185 }
1186
1187 void Server::SetBlocksNotSent(std::map<v3s16, MapBlock *>& block)
1188 {
1189         std::vector<session_t> clients = m_clients.getClientIDs();
1190         m_clients.lock();
1191         // Set the modified blocks unsent for all the clients
1192         for (const session_t client_id : clients) {
1193                         if (RemoteClient *client = m_clients.lockedGetClientNoEx(client_id))
1194                                 client->SetBlocksNotSent(block);
1195         }
1196         m_clients.unlock();
1197 }
1198
1199 void Server::peerAdded(con::Peer *peer)
1200 {
1201         verbosestream<<"Server::peerAdded(): peer->id="
1202                         <<peer->id<<std::endl;
1203
1204         m_peer_change_queue.push(con::PeerChange(con::PEER_ADDED, peer->id, false));
1205 }
1206
1207 void Server::deletingPeer(con::Peer *peer, bool timeout)
1208 {
1209         verbosestream<<"Server::deletingPeer(): peer->id="
1210                         <<peer->id<<", timeout="<<timeout<<std::endl;
1211
1212         m_clients.event(peer->id, CSE_Disconnect);
1213         m_peer_change_queue.push(con::PeerChange(con::PEER_REMOVED, peer->id, timeout));
1214 }
1215
1216 bool Server::getClientConInfo(session_t peer_id, con::rtt_stat_type type, float* retval)
1217 {
1218         *retval = m_con->getPeerStat(peer_id,type);
1219         return *retval != -1;
1220 }
1221
1222 bool Server::getClientInfo(
1223                 session_t    peer_id,
1224                 ClientState* state,
1225                 u32*         uptime,
1226                 u8*          ser_vers,
1227                 u16*         prot_vers,
1228                 u8*          major,
1229                 u8*          minor,
1230                 u8*          patch,
1231                 std::string* vers_string,
1232                 std::string* lang_code
1233         )
1234 {
1235         *state = m_clients.getClientState(peer_id);
1236         m_clients.lock();
1237         RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_Invalid);
1238
1239         if (!client) {
1240                 m_clients.unlock();
1241                 return false;
1242         }
1243
1244         *uptime = client->uptime();
1245         *ser_vers = client->serialization_version;
1246         *prot_vers = client->net_proto_version;
1247
1248         *major = client->getMajor();
1249         *minor = client->getMinor();
1250         *patch = client->getPatch();
1251         *vers_string = client->getFull();
1252         *lang_code = client->getLangCode();
1253
1254         m_clients.unlock();
1255
1256         return true;
1257 }
1258
1259 void Server::handlePeerChanges()
1260 {
1261         while(!m_peer_change_queue.empty())
1262         {
1263                 con::PeerChange c = m_peer_change_queue.front();
1264                 m_peer_change_queue.pop();
1265
1266                 verbosestream<<"Server: Handling peer change: "
1267                                 <<"id="<<c.peer_id<<", timeout="<<c.timeout
1268                                 <<std::endl;
1269
1270                 switch(c.type)
1271                 {
1272                 case con::PEER_ADDED:
1273                         m_clients.CreateClient(c.peer_id);
1274                         break;
1275
1276                 case con::PEER_REMOVED:
1277                         DeleteClient(c.peer_id, c.timeout?CDR_TIMEOUT:CDR_LEAVE);
1278                         break;
1279
1280                 default:
1281                         FATAL_ERROR("Invalid peer change event received!");
1282                         break;
1283                 }
1284         }
1285 }
1286
1287 void Server::printToConsoleOnly(const std::string &text)
1288 {
1289         if (m_admin_chat) {
1290                 m_admin_chat->outgoing_queue.push_back(
1291                         new ChatEventChat("", utf8_to_wide(text)));
1292         } else {
1293                 std::cout << text << std::endl;
1294         }
1295 }
1296
1297 void Server::Send(NetworkPacket *pkt)
1298 {
1299         Send(pkt->getPeerId(), pkt);
1300 }
1301
1302 void Server::Send(session_t peer_id, NetworkPacket *pkt)
1303 {
1304         m_clients.send(peer_id,
1305                 clientCommandFactoryTable[pkt->getCommand()].channel,
1306                 pkt,
1307                 clientCommandFactoryTable[pkt->getCommand()].reliable);
1308 }
1309
1310 void Server::SendMovement(session_t peer_id)
1311 {
1312         std::ostringstream os(std::ios_base::binary);
1313
1314         NetworkPacket pkt(TOCLIENT_MOVEMENT, 12 * sizeof(float), peer_id);
1315
1316         pkt << g_settings->getFloat("movement_acceleration_default");
1317         pkt << g_settings->getFloat("movement_acceleration_air");
1318         pkt << g_settings->getFloat("movement_acceleration_fast");
1319         pkt << g_settings->getFloat("movement_speed_walk");
1320         pkt << g_settings->getFloat("movement_speed_crouch");
1321         pkt << g_settings->getFloat("movement_speed_fast");
1322         pkt << g_settings->getFloat("movement_speed_climb");
1323         pkt << g_settings->getFloat("movement_speed_jump");
1324         pkt << g_settings->getFloat("movement_liquid_fluidity");
1325         pkt << g_settings->getFloat("movement_liquid_fluidity_smooth");
1326         pkt << g_settings->getFloat("movement_liquid_sink");
1327         pkt << g_settings->getFloat("movement_gravity");
1328
1329         Send(&pkt);
1330 }
1331
1332 void Server::SendPlayerHPOrDie(PlayerSAO *playersao, const PlayerHPChangeReason &reason)
1333 {
1334         if (playersao->isImmortal())
1335                 return;
1336
1337         session_t peer_id = playersao->getPeerID();
1338         bool is_alive = playersao->getHP() > 0;
1339
1340         if (is_alive)
1341                 SendPlayerHP(peer_id);
1342         else
1343                 DiePlayer(peer_id, reason);
1344 }
1345
1346 void Server::SendHP(session_t peer_id, u16 hp)
1347 {
1348         NetworkPacket pkt(TOCLIENT_HP, 1, peer_id);
1349         pkt << hp;
1350         Send(&pkt);
1351 }
1352
1353 void Server::SendBreath(session_t peer_id, u16 breath)
1354 {
1355         NetworkPacket pkt(TOCLIENT_BREATH, 2, peer_id);
1356         pkt << (u16) breath;
1357         Send(&pkt);
1358 }
1359
1360 void Server::SendAccessDenied(session_t peer_id, AccessDeniedCode reason,
1361                 const std::string &custom_reason, bool reconnect)
1362 {
1363         assert(reason < SERVER_ACCESSDENIED_MAX);
1364
1365         NetworkPacket pkt(TOCLIENT_ACCESS_DENIED, 1, peer_id);
1366         pkt << (u8)reason;
1367         if (reason == SERVER_ACCESSDENIED_CUSTOM_STRING)
1368                 pkt << custom_reason;
1369         else if (reason == SERVER_ACCESSDENIED_SHUTDOWN ||
1370                         reason == SERVER_ACCESSDENIED_CRASH)
1371                 pkt << custom_reason << (u8)reconnect;
1372         Send(&pkt);
1373 }
1374
1375 void Server::SendAccessDenied_Legacy(session_t peer_id,const std::wstring &reason)
1376 {
1377         NetworkPacket pkt(TOCLIENT_ACCESS_DENIED_LEGACY, 0, peer_id);
1378         pkt << reason;
1379         Send(&pkt);
1380 }
1381
1382 void Server::SendDeathscreen(session_t peer_id, bool set_camera_point_target,
1383                 v3f camera_point_target)
1384 {
1385         NetworkPacket pkt(TOCLIENT_DEATHSCREEN, 1 + sizeof(v3f), peer_id);
1386         pkt << set_camera_point_target << camera_point_target;
1387         Send(&pkt);
1388 }
1389
1390 void Server::SendItemDef(session_t peer_id,
1391                 IItemDefManager *itemdef, u16 protocol_version)
1392 {
1393         NetworkPacket pkt(TOCLIENT_ITEMDEF, 0, peer_id);
1394
1395         /*
1396                 u16 command
1397                 u32 length of the next item
1398                 zlib-compressed serialized ItemDefManager
1399         */
1400         std::ostringstream tmp_os(std::ios::binary);
1401         itemdef->serialize(tmp_os, protocol_version);
1402         std::ostringstream tmp_os2(std::ios::binary);
1403         compressZlib(tmp_os.str(), tmp_os2);
1404         pkt.putLongString(tmp_os2.str());
1405
1406         // Make data buffer
1407         verbosestream << "Server: Sending item definitions to id(" << peer_id
1408                         << "): size=" << pkt.getSize() << std::endl;
1409
1410         Send(&pkt);
1411 }
1412
1413 void Server::SendNodeDef(session_t peer_id,
1414         const NodeDefManager *nodedef, u16 protocol_version)
1415 {
1416         NetworkPacket pkt(TOCLIENT_NODEDEF, 0, peer_id);
1417
1418         /*
1419                 u16 command
1420                 u32 length of the next item
1421                 zlib-compressed serialized NodeDefManager
1422         */
1423         std::ostringstream tmp_os(std::ios::binary);
1424         nodedef->serialize(tmp_os, protocol_version);
1425         std::ostringstream tmp_os2(std::ios::binary);
1426         compressZlib(tmp_os.str(), tmp_os2);
1427
1428         pkt.putLongString(tmp_os2.str());
1429
1430         // Make data buffer
1431         verbosestream << "Server: Sending node definitions to id(" << peer_id
1432                         << "): size=" << pkt.getSize() << std::endl;
1433
1434         Send(&pkt);
1435 }
1436
1437 /*
1438         Non-static send methods
1439 */
1440
1441 void Server::SendInventory(PlayerSAO *sao, bool incremental)
1442 {
1443         RemotePlayer *player = sao->getPlayer();
1444
1445         // Do not send new format to old clients
1446         incremental &= player->protocol_version >= 38;
1447
1448         UpdateCrafting(player);
1449
1450         /*
1451                 Serialize it
1452         */
1453
1454         NetworkPacket pkt(TOCLIENT_INVENTORY, 0, sao->getPeerID());
1455
1456         std::ostringstream os(std::ios::binary);
1457         sao->getInventory()->serialize(os, incremental);
1458         sao->getInventory()->setModified(false);
1459         player->setModified(true);
1460
1461         const std::string &s = os.str();
1462         pkt.putRawString(s.c_str(), s.size());
1463         Send(&pkt);
1464 }
1465
1466 void Server::SendChatMessage(session_t peer_id, const ChatMessage &message)
1467 {
1468         NetworkPacket pkt(TOCLIENT_CHAT_MESSAGE, 0, peer_id);
1469         u8 version = 1;
1470         u8 type = message.type;
1471         pkt << version << type << std::wstring(L"") << message.message << (u64)message.timestamp;
1472
1473         if (peer_id != PEER_ID_INEXISTENT) {
1474                 RemotePlayer *player = m_env->getPlayer(peer_id);
1475                 if (!player)
1476                         return;
1477
1478                 Send(&pkt);
1479         } else {
1480                 m_clients.sendToAll(&pkt);
1481         }
1482 }
1483
1484 void Server::SendShowFormspecMessage(session_t peer_id, const std::string &formspec,
1485         const std::string &formname)
1486 {
1487         NetworkPacket pkt(TOCLIENT_SHOW_FORMSPEC, 0, peer_id);
1488         if (formspec.empty()){
1489                 //the client should close the formspec
1490                 //but make sure there wasn't another one open in meantime
1491                 const auto it = m_formspec_state_data.find(peer_id);
1492                 if (it != m_formspec_state_data.end() && it->second == formname) {
1493                         m_formspec_state_data.erase(peer_id);
1494                 }
1495                 pkt.putLongString("");
1496         } else {
1497                 m_formspec_state_data[peer_id] = formname;
1498                 pkt.putLongString(formspec);
1499         }
1500         pkt << formname;
1501
1502         Send(&pkt);
1503 }
1504
1505 // Spawns a particle on peer with peer_id
1506 void Server::SendSpawnParticle(session_t peer_id, u16 protocol_version,
1507         const ParticleParameters &p)
1508 {
1509         static thread_local const float radius =
1510                         g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE * BS;
1511
1512         if (peer_id == PEER_ID_INEXISTENT) {
1513                 std::vector<session_t> clients = m_clients.getClientIDs();
1514                 const v3f pos = p.pos * BS;
1515                 const float radius_sq = radius * radius;
1516
1517                 for (const session_t client_id : clients) {
1518                         RemotePlayer *player = m_env->getPlayer(client_id);
1519                         if (!player)
1520                                 continue;
1521
1522                         PlayerSAO *sao = player->getPlayerSAO();
1523                         if (!sao)
1524                                 continue;
1525
1526                         // Do not send to distant clients
1527                         if (sao->getBasePosition().getDistanceFromSQ(pos) > radius_sq)
1528                                 continue;
1529
1530                         SendSpawnParticle(client_id, player->protocol_version, p);
1531                 }
1532                 return;
1533         }
1534         assert(protocol_version != 0);
1535
1536         NetworkPacket pkt(TOCLIENT_SPAWN_PARTICLE, 0, peer_id);
1537
1538         {
1539                 // NetworkPacket and iostreams are incompatible...
1540                 std::ostringstream oss(std::ios_base::binary);
1541                 p.serialize(oss, protocol_version);
1542                 pkt.putRawString(oss.str());
1543         }
1544
1545         Send(&pkt);
1546 }
1547
1548 // Adds a ParticleSpawner on peer with peer_id
1549 void Server::SendAddParticleSpawner(session_t peer_id, u16 protocol_version,
1550         const ParticleSpawnerParameters &p, u16 attached_id, u32 id)
1551 {
1552         if (peer_id == PEER_ID_INEXISTENT) {
1553                 std::vector<session_t> clients = m_clients.getClientIDs();
1554                 for (const session_t client_id : clients) {
1555                         RemotePlayer *player = m_env->getPlayer(client_id);
1556                         if (!player)
1557                                 continue;
1558                         SendAddParticleSpawner(client_id, player->protocol_version,
1559                                 p, attached_id, id);
1560                 }
1561                 return;
1562         }
1563         assert(protocol_version != 0);
1564
1565         NetworkPacket pkt(TOCLIENT_ADD_PARTICLESPAWNER, 100, peer_id);
1566
1567         pkt << p.amount << p.time << p.minpos << p.maxpos << p.minvel
1568                 << p.maxvel << p.minacc << p.maxacc << p.minexptime << p.maxexptime
1569                 << p.minsize << p.maxsize << p.collisiondetection;
1570
1571         pkt.putLongString(p.texture);
1572
1573         pkt << id << p.vertical << p.collision_removal << attached_id;
1574         {
1575                 std::ostringstream os(std::ios_base::binary);
1576                 p.animation.serialize(os, protocol_version);
1577                 pkt.putRawString(os.str());
1578         }
1579         pkt << p.glow << p.object_collision;
1580         pkt << p.node.param0 << p.node.param2 << p.node_tile;
1581
1582         Send(&pkt);
1583 }
1584
1585 void Server::SendDeleteParticleSpawner(session_t peer_id, u32 id)
1586 {
1587         NetworkPacket pkt(TOCLIENT_DELETE_PARTICLESPAWNER, 4, peer_id);
1588
1589         pkt << id;
1590
1591         if (peer_id != PEER_ID_INEXISTENT)
1592                 Send(&pkt);
1593         else
1594                 m_clients.sendToAll(&pkt);
1595
1596 }
1597
1598 void Server::SendHUDAdd(session_t peer_id, u32 id, HudElement *form)
1599 {
1600         NetworkPacket pkt(TOCLIENT_HUDADD, 0 , peer_id);
1601
1602         pkt << id << (u8) form->type << form->pos << form->name << form->scale
1603                         << form->text << form->number << form->item << form->dir
1604                         << form->align << form->offset << form->world_pos << form->size
1605                         << form->z_index << form->text2;
1606
1607         Send(&pkt);
1608 }
1609
1610 void Server::SendHUDRemove(session_t peer_id, u32 id)
1611 {
1612         NetworkPacket pkt(TOCLIENT_HUDRM, 4, peer_id);
1613         pkt << id;
1614         Send(&pkt);
1615 }
1616
1617 void Server::SendHUDChange(session_t peer_id, u32 id, HudElementStat stat, void *value)
1618 {
1619         NetworkPacket pkt(TOCLIENT_HUDCHANGE, 0, peer_id);
1620         pkt << id << (u8) stat;
1621
1622         switch (stat) {
1623                 case HUD_STAT_POS:
1624                 case HUD_STAT_SCALE:
1625                 case HUD_STAT_ALIGN:
1626                 case HUD_STAT_OFFSET:
1627                         pkt << *(v2f *) value;
1628                         break;
1629                 case HUD_STAT_NAME:
1630                 case HUD_STAT_TEXT:
1631                 case HUD_STAT_TEXT2:
1632                         pkt << *(std::string *) value;
1633                         break;
1634                 case HUD_STAT_WORLD_POS:
1635                         pkt << *(v3f *) value;
1636                         break;
1637                 case HUD_STAT_SIZE:
1638                         pkt << *(v2s32 *) value;
1639                         break;
1640                 case HUD_STAT_NUMBER:
1641                 case HUD_STAT_ITEM:
1642                 case HUD_STAT_DIR:
1643                 default:
1644                         pkt << *(u32 *) value;
1645                         break;
1646         }
1647
1648         Send(&pkt);
1649 }
1650
1651 void Server::SendHUDSetFlags(session_t peer_id, u32 flags, u32 mask)
1652 {
1653         NetworkPacket pkt(TOCLIENT_HUD_SET_FLAGS, 4 + 4, peer_id);
1654
1655         flags &= ~(HUD_FLAG_HEALTHBAR_VISIBLE | HUD_FLAG_BREATHBAR_VISIBLE);
1656
1657         pkt << flags << mask;
1658
1659         Send(&pkt);
1660 }
1661
1662 void Server::SendHUDSetParam(session_t peer_id, u16 param, const std::string &value)
1663 {
1664         NetworkPacket pkt(TOCLIENT_HUD_SET_PARAM, 0, peer_id);
1665         pkt << param << value;
1666         Send(&pkt);
1667 }
1668
1669 void Server::SendSetSky(session_t peer_id, const SkyboxParams &params)
1670 {
1671         NetworkPacket pkt(TOCLIENT_SET_SKY, 0, peer_id);
1672
1673         // Handle prior clients here
1674         if (m_clients.getProtocolVersion(peer_id) < 39) {
1675                 pkt << params.bgcolor << params.type << (u16) params.textures.size();
1676
1677                 for (const std::string& texture : params.textures)
1678                         pkt << texture;
1679
1680                 pkt << params.clouds;
1681         } else { // Handle current clients and future clients
1682                 pkt << params.bgcolor << params.type
1683                 << params.clouds << params.fog_sun_tint
1684                 << params.fog_moon_tint << params.fog_tint_type;
1685
1686                 if (params.type == "skybox") {
1687                         pkt << (u16) params.textures.size();
1688                         for (const std::string &texture : params.textures)
1689                                 pkt << texture;
1690                 } else if (params.type == "regular") {
1691                         pkt << params.sky_color.day_sky << params.sky_color.day_horizon
1692                                 << params.sky_color.dawn_sky << params.sky_color.dawn_horizon
1693                                 << params.sky_color.night_sky << params.sky_color.night_horizon
1694                                 << params.sky_color.indoors;
1695                 }
1696         }
1697
1698         Send(&pkt);
1699 }
1700
1701 void Server::SendSetSun(session_t peer_id, const SunParams &params)
1702 {
1703         NetworkPacket pkt(TOCLIENT_SET_SUN, 0, peer_id);
1704         pkt << params.visible << params.texture
1705                 << params.tonemap << params.sunrise
1706                 << params.sunrise_visible << params.scale;
1707
1708         Send(&pkt);
1709 }
1710 void Server::SendSetMoon(session_t peer_id, const MoonParams &params)
1711 {
1712         NetworkPacket pkt(TOCLIENT_SET_MOON, 0, peer_id);
1713
1714         pkt << params.visible << params.texture
1715                 << params.tonemap << params.scale;
1716
1717         Send(&pkt);
1718 }
1719 void Server::SendSetStars(session_t peer_id, const StarParams &params)
1720 {
1721         NetworkPacket pkt(TOCLIENT_SET_STARS, 0, peer_id);
1722
1723         pkt << params.visible << params.count
1724                 << params.starcolor << params.scale;
1725
1726         Send(&pkt);
1727 }
1728
1729 void Server::SendCloudParams(session_t peer_id, const CloudParams &params)
1730 {
1731         NetworkPacket pkt(TOCLIENT_CLOUD_PARAMS, 0, peer_id);
1732         pkt << params.density << params.color_bright << params.color_ambient
1733                         << params.height << params.thickness << params.speed;
1734         Send(&pkt);
1735 }
1736
1737 void Server::SendOverrideDayNightRatio(session_t peer_id, bool do_override,
1738                 float ratio)
1739 {
1740         NetworkPacket pkt(TOCLIENT_OVERRIDE_DAY_NIGHT_RATIO,
1741                         1 + 2, peer_id);
1742
1743         pkt << do_override << (u16) (ratio * 65535);
1744
1745         Send(&pkt);
1746 }
1747
1748 void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed)
1749 {
1750         NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id);
1751         pkt << time << time_speed;
1752
1753         if (peer_id == PEER_ID_INEXISTENT) {
1754                 m_clients.sendToAll(&pkt);
1755         }
1756         else {
1757                 Send(&pkt);
1758         }
1759 }
1760
1761 void Server::SendPlayerHP(session_t peer_id)
1762 {
1763         PlayerSAO *playersao = getPlayerSAO(peer_id);
1764         assert(playersao);
1765
1766         SendHP(peer_id, playersao->getHP());
1767         m_script->player_event(playersao,"health_changed");
1768
1769         // Send to other clients
1770         playersao->sendPunchCommand();
1771 }
1772
1773 void Server::SendPlayerBreath(PlayerSAO *sao)
1774 {
1775         assert(sao);
1776
1777         m_script->player_event(sao, "breath_changed");
1778         SendBreath(sao->getPeerID(), sao->getBreath());
1779 }
1780
1781 void Server::SendMovePlayer(session_t peer_id)
1782 {
1783         RemotePlayer *player = m_env->getPlayer(peer_id);
1784         assert(player);
1785         PlayerSAO *sao = player->getPlayerSAO();
1786         assert(sao);
1787
1788         NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, peer_id);
1789         pkt << sao->getBasePosition() << sao->getLookPitch() << sao->getRotation().Y;
1790
1791         {
1792                 v3f pos = sao->getBasePosition();
1793                 verbosestream << "Server: Sending TOCLIENT_MOVE_PLAYER"
1794                                 << " pos=(" << pos.X << "," << pos.Y << "," << pos.Z << ")"
1795                                 << " pitch=" << sao->getLookPitch()
1796                                 << " yaw=" << sao->getRotation().Y
1797                                 << std::endl;
1798         }
1799
1800         Send(&pkt);
1801 }
1802
1803 void Server::SendPlayerFov(session_t peer_id)
1804 {
1805         NetworkPacket pkt(TOCLIENT_FOV, 4 + 1 + 4, peer_id);
1806
1807         PlayerFovSpec fov_spec = m_env->getPlayer(peer_id)->getFov();
1808         pkt << fov_spec.fov << fov_spec.is_multiplier << fov_spec.transition_time;
1809
1810         Send(&pkt);
1811 }
1812
1813 void Server::SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4],
1814                 f32 animation_speed)
1815 {
1816         NetworkPacket pkt(TOCLIENT_LOCAL_PLAYER_ANIMATIONS, 0,
1817                 peer_id);
1818
1819         pkt << animation_frames[0] << animation_frames[1] << animation_frames[2]
1820                         << animation_frames[3] << animation_speed;
1821
1822         Send(&pkt);
1823 }
1824
1825 void Server::SendEyeOffset(session_t peer_id, v3f first, v3f third)
1826 {
1827         NetworkPacket pkt(TOCLIENT_EYE_OFFSET, 0, peer_id);
1828         pkt << first << third;
1829         Send(&pkt);
1830 }
1831
1832 void Server::SendPlayerPrivileges(session_t peer_id)
1833 {
1834         RemotePlayer *player = m_env->getPlayer(peer_id);
1835         assert(player);
1836         if(player->getPeerId() == PEER_ID_INEXISTENT)
1837                 return;
1838
1839         std::set<std::string> privs;
1840         m_script->getAuth(player->getName(), NULL, &privs);
1841
1842         NetworkPacket pkt(TOCLIENT_PRIVILEGES, 0, peer_id);
1843         pkt << (u16) privs.size();
1844
1845         for (const std::string &priv : privs) {
1846                 pkt << priv;
1847         }
1848
1849         Send(&pkt);
1850 }
1851
1852 void Server::SendPlayerInventoryFormspec(session_t peer_id)
1853 {
1854         RemotePlayer *player = m_env->getPlayer(peer_id);
1855         assert(player);
1856         if (player->getPeerId() == PEER_ID_INEXISTENT)
1857                 return;
1858
1859         NetworkPacket pkt(TOCLIENT_INVENTORY_FORMSPEC, 0, peer_id);
1860         pkt.putLongString(player->inventory_formspec);
1861
1862         Send(&pkt);
1863 }
1864
1865 void Server::SendPlayerFormspecPrepend(session_t peer_id)
1866 {
1867         RemotePlayer *player = m_env->getPlayer(peer_id);
1868         assert(player);
1869         if (player->getPeerId() == PEER_ID_INEXISTENT)
1870                 return;
1871
1872         NetworkPacket pkt(TOCLIENT_FORMSPEC_PREPEND, 0, peer_id);
1873         pkt << player->formspec_prepend;
1874         Send(&pkt);
1875 }
1876
1877 void Server::SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersao)
1878 {
1879         // Radius inside which objects are active
1880         static thread_local const s16 radius =
1881                 g_settings->getS16("active_object_send_range_blocks") * MAP_BLOCKSIZE;
1882
1883         // Radius inside which players are active
1884         static thread_local const bool is_transfer_limited =
1885                 g_settings->exists("unlimited_player_transfer_distance") &&
1886                 !g_settings->getBool("unlimited_player_transfer_distance");
1887
1888         static thread_local const s16 player_transfer_dist =
1889                 g_settings->getS16("player_transfer_distance") * MAP_BLOCKSIZE;
1890
1891         s16 player_radius = player_transfer_dist == 0 && is_transfer_limited ?
1892                 radius : player_transfer_dist;
1893
1894         s16 my_radius = MYMIN(radius, playersao->getWantedRange() * MAP_BLOCKSIZE);
1895         if (my_radius <= 0)
1896                 my_radius = radius;
1897
1898         std::queue<u16> removed_objects, added_objects;
1899         m_env->getRemovedActiveObjects(playersao, my_radius, player_radius,
1900                 client->m_known_objects, removed_objects);
1901         m_env->getAddedActiveObjects(playersao, my_radius, player_radius,
1902                 client->m_known_objects, added_objects);
1903
1904         int removed_count = removed_objects.size();
1905         int added_count   = added_objects.size();
1906
1907         if (removed_objects.empty() && added_objects.empty())
1908                 return;
1909
1910         char buf[4];
1911         std::string data;
1912
1913         // Handle removed objects
1914         writeU16((u8*)buf, removed_objects.size());
1915         data.append(buf, 2);
1916         while (!removed_objects.empty()) {
1917                 // Get object
1918                 u16 id = removed_objects.front();
1919                 ServerActiveObject* obj = m_env->getActiveObject(id);
1920
1921                 // Add to data buffer for sending
1922                 writeU16((u8*)buf, id);
1923                 data.append(buf, 2);
1924
1925                 // Remove from known objects
1926                 client->m_known_objects.erase(id);
1927
1928                 if (obj && obj->m_known_by_count > 0)
1929                         obj->m_known_by_count--;
1930
1931                 removed_objects.pop();
1932         }
1933
1934         // Handle added objects
1935         writeU16((u8*)buf, added_objects.size());
1936         data.append(buf, 2);
1937         while (!added_objects.empty()) {
1938                 // Get object
1939                 u16 id = added_objects.front();
1940                 ServerActiveObject *obj = m_env->getActiveObject(id);
1941                 added_objects.pop();
1942
1943                 if (!obj) {
1944                         warningstream << FUNCTION_NAME << ": NULL object id="
1945                                 << (int)id << std::endl;
1946                         continue;
1947                 }
1948
1949                 // Get object type
1950                 u8 type = obj->getSendType();
1951
1952                 // Add to data buffer for sending
1953                 writeU16((u8*)buf, id);
1954                 data.append(buf, 2);
1955                 writeU8((u8*)buf, type);
1956                 data.append(buf, 1);
1957
1958                 data.append(serializeLongString(
1959                         obj->getClientInitializationData(client->net_proto_version)));
1960
1961                 // Add to known objects
1962                 client->m_known_objects.insert(id);
1963
1964                 obj->m_known_by_count++;
1965         }
1966
1967         NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD, data.size(), client->peer_id);
1968         pkt.putRawString(data.c_str(), data.size());
1969         Send(&pkt);
1970
1971         verbosestream << "Server::SendActiveObjectRemoveAdd: "
1972                 << removed_count << " removed, " << added_count << " added, "
1973                 << "packet size is " << pkt.getSize() << std::endl;
1974 }
1975
1976 void Server::SendActiveObjectMessages(session_t peer_id, const std::string &datas,
1977                 bool reliable)
1978 {
1979         NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_MESSAGES,
1980                         datas.size(), peer_id);
1981
1982         pkt.putRawString(datas.c_str(), datas.size());
1983
1984         m_clients.send(pkt.getPeerId(),
1985                         reliable ? clientCommandFactoryTable[pkt.getCommand()].channel : 1,
1986                         &pkt, reliable);
1987 }
1988
1989 void Server::SendCSMRestrictionFlags(session_t peer_id)
1990 {
1991         NetworkPacket pkt(TOCLIENT_CSM_RESTRICTION_FLAGS,
1992                 sizeof(m_csm_restriction_flags) + sizeof(m_csm_restriction_noderange), peer_id);
1993         pkt << m_csm_restriction_flags << m_csm_restriction_noderange;
1994         Send(&pkt);
1995 }
1996
1997 void Server::SendPlayerSpeed(session_t peer_id, const v3f &added_vel)
1998 {
1999         NetworkPacket pkt(TOCLIENT_PLAYER_SPEED, 0, peer_id);
2000         pkt << added_vel;
2001         Send(&pkt);
2002 }
2003
2004 inline s32 Server::nextSoundId()
2005 {
2006         s32 ret = m_next_sound_id;
2007         if (m_next_sound_id == INT32_MAX)
2008                 m_next_sound_id = 0; // signed overflow is undefined
2009         else
2010                 m_next_sound_id++;
2011         return ret;
2012 }
2013
2014 s32 Server::playSound(const SimpleSoundSpec &spec,
2015                 const ServerSoundParams &params, bool ephemeral)
2016 {
2017         // Find out initial position of sound
2018         bool pos_exists = false;
2019         v3f pos = params.getPos(m_env, &pos_exists);
2020         // If position is not found while it should be, cancel sound
2021         if(pos_exists != (params.type != ServerSoundParams::SSP_LOCAL))
2022                 return -1;
2023
2024         // Filter destination clients
2025         std::vector<session_t> dst_clients;
2026         if (!params.to_player.empty()) {
2027                 RemotePlayer *player = m_env->getPlayer(params.to_player.c_str());
2028                 if(!player){
2029                         infostream<<"Server::playSound: Player \""<<params.to_player
2030                                         <<"\" not found"<<std::endl;
2031                         return -1;
2032                 }
2033                 if (player->getPeerId() == PEER_ID_INEXISTENT) {
2034                         infostream<<"Server::playSound: Player \""<<params.to_player
2035                                         <<"\" not connected"<<std::endl;
2036                         return -1;
2037                 }
2038                 dst_clients.push_back(player->getPeerId());
2039         } else {
2040                 std::vector<session_t> clients = m_clients.getClientIDs();
2041
2042                 for (const session_t client_id : clients) {
2043                         RemotePlayer *player = m_env->getPlayer(client_id);
2044                         if (!player)
2045                                 continue;
2046                         if (!params.exclude_player.empty() &&
2047                                         params.exclude_player == player->getName())
2048                                 continue;
2049
2050                         PlayerSAO *sao = player->getPlayerSAO();
2051                         if (!sao)
2052                                 continue;
2053
2054                         if (pos_exists) {
2055                                 if(sao->getBasePosition().getDistanceFrom(pos) >
2056                                                 params.max_hear_distance)
2057                                         continue;
2058                         }
2059                         dst_clients.push_back(client_id);
2060                 }
2061         }
2062
2063         if(dst_clients.empty())
2064                 return -1;
2065
2066         // Create the sound
2067         s32 id;
2068         ServerPlayingSound *psound = nullptr;
2069         if (ephemeral) {
2070                 id = -1; // old clients will still use this, so pick a reserved ID
2071         } else {
2072                 id = nextSoundId();
2073                 // The sound will exist as a reference in m_playing_sounds
2074                 m_playing_sounds[id] = ServerPlayingSound();
2075                 psound = &m_playing_sounds[id];
2076                 psound->params = params;
2077                 psound->spec = spec;
2078         }
2079
2080         float gain = params.gain * spec.gain;
2081         NetworkPacket pkt(TOCLIENT_PLAY_SOUND, 0);
2082         pkt << id << spec.name << gain
2083                         << (u8) params.type << pos << params.object
2084                         << params.loop << params.fade << params.pitch
2085                         << ephemeral;
2086
2087         bool as_reliable = !ephemeral;
2088
2089         for (const u16 dst_client : dst_clients) {
2090                 if (psound)
2091                         psound->clients.insert(dst_client);
2092                 m_clients.send(dst_client, 0, &pkt, as_reliable);
2093         }
2094         return id;
2095 }
2096 void Server::stopSound(s32 handle)
2097 {
2098         // Get sound reference
2099         std::unordered_map<s32, ServerPlayingSound>::iterator i =
2100                 m_playing_sounds.find(handle);
2101         if (i == m_playing_sounds.end())
2102                 return;
2103         ServerPlayingSound &psound = i->second;
2104
2105         NetworkPacket pkt(TOCLIENT_STOP_SOUND, 4);
2106         pkt << handle;
2107
2108         for (std::unordered_set<session_t>::const_iterator si = psound.clients.begin();
2109                         si != psound.clients.end(); ++si) {
2110                 // Send as reliable
2111                 m_clients.send(*si, 0, &pkt, true);
2112         }
2113         // Remove sound reference
2114         m_playing_sounds.erase(i);
2115 }
2116
2117 void Server::fadeSound(s32 handle, float step, float gain)
2118 {
2119         // Get sound reference
2120         std::unordered_map<s32, ServerPlayingSound>::iterator i =
2121                 m_playing_sounds.find(handle);
2122         if (i == m_playing_sounds.end())
2123                 return;
2124
2125         ServerPlayingSound &psound = i->second;
2126         psound.params.gain = gain;
2127
2128         NetworkPacket pkt(TOCLIENT_FADE_SOUND, 4);
2129         pkt << handle << step << gain;
2130
2131         // Backwards compability
2132         bool play_sound = gain > 0;
2133         ServerPlayingSound compat_psound = psound;
2134         compat_psound.clients.clear();
2135
2136         NetworkPacket compat_pkt(TOCLIENT_STOP_SOUND, 4);
2137         compat_pkt << handle;
2138
2139         for (std::unordered_set<u16>::iterator it = psound.clients.begin();
2140                         it != psound.clients.end();) {
2141                 if (m_clients.getProtocolVersion(*it) >= 32) {
2142                         // Send as reliable
2143                         m_clients.send(*it, 0, &pkt, true);
2144                         ++it;
2145                 } else {
2146                         compat_psound.clients.insert(*it);
2147                         // Stop old sound
2148                         m_clients.send(*it, 0, &compat_pkt, true);
2149                         psound.clients.erase(it++);
2150                 }
2151         }
2152
2153         // Remove sound reference
2154         if (!play_sound || psound.clients.empty())
2155                 m_playing_sounds.erase(i);
2156
2157         if (play_sound && !compat_psound.clients.empty()) {
2158                 // Play new sound volume on older clients
2159                 playSound(compat_psound.spec, compat_psound.params);
2160         }
2161 }
2162
2163 void Server::sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players,
2164                 float far_d_nodes)
2165 {
2166         float maxd = far_d_nodes * BS;
2167         v3f p_f = intToFloat(p, BS);
2168         v3s16 block_pos = getNodeBlockPos(p);
2169
2170         NetworkPacket pkt(TOCLIENT_REMOVENODE, 6);
2171         pkt << p;
2172
2173         std::vector<session_t> clients = m_clients.getClientIDs();
2174         m_clients.lock();
2175
2176         for (session_t client_id : clients) {
2177                 RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
2178                 if (!client)
2179                         continue;
2180
2181                 RemotePlayer *player = m_env->getPlayer(client_id);
2182                 PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr;
2183
2184                 // If player is far away, only set modified blocks not sent
2185                 if (!client->isBlockSent(block_pos) || (sao &&
2186                                 sao->getBasePosition().getDistanceFrom(p_f) > maxd)) {
2187                         if (far_players)
2188                                 far_players->emplace(client_id);
2189                         else
2190                                 client->SetBlockNotSent(block_pos);
2191                         continue;
2192                 }
2193
2194                 // Send as reliable
2195                 m_clients.send(client_id, 0, &pkt, true);
2196         }
2197
2198         m_clients.unlock();
2199 }
2200
2201 void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_players,
2202                 float far_d_nodes, bool remove_metadata)
2203 {
2204         float maxd = far_d_nodes * BS;
2205         v3f p_f = intToFloat(p, BS);
2206         v3s16 block_pos = getNodeBlockPos(p);
2207
2208         NetworkPacket pkt(TOCLIENT_ADDNODE, 6 + 2 + 1 + 1 + 1);
2209         pkt << p << n.param0 << n.param1 << n.param2
2210                         << (u8) (remove_metadata ? 0 : 1);
2211
2212         std::vector<session_t> clients = m_clients.getClientIDs();
2213         m_clients.lock();
2214
2215         for (session_t client_id : clients) {
2216                 RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
2217                 if (!client)
2218                         continue;
2219
2220                 RemotePlayer *player = m_env->getPlayer(client_id);
2221                 PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr;
2222
2223                 // If player is far away, only set modified blocks not sent
2224                 if (!client->isBlockSent(block_pos) || (sao &&
2225                                 sao->getBasePosition().getDistanceFrom(p_f) > maxd)) {
2226                         if (far_players)
2227                                 far_players->emplace(client_id);
2228                         else
2229                                 client->SetBlockNotSent(block_pos);
2230                         continue;
2231                 }
2232
2233                 // Send as reliable
2234                 m_clients.send(client_id, 0, &pkt, true);
2235         }
2236
2237         m_clients.unlock();
2238 }
2239
2240 void Server::sendMetadataChanged(const std::list<v3s16> &meta_updates, float far_d_nodes)
2241 {
2242         float maxd = far_d_nodes * BS;
2243         NodeMetadataList meta_updates_list(false);
2244         std::vector<session_t> clients = m_clients.getClientIDs();
2245
2246         m_clients.lock();
2247
2248         for (session_t i : clients) {
2249                 RemoteClient *client = m_clients.lockedGetClientNoEx(i);
2250                 if (!client)
2251                         continue;
2252
2253                 ServerActiveObject *player = m_env->getActiveObject(i);
2254                 v3f player_pos = player ? player->getBasePosition() : v3f();
2255
2256                 for (const v3s16 &pos : meta_updates) {
2257                         NodeMetadata *meta = m_env->getMap().getNodeMetadata(pos);
2258
2259                         if (!meta)
2260                                 continue;
2261
2262                         v3s16 block_pos = getNodeBlockPos(pos);
2263                         if (!client->isBlockSent(block_pos) || (player &&
2264                                         player_pos.getDistanceFrom(intToFloat(pos, BS)) > maxd)) {
2265                                 client->SetBlockNotSent(block_pos);
2266                                 continue;
2267                         }
2268
2269                         // Add the change to send list
2270                         meta_updates_list.set(pos, meta);
2271                 }
2272                 if (meta_updates_list.size() == 0)
2273                         continue;
2274
2275                 // Send the meta changes
2276                 std::ostringstream os(std::ios::binary);
2277                 meta_updates_list.serialize(os, client->net_proto_version, false, true);
2278                 std::ostringstream oss(std::ios::binary);
2279                 compressZlib(os.str(), oss);
2280
2281                 NetworkPacket pkt(TOCLIENT_NODEMETA_CHANGED, 0);
2282                 pkt.putLongString(oss.str());
2283                 m_clients.send(i, 0, &pkt, true);
2284
2285                 meta_updates_list.clear();
2286         }
2287
2288         m_clients.unlock();
2289 }
2290
2291 void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver,
2292                 u16 net_proto_version)
2293 {
2294         /*
2295                 Create a packet with the block in the right format
2296         */
2297
2298         std::ostringstream os(std::ios_base::binary);
2299         block->serialize(os, ver, false);
2300         block->serializeNetworkSpecific(os);
2301         std::string s = os.str();
2302
2303         NetworkPacket pkt(TOCLIENT_BLOCKDATA, 2 + 2 + 2 + 2 + s.size(), peer_id);
2304
2305         pkt << block->getPos();
2306         pkt.putRawString(s.c_str(), s.size());
2307         Send(&pkt);
2308 }
2309
2310 void Server::SendBlocks(float dtime)
2311 {
2312         MutexAutoLock envlock(m_env_mutex);
2313         //TODO check if one big lock could be faster then multiple small ones
2314
2315         std::vector<PrioritySortedBlockTransfer> queue;
2316
2317         u32 total_sending = 0;
2318
2319         {
2320                 ScopeProfiler sp2(g_profiler, "Server::SendBlocks(): Collect list");
2321
2322                 std::vector<session_t> clients = m_clients.getClientIDs();
2323
2324                 m_clients.lock();
2325                 for (const session_t client_id : clients) {
2326                         RemoteClient *client = m_clients.lockedGetClientNoEx(client_id, CS_Active);
2327
2328                         if (!client)
2329                                 continue;
2330
2331                         total_sending += client->getSendingCount();
2332                         client->GetNextBlocks(m_env,m_emerge, dtime, queue);
2333                 }
2334                 m_clients.unlock();
2335         }
2336
2337         // Sort.
2338         // Lowest priority number comes first.
2339         // Lowest is most important.
2340         std::sort(queue.begin(), queue.end());
2341
2342         m_clients.lock();
2343
2344         // Maximal total count calculation
2345         // The per-client block sends is halved with the maximal online users
2346         u32 max_blocks_to_send = (m_env->getPlayerCount() + g_settings->getU32("max_users")) *
2347                 g_settings->getU32("max_simultaneous_block_sends_per_client") / 4 + 1;
2348
2349         ScopeProfiler sp(g_profiler, "Server::SendBlocks(): Send to clients");
2350         Map &map = m_env->getMap();
2351
2352         for (const PrioritySortedBlockTransfer &block_to_send : queue) {
2353                 if (total_sending >= max_blocks_to_send)
2354                         break;
2355
2356                 MapBlock *block = map.getBlockNoCreateNoEx(block_to_send.pos);
2357                 if (!block)
2358                         continue;
2359
2360                 RemoteClient *client = m_clients.lockedGetClientNoEx(block_to_send.peer_id,
2361                                 CS_Active);
2362                 if (!client)
2363                         continue;
2364
2365                 SendBlockNoLock(block_to_send.peer_id, block, client->serialization_version,
2366                                 client->net_proto_version);
2367
2368                 client->SentBlock(block_to_send.pos);
2369                 total_sending++;
2370         }
2371         m_clients.unlock();
2372 }
2373
2374 bool Server::SendBlock(session_t peer_id, const v3s16 &blockpos)
2375 {
2376         MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
2377         if (!block)
2378                 return false;
2379
2380         m_clients.lock();
2381         RemoteClient *client = m_clients.lockedGetClientNoEx(peer_id, CS_Active);
2382         if (!client || client->isBlockSent(blockpos)) {
2383                 m_clients.unlock();
2384                 return false;
2385         }
2386         SendBlockNoLock(peer_id, block, client->serialization_version,
2387                         client->net_proto_version);
2388         m_clients.unlock();
2389
2390         return true;
2391 }
2392
2393 void Server::fillMediaCache()
2394 {
2395         infostream<<"Server: Calculating media file checksums"<<std::endl;
2396
2397         // Collect all media file paths
2398         std::vector<std::string> paths;
2399         m_modmgr->getModsMediaPaths(paths);
2400         fs::GetRecursiveDirs(paths, m_gamespec.path + DIR_DELIM + "textures");
2401         fs::GetRecursiveDirs(paths, porting::path_user + DIR_DELIM + "textures" + DIR_DELIM + "server");
2402
2403         // Collect media file information from paths into cache
2404         for (const std::string &mediapath : paths) {
2405                 std::vector<fs::DirListNode> dirlist = fs::GetDirListing(mediapath);
2406                 for (const fs::DirListNode &dln : dirlist) {
2407                         if (dln.dir) // Ignode dirs
2408                                 continue;
2409                         std::string filename = dln.name;
2410                         // If name contains illegal characters, ignore the file
2411                         if (!string_allowed(filename, TEXTURENAME_ALLOWED_CHARS)) {
2412                                 infostream<<"Server: ignoring illegal file name: \""
2413                                                 << filename << "\"" << std::endl;
2414                                 continue;
2415                         }
2416                         // If name is not in a supported format, ignore it
2417                         const char *supported_ext[] = {
2418                                 ".png", ".jpg", ".bmp", ".tga",
2419                                 ".pcx", ".ppm", ".psd", ".wal", ".rgb",
2420                                 ".ogg",
2421                                 ".x", ".b3d", ".md2", ".obj",
2422                                 // Custom translation file format
2423                                 ".tr",
2424                                 NULL
2425                         };
2426                         if (removeStringEnd(filename, supported_ext).empty()){
2427                                 infostream << "Server: ignoring unsupported file extension: \""
2428                                                 << filename << "\"" << std::endl;
2429                                 continue;
2430                         }
2431                         // Ok, attempt to load the file and add to cache
2432                         std::string filepath;
2433                         filepath.append(mediapath).append(DIR_DELIM).append(filename);
2434
2435                         // Read data
2436                         std::ifstream fis(filepath.c_str(), std::ios_base::binary);
2437                         if (!fis.good()) {
2438                                 errorstream << "Server::fillMediaCache(): Could not open \""
2439                                                 << filename << "\" for reading" << std::endl;
2440                                 continue;
2441                         }
2442                         std::ostringstream tmp_os(std::ios_base::binary);
2443                         bool bad = false;
2444                         for(;;) {
2445                                 char buf[1024];
2446                                 fis.read(buf, 1024);
2447                                 std::streamsize len = fis.gcount();
2448                                 tmp_os.write(buf, len);
2449                                 if (fis.eof())
2450                                         break;
2451                                 if (!fis.good()) {
2452                                         bad = true;
2453                                         break;
2454                                 }
2455                         }
2456                         if(bad) {
2457                                 errorstream<<"Server::fillMediaCache(): Failed to read \""
2458                                                 << filename << "\"" << std::endl;
2459                                 continue;
2460                         }
2461                         if(tmp_os.str().length() == 0) {
2462                                 errorstream << "Server::fillMediaCache(): Empty file \""
2463                                                 << filepath << "\"" << std::endl;
2464                                 continue;
2465                         }
2466
2467                         SHA1 sha1;
2468                         sha1.addBytes(tmp_os.str().c_str(), tmp_os.str().length());
2469
2470                         unsigned char *digest = sha1.getDigest();
2471                         std::string sha1_base64 = base64_encode(digest, 20);
2472                         std::string sha1_hex = hex_encode((char*)digest, 20);
2473                         free(digest);
2474
2475                         // Put in list
2476                         m_media[filename] = MediaInfo(filepath, sha1_base64);
2477                         verbosestream << "Server: " << sha1_hex << " is " << filename
2478                                         << std::endl;
2479                 }
2480         }
2481 }
2482
2483 void Server::sendMediaAnnouncement(session_t peer_id, const std::string &lang_code)
2484 {
2485         // Make packet
2486         NetworkPacket pkt(TOCLIENT_ANNOUNCE_MEDIA, 0, peer_id);
2487
2488         u16 media_sent = 0;
2489         std::string lang_suffix;
2490         lang_suffix.append(".").append(lang_code).append(".tr");
2491         for (const auto &i : m_media) {
2492                 if (str_ends_with(i.first, ".tr") && !str_ends_with(i.first, lang_suffix))
2493                         continue;
2494                 media_sent++;
2495         }
2496
2497         pkt << media_sent;
2498
2499         for (const auto &i : m_media) {
2500                 if (str_ends_with(i.first, ".tr") && !str_ends_with(i.first, lang_suffix))
2501                         continue;
2502                 pkt << i.first << i.second.sha1_digest;
2503         }
2504
2505         pkt << g_settings->get("remote_media");
2506         Send(&pkt);
2507
2508         verbosestream << "Server: Announcing files to id(" << peer_id
2509                 << "): count=" << media_sent << " size=" << pkt.getSize() << std::endl;
2510 }
2511
2512 struct SendableMedia
2513 {
2514         std::string name;
2515         std::string path;
2516         std::string data;
2517
2518         SendableMedia(const std::string &name_="", const std::string &path_="",
2519                       const std::string &data_=""):
2520                 name(name_),
2521                 path(path_),
2522                 data(data_)
2523         {}
2524 };
2525
2526 void Server::sendRequestedMedia(session_t peer_id,
2527                 const std::vector<std::string> &tosend)
2528 {
2529         verbosestream<<"Server::sendRequestedMedia(): "
2530                         <<"Sending files to client"<<std::endl;
2531
2532         /* Read files */
2533
2534         // Put 5kB in one bunch (this is not accurate)
2535         u32 bytes_per_bunch = 5000;
2536
2537         std::vector< std::vector<SendableMedia> > file_bunches;
2538         file_bunches.emplace_back();
2539
2540         u32 file_size_bunch_total = 0;
2541
2542         for (const std::string &name : tosend) {
2543                 if (m_media.find(name) == m_media.end()) {
2544                         errorstream<<"Server::sendRequestedMedia(): Client asked for "
2545                                         <<"unknown file \""<<(name)<<"\""<<std::endl;
2546                         continue;
2547                 }
2548
2549                 //TODO get path + name
2550                 std::string tpath = m_media[name].path;
2551
2552                 // Read data
2553                 std::ifstream fis(tpath.c_str(), std::ios_base::binary);
2554                 if(!fis.good()){
2555                         errorstream<<"Server::sendRequestedMedia(): Could not open \""
2556                                         <<tpath<<"\" for reading"<<std::endl;
2557                         continue;
2558                 }
2559                 std::ostringstream tmp_os(std::ios_base::binary);
2560                 bool bad = false;
2561                 for(;;) {
2562                         char buf[1024];
2563                         fis.read(buf, 1024);
2564                         std::streamsize len = fis.gcount();
2565                         tmp_os.write(buf, len);
2566                         file_size_bunch_total += len;
2567                         if(fis.eof())
2568                                 break;
2569                         if(!fis.good()) {
2570                                 bad = true;
2571                                 break;
2572                         }
2573                 }
2574                 if (bad) {
2575                         errorstream<<"Server::sendRequestedMedia(): Failed to read \""
2576                                         <<name<<"\""<<std::endl;
2577                         continue;
2578                 }
2579                 /*infostream<<"Server::sendRequestedMedia(): Loaded \""
2580                                 <<tname<<"\""<<std::endl;*/
2581                 // Put in list
2582                 file_bunches[file_bunches.size()-1].emplace_back(name, tpath, tmp_os.str());
2583
2584                 // Start next bunch if got enough data
2585                 if(file_size_bunch_total >= bytes_per_bunch) {
2586                         file_bunches.emplace_back();
2587                         file_size_bunch_total = 0;
2588                 }
2589
2590         }
2591
2592         /* Create and send packets */
2593
2594         u16 num_bunches = file_bunches.size();
2595         for (u16 i = 0; i < num_bunches; i++) {
2596                 /*
2597                         u16 command
2598                         u16 total number of texture bunches
2599                         u16 index of this bunch
2600                         u32 number of files in this bunch
2601                         for each file {
2602                                 u16 length of name
2603                                 string name
2604                                 u32 length of data
2605                                 data
2606                         }
2607                 */
2608
2609                 NetworkPacket pkt(TOCLIENT_MEDIA, 4 + 0, peer_id);
2610                 pkt << num_bunches << i << (u32) file_bunches[i].size();
2611
2612                 for (const SendableMedia &j : file_bunches[i]) {
2613                         pkt << j.name;
2614                         pkt.putLongString(j.data);
2615                 }
2616
2617                 verbosestream << "Server::sendRequestedMedia(): bunch "
2618                                 << i << "/" << num_bunches
2619                                 << " files=" << file_bunches[i].size()
2620                                 << " size="  << pkt.getSize() << std::endl;
2621                 Send(&pkt);
2622         }
2623 }
2624
2625 void Server::sendDetachedInventory(Inventory *inventory, const std::string &name, session_t peer_id)
2626 {
2627         NetworkPacket pkt(TOCLIENT_DETACHED_INVENTORY, 0, peer_id);
2628         pkt << name;
2629
2630         if (!inventory) {
2631                 pkt << false; // Remove inventory
2632         } else {
2633                 pkt << true; // Update inventory
2634
2635                 // Serialization & NetworkPacket isn't a love story
2636                 std::ostringstream os(std::ios_base::binary);
2637                 inventory->serialize(os);
2638                 inventory->setModified(false);
2639
2640                 const std::string &os_str = os.str();
2641                 pkt << static_cast<u16>(os_str.size()); // HACK: to keep compatibility with 5.0.0 clients
2642                 pkt.putRawString(os_str);
2643         }
2644
2645         if (peer_id == PEER_ID_INEXISTENT)
2646                 m_clients.sendToAll(&pkt);
2647         else
2648                 Send(&pkt);
2649 }
2650
2651 void Server::sendDetachedInventories(session_t peer_id, bool incremental)
2652 {
2653         // Lookup player name, to filter detached inventories just after
2654         std::string peer_name;
2655         if (peer_id != PEER_ID_INEXISTENT) {
2656                 peer_name = getClient(peer_id, CS_Created)->getName();
2657         }
2658
2659         auto send_cb = [this, peer_id](const std::string &name, Inventory *inv) {
2660                 sendDetachedInventory(inv, name, peer_id);
2661         };
2662
2663         m_inventory_mgr->sendDetachedInventories(peer_name, incremental, send_cb);
2664 }
2665
2666 /*
2667         Something random
2668 */
2669
2670 void Server::DiePlayer(session_t peer_id, const PlayerHPChangeReason &reason)
2671 {
2672         PlayerSAO *playersao = getPlayerSAO(peer_id);
2673         assert(playersao);
2674
2675         infostream << "Server::DiePlayer(): Player "
2676                         << playersao->getPlayer()->getName()
2677                         << " dies" << std::endl;
2678
2679         playersao->setHP(0, reason);
2680         playersao->clearParentAttachment();
2681
2682         // Trigger scripted stuff
2683         m_script->on_dieplayer(playersao, reason);
2684
2685         SendPlayerHP(peer_id);
2686         SendDeathscreen(peer_id, false, v3f(0,0,0));
2687 }
2688
2689 void Server::RespawnPlayer(session_t peer_id)
2690 {
2691         PlayerSAO *playersao = getPlayerSAO(peer_id);
2692         assert(playersao);
2693
2694         infostream << "Server::RespawnPlayer(): Player "
2695                         << playersao->getPlayer()->getName()
2696                         << " respawns" << std::endl;
2697
2698         playersao->setHP(playersao->accessObjectProperties()->hp_max,
2699                         PlayerHPChangeReason(PlayerHPChangeReason::RESPAWN));
2700         playersao->setBreath(playersao->accessObjectProperties()->breath_max);
2701
2702         bool repositioned = m_script->on_respawnplayer(playersao);
2703         if (!repositioned) {
2704                 // setPos will send the new position to client
2705                 playersao->setPos(findSpawnPos());
2706         }
2707
2708         SendPlayerHP(peer_id);
2709 }
2710
2711
2712 void Server::DenySudoAccess(session_t peer_id)
2713 {
2714         NetworkPacket pkt(TOCLIENT_DENY_SUDO_MODE, 0, peer_id);
2715         Send(&pkt);
2716 }
2717
2718
2719 void Server::DenyAccessVerCompliant(session_t peer_id, u16 proto_ver, AccessDeniedCode reason,
2720                 const std::string &str_reason, bool reconnect)
2721 {
2722         SendAccessDenied(peer_id, reason, str_reason, reconnect);
2723
2724         m_clients.event(peer_id, CSE_SetDenied);
2725         DisconnectPeer(peer_id);
2726 }
2727
2728
2729 void Server::DenyAccess(session_t peer_id, AccessDeniedCode reason,
2730                 const std::string &custom_reason)
2731 {
2732         SendAccessDenied(peer_id, reason, custom_reason);
2733         m_clients.event(peer_id, CSE_SetDenied);
2734         DisconnectPeer(peer_id);
2735 }
2736
2737 // 13/03/15: remove this function when protocol version 25 will become
2738 // the minimum version for MT users, maybe in 1 year
2739 void Server::DenyAccess_Legacy(session_t peer_id, const std::wstring &reason)
2740 {
2741         SendAccessDenied_Legacy(peer_id, reason);
2742         m_clients.event(peer_id, CSE_SetDenied);
2743         DisconnectPeer(peer_id);
2744 }
2745
2746 void Server::DisconnectPeer(session_t peer_id)
2747 {
2748         m_modchannel_mgr->leaveAllChannels(peer_id);
2749         m_con->DisconnectPeer(peer_id);
2750 }
2751
2752 void Server::acceptAuth(session_t peer_id, bool forSudoMode)
2753 {
2754         if (!forSudoMode) {
2755                 RemoteClient* client = getClient(peer_id, CS_Invalid);
2756
2757                 NetworkPacket resp_pkt(TOCLIENT_AUTH_ACCEPT, 1 + 6 + 8 + 4, peer_id);
2758
2759                 // Right now, the auth mechs don't change between login and sudo mode.
2760                 u32 sudo_auth_mechs = client->allowed_auth_mechs;
2761                 client->allowed_sudo_mechs = sudo_auth_mechs;
2762
2763                 resp_pkt << v3f(0,0,0) << (u64) m_env->getServerMap().getSeed()
2764                                 << g_settings->getFloat("dedicated_server_step")
2765                                 << sudo_auth_mechs;
2766
2767                 Send(&resp_pkt);
2768                 m_clients.event(peer_id, CSE_AuthAccept);
2769         } else {
2770                 NetworkPacket resp_pkt(TOCLIENT_ACCEPT_SUDO_MODE, 1 + 6 + 8 + 4, peer_id);
2771
2772                 // We only support SRP right now
2773                 u32 sudo_auth_mechs = AUTH_MECHANISM_FIRST_SRP;
2774
2775                 resp_pkt << sudo_auth_mechs;
2776                 Send(&resp_pkt);
2777                 m_clients.event(peer_id, CSE_SudoSuccess);
2778         }
2779 }
2780
2781 void Server::DeleteClient(session_t peer_id, ClientDeletionReason reason)
2782 {
2783         std::wstring message;
2784         {
2785                 /*
2786                         Clear references to playing sounds
2787                 */
2788                 for (std::unordered_map<s32, ServerPlayingSound>::iterator
2789                                  i = m_playing_sounds.begin(); i != m_playing_sounds.end();) {
2790                         ServerPlayingSound &psound = i->second;
2791                         psound.clients.erase(peer_id);
2792                         if (psound.clients.empty())
2793                                 m_playing_sounds.erase(i++);
2794                         else
2795                                 ++i;
2796                 }
2797
2798                 // clear formspec info so the next client can't abuse the current state
2799                 m_formspec_state_data.erase(peer_id);
2800
2801                 RemotePlayer *player = m_env->getPlayer(peer_id);
2802
2803                 /* Run scripts and remove from environment */
2804                 if (player) {
2805                         PlayerSAO *playersao = player->getPlayerSAO();
2806                         assert(playersao);
2807
2808                         playersao->clearChildAttachments();
2809                         playersao->clearParentAttachment();
2810
2811                         // inform connected clients
2812                         const std::string &player_name = player->getName();
2813                         NetworkPacket notice(TOCLIENT_UPDATE_PLAYER_LIST, 0, PEER_ID_INEXISTENT);
2814                         // (u16) 1 + std::string represents a vector serialization representation
2815                         notice << (u8) PLAYER_LIST_REMOVE  << (u16) 1 << player_name;
2816                         m_clients.sendToAll(&notice);
2817                         // run scripts
2818                         m_script->on_leaveplayer(playersao, reason == CDR_TIMEOUT);
2819
2820                         playersao->disconnected();
2821                 }
2822
2823                 /*
2824                         Print out action
2825                 */
2826                 {
2827                         if (player && reason != CDR_DENY) {
2828                                 std::ostringstream os(std::ios_base::binary);
2829                                 std::vector<session_t> clients = m_clients.getClientIDs();
2830
2831                                 for (const session_t client_id : clients) {
2832                                         // Get player
2833                                         RemotePlayer *player = m_env->getPlayer(client_id);
2834                                         if (!player)
2835                                                 continue;
2836
2837                                         // Get name of player
2838                                         os << player->getName() << " ";
2839                                 }
2840
2841                                 std::string name = player->getName();
2842                                 actionstream << name << " "
2843                                                 << (reason == CDR_TIMEOUT ? "times out." : "leaves game.")
2844                                                 << " List of players: " << os.str() << std::endl;
2845                                 if (m_admin_chat)
2846                                         m_admin_chat->outgoing_queue.push_back(
2847                                                 new ChatEventNick(CET_NICK_REMOVE, name));
2848                         }
2849                 }
2850                 {
2851                         MutexAutoLock env_lock(m_env_mutex);
2852                         m_clients.DeleteClient(peer_id);
2853                 }
2854         }
2855
2856         // Send leave chat message to all remaining clients
2857         if (!message.empty()) {
2858                 SendChatMessage(PEER_ID_INEXISTENT,
2859                                 ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE, message));
2860         }
2861 }
2862
2863 void Server::UpdateCrafting(RemotePlayer *player)
2864 {
2865         InventoryList *clist = player->inventory.getList("craft");
2866         if (!clist || clist->getSize() == 0)
2867                 return;
2868
2869         if (!clist->checkModified())
2870                 return;
2871
2872         // Get a preview for crafting
2873         ItemStack preview;
2874         InventoryLocation loc;
2875         loc.setPlayer(player->getName());
2876         std::vector<ItemStack> output_replacements;
2877         getCraftingResult(&player->inventory, preview, output_replacements, false, this);
2878         m_env->getScriptIface()->item_CraftPredict(preview, player->getPlayerSAO(),
2879                         clist, loc);
2880
2881         InventoryList *plist = player->inventory.getList("craftpreview");
2882         if (plist && plist->getSize() >= 1) {
2883                 // Put the new preview in
2884                 plist->changeItem(0, preview);
2885         }
2886 }
2887
2888 void Server::handleChatInterfaceEvent(ChatEvent *evt)
2889 {
2890         if (evt->type == CET_NICK_ADD) {
2891                 // The terminal informed us of its nick choice
2892                 m_admin_nick = ((ChatEventNick *)evt)->nick;
2893                 if (!m_script->getAuth(m_admin_nick, NULL, NULL)) {
2894                         errorstream << "You haven't set up an account." << std::endl
2895                                 << "Please log in using the client as '"
2896                                 << m_admin_nick << "' with a secure password." << std::endl
2897                                 << "Until then, you can't execute admin tasks via the console," << std::endl
2898                                 << "and everybody can claim the user account instead of you," << std::endl
2899                                 << "giving them full control over this server." << std::endl;
2900                 }
2901         } else {
2902                 assert(evt->type == CET_CHAT);
2903                 handleAdminChat((ChatEventChat *)evt);
2904         }
2905 }
2906
2907 std::wstring Server::handleChat(const std::string &name, const std::wstring &wname,
2908         std::wstring wmessage, bool check_shout_priv, RemotePlayer *player)
2909 {
2910         // If something goes wrong, this player is to blame
2911         RollbackScopeActor rollback_scope(m_rollback,
2912                         std::string("player:") + name);
2913
2914         if (g_settings->getBool("strip_color_codes"))
2915                 wmessage = unescape_enriched(wmessage);
2916
2917         if (player) {
2918                 switch (player->canSendChatMessage()) {
2919                 case RPLAYER_CHATRESULT_FLOODING: {
2920                         std::wstringstream ws;
2921                         ws << L"You cannot send more messages. You are limited to "
2922                                         << g_settings->getFloat("chat_message_limit_per_10sec")
2923                                         << L" messages per 10 seconds.";
2924                         return ws.str();
2925                 }
2926                 case RPLAYER_CHATRESULT_KICK:
2927                         DenyAccess_Legacy(player->getPeerId(),
2928                                         L"You have been kicked due to message flooding.");
2929                         return L"";
2930                 case RPLAYER_CHATRESULT_OK:
2931                         break;
2932                 default:
2933                         FATAL_ERROR("Unhandled chat filtering result found.");
2934                 }
2935         }
2936
2937         if (m_max_chatmessage_length > 0
2938                         && wmessage.length() > m_max_chatmessage_length) {
2939                 return L"Your message exceed the maximum chat message limit set on the server. "
2940                                 L"It was refused. Send a shorter message";
2941         }
2942
2943         auto message = trim(wide_to_utf8(wmessage));
2944         if (message.find_first_of("\n\r") != std::wstring::npos) {
2945                 return L"New lines are not permitted in chat messages";
2946         }
2947
2948         // Run script hook, exit if script ate the chat message
2949         if (m_script->on_chat_message(name, message))
2950                 return L"";
2951
2952         // Line to send
2953         std::wstring line;
2954         // Whether to send line to the player that sent the message, or to all players
2955         bool broadcast_line = true;
2956
2957         if (check_shout_priv && !checkPriv(name, "shout")) {
2958                 line += L"-!- You don't have permission to shout.";
2959                 broadcast_line = false;
2960         } else {
2961                 /*
2962                         Workaround for fixing chat on Android. Lua doesn't handle
2963                         the Cyrillic alphabet and some characters on older Android devices
2964                 */
2965 #ifdef __ANDROID__
2966                 line += L"<" + wname + L"> " + wmessage;
2967 #else
2968                 line += narrow_to_wide(m_script->formatChatMessage(name,
2969                                 wide_to_narrow(wmessage)));
2970 #endif
2971         }
2972
2973         /*
2974                 Tell calling method to send the message to sender
2975         */
2976         if (!broadcast_line)
2977                 return line;
2978
2979         /*
2980                 Send the message to others
2981         */
2982         actionstream << "CHAT: " << wide_to_narrow(unescape_enriched(line)) << std::endl;
2983
2984         std::vector<session_t> clients = m_clients.getClientIDs();
2985
2986         /*
2987                 Send the message back to the inital sender
2988                 if they are using protocol version >= 29
2989         */
2990
2991         session_t peer_id_to_avoid_sending =
2992                 (player ? player->getPeerId() : PEER_ID_INEXISTENT);
2993
2994         if (player && player->protocol_version >= 29)
2995                 peer_id_to_avoid_sending = PEER_ID_INEXISTENT;
2996
2997         for (u16 cid : clients) {
2998                 if (cid != peer_id_to_avoid_sending)
2999                         SendChatMessage(cid, ChatMessage(line));
3000         }
3001         return L"";
3002 }
3003
3004 void Server::handleAdminChat(const ChatEventChat *evt)
3005 {
3006         std::string name = evt->nick;
3007         std::wstring wname = utf8_to_wide(name);
3008         std::wstring wmessage = evt->evt_msg;
3009
3010         std::wstring answer = handleChat(name, wname, wmessage);
3011
3012         // If asked to send answer to sender
3013         if (!answer.empty()) {
3014                 m_admin_chat->outgoing_queue.push_back(new ChatEventChat("", answer));
3015         }
3016 }
3017
3018 RemoteClient *Server::getClient(session_t peer_id, ClientState state_min)
3019 {
3020         RemoteClient *client = getClientNoEx(peer_id,state_min);
3021         if(!client)
3022                 throw ClientNotFoundException("Client not found");
3023
3024         return client;
3025 }
3026 RemoteClient *Server::getClientNoEx(session_t peer_id, ClientState state_min)
3027 {
3028         return m_clients.getClientNoEx(peer_id, state_min);
3029 }
3030
3031 std::string Server::getPlayerName(session_t peer_id)
3032 {
3033         RemotePlayer *player = m_env->getPlayer(peer_id);
3034         if (!player)
3035                 return "[id="+itos(peer_id)+"]";
3036         return player->getName();
3037 }
3038
3039 PlayerSAO *Server::getPlayerSAO(session_t peer_id)
3040 {
3041         RemotePlayer *player = m_env->getPlayer(peer_id);
3042         if (!player)
3043                 return NULL;
3044         return player->getPlayerSAO();
3045 }
3046
3047 std::wstring Server::getStatusString()
3048 {
3049         std::wostringstream os(std::ios_base::binary);
3050         os << L"# Server: ";
3051         // Version
3052         os << L"version=" << narrow_to_wide(g_version_string);
3053         // Uptime
3054         os << L", uptime=" << m_uptime_counter->get();
3055         // Max lag estimate
3056         os << L", max_lag=" << (m_env ? m_env->getMaxLagEstimate() : 0);
3057
3058         // Information about clients
3059         bool first = true;
3060         os << L", clients={";
3061         if (m_env) {
3062                 std::vector<session_t> clients = m_clients.getClientIDs();
3063                 for (session_t client_id : clients) {
3064                         RemotePlayer *player = m_env->getPlayer(client_id);
3065
3066                         // Get name of player
3067                         std::wstring name = L"unknown";
3068                         if (player)
3069                                 name = narrow_to_wide(player->getName());
3070
3071                         // Add name to information string
3072                         if (!first)
3073                                 os << L", ";
3074                         else
3075                                 first = false;
3076
3077                         os << name;
3078                 }
3079         }
3080         os << L"}";
3081
3082         if (m_env && !((ServerMap*)(&m_env->getMap()))->isSavingEnabled())
3083                 os << std::endl << L"# Server: " << " WARNING: Map saving is disabled.";
3084
3085         if (!g_settings->get("motd").empty())
3086                 os << std::endl << L"# Server: " << narrow_to_wide(g_settings->get("motd"));
3087
3088         return os.str();
3089 }
3090
3091 std::set<std::string> Server::getPlayerEffectivePrivs(const std::string &name)
3092 {
3093         std::set<std::string> privs;
3094         m_script->getAuth(name, NULL, &privs);
3095         return privs;
3096 }
3097
3098 bool Server::checkPriv(const std::string &name, const std::string &priv)
3099 {
3100         std::set<std::string> privs = getPlayerEffectivePrivs(name);
3101         return (privs.count(priv) != 0);
3102 }
3103
3104 void Server::reportPrivsModified(const std::string &name)
3105 {
3106         if (name.empty()) {
3107                 std::vector<session_t> clients = m_clients.getClientIDs();
3108                 for (const session_t client_id : clients) {
3109                         RemotePlayer *player = m_env->getPlayer(client_id);
3110                         reportPrivsModified(player->getName());
3111                 }
3112         } else {
3113                 RemotePlayer *player = m_env->getPlayer(name.c_str());
3114                 if (!player)
3115                         return;
3116                 SendPlayerPrivileges(player->getPeerId());
3117                 PlayerSAO *sao = player->getPlayerSAO();
3118                 if(!sao)
3119                         return;
3120                 sao->updatePrivileges(
3121                                 getPlayerEffectivePrivs(name),
3122                                 isSingleplayer());
3123         }
3124 }
3125
3126 void Server::reportInventoryFormspecModified(const std::string &name)
3127 {
3128         RemotePlayer *player = m_env->getPlayer(name.c_str());
3129         if (!player)
3130                 return;
3131         SendPlayerInventoryFormspec(player->getPeerId());
3132 }
3133
3134 void Server::reportFormspecPrependModified(const std::string &name)
3135 {
3136         RemotePlayer *player = m_env->getPlayer(name.c_str());
3137         if (!player)
3138                 return;
3139         SendPlayerFormspecPrepend(player->getPeerId());
3140 }
3141
3142 void Server::setIpBanned(const std::string &ip, const std::string &name)
3143 {
3144         m_banmanager->add(ip, name);
3145 }
3146
3147 void Server::unsetIpBanned(const std::string &ip_or_name)
3148 {
3149         m_banmanager->remove(ip_or_name);
3150 }
3151
3152 std::string Server::getBanDescription(const std::string &ip_or_name)
3153 {
3154         return m_banmanager->getBanDescription(ip_or_name);
3155 }
3156
3157 void Server::notifyPlayer(const char *name, const std::wstring &msg)
3158 {
3159         // m_env will be NULL if the server is initializing
3160         if (!m_env)
3161                 return;
3162
3163         if (m_admin_nick == name && !m_admin_nick.empty()) {
3164                 m_admin_chat->outgoing_queue.push_back(new ChatEventChat("", msg));
3165         }
3166
3167         RemotePlayer *player = m_env->getPlayer(name);
3168         if (!player) {
3169                 return;
3170         }
3171
3172         if (player->getPeerId() == PEER_ID_INEXISTENT)
3173                 return;
3174
3175         SendChatMessage(player->getPeerId(), ChatMessage(msg));
3176 }
3177
3178 bool Server::showFormspec(const char *playername, const std::string &formspec,
3179         const std::string &formname)
3180 {
3181         // m_env will be NULL if the server is initializing
3182         if (!m_env)
3183                 return false;
3184
3185         RemotePlayer *player = m_env->getPlayer(playername);
3186         if (!player)
3187                 return false;
3188
3189         SendShowFormspecMessage(player->getPeerId(), formspec, formname);
3190         return true;
3191 }
3192
3193 u32 Server::hudAdd(RemotePlayer *player, HudElement *form)
3194 {
3195         if (!player)
3196                 return -1;
3197
3198         u32 id = player->addHud(form);
3199
3200         SendHUDAdd(player->getPeerId(), id, form);
3201
3202         return id;
3203 }
3204
3205 bool Server::hudRemove(RemotePlayer *player, u32 id) {
3206         if (!player)
3207                 return false;
3208
3209         HudElement* todel = player->removeHud(id);
3210
3211         if (!todel)
3212                 return false;
3213
3214         delete todel;
3215
3216         SendHUDRemove(player->getPeerId(), id);
3217         return true;
3218 }
3219
3220 bool Server::hudChange(RemotePlayer *player, u32 id, HudElementStat stat, void *data)
3221 {
3222         if (!player)
3223                 return false;
3224
3225         SendHUDChange(player->getPeerId(), id, stat, data);
3226         return true;
3227 }
3228
3229 bool Server::hudSetFlags(RemotePlayer *player, u32 flags, u32 mask)
3230 {
3231         if (!player)
3232                 return false;
3233
3234         SendHUDSetFlags(player->getPeerId(), flags, mask);
3235         player->hud_flags &= ~mask;
3236         player->hud_flags |= flags;
3237
3238         PlayerSAO* playersao = player->getPlayerSAO();
3239
3240         if (!playersao)
3241                 return false;
3242
3243         m_script->player_event(playersao, "hud_changed");
3244         return true;
3245 }
3246
3247 bool Server::hudSetHotbarItemcount(RemotePlayer *player, s32 hotbar_itemcount)
3248 {
3249         if (!player)
3250                 return false;
3251
3252         if (hotbar_itemcount <= 0 || hotbar_itemcount > HUD_HOTBAR_ITEMCOUNT_MAX)
3253                 return false;
3254
3255         player->setHotbarItemcount(hotbar_itemcount);
3256         std::ostringstream os(std::ios::binary);
3257         writeS32(os, hotbar_itemcount);
3258         SendHUDSetParam(player->getPeerId(), HUD_PARAM_HOTBAR_ITEMCOUNT, os.str());
3259         return true;
3260 }
3261
3262 void Server::hudSetHotbarImage(RemotePlayer *player, const std::string &name)
3263 {
3264         if (!player)
3265                 return;
3266
3267         player->setHotbarImage(name);
3268         SendHUDSetParam(player->getPeerId(), HUD_PARAM_HOTBAR_IMAGE, name);
3269 }
3270
3271 void Server::hudSetHotbarSelectedImage(RemotePlayer *player, const std::string &name)
3272 {
3273         if (!player)
3274                 return;
3275
3276         player->setHotbarSelectedImage(name);
3277         SendHUDSetParam(player->getPeerId(), HUD_PARAM_HOTBAR_SELECTED_IMAGE, name);
3278 }
3279
3280 Address Server::getPeerAddress(session_t peer_id)
3281 {
3282         return m_con->GetPeerAddress(peer_id);
3283 }
3284
3285 void Server::setLocalPlayerAnimations(RemotePlayer *player,
3286                 v2s32 animation_frames[4], f32 frame_speed)
3287 {
3288         sanity_check(player);
3289         player->setLocalAnimations(animation_frames, frame_speed);
3290         SendLocalPlayerAnimations(player->getPeerId(), animation_frames, frame_speed);
3291 }
3292
3293 void Server::setPlayerEyeOffset(RemotePlayer *player, const v3f &first, const v3f &third)
3294 {
3295         sanity_check(player);
3296         player->eye_offset_first = first;
3297         player->eye_offset_third = third;
3298         SendEyeOffset(player->getPeerId(), first, third);
3299 }
3300
3301 void Server::setSky(RemotePlayer *player, const SkyboxParams &params)
3302 {
3303         sanity_check(player);
3304         player->setSky(params);
3305         SendSetSky(player->getPeerId(), params);
3306 }
3307
3308 void Server::setSun(RemotePlayer *player, const SunParams &params)
3309 {
3310         sanity_check(player);
3311         player->setSun(params);
3312         SendSetSun(player->getPeerId(), params);
3313 }
3314
3315 void Server::setMoon(RemotePlayer *player, const MoonParams &params)
3316 {
3317         sanity_check(player);
3318         player->setMoon(params);
3319         SendSetMoon(player->getPeerId(), params);
3320 }
3321
3322 void Server::setStars(RemotePlayer *player, const StarParams &params)
3323 {
3324         sanity_check(player);
3325         player->setStars(params);
3326         SendSetStars(player->getPeerId(), params);
3327 }
3328
3329 void Server::setClouds(RemotePlayer *player, const CloudParams &params)
3330 {
3331         sanity_check(player);
3332         player->setCloudParams(params);
3333         SendCloudParams(player->getPeerId(), params);
3334 }
3335
3336 void Server::overrideDayNightRatio(RemotePlayer *player, bool do_override,
3337         float ratio)
3338 {
3339         sanity_check(player);
3340         player->overrideDayNightRatio(do_override, ratio);
3341         SendOverrideDayNightRatio(player->getPeerId(), do_override, ratio);
3342 }
3343
3344 void Server::notifyPlayers(const std::wstring &msg)
3345 {
3346         SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(msg));
3347 }
3348
3349 void Server::spawnParticle(const std::string &playername,
3350         const ParticleParameters &p)
3351 {
3352         // m_env will be NULL if the server is initializing
3353         if (!m_env)
3354                 return;
3355
3356         session_t peer_id = PEER_ID_INEXISTENT;
3357         u16 proto_ver = 0;
3358         if (!playername.empty()) {
3359                 RemotePlayer *player = m_env->getPlayer(playername.c_str());
3360                 if (!player)
3361                         return;
3362                 peer_id = player->getPeerId();
3363                 proto_ver = player->protocol_version;
3364         }
3365
3366         SendSpawnParticle(peer_id, proto_ver, p);
3367 }
3368
3369 u32 Server::addParticleSpawner(const ParticleSpawnerParameters &p,
3370         ServerActiveObject *attached, const std::string &playername)
3371 {
3372         // m_env will be NULL if the server is initializing
3373         if (!m_env)
3374                 return -1;
3375
3376         session_t peer_id = PEER_ID_INEXISTENT;
3377         u16 proto_ver = 0;
3378         if (!playername.empty()) {
3379                 RemotePlayer *player = m_env->getPlayer(playername.c_str());
3380                 if (!player)
3381                         return -1;
3382                 peer_id = player->getPeerId();
3383                 proto_ver = player->protocol_version;
3384         }
3385
3386         u16 attached_id = attached ? attached->getId() : 0;
3387
3388         u32 id;
3389         if (attached_id == 0)
3390                 id = m_env->addParticleSpawner(p.time);
3391         else
3392                 id = m_env->addParticleSpawner(p.time, attached_id);
3393
3394         SendAddParticleSpawner(peer_id, proto_ver, p, attached_id, id);
3395         return id;
3396 }
3397
3398 void Server::deleteParticleSpawner(const std::string &playername, u32 id)
3399 {
3400         // m_env will be NULL if the server is initializing
3401         if (!m_env)
3402                 throw ServerError("Can't delete particle spawners during initialisation!");
3403
3404         session_t peer_id = PEER_ID_INEXISTENT;
3405         if (!playername.empty()) {
3406                 RemotePlayer *player = m_env->getPlayer(playername.c_str());
3407                 if (!player)
3408                         return;
3409                 peer_id = player->getPeerId();
3410         }
3411
3412         m_env->deleteParticleSpawner(id);
3413         SendDeleteParticleSpawner(peer_id, id);
3414 }
3415
3416 // actions: time-reversed list
3417 // Return value: success/failure
3418 bool Server::rollbackRevertActions(const std::list<RollbackAction> &actions,
3419                 std::list<std::string> *log)
3420 {
3421         infostream<<"Server::rollbackRevertActions(len="<<actions.size()<<")"<<std::endl;
3422         ServerMap *map = (ServerMap*)(&m_env->getMap());
3423
3424         // Fail if no actions to handle
3425         if (actions.empty()) {
3426                 assert(log);
3427                 log->push_back("Nothing to do.");
3428                 return false;
3429         }
3430
3431         int num_tried = 0;
3432         int num_failed = 0;
3433
3434         for (const RollbackAction &action : actions) {
3435                 num_tried++;
3436                 bool success = action.applyRevert(map, m_inventory_mgr.get(), this);
3437                 if(!success){
3438                         num_failed++;
3439                         std::ostringstream os;
3440                         os<<"Revert of step ("<<num_tried<<") "<<action.toString()<<" failed";
3441                         infostream<<"Map::rollbackRevertActions(): "<<os.str()<<std::endl;
3442                         if (log)
3443                                 log->push_back(os.str());
3444                 }else{
3445                         std::ostringstream os;
3446                         os<<"Successfully reverted step ("<<num_tried<<") "<<action.toString();
3447                         infostream<<"Map::rollbackRevertActions(): "<<os.str()<<std::endl;
3448                         if (log)
3449                                 log->push_back(os.str());
3450                 }
3451         }
3452
3453         infostream<<"Map::rollbackRevertActions(): "<<num_failed<<"/"<<num_tried
3454                         <<" failed"<<std::endl;
3455
3456         // Call it done if less than half failed
3457         return num_failed <= num_tried/2;
3458 }
3459
3460 // IGameDef interface
3461 // Under envlock
3462 IItemDefManager *Server::getItemDefManager()
3463 {
3464         return m_itemdef;
3465 }
3466
3467 const NodeDefManager *Server::getNodeDefManager()
3468 {
3469         return m_nodedef;
3470 }
3471
3472 ICraftDefManager *Server::getCraftDefManager()
3473 {
3474         return m_craftdef;
3475 }
3476
3477 u16 Server::allocateUnknownNodeId(const std::string &name)
3478 {
3479         return m_nodedef->allocateDummy(name);
3480 }
3481
3482 IWritableItemDefManager *Server::getWritableItemDefManager()
3483 {
3484         return m_itemdef;
3485 }
3486
3487 NodeDefManager *Server::getWritableNodeDefManager()
3488 {
3489         return m_nodedef;
3490 }
3491
3492 IWritableCraftDefManager *Server::getWritableCraftDefManager()
3493 {
3494         return m_craftdef;
3495 }
3496
3497 const std::vector<ModSpec> & Server::getMods() const
3498 {
3499         return m_modmgr->getMods();
3500 }
3501
3502 const ModSpec *Server::getModSpec(const std::string &modname) const
3503 {
3504         return m_modmgr->getModSpec(modname);
3505 }
3506
3507 void Server::getModNames(std::vector<std::string> &modlist)
3508 {
3509         m_modmgr->getModNames(modlist);
3510 }
3511
3512 std::string Server::getBuiltinLuaPath()
3513 {
3514         return porting::path_share + DIR_DELIM + "builtin";
3515 }
3516
3517 std::string Server::getModStoragePath() const
3518 {
3519         return m_path_world + DIR_DELIM + "mod_storage";
3520 }
3521
3522 v3f Server::findSpawnPos()
3523 {
3524         ServerMap &map = m_env->getServerMap();
3525         v3f nodeposf;
3526         if (g_settings->getV3FNoEx("static_spawnpoint", nodeposf))
3527                 return nodeposf * BS;
3528
3529         bool is_good = false;
3530         // Limit spawn range to mapgen edges (determined by 'mapgen_limit')
3531         s32 range_max = map.getMapgenParams()->getSpawnRangeMax();
3532
3533         // Try to find a good place a few times
3534         for (s32 i = 0; i < 4000 && !is_good; i++) {
3535                 s32 range = MYMIN(1 + i, range_max);
3536                 // We're going to try to throw the player to this position
3537                 v2s16 nodepos2d = v2s16(
3538                         -range + (myrand() % (range * 2)),
3539                         -range + (myrand() % (range * 2)));
3540                 // Get spawn level at point
3541                 s16 spawn_level = m_emerge->getSpawnLevelAtPoint(nodepos2d);
3542                 // Continue if MAX_MAP_GENERATION_LIMIT was returned by the mapgen to
3543                 // signify an unsuitable spawn position, or if outside limits.
3544                 if (spawn_level >= MAX_MAP_GENERATION_LIMIT ||
3545                                 spawn_level <= -MAX_MAP_GENERATION_LIMIT)
3546                         continue;
3547
3548                 v3s16 nodepos(nodepos2d.X, spawn_level, nodepos2d.Y);
3549                 // Consecutive empty nodes
3550                 s32 air_count = 0;
3551
3552                 // Search upwards from 'spawn level' for 2 consecutive empty nodes, to
3553                 // avoid obstructions in already-generated mapblocks.
3554                 // In ungenerated mapblocks consisting of 'ignore' nodes, there will be
3555                 // no obstructions, but mapgen decorations are generated after spawn so
3556                 // the player may end up inside one.
3557                 for (s32 i = 0; i < 8; i++) {
3558                         v3s16 blockpos = getNodeBlockPos(nodepos);
3559                         map.emergeBlock(blockpos, true);
3560                         content_t c = map.getNode(nodepos).getContent();
3561
3562                         // In generated mapblocks allow spawn in all 'airlike' drawtype nodes.
3563                         // In ungenerated mapblocks allow spawn in 'ignore' nodes.
3564                         if (m_nodedef->get(c).drawtype == NDT_AIRLIKE || c == CONTENT_IGNORE) {
3565                                 air_count++;
3566                                 if (air_count >= 2) {
3567                                         // Spawn in lower empty node
3568                                         nodepos.Y--;
3569                                         nodeposf = intToFloat(nodepos, BS);
3570                                         // Don't spawn the player outside map boundaries
3571                                         if (objectpos_over_limit(nodeposf))
3572                                                 // Exit this loop, positions above are probably over limit
3573                                                 break;
3574
3575                                         // Good position found, cause an exit from main loop
3576                                         is_good = true;
3577                                         break;
3578                                 }
3579                         } else {
3580                                 air_count = 0;
3581                         }
3582                         nodepos.Y++;
3583                 }
3584         }
3585
3586         if (is_good)
3587                 return nodeposf;
3588
3589         // No suitable spawn point found, return fallback 0,0,0
3590         return v3f(0.0f, 0.0f, 0.0f);
3591 }
3592
3593 void Server::requestShutdown(const std::string &msg, bool reconnect, float delay)
3594 {
3595         if (delay == 0.0f) {
3596         // No delay, shutdown immediately
3597                 m_shutdown_state.is_requested = true;
3598                 // only print to the infostream, a chat message saying
3599                 // "Server Shutting Down" is sent when the server destructs.
3600                 infostream << "*** Immediate Server shutdown requested." << std::endl;
3601         } else if (delay < 0.0f && m_shutdown_state.isTimerRunning()) {
3602                 // Negative delay, cancel shutdown if requested
3603                 m_shutdown_state.reset();
3604                 std::wstringstream ws;
3605
3606                 ws << L"*** Server shutdown canceled.";
3607
3608                 infostream << wide_to_utf8(ws.str()).c_str() << std::endl;
3609                 SendChatMessage(PEER_ID_INEXISTENT, ws.str());
3610                 // m_shutdown_* are already handled, skip.
3611                 return;
3612         } else if (delay > 0.0f) {
3613         // Positive delay, tell the clients when the server will shut down
3614                 std::wstringstream ws;
3615
3616                 ws << L"*** Server shutting down in "
3617                                 << duration_to_string(myround(delay)).c_str()
3618                                 << ".";
3619
3620                 infostream << wide_to_utf8(ws.str()).c_str() << std::endl;
3621                 SendChatMessage(PEER_ID_INEXISTENT, ws.str());
3622         }
3623
3624         m_shutdown_state.trigger(delay, msg, reconnect);
3625 }
3626
3627 PlayerSAO* Server::emergePlayer(const char *name, session_t peer_id, u16 proto_version)
3628 {
3629         /*
3630                 Try to get an existing player
3631         */
3632         RemotePlayer *player = m_env->getPlayer(name);
3633
3634         // If player is already connected, cancel
3635         if (player && player->getPeerId() != PEER_ID_INEXISTENT) {
3636                 infostream<<"emergePlayer(): Player already connected"<<std::endl;
3637                 return NULL;
3638         }
3639
3640         /*
3641                 If player with the wanted peer_id already exists, cancel.
3642         */
3643         if (m_env->getPlayer(peer_id)) {
3644                 infostream<<"emergePlayer(): Player with wrong name but same"
3645                                 " peer_id already exists"<<std::endl;
3646                 return NULL;
3647         }
3648
3649         if (!player) {
3650                 player = new RemotePlayer(name, idef());
3651         }
3652
3653         bool newplayer = false;
3654
3655         // Load player
3656         PlayerSAO *playersao = m_env->loadPlayer(player, &newplayer, peer_id, isSingleplayer());
3657
3658         // Complete init with server parts
3659         playersao->finalize(player, getPlayerEffectivePrivs(player->getName()));
3660         player->protocol_version = proto_version;
3661
3662         /* Run scripts */
3663         if (newplayer) {
3664                 m_script->on_newplayer(playersao);
3665         }
3666
3667         return playersao;
3668 }
3669
3670 bool Server::registerModStorage(ModMetadata *storage)
3671 {
3672         if (m_mod_storages.find(storage->getModName()) != m_mod_storages.end()) {
3673                 errorstream << "Unable to register same mod storage twice. Storage name: "
3674                                 << storage->getModName() << std::endl;
3675                 return false;
3676         }
3677
3678         m_mod_storages[storage->getModName()] = storage;
3679         return true;
3680 }
3681
3682 void Server::unregisterModStorage(const std::string &name)
3683 {
3684         std::unordered_map<std::string, ModMetadata *>::const_iterator it = m_mod_storages.find(name);
3685         if (it != m_mod_storages.end()) {
3686                 // Save unconditionaly on unregistration
3687                 it->second->save(getModStoragePath());
3688                 m_mod_storages.erase(name);
3689         }
3690 }
3691
3692 void dedicated_server_loop(Server &server, bool &kill)
3693 {
3694         verbosestream<<"dedicated_server_loop()"<<std::endl;
3695
3696         IntervalLimiter m_profiler_interval;
3697
3698         static thread_local const float steplen =
3699                         g_settings->getFloat("dedicated_server_step");
3700         static thread_local const float profiler_print_interval =
3701                         g_settings->getFloat("profiler_print_interval");
3702
3703         /*
3704          * The dedicated server loop only does time-keeping (in Server::step) and
3705          * provides a way to main.cpp to kill the server externally (bool &kill).
3706          */
3707
3708         for(;;) {
3709                 // This is kind of a hack but can be done like this
3710                 // because server.step() is very light
3711                 sleep_ms((int)(steplen*1000.0));
3712                 server.step(steplen);
3713
3714                 if (server.isShutdownRequested() || kill)
3715                         break;
3716
3717                 /*
3718                         Profiler
3719                 */
3720                 if (profiler_print_interval != 0) {
3721                         if(m_profiler_interval.step(steplen, profiler_print_interval))
3722                         {
3723                                 infostream<<"Profiler:"<<std::endl;
3724                                 g_profiler->print(infostream);
3725                                 g_profiler->clear();
3726                         }
3727                 }
3728         }
3729
3730         infostream << "Dedicated server quitting" << std::endl;
3731 #if USE_CURL
3732         if (g_settings->getBool("server_announce"))
3733                 ServerList::sendAnnounce(ServerList::AA_DELETE,
3734                         server.m_bind_addr.getPort());
3735 #endif
3736 }
3737
3738 /*
3739  * Mod channels
3740  */
3741
3742
3743 bool Server::joinModChannel(const std::string &channel)
3744 {
3745         return m_modchannel_mgr->joinChannel(channel, PEER_ID_SERVER) &&
3746                         m_modchannel_mgr->setChannelState(channel, MODCHANNEL_STATE_READ_WRITE);
3747 }
3748
3749 bool Server::leaveModChannel(const std::string &channel)
3750 {
3751         return m_modchannel_mgr->leaveChannel(channel, PEER_ID_SERVER);
3752 }
3753
3754 bool Server::sendModChannelMessage(const std::string &channel, const std::string &message)
3755 {
3756         if (!m_modchannel_mgr->canWriteOnChannel(channel))
3757                 return false;
3758
3759         broadcastModChannelMessage(channel, message, PEER_ID_SERVER);
3760         return true;
3761 }
3762
3763 ModChannel* Server::getModChannel(const std::string &channel)
3764 {
3765         return m_modchannel_mgr->getModChannel(channel);
3766 }
3767
3768 void Server::broadcastModChannelMessage(const std::string &channel,
3769                 const std::string &message, session_t from_peer)
3770 {
3771         const std::vector<u16> &peers = m_modchannel_mgr->getChannelPeers(channel);
3772         if (peers.empty())
3773                 return;
3774
3775         if (message.size() > STRING_MAX_LEN) {
3776                 warningstream << "ModChannel message too long, dropping before sending "
3777                                 << " (" << message.size() << " > " << STRING_MAX_LEN << ", channel: "
3778                                 << channel << ")" << std::endl;
3779                 return;
3780         }
3781
3782         std::string sender;
3783         if (from_peer != PEER_ID_SERVER) {
3784                 sender = getPlayerName(from_peer);
3785         }
3786
3787         NetworkPacket resp_pkt(TOCLIENT_MODCHANNEL_MSG,
3788                         2 + channel.size() + 2 + sender.size() + 2 + message.size());
3789         resp_pkt << channel << sender << message;
3790         for (session_t peer_id : peers) {
3791                 // Ignore sender
3792                 if (peer_id == from_peer)
3793                         continue;
3794
3795                 Send(peer_id, &resp_pkt);
3796         }
3797
3798         if (from_peer != PEER_ID_SERVER) {
3799                 m_script->on_modchannel_message(channel, sender, message);
3800         }
3801 }
3802
3803 void Server::loadTranslationLanguage(const std::string &lang_code)
3804 {
3805         if (g_server_translations->count(lang_code))
3806                 return; // Already loaded
3807
3808         std::string suffix = "." + lang_code + ".tr";
3809         for (const auto &i : m_media) {
3810                 if (str_ends_with(i.first, suffix)) {
3811                         std::ifstream t(i.second.path);
3812                         std::string data((std::istreambuf_iterator<char>(t)),
3813                         std::istreambuf_iterator<char>());
3814
3815                         (*g_server_translations)[lang_code].loadTranslation(data);
3816                 }
3817         }
3818 }