EXP-1942,EXP-1945: Ensuring that the teleport process waits for the maturity preferences to be synced between viewer and server.

meow-7.2.2
Todd Stinson 2012-05-29 16:15:25 -07:00
parent b8bc62a514
commit 8ff00d6ecf
4 changed files with 97 additions and 165 deletions

View File

@ -116,9 +116,20 @@ 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;
@ -127,7 +138,7 @@ public:
protected:
private:
EStatus mStatus;
};
class LLTeleportRequestViaLandmark : public LLTeleportRequest
@ -334,14 +345,12 @@ LLAgent::LLAgent() :
mAgentAccess(new LLAgentAccess(gSavedSettings)),
mCanEditParcel(false),
mTeleportSourceSLURL(new LLSLURL),
mCurrentTeleportRequest(),
mFailedTeleportRequest(),
mTeleportRequest(),
mTeleportFinishedSlot(),
mTeleportFailedSlot(),
mIsMaturityRatingChangingDuringTeleport(false),
mMaturityRatingChange(0U),
mIsDoSendMaturityPreferenceToServer(false),
mMaturityPreferenceConfirmCallback(NULL),
mMaturityPreferenceRequestId(0U),
mMaturityPreferenceResponseId(0U),
mMaturityPreferenceNumRetries(0U),
@ -2500,7 +2509,7 @@ int LLAgent::convertTextToMaturity(char text)
class LLMaturityPreferencesResponder : public LLHTTPClient::Responder
{
public:
LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity, LLAgent::maturity_preferences_callback_t pMaturityPreferencesCallback);
LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity);
virtual ~LLMaturityPreferencesResponder();
virtual void result(const LLSD &pContent);
@ -2514,15 +2523,13 @@ private:
LLAgent *mAgent;
U8 mPreferredMaturity;
U8 mPreviousMaturity;
LLAgent::maturity_preferences_callback_t mMaturityPreferencesCallback;
};
LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity, LLAgent::maturity_preferences_callback_t pMaturityPreferencesCallback)
LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity)
: LLHTTPClient::Responder(),
mAgent(pAgent),
mPreferredMaturity(pPreferredMaturity),
mPreviousMaturity(pPreviousMaturity),
mMaturityPreferencesCallback(pMaturityPreferencesCallback)
mPreviousMaturity(pPreviousMaturity)
{
}
@ -2542,11 +2549,6 @@ void LLMaturityPreferencesResponder::result(const LLSD &pContent)
<< pContent << "]" << llendl;
}
mAgent->handlePreferredMaturityResult(actualMaturity);
if (!mMaturityPreferencesCallback.empty())
{
mMaturityPreferencesCallback(actualMaturity);
}
}
void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason)
@ -2555,10 +2557,6 @@ void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReas
<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error because '"
<< pReason << "' [status:" << pStatus << "]" << llendl;
mAgent->handlePreferredMaturityError();
if (!mMaturityPreferencesCallback.empty())
{
mMaturityPreferencesCallback(mPreviousMaturity);
}
}
U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent)
@ -2613,19 +2611,6 @@ U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &p
return maturity;
}
void LLAgent::setMaturityPreferenceAndConfirm(U32 preferredMaturity, maturity_preferences_callback_t pMaturityPreferencesCallback)
{
llassert(mMaturityPreferenceConfirmCallback == NULL);
mMaturityPreferenceConfirmCallback = pMaturityPreferencesCallback;
gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity));
// PreferredMaturity has a signal hook on change that will call LLAgent::sendMaturityPreferenceToServer
// sendMaturityPreferenceToServer will use mMaturityPreferenceConfirmCallback in the LLHTTPResponder
// This allows for confirmation that the server has officially received the maturity preference change
mMaturityPreferenceConfirmCallback = NULL;
}
void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity)
{
// Update the number of responses received
@ -2642,6 +2627,7 @@ void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity)
if (mLastKnownRequestMaturity == mLastKnownResponseMaturity)
{
mMaturityPreferenceNumRetries = 0;
reportPreferredMaturitySuccess();
llassert(static_cast<U8>(gSavedSettings.getU32("PreferredMaturity")) == mLastKnownResponseMaturity);
}
// Else, the viewer is out of sync with the server, so let's try to re-sync with the
@ -2689,6 +2675,14 @@ void LLAgent::handlePreferredMaturityError()
}
}
void LLAgent::reportPreferredMaturitySuccess()
{
if (hasPendingTeleportRequest())
{
startTeleportRequest();
}
}
void LLAgent::reportPreferredMaturityError()
{
// Get the last known maturity request from the user activity
@ -2718,6 +2712,11 @@ void LLAgent::reportPreferredMaturityError()
}
}
bool LLAgent::isMaturityPreferenceSyncedWithServer() const
{
return (mMaturityPreferenceRequestId == mMaturityPreferenceResponseId);
}
void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
{
// Only send maturity preference to the server if enabled
@ -2730,7 +2729,7 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
mLastKnownRequestMaturity = pPreferredMaturity;
// Create a response handler
LLHTTPClient::ResponderPtr responderPtr = LLHTTPClient::ResponderPtr(new LLMaturityPreferencesResponder(this, pPreferredMaturity, mLastKnownResponseMaturity, mMaturityPreferenceConfirmCallback));
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)
@ -3808,23 +3807,22 @@ bool LLAgent::teleportCore(bool is_local)
bool LLAgent::hasRestartableFailedTeleportRequest()
{
return hasFailedTeleportRequest() && mFailedTeleportRequest->canRestartTeleport();
return ((mTeleportRequest != NULL) && (mTeleportRequest->getStatus() == LLTeleportRequest::kFailed) &&
mTeleportRequest->canRestartTeleport());
}
void LLAgent::restartFailedTeleportRequest()
{
if (hasRestartableFailedTeleportRequest())
{
mFailedTeleportRequest->restartTeleport();
mTeleportRequest->setStatus(LLTeleportRequest::kRestartPending);
startTeleportRequest();
}
}
void LLAgent::clearFailedTeleportRequest()
void LLAgent::clearTeleportRequest()
{
if (hasFailedTeleportRequest())
{
mFailedTeleportRequest.reset();
}
mTeleportRequest.reset();
}
void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)
@ -3833,16 +3831,38 @@ void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)
mMaturityRatingChange = pMaturityRatingChange;
}
bool LLAgent::hasPendingTeleportRequest()
{
return ((mTeleportRequest != NULL) &&
((mTeleportRequest->getStatus() == LLTeleportRequest::kPending) ||
(mTeleportRequest->getStatus() == LLTeleportRequest::kRestartPending)));
}
void LLAgent::startTeleportRequest()
{
if (hasPendingTeleportRequest() && isMaturityPreferenceSyncedWithServer())
{
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()
{
if (hasCurrentTeleportRequest())
{
mCurrentTeleportRequest.reset();
}
if (hasFailedTeleportRequest())
{
clearFailedTeleportRequest();
}
clearTeleportRequest();
if (mIsMaturityRatingChangingDuringTeleport)
{
// notify user that the maturity preference has been changed
@ -3857,9 +3877,10 @@ void LLAgent::handleTeleportFinished()
void LLAgent::handleTeleportFailed()
{
if (hasCurrentTeleportRequest())
llassert(mTeleportRequest != NULL);
if (mTeleportRequest != NULL)
{
mFailedTeleportRequest = mCurrentTeleportRequest;
mTeleportRequest->setStatus(LLTeleportRequest::kFailed);
}
if (mIsMaturityRatingChangingDuringTeleport)
{
@ -3905,8 +3926,8 @@ void LLAgent::teleportRequest(
// Landmark ID = LLUUID::null means teleport home
void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
{
mCurrentTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLandmark(landmark_asset_id));
mCurrentTeleportRequest->startTeleport();
mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLandmark(landmark_asset_id));
startTeleportRequest();
}
void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
@ -3926,8 +3947,8 @@ void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)
{
mCurrentTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLure(lure_id, godlike));
mCurrentTeleportRequest->startTeleport();
mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLure(lure_id, godlike));
startTeleportRequest();
}
void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike)
@ -3963,6 +3984,7 @@ void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike)
// James Cook, July 28, 2005
void LLAgent::teleportCancel()
{
clearTeleportRequest();
LLViewerRegion* regionp = getRegion();
if(regionp)
{
@ -3981,8 +4003,8 @@ void LLAgent::teleportCancel()
void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
{
mCurrentTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocation(pos_global));
mCurrentTeleportRequest->startTeleport();
mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocation(pos_global));
startTeleportRequest();
}
void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
@ -4029,8 +4051,8 @@ void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global)
// Teleport to global position, but keep facing in the same direction
void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global)
{
mCurrentTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocationLookAt(pos_global));
mCurrentTeleportRequest->startTeleport();
mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocationLookAt(pos_global));
startTeleportRequest();
}
void LLAgent::doTeleportViaLocationLookAt(const LLVector3d& pos_global)
@ -4473,6 +4495,7 @@ LLAgentQueryManager::~LLAgentQueryManager()
//-----------------------------------------------------------------------------
LLTeleportRequest::LLTeleportRequest()
: mStatus(kPending)
{
}

View File

@ -576,11 +576,9 @@ protected:
//--------------------------------------------------------------------
public:
inline bool hasCurrentTeleportRequest() {return (mCurrentTeleportRequest != NULL);};
inline bool hasFailedTeleportRequest() {return (mFailedTeleportRequest != NULL);};
bool hasRestartableFailedTeleportRequest();
void restartFailedTeleportRequest();
void clearFailedTeleportRequest();
void clearTeleportRequest();
void setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange);
private:
@ -590,14 +588,16 @@ private:
friend class LLTeleportRequestViaLocation;
friend class LLTeleportRequestViaLocationLookAt;
LLTeleportRequestPtr mCurrentTeleportRequest;
LLTeleportRequestPtr mFailedTeleportRequest;
LLTeleportRequestPtr mTeleportRequest;
boost::signals2::connection mTeleportFinishedSlot;
boost::signals2::connection mTeleportFailedSlot;
bool mIsMaturityRatingChangingDuringTeleport;
U8 mMaturityRatingChange;
bool hasPendingTeleportRequest();
void startTeleportRequest();
void teleportRequest(const U64& region_handle,
const LLVector3& pos_local, // Go to a named location home
bool look_at_from_camera = false);
@ -691,22 +691,21 @@ public:
void setMaturity(char text);
static int convertTextToMaturity(char text);
typedef boost::function<void (U8)> maturity_preferences_callback_t;
void setMaturityPreferenceAndConfirm(U32 preferredMaturity, maturity_preferences_callback_t pMaturityPreferencesCallback);
private:
bool mIsDoSendMaturityPreferenceToServer;
maturity_preferences_callback_t mMaturityPreferenceConfirmCallback;
unsigned int mMaturityPreferenceRequestId;
unsigned int mMaturityPreferenceResponseId;
unsigned int mMaturityPreferenceNumRetries;
U8 mLastKnownRequestMaturity;
U8 mLastKnownResponseMaturity;
bool isMaturityPreferenceSyncedWithServer() const;
void sendMaturityPreferenceToServer(U8 pPreferredMaturity);
friend class LLMaturityPreferencesResponder;
void handlePreferredMaturityResult(U8 pServerMaturity);
void handlePreferredMaturityError();
void reportPreferredMaturitySuccess();
void reportPreferredMaturityError();
// Maturity callbacks for PreferredMaturity control variable

View File

@ -5391,87 +5391,6 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
}
}
void handle_maturity_preference_change_and_reteleport(U8 pActualMaturityRating, U8 pRequestedMaturityRating)
{
bool isMaturityPreferenceElevated = false;
switch (pActualMaturityRating)
{
case SIM_ACCESS_MIN :
switch (pRequestedMaturityRating)
{
case SIM_ACCESS_MIN :
isMaturityPreferenceElevated = true;
break;
case SIM_ACCESS_PG :
case SIM_ACCESS_MATURE :
case SIM_ACCESS_ADULT :
default :
isMaturityPreferenceElevated = false;
break;
}
break;
case SIM_ACCESS_PG :
switch (pRequestedMaturityRating)
{
case SIM_ACCESS_MIN :
case SIM_ACCESS_PG :
isMaturityPreferenceElevated = true;
break;
case SIM_ACCESS_MATURE :
case SIM_ACCESS_ADULT :
default :
isMaturityPreferenceElevated = false;
break;
}
break;
case SIM_ACCESS_MATURE :
switch (pRequestedMaturityRating)
{
case SIM_ACCESS_MIN :
case SIM_ACCESS_PG :
case SIM_ACCESS_MATURE :
isMaturityPreferenceElevated = true;
break;
case SIM_ACCESS_ADULT :
default :
isMaturityPreferenceElevated = false;
break;
}
break;
case SIM_ACCESS_ADULT :
switch (pRequestedMaturityRating)
{
case SIM_ACCESS_MIN :
case SIM_ACCESS_PG :
case SIM_ACCESS_MATURE :
case SIM_ACCESS_ADULT :
isMaturityPreferenceElevated = true;
break;
default :
isMaturityPreferenceElevated = false;
break;
}
break;
default :
isMaturityPreferenceElevated = false;
break;
}
if (isMaturityPreferenceElevated)
{
gAgent.setMaturityRatingChangeDuringTeleport(pActualMaturityRating);
gAgent.restartFailedTeleportRequest();
}
else
{
LLSD args;
args["RATING"] = LLViewerRegion::accessToString(pRequestedMaturityRating);
LLNotificationsUtil::add("MaturityCouldNotBeChanged", args);
gAgent.clearFailedTeleportRequest();
}
}
bool handle_prompt_for_maturity_level_change_callback(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@ -5494,11 +5413,13 @@ bool handle_prompt_for_maturity_level_change_and_reteleport_callback(const LLSD&
{
// set the preference to the maturity of the region we're calling
U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger());
gAgent.setMaturityPreferenceAndConfirm(static_cast<U32>(preferredMaturity), boost::bind(&handle_maturity_preference_change_and_reteleport, _1, preferredMaturity));
gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity));
gAgent.setMaturityRatingChangeDuringTeleport(preferredMaturity);
gAgent.restartFailedTeleportRequest();
}
else
{
gAgent.clearFailedTeleportRequest();
gAgent.clearTeleportRequest();
}
return false;
@ -5519,7 +5440,7 @@ bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
{
if (gAgent.isTeen())
{
gAgent.clearFailedTeleportRequest();
gAgent.clearTeleportRequest();
maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock);
returnValue = true;
@ -5535,14 +5456,14 @@ bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
}
else
{
gAgent.clearFailedTeleportRequest();
gAgent.clearTeleportRequest();
maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
returnValue = true;
}
}
else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0)
{
gAgent.clearFailedTeleportRequest();
gAgent.clearTeleportRequest();
maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
returnValue = true;
}
@ -5551,7 +5472,7 @@ bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
{
if (!gAgent.isAdult())
{
gAgent.clearFailedTeleportRequest();
gAgent.clearTeleportRequest();
maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock);
returnValue = true;
@ -5567,14 +5488,14 @@ bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
}
else
{
gAgent.clearFailedTeleportRequest();
gAgent.clearTeleportRequest();
maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
returnValue = true;
}
}
else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0)
{
gAgent.clearFailedTeleportRequest();
gAgent.clearTeleportRequest();
maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback);
returnValue = true;
}

View File

@ -4173,17 +4173,6 @@ You won't receive any more notifications that you're about to visit a region wit
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="MaturityCouldNotBeChanged"
type="alertmodal">
We were unable to change your preferences to view [RATING] content at this time. Please change your preferences by using Me &gt; Preferences &gt; General from the menu bar, and then attempt your teleport again.
<tag>confirm</tag>
<usetemplate
name="okbutton"
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="MaturityChangeError"