From 7fec6599790f56ecf816bcf30187bdf928ece67b Mon Sep 17 00:00:00 2001 From: Siana Gearz Date: Wed, 25 Jan 2012 21:11:33 +0100 Subject: [PATCH] Update RLVa to 1.4.0-compatible --- indra/llcommon/llmd5.h | 3 + indra/newview/llagentwearables.cpp | 10 +- indra/newview/llglsandbox.cpp | 16 +- indra/newview/llimpanel.cpp | 76 +++--- indra/newview/llimpanel.h | 11 + indra/newview/llimview.cpp | 15 +- indra/newview/llinventorybridge.cpp | 76 +++++- indra/newview/llinventoryfunctions.cpp | 66 ++++- indra/newview/llinventoryfunctions.h | 16 ++ indra/newview/llselectmgr.cpp | 15 +- indra/newview/lltoolface.cpp | 6 +- indra/newview/lltoolselect.cpp | 4 +- indra/newview/llviewermenu.cpp | 21 +- indra/newview/llviewermessage.cpp | 68 ++--- indra/newview/llviewerobject.cpp | 4 +- indra/newview/llvoavatar.cpp | 5 + indra/newview/llvovolume.cpp | 6 +- indra/newview/pipeline.cpp | 4 +- indra/newview/rlvcommon.cpp | 9 +- indra/newview/rlvcommon.h | 15 +- indra/newview/rlvdefines.h | 28 ++- indra/newview/rlvhandler.cpp | 294 ++++++++++++++++++---- indra/newview/rlvhandler.h | 108 ++++---- indra/newview/rlvhelper.cpp | 107 ++++++-- indra/newview/rlvhelper.h | 129 ++++++---- indra/newview/rlvinventory.cpp | 51 +++- indra/newview/rlvinventory.h | 42 +++- indra/newview/rlvlocks.cpp | 331 ++++++++++++++++++++++++- indra/newview/rlvlocks.h | 291 ++++++++++++++++++++-- indra/newview/rlvviewer2.cpp | 102 ++++++++ indra/newview/rlvviewer2.h | 30 +++ 31 files changed, 1637 insertions(+), 322 deletions(-) diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h index 8bf715f14..590718687 100644 --- a/indra/llcommon/llmd5.h +++ b/indra/llcommon/llmd5.h @@ -134,4 +134,7 @@ private: LL_COMMON_API bool operator==(const LLMD5& a, const LLMD5& b); LL_COMMON_API bool operator!=(const LLMD5& a, const LLMD5& b); +LL_COMMON_API bool operator==(const LLMD5& a, const LLMD5& b); +LL_COMMON_API bool operator!=(const LLMD5& a, const LLMD5& b); + #endif // LL_LLMD5_H diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 610c7af61..01cb1d74a 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1578,7 +1578,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it { const LLUUID& old_item_id = getWearableItemID(type, 0); if( (old_wearable->getAssetID() == new_wearable->getAssetID()) && - (old_item_id == new_item->getUUID()) ) + (old_item_id == new_item->getLinkedUUID()) ) { lldebugs << "No change to wearable asset and item: " << LLWearableType::getTypeName( type ) << llendl; continue; @@ -1600,7 +1600,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it } new_wearable->setName(new_item->getName()); - new_wearable->setItemID(new_item->getUUID()); + new_wearable->setItemID(new_item->getLinkedUUID()); if (LLWearableType::getAssetType(type) == LLAssetType::AT_BODYPART) { @@ -1675,9 +1675,9 @@ void LLAgentWearables::setWearableItem( LLInventoryItem* new_item, LLWearable* n LLWearableType::EType type = new_wearable->getType(); -// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) +// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.1.4a) // Block if: we can't wear on that layer; or we're already wearing something there we can't take off - if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canWear(type)) ) + if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canWear(dynamic_cast(new_item))) ) { return; } @@ -1762,7 +1762,7 @@ void LLAgentWearables::setWearableFinal( LLInventoryItem* new_item, LLWearable* { old_item_id = old_wearable->getItemID(); } - new_wearable->setItemID(new_item->getUUID()); + new_wearable->setItemID(new_item->getLinkedUUID()); setWearable(type,0,new_wearable); if (old_item_id.notNull()) diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 5423a268a..410910aaa 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -76,8 +76,13 @@ // Returns true if you got at least one object void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) { -// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l - if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT))) ) +// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c + // Block rectangle selection if: + // - prevented from editing and no exceptions are set (see below for the case where exceptions are set) + // - prevented from interacting at all + if ( (rlv_handler_t::isEnabled()) && + ( ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasException(RLV_BHVR_EDIT))) || + (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) ) ) { return; } @@ -242,6 +247,13 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) continue; } +// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Added: RLVa-1.3.0c + if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canEdit(vobjp)) ) + { + continue; + } +// [/RLVa:KB] + S32 result = LLViewerCamera::getInstance()->sphereInFrustum(drawable->getPositionAgent(), drawable->getRadius()); if (result) { diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 3f83c92f2..115476183 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -1167,6 +1167,9 @@ LLFloaterIMPanel::LLFloaterIMPanel( void LLFloaterIMPanel::init(const std::string& session_label) { + // set P2P type by default + mSessionType = P2P_SESSION; + mSessionLabel = session_label; // [Ansariel: Display name support] @@ -1219,6 +1222,15 @@ void LLFloaterIMPanel::init(const std::string& session_label) break; } + if ( (IM_NOTHING_SPECIAL != mDialog) && (IM_SESSION_P2P_INVITE != mDialog) ) + { + // determine whether it is group or conference session + if (gAgent.isInGroup(mSessionUUID)) + mSessionType = GROUP_SESSION; + else + mSessionType = ADHOC_SESSION; + } + mSpeakers = new LLIMSpeakerMgr(mVoiceChannel); LLUICtrlFactory::getInstance()->buildFloater(this, @@ -2192,40 +2204,48 @@ void LLFloaterIMPanel::sendMsg() std::string prefix = utf8text.substr(0, 4); if (prefix != "/me " && prefix != "/me'") if (mRPMode) utf8text = "[[" + utf8text + "]]"; - -// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-1.0.0g - if (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) + +// [RLVa:KB] - Checked: 2011-09-17 (RLVa-1.1.4b) | Modified: RLVa-1.1.4b + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) ) { - if (IM_NOTHING_SPECIAL == mDialog) // One-on-one IM: allow if recipient is a sendim exception + bool fRlvFilter = false; + switch (mSessionType) { - if (!gRlvHandler.isException(RLV_BHVR_SENDIM, mOtherParticipantUUID)) - utf8text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM); - } - else if (gAgent.isInGroup(mSessionUUID)) // Group chat: allow if recipient is a sendim exception - { - if (!gRlvHandler.isException(RLV_BHVR_SENDIM, mSessionUUID)) - utf8text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM); - } - else if (mSpeakers) // Conference chat: allow if all participants are sendim exceptions - { - LLSpeakerMgr::speaker_list_t speakers; - mSpeakers->getSpeakerList(&speakers, TRUE); - - for (LLSpeakerMgr::speaker_list_t::const_iterator itSpeaker = speakers.begin(); - itSpeaker != speakers.end(); ++itSpeaker) - { - LLSpeaker* pSpeaker = *itSpeaker; - if ( (gAgent.getID() != pSpeaker->mID) && (!gRlvHandler.isException(RLV_BHVR_SENDIM, pSpeaker->mID)) ) + case P2P_SESSION: // One-on-one IM + fRlvFilter = !gRlvHandler.canSendIM(mOtherParticipantUUID); + break; + case GROUP_SESSION: // Group chat + fRlvFilter = !gRlvHandler.canSendIM(mSessionUUID); + break; + case ADHOC_SESSION: // Conference chat: allow if all participants can be sent an IM { - utf8text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM); - break; + if (!mSpeakers) + { + fRlvFilter = true; + break; + } + + LLSpeakerMgr::speaker_list_t speakers; + mSpeakers->getSpeakerList(&speakers, TRUE); + for (LLSpeakerMgr::speaker_list_t::const_iterator itSpeaker = speakers.begin(); + itSpeaker != speakers.end(); ++itSpeaker) + { + const LLSpeaker* pSpeaker = *itSpeaker; + if ( (gAgent.getID() != pSpeaker->mID) && (!gRlvHandler.canSendIM(pSpeaker->mID)) ) + { + fRlvFilter = true; + break; + } + } } - } + break; + default: + fRlvFilter = true; + break; } - else // Catch all fall-through - { + + if (fRlvFilter) utf8text = RlvStrings::getString(RLV_STRING_BLOCKED_SENDIM); - } } // [/RLVa:KB] diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index 6f4e7d43a..69cd8f19e 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -279,6 +279,17 @@ public: static bool onConfirmForceCloseError(const LLSD& notification, const LLSD& response); + typedef enum e_session_type + { + P2P_SESSION, + GROUP_SESSION, + ADHOC_SESSION + } SType; + bool isP2PSessionType() const { return mSessionType == P2P_SESSION;} + bool isAdHocSessionType() const { return mSessionType == ADHOC_SESSION;} + bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;} + SType mSessionType; + private: // called by constructors void init(const std::string& session_label); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 8e484a5b1..ba794068a 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1656,17 +1656,18 @@ public: { return; } -// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) - // TODO-RLVa: duplicate from process_improved_im()? - if (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIMFROM)) ) { - if (gAgent.isInGroup(session_id)) + if (gAgent.isInGroup(session_id)) // Group chat: don't accept the invite if not an exception { - if (!gRlvHandler.isException(RLV_BHVR_RECVIM, session_id)) + if (!gRlvHandler.canReceiveIM(session_id)) return; } - else if (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) - message = message.substr(0, message_offset) + RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM); + else if (!gRlvHandler.canReceiveIM(from_id)) // Conference chat: don't block; censor if not an exception + { + message = RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM); + } } // [/RLVa:KB] diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 84d47a3f2..61418100f 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1375,6 +1375,11 @@ BOOL LLItemBridge::isItemRenameable() const return FALSE; } +// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g + if ( (rlv_handler_t::isEnabled()) && (!RlvFolderLocks::instance().canRenameItem(mUUID)) ) + return FALSE; +// [/RLVa:KB] + return (item->getPermissions().allowModifyBy(gAgent.getID())); } return FALSE; @@ -1545,6 +1550,13 @@ BOOL LLFolderBridge::isItemRemovable() return FALSE; } +// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g + if ( ((rlv_handler_t::isEnabled()) && (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) && (!RlvFolderLocks::instance().canRemoveFolder(mUUID))) ) + { + return FALSE; + } +// [/RLVa:KB] + LLVOAvatar* avatar = gAgentAvatarp; if( !avatar ) { @@ -1728,6 +1740,13 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, // //-------------------------------------------------------------------------------- +// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Added: RLVa-1.3.0g + if ( (is_movable) && (rlv_handler_t::isEnabled()) && (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) ) + { + is_movable = RlvFolderLocks::instance().canMoveFolder(cat_id, mUUID); + } +// [/RLVa:KB] + accept = is_movable && (mUUID != cat_id) // Can't move a folder into itself && (mUUID != inv_cat->getParentUUID()) // Avoid moves that would change nothing @@ -2864,6 +2883,22 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, is_movable &= inv_item->getIsLinkType() || !get_is_item_worn(inv_item->getUUID()); } +// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g + if ( (rlv_handler_t::isEnabled()) && (is_movable) ) + { + if (move_is_into_current_outfit) + { + // RELEASE-RLVa: [RLVa-1.3.0] Keep sync'ed with code below => LLAppearanceMgr::wearItemOnAvatar() with "replace == true" + const LLViewerInventoryItem* pItem = dynamic_cast(inv_item); + is_movable = rlvPredCanWearItem(pItem, RLV_WEAR_REPLACE); + } + if (is_movable) + { + is_movable = (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) && (RlvFolderLocks::instance().canMoveItem(inv_item->getUUID(), mUUID)); + } + } + // [/RLVa:KB] + accept = is_movable && (mUUID != inv_item->getParentUUID()); if(accept && drop) { @@ -2894,7 +2929,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, wear_inventory_item_on_avatar(inv_item); break; case LLAssetType::AT_OBJECT: - rez_attachment((LLViewerInventoryItem*)inv_item, NULL, false); + rez_attachment((LLViewerInventoryItem*)inv_item, NULL, true); break; /* case LLAssetType::AT_GESTURE: @@ -3834,6 +3869,12 @@ BOOL LLObjectBridge::isItemRemovable() { return FALSE; } +// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g + if ( (rlv_handler_t::isEnabled()) && (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) && (!RlvFolderLocks::instance().canRemoveItem(mUUID)) ) + { + return FALSE; + } +// [/RLVa:KB] const LLInventoryObject *obj = model->getItem(mUUID); if (obj && obj->getIsLinkType()) { @@ -4888,8 +4929,8 @@ void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, B // item->setAssetUUID(wearable->getID()); // item->updateAssetOnServer(); // } -// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.1.3b) | Modified: RLVa-1.1.3b - if (!gRlvWearableLocks.canWear(wearable->getType())) +// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.1.3b) | Modified: RLVa-1.1.4a + if (!gRlvWearableLocks.canWear(item)) { continue; } @@ -5053,6 +5094,18 @@ BOOL LLWearableBridge::isItemRemovable() { return FALSE; } +// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g + if ( (rlv_handler_t::isEnabled()) && (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) && (!RlvFolderLocks::instance().canRemoveItem(mUUID)) ) + { + return FALSE; + } +// [/RLVa:KB] +// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g + if ( (rlv_handler_t::isEnabled()) && (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) && (!RlvFolderLocks::instance().canRemoveItem(mUUID)) ) + { + return FALSE; + } +// [/RLVa:KB] const LLInventoryObject *obj = model->getItem(mUUID); if (obj && obj->getIsLinkType()) { @@ -5196,6 +5249,13 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Wearable Wear")); items.push_back(std::string("Wearable Edit")); +// [RLVa:KB] - Checked: 2011-09-16 (RLVa-1.1.4a) | Added: RLVa-1.1.4a + if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(item)) ) + { + disabled_items.push_back(std::string("Wearable Wear")); + disabled_items.push_back(std::string("Wearable Edit")); + } +// [/RLVa:KB] if ((flags & FIRST_SELECTED_ITEM) == 0) { @@ -5215,20 +5275,24 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) switch (item->getType()) { case LLAssetType::AT_CLOTHING: - items.push_back(std::string("Take Off")); + items.push_back(std::string("Take Off")); +// [RLVa:KB] - Checked: 2011-09-16 (RLVa-1.1.4a) | Added: RLVa-1.1.4a + if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(item)) ) + disabled_items.push_back(std::string("Take Off")); +// [/RLVa:KB] // Fallthrough since clothing and bodypart share wear options case LLAssetType::AT_BODYPART: if (get_is_item_worn(item->getUUID())) { disabled_items.push_back(std::string("Wearable And Wear")); disabled_items.push_back(std::string("Wearable Add")); - } + } else { items.push_back(std::string("Wearable Wear")); disabled_items.push_back(std::string("Take Off")); disabled_items.push_back(std::string("Wearable Edit")); - } + } /*if (LLWearableType::getAllowMultiwear(mWearableType)) { diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index dafa4434b..c4546838d 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -75,6 +75,11 @@ #include "llvoavatarself.h" #include "llwearablelist.h" +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) +#include "rlvhandler.h" +#include "rlvlocks.h" +// [/RLVa:KB] + #include "cofmgr.h" BOOL LLInventoryState::sWearNewClothing = FALSE; @@ -269,10 +274,10 @@ BOOL get_is_item_worn(const LLInventoryItem *item) return FALSE; // Consider the item as worn if it has links in COF. - if (LLCOFMgr::instance().isLinkInCOF(item->getUUID())) - { + /* if (LLCOFMgr::instance().isLinkInCOF(item->getUUID())) + { REMOVED due to advice from Kitty Barnett, looks like it WILL cause trouble on some grids -SG return TRUE; - } + } */ switch(item->getType()) { @@ -390,6 +395,14 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id) } } +// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g + if ( (rlv_handler_t::isEnabled()) && + (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) && (!RlvFolderLocks::instance().canRemoveItem(id)) ) + { + return FALSE; + } +// [/RLVa:KB] + const LLInventoryObject *obj = model->getItem(id); if (obj && obj->getIsLinkType()) { @@ -418,6 +431,14 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id) return FALSE; } +// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g + if ( ((rlv_handler_t::isEnabled()) && + (RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) && (!RlvFolderLocks::instance().canRemoveFolder(id))) ) + { + return FALSE; + } +// [/RLVa:KB] + if (!isAgentAvatarValid()) return FALSE; const LLInventoryCategory* category = model->getCategory(id); @@ -453,6 +474,13 @@ BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id) return FALSE; } +// [RLVa:KB] - Checked: 2011-03-29 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g + if ( (rlv_handler_t::isEnabled()) && (model == &gInventory) && (!RlvFolderLocks::instance().canRenameFolder(id)) ) + { + return FALSE; + } +// [/RLVa:KB] + LLViewerInventoryCategory* cat = model->getCategory(id); if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) && @@ -627,6 +655,38 @@ bool LLFindWearables::operator()(LLInventoryCategory* cat, return FALSE; } +LLFindWearablesEx::LLFindWearablesEx(bool is_worn, bool include_body_parts) +: mIsWorn(is_worn) +, mIncludeBodyParts(include_body_parts) +{} + +bool LLFindWearablesEx::operator()(LLInventoryCategory* cat, LLInventoryItem* item) +{ + LLViewerInventoryItem *vitem = dynamic_cast(item); + if (!vitem) return false; + + // Skip non-wearables. + if (!vitem->isWearableType() && vitem->getType() != LLAssetType::AT_OBJECT) + { + return false; + } + + // Skip body parts if requested. + if (!mIncludeBodyParts && vitem->getType() == LLAssetType::AT_BODYPART) + { + return false; + } + + // Skip broken links. + if (vitem->getIsBrokenLink()) + { + return false; + } + + return (bool) get_is_item_worn(item->getUUID()) == mIsWorn; +} + + ///---------------------------------------------------------------------------- /// LLAssetIDMatches ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index b2e2be357..edae3872f 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -276,6 +276,22 @@ public: LLInventoryItem* item); }; +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFindWearables +// +// Collects wearables based on given criteria. +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +class LLFindWearablesEx : public LLInventoryCollectFunctor +{ +public: + LLFindWearablesEx(bool is_worn, bool include_body_parts = true); + virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item); +private: + bool mIncludeBodyParts; + bool mIsWorn; +}; + /** Inventory Collector Functions ** ** *******************************************************************************/ diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 1733cac0d..7a9abeaf6 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -3719,7 +3719,20 @@ void LLSelectMgr::deselectAllIfTooFar() return; } -// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l +// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c + if ( (!mSelectedObjects->isEmpty()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ))) ) + { + struct NotTransientOrEditable : public LLSelectedNodeFunctor + { + bool apply(LLSelectNode* pNode) + { + const LLViewerObject* pObj = pNode->getObject(); + return (!pNode->isTransient()) && (pObj) && (!gRlvHandler.canEdit(pObj)); + } + } f; + if (mSelectedObjects->getFirstRootNode(&f, TRUE)) + deselectAll(); + } #ifdef RLV_EXTENSION_CMD_INTERACT // [Fall-back code] Don't allow an active selection (except for HUD attachments - see above) when @interact=n restricted if (gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) diff --git a/indra/newview/lltoolface.cpp b/indra/newview/lltoolface.cpp index 735ecd9dc..4b5f19eba 100644 --- a/indra/newview/lltoolface.cpp +++ b/indra/newview/lltoolface.cpp @@ -104,10 +104,10 @@ void LLToolFace::pickCallback(const LLPickInfo& pick_info) return; } -// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l +// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c if ( (rlv_handler_t::isEnabled()) && - ( (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || - ((gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (!gRlvHandler.canTouch(hit_obj, pick_info.mObjectOffset))) ) ) + ( (!gRlvHandler.canEdit(hit_obj)) || + ((gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (!gRlvHandler.canTouch(hit_obj, pick_info.mObjectOffset))) ) ) { return; } diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index c46c505ab..5cfd6c59e 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -87,10 +87,10 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi object = object->getRootEdit(); } -// [RLVa:KB] - Checked: 2010-01-02 (RLVa-1.1.0l) | Modified: RLVa-1.1.0l +// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c if (rlv_handler_t::isEnabled()) { - if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) + if (!gRlvHandler.canEdit(object)) { if (!temp_select) { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 658c62ec1..710a3ec7f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1969,9 +1969,10 @@ class LLObjectOpen : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { -// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0b) | OK +// [RLVa:KB] - Checked: 2011-09-16 (RLVa-1.1.4b) | Modified: RLVa-1.1.4b // TODO-RLVa: shouldn't we be checking for fartouch here as well? - if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) + const LLViewerObject* pObj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canEdit(pObj)) ) { return true; } @@ -2059,9 +2060,13 @@ bool toggle_build_mode() } // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) - if ( (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (LLSelectMgr::getInstance()) ) + bool fRlvCanEdit = (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ)); + if (!fRlvCanEdit) { - LLSelectMgr::getInstance()->deselectAll(); + LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); + RlvSelectIsEditable f; + if ((hSel.notNull()) && ((hSel->getFirstRootNode(&f, TRUE)) != NULL)) + LLSelectMgr::getInstance()->deselectAll(); } // [/RLVa:KB] @@ -2167,9 +2172,13 @@ class LLObjectEdit : public view_listener_t // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0f if (rlv_handler_t::isEnabled()) { - if (gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) + bool fRlvCanEdit = (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDITOBJ)); + if (!fRlvCanEdit) { - return true; // Can't edit any object under @edit=n + LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); + RlvSelectIsEditable f; + if ((hSel.notNull()) && ((hSel->getFirstRootNode(&f, TRUE)) != NULL)) + return true; // Can't edit any object under @edit=n } else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (SELECT_TYPE_WORLD == LLSelectMgr::getInstance()->getSelection()->getSelectType()) && diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index fadfa3732..ef5efc2ac 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2012,9 +2012,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } // [/RLVa:KB] // else if (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM) -// [RLVa:KB] - Checked: 2010-03-23 (RLVa-1.2.0a) | Modified: RLVa-1.0.0g - else if ( (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM) && - ( (!gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) || (gRlvHandler.isException(RLV_BHVR_RECVIM, from_id))) ) +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c + else if ( (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM) && (gRlvHandler.canReceiveIM(from_id)) ) // [/RLVa:KB] { // return a standard "busy" message, but only do it to online IM @@ -2102,10 +2101,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) else { // standard message, not from system -// [RLVa:KB] - Checked: 2010-03-23 (RLVa-1.1.3a) | Modified: RLVa-1.2.0a +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c // Don't block offline IMs, or IMs from Lindens - if ( (rlv_handler_t::isEnabled()) && (offline != IM_OFFLINE) && (!is_linden) && - (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) && (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) ) + if ( (rlv_handler_t::isEnabled()) && (offline != IM_OFFLINE) && (!is_linden) && (!gRlvHandler.canReceiveIM(from_id)) ) { if (!is_muted) RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM_REMOTE), session_id); @@ -2448,24 +2446,33 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) // Only show messages if we have a session open (which // should happen after you get an "invitation" - if ( !gIMMgr->hasSession(session_id) ) +// if ( !gIMMgr->hasSession(session_id) ) +// { +// return; +// } +// [RLVa:KB] - Checked: 2011-09-17 (RLVa-1.1.4b) | Modified: RLVa-1.1.4b + LLFloaterIMPanel* pIMFloater = gIMMgr->findFloaterBySession(session_id); + if (!pIMFloater) { return; } -// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) - if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) ) + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIMFROM)) ) { - if (gAgent.isInGroup(session_id)) + switch (pIMFloater->mSessionType) { - if (!gRlvHandler.isException(RLV_BHVR_RECVIM, session_id)) + case LLFloaterIMPanel::GROUP_SESSION: // Group chat + if ( (from_id != gAgent.getID()) && (!gRlvHandler.canReceiveIM(session_id)) ) + return; + break; + case LLFloaterIMPanel::ADHOC_SESSION: // Conference chat + if ( (from_id != gAgent.getID()) && (!gRlvHandler.canReceiveIM(from_id)) ) + message = RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM); + break; + default: + RLV_ASSERT(false); return; } - else - { - if ( (from_id != gAgent.getID()) && (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) ) - message = message.substr(0, message_offset) + RlvStrings::getString(RLV_STRING_BLOCKED_RECVIM); - } } // [/RLVa:KB] @@ -2616,7 +2623,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } else { -// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.1.3a) | Modified: RLVa-1.0.0d +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c if (rlv_handler_t::isEnabled()) { if (!gRlvHandler.canTeleportViaLure(from_id)) @@ -2627,9 +2634,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) return; } - // Censor lure message if: 1) @revcim=n restricted (and sender isn't an exception), or 2) @showloc=n restricted - if ( ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVIM)) && (!gRlvHandler.isException(RLV_BHVR_RECVIM, from_id)) ) || - (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) + // Censor lure message if: 1) restricted from receiving IMs from the sender, or 2) @showloc=n restricted + if ( (!gRlvHandler.canReceiveIM(from_id)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) { message = RlvStrings::getString(RLV_STRING_HIDDEN); } @@ -2646,11 +2652,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) payload["godlike"] = FALSE; //LLNotificationsUtil::add("TeleportOffered", args, payload); -// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-07 (RLVa-1.0.0d) | Modified: RLVa-0.2.0b - if ( (rlv_handler_t::isEnabled()) && - ((gRlvHandler.hasBehaviour(RLV_BHVR_ACCEPTTP)) || (gRlvHandler.isException(RLV_BHVR_ACCEPTTP, from_id))) ) +// [RLVa:KB] - Checked: 2010-12-11 (RLVa-1.2.2c) | Modified: RLVa-1.2.2c + if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_ACCEPTTP)) || (fRlvSummon)) ) { gRlvHandler.setCanCancelTp(false); + if (is_busy) + busy_message(msg,from_id); LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); } else @@ -3297,10 +3304,14 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) { if (!RlvUtil::isEmote(mesg)) { - if ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVCHAT)) && (!gRlvHandler.isException(RLV_BHVR_RECVCHAT, from_id)) ) + if ( ((gRlvHandler.hasBehaviour(RLV_BHVR_RECVCHAT)) && (!gRlvHandler.isException(RLV_BHVR_RECVCHAT, from_id))) && + ((!gRlvHandler.hasBehaviour(RLV_BHVR_RECVCHATFROM)) || (gRlvHandler.isException(RLV_BHVR_RECVCHATFROM, from_id))) ) + { gRlvHandler.filterChat(mesg, false); + } } - else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_RECVEMOTE)) && (!gRlvHandler.isException(RLV_BHVR_RECVEMOTE, from_id)) ) + else if ( ((gRlvHandler.hasBehaviour(RLV_BHVR_RECVEMOTE)) && (!gRlvHandler.isException(RLV_BHVR_RECVEMOTE, from_id))) && + ((!gRlvHandler.hasBehaviour(RLV_BHVR_RECVEMOTEFROM)) || (gRlvHandler.isException(RLV_BHVR_RECVEMOTEFROM, from_id))) ) { mesg = "/me ..."; } @@ -6322,13 +6333,14 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response) if(0 == option) { -// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0b - if (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) +// [RLVa:KB] - Checked: 2010-11-30 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SENDIMTO)) ) { + // Filter the lure message if one of the recipients of the lure can't be sent an IM to for (LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray(); it != notification["payload"]["ids"].endArray(); ++it) { - if (!gRlvHandler.isException(RLV_BHVR_SENDIM, it->asUUID())) + if (!gRlvHandler.canSendIM(it->asUUID())) { text = RlvStrings::getString(RLV_STRING_HIDDEN); break; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index c1a461ca7..31df93696 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5244,8 +5244,8 @@ BOOL LLViewerObject::permTransfer() const // given you modify rights to. JC BOOL LLViewerObject::allowOpen() const { -// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0b) - return !flagInventoryEmpty() && (permYouOwner() || permModify()) && (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)); +// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c + return !flagInventoryEmpty() && (permYouOwner() || permModify()) && ((!rlv_handler_t::isEnabled()) || (gRlvHandler.canEdit(this))); // [/RLVa:KB] // return !flagInventoryEmpty() && (permYouOwner() || permModify()); } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 87005a669..8bcaccf98 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2056,6 +2056,11 @@ void LLVOAvatar::buildCharacter() return; } +// [RLVa:KB] - Checked: 2010-12-12 (RLVa-1.2.2c) | Added: RLVa-1.2.2c + if (isSelf()) + RlvAttachPtLookup::initLookupTable(); +// [/RLVa:KB] + //------------------------------------------------------------------------- // initialize "well known" joint pointers //------------------------------------------------------------------------- diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 98c2f6661..4b5fde59a 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2733,9 +2733,11 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e { if (!mbCanSelect || // (gHideSelectedObjects && isSelected()) || -// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.1.3b) | Modified: RLVa-1.1.3b +// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c ( (LLSelectMgr::getInstance()->mHideSelectedObjects && isSelected()) && - ((!rlv_handler_t::isEnabled()) || (!isHUDAttachment()) || (!gRlvAttachmentLocks.isLockedAttachment(getRootEdit()))) ) || + ( (!rlv_handler_t::isEnabled()) || + ( ((!isHUDAttachment()) || (!gRlvAttachmentLocks.isLockedAttachment(getRootEdit()))) && + (gRlvHandler.canEdit(this)) ) ) ) || // [/RLVa:KB] mDrawable->isDead() || !gPipeline.hasRenderType(mDrawable->getRenderType())) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 3fe1cc896..d78beb0d2 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2847,7 +2847,9 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) // [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f const LLViewerObject* pObj = drawablep->getVObj(); if ( (pObj) && (pObj->isSelected()) && - ((!rlv_handler_t::isEnabled()) || (!pObj->isHUDAttachment()) || (!gRlvAttachmentLocks.isLockedAttachment(pObj->getRootEdit()))) ) + ( (!rlv_handler_t::isEnabled()) || + ( ((!pObj->isHUDAttachment()) || (!gRlvAttachmentLocks.isLockedAttachment(pObj->getRootEdit()))) && + (gRlvHandler.canEdit(pObj)) ) ) ) // [/RLVa:KB] { return; diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index c45551516..efb70cd71 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2009-2010, Kitty Barnett + * Copyright (c) 2009-2011, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY; @@ -500,6 +500,13 @@ bool RlvSelectHasLockedAttach::apply(LLSelectNode* pNode) return (pNode->getObject()) ? gRlvAttachmentLocks.isLockedAttachment(pNode->getObject()->getRootEdit()) : false; } +// Checked: 2010-11-29 (RLVa-1.3.0c) | Added: RLVa-1.3.0c +bool RlvSelectIsEditable::apply(LLSelectNode* pNode) +{ + const LLViewerObject* pObj = pNode->getObject(); + return (pObj) && (!gRlvHandler.canEdit(pObj)); +} + // Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0f bool RlvSelectIsOwnedByOrGroupOwned::apply(LLSelectNode* pNode) { diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index e5f7fc3b8..b2513a467 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2009-2010, Kitty Barnett + * Copyright (c) 2009-2011, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY; @@ -208,6 +208,13 @@ struct RlvSelectHasLockedAttach : public LLSelectedNodeFunctor virtual bool apply(LLSelectNode* pNode); }; +// Filters out selected objects that can't be editable (i.e. getFirstNode() will return NULL if the selection is fully editable) +struct RlvSelectIsEditable : public LLSelectedNodeFunctor +{ + RlvSelectIsEditable() {} + /*virtual*/ bool apply(LLSelectNode* pNode); +}; + struct RlvSelectIsOwnedByOrGroupOwned : public LLSelectedNodeFunctor { RlvSelectIsOwnedByOrGroupOwned(const LLUUID& uuid) : m_idAgent(uuid) {} @@ -268,6 +275,12 @@ protected: const LLViewerInventoryItem* m_pItem; }; +template struct RlvPredValuesEqual +{ + bool operator()(const T* pT2) const { return (pT1) && (pT2) && (*pT1 == *pT2); } + const T* pT1; +}; + // ============================================================================ // Inlined class member functions // diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 02458fbc9..74b28359e 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2009-2010, Kitty Barnett + * Copyright (c) 2009-2011, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY; @@ -76,8 +76,8 @@ const S32 RLV_VERSION_BUILD = 1; // Implementation version const S32 RLVa_VERSION_MAJOR = 1; const S32 RLVa_VERSION_MINOR = 1; -const S32 RLVa_VERSION_PATCH = 3; -const S32 RLVa_VERSION_BUILD = 2; +const S32 RLVa_VERSION_PATCH = 4; +const S32 RLVa_VERSION_BUILD = 0; // Uncomment before a final release #define RLV_RELEASE @@ -135,10 +135,16 @@ enum ERlvBehaviour { RLV_BHVR_REMATTACH, // "remattach" RLV_BHVR_ADDOUTFIT, // "addoutfit" RLV_BHVR_REMOUTFIT, // "remoutfit" + RLV_BHVR_SHAREDWEAR, // "sharedwear" + RLV_BHVR_SHAREDUNWEAR, // "sharedunwear" + RLV_BHVR_UNSHAREDWEAR, // "unsharedwear" + RLV_BHVR_UNSHAREDUNWEAR, // "unsharedunwear" RLV_BHVR_EMOTE, // "emote" RLV_BHVR_SENDCHAT, // "sendchat" RLV_BHVR_RECVCHAT, // "recvchat" + RLV_BHVR_RECVCHATFROM, // "recvchatfrom" RLV_BHVR_RECVEMOTE, // "recvemote" + RLV_BHVR_RECVEMOTEFROM, // "recvemotefrom" RLV_BHVR_REDIRCHAT, // "redirchat" RLV_BHVR_REDIREMOTE, // "rediremote" RLV_BHVR_CHATWHISPER, // "chatwhisper" @@ -146,7 +152,9 @@ enum ERlvBehaviour { RLV_BHVR_CHATSHOUT, // "chatshout" RLV_BHVR_SENDCHANNEL, // "sendchannel" RLV_BHVR_SENDIM, // "sendim" + RLV_BHVR_SENDIMTO, // "sendimto" RLV_BHVR_RECVIM, // "recvim" + RLV_BHVR_RECVIMFROM, // "recvimfrom" RLV_BHVR_PERMISSIVE, // "permissive" RLV_BHVR_NOTIFY, // "notify" RLV_BHVR_SHOWINV, // "showinv" @@ -168,13 +176,18 @@ enum ERlvBehaviour { RLV_BHVR_ACCEPTTP, // "accepttp" RLV_BHVR_ALLOWIDLE, // "allowidle" RLV_BHVR_EDIT, // "edit" + RLV_BHVR_EDITOBJ, // "editobj" RLV_BHVR_REZ, // "rez" RLV_BHVR_FARTOUCH, // "fartouch" RLV_BHVR_INTERACT, // "interact" - RLV_BHVR_TOUCH, // "touch" + RLV_BHVR_TOUCHTHIS, // "touchthis" RLV_BHVR_TOUCHATTACH, // "touchattach" + RLV_BHVR_TOUCHATTACHSELF, // "touchattachself" + RLV_BHVR_TOUCHATTACHOTHER, // "touchattachother" RLV_BHVR_TOUCHHUD, // "touchhud" RLV_BHVR_TOUCHWORLD, // "touchworld" + RLV_BHVR_TOUCHALL, // "touchall" + RLV_BHVR_TOUCHME, // "touchme" RLV_BHVR_FLY, // "fly" RLV_BHVR_UNSIT, // "unsit" RLV_BHVR_SIT, // "sit" @@ -186,13 +199,18 @@ enum ERlvBehaviour { RLV_BHVR_ATTACHOVER, // "attachover" RLV_BHVR_ATTACHTHIS, // "attachthis" RLV_BHVR_ATTACHTHISOVER, // "attachthisover" + RLV_BHVR_ATTACHTHISEXCEPT, // "attachthisexcept" RLV_BHVR_DETACHTHIS, // "detachthis" + RLV_BHVR_DETACHTHISEXCEPT, // "detachthisexcept" RLV_BHVR_ATTACHALL, // "attachall" RLV_BHVR_ATTACHALLOVER, // "attachallover" RLV_BHVR_DETACHALL, // "detachall" RLV_BHVR_ATTACHALLTHIS, // "attachallthis" + RLV_BHVR_ATTACHALLTHISEXCEPT, // "attachallthisexcept" RLV_BHVR_ATTACHALLTHISOVER, // "attachallthisover" RLV_BHVR_DETACHALLTHIS, // "detachallthis" + RLV_BHVR_DETACHALLTHISEXCEPT, // "detachallthisexcept" + RLV_BHVR_ADJUSTHEIGHT, // "adjustheight" RLV_BHVR_TPTO, // "tpto" RLV_BHVR_VERSION, // "version" RLV_BHVR_VERSIONNEW, // "versionnew" @@ -303,6 +321,8 @@ enum ERlvAttachGroupType #define RLV_SETTING_FIRSTUSE_PREFIX "FirstRLV" #define RLV_SETTING_FIRSTUSE_GIVETORLV RLV_SETTING_FIRSTUSE_PREFIX"GiveToRLV" +#define RLV_SETTING_AVATAROFFSET_Z "AscentAvatarZModifier" + // ============================================================================ // Strings // diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 0d4d623a6..e3da0a79a 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2009-2010, Kitty Barnett + * Copyright (c) 2009-2011, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY; @@ -97,10 +97,19 @@ RlvHandler::~RlvHandler() // Behaviour related functions // -bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const +bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBhvr, 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, false)) ) + if ( (idObj != itObj->second.getObjectID()) && (itObj->second.hasBehaviour(eBhvr, strOption, false)) ) + return true; + return false; +} + +// Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h +bool RlvHandler::hasBehaviourRoot(const LLUUID& idObjRoot, ERlvBehaviour eBhvr, const std::string& strOption) const +{ + for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) + if ( (idObjRoot == itObj->second.getRootID()) && (itObj->second.hasBehaviour(eBhvr, strOption, false)) ) return true; return false; } @@ -112,7 +121,7 @@ bool RlvHandler::isException(ERlvBehaviour eBhvr, const RlvExceptionOption& varO if (RLV_CHECK_DEFAULT == typeCheck) typeCheck = ( (hasBehaviour(eBhvr)) && (!isPermissive(eBhvr)) ) ? RLV_CHECK_STRICT : RLV_CHECK_PERMISSIVE; - std::list objList; + uuid_vec_t objList; if (RLV_CHECK_STRICT == typeCheck) { // If we're "strict checking" then we need the UUID of every object that currently has 'eBhvr' restricted @@ -131,7 +140,7 @@ bool RlvHandler::isException(ERlvBehaviour eBhvr, const RlvExceptionOption& varO 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); + uuid_vec_t::iterator itList = std::find(objList.begin(), objList.end(), itException->second.idObject); if (itList != objList.end()) objList.erase(itList); if (objList.empty()) @@ -226,7 +235,7 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj) } // Using a stack for executing commands solves a few problems: - // - if we passed RlvObject::m_UUID for idObj somewhere and process a @clear then idObj points to invalid/cleared memory at the end + // - if we passed RlvObject::m_idObj for idObj somewhere and process a @clear then idObj points to invalid/cleared memory at the end // - if command X triggers command Y along the way then getCurrentCommand()/getCurrentObject() still return Y even when finished m_CurCommandStack.push(&rlvCmd); m_CurObjectStack.push(rlvCmd.getObjectID()); const LLUUID& idCurObj = m_CurObjectStack.top(); @@ -393,7 +402,12 @@ void RlvHandler::onSitOrStand(bool fSitting) if ( (hasBehaviour(RLV_BHVR_STANDTP)) && (!fSitting) && (!m_posSitSource.isExactlyZero()) ) { - RlvUtil::forceTp(m_posSitSource); + // NOTE: we need to do this due to the way @standtp triggers a forced teleport: + // - when standing we're called from LLVOAvatar::sitDown() which is called from LLVOAvatar::getOffObject() + // -> at the time sitDown() is called the avatar's parent is still the linkset it was sitting on so "isRoot()" on the avatar will + // return FALSE and we will crash in LLVOAvatar::getRenderPosition() when trying to teleport + // -> postponing the teleport until the next idle tick will ensure that everything has all been properly cleaned up + doOnIdleOneTime(boost::bind(RlvUtil::forceTp, m_posSitSource)); m_posSitSource.setZero(); } } @@ -424,7 +438,7 @@ void RlvHandler::onAttach(const LLViewerObject* pAttachObj, const LLViewerJointA // We need to check this object for an active "@detach=n" and actually lock it down now that it's been attached somewhere if (itObj->second.hasBehaviour(RLV_BHVR_DETACH, false)) - gRlvAttachmentLocks.addAttachmentLock(pAttachObj->getID(), itObj->second.m_UUID); + gRlvAttachmentLocks.addAttachmentLock(pAttachObj->getID(), itObj->second.getObjectID()); } } } @@ -464,7 +478,7 @@ void RlvHandler::onDetach(const LLViewerObject* pAttachObj, const LLViewerJointA // If this object has an active "@detach=n" then we need to release the attachment lock since it's no longer attached if (itObj->second.hasBehaviour(RLV_BHVR_DETACH, false)) - gRlvAttachmentLocks.removeAttachmentLock(pAttachObj->getID(), itObj->second.m_UUID); + gRlvAttachmentLocks.removeAttachmentLock(pAttachObj->getID(), itObj->second.getObjectID()); } } } @@ -484,7 +498,7 @@ void RlvHandler::onDetach(const LLViewerObject* pAttachObj, const LLViewerJointA if (itCurObj->second.m_idRoot == pAttachObj->getID()) { RLV_INFOS << "Clearing " << itCurObj->first.asString() << ":" << RLV_ENDL; - processCommand(itCurObj->second.m_UUID, "clear", true); + processCommand(itCurObj->second.getObjectID(), "clear", true); RLV_INFOS << "\t-> done" << RLV_ENDL; } } @@ -503,7 +517,7 @@ bool RlvHandler::onGC() RLV_ASSERT(itObj); #endif // RLV_DEBUG - const LLViewerObject* pObj = gObjectList.findObject(itCurObj->second.m_UUID); + const LLViewerObject* pObj = gObjectList.findObject(itCurObj->second.getObjectID()); if (!pObj) { // If the RlvObject once existed in gObjectList and now doesn't then expire it right away @@ -532,7 +546,7 @@ bool RlvHandler::onGC() // -> if it does run it likely means that there's a @detach=n in a *child* prim that we couldn't look up in onAttach() // -> since RLV doesn't currently support @detach=n from child prims it's actually not such a big deal right now but still if ( (pObj->isAttachment()) && (itCurObj->second.hasBehaviour(RLV_BHVR_DETACH, false)) ) - gRlvAttachmentLocks.addAttachmentLock(pObj->getID(), itCurObj->second.m_UUID); + gRlvAttachmentLocks.addAttachmentLock(pObj->getID(), itCurObj->second.getObjectID()); } } } @@ -568,8 +582,6 @@ void RlvHandler::onIdleStartup(void* pParam) // Checked: 2010-03-09 (RLVa-1.2.0a) | Added: RLVa-1.2.0a void RlvHandler::onLoginComplete() { - RlvAttachPtLookup::initLookupTable(); - RlvInventory::instance().fetchWornItems(); RlvInventory::instance().fetchSharedInventory(); @@ -584,7 +596,44 @@ void RlvHandler::onLoginComplete() // String/chat censoring functions // -// LL must have included an strlen for UTF8 *somewhere* but I can't seem to find it so this one is home grown +// Checked: 2010-04-11 (RLVa-1.3.0h) | Modified: RLVa-1.3.0h +bool RlvHandler::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset /*=LLVector3::zero*/) const +{ + const LLUUID& idRoot = (pObj) ? pObj->getRootEdit()->getID() : LLUUID::null; + bool fCanTouch = (idRoot.notNull()) && ((!pObj->isHUDAttachment()) || (!hasBehaviour(RLV_BHVR_TOUCHALL))) && + ((!hasBehaviour(RLV_BHVR_TOUCHTHIS)) || (!isException(RLV_BHVR_TOUCHTHIS, idRoot, RLV_CHECK_PERMISSIVE))); + + if (fCanTouch) + { + if ( (!pObj->isAttachment()) || (!pObj->permYouOwner()) ) + { + // Rezzed prim or attachment worn by another avie + fCanTouch = + ( (!hasBehaviour(RLV_BHVR_TOUCHWORLD)) || (isException(RLV_BHVR_TOUCHWORLD, idRoot, RLV_CHECK_PERMISSIVE)) ) && + ( (!pObj->isAttachment()) || (!hasBehaviour(RLV_BHVR_TOUCHATTACHOTHER)) ) && + ( (!hasBehaviour(RLV_BHVR_FARTOUCH)) || + (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) <= 1.5f * 1.5f) ); + } + else if (!pObj->isHUDAttachment()) + { + // Regular attachment worn by this avie + fCanTouch = + ((!hasBehaviour(RLV_BHVR_TOUCHATTACH)) || (isException(RLV_BHVR_TOUCHATTACH, idRoot, RLV_CHECK_PERMISSIVE))) && + ((!hasBehaviour(RLV_BHVR_TOUCHATTACHSELF)) || (isException(RLV_BHVR_TOUCHATTACH, idRoot, RLV_CHECK_PERMISSIVE))); + } +#ifdef RLV_EXTENSION_CMD_TOUCHXXX + else + { + // HUD attachment + fCanTouch = (!hasBehaviour(RLV_BHVR_TOUCHHUD)) || (isException(RLV_BHVR_TOUCHHUD, idRoot, RLV_CHECK_PERMISSIVE)); + } +#endif // RLV_EXTENSION_CMD_TOUCHXXX + } + if ( (!fCanTouch) && (hasBehaviour(RLV_BHVR_TOUCHME)) ) + fCanTouch = hasBehaviourRoot(idRoot, RLV_BHVR_TOUCHME); + return fCanTouch; +} + size_t utf8str_strlen(const std::string& utf8) { const char* pUTF8 = utf8.c_str(); size_t length = 0; @@ -943,6 +992,18 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd) case RLV_BHVR_REMATTACH: // @addattach[: