From 63fc728a84a5ba97240233ad1c5d94f1ade2deb1 Mon Sep 17 00:00:00 2001
From: Wuzzy <wuzzy2@mail.ru>
Date: Thu, 24 Jun 2021 18:21:19 +0000
Subject: Require 'basic_debug' priv to view gameplay-relevant debug info,
 require 'debug' priv to view wireframe (#9315)

Fixes #7245.
---
 src/client/game.cpp                 | 59 ++++++++++++++++++++++++++++++++-----
 src/client/gameui.cpp               | 19 +++++++-----
 src/client/gameui.h                 |  3 +-
 src/client/hud.cpp                  |  5 ++++
 src/client/hud.h                    |  1 +
 src/network/clientpackethandler.cpp |  5 ++++
 src/network/networkprotocol.h       |  4 ++-
 7 files changed, 79 insertions(+), 17 deletions(-)

(limited to 'src')

diff --git a/src/client/game.cpp b/src/client/game.cpp
index d240ebc0f..9f643e611 100644
--- a/src/client/game.cpp
+++ b/src/client/game.cpp
@@ -676,6 +676,7 @@ protected:
 	bool handleCallbacks();
 	void processQueues();
 	void updateProfilers(const RunStats &stats, const FpsControl &draw_times, f32 dtime);
+	void updateBasicDebugState();
 	void updateStats(RunStats *stats, const FpsControl &draw_times, f32 dtime);
 	void updateProfilerGraphs(ProfilerGraph *graph);
 
@@ -693,6 +694,7 @@ protected:
 	void toggleFast();
 	void toggleNoClip();
 	void toggleCinematic();
+	void toggleBlockBounds();
 	void toggleAutoforward();
 
 	void toggleMinimap(bool shift_pressed);
@@ -1108,6 +1110,7 @@ void Game::run()
 		m_game_ui->clearInfoText();
 		hud->resizeHotbar();
 
+
 		updateProfilers(stats, draw_times, dtime);
 		processUserInput(dtime);
 		// Update camera before player movement to avoid camera lag of one frame
@@ -1119,10 +1122,11 @@ void Game::run()
 		updatePlayerControl(cam_view);
 		step(&dtime);
 		processClientEvents(&cam_view_target);
+		updateBasicDebugState();
 		updateCamera(draw_times.busy_time, dtime);
 		updateSound(dtime);
 		processPlayerInteraction(dtime, m_game_ui->m_flags.show_hud,
-			m_game_ui->m_flags.show_debug);
+			m_game_ui->m_flags.show_basic_debug);
 		updateFrame(&graph, &stats, dtime, cam_view);
 		updateProfilerGraphs(&graph);
 
@@ -1723,6 +1727,19 @@ void Game::processQueues()
 	shader_src->processQueue();
 }
 
+void Game::updateBasicDebugState()
+{
+	if (m_game_ui->m_flags.show_basic_debug) {
+		if (!client->checkPrivilege("basic_debug")) {
+			m_game_ui->m_flags.show_basic_debug = false;
+			hud->disableBlockBounds();
+		}
+	} else if (m_game_ui->m_flags.show_minimal_debug) {
+		if (client->checkPrivilege("basic_debug")) {
+			m_game_ui->m_flags.show_basic_debug = true;
+		}
+	}
+}
 
 void Game::updateProfilers(const RunStats &stats, const FpsControl &draw_times,
 		f32 dtime)
@@ -1935,7 +1952,7 @@ void Game::processKeyInput()
 	} else if (wasKeyDown(KeyType::SCREENSHOT)) {
 		client->makeScreenshot();
 	} else if (wasKeyDown(KeyType::TOGGLE_BLOCK_BOUNDS)) {
-		hud->toggleBlockBounds();
+		toggleBlockBounds();
 	} else if (wasKeyDown(KeyType::TOGGLE_HUD)) {
 		m_game_ui->toggleHud();
 	} else if (wasKeyDown(KeyType::MINIMAP)) {
@@ -2173,6 +2190,15 @@ void Game::toggleCinematic()
 		m_game_ui->showTranslatedStatusText("Cinematic mode disabled");
 }
 
+void Game::toggleBlockBounds()
+{
+	if (client->checkPrivilege("basic_debug")) {
+		hud->toggleBlockBounds();
+	} else {
+		m_game_ui->showTranslatedStatusText("Can't show block bounds (need 'basic_debug' privilege)");
+	}
+}
+
 // Autoforward by toggling continuous forward.
 void Game::toggleAutoforward()
 {
@@ -2236,24 +2262,41 @@ void Game::toggleFog()
 
 void Game::toggleDebug()
 {
-	// Initial / 4x toggle: Chat only
-	// 1x toggle: Debug text with chat
+	// Initial: No debug info
+	// 1x toggle: Debug text
 	// 2x toggle: Debug text with profiler graph
-	// 3x toggle: Debug text and wireframe
-	if (!m_game_ui->m_flags.show_debug) {
-		m_game_ui->m_flags.show_debug = true;
+	// 3x toggle: Debug text and wireframe (needs "debug" priv)
+	// Next toggle: Back to initial
+	//
+	// The debug text can be in 2 modes: minimal and basic.
+	// * Minimal: Only technical client info that not gameplay-relevant
+	// * Basic: Info that might give gameplay advantage, e.g. pos, angle
+	// Basic mode is used when player has "basic_debug" priv,
+	// otherwise the Minimal mode is used.
+	if (!m_game_ui->m_flags.show_minimal_debug) {
+		m_game_ui->m_flags.show_minimal_debug = true;
+		if (client->checkPrivilege("basic_debug")) {
+			m_game_ui->m_flags.show_basic_debug = true;
+		}
 		m_game_ui->m_flags.show_profiler_graph = false;
 		draw_control->show_wireframe = false;
 		m_game_ui->showTranslatedStatusText("Debug info shown");
 	} else if (!m_game_ui->m_flags.show_profiler_graph && !draw_control->show_wireframe) {
+		if (client->checkPrivilege("basic_debug")) {
+			m_game_ui->m_flags.show_basic_debug = true;
+		}
 		m_game_ui->m_flags.show_profiler_graph = true;
 		m_game_ui->showTranslatedStatusText("Profiler graph shown");
 	} else if (!draw_control->show_wireframe && client->checkPrivilege("debug")) {
+		if (client->checkPrivilege("basic_debug")) {
+			m_game_ui->m_flags.show_basic_debug = true;
+		}
 		m_game_ui->m_flags.show_profiler_graph = false;
 		draw_control->show_wireframe = true;
 		m_game_ui->showTranslatedStatusText("Wireframe shown");
 	} else {
-		m_game_ui->m_flags.show_debug = false;
+		m_game_ui->m_flags.show_minimal_debug = false;
+		m_game_ui->m_flags.show_basic_debug = false;
 		m_game_ui->m_flags.show_profiler_graph = false;
 		draw_control->show_wireframe = false;
 		if (client->checkPrivilege("debug")) {
diff --git a/src/client/gameui.cpp b/src/client/gameui.cpp
index ebc6b108c..323967550 100644
--- a/src/client/gameui.cpp
+++ b/src/client/gameui.cpp
@@ -99,7 +99,8 @@ void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_
 {
 	v2u32 screensize = RenderingEngine::getWindowSize();
 
-	if (m_flags.show_debug) {
+	// Minimal debug text must only contain info that can't give a gameplay advantage
+	if (m_flags.show_minimal_debug) {
 		static float drawtime_avg = 0;
 		drawtime_avg = drawtime_avg * 0.95 + stats.drawtime * 0.05;
 		u16 fps = 1.0 / stats.dtime_jitter.avg;
@@ -125,9 +126,10 @@ void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_
 	}
 
 	// Finally set the guitext visible depending on the flag
-	m_guitext->setVisible(m_flags.show_debug);
+	m_guitext->setVisible(m_flags.show_minimal_debug);
 
-	if (m_flags.show_debug) {
+	// Basic debug text also shows info that might give a gameplay advantage
+	if (m_flags.show_basic_debug) {
 		LocalPlayer *player = client->getEnv().getLocalPlayer();
 		v3f player_position = player->getPosition();
 
@@ -160,7 +162,7 @@ void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_
 		));
 	}
 
-	m_guitext2->setVisible(m_flags.show_debug);
+	m_guitext2->setVisible(m_flags.show_basic_debug);
 
 	setStaticText(m_guitext_info, m_infotext.c_str());
 	m_guitext_info->setVisible(m_flags.show_hud && g_menumgr.menuCount() == 0);
@@ -204,7 +206,8 @@ void GameUI::update(const RunStats &stats, Client *client, MapDrawControl *draw_
 void GameUI::initFlags()
 {
 	m_flags = GameUI::Flags();
-	m_flags.show_debug = g_settings->getBool("show_debug");
+	m_flags.show_minimal_debug = g_settings->getBool("show_debug");
+	m_flags.show_basic_debug = false;
 }
 
 void GameUI::showMinimap(bool show)
@@ -225,8 +228,10 @@ void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count)
 	// Update gui element size and position
 	s32 chat_y = 5;
 
-	if (m_flags.show_debug)
-		chat_y += 2 * g_fontengine->getLineHeight();
+	if (m_flags.show_minimal_debug)
+		chat_y += g_fontengine->getLineHeight();
+	if (m_flags.show_basic_debug)
+		chat_y += g_fontengine->getLineHeight();
 
 	const v2u32 &window_size = RenderingEngine::getWindowSize();
 
diff --git a/src/client/gameui.h b/src/client/gameui.h
index b6c8a224d..cb460b1c3 100644
--- a/src/client/gameui.h
+++ b/src/client/gameui.h
@@ -58,7 +58,8 @@ public:
 		bool show_chat = true;
 		bool show_hud = true;
 		bool show_minimap = false;
-		bool show_debug = true;
+		bool show_minimal_debug = false;
+		bool show_basic_debug = false;
 		bool show_profiler_graph = false;
 	};
 
diff --git a/src/client/hud.cpp b/src/client/hud.cpp
index 0bfdd5af0..fbfc886d2 100644
--- a/src/client/hud.cpp
+++ b/src/client/hud.cpp
@@ -870,6 +870,11 @@ void Hud::toggleBlockBounds()
 	}
 }
 
+void Hud::disableBlockBounds()
+{
+	m_block_bounds_mode = BLOCK_BOUNDS_OFF;
+}
+
 void Hud::drawBlockBounds()
 {
 	if (m_block_bounds_mode == BLOCK_BOUNDS_OFF) {
diff --git a/src/client/hud.h b/src/client/hud.h
index d341105d2..e228c1d52 100644
--- a/src/client/hud.h
+++ b/src/client/hud.h
@@ -52,6 +52,7 @@ public:
 	~Hud();
 
 	void toggleBlockBounds();
+	void disableBlockBounds();
 	void drawBlockBounds();
 
 	void drawHotbar(u16 playeritem);
diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp
index c8a160732..b86bdac18 100644
--- a/src/network/clientpackethandler.cpp
+++ b/src/network/clientpackethandler.cpp
@@ -896,6 +896,11 @@ void Client::handleCommand_Privileges(NetworkPacket* pkt)
 		m_privileges.insert(priv);
 		infostream << priv << " ";
 	}
+
+	// Enable basic_debug on server versions before it was added
+	if (m_proto_ver < 40)
+		m_privileges.insert("basic_debug");
+
 	infostream << std::endl;
 }
 
diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h
index 838bf0b2c..b647aab1a 100644
--- a/src/network/networkprotocol.h
+++ b/src/network/networkprotocol.h
@@ -205,9 +205,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 		Updated set_sky packet
 		Adds new sun, moon and stars packets
 		Minimap modes
+	PROTOCOL VERSION 40:
+		Added 'basic_debug' privilege
 */
 
-#define LATEST_PROTOCOL_VERSION 39
+#define LATEST_PROTOCOL_VERSION 40
 #define LATEST_PROTOCOL_VERSION_STRING TOSTRING(LATEST_PROTOCOL_VERSION)
 
 // Server's supported network protocol range
-- 
cgit v1.2.3