From 880be86cf2f8d7cb7e948d8a456fd8cf5723b3f2 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Fri, 10 Mar 2017 15:07:55 -0800
Subject: [PATCH] MAINT-7196: Viewer changes supporting new Allow Access
 Override opition for estate owners.

---
 indra/llinventory/llparcel.h                  |   5 +
 indra/llmessage/llregionflags.h               |   3 +
 indra/llmessage/message_prehash.cpp           |   3 +
 indra/llmessage/message_prehash.h             |   2 +
 indra/newview/llestateinfomodel.cpp           |  80 ++----
 indra/newview/llestateinfomodel.h             |   4 +-
 indra/newview/llfloaterland.cpp               |  20 +-
 indra/newview/llfloaterregioninfo.cpp         |   6 +-
 indra/newview/llviewerparcelmgr.cpp           | 229 +++++++++---------
 .../default/xui/en/panel_region_estate.xml    |  20 +-
 scripts/messages/message_template.msg         |   4 +
 scripts/messages/message_template.msg.sha1    |   2 +-
 12 files changed, 191 insertions(+), 187 deletions(-)

diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index e68331b99a7..135d0ca7b93 100644
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -508,6 +508,9 @@ class LLParcel
 					{ return mRegionDenyAnonymousOverride; }
 	BOOL	getRegionDenyAgeUnverifiedOverride() const
 					{ return mRegionDenyAgeUnverifiedOverride; }
+    BOOL    getRegionAllowAccessOverride() const
+                    { return mRegionAllowAccessoverride; }
+
 
 	BOOL	getAllowGroupAVSounds()	const	{ return mAllowGroupAVSounds;	} 
 	BOOL	getAllowAnyAVSounds()	const	{ return mAllowAnyAVSounds;		}
@@ -576,6 +579,7 @@ class LLParcel
 	void	setRegionPushOverride(BOOL override) {mRegionPushOverride = override; }
 	void	setRegionDenyAnonymousOverride(BOOL override)	{ mRegionDenyAnonymousOverride = override; }
 	void	setRegionDenyAgeUnverifiedOverride(BOOL override)	{ mRegionDenyAgeUnverifiedOverride = override; }
+    void    setRegionAllowAccessOverride(BOOL override) { mRegionAllowAccessoverride = override; }
 
 	// Accessors for parcel sellWithObjects
 	void	setPreviousOwnerID(LLUUID prev_owner)	{ mPreviousOwnerID = prev_owner; }
@@ -657,6 +661,7 @@ class LLParcel
 	BOOL				mRegionPushOverride;
 	BOOL				mRegionDenyAnonymousOverride;
 	BOOL				mRegionDenyAgeUnverifiedOverride;
+    BOOL                mRegionAllowAccessoverride;
 	BOOL				mAllowGroupAVSounds;
 	BOOL				mAllowAnyAVSounds;
 	
diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h
index eb0c4e6d1e0..d3791ef4d1f 100644
--- a/indra/llmessage/llregionflags.h
+++ b/indra/llmessage/llregionflags.h
@@ -42,6 +42,9 @@ const U64 REGION_FLAGS_RESET_HOME_ON_TELEPORT	= (1 << 3);
 // Does the sun move?
 const U64 REGION_FLAGS_SUN_FIXED				= (1 << 4);
 
+// Does the estate owner allow private parcels?
+const U64 REGION_FLAGS_ALLOW_ACCESS_OVERRIDE    = (1 << 5);
+
 // Can't change the terrain heightfield, even on owned parcels,
 // but can plant trees and grass.
 const U64 REGION_FLAGS_BLOCK_TERRAFORM			= (1 << 6);
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 5c6b3d5fab1..a551f492505 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -1372,6 +1372,9 @@ char const* const _PREHASH_OwnerMask = LLMessageStringTable::getInstance()->getS
 char const* const _PREHASH_TransferInventoryAck = LLMessageStringTable::getInstance()->getString("TransferInventoryAck");
 char const* const _PREHASH_RegionDenyAgeUnverified = LLMessageStringTable::getInstance()->getString("RegionDenyAgeUnverified");
 char const* const _PREHASH_AgeVerificationBlock = LLMessageStringTable::getInstance()->getString("AgeVerificationBlock");
+char const* const _PREHASH_RegionAllowAccessBlock = LLMessageStringTable::getInstance()->getString("RegionAllowAccessBlock");
+char const* const _PREHASH_RegionAllowAccessOverride = LLMessageStringTable::getInstance()->getString("RegionAllowAccessOverride");
+
 char const* const _PREHASH_UCoord = LLMessageStringTable::getInstance()->getString("UCoord");
 char const* const _PREHASH_VCoord = LLMessageStringTable::getInstance()->getString("VCoord");
 char const* const _PREHASH_FaceIndex = LLMessageStringTable::getInstance()->getString("FaceIndex");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index e696c3b0cae..e38ced94ebd 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -1372,6 +1372,8 @@ extern char const* const _PREHASH_OwnerMask;
 extern char const* const _PREHASH_TransferInventoryAck;
 extern char const* const _PREHASH_RegionDenyAgeUnverified;
 extern char const* const _PREHASH_AgeVerificationBlock;
+extern char const* const _PREHASH_RegionAllowAccessBlock;
+extern char const* const _PREHASH_RegionAllowAccessOverride;
 extern char const* const _PREHASH_UCoord;
 extern char const* const _PREHASH_VCoord;
 extern char const* const _PREHASH_FaceIndex;
diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp
index 8f2eb413073..950ac712d15 100644
--- a/indra/newview/llestateinfomodel.cpp
+++ b/indra/newview/llestateinfomodel.cpp
@@ -58,12 +58,18 @@ boost::signals2::connection LLEstateInfoModel::setCommitCallback(const update_si
 
 void LLEstateInfoModel::sendEstateInfo()
 {
-	if (!commitEstateInfoCaps())
-	{
-		// the caps method failed, try the old way
-		LLFloaterRegionInfo::nextInvoice();
-		commitEstateInfoDataserver();
-	}
+    std::string url = gAgent.getRegion()->getCapability("EstateChangeInfo");
+
+    if (url.empty())
+    {
+        LL_WARNS("EstateInfo") << "Unable to get URL for cap: EstateChangeInfo!!!" << LL_ENDL;
+        // whoops, couldn't find the cap, so bail out
+        return;
+    }
+
+    LLCoros::instance().launch("LLEstateInfoModel::commitEstateInfoCapsCoro",
+        boost::bind(&LLEstateInfoModel::commitEstateInfoCapsCoro, this, url));
+
 }
 
 bool LLEstateInfoModel::getUseFixedSun()			const {	return getFlag(REGION_FLAGS_SUN_FIXED);				}
@@ -71,14 +77,16 @@ bool LLEstateInfoModel::getIsExternallyVisible()	const {	return getFlag(REGION_F
 bool LLEstateInfoModel::getAllowDirectTeleport()	const {	return getFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT);	}
 bool LLEstateInfoModel::getDenyAnonymous()			const {	return getFlag(REGION_FLAGS_DENY_ANONYMOUS); 		}
 bool LLEstateInfoModel::getDenyAgeUnverified()		const {	return getFlag(REGION_FLAGS_DENY_AGEUNVERIFIED);	}
-bool LLEstateInfoModel::getAllowVoiceChat()			const {	return getFlag(REGION_FLAGS_ALLOW_VOICE);			}
+bool LLEstateInfoModel::getAllowVoiceChat()			const { return getFlag(REGION_FLAGS_ALLOW_VOICE); }
+bool LLEstateInfoModel::getAllowAccessOverride()	const { return getFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE); }
 
 void LLEstateInfoModel::setUseFixedSun(bool val)			{ setFlag(REGION_FLAGS_SUN_FIXED, 				val);	}
 void LLEstateInfoModel::setIsExternallyVisible(bool val)	{ setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE,		val);	}
 void LLEstateInfoModel::setAllowDirectTeleport(bool val)	{ setFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT,	val);	}
 void LLEstateInfoModel::setDenyAnonymous(bool val)			{ setFlag(REGION_FLAGS_DENY_ANONYMOUS,			val);	}
 void LLEstateInfoModel::setDenyAgeUnverified(bool val)		{ setFlag(REGION_FLAGS_DENY_AGEUNVERIFIED,		val);	}
-void LLEstateInfoModel::setAllowVoiceChat(bool val)			{ setFlag(REGION_FLAGS_ALLOW_VOICE,				val);	}
+void LLEstateInfoModel::setAllowVoiceChat(bool val)		    { setFlag(REGION_FLAGS_ALLOW_VOICE,				val);	}
+void LLEstateInfoModel::setAllowAccessOverride(bool val)    { setFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE,   val);   }
 
 void LLEstateInfoModel::update(const strings_t& strings)
 {
@@ -111,23 +119,6 @@ void LLEstateInfoModel::notifyCommit()
 
 //== PRIVATE STUFF ============================================================
 
-// tries to send estate info using a cap; returns true if it succeeded
-bool LLEstateInfoModel::commitEstateInfoCaps()
-{
-	std::string url = gAgent.getRegion()->getCapability("EstateChangeInfo");
-
-	if (url.empty())
-	{
-		// whoops, couldn't find the cap, so bail out
-		return false;
-	}
-
-    LLCoros::instance().launch("LLEstateInfoModel::commitEstateInfoCapsCoro",
-        boost::bind(&LLEstateInfoModel::commitEstateInfoCapsCoro, this, url));
-
-    return true;
-}
-
 void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url)
 {
     LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
@@ -145,6 +136,7 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url)
     body["deny_anonymous"] = getDenyAnonymous();
     body["deny_age_unverified"] = getDenyAgeUnverified();
     body["allow_voice_chat"] = getAllowVoiceChat();
+    body["override_public_access"] = getAllowAccessOverride();
 
     body["invoice"] = LLFloaterRegionInfo::getLastInvoice();
 
@@ -169,43 +161,6 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url)
     }
 }
 
-/* This is the old way of doing things, is deprecated, and should be
-   deleted when the dataserver model can be removed */
-// key = "estatechangeinfo"
-// strings[0] = str(estate_id) (added by simulator before relay - not here)
-// strings[1] = estate_name
-// strings[2] = str(estate_flags)
-// strings[3] = str((S32)(sun_hour * 1024.f))
-void LLEstateInfoModel::commitEstateInfoDataserver()
-{
-	LL_DEBUGS("Windlight Sync") << "Sending estate info: "
-		<< "is_sun_fixed = " << getUseFixedSun()
-		<< ", sun_hour = " << getSunHour() << LL_ENDL;
-	LL_DEBUGS() << getInfoDump() << LL_ENDL;
-
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessage("EstateOwnerMessage");
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
-
-	msg->nextBlock("MethodData");
-	msg->addString("Method", "estatechangeinfo");
-	msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice());
-
-	msg->nextBlock("ParamList");
-	msg->addString("Parameter", getName());
-
-	msg->nextBlock("ParamList");
-	msg->addString("Parameter", llformat("%u", getFlags()));
-
-	msg->nextBlock("ParamList");
-	msg->addString("Parameter", llformat("%d", (S32) (getSunHour() * 1024.0f)));
-
-	gAgent.sendMessage();
-}
-
 std::string LLEstateInfoModel::getInfoDump()
 {
 	LLSD dump;
@@ -218,6 +173,7 @@ std::string LLEstateInfoModel::getInfoDump()
 	dump["deny_anonymous"       ] = getDenyAnonymous();
 	dump["deny_age_unverified"  ] = getDenyAgeUnverified();
 	dump["allow_voice_chat"     ] = getAllowVoiceChat();
+    dump["override_public_access"] = getAllowAccessOverride();
 
 	std::stringstream dump_str;
 	dump_str << dump;
diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h
index e7a6a2a725c..566cde34eb3 100644
--- a/indra/newview/llestateinfomodel.h
+++ b/indra/newview/llestateinfomodel.h
@@ -55,6 +55,7 @@ class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel>
 	bool				getDenyAnonymous()			const;
 	bool				getDenyAgeUnverified()		const;
 	bool				getAllowVoiceChat()			const;
+    bool                getAllowAccessOverride()    const;
 
 	const std::string&	getName()					const { return mName; }
 	const LLUUID&		getOwnerID()				const { return mOwnerID; }
@@ -68,6 +69,7 @@ class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel>
 	void setDenyAnonymous(bool val);
 	void setDenyAgeUnverified(bool val);
 	void setAllowVoiceChat(bool val);
+    void setAllowAccessOverride(bool val);
 
 	void setSunHour(F32 sun_hour) { mSunHour = sun_hour; }
 
@@ -82,8 +84,6 @@ class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel>
 	void notifyCommit();
 
 private:
-	bool commitEstateInfoCaps();
-	void commitEstateInfoDataserver();
 	inline bool getFlag(U64 flag) const;
 	inline void setFlag(U64 flag, bool val);
 	U64  getFlags() const { return mFlags; }
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index a340cd1143e..abe9f999140 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -2432,9 +2432,16 @@ void LLPanelLandAccess::refresh()
 		BOOL use_group = parcel->getParcelFlag(PF_USE_ACCESS_GROUP);
 		BOOL public_access = !use_access_list;
 		
-		getChild<LLUICtrl>("public_access")->setValue(public_access );
-		getChild<LLUICtrl>("GroupCheck")->setValue(use_group );
-
+        if (parcel->getRegionAllowAccessOverride())
+        {
+            getChild<LLUICtrl>("public_access")->setValue(public_access);
+            getChild<LLUICtrl>("GroupCheck")->setValue(use_group);
+        }
+        else
+        {
+            getChild<LLUICtrl>("public_access")->setValue(TRUE);
+            getChild<LLUICtrl>("GroupCheck")->setValue(FALSE);
+        }
 		std::string group_name;
 		gCacheName->getGroupName(parcel->getGroupID(), group_name);
 		getChild<LLUICtrl>("GroupCheck")->setLabelArg("[GROUP]", group_name );
@@ -2610,9 +2617,14 @@ void LLPanelLandAccess::refresh_ui()
 	LLParcel *parcel = mParcel->getParcel();
 	if (parcel && !gDisconnected)
 	{
-		BOOL can_manage_allowed = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_ALLOWED);
+        BOOL can_manage_allowed = false;
 		BOOL can_manage_banned = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_BANNED);
 	
+        if (parcel->getRegionAllowAccessOverride())
+        {   // Estate owner may have disabled allowing the parcel owner from managing access.
+            can_manage_allowed = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_ALLOWED);
+        }
+
 		getChildView("public_access")->setEnabled(can_manage_allowed);
 		BOOL public_access = getChild<LLUICtrl>("public_access")->getValue().asBoolean();
 		if (public_access)
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 843dbbf25ef..f4bc3302ba3 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -2236,6 +2236,7 @@ BOOL LLPanelEstateInfo::postBuild()
 	initCtrl("limit_payment");
 	initCtrl("limit_age_verified");
 	initCtrl("voice_chat_check");
+    initCtrl("parcel_access_override");
 
 	getChild<LLUICtrl>("allowed_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1));	
 	LLNameListCtrl *avatar_name_list = getChild<LLNameListCtrl>("allowed_avatar_name_list");
@@ -2315,6 +2316,7 @@ void LLPanelEstateInfo::refreshFromEstate()
 	getChild<LLUICtrl>("allow_direct_teleport")->setValue(estate_info.getAllowDirectTeleport());
 	getChild<LLUICtrl>("limit_payment")->setValue(estate_info.getDenyAnonymous());
 	getChild<LLUICtrl>("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified());
+    getChild<LLUICtrl>("parcel_access_override")->setValue(estate_info.getAllowAccessOverride());
 
 	// Ensure appriopriate state of the management UI
 	updateControls(gAgent.getRegion());
@@ -2357,7 +2359,9 @@ bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, con
 			estate_info.setDenyAnonymous(getChild<LLUICtrl>("limit_payment")->getValue().asBoolean());
 			estate_info.setDenyAgeUnverified(getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean());
 			estate_info.setAllowVoiceChat(getChild<LLUICtrl>("voice_chat_check")->getValue().asBoolean());
-
+            estate_info.setAllowAccessOverride(getChild<LLUICtrl>("parcel_access_override")->getValue().asBoolean());
+            // JIGGLYPUFF
+            //estate_info.setAllowAccessOverride(getChild<LLUICtrl>("")->getValue().asBoolean());
 			// send the update to sim
 			estate_info.sendEstateInfo();
 		}
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 2a126c9f01a..a61181badac 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1427,122 +1427,128 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user)
 // static
 void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **user)
 {
-	S32		request_result;
-	S32		sequence_id;
-	BOOL	snap_selection = FALSE;
-	S32		self_count = 0;
-	S32		other_count = 0;
-	S32		public_count = 0;
-	S32		local_id;
-	LLUUID	owner_id;
-	BOOL	is_group_owned;
-	U32 auction_id = 0;
-	S32		claim_price_per_meter = 0;
-	S32		rent_price_per_meter = 0;
-	S32		claim_date = 0;
-	LLVector3	aabb_min;
-	LLVector3	aabb_max;
-	S32		area = 0;
-	S32		sw_max_prims = 0;
-	S32		sw_total_prims = 0;
-	//LLUUID	buyer_id;
-	U8 status = 0;
-	S32		max_prims = 0;
-	S32		total_prims = 0;
-	S32		owner_prims = 0;
-	S32		group_prims = 0;
-	S32		other_prims = 0;
-	S32		selected_prims = 0;
-	F32		parcel_prim_bonus = 1.f;
-	BOOL	region_push_override = false;
-	BOOL	region_deny_anonymous_override = false;
-	BOOL	region_deny_identified_override = false; // Deprecated
-	BOOL	region_deny_transacted_override = false; // Deprecated
-	BOOL	region_deny_age_unverified_override = false;
+    S32		request_result;
+    S32		sequence_id;
+    BOOL	snap_selection = FALSE;
+    S32		self_count = 0;
+    S32		other_count = 0;
+    S32		public_count = 0;
+    S32		local_id;
+    LLUUID	owner_id;
+    BOOL	is_group_owned;
+    U32 auction_id = 0;
+    S32		claim_price_per_meter = 0;
+    S32		rent_price_per_meter = 0;
+    S32		claim_date = 0;
+    LLVector3	aabb_min;
+    LLVector3	aabb_max;
+    S32		area = 0;
+    S32		sw_max_prims = 0;
+    S32		sw_total_prims = 0;
+    //LLUUID	buyer_id;
+    U8 status = 0;
+    S32		max_prims = 0;
+    S32		total_prims = 0;
+    S32		owner_prims = 0;
+    S32		group_prims = 0;
+    S32		other_prims = 0;
+    S32		selected_prims = 0;
+    F32		parcel_prim_bonus = 1.f;
+    BOOL	region_push_override = false;
+    BOOL	region_deny_anonymous_override = false;
+    BOOL	region_deny_identified_override = false; // Deprecated
+    BOOL	region_deny_transacted_override = false; // Deprecated
+    BOOL	region_deny_age_unverified_override = false;
+    BOOL    region_allow_access_override = true;
     BOOL	agent_parcel_update = false; // updating previous(existing) agent parcel
 
-	S32		other_clean_time = 0;
+    S32		other_clean_time = 0;
 
-	LLViewerParcelMgr& parcel_mgr = LLViewerParcelMgr::instance();
+    LLViewerParcelMgr& parcel_mgr = LLViewerParcelMgr::instance();
 
-	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RequestResult, request_result );
-	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id );
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RequestResult, request_result);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id);
 
-	if (request_result == PARCEL_RESULT_NO_DATA)
-	{
-		// no valid parcel data
-		LL_INFOS() << "no valid parcel data" << LL_ENDL;
-		return;
-	}
-
-	// Decide where the data will go.
-	LLParcel* parcel = NULL;
-	if (sequence_id == SELECTED_PARCEL_SEQ_ID)
-	{
-		// ...selected parcels report this sequence id
-		parcel_mgr.mRequestResult = PARCEL_RESULT_SUCCESS;
-		parcel = parcel_mgr.mCurrentParcel;
-	}
-	else if (sequence_id == HOVERED_PARCEL_SEQ_ID)
-	{
-		parcel_mgr.mHoverRequestResult = PARCEL_RESULT_SUCCESS;
-		parcel = parcel_mgr.mHoverParcel;
-	}
-	else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID ||
-			 sequence_id == COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID ||
-			 sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
-	{
-		parcel_mgr.mHoverRequestResult = PARCEL_RESULT_SUCCESS;
-		parcel = parcel_mgr.mCollisionParcel;
-	}
-	else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID)
-	{
-		// new agent parcel
-		parcel_mgr.mAgentParcelSequenceID = sequence_id;
-		parcel = parcel_mgr.mAgentParcel;
-	}
-	else
-	{
-		LL_INFOS() << "out of order agent parcel sequence id " << sequence_id
-			<< " last good " << parcel_mgr.mAgentParcelSequenceID
-			<< LL_ENDL;
-		return;
-	}
-
-	msg->getBOOL("ParcelData", "SnapSelection", snap_selection);
-	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelfCount, self_count);
-	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherCount, other_count);
-	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_PublicCount, public_count);
-	msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_LocalID,		local_id );
-	msg->getUUIDFast(_PREHASH_ParcelData, _PREHASH_OwnerID,		owner_id);
-	msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_IsGroupOwned, is_group_owned);
-	msg->getU32Fast(_PREHASH_ParcelData, _PREHASH_AuctionID, auction_id);
-	msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_ClaimDate,	claim_date);
-	msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_ClaimPrice,	claim_price_per_meter);
-	msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_RentPrice,	rent_price_per_meter);
-	msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMin, aabb_min);
-	msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMax, aabb_max);
-	msg->getS32Fast(	_PREHASH_ParcelData, _PREHASH_Area, area );
-	//msg->getUUIDFast(	_PREHASH_ParcelData, _PREHASH_BuyerID, buyer_id);
-	msg->getU8("ParcelData", "Status", status);
-	msg->getS32("ParcelData", "SimWideMaxPrims", sw_max_prims );
-	msg->getS32("ParcelData", "SimWideTotalPrims", sw_total_prims );
-	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_MaxPrims, max_prims );
-	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_TotalPrims, total_prims );
-	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OwnerPrims, owner_prims );
-	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_GroupPrims, group_prims );
-	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherPrims, other_prims );
-	msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelectedPrims, selected_prims );
-	msg->getF32Fast(_PREHASH_ParcelData, _PREHASH_ParcelPrimBonus, parcel_prim_bonus );
-	msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionPushOverride, region_push_override );
-	msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyAnonymous, region_deny_anonymous_override );
-	msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyIdentified, region_deny_identified_override ); // Deprecated
-	msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyTransacted, region_deny_transacted_override ); // Deprecated
-	if (msg->getNumberOfBlocksFast(_PREHASH_AgeVerificationBlock))
-	{
-		// this block was added later and may not be on older sims, so we have to test its existence first
-		msg->getBOOLFast(_PREHASH_AgeVerificationBlock, _PREHASH_RegionDenyAgeUnverified, region_deny_age_unverified_override );
-	}
+    if (request_result == PARCEL_RESULT_NO_DATA)
+    {
+        // no valid parcel data
+        LL_INFOS() << "no valid parcel data" << LL_ENDL;
+        return;
+    }
+
+    // Decide where the data will go.
+    LLParcel* parcel = NULL;
+    if (sequence_id == SELECTED_PARCEL_SEQ_ID)
+    {
+        // ...selected parcels report this sequence id
+        parcel_mgr.mRequestResult = PARCEL_RESULT_SUCCESS;
+        parcel = parcel_mgr.mCurrentParcel;
+    }
+    else if (sequence_id == HOVERED_PARCEL_SEQ_ID)
+    {
+        parcel_mgr.mHoverRequestResult = PARCEL_RESULT_SUCCESS;
+        parcel = parcel_mgr.mHoverParcel;
+    }
+    else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID ||
+        sequence_id == COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID ||
+        sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
+    {
+        parcel_mgr.mHoverRequestResult = PARCEL_RESULT_SUCCESS;
+        parcel = parcel_mgr.mCollisionParcel;
+    }
+    else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID)
+    {
+        // new agent parcel
+        parcel_mgr.mAgentParcelSequenceID = sequence_id;
+        parcel = parcel_mgr.mAgentParcel;
+    }
+    else
+    {
+        LL_INFOS() << "out of order agent parcel sequence id " << sequence_id
+            << " last good " << parcel_mgr.mAgentParcelSequenceID
+            << LL_ENDL;
+        return;
+    }
+
+    msg->getBOOL("ParcelData", "SnapSelection", snap_selection);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelfCount, self_count);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherCount, other_count);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_PublicCount, public_count);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_LocalID, local_id);
+    msg->getUUIDFast(_PREHASH_ParcelData, _PREHASH_OwnerID, owner_id);
+    msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_IsGroupOwned, is_group_owned);
+    msg->getU32Fast(_PREHASH_ParcelData, _PREHASH_AuctionID, auction_id);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_ClaimDate, claim_date);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_ClaimPrice, claim_price_per_meter);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RentPrice, rent_price_per_meter);
+    msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMin, aabb_min);
+    msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMax, aabb_max);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_Area, area);
+    //msg->getUUIDFast(	_PREHASH_ParcelData, _PREHASH_BuyerID, buyer_id);
+    msg->getU8("ParcelData", "Status", status);
+    msg->getS32("ParcelData", "SimWideMaxPrims", sw_max_prims);
+    msg->getS32("ParcelData", "SimWideTotalPrims", sw_total_prims);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_MaxPrims, max_prims);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_TotalPrims, total_prims);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OwnerPrims, owner_prims);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_GroupPrims, group_prims);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherPrims, other_prims);
+    msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelectedPrims, selected_prims);
+    msg->getF32Fast(_PREHASH_ParcelData, _PREHASH_ParcelPrimBonus, parcel_prim_bonus);
+    msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionPushOverride, region_push_override);
+    msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyAnonymous, region_deny_anonymous_override);
+    msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyIdentified, region_deny_identified_override); // Deprecated
+    msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyTransacted, region_deny_transacted_override); // Deprecated
+    if (msg->getNumberOfBlocksFast(_PREHASH_AgeVerificationBlock))
+    {
+        // this block was added later and may not be on older sims, so we have to test its existence first
+        msg->getBOOLFast(_PREHASH_AgeVerificationBlock, _PREHASH_RegionDenyAgeUnverified, region_deny_age_unverified_override);
+    }
+
+    if (msg->getNumberOfBlocks(_PREHASH_RegionAllowAccessBlock))
+    {
+        msg->getBOOLFast(_PREHASH_RegionAllowAccessBlock, _PREHASH_RegionAllowAccessOverride, region_allow_access_override);
+    }
 
 	msg->getS32("ParcelData", "OtherCleanTime", other_clean_time );
 
@@ -1585,6 +1591,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
 		parcel->setRegionPushOverride(region_push_override);
 		parcel->setRegionDenyAnonymousOverride(region_deny_anonymous_override);
 		parcel->setRegionDenyAgeUnverifiedOverride(region_deny_age_unverified_override);
+        parcel->setRegionAllowAccessOverride(region_allow_access_override);
 		parcel->unpackMessage(msg);
 
 		if (parcel == parcel_mgr.mAgentParcel)
diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml
index 76a82212ae9..69e7a7b7a56 100644
--- a/indra/newview/skins/default/xui/en/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml
@@ -98,20 +98,28 @@
      width="200" />
 
     <check_box
-     height="20"
-     label="Allow Voice Chat"
+     height="18"
+     label="Allow Parcel Access Override"
      layout="topleft"
      left="280"
-     name="voice_chat_check"
+     name="parcel_access_override"
      top_delta="0"
      width="200" />
     <check_box
-     height="20"
+     height="18"
+     label="Allow Voice Chat"
+     layout="topleft"
+     left_delta ="0"
+     name="voice_chat_check"
+     top_pad="4"
+     width="200" />
+    <check_box
+     height="18"
      label="Allow Direct Teleport"
      layout="topleft"
      left_delta="0"
      name="allow_direct_teleport"
-     top_pad="4"
+     top_pad="2"
      width="80" />
     <button
      enabled="false"
@@ -120,7 +128,7 @@
      label="Apply"
      layout="topleft"
      name="apply_btn"
-     top_pad="15"
+     top_pad="7"
      left_delta="0"
      width="97" />
 
diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg
index fbbc385e5ba..c56eaae6fe9 100755
--- a/scripts/messages/message_template.msg
+++ b/scripts/messages/message_template.msg
@@ -4499,6 +4499,10 @@ version 2.0
 		AgeVerificationBlock Single
 		{   RegionDenyAgeUnverified BOOL    }
 	}
+    {
+        RegionAllowAccessBlock Single
+        {   RegionAllowAccessOverride BOOL  }  
+    }
 }
 
 // ParcelPropertiesUpdate
diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1
index 2c6489906c6..5bc06ec0427 100755
--- a/scripts/messages/message_template.msg.sha1
+++ b/scripts/messages/message_template.msg.sha1
@@ -1 +1 @@
-845459c1bb7fe8174fb493528fe2a214015f996d
\ No newline at end of file
+337f351910b0c8821cb3d447bc6578516a043c80
\ No newline at end of file
-- 
GitLab