From 27d4e89d326337c8d8cafc681acde8bfbde7de77 Mon Sep 17 00:00:00 2001
From: Loic Blot <loic.blot@unix-experience.fr>
Date: Tue, 17 Feb 2015 20:09:36 +0100
Subject: [PATCH] Fix unused (and so, broken) enable_rollback_recording. This
 option must be reloaded at server loop but loaded when server starts, for
 data consistency (not a hot load variable) ok @ShadowNinja

---
 builtin/game/chatcommands.lua     | 10 ++++++++++
 minetest.conf.example             |  1 +
 src/map.cpp                       |  4 ++--
 src/script/lua_api/l_rollback.cpp | 10 ++++++++++
 src/server.cpp                    | 13 ++++++-------
 5 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/builtin/game/chatcommands.lua b/builtin/game/chatcommands.lua
index 2d94817e8..91b685fdf 100644
--- a/builtin/game/chatcommands.lua
+++ b/builtin/game/chatcommands.lua
@@ -570,6 +570,9 @@ core.register_chatcommand("rollback_check", {
 			.. " seconds=86400=24h, limit=5)",
 	privs = {rollback=true},
 	func = function(name, param)
+		if not core.setting_getbool("enable_rollback_recording") then
+			return false, "Rollback functions are disabled."
+		end
 		local range, seconds, limit =
 			param:match("(%d+) *(%d*) *(%d*)")
 		range = tonumber(range) or 0
@@ -583,6 +586,10 @@ core.register_chatcommand("rollback_check", {
 			local name = puncher:get_player_name()
 			core.chat_send_player(name, "Checking " .. core.pos_to_string(pos) .. "...")
 			local actions = core.rollback_get_node_actions(pos, range, seconds, limit)
+			if not actions then
+				core.chat_send_player(name, "Rollback functions are disabled")
+				return
+			end
 			local num_actions = #actions
 			if num_actions == 0 then
 				core.chat_send_player(name, "Nobody has touched"
@@ -614,6 +621,9 @@ core.register_chatcommand("rollback", {
 	description = "revert actions of a player; default for <seconds> is 60",
 	privs = {rollback=true},
 	func = function(name, param)
+		if not core.setting_getbool("enable_rollback_recording") then
+			return false, "Rollback functions are disabled."
+		end
 		local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)")
 		if not target_name then
 			local player_name = nil
diff --git a/minetest.conf.example b/minetest.conf.example
index eb883fa8e..eefe3b7bc 100644
--- a/minetest.conf.example
+++ b/minetest.conf.example
@@ -337,6 +337,7 @@
 #    If true, disable cheat prevention in multiplayer
 #disable_anticheat = false
 #    If true, actions are recorded for rollback
+#    This option is only read when server starts
 #enable_rollback_recording = false
 #    Handling for deprecated lua api calls:
 #        "legacy" = (try to) mimic old behaviour (default for release).
diff --git a/src/map.cpp b/src/map.cpp
index 0877d8c8e..a9ff22c32 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -1857,11 +1857,11 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
 
 		// Find out whether there is a suspect for this action
 		std::string suspect;
-		if(m_gamedef->rollback()){
+		if(m_gamedef->rollback()) {
 			suspect = m_gamedef->rollback()->getSuspect(p0, 83, 1);
 		}
 
-		if(!suspect.empty()){
+		if(m_gamedef->rollback() && !suspect.empty()){
 			// Blame suspect
 			RollbackScopeActor rollback_scope(m_gamedef->rollback(), suspect, true);
 			// Get old node for rollback
diff --git a/src/script/lua_api/l_rollback.cpp b/src/script/lua_api/l_rollback.cpp
index f55a72d1b..5744e6813 100644
--- a/src/script/lua_api/l_rollback.cpp
+++ b/src/script/lua_api/l_rollback.cpp
@@ -44,6 +44,9 @@ int ModApiRollback::l_rollback_get_node_actions(lua_State *L)
 	int limit = luaL_checknumber(L, 4);
 	Server *server = getServer(L);
 	IRollbackManager *rollback = server->getRollbackManager();
+	if (rollback == NULL) {
+		return 0;
+	}
 
 	std::list<RollbackAction> actions = rollback->getNodeActors(pos, range, seconds, limit);
 	std::list<RollbackAction>::iterator iter = actions.begin();
@@ -80,6 +83,13 @@ int ModApiRollback::l_rollback_revert_actions_by(lua_State *L)
 	int seconds = luaL_checknumber(L, 2);
 	Server *server = getServer(L);
 	IRollbackManager *rollback = server->getRollbackManager();
+
+	// If rollback is disabled, tell it's not a success.
+	if (rollback == NULL) {
+		lua_pushboolean(L, false);
+		lua_newtable(L);
+		return 2;
+	}
 	std::list<RollbackAction> actions = rollback->getRevertActions(actor, seconds);
 	std::list<std::string> log;
 	bool success = server->rollbackRevertActions(actions, &log);
diff --git a/src/server.cpp b/src/server.cpp
index a118e15dd..a75e27456 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -243,9 +243,6 @@ Server::Server(
 	std::string ban_path = m_path_world + DIR_DELIM "ipban.txt";
 	m_banmanager = new BanManager(ban_path);
 
-	// Create rollback manager
-	m_rollback = new RollbackManager(m_path_world, this);
-
 	ModConfiguration modconf(m_path_world);
 	m_mods = modconf.getMods();
 	std::vector<ModSpec> unsatisfied_mods = modconf.getUnsatisfiedMods();
@@ -353,6 +350,12 @@ Server::Server(
 	// Initialize mapgens
 	m_emerge->initMapgens();
 
+	m_enable_rollback_recording = g_settings->getBool("enable_rollback_recording");
+	if (m_enable_rollback_recording) {
+		// Create rollback manager
+		m_rollback = new RollbackManager(m_path_world, this);
+	}
+
 	// Give environment reference to scripting api
 	m_script->initializeEnvironment(m_env);
 
@@ -1068,10 +1071,6 @@ void Server::AsyncRunStep(bool initial_step)
 			counter = 0.0;
 
 			m_emerge->startThreads();
-
-			// Update m_enable_rollback_recording here too
-			m_enable_rollback_recording =
-					g_settings->getBool("enable_rollback_recording");
 		}
 	}
 
-- 
GitLab