From f9dbec6edf94ce20d52d38569545674cfb742eae Mon Sep 17 00:00:00 2001
From: nerzhul <loic.blot@unix-experience.fr>
Date: Thu, 16 Jul 2015 17:37:46 +0200
Subject: [PATCH] Kick players when shutting down server and there is a crash
 due to a Lua stack exception

---
 src/environment.cpp | 10 ++++++++++
 src/environment.h   |  1 +
 src/server.cpp      |  8 ++++++--
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/environment.cpp b/src/environment.cpp
index 5affda6fa..cad1f298b 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapblock_mesh.h"
 #include "event.h"
 #endif
+#include "server.h"
 #include "daynightratio.h"
 #include "map.h"
 #include "emerge.h"
@@ -425,6 +426,15 @@ bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, float stepsize, v3s16
 	return true;
 }
 
+void ServerEnvironment::kickAllPlayers(const std::string &reason)
+{
+	for (std::vector<Player*>::iterator it = m_players.begin();
+			it != m_players.end();
+			++it) {
+		((Server*)m_gamedef)->DenyAccess_Legacy((*it)->peer_id, utf8_to_wide(reason));
+	}
+}
+
 void ServerEnvironment::saveLoadedPlayers()
 {
 	std::string players_path = m_path_world + DIR_DELIM "players";
diff --git a/src/environment.h b/src/environment.h
index b35ca4249..794f1971c 100644
--- a/src/environment.h
+++ b/src/environment.h
@@ -221,6 +221,7 @@ class ServerEnvironment : public Environment
 	float getSendRecommendedInterval()
 		{ return m_recommended_send_interval; }
 
+	void kickAllPlayers(const std::string &reason);
 	// Save players
 	void saveLoadedPlayers();
 	void savePlayer(const std::string &playername);
diff --git a/src/server.cpp b/src/server.cpp
index 9d70ad7b7..0cad82613 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -394,10 +394,13 @@ Server::~Server()
 		// Execute script shutdown hooks
 		m_script->on_shutdown();
 
-		infostream<<"Server: Saving players"<<std::endl;
+		infostream << "Server: Saving players" << std::endl;
 		m_env->saveLoadedPlayers();
 
-		infostream<<"Server: Saving environment metadata"<<std::endl;
+		infostream << "Server: kick players" << std::endl;
+		m_env->kickAllPlayers("Server shutting down...");
+
+		infostream << "Server: Saving environment metadata" << std::endl;
 		m_env->saveMeta();
 	}
 
@@ -499,6 +502,7 @@ void Server::step(float dtime)
 			throw ServerError(async_err);
 		}
 		else {
+			m_env->kickAllPlayers("The server has crashed. Disconnecting all players. Please reconnect soon...");
 			errorstream << "UNRECOVERABLE error occurred. Stopping server. "
 					<< "Please fix the following error:" << std::endl
 					<< async_err << std::endl;
-- 
GitLab