From a7e5b8ecc953d5e8da27970b1d94e79bce8b2d2a Mon Sep 17 00:00:00 2001
From: Kitty Barnett <develop@catznip.com>
Date: Mon, 27 Apr 2020 00:07:19 +0200
Subject: [PATCH] Restore the @setenv restriction

---
 indra/newview/llenvironment.cpp  | 11 +++++
 indra/newview/rlvactions.cpp     |  9 ++++
 indra/newview/rlvactions.h       | 11 +++++
 indra/newview/rlvenvironment.cpp | 26 +++++++++---
 indra/newview/rlvenvironment.h   |  1 +
 indra/newview/rlvhandler.cpp     | 70 +++++++++++++++++++-------------
 indra/newview/rlvhelper.cpp      |  2 +-
 7 files changed, 94 insertions(+), 36 deletions(-)

diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index 0e1c4f94346..8f17e563d59 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -65,6 +65,10 @@
 #include "llviewergenericmessage.h"
 #include "llexperiencelog.h"
 
+// [RLVa:KB] - Checked: RLVa-2.4 (@setenv)
+#include "rlvactions.h"
+// [/RLVa:KB]
+
 //=========================================================================
 namespace
 {
@@ -1057,6 +1061,13 @@ bool LLEnvironment::getIsMoonUp() const
 //-------------------------------------------------------------------------
 void LLEnvironment::setSelectedEnvironment(LLEnvironment::EnvSelection_t env, LLSettingsBase::Seconds transition, bool forced)
 {
+// [RLVa:KB] - Checked: RLVa-2.4 (@setenv)
+    if ( (!RlvActions::canChangeEnvironment()) && (LLEnvironment::ENV_EDIT != env) )
+    {
+        return;
+    }
+// [/RLVa:KB]
+
     mSelectedEnvironment = env;
     updateEnvironment(transition, forced);
 }
diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp
index f5c5dc52a6e..9acbb47ea10 100644
--- a/indra/newview/rlvactions.cpp
+++ b/indra/newview/rlvactions.cpp
@@ -351,6 +351,15 @@ bool RlvActions::isLocalTp(const LLVector3d& posGlobal)
 	return nDistSq < RLV_MODIFIER_TPLOCAL_DEFAULT * RLV_MODIFIER_TPLOCAL_DEFAULT;
 }
 
+// ============================================================================
+// WindLight
+//
+
+bool RlvActions::canChangeEnvironment()
+{
+	return !gRlvHandler.hasBehaviour(RLV_BHVR_SETENV);
+}
+
 // ============================================================================
 // World interaction
 //
diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h
index 90b1069f6bd..be22f4ce6ae 100644
--- a/indra/newview/rlvactions.h
+++ b/indra/newview/rlvactions.h
@@ -26,6 +26,7 @@
 
 class LLInventoryCategory;
 class LLInventoryItem;
+class LLViewerObject;
 
 // ============================================================================
 // RlvActions class declaration - developer-friendly non-RLVa code facing class, use in lieu of RlvHandler whenever possible
@@ -207,6 +208,16 @@ class RlvActions
 	 */
 	static bool isLocalTp(const LLVector3d& posGlobal);
 
+	// =========
+	// WindLight
+	// =========
+public:
+	/*
+	 * Returns true if the user can make changes to their WindLight environment 
+	 */
+	static bool canChangeEnvironment();
+
+
 	// =================
 	// World interaction
 	// =================
diff --git a/indra/newview/rlvenvironment.cpp b/indra/newview/rlvenvironment.cpp
index 83423994856..b4e1c6fbeaf 100644
--- a/indra/newview/rlvenvironment.cpp
+++ b/indra/newview/rlvenvironment.cpp
@@ -20,6 +20,7 @@
 #include "llsettingsvo.h"
 #include <boost/algorithm/string.hpp>
 
+#include "rlvactions.h"
 #include "rlvenvironment.h"
 #include "rlvhelper.h"
 
@@ -413,9 +414,16 @@ RlvEnvironment::RlvEnvironment()
 												if ((nValue >= 0.f) && (nValue <= 1.0f))
 												{
 													LLSettingsDay::ptr_t pDay;
-													LLEnvironment::EnvSelection_t envs[] = { LLEnvironment::ENV_LOCAL, LLEnvironment::ENV_PUSH, LLEnvironment::ENV_PARCEL, LLEnvironment::ENV_REGION };
-													for (size_t idxEnv = 0, cntEnv = sizeof(envs) / sizeof(LLEnvironment::EnvSelection_t); idxEnv < cntEnv && !pDay; idxEnv++)
-														pDay = LLEnvironment::instance().getEnvironmentDay(envs[idxEnv]);
+													if (LLEnvironment::ENV_EDIT != env)
+													{
+														LLEnvironment::EnvSelection_t envs[] = { LLEnvironment::ENV_LOCAL, LLEnvironment::ENV_PUSH, LLEnvironment::ENV_PARCEL, LLEnvironment::ENV_REGION };
+														for (size_t idxEnv = 0, cntEnv = sizeof(envs) / sizeof(LLEnvironment::EnvSelection_t); idxEnv < cntEnv && !pDay; idxEnv++)
+															pDay = LLEnvironment::instance().getEnvironmentDay(envs[idxEnv]);
+													}
+													else
+													{
+														pDay = LLEnvironment::instance().getEnvironmentDay(LLEnvironment::ENV_EDIT);
+													}
 
 													if (pDay)
 													{
@@ -445,7 +453,7 @@ RlvEnvironment::RlvEnvironment()
 											{
 												// I forgot how much I hate this command... it literally makes no sense since time of day only has any meaning in an
 												// actively animating day cycle (but in that case we have to return -1).
-												if (!LLEnvironment::instance().getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL)) {
+												if (!LLEnvironment::instance().getEnvironmentFixedSky(env)) {
 													return std::to_string(-1.f);
 												}
 
@@ -458,6 +466,12 @@ RlvEnvironment::~RlvEnvironment()
 {
 }
 
+// static
+LLEnvironment::EnvSelection_t RlvEnvironment::getTargetEnvironment()
+{
+	return RlvActions::canChangeEnvironment() ? LLEnvironment::ENV_LOCAL : LLEnvironment::ENV_EDIT;
+}
+
 // static
 bool RlvEnvironment::onHandleCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet, const std::string& strCmdPrefix, const handler_map_t& fnLookup, const legacy_handler_map_t& legacyFnLookup)
 {
@@ -611,7 +625,7 @@ void RlvEnvironment::registerGetEnvFn(const std::string& strFnName, const std::f
 	RLV_ASSERT(m_GetFnLookup.end() == m_GetFnLookup.find(strFnName));
 	m_GetFnLookup.insert(std::make_pair(strFnName, [this, getFn](const std::string& strRlvParam)
 		{
-			if (RlvUtil::sendChatReply(strRlvParam, getFn(LLEnvironment::ENV_LOCAL)))
+			if (RlvUtil::sendChatReply(strRlvParam, getFn(getTargetEnvironment())))
 				return RLV_RET_SUCCESS;
 			return RLV_RET_FAILED_PARAM;
 		}));
@@ -626,7 +640,7 @@ void RlvEnvironment::registerSetEnvFn(const std::string& strFnName, const std::f
 			T optionValue;
 			if (!RlvCommandOptionHelper::parseOption<T>(strRlvOption, optionValue))
 				return RLV_RET_FAILED_PARAM;
-			return setFn(LLEnvironment::ENV_LOCAL, optionValue);
+			return setFn(getTargetEnvironment(), optionValue);
 		}));
 }
 
diff --git a/indra/newview/rlvenvironment.h b/indra/newview/rlvenvironment.h
index 9ad60f72645..0f70e24cae2 100644
--- a/indra/newview/rlvenvironment.h
+++ b/indra/newview/rlvenvironment.h
@@ -33,6 +33,7 @@ class RlvEnvironment : public RlvExtCommandHandler
 	bool onReplyCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet) override;
 	bool onForceCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet) override;
 protected:
+	static LLEnvironment::EnvSelection_t getTargetEnvironment();
 	typedef std::map<std::string, std::function<ERlvCmdRet(const std::string&)>> handler_map_t;
 	typedef std::map<std::string, std::function<ERlvCmdRet(const std::string&, U32)>> legacy_handler_map_t;
 	static bool onHandleCommand(const RlvCommand& rlvCmd, ERlvCmdRet& cmdRet, const std::string& strCmdPrefix, const handler_map_t& fnLookup, const legacy_handler_map_t& legacyFnLookup);
diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp
index 71a6b51b153..21c48421a6f 100644
--- a/indra/newview/rlvhandler.cpp
+++ b/indra/newview/rlvhandler.cpp
@@ -37,7 +37,6 @@
 #include "llavataractions.h"            // @stopim IM query
 #include "llavatarnamecache.h"			// @shownames
 #include "llavatarlist.h"				// @shownames
-//#include "llenvmanager.h"				// @setenv
 #include "llfloatersidepanelcontainer.h"// @shownames
 #include "llnotifications.h"			// @list IM query
 #include "llnotificationsutil.h"
@@ -2235,34 +2234,47 @@ void RlvBehaviourToggleHandler<RLV_BHVR_SETDEBUG>::onCommandToggle(ERlvBehaviour
 }
 
 // Handles: @setenv=n|y toggles
-//template<> template<>
-//void RlvBehaviourToggleHandler<RLV_BHVR_SETENV>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
-//{
-//	const std::string strEnvFloaters[] = { "env_post_process", "env_settings", "env_delete_preset", "env_edit_sky", "env_edit_water", "env_edit_day_cycle" };
-//	for (int idxFloater = 0, cntFloater = sizeof(strEnvFloaters) / sizeof(std::string); idxFloater < cntFloater; idxFloater++)
-//	{
-//		if (fHasBhvr)
-//		{
-//			// Hide the floater if it's currently visible
-//			LLFloaterReg::const_instance_list_t envFloaters = LLFloaterReg::getFloaterList(strEnvFloaters[idxFloater]);
-//			for (LLFloater* pFloater : envFloaters)
-//				pFloater->closeFloater();
-//			RlvUIEnabler::instance().addGenericFloaterFilter(strEnvFloaters[idxFloater]);
-//		}
-//		else
-//		{
-//			RlvUIEnabler::instance().removeGenericFloaterFilter(strEnvFloaters[idxFloater]);
-//		}
-//	}
-//
-//	// Don't allow toggling "Basic Shaders" and/or "Atmopsheric Shaders" through the debug settings under @setenv=n
-//	gSavedSettings.getControl("VertexShaderEnable")->setHiddenFromSettingsEditor(fHasBhvr);
-//	gSavedSettings.getControl("WindLightUseAtmosShaders")->setHiddenFromSettingsEditor(fHasBhvr);
-//
-//	// Restore the user's WindLight preferences when releasing
-//	if (!fHasBhvr)
-//		LLEnvManagerNew::instance().usePrefs();
-//}
+template<> template<>
+void RlvBehaviourToggleHandler<RLV_BHVR_SETENV>::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr)
+{
+	const std::string strEnvFloaters[] = { "env_adjust_snapshot", "env_edit_extdaycycle", "env_fixed_environmentent_sky", "env_fixed_environmentent_water", "my_environments" };
+	for (int idxFloater = 0, cntFloater = sizeof(strEnvFloaters) / sizeof(std::string); idxFloater < cntFloater; idxFloater++)
+	{
+		if (fHasBhvr)
+		{
+			// Hide the floater if it's currently visible
+			LLFloaterReg::const_instance_list_t envFloaters = LLFloaterReg::getFloaterList(strEnvFloaters[idxFloater]);
+			for (LLFloater* pFloater : envFloaters)
+				pFloater->closeFloater();
+			RlvUIEnabler::instance().addGenericFloaterFilter(strEnvFloaters[idxFloater]);
+		}
+		else
+		{
+			RlvUIEnabler::instance().removeGenericFloaterFilter(strEnvFloaters[idxFloater]);
+		}
+	}
+
+	// Don't allow toggling "Atmopsheric Shaders" through the debug settings under @setenv=n
+	gSavedSettings.getControl("WindLightUseAtmosShaders")->setHiddenFromSettingsEditor(fHasBhvr);
+
+	if (fHasBhvr)
+	{
+		// Usurp the 'edit' environment for RLVa locking so TPV tools like quick prefs and phototools are automatically locked out as well
+		// (these needed per-feature awareness of RLV in the previous implementation which often wasn't implemented)
+		LLEnvironment* pEnv = LLEnvironment::getInstance();
+		LLSettingsSky::ptr_t pRlvSky = pEnv->getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL, true)->buildClone();
+		pEnv->setEnvironment(LLEnvironment::ENV_EDIT, pRlvSky);
+		pEnv->setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);
+		pEnv->updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+	}
+	else
+	{
+		// Restore the user's WindLight preferences when releasing
+		LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_EDIT);
+		LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+		LLEnvironment::instance().updateEnvironment();
+	}
+}
 
 // Handles: @showhovertext:<uuid>=n|y
 template<> template<>
diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp
index a58c5b7abd4..5482f4b51eb 100644
--- a/indra/newview/rlvhelper.cpp
+++ b/indra/newview/rlvhelper.cpp
@@ -129,7 +129,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_EXCEPTION>("sendimto", RLV_BHVR_SENDIMTO, RlvBehaviourInfo::BHVR_STRICT));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("sendgesture", RLV_BHVR_SENDGESTURE, RlvBehaviourInfo::BHVR_EXPERIMENTAL));
 	addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETDEBUG, RLV_OPTION_NONE>("setdebug"));
-//	addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETENV, RLV_OPTION_NONE>("setenv"));
+	addEntry(new RlvBehaviourGenericToggleProcessor<RLV_BHVR_SETENV, RLV_OPTION_NONE>("setenv"));
 	addEntry(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE>("setgroup", RLV_BHVR_SETGROUP));
 	addEntry(new RlvBehaviourInfo("sharedunwear",			RLV_BHVR_SHAREDUNWEAR,			RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_EXTENDED));
 	addEntry(new RlvBehaviourInfo("sharedwear",				RLV_BHVR_SHAREDWEAR,			RLV_TYPE_ADDREM, RlvBehaviourInfo::BHVR_EXTENDED));
-- 
GitLab