From ce82adec2a0124fe27f363653d2652b0f5c61f04 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted Date: Fri, 16 Oct 2009 16:39:44 -0700 Subject: Applied RLVa-1.0.4e_20091010_SL-1.22.11-diff.patch --- linden/indra/newview/app_settings/settings.xml | 2 +- linden/indra/newview/llagent.cpp | 4 +- linden/indra/newview/llchatbar.cpp | 18 ++-- linden/indra/newview/llinventorybridge.cpp | 2 +- linden/indra/newview/llpanelinventory.cpp | 2 +- linden/indra/newview/llviewermenu.cpp | 2 +- linden/indra/newview/llviewermessage.cpp | 9 +- linden/indra/newview/llviewertexteditor.cpp | 2 +- linden/indra/newview/rlvdefines.h | 17 +++- linden/indra/newview/rlvextensions.cpp | 34 ++++++- linden/indra/newview/rlvextensions.h | 2 + linden/indra/newview/rlvhandler.cpp | 122 ++++++++++++++++++------- linden/indra/newview/rlvhandler.h | 108 +++++++++------------- linden/indra/newview/rlvhelper.cpp | 67 +++++++------- linden/indra/newview/rlvhelper.h | 55 ++++++++++- 15 files changed, 285 insertions(+), 161 deletions(-) (limited to 'linden/indra') diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 55e6131..15bb319 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -65,7 +65,7 @@ Type Boolean Value - 0 + 1 RLVaHideLockedLayers diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 022e1cc..8b118e0 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -5991,7 +5991,7 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id) { // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) if ( (rlv_handler_t::isEnabled()) && - ( (gRlvHandler.hasBehaviour("tplm")) || + ( (gRlvHandler.hasBehaviour(RLV_BHVR_TPLM)) || ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting)) )) { return; @@ -6065,7 +6065,7 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global) // [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-07 (RLVa-1.0.0d) // If we're getting teleported due to @tpto we should disregard any @tploc=n or @unsit=n restrictions from the same object if ( (rlv_handler_t::isEnabled()) && - ( (gRlvHandler.hasBehaviourExcept("tploc", gRlvHandler.getCurrentObject())) || + ( (gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOC, gRlvHandler.getCurrentObject())) || ( (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting) && (gRlvHandler.hasBehaviourExcept(RLV_BHVR_UNSIT, gRlvHandler.getCurrentObject()))) ) ) { diff --git a/linden/indra/newview/llchatbar.cpp b/linden/indra/newview/llchatbar.cpp index 608fb54..710677a 100644 --- a/linden/indra/newview/llchatbar.cpp +++ b/linden/indra/newview/llchatbar.cpp @@ -634,11 +634,11 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL if ( (0 == channel) && (rlv_handler_t::isEnabled()) ) { // Adjust the (public) chat "volume" on chat and gestures (also takes care of playing the proper animation) - if ( ((CHAT_TYPE_SHOUT == type) || (CHAT_TYPE_NORMAL == type)) && (gRlvHandler.hasBehaviour("chatnormal")) ) + if ( ((CHAT_TYPE_SHOUT == type) || (CHAT_TYPE_NORMAL == type)) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATNORMAL)) ) type = CHAT_TYPE_WHISPER; - else if ( (CHAT_TYPE_SHOUT == type) && (gRlvHandler.hasBehaviour("chatshout")) ) + else if ( (CHAT_TYPE_SHOUT == type) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATSHOUT)) ) type = CHAT_TYPE_NORMAL; - else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour("chatwhisper")) ) + else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATWHISPER)) ) type = CHAT_TYPE_NORMAL; animate &= !gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT); @@ -692,11 +692,11 @@ void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channe if (0 == channel) { // (We already did this before, but LLChatHandler::handle() calls this directly) - if ( ((CHAT_TYPE_SHOUT == type) || (CHAT_TYPE_NORMAL == type)) && (gRlvHandler.hasBehaviour("chatnormal")) ) + if ( ((CHAT_TYPE_SHOUT == type) || (CHAT_TYPE_NORMAL == type)) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATNORMAL)) ) type = CHAT_TYPE_WHISPER; - else if ( (CHAT_TYPE_SHOUT == type) && (gRlvHandler.hasBehaviour("chatshout")) ) + else if ( (CHAT_TYPE_SHOUT == type) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATSHOUT)) ) type = CHAT_TYPE_NORMAL; - else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour("chatwhisper")) ) + else if ( (CHAT_TYPE_WHISPER == type) && (gRlvHandler.hasBehaviour(RLV_BHVR_CHATWHISPER)) ) type = CHAT_TYPE_NORMAL; // Redirect chat if needed @@ -707,20 +707,20 @@ void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channe } // Filter public chat if sendchat restricted (and filter anything that redirchat didn't redirect) - if ( (gRlvHandler.hasBehaviour("sendchat")) || (gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT)) ) + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHAT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT)) ) gRlvHandler.filterChat(utf8_out_text, true); } else { // Don't allow chat on a non-public channel if sendchannel restricted (unless the channel is an exception) - if ( (gRlvHandler.hasBehaviour("sendchannel")) && (!gRlvHandler.hasBehaviour("sendchannel", llformat("%d", channel))) ) + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHANNEL)) && (!gRlvHandler.isException(RLV_BHVR_SENDCHANNEL, channel)) ) return; // Don't allow chat on debug channel if @sendchat, @redirchat or @rediremote restricted (shows as public chat on viewers) if (channel >= CHAT_CHANNEL_DEBUG) { bool fIsEmote = rlvIsEmote(utf8_out_text); - if ( (gRlvHandler.hasBehaviour("sendchat")) || + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHAT)) || ((!fIsEmote) && (gRlvHandler.hasBehaviour(RLV_BHVR_REDIRCHAT))) || ((fIsEmote) && (gRlvHandler.hasBehaviour(RLV_BHVR_REDIREMOTE))) ) { diff --git a/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp index 0d5625c..5060d21 100644 --- a/linden/indra/newview/llinventorybridge.cpp +++ b/linden/indra/newview/llinventorybridge.cpp @@ -2943,7 +2943,7 @@ void open_notecard(LLViewerInventoryItem* inv_item, BOOL take_focus) { // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) - if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour("viewnote")) ) + if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) ) { return; } diff --git a/linden/indra/newview/llpanelinventory.cpp b/linden/indra/newview/llpanelinventory.cpp index 7ab850f..0ae2aec 100644 --- a/linden/indra/newview/llpanelinventory.cpp +++ b/linden/indra/newview/llpanelinventory.cpp @@ -1377,7 +1377,7 @@ void LLTaskNotecardBridge::openItem() return; } // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) - if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour("viewnote")) || (!gRlvHandler.isDetachable(object))) ) + if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) || (!gRlvHandler.isDetachable(object))) ) { return; } diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index ceb5d5f..4493ddf 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -1423,7 +1423,7 @@ void init_debug_rlva_menu(LLMenuGL* menu) #ifdef RLV_EXTENSION_ENABLE_WEAR if (gSavedSettings.controlExists(RLV_SETTING_ENABLEWEAR)) - menu->append(new LLMenuItemCheckGL("Enable Wear", menu_toggle_control, NULL, menu_check_control, (void*)RLV_SETTING_ENABLEWEAR)); + menu->append(new LLMenuItemCheckGL("Enable Wear", menu_toggle_control, rlvEnableWearEnabler, menu_check_control, (void*)RLV_SETTING_ENABLEWEAR)); menu->appendSeparator(); #endif // RLV_EXTENSION_ENABLE_WEAR diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp index 3baeec0..c403e3e 100644 --- a/linden/indra/newview/llviewermessage.cpp +++ b/linden/indra/newview/llviewermessage.cpp @@ -2485,7 +2485,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) color.setVec(1.f,1.f,1.f,1.f); msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg); -// [RLVa:KB] - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d +// [RLVa:KB] - Checked: 2009-10-06 (RLVa-1.0.4d) | Modified: RLVa-1.0.4d if ( (rlv_handler_t::isEnabled()) && (CHAT_TYPE_START != chat.mChatType) && (CHAT_TYPE_STOP != chat.mChatType) && (CHAT_TYPE_OWNER != chat.mChatType) ) { @@ -2495,7 +2495,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) // Filtering "rules": // avatar => filter all avie text (unless it's this avie or they're an exemption) // objects => filter everything except attachments this avie owns - if ( ((CHAT_SOURCE_AGENT == chat.mSourceType) && (from_id != gAgent.getID())) || (!is_owned_by_me) || (!is_attachment) ) + if ( ( (CHAT_SOURCE_AGENT == chat.mSourceType) && (from_id != gAgent.getID()) ) || + ( (CHAT_SOURCE_OBJECT == chat.mSourceType) && ((!is_owned_by_me) || (!is_attachment)) ) ) { if (!rlvIsEmote(mesg)) { @@ -4933,7 +4934,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data) // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0e S32 rlvQuestionsOther = questions; - if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour("acceptpermission")) ) + if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_ACCEPTPERMISSION)) ) { LLViewerObject* pObj = gObjectList.findObject(taskid); if (pObj) @@ -5308,7 +5309,7 @@ void handle_lure(LLDynamicArray& ids) for (LLDynamicArray::iterator it = ids.begin(); it != ids.end(); ++it) { const LLRelationship* pBuddyInfo = LLAvatarTracker::instance().getBuddyInfo(*it); - if ( (!gRlvHandler.isException(RLV_BHVR_TPLURE, *it)) && + if ( (!gRlvHandler.isException(RLV_BHVR_TPLURE, *it, RLV_CHECK_PERMISSIVE)) && ((!pBuddyInfo) || (!pBuddyInfo->isOnline()) || (!pBuddyInfo->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION))) ) { delete userdata; diff --git a/linden/indra/newview/llviewertexteditor.cpp b/linden/indra/newview/llviewertexteditor.cpp index 76b752c..8f4a944 100644 --- a/linden/indra/newview/llviewertexteditor.cpp +++ b/linden/indra/newview/llviewertexteditor.cpp @@ -96,7 +96,7 @@ public: else { // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) - if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour("viewnote")) ) + if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) ) { return; } diff --git a/linden/indra/newview/rlvdefines.h b/linden/indra/newview/rlvdefines.h index 4e6a4d4..d1e0b75 100644 --- a/linden/indra/newview/rlvdefines.h +++ b/linden/indra/newview/rlvdefines.h @@ -41,13 +41,14 @@ // Version of the specifcation we support const S32 RLV_VERSION_MAJOR = 1; -const S32 RLV_VERSION_MINOR = 20; -const S32 RLV_VERSION_PATCH = 2; +const S32 RLV_VERSION_MINOR = 21; +const S32 RLV_VERSION_PATCH = 0; +const S32 RLV_VERSION_BUILD = 0; // Implementation version const S32 RLVa_VERSION_MAJOR = 1; const S32 RLVa_VERSION_MINOR = 0; -const S32 RLVa_VERSION_PATCH = 3; +const S32 RLVa_VERSION_PATCH = 4; const S32 RLVa_VERSION_BUILD = 4; // The official viewer version we're patching against @@ -136,6 +137,7 @@ enum ERlvBehaviour { RLV_BHVR_SHOWLOC, // "showloc" RLV_BHVR_TPTO, // "tpto" RLV_BHVR_ACCEPTTP, // "accepttp" + RLV_BHVR_ACCEPTPERMISSION, // "acceptpermission" RLV_BHVR_SHOWNAMES, // "shownames" RLV_BHVR_FLY, // "fly" RLV_BHVR_GETSITID, // "getsitid" @@ -147,6 +149,9 @@ enum ERlvBehaviour { RLV_BHVR_SHOWHOVERTEXTHUD, // "showhovertexthud" RLV_BHVR_SHOWHOVERTEXT, // "showhovertext" RLV_BHVR_NOTIFY, // "notify" + RLV_BHVR_DEFAULTWEAR, // "defaultwear" + RLV_BHVR_VERSIONNUM, // "versionnum" + RLV_BHVR_PERMISSIVE, // "permissive" RLV_BHVR_COUNT, RLV_BHVR_UNKNOWN @@ -174,6 +179,12 @@ enum ERlvCmdRet { RLV_RET_UNKNOWN // Command unkown }; +enum ERlvExceptionCheck { + RLV_CHECK_PERMISSIVE, // Exception can be set by any object + RLV_CHECK_STRICT, // Exception must be set by all objects holding the restriction + RLV_CHECK_DEFAULT // Permissive or strict will be determined by currently enforced restrictions +}; + // ============================================================================ // Settings diff --git a/linden/indra/newview/rlvextensions.cpp b/linden/indra/newview/rlvextensions.cpp index 10d1c46..f31c62e 100644 --- a/linden/indra/newview/rlvextensions.cpp +++ b/linden/indra/newview/rlvextensions.cpp @@ -12,13 +12,14 @@ // ============================================================================ std::map RlvExtGetSet::m_DbgAllowed; +std::map RlvExtGetSet::m_PseudoDebug; // Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h RlvExtGetSet::RlvExtGetSet() { if (!m_DbgAllowed.size()) // m_DbgAllowed is static and should only be initialized once { - m_DbgAllowed.insert(std::pair("AvatarSex", DBG_READ | DBG_PSEUDO)); + m_DbgAllowed.insert(std::pair("AvatarSex", DBG_READ | DBG_WRITE | DBG_PSEUDO)); m_DbgAllowed.insert(std::pair("RenderResolutionDivisor", DBG_READ | DBG_WRITE)); #ifdef RLV_EXTENSION_CMD_GETSETDEBUG_EX m_DbgAllowed.insert(std::pair(RLV_SETTING_FORBIDGIVETORLV, DBG_READ)); @@ -172,19 +173,27 @@ std::string RlvExtGetSet::onGetDebug(std::string strSetting) return std::string(); } -// Checked: 2009-06-03 (RLVa-0.2.0h) | Added: RLVa-0.2.0h +// Checked: 2009-10-03 (RLVa-1.0.4e) | Added: RLVa-1.0.4e std::string RlvExtGetSet::onGetPseudoDebug(const std::string& strSetting) { // Skip sanity checking because it's all done in RlvExtGetSet::onGetDebug() already if ("AvatarSex" == strSetting) { - if (gAgent.getAvatarObject()) - return llformat("%d", (gAgent.getAvatarObject()->getSex() == SEX_MALE)); // [See LLFloaterCustomize::LLFloaterCustomize()] + std::map::const_iterator itPseudo = m_PseudoDebug.find(strSetting); + if (itPseudo != m_PseudoDebug.end()) + { + return itPseudo->second; + } + else + { + if (gAgent.getAvatarObject()) + return llformat("%d", (gAgent.getAvatarObject()->getSex() == SEX_MALE)); // [See LLFloaterCustomize::LLFloaterCustomize()] + } } return std::string(); } -// Checked: 2009-06-03 (RLVa-0.2.0h) | Modified: RLVa-0.2.0h +// Checked: 2009-10-10 (RLVa-1.0.4e) | Modified: RLVa-1.0.4e void RlvExtGetSet::onSetDebug(std::string strSetting, const std::string& strValue) { S16 dbgFlags; @@ -219,6 +228,21 @@ void RlvExtGetSet::onSetDebug(std::string strSetting, const std::string& strValu pSetting->setPersist( (pSetting->isDefault()) ? ((dbgFlags & DBG_PERSIST) == DBG_PERSIST) : false ); } } + else + { + onSetPseudoDebug(strSetting, strValue); + } + } +} + +// Checked: 2009-10-10 (RLVa-1.0.4e) | Modified: RLVa-1.0.4e +void RlvExtGetSet::onSetPseudoDebug(const std::string& strSetting, const std::string& strValue) +{ + if ("AvatarSex" == strSetting) + { + BOOL fValue; + if (LLStringUtil::convertToBOOL(strValue, fValue)) + m_PseudoDebug[strSetting] = strValue; } } diff --git a/linden/indra/newview/rlvextensions.h b/linden/indra/newview/rlvextensions.h index 5c10c58..5720ba0 100644 --- a/linden/indra/newview/rlvextensions.h +++ b/linden/indra/newview/rlvextensions.h @@ -24,6 +24,7 @@ protected: std::string onGetDebug(std::string strSetting); std::string onGetPseudoDebug(const std::string& strSetting); void onSetDebug(std::string strSetting, const std::string& strValue); + void onSetPseudoDebug(const std::string& strSetting, const std::string& strValue); std::string onGetEnv(std::string strSetting); void onSetEnv(std::string strSetting, const std::string& strValue); @@ -33,6 +34,7 @@ protected: public: enum { DBG_READ = 0x01, DBG_WRITE = 0x02, DBG_PERSIST = 0x04, DBG_PSEUDO = 0x08 }; static std::map m_DbgAllowed; + static std::map m_PseudoDebug; static bool findDebugSetting(/*[in,out]*/ std::string& strSetting, /*[out]*/ S16& flags); static S16 getDebugSettingFlags(const std::string& strSetting); diff --git a/linden/indra/newview/rlvhandler.cpp b/linden/indra/newview/rlvhandler.cpp index 6044aa9..69e2e2f 100644 --- a/linden/indra/newview/rlvhandler.cpp +++ b/linden/indra/newview/rlvhandler.cpp @@ -286,7 +286,7 @@ bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDe if (!fDetachable) { #ifdef RLV_EXPERIMENTAL_FIRSTUSE - LLFirstUse::useRlvDetach(); + //LLFirstUse::useRlvDetach(); #endif // RLV_EXPERIMENTAL_FIRSTUSE // NOTE: m_Attachments can contain duplicate pairs (ie @detach:spine=n,detach=n from an attachment on spine) @@ -338,27 +338,47 @@ bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDe // Behaviour related functions // -bool RlvHandler::hasBehaviourExcept(const std::string& strBehaviour, const LLUUID& idObj) const -{ - for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) - if ( (idObj != itObj->second.m_UUID) && (itObj->second.hasBehaviour(strBehaviour)) ) - return true; - return false; -} - bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const { for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) - if ( (idObj != itObj->second.m_UUID) && (itObj->second.hasBehaviour(eBehaviour, strOption)) ) + if ( (idObj != itObj->second.m_UUID) && (itObj->second.hasBehaviour(eBehaviour, strOption, false)) ) return true; return false; } -bool RlvHandler::hasBehaviourExcept(const std::string& strBehaviour, const std::string& strOption, const LLUUID& idObj) const +// Checked: 2009-10-04 (RLVa-1.0.4c) | Modified: RLVa-1.0.4c +bool RlvHandler::isException(ERlvBehaviour eBhvr, const RlvExceptionOption& varOption, ERlvExceptionCheck typeCheck) const { - for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) - if ( (idObj != itObj->second.m_UUID) && (itObj->second.hasBehaviour(strBehaviour, strOption)) ) - return true; + // We need to "strict check" exceptions only if: the restriction is actually in place *and* (isPermissive(eBhvr) == FALSE) + if (RLV_CHECK_DEFAULT == typeCheck) + typeCheck = ( (hasBehaviour(eBhvr)) && (!isPermissive(eBhvr)) ) ? RLV_CHECK_STRICT : RLV_CHECK_PERMISSIVE; + + std::list objList; + if (RLV_CHECK_STRICT == typeCheck) + { + // If we're "strict checking" then we need the UUID of every object that currently has 'eBhvr' restricted + for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) + if (itObj->second.hasBehaviour(eBhvr, !hasBehaviour(RLV_BHVR_PERMISSIVE))) + objList.push_back(itObj->first); + } + + for (rlv_exception_map_t::const_iterator itException = m_Exceptions.lower_bound(eBhvr), + endException = m_Exceptions.upper_bound(eBhvr); itException != endException; ++itException) + { + if (itException->second.varOption == varOption) + { + // For permissive checks we just return on the very first match + if (RLV_CHECK_PERMISSIVE == typeCheck) + return true; + + // For strict checks we don't return until the list is empty (every object with 'eBhvr' restricted also contains the exception) + std::list::iterator itList = std::find(objList.begin(), objList.end(), itException->second.idObject); + if (itList != objList.end()) + objList.erase(itList); + if (objList.empty()) + return true; + } + } return false; } @@ -509,7 +529,11 @@ BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) const std::string& strOption = rlvCmd.getOption(); if ( (RLV_BHVR_UNKNOWN != eBehaviour) && (strOption.empty()) ) + { + if (rlvCmd.isStrict()) + addException(uuid, RLV_BHVR_PERMISSIVE, eBehaviour); m_Behaviours[eBehaviour]++; + } switch (eBehaviour) { @@ -649,7 +673,7 @@ BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) case RLV_BHVR_FARTOUCH: { #ifdef RLV_EXPERIMENTAL_FIRSTUSE - LLFirstUse::useRlvFartouch(); + //LLFirstUse::useRlvFartouch(); #endif // RLV_EXPERIMENTAL_FIRSTUSE } break; @@ -695,9 +719,9 @@ BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:=n - Checked: 2009-07-09 (RLVa-0.2.2a) | Modified: RLVa-1.0.0f { LLUUID idException(strOption); - if (!idException.isNull()) // If there's an option it should be a valid UUID + if (idException.notNull()) // If there's an option it should be a valid UUID { - addException(eBehaviour, LLUUID(strOption)); + addException(uuid, eBehaviour, idException); // Clear the object's hover text LLViewerObject* pObj = gObjectList.findObject(idException); @@ -717,6 +741,13 @@ BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) } } break; + case RLV_BHVR_SENDCHANNEL: // @sendchannel:=add - Checked: 2009-10-05 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a + { + S32 nChannel; // If there's an option it should be a valid (=positive and non-zero) chat channel + if ( (!strOption.empty()) && (LLStringUtil::convertToS32(strOption, nChannel)) && (nChannel > 0) ) + addException(uuid, eBehaviour, nChannel); + } + break; case RLV_BHVR_RECVCHAT: // @recvchat:=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f case RLV_BHVR_RECVEMOTE: // @recvemote:=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f case RLV_BHVR_RECVIM: // @recvim:=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f @@ -724,16 +755,20 @@ BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) case RLV_BHVR_TPLURE: // @tplure:=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f case RLV_BHVR_ACCEPTTP: // @accepttp:=add - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f { - addException(eBehaviour, LLUUID(strOption)); + LLUUID idException(strOption); + if (idException.notNull()) // If there's an option it should be a valid UUID + addException(uuid, eBehaviour, LLUUID(strOption)); } break; - default: + case RLV_BHVR_UNKNOWN: { // Give our observers a chance to handle any command we don't RlvEvent rlvEvent(uuid, rlvCmd); m_Emitter.update(&RlvObserver::onAddCommand, rlvEvent); } break; + default: + break; } return TRUE; // Add command success/failure is decided by RlvObject::addCommand() } @@ -756,7 +791,11 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC const std::string& strOption = rlvCmd.getOption(); if ( (RLV_BHVR_UNKNOWN != eBehaviour) && (strOption.empty()) ) + { + if (rlvCmd.isStrict()) + removeException(uuid, RLV_BHVR_PERMISSIVE, eBehaviour); m_Behaviours[eBehaviour]--; + } switch (eBehaviour) { @@ -842,9 +881,9 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:=y - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f { LLUUID idException(strOption); - if (!idException.isNull()) // If there's an option it should be a valid UUID + if (idException.notNull()) // If there's an option it should be a valid UUID { - removeException(eBehaviour, LLUUID(strOption)); + removeException(uuid, eBehaviour, idException); // Restore the object's hover text LLViewerObject* pObj = gObjectList.findObject(idException); @@ -869,6 +908,13 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC } } break; + case RLV_BHVR_SENDCHANNEL: // @sendchannel:=rem - Checked: 2009-10-05 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a + { + S32 nChannel; // If there's an option it should be a valid (=positive and non-zero) chat channel + if ( (!strOption.empty()) && (LLStringUtil::convertToS32(strOption, nChannel)) && (nChannel > 0) ) + removeException(uuid, eBehaviour, nChannel); + } + break; case RLV_BHVR_RECVCHAT: // @recvchat:=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f case RLV_BHVR_RECVEMOTE: // @recvemote:=red - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f case RLV_BHVR_RECVIM: // @recvim:=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f @@ -876,16 +922,20 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC case RLV_BHVR_TPLURE: // @recvim:=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f case RLV_BHVR_ACCEPTTP: // @accepttp:=rem - Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f { - removeException(eBehaviour, LLUUID(strOption)); + LLUUID idException(strOption); + if (idException.notNull()) // If there's an option it should be a valid UUID + removeException(uuid, eBehaviour, LLUUID(strOption)); } break; - default: + case RLV_BHVR_UNKNOWN: { // Give our observers a chance to handle any command we don't RlvEvent rlvEvent(uuid, rlvCmd); m_Emitter.update(&RlvObserver::onRemoveCommand, rlvEvent); } break; + default: + break; } return TRUE; // Remove commands don't fail, doesn't matter what we return here } @@ -1006,13 +1056,15 @@ BOOL RlvHandler::processForceCommand(const LLUUID& idObj, const RlvCommand& rlvC } } break; - default: + case RLV_BHVR_UNKNOWN: { // Give our observers a chance to handle any command we don't RlvEvent rlvEvent(idObj, rlvCmd); fHandled = m_Emitter.update(&RlvObserver::onForceCommand, rlvEvent); } break; + default: + break; } return fHandled; // If we handled it then it'll still be TRUE; if an observer doesn't handle it'll be FALSE } @@ -1030,6 +1082,9 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm case RLV_BHVR_VERSION: // @version= - Checked: 2009-07-12 (RLVa-1.0.0h) strReply = getVersionString(); break; + case RLV_BHVR_VERSIONNUM: // @versionnum= - Checked: 2009-10-04 (RLVa-1.0.4b) | Added: RLVa-1.0.4b + strReply = getVersionNumString(); + break; case RLV_BHVR_GETOUTFIT: // @getoufit[:]= - Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d { // (Quirk: RLV 1.16.1 will execute @getoutfit= if is invalid, so we need to as well) @@ -1225,13 +1280,15 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm strReply = uuid.asString(); } break; - default: + case RLV_BHVR_UNKNOWN: { // Give our observers a chance to handle any command we don't RlvEvent rlvEvent(uuid, rlvCmd); return m_Emitter.update(&RlvObserver::onReplyCommand, rlvEvent); } break; + default: + break; } if (fHandled) @@ -1318,7 +1375,7 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded) itObj->second.m_fLookup = true; // In both cases we should check for "@detach=n" and actually lock down the attachment point it got attached to - if (itObj->second.hasBehaviour(RLV_BHVR_DETACH)) + if (itObj->second.hasBehaviour(RLV_BHVR_DETACH, false)) { // (Copy/paste from processAddCommand) setDetachable(idxAttachPt, pObj->getID(), false); @@ -1569,7 +1626,7 @@ void RlvHandler::filterChat(std::string& strUTF8Text, bool fFilterEmote) const { strUTF8Text = "..."; // Emote contains illegal character (or character sequence) } - else if (!hasBehaviour("emote")) + else if (!hasBehaviour(RLV_BHVR_EMOTE)) { int idx = strUTF8Text.find('.'); // Truncate at 20 characters or at the dot (whichever is shorter) strUTF8Text = utf8str_chtruncate(strUTF8Text, ( (idx > 0) && (idx < 20) ) ? idx + 1 : 20); @@ -1674,17 +1731,18 @@ bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const return false; // @sendchat wouldn't filter it so @redirchat won't redirect it either } - bool fSendChannel = hasBehaviour("sendchannel"); + bool fSendChannel = hasBehaviour(RLV_BHVR_SENDCHANNEL); S32 nChannel = 0; for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) { for (rlv_command_list_t::const_iterator itCmd = itObj->second.m_Commands.begin(), endCmd = itObj->second.m_Commands.end(); itCmd != endCmd; ++itCmd) { - if ( ( ((!fIsEmote) && (RLV_BHVR_REDIRCHAT == itCmd->getBehaviourType())) || - ((fIsEmote) && (RLV_BHVR_REDIREMOTE == itCmd->getBehaviourType())) ) && - ( (!fSendChannel) || (hasBehaviour("sendchannel", itCmd->getOption())) ) ) + if ( ( ((!fIsEmote) && (RLV_BHVR_REDIRCHAT == itCmd->getBehaviourType())) || // Redirect if: (not an emote and @redirchat + ((fIsEmote) && (RLV_BHVR_REDIREMOTE == itCmd->getBehaviourType())) ) && // OR an emote and @rediremote) + (LLStringUtil::convertToS32(itCmd->getOption(), nChannel)) && // AND the channel is a number + ( (!fSendChannel) || (isException(RLV_BHVR_SENDCHANNEL, nChannel)) ) ) // AND we're allowed to send to that channel { - rlvSendChatReply(itCmd->getOption(), strUTF8Text); + rlvSendChatReply(nChannel, strUTF8Text); } } } diff --git a/linden/indra/newview/rlvhandler.h b/linden/indra/newview/rlvhandler.h index 4470632..5295a72 100644 --- a/linden/indra/newview/rlvhandler.h +++ b/linden/indra/newview/rlvhandler.h @@ -18,7 +18,7 @@ typedef std::map rlv_object_map_t; typedef std::multimap rlv_detach_map_t; typedef std::map rlv_reattach_map_t; -typedef std::multimap rlv_exception_map_t; +typedef std::multimap rlv_exception_map_t; class RlvHandler { @@ -29,7 +29,7 @@ public: // -------------------------------- /* - * Rule checking functions + * Attachment point helper functions */ public: // Returns a pointer to the attachment point for a supplied parameter @@ -42,45 +42,45 @@ public: S32 getAttachPointIndex(const LLViewerJointAttachment* pObj) const; bool hasAttachPointName(const LLInventoryItem* pItem, bool fStrict) const; - // Returns TRUE is at least one object contains the specified behaviour (and optional parameter) + // -------------------------------- + + /* + * Rule checking functions + */ // NOTE: - to check @detach=n -> hasLockedAttachment() / hasLockedHUD() / isDetachable() + // - to check exceptions -> isException() // - to check @addoutfit=n -> isWearable() // - to check @remoutfit=n -> isRemovable() - // - to check exceptions -> isException() - // (You *can* use hasBehaviour(); the specialized ones just don't have to iterate over all the objects) +public: + // Returns TRUE is at least one object contains the specified behaviour (and optional option) bool hasBehaviour(ERlvBehaviour eBehaviour) const { return (eBehaviour < RLV_BHVR_COUNT) ? (0 != m_Behaviours[eBehaviour]) : false; } - bool hasBehaviour(const std::string& strBehaviour) const; bool hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const; - bool hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const; - - // Returns TRUE if at least one object (except the specified one) contains the specified behaviour + // Returns TRUE if at least one object (except the specified one) contains the specified behaviour (and optional option) bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const; - bool hasBehaviourExcept(const std::string& strBehaviour, const LLUUID& uuid) const; bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const; - bool hasBehaviourExcept(const std::string& strBehaviour, const std::string& strOption, const LLUUID& idObj) const; - // Returns TRUE if there is at least 1 undetachable attachment + // Returns TRUE if there is at least 1 non-detachable attachment bool hasLockedAttachment() const { return (0 != m_Attachments.size()); } - // Returns TRUE if there is at least 1 undetachable HUD attachment + // Returns TRUE if there is at least 1 non-detachable HUD attachment bool hasLockedHUD() const; - // Returns TRUE if the specified attachment point is detachable bool isDetachable(S32 idxAttachPt) const { return (idxAttachPt) && (m_Attachments.find(idxAttachPt) == m_Attachments.end()); } bool isDetachable(const LLInventoryItem* pItem) const; bool isDetachable(LLViewerJointAttachment* pAttachPt) const; bool isDetachable(LLViewerObject* pObj) const; - // Returns TRUE if the specified attachment point is set undetachable by anything other than pObj (or one of its children) + // Returns TRUE if the specified attachment point is set non-detachable by anything other than pObj (or one of its children) bool isDetachableExcept(S32 idxAttachPt, LLViewerObject* pObj) const; - // Marks the specified attachment point as (un)detachable (return value indicates success ; used by unit tests) + // Marks the specified attachment point as (non-)detachable (return value indicates success ; used by unit tests) bool setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable); bool setDetachable(LLViewerObject* pObj, const LLUUID& idRlvObj, bool fDetachable); - // Adds or removes an exception for the specified restriction - void addException(ERlvBehaviour eBehaviour, const LLUUID& uuid); - void removeException(ERlvBehaviour eBehaviour, const LLUUID& uuid); - // Returns TRUE is the specified UUID is exempt from a restriction (tplure/sendim/recvim/etc) - bool isException(ERlvBehaviour eBehaviour, const LLUUID& uuid) const; - bool isException(const std::string& strBehaviour, const LLUUID& uuid) const; + // Adds or removes an exception for the specified behaviour + void addException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption); + void removeException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption); + // Returns TRUE if the specified option was added as an exception for the specified behaviour + bool isException(ERlvBehaviour eBhvr, const RlvExceptionOption& varOption, ERlvExceptionCheck typeCheck = RLV_CHECK_DEFAULT) const; + // Returns TRUE if the specified behaviour should behave "permissive" (rather than "strict"/"secure") + bool isPermissive(ERlvBehaviour eBhvr) const; // Returns TRUE if the specified layer is removable (use hasBehaviour(RLV_BHVR_REMOUTFIT) for the general case) bool isRemovable(EWearableType type) const { return (type < WT_COUNT) ? (0 == m_LayersRem[type]) : true; } @@ -121,6 +121,7 @@ public: void filterNames(std::string& strUTF8Text) const; // @shownames const std::string& getAnonym(const std::string& strName) const; // @shownames std::string getVersionString() const; // @version + std::string getVersionNumString() const; // @versionnum BOOL isAgentNearby(const LLUUID& uuid) const; // @shownames bool redirectChatOrEmote(const std::string& strUTF8Test) const; // @redirchat and @rediremote @@ -274,11 +275,10 @@ extern rlv_handler_t gRlvHandler; // Inlined member functions // -// Checked: 2009-07-09 (RLVa-1.0.0f) -inline void RlvHandler::addException(ERlvBehaviour eBehaviour, const LLUUID& uuid) +// Checked: 2009-10-04 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a +inline void RlvHandler::addException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption) { - if (!uuid.isNull()) - m_Exceptions.insert(std::pair(uuid, eBehaviour)); + m_Exceptions.insert(std::pair(eBhvr, RlvException(idObj, eBhvr, varOption))); } // Checked: 2009-07-09 (RLVa-1.0.0f) | Modified: RLVa-1.0.0f @@ -288,7 +288,7 @@ inline bool RlvHandler::canShowHoverText(LLViewerObject *pObj) const !( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTALL)) || ( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTWORLD)) && (!pObj->isHUDAttachment()) ) || ( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTHUD)) && (pObj->isHUDAttachment()) ) || - (isException(RLV_BHVR_SHOWHOVERTEXT, pObj->getID())) ) ); + (isException(RLV_BHVR_SHOWHOVERTEXT, pObj->getID(), RLV_CHECK_PERMISSIVE)) ) ); } // Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d @@ -321,6 +321,12 @@ inline std::string RlvHandler::getVersionString() const RLVa_VERSION_MAJOR, RLVa_VERSION_MINOR, RLVa_VERSION_PATCH); } +// Checked: 2009-10-04 (RLVa-1.0.4b) | Added: RLVa-1.0.4b +inline std::string RlvHandler::getVersionNumString() const +{ + return llformat("%d%02d%02d%02d", RLV_VERSION_MAJOR, RLV_VERSION_MINOR, RLV_VERSION_PATCH, RLV_VERSION_BUILD); +} + // Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d inline bool RlvHandler::hasAttachPointName(const LLInventoryItem *pItem, bool fStrict) const { @@ -334,18 +340,6 @@ inline bool RlvHandler::hasBehaviour(ERlvBehaviour eBehaviour, const std::string } // Checked: -inline bool RlvHandler::hasBehaviour(const std::string& strBehaviour) const -{ - return hasBehaviourExcept(strBehaviour, LLUUID::null); -} - -// Checked: -inline bool RlvHandler::hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const -{ - return hasBehaviourExcept(strBehaviour, strOption, LLUUID::null); -} - -// Checked: inline bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const { return hasBehaviourExcept(eBehaviour, std::string(), idObj); @@ -379,22 +373,11 @@ inline bool RlvHandler::isDetachable(LLViewerObject* pObj) const return (pObj == NULL) || (!pObj->isAttachment()) || (isDetachable(getAttachPointIndex(pObj))); } -// Checked: -inline bool RlvHandler::isException(ERlvBehaviour eBehaviour, const LLUUID& uuid) const -{ - for (rlv_exception_map_t::const_iterator itException = m_Exceptions.lower_bound(uuid), - endException = m_Exceptions.upper_bound(uuid); itException != endException; ++itException) - { - if (itException->second == eBehaviour) - return true; - } - return false; -} - -// Checked: -inline bool RlvHandler::isException(const std::string& strBehaviour, const LLUUID& uuid) const +inline bool RlvHandler::isPermissive(ERlvBehaviour eBhvr) const { - return hasBehaviour(strBehaviour, uuid.asString()); + return (RlvCommand::hasStrictVariant(eBhvr)) + ? !((hasBehaviour(RLV_BHVR_PERMISSIVE)) || (isException(RLV_BHVR_PERMISSIVE, eBhvr, RLV_CHECK_PERMISSIVE))) + : true; } // Checked: 2009-07-29 (RLVa-1.0.1b) | Added: RLVa-1.0.1b @@ -428,19 +411,16 @@ inline bool RlvHandler::isRemovableExcept(EWearableType type, const LLUUID& idOb } #endif // RLV_EXTENSION_FLAG_NOSTRIP -// Checked: 2009-07-09 (RLVa-1.0.0f) -inline void RlvHandler::removeException(ERlvBehaviour eBehaviour, const LLUUID &uuid) +// Checked: 2009-10-04 (RLVa-1.0.4a) | Modified: RLVa-1.0.4a +inline void RlvHandler::removeException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption) { - if (!uuid.isNull()) + for (rlv_exception_map_t::iterator itException = m_Exceptions.lower_bound(eBhvr), + endException = m_Exceptions.upper_bound(eBhvr); itException != endException; ++itException) { - for (rlv_exception_map_t::iterator itException = m_Exceptions.lower_bound(uuid), - endException = m_Exceptions.upper_bound(uuid); itException != endException; ++itException) + if ( (itException->second.idObject == idObj) && (itException->second.varOption == varOption) ) { - if (itException->second == eBehaviour) - { - m_Exceptions.erase(itException); - break; - } + m_Exceptions.erase(itException); + break; } } } diff --git a/linden/indra/newview/rlvhelper.cpp b/linden/indra/newview/rlvhelper.cpp index f495384..c8d430d 100644 --- a/linden/indra/newview/rlvhelper.cpp +++ b/linden/indra/newview/rlvhelper.cpp @@ -23,7 +23,7 @@ RlvCommand::RlvBhvrTable RlvCommand::m_BhvrMap; // Checked: 2009-09-10 (RLVa-1.0.3a) | Modified: RLVa-1.0.3a RlvCommand::RlvCommand(const std::string& strCommand) - : m_eBehaviour(RLV_BHVR_UNKNOWN), m_eParamType(RLV_TYPE_UNKNOWN) + : m_eBehaviour(RLV_BHVR_UNKNOWN), m_fStrict(false), m_eParamType(RLV_TYPE_UNKNOWN) { if ((m_fValid = parseCommand(strCommand, m_strBehaviour, m_strOption, m_strParam))) { @@ -51,8 +51,12 @@ RlvCommand::RlvCommand(const std::string& strCommand) return; } - RlvBhvrTable::const_iterator itBhvr = m_BhvrMap.find(m_strBehaviour); - if (itBhvr != m_BhvrMap.end()) + // Check if this is the "strict" (aka "secure") variation of a behaviour + std::string::size_type idxStrict = m_strBehaviour.find("_sec"); + m_fStrict = (std::string::npos != idxStrict) && (idxStrict + 4 == m_strBehaviour.length()); + + RlvBhvrTable::const_iterator itBhvr = m_BhvrMap.find( (!m_fStrict) ? m_strBehaviour : m_strBehaviour.substr(0, idxStrict)); + if ( (itBhvr != m_BhvrMap.end()) && ((!m_fStrict) || (hasStrictVariant(itBhvr->second))) ) m_eBehaviour = itBhvr->second; } @@ -104,8 +108,8 @@ void RlvCommand::initLookupTable() "remoutfit", "getoutfit", "getattach", "showinv", "viewnote", "unsit", "sit", "sendchannel", "getstatus", "getstatusall", "getinv", "getinvworn", "findfolder", "findfolders", "attach", "attachall", "detachall", "getpath", "attachthis", "attachallthis", "detachthis", "detachallthis", "fartouch", "showworldmap", "showminimap", "showloc", "tpto", "accepttp", - "shownames", "fly", "getsitid", "setdebug", "setenv", "detachme", "showhovertextall", "showhovertextworld", - "showhovertexthud", "showhovertext", "notify" + "acceptpermission", "shownames", "fly", "getsitid", "setdebug", "setenv", "detachme", "showhovertextall", + "showhovertextworld", "showhovertexthud", "showhovertext", "notify", "defaultwear", "versionnum", "permissive" }; for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++) @@ -133,12 +137,14 @@ bool RlvObject::addCommand(const RlvCommand& rlvCmd) return false; // Don't add duplicate commands for this object (ie @detach=n followed by another @detach=n later on) - bool fDuplicate = - (RLV_BHVR_UNKNOWN != rlvCmd.getBehaviourType()) - ? hasBehaviour(rlvCmd.getBehaviourType(), rlvCmd.getOption()) - : hasBehaviour(rlvCmd.getBehaviour(), rlvCmd.getOption()); - if (fDuplicate) - return false; + for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) + { + if ( (itCmd->getBehaviour() == rlvCmd.getBehaviour()) && (itCmd->getOption() == rlvCmd.getOption()) && + (itCmd->isStrict() == rlvCmd.isStrict() ) ) + { + return false; + } + } // Now that we know it's not a duplicate, add it to the end of the list m_Commands.push_back(rlvCmd); @@ -155,7 +161,8 @@ bool RlvObject::removeCommand(const RlvCommand& rlvCmd) for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) { //if (*itCmd == rlvCmd) <- commands will never be equal since one is an add and the other is a remove *rolls eyes* - if ( (itCmd->getBehaviour() == rlvCmd.getBehaviour()) && (itCmd->getOption() == rlvCmd.getOption()) ) + if ( (itCmd->getBehaviour() == rlvCmd.getBehaviour()) && (itCmd->getOption() == rlvCmd.getOption()) && + (itCmd->isStrict() == rlvCmd.isStrict() ) ) { m_Commands.erase(itCmd); return true; @@ -164,34 +171,18 @@ bool RlvObject::removeCommand(const RlvCommand& rlvCmd) return false; // Command was never added so nothing to remove now } -bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour) const -{ - for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) - if ( (itCmd->getBehaviourType() == eBehaviour) && (itCmd->getOption().empty()) ) - return true; - return false; -} - -bool RlvObject::hasBehaviour(const std::string& strBehaviour) const -{ - for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) - if ( (itCmd->getBehaviour() == strBehaviour) && (itCmd->getOption().empty()) ) - return true; - return false; -} - -bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const +bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, bool fStrictOnly) const { for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) - if ( (itCmd->getBehaviourType() == eBehaviour) && (itCmd->getOption() == strOption) ) + if ( (itCmd->getBehaviourType() == eBehaviour) && (itCmd->getOption().empty()) && ((!fStrictOnly) || (itCmd->isStrict())) ) return true; return false; } -bool RlvObject::hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const +bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption, bool fStrictOnly) const { for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) - if ( (itCmd->getBehaviour() == strBehaviour) && (itCmd->getOption() == strOption) ) + if ( (itCmd->getBehaviourType() == eBehaviour) && (itCmd->getOption() == strOption) && ((!fStrictOnly) || (itCmd->isStrict())) ) return true; return false; } @@ -361,6 +352,11 @@ RlvWLSnapshot* RlvWLSnapshot::takeSnapshot() BOOL RlvSettings::fShowNameTags = FALSE; +BOOL RlvSettings::getEnableWear() +{ + return rlvGetSettingBOOL(RLV_SETTING_ENABLEWEAR, TRUE) && (!gRlvHandler.hasBehaviour(RLV_BHVR_DEFAULTWEAR)); +} + #ifdef RLV_EXTENSION_STARTLOCATION // Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1d void RlvSettings::updateLoginLastLocation() @@ -475,6 +471,13 @@ bool rlvCanDeleteOrReturn() return fIsAllowed; } +// Checked: 2009-10-04 (RLVa-1.0.4b) | Modified: RLVa-1.0.4b +BOOL rlvEnableWearEnabler(void* pParam) +{ + // Visually disables the "Enable Wear" option when restricted from toggling it + return (!gRlvHandler.hasBehaviour(RLV_BHVR_DEFAULTWEAR)); +} + // Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type) { diff --git a/linden/indra/newview/rlvhelper.h b/linden/indra/newview/rlvhelper.h index f36989b..42d10b8 100644 --- a/linden/indra/newview/rlvhelper.h +++ b/linden/indra/newview/rlvhelper.h @@ -9,6 +9,15 @@ #include "llwlparamset.h" #include "rlvdefines.h" +#ifdef LL_WINDOWS + #pragma warning (push) + #pragma warning (disable : 4702) // warning C4702: unreachable code +#endif +#include +#ifdef LL_WINDOWS + #pragma warning (pop) +#endif + // ============================================================================ // RlvCommand // @@ -28,10 +37,12 @@ public: const std::string& getOption() const { return m_strOption; } const std::string& getParam() const { return m_strParam; } ERlvParamType getParamType() const { return m_eParamType; } + bool isStrict() const { return m_fStrict; } bool isValid() const { return m_fValid; } static ERlvBehaviour getBehaviourFromString(const std::string& strBhvr); static const std::string& getStringFromBehaviour(ERlvBehaviour eBhvr); + static bool hasStrictVariant(ERlvBehaviour eBhvr); static void initLookupTable(); protected: @@ -50,6 +61,7 @@ protected: bool m_fValid; std::string m_strBehaviour; ERlvBehaviour m_eBehaviour; + bool m_fStrict; std::string m_strOption; std::string m_strParam; ERlvParamType m_eParamType; @@ -78,10 +90,8 @@ public: bool removeCommand(const RlvCommand& rlvCmd); std::string getStatusString(const std::string& strMatch) const; - bool hasBehaviour(ERlvBehaviour eBehaviour) const; - bool hasBehaviour(const std::string& strBehaviour) const; - bool hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const; - bool hasBehaviour(const std::string& strBehaviour, const std::string& strOption) const; + bool hasBehaviour(ERlvBehaviour eBehaviour, bool fStrictOnly) const; + bool hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption, bool fStrictOnly) const; const rlv_command_list_t* getCommandList() const { return &m_Commands; } @@ -190,6 +200,24 @@ private: typedef std::list rlv_retained_list_t; // ============================================================================ +// RlvException +// + +typedef boost::variant RlvExceptionOption; + +struct RlvException +{ +public: + LLUUID idObject; // UUID of the object that added the exception + ERlvBehaviour eBehaviour; // Behaviour the exception applies to + RlvExceptionOption varOption; // Exception data (type is dependent on eBehaviour) + + RlvException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& option) : idObject(idObj), eBehaviour(eBhvr), varOption(option) {} +private: + RlvException(); +}; + +// ============================================================================ // RlvWLSnapshot // @@ -225,7 +253,7 @@ public: static BOOL getDebug() { return rlvGetSettingBOOL(RLV_SETTING_DEBUG, FALSE); } static BOOL getForbidGiveToRLV() { return rlvGetSettingBOOL(RLV_SETTING_FORBIDGIVETORLV, TRUE); } - static BOOL getEnableWear() { return rlvGetSettingBOOL(RLV_SETTING_ENABLEWEAR, FALSE); } + static BOOL getEnableWear(); static BOOL getHideLockedLayers() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDLAYER, FALSE); } static BOOL getHideLockedAttach() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDATTACH, FALSE); } static BOOL getHideLockedInventory() { return rlvGetSettingBOOL(RLV_SETTING_HIDELOCKEDINVENTORY, FALSE); } @@ -290,6 +318,7 @@ struct RlvSelectIsSittingOn : public LLSelectedNodeFunctor BOOL rlvAttachToEnabler(void* pParam); bool rlvCanDeleteOrReturn(); +BOOL rlvEnableWearEnabler(void* pParam); S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type); bool rlvIsEmote(const std::string& strUTF8Text); bool rlvIsValidReplyChannel(S32 nChannel); @@ -344,6 +373,22 @@ inline void RlvCurrentlyWorn::fetchItem(const LLUUID& idItem) } } +inline bool RlvCommand::hasStrictVariant(ERlvBehaviour eBhvr) +{ + switch (eBhvr) + { + case RLV_BHVR_RECVCHAT: + case RLV_BHVR_RECVEMOTE: + case RLV_BHVR_RECVIM: + case RLV_BHVR_SENDIM: + case RLV_BHVR_TPLURE: + case RLV_BHVR_SENDCHANNEL: + return true; + default: + return false; + } +} + // ============================================================================ // Inlined helper functions // -- cgit v1.1