From de2ce3f51ff54e67017d765c95264c66211c89da Mon Sep 17 00:00:00 2001
From: Chris Baker <baker@lindenlab.com>
Date: Thu, 23 Aug 2012 19:40:10 -0700
Subject: Start of getting WSGI service on viewer

---
 indra/newview/llgroupmgr.cpp          |   91 +
 indra/newview/llgroupmgr.h            |    3 +
 indra/newview/llpanelgroupgeneral.cpp |    9 +-
 indra/newview/llpanelgroupinvite.cpp  |    9 +-
 indra/newview/llpanelgrouproles.cpp   |   22 +-
 indra/newview/llviewerregion.cpp      | 3739 ++++++++++++++++-----------------
 6 files changed, 1997 insertions(+), 1876 deletions(-)

diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index aceb7f0614..3300034f7f 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -1500,6 +1500,10 @@ void LLGroupMgr::sendGroupMembersRequest(const LLUUID& group_id)
 	}
 }
 
+
+
+
+
 void LLGroupMgr::sendGroupRoleDataRequest(const LLUUID& group_id)
 {
 	lldebugs << "LLGroupMgr::sendGroupRoleDataRequest" << llendl;
@@ -1832,6 +1836,93 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
 	}
 }
 
+
+//////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////// 
+// STUBBED IN FOR code completion
+class GroupMemberDataResponder : public LLHTTPClient::Responder
+{
+public:
+		GroupMemberDataResponder() {}
+		virtual ~GroupMemberDataResponder() {}
+		virtual void result(const LLSD& pContent);
+		virtual void error(U32 pStatus, const std::string& pReason) {}
+private:
+		LLSD mMemberData;
+};
+
+void GroupMemberDataResponder::result(const LLSD& pContent)
+{
+	LL_INFOS("BAKER") << "BAKER TAG ////////////////////////////////////////////////////////////////" << LL_ENDL;
+	// Did we get anything in pContent?
+	if(pContent.size())
+	{
+		LL_INFOS("BAKER") << "Lik dis if u cry evertim" << LL_ENDL;
+
+		// BAKER TODO:
+		// Figure out what to do with all the dataz.
+		// Looks like processGroupMembersReply does the work
+		LLUUID	agent_id	= pContent["agent_id"];
+		LLUUID	group_id	= pContent["group_id"];
+		LLSD	member_list	= pContent["members"];
+		LLSD	titles		= pContent["titles"];
+		LLSD	defaults	= pContent["defaults"];
+
+		int i = 0;
+		++i;
+
+
+
+	}
+	else
+	{
+		LL_INFOS("BAKER") << "WE AIN'T FOUND SHIT!" << LL_ENDL;
+
+		// BAKER TODO:
+		// Handle this case
+
+	}
+	LL_INFOS("BAKER") << "//////////////////////////////////////////////////////////////////////////\n" << LL_ENDL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////// 
+// BAKER
+// static
+void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
+{
+	//sendGroupMembersRequest(group_id);
+	//return;
+
+#if 1
+	LLViewerRegion* currentRegion = gAgent.getRegion();
+
+	// Check to make sure we have our capabilities
+	if(!currentRegion->capabilitiesReceived())
+	{
+		LL_INFOS("BAKER") << " Capabilities not received! -- OSHITSON --" << LL_ENDL;
+		// BAKER TODO: Handle this!
+	}
+
+	// Get our capability
+	std::string cap_url =  currentRegion->getCapability("GroupMemberData");
+
+	// Post to our service.  Add a body containing the group_id.
+	LLSD body = LLSD::emptyMap();
+	body["group_id"] = group_id;
+
+	LLHTTPClient::ResponderPtr grp_data_responder = new GroupMemberDataResponder();
+	 // This could take a while to finish, timeout after 10 minutes.
+	LLHTTPClient::post(cap_url, body, grp_data_responder, LLSD(), 600);
+#endif
+}
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+
 void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id)
 {
 	lldebugs << "LLGroupMgr::sendGroupRoleChanges" << llendl;
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index df3cd17e03..5b535f5056 100644
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -340,6 +340,9 @@ public:
 	static void sendGroupMemberEjects(const LLUUID& group_id,
 									  uuid_vec_t& member_ids);
 
+	// BAKER
+	void sendCapGroupMembersRequest(const LLUUID& group_id);
+
 	void cancelGroupRoleChanges(const LLUUID& group_id);
 
 	static void processGroupPropertiesReply(LLMessageSystem* msg, void** data);
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index bc594b5517..fa5f5574dc 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -317,7 +317,12 @@ void LLPanelGroupGeneral::activate()
 		
 		if (!gdatap || !gdatap->isMemberDataComplete() )
 		{
-			LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
+			//////////////////////////////////////////////////////////////////////////
+			// BAKER TODO:
+			//	Use cap here!
+			//////////////////////////////////////////////////////////////////////////
+			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
+			//LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
 		}
 
 		mFirstUse = FALSE;
@@ -714,7 +719,7 @@ void LLPanelGroupGeneral::updateMembers()
 	for( ; mMemberProgress != gdatap->mMembers.end() && i<UPDATE_MEMBERS_PER_FRAME; 
 			++mMemberProgress, ++i)
 	{
-		//llinfos << "Adding " << iter->first << ", " << iter->second->getTitle() << llendl;
+		llinfos << "Adding " << mMemberProgress->first << ", " << mMemberProgress->second->getTitle() << llendl;
 		LLGroupMemberData* member = mMemberProgress->second;
 		if (!member)
 		{
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 00dd206571..f05358bf59 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -570,7 +570,14 @@ void LLPanelGroupInvite::updateLists()
 		if (!mPendingUpdate) 
 		{
 			LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID);
-			LLGroupMgr::getInstance()->sendGroupMembersRequest(mImplementation->mGroupID);
+			
+			//////////////////////////////////////////////////////////////////////////
+			// BAKER TODO:
+			//	Use cap here!
+			//////////////////////////////////////////////////////////////////////////
+			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
+			//LLGroupMgr::getInstance()->sendGroupMembersRequest(mImplementation->mGroupID);
+
 			LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID);
 		}
 		mPendingUpdate = TRUE;
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index f825ee3215..9b0fb37693 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -356,7 +356,12 @@ void LLPanelGroupRoles::activate()
 		
 		if (!gdatap || !gdatap->isMemberDataComplete() )
 		{
-			LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
+			//////////////////////////////////////////////////////////////////////////
+			// BAKER TODO:
+			//	Use cap here!
+			//////////////////////////////////////////////////////////////////////////
+			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
+			//LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
 		}
 
 		// Check role data.
@@ -1987,7 +1992,12 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
 
 	if (!gdatap || !gdatap->isMemberDataComplete())
 	{
-		LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
+		//////////////////////////////////////////////////////////////////////////
+		// BAKER TODO:
+		//	Use cap here!
+		//////////////////////////////////////////////////////////////////////////
+		LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
+		//LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
 	}
 	
 	if (!gdatap || !gdatap->isRoleMemberDataComplete())
@@ -2580,7 +2590,12 @@ void LLPanelGroupActionsSubTab::handleActionSelect()
 	}
 	else
 	{
-		LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
+		//////////////////////////////////////////////////////////////////////////
+		// BAKER TODO:
+		//	Use cap here!
+		//////////////////////////////////////////////////////////////////////////
+		LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
+		//LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
 	}
 
 	if (gdatap->isRoleDataComplete())
@@ -2604,6 +2619,7 @@ void LLPanelGroupActionsSubTab::handleActionSelect()
 		LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID);
 	}
 }
+
 void LLPanelGroupRoles::setGroupID(const LLUUID& id)
 {
 	LLPanelGroupTab::setGroupID(id);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index effa368b7a..c00d4e91d7 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1,1870 +1,1869 @@
-/** 
- * @file llviewerregion.cpp
- * @brief Implementation of the LLViewerRegion class.
- *
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llviewerregion.h"
-
-// linden libraries
-#include "indra_constants.h"
-#include "llavatarnamecache.h"		// name lookup cap url
-#include "llfloaterreg.h"
-#include "llmath.h"
-#include "llhttpclient.h"
-#include "llregionflags.h"
-#include "llregionhandle.h"
-#include "llsurface.h"
-#include "message.h"
-//#include "vmath.h"
-#include "v3math.h"
-#include "v4math.h"
-
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llcallingcard.h"
-#include "llcaphttpsender.h"
-#include "llcapabilitylistener.h"
-#include "llcommandhandler.h"
-#include "lldir.h"
-#include "lleventpoll.h"
-#include "llfloatergodtools.h"
-#include "llfloaterreporter.h"
-#include "llfloaterregioninfo.h"
-#include "llhttpnode.h"
-#include "llregioninfomodel.h"
-#include "llsdutil.h"
-#include "llstartup.h"
-#include "lltrans.h"
-#include "llurldispatcher.h"
-#include "llviewerobjectlist.h"
-#include "llviewerparceloverlay.h"
-#include "llviewerstatsrecorder.h"
-#include "llvlmanager.h"
-#include "llvlcomposition.h"
-#include "llvocache.h"
-#include "llworld.h"
-#include "llspatialpartition.h"
-#include "stringize.h"
-#include "llviewercontrol.h"
-#include "llsdserialize.h"
-
-#ifdef LL_WINDOWS
-	#pragma warning(disable:4355)
-#endif
-
-const F32 WATER_TEXTURE_SCALE = 8.f;			//  Number of times to repeat the water texture across a region
-const S16 MAX_MAP_DIST = 10;
-// The server only keeps our pending agent info for 60 seconds.
-// We want to allow for seed cap retry, but its not useful after that 60 seconds.
-// Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up.
-const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3;
-const F32 CAP_REQUEST_TIMEOUT = 18;
-// Even though we gave up on login, keep trying for caps after we are logged in:
-const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
-
-typedef std::map<std::string, std::string> CapabilityMap;
-
-class LLViewerRegionImpl {
-public:
-	LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host)
-		:	mHost(host),
-			mCompositionp(NULL),
-			mEventPoll(NULL),
-			mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
-			mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
-			mSeedCapAttempts(0),
-			mHttpResponderID(0),
-		    // I'd prefer to set the LLCapabilityListener name to match the region
-		    // name -- it's disappointing that's not available at construction time.
-		    // We could instead store an LLCapabilityListener*, making
-		    // setRegionNameAndZone() replace the instance. Would that pose
-		    // consistency problems? Can we even request a capability before calling
-		    // setRegionNameAndZone()?
-		    // For testability -- the new Michael Feathers paradigm --
-		    // LLCapabilityListener binds all the globals it expects to need at
-		    // construction time.
-		    mCapabilityListener(host.getString(), gMessageSystem, *region,
-		                        gAgent.getID(), gAgent.getSessionID())
-	{
-	}
-
-	void buildCapabilityNames(LLSD& capabilityNames);
-
-	// The surfaces and other layers
-	LLSurface*	mLandp;
-
-	// Region geometry data
-	LLVector3d	mOriginGlobal;	// Location of southwest corner of region (meters)
-	LLVector3d	mCenterGlobal;	// Location of center in world space (meters)
-	LLHost		mHost;
-
-	// The unique ID for this region.
-	LLUUID mRegionID;
-
-	// region/estate owner - usually null.
-	LLUUID mOwnerID;
-
-	// Network statistics for the region's circuit...
-	LLTimer mLastNetUpdate;
-
-	// Misc
-	LLVLComposition *mCompositionp;		// Composition layer for the surface
-
-	LLVOCacheEntry::vocache_entry_map_t		mCacheMap;
-	// time?
-	// LRU info?
-
-	// Cache ID is unique per-region, across renames, moving locations,
-	// etc.
-	LLUUID mCacheID;
-
-	CapabilityMap mCapabilities;
-	
-	LLEventPoll* mEventPoll;
-
-	S32 mSeedCapMaxAttempts;
-	S32 mSeedCapMaxAttemptsBeforeLogin;
-	S32 mSeedCapAttempts;
-
-	S32 mHttpResponderID;
-
-	/// Post an event to this LLCapabilityListener to invoke a capability message on
-	/// this LLViewerRegion's server
-	/// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
-	LLCapabilityListener mCapabilityListener;
-
-	//spatial partitions for objects in this region
-	std::vector<LLSpatialPartition*> mObjectPartition;
-};
-
-// support for secondlife:///app/region/{REGION} SLapps
-// N.B. this is defined to work exactly like the classic secondlife://{REGION}
-// However, the later syntax cannot support spaces in the region name because
-// spaces (and %20 chars) are illegal in the hostname of an http URL. Some
-// browsers let you get away with this, but some do not (such as Qt's Webkit).
-// Hence we introduced the newer secondlife:///app/region alternative.
-class LLRegionHandler : public LLCommandHandler
-{
-public:
-	// requests will be throttled from a non-trusted browser
-	LLRegionHandler() : LLCommandHandler("region", UNTRUSTED_THROTTLE) {}
-
-	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
-	{
-		// make sure that we at least have a region name
-		int num_params = params.size();
-		if (num_params < 1)
-		{
-			return false;
-		}
-
-		// build a secondlife://{PLACE} SLurl from this SLapp
-		std::string url = "secondlife://";
-		for (int i = 0; i < num_params; i++)
-		{
-			if (i > 0)
-			{
-				url += "/";
-			}
-			url += params[i].asString();
-		}
-
-		// Process the SLapp as if it was a secondlife://{PLACE} SLurl
-		LLURLDispatcher::dispatch(url, "clicked", web, true);
-		return true;
-	}
-};
-LLRegionHandler gRegionHandler;
-
-class BaseCapabilitiesComplete : public LLHTTPClient::Responder
-{
-	LOG_CLASS(BaseCapabilitiesComplete);
-public:
-    BaseCapabilitiesComplete(U64 region_handle, S32 id)
-		: mRegionHandle(region_handle), mID(id)
-    { }
-	virtual ~BaseCapabilitiesComplete()
-	{ }
-
-    void error(U32 statusNum, const std::string& reason)
-    {
-		LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL;
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if (regionp)
-		{
-			regionp->failedSeedCapability();
-		}
-    }
-
-    void result(const LLSD& content)
-    {
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if(!regionp) //region was removed
-		{
-			LL_WARNS2("AppInit", "Capabilities") << "Received results for region that no longer exists!" << LL_ENDL;
-			return ;
-		}
-		if( mID != regionp->getHttpResponderID() ) // region is no longer referring to this responder
-		{
-			LL_WARNS2("AppInit", "Capabilities") << "Received results for a stale http responder!" << LL_ENDL;
-			return ;
-		}
-
-		LLSD::map_const_iterator iter;
-		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
-		{
-			regionp->setCapability(iter->first, iter->second);
-			LL_DEBUGS2("AppInit", "Capabilities") << "got capability for " 
-				<< iter->first << LL_ENDL;
-
-			/* HACK we're waiting for the ServerReleaseNotes */
-			if (iter->first == "ServerReleaseNotes" && regionp->getReleaseNotesRequested())
-			{
-				regionp->showReleaseNotes();
-			}
-		}
-
-		regionp->setCapabilitiesReceived(true);
-
-		if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
-		{
-			LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
-		}
-	}
-
-    static boost::intrusive_ptr<BaseCapabilitiesComplete> build( U64 region_handle, S32 id )
-    {
-		return boost::intrusive_ptr<BaseCapabilitiesComplete>( 
-				new BaseCapabilitiesComplete(region_handle, id) );
-    }
-
-private:
-	U64 mRegionHandle;
-	S32 mID;
-};
-
-
-LLViewerRegion::LLViewerRegion(const U64 &handle,
-							   const LLHost &host,
-							   const U32 grids_per_region_edge, 
-							   const U32 grids_per_patch_edge, 
-							   const F32 region_width_meters)
-:	mImpl(new LLViewerRegionImpl(this, host)),
-	mHandle(handle),
-	mTimeDilation(1.0f),
-	mName(""),
-	mZoning(""),
-	mIsEstateManager(FALSE),
-	mRegionFlags( REGION_FLAGS_DEFAULT ),
-	mSimAccess( SIM_ACCESS_MIN ),
-	mBillableFactor(1.0),
-	mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT),
-	mClassID(0),
-	mCPURatio(0),
-	mColoName("unknown"),
-	mProductSKU("unknown"),
-	mProductName("unknown"),
-	mHttpUrl(""),
-	mCacheLoaded(FALSE),
-	mCacheDirty(FALSE),
-	mReleaseNotesRequested(FALSE),
-	mCapabilitiesReceived(false)
-{
-	mWidth = region_width_meters;
-	mImpl->mOriginGlobal = from_region_handle(handle); 
-	updateRenderMatrix();
-
-	mImpl->mLandp = new LLSurface('l', NULL);
-
-	// Create the composition layer for the surface
-	mImpl->mCompositionp =
-		new LLVLComposition(mImpl->mLandp,
-							grids_per_region_edge,
-							region_width_meters / grids_per_region_edge);
-	mImpl->mCompositionp->setSurface(mImpl->mLandp);
-
-	// Create the surfaces
-	mImpl->mLandp->setRegion(this);
-	mImpl->mLandp->create(grids_per_region_edge,
-					grids_per_patch_edge,
-					mImpl->mOriginGlobal,
-					mWidth);
-
-	mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters);
-
-	setOriginGlobal(from_region_handle(handle));
-	calculateCenterGlobal();
-
-	// Create the object lists
-	initStats();
-
-	//create object partitions
-	//MUST MATCH declaration of eObjectPartitions
-	mImpl->mObjectPartition.push_back(new LLHUDPartition());		//PARTITION_HUD
-	mImpl->mObjectPartition.push_back(new LLTerrainPartition());	//PARTITION_TERRAIN
-	mImpl->mObjectPartition.push_back(new LLVoidWaterPartition());	//PARTITION_VOIDWATER
-	mImpl->mObjectPartition.push_back(new LLWaterPartition());		//PARTITION_WATER
-	mImpl->mObjectPartition.push_back(new LLTreePartition());		//PARTITION_TREE
-	mImpl->mObjectPartition.push_back(new LLParticlePartition());	//PARTITION_PARTICLE
-	mImpl->mObjectPartition.push_back(new LLGrassPartition());		//PARTITION_GRASS
-	mImpl->mObjectPartition.push_back(new LLVolumePartition());	//PARTITION_VOLUME
-	mImpl->mObjectPartition.push_back(new LLBridgePartition());	//PARTITION_BRIDGE
-	mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE
-	mImpl->mObjectPartition.push_back(NULL);						//PARTITION_NONE
-}
-
-
-void LLViewerRegion::initStats()
-{
-	mImpl->mLastNetUpdate.reset();
-	mPacketsIn = 0;
-	mBitsIn = 0;
-	mLastBitsIn = 0;
-	mLastPacketsIn = 0;
-	mPacketsOut = 0;
-	mLastPacketsOut = 0;
-	mPacketsLost = 0;
-	mLastPacketsLost = 0;
-	mPingDelay = 0;
-	mAlive = false;					// can become false if circuit disconnects
-}
-
-LLViewerRegion::~LLViewerRegion() 
-{
-	gVLManager.cleanupData(this);
-	// Can't do this on destruction, because the neighbor pointers might be invalid.
-	// This should be reference counted...
-	disconnectAllNeighbors();
-	LLViewerPartSim::getInstance()->cleanupRegion(this);
-
-	gObjectList.killObjects(this);
-
-	delete mImpl->mCompositionp;
-	delete mParcelOverlay;
-	delete mImpl->mLandp;
-	delete mImpl->mEventPoll;
-	LLHTTPSender::clearSender(mImpl->mHost);
-	
-	saveObjectCache();
-
-	std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer());
-
-	delete mImpl;
-	mImpl = NULL;
-}
-
-LLEventPump& LLViewerRegion::getCapAPI() const
-{
-	return mImpl->mCapabilityListener.getCapAPI();
-}
-
-/*virtual*/ 
-const LLHost&	LLViewerRegion::getHost() const				
-{ 
-	return mImpl->mHost; 
-}
-
-LLSurface & LLViewerRegion::getLand() const
-{
-	return *mImpl->mLandp;
-}
-
-const LLUUID& LLViewerRegion::getRegionID() const
-{
-	return mImpl->mRegionID;
-}
-
-void LLViewerRegion::setRegionID(const LLUUID& region_id)
-{
-	mImpl->mRegionID = region_id;
-}
-
-void LLViewerRegion::loadObjectCache()
-{
-	if (mCacheLoaded)
-	{
-		return;
-	}
-
-	// Presume success.  If it fails, we don't want to try again.
-	mCacheLoaded = TRUE;
-
-	if(LLVOCache::hasInstance())
-	{
-		LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ;
-	}
-}
-
-
-void LLViewerRegion::saveObjectCache()
-{
-	if (!mCacheLoaded)
-	{
-		return;
-	}
-
-	if (mImpl->mCacheMap.empty())
-	{
-		return;
-	}
-
-	if(LLVOCache::hasInstance())
-	{
-		LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty) ;
-		mCacheDirty = FALSE;
-	}
-
-	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)
-	{
-		delete iter->second;
-	}
-	mImpl->mCacheMap.clear();
-}
-
-void LLViewerRegion::sendMessage()
-{
-	gMessageSystem->sendMessage(mImpl->mHost);
-}
-
-void LLViewerRegion::sendReliableMessage()
-{
-	gMessageSystem->sendReliable(mImpl->mHost);
-}
-
-void LLViewerRegion::setFlags(BOOL b, U32 flags)
-{
-	if (b)
-	{
-		mRegionFlags |=  flags;
-	}
-	else
-	{
-		mRegionFlags &= ~flags;
-	}
-}
-
-void LLViewerRegion::setWaterHeight(F32 water_level)
-{
-	mImpl->mLandp->setWaterHeight(water_level);
-}
-
-F32 LLViewerRegion::getWaterHeight() const
-{
-	return mImpl->mLandp->getWaterHeight();
-}
-
-BOOL LLViewerRegion::isVoiceEnabled() const
-{
-	return (getRegionFlags() & REGION_FLAGS_ALLOW_VOICE);
-}
-
-void LLViewerRegion::setRegionFlags(U32 flags)
-{
-	mRegionFlags = flags;
-}
-
-
-void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global) 
-{ 
-	mImpl->mOriginGlobal = origin_global; 
-	updateRenderMatrix();
-	mImpl->mLandp->setOriginGlobal(origin_global);
-	mWind.setOriginGlobal(origin_global);
-	calculateCenterGlobal();
-}
-
-void LLViewerRegion::updateRenderMatrix()
-{
-	mRenderMatrix.setTranslation(getOriginAgent());
-}
-
-void LLViewerRegion::setTimeDilation(F32 time_dilation)
-{
-	mTimeDilation = time_dilation;
-}
-
-const LLVector3d & LLViewerRegion::getOriginGlobal() const
-{
-	return mImpl->mOriginGlobal;
-}
-
-LLVector3 LLViewerRegion::getOriginAgent() const
-{
-	return gAgent.getPosAgentFromGlobal(mImpl->mOriginGlobal);
-}
-
-const LLVector3d & LLViewerRegion::getCenterGlobal() const
-{
-	return mImpl->mCenterGlobal;
-}
-
-LLVector3 LLViewerRegion::getCenterAgent() const
-{
-	return gAgent.getPosAgentFromGlobal(mImpl->mCenterGlobal);
-}
-
-void LLViewerRegion::setOwner(const LLUUID& owner_id)
-{
-	mImpl->mOwnerID = owner_id;
-}
-
-const LLUUID& LLViewerRegion::getOwner() const
-{
-	return mImpl->mOwnerID;
-}
-
-void LLViewerRegion::setRegionNameAndZone	(const std::string& name_zone)
-{
-	std::string::size_type pipe_pos = name_zone.find('|');
-	S32 length   = name_zone.size();
-	if (pipe_pos != std::string::npos)
-	{
-		mName   = name_zone.substr(0, pipe_pos);
-		mZoning = name_zone.substr(pipe_pos+1, length-(pipe_pos+1));
-	}
-	else
-	{
-		mName   = name_zone;
-		mZoning = "";
-	}
-
-	LLStringUtil::stripNonprintable(mName);
-	LLStringUtil::stripNonprintable(mZoning);
-}
-
-BOOL LLViewerRegion::canManageEstate() const
-{
-	return gAgent.isGodlike()
-		|| isEstateManager()
-		|| gAgent.getID() == getOwner();
-}
-
-const std::string LLViewerRegion::getSimAccessString() const
-{
-	return accessToString(mSimAccess);
-}
-
-std::string LLViewerRegion::getLocalizedSimProductName() const
-{
-	std::string localized_spn;
-	return LLTrans::findString(localized_spn, mProductName) ? localized_spn : mProductName;
-}
-
-// static
-std::string LLViewerRegion::regionFlagsToString(U32 flags)
-{
-	std::string result;
-
-	if (flags & REGION_FLAGS_SANDBOX)
-	{
-		result += "Sandbox";
-	}
-
-	if (flags & REGION_FLAGS_ALLOW_DAMAGE)
-	{
-		result += " Not Safe";
-	}
-
-	return result;
-}
-
-// static
-std::string LLViewerRegion::accessToString(U8 sim_access)
-{
-	switch(sim_access)
-	{
-	case SIM_ACCESS_PG:
-		return LLTrans::getString("SIM_ACCESS_PG");
-
-	case SIM_ACCESS_MATURE:
-		return LLTrans::getString("SIM_ACCESS_MATURE");
-
-	case SIM_ACCESS_ADULT:
-		return LLTrans::getString("SIM_ACCESS_ADULT");
-
-	case SIM_ACCESS_DOWN:
-		return LLTrans::getString("SIM_ACCESS_DOWN");
-
-	case SIM_ACCESS_MIN:
-	default:
-		return LLTrans::getString("SIM_ACCESS_MIN");
-	}
-}
-
-// static
-std::string LLViewerRegion::getAccessIcon(U8 sim_access)
-{
-	switch(sim_access)
-	{
-	case SIM_ACCESS_MATURE:
-		return "Parcel_M_Dark";
-
-	case SIM_ACCESS_ADULT:
-		return "Parcel_R_Light";
-
-	case SIM_ACCESS_PG:
-		return "Parcel_PG_Light";
-
-	case SIM_ACCESS_MIN:
-	default:
-		return "";
-	}
-}
-
-// static
-std::string LLViewerRegion::accessToShortString(U8 sim_access)
-{
-	switch(sim_access)		/* Flawfinder: ignore */
-	{
-	case SIM_ACCESS_PG:
-		return "PG";
-
-	case SIM_ACCESS_MATURE:
-		return "M";
-
-	case SIM_ACCESS_ADULT:
-		return "A";
-
-	case SIM_ACCESS_MIN:
-	default:
-		return "U";
-	}
-}
-
-// 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**)
-{
-	// send it to 'observers'
-	// *TODO: switch the floaters to using LLRegionInfoModel
-	llinfos << "Processing region info" << llendl;
-	LLRegionInfoModel::instance().update(msg);
-	LLFloaterGodTools::processRegionInfo(msg);
-	LLFloaterRegionInfo::processRegionInfo(msg);
-	LLFloaterReporter::processRegionInfo(msg);
-}
-
-void LLViewerRegion::setCacheID(const LLUUID& id)
-{
-	mImpl->mCacheID = id;
-}
-
-S32 LLViewerRegion::renderPropertyLines()
-{
-	if (mParcelOverlay)
-	{
-		return mParcelOverlay->renderPropertyLines();
-	}
-	else
-	{
-		return 0;
-	}
-}
-
-// This gets called when the height field changes.
-void LLViewerRegion::dirtyHeights()
-{
-	// Property lines need to be reconstructed when the land changes.
-	if (mParcelOverlay)
-	{
-		mParcelOverlay->setDirty();
-	}
-}
-
-BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
-{
-	LLMemType mt_ivr(LLMemType::MTYPE_IDLE_UPDATE_VIEWER_REGION);
-	// did_update returns TRUE if we did at least one significant update
-	BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time);
-	
-	if (mParcelOverlay)
-	{
-		// Hopefully not a significant time sink...
-		mParcelOverlay->idleUpdate();
-	}
-
-	return did_update;
-}
-
-
-// As above, but forcibly do the update.
-void LLViewerRegion::forceUpdate()
-{
-	mImpl->mLandp->idleUpdate(0.f);
-
-	if (mParcelOverlay)
-	{
-		mParcelOverlay->idleUpdate(true);
-	}
-}
-
-void LLViewerRegion::connectNeighbor(LLViewerRegion *neighborp, U32 direction)
-{
-	mImpl->mLandp->connectNeighbor(neighborp->mImpl->mLandp, direction);
-}
-
-
-void LLViewerRegion::disconnectAllNeighbors()
-{
-	mImpl->mLandp->disconnectAllNeighbors();
-}
-
-LLVLComposition * LLViewerRegion::getComposition() const
-{
-	return mImpl->mCompositionp;
-}
-
-F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
-{
-	if (x >= 256)
-	{
-		if (y >= 256)
-		{
-			LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 256.f, 0.f);
-			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
-			if (regionp)
-			{
-				// OK, we need to do some hackery here - different simulators no longer use
-				// the same composition values, necessarily.
-				// If we're attempting to blend, then we want to make the fractional part of
-				// this region match the fractional of the adjacent.  For now, just minimize
-				// the delta.
-				F32 our_comp = getComposition()->getValueScaled(255, 255);
-				F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, y - 256.f);
-				while (llabs(our_comp - adj_comp) >= 1.f)
-				{
-					if (our_comp > adj_comp)
-					{
-						adj_comp += 1.f;
-					}
-					else
-					{
-						adj_comp -= 1.f;
-					}
-				}
-				return adj_comp;
-			}
-		}
-		else
-		{
-			LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 0, 0.f);
-			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
-			if (regionp)
-			{
-				// OK, we need to do some hackery here - different simulators no longer use
-				// the same composition values, necessarily.
-				// If we're attempting to blend, then we want to make the fractional part of
-				// this region match the fractional of the adjacent.  For now, just minimize
-				// the delta.
-				F32 our_comp = getComposition()->getValueScaled(255.f, (F32)y);
-				F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, (F32)y);
-				while (llabs(our_comp - adj_comp) >= 1.f)
-				{
-					if (our_comp > adj_comp)
-					{
-						adj_comp += 1.f;
-					}
-					else
-					{
-						adj_comp -= 1.f;
-					}
-				}
-				return adj_comp;
-			}
-		}
-	}
-	else if (y >= 256)
-	{
-		LLVector3d center = getCenterGlobal() + LLVector3d(0.f, 256.f, 0.f);
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
-		if (regionp)
-		{
-			// OK, we need to do some hackery here - different simulators no longer use
-			// the same composition values, necessarily.
-			// If we're attempting to blend, then we want to make the fractional part of
-			// this region match the fractional of the adjacent.  For now, just minimize
-			// the delta.
-			F32 our_comp = getComposition()->getValueScaled((F32)x, 255.f);
-			F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - 256.f);
-			while (llabs(our_comp - adj_comp) >= 1.f)
-			{
-				if (our_comp > adj_comp)
-				{
-					adj_comp += 1.f;
-				}
-				else
-				{
-					adj_comp -= 1.f;
-				}
-			}
-			return adj_comp;
-		}
-	}
-
-	return getComposition()->getValueScaled((F32)x, (F32)y);
-}
-
-void LLViewerRegion::calculateCenterGlobal() 
-{
-	mImpl->mCenterGlobal = mImpl->mOriginGlobal;
-	mImpl->mCenterGlobal.mdV[VX] += 0.5 * mWidth;
-	mImpl->mCenterGlobal.mdV[VY] += 0.5 * mWidth;
-	mImpl->mCenterGlobal.mdV[VZ] = 0.5 * mImpl->mLandp->getMinZ() + mImpl->mLandp->getMaxZ();
-}
-
-void LLViewerRegion::calculateCameraDistance()
-{
-	mCameraDistanceSquared = (F32)(gAgentCamera.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared();
-}
-
-std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region)
-{
-	s << "{ ";
-	s << region.mImpl->mHost;
-	s << " mOriginGlobal = " << region.getOriginGlobal()<< "\n";
-    std::string name(region.getName()), zone(region.getZoning());
-    if (! name.empty())
-    {
-        s << " mName         = " << name << '\n';
-    }
-    if (! zone.empty())
-    {
-        s << " mZoning       = " << zone << '\n';
-    }
-	s << "}";
-	return s;
-}
-
-
-// ---------------- Protected Member Functions ----------------
-
-void LLViewerRegion::updateNetStats()
-{
-	F32 dt = mImpl->mLastNetUpdate.getElapsedTimeAndResetF32();
-
-	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);
-	if (!cdp)
-	{
-		mAlive = false;
-		return;
-	}
-
-	mAlive = true;
-	mDeltaTime = dt;
-
-	mLastPacketsIn =	mPacketsIn;
-	mLastBitsIn =		mBitsIn;
-	mLastPacketsOut =	mPacketsOut;
-	mLastPacketsLost =	mPacketsLost;
-
-	mPacketsIn =				cdp->getPacketsIn();
-	mBitsIn =					8 * cdp->getBytesIn();
-	mPacketsOut =				cdp->getPacketsOut();
-	mPacketsLost =				cdp->getPacketsLost();
-	mPingDelay =				cdp->getPingDelay();
-
-	mBitStat.addValue(mBitsIn - mLastBitsIn);
-	mPacketsStat.addValue(mPacketsIn - mLastPacketsIn);
-	mPacketsLostStat.addValue(mPacketsLost);
-}
-
-
-U32 LLViewerRegion::getPacketsLost() const
-{
-	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);
-	if (!cdp)
-	{
-		llinfos << "LLViewerRegion::getPacketsLost couldn't find circuit for " << mImpl->mHost << llendl;
-		return 0;
-	}
-	else
-	{
-		return cdp->getPacketsLost();
-	}
-}
-
-S32 LLViewerRegion::getHttpResponderID() const
-{
-	return mImpl->mHttpResponderID;
-}
-
-BOOL LLViewerRegion::pointInRegionGlobal(const LLVector3d &point_global) const
-{
-	LLVector3 pos_region = getPosRegionFromGlobal(point_global);
-
-	if (pos_region.mV[VX] < 0)
-	{
-		return FALSE;
-	}
-	if (pos_region.mV[VX] >= mWidth)
-	{
-		return FALSE;
-	}
-	if (pos_region.mV[VY] < 0)
-	{
-		return FALSE;
-	}
-	if (pos_region.mV[VY] >= mWidth)
-	{
-		return FALSE;
-	}
-	return TRUE;
-}
-
-LLVector3 LLViewerRegion::getPosRegionFromGlobal(const LLVector3d &point_global) const
-{
-	LLVector3 pos_region;
-	pos_region.setVec(point_global - mImpl->mOriginGlobal);
-	return pos_region;
-}
-
-LLVector3d LLViewerRegion::getPosGlobalFromRegion(const LLVector3 &pos_region) const
-{
-	LLVector3d pos_region_d;
-	pos_region_d.setVec(pos_region);
-	return pos_region_d + mImpl->mOriginGlobal;
-}
-
-LLVector3 LLViewerRegion::getPosAgentFromRegion(const LLVector3 &pos_region) const
-{
-	LLVector3d pos_global = getPosGlobalFromRegion(pos_region);
-
-	return gAgent.getPosAgentFromGlobal(pos_global);
-}
-
-LLVector3 LLViewerRegion::getPosRegionFromAgent(const LLVector3 &pos_agent) const
-{
-	return pos_agent - getOriginAgent();
-}
-
-F32 LLViewerRegion::getLandHeightRegion(const LLVector3& region_pos)
-{
-	return mImpl->mLandp->resolveHeightRegion( region_pos );
-}
-
-bool LLViewerRegion::isAlive()
-{
-	return mAlive;
-}
-
-BOOL LLViewerRegion::isOwnedSelf(const LLVector3& pos)
-{
-	if (mParcelOverlay)
-	{
-		return mParcelOverlay->isOwnedSelf(pos);
-	} else {
-		return FALSE;
-	}
-}
-
-// Owned by a group you belong to?  (officer or member)
-BOOL LLViewerRegion::isOwnedGroup(const LLVector3& pos)
-{
-	if (mParcelOverlay)
-	{
-		return mParcelOverlay->isOwnedGroup(pos);
-	} else {
-		return FALSE;
-	}
-}
-
-// the new TCP coarse location handler node
-class CoarseLocationUpdate : public LLHTTPNode
-{
-public:
-	virtual void post(
-		ResponsePtr responder,
-		const LLSD& context,
-		const LLSD& input) const
-	{
-		LLHost host(input["sender"].asString());
-		LLViewerRegion* region = LLWorld::getInstance()->getRegion(host);
-		if( !region )
-		{
-			return;
-		}
-
-		S32 target_index = input["body"]["Index"][0]["Prey"].asInteger();
-		S32 you_index    = input["body"]["Index"][0]["You" ].asInteger();
-
-		LLDynamicArray<U32>* avatar_locs = &region->mMapAvatars;
-		LLDynamicArray<LLUUID>* avatar_ids = &region->mMapAvatarIDs;
-		avatar_locs->reset();
-		avatar_ids->reset();
-
-		//llinfos << "coarse locations agent[0] " << input["body"]["AgentData"][0]["AgentID"].asUUID() << llendl;
-		//llinfos << "my agent id = " << gAgent.getID() << llendl;
-		//llinfos << ll_pretty_print_sd(input) << llendl;
-
-		LLSD 
-			locs   = input["body"]["Location"],
-			agents = input["body"]["AgentData"];
-		LLSD::array_iterator 
-			locs_it = locs.beginArray(), 
-			agents_it = agents.beginArray();
-		BOOL has_agent_data = input["body"].has("AgentData");
-
-		for(int i=0; 
-			locs_it != locs.endArray(); 
-			i++, locs_it++)
-		{
-			U8 
-				x = locs_it->get("X").asInteger(),
-				y = locs_it->get("Y").asInteger(),
-				z = locs_it->get("Z").asInteger();
-			// treat the target specially for the map, and don't add you or the target
-			if(i == target_index)
-			{
-				LLVector3d global_pos(region->getOriginGlobal());
-				global_pos.mdV[VX] += (F64)x;
-				global_pos.mdV[VY] += (F64)y;
-				global_pos.mdV[VZ] += (F64)z * 4.0;
-				LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
-			}
-			else if( i != you_index)
-			{
-				U32 loc = x << 16 | y << 8 | z; loc = loc;
-				U32 pos = 0x0;
-				pos |= x;
-				pos <<= 8;
-				pos |= y;
-				pos <<= 8;
-				pos |= z;
-				avatar_locs->put(pos);
-				//llinfos << "next pos: " << x << "," << y << "," << z << ": " << pos << llendl;
-				if(has_agent_data) // for backwards compatibility with old message format
-				{
-					LLUUID agent_id(agents_it->get("AgentID").asUUID());
-					//llinfos << "next agent: " << agent_id.asString() << llendl;
-					avatar_ids->put(agent_id);
-				}
-			}
-			if (has_agent_data)
-			{
-				agents_it++;
-			}
-		}
-	}
-};
-
-// build the coarse location HTTP node under the "/message" URL
-LLHTTPRegistration<CoarseLocationUpdate>
-   gHTTPRegistrationCoarseLocationUpdate(
-	   "/message/CoarseLocationUpdate");
-
-
-// the deprecated coarse location handler
-void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg)
-{
-	//llinfos << "CoarseLocationUpdate" << llendl;
-	mMapAvatars.reset();
-	mMapAvatarIDs.reset(); // only matters in a rare case but it's good to be safe.
-
-	U8 x_pos = 0;
-	U8 y_pos = 0;
-	U8 z_pos = 0;
-
-	U32 pos = 0x0;
-
-	S16 agent_index;
-	S16 target_index;
-	msg->getS16Fast(_PREHASH_Index, _PREHASH_You, agent_index);
-	msg->getS16Fast(_PREHASH_Index, _PREHASH_Prey, target_index);
-
-	BOOL has_agent_data = msg->has(_PREHASH_AgentData);
-	S32 count = msg->getNumberOfBlocksFast(_PREHASH_Location);
-	for(S32 i = 0; i < count; i++)
-	{
-		msg->getU8Fast(_PREHASH_Location, _PREHASH_X, x_pos, i);
-		msg->getU8Fast(_PREHASH_Location, _PREHASH_Y, y_pos, i);
-		msg->getU8Fast(_PREHASH_Location, _PREHASH_Z, z_pos, i);
-		LLUUID agent_id = LLUUID::null;
-		if(has_agent_data)
-		{
-			msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id, i);
-		}
-
-		//llinfos << "  object X: " << (S32)x_pos << " Y: " << (S32)y_pos
-		//		<< " Z: " << (S32)(z_pos * 4)
-		//		<< llendl;
-
-		// treat the target specially for the map
-		if(i == target_index)
-		{
-			LLVector3d global_pos(mImpl->mOriginGlobal);
-			global_pos.mdV[VX] += (F64)(x_pos);
-			global_pos.mdV[VY] += (F64)(y_pos);
-			global_pos.mdV[VZ] += (F64)(z_pos) * 4.0;
-			LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
-		}
-		
-		//don't add you
-		if( i != agent_index)
-		{
-			pos = 0x0;
-			pos |= x_pos;
-			pos <<= 8;
-			pos |= y_pos;
-			pos <<= 8;
-			pos |= z_pos;
-			mMapAvatars.put(pos);
-			if(has_agent_data)
-			{
-				mMapAvatarIDs.put(agent_id);
-			}
-		}
-	}
-}
-
-void LLViewerRegion::getInfo(LLSD& info)
-{
-	info["Region"]["Host"] = getHost().getIPandPort();
-	info["Region"]["Name"] = getName();
-	U32 x, y;
-	from_region_handle(getHandle(), &x, &y);
-	info["Region"]["Handle"]["x"] = (LLSD::Integer)x;
-	info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
-}
-
-void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features)
-{
-	sim_features = mSimulatorFeatures;
-
-}
-
-void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
-{
-	std::stringstream str;
-	
-	LLSDSerialize::toPrettyXML(sim_features, str);
-	llinfos << str.str() << llendl;
-	mSimulatorFeatures = sim_features;
-}
-
-LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp)
-{
-	U32 local_id = objectp->getLocalID();
-	U32 crc = objectp->getCRC();
-
-	LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);
-
-	if (entry)
-	{
-		// we've seen this object before
-		if (entry->getCRC() == crc)
-		{
-			// Record a hit
-			entry->recordDupe();
-			return CACHE_UPDATE_DUPE;
-		}
-
-		// Update the cache entry
-		mImpl->mCacheMap.erase(local_id);
-		delete entry;
-		entry = new LLVOCacheEntry(local_id, crc, dp);
-		mImpl->mCacheMap[local_id] = entry;
-		return CACHE_UPDATE_CHANGED;
-	}
-
-	// we haven't seen this object before
-
-	// Create new entry and add to map
-	eCacheUpdateResult result = CACHE_UPDATE_ADDED;
-	if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES)
-	{
-		delete mImpl->mCacheMap.begin()->second ;
-		mImpl->mCacheMap.erase(mImpl->mCacheMap.begin());
-		result = CACHE_UPDATE_REPLACED;
-		
-	}
-	entry = new LLVOCacheEntry(local_id, crc, dp);
-
-	mImpl->mCacheMap[local_id] = entry;
-	return result;
-}
-
-// Get data packer for this object, if we have cached data
-// AND the CRC matches. JC
-LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type)
-{
-	//llassert(mCacheLoaded);  This assert failes often, changing to early-out -- davep, 2010/10/18
-
-	LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);
-
-	if (entry)
-	{
-		// we've seen this object before
-		if (entry->getCRC() == crc)
-		{
-			// Record a hit
-			entry->recordHit();
-		cache_miss_type = CACHE_MISS_TYPE_NONE;
-			return entry->getDP(crc);
-		}
-		else
-		{
-			// llinfos << "CRC miss for " << local_id << llendl;
-		cache_miss_type = CACHE_MISS_TYPE_CRC;
-			mCacheMissCRC.put(local_id);
-		}
-	}
-	else
-	{
-		// llinfos << "Cache miss for " << local_id << llendl;
-	cache_miss_type = CACHE_MISS_TYPE_FULL;
-		mCacheMissFull.put(local_id);
-	}
-
-	return NULL;
-}
-
-void LLViewerRegion::addCacheMissFull(const U32 local_id)
-{
-	mCacheMissFull.put(local_id);
-}
-
-void LLViewerRegion::requestCacheMisses()
-{
-	S32 full_count = mCacheMissFull.count();
-	S32 crc_count = mCacheMissCRC.count();
-	if (full_count == 0 && crc_count == 0) return;
-
-	LLMessageSystem* msg = gMessageSystem;
-	BOOL start_new_message = TRUE;
-	S32 blocks = 0;
-	S32 i;
-
-	// Send full cache miss updates.  For these, we KNOW we don't
-	// have a viewer object.
-	for (i = 0; i < full_count; i++)
-	{
-		if (start_new_message)
-		{
-			msg->newMessageFast(_PREHASH_RequestMultipleObjects);
-			msg->nextBlockFast(_PREHASH_AgentData);
-			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			start_new_message = FALSE;
-		}
-
-		msg->nextBlockFast(_PREHASH_ObjectData);
-		msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_FULL);
-		msg->addU32Fast(_PREHASH_ID, mCacheMissFull[i]);
-		blocks++;
-
-		if (blocks >= 255)
-		{
-			sendReliableMessage();
-			start_new_message = TRUE;
-			blocks = 0;
-		}
-	}
-
-	// Send CRC miss updates.  For these, we _might_ have a viewer object,
-	// but probably not.
-	for (i = 0; i < crc_count; i++)
-	{
-		if (start_new_message)
-		{
-			msg->newMessageFast(_PREHASH_RequestMultipleObjects);
-			msg->nextBlockFast(_PREHASH_AgentData);
-			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			start_new_message = FALSE;
-		}
-
-		msg->nextBlockFast(_PREHASH_ObjectData);
-		msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_CRC);
-		msg->addU32Fast(_PREHASH_ID, mCacheMissCRC[i]);
-		blocks++;
-
-		if (blocks >= 255)
-		{
-			sendReliableMessage();
-			start_new_message = TRUE;
-			blocks = 0;
-		}
-	}
-
-	// finish any pending message
-	if (!start_new_message)
-	{
-		sendReliableMessage();
-	}
-	mCacheMissFull.reset();
-	mCacheMissCRC.reset();
-
-	mCacheDirty = TRUE ;
-	// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl;
-	#if LL_RECORD_VIEWER_STATS
-	LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(this);
-	LLViewerStatsRecorder::instance()->recordRequestCacheMissesEvent(full_count + crc_count);
-	LLViewerStatsRecorder::instance()->endObjectUpdateEvents();
-	#endif
-}
-
-void LLViewerRegion::dumpCache()
-{
-	const S32 BINS = 4;
-	S32 hit_bin[BINS];
-	S32 change_bin[BINS];
-
-	S32 i;
-	for (i = 0; i < BINS; ++i)
-	{
-		hit_bin[i] = 0;
-		change_bin[i] = 0;
-	}
-
-	LLVOCacheEntry *entry;
-	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)
-	{
-		entry = iter->second ;
-
-		S32 hits = entry->getHitCount();
-		S32 changes = entry->getCRCChangeCount();
-
-		hits = llclamp(hits, 0, BINS-1);
-		changes = llclamp(changes, 0, BINS-1);
-
-		hit_bin[hits]++;
-		change_bin[changes]++;
-	}
-
-	llinfos << "Count " << mImpl->mCacheMap.size() << llendl;
-	for (i = 0; i < BINS; i++)
-	{
-		llinfos << "Hits " << i << " " << hit_bin[i] << llendl;
-	}
-	for (i = 0; i < BINS; i++)
-	{
-		llinfos << "Changes " << i << " " << change_bin[i] << llendl;
-	}
-}
-
-void LLViewerRegion::unpackRegionHandshake()
-{
-	LLMessageSystem *msg = gMessageSystem;
-
-	U32 region_flags;
-	U8 sim_access;
-	std::string sim_name;
-	LLUUID sim_owner;
-	BOOL is_estate_manager;
-	F32 water_height;
-	F32 billable_factor;
-	LLUUID cache_id;
-
-	msg->getU32		("RegionInfo", "RegionFlags", region_flags);
-	msg->getU8		("RegionInfo", "SimAccess", sim_access);
-	msg->getString	("RegionInfo", "SimName", sim_name);
-	msg->getUUID	("RegionInfo", "SimOwner", sim_owner);
-	msg->getBOOL	("RegionInfo", "IsEstateManager", is_estate_manager);
-	msg->getF32		("RegionInfo", "WaterHeight", water_height);
-	msg->getF32		("RegionInfo", "BillableFactor", billable_factor);
-	msg->getUUID	("RegionInfo", "CacheID", cache_id );
-
-	setRegionFlags(region_flags);
-	setSimAccess(sim_access);
-	setRegionNameAndZone(sim_name);
-	setOwner(sim_owner);
-	setIsEstateManager(is_estate_manager);
-	setWaterHeight(water_height);
-	setBillableFactor(billable_factor);
-	setCacheID(cache_id);
-
-	LLUUID region_id;
-	msg->getUUID("RegionInfo2", "RegionID", region_id);
-	setRegionID(region_id);
-	
-	// Retrieve the CR-53 (Homestead/Land SKU) information
-	S32 classID = 0;
-	S32 cpuRatio = 0;
-	std::string coloName;
-	std::string productSKU;
-	std::string productName;
-
-	// the only reasonable way to decide if we actually have any data is to
-	// check to see if any of these fields have positive sizes
-	if (msg->getSize("RegionInfo3", "ColoName") > 0 ||
-	    msg->getSize("RegionInfo3", "ProductSKU") > 0 ||
-	    msg->getSize("RegionInfo3", "ProductName") > 0)
-	{
-		msg->getS32     ("RegionInfo3", "CPUClassID",  classID);
-		msg->getS32     ("RegionInfo3", "CPURatio",    cpuRatio);
-		msg->getString  ("RegionInfo3", "ColoName",    coloName);
-		msg->getString  ("RegionInfo3", "ProductSKU",  productSKU);
-		msg->getString  ("RegionInfo3", "ProductName", productName);
-		
-		mClassID = classID;
-		mCPURatio = cpuRatio;
-		mColoName = coloName;
-		mProductSKU = productSKU;
-		mProductName = productName;
-	}
-
-	LLVLComposition *compp = getComposition();
-	if (compp)
-	{
-		LLUUID tmp_id;
-
-		msg->getUUID("RegionInfo", "TerrainDetail0", tmp_id);
-		compp->setDetailTextureID(0, tmp_id);
-		msg->getUUID("RegionInfo", "TerrainDetail1", tmp_id);
-		compp->setDetailTextureID(1, tmp_id);
-		msg->getUUID("RegionInfo", "TerrainDetail2", tmp_id);
-		compp->setDetailTextureID(2, tmp_id);
-		msg->getUUID("RegionInfo", "TerrainDetail3", tmp_id);
-		compp->setDetailTextureID(3, tmp_id);
-
-		F32 tmp_f32;
-		msg->getF32("RegionInfo", "TerrainStartHeight00", tmp_f32);
-		compp->setStartHeight(0, tmp_f32);
-		msg->getF32("RegionInfo", "TerrainStartHeight01", tmp_f32);
-		compp->setStartHeight(1, tmp_f32);
-		msg->getF32("RegionInfo", "TerrainStartHeight10", tmp_f32);
-		compp->setStartHeight(2, tmp_f32);
-		msg->getF32("RegionInfo", "TerrainStartHeight11", tmp_f32);
-		compp->setStartHeight(3, tmp_f32);
-
-		msg->getF32("RegionInfo", "TerrainHeightRange00", tmp_f32);
-		compp->setHeightRange(0, tmp_f32);
-		msg->getF32("RegionInfo", "TerrainHeightRange01", tmp_f32);
-		compp->setHeightRange(1, tmp_f32);
-		msg->getF32("RegionInfo", "TerrainHeightRange10", tmp_f32);
-		compp->setHeightRange(2, tmp_f32);
-		msg->getF32("RegionInfo", "TerrainHeightRange11", tmp_f32);
-		compp->setHeightRange(3, tmp_f32);
-
-		// If this is an UPDATE (params already ready, we need to regenerate
-		// all of our terrain stuff, by
-		if (compp->getParamsReady())
-		{
-			//this line creates frame stalls on region crossing and removing it appears to have no effect
-			//getLand().dirtyAllPatches();
-		}
-		else
-		{
-			compp->setParamsReady();
-		}
-	}
-
-
-	// Now that we have the name, we can load the cache file
-	// off disk.
-	loadObjectCache();
-
-	// After loading cache, signal that simulator can start
-	// sending data.
-	// TODO: Send all upstream viewer->sim handshake info here.
-	LLHost host = msg->getSender();
-	msg->newMessage("RegionHandshakeReply");
-	msg->nextBlock("AgentData");
-	msg->addUUID("AgentID", gAgent.getID());
-	msg->addUUID("SessionID", gAgent.getSessionID());
-	msg->nextBlock("RegionInfo");
-	msg->addU32("Flags", 0x0 );
-	msg->sendReliable(host);
-}
-
-void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
-{
-	capabilityNames.append("AgentState");
-	capabilityNames.append("AttachmentResources");
-	capabilityNames.append("AvatarPickerSearch");
-	capabilityNames.append("CharacterProperties");
-	capabilityNames.append("ChatSessionRequest");
-	capabilityNames.append("CopyInventoryFromNotecard");
-	capabilityNames.append("CreateInventoryCategory");
-	capabilityNames.append("DispatchRegionInfo");
-	capabilityNames.append("EstateChangeInfo");
-	capabilityNames.append("EventQueueGet");
-	capabilityNames.append("EnvironmentSettings");
-	capabilityNames.append("ObjectMedia");
-	capabilityNames.append("ObjectMediaNavigate");
-
-	if (gSavedSettings.getBOOL("UseHTTPInventory"))
-	{
-		capabilityNames.append("FetchLib2");
-		capabilityNames.append("FetchLibDescendents2");
-		capabilityNames.append("FetchInventory2");
-		capabilityNames.append("FetchInventoryDescendents2");
-	}
-
-	capabilityNames.append("GetDisplayNames");
-	capabilityNames.append("GetTexture");
-	capabilityNames.append("GetMesh");
-	capabilityNames.append("GetObjectCost");
-	capabilityNames.append("GetObjectPhysicsData");
-	capabilityNames.append("GroupProposalBallot");
-	capabilityNames.append("HomeLocation");
-	capabilityNames.append("LandResources");
-	capabilityNames.append("MapLayer");
-	capabilityNames.append("MapLayerGod");
-	capabilityNames.append("MeshUploadFlag");	
-	capabilityNames.append("NavMeshGenerationStatus");
-	capabilityNames.append("NewFileAgentInventory");
-	capabilityNames.append("ObjectNavMeshProperties");
-	capabilityNames.append("ParcelPropertiesUpdate");
-	capabilityNames.append("ParcelNavigateMedia");
-	capabilityNames.append("ParcelVoiceInfoRequest");
-	capabilityNames.append("ProductInfoRequest");
-	capabilityNames.append("ProvisionVoiceAccountRequest");
-	capabilityNames.append("RemoteParcelRequest");
-	capabilityNames.append("RequestTextureDownload");
-	capabilityNames.append("ResourceCostSelected");
-	capabilityNames.append("RetrieveNavMeshSrc");
-	capabilityNames.append("SearchStatRequest");
-	capabilityNames.append("SearchStatTracking");
-	capabilityNames.append("SendPostcard");
-	capabilityNames.append("SendUserReport");
-	capabilityNames.append("SendUserReportWithScreenshot");
-	capabilityNames.append("ServerReleaseNotes");
-	capabilityNames.append("SimConsole");
-	capabilityNames.append("SimulatorFeatures");
-	capabilityNames.append("SetDisplayName");
-	capabilityNames.append("SimConsoleAsync");
-	capabilityNames.append("StartGroupProposal");
-	capabilityNames.append("TerrainNavMeshProperties");
-	capabilityNames.append("TextureStats");
-	capabilityNames.append("UntrustedSimulatorMessage");
-	capabilityNames.append("UpdateAgentInformation");
-	capabilityNames.append("UpdateAgentLanguage");
-	capabilityNames.append("UpdateGestureAgentInventory");
-	capabilityNames.append("UpdateNotecardAgentInventory");
-	capabilityNames.append("UpdateScriptAgent");
-	capabilityNames.append("UpdateGestureTaskInventory");
-	capabilityNames.append("UpdateNotecardTaskInventory");
-	capabilityNames.append("UpdateScriptTask");
-	capabilityNames.append("UploadBakedTexture");
-	capabilityNames.append("ViewerMetrics");
-	capabilityNames.append("ViewerStartAuction");
-	capabilityNames.append("ViewerStats");
-
-	// Please add new capabilities alphabetically to reduce
-	// merge conflicts.
-}
-
-void LLViewerRegion::setSeedCapability(const std::string& url)
-{
-	if (getCapability("Seed") == url)
-    {
-		// llwarns << "Ignoring duplicate seed capability" << llendl;
-		return;
-    }
-	
-	delete mImpl->mEventPoll;
-	mImpl->mEventPoll = NULL;
-	
-	mImpl->mCapabilities.clear();
-	setCapability("Seed", url);
-
-	LLSD capabilityNames = LLSD::emptyArray();
-	mImpl->buildCapabilityNames(capabilityNames);
-
-	llinfos << "posting to seed " << url << llendl;
-
-	S32 id = ++mImpl->mHttpResponderID;
-	LLHTTPClient::post(url, capabilityNames, 
-						BaseCapabilitiesComplete::build(getHandle(), id),
-						LLSD(), CAP_REQUEST_TIMEOUT);
-}
-
-S32 LLViewerRegion::getNumSeedCapRetries()
-{
-	return mImpl->mSeedCapAttempts;
-}
-
-void LLViewerRegion::failedSeedCapability()
-{
-	// Should we retry asking for caps?
-	mImpl->mSeedCapAttempts++;
-	std::string url = getCapability("Seed");
-	if ( url.empty() )
-	{
-		LL_WARNS2("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url for retries!" << LL_ENDL;
-		return;
-	}
-	// After a few attempts, continue login.  We will keep trying once in-world:
-	if ( mImpl->mSeedCapAttempts >= mImpl->mSeedCapMaxAttemptsBeforeLogin &&
-		 STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState() )
-	{
-		LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
-	}
-
-	if ( mImpl->mSeedCapAttempts < mImpl->mSeedCapMaxAttempts)
-	{
-		LLSD capabilityNames = LLSD::emptyArray();
-		mImpl->buildCapabilityNames(capabilityNames);
-
-		llinfos << "posting to seed " << url << " (retry " 
-				<< mImpl->mSeedCapAttempts << ")" << llendl;
-
-		S32 id = ++mImpl->mHttpResponderID;
-		LLHTTPClient::post(url, capabilityNames, 
-						BaseCapabilitiesComplete::build(getHandle(), id),
-						LLSD(), CAP_REQUEST_TIMEOUT);
-	}
-	else
-	{
-		// *TODO: Give a user pop-up about this error?
-		LL_WARNS2("AppInit", "Capabilities") << "Failed to get seed capabilities from '" << url << "' after " << mImpl->mSeedCapAttempts << " attempts.  Giving up!" << LL_ENDL;
-	}
-}
-
-class SimulatorFeaturesReceived : public LLHTTPClient::Responder
-{
-	LOG_CLASS(SimulatorFeaturesReceived);
-public:
-    SimulatorFeaturesReceived(const std::string& retry_url, U64 region_handle, 
-			S32 attempt = 0, S32 max_attempts = MAX_CAP_REQUEST_ATTEMPTS)
-	: mRetryURL(retry_url), mRegionHandle(region_handle), mAttempt(attempt), mMaxAttempts(max_attempts)
-    { }
-	
-	
-    void error(U32 statusNum, const std::string& reason)
-    {
-		LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL;
-		retry();
-    }
-
-    void result(const LLSD& content)
-    {
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if(!regionp) //region is removed or responder is not created.
-		{
-			LL_WARNS2("AppInit", "SimulatorFeatures") << "Received results for region that no longer exists!" << LL_ENDL;
-			return ;
-		}
-		
-		regionp->setSimulatorFeatures(content);
-	}
-
-private:
-	void retry()
-	{
-		if (mAttempt < mMaxAttempts)
-		{
-			mAttempt++;
-			LL_WARNS2("AppInit", "SimulatorFeatures") << "Re-trying '" << mRetryURL << "'.  Retry #" << mAttempt << LL_ENDL;
-			LLHTTPClient::get(mRetryURL, new SimulatorFeaturesReceived(*this), LLSD(), CAP_REQUEST_TIMEOUT);
-		}
-	}
-	
-	std::string mRetryURL;
-	U64 mRegionHandle;
-	S32 mAttempt;
-	S32 mMaxAttempts;
-};
-
-
-void LLViewerRegion::setCapability(const std::string& name, const std::string& url)
-{
-	if(name == "EventQueueGet")
-	{
-		delete mImpl->mEventPoll;
-		mImpl->mEventPoll = NULL;
-		mImpl->mEventPoll = new LLEventPoll(url, getHost());
-	}
-	else if(name == "UntrustedSimulatorMessage")
-	{
-		LLHTTPSender::setSender(mImpl->mHost, new LLCapHTTPSender(url));
-	}
-	else if (name == "SimulatorFeatures")
-	{
-		// kick off a request for simulator features
-		LLHTTPClient::get(url, new SimulatorFeaturesReceived(url, getHandle()), LLSD(), CAP_REQUEST_TIMEOUT);
-	}
-	else
-	{
-		mImpl->mCapabilities[name] = url;
-		if(name == "GetTexture")
-		{
-			mHttpUrl = url ;
-		}
-	}
-}
-
-bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
-{
-	return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
-}
-
-std::string LLViewerRegion::getCapability(const std::string& name) const
-{
-	CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
-	if(iter == mImpl->mCapabilities.end())
-	{
-		return "";
-	}
-
-	return iter->second;
-}
-
-bool LLViewerRegion::capabilitiesReceived() const
-{
-	return mCapabilitiesReceived;
-}
-
-void LLViewerRegion::setCapabilitiesReceived(bool received)
-{
-	mCapabilitiesReceived = received;
-
-	// Tell interested parties that we've received capabilities,
-	// so that they can safely use getCapability().
-	if (received)
-	{
-		mCapabilitiesReceivedSignal(getRegionID());
-
-		// This is a single-shot signal. Forget callbacks to save resources.
-		mCapabilitiesReceivedSignal.disconnect_all_slots();
-	}
-}
-
-boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb)
-{
-	return mCapabilitiesReceivedSignal.connect(cb);
-}
-
-void LLViewerRegion::logActiveCapabilities() const
-{
-	int count = 0;
-	CapabilityMap::const_iterator iter;
-	for (iter = mImpl->mCapabilities.begin(); iter != mImpl->mCapabilities.end(); ++iter, ++count)
-	{
-		if (!iter->second.empty())
-		{
-			llinfos << iter->first << " URL is " << iter->second << llendl;
-		}
-	}
-	llinfos << "Dumped " << count << " entries." << llendl;
-}
-
-LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
-{
-	if (type < mImpl->mObjectPartition.size())
-	{
-		return mImpl->mObjectPartition[type];
-	}
-	return NULL;
-}
-
-// the viewer can not yet distinquish between normal- and estate-owned objects
-// so we collapse these two bits and enable the UI if either are set
-const U32 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT
-											| REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT;
-
-bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const
-{
-	return (mParcelOverlay != NULL)
-		&& (mParcelOverlay->isOwnedSelf(pos)
-			|| mParcelOverlay->isOwnedGroup(pos)
-			|| ((mRegionFlags & ALLOW_RETURN_ENCROACHING_OBJECT)
-				&& mParcelOverlay->encroachesOwned(boxes)) );
-}
-
-bool LLViewerRegion::childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const
-{
-	bool result = false;
-	result = ( mParcelOverlay && mParcelOverlay->encroachesOnUnowned( boxes ) ) ? 1 : 0;
-	return result;
-}
-
-bool LLViewerRegion::objectsCrossParcel(const std::vector<LLBBox>& boxes) const
-{
-	return mParcelOverlay && mParcelOverlay->encroachesOnNearbyParcel(boxes);
-}
-
-void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions )
-{
-	mImpl->mLandp->getNeighboringRegions( uniqueRegions );
-}
-void LLViewerRegion::getNeighboringRegionsStatus( std::vector<S32>& regions )
-{
-	mImpl->mLandp->getNeighboringRegionsStatus( regions );
-}
-void LLViewerRegion::showReleaseNotes()
-{
-	std::string url = this->getCapability("ServerReleaseNotes");
-
-	if (url.empty()) {
-		// HACK haven't received the capability yet, we'll wait until
-		// it arives.
-		mReleaseNotesRequested = TRUE;
-		return;
-	}
-
-	LLWeb::loadURL(url);
-	mReleaseNotesRequested = FALSE;
-}
-
-std::string LLViewerRegion::getDescription() const
-{
-    return stringize(*this);
-}
-
-bool LLViewerRegion::meshUploadEnabled() const
-{
-	return (mSimulatorFeatures.has("MeshUploadEnabled") &&
-		mSimulatorFeatures["MeshUploadEnabled"].asBoolean());
-}
-
-bool LLViewerRegion::meshRezEnabled() const
-{
-	return (mSimulatorFeatures.has("MeshRezEnabled") &&
-				mSimulatorFeatures["MeshRezEnabled"].asBoolean());
-}
-
-bool LLViewerRegion::dynamicPathfindingEnabled() const
-{
-	return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") &&
-			 mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean());
-}
-
+/** 
+ * @file llviewerregion.cpp
+ * @brief Implementation of the LLViewerRegion class.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerregion.h"
+
+// linden libraries
+#include "indra_constants.h"
+#include "llavatarnamecache.h"		// name lookup cap url
+#include "llfloaterreg.h"
+#include "llmath.h"
+#include "llhttpclient.h"
+#include "llregionflags.h"
+#include "llregionhandle.h"
+#include "llsurface.h"
+#include "message.h"
+//#include "vmath.h"
+#include "v3math.h"
+#include "v4math.h"
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llcallingcard.h"
+#include "llcaphttpsender.h"
+#include "llcapabilitylistener.h"
+#include "llcommandhandler.h"
+#include "lldir.h"
+#include "lleventpoll.h"
+#include "llfloatergodtools.h"
+#include "llfloaterreporter.h"
+#include "llfloaterregioninfo.h"
+#include "llhttpnode.h"
+#include "llregioninfomodel.h"
+#include "llsdutil.h"
+#include "llstartup.h"
+#include "lltrans.h"
+#include "llurldispatcher.h"
+#include "llviewerobjectlist.h"
+#include "llviewerparceloverlay.h"
+#include "llviewerstatsrecorder.h"
+#include "llvlmanager.h"
+#include "llvlcomposition.h"
+#include "llvocache.h"
+#include "llworld.h"
+#include "llspatialpartition.h"
+#include "stringize.h"
+#include "llviewercontrol.h"
+#include "llsdserialize.h"
+
+#ifdef LL_WINDOWS
+	#pragma warning(disable:4355)
+#endif
+
+const F32 WATER_TEXTURE_SCALE = 8.f;			//  Number of times to repeat the water texture across a region
+const S16 MAX_MAP_DIST = 10;
+// The server only keeps our pending agent info for 60 seconds.
+// We want to allow for seed cap retry, but its not useful after that 60 seconds.
+// Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up.
+const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3;
+const F32 CAP_REQUEST_TIMEOUT = 18;
+// Even though we gave up on login, keep trying for caps after we are logged in:
+const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
+
+typedef std::map<std::string, std::string> CapabilityMap;
+
+class LLViewerRegionImpl {
+public:
+	LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host)
+		:	mHost(host),
+			mCompositionp(NULL),
+			mEventPoll(NULL),
+			mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
+			mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
+			mSeedCapAttempts(0),
+			mHttpResponderID(0),
+		    // I'd prefer to set the LLCapabilityListener name to match the region
+		    // name -- it's disappointing that's not available at construction time.
+		    // We could instead store an LLCapabilityListener*, making
+		    // setRegionNameAndZone() replace the instance. Would that pose
+		    // consistency problems? Can we even request a capability before calling
+		    // setRegionNameAndZone()?
+		    // For testability -- the new Michael Feathers paradigm --
+		    // LLCapabilityListener binds all the globals it expects to need at
+		    // construction time.
+		    mCapabilityListener(host.getString(), gMessageSystem, *region,
+		                        gAgent.getID(), gAgent.getSessionID())
+	{
+	}
+
+	void buildCapabilityNames(LLSD& capabilityNames);
+
+	// The surfaces and other layers
+	LLSurface*	mLandp;
+
+	// Region geometry data
+	LLVector3d	mOriginGlobal;	// Location of southwest corner of region (meters)
+	LLVector3d	mCenterGlobal;	// Location of center in world space (meters)
+	LLHost		mHost;
+
+	// The unique ID for this region.
+	LLUUID mRegionID;
+
+	// region/estate owner - usually null.
+	LLUUID mOwnerID;
+
+	// Network statistics for the region's circuit...
+	LLTimer mLastNetUpdate;
+
+	// Misc
+	LLVLComposition *mCompositionp;		// Composition layer for the surface
+
+	LLVOCacheEntry::vocache_entry_map_t		mCacheMap;
+	// time?
+	// LRU info?
+
+	// Cache ID is unique per-region, across renames, moving locations,
+	// etc.
+	LLUUID mCacheID;
+
+	CapabilityMap mCapabilities;
+	
+	LLEventPoll* mEventPoll;
+
+	S32 mSeedCapMaxAttempts;
+	S32 mSeedCapMaxAttemptsBeforeLogin;
+	S32 mSeedCapAttempts;
+
+	S32 mHttpResponderID;
+
+	/// Post an event to this LLCapabilityListener to invoke a capability message on
+	/// this LLViewerRegion's server
+	/// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
+	LLCapabilityListener mCapabilityListener;
+
+	//spatial partitions for objects in this region
+	std::vector<LLSpatialPartition*> mObjectPartition;
+};
+
+// support for secondlife:///app/region/{REGION} SLapps
+// N.B. this is defined to work exactly like the classic secondlife://{REGION}
+// However, the later syntax cannot support spaces in the region name because
+// spaces (and %20 chars) are illegal in the hostname of an http URL. Some
+// browsers let you get away with this, but some do not (such as Qt's Webkit).
+// Hence we introduced the newer secondlife:///app/region alternative.
+class LLRegionHandler : public LLCommandHandler
+{
+public:
+	// requests will be throttled from a non-trusted browser
+	LLRegionHandler() : LLCommandHandler("region", UNTRUSTED_THROTTLE) {}
+
+	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+	{
+		// make sure that we at least have a region name
+		int num_params = params.size();
+		if (num_params < 1)
+		{
+			return false;
+		}
+
+		// build a secondlife://{PLACE} SLurl from this SLapp
+		std::string url = "secondlife://";
+		for (int i = 0; i < num_params; i++)
+		{
+			if (i > 0)
+			{
+				url += "/";
+			}
+			url += params[i].asString();
+		}
+
+		// Process the SLapp as if it was a secondlife://{PLACE} SLurl
+		LLURLDispatcher::dispatch(url, "clicked", web, true);
+		return true;
+	}
+};
+LLRegionHandler gRegionHandler;
+
+class BaseCapabilitiesComplete : public LLHTTPClient::Responder
+{
+	LOG_CLASS(BaseCapabilitiesComplete);
+public:
+    BaseCapabilitiesComplete(U64 region_handle, S32 id)
+		: mRegionHandle(region_handle), mID(id)
+    { }
+	virtual ~BaseCapabilitiesComplete()
+	{ }
+
+    void error(U32 statusNum, const std::string& reason)
+    {
+		LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL;
+		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+		if (regionp)
+		{
+			regionp->failedSeedCapability();
+		}
+    }
+
+    void result(const LLSD& content)
+    {
+		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+		if(!regionp) //region was removed
+		{
+			LL_WARNS2("AppInit", "Capabilities") << "Received results for region that no longer exists!" << LL_ENDL;
+			return ;
+		}
+		if( mID != regionp->getHttpResponderID() ) // region is no longer referring to this responder
+		{
+			LL_WARNS2("AppInit", "Capabilities") << "Received results for a stale http responder!" << LL_ENDL;
+			return ;
+		}
+
+		LLSD::map_const_iterator iter;
+		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
+		{
+			regionp->setCapability(iter->first, iter->second);
+			LL_DEBUGS2("AppInit", "Capabilities") << "got capability for " 
+				<< iter->first << LL_ENDL;
+
+			/* HACK we're waiting for the ServerReleaseNotes */
+			if (iter->first == "ServerReleaseNotes" && regionp->getReleaseNotesRequested())
+			{
+				regionp->showReleaseNotes();
+			}
+		}
+
+		regionp->setCapabilitiesReceived(true);
+
+		if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
+		{
+			LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
+		}
+	}
+
+    static boost::intrusive_ptr<BaseCapabilitiesComplete> build( U64 region_handle, S32 id )
+    {
+		return boost::intrusive_ptr<BaseCapabilitiesComplete>( 
+				new BaseCapabilitiesComplete(region_handle, id) );
+    }
+
+private:
+	U64 mRegionHandle;
+	S32 mID;
+};
+
+
+LLViewerRegion::LLViewerRegion(const U64 &handle,
+							   const LLHost &host,
+							   const U32 grids_per_region_edge, 
+							   const U32 grids_per_patch_edge, 
+							   const F32 region_width_meters)
+:	mImpl(new LLViewerRegionImpl(this, host)),
+	mHandle(handle),
+	mTimeDilation(1.0f),
+	mName(""),
+	mZoning(""),
+	mIsEstateManager(FALSE),
+	mRegionFlags( REGION_FLAGS_DEFAULT ),
+	mSimAccess( SIM_ACCESS_MIN ),
+	mBillableFactor(1.0),
+	mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT),
+	mClassID(0),
+	mCPURatio(0),
+	mColoName("unknown"),
+	mProductSKU("unknown"),
+	mProductName("unknown"),
+	mHttpUrl(""),
+	mCacheLoaded(FALSE),
+	mCacheDirty(FALSE),
+	mReleaseNotesRequested(FALSE),
+	mCapabilitiesReceived(false)
+{
+	mWidth = region_width_meters;
+	mImpl->mOriginGlobal = from_region_handle(handle); 
+	updateRenderMatrix();
+
+	mImpl->mLandp = new LLSurface('l', NULL);
+
+	// Create the composition layer for the surface
+	mImpl->mCompositionp =
+		new LLVLComposition(mImpl->mLandp,
+							grids_per_region_edge,
+							region_width_meters / grids_per_region_edge);
+	mImpl->mCompositionp->setSurface(mImpl->mLandp);
+
+	// Create the surfaces
+	mImpl->mLandp->setRegion(this);
+	mImpl->mLandp->create(grids_per_region_edge,
+					grids_per_patch_edge,
+					mImpl->mOriginGlobal,
+					mWidth);
+
+	mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters);
+
+	setOriginGlobal(from_region_handle(handle));
+	calculateCenterGlobal();
+
+	// Create the object lists
+	initStats();
+
+	//create object partitions
+	//MUST MATCH declaration of eObjectPartitions
+	mImpl->mObjectPartition.push_back(new LLHUDPartition());		//PARTITION_HUD
+	mImpl->mObjectPartition.push_back(new LLTerrainPartition());	//PARTITION_TERRAIN
+	mImpl->mObjectPartition.push_back(new LLVoidWaterPartition());	//PARTITION_VOIDWATER
+	mImpl->mObjectPartition.push_back(new LLWaterPartition());		//PARTITION_WATER
+	mImpl->mObjectPartition.push_back(new LLTreePartition());		//PARTITION_TREE
+	mImpl->mObjectPartition.push_back(new LLParticlePartition());	//PARTITION_PARTICLE
+	mImpl->mObjectPartition.push_back(new LLGrassPartition());		//PARTITION_GRASS
+	mImpl->mObjectPartition.push_back(new LLVolumePartition());	//PARTITION_VOLUME
+	mImpl->mObjectPartition.push_back(new LLBridgePartition());	//PARTITION_BRIDGE
+	mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE
+	mImpl->mObjectPartition.push_back(NULL);						//PARTITION_NONE
+}
+
+
+void LLViewerRegion::initStats()
+{
+	mImpl->mLastNetUpdate.reset();
+	mPacketsIn = 0;
+	mBitsIn = 0;
+	mLastBitsIn = 0;
+	mLastPacketsIn = 0;
+	mPacketsOut = 0;
+	mLastPacketsOut = 0;
+	mPacketsLost = 0;
+	mLastPacketsLost = 0;
+	mPingDelay = 0;
+	mAlive = false;					// can become false if circuit disconnects
+}
+
+LLViewerRegion::~LLViewerRegion() 
+{
+	gVLManager.cleanupData(this);
+	// Can't do this on destruction, because the neighbor pointers might be invalid.
+	// This should be reference counted...
+	disconnectAllNeighbors();
+	LLViewerPartSim::getInstance()->cleanupRegion(this);
+
+	gObjectList.killObjects(this);
+
+	delete mImpl->mCompositionp;
+	delete mParcelOverlay;
+	delete mImpl->mLandp;
+	delete mImpl->mEventPoll;
+	LLHTTPSender::clearSender(mImpl->mHost);
+	
+	saveObjectCache();
+
+	std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer());
+
+	delete mImpl;
+	mImpl = NULL;
+}
+
+LLEventPump& LLViewerRegion::getCapAPI() const
+{
+	return mImpl->mCapabilityListener.getCapAPI();
+}
+
+/*virtual*/ 
+const LLHost&	LLViewerRegion::getHost() const				
+{ 
+	return mImpl->mHost; 
+}
+
+LLSurface & LLViewerRegion::getLand() const
+{
+	return *mImpl->mLandp;
+}
+
+const LLUUID& LLViewerRegion::getRegionID() const
+{
+	return mImpl->mRegionID;
+}
+
+void LLViewerRegion::setRegionID(const LLUUID& region_id)
+{
+	mImpl->mRegionID = region_id;
+}
+
+void LLViewerRegion::loadObjectCache()
+{
+	if (mCacheLoaded)
+	{
+		return;
+	}
+
+	// Presume success.  If it fails, we don't want to try again.
+	mCacheLoaded = TRUE;
+
+	if(LLVOCache::hasInstance())
+	{
+		LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ;
+	}
+}
+
+
+void LLViewerRegion::saveObjectCache()
+{
+	if (!mCacheLoaded)
+	{
+		return;
+	}
+
+	if (mImpl->mCacheMap.empty())
+	{
+		return;
+	}
+
+	if(LLVOCache::hasInstance())
+	{
+		LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty) ;
+		mCacheDirty = FALSE;
+	}
+
+	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)
+	{
+		delete iter->second;
+	}
+	mImpl->mCacheMap.clear();
+}
+
+void LLViewerRegion::sendMessage()
+{
+	gMessageSystem->sendMessage(mImpl->mHost);
+}
+
+void LLViewerRegion::sendReliableMessage()
+{
+	gMessageSystem->sendReliable(mImpl->mHost);
+}
+
+void LLViewerRegion::setFlags(BOOL b, U32 flags)
+{
+	if (b)
+	{
+		mRegionFlags |=  flags;
+	}
+	else
+	{
+		mRegionFlags &= ~flags;
+	}
+}
+
+void LLViewerRegion::setWaterHeight(F32 water_level)
+{
+	mImpl->mLandp->setWaterHeight(water_level);
+}
+
+F32 LLViewerRegion::getWaterHeight() const
+{
+	return mImpl->mLandp->getWaterHeight();
+}
+
+BOOL LLViewerRegion::isVoiceEnabled() const
+{
+	return (getRegionFlags() & REGION_FLAGS_ALLOW_VOICE);
+}
+
+void LLViewerRegion::setRegionFlags(U32 flags)
+{
+	mRegionFlags = flags;
+}
+
+
+void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global) 
+{ 
+	mImpl->mOriginGlobal = origin_global; 
+	updateRenderMatrix();
+	mImpl->mLandp->setOriginGlobal(origin_global);
+	mWind.setOriginGlobal(origin_global);
+	calculateCenterGlobal();
+}
+
+void LLViewerRegion::updateRenderMatrix()
+{
+	mRenderMatrix.setTranslation(getOriginAgent());
+}
+
+void LLViewerRegion::setTimeDilation(F32 time_dilation)
+{
+	mTimeDilation = time_dilation;
+}
+
+const LLVector3d & LLViewerRegion::getOriginGlobal() const
+{
+	return mImpl->mOriginGlobal;
+}
+
+LLVector3 LLViewerRegion::getOriginAgent() const
+{
+	return gAgent.getPosAgentFromGlobal(mImpl->mOriginGlobal);
+}
+
+const LLVector3d & LLViewerRegion::getCenterGlobal() const
+{
+	return mImpl->mCenterGlobal;
+}
+
+LLVector3 LLViewerRegion::getCenterAgent() const
+{
+	return gAgent.getPosAgentFromGlobal(mImpl->mCenterGlobal);
+}
+
+void LLViewerRegion::setOwner(const LLUUID& owner_id)
+{
+	mImpl->mOwnerID = owner_id;
+}
+
+const LLUUID& LLViewerRegion::getOwner() const
+{
+	return mImpl->mOwnerID;
+}
+
+void LLViewerRegion::setRegionNameAndZone	(const std::string& name_zone)
+{
+	std::string::size_type pipe_pos = name_zone.find('|');
+	S32 length   = name_zone.size();
+	if (pipe_pos != std::string::npos)
+	{
+		mName   = name_zone.substr(0, pipe_pos);
+		mZoning = name_zone.substr(pipe_pos+1, length-(pipe_pos+1));
+	}
+	else
+	{
+		mName   = name_zone;
+		mZoning = "";
+	}
+
+	LLStringUtil::stripNonprintable(mName);
+	LLStringUtil::stripNonprintable(mZoning);
+}
+
+BOOL LLViewerRegion::canManageEstate() const
+{
+	return gAgent.isGodlike()
+		|| isEstateManager()
+		|| gAgent.getID() == getOwner();
+}
+
+const std::string LLViewerRegion::getSimAccessString() const
+{
+	return accessToString(mSimAccess);
+}
+
+std::string LLViewerRegion::getLocalizedSimProductName() const
+{
+	std::string localized_spn;
+	return LLTrans::findString(localized_spn, mProductName) ? localized_spn : mProductName;
+}
+
+// static
+std::string LLViewerRegion::regionFlagsToString(U32 flags)
+{
+	std::string result;
+
+	if (flags & REGION_FLAGS_SANDBOX)
+	{
+		result += "Sandbox";
+	}
+
+	if (flags & REGION_FLAGS_ALLOW_DAMAGE)
+	{
+		result += " Not Safe";
+	}
+
+	return result;
+}
+
+// static
+std::string LLViewerRegion::accessToString(U8 sim_access)
+{
+	switch(sim_access)
+	{
+	case SIM_ACCESS_PG:
+		return LLTrans::getString("SIM_ACCESS_PG");
+
+	case SIM_ACCESS_MATURE:
+		return LLTrans::getString("SIM_ACCESS_MATURE");
+
+	case SIM_ACCESS_ADULT:
+		return LLTrans::getString("SIM_ACCESS_ADULT");
+
+	case SIM_ACCESS_DOWN:
+		return LLTrans::getString("SIM_ACCESS_DOWN");
+
+	case SIM_ACCESS_MIN:
+	default:
+		return LLTrans::getString("SIM_ACCESS_MIN");
+	}
+}
+
+// static
+std::string LLViewerRegion::getAccessIcon(U8 sim_access)
+{
+	switch(sim_access)
+	{
+	case SIM_ACCESS_MATURE:
+		return "Parcel_M_Dark";
+
+	case SIM_ACCESS_ADULT:
+		return "Parcel_R_Light";
+
+	case SIM_ACCESS_PG:
+		return "Parcel_PG_Light";
+
+	case SIM_ACCESS_MIN:
+	default:
+		return "";
+	}
+}
+
+// static
+std::string LLViewerRegion::accessToShortString(U8 sim_access)
+{
+	switch(sim_access)		/* Flawfinder: ignore */
+	{
+	case SIM_ACCESS_PG:
+		return "PG";
+
+	case SIM_ACCESS_MATURE:
+		return "M";
+
+	case SIM_ACCESS_ADULT:
+		return "A";
+
+	case SIM_ACCESS_MIN:
+	default:
+		return "U";
+	}
+}
+
+// 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**)
+{
+	// send it to 'observers'
+	// *TODO: switch the floaters to using LLRegionInfoModel
+	llinfos << "Processing region info" << llendl;
+	LLRegionInfoModel::instance().update(msg);
+	LLFloaterGodTools::processRegionInfo(msg);
+	LLFloaterRegionInfo::processRegionInfo(msg);
+	LLFloaterReporter::processRegionInfo(msg);
+}
+
+void LLViewerRegion::setCacheID(const LLUUID& id)
+{
+	mImpl->mCacheID = id;
+}
+
+S32 LLViewerRegion::renderPropertyLines()
+{
+	if (mParcelOverlay)
+	{
+		return mParcelOverlay->renderPropertyLines();
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+// This gets called when the height field changes.
+void LLViewerRegion::dirtyHeights()
+{
+	// Property lines need to be reconstructed when the land changes.
+	if (mParcelOverlay)
+	{
+		mParcelOverlay->setDirty();
+	}
+}
+
+BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
+{
+	LLMemType mt_ivr(LLMemType::MTYPE_IDLE_UPDATE_VIEWER_REGION);
+	// did_update returns TRUE if we did at least one significant update
+	BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time);
+	
+	if (mParcelOverlay)
+	{
+		// Hopefully not a significant time sink...
+		mParcelOverlay->idleUpdate();
+	}
+
+	return did_update;
+}
+
+
+// As above, but forcibly do the update.
+void LLViewerRegion::forceUpdate()
+{
+	mImpl->mLandp->idleUpdate(0.f);
+
+	if (mParcelOverlay)
+	{
+		mParcelOverlay->idleUpdate(true);
+	}
+}
+
+void LLViewerRegion::connectNeighbor(LLViewerRegion *neighborp, U32 direction)
+{
+	mImpl->mLandp->connectNeighbor(neighborp->mImpl->mLandp, direction);
+}
+
+
+void LLViewerRegion::disconnectAllNeighbors()
+{
+	mImpl->mLandp->disconnectAllNeighbors();
+}
+
+LLVLComposition * LLViewerRegion::getComposition() const
+{
+	return mImpl->mCompositionp;
+}
+
+F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
+{
+	if (x >= 256)
+	{
+		if (y >= 256)
+		{
+			LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 256.f, 0.f);
+			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
+			if (regionp)
+			{
+				// OK, we need to do some hackery here - different simulators no longer use
+				// the same composition values, necessarily.
+				// If we're attempting to blend, then we want to make the fractional part of
+				// this region match the fractional of the adjacent.  For now, just minimize
+				// the delta.
+				F32 our_comp = getComposition()->getValueScaled(255, 255);
+				F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, y - 256.f);
+				while (llabs(our_comp - adj_comp) >= 1.f)
+				{
+					if (our_comp > adj_comp)
+					{
+						adj_comp += 1.f;
+					}
+					else
+					{
+						adj_comp -= 1.f;
+					}
+				}
+				return adj_comp;
+			}
+		}
+		else
+		{
+			LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 0, 0.f);
+			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
+			if (regionp)
+			{
+				// OK, we need to do some hackery here - different simulators no longer use
+				// the same composition values, necessarily.
+				// If we're attempting to blend, then we want to make the fractional part of
+				// this region match the fractional of the adjacent.  For now, just minimize
+				// the delta.
+				F32 our_comp = getComposition()->getValueScaled(255.f, (F32)y);
+				F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, (F32)y);
+				while (llabs(our_comp - adj_comp) >= 1.f)
+				{
+					if (our_comp > adj_comp)
+					{
+						adj_comp += 1.f;
+					}
+					else
+					{
+						adj_comp -= 1.f;
+					}
+				}
+				return adj_comp;
+			}
+		}
+	}
+	else if (y >= 256)
+	{
+		LLVector3d center = getCenterGlobal() + LLVector3d(0.f, 256.f, 0.f);
+		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
+		if (regionp)
+		{
+			// OK, we need to do some hackery here - different simulators no longer use
+			// the same composition values, necessarily.
+			// If we're attempting to blend, then we want to make the fractional part of
+			// this region match the fractional of the adjacent.  For now, just minimize
+			// the delta.
+			F32 our_comp = getComposition()->getValueScaled((F32)x, 255.f);
+			F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - 256.f);
+			while (llabs(our_comp - adj_comp) >= 1.f)
+			{
+				if (our_comp > adj_comp)
+				{
+					adj_comp += 1.f;
+				}
+				else
+				{
+					adj_comp -= 1.f;
+				}
+			}
+			return adj_comp;
+		}
+	}
+
+	return getComposition()->getValueScaled((F32)x, (F32)y);
+}
+
+void LLViewerRegion::calculateCenterGlobal() 
+{
+	mImpl->mCenterGlobal = mImpl->mOriginGlobal;
+	mImpl->mCenterGlobal.mdV[VX] += 0.5 * mWidth;
+	mImpl->mCenterGlobal.mdV[VY] += 0.5 * mWidth;
+	mImpl->mCenterGlobal.mdV[VZ] = 0.5 * mImpl->mLandp->getMinZ() + mImpl->mLandp->getMaxZ();
+}
+
+void LLViewerRegion::calculateCameraDistance()
+{
+	mCameraDistanceSquared = (F32)(gAgentCamera.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared();
+}
+
+std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region)
+{
+	s << "{ ";
+	s << region.mImpl->mHost;
+	s << " mOriginGlobal = " << region.getOriginGlobal()<< "\n";
+    std::string name(region.getName()), zone(region.getZoning());
+    if (! name.empty())
+    {
+        s << " mName         = " << name << '\n';
+    }
+    if (! zone.empty())
+    {
+        s << " mZoning       = " << zone << '\n';
+    }
+	s << "}";
+	return s;
+}
+
+
+// ---------------- Protected Member Functions ----------------
+
+void LLViewerRegion::updateNetStats()
+{
+	F32 dt = mImpl->mLastNetUpdate.getElapsedTimeAndResetF32();
+
+	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);
+	if (!cdp)
+	{
+		mAlive = false;
+		return;
+	}
+
+	mAlive = true;
+	mDeltaTime = dt;
+
+	mLastPacketsIn =	mPacketsIn;
+	mLastBitsIn =		mBitsIn;
+	mLastPacketsOut =	mPacketsOut;
+	mLastPacketsLost =	mPacketsLost;
+
+	mPacketsIn =				cdp->getPacketsIn();
+	mBitsIn =					8 * cdp->getBytesIn();
+	mPacketsOut =				cdp->getPacketsOut();
+	mPacketsLost =				cdp->getPacketsLost();
+	mPingDelay =				cdp->getPingDelay();
+
+	mBitStat.addValue(mBitsIn - mLastBitsIn);
+	mPacketsStat.addValue(mPacketsIn - mLastPacketsIn);
+	mPacketsLostStat.addValue(mPacketsLost);
+}
+
+
+U32 LLViewerRegion::getPacketsLost() const
+{
+	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);
+	if (!cdp)
+	{
+		llinfos << "LLViewerRegion::getPacketsLost couldn't find circuit for " << mImpl->mHost << llendl;
+		return 0;
+	}
+	else
+	{
+		return cdp->getPacketsLost();
+	}
+}
+
+S32 LLViewerRegion::getHttpResponderID() const
+{
+	return mImpl->mHttpResponderID;
+}
+
+BOOL LLViewerRegion::pointInRegionGlobal(const LLVector3d &point_global) const
+{
+	LLVector3 pos_region = getPosRegionFromGlobal(point_global);
+
+	if (pos_region.mV[VX] < 0)
+	{
+		return FALSE;
+	}
+	if (pos_region.mV[VX] >= mWidth)
+	{
+		return FALSE;
+	}
+	if (pos_region.mV[VY] < 0)
+	{
+		return FALSE;
+	}
+	if (pos_region.mV[VY] >= mWidth)
+	{
+		return FALSE;
+	}
+	return TRUE;
+}
+
+LLVector3 LLViewerRegion::getPosRegionFromGlobal(const LLVector3d &point_global) const
+{
+	LLVector3 pos_region;
+	pos_region.setVec(point_global - mImpl->mOriginGlobal);
+	return pos_region;
+}
+
+LLVector3d LLViewerRegion::getPosGlobalFromRegion(const LLVector3 &pos_region) const
+{
+	LLVector3d pos_region_d;
+	pos_region_d.setVec(pos_region);
+	return pos_region_d + mImpl->mOriginGlobal;
+}
+
+LLVector3 LLViewerRegion::getPosAgentFromRegion(const LLVector3 &pos_region) const
+{
+	LLVector3d pos_global = getPosGlobalFromRegion(pos_region);
+
+	return gAgent.getPosAgentFromGlobal(pos_global);
+}
+
+LLVector3 LLViewerRegion::getPosRegionFromAgent(const LLVector3 &pos_agent) const
+{
+	return pos_agent - getOriginAgent();
+}
+
+F32 LLViewerRegion::getLandHeightRegion(const LLVector3& region_pos)
+{
+	return mImpl->mLandp->resolveHeightRegion( region_pos );
+}
+
+bool LLViewerRegion::isAlive()
+{
+	return mAlive;
+}
+
+BOOL LLViewerRegion::isOwnedSelf(const LLVector3& pos)
+{
+	if (mParcelOverlay)
+	{
+		return mParcelOverlay->isOwnedSelf(pos);
+	} else {
+		return FALSE;
+	}
+}
+
+// Owned by a group you belong to?  (officer or member)
+BOOL LLViewerRegion::isOwnedGroup(const LLVector3& pos)
+{
+	if (mParcelOverlay)
+	{
+		return mParcelOverlay->isOwnedGroup(pos);
+	} else {
+		return FALSE;
+	}
+}
+
+// the new TCP coarse location handler node
+class CoarseLocationUpdate : public LLHTTPNode
+{
+public:
+	virtual void post(
+		ResponsePtr responder,
+		const LLSD& context,
+		const LLSD& input) const
+	{
+		LLHost host(input["sender"].asString());
+		LLViewerRegion* region = LLWorld::getInstance()->getRegion(host);
+		if( !region )
+		{
+			return;
+		}
+
+		S32 target_index = input["body"]["Index"][0]["Prey"].asInteger();
+		S32 you_index    = input["body"]["Index"][0]["You" ].asInteger();
+
+		LLDynamicArray<U32>* avatar_locs = &region->mMapAvatars;
+		LLDynamicArray<LLUUID>* avatar_ids = &region->mMapAvatarIDs;
+		avatar_locs->reset();
+		avatar_ids->reset();
+
+		//llinfos << "coarse locations agent[0] " << input["body"]["AgentData"][0]["AgentID"].asUUID() << llendl;
+		//llinfos << "my agent id = " << gAgent.getID() << llendl;
+		//llinfos << ll_pretty_print_sd(input) << llendl;
+
+		LLSD 
+			locs   = input["body"]["Location"],
+			agents = input["body"]["AgentData"];
+		LLSD::array_iterator 
+			locs_it = locs.beginArray(), 
+			agents_it = agents.beginArray();
+		BOOL has_agent_data = input["body"].has("AgentData");
+
+		for(int i=0; 
+			locs_it != locs.endArray(); 
+			i++, locs_it++)
+		{
+			U8 
+				x = locs_it->get("X").asInteger(),
+				y = locs_it->get("Y").asInteger(),
+				z = locs_it->get("Z").asInteger();
+			// treat the target specially for the map, and don't add you or the target
+			if(i == target_index)
+			{
+				LLVector3d global_pos(region->getOriginGlobal());
+				global_pos.mdV[VX] += (F64)x;
+				global_pos.mdV[VY] += (F64)y;
+				global_pos.mdV[VZ] += (F64)z * 4.0;
+				LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
+			}
+			else if( i != you_index)
+			{
+				U32 loc = x << 16 | y << 8 | z; loc = loc;
+				U32 pos = 0x0;
+				pos |= x;
+				pos <<= 8;
+				pos |= y;
+				pos <<= 8;
+				pos |= z;
+				avatar_locs->put(pos);
+				//llinfos << "next pos: " << x << "," << y << "," << z << ": " << pos << llendl;
+				if(has_agent_data) // for backwards compatibility with old message format
+				{
+					LLUUID agent_id(agents_it->get("AgentID").asUUID());
+					//llinfos << "next agent: " << agent_id.asString() << llendl;
+					avatar_ids->put(agent_id);
+				}
+			}
+			if (has_agent_data)
+			{
+				agents_it++;
+			}
+		}
+	}
+};
+
+// build the coarse location HTTP node under the "/message" URL
+LLHTTPRegistration<CoarseLocationUpdate>
+   gHTTPRegistrationCoarseLocationUpdate(
+	   "/message/CoarseLocationUpdate");
+
+
+// the deprecated coarse location handler
+void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg)
+{
+	//llinfos << "CoarseLocationUpdate" << llendl;
+	mMapAvatars.reset();
+	mMapAvatarIDs.reset(); // only matters in a rare case but it's good to be safe.
+
+	U8 x_pos = 0;
+	U8 y_pos = 0;
+	U8 z_pos = 0;
+
+	U32 pos = 0x0;
+
+	S16 agent_index;
+	S16 target_index;
+	msg->getS16Fast(_PREHASH_Index, _PREHASH_You, agent_index);
+	msg->getS16Fast(_PREHASH_Index, _PREHASH_Prey, target_index);
+
+	BOOL has_agent_data = msg->has(_PREHASH_AgentData);
+	S32 count = msg->getNumberOfBlocksFast(_PREHASH_Location);
+	for(S32 i = 0; i < count; i++)
+	{
+		msg->getU8Fast(_PREHASH_Location, _PREHASH_X, x_pos, i);
+		msg->getU8Fast(_PREHASH_Location, _PREHASH_Y, y_pos, i);
+		msg->getU8Fast(_PREHASH_Location, _PREHASH_Z, z_pos, i);
+		LLUUID agent_id = LLUUID::null;
+		if(has_agent_data)
+		{
+			msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id, i);
+		}
+
+		//llinfos << "  object X: " << (S32)x_pos << " Y: " << (S32)y_pos
+		//		<< " Z: " << (S32)(z_pos * 4)
+		//		<< llendl;
+
+		// treat the target specially for the map
+		if(i == target_index)
+		{
+			LLVector3d global_pos(mImpl->mOriginGlobal);
+			global_pos.mdV[VX] += (F64)(x_pos);
+			global_pos.mdV[VY] += (F64)(y_pos);
+			global_pos.mdV[VZ] += (F64)(z_pos) * 4.0;
+			LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
+		}
+		
+		//don't add you
+		if( i != agent_index)
+		{
+			pos = 0x0;
+			pos |= x_pos;
+			pos <<= 8;
+			pos |= y_pos;
+			pos <<= 8;
+			pos |= z_pos;
+			mMapAvatars.put(pos);
+			if(has_agent_data)
+			{
+				mMapAvatarIDs.put(agent_id);
+			}
+		}
+	}
+}
+
+void LLViewerRegion::getInfo(LLSD& info)
+{
+	info["Region"]["Host"] = getHost().getIPandPort();
+	info["Region"]["Name"] = getName();
+	U32 x, y;
+	from_region_handle(getHandle(), &x, &y);
+	info["Region"]["Handle"]["x"] = (LLSD::Integer)x;
+	info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
+}
+
+void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features)
+{
+	sim_features = mSimulatorFeatures;
+
+}
+
+void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
+{
+	std::stringstream str;
+	
+	LLSDSerialize::toPrettyXML(sim_features, str);
+	llinfos << str.str() << llendl;
+	mSimulatorFeatures = sim_features;
+}
+
+LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp)
+{
+	U32 local_id = objectp->getLocalID();
+	U32 crc = objectp->getCRC();
+
+	LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);
+
+	if (entry)
+	{
+		// we've seen this object before
+		if (entry->getCRC() == crc)
+		{
+			// Record a hit
+			entry->recordDupe();
+			return CACHE_UPDATE_DUPE;
+		}
+
+		// Update the cache entry
+		mImpl->mCacheMap.erase(local_id);
+		delete entry;
+		entry = new LLVOCacheEntry(local_id, crc, dp);
+		mImpl->mCacheMap[local_id] = entry;
+		return CACHE_UPDATE_CHANGED;
+	}
+
+	// we haven't seen this object before
+
+	// Create new entry and add to map
+	eCacheUpdateResult result = CACHE_UPDATE_ADDED;
+	if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES)
+	{
+		delete mImpl->mCacheMap.begin()->second ;
+		mImpl->mCacheMap.erase(mImpl->mCacheMap.begin());
+		result = CACHE_UPDATE_REPLACED;
+		
+	}
+	entry = new LLVOCacheEntry(local_id, crc, dp);
+
+	mImpl->mCacheMap[local_id] = entry;
+	return result;
+}
+
+// Get data packer for this object, if we have cached data
+// AND the CRC matches. JC
+LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type)
+{
+	//llassert(mCacheLoaded);  This assert failes often, changing to early-out -- davep, 2010/10/18
+
+	LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);
+
+	if (entry)
+	{
+		// we've seen this object before
+		if (entry->getCRC() == crc)
+		{
+			// Record a hit
+			entry->recordHit();
+		cache_miss_type = CACHE_MISS_TYPE_NONE;
+			return entry->getDP(crc);
+		}
+		else
+		{
+			// llinfos << "CRC miss for " << local_id << llendl;
+		cache_miss_type = CACHE_MISS_TYPE_CRC;
+			mCacheMissCRC.put(local_id);
+		}
+	}
+	else
+	{
+		// llinfos << "Cache miss for " << local_id << llendl;
+	cache_miss_type = CACHE_MISS_TYPE_FULL;
+		mCacheMissFull.put(local_id);
+	}
+
+	return NULL;
+}
+
+void LLViewerRegion::addCacheMissFull(const U32 local_id)
+{
+	mCacheMissFull.put(local_id);
+}
+
+void LLViewerRegion::requestCacheMisses()
+{
+	S32 full_count = mCacheMissFull.count();
+	S32 crc_count = mCacheMissCRC.count();
+	if (full_count == 0 && crc_count == 0) return;
+
+	LLMessageSystem* msg = gMessageSystem;
+	BOOL start_new_message = TRUE;
+	S32 blocks = 0;
+	S32 i;
+
+	// Send full cache miss updates.  For these, we KNOW we don't
+	// have a viewer object.
+	for (i = 0; i < full_count; i++)
+	{
+		if (start_new_message)
+		{
+			msg->newMessageFast(_PREHASH_RequestMultipleObjects);
+			msg->nextBlockFast(_PREHASH_AgentData);
+			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+			start_new_message = FALSE;
+		}
+
+		msg->nextBlockFast(_PREHASH_ObjectData);
+		msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_FULL);
+		msg->addU32Fast(_PREHASH_ID, mCacheMissFull[i]);
+		blocks++;
+
+		if (blocks >= 255)
+		{
+			sendReliableMessage();
+			start_new_message = TRUE;
+			blocks = 0;
+		}
+	}
+
+	// Send CRC miss updates.  For these, we _might_ have a viewer object,
+	// but probably not.
+	for (i = 0; i < crc_count; i++)
+	{
+		if (start_new_message)
+		{
+			msg->newMessageFast(_PREHASH_RequestMultipleObjects);
+			msg->nextBlockFast(_PREHASH_AgentData);
+			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+			start_new_message = FALSE;
+		}
+
+		msg->nextBlockFast(_PREHASH_ObjectData);
+		msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_CRC);
+		msg->addU32Fast(_PREHASH_ID, mCacheMissCRC[i]);
+		blocks++;
+
+		if (blocks >= 255)
+		{
+			sendReliableMessage();
+			start_new_message = TRUE;
+			blocks = 0;
+		}
+	}
+
+	// finish any pending message
+	if (!start_new_message)
+	{
+		sendReliableMessage();
+	}
+	mCacheMissFull.reset();
+	mCacheMissCRC.reset();
+
+	mCacheDirty = TRUE ;
+	// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl;
+	#if LL_RECORD_VIEWER_STATS
+	LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(this);
+	LLViewerStatsRecorder::instance()->recordRequestCacheMissesEvent(full_count + crc_count);
+	LLViewerStatsRecorder::instance()->endObjectUpdateEvents();
+	#endif
+}
+
+void LLViewerRegion::dumpCache()
+{
+	const S32 BINS = 4;
+	S32 hit_bin[BINS];
+	S32 change_bin[BINS];
+
+	S32 i;
+	for (i = 0; i < BINS; ++i)
+	{
+		hit_bin[i] = 0;
+		change_bin[i] = 0;
+	}
+
+	LLVOCacheEntry *entry;
+	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)
+	{
+		entry = iter->second ;
+
+		S32 hits = entry->getHitCount();
+		S32 changes = entry->getCRCChangeCount();
+
+		hits = llclamp(hits, 0, BINS-1);
+		changes = llclamp(changes, 0, BINS-1);
+
+		hit_bin[hits]++;
+		change_bin[changes]++;
+	}
+
+	llinfos << "Count " << mImpl->mCacheMap.size() << llendl;
+	for (i = 0; i < BINS; i++)
+	{
+		llinfos << "Hits " << i << " " << hit_bin[i] << llendl;
+	}
+	for (i = 0; i < BINS; i++)
+	{
+		llinfos << "Changes " << i << " " << change_bin[i] << llendl;
+	}
+}
+
+void LLViewerRegion::unpackRegionHandshake()
+{
+	LLMessageSystem *msg = gMessageSystem;
+
+	U32 region_flags;
+	U8 sim_access;
+	std::string sim_name;
+	LLUUID sim_owner;
+	BOOL is_estate_manager;
+	F32 water_height;
+	F32 billable_factor;
+	LLUUID cache_id;
+
+	msg->getU32		("RegionInfo", "RegionFlags", region_flags);
+	msg->getU8		("RegionInfo", "SimAccess", sim_access);
+	msg->getString	("RegionInfo", "SimName", sim_name);
+	msg->getUUID	("RegionInfo", "SimOwner", sim_owner);
+	msg->getBOOL	("RegionInfo", "IsEstateManager", is_estate_manager);
+	msg->getF32		("RegionInfo", "WaterHeight", water_height);
+	msg->getF32		("RegionInfo", "BillableFactor", billable_factor);
+	msg->getUUID	("RegionInfo", "CacheID", cache_id );
+
+	setRegionFlags(region_flags);
+	setSimAccess(sim_access);
+	setRegionNameAndZone(sim_name);
+	setOwner(sim_owner);
+	setIsEstateManager(is_estate_manager);
+	setWaterHeight(water_height);
+	setBillableFactor(billable_factor);
+	setCacheID(cache_id);
+
+	LLUUID region_id;
+	msg->getUUID("RegionInfo2", "RegionID", region_id);
+	setRegionID(region_id);
+	
+	// Retrieve the CR-53 (Homestead/Land SKU) information
+	S32 classID = 0;
+	S32 cpuRatio = 0;
+	std::string coloName;
+	std::string productSKU;
+	std::string productName;
+
+	// the only reasonable way to decide if we actually have any data is to
+	// check to see if any of these fields have positive sizes
+	if (msg->getSize("RegionInfo3", "ColoName") > 0 ||
+	    msg->getSize("RegionInfo3", "ProductSKU") > 0 ||
+	    msg->getSize("RegionInfo3", "ProductName") > 0)
+	{
+		msg->getS32     ("RegionInfo3", "CPUClassID",  classID);
+		msg->getS32     ("RegionInfo3", "CPURatio",    cpuRatio);
+		msg->getString  ("RegionInfo3", "ColoName",    coloName);
+		msg->getString  ("RegionInfo3", "ProductSKU",  productSKU);
+		msg->getString  ("RegionInfo3", "ProductName", productName);
+		
+		mClassID = classID;
+		mCPURatio = cpuRatio;
+		mColoName = coloName;
+		mProductSKU = productSKU;
+		mProductName = productName;
+	}
+
+	LLVLComposition *compp = getComposition();
+	if (compp)
+	{
+		LLUUID tmp_id;
+
+		msg->getUUID("RegionInfo", "TerrainDetail0", tmp_id);
+		compp->setDetailTextureID(0, tmp_id);
+		msg->getUUID("RegionInfo", "TerrainDetail1", tmp_id);
+		compp->setDetailTextureID(1, tmp_id);
+		msg->getUUID("RegionInfo", "TerrainDetail2", tmp_id);
+		compp->setDetailTextureID(2, tmp_id);
+		msg->getUUID("RegionInfo", "TerrainDetail3", tmp_id);
+		compp->setDetailTextureID(3, tmp_id);
+
+		F32 tmp_f32;
+		msg->getF32("RegionInfo", "TerrainStartHeight00", tmp_f32);
+		compp->setStartHeight(0, tmp_f32);
+		msg->getF32("RegionInfo", "TerrainStartHeight01", tmp_f32);
+		compp->setStartHeight(1, tmp_f32);
+		msg->getF32("RegionInfo", "TerrainStartHeight10", tmp_f32);
+		compp->setStartHeight(2, tmp_f32);
+		msg->getF32("RegionInfo", "TerrainStartHeight11", tmp_f32);
+		compp->setStartHeight(3, tmp_f32);
+
+		msg->getF32("RegionInfo", "TerrainHeightRange00", tmp_f32);
+		compp->setHeightRange(0, tmp_f32);
+		msg->getF32("RegionInfo", "TerrainHeightRange01", tmp_f32);
+		compp->setHeightRange(1, tmp_f32);
+		msg->getF32("RegionInfo", "TerrainHeightRange10", tmp_f32);
+		compp->setHeightRange(2, tmp_f32);
+		msg->getF32("RegionInfo", "TerrainHeightRange11", tmp_f32);
+		compp->setHeightRange(3, tmp_f32);
+
+		// If this is an UPDATE (params already ready, we need to regenerate
+		// all of our terrain stuff, by
+		if (compp->getParamsReady())
+		{
+			//this line creates frame stalls on region crossing and removing it appears to have no effect
+			//getLand().dirtyAllPatches();
+		}
+		else
+		{
+			compp->setParamsReady();
+		}
+	}
+
+
+	// Now that we have the name, we can load the cache file
+	// off disk.
+	loadObjectCache();
+
+	// After loading cache, signal that simulator can start
+	// sending data.
+	// TODO: Send all upstream viewer->sim handshake info here.
+	LLHost host = msg->getSender();
+	msg->newMessage("RegionHandshakeReply");
+	msg->nextBlock("AgentData");
+	msg->addUUID("AgentID", gAgent.getID());
+	msg->addUUID("SessionID", gAgent.getSessionID());
+	msg->nextBlock("RegionInfo");
+	msg->addU32("Flags", 0x0 );
+	msg->sendReliable(host);
+}
+
+void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
+{
+	capabilityNames.append("AgentState");
+	capabilityNames.append("AttachmentResources");
+	capabilityNames.append("AvatarPickerSearch");
+	capabilityNames.append("CharacterProperties");
+	capabilityNames.append("ChatSessionRequest");
+	capabilityNames.append("CopyInventoryFromNotecard");
+	capabilityNames.append("CreateInventoryCategory");
+	capabilityNames.append("DispatchRegionInfo");
+	capabilityNames.append("EnvironmentSettings");
+	capabilityNames.append("EstateChangeInfo");
+	capabilityNames.append("EventQueueGet");
+
+	if (gSavedSettings.getBOOL("UseHTTPInventory"))
+	{
+		capabilityNames.append("FetchLib2");
+		capabilityNames.append("FetchLibDescendents2");
+		capabilityNames.append("FetchInventory2");
+		capabilityNames.append("FetchInventoryDescendents2");
+	}
+
+	capabilityNames.append("GetDisplayNames");
+	capabilityNames.append("GetMesh");
+	capabilityNames.append("GetObjectCost");
+	capabilityNames.append("GetObjectPhysicsData");
+	capabilityNames.append("GetTexture");
+	capabilityNames.append("GroupMemberData");
+	capabilityNames.append("GroupProposalBallot");
+	capabilityNames.append("HomeLocation");
+	capabilityNames.append("LandResources");
+	capabilityNames.append("MapLayer");
+	capabilityNames.append("MapLayerGod");
+	capabilityNames.append("MeshUploadFlag");	
+	capabilityNames.append("NavMeshGenerationStatus");
+	capabilityNames.append("NewFileAgentInventory");
+	capabilityNames.append("ObjectMedia");
+	capabilityNames.append("ObjectMediaNavigate");
+	capabilityNames.append("ObjectNavMeshProperties");
+	capabilityNames.append("ParcelPropertiesUpdate");
+	capabilityNames.append("ParcelVoiceInfoRequest");
+	capabilityNames.append("ProductInfoRequest");
+	capabilityNames.append("ProvisionVoiceAccountRequest");
+	capabilityNames.append("RemoteParcelRequest");
+	capabilityNames.append("RequestTextureDownload");
+	capabilityNames.append("ResourceCostSelected");
+	capabilityNames.append("RetrieveNavMeshSrc");
+	capabilityNames.append("SearchStatRequest");
+	capabilityNames.append("SearchStatTracking");
+	capabilityNames.append("SendPostcard");
+	capabilityNames.append("SendUserReport");
+	capabilityNames.append("SendUserReportWithScreenshot");
+	capabilityNames.append("ServerReleaseNotes");
+	capabilityNames.append("SetDisplayName");
+	capabilityNames.append("SimConsoleAsync");
+	capabilityNames.append("SimulatorFeatures");
+	capabilityNames.append("StartGroupProposal");
+	capabilityNames.append("TerrainNavMeshProperties");
+	capabilityNames.append("TextureStats");
+	capabilityNames.append("UntrustedSimulatorMessage");
+	capabilityNames.append("UpdateAgentInformation");
+	capabilityNames.append("UpdateAgentLanguage");
+	capabilityNames.append("UpdateGestureAgentInventory");
+	capabilityNames.append("UpdateGestureTaskInventory");
+	capabilityNames.append("UpdateNotecardAgentInventory");
+	capabilityNames.append("UpdateNotecardTaskInventory");
+	capabilityNames.append("UpdateScriptAgent");
+	capabilityNames.append("UpdateScriptTask");
+	capabilityNames.append("UploadBakedTexture");
+	capabilityNames.append("ViewerMetrics");
+	capabilityNames.append("ViewerStartAuction");
+	capabilityNames.append("ViewerStats");
+
+	// Please add new capabilities alphabetically to reduce
+	// merge conflicts.
+}
+
+void LLViewerRegion::setSeedCapability(const std::string& url)
+{
+	if (getCapability("Seed") == url)
+    {
+		// llwarns << "Ignoring duplicate seed capability" << llendl;
+		return;
+    }
+	
+	delete mImpl->mEventPoll;
+	mImpl->mEventPoll = NULL;
+	
+	mImpl->mCapabilities.clear();
+	setCapability("Seed", url);
+
+	LLSD capabilityNames = LLSD::emptyArray();
+	mImpl->buildCapabilityNames(capabilityNames);
+
+	llinfos << "posting to seed " << url << llendl;
+
+	S32 id = ++mImpl->mHttpResponderID;
+	LLHTTPClient::post(url, capabilityNames, 
+						BaseCapabilitiesComplete::build(getHandle(), id),
+						LLSD(), CAP_REQUEST_TIMEOUT);
+}
+
+S32 LLViewerRegion::getNumSeedCapRetries()
+{
+	return mImpl->mSeedCapAttempts;
+}
+
+void LLViewerRegion::failedSeedCapability()
+{
+	// Should we retry asking for caps?
+	mImpl->mSeedCapAttempts++;
+	std::string url = getCapability("Seed");
+	if ( url.empty() )
+	{
+		LL_WARNS2("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url for retries!" << LL_ENDL;
+		return;
+	}
+	// After a few attempts, continue login.  We will keep trying once in-world:
+	if ( mImpl->mSeedCapAttempts >= mImpl->mSeedCapMaxAttemptsBeforeLogin &&
+		 STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState() )
+	{
+		LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
+	}
+
+	if ( mImpl->mSeedCapAttempts < mImpl->mSeedCapMaxAttempts)
+	{
+		LLSD capabilityNames = LLSD::emptyArray();
+		mImpl->buildCapabilityNames(capabilityNames);
+
+		llinfos << "posting to seed " << url << " (retry " 
+				<< mImpl->mSeedCapAttempts << ")" << llendl;
+
+		S32 id = ++mImpl->mHttpResponderID;
+		LLHTTPClient::post(url, capabilityNames, 
+						BaseCapabilitiesComplete::build(getHandle(), id),
+						LLSD(), CAP_REQUEST_TIMEOUT);
+	}
+	else
+	{
+		// *TODO: Give a user pop-up about this error?
+		LL_WARNS2("AppInit", "Capabilities") << "Failed to get seed capabilities from '" << url << "' after " << mImpl->mSeedCapAttempts << " attempts.  Giving up!" << LL_ENDL;
+	}
+}
+
+class SimulatorFeaturesReceived : public LLHTTPClient::Responder
+{
+	LOG_CLASS(SimulatorFeaturesReceived);
+public:
+    SimulatorFeaturesReceived(const std::string& retry_url, U64 region_handle, 
+			S32 attempt = 0, S32 max_attempts = MAX_CAP_REQUEST_ATTEMPTS)
+	: mRetryURL(retry_url), mRegionHandle(region_handle), mAttempt(attempt), mMaxAttempts(max_attempts)
+    { }
+	
+	
+    void error(U32 statusNum, const std::string& reason)
+    {
+		LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL;
+		retry();
+    }
+
+    void result(const LLSD& content)
+    {
+		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+		if(!regionp) //region is removed or responder is not created.
+		{
+			LL_WARNS2("AppInit", "SimulatorFeatures") << "Received results for region that no longer exists!" << LL_ENDL;
+			return ;
+		}
+		
+		regionp->setSimulatorFeatures(content);
+	}
+
+private:
+	void retry()
+	{
+		if (mAttempt < mMaxAttempts)
+		{
+			mAttempt++;
+			LL_WARNS2("AppInit", "SimulatorFeatures") << "Re-trying '" << mRetryURL << "'.  Retry #" << mAttempt << LL_ENDL;
+			LLHTTPClient::get(mRetryURL, new SimulatorFeaturesReceived(*this), LLSD(), CAP_REQUEST_TIMEOUT);
+		}
+	}
+	
+	std::string mRetryURL;
+	U64 mRegionHandle;
+	S32 mAttempt;
+	S32 mMaxAttempts;
+};
+
+
+void LLViewerRegion::setCapability(const std::string& name, const std::string& url)
+{
+	if(name == "EventQueueGet")
+	{
+		delete mImpl->mEventPoll;
+		mImpl->mEventPoll = NULL;
+		mImpl->mEventPoll = new LLEventPoll(url, getHost());
+	}
+	else if(name == "UntrustedSimulatorMessage")
+	{
+		LLHTTPSender::setSender(mImpl->mHost, new LLCapHTTPSender(url));
+	}
+	else if (name == "SimulatorFeatures")
+	{
+		// kick off a request for simulator features
+		LLHTTPClient::get(url, new SimulatorFeaturesReceived(url, getHandle()), LLSD(), CAP_REQUEST_TIMEOUT);
+	}
+	else
+	{
+		mImpl->mCapabilities[name] = url;
+		if(name == "GetTexture")
+		{
+			mHttpUrl = url ;
+		}
+	}
+}
+
+bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
+{
+	return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
+}
+
+std::string LLViewerRegion::getCapability(const std::string& name) const
+{
+	CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
+	if(iter == mImpl->mCapabilities.end())
+	{
+		return "";
+	}
+
+	return iter->second;
+}
+
+bool LLViewerRegion::capabilitiesReceived() const
+{
+	return mCapabilitiesReceived;
+}
+
+void LLViewerRegion::setCapabilitiesReceived(bool received)
+{
+	mCapabilitiesReceived = received;
+
+	// Tell interested parties that we've received capabilities,
+	// so that they can safely use getCapability().
+	if (received)
+	{
+		mCapabilitiesReceivedSignal(getRegionID());
+
+		// This is a single-shot signal. Forget callbacks to save resources.
+		mCapabilitiesReceivedSignal.disconnect_all_slots();
+	}
+}
+
+boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb)
+{
+	return mCapabilitiesReceivedSignal.connect(cb);
+}
+
+void LLViewerRegion::logActiveCapabilities() const
+{
+	int count = 0;
+	CapabilityMap::const_iterator iter;
+	for (iter = mImpl->mCapabilities.begin(); iter != mImpl->mCapabilities.end(); ++iter, ++count)
+	{
+		if (!iter->second.empty())
+		{
+			llinfos << iter->first << " URL is " << iter->second << llendl;
+		}
+	}
+	llinfos << "Dumped " << count << " entries." << llendl;
+}
+
+LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
+{
+	if (type < mImpl->mObjectPartition.size())
+	{
+		return mImpl->mObjectPartition[type];
+	}
+	return NULL;
+}
+
+// the viewer can not yet distinquish between normal- and estate-owned objects
+// so we collapse these two bits and enable the UI if either are set
+const U32 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT
+											| REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT;
+
+bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const
+{
+	return (mParcelOverlay != NULL)
+		&& (mParcelOverlay->isOwnedSelf(pos)
+			|| mParcelOverlay->isOwnedGroup(pos)
+			|| ((mRegionFlags & ALLOW_RETURN_ENCROACHING_OBJECT)
+				&& mParcelOverlay->encroachesOwned(boxes)) );
+}
+
+bool LLViewerRegion::childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const
+{
+	bool result = false;
+	result = ( mParcelOverlay && mParcelOverlay->encroachesOnUnowned( boxes ) ) ? 1 : 0;
+	return result;
+}
+
+bool LLViewerRegion::objectsCrossParcel(const std::vector<LLBBox>& boxes) const
+{
+	return mParcelOverlay && mParcelOverlay->encroachesOnNearbyParcel(boxes);
+}
+
+void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions )
+{
+	mImpl->mLandp->getNeighboringRegions( uniqueRegions );
+}
+void LLViewerRegion::getNeighboringRegionsStatus( std::vector<S32>& regions )
+{
+	mImpl->mLandp->getNeighboringRegionsStatus( regions );
+}
+void LLViewerRegion::showReleaseNotes()
+{
+	std::string url = this->getCapability("ServerReleaseNotes");
+
+	if (url.empty()) {
+		// HACK haven't received the capability yet, we'll wait until
+		// it arives.
+		mReleaseNotesRequested = TRUE;
+		return;
+	}
+
+	LLWeb::loadURL(url);
+	mReleaseNotesRequested = FALSE;
+}
+
+std::string LLViewerRegion::getDescription() const
+{
+    return stringize(*this);
+}
+
+bool LLViewerRegion::meshUploadEnabled() const
+{
+	return (mSimulatorFeatures.has("MeshUploadEnabled") &&
+		mSimulatorFeatures["MeshUploadEnabled"].asBoolean());
+}
+
+bool LLViewerRegion::meshRezEnabled() const
+{
+	return (mSimulatorFeatures.has("MeshRezEnabled") &&
+				mSimulatorFeatures["MeshRezEnabled"].asBoolean());
+}
+
+bool LLViewerRegion::dynamicPathfindingEnabled() const
+{
+	return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") &&
+			 mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean());
+}
+
-- 
cgit v1.2.3


From 238ac6c0e869d1c8c380e3e7b70d4803c385f352 Mon Sep 17 00:00:00 2001
From: Chris Baker <baker@lindenlab.com>
Date: Tue, 28 Aug 2012 17:32:01 -0700
Subject: Got viewer displaying new data format

---
 indra/newview/llgroupmgr.cpp | 142 ++++++++++++++++++++++++++++++++++---------
 indra/newview/llgroupmgr.h   |   2 +
 2 files changed, 114 insertions(+), 30 deletions(-)

diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 3300034f7f..2e1d1d5c77 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -1851,38 +1851,13 @@ private:
 		LLSD mMemberData;
 };
 
-void GroupMemberDataResponder::result(const LLSD& pContent)
+void GroupMemberDataResponder::result(const LLSD& content)
 {
 	LL_INFOS("BAKER") << "BAKER TAG ////////////////////////////////////////////////////////////////" << LL_ENDL;
-	// Did we get anything in pContent?
-	if(pContent.size())
-	{
-		LL_INFOS("BAKER") << "Lik dis if u cry evertim" << LL_ENDL;
-
-		// BAKER TODO:
-		// Figure out what to do with all the dataz.
-		// Looks like processGroupMembersReply does the work
-		LLUUID	agent_id	= pContent["agent_id"];
-		LLUUID	group_id	= pContent["group_id"];
-		LLSD	member_list	= pContent["members"];
-		LLSD	titles		= pContent["titles"];
-		LLSD	defaults	= pContent["defaults"];
-
-		int i = 0;
-		++i;
-
-
-
-	}
-	else
-	{
-		LL_INFOS("BAKER") << "WE AIN'T FOUND SHIT!" << LL_ENDL;
-
-		// BAKER TODO:
-		// Handle this case
-
-	}
+	LL_INFOS("BAKER") << "Got data from responder" << LL_ENDL;
+	LLGroupMgr::processCapGroupMembersRequest(content);
 	LL_INFOS("BAKER") << "//////////////////////////////////////////////////////////////////////////\n" << LL_ENDL;
+
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -1898,6 +1873,7 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 	//return;
 
 #if 1
+	
 	LLViewerRegion* currentRegion = gAgent.getRegion();
 
 	// Check to make sure we have our capabilities
@@ -1912,13 +1888,119 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 
 	// Post to our service.  Add a body containing the group_id.
 	LLSD body = LLSD::emptyMap();
-	body["group_id"] = group_id;
+	body["group_id"]	= group_id;
+	// Session id?
 
 	LLHTTPClient::ResponderPtr grp_data_responder = new GroupMemberDataResponder();
 	 // This could take a while to finish, timeout after 10 minutes.
 	LLHTTPClient::post(cap_url, body, grp_data_responder, LLSD(), 600);
+
 #endif
 }
+
+
+// static
+void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
+{
+	LL_INFOS("BAKER") << "BAKER TAG ////////////////////////////////////////////////////////////////" << LL_ENDL;
+	// Did we get anything in content?
+	if(!content.size())
+	{
+		LL_INFOS("BAKER") << "WE AIN'T FOUND SHIT!" << LL_ENDL;
+		// BAKER TODO:
+		// Handle this case
+	}
+
+	LL_INFOS("BAKER") << "Lik dis if u cry evertim" << LL_ENDL;
+
+	// If we have no members, there's no reason to do anything else
+	S32	num_members	= content["member_count"];
+	if(num_members < 1)
+		return;
+	
+	LLUUID	group_id = content["group_id"].asUUID();
+
+	LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);
+	if(!group_datap)
+	{
+		LL_WARNS("GrpMgr") << "Received incorrect, possibly stale, group or request id" << LL_ENDL;
+		return;
+	}
+
+	group_datap->mMemberCount = num_members;
+
+	LLSD	member_list	= content["members"];
+	LLSD	titles		= content["titles"];
+	LLSD	defaults	= content["defaults"];
+
+	std::string online_status;
+	std::string title;
+	S32			contribution;
+	U64			member_powers;
+	// If this is changed to a bool, make sure to change the LLGroupMemberData constructor
+	BOOL		is_owner;
+
+	// Compute this once, rather than every time.
+	U64	default_powers	= llstrtou64(defaults["default_powers"].asString().c_str(), NULL, 16);
+
+	LLSD::map_const_iterator member_iter_start	= member_list.beginMap();
+	LLSD::map_const_iterator member_iter_end	= member_list.endMap();
+	for( ; member_iter_start != member_iter_end; ++member_iter_start)
+	{
+		// Reset defaults
+		online_status	= "unknown";
+		title			= titles[0];
+		contribution	= 0;
+		member_powers	= default_powers;
+		is_owner		= false;
+
+		const LLUUID member_id(member_iter_start->first);
+		LLSD member_info = member_iter_start->second;
+
+		// Online Status
+		if(member_info.has("last_login"))
+		{
+			online_status = member_info["last_login"];
+			if(online_status == "Online")
+				online_status = LLTrans::getString("group_member_status_online");
+			else
+				formatDateString(online_status);
+		}
+
+		// Title
+		if(member_info.has("title"))
+			title = titles[member_info["title"].asInteger()];
+
+		// Powers
+		if(member_info.has("powers"))
+			member_powers = llstrtou64(member_info["powers"].asString().c_str(), NULL, 16);
+
+		// Land Contribution
+		if(member_info.has("donated_square_meters"))
+			contribution = member_info["donated_square_meters"];
+
+		if(member_info.has("owner"))
+			is_owner = true;
+
+		LLGroupMemberData* data = new LLGroupMemberData(member_id, 
+			contribution, 
+			member_powers, 
+			title,
+			online_status,
+			is_owner);
+
+		group_datap->mMembers[member_id] = data;
+	}
+
+	group_datap->mMemberDataComplete = TRUE;
+	group_datap->mRoleMemberDataComplete = TRUE;
+	group_datap->mMemberRequestID.setNull();
+	group_datap->mChanged = TRUE;
+	LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);
+
+	LL_INFOS("BAKER") << "//////////////////////////////////////////////////////////////////////////\n" << LL_ENDL;
+}
+
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index 5b535f5056..b0c3cd025d 100644
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -341,7 +341,9 @@ public:
 									  uuid_vec_t& member_ids);
 
 	// BAKER
+	//static void sendCapGroupMembersRequest(const LLUUID& group_id);
 	void sendCapGroupMembersRequest(const LLUUID& group_id);
+	static void processCapGroupMembersRequest(const LLSD& content);
 
 	void cancelGroupRoleChanges(const LLUUID& group_id);
 
-- 
cgit v1.2.3


From 7ecf3ce40f4ec27a43878a3a2192c97479d22fcf Mon Sep 17 00:00:00 2001
From: Chris Baker <baker@lindenlab.com>
Date: Fri, 31 Aug 2012 17:53:47 -0700
Subject: - Fixed an issue where service was called twice in a frame - Changed
 level of output logs - Cleaned up comments

---
 indra/newview/llgroupmgr.cpp          | 54 +++++++++++++++++------------------
 indra/newview/llgroupmgr.h            |  3 +-
 indra/newview/llpanelgroupgeneral.cpp | 16 ++++-------
 indra/newview/llpanelgroupinvite.cpp  |  4 ---
 indra/newview/llpanelgrouproles.cpp   | 12 --------
 5 files changed, 34 insertions(+), 55 deletions(-)

diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 2e1d1d5c77..b9bcedda13 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -36,6 +36,7 @@
 #include <vector>
 #include <algorithm>
 
+#include "llappviewer.h"
 #include "llagent.h"
 #include "llui.h"
 #include "message.h"
@@ -745,6 +746,7 @@ void LLGroupMgrGroupData::cancelRoleChanges()
 
 LLGroupMgr::LLGroupMgr()
 {
+	mLastGroupMembersRequestFrame = 0;
 }
 
 LLGroupMgr::~LLGroupMgr()
@@ -1501,9 +1503,6 @@ void LLGroupMgr::sendGroupMembersRequest(const LLUUID& group_id)
 }
 
 
-
-
-
 void LLGroupMgr::sendGroupRoleDataRequest(const LLUUID& group_id)
 {
 	lldebugs << "LLGroupMgr::sendGroupRoleDataRequest" << llendl;
@@ -1839,7 +1838,7 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
 
 //////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////// 
-// STUBBED IN FOR code completion
+// I DON'T KNOW WHERE TO PUT THIS
 class GroupMemberDataResponder : public LLHTTPClient::Responder
 {
 public:
@@ -1853,26 +1852,18 @@ private:
 
 void GroupMemberDataResponder::result(const LLSD& content)
 {
-	LL_INFOS("BAKER") << "BAKER TAG ////////////////////////////////////////////////////////////////" << LL_ENDL;
-	LL_INFOS("BAKER") << "Got data from responder" << LL_ENDL;
 	LLGroupMgr::processCapGroupMembersRequest(content);
-	LL_INFOS("BAKER") << "//////////////////////////////////////////////////////////////////////////\n" << LL_ENDL;
-
 }
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
 //////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////// 
-// BAKER
+
+
 // static
 void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 {
-	//sendGroupMembersRequest(group_id);
-	//return;
-
-#if 1
+	// Have we requested the information already this frame?
+	if(mLastGroupMembersRequestFrame == gFrameCount)
+		return;
 	
 	LLViewerRegion* currentRegion = gAgent.getRegion();
 
@@ -1895,24 +1886,20 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 	 // This could take a while to finish, timeout after 10 minutes.
 	LLHTTPClient::post(cap_url, body, grp_data_responder, LLSD(), 600);
 
-#endif
+	mLastGroupMembersRequestFrame = gFrameCount;
 }
 
 
 // static
 void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 {
-	LL_INFOS("BAKER") << "BAKER TAG ////////////////////////////////////////////////////////////////" << LL_ENDL;
 	// Did we get anything in content?
 	if(!content.size())
 	{
-		LL_INFOS("BAKER") << "WE AIN'T FOUND SHIT!" << LL_ENDL;
 		// BAKER TODO:
-		// Handle this case
+		// Maybe display a popup saying something went wrong?
 	}
 
-	LL_INFOS("BAKER") << "Lik dis if u cry evertim" << LL_ENDL;
-
 	// If we have no members, there's no reason to do anything else
 	S32	num_members	= content["member_count"];
 	if(num_members < 1)
@@ -1979,6 +1966,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 		if(member_info.has("donated_square_meters"))
 			contribution = member_info["donated_square_meters"];
 
+		// Owner Flag
 		if(member_info.has("owner"))
 			is_owner = true;
 
@@ -1992,18 +1980,28 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 		group_datap->mMembers[member_id] = data;
 	}
 
+	// Technically, we have this data, but to prevent completely overhauling
+	// this entire system (it would be nice, but I don't have the time), 
+	// I'm going to be dumb and just call services I most likely don't need 
+	// with the thought being that the system might need it to be done.
+	if(group_datap->mTitles.size() < 1)
+		LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id);
+
+
 	group_datap->mMemberDataComplete = TRUE;
-	group_datap->mRoleMemberDataComplete = TRUE;
 	group_datap->mMemberRequestID.setNull();
+	// Make the role-member data request
+	if (group_datap->mPendingRoleMemberRequest)
+	{
+		group_datap->mPendingRoleMemberRequest = FALSE;
+		LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id);
+	}
+
 	group_datap->mChanged = TRUE;
 	LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA);
 
-	LL_INFOS("BAKER") << "//////////////////////////////////////////////////////////////////////////\n" << LL_ENDL;
 }
 
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
 
 void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id)
 {
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index b0c3cd025d..62b2978f21 100644
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -341,7 +341,6 @@ public:
 									  uuid_vec_t& member_ids);
 
 	// BAKER
-	//static void sendCapGroupMembersRequest(const LLUUID& group_id);
 	void sendCapGroupMembersRequest(const LLUUID& group_id);
 	static void processCapGroupMembersRequest(const LLSD& content);
 
@@ -380,6 +379,8 @@ private:
 	typedef std::set<LLParticularGroupObserver*> observer_set_t;
 	typedef std::map<LLUUID,observer_set_t> observer_map_t;
 	observer_map_t mParticularObservers;
+
+	S32 mLastGroupMembersRequestFrame;
 };
 
 
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index fa5f5574dc..5b1c15ca45 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -317,10 +317,6 @@ void LLPanelGroupGeneral::activate()
 		
 		if (!gdatap || !gdatap->isMemberDataComplete() )
 		{
-			//////////////////////////////////////////////////////////////////////////
-			// BAKER TODO:
-			//	Use cap here!
-			//////////////////////////////////////////////////////////////////////////
 			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
 			//LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
 		}
@@ -719,7 +715,7 @@ void LLPanelGroupGeneral::updateMembers()
 	for( ; mMemberProgress != gdatap->mMembers.end() && i<UPDATE_MEMBERS_PER_FRAME; 
 			++mMemberProgress, ++i)
 	{
-		llinfos << "Adding " << mMemberProgress->first << ", " << mMemberProgress->second->getTitle() << llendl;
+		lldebugs << "Adding " << mMemberProgress->first << ", " << mMemberProgress->second->getTitle() << llendl;
 		LLGroupMemberData* member = mMemberProgress->second;
 		if (!member)
 		{
@@ -763,15 +759,15 @@ void LLPanelGroupGeneral::updateMembers()
 	}
 	sAllTime += all_timer.getElapsedTimeF32();
 
-	llinfos << "Updated " << i << " of " << UPDATE_MEMBERS_PER_FRAME << "members in the list." << llendl;
+	lldebugs << "Updated " << i << " of " << UPDATE_MEMBERS_PER_FRAME << "members in the list." << llendl;
 	if (mMemberProgress == gdatap->mMembers.end())
 	{
-		llinfos << "   member list completed." << llendl;
+		lldebugs << "   member list completed." << llendl;
 		mListVisibleMembers->setEnabled(TRUE);
 
-		llinfos << "All Time: " << sAllTime << llendl;
-		llinfos << "SD Time: " << sSDTime << llendl;
-		llinfos << "Element Time: " << sElementTime << llendl;
+		lldebugs << "All Time: " << sAllTime << llendl;
+		lldebugs << "SD Time: " << sSDTime << llendl;
+		lldebugs << "Element Time: " << sElementTime << llendl;
 	}
 	else
 	{
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index f05358bf59..f1ba84ec36 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -571,10 +571,6 @@ void LLPanelGroupInvite::updateLists()
 		{
 			LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID);
 			
-			//////////////////////////////////////////////////////////////////////////
-			// BAKER TODO:
-			//	Use cap here!
-			//////////////////////////////////////////////////////////////////////////
 			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
 			//LLGroupMgr::getInstance()->sendGroupMembersRequest(mImplementation->mGroupID);
 
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 9b0fb37693..0e40224346 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -356,10 +356,6 @@ void LLPanelGroupRoles::activate()
 		
 		if (!gdatap || !gdatap->isMemberDataComplete() )
 		{
-			//////////////////////////////////////////////////////////////////////////
-			// BAKER TODO:
-			//	Use cap here!
-			//////////////////////////////////////////////////////////////////////////
 			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
 			//LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
 		}
@@ -1992,10 +1988,6 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
 
 	if (!gdatap || !gdatap->isMemberDataComplete())
 	{
-		//////////////////////////////////////////////////////////////////////////
-		// BAKER TODO:
-		//	Use cap here!
-		//////////////////////////////////////////////////////////////////////////
 		LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
 		//LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
 	}
@@ -2590,10 +2582,6 @@ void LLPanelGroupActionsSubTab::handleActionSelect()
 	}
 	else
 	{
-		//////////////////////////////////////////////////////////////////////////
-		// BAKER TODO:
-		//	Use cap here!
-		//////////////////////////////////////////////////////////////////////////
 		LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
 		//LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
 	}
-- 
cgit v1.2.3


From 5dfbc62c1bbab145b1f1b826833c0e485fc73250 Mon Sep 17 00:00:00 2001
From: Chris Baker <baker@lindenlab.com>
Date: Tue, 4 Sep 2012 10:54:16 -0700
Subject: Cleaned up comments

---
 indra/newview/llgroupmgr.cpp | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index b9bcedda13..7a738bd9ea 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -1836,9 +1836,7 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
 }
 
 
-//////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////// 
-// I DON'T KNOW WHERE TO PUT THIS
+// Responder class for capability group management
 class GroupMemberDataResponder : public LLHTTPClient::Responder
 {
 public:
@@ -1854,8 +1852,6 @@ void GroupMemberDataResponder::result(const LLSD& content)
 {
 	LLGroupMgr::processCapGroupMembersRequest(content);
 }
-//////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////// 
 
 
 // static
@@ -1870,8 +1866,8 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 	// Check to make sure we have our capabilities
 	if(!currentRegion->capabilitiesReceived())
 	{
-		LL_INFOS("BAKER") << " Capabilities not received! -- OSHITSON --" << LL_ENDL;
-		// BAKER TODO: Handle this!
+		LL_INFOS("BAKER") << " Capabilities not received!" << LL_ENDL;
+		return;
 	}
 
 	// Get our capability
@@ -1880,10 +1876,10 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 	// Post to our service.  Add a body containing the group_id.
 	LLSD body = LLSD::emptyMap();
 	body["group_id"]	= group_id;
-	// Session id?
 
 	LLHTTPClient::ResponderPtr grp_data_responder = new GroupMemberDataResponder();
-	 // This could take a while to finish, timeout after 10 minutes.
+	
+	// This could take a while to finish, timeout after 10 minutes.
 	LLHTTPClient::post(cap_url, body, grp_data_responder, LLSD(), 600);
 
 	mLastGroupMembersRequestFrame = gFrameCount;
@@ -1896,8 +1892,8 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 	// Did we get anything in content?
 	if(!content.size())
 	{
-		// BAKER TODO:
-		// Maybe display a popup saying something went wrong?
+		LL_DEBUGS("GrpMgr") << "No group member data received." << LL_ENDL;
+		return;
 	}
 
 	// If we have no members, there's no reason to do anything else
@@ -1943,8 +1939,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 
 		const LLUUID member_id(member_iter_start->first);
 		LLSD member_info = member_iter_start->second;
-
-		// Online Status
+		
 		if(member_info.has("last_login"))
 		{
 			online_status = member_info["last_login"];
@@ -1954,19 +1949,15 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 				formatDateString(online_status);
 		}
 
-		// Title
 		if(member_info.has("title"))
 			title = titles[member_info["title"].asInteger()];
 
-		// Powers
 		if(member_info.has("powers"))
 			member_powers = llstrtou64(member_info["powers"].asString().c_str(), NULL, 16);
 
-		// Land Contribution
 		if(member_info.has("donated_square_meters"))
 			contribution = member_info["donated_square_meters"];
 
-		// Owner Flag
 		if(member_info.has("owner"))
 			is_owner = true;
 
-- 
cgit v1.2.3


From e459024c8283a26a1aefce0db65e0d7dd2c7e16d Mon Sep 17 00:00:00 2001
From: Baker Linden <baker@lindenlab.com>
Date: Wed, 5 Sep 2012 15:55:34 -0700
Subject: [MAINT-513] Large group management - Reduced the timeout to 5
 minutes, down from 10 minutes. - Provided output for GroupMemberResponder
 error - Removed commented calls to sendGroupMembersRequest - Reordered calls
 to sendCapGroupMembersRequest so it's called last

---
 indra/newview/llgroupmgr.cpp          | 16 ++++++++++++----
 indra/newview/llpanelgroupgeneral.cpp |  2 --
 indra/newview/llpanelgroupinvite.cpp  |  5 +----
 indra/newview/llpanelgrouproles.cpp   |  3 ---
 4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 7a738bd9ea..3fed8bb9b0 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -1843,11 +1843,16 @@ public:
 		GroupMemberDataResponder() {}
 		virtual ~GroupMemberDataResponder() {}
 		virtual void result(const LLSD& pContent);
-		virtual void error(U32 pStatus, const std::string& pReason) {}
+		virtual void error(U32 pStatus, const std::string& pReason);
 private:
 		LLSD mMemberData;
 };
 
+void GroupMemberDataResponder::error(U32 pStatus, const std::string& pReason)
+{
+	LL_WARNS("GrpMgr") << "Error receiving group member data." << LL_ENDL;
+}
+
 void GroupMemberDataResponder::result(const LLSD& content)
 {
 	LLGroupMgr::processCapGroupMembersRequest(content);
@@ -1866,7 +1871,7 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 	// Check to make sure we have our capabilities
 	if(!currentRegion->capabilitiesReceived())
 	{
-		LL_INFOS("BAKER") << " Capabilities not received!" << LL_ENDL;
+		LL_WARNS("GrpMgr") << " Capabilities not received!" << LL_ENDL;
 		return;
 	}
 
@@ -1879,8 +1884,8 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 
 	LLHTTPClient::ResponderPtr grp_data_responder = new GroupMemberDataResponder();
 	
-	// This could take a while to finish, timeout after 10 minutes.
-	LLHTTPClient::post(cap_url, body, grp_data_responder, LLSD(), 600);
+	// This could take a while to finish, timeout after 5 minutes.
+	LLHTTPClient::post(cap_url, body, grp_data_responder, LLSD(), 300);
 
 	mLastGroupMembersRequestFrame = gFrameCount;
 }
@@ -1975,6 +1980,9 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 	// this entire system (it would be nice, but I don't have the time), 
 	// I'm going to be dumb and just call services I most likely don't need 
 	// with the thought being that the system might need it to be done.
+	// 
+	// TODO:
+	// Refactor to reduce multiple calls for data we already have.
 	if(group_datap->mTitles.size() < 1)
 		LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id);
 
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 5b1c15ca45..f6ce7de47e 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -313,12 +313,10 @@ void LLPanelGroupGeneral::activate()
 	{
 		LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID);
 		LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID);
-
 		
 		if (!gdatap || !gdatap->isMemberDataComplete() )
 		{
 			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
-			//LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
 		}
 
 		mFirstUse = FALSE;
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index f1ba84ec36..1ed8d8cf03 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -570,11 +570,8 @@ void LLPanelGroupInvite::updateLists()
 		if (!mPendingUpdate) 
 		{
 			LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID);
-			
-			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
-			//LLGroupMgr::getInstance()->sendGroupMembersRequest(mImplementation->mGroupID);
-
 			LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID);
+			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID);
 		}
 		mPendingUpdate = TRUE;
 	} 
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 0e40224346..bbe47ae943 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -357,7 +357,6 @@ void LLPanelGroupRoles::activate()
 		if (!gdatap || !gdatap->isMemberDataComplete() )
 		{
 			LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
-			//LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
 		}
 
 		// Check role data.
@@ -1989,7 +1988,6 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
 	if (!gdatap || !gdatap->isMemberDataComplete())
 	{
 		LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
-		//LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
 	}
 	
 	if (!gdatap || !gdatap->isRoleMemberDataComplete())
@@ -2583,7 +2581,6 @@ void LLPanelGroupActionsSubTab::handleActionSelect()
 	else
 	{
 		LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
-		//LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
 	}
 
 	if (gdatap->isRoleDataComplete())
-- 
cgit v1.2.3


From c30ecf2ebd6ff6b6b4def9da25aea2b4c975328d Mon Sep 17 00:00:00 2001
From: Baker Linden <baker@lindenlab.com>
Date: Thu, 6 Sep 2012 15:19:05 -0700
Subject: Added explicit casting for Linux build, hopefully making it work.

---
 indra/newview/llgroupmgr.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 3fed8bb9b0..9841eda625 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -1937,7 +1937,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 	{
 		// Reset defaults
 		online_status	= "unknown";
-		title			= titles[0];
+		title			= (std::string)titles[0];
 		contribution	= 0;
 		member_powers	= default_powers;
 		is_owner		= false;
@@ -1947,7 +1947,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 		
 		if(member_info.has("last_login"))
 		{
-			online_status = member_info["last_login"];
+			online_status = (std::string)member_info["last_login"];
 			if(online_status == "Online")
 				online_status = LLTrans::getString("group_member_status_online");
 			else
@@ -1955,7 +1955,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 		}
 
 		if(member_info.has("title"))
-			title = titles[member_info["title"].asInteger()];
+			title = (std::string)titles[member_info["title"].asInteger()];
 
 		if(member_info.has("powers"))
 			member_powers = llstrtou64(member_info["powers"].asString().c_str(), NULL, 16);
-- 
cgit v1.2.3


From 5520bebaeb486462a3482173ccc8518d9158e0d5 Mon Sep 17 00:00:00 2001
From: Baker Linden <baker@lindenlab.com>
Date: Thu, 6 Sep 2012 16:00:59 -0700
Subject: Do the proper fix this time...

---
 indra/newview/llgroupmgr.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 9841eda625..9c0a30e689 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -1937,7 +1937,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 	{
 		// Reset defaults
 		online_status	= "unknown";
-		title			= (std::string)titles[0];
+		title			= titles[0].asString();
 		contribution	= 0;
 		member_powers	= default_powers;
 		is_owner		= false;
@@ -1947,7 +1947,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 		
 		if(member_info.has("last_login"))
 		{
-			online_status = (std::string)member_info["last_login"];
+			online_status = member_info["last_login"].asString();
 			if(online_status == "Online")
 				online_status = LLTrans::getString("group_member_status_online");
 			else
@@ -1955,7 +1955,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
 		}
 
 		if(member_info.has("title"))
-			title = (std::string)titles[member_info["title"].asInteger()];
+			title = titles[member_info["title"].asInteger()].asString();
 
 		if(member_info.has("powers"))
 			member_powers = llstrtou64(member_info["powers"].asString().c_str(), NULL, 16);
-- 
cgit v1.2.3


From 3759a91ba70939c04e12202fe53673f51accab72 Mon Sep 17 00:00:00 2001
From: Baker Linden <baker@lindenlab.com>
Date: Mon, 10 Sep 2012 16:30:45 -0700
Subject: Fixed line endings from DOS to UNIX.

---
 indra/newview/llviewerregion.cpp | 3738 +++++++++++++++++++-------------------
 1 file changed, 1869 insertions(+), 1869 deletions(-)

diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index c00d4e91d7..d825646da0 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1,1869 +1,1869 @@
-/** 
- * @file llviewerregion.cpp
- * @brief Implementation of the LLViewerRegion class.
- *
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llviewerregion.h"
-
-// linden libraries
-#include "indra_constants.h"
-#include "llavatarnamecache.h"		// name lookup cap url
-#include "llfloaterreg.h"
-#include "llmath.h"
-#include "llhttpclient.h"
-#include "llregionflags.h"
-#include "llregionhandle.h"
-#include "llsurface.h"
-#include "message.h"
-//#include "vmath.h"
-#include "v3math.h"
-#include "v4math.h"
-
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llcallingcard.h"
-#include "llcaphttpsender.h"
-#include "llcapabilitylistener.h"
-#include "llcommandhandler.h"
-#include "lldir.h"
-#include "lleventpoll.h"
-#include "llfloatergodtools.h"
-#include "llfloaterreporter.h"
-#include "llfloaterregioninfo.h"
-#include "llhttpnode.h"
-#include "llregioninfomodel.h"
-#include "llsdutil.h"
-#include "llstartup.h"
-#include "lltrans.h"
-#include "llurldispatcher.h"
-#include "llviewerobjectlist.h"
-#include "llviewerparceloverlay.h"
-#include "llviewerstatsrecorder.h"
-#include "llvlmanager.h"
-#include "llvlcomposition.h"
-#include "llvocache.h"
-#include "llworld.h"
-#include "llspatialpartition.h"
-#include "stringize.h"
-#include "llviewercontrol.h"
-#include "llsdserialize.h"
-
-#ifdef LL_WINDOWS
-	#pragma warning(disable:4355)
-#endif
-
-const F32 WATER_TEXTURE_SCALE = 8.f;			//  Number of times to repeat the water texture across a region
-const S16 MAX_MAP_DIST = 10;
-// The server only keeps our pending agent info for 60 seconds.
-// We want to allow for seed cap retry, but its not useful after that 60 seconds.
-// Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up.
-const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3;
-const F32 CAP_REQUEST_TIMEOUT = 18;
-// Even though we gave up on login, keep trying for caps after we are logged in:
-const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
-
-typedef std::map<std::string, std::string> CapabilityMap;
-
-class LLViewerRegionImpl {
-public:
-	LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host)
-		:	mHost(host),
-			mCompositionp(NULL),
-			mEventPoll(NULL),
-			mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
-			mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
-			mSeedCapAttempts(0),
-			mHttpResponderID(0),
-		    // I'd prefer to set the LLCapabilityListener name to match the region
-		    // name -- it's disappointing that's not available at construction time.
-		    // We could instead store an LLCapabilityListener*, making
-		    // setRegionNameAndZone() replace the instance. Would that pose
-		    // consistency problems? Can we even request a capability before calling
-		    // setRegionNameAndZone()?
-		    // For testability -- the new Michael Feathers paradigm --
-		    // LLCapabilityListener binds all the globals it expects to need at
-		    // construction time.
-		    mCapabilityListener(host.getString(), gMessageSystem, *region,
-		                        gAgent.getID(), gAgent.getSessionID())
-	{
-	}
-
-	void buildCapabilityNames(LLSD& capabilityNames);
-
-	// The surfaces and other layers
-	LLSurface*	mLandp;
-
-	// Region geometry data
-	LLVector3d	mOriginGlobal;	// Location of southwest corner of region (meters)
-	LLVector3d	mCenterGlobal;	// Location of center in world space (meters)
-	LLHost		mHost;
-
-	// The unique ID for this region.
-	LLUUID mRegionID;
-
-	// region/estate owner - usually null.
-	LLUUID mOwnerID;
-
-	// Network statistics for the region's circuit...
-	LLTimer mLastNetUpdate;
-
-	// Misc
-	LLVLComposition *mCompositionp;		// Composition layer for the surface
-
-	LLVOCacheEntry::vocache_entry_map_t		mCacheMap;
-	// time?
-	// LRU info?
-
-	// Cache ID is unique per-region, across renames, moving locations,
-	// etc.
-	LLUUID mCacheID;
-
-	CapabilityMap mCapabilities;
-	
-	LLEventPoll* mEventPoll;
-
-	S32 mSeedCapMaxAttempts;
-	S32 mSeedCapMaxAttemptsBeforeLogin;
-	S32 mSeedCapAttempts;
-
-	S32 mHttpResponderID;
-
-	/// Post an event to this LLCapabilityListener to invoke a capability message on
-	/// this LLViewerRegion's server
-	/// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
-	LLCapabilityListener mCapabilityListener;
-
-	//spatial partitions for objects in this region
-	std::vector<LLSpatialPartition*> mObjectPartition;
-};
-
-// support for secondlife:///app/region/{REGION} SLapps
-// N.B. this is defined to work exactly like the classic secondlife://{REGION}
-// However, the later syntax cannot support spaces in the region name because
-// spaces (and %20 chars) are illegal in the hostname of an http URL. Some
-// browsers let you get away with this, but some do not (such as Qt's Webkit).
-// Hence we introduced the newer secondlife:///app/region alternative.
-class LLRegionHandler : public LLCommandHandler
-{
-public:
-	// requests will be throttled from a non-trusted browser
-	LLRegionHandler() : LLCommandHandler("region", UNTRUSTED_THROTTLE) {}
-
-	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
-	{
-		// make sure that we at least have a region name
-		int num_params = params.size();
-		if (num_params < 1)
-		{
-			return false;
-		}
-
-		// build a secondlife://{PLACE} SLurl from this SLapp
-		std::string url = "secondlife://";
-		for (int i = 0; i < num_params; i++)
-		{
-			if (i > 0)
-			{
-				url += "/";
-			}
-			url += params[i].asString();
-		}
-
-		// Process the SLapp as if it was a secondlife://{PLACE} SLurl
-		LLURLDispatcher::dispatch(url, "clicked", web, true);
-		return true;
-	}
-};
-LLRegionHandler gRegionHandler;
-
-class BaseCapabilitiesComplete : public LLHTTPClient::Responder
-{
-	LOG_CLASS(BaseCapabilitiesComplete);
-public:
-    BaseCapabilitiesComplete(U64 region_handle, S32 id)
-		: mRegionHandle(region_handle), mID(id)
-    { }
-	virtual ~BaseCapabilitiesComplete()
-	{ }
-
-    void error(U32 statusNum, const std::string& reason)
-    {
-		LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL;
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if (regionp)
-		{
-			regionp->failedSeedCapability();
-		}
-    }
-
-    void result(const LLSD& content)
-    {
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if(!regionp) //region was removed
-		{
-			LL_WARNS2("AppInit", "Capabilities") << "Received results for region that no longer exists!" << LL_ENDL;
-			return ;
-		}
-		if( mID != regionp->getHttpResponderID() ) // region is no longer referring to this responder
-		{
-			LL_WARNS2("AppInit", "Capabilities") << "Received results for a stale http responder!" << LL_ENDL;
-			return ;
-		}
-
-		LLSD::map_const_iterator iter;
-		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
-		{
-			regionp->setCapability(iter->first, iter->second);
-			LL_DEBUGS2("AppInit", "Capabilities") << "got capability for " 
-				<< iter->first << LL_ENDL;
-
-			/* HACK we're waiting for the ServerReleaseNotes */
-			if (iter->first == "ServerReleaseNotes" && regionp->getReleaseNotesRequested())
-			{
-				regionp->showReleaseNotes();
-			}
-		}
-
-		regionp->setCapabilitiesReceived(true);
-
-		if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
-		{
-			LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
-		}
-	}
-
-    static boost::intrusive_ptr<BaseCapabilitiesComplete> build( U64 region_handle, S32 id )
-    {
-		return boost::intrusive_ptr<BaseCapabilitiesComplete>( 
-				new BaseCapabilitiesComplete(region_handle, id) );
-    }
-
-private:
-	U64 mRegionHandle;
-	S32 mID;
-};
-
-
-LLViewerRegion::LLViewerRegion(const U64 &handle,
-							   const LLHost &host,
-							   const U32 grids_per_region_edge, 
-							   const U32 grids_per_patch_edge, 
-							   const F32 region_width_meters)
-:	mImpl(new LLViewerRegionImpl(this, host)),
-	mHandle(handle),
-	mTimeDilation(1.0f),
-	mName(""),
-	mZoning(""),
-	mIsEstateManager(FALSE),
-	mRegionFlags( REGION_FLAGS_DEFAULT ),
-	mSimAccess( SIM_ACCESS_MIN ),
-	mBillableFactor(1.0),
-	mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT),
-	mClassID(0),
-	mCPURatio(0),
-	mColoName("unknown"),
-	mProductSKU("unknown"),
-	mProductName("unknown"),
-	mHttpUrl(""),
-	mCacheLoaded(FALSE),
-	mCacheDirty(FALSE),
-	mReleaseNotesRequested(FALSE),
-	mCapabilitiesReceived(false)
-{
-	mWidth = region_width_meters;
-	mImpl->mOriginGlobal = from_region_handle(handle); 
-	updateRenderMatrix();
-
-	mImpl->mLandp = new LLSurface('l', NULL);
-
-	// Create the composition layer for the surface
-	mImpl->mCompositionp =
-		new LLVLComposition(mImpl->mLandp,
-							grids_per_region_edge,
-							region_width_meters / grids_per_region_edge);
-	mImpl->mCompositionp->setSurface(mImpl->mLandp);
-
-	// Create the surfaces
-	mImpl->mLandp->setRegion(this);
-	mImpl->mLandp->create(grids_per_region_edge,
-					grids_per_patch_edge,
-					mImpl->mOriginGlobal,
-					mWidth);
-
-	mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters);
-
-	setOriginGlobal(from_region_handle(handle));
-	calculateCenterGlobal();
-
-	// Create the object lists
-	initStats();
-
-	//create object partitions
-	//MUST MATCH declaration of eObjectPartitions
-	mImpl->mObjectPartition.push_back(new LLHUDPartition());		//PARTITION_HUD
-	mImpl->mObjectPartition.push_back(new LLTerrainPartition());	//PARTITION_TERRAIN
-	mImpl->mObjectPartition.push_back(new LLVoidWaterPartition());	//PARTITION_VOIDWATER
-	mImpl->mObjectPartition.push_back(new LLWaterPartition());		//PARTITION_WATER
-	mImpl->mObjectPartition.push_back(new LLTreePartition());		//PARTITION_TREE
-	mImpl->mObjectPartition.push_back(new LLParticlePartition());	//PARTITION_PARTICLE
-	mImpl->mObjectPartition.push_back(new LLGrassPartition());		//PARTITION_GRASS
-	mImpl->mObjectPartition.push_back(new LLVolumePartition());	//PARTITION_VOLUME
-	mImpl->mObjectPartition.push_back(new LLBridgePartition());	//PARTITION_BRIDGE
-	mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE
-	mImpl->mObjectPartition.push_back(NULL);						//PARTITION_NONE
-}
-
-
-void LLViewerRegion::initStats()
-{
-	mImpl->mLastNetUpdate.reset();
-	mPacketsIn = 0;
-	mBitsIn = 0;
-	mLastBitsIn = 0;
-	mLastPacketsIn = 0;
-	mPacketsOut = 0;
-	mLastPacketsOut = 0;
-	mPacketsLost = 0;
-	mLastPacketsLost = 0;
-	mPingDelay = 0;
-	mAlive = false;					// can become false if circuit disconnects
-}
-
-LLViewerRegion::~LLViewerRegion() 
-{
-	gVLManager.cleanupData(this);
-	// Can't do this on destruction, because the neighbor pointers might be invalid.
-	// This should be reference counted...
-	disconnectAllNeighbors();
-	LLViewerPartSim::getInstance()->cleanupRegion(this);
-
-	gObjectList.killObjects(this);
-
-	delete mImpl->mCompositionp;
-	delete mParcelOverlay;
-	delete mImpl->mLandp;
-	delete mImpl->mEventPoll;
-	LLHTTPSender::clearSender(mImpl->mHost);
-	
-	saveObjectCache();
-
-	std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer());
-
-	delete mImpl;
-	mImpl = NULL;
-}
-
-LLEventPump& LLViewerRegion::getCapAPI() const
-{
-	return mImpl->mCapabilityListener.getCapAPI();
-}
-
-/*virtual*/ 
-const LLHost&	LLViewerRegion::getHost() const				
-{ 
-	return mImpl->mHost; 
-}
-
-LLSurface & LLViewerRegion::getLand() const
-{
-	return *mImpl->mLandp;
-}
-
-const LLUUID& LLViewerRegion::getRegionID() const
-{
-	return mImpl->mRegionID;
-}
-
-void LLViewerRegion::setRegionID(const LLUUID& region_id)
-{
-	mImpl->mRegionID = region_id;
-}
-
-void LLViewerRegion::loadObjectCache()
-{
-	if (mCacheLoaded)
-	{
-		return;
-	}
-
-	// Presume success.  If it fails, we don't want to try again.
-	mCacheLoaded = TRUE;
-
-	if(LLVOCache::hasInstance())
-	{
-		LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ;
-	}
-}
-
-
-void LLViewerRegion::saveObjectCache()
-{
-	if (!mCacheLoaded)
-	{
-		return;
-	}
-
-	if (mImpl->mCacheMap.empty())
-	{
-		return;
-	}
-
-	if(LLVOCache::hasInstance())
-	{
-		LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty) ;
-		mCacheDirty = FALSE;
-	}
-
-	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)
-	{
-		delete iter->second;
-	}
-	mImpl->mCacheMap.clear();
-}
-
-void LLViewerRegion::sendMessage()
-{
-	gMessageSystem->sendMessage(mImpl->mHost);
-}
-
-void LLViewerRegion::sendReliableMessage()
-{
-	gMessageSystem->sendReliable(mImpl->mHost);
-}
-
-void LLViewerRegion::setFlags(BOOL b, U32 flags)
-{
-	if (b)
-	{
-		mRegionFlags |=  flags;
-	}
-	else
-	{
-		mRegionFlags &= ~flags;
-	}
-}
-
-void LLViewerRegion::setWaterHeight(F32 water_level)
-{
-	mImpl->mLandp->setWaterHeight(water_level);
-}
-
-F32 LLViewerRegion::getWaterHeight() const
-{
-	return mImpl->mLandp->getWaterHeight();
-}
-
-BOOL LLViewerRegion::isVoiceEnabled() const
-{
-	return (getRegionFlags() & REGION_FLAGS_ALLOW_VOICE);
-}
-
-void LLViewerRegion::setRegionFlags(U32 flags)
-{
-	mRegionFlags = flags;
-}
-
-
-void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global) 
-{ 
-	mImpl->mOriginGlobal = origin_global; 
-	updateRenderMatrix();
-	mImpl->mLandp->setOriginGlobal(origin_global);
-	mWind.setOriginGlobal(origin_global);
-	calculateCenterGlobal();
-}
-
-void LLViewerRegion::updateRenderMatrix()
-{
-	mRenderMatrix.setTranslation(getOriginAgent());
-}
-
-void LLViewerRegion::setTimeDilation(F32 time_dilation)
-{
-	mTimeDilation = time_dilation;
-}
-
-const LLVector3d & LLViewerRegion::getOriginGlobal() const
-{
-	return mImpl->mOriginGlobal;
-}
-
-LLVector3 LLViewerRegion::getOriginAgent() const
-{
-	return gAgent.getPosAgentFromGlobal(mImpl->mOriginGlobal);
-}
-
-const LLVector3d & LLViewerRegion::getCenterGlobal() const
-{
-	return mImpl->mCenterGlobal;
-}
-
-LLVector3 LLViewerRegion::getCenterAgent() const
-{
-	return gAgent.getPosAgentFromGlobal(mImpl->mCenterGlobal);
-}
-
-void LLViewerRegion::setOwner(const LLUUID& owner_id)
-{
-	mImpl->mOwnerID = owner_id;
-}
-
-const LLUUID& LLViewerRegion::getOwner() const
-{
-	return mImpl->mOwnerID;
-}
-
-void LLViewerRegion::setRegionNameAndZone	(const std::string& name_zone)
-{
-	std::string::size_type pipe_pos = name_zone.find('|');
-	S32 length   = name_zone.size();
-	if (pipe_pos != std::string::npos)
-	{
-		mName   = name_zone.substr(0, pipe_pos);
-		mZoning = name_zone.substr(pipe_pos+1, length-(pipe_pos+1));
-	}
-	else
-	{
-		mName   = name_zone;
-		mZoning = "";
-	}
-
-	LLStringUtil::stripNonprintable(mName);
-	LLStringUtil::stripNonprintable(mZoning);
-}
-
-BOOL LLViewerRegion::canManageEstate() const
-{
-	return gAgent.isGodlike()
-		|| isEstateManager()
-		|| gAgent.getID() == getOwner();
-}
-
-const std::string LLViewerRegion::getSimAccessString() const
-{
-	return accessToString(mSimAccess);
-}
-
-std::string LLViewerRegion::getLocalizedSimProductName() const
-{
-	std::string localized_spn;
-	return LLTrans::findString(localized_spn, mProductName) ? localized_spn : mProductName;
-}
-
-// static
-std::string LLViewerRegion::regionFlagsToString(U32 flags)
-{
-	std::string result;
-
-	if (flags & REGION_FLAGS_SANDBOX)
-	{
-		result += "Sandbox";
-	}
-
-	if (flags & REGION_FLAGS_ALLOW_DAMAGE)
-	{
-		result += " Not Safe";
-	}
-
-	return result;
-}
-
-// static
-std::string LLViewerRegion::accessToString(U8 sim_access)
-{
-	switch(sim_access)
-	{
-	case SIM_ACCESS_PG:
-		return LLTrans::getString("SIM_ACCESS_PG");
-
-	case SIM_ACCESS_MATURE:
-		return LLTrans::getString("SIM_ACCESS_MATURE");
-
-	case SIM_ACCESS_ADULT:
-		return LLTrans::getString("SIM_ACCESS_ADULT");
-
-	case SIM_ACCESS_DOWN:
-		return LLTrans::getString("SIM_ACCESS_DOWN");
-
-	case SIM_ACCESS_MIN:
-	default:
-		return LLTrans::getString("SIM_ACCESS_MIN");
-	}
-}
-
-// static
-std::string LLViewerRegion::getAccessIcon(U8 sim_access)
-{
-	switch(sim_access)
-	{
-	case SIM_ACCESS_MATURE:
-		return "Parcel_M_Dark";
-
-	case SIM_ACCESS_ADULT:
-		return "Parcel_R_Light";
-
-	case SIM_ACCESS_PG:
-		return "Parcel_PG_Light";
-
-	case SIM_ACCESS_MIN:
-	default:
-		return "";
-	}
-}
-
-// static
-std::string LLViewerRegion::accessToShortString(U8 sim_access)
-{
-	switch(sim_access)		/* Flawfinder: ignore */
-	{
-	case SIM_ACCESS_PG:
-		return "PG";
-
-	case SIM_ACCESS_MATURE:
-		return "M";
-
-	case SIM_ACCESS_ADULT:
-		return "A";
-
-	case SIM_ACCESS_MIN:
-	default:
-		return "U";
-	}
-}
-
-// 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**)
-{
-	// send it to 'observers'
-	// *TODO: switch the floaters to using LLRegionInfoModel
-	llinfos << "Processing region info" << llendl;
-	LLRegionInfoModel::instance().update(msg);
-	LLFloaterGodTools::processRegionInfo(msg);
-	LLFloaterRegionInfo::processRegionInfo(msg);
-	LLFloaterReporter::processRegionInfo(msg);
-}
-
-void LLViewerRegion::setCacheID(const LLUUID& id)
-{
-	mImpl->mCacheID = id;
-}
-
-S32 LLViewerRegion::renderPropertyLines()
-{
-	if (mParcelOverlay)
-	{
-		return mParcelOverlay->renderPropertyLines();
-	}
-	else
-	{
-		return 0;
-	}
-}
-
-// This gets called when the height field changes.
-void LLViewerRegion::dirtyHeights()
-{
-	// Property lines need to be reconstructed when the land changes.
-	if (mParcelOverlay)
-	{
-		mParcelOverlay->setDirty();
-	}
-}
-
-BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
-{
-	LLMemType mt_ivr(LLMemType::MTYPE_IDLE_UPDATE_VIEWER_REGION);
-	// did_update returns TRUE if we did at least one significant update
-	BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time);
-	
-	if (mParcelOverlay)
-	{
-		// Hopefully not a significant time sink...
-		mParcelOverlay->idleUpdate();
-	}
-
-	return did_update;
-}
-
-
-// As above, but forcibly do the update.
-void LLViewerRegion::forceUpdate()
-{
-	mImpl->mLandp->idleUpdate(0.f);
-
-	if (mParcelOverlay)
-	{
-		mParcelOverlay->idleUpdate(true);
-	}
-}
-
-void LLViewerRegion::connectNeighbor(LLViewerRegion *neighborp, U32 direction)
-{
-	mImpl->mLandp->connectNeighbor(neighborp->mImpl->mLandp, direction);
-}
-
-
-void LLViewerRegion::disconnectAllNeighbors()
-{
-	mImpl->mLandp->disconnectAllNeighbors();
-}
-
-LLVLComposition * LLViewerRegion::getComposition() const
-{
-	return mImpl->mCompositionp;
-}
-
-F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
-{
-	if (x >= 256)
-	{
-		if (y >= 256)
-		{
-			LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 256.f, 0.f);
-			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
-			if (regionp)
-			{
-				// OK, we need to do some hackery here - different simulators no longer use
-				// the same composition values, necessarily.
-				// If we're attempting to blend, then we want to make the fractional part of
-				// this region match the fractional of the adjacent.  For now, just minimize
-				// the delta.
-				F32 our_comp = getComposition()->getValueScaled(255, 255);
-				F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, y - 256.f);
-				while (llabs(our_comp - adj_comp) >= 1.f)
-				{
-					if (our_comp > adj_comp)
-					{
-						adj_comp += 1.f;
-					}
-					else
-					{
-						adj_comp -= 1.f;
-					}
-				}
-				return adj_comp;
-			}
-		}
-		else
-		{
-			LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 0, 0.f);
-			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
-			if (regionp)
-			{
-				// OK, we need to do some hackery here - different simulators no longer use
-				// the same composition values, necessarily.
-				// If we're attempting to blend, then we want to make the fractional part of
-				// this region match the fractional of the adjacent.  For now, just minimize
-				// the delta.
-				F32 our_comp = getComposition()->getValueScaled(255.f, (F32)y);
-				F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, (F32)y);
-				while (llabs(our_comp - adj_comp) >= 1.f)
-				{
-					if (our_comp > adj_comp)
-					{
-						adj_comp += 1.f;
-					}
-					else
-					{
-						adj_comp -= 1.f;
-					}
-				}
-				return adj_comp;
-			}
-		}
-	}
-	else if (y >= 256)
-	{
-		LLVector3d center = getCenterGlobal() + LLVector3d(0.f, 256.f, 0.f);
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
-		if (regionp)
-		{
-			// OK, we need to do some hackery here - different simulators no longer use
-			// the same composition values, necessarily.
-			// If we're attempting to blend, then we want to make the fractional part of
-			// this region match the fractional of the adjacent.  For now, just minimize
-			// the delta.
-			F32 our_comp = getComposition()->getValueScaled((F32)x, 255.f);
-			F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - 256.f);
-			while (llabs(our_comp - adj_comp) >= 1.f)
-			{
-				if (our_comp > adj_comp)
-				{
-					adj_comp += 1.f;
-				}
-				else
-				{
-					adj_comp -= 1.f;
-				}
-			}
-			return adj_comp;
-		}
-	}
-
-	return getComposition()->getValueScaled((F32)x, (F32)y);
-}
-
-void LLViewerRegion::calculateCenterGlobal() 
-{
-	mImpl->mCenterGlobal = mImpl->mOriginGlobal;
-	mImpl->mCenterGlobal.mdV[VX] += 0.5 * mWidth;
-	mImpl->mCenterGlobal.mdV[VY] += 0.5 * mWidth;
-	mImpl->mCenterGlobal.mdV[VZ] = 0.5 * mImpl->mLandp->getMinZ() + mImpl->mLandp->getMaxZ();
-}
-
-void LLViewerRegion::calculateCameraDistance()
-{
-	mCameraDistanceSquared = (F32)(gAgentCamera.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared();
-}
-
-std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region)
-{
-	s << "{ ";
-	s << region.mImpl->mHost;
-	s << " mOriginGlobal = " << region.getOriginGlobal()<< "\n";
-    std::string name(region.getName()), zone(region.getZoning());
-    if (! name.empty())
-    {
-        s << " mName         = " << name << '\n';
-    }
-    if (! zone.empty())
-    {
-        s << " mZoning       = " << zone << '\n';
-    }
-	s << "}";
-	return s;
-}
-
-
-// ---------------- Protected Member Functions ----------------
-
-void LLViewerRegion::updateNetStats()
-{
-	F32 dt = mImpl->mLastNetUpdate.getElapsedTimeAndResetF32();
-
-	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);
-	if (!cdp)
-	{
-		mAlive = false;
-		return;
-	}
-
-	mAlive = true;
-	mDeltaTime = dt;
-
-	mLastPacketsIn =	mPacketsIn;
-	mLastBitsIn =		mBitsIn;
-	mLastPacketsOut =	mPacketsOut;
-	mLastPacketsLost =	mPacketsLost;
-
-	mPacketsIn =				cdp->getPacketsIn();
-	mBitsIn =					8 * cdp->getBytesIn();
-	mPacketsOut =				cdp->getPacketsOut();
-	mPacketsLost =				cdp->getPacketsLost();
-	mPingDelay =				cdp->getPingDelay();
-
-	mBitStat.addValue(mBitsIn - mLastBitsIn);
-	mPacketsStat.addValue(mPacketsIn - mLastPacketsIn);
-	mPacketsLostStat.addValue(mPacketsLost);
-}
-
-
-U32 LLViewerRegion::getPacketsLost() const
-{
-	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);
-	if (!cdp)
-	{
-		llinfos << "LLViewerRegion::getPacketsLost couldn't find circuit for " << mImpl->mHost << llendl;
-		return 0;
-	}
-	else
-	{
-		return cdp->getPacketsLost();
-	}
-}
-
-S32 LLViewerRegion::getHttpResponderID() const
-{
-	return mImpl->mHttpResponderID;
-}
-
-BOOL LLViewerRegion::pointInRegionGlobal(const LLVector3d &point_global) const
-{
-	LLVector3 pos_region = getPosRegionFromGlobal(point_global);
-
-	if (pos_region.mV[VX] < 0)
-	{
-		return FALSE;
-	}
-	if (pos_region.mV[VX] >= mWidth)
-	{
-		return FALSE;
-	}
-	if (pos_region.mV[VY] < 0)
-	{
-		return FALSE;
-	}
-	if (pos_region.mV[VY] >= mWidth)
-	{
-		return FALSE;
-	}
-	return TRUE;
-}
-
-LLVector3 LLViewerRegion::getPosRegionFromGlobal(const LLVector3d &point_global) const
-{
-	LLVector3 pos_region;
-	pos_region.setVec(point_global - mImpl->mOriginGlobal);
-	return pos_region;
-}
-
-LLVector3d LLViewerRegion::getPosGlobalFromRegion(const LLVector3 &pos_region) const
-{
-	LLVector3d pos_region_d;
-	pos_region_d.setVec(pos_region);
-	return pos_region_d + mImpl->mOriginGlobal;
-}
-
-LLVector3 LLViewerRegion::getPosAgentFromRegion(const LLVector3 &pos_region) const
-{
-	LLVector3d pos_global = getPosGlobalFromRegion(pos_region);
-
-	return gAgent.getPosAgentFromGlobal(pos_global);
-}
-
-LLVector3 LLViewerRegion::getPosRegionFromAgent(const LLVector3 &pos_agent) const
-{
-	return pos_agent - getOriginAgent();
-}
-
-F32 LLViewerRegion::getLandHeightRegion(const LLVector3& region_pos)
-{
-	return mImpl->mLandp->resolveHeightRegion( region_pos );
-}
-
-bool LLViewerRegion::isAlive()
-{
-	return mAlive;
-}
-
-BOOL LLViewerRegion::isOwnedSelf(const LLVector3& pos)
-{
-	if (mParcelOverlay)
-	{
-		return mParcelOverlay->isOwnedSelf(pos);
-	} else {
-		return FALSE;
-	}
-}
-
-// Owned by a group you belong to?  (officer or member)
-BOOL LLViewerRegion::isOwnedGroup(const LLVector3& pos)
-{
-	if (mParcelOverlay)
-	{
-		return mParcelOverlay->isOwnedGroup(pos);
-	} else {
-		return FALSE;
-	}
-}
-
-// the new TCP coarse location handler node
-class CoarseLocationUpdate : public LLHTTPNode
-{
-public:
-	virtual void post(
-		ResponsePtr responder,
-		const LLSD& context,
-		const LLSD& input) const
-	{
-		LLHost host(input["sender"].asString());
-		LLViewerRegion* region = LLWorld::getInstance()->getRegion(host);
-		if( !region )
-		{
-			return;
-		}
-
-		S32 target_index = input["body"]["Index"][0]["Prey"].asInteger();
-		S32 you_index    = input["body"]["Index"][0]["You" ].asInteger();
-
-		LLDynamicArray<U32>* avatar_locs = &region->mMapAvatars;
-		LLDynamicArray<LLUUID>* avatar_ids = &region->mMapAvatarIDs;
-		avatar_locs->reset();
-		avatar_ids->reset();
-
-		//llinfos << "coarse locations agent[0] " << input["body"]["AgentData"][0]["AgentID"].asUUID() << llendl;
-		//llinfos << "my agent id = " << gAgent.getID() << llendl;
-		//llinfos << ll_pretty_print_sd(input) << llendl;
-
-		LLSD 
-			locs   = input["body"]["Location"],
-			agents = input["body"]["AgentData"];
-		LLSD::array_iterator 
-			locs_it = locs.beginArray(), 
-			agents_it = agents.beginArray();
-		BOOL has_agent_data = input["body"].has("AgentData");
-
-		for(int i=0; 
-			locs_it != locs.endArray(); 
-			i++, locs_it++)
-		{
-			U8 
-				x = locs_it->get("X").asInteger(),
-				y = locs_it->get("Y").asInteger(),
-				z = locs_it->get("Z").asInteger();
-			// treat the target specially for the map, and don't add you or the target
-			if(i == target_index)
-			{
-				LLVector3d global_pos(region->getOriginGlobal());
-				global_pos.mdV[VX] += (F64)x;
-				global_pos.mdV[VY] += (F64)y;
-				global_pos.mdV[VZ] += (F64)z * 4.0;
-				LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
-			}
-			else if( i != you_index)
-			{
-				U32 loc = x << 16 | y << 8 | z; loc = loc;
-				U32 pos = 0x0;
-				pos |= x;
-				pos <<= 8;
-				pos |= y;
-				pos <<= 8;
-				pos |= z;
-				avatar_locs->put(pos);
-				//llinfos << "next pos: " << x << "," << y << "," << z << ": " << pos << llendl;
-				if(has_agent_data) // for backwards compatibility with old message format
-				{
-					LLUUID agent_id(agents_it->get("AgentID").asUUID());
-					//llinfos << "next agent: " << agent_id.asString() << llendl;
-					avatar_ids->put(agent_id);
-				}
-			}
-			if (has_agent_data)
-			{
-				agents_it++;
-			}
-		}
-	}
-};
-
-// build the coarse location HTTP node under the "/message" URL
-LLHTTPRegistration<CoarseLocationUpdate>
-   gHTTPRegistrationCoarseLocationUpdate(
-	   "/message/CoarseLocationUpdate");
-
-
-// the deprecated coarse location handler
-void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg)
-{
-	//llinfos << "CoarseLocationUpdate" << llendl;
-	mMapAvatars.reset();
-	mMapAvatarIDs.reset(); // only matters in a rare case but it's good to be safe.
-
-	U8 x_pos = 0;
-	U8 y_pos = 0;
-	U8 z_pos = 0;
-
-	U32 pos = 0x0;
-
-	S16 agent_index;
-	S16 target_index;
-	msg->getS16Fast(_PREHASH_Index, _PREHASH_You, agent_index);
-	msg->getS16Fast(_PREHASH_Index, _PREHASH_Prey, target_index);
-
-	BOOL has_agent_data = msg->has(_PREHASH_AgentData);
-	S32 count = msg->getNumberOfBlocksFast(_PREHASH_Location);
-	for(S32 i = 0; i < count; i++)
-	{
-		msg->getU8Fast(_PREHASH_Location, _PREHASH_X, x_pos, i);
-		msg->getU8Fast(_PREHASH_Location, _PREHASH_Y, y_pos, i);
-		msg->getU8Fast(_PREHASH_Location, _PREHASH_Z, z_pos, i);
-		LLUUID agent_id = LLUUID::null;
-		if(has_agent_data)
-		{
-			msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id, i);
-		}
-
-		//llinfos << "  object X: " << (S32)x_pos << " Y: " << (S32)y_pos
-		//		<< " Z: " << (S32)(z_pos * 4)
-		//		<< llendl;
-
-		// treat the target specially for the map
-		if(i == target_index)
-		{
-			LLVector3d global_pos(mImpl->mOriginGlobal);
-			global_pos.mdV[VX] += (F64)(x_pos);
-			global_pos.mdV[VY] += (F64)(y_pos);
-			global_pos.mdV[VZ] += (F64)(z_pos) * 4.0;
-			LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
-		}
-		
-		//don't add you
-		if( i != agent_index)
-		{
-			pos = 0x0;
-			pos |= x_pos;
-			pos <<= 8;
-			pos |= y_pos;
-			pos <<= 8;
-			pos |= z_pos;
-			mMapAvatars.put(pos);
-			if(has_agent_data)
-			{
-				mMapAvatarIDs.put(agent_id);
-			}
-		}
-	}
-}
-
-void LLViewerRegion::getInfo(LLSD& info)
-{
-	info["Region"]["Host"] = getHost().getIPandPort();
-	info["Region"]["Name"] = getName();
-	U32 x, y;
-	from_region_handle(getHandle(), &x, &y);
-	info["Region"]["Handle"]["x"] = (LLSD::Integer)x;
-	info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
-}
-
-void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features)
-{
-	sim_features = mSimulatorFeatures;
-
-}
-
-void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
-{
-	std::stringstream str;
-	
-	LLSDSerialize::toPrettyXML(sim_features, str);
-	llinfos << str.str() << llendl;
-	mSimulatorFeatures = sim_features;
-}
-
-LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp)
-{
-	U32 local_id = objectp->getLocalID();
-	U32 crc = objectp->getCRC();
-
-	LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);
-
-	if (entry)
-	{
-		// we've seen this object before
-		if (entry->getCRC() == crc)
-		{
-			// Record a hit
-			entry->recordDupe();
-			return CACHE_UPDATE_DUPE;
-		}
-
-		// Update the cache entry
-		mImpl->mCacheMap.erase(local_id);
-		delete entry;
-		entry = new LLVOCacheEntry(local_id, crc, dp);
-		mImpl->mCacheMap[local_id] = entry;
-		return CACHE_UPDATE_CHANGED;
-	}
-
-	// we haven't seen this object before
-
-	// Create new entry and add to map
-	eCacheUpdateResult result = CACHE_UPDATE_ADDED;
-	if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES)
-	{
-		delete mImpl->mCacheMap.begin()->second ;
-		mImpl->mCacheMap.erase(mImpl->mCacheMap.begin());
-		result = CACHE_UPDATE_REPLACED;
-		
-	}
-	entry = new LLVOCacheEntry(local_id, crc, dp);
-
-	mImpl->mCacheMap[local_id] = entry;
-	return result;
-}
-
-// Get data packer for this object, if we have cached data
-// AND the CRC matches. JC
-LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type)
-{
-	//llassert(mCacheLoaded);  This assert failes often, changing to early-out -- davep, 2010/10/18
-
-	LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);
-
-	if (entry)
-	{
-		// we've seen this object before
-		if (entry->getCRC() == crc)
-		{
-			// Record a hit
-			entry->recordHit();
-		cache_miss_type = CACHE_MISS_TYPE_NONE;
-			return entry->getDP(crc);
-		}
-		else
-		{
-			// llinfos << "CRC miss for " << local_id << llendl;
-		cache_miss_type = CACHE_MISS_TYPE_CRC;
-			mCacheMissCRC.put(local_id);
-		}
-	}
-	else
-	{
-		// llinfos << "Cache miss for " << local_id << llendl;
-	cache_miss_type = CACHE_MISS_TYPE_FULL;
-		mCacheMissFull.put(local_id);
-	}
-
-	return NULL;
-}
-
-void LLViewerRegion::addCacheMissFull(const U32 local_id)
-{
-	mCacheMissFull.put(local_id);
-}
-
-void LLViewerRegion::requestCacheMisses()
-{
-	S32 full_count = mCacheMissFull.count();
-	S32 crc_count = mCacheMissCRC.count();
-	if (full_count == 0 && crc_count == 0) return;
-
-	LLMessageSystem* msg = gMessageSystem;
-	BOOL start_new_message = TRUE;
-	S32 blocks = 0;
-	S32 i;
-
-	// Send full cache miss updates.  For these, we KNOW we don't
-	// have a viewer object.
-	for (i = 0; i < full_count; i++)
-	{
-		if (start_new_message)
-		{
-			msg->newMessageFast(_PREHASH_RequestMultipleObjects);
-			msg->nextBlockFast(_PREHASH_AgentData);
-			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			start_new_message = FALSE;
-		}
-
-		msg->nextBlockFast(_PREHASH_ObjectData);
-		msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_FULL);
-		msg->addU32Fast(_PREHASH_ID, mCacheMissFull[i]);
-		blocks++;
-
-		if (blocks >= 255)
-		{
-			sendReliableMessage();
-			start_new_message = TRUE;
-			blocks = 0;
-		}
-	}
-
-	// Send CRC miss updates.  For these, we _might_ have a viewer object,
-	// but probably not.
-	for (i = 0; i < crc_count; i++)
-	{
-		if (start_new_message)
-		{
-			msg->newMessageFast(_PREHASH_RequestMultipleObjects);
-			msg->nextBlockFast(_PREHASH_AgentData);
-			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			start_new_message = FALSE;
-		}
-
-		msg->nextBlockFast(_PREHASH_ObjectData);
-		msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_CRC);
-		msg->addU32Fast(_PREHASH_ID, mCacheMissCRC[i]);
-		blocks++;
-
-		if (blocks >= 255)
-		{
-			sendReliableMessage();
-			start_new_message = TRUE;
-			blocks = 0;
-		}
-	}
-
-	// finish any pending message
-	if (!start_new_message)
-	{
-		sendReliableMessage();
-	}
-	mCacheMissFull.reset();
-	mCacheMissCRC.reset();
-
-	mCacheDirty = TRUE ;
-	// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl;
-	#if LL_RECORD_VIEWER_STATS
-	LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(this);
-	LLViewerStatsRecorder::instance()->recordRequestCacheMissesEvent(full_count + crc_count);
-	LLViewerStatsRecorder::instance()->endObjectUpdateEvents();
-	#endif
-}
-
-void LLViewerRegion::dumpCache()
-{
-	const S32 BINS = 4;
-	S32 hit_bin[BINS];
-	S32 change_bin[BINS];
-
-	S32 i;
-	for (i = 0; i < BINS; ++i)
-	{
-		hit_bin[i] = 0;
-		change_bin[i] = 0;
-	}
-
-	LLVOCacheEntry *entry;
-	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)
-	{
-		entry = iter->second ;
-
-		S32 hits = entry->getHitCount();
-		S32 changes = entry->getCRCChangeCount();
-
-		hits = llclamp(hits, 0, BINS-1);
-		changes = llclamp(changes, 0, BINS-1);
-
-		hit_bin[hits]++;
-		change_bin[changes]++;
-	}
-
-	llinfos << "Count " << mImpl->mCacheMap.size() << llendl;
-	for (i = 0; i < BINS; i++)
-	{
-		llinfos << "Hits " << i << " " << hit_bin[i] << llendl;
-	}
-	for (i = 0; i < BINS; i++)
-	{
-		llinfos << "Changes " << i << " " << change_bin[i] << llendl;
-	}
-}
-
-void LLViewerRegion::unpackRegionHandshake()
-{
-	LLMessageSystem *msg = gMessageSystem;
-
-	U32 region_flags;
-	U8 sim_access;
-	std::string sim_name;
-	LLUUID sim_owner;
-	BOOL is_estate_manager;
-	F32 water_height;
-	F32 billable_factor;
-	LLUUID cache_id;
-
-	msg->getU32		("RegionInfo", "RegionFlags", region_flags);
-	msg->getU8		("RegionInfo", "SimAccess", sim_access);
-	msg->getString	("RegionInfo", "SimName", sim_name);
-	msg->getUUID	("RegionInfo", "SimOwner", sim_owner);
-	msg->getBOOL	("RegionInfo", "IsEstateManager", is_estate_manager);
-	msg->getF32		("RegionInfo", "WaterHeight", water_height);
-	msg->getF32		("RegionInfo", "BillableFactor", billable_factor);
-	msg->getUUID	("RegionInfo", "CacheID", cache_id );
-
-	setRegionFlags(region_flags);
-	setSimAccess(sim_access);
-	setRegionNameAndZone(sim_name);
-	setOwner(sim_owner);
-	setIsEstateManager(is_estate_manager);
-	setWaterHeight(water_height);
-	setBillableFactor(billable_factor);
-	setCacheID(cache_id);
-
-	LLUUID region_id;
-	msg->getUUID("RegionInfo2", "RegionID", region_id);
-	setRegionID(region_id);
-	
-	// Retrieve the CR-53 (Homestead/Land SKU) information
-	S32 classID = 0;
-	S32 cpuRatio = 0;
-	std::string coloName;
-	std::string productSKU;
-	std::string productName;
-
-	// the only reasonable way to decide if we actually have any data is to
-	// check to see if any of these fields have positive sizes
-	if (msg->getSize("RegionInfo3", "ColoName") > 0 ||
-	    msg->getSize("RegionInfo3", "ProductSKU") > 0 ||
-	    msg->getSize("RegionInfo3", "ProductName") > 0)
-	{
-		msg->getS32     ("RegionInfo3", "CPUClassID",  classID);
-		msg->getS32     ("RegionInfo3", "CPURatio",    cpuRatio);
-		msg->getString  ("RegionInfo3", "ColoName",    coloName);
-		msg->getString  ("RegionInfo3", "ProductSKU",  productSKU);
-		msg->getString  ("RegionInfo3", "ProductName", productName);
-		
-		mClassID = classID;
-		mCPURatio = cpuRatio;
-		mColoName = coloName;
-		mProductSKU = productSKU;
-		mProductName = productName;
-	}
-
-	LLVLComposition *compp = getComposition();
-	if (compp)
-	{
-		LLUUID tmp_id;
-
-		msg->getUUID("RegionInfo", "TerrainDetail0", tmp_id);
-		compp->setDetailTextureID(0, tmp_id);
-		msg->getUUID("RegionInfo", "TerrainDetail1", tmp_id);
-		compp->setDetailTextureID(1, tmp_id);
-		msg->getUUID("RegionInfo", "TerrainDetail2", tmp_id);
-		compp->setDetailTextureID(2, tmp_id);
-		msg->getUUID("RegionInfo", "TerrainDetail3", tmp_id);
-		compp->setDetailTextureID(3, tmp_id);
-
-		F32 tmp_f32;
-		msg->getF32("RegionInfo", "TerrainStartHeight00", tmp_f32);
-		compp->setStartHeight(0, tmp_f32);
-		msg->getF32("RegionInfo", "TerrainStartHeight01", tmp_f32);
-		compp->setStartHeight(1, tmp_f32);
-		msg->getF32("RegionInfo", "TerrainStartHeight10", tmp_f32);
-		compp->setStartHeight(2, tmp_f32);
-		msg->getF32("RegionInfo", "TerrainStartHeight11", tmp_f32);
-		compp->setStartHeight(3, tmp_f32);
-
-		msg->getF32("RegionInfo", "TerrainHeightRange00", tmp_f32);
-		compp->setHeightRange(0, tmp_f32);
-		msg->getF32("RegionInfo", "TerrainHeightRange01", tmp_f32);
-		compp->setHeightRange(1, tmp_f32);
-		msg->getF32("RegionInfo", "TerrainHeightRange10", tmp_f32);
-		compp->setHeightRange(2, tmp_f32);
-		msg->getF32("RegionInfo", "TerrainHeightRange11", tmp_f32);
-		compp->setHeightRange(3, tmp_f32);
-
-		// If this is an UPDATE (params already ready, we need to regenerate
-		// all of our terrain stuff, by
-		if (compp->getParamsReady())
-		{
-			//this line creates frame stalls on region crossing and removing it appears to have no effect
-			//getLand().dirtyAllPatches();
-		}
-		else
-		{
-			compp->setParamsReady();
-		}
-	}
-
-
-	// Now that we have the name, we can load the cache file
-	// off disk.
-	loadObjectCache();
-
-	// After loading cache, signal that simulator can start
-	// sending data.
-	// TODO: Send all upstream viewer->sim handshake info here.
-	LLHost host = msg->getSender();
-	msg->newMessage("RegionHandshakeReply");
-	msg->nextBlock("AgentData");
-	msg->addUUID("AgentID", gAgent.getID());
-	msg->addUUID("SessionID", gAgent.getSessionID());
-	msg->nextBlock("RegionInfo");
-	msg->addU32("Flags", 0x0 );
-	msg->sendReliable(host);
-}
-
-void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
-{
-	capabilityNames.append("AgentState");
-	capabilityNames.append("AttachmentResources");
-	capabilityNames.append("AvatarPickerSearch");
-	capabilityNames.append("CharacterProperties");
-	capabilityNames.append("ChatSessionRequest");
-	capabilityNames.append("CopyInventoryFromNotecard");
-	capabilityNames.append("CreateInventoryCategory");
-	capabilityNames.append("DispatchRegionInfo");
-	capabilityNames.append("EnvironmentSettings");
-	capabilityNames.append("EstateChangeInfo");
-	capabilityNames.append("EventQueueGet");
-
-	if (gSavedSettings.getBOOL("UseHTTPInventory"))
-	{
-		capabilityNames.append("FetchLib2");
-		capabilityNames.append("FetchLibDescendents2");
-		capabilityNames.append("FetchInventory2");
-		capabilityNames.append("FetchInventoryDescendents2");
-	}
-
-	capabilityNames.append("GetDisplayNames");
-	capabilityNames.append("GetMesh");
-	capabilityNames.append("GetObjectCost");
-	capabilityNames.append("GetObjectPhysicsData");
-	capabilityNames.append("GetTexture");
-	capabilityNames.append("GroupMemberData");
-	capabilityNames.append("GroupProposalBallot");
-	capabilityNames.append("HomeLocation");
-	capabilityNames.append("LandResources");
-	capabilityNames.append("MapLayer");
-	capabilityNames.append("MapLayerGod");
-	capabilityNames.append("MeshUploadFlag");	
-	capabilityNames.append("NavMeshGenerationStatus");
-	capabilityNames.append("NewFileAgentInventory");
-	capabilityNames.append("ObjectMedia");
-	capabilityNames.append("ObjectMediaNavigate");
-	capabilityNames.append("ObjectNavMeshProperties");
-	capabilityNames.append("ParcelPropertiesUpdate");
-	capabilityNames.append("ParcelVoiceInfoRequest");
-	capabilityNames.append("ProductInfoRequest");
-	capabilityNames.append("ProvisionVoiceAccountRequest");
-	capabilityNames.append("RemoteParcelRequest");
-	capabilityNames.append("RequestTextureDownload");
-	capabilityNames.append("ResourceCostSelected");
-	capabilityNames.append("RetrieveNavMeshSrc");
-	capabilityNames.append("SearchStatRequest");
-	capabilityNames.append("SearchStatTracking");
-	capabilityNames.append("SendPostcard");
-	capabilityNames.append("SendUserReport");
-	capabilityNames.append("SendUserReportWithScreenshot");
-	capabilityNames.append("ServerReleaseNotes");
-	capabilityNames.append("SetDisplayName");
-	capabilityNames.append("SimConsoleAsync");
-	capabilityNames.append("SimulatorFeatures");
-	capabilityNames.append("StartGroupProposal");
-	capabilityNames.append("TerrainNavMeshProperties");
-	capabilityNames.append("TextureStats");
-	capabilityNames.append("UntrustedSimulatorMessage");
-	capabilityNames.append("UpdateAgentInformation");
-	capabilityNames.append("UpdateAgentLanguage");
-	capabilityNames.append("UpdateGestureAgentInventory");
-	capabilityNames.append("UpdateGestureTaskInventory");
-	capabilityNames.append("UpdateNotecardAgentInventory");
-	capabilityNames.append("UpdateNotecardTaskInventory");
-	capabilityNames.append("UpdateScriptAgent");
-	capabilityNames.append("UpdateScriptTask");
-	capabilityNames.append("UploadBakedTexture");
-	capabilityNames.append("ViewerMetrics");
-	capabilityNames.append("ViewerStartAuction");
-	capabilityNames.append("ViewerStats");
-
-	// Please add new capabilities alphabetically to reduce
-	// merge conflicts.
-}
-
-void LLViewerRegion::setSeedCapability(const std::string& url)
-{
-	if (getCapability("Seed") == url)
-    {
-		// llwarns << "Ignoring duplicate seed capability" << llendl;
-		return;
-    }
-	
-	delete mImpl->mEventPoll;
-	mImpl->mEventPoll = NULL;
-	
-	mImpl->mCapabilities.clear();
-	setCapability("Seed", url);
-
-	LLSD capabilityNames = LLSD::emptyArray();
-	mImpl->buildCapabilityNames(capabilityNames);
-
-	llinfos << "posting to seed " << url << llendl;
-
-	S32 id = ++mImpl->mHttpResponderID;
-	LLHTTPClient::post(url, capabilityNames, 
-						BaseCapabilitiesComplete::build(getHandle(), id),
-						LLSD(), CAP_REQUEST_TIMEOUT);
-}
-
-S32 LLViewerRegion::getNumSeedCapRetries()
-{
-	return mImpl->mSeedCapAttempts;
-}
-
-void LLViewerRegion::failedSeedCapability()
-{
-	// Should we retry asking for caps?
-	mImpl->mSeedCapAttempts++;
-	std::string url = getCapability("Seed");
-	if ( url.empty() )
-	{
-		LL_WARNS2("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url for retries!" << LL_ENDL;
-		return;
-	}
-	// After a few attempts, continue login.  We will keep trying once in-world:
-	if ( mImpl->mSeedCapAttempts >= mImpl->mSeedCapMaxAttemptsBeforeLogin &&
-		 STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState() )
-	{
-		LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
-	}
-
-	if ( mImpl->mSeedCapAttempts < mImpl->mSeedCapMaxAttempts)
-	{
-		LLSD capabilityNames = LLSD::emptyArray();
-		mImpl->buildCapabilityNames(capabilityNames);
-
-		llinfos << "posting to seed " << url << " (retry " 
-				<< mImpl->mSeedCapAttempts << ")" << llendl;
-
-		S32 id = ++mImpl->mHttpResponderID;
-		LLHTTPClient::post(url, capabilityNames, 
-						BaseCapabilitiesComplete::build(getHandle(), id),
-						LLSD(), CAP_REQUEST_TIMEOUT);
-	}
-	else
-	{
-		// *TODO: Give a user pop-up about this error?
-		LL_WARNS2("AppInit", "Capabilities") << "Failed to get seed capabilities from '" << url << "' after " << mImpl->mSeedCapAttempts << " attempts.  Giving up!" << LL_ENDL;
-	}
-}
-
-class SimulatorFeaturesReceived : public LLHTTPClient::Responder
-{
-	LOG_CLASS(SimulatorFeaturesReceived);
-public:
-    SimulatorFeaturesReceived(const std::string& retry_url, U64 region_handle, 
-			S32 attempt = 0, S32 max_attempts = MAX_CAP_REQUEST_ATTEMPTS)
-	: mRetryURL(retry_url), mRegionHandle(region_handle), mAttempt(attempt), mMaxAttempts(max_attempts)
-    { }
-	
-	
-    void error(U32 statusNum, const std::string& reason)
-    {
-		LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL;
-		retry();
-    }
-
-    void result(const LLSD& content)
-    {
-		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
-		if(!regionp) //region is removed or responder is not created.
-		{
-			LL_WARNS2("AppInit", "SimulatorFeatures") << "Received results for region that no longer exists!" << LL_ENDL;
-			return ;
-		}
-		
-		regionp->setSimulatorFeatures(content);
-	}
-
-private:
-	void retry()
-	{
-		if (mAttempt < mMaxAttempts)
-		{
-			mAttempt++;
-			LL_WARNS2("AppInit", "SimulatorFeatures") << "Re-trying '" << mRetryURL << "'.  Retry #" << mAttempt << LL_ENDL;
-			LLHTTPClient::get(mRetryURL, new SimulatorFeaturesReceived(*this), LLSD(), CAP_REQUEST_TIMEOUT);
-		}
-	}
-	
-	std::string mRetryURL;
-	U64 mRegionHandle;
-	S32 mAttempt;
-	S32 mMaxAttempts;
-};
-
-
-void LLViewerRegion::setCapability(const std::string& name, const std::string& url)
-{
-	if(name == "EventQueueGet")
-	{
-		delete mImpl->mEventPoll;
-		mImpl->mEventPoll = NULL;
-		mImpl->mEventPoll = new LLEventPoll(url, getHost());
-	}
-	else if(name == "UntrustedSimulatorMessage")
-	{
-		LLHTTPSender::setSender(mImpl->mHost, new LLCapHTTPSender(url));
-	}
-	else if (name == "SimulatorFeatures")
-	{
-		// kick off a request for simulator features
-		LLHTTPClient::get(url, new SimulatorFeaturesReceived(url, getHandle()), LLSD(), CAP_REQUEST_TIMEOUT);
-	}
-	else
-	{
-		mImpl->mCapabilities[name] = url;
-		if(name == "GetTexture")
-		{
-			mHttpUrl = url ;
-		}
-	}
-}
-
-bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
-{
-	return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
-}
-
-std::string LLViewerRegion::getCapability(const std::string& name) const
-{
-	CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
-	if(iter == mImpl->mCapabilities.end())
-	{
-		return "";
-	}
-
-	return iter->second;
-}
-
-bool LLViewerRegion::capabilitiesReceived() const
-{
-	return mCapabilitiesReceived;
-}
-
-void LLViewerRegion::setCapabilitiesReceived(bool received)
-{
-	mCapabilitiesReceived = received;
-
-	// Tell interested parties that we've received capabilities,
-	// so that they can safely use getCapability().
-	if (received)
-	{
-		mCapabilitiesReceivedSignal(getRegionID());
-
-		// This is a single-shot signal. Forget callbacks to save resources.
-		mCapabilitiesReceivedSignal.disconnect_all_slots();
-	}
-}
-
-boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb)
-{
-	return mCapabilitiesReceivedSignal.connect(cb);
-}
-
-void LLViewerRegion::logActiveCapabilities() const
-{
-	int count = 0;
-	CapabilityMap::const_iterator iter;
-	for (iter = mImpl->mCapabilities.begin(); iter != mImpl->mCapabilities.end(); ++iter, ++count)
-	{
-		if (!iter->second.empty())
-		{
-			llinfos << iter->first << " URL is " << iter->second << llendl;
-		}
-	}
-	llinfos << "Dumped " << count << " entries." << llendl;
-}
-
-LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
-{
-	if (type < mImpl->mObjectPartition.size())
-	{
-		return mImpl->mObjectPartition[type];
-	}
-	return NULL;
-}
-
-// the viewer can not yet distinquish between normal- and estate-owned objects
-// so we collapse these two bits and enable the UI if either are set
-const U32 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT
-											| REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT;
-
-bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const
-{
-	return (mParcelOverlay != NULL)
-		&& (mParcelOverlay->isOwnedSelf(pos)
-			|| mParcelOverlay->isOwnedGroup(pos)
-			|| ((mRegionFlags & ALLOW_RETURN_ENCROACHING_OBJECT)
-				&& mParcelOverlay->encroachesOwned(boxes)) );
-}
-
-bool LLViewerRegion::childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const
-{
-	bool result = false;
-	result = ( mParcelOverlay && mParcelOverlay->encroachesOnUnowned( boxes ) ) ? 1 : 0;
-	return result;
-}
-
-bool LLViewerRegion::objectsCrossParcel(const std::vector<LLBBox>& boxes) const
-{
-	return mParcelOverlay && mParcelOverlay->encroachesOnNearbyParcel(boxes);
-}
-
-void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions )
-{
-	mImpl->mLandp->getNeighboringRegions( uniqueRegions );
-}
-void LLViewerRegion::getNeighboringRegionsStatus( std::vector<S32>& regions )
-{
-	mImpl->mLandp->getNeighboringRegionsStatus( regions );
-}
-void LLViewerRegion::showReleaseNotes()
-{
-	std::string url = this->getCapability("ServerReleaseNotes");
-
-	if (url.empty()) {
-		// HACK haven't received the capability yet, we'll wait until
-		// it arives.
-		mReleaseNotesRequested = TRUE;
-		return;
-	}
-
-	LLWeb::loadURL(url);
-	mReleaseNotesRequested = FALSE;
-}
-
-std::string LLViewerRegion::getDescription() const
-{
-    return stringize(*this);
-}
-
-bool LLViewerRegion::meshUploadEnabled() const
-{
-	return (mSimulatorFeatures.has("MeshUploadEnabled") &&
-		mSimulatorFeatures["MeshUploadEnabled"].asBoolean());
-}
-
-bool LLViewerRegion::meshRezEnabled() const
-{
-	return (mSimulatorFeatures.has("MeshRezEnabled") &&
-				mSimulatorFeatures["MeshRezEnabled"].asBoolean());
-}
-
-bool LLViewerRegion::dynamicPathfindingEnabled() const
-{
-	return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") &&
-			 mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean());
-}
-
+/** 
+ * @file llviewerregion.cpp
+ * @brief Implementation of the LLViewerRegion class.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerregion.h"
+
+// linden libraries
+#include "indra_constants.h"
+#include "llavatarnamecache.h"		// name lookup cap url
+#include "llfloaterreg.h"
+#include "llmath.h"
+#include "llhttpclient.h"
+#include "llregionflags.h"
+#include "llregionhandle.h"
+#include "llsurface.h"
+#include "message.h"
+//#include "vmath.h"
+#include "v3math.h"
+#include "v4math.h"
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llcallingcard.h"
+#include "llcaphttpsender.h"
+#include "llcapabilitylistener.h"
+#include "llcommandhandler.h"
+#include "lldir.h"
+#include "lleventpoll.h"
+#include "llfloatergodtools.h"
+#include "llfloaterreporter.h"
+#include "llfloaterregioninfo.h"
+#include "llhttpnode.h"
+#include "llregioninfomodel.h"
+#include "llsdutil.h"
+#include "llstartup.h"
+#include "lltrans.h"
+#include "llurldispatcher.h"
+#include "llviewerobjectlist.h"
+#include "llviewerparceloverlay.h"
+#include "llviewerstatsrecorder.h"
+#include "llvlmanager.h"
+#include "llvlcomposition.h"
+#include "llvocache.h"
+#include "llworld.h"
+#include "llspatialpartition.h"
+#include "stringize.h"
+#include "llviewercontrol.h"
+#include "llsdserialize.h"
+
+#ifdef LL_WINDOWS
+	#pragma warning(disable:4355)
+#endif
+
+const F32 WATER_TEXTURE_SCALE = 8.f;			//  Number of times to repeat the water texture across a region
+const S16 MAX_MAP_DIST = 10;
+// The server only keeps our pending agent info for 60 seconds.
+// We want to allow for seed cap retry, but its not useful after that 60 seconds.
+// Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up.
+const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3;
+const F32 CAP_REQUEST_TIMEOUT = 18;
+// Even though we gave up on login, keep trying for caps after we are logged in:
+const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
+
+typedef std::map<std::string, std::string> CapabilityMap;
+
+class LLViewerRegionImpl {
+public:
+	LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host)
+		:	mHost(host),
+			mCompositionp(NULL),
+			mEventPoll(NULL),
+			mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
+			mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
+			mSeedCapAttempts(0),
+			mHttpResponderID(0),
+		    // I'd prefer to set the LLCapabilityListener name to match the region
+		    // name -- it's disappointing that's not available at construction time.
+		    // We could instead store an LLCapabilityListener*, making
+		    // setRegionNameAndZone() replace the instance. Would that pose
+		    // consistency problems? Can we even request a capability before calling
+		    // setRegionNameAndZone()?
+		    // For testability -- the new Michael Feathers paradigm --
+		    // LLCapabilityListener binds all the globals it expects to need at
+		    // construction time.
+		    mCapabilityListener(host.getString(), gMessageSystem, *region,
+		                        gAgent.getID(), gAgent.getSessionID())
+	{
+	}
+
+	void buildCapabilityNames(LLSD& capabilityNames);
+
+	// The surfaces and other layers
+	LLSurface*	mLandp;
+
+	// Region geometry data
+	LLVector3d	mOriginGlobal;	// Location of southwest corner of region (meters)
+	LLVector3d	mCenterGlobal;	// Location of center in world space (meters)
+	LLHost		mHost;
+
+	// The unique ID for this region.
+	LLUUID mRegionID;
+
+	// region/estate owner - usually null.
+	LLUUID mOwnerID;
+
+	// Network statistics for the region's circuit...
+	LLTimer mLastNetUpdate;
+
+	// Misc
+	LLVLComposition *mCompositionp;		// Composition layer for the surface
+
+	LLVOCacheEntry::vocache_entry_map_t		mCacheMap;
+	// time?
+	// LRU info?
+
+	// Cache ID is unique per-region, across renames, moving locations,
+	// etc.
+	LLUUID mCacheID;
+
+	CapabilityMap mCapabilities;
+	
+	LLEventPoll* mEventPoll;
+
+	S32 mSeedCapMaxAttempts;
+	S32 mSeedCapMaxAttemptsBeforeLogin;
+	S32 mSeedCapAttempts;
+
+	S32 mHttpResponderID;
+
+	/// Post an event to this LLCapabilityListener to invoke a capability message on
+	/// this LLViewerRegion's server
+	/// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities)
+	LLCapabilityListener mCapabilityListener;
+
+	//spatial partitions for objects in this region
+	std::vector<LLSpatialPartition*> mObjectPartition;
+};
+
+// support for secondlife:///app/region/{REGION} SLapps
+// N.B. this is defined to work exactly like the classic secondlife://{REGION}
+// However, the later syntax cannot support spaces in the region name because
+// spaces (and %20 chars) are illegal in the hostname of an http URL. Some
+// browsers let you get away with this, but some do not (such as Qt's Webkit).
+// Hence we introduced the newer secondlife:///app/region alternative.
+class LLRegionHandler : public LLCommandHandler
+{
+public:
+	// requests will be throttled from a non-trusted browser
+	LLRegionHandler() : LLCommandHandler("region", UNTRUSTED_THROTTLE) {}
+
+	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+	{
+		// make sure that we at least have a region name
+		int num_params = params.size();
+		if (num_params < 1)
+		{
+			return false;
+		}
+
+		// build a secondlife://{PLACE} SLurl from this SLapp
+		std::string url = "secondlife://";
+		for (int i = 0; i < num_params; i++)
+		{
+			if (i > 0)
+			{
+				url += "/";
+			}
+			url += params[i].asString();
+		}
+
+		// Process the SLapp as if it was a secondlife://{PLACE} SLurl
+		LLURLDispatcher::dispatch(url, "clicked", web, true);
+		return true;
+	}
+};
+LLRegionHandler gRegionHandler;
+
+class BaseCapabilitiesComplete : public LLHTTPClient::Responder
+{
+	LOG_CLASS(BaseCapabilitiesComplete);
+public:
+    BaseCapabilitiesComplete(U64 region_handle, S32 id)
+		: mRegionHandle(region_handle), mID(id)
+    { }
+	virtual ~BaseCapabilitiesComplete()
+	{ }
+
+    void error(U32 statusNum, const std::string& reason)
+    {
+		LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL;
+		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+		if (regionp)
+		{
+			regionp->failedSeedCapability();
+		}
+    }
+
+    void result(const LLSD& content)
+    {
+		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+		if(!regionp) //region was removed
+		{
+			LL_WARNS2("AppInit", "Capabilities") << "Received results for region that no longer exists!" << LL_ENDL;
+			return ;
+		}
+		if( mID != regionp->getHttpResponderID() ) // region is no longer referring to this responder
+		{
+			LL_WARNS2("AppInit", "Capabilities") << "Received results for a stale http responder!" << LL_ENDL;
+			return ;
+		}
+
+		LLSD::map_const_iterator iter;
+		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
+		{
+			regionp->setCapability(iter->first, iter->second);
+			LL_DEBUGS2("AppInit", "Capabilities") << "got capability for " 
+				<< iter->first << LL_ENDL;
+
+			/* HACK we're waiting for the ServerReleaseNotes */
+			if (iter->first == "ServerReleaseNotes" && regionp->getReleaseNotesRequested())
+			{
+				regionp->showReleaseNotes();
+			}
+		}
+
+		regionp->setCapabilitiesReceived(true);
+
+		if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
+		{
+			LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
+		}
+	}
+
+    static boost::intrusive_ptr<BaseCapabilitiesComplete> build( U64 region_handle, S32 id )
+    {
+		return boost::intrusive_ptr<BaseCapabilitiesComplete>( 
+				new BaseCapabilitiesComplete(region_handle, id) );
+    }
+
+private:
+	U64 mRegionHandle;
+	S32 mID;
+};
+
+
+LLViewerRegion::LLViewerRegion(const U64 &handle,
+							   const LLHost &host,
+							   const U32 grids_per_region_edge, 
+							   const U32 grids_per_patch_edge, 
+							   const F32 region_width_meters)
+:	mImpl(new LLViewerRegionImpl(this, host)),
+	mHandle(handle),
+	mTimeDilation(1.0f),
+	mName(""),
+	mZoning(""),
+	mIsEstateManager(FALSE),
+	mRegionFlags( REGION_FLAGS_DEFAULT ),
+	mSimAccess( SIM_ACCESS_MIN ),
+	mBillableFactor(1.0),
+	mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT),
+	mClassID(0),
+	mCPURatio(0),
+	mColoName("unknown"),
+	mProductSKU("unknown"),
+	mProductName("unknown"),
+	mHttpUrl(""),
+	mCacheLoaded(FALSE),
+	mCacheDirty(FALSE),
+	mReleaseNotesRequested(FALSE),
+	mCapabilitiesReceived(false)
+{
+	mWidth = region_width_meters;
+	mImpl->mOriginGlobal = from_region_handle(handle); 
+	updateRenderMatrix();
+
+	mImpl->mLandp = new LLSurface('l', NULL);
+
+	// Create the composition layer for the surface
+	mImpl->mCompositionp =
+		new LLVLComposition(mImpl->mLandp,
+							grids_per_region_edge,
+							region_width_meters / grids_per_region_edge);
+	mImpl->mCompositionp->setSurface(mImpl->mLandp);
+
+	// Create the surfaces
+	mImpl->mLandp->setRegion(this);
+	mImpl->mLandp->create(grids_per_region_edge,
+					grids_per_patch_edge,
+					mImpl->mOriginGlobal,
+					mWidth);
+
+	mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters);
+
+	setOriginGlobal(from_region_handle(handle));
+	calculateCenterGlobal();
+
+	// Create the object lists
+	initStats();
+
+	//create object partitions
+	//MUST MATCH declaration of eObjectPartitions
+	mImpl->mObjectPartition.push_back(new LLHUDPartition());		//PARTITION_HUD
+	mImpl->mObjectPartition.push_back(new LLTerrainPartition());	//PARTITION_TERRAIN
+	mImpl->mObjectPartition.push_back(new LLVoidWaterPartition());	//PARTITION_VOIDWATER
+	mImpl->mObjectPartition.push_back(new LLWaterPartition());		//PARTITION_WATER
+	mImpl->mObjectPartition.push_back(new LLTreePartition());		//PARTITION_TREE
+	mImpl->mObjectPartition.push_back(new LLParticlePartition());	//PARTITION_PARTICLE
+	mImpl->mObjectPartition.push_back(new LLGrassPartition());		//PARTITION_GRASS
+	mImpl->mObjectPartition.push_back(new LLVolumePartition());	//PARTITION_VOLUME
+	mImpl->mObjectPartition.push_back(new LLBridgePartition());	//PARTITION_BRIDGE
+	mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE
+	mImpl->mObjectPartition.push_back(NULL);						//PARTITION_NONE
+}
+
+
+void LLViewerRegion::initStats()
+{
+	mImpl->mLastNetUpdate.reset();
+	mPacketsIn = 0;
+	mBitsIn = 0;
+	mLastBitsIn = 0;
+	mLastPacketsIn = 0;
+	mPacketsOut = 0;
+	mLastPacketsOut = 0;
+	mPacketsLost = 0;
+	mLastPacketsLost = 0;
+	mPingDelay = 0;
+	mAlive = false;					// can become false if circuit disconnects
+}
+
+LLViewerRegion::~LLViewerRegion() 
+{
+	gVLManager.cleanupData(this);
+	// Can't do this on destruction, because the neighbor pointers might be invalid.
+	// This should be reference counted...
+	disconnectAllNeighbors();
+	LLViewerPartSim::getInstance()->cleanupRegion(this);
+
+	gObjectList.killObjects(this);
+
+	delete mImpl->mCompositionp;
+	delete mParcelOverlay;
+	delete mImpl->mLandp;
+	delete mImpl->mEventPoll;
+	LLHTTPSender::clearSender(mImpl->mHost);
+	
+	saveObjectCache();
+
+	std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer());
+
+	delete mImpl;
+	mImpl = NULL;
+}
+
+LLEventPump& LLViewerRegion::getCapAPI() const
+{
+	return mImpl->mCapabilityListener.getCapAPI();
+}
+
+/*virtual*/ 
+const LLHost&	LLViewerRegion::getHost() const				
+{ 
+	return mImpl->mHost; 
+}
+
+LLSurface & LLViewerRegion::getLand() const
+{
+	return *mImpl->mLandp;
+}
+
+const LLUUID& LLViewerRegion::getRegionID() const
+{
+	return mImpl->mRegionID;
+}
+
+void LLViewerRegion::setRegionID(const LLUUID& region_id)
+{
+	mImpl->mRegionID = region_id;
+}
+
+void LLViewerRegion::loadObjectCache()
+{
+	if (mCacheLoaded)
+	{
+		return;
+	}
+
+	// Presume success.  If it fails, we don't want to try again.
+	mCacheLoaded = TRUE;
+
+	if(LLVOCache::hasInstance())
+	{
+		LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ;
+	}
+}
+
+
+void LLViewerRegion::saveObjectCache()
+{
+	if (!mCacheLoaded)
+	{
+		return;
+	}
+
+	if (mImpl->mCacheMap.empty())
+	{
+		return;
+	}
+
+	if(LLVOCache::hasInstance())
+	{
+		LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty) ;
+		mCacheDirty = FALSE;
+	}
+
+	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)
+	{
+		delete iter->second;
+	}
+	mImpl->mCacheMap.clear();
+}
+
+void LLViewerRegion::sendMessage()
+{
+	gMessageSystem->sendMessage(mImpl->mHost);
+}
+
+void LLViewerRegion::sendReliableMessage()
+{
+	gMessageSystem->sendReliable(mImpl->mHost);
+}
+
+void LLViewerRegion::setFlags(BOOL b, U32 flags)
+{
+	if (b)
+	{
+		mRegionFlags |=  flags;
+	}
+	else
+	{
+		mRegionFlags &= ~flags;
+	}
+}
+
+void LLViewerRegion::setWaterHeight(F32 water_level)
+{
+	mImpl->mLandp->setWaterHeight(water_level);
+}
+
+F32 LLViewerRegion::getWaterHeight() const
+{
+	return mImpl->mLandp->getWaterHeight();
+}
+
+BOOL LLViewerRegion::isVoiceEnabled() const
+{
+	return (getRegionFlags() & REGION_FLAGS_ALLOW_VOICE);
+}
+
+void LLViewerRegion::setRegionFlags(U32 flags)
+{
+	mRegionFlags = flags;
+}
+
+
+void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global) 
+{ 
+	mImpl->mOriginGlobal = origin_global; 
+	updateRenderMatrix();
+	mImpl->mLandp->setOriginGlobal(origin_global);
+	mWind.setOriginGlobal(origin_global);
+	calculateCenterGlobal();
+}
+
+void LLViewerRegion::updateRenderMatrix()
+{
+	mRenderMatrix.setTranslation(getOriginAgent());
+}
+
+void LLViewerRegion::setTimeDilation(F32 time_dilation)
+{
+	mTimeDilation = time_dilation;
+}
+
+const LLVector3d & LLViewerRegion::getOriginGlobal() const
+{
+	return mImpl->mOriginGlobal;
+}
+
+LLVector3 LLViewerRegion::getOriginAgent() const
+{
+	return gAgent.getPosAgentFromGlobal(mImpl->mOriginGlobal);
+}
+
+const LLVector3d & LLViewerRegion::getCenterGlobal() const
+{
+	return mImpl->mCenterGlobal;
+}
+
+LLVector3 LLViewerRegion::getCenterAgent() const
+{
+	return gAgent.getPosAgentFromGlobal(mImpl->mCenterGlobal);
+}
+
+void LLViewerRegion::setOwner(const LLUUID& owner_id)
+{
+	mImpl->mOwnerID = owner_id;
+}
+
+const LLUUID& LLViewerRegion::getOwner() const
+{
+	return mImpl->mOwnerID;
+}
+
+void LLViewerRegion::setRegionNameAndZone	(const std::string& name_zone)
+{
+	std::string::size_type pipe_pos = name_zone.find('|');
+	S32 length   = name_zone.size();
+	if (pipe_pos != std::string::npos)
+	{
+		mName   = name_zone.substr(0, pipe_pos);
+		mZoning = name_zone.substr(pipe_pos+1, length-(pipe_pos+1));
+	}
+	else
+	{
+		mName   = name_zone;
+		mZoning = "";
+	}
+
+	LLStringUtil::stripNonprintable(mName);
+	LLStringUtil::stripNonprintable(mZoning);
+}
+
+BOOL LLViewerRegion::canManageEstate() const
+{
+	return gAgent.isGodlike()
+		|| isEstateManager()
+		|| gAgent.getID() == getOwner();
+}
+
+const std::string LLViewerRegion::getSimAccessString() const
+{
+	return accessToString(mSimAccess);
+}
+
+std::string LLViewerRegion::getLocalizedSimProductName() const
+{
+	std::string localized_spn;
+	return LLTrans::findString(localized_spn, mProductName) ? localized_spn : mProductName;
+}
+
+// static
+std::string LLViewerRegion::regionFlagsToString(U32 flags)
+{
+	std::string result;
+
+	if (flags & REGION_FLAGS_SANDBOX)
+	{
+		result += "Sandbox";
+	}
+
+	if (flags & REGION_FLAGS_ALLOW_DAMAGE)
+	{
+		result += " Not Safe";
+	}
+
+	return result;
+}
+
+// static
+std::string LLViewerRegion::accessToString(U8 sim_access)
+{
+	switch(sim_access)
+	{
+	case SIM_ACCESS_PG:
+		return LLTrans::getString("SIM_ACCESS_PG");
+
+	case SIM_ACCESS_MATURE:
+		return LLTrans::getString("SIM_ACCESS_MATURE");
+
+	case SIM_ACCESS_ADULT:
+		return LLTrans::getString("SIM_ACCESS_ADULT");
+
+	case SIM_ACCESS_DOWN:
+		return LLTrans::getString("SIM_ACCESS_DOWN");
+
+	case SIM_ACCESS_MIN:
+	default:
+		return LLTrans::getString("SIM_ACCESS_MIN");
+	}
+}
+
+// static
+std::string LLViewerRegion::getAccessIcon(U8 sim_access)
+{
+	switch(sim_access)
+	{
+	case SIM_ACCESS_MATURE:
+		return "Parcel_M_Dark";
+
+	case SIM_ACCESS_ADULT:
+		return "Parcel_R_Light";
+
+	case SIM_ACCESS_PG:
+		return "Parcel_PG_Light";
+
+	case SIM_ACCESS_MIN:
+	default:
+		return "";
+	}
+}
+
+// static
+std::string LLViewerRegion::accessToShortString(U8 sim_access)
+{
+	switch(sim_access)		/* Flawfinder: ignore */
+	{
+	case SIM_ACCESS_PG:
+		return "PG";
+
+	case SIM_ACCESS_MATURE:
+		return "M";
+
+	case SIM_ACCESS_ADULT:
+		return "A";
+
+	case SIM_ACCESS_MIN:
+	default:
+		return "U";
+	}
+}
+
+// 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**)
+{
+	// send it to 'observers'
+	// *TODO: switch the floaters to using LLRegionInfoModel
+	llinfos << "Processing region info" << llendl;
+	LLRegionInfoModel::instance().update(msg);
+	LLFloaterGodTools::processRegionInfo(msg);
+	LLFloaterRegionInfo::processRegionInfo(msg);
+	LLFloaterReporter::processRegionInfo(msg);
+}
+
+void LLViewerRegion::setCacheID(const LLUUID& id)
+{
+	mImpl->mCacheID = id;
+}
+
+S32 LLViewerRegion::renderPropertyLines()
+{
+	if (mParcelOverlay)
+	{
+		return mParcelOverlay->renderPropertyLines();
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+// This gets called when the height field changes.
+void LLViewerRegion::dirtyHeights()
+{
+	// Property lines need to be reconstructed when the land changes.
+	if (mParcelOverlay)
+	{
+		mParcelOverlay->setDirty();
+	}
+}
+
+BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
+{
+	LLMemType mt_ivr(LLMemType::MTYPE_IDLE_UPDATE_VIEWER_REGION);
+	// did_update returns TRUE if we did at least one significant update
+	BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time);
+	
+	if (mParcelOverlay)
+	{
+		// Hopefully not a significant time sink...
+		mParcelOverlay->idleUpdate();
+	}
+
+	return did_update;
+}
+
+
+// As above, but forcibly do the update.
+void LLViewerRegion::forceUpdate()
+{
+	mImpl->mLandp->idleUpdate(0.f);
+
+	if (mParcelOverlay)
+	{
+		mParcelOverlay->idleUpdate(true);
+	}
+}
+
+void LLViewerRegion::connectNeighbor(LLViewerRegion *neighborp, U32 direction)
+{
+	mImpl->mLandp->connectNeighbor(neighborp->mImpl->mLandp, direction);
+}
+
+
+void LLViewerRegion::disconnectAllNeighbors()
+{
+	mImpl->mLandp->disconnectAllNeighbors();
+}
+
+LLVLComposition * LLViewerRegion::getComposition() const
+{
+	return mImpl->mCompositionp;
+}
+
+F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const
+{
+	if (x >= 256)
+	{
+		if (y >= 256)
+		{
+			LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 256.f, 0.f);
+			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
+			if (regionp)
+			{
+				// OK, we need to do some hackery here - different simulators no longer use
+				// the same composition values, necessarily.
+				// If we're attempting to blend, then we want to make the fractional part of
+				// this region match the fractional of the adjacent.  For now, just minimize
+				// the delta.
+				F32 our_comp = getComposition()->getValueScaled(255, 255);
+				F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, y - 256.f);
+				while (llabs(our_comp - adj_comp) >= 1.f)
+				{
+					if (our_comp > adj_comp)
+					{
+						adj_comp += 1.f;
+					}
+					else
+					{
+						adj_comp -= 1.f;
+					}
+				}
+				return adj_comp;
+			}
+		}
+		else
+		{
+			LLVector3d center = getCenterGlobal() + LLVector3d(256.f, 0, 0.f);
+			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
+			if (regionp)
+			{
+				// OK, we need to do some hackery here - different simulators no longer use
+				// the same composition values, necessarily.
+				// If we're attempting to blend, then we want to make the fractional part of
+				// this region match the fractional of the adjacent.  For now, just minimize
+				// the delta.
+				F32 our_comp = getComposition()->getValueScaled(255.f, (F32)y);
+				F32 adj_comp = regionp->getComposition()->getValueScaled(x - 256.f, (F32)y);
+				while (llabs(our_comp - adj_comp) >= 1.f)
+				{
+					if (our_comp > adj_comp)
+					{
+						adj_comp += 1.f;
+					}
+					else
+					{
+						adj_comp -= 1.f;
+					}
+				}
+				return adj_comp;
+			}
+		}
+	}
+	else if (y >= 256)
+	{
+		LLVector3d center = getCenterGlobal() + LLVector3d(0.f, 256.f, 0.f);
+		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(center);
+		if (regionp)
+		{
+			// OK, we need to do some hackery here - different simulators no longer use
+			// the same composition values, necessarily.
+			// If we're attempting to blend, then we want to make the fractional part of
+			// this region match the fractional of the adjacent.  For now, just minimize
+			// the delta.
+			F32 our_comp = getComposition()->getValueScaled((F32)x, 255.f);
+			F32 adj_comp = regionp->getComposition()->getValueScaled((F32)x, y - 256.f);
+			while (llabs(our_comp - adj_comp) >= 1.f)
+			{
+				if (our_comp > adj_comp)
+				{
+					adj_comp += 1.f;
+				}
+				else
+				{
+					adj_comp -= 1.f;
+				}
+			}
+			return adj_comp;
+		}
+	}
+
+	return getComposition()->getValueScaled((F32)x, (F32)y);
+}
+
+void LLViewerRegion::calculateCenterGlobal() 
+{
+	mImpl->mCenterGlobal = mImpl->mOriginGlobal;
+	mImpl->mCenterGlobal.mdV[VX] += 0.5 * mWidth;
+	mImpl->mCenterGlobal.mdV[VY] += 0.5 * mWidth;
+	mImpl->mCenterGlobal.mdV[VZ] = 0.5 * mImpl->mLandp->getMinZ() + mImpl->mLandp->getMaxZ();
+}
+
+void LLViewerRegion::calculateCameraDistance()
+{
+	mCameraDistanceSquared = (F32)(gAgentCamera.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared();
+}
+
+std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region)
+{
+	s << "{ ";
+	s << region.mImpl->mHost;
+	s << " mOriginGlobal = " << region.getOriginGlobal()<< "\n";
+    std::string name(region.getName()), zone(region.getZoning());
+    if (! name.empty())
+    {
+        s << " mName         = " << name << '\n';
+    }
+    if (! zone.empty())
+    {
+        s << " mZoning       = " << zone << '\n';
+    }
+	s << "}";
+	return s;
+}
+
+
+// ---------------- Protected Member Functions ----------------
+
+void LLViewerRegion::updateNetStats()
+{
+	F32 dt = mImpl->mLastNetUpdate.getElapsedTimeAndResetF32();
+
+	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);
+	if (!cdp)
+	{
+		mAlive = false;
+		return;
+	}
+
+	mAlive = true;
+	mDeltaTime = dt;
+
+	mLastPacketsIn =	mPacketsIn;
+	mLastBitsIn =		mBitsIn;
+	mLastPacketsOut =	mPacketsOut;
+	mLastPacketsLost =	mPacketsLost;
+
+	mPacketsIn =				cdp->getPacketsIn();
+	mBitsIn =					8 * cdp->getBytesIn();
+	mPacketsOut =				cdp->getPacketsOut();
+	mPacketsLost =				cdp->getPacketsLost();
+	mPingDelay =				cdp->getPingDelay();
+
+	mBitStat.addValue(mBitsIn - mLastBitsIn);
+	mPacketsStat.addValue(mPacketsIn - mLastPacketsIn);
+	mPacketsLostStat.addValue(mPacketsLost);
+}
+
+
+U32 LLViewerRegion::getPacketsLost() const
+{
+	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);
+	if (!cdp)
+	{
+		llinfos << "LLViewerRegion::getPacketsLost couldn't find circuit for " << mImpl->mHost << llendl;
+		return 0;
+	}
+	else
+	{
+		return cdp->getPacketsLost();
+	}
+}
+
+S32 LLViewerRegion::getHttpResponderID() const
+{
+	return mImpl->mHttpResponderID;
+}
+
+BOOL LLViewerRegion::pointInRegionGlobal(const LLVector3d &point_global) const
+{
+	LLVector3 pos_region = getPosRegionFromGlobal(point_global);
+
+	if (pos_region.mV[VX] < 0)
+	{
+		return FALSE;
+	}
+	if (pos_region.mV[VX] >= mWidth)
+	{
+		return FALSE;
+	}
+	if (pos_region.mV[VY] < 0)
+	{
+		return FALSE;
+	}
+	if (pos_region.mV[VY] >= mWidth)
+	{
+		return FALSE;
+	}
+	return TRUE;
+}
+
+LLVector3 LLViewerRegion::getPosRegionFromGlobal(const LLVector3d &point_global) const
+{
+	LLVector3 pos_region;
+	pos_region.setVec(point_global - mImpl->mOriginGlobal);
+	return pos_region;
+}
+
+LLVector3d LLViewerRegion::getPosGlobalFromRegion(const LLVector3 &pos_region) const
+{
+	LLVector3d pos_region_d;
+	pos_region_d.setVec(pos_region);
+	return pos_region_d + mImpl->mOriginGlobal;
+}
+
+LLVector3 LLViewerRegion::getPosAgentFromRegion(const LLVector3 &pos_region) const
+{
+	LLVector3d pos_global = getPosGlobalFromRegion(pos_region);
+
+	return gAgent.getPosAgentFromGlobal(pos_global);
+}
+
+LLVector3 LLViewerRegion::getPosRegionFromAgent(const LLVector3 &pos_agent) const
+{
+	return pos_agent - getOriginAgent();
+}
+
+F32 LLViewerRegion::getLandHeightRegion(const LLVector3& region_pos)
+{
+	return mImpl->mLandp->resolveHeightRegion( region_pos );
+}
+
+bool LLViewerRegion::isAlive()
+{
+	return mAlive;
+}
+
+BOOL LLViewerRegion::isOwnedSelf(const LLVector3& pos)
+{
+	if (mParcelOverlay)
+	{
+		return mParcelOverlay->isOwnedSelf(pos);
+	} else {
+		return FALSE;
+	}
+}
+
+// Owned by a group you belong to?  (officer or member)
+BOOL LLViewerRegion::isOwnedGroup(const LLVector3& pos)
+{
+	if (mParcelOverlay)
+	{
+		return mParcelOverlay->isOwnedGroup(pos);
+	} else {
+		return FALSE;
+	}
+}
+
+// the new TCP coarse location handler node
+class CoarseLocationUpdate : public LLHTTPNode
+{
+public:
+	virtual void post(
+		ResponsePtr responder,
+		const LLSD& context,
+		const LLSD& input) const
+	{
+		LLHost host(input["sender"].asString());
+		LLViewerRegion* region = LLWorld::getInstance()->getRegion(host);
+		if( !region )
+		{
+			return;
+		}
+
+		S32 target_index = input["body"]["Index"][0]["Prey"].asInteger();
+		S32 you_index    = input["body"]["Index"][0]["You" ].asInteger();
+
+		LLDynamicArray<U32>* avatar_locs = &region->mMapAvatars;
+		LLDynamicArray<LLUUID>* avatar_ids = &region->mMapAvatarIDs;
+		avatar_locs->reset();
+		avatar_ids->reset();
+
+		//llinfos << "coarse locations agent[0] " << input["body"]["AgentData"][0]["AgentID"].asUUID() << llendl;
+		//llinfos << "my agent id = " << gAgent.getID() << llendl;
+		//llinfos << ll_pretty_print_sd(input) << llendl;
+
+		LLSD 
+			locs   = input["body"]["Location"],
+			agents = input["body"]["AgentData"];
+		LLSD::array_iterator 
+			locs_it = locs.beginArray(), 
+			agents_it = agents.beginArray();
+		BOOL has_agent_data = input["body"].has("AgentData");
+
+		for(int i=0; 
+			locs_it != locs.endArray(); 
+			i++, locs_it++)
+		{
+			U8 
+				x = locs_it->get("X").asInteger(),
+				y = locs_it->get("Y").asInteger(),
+				z = locs_it->get("Z").asInteger();
+			// treat the target specially for the map, and don't add you or the target
+			if(i == target_index)
+			{
+				LLVector3d global_pos(region->getOriginGlobal());
+				global_pos.mdV[VX] += (F64)x;
+				global_pos.mdV[VY] += (F64)y;
+				global_pos.mdV[VZ] += (F64)z * 4.0;
+				LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
+			}
+			else if( i != you_index)
+			{
+				U32 loc = x << 16 | y << 8 | z; loc = loc;
+				U32 pos = 0x0;
+				pos |= x;
+				pos <<= 8;
+				pos |= y;
+				pos <<= 8;
+				pos |= z;
+				avatar_locs->put(pos);
+				//llinfos << "next pos: " << x << "," << y << "," << z << ": " << pos << llendl;
+				if(has_agent_data) // for backwards compatibility with old message format
+				{
+					LLUUID agent_id(agents_it->get("AgentID").asUUID());
+					//llinfos << "next agent: " << agent_id.asString() << llendl;
+					avatar_ids->put(agent_id);
+				}
+			}
+			if (has_agent_data)
+			{
+				agents_it++;
+			}
+		}
+	}
+};
+
+// build the coarse location HTTP node under the "/message" URL
+LLHTTPRegistration<CoarseLocationUpdate>
+   gHTTPRegistrationCoarseLocationUpdate(
+	   "/message/CoarseLocationUpdate");
+
+
+// the deprecated coarse location handler
+void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg)
+{
+	//llinfos << "CoarseLocationUpdate" << llendl;
+	mMapAvatars.reset();
+	mMapAvatarIDs.reset(); // only matters in a rare case but it's good to be safe.
+
+	U8 x_pos = 0;
+	U8 y_pos = 0;
+	U8 z_pos = 0;
+
+	U32 pos = 0x0;
+
+	S16 agent_index;
+	S16 target_index;
+	msg->getS16Fast(_PREHASH_Index, _PREHASH_You, agent_index);
+	msg->getS16Fast(_PREHASH_Index, _PREHASH_Prey, target_index);
+
+	BOOL has_agent_data = msg->has(_PREHASH_AgentData);
+	S32 count = msg->getNumberOfBlocksFast(_PREHASH_Location);
+	for(S32 i = 0; i < count; i++)
+	{
+		msg->getU8Fast(_PREHASH_Location, _PREHASH_X, x_pos, i);
+		msg->getU8Fast(_PREHASH_Location, _PREHASH_Y, y_pos, i);
+		msg->getU8Fast(_PREHASH_Location, _PREHASH_Z, z_pos, i);
+		LLUUID agent_id = LLUUID::null;
+		if(has_agent_data)
+		{
+			msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id, i);
+		}
+
+		//llinfos << "  object X: " << (S32)x_pos << " Y: " << (S32)y_pos
+		//		<< " Z: " << (S32)(z_pos * 4)
+		//		<< llendl;
+
+		// treat the target specially for the map
+		if(i == target_index)
+		{
+			LLVector3d global_pos(mImpl->mOriginGlobal);
+			global_pos.mdV[VX] += (F64)(x_pos);
+			global_pos.mdV[VY] += (F64)(y_pos);
+			global_pos.mdV[VZ] += (F64)(z_pos) * 4.0;
+			LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
+		}
+		
+		//don't add you
+		if( i != agent_index)
+		{
+			pos = 0x0;
+			pos |= x_pos;
+			pos <<= 8;
+			pos |= y_pos;
+			pos <<= 8;
+			pos |= z_pos;
+			mMapAvatars.put(pos);
+			if(has_agent_data)
+			{
+				mMapAvatarIDs.put(agent_id);
+			}
+		}
+	}
+}
+
+void LLViewerRegion::getInfo(LLSD& info)
+{
+	info["Region"]["Host"] = getHost().getIPandPort();
+	info["Region"]["Name"] = getName();
+	U32 x, y;
+	from_region_handle(getHandle(), &x, &y);
+	info["Region"]["Handle"]["x"] = (LLSD::Integer)x;
+	info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
+}
+
+void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features)
+{
+	sim_features = mSimulatorFeatures;
+
+}
+
+void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
+{
+	std::stringstream str;
+	
+	LLSDSerialize::toPrettyXML(sim_features, str);
+	llinfos << str.str() << llendl;
+	mSimulatorFeatures = sim_features;
+}
+
+LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp)
+{
+	U32 local_id = objectp->getLocalID();
+	U32 crc = objectp->getCRC();
+
+	LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);
+
+	if (entry)
+	{
+		// we've seen this object before
+		if (entry->getCRC() == crc)
+		{
+			// Record a hit
+			entry->recordDupe();
+			return CACHE_UPDATE_DUPE;
+		}
+
+		// Update the cache entry
+		mImpl->mCacheMap.erase(local_id);
+		delete entry;
+		entry = new LLVOCacheEntry(local_id, crc, dp);
+		mImpl->mCacheMap[local_id] = entry;
+		return CACHE_UPDATE_CHANGED;
+	}
+
+	// we haven't seen this object before
+
+	// Create new entry and add to map
+	eCacheUpdateResult result = CACHE_UPDATE_ADDED;
+	if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES)
+	{
+		delete mImpl->mCacheMap.begin()->second ;
+		mImpl->mCacheMap.erase(mImpl->mCacheMap.begin());
+		result = CACHE_UPDATE_REPLACED;
+		
+	}
+	entry = new LLVOCacheEntry(local_id, crc, dp);
+
+	mImpl->mCacheMap[local_id] = entry;
+	return result;
+}
+
+// Get data packer for this object, if we have cached data
+// AND the CRC matches. JC
+LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type)
+{
+	//llassert(mCacheLoaded);  This assert failes often, changing to early-out -- davep, 2010/10/18
+
+	LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);
+
+	if (entry)
+	{
+		// we've seen this object before
+		if (entry->getCRC() == crc)
+		{
+			// Record a hit
+			entry->recordHit();
+		cache_miss_type = CACHE_MISS_TYPE_NONE;
+			return entry->getDP(crc);
+		}
+		else
+		{
+			// llinfos << "CRC miss for " << local_id << llendl;
+		cache_miss_type = CACHE_MISS_TYPE_CRC;
+			mCacheMissCRC.put(local_id);
+		}
+	}
+	else
+	{
+		// llinfos << "Cache miss for " << local_id << llendl;
+	cache_miss_type = CACHE_MISS_TYPE_FULL;
+		mCacheMissFull.put(local_id);
+	}
+
+	return NULL;
+}
+
+void LLViewerRegion::addCacheMissFull(const U32 local_id)
+{
+	mCacheMissFull.put(local_id);
+}
+
+void LLViewerRegion::requestCacheMisses()
+{
+	S32 full_count = mCacheMissFull.count();
+	S32 crc_count = mCacheMissCRC.count();
+	if (full_count == 0 && crc_count == 0) return;
+
+	LLMessageSystem* msg = gMessageSystem;
+	BOOL start_new_message = TRUE;
+	S32 blocks = 0;
+	S32 i;
+
+	// Send full cache miss updates.  For these, we KNOW we don't
+	// have a viewer object.
+	for (i = 0; i < full_count; i++)
+	{
+		if (start_new_message)
+		{
+			msg->newMessageFast(_PREHASH_RequestMultipleObjects);
+			msg->nextBlockFast(_PREHASH_AgentData);
+			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+			start_new_message = FALSE;
+		}
+
+		msg->nextBlockFast(_PREHASH_ObjectData);
+		msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_FULL);
+		msg->addU32Fast(_PREHASH_ID, mCacheMissFull[i]);
+		blocks++;
+
+		if (blocks >= 255)
+		{
+			sendReliableMessage();
+			start_new_message = TRUE;
+			blocks = 0;
+		}
+	}
+
+	// Send CRC miss updates.  For these, we _might_ have a viewer object,
+	// but probably not.
+	for (i = 0; i < crc_count; i++)
+	{
+		if (start_new_message)
+		{
+			msg->newMessageFast(_PREHASH_RequestMultipleObjects);
+			msg->nextBlockFast(_PREHASH_AgentData);
+			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+			start_new_message = FALSE;
+		}
+
+		msg->nextBlockFast(_PREHASH_ObjectData);
+		msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_CRC);
+		msg->addU32Fast(_PREHASH_ID, mCacheMissCRC[i]);
+		blocks++;
+
+		if (blocks >= 255)
+		{
+			sendReliableMessage();
+			start_new_message = TRUE;
+			blocks = 0;
+		}
+	}
+
+	// finish any pending message
+	if (!start_new_message)
+	{
+		sendReliableMessage();
+	}
+	mCacheMissFull.reset();
+	mCacheMissCRC.reset();
+
+	mCacheDirty = TRUE ;
+	// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl;
+	#if LL_RECORD_VIEWER_STATS
+	LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(this);
+	LLViewerStatsRecorder::instance()->recordRequestCacheMissesEvent(full_count + crc_count);
+	LLViewerStatsRecorder::instance()->endObjectUpdateEvents();
+	#endif
+}
+
+void LLViewerRegion::dumpCache()
+{
+	const S32 BINS = 4;
+	S32 hit_bin[BINS];
+	S32 change_bin[BINS];
+
+	S32 i;
+	for (i = 0; i < BINS; ++i)
+	{
+		hit_bin[i] = 0;
+		change_bin[i] = 0;
+	}
+
+	LLVOCacheEntry *entry;
+	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)
+	{
+		entry = iter->second ;
+
+		S32 hits = entry->getHitCount();
+		S32 changes = entry->getCRCChangeCount();
+
+		hits = llclamp(hits, 0, BINS-1);
+		changes = llclamp(changes, 0, BINS-1);
+
+		hit_bin[hits]++;
+		change_bin[changes]++;
+	}
+
+	llinfos << "Count " << mImpl->mCacheMap.size() << llendl;
+	for (i = 0; i < BINS; i++)
+	{
+		llinfos << "Hits " << i << " " << hit_bin[i] << llendl;
+	}
+	for (i = 0; i < BINS; i++)
+	{
+		llinfos << "Changes " << i << " " << change_bin[i] << llendl;
+	}
+}
+
+void LLViewerRegion::unpackRegionHandshake()
+{
+	LLMessageSystem *msg = gMessageSystem;
+
+	U32 region_flags;
+	U8 sim_access;
+	std::string sim_name;
+	LLUUID sim_owner;
+	BOOL is_estate_manager;
+	F32 water_height;
+	F32 billable_factor;
+	LLUUID cache_id;
+
+	msg->getU32		("RegionInfo", "RegionFlags", region_flags);
+	msg->getU8		("RegionInfo", "SimAccess", sim_access);
+	msg->getString	("RegionInfo", "SimName", sim_name);
+	msg->getUUID	("RegionInfo", "SimOwner", sim_owner);
+	msg->getBOOL	("RegionInfo", "IsEstateManager", is_estate_manager);
+	msg->getF32		("RegionInfo", "WaterHeight", water_height);
+	msg->getF32		("RegionInfo", "BillableFactor", billable_factor);
+	msg->getUUID	("RegionInfo", "CacheID", cache_id );
+
+	setRegionFlags(region_flags);
+	setSimAccess(sim_access);
+	setRegionNameAndZone(sim_name);
+	setOwner(sim_owner);
+	setIsEstateManager(is_estate_manager);
+	setWaterHeight(water_height);
+	setBillableFactor(billable_factor);
+	setCacheID(cache_id);
+
+	LLUUID region_id;
+	msg->getUUID("RegionInfo2", "RegionID", region_id);
+	setRegionID(region_id);
+	
+	// Retrieve the CR-53 (Homestead/Land SKU) information
+	S32 classID = 0;
+	S32 cpuRatio = 0;
+	std::string coloName;
+	std::string productSKU;
+	std::string productName;
+
+	// the only reasonable way to decide if we actually have any data is to
+	// check to see if any of these fields have positive sizes
+	if (msg->getSize("RegionInfo3", "ColoName") > 0 ||
+	    msg->getSize("RegionInfo3", "ProductSKU") > 0 ||
+	    msg->getSize("RegionInfo3", "ProductName") > 0)
+	{
+		msg->getS32     ("RegionInfo3", "CPUClassID",  classID);
+		msg->getS32     ("RegionInfo3", "CPURatio",    cpuRatio);
+		msg->getString  ("RegionInfo3", "ColoName",    coloName);
+		msg->getString  ("RegionInfo3", "ProductSKU",  productSKU);
+		msg->getString  ("RegionInfo3", "ProductName", productName);
+		
+		mClassID = classID;
+		mCPURatio = cpuRatio;
+		mColoName = coloName;
+		mProductSKU = productSKU;
+		mProductName = productName;
+	}
+
+	LLVLComposition *compp = getComposition();
+	if (compp)
+	{
+		LLUUID tmp_id;
+
+		msg->getUUID("RegionInfo", "TerrainDetail0", tmp_id);
+		compp->setDetailTextureID(0, tmp_id);
+		msg->getUUID("RegionInfo", "TerrainDetail1", tmp_id);
+		compp->setDetailTextureID(1, tmp_id);
+		msg->getUUID("RegionInfo", "TerrainDetail2", tmp_id);
+		compp->setDetailTextureID(2, tmp_id);
+		msg->getUUID("RegionInfo", "TerrainDetail3", tmp_id);
+		compp->setDetailTextureID(3, tmp_id);
+
+		F32 tmp_f32;
+		msg->getF32("RegionInfo", "TerrainStartHeight00", tmp_f32);
+		compp->setStartHeight(0, tmp_f32);
+		msg->getF32("RegionInfo", "TerrainStartHeight01", tmp_f32);
+		compp->setStartHeight(1, tmp_f32);
+		msg->getF32("RegionInfo", "TerrainStartHeight10", tmp_f32);
+		compp->setStartHeight(2, tmp_f32);
+		msg->getF32("RegionInfo", "TerrainStartHeight11", tmp_f32);
+		compp->setStartHeight(3, tmp_f32);
+
+		msg->getF32("RegionInfo", "TerrainHeightRange00", tmp_f32);
+		compp->setHeightRange(0, tmp_f32);
+		msg->getF32("RegionInfo", "TerrainHeightRange01", tmp_f32);
+		compp->setHeightRange(1, tmp_f32);
+		msg->getF32("RegionInfo", "TerrainHeightRange10", tmp_f32);
+		compp->setHeightRange(2, tmp_f32);
+		msg->getF32("RegionInfo", "TerrainHeightRange11", tmp_f32);
+		compp->setHeightRange(3, tmp_f32);
+
+		// If this is an UPDATE (params already ready, we need to regenerate
+		// all of our terrain stuff, by
+		if (compp->getParamsReady())
+		{
+			//this line creates frame stalls on region crossing and removing it appears to have no effect
+			//getLand().dirtyAllPatches();
+		}
+		else
+		{
+			compp->setParamsReady();
+		}
+	}
+
+
+	// Now that we have the name, we can load the cache file
+	// off disk.
+	loadObjectCache();
+
+	// After loading cache, signal that simulator can start
+	// sending data.
+	// TODO: Send all upstream viewer->sim handshake info here.
+	LLHost host = msg->getSender();
+	msg->newMessage("RegionHandshakeReply");
+	msg->nextBlock("AgentData");
+	msg->addUUID("AgentID", gAgent.getID());
+	msg->addUUID("SessionID", gAgent.getSessionID());
+	msg->nextBlock("RegionInfo");
+	msg->addU32("Flags", 0x0 );
+	msg->sendReliable(host);
+}
+
+void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
+{
+	capabilityNames.append("AgentState");
+	capabilityNames.append("AttachmentResources");
+	capabilityNames.append("AvatarPickerSearch");
+	capabilityNames.append("CharacterProperties");
+	capabilityNames.append("ChatSessionRequest");
+	capabilityNames.append("CopyInventoryFromNotecard");
+	capabilityNames.append("CreateInventoryCategory");
+	capabilityNames.append("DispatchRegionInfo");
+	capabilityNames.append("EnvironmentSettings");
+	capabilityNames.append("EstateChangeInfo");
+	capabilityNames.append("EventQueueGet");
+
+	if (gSavedSettings.getBOOL("UseHTTPInventory"))
+	{
+		capabilityNames.append("FetchLib2");
+		capabilityNames.append("FetchLibDescendents2");
+		capabilityNames.append("FetchInventory2");
+		capabilityNames.append("FetchInventoryDescendents2");
+	}
+
+	capabilityNames.append("GetDisplayNames");
+	capabilityNames.append("GetMesh");
+	capabilityNames.append("GetObjectCost");
+	capabilityNames.append("GetObjectPhysicsData");
+	capabilityNames.append("GetTexture");
+	capabilityNames.append("GroupMemberData");
+	capabilityNames.append("GroupProposalBallot");
+	capabilityNames.append("HomeLocation");
+	capabilityNames.append("LandResources");
+	capabilityNames.append("MapLayer");
+	capabilityNames.append("MapLayerGod");
+	capabilityNames.append("MeshUploadFlag");	
+	capabilityNames.append("NavMeshGenerationStatus");
+	capabilityNames.append("NewFileAgentInventory");
+	capabilityNames.append("ObjectMedia");
+	capabilityNames.append("ObjectMediaNavigate");
+	capabilityNames.append("ObjectNavMeshProperties");
+	capabilityNames.append("ParcelPropertiesUpdate");
+	capabilityNames.append("ParcelVoiceInfoRequest");
+	capabilityNames.append("ProductInfoRequest");
+	capabilityNames.append("ProvisionVoiceAccountRequest");
+	capabilityNames.append("RemoteParcelRequest");
+	capabilityNames.append("RequestTextureDownload");
+	capabilityNames.append("ResourceCostSelected");
+	capabilityNames.append("RetrieveNavMeshSrc");
+	capabilityNames.append("SearchStatRequest");
+	capabilityNames.append("SearchStatTracking");
+	capabilityNames.append("SendPostcard");
+	capabilityNames.append("SendUserReport");
+	capabilityNames.append("SendUserReportWithScreenshot");
+	capabilityNames.append("ServerReleaseNotes");
+	capabilityNames.append("SetDisplayName");
+	capabilityNames.append("SimConsoleAsync");
+	capabilityNames.append("SimulatorFeatures");
+	capabilityNames.append("StartGroupProposal");
+	capabilityNames.append("TerrainNavMeshProperties");
+	capabilityNames.append("TextureStats");
+	capabilityNames.append("UntrustedSimulatorMessage");
+	capabilityNames.append("UpdateAgentInformation");
+	capabilityNames.append("UpdateAgentLanguage");
+	capabilityNames.append("UpdateGestureAgentInventory");
+	capabilityNames.append("UpdateGestureTaskInventory");
+	capabilityNames.append("UpdateNotecardAgentInventory");
+	capabilityNames.append("UpdateNotecardTaskInventory");
+	capabilityNames.append("UpdateScriptAgent");
+	capabilityNames.append("UpdateScriptTask");
+	capabilityNames.append("UploadBakedTexture");
+	capabilityNames.append("ViewerMetrics");
+	capabilityNames.append("ViewerStartAuction");
+	capabilityNames.append("ViewerStats");
+
+	// Please add new capabilities alphabetically to reduce
+	// merge conflicts.
+}
+
+void LLViewerRegion::setSeedCapability(const std::string& url)
+{
+	if (getCapability("Seed") == url)
+    {
+		// llwarns << "Ignoring duplicate seed capability" << llendl;
+		return;
+    }
+	
+	delete mImpl->mEventPoll;
+	mImpl->mEventPoll = NULL;
+	
+	mImpl->mCapabilities.clear();
+	setCapability("Seed", url);
+
+	LLSD capabilityNames = LLSD::emptyArray();
+	mImpl->buildCapabilityNames(capabilityNames);
+
+	llinfos << "posting to seed " << url << llendl;
+
+	S32 id = ++mImpl->mHttpResponderID;
+	LLHTTPClient::post(url, capabilityNames, 
+						BaseCapabilitiesComplete::build(getHandle(), id),
+						LLSD(), CAP_REQUEST_TIMEOUT);
+}
+
+S32 LLViewerRegion::getNumSeedCapRetries()
+{
+	return mImpl->mSeedCapAttempts;
+}
+
+void LLViewerRegion::failedSeedCapability()
+{
+	// Should we retry asking for caps?
+	mImpl->mSeedCapAttempts++;
+	std::string url = getCapability("Seed");
+	if ( url.empty() )
+	{
+		LL_WARNS2("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url for retries!" << LL_ENDL;
+		return;
+	}
+	// After a few attempts, continue login.  We will keep trying once in-world:
+	if ( mImpl->mSeedCapAttempts >= mImpl->mSeedCapMaxAttemptsBeforeLogin &&
+		 STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState() )
+	{
+		LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
+	}
+
+	if ( mImpl->mSeedCapAttempts < mImpl->mSeedCapMaxAttempts)
+	{
+		LLSD capabilityNames = LLSD::emptyArray();
+		mImpl->buildCapabilityNames(capabilityNames);
+
+		llinfos << "posting to seed " << url << " (retry " 
+				<< mImpl->mSeedCapAttempts << ")" << llendl;
+
+		S32 id = ++mImpl->mHttpResponderID;
+		LLHTTPClient::post(url, capabilityNames, 
+						BaseCapabilitiesComplete::build(getHandle(), id),
+						LLSD(), CAP_REQUEST_TIMEOUT);
+	}
+	else
+	{
+		// *TODO: Give a user pop-up about this error?
+		LL_WARNS2("AppInit", "Capabilities") << "Failed to get seed capabilities from '" << url << "' after " << mImpl->mSeedCapAttempts << " attempts.  Giving up!" << LL_ENDL;
+	}
+}
+
+class SimulatorFeaturesReceived : public LLHTTPClient::Responder
+{
+	LOG_CLASS(SimulatorFeaturesReceived);
+public:
+    SimulatorFeaturesReceived(const std::string& retry_url, U64 region_handle, 
+			S32 attempt = 0, S32 max_attempts = MAX_CAP_REQUEST_ATTEMPTS)
+	: mRetryURL(retry_url), mRegionHandle(region_handle), mAttempt(attempt), mMaxAttempts(max_attempts)
+    { }
+	
+	
+    void error(U32 statusNum, const std::string& reason)
+    {
+		LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL;
+		retry();
+    }
+
+    void result(const LLSD& content)
+    {
+		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+		if(!regionp) //region is removed or responder is not created.
+		{
+			LL_WARNS2("AppInit", "SimulatorFeatures") << "Received results for region that no longer exists!" << LL_ENDL;
+			return ;
+		}
+		
+		regionp->setSimulatorFeatures(content);
+	}
+
+private:
+	void retry()
+	{
+		if (mAttempt < mMaxAttempts)
+		{
+			mAttempt++;
+			LL_WARNS2("AppInit", "SimulatorFeatures") << "Re-trying '" << mRetryURL << "'.  Retry #" << mAttempt << LL_ENDL;
+			LLHTTPClient::get(mRetryURL, new SimulatorFeaturesReceived(*this), LLSD(), CAP_REQUEST_TIMEOUT);
+		}
+	}
+	
+	std::string mRetryURL;
+	U64 mRegionHandle;
+	S32 mAttempt;
+	S32 mMaxAttempts;
+};
+
+
+void LLViewerRegion::setCapability(const std::string& name, const std::string& url)
+{
+	if(name == "EventQueueGet")
+	{
+		delete mImpl->mEventPoll;
+		mImpl->mEventPoll = NULL;
+		mImpl->mEventPoll = new LLEventPoll(url, getHost());
+	}
+	else if(name == "UntrustedSimulatorMessage")
+	{
+		LLHTTPSender::setSender(mImpl->mHost, new LLCapHTTPSender(url));
+	}
+	else if (name == "SimulatorFeatures")
+	{
+		// kick off a request for simulator features
+		LLHTTPClient::get(url, new SimulatorFeaturesReceived(url, getHandle()), LLSD(), CAP_REQUEST_TIMEOUT);
+	}
+	else
+	{
+		mImpl->mCapabilities[name] = url;
+		if(name == "GetTexture")
+		{
+			mHttpUrl = url ;
+		}
+	}
+}
+
+bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
+{
+	return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
+}
+
+std::string LLViewerRegion::getCapability(const std::string& name) const
+{
+	CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
+	if(iter == mImpl->mCapabilities.end())
+	{
+		return "";
+	}
+
+	return iter->second;
+}
+
+bool LLViewerRegion::capabilitiesReceived() const
+{
+	return mCapabilitiesReceived;
+}
+
+void LLViewerRegion::setCapabilitiesReceived(bool received)
+{
+	mCapabilitiesReceived = received;
+
+	// Tell interested parties that we've received capabilities,
+	// so that they can safely use getCapability().
+	if (received)
+	{
+		mCapabilitiesReceivedSignal(getRegionID());
+
+		// This is a single-shot signal. Forget callbacks to save resources.
+		mCapabilitiesReceivedSignal.disconnect_all_slots();
+	}
+}
+
+boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb)
+{
+	return mCapabilitiesReceivedSignal.connect(cb);
+}
+
+void LLViewerRegion::logActiveCapabilities() const
+{
+	int count = 0;
+	CapabilityMap::const_iterator iter;
+	for (iter = mImpl->mCapabilities.begin(); iter != mImpl->mCapabilities.end(); ++iter, ++count)
+	{
+		if (!iter->second.empty())
+		{
+			llinfos << iter->first << " URL is " << iter->second << llendl;
+		}
+	}
+	llinfos << "Dumped " << count << " entries." << llendl;
+}
+
+LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
+{
+	if (type < mImpl->mObjectPartition.size())
+	{
+		return mImpl->mObjectPartition[type];
+	}
+	return NULL;
+}
+
+// the viewer can not yet distinquish between normal- and estate-owned objects
+// so we collapse these two bits and enable the UI if either are set
+const U32 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT
+											| REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT;
+
+bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const
+{
+	return (mParcelOverlay != NULL)
+		&& (mParcelOverlay->isOwnedSelf(pos)
+			|| mParcelOverlay->isOwnedGroup(pos)
+			|| ((mRegionFlags & ALLOW_RETURN_ENCROACHING_OBJECT)
+				&& mParcelOverlay->encroachesOwned(boxes)) );
+}
+
+bool LLViewerRegion::childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const
+{
+	bool result = false;
+	result = ( mParcelOverlay && mParcelOverlay->encroachesOnUnowned( boxes ) ) ? 1 : 0;
+	return result;
+}
+
+bool LLViewerRegion::objectsCrossParcel(const std::vector<LLBBox>& boxes) const
+{
+	return mParcelOverlay && mParcelOverlay->encroachesOnNearbyParcel(boxes);
+}
+
+void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions )
+{
+	mImpl->mLandp->getNeighboringRegions( uniqueRegions );
+}
+void LLViewerRegion::getNeighboringRegionsStatus( std::vector<S32>& regions )
+{
+	mImpl->mLandp->getNeighboringRegionsStatus( regions );
+}
+void LLViewerRegion::showReleaseNotes()
+{
+	std::string url = this->getCapability("ServerReleaseNotes");
+
+	if (url.empty()) {
+		// HACK haven't received the capability yet, we'll wait until
+		// it arives.
+		mReleaseNotesRequested = TRUE;
+		return;
+	}
+
+	LLWeb::loadURL(url);
+	mReleaseNotesRequested = FALSE;
+}
+
+std::string LLViewerRegion::getDescription() const
+{
+    return stringize(*this);
+}
+
+bool LLViewerRegion::meshUploadEnabled() const
+{
+	return (mSimulatorFeatures.has("MeshUploadEnabled") &&
+		mSimulatorFeatures["MeshUploadEnabled"].asBoolean());
+}
+
+bool LLViewerRegion::meshRezEnabled() const
+{
+	return (mSimulatorFeatures.has("MeshRezEnabled") &&
+				mSimulatorFeatures["MeshRezEnabled"].asBoolean());
+}
+
+bool LLViewerRegion::dynamicPathfindingEnabled() const
+{
+	return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") &&
+			 mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean());
+}
+
-- 
cgit v1.2.3


From a905f7c74ee35ac16237311eb1d0fbda6577aadb Mon Sep 17 00:00:00 2001
From: Chris Baker <baker@lindenlab.com>
Date: Wed, 3 Oct 2012 21:16:04 +0000
Subject: - Fixed an issue where group list wouldn't fall back to UDP if the
 region doesn't support the new GroupMemberData capabaility - Fixed a
 potential null pointer crash.

Thanks to Ansariel from Firestorm for these!

Reviewer: Myself
---
 indra/newview/llgroupmgr.cpp | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 9c0a30e689..6916cf813a 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -1867,6 +1867,12 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 		return;
 	
 	LLViewerRegion* currentRegion = gAgent.getRegion();
+	// Thank you FS:Ansariel!
+	if(!currentRegion)
+	{
+		LL_WARNS("GrpMgr") << "Agent does not have a current region. Uh-oh!" << LL_ENDL;
+		return;
+	}
 
 	// Check to make sure we have our capabilities
 	if(!currentRegion->capabilitiesReceived())
@@ -1878,6 +1884,14 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id)
 	// Get our capability
 	std::string cap_url =  currentRegion->getCapability("GroupMemberData");
 
+	// Thank you FS:Ansariel!
+	if(cap_url.empty())
+	{
+		LL_INFOS("GrpMgr") << "Region has no GroupMemberData capability.  Falling back to UDP fetch." << LL_ENDL;
+		sendGroupMembersRequest(group_id);
+		return;
+	}
+
 	// Post to our service.  Add a body containing the group_id.
 	LLSD body = LLSD::emptyMap();
 	body["group_id"]	= group_id;
-- 
cgit v1.2.3


From 21de2d948c86cd2ccc728f6165369e01ff09049e Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Mon, 5 Nov 2012 16:26:48 -0500
Subject: tag merge of DRTVWR-217

---
 .hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.hgtags b/.hgtags
index c1bd6a13f1..7698982990 100755
--- a/.hgtags
+++ b/.hgtags
@@ -329,3 +329,4 @@ fba99f381b8d4ad1b7b42fa4993b29998d95be18 DRTVWR-179
 9c4519aa5c70f7560111fb5c740d3a7dc20a845a 3.4.1-beta9
 637fe8bbee5e24940448198c221d5ee0fa3247b4 3.4.1-beta9
 4e0d84e92132e9e95a1d52a1e49bad69c278ea05 3.4.1-beta10
+32896d5e920ca9a29256ff3b747c2e99752aa5ae DRTVWR-217
-- 
cgit v1.2.3