summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Stinson <stinson@lindenlab.com>2012-05-24 19:41:20 -0700
committerTodd Stinson <stinson@lindenlab.com>2012-05-24 19:41:20 -0700
commit55392ef7f6499c639b10e56646cf535742152682 (patch)
tree99fb336c7953ffbf966c20dde07d5854d7a1a4a3
parent9b27e32a8d73e2f50a86562cf79f4ef637e83dae (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.cpp14
-rw-r--r--indra/llxml/llcontrol.h8
-rwxr-xr-xindra/newview/llagent.cpp197
-rw-r--r--indra/newview/llagent.h15
-rwxr-xr-xindra/newview/llfloaterpreference.cpp2
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();