summaryrefslogtreecommitdiff
path: root/indra/newview/llviewerregion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llviewerregion.cpp')
-rw-r--r--indra/newview/llviewerregion.cpp296
1 files changed, 230 insertions, 66 deletions
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index f835351c04..5be2234ec2 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -54,6 +54,7 @@
#include "llfloaterreporter.h"
#include "llfloaterregioninfo.h"
#include "llhttpnode.h"
+#include "llregioninfomodel.h"
#include "llsdutil.h"
#include "llstartup.h"
#include "lltrans.h"
@@ -64,11 +65,11 @@
#include "llvlmanager.h"
#include "llvlcomposition.h"
#include "llvocache.h"
-#include "llvoclouds.h"
#include "llworld.h"
#include "llspatialpartition.h"
#include "stringize.h"
#include "llviewercontrol.h"
+#include "llsdserialize.h"
#ifdef LL_WINDOWS
#pragma warning(disable:4355)
@@ -76,6 +77,13 @@
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;
@@ -85,6 +93,10 @@ public:
: 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
@@ -99,6 +111,8 @@ public:
{
}
+ void buildCapabilityNames(LLSD& capabilityNames);
+
// The surfaces and other layers
LLSurface* mLandp;
@@ -131,6 +145,12 @@ public:
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)
@@ -138,8 +158,6 @@ public:
//spatial partitions for objects in this region
std::vector<LLSpatialPartition*> mObjectPartition;
-
- LLHTTPClient::ResponderPtr mHttpResponderPtr ;
};
// support for secondlife:///app/region/{REGION} SLapps
@@ -185,54 +203,51 @@ class BaseCapabilitiesComplete : public LLHTTPClient::Responder
{
LOG_CLASS(BaseCapabilitiesComplete);
public:
- BaseCapabilitiesComplete(LLViewerRegion* region)
- : mRegion(region)
+ BaseCapabilitiesComplete(U64 region_handle, S32 id)
+ : mRegionHandle(region_handle), mID(id)
{ }
virtual ~BaseCapabilitiesComplete()
- {
- if(mRegion)
- {
- mRegion->setHttpResponderPtrNULL() ;
- }
- }
-
- void setRegion(LLViewerRegion* region)
- {
- mRegion = region ;
- }
+ { }
void error(U32 statusNum, const std::string& reason)
{
LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL;
-
- if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
+ LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+ if (regionp)
{
- LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
+ regionp->failedSeedCapability();
}
}
void result(const LLSD& content)
{
- if(!mRegion || LLHTTPClient::ResponderPtr(this) != mRegion->getHttpResponderPtr()) //region is removed or responder is not created.
+ 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)
{
- mRegion->setCapability(iter->first, iter->second);
+ 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" && mRegion->getReleaseNotesRequested())
+ if (iter->first == "ServerReleaseNotes" && regionp->getReleaseNotesRequested())
{
- mRegion->showReleaseNotes();
+ regionp->showReleaseNotes();
}
}
- mRegion->setCapabilitiesReceived(true);
+ regionp->setCapabilitiesReceived(true);
if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
{
@@ -240,15 +255,15 @@ public:
}
}
- static boost::intrusive_ptr<BaseCapabilitiesComplete> build(
- LLViewerRegion* region)
+ static boost::intrusive_ptr<BaseCapabilitiesComplete> build( U64 region_handle, S32 id )
{
- return boost::intrusive_ptr<BaseCapabilitiesComplete>(
- new BaseCapabilitiesComplete(region));
+ return boost::intrusive_ptr<BaseCapabilitiesComplete>(
+ new BaseCapabilitiesComplete(region_handle, id) );
}
private:
- LLViewerRegion* mRegion;
+ U64 mRegionHandle;
+ S32 mID;
};
@@ -314,7 +329,6 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
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 LLCloudPartition()); //PARTITION_CLOUD
mImpl->mObjectPartition.push_back(new LLGrassPartition()); //PARTITION_GRASS
mImpl->mObjectPartition.push_back(new LLVolumePartition()); //PARTITION_VOLUME
mImpl->mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE
@@ -340,16 +354,10 @@ void LLViewerRegion::initStats()
LLViewerRegion::~LLViewerRegion()
{
- if(mImpl->mHttpResponderPtr)
- {
- (static_cast<BaseCapabilitiesComplete*>(mImpl->mHttpResponderPtr.get()))->setRegion(NULL) ;
- }
-
gVLManager.cleanupData(this);
// Can't do this on destruction, because the neighbor pointers might be invalid.
// This should be reference counted...
disconnectAllNeighbors();
- mCloudLayer.destroy();
LLViewerPartSim::getInstance()->cleanupRegion(this);
gObjectList.killObjects(this);
@@ -485,7 +493,6 @@ void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global)
updateRenderMatrix();
mImpl->mLandp->setOriginGlobal(origin_global);
mWind.setOriginGlobal(origin_global);
- mCloudLayer.setOriginGlobal(origin_global);
calculateCenterGlobal();
}
@@ -646,6 +653,9 @@ std::string LLViewerRegion::accessToShortString(U8 sim_access)
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);
@@ -708,14 +718,12 @@ void LLViewerRegion::forceUpdate()
void LLViewerRegion::connectNeighbor(LLViewerRegion *neighborp, U32 direction)
{
mImpl->mLandp->connectNeighbor(neighborp->mImpl->mLandp, direction);
- mCloudLayer.connectNeighbor(&(neighborp->mCloudLayer), direction);
}
void LLViewerRegion::disconnectAllNeighbors()
{
mImpl->mLandp->disconnectAllNeighbors();
- mCloudLayer.disconnectAllNeighbors();
}
LLVLComposition * LLViewerRegion::getComposition() const
@@ -892,14 +900,9 @@ U32 LLViewerRegion::getPacketsLost() const
}
}
-void LLViewerRegion::setHttpResponderPtrNULL()
+S32 LLViewerRegion::getHttpResponderID() const
{
- mImpl->mHttpResponderPtr = NULL;
-}
-
-const LLHTTPClient::ResponderPtr LLViewerRegion::getHttpResponderPtr() const
-{
- return mImpl->mHttpResponderPtr;
+ return mImpl->mHttpResponderID;
}
BOOL LLViewerRegion::pointInRegionGlobal(const LLVector3d &point_global) const
@@ -1140,6 +1143,20 @@ void LLViewerRegion::getInfo(LLSD& info)
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();
@@ -1464,22 +1481,11 @@ void LLViewerRegion::unpackRegionHandshake()
msg->sendReliable(host);
}
-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();
+void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
+{
+ capabilityNames.append("AccountingParcel");
+ capabilityNames.append("AccountingSelection");
capabilityNames.append("AttachmentResources");
capabilityNames.append("AvatarPickerSearch");
capabilityNames.append("ChatSessionRequest");
@@ -1487,6 +1493,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("DispatchRegionInfo");
capabilityNames.append("EstateChangeInfo");
capabilityNames.append("EventQueueGet");
+ capabilityNames.append("EnvironmentSettings");
capabilityNames.append("ObjectMedia");
capabilityNames.append("ObjectMediaNavigate");
@@ -1508,9 +1515,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("LandResources");
capabilityNames.append("MapLayer");
capabilityNames.append("MapLayerGod");
+ capabilityNames.append("MeshUploadFlag");
capabilityNames.append("NewFileAgentInventory");
- capabilityNames.append("NewFileAgentInventoryVariablePrice");
- capabilityNames.append("ObjectAdd");
capabilityNames.append("ParcelPropertiesUpdate");
capabilityNames.append("ParcelMediaURLFilterList");
capabilityNames.append("ParcelNavigateMedia");
@@ -1541,19 +1547,131 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("UpdateNotecardTaskInventory");
capabilityNames.append("UpdateScriptTask");
capabilityNames.append("UploadBakedTexture");
- capabilityNames.append("UploadObjectAsset");
capabilityNames.append("ViewerMetrics");
capabilityNames.append("ViewerStartAuction");
capabilityNames.append("ViewerStats");
+ //prep# Finalize these!!!!!!!!!
+ //capabilityNames.append("AccountingVO");
+ capabilityNames.append("AccountingParcel");
+ capabilityNames.append("AccountingRegion");
+
// 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;
- mImpl->mHttpResponderPtr = BaseCapabilitiesComplete::build(this) ;
- LLHTTPClient::post(url, capabilityNames, mImpl->mHttpResponderPtr);
+ 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")
@@ -1566,6 +1684,11 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u
{
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;
@@ -1600,6 +1723,21 @@ bool LLViewerRegion::capabilitiesReceived() const
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
@@ -1639,6 +1777,18 @@ bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<
&& mParcelOverlay->encroachesOwned(boxes)) );
}
+bool LLViewerRegion::childrenObjectReturnable( const std::vector<LLBBox>& boxes ) const
+{
+ bool result = false;
+ result = ( mParcelOverlay && mParcelOverlay->encroachesOnUnowned( boxes ) ) ? 1 : 0;
+ return result;
+}
+
+void LLViewerRegion::getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions )
+{
+ mImpl->mLandp->getNeighboringRegions( uniqueRegions );
+}
+
void LLViewerRegion::showReleaseNotes()
{
std::string url = this->getCapability("ServerReleaseNotes");
@@ -1658,3 +1808,17 @@ 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());
+}
+
+