diff options
| author | Kelly Washington <kelly@lindenlab.com> | 2012-06-27 14:43:10 -0700 | 
|---|---|---|
| committer | Kelly Washington <kelly@lindenlab.com> | 2012-06-27 14:43:10 -0700 | 
| commit | a68c7c27f9980a130af5eaf65c6731271a27b060 (patch) | |
| tree | fa2d9a9444cfe742d1db3166079fd6631a26ddbd /indra/newview/llagent.cpp | |
| parent | 14ebeffe8776562c0ac9711a44b7ebe3dec49c47 (diff) | |
| parent | 8a7fa77f23b94f9ba2cb6da1942e4f86da314b5a (diff) | |
Merge pulled in lindenlab/viewer-beta to kelly_linden/maint-1078
Diffstat (limited to 'indra/newview/llagent.cpp')
| -rwxr-xr-x | indra/newview/llagent.cpp | 716 | 
1 files changed, 669 insertions, 47 deletions
| diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 3367604753..a6776d4c8d 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -81,6 +81,7 @@  #include "llviewermenu.h"  #include "llviewerobjectlist.h"  #include "llviewerparcelmgr.h" +#include "llviewerregion.h"  #include "llviewerstats.h"  #include "llviewerwindow.h"  #include "llvoavatarself.h" @@ -112,6 +113,105 @@ const F32 MAX_FIDGET_TIME = 20.f; // seconds  // The agent instance.  LLAgent gAgent; +class LLTeleportRequest +{ +public: +	enum EStatus +	{ +		kPending, +		kStarted, +		kFailed, +		kRestartPending +	}; + +	LLTeleportRequest(); +	virtual ~LLTeleportRequest(); + +	EStatus getStatus() const          {return mStatus;}; +	void    setStatus(EStatus pStatus) {mStatus = pStatus;}; + +	virtual bool canRestartTeleport(); + +	virtual void startTeleport() = 0; +	virtual void restartTeleport(); + +protected: + +private: +	EStatus mStatus; +}; + +class LLTeleportRequestViaLandmark : public LLTeleportRequest +{ +public: +	LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId); +	virtual ~LLTeleportRequestViaLandmark(); + +	virtual bool canRestartTeleport(); + +	virtual void startTeleport(); +	virtual void restartTeleport(); + +protected: +	inline const LLUUID &getLandmarkId() const {return mLandmarkId;}; + +private: +	LLUUID mLandmarkId; +}; + +class LLTeleportRequestViaLure : public LLTeleportRequestViaLandmark +{ +public: +	LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike); +	virtual ~LLTeleportRequestViaLure(); + +	virtual bool canRestartTeleport(); + +	virtual void startTeleport(); + +protected: +	inline BOOL isLureGodLike() const {return mIsLureGodLike;}; + +private: +	BOOL mIsLureGodLike; +}; + +class LLTeleportRequestViaLocation : public LLTeleportRequest +{ +public: +	LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal); +	virtual ~LLTeleportRequestViaLocation(); + +	virtual bool canRestartTeleport(); + +	virtual void startTeleport(); +	virtual void restartTeleport(); + +protected: +	inline const LLVector3d &getPosGlobal() const {return mPosGlobal;}; + +private: +	LLVector3d mPosGlobal; +}; + + +class LLTeleportRequestViaLocationLookAt : public LLTeleportRequestViaLocation +{ +public: +	LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal); +	virtual ~LLTeleportRequestViaLocationLookAt(); + +	virtual bool canRestartTeleport(); + +	virtual void startTeleport(); +	virtual void restartTeleport(); + +protected: + +private: + +}; +  //--------------------------------------------------------------------  // Statics  // @@ -245,6 +345,17 @@ LLAgent::LLAgent() :  	mAgentAccess(new LLAgentAccess(gSavedSettings)),  	mCanEditParcel(false),  	mTeleportSourceSLURL(new LLSLURL), +	mTeleportRequest(), +	mTeleportFinishedSlot(), +	mTeleportFailedSlot(), +	mIsMaturityRatingChangingDuringTeleport(false), +	mMaturityRatingChange(0U), +	mIsDoSendMaturityPreferenceToServer(false), +	mMaturityPreferenceRequestId(0U), +	mMaturityPreferenceResponseId(0U), +	mMaturityPreferenceNumRetries(0U), +	mLastKnownRequestMaturity(SIM_ACCESS_MIN), +	mLastKnownResponseMaturity(SIM_ACCESS_MIN),  	mTeleportState( TELEPORT_NONE ),  	mRegionp(NULL), @@ -330,9 +441,21 @@ void LLAgent::init()  	gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2));  	gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2)); +	mLastKnownResponseMaturity = static_cast<U8>(gSavedSettings.getU32("PreferredMaturity")); +	mLastKnownRequestMaturity = mLastKnownResponseMaturity; +	mIsDoSendMaturityPreferenceToServer = true;  	LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback)); +	if (!mTeleportFinishedSlot.connected()) +	{ +		mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLAgent::handleTeleportFinished, this)); +	} +	if (!mTeleportFailedSlot.connected()) +	{ +		mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLAgent::handleTeleportFailed, this)); +	} +  	mInitialized = TRUE;  } @@ -342,6 +465,14 @@ void LLAgent::init()  void LLAgent::cleanup()  {  	mRegionp = NULL; +	if (mTeleportFinishedSlot.connected()) +	{ +		mTeleportFinishedSlot.disconnect(); +	} +	if (mTeleportFailedSlot.connected()) +	{ +		mTeleportFailedSlot.disconnect(); +	}  }  //----------------------------------------------------------------------------- @@ -2371,49 +2502,278 @@ bool LLAgent::isAdult() const  	return mAgentAccess->isAdult();  } -void LLAgent::setTeen(bool teen) -{ -	mAgentAccess->setTeen(teen); -} -  //static   int LLAgent::convertTextToMaturity(char text)  {  	return LLAgentAccess::convertTextToMaturity(text);  } -bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity) +class LLMaturityPreferencesResponder : public LLHTTPClient::Responder  { -	if (!getRegion()) -		return false; +public: +	LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity); +	virtual ~LLMaturityPreferencesResponder(); + +	virtual void result(const LLSD &pContent); +	virtual void error(U32 pStatus, const std::string& pReason); + +protected: + +private: +	U8 parseMaturityFromServerResponse(const LLSD &pContent); + +	LLAgent                                  *mAgent; +	U8                                       mPreferredMaturity; +	U8                                       mPreviousMaturity; +}; + +LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity) +	: LLHTTPClient::Responder(), +	mAgent(pAgent), +	mPreferredMaturity(pPreferredMaturity), +	mPreviousMaturity(pPreviousMaturity) +{ +} + +LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder() +{ +} + +void LLMaturityPreferencesResponder::result(const LLSD &pContent) +{ +	U8 actualMaturity = parseMaturityFromServerResponse(pContent); + +	if (actualMaturity != mPreferredMaturity) +	{ +		llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity) +			<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', the server responded with '" +			<< LLViewerRegion::accessToString(actualMaturity) << "' [value:" << static_cast<U32>(actualMaturity) << ", llsd:" +			<< pContent << "]" << llendl; +	} +	mAgent->handlePreferredMaturityResult(actualMaturity); +} + +void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason) +{ +	llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity) +		<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error because '" +		<< pReason << "' [status:" << pStatus << "]" << llendl; +	mAgent->handlePreferredMaturityError(); +} + +U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent) +{ +	// stinson 05/24/2012 Pathfinding regions have re-defined the response behavior.  In the old server code, +	// if you attempted to change the preferred maturity to the same value, the response content would be an +	// undefined LLSD block.  In the new server code with pathfinding, the response content should always be +	// defined.  Thus, the check for isUndefined() can be replaced with an assert after pathfinding is merged +	// into server trunk and fully deployed. +	U8 maturity = SIM_ACCESS_MIN; +	if (pContent.isUndefined()) +	{ +		maturity = mPreferredMaturity; +	} +	else +	{ +		llassert(!pContent.isUndefined()); +		llassert(pContent.isMap()); -	// Update agent access preference on the server -	std::string url = getRegion()->getCapability("UpdateAgentInformation"); -	if (!url.empty()) +		if (!pContent.isUndefined() && pContent.isMap()) +		{ +			// stinson 05/24/2012 Pathfinding regions have re-defined the response syntax.  The if statement catches +			// the new syntax, and the else statement catches the old syntax.  After pathfinding is merged into +			// server trunk and fully deployed, we can remove the else statement. +			if (pContent.has("access_prefs")) +			{ +				llassert(pContent.has("access_prefs")); +				llassert(pContent.get("access_prefs").isMap()); +				llassert(pContent.get("access_prefs").has("max")); +				llassert(pContent.get("access_prefs").get("max").isString()); +				if (pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max") && +					pContent.get("access_prefs").get("max").isString()) +				{ +					LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString(); +					LLStringUtil::trim(actualPreference); +					maturity = LLViewerRegion::shortStringToAccess(actualPreference); +				} +			} +			else if (pContent.has("max")) +			{ +				llassert(pContent.get("max").isString()); +				if (pContent.get("max").isString()) +				{ +					LLSD::String actualPreference = pContent.get("max").asString(); +					LLStringUtil::trim(actualPreference); +					maturity = LLViewerRegion::shortStringToAccess(actualPreference); +				} +			} +		} +	} + +	return maturity; +} + +void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity) +{ +	// Update the number of responses received +	++mMaturityPreferenceResponseId; +	llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId); + +	// Update the last known server maturity response +	mLastKnownResponseMaturity = pServerMaturity; + +	// Ignore all responses if we know there are more unanswered requests that are expected +	if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId)  	{ -		// Set new access preference -		LLSD access_prefs = LLSD::emptyMap(); -		if (preferredMaturity == SIM_ACCESS_PG) +		// If we received a response that matches the last known request, then we are good +		if (mLastKnownRequestMaturity == mLastKnownResponseMaturity)  		{ -			access_prefs["max"] = "PG"; +			mMaturityPreferenceNumRetries = 0; +			reportPreferredMaturitySuccess(); +			llassert(static_cast<U8>(gSavedSettings.getU32("PreferredMaturity")) == mLastKnownResponseMaturity);  		} -		else if (preferredMaturity == SIM_ACCESS_MATURE) +		// Else, the viewer is out of sync with the server, so let's try to re-sync with the +		// server by re-sending our last known request.  Cap the re-tries at 3 just to be safe. +		else if (++mMaturityPreferenceNumRetries <= 3)  		{ -			access_prefs["max"] = "M"; +			llinfos << "Retrying attempt #" << mMaturityPreferenceNumRetries << " to set viewer preferred maturity to '" +				<< LLViewerRegion::accessToString(mLastKnownRequestMaturity) << "'" << llendl; +			sendMaturityPreferenceToServer(mLastKnownRequestMaturity);  		} -		if (preferredMaturity == SIM_ACCESS_ADULT) +		// Else, the viewer is style out of sync with the server after 3 retries, so inform the user +		else  		{ -			access_prefs["max"] = "A"; +			mMaturityPreferenceNumRetries = 0; +			reportPreferredMaturityError(); +		} +	} +} + +void LLAgent::handlePreferredMaturityError() +{ +	// Update the number of responses received +	++mMaturityPreferenceResponseId; +	llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId); + +	// Ignore all responses if we know there are more unanswered requests that are expected +	if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId) +	{ +		mMaturityPreferenceNumRetries = 0; + +		// If we received a response that matches the last known request, then we are synced with +		// the server, but not quite sure why we are +		if (mLastKnownRequestMaturity == mLastKnownResponseMaturity) +		{ +			llwarns << "Got an error but maturity preference '" << LLViewerRegion::accessToString(mLastKnownRequestMaturity) +				<< "' seems to be in sync with the server" << llendl; +			reportPreferredMaturitySuccess(); +		} +		// Else, the more likely case is that the last request does not match the last response, +		// so inform the user +		else +		{ +			reportPreferredMaturityError(); +		} +	} +} + +void LLAgent::reportPreferredMaturitySuccess() +{ +	// If there is a pending teleport request waiting for the maturity preference to be synced with +	// the server, let's start the pending request +	if (hasPendingTeleportRequest()) +	{ +		startTeleportRequest(); +	} +} + +void LLAgent::reportPreferredMaturityError() +{ +	// If there is a pending teleport request waiting for the maturity preference to be synced with +	// the server, we were unable to successfully sync with the server on maturity preference, so let's +	// just raise the screen. +	mIsMaturityRatingChangingDuringTeleport = false; +	if (hasPendingTeleportRequest()) +	{ +		setTeleportState(LLAgent::TELEPORT_NONE); +	} + +	// Get the last known maturity request from the user activity +	std::string preferredMaturity = LLViewerRegion::accessToString(mLastKnownRequestMaturity); +	LLStringUtil::toLower(preferredMaturity); + +	// Get the last known maturity response from the server +	std::string actualMaturity = LLViewerRegion::accessToString(mLastKnownResponseMaturity); +	LLStringUtil::toLower(actualMaturity); + +	// Notify the user +	LLSD args = LLSD::emptyMap(); +	args["PREFERRED_MATURITY"] = preferredMaturity; +	args["ACTUAL_MATURITY"] = actualMaturity; +	LLNotificationsUtil::add("MaturityChangeError", args); + +	// Check the saved settings to ensure that we are consistent.  If we are not consistent, update +	// the viewer, but do not send anything to server +	U8 localMaturity = static_cast<U8>(gSavedSettings.getU32("PreferredMaturity")); +	if (localMaturity != mLastKnownResponseMaturity) +	{ +		bool tmpIsDoSendMaturityPreferenceToServer = mIsDoSendMaturityPreferenceToServer; +		mIsDoSendMaturityPreferenceToServer = false; +		llinfos << "Setting viewer preferred maturity to '" << LLViewerRegion::accessToString(mLastKnownResponseMaturity) << "'" << llendl; +		gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(mLastKnownResponseMaturity)); +		mIsDoSendMaturityPreferenceToServer = tmpIsDoSendMaturityPreferenceToServer; +	} +} + +bool LLAgent::isMaturityPreferenceSyncedWithServer() const +{ +	return (mMaturityPreferenceRequestId == mMaturityPreferenceResponseId); +} + +void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity) +{ +	// Only send maturity preference to the server if enabled +	if (mIsDoSendMaturityPreferenceToServer) +	{ +		// Increment the number of requests.  The handlers manage a separate count of responses. +		++mMaturityPreferenceRequestId; + +		// Update the last know maturity request +		mLastKnownRequestMaturity = pPreferredMaturity; + +		// Create a response handler +		LLHTTPClient::ResponderPtr responderPtr = LLHTTPClient::ResponderPtr(new LLMaturityPreferencesResponder(this, pPreferredMaturity, mLastKnownResponseMaturity)); + +		// If we don't have a region, report it as an error +		if (getRegion() == NULL) +		{ +			responderPtr->error(0U, "region is not defined"); +		} +		else +		{ +			// Find the capability to send maturity preference +			std::string url = getRegion()->getCapability("UpdateAgentInformation"); + +			// If the capability is not defined, report it as an error +			if (url.empty()) +			{ +				responderPtr->error(0U, "capability 'UpdateAgentInformation' is not defined for region"); +			} +			else +			{ +				// Set new access preference +				LLSD access_prefs = LLSD::emptyMap(); +				access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity); + +				LLSD body = LLSD::emptyMap(); +				body["access_prefs"] = access_prefs; +				llinfos << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity) +					<< "' via capability to: " << url << llendl; +				LLSD headers; +				LLHTTPClient::post(url, body, responderPtr, headers, 30.0f); +			}  		} -		 -		LLSD body = LLSD::emptyMap(); -		body["access_prefs"] = access_prefs; -		llinfos << "Sending access prefs update to " << (access_prefs["max"].asString()) << " via capability to: " -		<< url << llendl; -		LLHTTPClient::post(url, body, new LLHTTPClient::Responder());    // Ignore response -		return true;  	} -	return false;  }  BOOL LLAgent::getAdminOverride() const	 @@ -2436,11 +2796,6 @@ void LLAgent::setGodLevel(U8 god_level)  	mAgentAccess->setGodLevel(god_level);  } -void LLAgent::setAOTransition() -{ -	mAgentAccess->setTransition(); -} -  const LLAgentAccess& LLAgent::getAgentAccess()  {  	return *mAgentAccess; @@ -2451,9 +2806,9 @@ bool LLAgent::validateMaturity(const LLSD& newvalue)  	return mAgentAccess->canSetMaturity(newvalue.asInteger());  } -void LLAgent::handleMaturity(const LLSD& newvalue) +void LLAgent::handleMaturity(const LLSD &pNewValue)  { -	sendMaturityPreferenceToServer(newvalue.asInteger()); +	sendMaturityPreferenceToServer(static_cast<U8>(pNewValue.asInteger()));  }  //---------------------------------------------------------------------------- @@ -3388,7 +3743,7 @@ void LLAgent::clearVisualParams(void *data)  // protected  bool LLAgent::teleportCore(bool is_local)  { -	if(TELEPORT_NONE != mTeleportState) +	if ((TELEPORT_NONE != mTeleportState) && (mTeleportState != TELEPORT_PENDING))  	{  		llwarns << "Attempt to teleport when already teleporting." << llendl;  		return false; @@ -3466,6 +3821,102 @@ bool LLAgent::teleportCore(bool is_local)  	return true;  } +bool LLAgent::hasRestartableFailedTeleportRequest() +{ +	return ((mTeleportRequest != NULL) && (mTeleportRequest->getStatus() == LLTeleportRequest::kFailed) && +		mTeleportRequest->canRestartTeleport()); +} + +void LLAgent::restartFailedTeleportRequest() +{ +	if (hasRestartableFailedTeleportRequest()) +	{ +		mTeleportRequest->setStatus(LLTeleportRequest::kRestartPending); +		startTeleportRequest(); +	} +} + +void LLAgent::clearTeleportRequest() +{ +	mTeleportRequest.reset(); +} + +void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange) +{ +	mIsMaturityRatingChangingDuringTeleport = true; +	mMaturityRatingChange = pMaturityRatingChange; +} + +bool LLAgent::hasPendingTeleportRequest() +{ +	return ((mTeleportRequest != NULL) && +		((mTeleportRequest->getStatus() == LLTeleportRequest::kPending) || +		(mTeleportRequest->getStatus() == LLTeleportRequest::kRestartPending))); +} + +void LLAgent::startTeleportRequest() +{ +	if (hasPendingTeleportRequest()) +	{ +		if  (!isMaturityPreferenceSyncedWithServer()) +		{ +			gTeleportDisplay = TRUE; +			setTeleportState(TELEPORT_PENDING); +		} +		else +		{ +			switch (mTeleportRequest->getStatus()) +			{ +			case LLTeleportRequest::kPending : +				mTeleportRequest->setStatus(LLTeleportRequest::kStarted); +				mTeleportRequest->startTeleport(); +				break; +			case LLTeleportRequest::kRestartPending : +				llassert(mTeleportRequest->canRestartTeleport()); +				mTeleportRequest->setStatus(LLTeleportRequest::kStarted); +				mTeleportRequest->restartTeleport(); +				break; +			default : +				llassert(0); +				break; +			} +		} +	} +} + +void LLAgent::handleTeleportFinished() +{ +	clearTeleportRequest(); +	if (mIsMaturityRatingChangingDuringTeleport) +	{ +		// notify user that the maturity preference has been changed +		std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange); +		LLStringUtil::toLower(maturityRating); +		LLSD args; +		args["RATING"] = maturityRating; +		LLNotificationsUtil::add("PreferredMaturityChanged", args); +		mIsMaturityRatingChangingDuringTeleport = false; +	} +} + +void LLAgent::handleTeleportFailed() +{ +	if (mTeleportRequest != NULL) +	{ +		mTeleportRequest->setStatus(LLTeleportRequest::kFailed); +	} +	if (mIsMaturityRatingChangingDuringTeleport) +	{ +		// notify user that the maturity preference has been changed +		std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange); +		LLStringUtil::toLower(maturityRating); +		LLSD args; +		args["RATING"] = maturityRating; +		LLNotificationsUtil::add("PreferredMaturityChanged", args); +		mIsMaturityRatingChangingDuringTeleport = false; +	} +} +  void LLAgent::teleportRequest(  	const U64& region_handle,  	const LLVector3& pos_local, @@ -3498,6 +3949,12 @@ void LLAgent::teleportRequest(  // Landmark ID = LLUUID::null means teleport home  void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)  { +	mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLandmark(landmark_asset_id)); +	startTeleportRequest(); +} + +void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id) +{  	LLViewerRegion *regionp = getRegion();  	if(regionp && teleportCore())  	{ @@ -3513,6 +3970,12 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)  void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)  { +	mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLure(lure_id, godlike)); +	startTeleportRequest(); +} + +void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike) +{  	LLViewerRegion* regionp = getRegion();  	if(regionp && teleportCore())  	{ @@ -3544,24 +4007,33 @@ void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)  // James Cook, July 28, 2005  void LLAgent::teleportCancel()  { -	LLViewerRegion* regionp = getRegion(); -	if(regionp) +	if (!hasPendingTeleportRequest())  	{ -		// send the message -		LLMessageSystem* msg = gMessageSystem; -		msg->newMessage("TeleportCancel"); -		msg->nextBlockFast(_PREHASH_Info); -		msg->addUUIDFast(_PREHASH_AgentID, getID()); -		msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); -		sendReliableMessage(); -	}	 -	gTeleportDisplay = FALSE; +		LLViewerRegion* regionp = getRegion(); +		if(regionp) +		{ +			// send the message +			LLMessageSystem* msg = gMessageSystem; +			msg->newMessage("TeleportCancel"); +			msg->nextBlockFast(_PREHASH_Info); +			msg->addUUIDFast(_PREHASH_AgentID, getID()); +			msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); +			sendReliableMessage(); +		}	 +	} +	clearTeleportRequest();  	gAgent.setTeleportState( LLAgent::TELEPORT_NONE );  }  void LLAgent::teleportViaLocation(const LLVector3d& pos_global)  { +	mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocation(pos_global)); +	startTeleportRequest(); +} + +void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global) +{  	LLViewerRegion* regionp = getRegion();  	U64 handle = to_region_handle(pos_global);  	LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); @@ -3604,6 +4076,12 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global)  // Teleport to global position, but keep facing in the same direction   void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global)  { +	mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocationLookAt(pos_global)); +	startTeleportRequest(); +} + +void LLAgent::doTeleportViaLocationLookAt(const LLVector3d& pos_global) +{  	mbTeleportKeepsLookAt = true;  	gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);	// detach camera form avatar, so it keeps direction  	U64 region_handle = to_region_handle(pos_global); @@ -4045,5 +4523,149 @@ LLAgentQueryManager::~LLAgentQueryManager()  {  } -// EOF +//----------------------------------------------------------------------------- +// LLTeleportRequest +//----------------------------------------------------------------------------- + +LLTeleportRequest::LLTeleportRequest() +	: mStatus(kPending) +{ +} + +LLTeleportRequest::~LLTeleportRequest() +{ +} +bool LLTeleportRequest::canRestartTeleport() +{ +	return false; +} + +void LLTeleportRequest::restartTeleport() +{ +	llassert(0); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLandmark +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId) +	: LLTeleportRequest(), +	mLandmarkId(pLandmarkId) +{ +} + +LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark() +{ +} + +bool LLTeleportRequestViaLandmark::canRestartTeleport() +{ +	return true; +} + +void LLTeleportRequestViaLandmark::startTeleport() +{ +	gAgent.doTeleportViaLandmark(getLandmarkId()); +} + +void LLTeleportRequestViaLandmark::restartTeleport() +{ +	gAgent.doTeleportViaLandmark(getLandmarkId()); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLure +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLure::LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike) +	: LLTeleportRequestViaLandmark(pLureId), +	mIsLureGodLike(pIsLureGodLike) +{ +} + +LLTeleportRequestViaLure::~LLTeleportRequestViaLure() +{ +} + +bool LLTeleportRequestViaLure::canRestartTeleport() +{ +	// stinson 05/17/2012 : cannot restart a teleport via lure because of server-side restrictions +	// The current scenario is as follows: +	//    1. User A initializes a request for User B to teleport via lure +	//    2. User B accepts the teleport via lure request +	//    3. The server sees the init request from User A and the accept request from User B and matches them up +	//    4. The server then removes the paired requests up from the "queue" +	//    5. The server then fails User B's teleport for reason of maturity level (for example) +	//    6. User B's viewer prompts user to increase their maturity level profile value. +	//    7. User B confirms and accepts increase in maturity level +	//    8. User B's viewer then attempts to teleport via lure again +	//    9. This request will time-out on the viewer-side because User A's initial request has been removed from the "queue" in step 4 + +	return false; +} + +void LLTeleportRequestViaLure::startTeleport() +{ +	gAgent.doTeleportViaLure(getLandmarkId(), isLureGodLike()); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLocation +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLocation::LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal) +	: LLTeleportRequest(), +	mPosGlobal(pPosGlobal) +{ +} + +LLTeleportRequestViaLocation::~LLTeleportRequestViaLocation() +{ +} + +bool LLTeleportRequestViaLocation::canRestartTeleport() +{ +	return true; +} + +void LLTeleportRequestViaLocation::startTeleport() +{ +	gAgent.doTeleportViaLocation(getPosGlobal()); +} + +void LLTeleportRequestViaLocation::restartTeleport() +{ +	gAgent.doTeleportViaLocation(getPosGlobal()); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLocationLookAt +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLocationLookAt::LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal) +	: LLTeleportRequestViaLocation(pPosGlobal) +{ +} + +LLTeleportRequestViaLocationLookAt::~LLTeleportRequestViaLocationLookAt() +{ +} + +bool LLTeleportRequestViaLocationLookAt::canRestartTeleport() +{ +	return true; +} + +void LLTeleportRequestViaLocationLookAt::startTeleport() +{ +	gAgent.doTeleportViaLocationLookAt(getPosGlobal()); +} + +void LLTeleportRequestViaLocationLookAt::restartTeleport() +{ +	gAgent.doTeleportViaLocationLookAt(getPosGlobal()); +} + +// EOF | 
