From ecdc5cf7647c0cbbb057dba2f4bdeaafc3f5a93f Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Thu, 17 May 2012 14:50:33 -0700
Subject: [PATCH] EXP-1928: Handling the rare case that the user preferences
 cannot be successfully changed, and reporting that to the user.

---
 indra/newview/llagent.cpp                     |   4 +-
 indra/newview/llagent.h                       |   4 +-
 indra/newview/llviewermessage.cpp             | 102 ++++++++++++++++--
 indra/newview/llviewerregion.cpp              |  25 +++++
 indra/newview/llviewerregion.h                |   1 +
 .../skins/default/xui/en/notifications.xml    |  11 ++
 6 files changed, 135 insertions(+), 12 deletions(-)

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 3b1e894ed3c..5d5e5855630 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -325,7 +325,7 @@ LLAgent::LLAgent() :
 	mTeleportFinishedSlot(),
 	mTeleportFailedSlot(),
 	mIsMaturityRatingChangingDuringTeleport(false),
-	mMaturityRatingChange(0),
+	mMaturityRatingChange(0U),
 	mTeleportState( TELEPORT_NONE ),
 	mRegionp(NULL),
 
@@ -3618,7 +3618,7 @@ void LLAgent::clearFailedTeleportRequest()
 	}
 }
 
-void LLAgent::setMaturityRatingChangeDuringTeleport(int pMaturityRatingChange)
+void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)
 {
 	mIsMaturityRatingChangingDuringTeleport = true;
 	mMaturityRatingChange = pMaturityRatingChange;
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 07ceaf11b10..cbfe8af90c5 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -580,7 +580,7 @@ class LLAgent : public LLOldEvents::LLObservable
 	inline bool     hasFailedTeleportRequest() {return (mFailedTeleportRequest != NULL);};
 	void            restartFailedTeleportRequest();
 	void            clearFailedTeleportRequest();
-	void            setMaturityRatingChangeDuringTeleport(int pMaturityRatingChange);
+	void            setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange);
 
 private:
 	friend class LLTeleportRequest;
@@ -595,7 +595,7 @@ class LLAgent : public LLOldEvents::LLObservable
 	boost::signals2::connection mTeleportFailedSlot;
 
 	bool            mIsMaturityRatingChangingDuringTeleport;
-	int             mMaturityRatingChange;
+	U8              mMaturityRatingChange;
 
 	void 			teleportRequest(const U64& region_handle,
 									const LLVector3& pos_local,				// Go to a named location home
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index d88a6f1a9b7..84de54986f6 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -42,6 +42,7 @@
 #include "llinventorydefines.h"
 #include "lllslconstants.h"
 #include "llregionhandle.h"
+#include "llsd.h"
 #include "llsdserialize.h"
 #include "llteleportflags.h"
 #include "lltransactionflags.h"
@@ -107,6 +108,7 @@
 #include "llagentui.h"
 #include "llpanelblockedlist.h"
 #include "llpanelplaceprofile.h"
+#include "llviewerregion.h"
 
 #include <boost/algorithm/string/split.hpp> //
 #include <boost/regex.hpp>
@@ -5385,18 +5387,102 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
 	}
 }
 
-void handle_maturity_preference_change(const LLSD &pResponse, int pMaturityRatingChange)
+void handle_maturity_preference_change(const LLSD &pResponse, U8 pMaturityRatingChange)
 {
-	if (pResponse.isUndefined())
+	bool isMaturityPreferenceElevated = false;
+	U8 actualPrefValue = SIM_ACCESS_MIN;
+
+	llassert(!pResponse.isUndefined());
+	llassert(pResponse.isMap());
+	llassert(pResponse.has("access_prefs"));
+	llassert(pResponse.get("access_prefs").isMap());
+	llassert(pResponse.get("access_prefs").has("max"));
+	llassert(pResponse.get("access_prefs").get("max").isString());
+
+	if (!pResponse.isUndefined() && pResponse.isMap() && pResponse.has("access_prefs") &&
+		pResponse.get("access_prefs").isMap() && pResponse.get("access_prefs").has("max") &&
+		pResponse.get("access_prefs").get("max").isString())
 	{
-		// XXX stinson 05/15/2012 : should report some notification that the preference has not changed
-		gAgent.clearFailedTeleportRequest();
+		LLSD::String actualPreference = pResponse.get("access_prefs").get("max").asString();
+		LLStringUtil::trim(actualPreference);
+		actualPrefValue = LLViewerRegion::shortStringToAccess(actualPreference);
 	}
-	else
+
+	switch (actualPrefValue)
+	{
+	case SIM_ACCESS_MIN :
+		switch (pMaturityRatingChange)
+		{
+		case SIM_ACCESS_MIN :
+			isMaturityPreferenceElevated = true;
+			break;
+		case SIM_ACCESS_PG :
+		case SIM_ACCESS_MATURE :
+		case SIM_ACCESS_ADULT :
+		default :
+			isMaturityPreferenceElevated = false;
+			break;
+		}
+		break;
+	case SIM_ACCESS_PG :
+		switch (pMaturityRatingChange)
+		{
+		case SIM_ACCESS_MIN :
+		case SIM_ACCESS_PG :
+			isMaturityPreferenceElevated = true;
+			break;
+		case SIM_ACCESS_MATURE :
+		case SIM_ACCESS_ADULT :
+		default :
+			isMaturityPreferenceElevated = false;
+			break;
+		}
+		break;
+	case SIM_ACCESS_MATURE :
+		switch (pMaturityRatingChange)
+		{
+		case SIM_ACCESS_MIN :
+		case SIM_ACCESS_PG :
+		case SIM_ACCESS_MATURE :
+			isMaturityPreferenceElevated = true;
+			break;
+		case SIM_ACCESS_ADULT :
+		default :
+			isMaturityPreferenceElevated = false;
+			break;
+		}
+		break;
+	case SIM_ACCESS_ADULT :
+		switch (pMaturityRatingChange)
+		{
+		case SIM_ACCESS_MIN :
+		case SIM_ACCESS_PG :
+		case SIM_ACCESS_MATURE :
+		case SIM_ACCESS_ADULT :
+			isMaturityPreferenceElevated = true;
+			break;
+		default :
+			isMaturityPreferenceElevated = false;
+			break;
+		}
+		break;
+	default :
+		isMaturityPreferenceElevated = false;
+		break;
+	}
+
+	if (isMaturityPreferenceElevated)
 	{
 		gAgent.setMaturityRatingChangeDuringTeleport(pMaturityRatingChange);
 		gAgent.restartFailedTeleportRequest();
 	}
+	else
+	{
+		LLSD args;
+		args["RATING"] = LLViewerRegion::accessToString(pMaturityRatingChange);
+		LLNotificationsUtil::add("MaturityCouldNotBeChanged", args);
+		gAgent.clearFailedTeleportRequest();
+	}
 }
 
 bool handle_special_notification_callback(const LLSD& notification, const LLSD& response)
@@ -5406,8 +5492,8 @@ bool handle_special_notification_callback(const LLSD& notification, const LLSD&
 	if (0 == option)
 	{
 		// set the preference to the maturity of the region we're calling
-		int preferredMaturity = notification["payload"]["_region_access"].asInteger();
-		gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
+		U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger());
+		gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity));
 		gAgent.sendMaturityPreferenceToServer(preferredMaturity, boost::bind(&handle_maturity_preference_change, _1, preferredMaturity));
 	}
 	else
@@ -5421,7 +5507,7 @@ bool handle_special_notification_callback(const LLSD& notification, const LLSD&
 // some of the server notifications need special handling. This is where we do that.
 bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
 {
-	int regionAccess = llsdBlock["_region_access"].asInteger();
+	U8 regionAccess = static_cast<U8>(llsdBlock["_region_access"].asInteger());
 	llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess);
 	
 	bool returnValue = false;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index e3cb985ddb3..f3771e93d97 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -654,6 +654,31 @@ std::string LLViewerRegion::accessToShortString(U8 sim_access)
 	}
 }
 
+// static
+U8 LLViewerRegion::shortStringToAccess(const std::string &sim_access)
+{
+	U8 accessValue;
+
+	if (LLStringUtil::compareStrings(sim_access, "PG") == 0)
+	{
+		accessValue = SIM_ACCESS_PG;
+	}
+	else if (LLStringUtil::compareStrings(sim_access, "M") == 0)
+	{
+		accessValue = SIM_ACCESS_MATURE;
+	}
+	else if (LLStringUtil::compareStrings(sim_access, "A") == 0)
+	{
+		accessValue = SIM_ACCESS_ADULT;
+	}
+	else
+	{
+		accessValue = SIM_ACCESS_MIN;
+	}
+
+	return accessValue;
+}
+
 // static
 void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**)
 {
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index c483c6ef529..7280c7f2e6b 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -202,6 +202,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 
 	// Returns "M", "PG", "A" etc.
 	static std::string accessToShortString(U8 sim_access);
+	static U8          shortStringToAccess(const std::string &sim_access);
 
 	// Return access icon name
 	static std::string getAccessIcon(U8 sim_access);
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 649d1982b14..c76c28579b2 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4137,6 +4137,17 @@ You won't receive any more notifications that you're about to visit a region wit
      yestext="OK"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="MaturityCouldNotBeChanged"
+   type="alertmodal">
+We were unable to change your preferences to view [RATING] content at this time.  Please attempt to change your preferences by using Me &gt; Preferences &gt; General from the menu bar, and then retrying your teleport.
+    <tag>confirm</tag>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="LandClaimAccessBlocked"
-- 
GitLab