From fa1beb1b38af303adf466c7a16fb7416b6314386 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sat, 9 Jul 2016 16:17:26 +0200 Subject: [PATCH 1/8] Configuration queries via IMs (e.g. @version) can be disabled -> "RLVaEnableIMQuery" debug setting (enabled by default) --HG-- branch : RLVa --- indra/newview/app_settings/settings.xml | 11 +++++++++++ indra/newview/llviewermessage.cpp | 7 +++---- indra/newview/rlvcommon.h | 1 + indra/newview/rlvdefines.h | 16 ++++++++-------- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 8098191bf7..3f72924a64 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -123,6 +123,17 @@ Value 0 + RLVaEnableIMQuery + + Comment + Enables a limited number of configuration queries via IM (e.g. @version) + Persist + 1 + Type + Boolean + Value + 1 + RLVaEnableLegacyNaming Comment diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index f4d58272b3..1eb739e698 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2592,11 +2592,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // do nothing -- don't distract newbies in // Prelude with global IMs } -// [RLVa:KB] - Checked: 2011-05-28 (RLVa-1.4.0) - else if ( (rlv_handler_t::isEnabled()) && (offline == IM_ONLINE) && ("@version" == message) && - (!is_muted) && ((!accept_im_from_only_friend) || (is_friend)) ) +// [RLVa:KB] - Checked: RLVa-2.0.3 + else if ( (RlvActions::isRlvEnabled()) && (RlvSettings::getEnableIMQuery()) && (offline == IM_ONLINE) && ("@version" == message) && (!is_muted) && ((!accept_im_from_only_friend) || (is_friend)) ) { - RlvUtil::sendBusyMessage(from_id, RlvStrings::getVersion(), session_id); + RlvUtil::sendBusyMessage(from_id, RlvStrings::getVersion(LLUUID::null), session_id); } // [/RLVa:KB] // else if (offline == IM_ONLINE diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index 9d586e1724..373e5172ad 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -91,6 +91,7 @@ public: #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS static BOOL getEnableComposites() { return fCompositeFolders; } #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS + static bool getEnableIMQuery() { return rlvGetSetting("RLVaEnableIMQuery", true); } static bool getEnableLegacyNaming() { return fLegacyNaming; } static bool getEnableSharedWear() { return rlvGetSetting(RLV_SETTING_ENABLESHAREDWEAR, false); } static bool getHideLockedLayers() { return rlvGetSetting(RLV_SETTING_HIDELOCKEDLAYER, false); } diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index e227f3a66d..979fd52af6 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -1,17 +1,17 @@ -/** +/** * * Copyright (c) 2009-2016, Kitty Barnett - * - * The source code in this file is provided to you under the terms of the + * + * The source code in this file is provided to you under the terms of the * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt - * + * * By copying, modifying or distributing this software, you acknowledge that - * you have read and understood your obligations described above, and agree to + * you have read and understood your obligations described above, and agree to * abide by those obligations. - * + * */ #ifndef RLV_DEFINES_H From 21b6dd58ac35469049cebd98c57ec14bf030a02d Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sat, 9 Jul 2016 16:24:43 +0200 Subject: [PATCH 2/8] Compatibility mode allows reporting a different (lower) version number to specific items -> TPVs implementing dynamic viewer data should call RlvSettings::initCompatibilityMode() with the setting -> End-users also have manual control over the list through the "RLVaCompatibilityModeList" debug setting -> Format: (;-separated) * creator: * name: --HG-- branch : RLVa --- indra/newview/app_settings/settings.xml | 11 +++ indra/newview/rlvcommon.cpp | 106 +++++++++++++++++++----- indra/newview/rlvcommon.h | 34 +++++--- indra/newview/rlvdefines.h | 11 ++- indra/newview/rlvfloaters.cpp | 2 +- indra/newview/rlvhandler.cpp | 6 +- 6 files changed, 131 insertions(+), 39 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 3f72924a64..6a8cdf13d9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -90,6 +90,17 @@ Value + + RLVaCompatibilityModeList + + Comment + Contains a list of creators or partial items names that require compatibility mode handling (see wiki for more information and syntax) + Persist + 1 + Type + String + Value + + RLVaDebugDeprecateExplicitPoint Comment diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index ecc4ae5453..a455bd8e06 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -23,8 +23,10 @@ #include "llregionhandle.h" #include "llsdserialize.h" #include "lltrans.h" +#include "llversioninfo.h" #include "llviewerparcelmgr.h" #include "llviewermenu.h" +#include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llworld.h" @@ -36,6 +38,8 @@ #include "lscript_byteformat.h" #include +#include + // ============================================================================ // Forward declarations @@ -74,11 +78,13 @@ void RlvNotifications::onGiveToRLVConfirmation(const LLSD& notification, const L // #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS -bool RlvSettings::fCompositeFolders = false; +bool RlvSettings::s_fCompositeFolders = false; #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS -bool RlvSettings::fCanOOC = true; -bool RlvSettings::fLegacyNaming = true; -bool RlvSettings::fNoSetEnv = false; +bool RlvSettings::s_fCanOOC = true; +bool RlvSettings::s_fLegacyNaming = true; +bool RlvSettings::s_fNoSetEnv = false; +std::list RlvSettings::s_CompatItemCreators; +std::list RlvSettings::s_CompatItemNames; // Checked: 2010-02-27 (RLVa-1.2.0a) | Modified: RLVa-1.1.0i void RlvSettings::initClass() @@ -86,18 +92,20 @@ void RlvSettings::initClass() static bool fInitialized = false; if (!fInitialized) { + initCompatibilityMode(LLStringUtil::null); + #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS - fCompositeFolders = rlvGetSetting(RLV_SETTING_ENABLECOMPOSITES, false); + s_fCompositeFolders = rlvGetSetting(RLV_SETTING_ENABLECOMPOSITES, false); if (gSavedSettings.controlExists(RLV_SETTING_ENABLECOMPOSITES)) - gSavedSettings.getControl(RLV_SETTING_ENABLECOMPOSITES)->getSignal()->connect(boost::bind(&onChangedSettingBOOL, _2, &fCompositeFolders)); + gSavedSettings.getControl(RLV_SETTING_ENABLECOMPOSITES)->getSignal()->connect(boost::bind(&onChangedSettingBOOL, _2, &s_fCompositeFolders)); #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS - fLegacyNaming = rlvGetSetting(RLV_SETTING_ENABLELEGACYNAMING, true); + s_fLegacyNaming = rlvGetSetting(RLV_SETTING_ENABLELEGACYNAMING, true); if (gSavedSettings.controlExists(RLV_SETTING_ENABLELEGACYNAMING)) - gSavedSettings.getControl(RLV_SETTING_ENABLELEGACYNAMING)->getSignal()->connect(boost::bind(&onChangedSettingBOOL, _2, &fLegacyNaming)); + gSavedSettings.getControl(RLV_SETTING_ENABLELEGACYNAMING)->getSignal()->connect(boost::bind(&onChangedSettingBOOL, _2, &s_fLegacyNaming)); - fCanOOC = rlvGetSetting(RLV_SETTING_CANOOC, true); - fNoSetEnv = rlvGetSetting(RLV_SETTING_NOSETENV, false); + s_fCanOOC = rlvGetSetting(RLV_SETTING_CANOOC, true); + s_fNoSetEnv = rlvGetSetting(RLV_SETTING_NOSETENV, false); // Don't allow toggling RLVaLoginLastLocation from the debug settings floater if (gSavedPerAccountSettings.controlExists(RLV_SETTING_LOGINLASTLOCATION)) @@ -152,6 +160,65 @@ void RlvSettings::onChangedSettingMain(const LLSD& sdValue) } } +void RlvSettings::initCompatibilityMode(std::string strCompatList) +{ + // NOTE: this function can be called more than once + s_CompatItemCreators.clear(); + s_CompatItemNames.clear(); + + strCompatList.append(";").append(rlvGetSetting("RLVaCompatibilityModeList", "")); + + boost_tokenizer tokCompatList(strCompatList, boost::char_separator(";", "", boost::drop_empty_tokens)); + for (const std::string& strCompatEntry : tokCompatList) + { + if (boost::starts_with(strCompatEntry, "creator:")) + { + LLUUID idCreator; + if ( (44 == strCompatEntry.size()) && (LLUUID::parseUUID(strCompatEntry.substr(8), &idCreator)) && + (s_CompatItemCreators.end() == std::find(s_CompatItemCreators.begin(), s_CompatItemCreators.end(), idCreator)) ) + { + s_CompatItemCreators.push_back(idCreator); + } + } + else if (boost::starts_with(strCompatEntry, "name:")) + { + if (strCompatEntry.size() > 5) + s_CompatItemNames.push_back(strCompatEntry.substr(5)); + } + } +} + +bool RlvSettings::isCompatibilityModeObject(const LLUUID& idRlvObject) +{ + bool fCompatMode = false; + if (idRlvObject.notNull()) + { + const LLViewerObject* pObj = gObjectList.findObject(idRlvObject); + if ( (pObj) && (pObj->isAttachment()) ) + { + const LLViewerInventoryItem* pItem = gInventory.getItem(pObj->getAttachmentItemID()); + if (pItem) + { + fCompatMode = s_CompatItemCreators.end() != std::find(s_CompatItemCreators.begin(), s_CompatItemCreators.end(), pItem->getCreatorUUID()); + if (!fCompatMode) + { + const std::string& strAttachName = pItem->getName(); + for (const std::string& strCompatName : s_CompatItemNames) + { + boost::regex regexp(strCompatName, boost::regex::perl | boost::regex::icase); + if (boost::regex_match(strAttachName, regexp)) + { + fCompatMode = true; + break; + } + } + } + } + } + } + return fCompatMode; +} + // ============================================================================ // RlvStrings // @@ -314,27 +381,26 @@ const char* RlvStrings::getStringFromReturnCode(ERlvCmdRet eRet) return NULL; } -// Checked: 2012-02-25 (RLVa-1.4.5) | Modified: RLVa-1.4.5 -std::string RlvStrings::getVersion(bool fLegacy) +std::string RlvStrings::getVersion(const LLUUID& idRlvObject, bool fLegacy) { + bool fCompatMode = RlvSettings::isCompatibilityModeObject(idRlvObject); return llformat("%s viewer v%d.%d.%d (RLVa %d.%d.%d)", ( (!fLegacy) ? "RestrainedLove" : "RestrainedLife" ), - RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, + (!fCompatMode) ? RLV_VERSION_MAJOR : RLV_VERSION_MAJOR_COMPAT, (!fCompatMode) ? RLV_VERSION_MINOR : RLV_VERSION_MINOR_COMPAT, (!fCompatMode) ? RLV_VERSION_PATCH : RLV_VERSION_PATCH_COMPAT, RLVa_VERSION_MAJOR, RLVa_VERSION_MINOR, RLVa_VERSION_PATCH); } -// Checked: 2010-04-18 (RLVa-1.4.0a) | Added: RLVa-1.2.0e std::string RlvStrings::getVersionAbout() { - return llformat("RLV v%d.%d.%d / RLVa v%d.%d.%d%c" , - RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, - RLVa_VERSION_MAJOR, RLVa_VERSION_MINOR, RLVa_VERSION_PATCH, 'a' + RLVa_VERSION_BUILD); + return llformat("RLV v%d.%d.%d / RLVa v%d.%d.%d.%d", RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, RLVa_VERSION_MAJOR, RLVa_VERSION_MINOR, RLVa_VERSION_PATCH, LLVersionInfo::getBuild()); } -// Checked: 2010-03-27 (RLVa-1.4.0a) | Modified: RLVa-1.1.0a -std::string RlvStrings::getVersionNum() +std::string RlvStrings::getVersionNum(const LLUUID& idRlvObject) { - return llformat("%d%02d%02d%02d", RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, RLV_VERSION_BUILD); + bool fCompatMode = RlvSettings::isCompatibilityModeObject(idRlvObject); + return llformat("%d%02d%02d%02d", + (!fCompatMode) ? RLV_VERSION_MAJOR : RLV_VERSION_MAJOR_COMPAT, (!fCompatMode) ? RLV_VERSION_MINOR : RLV_VERSION_MINOR_COMPAT, + (!fCompatMode) ? RLV_VERSION_PATCH : RLV_VERSION_PATCH_COMPAT, (!fCompatMode) ? RLV_VERSION_BUILD : RLV_VERSION_BUILD_COMPAT); } // Checked: 2011-11-08 (RLVa-1.5.0) diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index 373e5172ad..fa50475452 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -80,21 +80,21 @@ class RlvSettings { public: static bool getDebug() { return rlvGetSetting(RLV_SETTING_DEBUG, false); } - static bool getCanOOC() { return fCanOOC; } + static bool getCanOOC() { return s_fCanOOC; } static bool getForbidGiveToRLV() { return rlvGetSetting(RLV_SETTING_FORBIDGIVETORLV, true); } - static bool getNoSetEnv() { return fNoSetEnv; } + static bool getNoSetEnv() { return s_fNoSetEnv; } static std::string getWearAddPrefix() { return rlvGetSetting(RLV_SETTING_WEARADDPREFIX, LLStringUtil::null); } static std::string getWearReplacePrefix() { return rlvGetSetting(RLV_SETTING_WEARREPLACEPREFIX, LLStringUtil::null); } static bool getDebugHideUnsetDup() { return rlvGetSetting(RLV_SETTING_DEBUGHIDEUNSETDUP, false); } #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS - static BOOL getEnableComposites() { return fCompositeFolders; } + static BOOL getEnableComposites() { return s_fCompositeFolders; } #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS static bool getEnableIMQuery() { return rlvGetSetting("RLVaEnableIMQuery", true); } - static bool getEnableLegacyNaming() { return fLegacyNaming; } + static bool getEnableLegacyNaming() { return s_fLegacyNaming; } static bool getEnableSharedWear() { return rlvGetSetting(RLV_SETTING_ENABLESHAREDWEAR, false); } - static bool getHideLockedLayers() { return rlvGetSetting(RLV_SETTING_HIDELOCKEDLAYER, false); } + static bool getHideLockedLayers() { return rlvGetSetting(RLV_SETTING_HIDELOCKEDLAYER, false); } static bool getHideLockedAttach() { return rlvGetSetting(RLV_SETTING_HIDELOCKEDATTACH, false); } static bool getHideLockedInventory() { return rlvGetSetting(RLV_SETTING_HIDELOCKEDINVENTORY, false); } static bool getSharedInvAutoRename() { return rlvGetSetting(RLV_SETTING_SHAREDINVAUTORENAME, true); } @@ -102,6 +102,9 @@ public: static bool getLoginLastLocation() { return rlvGetPerUserSetting(RLV_SETTING_LOGINLASTLOCATION, true); } static void updateLoginLastLocation(); + static void initCompatibilityMode(std::string strCompatList); + static bool isCompatibilityModeObject(const LLUUID& idRlvObject); + static void initClass(); static void onChangedSettingMain(const LLSD& sdValue); protected: @@ -109,11 +112,18 @@ protected: static bool onChangedSettingBOOL(const LLSD& sdValue, bool* pfSetting); #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS - static BOOL fCompositeFolders; + static BOOL s_fCompositeFolders; #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS - static bool fCanOOC; - static bool fLegacyNaming; - static bool fNoSetEnv; + + /* + * Member variables + */ +protected: + static bool s_fCanOOC; + static bool s_fLegacyNaming; + static bool s_fNoSetEnv; + static std::list s_CompatItemCreators; + static std::list s_CompatItemNames; }; // ============================================================================ @@ -132,9 +142,9 @@ public: static const std::string& getString(const std::string& strStringName); static const char* getStringFromReturnCode(ERlvCmdRet eRet); static const std::string& getStringMapPath() { return m_StringMapPath; } - static std::string getVersion(bool fLegacy = false); // @version - static std::string getVersionAbout(); // Shown in Help / About - static std::string getVersionNum(); // @versionnum + static std::string getVersion(const LLUUID& idRlvObject, bool fLegacy = false); + static std::string getVersionAbout(); + static std::string getVersionNum(const LLUUID& idRlvObject); static bool hasString(const std::string& strStringName, bool fCheckCustom = false); static void setCustomString(const std::string& strStringName, const std::string& strStringValue); diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 979fd52af6..84a921b3fb 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -21,17 +21,22 @@ // Defines // -// Version of the specifcation we support +// Version of the specifcation we report const S32 RLV_VERSION_MAJOR = 3; const S32 RLV_VERSION_MINOR = 1; const S32 RLV_VERSION_PATCH = 4; const S32 RLV_VERSION_BUILD = 0; +// Version of the specifcation we report (in compatibility mode) +const S32 RLV_VERSION_MAJOR_COMPAT = 2; +const S32 RLV_VERSION_MINOR_COMPAT = 8; +const S32 RLV_VERSION_PATCH_COMPAT = 0; +const S32 RLV_VERSION_BUILD_COMPAT = 0; + // Implementation version const S32 RLVa_VERSION_MAJOR = 2; const S32 RLVa_VERSION_MINOR = 0; -const S32 RLVa_VERSION_PATCH = 0; -const S32 RLVa_VERSION_BUILD = 0; +const S32 RLVa_VERSION_PATCH = 3; // Uncomment before a final release //#define RLV_RELEASE diff --git a/indra/newview/rlvfloaters.cpp b/indra/newview/rlvfloaters.cpp index 7f7d49cdf8..4b4303cf27 100644 --- a/indra/newview/rlvfloaters.cpp +++ b/indra/newview/rlvfloaters.cpp @@ -234,7 +234,7 @@ void RlvFloaterBehaviours::onBtnCopyToClipboard() { std::ostringstream strRestrictions; - strRestrictions << RlvStrings::getVersion() << "\n"; + strRestrictions << RlvStrings::getVersion(LLUUID::null) << "\n"; const RlvHandler::rlv_object_map_t* pObjects = gRlvHandler.getObjectMap(); for (RlvHandler::rlv_object_map_t::const_iterator itObj = pObjects->begin(), endObj = pObjects->end(); itObj != endObj; ++itObj) diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index e769847d18..f4033a2380 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -1070,7 +1070,7 @@ BOOL RlvHandler::setEnabled(BOOL fEnable) if (fEnable) { - RLV_INFOS << "Enabling Restrained Love API support - " << RlvStrings::getVersion() << RLV_ENDL; + RLV_INFOS << "Enabling Restrained Love API support - " << RlvStrings::getVersionAbout() << RLV_ENDL; m_fEnabled = TRUE; // Initialize static classes @@ -2540,11 +2540,11 @@ ERlvCmdRet RlvHandler::processReplyCommand(const RlvCommand& rlvCmd) const case RLV_BHVR_VERSION: // @version= - Checked: 2010-03-27 (RLVa-1.4.0a) case RLV_BHVR_VERSIONNEW: // @versionnew= - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.2.0b // NOTE: RLV will respond even if there's an option - strReply = RlvStrings::getVersion(RLV_BHVR_VERSION == rlvCmd.getBehaviourType()); + strReply = RlvStrings::getVersion(rlvCmd.getObjectID(), RLV_BHVR_VERSION == rlvCmd.getBehaviourType()); break; case RLV_BHVR_VERSIONNUM: // @versionnum= - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.4b // NOTE: RLV will respond even if there's an option - strReply = RlvStrings::getVersionNum(); + strReply = RlvStrings::getVersionNum(rlvCmd.getObjectID()); break; case RLV_BHVR_GETATTACH: // @getattach[:]= eRet = onGetAttach(rlvCmd, strReply); From fda5eb9cccdef09e99edc2d280295f17149560b3 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sat, 9 Jul 2016 22:08:23 +0200 Subject: [PATCH 3/8] Code cleanup: better handling of group joins when @setgroup restricted -> bundle all permission checks in a predictable single function (see RlvActions::canChangeActiveGroup) -> properly handle the case where a user is ejected from a group -> provide feedback to the user after we force the previous group back when joining a new group --HG-- branch : RLVa --- indra/newview/llgroupactions.cpp | 8 ++-- indra/newview/llgrouplist.cpp | 16 +++---- indra/newview/rlvactions.cpp | 7 +++ indra/newview/rlvactions.h | 5 ++ indra/newview/rlvdefines.h | 1 + indra/newview/rlvhandler.cpp | 48 ++++++++++++++----- .../skins/default/xui/en/rlva_strings.xml | 5 ++ 7 files changed, 65 insertions(+), 25 deletions(-) diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index aaa5952ef7..73bb8543ee 100755 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -294,8 +294,8 @@ bool LLGroupActions::onJoinGroup(const LLSD& notification, const LLSD& response) void LLGroupActions::leave(const LLUUID& group_id) { // if (group_id.isNull()) -// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f - if ( (group_id.isNull()) || ((gAgent.getGroupID() == group_id) && (gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP))) ) +// [RLVa:KB] - Checked: RLVa-1.3.0 + if ( (group_id.isNull()) || ((gAgent.getGroupID() == group_id) && (!RlvActions::canChangeActiveGroup())) ) // [/RLVa:KB] { return; @@ -348,8 +348,8 @@ void LLGroupActions::processLeaveGroupDataResponse(const LLUUID group_id) // static void LLGroupActions::activate(const LLUUID& group_id) { -// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f - if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP)) && (gRlvHandler.getAgentGroup() != group_id) ) +// [RLVa:KB] - Checked: RLVa-1.3.0 + if ( (!RlvActions::canChangeActiveGroup()) && (gRlvHandler.getAgentGroup() != group_id) ) { return; } diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index 062154f03c..339414e5cb 100755 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -43,8 +43,8 @@ #include "llviewercontrol.h" // for gSavedSettings #include "llviewermenu.h" // for gMenuHolder #include "llvoiceclient.h" -// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f -#include "rlvhandler.h" +// [RLVa:KB] - Checked: RLVa-2.0.3 +#include "rlvactions.h" // [/RLVa:KB] static LLDefaultChildRegistry::Register r("group_list"); @@ -284,14 +284,14 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata) bool real_group_selected = selected_group_id.notNull(); // a "real" (not "none") group is selected // each group including "none" can be activated +// [RLVa:KB] - Checked: RLVa-1.3.0 + if (userdata.asString() == "activate") + return (gAgent.getGroupID() != selected_group_id) && (RlvActions::canChangeActiveGroup()); + else if (userdata.asString() == "leave") + return (real_group_selected) && ((gAgent.getGroupID() != selected_group_id) || (RlvActions::canChangeActiveGroup())); +// [/RLVa:KB] // if (userdata.asString() == "activate") // return gAgent.getGroupID() != selected_group_id; -// [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.4.1a) | Added: RLVa-1.3.0f - if (userdata.asString() == "activate") - return (gAgent.getGroupID() != selected_group_id) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP)); - else if (userdata.asString() == "leave") - return (real_group_selected) && ((gAgent.getGroupID() != selected_group_id) || (!gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP))); -// [/RLVa:KB] if (userdata.asString() == "call") return real_group_selected && LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking(); diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index 1def8205fb..b98de3cbf2 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -121,6 +121,13 @@ bool RlvActions::getCameraFOVLimits(F32& nFOVMin, F32& nFOVMax) bool RlvActions::s_BlockNamesContexts[SNC_COUNT] = { 0 }; +bool RlvActions::canChangeActiveGroup(const LLUUID& idRlvObject) +{ + // User can change their active group if: + // - not specifically restricted (by another object that the one specified) from changing their active group + return (idRlvObject.isNull()) ? !gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP) : !gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETGROUP, idRlvObject); +} + // Little helper function to check the IM exclusion range for @recvim, @sendim and @startim (returns: min_dist <= (pos user - pos target) <= max_dist) static bool rlvCheckAvatarIMDistance(const LLUUID& idAvatar, ERlvBehaviourModifier eModDistMin, ERlvBehaviourModifier eModDistMax) { diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h index e11066e25a..14f0c3b85b 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -74,6 +74,11 @@ public: // Communication/Avatar interaction // ================================ public: + /* + * Returns true if the user is allowed to change their currently active group + */ + static bool canChangeActiveGroup(const LLUUID& idRlvObject = LLUUID::null); + /* * Returns true if the user is allowed to receive IMs from the specified sender (can be an avatar or a group) */ diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 84a921b3fb..3011a41325 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -370,6 +370,7 @@ enum ERlvAttachGroupType #define RLV_STRING_BLOCKED_AUTOPILOT "blocked_autopilot" #define RLV_STRING_BLOCKED_GENERIC "blocked_generic" +#define RLV_STRING_BLOCKED_GROUPCHANGE "blocked_groupchange" #define RLV_STRING_BLOCKED_PERMATTACH "blocked_permattach" #define RLV_STRING_BLOCKED_PERMTELEPORT "blocked_permteleport" #define RLV_STRING_BLOCKED_RECVIM "blocked_recvim" diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index f4033a2380..6ad9e4c848 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -472,21 +472,43 @@ ERlvCmdRet RlvHandler::processClearCommand(const RlvCommand& rlvCmd) // Externally invoked event handlers // -// Checked: 2011-05-22 (RLVa-1.4.1a) | Added: RLVa-1.3.1b bool RlvHandler::handleEvent(LLPointer event, const LLSD& sdUserdata) { - // If the user managed to change their active group (= newly joined or created group) we need to reactivate the previous one - if ( (hasBehaviour(RLV_BHVR_SETGROUP)) && ("new group" == event->desc()) && (m_idAgentGroup != gAgent.getGroupID()) ) + // NOTE: we'll fire once for every group the user belongs to so we need to manually keep track of pending changes + static LLUUID s_idLastAgentGroup = LLUUID::null; + static bool s_fGroupChanging = false; + + if (s_idLastAgentGroup != gAgent.getGroupID()) { - // [Copy/paste from LLGroupActions::activate()] - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ActivateGroup); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_GroupID, m_idAgentGroup); - gAgent.sendReliableMessage(); - return true; + s_idLastAgentGroup = gAgent.getGroupID(); + s_fGroupChanging = false; + } + + // If the user managed to change their active group (= newly joined or created group) we need to reactivate the previous one + if ( (!RlvActions::canChangeActiveGroup()) && ("new group" == event->desc()) && (m_idAgentGroup != gAgent.getGroupID()) ) + { + // Make sure they still belong to the group + if ( (m_idAgentGroup.notNull()) && (!gAgent.isInGroup(m_idAgentGroup)) ) + { + m_idAgentGroup.setNull(); + s_fGroupChanging = false; + } + + if (!s_fGroupChanging) + { + RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_GROUPCHANGE, LLSD().with("GROUP_SLURL", (m_idAgentGroup.notNull()) ? llformat("secondlife:///app/group/%s/about", m_idAgentGroup.asString()) : "(none)")); + + // [Copy/paste from LLGroupActions::activate()] + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ActivateGroup); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_GroupID, m_idAgentGroup); + gAgent.sendReliableMessage(); + s_fGroupChanging = true; + return true; + } } else { @@ -2384,7 +2406,7 @@ void RlvHandler::onForceWearCallback(const uuid_vec_t& idItems, U32 nFlags) cons template<> template<> ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) { - if (gRlvHandler.hasBehaviourExcept(RLV_BHVR_SETGROUP, rlvCmd.getObjectID())) + if (!RlvActions::canChangeActiveGroup(rlvCmd.getObjectID())) { return RLV_RET_FAILED_LOCK; } diff --git a/indra/newview/skins/default/xui/en/rlva_strings.xml b/indra/newview/skins/default/xui/en/rlva_strings.xml index 6861f9c465..62651c9a09 100644 --- a/indra/newview/skins/default/xui/en/rlva_strings.xml +++ b/indra/newview/skins/default/xui/en/rlva_strings.xml @@ -56,6 +56,11 @@ value Unable to perform action due to RLV restrictions + blocked_groupchange + + value + Unable to change your active group due to an RLV restriction; switching back to [GROUP_SLURL] + blocked_permattach value From 5e4235be4e6e3fa73700b31f9a0b8aa58af4cd49 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sat, 9 Jul 2016 22:49:33 +0200 Subject: [PATCH 4/8] Processing of RLV commands by temporary attachments can be toggled by the user -> "RLVaEnableTemporaryAttachments" debug setting (enabled by default) --HG-- branch : RLVa --- indra/newview/app_settings/settings.xml | 22 +++++++++---------- indra/newview/llviewermessage.cpp | 3 ++- indra/newview/rlvcommon.cpp | 5 +++++ indra/newview/rlvcommon.h | 2 ++ indra/newview/rlvdefines.h | 1 + indra/newview/rlvlocks.h | 7 +++--- .../skins/default/xui/en/menu_viewer.xml | 10 +++++++++ 7 files changed, 34 insertions(+), 16 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6a8cdf13d9..b3879d4a52 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -167,6 +167,17 @@ Value 1 + RLVaEnableTemporaryAttachments + + Comment + Allows temporary attachments (regardless of origin) to issue RLV commands + Persist + 1 + Type + Boolean + Value + 1 + RLVaExperimentalCommands Comment @@ -244,17 +255,6 @@ Value 1 - WarnFirstRLVGiveToRLV - - Comment - Enables FirstRLVGiveToRLV warning dialog - Persist - 1 - Type - Boolean - Value - 1 - ImporterDebug Comment diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 1eb739e698..2d317562aa 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4027,7 +4027,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) case CHAT_TYPE_OWNER: // [RLVa:KB] - Checked: 2010-02-XX (RLVa-1.2.0a) | Modified: RLVa-1.1.0f // TODO-RLVa: [RLVa-1.2.0] consider rewriting this before a RLVa-1.2.0 release - if ( (rlv_handler_t::isEnabled()) && (mesg.length() > 3) && (RLV_CMD_PREFIX == mesg[0]) && (CHAT_TYPE_OWNER == chat.mChatType) ) + if ( (rlv_handler_t::isEnabled()) && (mesg.length() > 3) && (RLV_CMD_PREFIX == mesg[0]) && (CHAT_TYPE_OWNER == chat.mChatType) && + ((!chatter) || (!chatter->isAttachment()) || (!chatter->isTempAttachment()) || (RlvSettings::getEnableTemporaryAttachments())) ) { mesg.erase(0, 1); LLStringUtil::toLower(mesg); diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index a455bd8e06..319441d9c7 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -83,6 +83,7 @@ bool RlvSettings::s_fCompositeFolders = false; bool RlvSettings::s_fCanOOC = true; bool RlvSettings::s_fLegacyNaming = true; bool RlvSettings::s_fNoSetEnv = false; +bool RlvSettings::s_fTempAttach = true; std::list RlvSettings::s_CompatItemCreators; std::list RlvSettings::s_CompatItemNames; @@ -94,6 +95,10 @@ void RlvSettings::initClass() { initCompatibilityMode(LLStringUtil::null); + s_fTempAttach = rlvGetSetting(RLV_SETTING_ENABLETEMPATTACH, true); + if (gSavedSettings.controlExists(RLV_SETTING_ENABLETEMPATTACH)) + gSavedSettings.getControl(RLV_SETTING_ENABLETEMPATTACH)->getSignal()->connect(boost::bind(&onChangedSettingBOOL, _2, &s_fTempAttach)); + #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS s_fCompositeFolders = rlvGetSetting(RLV_SETTING_ENABLECOMPOSITES, false); if (gSavedSettings.controlExists(RLV_SETTING_ENABLECOMPOSITES)) diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index fa50475452..96cde804f4 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -94,6 +94,7 @@ public: static bool getEnableIMQuery() { return rlvGetSetting("RLVaEnableIMQuery", true); } static bool getEnableLegacyNaming() { return s_fLegacyNaming; } static bool getEnableSharedWear() { return rlvGetSetting(RLV_SETTING_ENABLESHAREDWEAR, false); } + static bool getEnableTemporaryAttachments() { return s_fTempAttach; } static bool getHideLockedLayers() { return rlvGetSetting(RLV_SETTING_HIDELOCKEDLAYER, false); } static bool getHideLockedAttach() { return rlvGetSetting(RLV_SETTING_HIDELOCKEDATTACH, false); } static bool getHideLockedInventory() { return rlvGetSetting(RLV_SETTING_HIDELOCKEDINVENTORY, false); } @@ -122,6 +123,7 @@ protected: static bool s_fCanOOC; static bool s_fLegacyNaming; static bool s_fNoSetEnv; + static bool s_fTempAttach; static std::list s_CompatItemCreators; static std::list s_CompatItemNames; }; diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 3011a41325..5f681a430c 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -348,6 +348,7 @@ enum ERlvAttachGroupType #define RLV_SETTING_ENABLECOMPOSITES "RLVaEnableCompositeFolders" #define RLV_SETTING_ENABLELEGACYNAMING "RLVaEnableLegacyNaming" #define RLV_SETTING_ENABLESHAREDWEAR "RLVaEnableSharedWear" +#define RLV_SETTING_ENABLETEMPATTACH "RLVaEnableTemporaryAttachments" #define RLV_SETTING_HIDELOCKEDLAYER "RLVaHideLockedLayers" #define RLV_SETTING_HIDELOCKEDATTACH "RLVaHideLockedAttachments" #define RLV_SETTING_HIDELOCKEDINVENTORY "RLVaHideLockedInventory" diff --git a/indra/newview/rlvlocks.h b/indra/newview/rlvlocks.h index 69df3c9283..0d57321068 100644 --- a/indra/newview/rlvlocks.h +++ b/indra/newview/rlvlocks.h @@ -475,15 +475,14 @@ inline bool RlvAttachmentLocks::isLockedAttachment(const LLViewerObject* pAttach RLV_ASSERT( (!pAttachObj) || (pAttachObj == pAttachObj->getRootEdit()) ); // Object is locked if: - // - it's not a temporary attachment // - it's specifically marked as non-detachable (ie @detach=n) // - it's attached to an attachment point that is RLV_LOCK_REMOVE locked (ie @remattach:=n) // - it's part of a locked folder return - (pAttachObj) && (pAttachObj->isAttachment()) && (!pAttachObj->isTempAttachment()) && - ( (m_AttachObjRem.find(pAttachObj->getID()) != m_AttachObjRem.end()) || + (pAttachObj) && (pAttachObj->isAttachment()) && + ( (m_AttachObjRem.find(pAttachObj->getID()) != m_AttachObjRem.end()) || (isLockedAttachmentPoint(RlvAttachPtLookup::getAttachPointIndex(pAttachObj), RLV_LOCK_REMOVE)) || - (RlvFolderLocks::instance().isLockedAttachment(pAttachObj->getAttachmentItemID())) ); + ((!pAttachObj->isTempAttachment()) && (RlvFolderLocks::instance().isLockedAttachment(pAttachObj->getAttachmentItemID()))) ); } // Checked: 2010-02-28 (RLVa-1.2.0a) | Added: RLVa-1.0.5a diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 5bb12beb74..f4bfb8e401 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1623,6 +1623,16 @@ function="ToggleControl" parameter="RestrainedLoveCanOOC" /> + + + + From 7bfd26e3dfd7e04a7052a3b7f92cbba46cdfca1b Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sun, 10 Jul 2016 16:40:20 +0200 Subject: [PATCH 5/8] [FIXED] @unsharedwear=n doesn't block "Add to Outfit" (if no attachment/wearable locks exist) -> wearables would be properly filtered if there was at least one wearable lock -> attachments would be properly filtered if there was at least one attachment lock => added explicit check for add-restricted folders => gray out the relevant context menu items (i.e. "Add to Outfit" and "Replace Current Outfit) --HG-- branch : RLVa --- indra/newview/llappearancemgr.cpp | 28 ++++++++++++++++++++++------ indra/newview/llinventorybridge.cpp | 12 ++++++++++++ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 144e89196f..02cdbc84f8 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -55,6 +55,7 @@ #include "llhttpretrypolicy.h" #include "llaisapi.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) +#include "rlvactions.h" #include "rlvhandler.h" #include "rlvhelper.h" #include "rlvlocks.h" @@ -1874,6 +1875,13 @@ bool LLAppearanceMgr::getCanAddToCOF(const LLUUID& outfit_cat_id) return false; } +// [RLVa:KB] - Checked: RLVa-2.0.3 + if ( (RlvActions::isRlvEnabled()) && (RlvFolderLocks::instance().isLockedFolder(outfit_cat_id, RLV_LOCK_ADD)) ) + { + return false; + } +// [/RLVa:KB] + LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false); @@ -1894,6 +1902,14 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id) return false; } +// [RLVa:KB] - Checked: RLVa-2.0.3 + // Block "Replace Current Outfit" if the user can't wear the new folder + if ( (RlvActions::isRlvEnabled()) && (RlvFolderLocks::instance().isLockedFolder(outfit_cat_id, RLV_LOCK_ADD)) ) + { + return false; + } +// [/RLVa:KB] + // Check whether it's the base outfit. // if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID()) // [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-21 (Catznip-2.1) @@ -2087,9 +2103,9 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t body_items; getDescendentsOfAssetType(cof, body_items, LLAssetType::AT_BODYPART); // getDescendentsOfAssetType(category, body_items, LLAssetType::AT_BODYPART); -// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0) +// [RLVa:KB] - Checked: RLVa-2.0.3 // Filter out any new body parts that can't be worn before adding them - if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) ) + if ( (RlvActions::isRlvEnabled()) && ((gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ADD))) ) body_items_new.erase(std::remove_if(body_items_new.begin(), body_items_new.end(), RlvPredCanNotWearItem(RLV_WEAR_REPLACE)), body_items_new.end()); body_items.insert(body_items.end(), body_items_new.begin(), body_items_new.end()); // [/RLVa:KB] @@ -2115,9 +2131,9 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, } // [/RLVa:KB] // getDescendentsOfAssetType(category, wear_items, LLAssetType::AT_CLOTHING); -// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0) +// [RLVa:KB] - Checked: RLVa-2.0.3 // Filter out any new wearables that can't be worn before adding them - if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) ) + if ( (RlvActions::isRlvEnabled()) && ((gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ADD))) ) wear_items_new.erase(std::remove_if(wear_items_new.begin(), wear_items_new.end(), RlvPredCanNotWearItem(RLV_WEAR)), wear_items_new.end()); wear_items.insert(wear_items.end(), wear_items_new.begin(), wear_items_new.end()); // [/RLVa:KB] @@ -2143,9 +2159,9 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, } // [/RLVa:KB] // getDescendentsOfAssetType(category, obj_items, LLAssetType::AT_OBJECT); -// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0) +// [RLVa:KB] - Checked: RLVa-2.0.3 // Filter out any new attachments that can't be worn before adding them - if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) + if ( (RlvActions::isRlvEnabled()) && ((gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ADD))) ) obj_items_new.erase(std::remove_if(obj_items_new.begin(), obj_items_new.end(), RlvPredCanNotWearItem(RLV_WEAR)), obj_items_new.end()); obj_items.insert(obj_items.end(), obj_items_new.begin(), obj_items_new.end()); // [/RLVa:KB] diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index f6be12747c..45a7ef8f5c 100755 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4118,6 +4118,13 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& { disabled_items.push_back(std::string("Replace Outfit")); } +// [RLVa:KB] - Checked: RLVa-2.0.3 + // Block "Replace Current Outfit" if the user can't wear the new folder + if ( (RlvActions::isRlvEnabled()) && (RlvFolderLocks::instance().isLockedFolder(mUUID, RLV_LOCK_ADD)) ) + { + disabled_items.push_back(std::string("Replace Outfit")); + } +// [/RLVa:KB] if (!LLAppearanceMgr::instance().getCanAddToCOF(mUUID)) { disabled_items.push_back(std::string("Add To Outfit")); @@ -6185,6 +6192,11 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach { attachment = RlvAttachPtLookup::getAttachPoint(item); } + + if ( (RlvActions::isRlvEnabled()) && (!rlvPredCanWearItem(item, RLV_WEAR_REPLACE)) ) + { + return; + } // [/RLVa:KB] const LLUUID& item_id = item->getLinkedUUID(); From bb9affd554e34b7766968a2107179e39f59003ab Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sun, 10 Jul 2016 17:45:30 +0200 Subject: [PATCH 6/8] [FIXED] @unsharedunwear=n doesn't block "Remove from Outfit" (if no attachment/wearable locks exist) -> see previous commit as well -> lookups ended up refreshing before the actual attachments were attached leaving them (from a user's perspective unpredictably) detachable --HG-- branch : RLVa --- indra/newview/llappearancemgr.cpp | 15 +++++++++++---- indra/newview/rlvlocks.cpp | 3 +++ indra/newview/rlvlocks.h | 2 ++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 02cdbc84f8..35a545ed16 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1856,6 +1856,13 @@ bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id) { return false; } +// [RLVa:KB] - Checked: RLVa-2.0.3 + if ( (RlvActions::isRlvEnabled()) && (RlvFolderLocks::instance().isLockedFolder(outfit_cat_id, RLV_LOCK_REMOVE)) ) + { + return false; + } +// [/RLVa:KB] + LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false); @@ -2122,8 +2129,8 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t wear_items; if (append) getDescendentsOfAssetType(cof, wear_items, LLAssetType::AT_CLOTHING); -// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0) - else if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) ) +// [RLVa:KB] - Checked: RLVa-2.0.3 + else if ( (RlvActions::isRlvEnabled()) && ((gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_REMOVE))) ) { // Make sure that all currently locked clothing layers remain in COF when replacing getDescendentsOfAssetType(cof, wear_items, LLAssetType::AT_CLOTHING); @@ -2150,8 +2157,8 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t obj_items; if (append) getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT); -// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0z) | Modified: RLVa-1.2.0b - else if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) +// [RLVa:KB] - Checked: RLVa-2.0.3 + else if ( (RlvActions::isRlvEnabled()) && ((gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_REMOVE))) ) { // Make sure that all currently locked attachments remain in COF when replacing getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT); diff --git a/indra/newview/rlvlocks.cpp b/indra/newview/rlvlocks.cpp index 7d45af199c..f9ba91e049 100644 --- a/indra/newview/rlvlocks.cpp +++ b/indra/newview/rlvlocks.cpp @@ -964,6 +964,9 @@ void RlvFolderLocks::addFolderLock(const folderlock_source_t& lockSource, ELockP else if (RLV_LOCK_ADD == eLockType) m_cntLockAdd++; } + + if (!m_AttachmentChangeConnection.connected()) + m_AttachmentChangeConnection = gAgentAvatarp->setAttachmentCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this)); m_fLookupDirty = true; } diff --git a/indra/newview/rlvlocks.h b/indra/newview/rlvlocks.h index 0d57321068..3643845f91 100644 --- a/indra/newview/rlvlocks.h +++ b/indra/newview/rlvlocks.h @@ -367,6 +367,8 @@ public: const uuid_vec_t& getAttachmentLookups() { return m_LockedAttachmentRem; } const uuid_vec_t& getWearableLookups() { return m_LockedWearableRem; } protected: + boost::signals2::connection m_AttachmentChangeConnection; + // Map of folder locks (idRlvObj -> lockDescr) folderlock_list_t m_FolderLocks; // List of add and remove locked folder descriptions S32 m_cntLockAdd; // Number of RLV_LOCK_ADD locked folders in m_FolderLocks From d956fb60db79a04e21e082a2fcef85e57cfc22db Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sun, 10 Jul 2016 22:39:06 +0200 Subject: [PATCH 7/8] [FIXED] Strict versions of restictions fail with "unknown command" -> additionally, revert to using the stored string behaviour otherwise @sendim_sec=n,getstatus=0 shows /sendim rather than /sendim_sec --HG-- branch : RLVa --- indra/newview/rlvhelper.cpp | 2 +- indra/newview/rlvhelper.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 80929deceb..fde6a6e4bc 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -357,7 +357,7 @@ const RlvBehaviourInfo* RlvBehaviourDictionary::getBehaviourInfo(const std::stri if (pfStrict) *pfStrict = fStrict; - rlv_string2info_map_t::const_iterator itBhvr = m_String2InfoMap.find(std::make_pair(strBhvr, (eParamType & RLV_TYPE_ADDREM) ? RLV_TYPE_ADDREM : eParamType)); + rlv_string2info_map_t::const_iterator itBhvr = m_String2InfoMap.find(std::make_pair( (!fStrict) ? strBhvr : strBhvr.substr(0, strBhvr.size() - 4), (eParamType & RLV_TYPE_ADDREM) ? RLV_TYPE_ADDREM : eParamType)); return ( (itBhvr != m_String2InfoMap.end()) && ((!fStrict) || (itBhvr->second->hasStrict())) ) ? itBhvr->second : NULL; } diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index 72b157ec94..f9bb093bee 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -385,7 +385,7 @@ public: */ public: std::string asString() const; - const std::string& getBehaviour() const { return (m_pBhvrInfo) ? m_pBhvrInfo->getBehaviour() : m_strBehaviour; } + const std::string& getBehaviour() const { return m_strBehaviour; } ERlvBehaviour getBehaviourType() const { return (m_pBhvrInfo) ? m_pBhvrInfo->getBehaviourType() : RLV_BHVR_UNKNOWN; } U32 getBehaviourFlags() const{ return (m_pBhvrInfo) ? m_pBhvrInfo->getBehaviourFlags() : 0; } const LLUUID& getObjectID() const { return m_idObj; } From 822845e78f552071243eeb45a416fde85e8879f1 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Mon, 11 Jul 2016 02:07:44 +0200 Subject: [PATCH 8/8] [FIXED] Changes to camera FOV persist across relogs and don't reset/restore upon release --HG-- branch : RLVa --- indra/newview/rlvhandler.cpp | 40 ++++++++++++++++++++++++++++++++++++ indra/newview/rlvhelper.cpp | 6 +++--- indra/newview/rlvhelper.h | 1 + 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 6ad9e4c848..6ec5f73ddd 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -1771,6 +1771,38 @@ void RlvBehaviourModifierHandler::onValueChange } } +// Handles: @setcam_fovmin:=n|y and @setcam_fovmax:=n|y +template<> template<> +ERlvCmdRet RlvBehaviourSetCamFovHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) +{ + static float s_nLastCameraAngle = DEFAULT_FIELD_OF_VIEW; + + S32 nRefMinBhvr = gRlvHandler.m_Behaviours[RLV_BHVR_SETCAM_FOVMIN], nRefMaxBhvr = gRlvHandler.m_Behaviours[RLV_BHVR_SETCAM_FOVMAX]; + LLControlVariable* pSetting = gSavedSettings.getControl("CameraAngle"); + + // Save the user's current FOV angle if nothing's been restricted (yet) + if ( (!nRefMinBhvr) && (!nRefMaxBhvr) && (pSetting) ) + s_nLastCameraAngle = (pSetting->isPersisted()) ? LLViewerCamera::instance().getDefaultFOV() : DEFAULT_FIELD_OF_VIEW; + + // Perform default handling of the command + ERlvCmdRet eRet = RlvBehaviourGenericHandler::onCommand(rlvCmd, fRefCount); + if ( (RLV_RET_SUCCESS == eRet) && (fRefCount) && (pSetting) ) + { + if (RLV_TYPE_ADD == rlvCmd.getParamType()) + { + // Don't persist changes from this point + pSetting->setPersist(LLControlVariable::PERSIST_NO); + } + else if ( (RLV_TYPE_REMOVE == rlvCmd.getParamType()) && (1 == nRefMinBhvr + nRefMaxBhvr) ) + { + // Restore the user's last FOV angle (and resume persistance) + LLViewerCamera::instance().setDefaultFOV(s_nLastCameraAngle); + pSetting->setPersist(LLControlVariable::PERSIST_NONDFT); + } + } + return eRet; +} + // Handles: @setcam_fovmin:=n|y changes template<> void RlvBehaviourModifierHandler::onValueChange() const @@ -2354,6 +2386,14 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlv return RLV_RET_FAILED_OPTION; LLViewerCamera::getInstance()->setDefaultFOV(nFOV); + + // Don't persist non-default changes that are due to RLV; but do resume persistance once reset back to the default + if ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOVMIN)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOVMAX)) ) + { + if (LLControlVariable* pSetting = gSavedSettings.getControl("CameraAngle")) + pSetting->setPersist( (pSetting->isDefault()) ? LLControlVariable::PERSIST_NONDFT : LLControlVariable::PERSIST_NO ); + } + return RLV_RET_SUCCESS; } diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index fde6a6e4bc..63c447e703 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -187,11 +187,11 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addModifier(RLV_BHVR_SETCAM_EYEOFFSET, RLV_MODIFIER_SETCAM_EYEOFFSET, new RlvBehaviourModifierHandler("Camera - Eye Offset", LLVector3::zero, true, nullptr)); addEntry(new RlvBehaviourGenericToggleProcessor("setcam_focusoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addModifier(RLV_BHVR_SETCAM_FOCUSOFFSET, RLV_MODIFIER_SETCAM_FOCUSOFFSET, new RlvBehaviourModifierHandler("Camera - Focus Offset", LLVector3::zero, true, nullptr)); - addEntry(new RlvBehaviourGenericProcessor("setcam_fovmin", RLV_BHVR_SETCAM_FOVMIN)); + addEntry(new RlvBehaviourProcessor("setcam_fovmin")); addModifier(RLV_BHVR_SETCAM_FOVMIN, RLV_MODIFIER_SETCAM_FOVMIN, new RlvBehaviourModifierHandler("Camera - FOV (Min)", DEFAULT_FIELD_OF_VIEW, true, new RlvBehaviourModifier_CompMax)); - addEntry(new RlvBehaviourGenericProcessor("setcam_fovmax", RLV_BHVR_SETCAM_FOVMAX)); - addEntry(new RlvBehaviourGenericToggleProcessor("setcam_mouselook")); + addEntry(new RlvBehaviourProcessor("setcam_fovmax")); addModifier(RLV_BHVR_SETCAM_FOVMAX, RLV_MODIFIER_SETCAM_FOVMAX, new RlvBehaviourModifierHandler("Camera - FOV (Max)", DEFAULT_FIELD_OF_VIEW, true, new RlvBehaviourModifier_CompMin)); + addEntry(new RlvBehaviourGenericToggleProcessor("setcam_mouselook")); addEntry(new RlvBehaviourGenericProcessor("setcam_textures", RLV_BHVR_SETCAM_TEXTURES)); addModifier(RLV_BHVR_SETCAM_TEXTURES, RLV_MODIFIER_SETCAM_TEXTURE, new RlvBehaviourModifierHandler("Camera - Forced Texture", IMG_DEFAULT, true, nullptr)); addEntry(new RlvBehaviourGenericToggleProcessor("setcam_unlock")); diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index f9bb093bee..6f9dc3c722 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -174,6 +174,7 @@ typedef RlvBehaviourToggleHandler RlvBehaviourCamEyeF typedef RlvBehaviourHandler RlvBehaviourAddRemAttachHandler; // Shared between @addattach and @remattach typedef RlvBehaviourHandler RlvBehaviourSendChannelHandler; // Shared between @sendchannel and @sendchannel_except typedef RlvBehaviourHandler RlvBehaviourRecvSendStartIMHandler; // Shared between @recvim, @sendim and @startim +typedef RlvBehaviourHandler RlvBehaviourSetCamFovHandler; // Shared between @setcam_fovmin and @setcam_fovmax typedef RlvBehaviourToggleHandler RlvBehaviourShowSelfToggleHandler; // Shared between @showself and @showselfhead typedef RlvBehaviourHandler RlvBehaviourCamZoomMinMaxHandler; // Shared between @camzoommin and @camzoommax (deprecated) typedef RlvReplyHandler RlvReplyCamMinMaxModifierHandler; // Shared between @getcam_avdistmin and @getcam_avdistmax