diff options
34 files changed, 1497 insertions, 530 deletions
@@ -301,6 +301,7 @@ c623bbc854b6f7ee1b33a3718f76715046aa2937 viewer-release-candidate 675668bd24d3bea570814f71762a2a806f7e1b8d viewer-release-candidate 675668bd24d3bea570814f71762a2a806f7e1b8d 3.3.2-release 675668bd24d3bea570814f71762a2a806f7e1b8d viewer-release-candidate +b9d0170b62eb1c7c3adaa37a0b13a833e5e659f9 DRTVWR-171 c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163 600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162 600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162 diff --git a/BuildParams b/BuildParams index 6f1af583f0..fc5dbdfbd6 100644 --- a/BuildParams +++ b/BuildParams @@ -112,6 +112,17 @@ viewer-mesh.login_channel = "Project Viewer - Mesh" viewer-mesh.viewer_grid = aditi viewer-mesh.email = shining@lists.lindenlab.com +# ======================================== +# viewer-adult-check +# ======================================== + +viewer-adult-check.viewer_channel = "Project Viewer - AdultCheck" +viewer-adult-check.login_channel = "Project Viewer - AdultCheck" +viewer-adult-check.viewer_grid = agni +viewer-adult-check.build_debug_release_separately = true +viewer-adult-check.build_CYGWIN_Debug = false +viewer-adult-check.build_viewer_update_version_manager = false + # ================ # oz # ================ diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 7aeeae298f..ef17fa4887 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1699,9 +1699,6 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para while ( LLUrlRegistry::instance().findUrl(text, match, boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) ) { - - LLTextUtil::processUrlMatch(&match,this); - start = match.getStart(); end = match.getEnd()+1; @@ -1737,6 +1734,8 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para } } + LLTextUtil::processUrlMatch(&match,this); + // move on to the rest of the text after the Url if (end < (S32)text.length()) { diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index 53cecf9d4a..8b356ba138 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -46,7 +46,7 @@ LLKeyStringTranslatorFunc* LLKeyboard::mStringTranslator = NULL; // Used for l10 // Class Implementation // -LLKeyboard::LLKeyboard() : mCallbacks(NULL), mNumpadDistinct(ND_NUMLOCK_OFF) +LLKeyboard::LLKeyboard() : mCallbacks(NULL) { S32 i; diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index ba472cfde5..c155c1b362 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -63,14 +63,6 @@ class LLWindowCallbacks; class LLKeyboard { public: - typedef enum e_numpad_distinct - { - ND_NEVER, - ND_NUMLOCK_OFF, - ND_NUMLOCK_ON - } ENumpadDistinct; - -public: LLKeyboard(); virtual ~LLKeyboard(); @@ -107,8 +99,6 @@ public: static BOOL keyFromString(const std::string& str, KEY *key); // False on failure static std::string stringFromKey(KEY key); static std::string stringFromAccelerator( MASK accel_mask, KEY key ); - e_numpad_distinct getNumpadDistinct() { return mNumpadDistinct; } - void setNumpadDistinct(e_numpad_distinct val) { mNumpadDistinct = val; } void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; } F32 getKeyElapsedTime( KEY key ); // Returns time in seconds since key was pressed. @@ -135,8 +125,6 @@ protected: static LLKeyStringTranslatorFunc* mStringTranslator; // Used for l10n + PC/Mac/Linux accelerator labeling - e_numpad_distinct mNumpadDistinct; - EKeyboardInsertMode mInsertMode; static std::map<KEY,std::string> sKeysToNames; diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp index ecc2631669..7f8f303517 100644 --- a/indra/llwindow/llkeyboardmacosx.cpp +++ b/indra/llwindow/llkeyboardmacosx.cpp @@ -299,28 +299,11 @@ void LLKeyboardMacOSX::scanKeyboard() BOOL LLKeyboardMacOSX::translateNumpadKey( const U16 os_key, KEY *translated_key ) { - if(mNumpadDistinct == ND_NUMLOCK_ON) - { - std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key); - if(iter != mTranslateNumpadMap.end()) - { - *translated_key = iter->second; - return TRUE; - } - } return translateKey(os_key, translated_key); } U16 LLKeyboardMacOSX::inverseTranslateNumpadKey(const KEY translated_key) { - if(mNumpadDistinct == ND_NUMLOCK_ON) - { - std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key); - if(iter != mInvTranslateNumpadMap.end()) - { - return iter->second; - } - } return inverseTranslateKey(translated_key); } diff --git a/indra/llwindow/llkeyboardsdl.cpp b/indra/llwindow/llkeyboardsdl.cpp index 4bb9603368..7c9aa1d340 100644 --- a/indra/llwindow/llkeyboardsdl.cpp +++ b/indra/llwindow/llkeyboardsdl.cpp @@ -312,29 +312,11 @@ void LLKeyboardSDL::scanKeyboard() BOOL LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key) { - if(mNumpadDistinct == ND_NUMLOCK_ON) - { - std::map<U16, KEY>::iterator iter= mTranslateNumpadMap.find(os_key); - if(iter != mTranslateNumpadMap.end()) - { - *translated_key = iter->second; - return TRUE; - } - } - BOOL success = translateKey(os_key, translated_key); - return success; + return translateKey(os_key, translated_key); } U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key) { - if(mNumpadDistinct == ND_NUMLOCK_ON) - { - std::map<KEY, U16>::iterator iter= mInvTranslateNumpadMap.find(translated_key); - if(iter != mInvTranslateNumpadMap.end()) - { - return iter->second; - } - } return inverseTranslateKey(translated_key); } diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp index df78816bd6..be3fe5deb0 100644 --- a/indra/llwindow/llkeyboardwin32.cpp +++ b/indra/llwindow/llkeyboardwin32.cpp @@ -299,69 +299,13 @@ void LLKeyboardWin32::scanKeyboard() BOOL LLKeyboardWin32::translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key) { - if(mNumpadDistinct == ND_NUMLOCK_ON) - { - std::map<U16, KEY>::iterator iter = mTranslateNumpadMap.find(os_key); - if (iter != mTranslateNumpadMap.end()) - { - *translated_key = iter->second; - return TRUE; - } - } - - BOOL success = translateKey(os_key, translated_key); - if(mNumpadDistinct != ND_NEVER) { - if(!success) return success; - if(mask & MASK_EXTENDED) - { - // this is where we'd create new keycodes for extended keys - // the set of extended keys includes the 'normal' arrow keys and - // the pgup/dn/insert/home/end/delete cluster above the arrow keys - // see http://windowssdk.msdn.microsoft.com/en-us/library/ms646280.aspx - - // only process the return key if numlock is off - if(((mNumpadDistinct == ND_NUMLOCK_OFF && - !(GetKeyState(VK_NUMLOCK) & 1)) - || mNumpadDistinct == ND_NUMLOCK_ON) && - *translated_key == KEY_RETURN) { - *translated_key = KEY_PAD_RETURN; - } - } - else - { - // the non-extended keys, those are in the numpad - switch (*translated_key) - { - case KEY_LEFT: - *translated_key = KEY_PAD_LEFT; break; - case KEY_RIGHT: - *translated_key = KEY_PAD_RIGHT; break; - case KEY_UP: - *translated_key = KEY_PAD_UP; break; - case KEY_DOWN: - *translated_key = KEY_PAD_DOWN; break; - case KEY_HOME: - *translated_key = KEY_PAD_HOME; break; - case KEY_END: - *translated_key = KEY_PAD_END; break; - case KEY_PAGE_UP: - *translated_key = KEY_PAD_PGUP; break; - case KEY_PAGE_DOWN: - *translated_key = KEY_PAD_PGDN; break; - case KEY_INSERT: - *translated_key = KEY_PAD_INS; break; - case KEY_DELETE: - *translated_key = KEY_PAD_DEL; break; - } - } - } - return success; + return translateKey(os_key, translated_key); } U16 LLKeyboardWin32::inverseTranslateExtendedKey(const KEY translated_key) { // if numlock is on, then we need to translate KEY_PAD_FOO to the corresponding number pad number - if((mNumpadDistinct == ND_NUMLOCK_ON) && (GetKeyState(VK_NUMLOCK) & 1)) + if(GetKeyState(VK_NUMLOCK) & 1) { std::map<KEY, U16>::iterator iter = mInvTranslateNumpadMap.find(translated_key); if (iter != mInvTranslateNumpadMap.end()) 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/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f874df5cb4..2c5960ccd5 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6356,17 +6356,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>NumpadControl</key> - <map> - <key>Comment</key> - <string>How numpad keys control your avatar. 0 = Like the normal arrow keys, 1 = Numpad moves avatar when numlock is off, 2 = Numpad moves avatar regardless of numlock (use this if you have no numlock)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>0</integer> - </map> <key>ObjectCacheEnabled</key> <map> <key>Comment</key> 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 diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 740770bbdf..a505d5bbae 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -35,6 +35,8 @@ #include "llcoordframe.h" // for mFrameAgent #include "llvoavatardefines.h" +#include <boost/function.hpp> +#include <boost/shared_ptr.hpp> #include <boost/signals2.hpp> extern const BOOL ANIMATE; @@ -56,6 +58,9 @@ class LLAgentAccess; class LLSLURL; class LLPauseRequestHandle; class LLUIColor; +class LLTeleportRequest; + +typedef boost::shared_ptr<LLTeleportRequest> LLTeleportRequestPtr; //-------------------------------------------------------------------- // Types @@ -539,7 +544,8 @@ public: TELEPORT_MOVING = 3, // Viewer has received destination location from source simulator TELEPORT_START_ARRIVAL = 4, // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator TELEPORT_ARRIVING = 5, // Make the user wait while content "pre-caches" - TELEPORT_LOCAL = 6 // Teleporting in-sim without showing the progress screen + TELEPORT_LOCAL = 6, // Teleporting in-sim without showing the progress screen + TELEPORT_PENDING = 7 }; public: @@ -556,9 +562,6 @@ private: // Teleport Actions //-------------------------------------------------------------------- public: - void teleportRequest(const U64& region_handle, - const LLVector3& pos_local, // Go to a named location home - bool look_at_from_camera = false); void teleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark void teleportHome() { teleportViaLandmark(LLUUID::null); } // Go home void teleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location @@ -572,6 +575,44 @@ protected: //-------------------------------------------------------------------- // Teleport State //-------------------------------------------------------------------- + +public: + bool hasRestartableFailedTeleportRequest(); + void restartFailedTeleportRequest(); + void clearTeleportRequest(); + void setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange); + +private: + friend class LLTeleportRequest; + friend class LLTeleportRequestViaLandmark; + friend class LLTeleportRequestViaLure; + friend class LLTeleportRequestViaLocation; + friend class LLTeleportRequestViaLocationLookAt; + + 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); + void doTeleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark + void doTeleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location + void doTeleportViaLocation(const LLVector3d& pos_global); // To a global location - this will probably need to be deprecated + void doTeleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation + + void handleTeleportFinished(); + void handleTeleportFailed(); + + //-------------------------------------------------------------------- + // Teleport State + //-------------------------------------------------------------------- public: ETeleportState getTeleportState() const { return mTeleportState; } void setTeleportState(ETeleportState state); @@ -614,8 +655,6 @@ public: const LLAgentAccess& getAgentAccess(); BOOL canManageEstate() const; BOOL getAdminOverride() const; - // ! BACKWARDS COMPATIBILITY ! This function can go away after the AO transition (see llstartup.cpp). - void setAOTransition(); private: LLAgentAccess * mAgentAccess; @@ -650,13 +689,28 @@ public: bool isTeen() const; bool isMature() const; bool isAdult() const; - void setTeen(bool teen); void setMaturity(char text); - static int convertTextToMaturity(char text); - bool sendMaturityPreferenceToServer(int preferredMaturity); // ! "U8" instead of "int"? + static int convertTextToMaturity(char text); + +private: + bool mIsDoSendMaturityPreferenceToServer; + 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 - void handleMaturity(const LLSD& newvalue); + void handleMaturity(const LLSD &pNewValue); bool validateMaturity(const LLSD& newvalue); diff --git a/indra/newview/llagentaccess.cpp b/indra/newview/llagentaccess.cpp index 08a33ab04a..c4ee321e04 100644 --- a/indra/newview/llagentaccess.cpp +++ b/indra/newview/llagentaccess.cpp @@ -33,8 +33,7 @@ LLAgentAccess::LLAgentAccess(LLControlGroup& savedSettings) : mSavedSettings(savedSettings), mAccess(SIM_ACCESS_PG), mAdminOverride(false), - mGodLevel(GOD_NOT), - mAOTransition(false) + mGodLevel(GOD_NOT) { } @@ -133,18 +132,6 @@ bool LLAgentAccess::isAdult() const return mAccess >= SIM_ACCESS_ADULT; } -void LLAgentAccess::setTeen(bool teen) -{ - if (teen) - { - mAccess = SIM_ACCESS_PG; - } - else - { - mAccess = SIM_ACCESS_MATURE; - } -} - //static int LLAgentAccess::convertTextToMaturity(char text) { @@ -182,16 +169,6 @@ void LLAgentAccess::setMaturity(char text) mSavedSettings.setU32("PreferredMaturity", preferred_access); } -void LLAgentAccess::setTransition() -{ - mAOTransition = true; -} - -bool LLAgentAccess::isInTransition() const -{ - return mAOTransition; -} - bool LLAgentAccess::canSetMaturity(S32 maturity) { if (isGodlike()) // Gods can always set their Maturity level diff --git a/indra/newview/llagentaccess.h b/indra/newview/llagentaccess.h index 2e98e4eea1..4e851b0aa0 100644 --- a/indra/newview/llagentaccess.h +++ b/indra/newview/llagentaccess.h @@ -59,13 +59,10 @@ public: bool isMature() const; bool isAdult() const; - void setTeen(bool teen); void setMaturity(char text); static int convertTextToMaturity(char text); - void setTransition(); // sets the transition bit, which defaults to false - bool isInTransition() const; bool canSetMaturity(S32 maturity); private: @@ -73,13 +70,6 @@ private: U8 mGodLevel; bool mAdminOverride; - // this should be deleted after the 60-day AO transition. - // It should be safe to remove it in Viewer 2009 - // It's set by a special short-term flag in login.cgi - // called ao_transition. When that's gone, this can go, along with - // all of the code that depends on it. - bool mAOTransition; - LLControlGroup& mSavedSettings; }; diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index ee18c95b34..c503f70789 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -1865,23 +1865,8 @@ BOOL LLPanelLandOptions::postBuild() childSetCommitCallback("ShowDirectoryCheck", onCommitAny, this); - if (gAgent.getAgentAccess().isInTransition()) - { - // during the AO transition, this combo has an Adult item. - // Post-transition, it goes away. We can remove this conditional - // after the transition and just use the "else" clause. - mCategoryCombo = getChild<LLComboBox>( "land category with adult"); - childSetCommitCallback("land category with adult", onCommitAny, this); - } - else - { - // this is the code that should be preserved post-transition - // you could also change the XML to set visibility and enabled true. - mCategoryCombo = getChild<LLComboBox>( "land category"); - childSetCommitCallback("land category", onCommitAny, this); - } - mCategoryCombo->setVisible(true); - mCategoryCombo->setEnabled(true); + mCategoryCombo = getChild<LLComboBox>( "land category"); + childSetCommitCallback("land category", onCommitAny, this); mMatureCtrl = getChild<LLCheckBoxCtrl>( "MatureCheck"); 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(); diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 7c6287967a..16c51138a9 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -128,6 +128,8 @@ const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"), FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"), SERVER_OBJECT_MESSAGE("ServerObjectMessage"), TELEPORT_OFFERED("TeleportOffered"), + TELEPORT_OFFERED_MATURITY_EXCEEDED("TeleportOffered_MaturityExceeded"), + TELEPORT_OFFERED_MATURITY_BLOCKED("TeleportOffered_MaturityBlocked"), TELEPORT_OFFER_SENT("TeleportOfferSent"), IM_SYSTEM_MESSAGE_TIP("IMSystemMessageTip"); @@ -149,6 +151,8 @@ bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification) || INVENTORY_DECLINED == notification->getName() || USER_GIVE_ITEM == notification->getName() || TELEPORT_OFFERED == notification->getName() + || TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName() + || TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName() || TELEPORT_OFFER_SENT == notification->getName() || IM_SYSTEM_MESSAGE_TIP == notification->getName(); } @@ -169,7 +173,9 @@ bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification) { return OFFER_FRIENDSHIP == notification->getName() || USER_GIVE_ITEM == notification->getName() - || TELEPORT_OFFERED == notification->getName(); + || TELEPORT_OFFERED == notification->getName() + || TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName() + || TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName(); } // static @@ -177,7 +183,9 @@ bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification) { return OFFER_FRIENDSHIP == notification->getName() || USER_GIVE_ITEM == notification->getName() - || TELEPORT_OFFERED == notification->getName(); + || TELEPORT_OFFERED == notification->getName() + || TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName() + || TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName(); } // static @@ -185,7 +193,9 @@ bool LLHandlerUtil::isNotificationReusable(const LLNotificationPtr& notification { return OFFER_FRIENDSHIP == notification->getName() || USER_GIVE_ITEM == notification->getName() - || TELEPORT_OFFERED == notification->getName(); + || TELEPORT_OFFERED == notification->getName() + || TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName() + || TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName(); } // static @@ -212,7 +222,9 @@ bool LLHandlerUtil::canSpawnToast(const LLNotificationPtr& notification) if(OFFER_FRIENDSHIP == notification->getName() || USER_GIVE_ITEM == notification->getName() - || TELEPORT_OFFERED == notification->getName()) + || TELEPORT_OFFERED == notification->getName() + || TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName() + || TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName()) { // When ANY offer arrives, show toast, unless IM window is already open - EXT-5904 return ! isIMFloaterOpened(notification); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 6b0fc26db7..50e50ce63a 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -3215,17 +3215,6 @@ bool process_login_success_response() gSavedSettings.setU32("PreferredMaturity", preferredMaturity); } - // During the AO transition, this flag will be true. Then the flag will - // go away. After the AO transition, this code and all the code that - // uses it can be deleted. - text = response["ao_transition"].asString(); - if (!text.empty()) - { - if (text == "1") - { - gAgent.setAOTransition(); - } - } text = response["start_location"].asString(); if(!text.empty()) diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index a473ee7ce0..d629f3abac 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -457,7 +457,7 @@ button_name_set_t getButtonDisableList(const std::string& notification_name, con { search_map = user_give_item_disable_map; } - else if("TeleportOffered" == notification_name) + else if(("TeleportOffered" == notification_name) || ("TeleportOffered_MaturityExceeded" == notification_name)) { search_map = teleport_offered_disable_map; } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index f2712e7590..e5d75c9f9f 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -337,15 +337,6 @@ static bool handleUploadBakedTexOldChanged(const LLSD& newvalue) } -static bool handleNumpadControlChanged(const LLSD& newvalue) -{ - if (gKeyboard) - { - gKeyboard->setNumpadDistinct(static_cast<LLKeyboard::e_numpad_distinct>(newvalue.asInteger())); - } - return true; -} - static bool handleWLSkyDetailChanged(const LLSD&) { if (gSky.mVOWLSkyp.notNull()) @@ -637,7 +628,6 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2)); - gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2)); gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 0adb187dd2..1afe0d4050 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -383,15 +383,24 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) const std::string& message = gAgent.getTeleportMessage(); switch( gAgent.getTeleportState() ) { + case LLAgent::TELEPORT_PENDING: + gTeleportDisplayTimer.reset(); + gViewerWindow->setShowProgress(TRUE); + gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); + gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["pending"]); + gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["pending"]); + break; + case LLAgent::TELEPORT_START: // Transition to REQUESTED. Viewer has sent some kind // of TeleportRequest to the source simulator gTeleportDisplayTimer.reset(); gViewerWindow->setShowProgress(TRUE); - gViewerWindow->setProgressPercent(0); + gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["requesting"]); + gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["requesting"]); break; case LLAgent::TELEPORT_REQUESTED: diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c9af6a2820..b92354dcf4 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -300,7 +300,6 @@ BOOL enable_buy_land(void*); void handle_test_male(void *); void handle_test_female(void *); -void handle_toggle_pg(void*); void handle_dump_attachments(void *); void handle_dump_avatar_local_textures(void*); void handle_debug_avatar_textures(void*); @@ -1643,23 +1642,6 @@ class LLAdvancedTestFemale : public view_listener_t } }; - - -/////////////// -// TOGGLE PG // -/////////////// - - -class LLAdvancedTogglePG : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - handle_toggle_pg(NULL); - return true; - } -}; - - class LLAdvancedForceParamsToDefault : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -6746,15 +6728,6 @@ void handle_test_female(void*) //gGestureList.requestResetFromServer( FALSE ); } -void handle_toggle_pg(void*) -{ - gAgent.setTeen( !gAgent.isTeen() ); - - LLFloaterWorldMap::reloadIcons(NULL); - - llinfos << "PG status set to " << (S32)gAgent.isTeen() << llendl; -} - void handle_dump_attachments(void*) { if(!isAgentAvatarValid()) return; @@ -8322,7 +8295,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale"); view_listener_t::addMenu(new LLAdvancedTestFemale(), "Advanced.TestFemale"); - view_listener_t::addMenu(new LLAdvancedTogglePG(), "Advanced.TogglePG"); // Advanced > Character (toplevel) view_listener_t::addMenu(new LLAdvancedForceParamsToDefault(), "Advanced.ForceParamsToDefault"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 1813611c35..a07dfad0f5 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -42,6 +42,7 @@ #include "llinventorydefines.h" #include "lllslconstants.h" #include "llregionhandle.h" +#include "llsd.h" #include "llsdserialize.h" #include "llteleportflags.h" #include "lltransactionflags.h" @@ -107,6 +108,7 @@ #include "llagentui.h" #include "llpanelblockedlist.h" #include "llpanelplaceprofile.h" +#include "llviewerregion.h" #include <boost/algorithm/string/split.hpp> // #include <boost/regex.hpp> @@ -1992,6 +1994,46 @@ bool lure_callback(const LLSD& notification, const LLSD& response) } static LLNotificationFunctorRegistration lure_callback_reg("TeleportOffered", lure_callback); +bool mature_lure_callback(const LLSD& notification, const LLSD& response) +{ + S32 option = 0; + if (response.isInteger()) + { + option = response.asInteger(); + } + else + { + option = LLNotificationsUtil::getSelectedOption(notification, response); + } + + LLUUID from_id = notification["payload"]["from_id"].asUUID(); + LLUUID lure_id = notification["payload"]["lure_id"].asUUID(); + BOOL godlike = notification["payload"]["godlike"].asBoolean(); + U8 region_access = static_cast<U8>(notification["payload"]["region_maturity"].asInteger()); + + switch(option) + { + case 0: + { + // accept + gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(region_access)); + gAgent.setMaturityRatingChangeDuringTeleport(region_access); + gAgent.teleportViaLure(lure_id, godlike); + } + break; + case 1: + default: + // decline + send_simple_im(from_id, + LLStringUtil::null, + IM_LURE_DECLINED, + lure_id); + break; + } + return false; +} +static LLNotificationFunctorRegistration mature_lure_callback_reg("TeleportOffered_MaturityExceeded", mature_lure_callback); + bool goto_url_callback(const LLSD& notification, const LLSD& response) { std::string url = notification["payload"]["url"].asString(); @@ -2879,15 +2921,54 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { LLVector3 pos, look_at; U64 region_handle(0); - U8 region_access(0); + U8 region_access(SIM_ACCESS_MIN); std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size); std::string region_access_str = LLStringUtil::null; std::string region_access_icn = LLStringUtil::null; + std::string region_access_lc = LLStringUtil::null; + + bool canUserAccessDstRegion = true; + bool doesUserRequireMaturityIncrease = false; if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access)) { region_access_str = LLViewerRegion::accessToString(region_access); region_access_icn = LLViewerRegion::getAccessIcon(region_access); + region_access_lc = region_access_str; + LLStringUtil::toLower(region_access_lc); + + if (!gAgent.isGodlike()) + { + switch (region_access) + { + case SIM_ACCESS_MIN : + case SIM_ACCESS_PG : + break; + case SIM_ACCESS_MATURE : + if (gAgent.isTeen()) + { + canUserAccessDstRegion = false; + } + else if (gAgent.prefersPG()) + { + doesUserRequireMaturityIncrease = true; + } + break; + case SIM_ACCESS_ADULT : + if (!gAgent.isAdult()) + { + canUserAccessDstRegion = false; + } + else if (!gAgent.prefersAdult()) + { + doesUserRequireMaturityIncrease = true; + } + break; + default : + llassert(0); + break; + } + } } LLSD args; @@ -2896,28 +2977,130 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) args["MESSAGE"] = message; args["MATURITY_STR"] = region_access_str; args["MATURITY_ICON"] = region_access_icn; + args["REGION_CONTENT_MATURITY"] = region_access_lc; LLSD payload; payload["from_id"] = from_id; payload["lure_id"] = session_id; payload["godlike"] = FALSE; + payload["region_maturity"] = region_access; + + if (!canUserAccessDstRegion) + { + LLNotification::Params params("TeleportOffered_MaturityBlocked"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id); + send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id); + } + else if (doesUserRequireMaturityIncrease) + { + LLNotification::Params params("TeleportOffered_MaturityExceeded"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + } + else + { + LLNotification::Params params("TeleportOffered"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + } - LLNotification::Params params("TeleportOffered"); - params.substitutions = args; - params.payload = payload; - LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); } } break; case IM_GODLIKE_LURE_USER: { + LLVector3 pos, look_at; + U64 region_handle(0); + U8 region_access(SIM_ACCESS_MIN); + std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size); + std::string region_access_str = LLStringUtil::null; + std::string region_access_icn = LLStringUtil::null; + std::string region_access_lc = LLStringUtil::null; + + bool canUserAccessDstRegion = true; + bool doesUserRequireMaturityIncrease = false; + + if (parse_lure_bucket(region_info, region_handle, pos, look_at, region_access)) + { + region_access_str = LLViewerRegion::accessToString(region_access); + region_access_icn = LLViewerRegion::getAccessIcon(region_access); + region_access_lc = region_access_str; + LLStringUtil::toLower(region_access_lc); + + if (!gAgent.isGodlike()) + { + switch (region_access) + { + case SIM_ACCESS_MIN : + case SIM_ACCESS_PG : + break; + case SIM_ACCESS_MATURE : + if (gAgent.isTeen()) + { + canUserAccessDstRegion = false; + } + else if (gAgent.prefersPG()) + { + doesUserRequireMaturityIncrease = true; + } + break; + case SIM_ACCESS_ADULT : + if (!gAgent.isAdult()) + { + canUserAccessDstRegion = false; + } + else if (!gAgent.prefersAdult()) + { + doesUserRequireMaturityIncrease = true; + } + break; + default : + llassert(0); + break; + } + } + } + + LLSD args; + // *TODO: Translate -> [FIRST] [LAST] (maybe) + args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString(); + args["MESSAGE"] = message; + args["MATURITY_STR"] = region_access_str; + args["MATURITY_ICON"] = region_access_icn; + args["REGION_CONTENT_MATURITY"] = region_access_lc; LLSD payload; payload["from_id"] = from_id; payload["lure_id"] = session_id; payload["godlike"] = TRUE; - // do not show a message box, because you're about to be - // teleported. - LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); + payload["region_maturity"] = region_access; + + if (!canUserAccessDstRegion) + { + LLNotification::Params params("TeleportOffered_MaturityBlocked"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + send_simple_im(from_id, LLTrans::getString("TeleportMaturityExceeded"), IM_NOTHING_SPECIAL, session_id); + send_simple_im(from_id, LLStringUtil::null, IM_LURE_DECLINED, session_id); + } + else if (doesUserRequireMaturityIncrease) + { + LLNotification::Params params("TeleportOffered_MaturityExceeded"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + } + else + { + // do not show a message box, because you're about to be + // teleported. + LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); + } } break; @@ -5398,23 +5581,35 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) } } - - -bool handle_special_notification_callback(const LLSD& notification, const LLSD& response) +bool handle_prompt_for_maturity_level_change_callback(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (0 == option) { // set the preference to the maturity of the region we're calling - int preferredMaturity = notification["payload"]["_region_access"].asInteger(); - gSavedSettings.setU32("PreferredMaturity", preferredMaturity); - gAgent.sendMaturityPreferenceToServer(preferredMaturity); + U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger()); + gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity)); + } + + return false; +} - // notify user that the maturity preference has been changed - LLSD args; - args["RATING"] = LLViewerRegion::accessToString(preferredMaturity); - LLNotificationsUtil::add("PreferredMaturityChanged", args); +bool handle_prompt_for_maturity_level_change_and_reteleport_callback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + if (0 == option) + { + // set the preference to the maturity of the region we're calling + U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger()); + gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity)); + gAgent.setMaturityRatingChangeDuringTeleport(preferredMaturity); + gAgent.restartFailedTeleportRequest(); + } + else + { + gAgent.clearTeleportRequest(); } return false; @@ -5423,39 +5618,148 @@ bool handle_special_notification_callback(const LLSD& notification, const LLSD& // some of the server notifications need special handling. This is where we do that. bool handle_special_notification(std::string notificationID, LLSD& llsdBlock) { - int regionAccess = llsdBlock["_region_access"].asInteger(); - llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess); + U8 regionAccess = static_cast<U8>(llsdBlock["_region_access"].asInteger()); + std::string regionMaturity = LLViewerRegion::accessToString(regionAccess); + LLStringUtil::toLower(regionMaturity); + llsdBlock["REGIONMATURITY"] = regionMaturity; - // we're going to throw the LLSD in there in case anyone ever wants to use it - LLNotificationsUtil::add(notificationID+"_Notify", llsdBlock); + bool returnValue = false; + LLNotificationPtr maturityLevelNotification; + std::string notifySuffix = "_Notify"; + if (regionAccess == SIM_ACCESS_MATURE) + { + if (gAgent.isTeen()) + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; + } + else if (gAgent.prefersPG()) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock); + returnValue = true; + } + } + else if (regionAccess == SIM_ACCESS_ADULT) + { + if (!gAgent.isAdult()) + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; + } + else if (gAgent.prefersPG() || gAgent.prefersMature()) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock); + returnValue = true; + } + } + + if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored()) + { + // Given a simple notification if no maturityLevelNotification is set or it is ignore + LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock); + } + + return returnValue; +} + +// some of the server notifications need special handling. This is where we do that. +bool handle_teleport_access_blocked(LLSD& llsdBlock) +{ + std::string notificationID("TeleportEntryAccessBlocked"); + U8 regionAccess = static_cast<U8>(llsdBlock["_region_access"].asInteger()); + std::string regionMaturity = LLViewerRegion::accessToString(regionAccess); + LLStringUtil::toLower(regionMaturity); + llsdBlock["REGIONMATURITY"] = regionMaturity; + bool returnValue = false; + LLNotificationPtr maturityLevelNotification; + std::string notifySuffix = "_Notify"; if (regionAccess == SIM_ACCESS_MATURE) { if (gAgent.isTeen()) { - LLNotificationsUtil::add(notificationID+"_KB", llsdBlock); - return true; + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; } else if (gAgent.prefersPG()) { - LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback); - return true; + if (gAgent.hasRestartableFailedTeleportRequest()) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback); + returnValue = true; + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; } } else if (regionAccess == SIM_ACCESS_ADULT) { if (!gAgent.isAdult()) { - LLNotificationsUtil::add(notificationID+"_KB", llsdBlock); - return true; + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; } else if (gAgent.prefersPG() || gAgent.prefersMature()) { - LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback); - return true; + if (gAgent.hasRestartableFailedTeleportRequest()) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback); + returnValue = true; + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; } } - return false; + + if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored()) + { + // Given a simple notification if no maturityLevelNotification is set or it is ignore + LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock); + } + + return returnValue; } bool attempt_standard_notification(LLMessageSystem* msgsystem) @@ -5499,16 +5803,20 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem) RegionEntryAccessBlocked RegionEntryAccessBlocked_Notify + RegionEntryAccessBlocked_NotifyAdultsOnly RegionEntryAccessBlocked_Change - RegionEntryAccessBlocked_KB + RegionEntryAccessBlocked_AdultsOnlyContent + RegionEntryAccessBlocked_ChangeAndReTeleport LandClaimAccessBlocked LandClaimAccessBlocked_Notify + LandClaimAccessBlocked_NotifyAdultsOnly LandClaimAccessBlocked_Change - LandClaimAccessBlocked_KB + LandClaimAccessBlocked_AdultsOnlyContent LandBuyAccessBlocked LandBuyAccessBlocked_Notify + LandBuyAccessBlocked_NotifyAdultsOnly LandBuyAccessBlocked_Change - LandBuyAccessBlocked_KB + LandBuyAccessBlocked_AdultsOnlyContent -----------------------------------------------------------------------*/ if (handle_special_notification(notificationID, llsdBlock)) @@ -5560,6 +5868,30 @@ void process_alert_message(LLMessageSystem *msgsystem, void **user_data) } } +bool handle_not_age_verified_alert(const std::string &pAlertName) +{ + LLNotificationPtr notification = LLNotificationsUtil::add(pAlertName); + if ((notification == NULL) || notification->isIgnored()) + { + LLNotificationsUtil::add(pAlertName + "_Notify"); + } + + return true; +} + +bool handle_special_alerts(const std::string &pAlertName) +{ + bool isHandled = false; + + if (LLStringUtil::compareStrings(pAlertName, "NotAgeVerified") == 0) + { + + isHandled = handle_not_age_verified_alert(pAlertName); + } + + return isHandled; +} + void process_alert_core(const std::string& message, BOOL modal) { // HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml @@ -5583,7 +5915,10 @@ void process_alert_core(const std::string& message, BOOL modal) // Allow the server to spawn a named alert so that server alerts can be // translated out of English. std::string alert_name(message.substr(ALERT_PREFIX.length())); - LLNotificationsUtil::add(alert_name); + if (!handle_special_alerts(alert_name)) + { + LLNotificationsUtil::add(alert_name); + } } else if (message.find(NOTIFY_PREFIX) == 0) { @@ -6169,6 +6504,9 @@ void process_teleport_failed(LLMessageSystem *msg, void**) std::string big_reason; LLSD args; + // Let the interested parties know that teleport failed. + LLViewerParcelMgr::getInstance()->onTeleportFailed(); + // if we have additional alert data if (msg->has(_PREHASH_AlertInfo) && msg->getSizeFast(_PREHASH_AlertInfo, _PREHASH_Message) > 0) { @@ -6198,7 +6536,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**) else { // change notification name in this special case - if (handle_special_notification("RegionEntryAccessBlocked", llsd_block)) + if (handle_teleport_access_blocked(llsd_block)) { if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE ) { @@ -6227,9 +6565,6 @@ void process_teleport_failed(LLMessageSystem *msg, void**) LLNotificationsUtil::add("CouldNotTeleportReason", args); - // Let the interested parties know that teleport failed. - LLViewerParcelMgr::getInstance()->onTeleportFailed(); - if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE ) { gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index e3cb985ddb..f3771e93d9 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -655,6 +655,31 @@ std::string LLViewerRegion::accessToShortString(U8 sim_access) } // static +U8 LLViewerRegion::shortStringToAccess(const std::string &sim_access) +{ + U8 accessValue; + + if (LLStringUtil::compareStrings(sim_access, "PG") == 0) + { + accessValue = SIM_ACCESS_PG; + } + else if (LLStringUtil::compareStrings(sim_access, "M") == 0) + { + accessValue = SIM_ACCESS_MATURE; + } + else if (LLStringUtil::compareStrings(sim_access, "A") == 0) + { + accessValue = SIM_ACCESS_ADULT; + } + else + { + accessValue = SIM_ACCESS_MIN; + } + + return accessValue; +} + +// static void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**) { // send it to 'observers' diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index c483c6ef52..7280c7f2e6 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -202,6 +202,7 @@ public: // Returns "M", "PG", "A" etc. static std::string accessToShortString(U8 sim_access); + static U8 shortStringToAccess(const std::string &sim_access); // Return access icon name static std::string getAccessIcon(U8 sim_access); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 39e330ad66..fc6ef170c8 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1704,9 +1704,6 @@ LLViewerWindow::LLViewerWindow(const Params& p) // Can't have spaces in settings.ini strings, so use underscores instead and convert them. LLStringUtil::replaceChar(mOverlayTitle, '_', ' '); - // sync the keyboard's setting with the saved setting - gSavedSettings.getControl("NumpadControl")->firePropertyChanged(); - mDebugText = new LLDebugText(this); mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale); diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index fb123ec4d1..793a6e6fa1 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1354,79 +1354,13 @@ Only large parcels can be listed in search. top="150" width="430" /> <combo_box - enabled="false" - height="23" - layout="topleft" - left="20" - top="194" - name="land category with adult" - visible="false" - width="140"> - <combo_box.item - label="Any Category" - name="item0" - value="any" /> - <combo_box.item - label="Linden Location" - name="item1" - value="linden" /> - <combo_box.item - label="Adult" - name="item2" - value="adult" /> - <combo_box.item - label="Arts & Culture" - name="item3" - value="arts" /> - <combo_box.item - label="Business" - name="item4" - value="store" /> - <combo_box.item - label="Educational" - name="item5" - value="educational" /> - <combo_box.item - label="Gaming" - name="item6" - value="game" /> - <combo_box.item - label="Hangout" - name="item7" - value="gather" /> - <combo_box.item - label="Newcomer Friendly" - name="item8" - value="newcomer" /> - <combo_box.item - label="Parks & Nature" - name="item9" - value="park" /> - <combo_box.item - label="Residential" - name="item10" - value="home" /> - <combo_box.item - label="Shopping" - name="item11" - value="shopping" /> - <combo_box.item - label="Rental" - name="item13" - value="rental" /> - <combo_box.item - label="Other" - name="item12" - value="other" /> - </combo_box> - <combo_box - enabled="false" + enabled="true" height="23" layout="topleft" left="20" top="194" name="land category" - visible="false" + visible="true" width="140"> <combo_box.item label="Any Category" @@ -1989,11 +1923,11 @@ Only large parcels can be listed in search. <check_box follows="top|left" height="16" - label="Have been age-verified [ESTATE_AGE_LIMIT]" + label="Are age 18 or older [ESTATE_AGE_LIMIT]" layout="topleft" left_delta="0" name="limit_age_verified" - tool_tip="Residents must be age verified to access this parcel. See the [SUPPORT_SITE] for more information." + tool_tip="Residents must be age 18 or older to access this parcel. See the [SUPPORT_SITE] for more information." top_pad="4" width="278" /> <check_box diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 570ea3994d..6bcdc615c3 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3131,12 +3131,6 @@ <menu_item_call.on_click function="Advanced.TestFemale" /> </menu_item_call> - <menu_item_call - label="Toggle PG" - name="Toggle PG"> - <menu_item_call.on_click - function="Advanced.TogglePG" /> - </menu_item_call> <menu_item_check label="Allow Select Avatar" name="Allow Select Avatar"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index a26c5bb344..72454a1a1a 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4089,9 +4089,7 @@ Are you sure you want to change the Estate Covenant? name="RegionEntryAccessBlocked" type="alertmodal"> <tag>fail</tag> -You are not allowed in that Region due to your maturity Rating. This may be a result of a lack of information validating your age. - -Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. + The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me > Preferences > General. <usetemplate name="okbutton" yestext="OK"/> @@ -4099,13 +4097,11 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base <notification icon="alertmodal.tga" - name="RegionEntryAccessBlocked_KB" + name="RegionEntryAccessBlocked_AdultsOnlyContent" type="alertmodal"> <tag>fail</tag> <tag>confirm</tag> -You are not allowed in that region due to your maturity Rating. - -Go to the Knowledge Base for more information about maturity Ratings? + The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only. <url option="0" name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview </url> @@ -4113,7 +4109,7 @@ Go to the Knowledge Base for more information about maturity Ratings? name="okcancelignore" yestext="Go to Knowledge Base" notext="Close" - ignoretext="I can't enter this Region, due to restrictions of the maturity Rating"/> + ignoretext="Region crossing: The region you're trying to visit contains content which is accessible to adults only."/> </notification> <notification @@ -4121,47 +4117,156 @@ Go to the Knowledge Base for more information about maturity Ratings? name="RegionEntryAccessBlocked_Notify" type="notifytip"> <tag>fail</tag> -You are not allowed in that region due to your maturity Rating. +The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. + </notification> + + <notification + icon="notifytip.tga" + name="RegionEntryAccessBlocked_NotifyAdultsOnly" + type="notifytip"> + <tag>fail</tag> + The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only. </notification> <notification icon="alertmodal.tga" name="RegionEntryAccessBlocked_Change" type="alertmodal"> - <tag>fail</tag> + <tag>fail</tag> <tag>confirm</tag> -You are not allowed in that Region due to your maturity Rating preference. - -To enter the desired region, please change your maturity Rating preference. This will allow you to search for and access [REGIONMATURITY] content. To undo any changes, go to Me > Preferences > General. - <form name="form"> +The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, or you can cancel. After your preferences are changed, you may attempt to enter the region again. + <form name="form"> <button index="0" name="OK" - text="Change Preference"/> - <button + text="Change preferences"/> + <button default="true" index="1" name="Cancel" - text="Close"/> - <ignore name="ignore" text="My chosen Rating preference prevents me from entering a Region"/> + text="Cancel"/> + <ignore name="ignore" text="Region crossing: The region you're trying to visit contains content excluded by your preferences."/> </form> </notification> <notification + icon="alertmodal.tga" + name="RegionEntryAccessBlocked_PreferencesOutOfSync" + type="alertmodal"> + <tag>fail</tag> + We are having technical difficulties with your teleport because your preferences are out of sync with the server. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="TeleportEntryAccessBlocked" + type="alertmodal"> + <tag>fail</tag> + The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me > Preferences > General. + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="TeleportEntryAccessBlocked_AdultsOnlyContent" + type="alertmodal"> + <unique> + <context>REGIONMATURITY</context> + </unique> + <tag>fail</tag> + <tag>confirm</tag> + The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only. + <url option="0" name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate + name="okcancelignore" + yestext="Go to Knowledge Base" + notext="Close" + ignoretext="Teleport: The region you're trying to visit contains content which is accessible to adults only."/> + </notification> + + <notification icon="notifytip.tga" - name="PreferredMaturityChanged" + name="TeleportEntryAccessBlocked_Notify" type="notifytip"> -Your maturity Rating preference is now [RATING]. + <unique> + <context>REGIONMATURITY</context> + </unique> + <tag>fail</tag> + The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. + </notification> + + <notification + icon="notifytip.tga" + name="TeleportEntryAccessBlocked_NotifyAdultsOnly" + type="notifytip"> + <unique> + <context>REGIONMATURITY</context> + </unique> + <tag>fail</tag> + The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only. </notification> <notification icon="alertmodal.tga" - name="LandClaimAccessBlocked" + name="TeleportEntryAccessBlocked_ChangeAndReTeleport" type="alertmodal"> -You cannot claim this land due to your maturity Rating. This may be a result of a lack of information validating your age. + <unique> + <context>REGIONMATURITY</context> + </unique> + <tag>fail</tag> + <tag>confirm</tag> + The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences and continue with the teleport, or you can cancel this teleport. + <form name="form"> + <button + index="0" + name="OK" + text="Change and continue"/> + <button + default="true" + index="1" + name="Cancel" + text="Cancel"/> + <ignore name="ignore" text="Teleport (restartable): The region you're trying to visit contains content excluded by your preferences."/> + </form> + </notification> -Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. - <tag>fail</tag> + <notification + icon="alertmodal.tga" + name="TeleportEntryAccessBlocked_Change" + type="alertmodal"> + <unique> + <context>REGIONMATURITY</context> + </unique> + <tag>fail</tag> + <tag>confirm</tag> + The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, or you can cancel the teleport. After your preferences are changed, you will need to attempt the teleport again. + <form name="form"> + <button + index="0" + name="OK" + text="Change preferences"/> + <button + default="true" + index="1" + name="Cancel" + text="Cancel"/> + <ignore name="ignore" text="Teleport (non-restartable): The region you're trying to visit contains content excluded by your preferences."/> + </form> + </notification> + + <notification + icon="alertmodal.tga" + name="TeleportEntryAccessBlocked_PreferencesOutOfSync" + type="alertmodal"> + <tag>fail</tag> + We are having technical difficulties with your teleport because your preferences are out of sync with the server. <usetemplate name="okbutton" yestext="OK"/> @@ -4169,12 +4274,43 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base <notification icon="alertmodal.tga" - name="LandClaimAccessBlocked_KB" + name="PreferredMaturityChanged" type="alertmodal"> -You cannot claim this land due to your maturity Rating. +You won't receive any more notifications that you're about to visit a region with [RATING] content. You may change your content preferences in the future by using Me > Preferences > General from the menu bar. + <tag>confirm</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> -Go to the Knowledge Base for more information about maturity Ratings? - <tag>fail</tag> + <notification + icon="alertmodal.tga" + name="MaturityChangeError" + type="alertmodal"> + We were unable to change your preferences to view [PREFERRED_MATURITY] content at this time. Your preferences have been reset to view [ACTUAL_MATURITY] content. You may attempt to change your preferences again by using Me > Preferences > General from the menu bar. + <tag>confirm</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="LandClaimAccessBlocked" + type="alertmodal"> + The land you're trying to claim has a maturity rating exceeding your current preferences. You can change your preferences using Me > Preferences > General. + <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="LandClaimAccessBlocked_AdultsOnlyContent" + type="alertmodal"> + Only adults can claim this land. + <tag>fail</tag> <tag>confirm</tag> <url option="0" name="url"> http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview @@ -4183,41 +4319,52 @@ Go to the Knowledge Base for more information about maturity Ratings? name="okcancelignore" yestext="Go to Knowledge Base" notext="Close" - ignoretext="I can't claim this Land, due to restrictions of the maturity Rating"/> + ignoretext="Only adults can claim this land."/> </notification> <notification icon="notifytip.tga" name="LandClaimAccessBlocked_Notify" type="notifytip"> -You cannot claim this land due to your maturity Rating. - <tag>fail</tag> + The land you're trying to claim contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. + <tag>fail</tag> + </notification> + + <notification + icon="notifytip.tga" + name="LandClaimAccessBlocked_NotifyAdultsOnly" + type="notifytip"> + <tag>fail</tag> + The land you're trying to claim contains [REGIONMATURITY] content, which is accessible to adults only. </notification> <notification icon="alertmodal.tga" name="LandClaimAccessBlocked_Change" type="alertmodal"> -You cannot claim this land due to your maturity Rating preference. - -You can click 'Change Preference' to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me > Preferences > General. + The land you're trying to claim contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, then you can try claiming the land again. <tag>fail</tag> <tag>confirm</tag> - <usetemplate - name="okcancelignore" - yestext="Change Preference" - notext="Close" - ignoretext="My chosen Rating preference prevents me from claiming Land"/> + <form name="form"> + <button + index="0" + name="OK" + text="Change preferences"/> + <button + default="true" + index="1" + name="Cancel" + text="Cancel"/> + <ignore name="ignore" text="The land you're trying to claim contains content excluded by your preferences."/> + </form> </notification> <notification icon="alertmodal.tga" name="LandBuyAccessBlocked" type="alertmodal"> -You cannot buy this land due to your maturity Rating. This may be a result of a lack of information validating your age. - -Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. - <tag>fail</tag> + The land you're trying to buy has a maturity rating exceeding your current preferences. You can change your preferences using Me > Preferences > General. + <tag>fail</tag> <usetemplate name="okbutton" yestext="OK"/> @@ -4225,11 +4372,9 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base <notification icon="alertmodal.tga" - name="LandBuyAccessBlocked_KB" + name="LandBuyAccessBlocked_AdultsOnlyContent" type="alertmodal"> -You cannot buy this land due to your maturity Rating. - -Go to the Knowledge Base for more information about maturity Ratings? + Only adults can buy this land. <tag>confirm</tag> <tag>fail</tag> <url option="0" name="url"> @@ -4239,31 +4384,44 @@ Go to the Knowledge Base for more information about maturity Ratings? name="okcancelignore" yestext="Go to Knowledge Base" notext="Close" - ignoretext="I can't buy this Land, due to restrictions of the maturity Rating"/> + ignoretext="Only adults can buy this land."/> </notification> <notification icon="notifytip.tga" name="LandBuyAccessBlocked_Notify" type="notifytip"> -You cannot buy this land due to your maturity Rating. - <tag>fail</tag> + The land you're trying to buy contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. + <tag>fail</tag> + </notification> + + <notification + icon="notifytip.tga" + name="LandBuyAccessBlocked_NotifyAdultsOnly" + type="notifytip"> + <tag>fail</tag> + The land you're trying to buy contains [REGIONMATURITY] content, which is accessible to adults only. </notification> <notification icon="alertmodal.tga" name="LandBuyAccessBlocked_Change" type="alertmodal"> -You cannot buy this land due to your maturity Rating preference. - -You can click 'Change Preference' to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me > Preferences > General. + The land you're trying to buy contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content. We can change your preferences, then you can try buying the land again. <tag>confirm</tag> <tag>fail</tag> - <usetemplate - name="okcancelignore" - yestext="Change Preference" - notext="Close" - ignoretext="My chosen Rating preference prevents me from buying Land"/> + <form name="form"> + <button + index="0" + name="OK" + text="Change preferences"/> + <button + default="true" + index="1" + name="Cancel" + text="Cancel"/> + <ignore name="ignore" text="The land you're trying to buy contains content excluded by your preferences."/> + </form> </notification> <notification @@ -4418,10 +4576,11 @@ Type a short announcement which will be sent to everyone in this region. label="Changed Region Maturity" name="RegionMaturityChange" type="alertmodal"> -The maturity rating for this region has been updated. -It may take some time for the change to be reflected on the map. - -To enter Adult regions, Residents must be Account Verified, either by age-verification or payment-verification. +The maturity rating for this region has been changed. +It may take some time for this change to be reflected on the map. + <usetemplate + name="okbutton" + yestext="OK"/> </notification> <notification @@ -5127,20 +5286,20 @@ Would you like to automatically wear the clothing you are about to create? icon="alertmodal.tga" name="NotAgeVerified" type="alertmodal"> - <tag>fail</tag> -To access adult content and areas in Second Life you must be at least 18 years old. Please visit our age verification page to confirm you are over 18. -Note this will launch your web browser. - -[_URL] - <tag>confirm</tag> - <url option="0" name="url"> - https://secondlife.com/my/account/verification.php - </url> + The location you're trying to visit is restricted to residents age 18 and over. + <tag>fail</tag> <usetemplate - ignoretext="I have not verified my age" - name="okcancelignore" - notext="Cancel" - yestext="Go to Age Verification"/> + ignoretext="I am not old enough to visit age restricted areas." + name="okignore" + yestext="OK"/> + </notification> + + <notification + icon="notifytip.tga" + name="NotAgeVerified_Notify" + type="notifytip"> + Location restricted to age 18 and over. + <tag>fail</tag> </notification> <notification @@ -5287,7 +5446,7 @@ Terrain.raw downloaded icon="notifytip.tga" name="GestureMissing" type="notifytip"> -Hmm. Gesture [NAME] is missing from the database. +Gesture [NAME] is missing from the database. <tag>fail</tag> </notification> @@ -5825,9 +5984,7 @@ You can only claim public land in the Region you're in. persist="true" type="notify"> <tag>fail</tag> -You aren't allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. - -Please go to the Knowledge Base for details on accessing areas with this maturity Rating. + The region you're trying to visit contains content exceeding your current preferences. You can change your preferences using Me > Preferences > General. </notification> <notification @@ -5859,11 +6016,11 @@ You do not have proper payment status to enter this region. <notification icon="notify.tga" - name="MustGetAgeRgion" + name="MustGetAgeRegion" persist="true" type="notify"> <tag>fail</tag> -You must be age-verified to enter this region. +You must be age 18 or over to enter this region. </notification> <notification @@ -5872,7 +6029,7 @@ You must be age-verified to enter this region. persist="true" type="notify"> <tag>fail</tag> -You must be age-verified to enter this parcel. + You must be age 18 or over to enter this parcel. </notification> <notification @@ -6147,7 +6304,8 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th type="offer"> [NAME_SLURL] has offered to teleport you to their location: -[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] <tag>confirm</tag> <form name="form"> <button @@ -6163,6 +6321,42 @@ Your object named <nolink>[OBJECTFROMNAME]</nolink> has given you th <notification icon="notify.tga" + name="TeleportOffered_MaturityExceeded" + type="offer"> +[NAME_SLURL] has offered to teleport you to their location: + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +This region contains [REGION_CONTENT_MATURITY] content, but your current preferences are set to exclude [REGION_CONTENT_MATURITY] content. We can change your preferences and continue with the teleport, or you can cancel this teleport. + <tag>confirm</tag> + <form name="form"> + <button + index="0" + name="Teleport" + text="Change and Continue"/> + <button + index="1" + name="Cancel" + text="Cancel"/> + </form> + </notification> + + <notification + icon="notify.tga" + name="TeleportOffered_MaturityBlocked" + type="notifytip"> +[NAME_SLURL] has offered to teleport you to their location: + +“[MESSAGE]” +<icon>[MATURITY_ICON]</icon> - [MATURITY_STR] + +However, this region contains content accessible to adults only. + <tag>fail</tag> + </notification> + + <notification + icon="notify.tga" name="TeleportOfferSent" type="offer"> Teleport offer sent to [TO_NAME] diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml index bfd796a62b..76a82212ae 100644 --- a/indra/newview/skins/default/xui/en/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml @@ -149,11 +149,11 @@ <check_box follows="top|left" height="16" - label="Have been age-verified" + label="Are age 18 or older" layout="topleft" left_delta="0" name="limit_age_verified" - tool_tip="Residents must be age verified to access this estate. See the [SUPPORT_SITE] for more information." + tool_tip="Residents must be age 18 or older to access this estate. See the [SUPPORT_SITE] for more information." top_pad="2" width="278" /> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 866ea296c3..1953a321ce 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3758,4 +3758,6 @@ Try enclosing path to the editor with double quotes. <string name="snapshot_quality_high">High</string> <string name="snapshot_quality_very_high">Very High</string> + <string name="TeleportMaturityExceeded">The Resident cannot visit this region.</string> + </strings> diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml index dce6b8dd6d..fdf41991cd 100644 --- a/indra/newview/skins/default/xui/en/teleport_strings.xml +++ b/indra/newview/skins/default/xui/en/teleport_strings.xml @@ -45,6 +45,9 @@ Go to 'Welcome Island Public' to repeat the tutorial. <message name="no_inventory_host"> The inventory system is currently unavailable. </message> + <message name="MustGetAgeRegion"> + You must be age 18 or over to enter this region. + </message> </message_set> <message_set name="progress"> <message name="sending_dest"> @@ -80,5 +83,8 @@ Go to 'Welcome Island Public' to repeat the tutorial. <message name="requesting"> Requesting Teleport... </message> - </message_set> + <message name="pending"> + Pending Teleport... + </message> + </message_set> </teleport_messages> diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp index c970d79975..0141a219c5 100644 --- a/indra/newview/tests/llagentaccess_test.cpp +++ b/indra/newview/tests/llagentaccess_test.cpp @@ -111,18 +111,6 @@ namespace tut ensure("1 isMature", !aa.isMature()); ensure("1 isAdult", !aa.isAdult()); - // this is kinda bad -- setting this forces maturity to MATURE but !teen != Mature anymore - aa.setTeen(false); - ensure("2 isTeen", !aa.isTeen()); - ensure("2 isMature", aa.isMature()); - ensure("2 isAdult", !aa.isAdult()); - - // have to flip it back and make sure it still works - aa.setTeen(true); - ensure("3 isTeen", aa.isTeen()); - ensure("3 isMature", !aa.isMature()); - ensure("3 isAdult", !aa.isAdult()); - // check the conversion routine ensure_equals("1 conversion", SIM_ACCESS_PG, aa.convertTextToMaturity('P')); ensure_equals("2 conversion", SIM_ACCESS_MATURE, aa.convertTextToMaturity('M')); @@ -131,21 +119,21 @@ namespace tut // now try the other method of setting it - PG aa.setMaturity('P'); - ensure("4 isTeen", aa.isTeen()); - ensure("4 isMature", !aa.isMature()); - ensure("4 isAdult", !aa.isAdult()); + ensure("2 isTeen", aa.isTeen()); + ensure("2 isMature", !aa.isMature()); + ensure("2 isAdult", !aa.isAdult()); // Mature aa.setMaturity('M'); - ensure("5 isTeen", !aa.isTeen()); - ensure("5 isMature", aa.isMature()); - ensure("5 isAdult", !aa.isAdult()); + ensure("3 isTeen", !aa.isTeen()); + ensure("3 isMature", aa.isMature()); + ensure("3 isAdult", !aa.isAdult()); // Adult aa.setMaturity('A'); - ensure("6 isTeen", !aa.isTeen()); - ensure("6 isMature", aa.isMature()); - ensure("6 isAdult", aa.isAdult()); + ensure("4 isTeen", !aa.isTeen()); + ensure("4 isMature", aa.isMature()); + ensure("4 isAdult", aa.isAdult()); } @@ -239,18 +227,6 @@ namespace tut cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); LLAgentAccess aa(cgr); - ensure("1 transition starts false", !aa.isInTransition()); - aa.setTransition(); - ensure("2 transition now true", aa.isInTransition()); - } - - template<> template<> - void agentaccess_object_t::test<6>() - { - LLControlGroup cgr("test"); - cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE); - LLAgentAccess aa(cgr); - cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT); aa.setMaturity('M'); ensure("1 preferred maturity pegged to M when maturity is M", cgr.getU32("PreferredMaturity") == SIM_ACCESS_MATURE); |