diff options
author | Todd Stinson <stinson@lindenlab.com> | 2012-05-24 19:41:20 -0700 |
---|---|---|
committer | Todd Stinson <stinson@lindenlab.com> | 2012-05-24 19:41:20 -0700 |
commit | 55392ef7f6499c639b10e56646cf535742152682 (patch) | |
tree | 99fb336c7953ffbf966c20dde07d5854d7a1a4a3 | |
parent | 9b27e32a8d73e2f50a86562cf79f4ef637e83dae (diff) |
EXP-1942,EXP-1945: Altering behavior when setting maturity preference to check the server response in an effort to ensure the viewer and server remain in sync. This is a partial commit as I still need to add user behavior and notifications when things go wrong.
-rw-r--r-- | indra/llxml/llcontrol.cpp | 14 | ||||
-rw-r--r-- | indra/llxml/llcontrol.h | 8 | ||||
-rwxr-xr-x | indra/newview/llagent.cpp | 197 | ||||
-rw-r--r-- | indra/newview/llagent.h | 15 | ||||
-rwxr-xr-x | indra/newview/llfloaterpreference.cpp | 2 |
5 files changed, 179 insertions, 57 deletions
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 0809d95628..53d9380f4f 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -201,7 +201,8 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value) } LLSD storable_value = getComparableValue(new_value); - bool value_changed = llsd_compare(getValue(), storable_value) == FALSE; + LLSD original_value = getValue(); + bool value_changed = llsd_compare(original_value, storable_value) == FALSE; if(saved_value) { // If we're going to save this value, return to default but don't fire @@ -237,7 +238,7 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value) if(value_changed) { - mCommitSignal(this, storable_value); + firePropertyChanged(original_value); } } @@ -249,12 +250,13 @@ void LLControlVariable::setDefaultValue(const LLSD& value) // *NOTE: Default values are not saved, only read. LLSD comparable_value = getComparableValue(value); - bool value_changed = (llsd_compare(getValue(), comparable_value) == FALSE); + LLSD original_value = getValue(); + bool value_changed = (llsd_compare(original_value, comparable_value) == FALSE); resetToDefault(false); mValues[0] = comparable_value; if(value_changed) { - firePropertyChanged(); + firePropertyChanged(original_value); } } @@ -277,6 +279,8 @@ void LLControlVariable::resetToDefault(bool fire_signal) { //The first setting is always the default //Pop to it and fire off the listener + LLSD originalValue = mValues.back(); + while(mValues.size() > 1) { mValues.pop_back(); @@ -284,7 +288,7 @@ void LLControlVariable::resetToDefault(bool fire_signal) if(fire_signal) { - firePropertyChanged(); + firePropertyChanged(originalValue); } } diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 597031ec70..9a3a40e476 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -98,7 +98,7 @@ class LLControlVariable : public LLRefCount public: typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t; - typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&)> commit_signal_t; + typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&, const LLSD&)> commit_signal_t; private: std::string mName; @@ -146,11 +146,11 @@ public: void setHiddenFromSettingsEditor(bool hide); void setComment(const std::string& comment); - void firePropertyChanged() +private: + void firePropertyChanged(const LLSD &pPreviousValue) { - mCommitSignal(this, mValues.back()); + mCommitSignal(this, mValues.back(), pPreviousValue); } -private: LLSD getComparableValue(const LLSD& value); bool llsd_compare(const LLSD& a, const LLSD & b); }; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 1e0ec7f05b..804dec0b33 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" @@ -339,7 +340,11 @@ LLAgent::LLAgent() : mTeleportFailedSlot(), mIsMaturityRatingChangingDuringTeleport(false), mMaturityRatingChange(0U), + mIsDoSendMaturityPreferenceToServer(false), mMaturityPreferenceConfirmCallback(NULL), + mMaturityPerferenceMessageId(0U), + mPreferredMaturityValidateSlot(), + mPreferredMaturityCommitSlot(), mTeleportState( TELEPORT_NONE ), mRegionp(NULL), @@ -423,8 +428,9 @@ void LLAgent::init() *mEffectColor = LLUIColorTable::instance().getColor("EffectColor"); - gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2)); - gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2)); + mPreferredMaturityValidateSlot = gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2)); + mPreferredMaturityCommitSlot = gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2, _3)); + mIsDoSendMaturityPreferenceToServer = true; if (!mTeleportFinishedSlot.connected()) { @@ -2490,7 +2496,7 @@ int LLAgent::convertTextToMaturity(char text) class LLMaturityPreferencesResponder : public LLHTTPClient::Responder { public: - LLMaturityPreferencesResponder(LLAgent::maturity_preferences_callback_t pMaturityPreferencesCallback); + LLMaturityPreferencesResponder(LLAgent *pAgent, unsigned int pMessageId, U8 pPreferredMaturity, U8 pPreviousMaturity, LLAgent::maturity_preferences_callback_t pMaturityPreferencesCallback); virtual ~LLMaturityPreferencesResponder(); virtual void result(const LLSD &pContent); @@ -2499,11 +2505,21 @@ public: protected: private: + U8 parseMaturityFromServerResponse(const LLSD &pContent); + + LLAgent *mAgent; + unsigned int mMessageId; + U8 mPreferredMaturity; + U8 mPreviousMaturity; LLAgent::maturity_preferences_callback_t mMaturityPreferencesCallback; }; -LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent::maturity_preferences_callback_t pMaturityPreferencesCallback) +LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, unsigned int pMessageId, U8 pPreferredMaturity, U8 pPreviousMaturity, LLAgent::maturity_preferences_callback_t pMaturityPreferencesCallback) : LLHTTPClient::Responder(), + mAgent(pAgent), + mMessageId(pMessageId), + mPreferredMaturity(pPreferredMaturity), + mPreviousMaturity(pPreviousMaturity), mMaturityPreferencesCallback(pMaturityPreferencesCallback) { } @@ -2514,14 +2530,65 @@ LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder() void LLMaturityPreferencesResponder::result(const LLSD &pContent) { + U8 actualMaturity = parseMaturityFromServerResponse(pContent); + + if (actualMaturity == mPreferredMaturity) + { + llinfos << "succesfully changed 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(mMessageId, actualMaturity); + } + else + { + 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->handlePreferredMaturityUnexpectedResult(mMessageId, mPreferredMaturity, mPreviousMaturity, actualMaturity); + } + + if (!mMaturityPreferencesCallback.empty()) + { + mMaturityPreferencesCallback(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(mMessageId, mPreferredMaturity, mPreviousMaturity); if (!mMaturityPreferencesCallback.empty()) { - U8 actualPreferenceValue = SIM_ACCESS_MIN; + mMaturityPreferencesCallback(mPreviousMaturity); + } +} + +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 = mPreviousMaturity; + } + else + { llassert(!pContent.isUndefined()); llassert(pContent.isMap()); - + 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")); @@ -2533,7 +2600,7 @@ void LLMaturityPreferencesResponder::result(const LLSD &pContent) { LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString(); LLStringUtil::trim(actualPreference); - actualPreferenceValue = LLViewerRegion::shortStringToAccess(actualPreference); + maturity = LLViewerRegion::shortStringToAccess(actualPreference); } } else if (pContent.has("max")) @@ -2543,21 +2610,13 @@ void LLMaturityPreferencesResponder::result(const LLSD &pContent) { LLSD::String actualPreference = pContent.get("max").asString(); LLStringUtil::trim(actualPreference); - actualPreferenceValue = LLViewerRegion::shortStringToAccess(actualPreference); + maturity = LLViewerRegion::shortStringToAccess(actualPreference); } } } - - mMaturityPreferencesCallback(actualPreferenceValue); } -} -void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason) -{ - if (!mMaturityPreferencesCallback.empty()) - { - mMaturityPreferencesCallback(SIM_ACCESS_MIN); - } + return maturity; } void LLAgent::setMaturityPreferenceAndConfirm(U32 preferredMaturity, maturity_preferences_callback_t pMaturityPreferencesCallback) @@ -2573,39 +2632,87 @@ void LLAgent::setMaturityPreferenceAndConfirm(U32 preferredMaturity, maturity_pr mMaturityPreferenceConfirmCallback = NULL; } -bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity) +void LLAgent::handlePreferredMaturityResult(unsigned int pMessageId, U8 pServerMaturity) { - if (!getRegion()) - return false; - - // Update agent access preference on the server - std::string url = getRegion()->getCapability("UpdateAgentInformation"); - if (!url.empty()) + llassert(pMessageId <= mMaturityPerferenceMessageId); + if (pMessageId < mMaturityPerferenceMessageId) { - // Set new access preference - LLSD access_prefs = LLSD::emptyMap(); - if (preferredMaturity == SIM_ACCESS_PG) - { - access_prefs["max"] = "PG"; - } - else if (preferredMaturity == SIM_ACCESS_MATURE) + llwarns << "out of order result while changing maturity preference" << llendl; + } + U8 localMaturity = static_cast<U8>(gSavedSettings.getU32("PreferredMaturity")); + if (localMaturity != pServerMaturity) + { + bool tmpIsDoSendMaturityPreferenceToServer = mIsDoSendMaturityPreferenceToServer; + mIsDoSendMaturityPreferenceToServer = false; + llinfos << "Setting viewer preferred maturity to '" << LLViewerRegion::accessToString(pServerMaturity) << "'" << llendl; + gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(pServerMaturity)); + mIsDoSendMaturityPreferenceToServer = tmpIsDoSendMaturityPreferenceToServer; + } +} + +void LLAgent::handlePreferredMaturityError(unsigned int pMessageId, U8 pPreferredMaturity, U8 pPreviousMaturity) +{ + llassert(pMessageId <= mMaturityPerferenceMessageId); + if (pMessageId < mMaturityPerferenceMessageId) + { + llwarns << "out of order result while changing maturity preference" << llendl; + } + if (pMessageId == mMaturityPerferenceMessageId) + { + bool tmpIsDoSendMaturityPreferenceToServer = mIsDoSendMaturityPreferenceToServer; + mIsDoSendMaturityPreferenceToServer = false; + llinfos << "Setting viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreviousMaturity) << "'" << llendl; + gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(pPreviousMaturity)); + mIsDoSendMaturityPreferenceToServer = tmpIsDoSendMaturityPreferenceToServer; + } +} + +void LLAgent::handlePreferredMaturityUnexpectedResult(unsigned int pMessageId, U8 pPreferredMaturity, U8 pPreviousMaturity, U8 pServerMaturity) +{ + llassert(pMessageId <= mMaturityPerferenceMessageId); + if (pMessageId < mMaturityPerferenceMessageId) + { + llwarns << "out of order result while changing maturity preference" << llendl; + } + bool tmpIsDoSendMaturityPreferenceToServer = mIsDoSendMaturityPreferenceToServer; + mIsDoSendMaturityPreferenceToServer = false; + llinfos << "Setting viewer preferred maturity to '" << LLViewerRegion::accessToString(pServerMaturity) << "'" << llendl; + gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(pServerMaturity)); + mIsDoSendMaturityPreferenceToServer = tmpIsDoSendMaturityPreferenceToServer; +} + +void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity, U8 pPreviousMaturity) +{ + if (mIsDoSendMaturityPreferenceToServer) + { + LLHTTPClient::ResponderPtr responderPtr = LLHTTPClient::ResponderPtr(new LLMaturityPreferencesResponder(this, ++mMaturityPerferenceMessageId, pPreferredMaturity, pPreviousMaturity, mMaturityPreferenceConfirmCallback)); + if (getRegion() == NULL) { - access_prefs["max"] = "M"; + responderPtr->error(0U, "region is not defined"); } - if (preferredMaturity == SIM_ACCESS_ADULT) + else { - access_prefs["max"] = "A"; + // Update agent access preference on the server + std::string url = getRegion()->getCapability("UpdateAgentInformation"); + 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 access prefs update to " << (access_prefs["max"].asString()) << " 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::ResponderPtr responderPtr = LLHTTPClient::ResponderPtr(new LLMaturityPreferencesResponder(mMaturityPreferenceConfirmCallback)); - LLHTTPClient::post(url, body, responderPtr); - return true; } - return false; } BOOL LLAgent::getAdminOverride() const @@ -2638,9 +2745,9 @@ bool LLAgent::validateMaturity(const LLSD& newvalue) return mAgentAccess->canSetMaturity(newvalue.asInteger()); } -void LLAgent::handleMaturity(const LLSD& newvalue) +void LLAgent::handleMaturity(const LLSD &pNewValue, const LLSD &pPreviousValue) { - sendMaturityPreferenceToServer(newvalue.asInteger()); + sendMaturityPreferenceToServer(static_cast<U8>(pNewValue.asInteger()), static_cast<U8>(pPreviousValue.asInteger())); } //---------------------------------------------------------------------------- diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 1ca12f14b7..67f7c9c4f4 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -694,12 +694,21 @@ public: 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; - bool sendMaturityPreferenceToServer(int preferredMaturity); // ! "U8" instead of "int"? + unsigned int mMaturityPerferenceMessageId; + boost::signals2::connection mPreferredMaturityValidateSlot; + boost::signals2::connection mPreferredMaturityCommitSlot; + + void sendMaturityPreferenceToServer(U8 pPreferredMaturity, U8 pPreviousMaturity); // ! "U8" instead of "int"? + + friend class LLMaturityPreferencesResponder; + void handlePreferredMaturityResult(unsigned int pMessageId, U8 pServerMaturity); + void handlePreferredMaturityError(unsigned int pMessageId, U8 pPreferredMaturity, U8 pPreviousMaturity); + void handlePreferredMaturityUnexpectedResult(unsigned int pMessageId, U8 pPreferredMaturity, U8 pPreviousMaturity, U8 pServerMaturity); -public: // Maturity callbacks for PreferredMaturity control variable - void handleMaturity(const LLSD& newvalue); + void handleMaturity(const LLSD &pNewValue, const LLSD &pPreviousValue); bool validateMaturity(const LLSD& newvalue); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 173b0e538c..d6f5be9aae 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -435,6 +435,8 @@ BOOL LLFloaterPreference::postBuild() gSavedSettings.getControl("ChatBubbleOpacity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onNameTagOpacityChange, this, _2)); + gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeMaturity, this)); + LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core"); if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab"))) tabcontainer->selectFirstTab(); |