Update RLVa to 1.4.0-compatible
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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<const LLViewerInventoryItem*>(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())
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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<const LLViewerInventoryItem*>(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))
|
||||
{
|
||||
|
||||
@@ -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<LLViewerInventoryItem*>(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
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -1969,9 +1969,10 @@ class LLObjectOpen : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> 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()) &&
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
@@ -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()))
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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<typename T> struct RlvPredValuesEqual
|
||||
{
|
||||
bool operator()(const T* pT2) const { return (pT1) && (pT2) && (*pT1 == *pT2); }
|
||||
const T* pT1;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Inlined class member functions
|
||||
//
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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<LLUUID> 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<LLUUID>::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[:<option>]=n|y
|
||||
eRet = onAddRemAttach(rlvCmd, fRefCount);
|
||||
break;
|
||||
case RLV_BHVR_ATTACHTHIS: // @attachthis[:<option>]=n|y
|
||||
case RLV_BHVR_DETACHTHIS: // @detachthis[:<option>]=n|y
|
||||
case RLV_BHVR_ATTACHALLTHIS: // @attachtallhis[:<option>]=n|y
|
||||
case RLV_BHVR_DETACHALLTHIS: // @detachallthis[:<option>]=n|y
|
||||
eRet = onAddRemFolderLock(rlvCmd, fRefCount);
|
||||
break;
|
||||
case RLV_BHVR_ATTACHTHISEXCEPT: // @attachthisexcept[:<option>]=n|y
|
||||
case RLV_BHVR_DETACHTHISEXCEPT: // @detachthisexcept[:<option>]=n|y
|
||||
case RLV_BHVR_ATTACHALLTHISEXCEPT: // @attachallthisexcept[:<option>]=n|y
|
||||
case RLV_BHVR_DETACHALLTHISEXCEPT: // @detachallthisexcept[:<option>]=n|y
|
||||
eRet = onAddRemFolderLockException(rlvCmd, fRefCount);
|
||||
break;
|
||||
case RLV_BHVR_SETENV: // @setenv=n|y
|
||||
eRet = onAddRemSetEnv(rlvCmd, fRefCount);
|
||||
break;
|
||||
@@ -969,6 +1030,44 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RLV_BHVR_SHAREDWEAR: // @sharedwear=n|y - Checked: 2011-03-28 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
case RLV_BHVR_SHAREDUNWEAR: // @sharedunwear=n|y - Checked: 2011-03-28 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
{
|
||||
VERIFY_OPTION_REF(strOption.empty());
|
||||
|
||||
RlvFolderLocks::folderlock_source_t lockSource(RlvFolderLocks::ST_SHAREDPATH, LLStringUtil::null);
|
||||
RlvFolderLocks::ELockScope eLockScope = RlvFolderLocks::SCOPE_SUBTREE;
|
||||
ERlvLockMask eLockType = (RLV_BHVR_SHAREDUNWEAR == eBhvr) ? RLV_LOCK_REMOVE : RLV_LOCK_ADD;
|
||||
|
||||
if (RLV_TYPE_ADD == eType)
|
||||
RlvFolderLocks::instance().addFolderLock(lockSource, RlvFolderLocks::PERM_DENY, eLockScope, rlvCmd.getObjectID(), eLockType);
|
||||
else
|
||||
RlvFolderLocks::instance().removeFolderLock(lockSource, RlvFolderLocks::PERM_DENY, eLockScope, rlvCmd.getObjectID(), eLockType);
|
||||
}
|
||||
break;
|
||||
case RLV_BHVR_UNSHAREDWEAR: // @unsharedwear=n|y - Checked: 2011-03-28 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
case RLV_BHVR_UNSHAREDUNWEAR: // @unsharedunwear=n|y - Checked: 2011-03-28 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
{
|
||||
VERIFY_OPTION_REF(strOption.empty());
|
||||
|
||||
// Lock down the inventory root
|
||||
RlvFolderLocks::folderlock_source_t lockSource(RlvFolderLocks::ST_ROOTFOLDER, 0);
|
||||
RlvFolderLocks::ELockScope eLockScope = RlvFolderLocks::SCOPE_SUBTREE;
|
||||
ERlvLockMask eLockType = (RLV_BHVR_UNSHAREDUNWEAR == eBhvr) ? RLV_LOCK_REMOVE : RLV_LOCK_ADD;
|
||||
|
||||
if (RLV_TYPE_ADD == eType)
|
||||
RlvFolderLocks::instance().addFolderLock(lockSource, RlvFolderLocks::PERM_DENY, eLockScope, rlvCmd.getObjectID(), eLockType);
|
||||
else
|
||||
RlvFolderLocks::instance().removeFolderLock(lockSource, RlvFolderLocks::PERM_DENY, eLockScope, rlvCmd.getObjectID(), eLockType);
|
||||
|
||||
// Add the #RLV shared folder as an exception
|
||||
lockSource = RlvFolderLocks::folderlock_source_t(RlvFolderLocks::ST_SHAREDPATH, LLStringUtil::null);
|
||||
if (RLV_TYPE_ADD == eType)
|
||||
RlvFolderLocks::instance().addFolderLock(lockSource, RlvFolderLocks::PERM_ALLOW, eLockScope, rlvCmd.getObjectID(), eLockType);
|
||||
else
|
||||
RlvFolderLocks::instance().removeFolderLock(lockSource, RlvFolderLocks::PERM_ALLOW, eLockScope, rlvCmd.getObjectID(), eLockType);
|
||||
}
|
||||
break;
|
||||
case RLV_BHVR_REDIRCHAT: // @redirchat:<channel>=n|y - Checked: 2010-03-26 (RLVa-1.2.0b) | Modified: RLVa-1.1.0h
|
||||
case RLV_BHVR_REDIREMOTE: // @rediremote:<channel>=n|y - Checked: 2010-03-26 (RLVa-1.2.0b) | Modified: RLVa-1.1.0h
|
||||
{
|
||||
@@ -1140,8 +1239,17 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
|
||||
pObj->mText->setString( (RLV_TYPE_ADD == eType) ? "" : pObj->mText->getPreFilteredText());
|
||||
}
|
||||
break;
|
||||
case RLV_BHVR_EDIT: // @edit=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
|
||||
case RLV_BHVR_EDIT: // @edit[:<uuid>=n|y - Checked: 2011-09-16 (RLVa-1.4.0b) | Modified: RLVa-1.4.0b
|
||||
{
|
||||
LLUUID idException(strOption);
|
||||
if (idException.notNull()) // If there's an option then it should specify a valid UUID
|
||||
{
|
||||
if (RLV_TYPE_ADD == eType)
|
||||
addException(rlvCmd.getObjectID(), eBhvr, idException);
|
||||
else
|
||||
removeException(rlvCmd.getObjectID(), eBhvr, idException);
|
||||
break;
|
||||
}
|
||||
VERIFY_OPTION_REF(strOption.empty());
|
||||
|
||||
if (RLV_TYPE_ADD == eType)
|
||||
@@ -1163,20 +1271,6 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
|
||||
}
|
||||
}
|
||||
break;
|
||||
#ifdef RLV_EXTENSION_CMD_TOUCHXXX
|
||||
case RLV_BHVR_TOUCH: // @touch:<uuid>=n - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
|
||||
{
|
||||
// There should be an option and it should specify a valid UUID
|
||||
LLUUID idException(strOption);
|
||||
VERIFY_OPTION_REF(idException.notNull());
|
||||
|
||||
if (RLV_TYPE_ADD == eType)
|
||||
addException(rlvCmd.getObjectID(), eBhvr, idException);
|
||||
else
|
||||
removeException(rlvCmd.getObjectID(), eBhvr, idException);
|
||||
}
|
||||
break;
|
||||
#endif // RLV_EXTENSION_CMD_TOUCHXXX
|
||||
case RLV_BHVR_FLY: // @fly=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
|
||||
{
|
||||
VERIFY_OPTION_REF(strOption.empty());
|
||||
@@ -1207,6 +1301,10 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
|
||||
#ifdef RLV_EXTENSION_CMD_INTERACT
|
||||
case RLV_BHVR_INTERACT: // @interact=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
|
||||
#endif // RLV_EXTENSION_CMD_INTERACT
|
||||
case RLV_BHVR_TOUCHATTACHSELF: // @touchattachself=n|y - Checked: 2011-01-21 (RLVa-1.3.0e) | Added: RLVa-1.3.0e
|
||||
case RLV_BHVR_TOUCHATTACHOTHER: // @touchattachother=n|y - Checked: 2011-01-21 (RLVa-1.3.0e) | Added: RLVa-1.3.0e
|
||||
case RLV_BHVR_TOUCHALL: // @touchall=n|y - Checked: 2011-01-21 (RLVa-1.3.0e) | Added: RLVa-1.3.0e
|
||||
case RLV_BHVR_TOUCHME: // @touchme=n|y - Checked: 2011-04-11 (RLVa-1.3.0h) | Added: RLVa-1.3.0h
|
||||
case RLV_BHVR_UNSIT: // @unsit=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
|
||||
case RLV_BHVR_SIT: // @sit=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
|
||||
case RLV_BHVR_SITTP: // @sittp=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
|
||||
@@ -1220,11 +1318,11 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
|
||||
case RLV_BHVR_RECVIM: // @recvim[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
|
||||
case RLV_BHVR_TPLURE: // @tplure[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
|
||||
case RLV_BHVR_ACCEPTTP: // @accepttp[:<uuid>]=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h
|
||||
#ifdef RLV_EXTENSION_CMD_TOUCHXXX
|
||||
case RLV_BHVR_TOUCHWORLD: // @touchworld[:<uuid>=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
|
||||
case RLV_BHVR_TOUCHATTACH: // @touchattach[:<uuid>=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
|
||||
#ifdef RLV_EXTENSION_CMD_TOUCHXXX
|
||||
case RLV_BHVR_TOUCHHUD: // @touchhud[:<uuid>=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
|
||||
#endif // RLV_EXTENSION_CMD_TOUCHXXX
|
||||
case RLV_BHVR_TOUCHWORLD: // @touchworld[:<uuid>=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
|
||||
{
|
||||
LLUUID idException(strOption);
|
||||
if (idException.notNull()) // If there's an option then it should specify a valid UUID
|
||||
@@ -1238,6 +1336,29 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
|
||||
VERIFY_OPTION_REF(strOption.empty());
|
||||
}
|
||||
break;
|
||||
//
|
||||
// The following block is only valid if there an option that specifies a valid UUID (reference-counted per option)
|
||||
//
|
||||
case RLV_BHVR_RECVCHATFROM: // @recvchatfrom:<uuid>=n|y - Checked: 2010-11-30 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
|
||||
case RLV_BHVR_RECVEMOTEFROM: // @recvemotefrom:<uuid>=n|y - Checked: 2010-11-30 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
|
||||
case RLV_BHVR_SENDIMTO: // @sendimto:<uuid>=n|y - Checked: 2010-11-30 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
|
||||
case RLV_BHVR_RECVIMFROM: // @recvimfrom:<uuid>=n|y - Checked: 2010-11-30 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
|
||||
case RLV_BHVR_EDITOBJ: // @editobj:<uuid>=n|y - Checked: 2010-11-29 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
|
||||
case RLV_BHVR_TOUCHTHIS: // @touchthis:<uuid>=n|y - Checked: 2010-01-01 (RLVa-1.1.0l) | Added: RLVa-1.1.0l
|
||||
{
|
||||
// There should be an option and it should specify a valid UUID
|
||||
LLUUID idException(strOption);
|
||||
VERIFY_OPTION_REF(idException.notNull());
|
||||
|
||||
if (RLV_TYPE_ADD == eType)
|
||||
addException(rlvCmd.getObjectID(), eBhvr, idException);
|
||||
else
|
||||
removeException(rlvCmd.getObjectID(), eBhvr, idException);
|
||||
}
|
||||
break;
|
||||
//
|
||||
// Unknown or invalid
|
||||
//
|
||||
case RLV_BHVR_UNKNOWN:
|
||||
// Pass unknown commands on to registered command handlers
|
||||
return (notifyCommandHandlers(&RlvCommandHandler::onAddRemCommand, rlvCmd, eRet, false)) ? eRet : RLV_RET_FAILED_UNKNOWN;
|
||||
@@ -1359,6 +1480,82 @@ ERlvCmdRet RlvHandler::onAddRemDetach(const RlvCommand& rlvCmd, bool& fRefCount)
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
|
||||
ERlvCmdRet RlvHandler::onAddRemFolderLock(const RlvCommand& rlvCmd, bool& fRefCount)
|
||||
{
|
||||
RlvCommandOptionGeneric rlvCmdOption(rlvCmd.getOption());
|
||||
|
||||
RlvFolderLocks::folderlock_source_t lockSource;
|
||||
if (rlvCmdOption.isEmpty())
|
||||
{
|
||||
lockSource = RlvFolderLocks::folderlock_source_t(RlvFolderLocks::ST_ATTACHMENT, rlvCmd.getObjectID());
|
||||
}
|
||||
else if (rlvCmdOption.isSharedFolder())
|
||||
{
|
||||
lockSource = RlvFolderLocks::folderlock_source_t(RlvFolderLocks::ST_SHAREDPATH, rlvCmd.getOption());
|
||||
}
|
||||
else if (rlvCmdOption.isAttachmentPoint())
|
||||
{
|
||||
lockSource = RlvFolderLocks::folderlock_source_t(RlvFolderLocks::ST_ATTACHMENTPOINT, RlvAttachPtLookup::getAttachPointIndex(rlvCmdOption.getAttachmentPoint()));
|
||||
}
|
||||
else if (rlvCmdOption.isWearableType())
|
||||
{
|
||||
lockSource = RlvFolderLocks::folderlock_source_t(RlvFolderLocks::ST_WEARABLETYPE, rlvCmdOption.getWearableType());
|
||||
}
|
||||
else
|
||||
{
|
||||
fRefCount = false; // Don't reference count failure
|
||||
return RLV_RET_FAILED_OPTION;
|
||||
}
|
||||
|
||||
ERlvBehaviour eBhvr = rlvCmd.getBehaviourType();
|
||||
|
||||
// Determine the lock type
|
||||
ERlvLockMask eLockType = ((RLV_BHVR_ATTACHTHIS == eBhvr) || (RLV_BHVR_ATTACHALLTHIS == eBhvr)) ? RLV_LOCK_ADD : RLV_LOCK_REMOVE;
|
||||
|
||||
// Determine the folder lock options from the issued behaviour
|
||||
RlvFolderLocks::ELockPermission eLockPermission = RlvFolderLocks::PERM_DENY;
|
||||
RlvFolderLocks::ELockScope eLockScope =
|
||||
((RLV_BHVR_ATTACHALLTHIS == eBhvr) || (RLV_BHVR_DETACHALLTHIS == eBhvr)) ? RlvFolderLocks::SCOPE_SUBTREE : RlvFolderLocks::SCOPE_NODE;
|
||||
|
||||
if (RLV_TYPE_ADD == rlvCmd.getParamType())
|
||||
RlvFolderLocks::instance().addFolderLock(lockSource, eLockPermission, eLockScope, rlvCmd.getObjectID(), eLockType);
|
||||
else
|
||||
RlvFolderLocks::instance().removeFolderLock(lockSource, eLockPermission, eLockScope, rlvCmd.getObjectID(), eLockType);
|
||||
|
||||
fRefCount = true;
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// Checked: 2011-03-27 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
ERlvCmdRet RlvHandler::onAddRemFolderLockException(const RlvCommand& rlvCmd, bool& fRefCount)
|
||||
{
|
||||
// Sanity check - the option should specify a shared folder path
|
||||
RlvCommandOptionGeneric rlvCmdOption(rlvCmd.getOption());
|
||||
if (!rlvCmdOption.isSharedFolder())
|
||||
return RLV_RET_FAILED_OPTION;
|
||||
|
||||
ERlvBehaviour eBhvr = rlvCmd.getBehaviourType();
|
||||
|
||||
// Determine the lock type
|
||||
ERlvLockMask eLockType =
|
||||
((RLV_BHVR_ATTACHTHISEXCEPT == eBhvr) || (RLV_BHVR_ATTACHALLTHISEXCEPT == eBhvr)) ? RLV_LOCK_ADD : RLV_LOCK_REMOVE;
|
||||
|
||||
// Determine the folder lock options from the issued behaviour
|
||||
RlvFolderLocks::ELockPermission eLockPermission = RlvFolderLocks::PERM_ALLOW;
|
||||
RlvFolderLocks::ELockScope eLockScope =
|
||||
((RLV_BHVR_ATTACHALLTHISEXCEPT == eBhvr) || (RLV_BHVR_DETACHALLTHISEXCEPT == eBhvr)) ? RlvFolderLocks::SCOPE_SUBTREE : RlvFolderLocks::SCOPE_NODE;
|
||||
|
||||
RlvFolderLocks::folderlock_source_t lockSource(RlvFolderLocks::ST_SHAREDPATH, rlvCmd.getOption());
|
||||
if (RLV_TYPE_ADD == rlvCmd.getParamType())
|
||||
RlvFolderLocks::instance().addFolderLock(lockSource, eLockPermission, eLockScope, rlvCmd.getObjectID(), eLockType);
|
||||
else
|
||||
RlvFolderLocks::instance().removeFolderLock(lockSource, eLockPermission, eLockScope, rlvCmd.getObjectID(), eLockType);
|
||||
|
||||
fRefCount = true;
|
||||
return RLV_RET_SUCCESS;
|
||||
}
|
||||
|
||||
// Checked: 2010-03-18 (RLVa-1.2.0e) | Modified: RLVa-1.2.0a
|
||||
ERlvCmdRet RlvHandler::onAddRemSetEnv(const RlvCommand& rlvCmd, bool& fRefCount)
|
||||
{
|
||||
@@ -1443,28 +1640,27 @@ ERlvCmdRet RlvHandler::processForceCommand(const RlvCommand& rlvCmd) const
|
||||
case RLV_BHVR_SIT: // @sit:<option>=force
|
||||
eRet = onForceSit(rlvCmd);
|
||||
break;
|
||||
case RLV_BHVR_TPTO: // @tpto:<option>=force - Checked: 2010-04-07 (RLVa-1.2.0d) | Modified: RLVa-1.0.0h
|
||||
case RLV_BHVR_ADJUSTHEIGHT: // @adjustheight:<options>=force - Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
|
||||
{
|
||||
eRet = RLV_RET_FAILED_OPTION;
|
||||
if ( (!rlvCmd.getOption().empty()) && (std::string::npos == rlvCmd.getOption().find_first_not_of("0123456789/.")) )
|
||||
RlvCommandOptionAdjustHeight rlvCmdOption(rlvCmd);
|
||||
VERIFY_OPTION(rlvCmdOption.isValid());
|
||||
|
||||
LLVOAvatar* pAvatar = gAgentAvatarp;
|
||||
if (pAvatar)
|
||||
{
|
||||
LLVector3d posGlobal;
|
||||
|
||||
boost_tokenizer tokens(rlvCmd.getOption(), boost::char_separator<char>("/", "", boost::keep_empty_tokens)); int idx = 0;
|
||||
for (boost_tokenizer::const_iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken)
|
||||
{
|
||||
if (idx < 3)
|
||||
LLStringUtil::convertToF64(*itToken, posGlobal[idx++]);
|
||||
}
|
||||
|
||||
if (idx == 3)
|
||||
{
|
||||
gAgent.teleportViaLocation(posGlobal);
|
||||
eRet = RLV_RET_SUCCESS;
|
||||
}
|
||||
F32 nValue = (rlvCmdOption.m_nPelvisToFoot - pAvatar->getPelvisToFoot()) * rlvCmdOption.m_nPelvisToFootDeltaMult;
|
||||
nValue += rlvCmdOption.m_nPelvisToFootOffset;
|
||||
gSavedSettings.setF32(RLV_SETTING_AVATAROFFSET_Z, llclamp<F32>(nValue, -1.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RLV_BHVR_TPTO: // @tpto:<option>=force - Checked: 2011-03-28 (RLVa-1.3.0f) | Modified: RLVa-1.3.0f
|
||||
{
|
||||
RlvCommandOptionTpTo rlvCmdOption(rlvCmd);
|
||||
VERIFY_OPTION( (rlvCmdOption.isValid()) && (!rlvCmdOption.m_posGlobal.isNull()) );
|
||||
gAgent.teleportViaLocation(rlvCmdOption.m_posGlobal);
|
||||
}
|
||||
break;
|
||||
case RLV_BHVR_ATTACH:
|
||||
case RLV_BHVR_ATTACHOVER:
|
||||
case RLV_BHVR_ATTACHALL:
|
||||
|
||||
@@ -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;
|
||||
@@ -46,15 +46,19 @@ public:
|
||||
// - to check exceptions -> isException()
|
||||
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(ERlvBehaviour eBehaviour, const std::string& strOption) const;
|
||||
bool hasBehaviour(ERlvBehaviour eBhvr) const { return (eBhvr < RLV_BHVR_COUNT) ? (0 != m_Behaviours[eBhvr]) : false; }
|
||||
bool hasBehaviour(ERlvBehaviour eBhvr, const std::string& strOption) const;
|
||||
// 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(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const;
|
||||
bool hasBehaviourExcept(ERlvBehaviour eBhvr, const LLUUID& idObj) const;
|
||||
bool hasBehaviourExcept(ERlvBehaviour eBhvr, const std::string& strOption, const LLUUID& idObj) const;
|
||||
// Returns TRUE if at least one object in the linkset with specified root ID contains the specified behaviour (and optional option)
|
||||
bool hasBehaviourRoot(const LLUUID& idObjRoot, ERlvBehaviour eBhvr, const std::string& strOption = LLStringUtil::null) 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 behaviour has an added exception
|
||||
bool hasException(ERlvBehaviour eBhvr) const;
|
||||
// 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")
|
||||
@@ -90,7 +94,10 @@ public:
|
||||
void setSitSource(const LLVector3d& posSource) { m_posSitSource = posSource; } // @standtp
|
||||
|
||||
// Command specific helper functions
|
||||
bool canShowHoverText(LLViewerObject* pObj) const; // @showhovertext* command family
|
||||
bool canEdit(const LLViewerObject* pObj) const; // @edit and @editobj
|
||||
bool canReceiveIM(const LLUUID& idSender) const; // @recvim and @recvimfrom
|
||||
bool canShowHoverText(const LLViewerObject* pObj) const; // @showhovertext* command family
|
||||
bool canSendIM(const LLUUID& idRecipient) const; // @sendim and @sendimto
|
||||
bool canSit(LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero) const;
|
||||
bool canStand() const;
|
||||
bool canTeleportViaLure(const LLUUID& idAgent) const;
|
||||
@@ -149,6 +156,8 @@ protected:
|
||||
ERlvCmdRet processAddRemCommand(const RlvCommand& rlvCmd);
|
||||
ERlvCmdRet onAddRemAttach(const RlvCommand& rlvCmd, bool& fRefCount);
|
||||
ERlvCmdRet onAddRemDetach(const RlvCommand& rlvCmd, bool& fRefCount);
|
||||
ERlvCmdRet onAddRemFolderLock(const RlvCommand& rlvCmd, bool& fRefCount);
|
||||
ERlvCmdRet onAddRemFolderLockException(const RlvCommand& rlvCmd, bool& fRefCount);
|
||||
ERlvCmdRet onAddRemSetEnv(const RlvCommand& rlvCmd, bool& fRefCount);
|
||||
// Command handlers (RLV_TYPE_FORCE)
|
||||
ERlvCmdRet processForceCommand(const RlvCommand& rlvCmd) const;
|
||||
@@ -221,8 +230,42 @@ inline void RlvHandler::addException(const LLUUID& idObj, ERlvBehaviour eBhvr, c
|
||||
m_Exceptions.insert(std::pair<ERlvBehaviour, RlvException>(eBhvr, RlvException(idObj, eBhvr, varOption)));
|
||||
}
|
||||
|
||||
// Checked: 2010-11-29 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
|
||||
inline bool RlvHandler::canEdit(const LLViewerObject* pObj) const
|
||||
{
|
||||
// The specified object can be edited if:
|
||||
// - not generally restricted from editing (or the object's root is an exception)
|
||||
// - not specifically restricted from editing this object's root
|
||||
return
|
||||
(pObj) &&
|
||||
((!hasBehaviour(RLV_BHVR_EDIT)) || (isException(RLV_BHVR_EDIT, pObj->getRootEdit()->getID()))) &&
|
||||
((!hasBehaviour(RLV_BHVR_EDITOBJ)) || (!isException(RLV_BHVR_EDITOBJ, pObj->getRootEdit()->getID())));
|
||||
}
|
||||
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
|
||||
inline bool RlvHandler::canReceiveIM(const LLUUID& idSender) const
|
||||
{
|
||||
// User can receive an IM from "sender" (could be an agent or a group) if:
|
||||
// - not generally restricted from receiving IMs (or the sender is an exception)
|
||||
// - not specifically restricted from receiving an IM from the sender
|
||||
return
|
||||
( (!hasBehaviour(RLV_BHVR_RECVIM)) || (isException(RLV_BHVR_RECVIM, idSender)) ) &&
|
||||
( (!hasBehaviour(RLV_BHVR_RECVIMFROM)) || (!isException(RLV_BHVR_RECVIMFROM, idSender)) );
|
||||
}
|
||||
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
|
||||
inline bool RlvHandler::canSendIM(const LLUUID& idRecipient) const
|
||||
{
|
||||
// User can send an IM to "recipient" (could be an agent or a group) if:
|
||||
// - not generally restricted from sending IMs (or the recipient is an exception)
|
||||
// - not specifically restricted from sending an IM to the recipient
|
||||
return
|
||||
( (!hasBehaviour(RLV_BHVR_SENDIM)) || (isException(RLV_BHVR_SENDIM, idRecipient)) ) &&
|
||||
( (!hasBehaviour(RLV_BHVR_SENDIMTO)) || (!isException(RLV_BHVR_SENDIMTO, idRecipient)) );
|
||||
}
|
||||
|
||||
// Checked: 2010-03-27 (RLVa-1.2.0b) | Modified: RLVa-1.0.0f
|
||||
inline bool RlvHandler::canShowHoverText(LLViewerObject *pObj) const
|
||||
inline bool RlvHandler::canShowHoverText(const LLViewerObject *pObj) const
|
||||
{
|
||||
return ( (!pObj) || (LL_PCODE_VOLUME != pObj->getPCode()) ||
|
||||
!( (hasBehaviour(RLV_BHVR_SHOWHOVERTEXTALL)) ||
|
||||
@@ -264,57 +307,20 @@ inline bool RlvHandler::canTeleportViaLure(const LLUUID& idAgent) const
|
||||
return ((!hasBehaviour(RLV_BHVR_TPLURE)) || (isException(RLV_BHVR_TPLURE, idAgent))) && (canStand());
|
||||
}
|
||||
|
||||
// Checked: 2010-04-11 (RLVa-1.2.0e) | Modified: RLVa-1.1.0l
|
||||
inline bool RlvHandler::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset /*=LLVector3::zero*/) const
|
||||
inline bool RlvHandler::hasBehaviour(ERlvBehaviour eBhvr, const std::string& strOption) const
|
||||
{
|
||||
#ifdef RLV_EXTENSION_CMD_TOUCHXXX
|
||||
bool fCanTouch = (pObj) &&
|
||||
( (!hasBehaviour(RLV_BHVR_TOUCH)) || (!isException(RLV_BHVR_TOUCH, pObj->getRootEdit()->getID(), 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, pObj->getRootEdit()->getID(), RLV_CHECK_PERMISSIVE)) ) &&
|
||||
( (!hasBehaviour(RLV_BHVR_FARTOUCH)) ||
|
||||
(dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) <= 1.5f * 1.5f) );
|
||||
}
|
||||
else if (pObj->isHUDAttachment())
|
||||
{
|
||||
// HUD attachment
|
||||
fCanTouch = (!hasBehaviour(RLV_BHVR_TOUCHHUD)) ||
|
||||
(isException(RLV_BHVR_TOUCHHUD, pObj->getRootEdit()->getID(), RLV_CHECK_PERMISSIVE));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Regular attachment worn by this avie
|
||||
fCanTouch =
|
||||
( (!hasBehaviour(RLV_BHVR_TOUCHATTACH)) ||
|
||||
(isException(RLV_BHVR_TOUCHATTACH, pObj->getRootEdit()->getID(), RLV_CHECK_PERMISSIVE)) );
|
||||
}
|
||||
}
|
||||
return fCanTouch;
|
||||
#else
|
||||
return (pObj) &&
|
||||
(
|
||||
((pObj->isAttachment()) && (pObj->permYouOwner())) ||
|
||||
( (!hasBehaviour(RLV_BHVR_FARTOUCH)) ||
|
||||
(dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) <= 1.5f * 1.5f) )
|
||||
);
|
||||
#endif // RLV_EXTENSION_CMD_TOUCHXXX
|
||||
return hasBehaviourExcept(eBhvr, strOption, LLUUID::null);
|
||||
}
|
||||
|
||||
inline bool RlvHandler::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption) const
|
||||
inline bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBhvr, const LLUUID& idObj) const
|
||||
{
|
||||
return hasBehaviourExcept(eBehaviour, strOption, LLUUID::null);
|
||||
return hasBehaviourExcept(eBhvr, LLStringUtil::null, idObj);
|
||||
}
|
||||
|
||||
inline bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const
|
||||
// Checked: 2010-11-29 (RLVa-1.3.0c) | Added: RLVa-1.3.0c
|
||||
inline bool RlvHandler::hasException(ERlvBehaviour eBhvr) const
|
||||
{
|
||||
return hasBehaviourExcept(eBehaviour, std::string(), idObj);
|
||||
return (m_Exceptions.find(eBhvr) != m_Exceptions.end());
|
||||
}
|
||||
|
||||
inline bool RlvHandler::isPermissive(ERlvBehaviour eBhvr) const
|
||||
|
||||
@@ -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;
|
||||
@@ -35,6 +35,8 @@
|
||||
#include "rlvinventory.h"
|
||||
#include "rlvhandler.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
// Defined in llinventorybridge.cpp
|
||||
void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void*);
|
||||
|
||||
@@ -74,6 +76,9 @@ RlvCommand::RlvCommand(const LLUUID& idObj, const std::string& strCommand)
|
||||
return;
|
||||
}
|
||||
|
||||
// HACK: all those @*overorreplace synonyms are rather tedious (and error-prone) to deal with so replace them their equivalent
|
||||
if ( (RLV_TYPE_FORCE == m_eParamType) && (m_strBehaviour.length() - 13 == m_strBehaviour.rfind("overorreplace")) )
|
||||
m_strBehaviour.erase(m_strBehaviour.length() - 13, 13);
|
||||
// HACK: all those @addoutfit* synonyms are rather tedious (and error-prone) to deal with so replace them their @attach* equivalent
|
||||
if ( (RLV_TYPE_FORCE == m_eParamType) && (0 == m_strBehaviour.find("addoutfit")) )
|
||||
m_strBehaviour.replace(0, 9, "attach");
|
||||
@@ -157,16 +162,19 @@ void RlvCommand::initLookupTable()
|
||||
// NOTE: keep this matched with the enumeration at all times
|
||||
std::string arBehaviours[RLV_BHVR_COUNT] =
|
||||
{
|
||||
"detach", "attach", "addattach", "remattach", "addoutfit", "remoutfit", "emote", "sendchat", "recvchat", "recvemote",
|
||||
"redirchat", "rediremote", "chatwhisper", "chatnormal", "chatshout", "sendchannel", "sendim", "recvim", "permissive",
|
||||
"detach", "attach", "addattach", "remattach", "addoutfit", "remoutfit", "sharedwear", "sharedunwear", "unsharedwear",
|
||||
"unsharedunwear", "emote", "sendchat", "recvchat", "recvchatfrom", "recvemote", "recvemotefrom", "redirchat", "rediremote",
|
||||
"chatwhisper", "chatnormal", "chatshout", "sendchannel", "sendim", "sendimto", "recvim", "recvimfrom", "permissive",
|
||||
"notify", "showinv", "showminimap", "showworldmap", "showloc", "shownames", "showhovertext", "showhovertexthud",
|
||||
"showhovertextworld", "showhovertextall", "tplm", "tploc", "tplure", "viewnote", "viewscript", "viewtexture",
|
||||
"acceptpermission", "accepttp", "allowidle", "edit", "rez", "fartouch", "interact", "touch", "touchattach", "touchhud",
|
||||
"touchworld", "fly", "unsit", "sit", "sittp", "standtp", "setdebug", "setenv", "detachme", "attachover", "attachthis",
|
||||
"attachthisover", "detachthis", "attachall", "attachallover", "detachall", "attachallthis", "attachallthisover",
|
||||
"detachallthis", "tpto", "version", "versionnew", "versionnum", "getattach", "getattachnames", "getaddattachnames",
|
||||
"getremattachnames", "getoutfit", "getoutfitnames", "getaddoutfitnames", "getremoutfitnames", "findfolder", "findfolders",
|
||||
"getpath", "getpathnew", "getinv", "getinvworn", "getsitid", "getcommand", "getstatus", "getstatusall"
|
||||
"showhovertextworld", "showhovertextall", "tplm", "tploc", "tplure", "viewnote", "viewscript", "viewtexture",
|
||||
"acceptpermission", "accepttp", "allowidle", "edit", "editobj", "rez", "fartouch", "interact",
|
||||
"touchthis", "touchattach", "touchattachself", "touchattachother", "touchhud", "touchworld", "touchall", "touchme",
|
||||
"fly", "unsit", "sit", "sittp", "standtp", "setdebug", "setenv", "detachme", "attachover", "attachthis", "attachthisover",
|
||||
"attachthisexcept", "detachthis", "detachthisexcept", "attachall", "attachallover", "detachall", "attachallthis",
|
||||
"attachallthisexcept", "attachallthisover", "detachallthis", "detachallthisexcept", "adjustheight", "tpto",
|
||||
"version", "versionnew", "versionnum", "getattach", "getattachnames", "getaddattachnames", "getremattachnames",
|
||||
"getoutfit", "getoutfitnames", "getaddoutfitnames", "getremoutfitnames", "findfolder", "findfolders", "getpath",
|
||||
"getpathnew", "getinv", "getinvworn", "getsitid", "getcommand", "getstatus", "getstatusall"
|
||||
};
|
||||
|
||||
for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++)
|
||||
@@ -177,7 +185,7 @@ void RlvCommand::initLookupTable()
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// RlvCommandOption
|
||||
// RlvCommandOption structures
|
||||
//
|
||||
|
||||
// Checked: 2010-09-28 (RLVa-1.1.3a) | Added: RLVa-1.2.1c
|
||||
@@ -203,26 +211,21 @@ RlvCommandOptionGeneric::RlvCommandOptionGeneric(const std::string& strOption)
|
||||
}
|
||||
}
|
||||
|
||||
// Checked: 2010-09-28 (RLVa-1.1.3a) | Added: RLVa-1.2.1c
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.3.0b
|
||||
RlvCommandOptionGetPath::RlvCommandOptionGetPath(const RlvCommand& rlvCmd)
|
||||
: m_fValid(true) // Assume the option will be a valid one until we find out otherwise
|
||||
{
|
||||
m_fValid = true; // Assume the option will be a valid one until we find out otherwise
|
||||
|
||||
// @getpath[:<option>]=<channel> => <option> is transformed to a list of inventory item UUIDs to get the path of
|
||||
|
||||
RlvCommandOptionGeneric rlvCmdOption(rlvCmd.getOption());
|
||||
if (rlvCmdOption.isWearableType()) // <option> can be a clothing layer
|
||||
{
|
||||
LLWearableType::EType wtType = rlvCmdOption.getWearableType();
|
||||
m_idItems.push_back(gAgentWearables.getWearableItemID(wtType, 0)); // TODO: MULTI-WEARABLE
|
||||
getItemIDs(rlvCmdOption.getWearableType(), m_idItems, false);
|
||||
}
|
||||
else if (rlvCmdOption.isAttachmentPoint()) // ... or it can specify an attachment point
|
||||
{
|
||||
const LLViewerJointAttachment* pAttachPt = rlvCmdOption.getAttachmentPoint();
|
||||
for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachObj = pAttachPt->mAttachedObjects.begin();
|
||||
itAttachObj != pAttachPt->mAttachedObjects.end(); ++itAttachObj)
|
||||
{
|
||||
m_idItems.push_back((*itAttachObj)->getAttachmentItemID());
|
||||
}
|
||||
getItemIDs(rlvCmdOption.getAttachmentPoint(), m_idItems, false);
|
||||
}
|
||||
else if (rlvCmdOption.isEmpty()) // ... or it can be empty (in which case we act on the object that issued the command)
|
||||
{
|
||||
@@ -236,12 +239,70 @@ RlvCommandOptionGetPath::RlvCommandOptionGetPath(const RlvCommand& rlvCmd)
|
||||
}
|
||||
}
|
||||
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.3.0b
|
||||
bool RlvCommandOptionGetPath::getItemIDs(const LLViewerJointAttachment* pAttachPt, uuid_vec_t& idItems, bool fClear)
|
||||
{
|
||||
if (fClear)
|
||||
idItems.clear();
|
||||
uuid_vec_t::size_type cntItemsPrev = idItems.size();
|
||||
if (pAttachPt)
|
||||
{
|
||||
for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachObj = pAttachPt->mAttachedObjects.begin();
|
||||
itAttachObj != pAttachPt->mAttachedObjects.end(); ++itAttachObj)
|
||||
{
|
||||
idItems.push_back((*itAttachObj)->getAttachmentItemID());
|
||||
}
|
||||
}
|
||||
return (cntItemsPrev != idItems.size());
|
||||
}
|
||||
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.3.0b
|
||||
bool RlvCommandOptionGetPath::getItemIDs(LLWearableType::EType wtType, uuid_vec_t& idItems, bool fClear)
|
||||
{
|
||||
if (fClear)
|
||||
idItems.clear();
|
||||
uuid_vec_t::size_type cntItemsPrev = idItems.size();
|
||||
if (gAgentWearables.getWearable(wtType, 0))
|
||||
idItems.push_back(gAgentWearables.getWearableItemID(wtType,0));
|
||||
return (cntItemsPrev != idItems.size());
|
||||
}
|
||||
|
||||
// Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
|
||||
RlvCommandOptionAdjustHeight::RlvCommandOptionAdjustHeight(const RlvCommand& rlvCmd)
|
||||
: m_nPelvisToFoot(0.0f), m_nPelvisToFootDeltaMult(0.0f), m_nPelvisToFootOffset(0.0f)
|
||||
{
|
||||
std::vector<std::string> cmdTokens;
|
||||
boost::split(cmdTokens, rlvCmd.getOption(), boost::is_any_of(";"));
|
||||
if (1 == cmdTokens.size())
|
||||
{
|
||||
m_fValid = (LLStringUtil::convertToF32(cmdTokens[0], m_nPelvisToFootOffset));
|
||||
m_nPelvisToFootOffset = llclamp<F32>(m_nPelvisToFootOffset / 100, -1.0f, 1.0f);
|
||||
}
|
||||
else if ( (2 <= cmdTokens.size()) && (cmdTokens.size() <= 3) )
|
||||
{
|
||||
m_fValid = (LLStringUtil::convertToF32(cmdTokens[0], m_nPelvisToFoot)) &&
|
||||
(LLStringUtil::convertToF32(cmdTokens[1], m_nPelvisToFootDeltaMult)) &&
|
||||
( (2 == cmdTokens.size()) || (LLStringUtil::convertToF32(cmdTokens[2], m_nPelvisToFootOffset)) );
|
||||
}
|
||||
}
|
||||
|
||||
// Checked: 2011-03-28 (RLVa-1.3.0f) | Added: RLVa-1.3.0f
|
||||
RlvCommandOptionTpTo::RlvCommandOptionTpTo(const RlvCommand &rlvCmd)
|
||||
{
|
||||
std::vector<std::string> cmdTokens;
|
||||
boost::split(cmdTokens, rlvCmd.getOption(), boost::is_any_of("/"));
|
||||
|
||||
m_fValid = (3 == cmdTokens.size());
|
||||
for (int idxAxis = 0; (idxAxis < 3) && (m_fValid); idxAxis++)
|
||||
m_fValid &= (bool)LLStringUtil::convertToF64(cmdTokens[idxAxis], m_posGlobal[idxAxis]);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// RlvObject
|
||||
//
|
||||
|
||||
RlvObject::RlvObject(const LLUUID& idObj) : m_UUID(idObj), m_nLookupMisses(0)
|
||||
{
|
||||
RlvObject::RlvObject(const LLUUID& idObj) : m_idObj(idObj), m_nLookupMisses(0)
|
||||
{
|
||||
LLViewerObject* pObj = gObjectList.findObject(idObj);
|
||||
m_fLookup = (NULL != pObj);
|
||||
m_idxAttachPt = (pObj) ? ATTACHMENT_ID_FROM_STATE(pObj->getState()) : 0;
|
||||
|
||||
@@ -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;
|
||||
@@ -99,84 +99,81 @@ typedef std::list<RlvCommand> rlv_command_list_t;
|
||||
// RlvCommandOption (and derived classed)
|
||||
//
|
||||
|
||||
class RlvCommandOption
|
||||
struct RlvCommandOption
|
||||
{
|
||||
protected:
|
||||
RlvCommandOption() {}
|
||||
RlvCommandOption() : m_fValid(false) {}
|
||||
public:
|
||||
virtual ~RlvCommandOption() {}
|
||||
|
||||
public:
|
||||
virtual bool isAttachmentPoint() const { return false; }
|
||||
virtual bool isAttachmentPointGroup() const { return false; }
|
||||
virtual bool isEmpty() const = 0;
|
||||
virtual bool isSharedFolder() const { return false; }
|
||||
virtual bool isString() const { return false; }
|
||||
virtual bool isUUID() const { return false; }
|
||||
virtual bool isValid() const = 0;
|
||||
virtual bool isWearableType() const { return false; }
|
||||
|
||||
virtual LLViewerJointAttachment* getAttachmentPoint() const { return NULL; }
|
||||
virtual ERlvAttachGroupType getAttachmentPointGroup() const { return RLV_ATTACHGROUP_INVALID; }
|
||||
virtual LLViewerInventoryCategory* getSharedFolder() const { return NULL; }
|
||||
virtual const std::string& getString() const { return LLStringUtil::null; }
|
||||
virtual const LLUUID& getUUID() const { return LLUUID::null; }
|
||||
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_INVALID; }
|
||||
virtual bool isEmpty() const { return false; }
|
||||
virtual bool isValid() const { return m_fValid; }
|
||||
protected:
|
||||
bool m_fValid;
|
||||
};
|
||||
|
||||
class RlvCommandOptionGeneric : public RlvCommandOption
|
||||
|
||||
struct RlvCommandOptionGeneric : public RlvCommandOption
|
||||
{
|
||||
public:
|
||||
explicit RlvCommandOptionGeneric(const std::string& strOption);
|
||||
RlvCommandOptionGeneric(LLViewerJointAttachment* pAttachPt) : m_fEmpty(false) { m_varOption = pAttachPt; }
|
||||
RlvCommandOptionGeneric(LLViewerInventoryCategory* pFolder) : m_fEmpty(false) { m_varOption = pFolder; }
|
||||
RlvCommandOptionGeneric(const LLUUID& idOption) : m_fEmpty(false) { m_varOption = idOption; }
|
||||
RlvCommandOptionGeneric(LLWearableType::EType wtType) : m_fEmpty(false) { m_varOption = wtType; }
|
||||
/*virtual*/ ~RlvCommandOptionGeneric() {}
|
||||
|
||||
public:
|
||||
/*virtual*/ bool isAttachmentPoint() const { return (!isEmpty()) && (typeid(LLViewerJointAttachment*) == m_varOption.type()); }
|
||||
/*virtual*/ bool isAttachmentPointGroup() const { return (!isEmpty()) && (typeid(ERlvAttachGroupType) == m_varOption.type()); }
|
||||
/*virtual*/ bool isEmpty() const { return m_fEmpty; }
|
||||
/*virtual*/ bool isSharedFolder() const { return (!isEmpty()) && (typeid(LLViewerInventoryCategory*) == m_varOption.type()); }
|
||||
/*virtual*/ bool isString() const { return (!isEmpty()) && (typeid(std::string) == m_varOption.type()); }
|
||||
/*virtual*/ bool isUUID() const { return (!isEmpty()) && (typeid(LLUUID) == m_varOption.type()); }
|
||||
/*virtual*/ bool isValid() const { return true; } // This doesn't really have any significance for the generic class
|
||||
/*virtual*/ bool isWearableType() const { return (!isEmpty()) && (typeid(LLWearableType::EType) == m_varOption.type()); }
|
||||
bool isAttachmentPoint() const { return (!isEmpty()) && (typeid(LLViewerJointAttachment*) == m_varOption.type()); }
|
||||
bool isAttachmentPointGroup() const { return (!isEmpty()) && (typeid(ERlvAttachGroupType) == m_varOption.type()); }
|
||||
bool isEmpty() const { return m_fEmpty; }
|
||||
bool isSharedFolder() const { return (!isEmpty()) && (typeid(LLViewerInventoryCategory*) == m_varOption.type()); }
|
||||
bool isString() const { return (!isEmpty()) && (typeid(std::string) == m_varOption.type()); }
|
||||
bool isUUID() const { return (!isEmpty()) && (typeid(LLUUID) == m_varOption.type()); }
|
||||
bool isWearableType() const { return (!isEmpty()) && (typeid(LLWearableType::EType) == m_varOption.type()); }
|
||||
|
||||
/*virtual*/ LLViewerJointAttachment* getAttachmentPoint() const
|
||||
{ return (isAttachmentPoint()) ? boost::get<LLViewerJointAttachment*>(m_varOption) : RlvCommandOption::getAttachmentPoint(); }
|
||||
/*virtual*/ ERlvAttachGroupType getAttachmentPointGroup() const
|
||||
{ return (isAttachmentPointGroup()) ? boost::get<ERlvAttachGroupType>(m_varOption) : RlvCommandOption::getAttachmentPointGroup(); }
|
||||
/*virtual*/ LLViewerInventoryCategory* getSharedFolder() const
|
||||
{ return (isSharedFolder()) ? boost::get<LLViewerInventoryCategory*>(m_varOption) : RlvCommandOption::getSharedFolder(); }
|
||||
/*virtual*/ const std::string& getString() const
|
||||
{ return (isString()) ? boost::get<std::string>(m_varOption) : RlvCommandOption::getString(); }
|
||||
/*virtual*/ const LLUUID& getUUID() const
|
||||
{ return (isUUID()) ? boost::get<LLUUID>(m_varOption) : RlvCommandOption::getUUID(); }
|
||||
/*virtual*/ LLWearableType::EType getWearableType() const
|
||||
{ return (isWearableType()) ? boost::get<LLWearableType::EType>(m_varOption) : RlvCommandOption::getWearableType(); }
|
||||
LLViewerJointAttachment* getAttachmentPoint() const
|
||||
{ return (isAttachmentPoint()) ? boost::get<LLViewerJointAttachment*>(m_varOption) : NULL; }
|
||||
ERlvAttachGroupType getAttachmentPointGroup() const
|
||||
{ return (isAttachmentPointGroup()) ? boost::get<ERlvAttachGroupType>(m_varOption) : RLV_ATTACHGROUP_INVALID; }
|
||||
LLViewerInventoryCategory* getSharedFolder() const
|
||||
{ return (isSharedFolder()) ? boost::get<LLViewerInventoryCategory*>(m_varOption) : NULL; }
|
||||
const std::string& getString() const
|
||||
{ return (isString()) ? boost::get<std::string>(m_varOption) : LLStringUtil::null; }
|
||||
const LLUUID& getUUID() const
|
||||
{ return (isUUID()) ? boost::get<LLUUID>(m_varOption) : LLUUID::null; }
|
||||
LLWearableType::EType getWearableType() const
|
||||
{ return (isWearableType()) ? boost::get<LLWearableType::EType>(m_varOption) : LLWearableType::WT_INVALID; }
|
||||
|
||||
protected:
|
||||
bool m_fEmpty;
|
||||
boost::variant<LLViewerJointAttachment*, ERlvAttachGroupType, LLViewerInventoryCategory*, std::string, LLUUID, LLWearableType::EType> m_varOption;
|
||||
};
|
||||
|
||||
class RlvCommandOptionGetPath : public RlvCommandOption
|
||||
struct RlvCommandOptionGetPath : public RlvCommandOption
|
||||
{
|
||||
public:
|
||||
RlvCommandOptionGetPath(const RlvCommand& rlvCmd);
|
||||
/*virtual*/ ~RlvCommandOptionGetPath() {}
|
||||
|
||||
/*virtual*/ bool isEmpty() const { return m_idItems.empty(); }
|
||||
/*virtual*/ bool isValid() const { return m_fValid; }
|
||||
const uuid_vec_t& getItemIDs() const { return m_idItems; }
|
||||
|
||||
static bool getItemIDs(const LLViewerJointAttachment* pAttachPt, uuid_vec_t& idItems, bool fClear = true);
|
||||
static bool getItemIDs(LLWearableType::EType wtType, uuid_vec_t& idItems, bool fClear = true);
|
||||
|
||||
protected:
|
||||
bool m_fValid;
|
||||
uuid_vec_t m_idItems;
|
||||
};
|
||||
|
||||
struct RlvCommandOptionAdjustHeight : public RlvCommandOption
|
||||
{
|
||||
RlvCommandOptionAdjustHeight(const RlvCommand& rlvCmd);
|
||||
|
||||
F32 m_nPelvisToFoot;
|
||||
F32 m_nPelvisToFootDeltaMult;
|
||||
F32 m_nPelvisToFootOffset;
|
||||
};
|
||||
|
||||
struct RlvCommandOptionTpTo : public RlvCommandOption
|
||||
{
|
||||
RlvCommandOptionTpTo(const RlvCommand& rlvCmd);
|
||||
|
||||
LLVector3d m_posGlobal;
|
||||
};
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// RlvObject
|
||||
//
|
||||
@@ -199,13 +196,16 @@ public:
|
||||
|
||||
const rlv_command_list_t* getCommandList() const { return &m_Commands; }
|
||||
|
||||
const LLUUID& getObjectID() const { return m_idObj; }
|
||||
const LLUUID& getRootID() const { return m_idRoot; }
|
||||
|
||||
/*
|
||||
* Member variables
|
||||
*/
|
||||
protected:
|
||||
LLUUID m_UUID; // The object's UUID
|
||||
S32 m_idxAttachPt; // The object's attachment point (or 0 if it's not an attachment)
|
||||
LLUUID m_idRoot; // The UUID of the object's root (may or may not be different from m_UUID)
|
||||
LLUUID m_idObj; // The object's UUID
|
||||
LLUUID m_idRoot; // The UUID of the object's root (may or may not be different from m_idObj)
|
||||
bool m_fLookup; // TRUE if the object existed in gObjectList at one point in time
|
||||
S16 m_nLookupMisses; // Count of unsuccessful lookups in gObjectList by the GC
|
||||
rlv_command_list_t m_Commands; // List of behaviours held by this object (in the order they were received)
|
||||
@@ -396,6 +396,27 @@ public:
|
||||
virtual BOOL tick();
|
||||
};
|
||||
|
||||
class RlvCallbackTimerOnce : public LLEventTimer
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void ()> nullary_func_t;
|
||||
public:
|
||||
RlvCallbackTimerOnce(F32 nPeriod, nullary_func_t cb) : LLEventTimer(nPeriod), m_Callback(cb) {}
|
||||
/*virtual*/ BOOL tick()
|
||||
{
|
||||
m_Callback();
|
||||
return TRUE;
|
||||
}
|
||||
protected:
|
||||
nullary_func_t m_Callback;
|
||||
};
|
||||
|
||||
inline void rlvCallbackTimerOnce(F32 nPeriod, RlvCallbackTimerOnce::nullary_func_t cb)
|
||||
{
|
||||
// Timer will automatically delete itself after the callback
|
||||
new RlvCallbackTimerOnce(nPeriod, cb);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Various helper functions
|
||||
//
|
||||
|
||||
@@ -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;
|
||||
@@ -62,7 +62,36 @@ public:
|
||||
// RlvInventory member functions
|
||||
//
|
||||
|
||||
// Checked: 2010-02-28 (RLVa-1.1.3a) | Modified: RLVa-1.0.0h
|
||||
// Checked: 2011-03-28 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
|
||||
RlvInventory::RlvInventory()
|
||||
: m_fFetchStarted(false), m_fFetchComplete(false)
|
||||
{
|
||||
}
|
||||
|
||||
// Checked: 2011-03-28 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
RlvInventory::~RlvInventory()
|
||||
{
|
||||
if (gInventory.containsObserver(this))
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
|
||||
// Checked: 2011-03-28 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
void RlvInventory::changed(U32 mask)
|
||||
{
|
||||
const std::set<LLUUID>& idsChanged = gInventory.getChangedIDs();
|
||||
if (std::find(idsChanged.begin(), idsChanged.end(), m_idRlvRoot) != idsChanged.end())
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
|
||||
LLUUID idRlvRootPrev = m_idRlvRoot;
|
||||
m_idRlvRoot.setNull();
|
||||
|
||||
if (idRlvRootPrev != getSharedRootID())
|
||||
m_OnSharedRootIDChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// Checked: 2010-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.0.0h
|
||||
void RlvInventory::fetchSharedInventory()
|
||||
{
|
||||
// Sanity check - don't fetch if we're already fetching, or if we don't have a shared root
|
||||
@@ -222,25 +251,29 @@ bool RlvInventory::getPath(const uuid_vec_t& idItems, LLInventoryModel::cat_arra
|
||||
return (folders.count() != 0);
|
||||
}
|
||||
|
||||
// Checked: 2010-02-28 (RLVa-1.1.3a) | Modified: RLVa-1.0.0h
|
||||
LLViewerInventoryCategory* RlvInventory::getSharedRoot() const
|
||||
// Checked: 2011-03-28 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
|
||||
const LLUUID& RlvInventory::getSharedRootID() const
|
||||
{
|
||||
if (gInventory.isInventoryUsable())
|
||||
if ( (m_idRlvRoot.isNull()) && (gInventory.isInventoryUsable()) )
|
||||
{
|
||||
LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems;
|
||||
gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), pFolders, pItems);
|
||||
if (pFolders)
|
||||
{
|
||||
// NOTE: we might have multiple #RLV folders so we'll just go with the first one we come across
|
||||
LLViewerInventoryCategory* pFolder;
|
||||
const LLViewerInventoryCategory* pFolder;
|
||||
for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++)
|
||||
{
|
||||
if ( ((pFolder = pFolders->get(idxFolder)) != NULL) && (RlvInventory::cstrSharedRoot == pFolder->getName()) )
|
||||
return pFolder;
|
||||
if ( ((pFolder = pFolders->get(idxFolder)) != NULL) && (cstrSharedRoot == pFolder->getName()) )
|
||||
{
|
||||
if (!gInventory.containsObserver((RlvInventory*)this))
|
||||
gInventory.addObserver((RlvInventory*)this);
|
||||
m_idRlvRoot = pFolder->getUUID();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return m_idRlvRoot;
|
||||
}
|
||||
|
||||
// Checked: 2010-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.0.1a
|
||||
|
||||
@@ -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;
|
||||
@@ -28,30 +28,37 @@
|
||||
// RlvInventory class declaration
|
||||
//
|
||||
|
||||
// TODO-RLVa: [RLVa-1.2.0] Make all of this static rather than a singleton?
|
||||
class RlvInventory : public LLSingleton<RlvInventory>
|
||||
class RlvInventory : public LLSingleton<RlvInventory>, public LLInventoryObserver
|
||||
{
|
||||
protected:
|
||||
RlvInventory() : m_fFetchStarted(false), m_fFetchComplete(false) {}
|
||||
RlvInventory();
|
||||
public:
|
||||
~RlvInventory();
|
||||
|
||||
// LLInventoryObserver override
|
||||
/*virtual*/ void changed(U32 mask);
|
||||
|
||||
/*
|
||||
* #RLV Shared inventory
|
||||
*/
|
||||
public:
|
||||
typedef boost::signals2::signal<void (void)> callback_signal_t;
|
||||
void addSharedRootIDChangedCallback(const callback_signal_t::slot_type& cb) { m_OnSharedRootIDChanged.connect(cb); }
|
||||
// Find all folders that match a supplied criteria (clears the output array)
|
||||
bool findSharedFolders(const std::string& strCriteria, LLInventoryModel::cat_array_t& folders) const;
|
||||
bool findSharedFolders(const std::string& strCriteria, LLInventoryModel::cat_array_t& folders) const;
|
||||
// Gets the shared path for any shared items present in idItems (clears the output array)
|
||||
bool getPath(const uuid_vec_t& idItems, LLInventoryModel::cat_array_t& folders) const;
|
||||
bool getPath(const uuid_vec_t& idItems, LLInventoryModel::cat_array_t& folders) const;
|
||||
// Returns a pointer to the shared root folder (if there is one)
|
||||
LLViewerInventoryCategory* getSharedRoot() const;
|
||||
LLViewerInventoryCategory* getSharedRoot() const;
|
||||
const LLUUID& getSharedRootID() const;
|
||||
// Returns a subfolder of idParent that starts with strFolderName (exact match > partial match)
|
||||
LLViewerInventoryCategory* getSharedFolder(const LLUUID& idParent, const std::string& strFolderName) const;
|
||||
LLViewerInventoryCategory* getSharedFolder(const LLUUID& idParent, const std::string& strFolderName) const;
|
||||
// Looks up a folder from a path (relative to the shared root)
|
||||
LLViewerInventoryCategory* getSharedFolder(const std::string& strPath) const;
|
||||
LLViewerInventoryCategory* getSharedFolder(const std::string& strPath) const;
|
||||
// Returns the path of the supplied folder (relative to the shared root)
|
||||
std::string getSharedPath(const LLViewerInventoryCategory* pFolder) const;
|
||||
std::string getSharedPath(const LLViewerInventoryCategory* pFolder) const;
|
||||
// Returns TRUE if the supplied folder is a descendent of the #RLV folder
|
||||
bool isSharedFolder(const LLUUID& idFolder);
|
||||
bool isSharedFolder(const LLUUID& idFolder);
|
||||
|
||||
/*
|
||||
* Inventory fetching
|
||||
@@ -76,8 +83,10 @@ public:
|
||||
* Member variables
|
||||
*/
|
||||
protected:
|
||||
bool m_fFetchStarted; // TRUE if we fired off an inventory fetch
|
||||
bool m_fFetchComplete; // TRUE if everything was fetched
|
||||
bool m_fFetchStarted; // TRUE if we fired off an inventory fetch
|
||||
bool m_fFetchComplete; // TRUE if everything was fetched
|
||||
mutable LLUUID m_idRlvRoot;
|
||||
callback_signal_t m_OnSharedRootIDChanged;
|
||||
|
||||
private:
|
||||
static const std::string cstrSharedRoot;
|
||||
@@ -236,6 +245,13 @@ public:
|
||||
// RlvInventory inlined member functions
|
||||
//
|
||||
|
||||
// Checked: 2011-03-28 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
|
||||
inline LLViewerInventoryCategory* RlvInventory::getSharedRoot() const
|
||||
{
|
||||
const LLUUID& idRlvRoot = getSharedRootID();
|
||||
return (idRlvRoot.notNull()) ? gInventory.getCategory(idRlvRoot) : NULL;
|
||||
}
|
||||
|
||||
// Checked: 2010-03-19 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
|
||||
inline bool RlvInventory::isFoldedFolder(const LLInventoryCategory* pFolder, bool fCheckComposite)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
@@ -18,9 +18,11 @@
|
||||
#include "llattachmentsmgr.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "pipeline.h"
|
||||
#include "cofmgr.h"
|
||||
#include "llagentwearables.h"
|
||||
|
||||
#include "rlvhelper.h"
|
||||
#include "rlvinventory.h"
|
||||
#include "rlvlocks.h"
|
||||
|
||||
// ============================================================================
|
||||
@@ -36,7 +38,8 @@ void RlvAttachPtLookup::initLookupTable()
|
||||
if (!fInitialized)
|
||||
{
|
||||
LLVOAvatar* pAvatar = gAgentAvatarp;
|
||||
if (pAvatar)
|
||||
RLV_ASSERT( (pAvatar) && (pAvatar->mAttachmentPoints.size() > 0) );
|
||||
if ( (pAvatar) && (pAvatar->mAttachmentPoints.size() > 0) )
|
||||
{
|
||||
std::string strAttachPtName;
|
||||
for (LLVOAvatar::attachment_map_t::const_iterator itAttach = pAvatar->mAttachmentPoints.begin();
|
||||
@@ -997,3 +1000,327 @@ void RlvWearableLocks::removeWearableTypeLock(LLWearableType::EType eType, const
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// RlvFolderLocks member functions
|
||||
//
|
||||
|
||||
class RlvLockedDescendentsCollector : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
RlvLockedDescendentsCollector(int eSourceTypeMask, RlvFolderLocks::ELockPermission ePermMask, ERlvLockMask eLockTypeMask)
|
||||
: m_eSourceTypeMask(eSourceTypeMask), m_ePermMask(ePermMask), m_eLockTypeMask(eLockTypeMask) {}
|
||||
/*virtual*/ ~RlvLockedDescendentsCollector() {}
|
||||
/*virtual*/ bool operator()(LLInventoryCategory* pFolder, LLInventoryItem* pItem)
|
||||
{
|
||||
return (pFolder) && (RlvFolderLocks::instance().isLockedFolderEntry(pFolder->getUUID(), m_eSourceTypeMask, m_ePermMask, m_eLockTypeMask));
|
||||
}
|
||||
protected:
|
||||
RlvFolderLocks::ELockPermission m_ePermMask;
|
||||
int m_eSourceTypeMask;
|
||||
ERlvLockMask m_eLockTypeMask;
|
||||
};
|
||||
|
||||
// Checked: 2011-03-28 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
|
||||
RlvFolderLocks::RlvFolderLocks()
|
||||
: m_fLookupDirty(false), m_fLockedRoot(false)
|
||||
{
|
||||
LLCOFObserver::instance().addCOFChangedCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this));
|
||||
RlvInventory::instance().addSharedRootIDChangedCallback(boost::bind(&RlvFolderLocks::onNeedsLookupRefresh, this));
|
||||
}
|
||||
|
||||
// Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
|
||||
void RlvFolderLocks::addFolderLock(const folderlock_source_t& lockSource, ELockPermission ePerm, ELockScope eScope,
|
||||
const LLUUID& idRlvObj, ERlvLockMask eLockType)
|
||||
{
|
||||
// Sanity check - eLockType can be RLV_LOCK_ADD or RLV_LOCK_REMOVE but not both
|
||||
RLV_ASSERT( (RLV_LOCK_ADD == eLockType) || (RLV_LOCK_REMOVE == eLockType) );
|
||||
|
||||
// NOTE: m_FolderXXX can contain duplicate folderlock_descr_t
|
||||
m_FolderLocks.push_back(new folderlock_descr_t(idRlvObj, eLockType, lockSource, ePerm, eScope));
|
||||
|
||||
if (PERM_DENY == ePerm)
|
||||
{
|
||||
if (RLV_LOCK_REMOVE == eLockType)
|
||||
m_cntLockRem++;
|
||||
else if (RLV_LOCK_ADD == eLockType)
|
||||
m_cntLockAdd++;
|
||||
}
|
||||
m_fLookupDirty = true;
|
||||
}
|
||||
|
||||
// Checked: 2011-03-28 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
|
||||
bool RlvFolderLocks::getLockedFolders(const folderlock_source_t& lockSource, LLInventoryModel::cat_array_t& lockFolders) const
|
||||
{
|
||||
S32 cntFolders = lockFolders.count();
|
||||
switch (lockSource.first)
|
||||
{
|
||||
case ST_ATTACHMENT:
|
||||
{
|
||||
RLV_ASSERT(typeid(LLUUID) == lockSource.second.type())
|
||||
const LLViewerObject* pObj = gObjectList.findObject(boost::get<LLUUID>(lockSource.second));
|
||||
if ( (pObj) && (pObj->isAttachment()) )
|
||||
{
|
||||
const LLViewerInventoryItem* pItem = gInventory.getItem(pObj->getAttachmentItemID());
|
||||
if ( (pItem) && (RlvInventory::instance().isSharedFolder(pItem->getParentUUID())) )
|
||||
{
|
||||
LLViewerInventoryCategory* pItemFolder = gInventory.getCategory(pItem->getParentUUID());
|
||||
if (pItemFolder)
|
||||
lockFolders.push_back(pItemFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ST_FOLDER:
|
||||
{
|
||||
RLV_ASSERT(typeid(LLUUID) == lockSource.second.type())
|
||||
LLViewerInventoryCategory* pFolder = gInventory.getCategory(boost::get<LLUUID>(lockSource.second));
|
||||
if (pFolder)
|
||||
lockFolders.push_back(pFolder);
|
||||
}
|
||||
break;
|
||||
case ST_ROOTFOLDER:
|
||||
{
|
||||
LLViewerInventoryCategory* pFolder = gInventory.getCategory(gInventory.getRootFolderID());
|
||||
if (pFolder)
|
||||
lockFolders.push_back(pFolder);
|
||||
}
|
||||
break;
|
||||
case ST_SHAREDPATH:
|
||||
{
|
||||
RLV_ASSERT(typeid(std::string) == lockSource.second.type())
|
||||
LLViewerInventoryCategory* pSharedFolder = RlvInventory::instance().getSharedFolder(boost::get<std::string>(lockSource.second));
|
||||
if (pSharedFolder)
|
||||
lockFolders.push_back(pSharedFolder);
|
||||
}
|
||||
break;
|
||||
case ST_ATTACHMENTPOINT:
|
||||
case ST_WEARABLETYPE:
|
||||
{
|
||||
RLV_ASSERT( ((ST_ATTACHMENTPOINT == lockSource.first) && (typeid(S32) == lockSource.second.type())) ||
|
||||
((ST_WEARABLETYPE == lockSource.first) && (typeid(EWearableType) == lockSource.second.type())) );
|
||||
|
||||
uuid_vec_t idItems;
|
||||
if (ST_ATTACHMENTPOINT == lockSource.first)
|
||||
RlvCommandOptionGetPath::getItemIDs(RlvAttachPtLookup::getAttachPoint(boost::get<S32>(lockSource.second)), idItems);
|
||||
else if (ST_WEARABLETYPE == lockSource.first)
|
||||
RlvCommandOptionGetPath::getItemIDs(boost::get<LLWearableType::EType>(lockSource.second), idItems);
|
||||
|
||||
LLInventoryModel::cat_array_t itemFolders;
|
||||
if (RlvInventory::instance().getPath(idItems, itemFolders))
|
||||
lockFolders.insert(lockFolders.end(), itemFolders.begin(), itemFolders.end());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
};
|
||||
return cntFolders != lockFolders.count();
|
||||
}
|
||||
|
||||
// Checked: 2011-03-27 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
bool RlvFolderLocks::getLockedItems(const LLUUID& idFolder, LLInventoryModel::item_array_t& lockItems, bool fFollowLinks) const
|
||||
{
|
||||
S32 cntItems = lockItems.count();
|
||||
|
||||
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
|
||||
LLFindWearablesEx f(true, true); // Collect all worn wearables and body parts
|
||||
gInventory.collectDescendentsIf(idFolder, folders, items, FALSE, f);
|
||||
|
||||
LLUUID idPrev; bool fPrevLocked = false;
|
||||
for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++)
|
||||
{
|
||||
LLViewerInventoryItem* pItem = items.get(idxItem);
|
||||
if ( (fFollowLinks) && (LLAssetType::AT_LINK == pItem->getActualType()) )
|
||||
pItem = pItem->getLinkedItem();
|
||||
if (!pItem)
|
||||
continue;
|
||||
if (pItem->getParentUUID() != idPrev)
|
||||
{
|
||||
idPrev = pItem->getParentUUID();
|
||||
fPrevLocked = isLockedFolder(idPrev, RLV_LOCK_REMOVE);
|
||||
}
|
||||
if (fPrevLocked)
|
||||
lockItems.push_back(pItem);
|
||||
}
|
||||
|
||||
return cntItems != lockItems.count();
|
||||
}
|
||||
|
||||
// Checked: 2011-03-29 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
bool RlvFolderLocks::hasLockedFolderDescendent(const LLUUID& idFolder, int eSourceTypeMask, ELockPermission ePermMask,
|
||||
ERlvLockMask eLockTypeMask, bool fCheckSelf) const
|
||||
{
|
||||
if (!hasLockedFolder(eLockTypeMask))
|
||||
return false;
|
||||
if (m_fLookupDirty)
|
||||
refreshLockedLookups();
|
||||
if ( (fCheckSelf) && (isLockedFolderEntry(idFolder, eSourceTypeMask, ePermMask, RLV_LOCK_ANY)) )
|
||||
return true;
|
||||
|
||||
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
|
||||
RlvLockedDescendentsCollector f(eSourceTypeMask, ePermMask, eLockTypeMask);
|
||||
gInventory.collectDescendentsIf(idFolder, folders, items, FALSE, f, FALSE);
|
||||
return !folders.empty();
|
||||
}
|
||||
|
||||
// Checked: 2011-03-29 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
bool RlvFolderLocks::isLockedFolderEntry(const LLUUID& idFolder, int eSourceTypeMask, ELockPermission ePermMask, ERlvLockMask eLockTypeMask) const
|
||||
{
|
||||
for (folderlock_map_t::const_iterator itFolderLock = m_LockedFolderMap.lower_bound(idFolder),
|
||||
endFolderLock = m_LockedFolderMap.upper_bound(idFolder); itFolderLock != endFolderLock; ++itFolderLock)
|
||||
{
|
||||
const folderlock_descr_t* pLockDescr = itFolderLock->second;
|
||||
if ( (pLockDescr->lockSource.first & eSourceTypeMask) && (pLockDescr->eLockPermission & ePermMask) &&
|
||||
(pLockDescr->eLockType & eLockTypeMask) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
|
||||
bool RlvFolderLocks::isLockedFolder(const LLUUID& idFolder, ERlvLockMask eLockTypeMask, int eSourceTypeMask, folderlock_source_t* plockSource) const
|
||||
{
|
||||
// Sanity check - if there are no folder locks then we don't have to actually do anything
|
||||
if (!hasLockedFolder(eLockTypeMask))
|
||||
return false;
|
||||
|
||||
if (m_fLookupDirty)
|
||||
refreshLockedLookups();
|
||||
|
||||
// Walk up the folder tree and check if anything has 'idFolder' locked
|
||||
std::list<LLUUID> idsRlvObjRem, idsRlvObjAdd; const LLUUID& idFolderRoot = gInventory.getRootFolderID(); LLUUID idFolderCur = idFolder;
|
||||
while (idFolderRoot != idFolderCur)
|
||||
{
|
||||
// Iterate over any folder locks for 'idFolderCur'
|
||||
for (folderlock_map_t::const_iterator itFolderLock = m_LockedFolderMap.lower_bound(idFolderCur),
|
||||
endFolderLock = m_LockedFolderMap.upper_bound(idFolderCur); itFolderLock != endFolderLock; ++itFolderLock)
|
||||
{
|
||||
const folderlock_descr_t* pLockDescr = itFolderLock->second;
|
||||
|
||||
// We can skip over the current lock if:
|
||||
// - the current lock type doesn't match eLockTypeMask
|
||||
// - it's a node lock and the current folder doesn't match
|
||||
// - we encountered a PERM_ALLOW lock from the current lock owner before which supercedes any subsequent locks
|
||||
// - the lock source type doesn't match the mask passed in eSourceTypeMask
|
||||
ERlvLockMask eCurLockType = (ERlvLockMask)(pLockDescr->eLockType & eLockTypeMask);
|
||||
std::list<LLUUID>* pidRlvObjList = (RLV_LOCK_REMOVE == eCurLockType) ? &idsRlvObjRem : &idsRlvObjAdd;
|
||||
if ( (0 == eCurLockType) || ((SCOPE_NODE == pLockDescr->eLockScope) && (idFolder != idFolderCur)) ||
|
||||
(pidRlvObjList->end() != std::find(pidRlvObjList->begin(), pidRlvObjList->end(), pLockDescr->idRlvObj)) ||
|
||||
(0 == (pLockDescr->eLockType & eSourceTypeMask)) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (PERM_DENY == pLockDescr->eLockPermission)
|
||||
{
|
||||
if (plockSource)
|
||||
*plockSource = pLockDescr->lockSource;
|
||||
return true; // Folder is explicitly denied, indicate locked folder to our caller
|
||||
}
|
||||
else if (PERM_ALLOW == pLockDescr->eLockPermission)
|
||||
{
|
||||
pidRlvObjList->push_back(pLockDescr->idRlvObj); // Folder is explicitly allowed, save the owner so we can skip it from now on
|
||||
}
|
||||
}
|
||||
|
||||
// Move up to the folder tree
|
||||
const LLViewerInventoryCategory* pParent = gInventory.getCategory(idFolderCur);
|
||||
idFolderCur = (pParent) ? pParent->getParentUUID() : idFolderRoot;
|
||||
}
|
||||
// If we didn't encounter an explicit deny lock with no exception then the folder is locked if the entire inventory is locked down
|
||||
return (m_fLockedRoot) && (idsRlvObjRem.empty()) && (idsRlvObjAdd.empty());
|
||||
}
|
||||
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0b) | Added: RLVa-1.3.0b
|
||||
void RlvFolderLocks::onNeedsLookupRefresh()
|
||||
{
|
||||
// NOTE: when removeFolderLock() removes the last folder lock we still want to refresh everything so mind the conditional OR assignment
|
||||
m_fLookupDirty |= !m_FolderLocks.empty();
|
||||
}
|
||||
|
||||
// Checked: 2011-03-27 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
void RlvFolderLocks::refreshLockedLookups() const
|
||||
{
|
||||
//
|
||||
// Refresh locked folders
|
||||
//
|
||||
m_fLockedRoot = false;
|
||||
m_LockedFolderMap.clear();
|
||||
for (folderlock_list_t::const_iterator itFolderLock = m_FolderLocks.begin(); itFolderLock != m_FolderLocks.end(); ++itFolderLock)
|
||||
{
|
||||
const folderlock_descr_t* pLockDescr = *itFolderLock;
|
||||
|
||||
LLInventoryModel::cat_array_t lockedFolders; const LLUUID& idFolderRoot = gInventory.getRootFolderID();
|
||||
if (getLockedFolders(pLockDescr->lockSource, lockedFolders))
|
||||
{
|
||||
for (S32 idxFolder = 0, cntFolder = lockedFolders.count(); idxFolder < cntFolder; idxFolder++)
|
||||
{
|
||||
const LLViewerInventoryCategory* pFolder = lockedFolders.get(idxFolder);
|
||||
if (idFolderRoot != pFolder->getUUID())
|
||||
m_LockedFolderMap.insert(std::pair<LLUUID, const folderlock_descr_t*>(pFolder->getUUID(), pLockDescr));
|
||||
else
|
||||
m_fLockedRoot |= (SCOPE_SUBTREE == pLockDescr->eLockScope);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_fLookupDirty = false;
|
||||
|
||||
//
|
||||
// Refresh locked items (iterate over COF and filter out any items residing in a RLV_LOCK_REMOVE locked PERM_DENY folder)
|
||||
//
|
||||
m_LockedAttachmentRem.clear();
|
||||
m_LockedWearableRem.clear();
|
||||
|
||||
LLInventoryModel::item_array_t lockedItems;
|
||||
if (getLockedItems(LLCOFMgr::instance().getCOF(), lockedItems, true))
|
||||
{
|
||||
for (S32 idxItem = 0, cntItem = lockedItems.count(); idxItem < cntItem; idxItem++)
|
||||
{
|
||||
const LLViewerInventoryItem* pItem = lockedItems.get(idxItem);
|
||||
switch (pItem->getType())
|
||||
{
|
||||
case LLAssetType::AT_BODYPART:
|
||||
case LLAssetType::AT_CLOTHING:
|
||||
m_LockedWearableRem.push_back(pItem->getLinkedUUID());
|
||||
break;
|
||||
case LLAssetType::AT_OBJECT:
|
||||
m_LockedAttachmentRem.push_back(pItem->getLinkedUUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any duplicate items we may have picked up
|
||||
std::sort(m_LockedAttachmentRem.begin(), m_LockedAttachmentRem.end());
|
||||
m_LockedAttachmentRem.erase(std::unique(m_LockedAttachmentRem.begin(), m_LockedAttachmentRem.end()), m_LockedAttachmentRem.end());
|
||||
std::sort(m_LockedWearableRem.begin(), m_LockedWearableRem.end());
|
||||
m_LockedWearableRem.erase(std::unique(m_LockedWearableRem.begin(), m_LockedWearableRem.end()), m_LockedWearableRem.end());
|
||||
}
|
||||
|
||||
// Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
|
||||
void RlvFolderLocks::removeFolderLock(const folderlock_source_t& lockSource, ELockPermission ePerm, ELockScope eScope,
|
||||
const LLUUID& idRlvObj, ERlvLockMask eLockType)
|
||||
{
|
||||
// Sanity check - eLockType can be RLV_LOCK_ADD or RLV_LOCK_REMOVE but not both
|
||||
RLV_ASSERT( (RLV_LOCK_ADD == eLockType) || (RLV_LOCK_REMOVE == eLockType) );
|
||||
|
||||
folderlock_descr_t lockDescr(idRlvObj, eLockType, lockSource, ePerm, eScope); RlvPredValuesEqual<folderlock_descr_t> f = { &lockDescr };
|
||||
folderlock_list_t::iterator itFolderLock = std::find_if(m_FolderLocks.begin(), m_FolderLocks.end(), f);
|
||||
RLV_ASSERT( m_FolderLocks.end() != itFolderLock ); // The lock should always exist
|
||||
if (m_FolderLocks.end() != itFolderLock)
|
||||
{
|
||||
delete *itFolderLock;
|
||||
m_FolderLocks.erase(itFolderLock);
|
||||
|
||||
if (PERM_DENY == ePerm)
|
||||
{
|
||||
if (RLV_LOCK_REMOVE == eLockType)
|
||||
m_cntLockRem--;
|
||||
else if (RLV_LOCK_ADD == eLockType)
|
||||
m_cntLockAdd--;
|
||||
}
|
||||
m_fLookupDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -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;
|
||||
@@ -20,6 +20,15 @@
|
||||
#include "rlvdefines.h"
|
||||
#include "rlvcommon.h"
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4702) // warning C4702: unreachable code
|
||||
#endif
|
||||
#include <boost/variant.hpp>
|
||||
#ifdef LL_WINDOWS
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
// ============================================================================
|
||||
// RlvAttachPtLookup class declaration
|
||||
//
|
||||
@@ -36,12 +45,13 @@
|
||||
class RlvAttachPtLookup
|
||||
{
|
||||
public:
|
||||
static LLViewerJointAttachment* getAttachPoint(S32 idxAttachPt);
|
||||
static LLViewerJointAttachment* getAttachPoint(const std::string& strText);
|
||||
static LLViewerJointAttachment* getAttachPoint(const LLInventoryItem* pItem);
|
||||
|
||||
static S32 getAttachPointIndex(std::string strText);
|
||||
static S32 getAttachPointIndex(const LLViewerObject* pObj);
|
||||
static S32 getAttachPointIndex(const LLViewerJointAttachment* pObj);
|
||||
static S32 getAttachPointIndex(const LLViewerObject* pAttachObj);
|
||||
static S32 getAttachPointIndex(const LLViewerJointAttachment* pAttachPt);
|
||||
static S32 getAttachPointIndex(const LLInventoryCategory* pFolder);
|
||||
static S32 getAttachPointIndex(const LLInventoryItem* pItem, bool fFollowLinks = true);
|
||||
|
||||
@@ -80,7 +90,7 @@ public:
|
||||
bool hasLockedHUD() const { return m_fHasLockedHUD; }
|
||||
|
||||
// Returns TRUE if the attachment is RLV_LOCK_REMOVE locked
|
||||
bool isLockedAttachment(const LLViewerObject* pObj) const;
|
||||
bool isLockedAttachment(const LLViewerObject* pAttachObj) const;
|
||||
// Returns TRUE if the attachment point is RLV_LOCK_REMOVE locked by anything other than idRlvObj
|
||||
bool isLockedAttachmentExcept(const LLViewerObject* pObj, const LLUUID& idRlvObj) const;
|
||||
// Returns TRUE if the attachment point is eLock type locked (RLV_LOCK_ANY = RLV_LOCK_ADD *or* RLV_LOCK_REMOVE)
|
||||
@@ -276,10 +286,118 @@ protected:
|
||||
|
||||
extern RlvWearableLocks gRlvWearableLocks;
|
||||
|
||||
// ============================================================================
|
||||
// RlvFolderLocks class declaration
|
||||
//
|
||||
|
||||
class RlvFolderLocks : public LLSingleton<RlvFolderLocks>
|
||||
{
|
||||
friend class RlvLockedDescendentsCollector;
|
||||
public:
|
||||
RlvFolderLocks();
|
||||
|
||||
// Specifies the source of a folder lock
|
||||
enum ELockSourceType
|
||||
{
|
||||
ST_ATTACHMENT = 0x01, ST_ATTACHMENTPOINT = 0x02, ST_FOLDER = 0x04, ST_ROOTFOLDER = 0x08,
|
||||
ST_SHAREDPATH = 0x10, ST_WEARABLETYPE = 0x20, ST_NONE= 0x00, ST_MASK_ANY = 0xFF
|
||||
};
|
||||
typedef boost::variant<LLUUID, std::string, S32, LLWearableType::EType> lock_source_t;
|
||||
typedef std::pair<ELockSourceType, lock_source_t> folderlock_source_t;
|
||||
// Specifies options for the folder lock
|
||||
enum ELockPermission { PERM_ALLOW = 0x1, PERM_DENY = 0x2, PERM_MASK_ANY = 0x3 };
|
||||
enum ELockScope { SCOPE_NODE, SCOPE_SUBTREE } ;
|
||||
protected:
|
||||
struct folderlock_descr_t
|
||||
{
|
||||
LLUUID idRlvObj;
|
||||
ERlvLockMask eLockType;
|
||||
folderlock_source_t lockSource;
|
||||
ELockPermission eLockPermission;
|
||||
ELockScope eLockScope;
|
||||
|
||||
folderlock_descr_t(const LLUUID& rlvObj, ERlvLockMask lockType, folderlock_source_t source, ELockPermission perm, ELockScope scope);
|
||||
bool operator ==(const folderlock_descr_t& rhs) const;
|
||||
};
|
||||
|
||||
public:
|
||||
// Adds an eLock type lock (held by idRlvObj) for the specified folder source (with ePerm and eScope lock options)
|
||||
void addFolderLock(const folderlock_source_t& lockSource, ELockPermission ePerm, ELockScope eScope, const LLUUID& idRlvObj, ERlvLockMask eLockType);
|
||||
|
||||
// Returns TRUE if there is at least 1 non-detachable attachment as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
|
||||
bool hasLockedAttachment() const;
|
||||
// Returns TRUE if there is at least 1 eLock type PERM_DENY locked folder (RLV_LOCK_ANY = RLV_LOCK_ADD *or* RLV_LOCK_REMOVE)
|
||||
bool hasLockedFolder(ERlvLockMask eLockTypeMask) const;
|
||||
// Returns TRUE if the folder has a descendent folder lock with the specified charateristics
|
||||
bool hasLockedFolderDescendent(const LLUUID& idFolder, int eSourceTypeMask, ELockPermission ePermMask,
|
||||
ERlvLockMask eLockTypeMask, bool fCheckSelf) const;
|
||||
// Returns TRUE if there is at least 1 non-removable wearable as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
|
||||
bool hasLockedWearable() const;
|
||||
// Returns TRUE if the attachment (specified by item UUID) is non-detachable as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
|
||||
bool isLockedAttachment(const LLUUID& idItem) const;
|
||||
// Returns TRUE if the folder is locked as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
|
||||
bool isLockedFolder(const LLUUID& idFolder, ERlvLockMask eLock, int eSourceTypeMask = ST_MASK_ANY, folderlock_source_t* plockSource = NULL) const;
|
||||
// Returns TRUE if the wearable (specified by item UUID) is non-removable as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock
|
||||
bool isLockedWearable(const LLUUID& idItem) const;
|
||||
|
||||
// Removes an eLock type lock (held by idRlvObj) for the specified folder source (with ePerm and eScope lock options)
|
||||
void removeFolderLock(const folderlock_source_t& lockSource, ELockPermission ePerm, ELockScope eScope, const LLUUID& idRlvObj, ERlvLockMask eLockType);
|
||||
|
||||
protected:
|
||||
// Returns TRUE if the folder has an explicit folder lock entry with the specified charateristics
|
||||
bool isLockedFolderEntry(const LLUUID& idFolder, int eSourceTypeMask, ELockPermission ePermMask, ERlvLockMask eLockTypeMask) const;
|
||||
|
||||
/*
|
||||
* canXXX helper functions (note that a more approriate name might be userCanXXX)
|
||||
*/
|
||||
public:
|
||||
bool canMoveFolder(const LLUUID& idFolder, const LLUUID& idFolderDest) const;
|
||||
bool canRemoveFolder(const LLUUID& idFolder) const;
|
||||
bool canRenameFolder(const LLUUID& idFolder) const;
|
||||
bool canMoveItem(const LLUUID& idItem, const LLUUID& idFolderDest) const;
|
||||
bool canRemoveItem(const LLUUID& idItem) const;
|
||||
bool canRenameItem(const LLUUID& idItem) const;
|
||||
|
||||
/*
|
||||
* Cached item/folder look-up helper functions
|
||||
*/
|
||||
protected:
|
||||
bool getLockedFolders(const folderlock_source_t& lockSource, LLInventoryModel::cat_array_t& lockFolders) const;
|
||||
bool getLockedItems(const LLUUID& idFolder, LLInventoryModel::item_array_t& lockItems, bool fFollowLinks) const;
|
||||
void onNeedsLookupRefresh();
|
||||
void refreshLockedLookups() const;
|
||||
|
||||
/*
|
||||
* Member variables
|
||||
*/
|
||||
protected:
|
||||
// Map of folder locks (idRlvObj -> lockDescr)
|
||||
typedef std::list<const folderlock_descr_t*> folderlock_list_t;
|
||||
folderlock_list_t m_FolderLocks; // List of add and remove locked folder descriptions
|
||||
S32 m_cntLockAdd; // Number of RLV_LOCK_ADD locked folders in m_FolderLocks
|
||||
S32 m_cntLockRem; // Number of RLV_LOCK_REMOVE locked folders in m_FolderLocks
|
||||
|
||||
// Cached item look-up variables
|
||||
typedef std::multimap<LLUUID, const folderlock_descr_t*> folderlock_map_t;
|
||||
mutable bool m_fLookupDirty;
|
||||
mutable bool m_fLockedRoot;
|
||||
mutable uuid_vec_t m_LockedAttachmentRem;
|
||||
mutable folderlock_map_t m_LockedFolderMap;
|
||||
mutable uuid_vec_t m_LockedWearableRem;
|
||||
private:
|
||||
friend class LLSingleton<RlvFolderLocks>;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// RlvAttachPtLookup inlined member functions
|
||||
//
|
||||
|
||||
// Checked: 2010-11-30 (RLVa-1.4.0b) | Added: RLVa-1.4.0b
|
||||
inline LLViewerJointAttachment* RlvAttachPtLookup::getAttachPoint(S32 idxAttachPt)
|
||||
{
|
||||
return (isAgentAvatarValid()) ? get_if_there(gAgentAvatarp->mAttachmentPoints, idxAttachPt, (LLViewerJointAttachment*)NULL) : NULL;
|
||||
}
|
||||
|
||||
// Checked: 2010-03-03 (RLVa-1.1.3a) | Modified: RLVa-0.2.0d
|
||||
inline LLViewerJointAttachment* RlvAttachPtLookup::getAttachPoint(const std::string& strText)
|
||||
{
|
||||
@@ -311,7 +429,7 @@ inline S32 RlvAttachPtLookup::getAttachPointIndex(const LLViewerObject* pObj)
|
||||
// RlvAttachmentLocks inlined member functions
|
||||
//
|
||||
|
||||
// Checked: 2010-08-07 (RLVa-1.2.0i) | Modified: RLVa-1.2.0i
|
||||
// Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
|
||||
inline ERlvWearMask RlvAttachmentLocks::canAttach(const LLInventoryItem* pItem, LLViewerJointAttachment** ppAttachPtOut /*=NULL*/) const
|
||||
{
|
||||
// The specified item can be attached if:
|
||||
@@ -320,7 +438,8 @@ inline ERlvWearMask RlvAttachmentLocks::canAttach(const LLInventoryItem* pItem,
|
||||
LLViewerJointAttachment* pAttachPt = RlvAttachPtLookup::getAttachPoint(pItem);
|
||||
if (ppAttachPtOut)
|
||||
*ppAttachPtOut = pAttachPt;
|
||||
return (!pAttachPt) ? RLV_WEAR : canAttach(pAttachPt);
|
||||
return ((pItem) && (!RlvFolderLocks::instance().isLockedFolder(pItem->getParentUUID(), RLV_LOCK_ADD)))
|
||||
? ((!pAttachPt) ? RLV_WEAR : canAttach(pAttachPt)) : RLV_WEAR_LOCKED;
|
||||
}
|
||||
|
||||
// Checked: 2010-08-07 (RLVa-1.2.0i) | Modified: RLVa-1.2.0i
|
||||
@@ -345,28 +464,30 @@ inline bool RlvAttachmentLocks::canDetach(const LLInventoryItem* pItem) const
|
||||
return (pAttachObj) && (!isLockedAttachment(pAttachObj));
|
||||
}
|
||||
|
||||
// Checked: 2010-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.3.0b
|
||||
inline bool RlvAttachmentLocks::hasLockedAttachmentPoint(ERlvLockMask eLock) const
|
||||
{
|
||||
// Remove locks are more common so check those first
|
||||
return
|
||||
( (eLock & RLV_LOCK_REMOVE) && ((!m_AttachPtRem.empty()) || (!m_AttachObjRem.empty())) ) ||
|
||||
( (eLock & RLV_LOCK_ADD) && (!m_AttachPtAdd.empty()) );
|
||||
((eLock & RLV_LOCK_REMOVE) && ((!m_AttachPtRem.empty()) || (!m_AttachObjRem.empty()) || (RlvFolderLocks::instance().hasLockedAttachment()))) ||
|
||||
((eLock & RLV_LOCK_ADD) && (!m_AttachPtAdd.empty()) );
|
||||
}
|
||||
|
||||
// Checked: 2010-02-28 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a
|
||||
inline bool RlvAttachmentLocks::isLockedAttachment(const LLViewerObject* pObj) const
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.3.0b
|
||||
inline bool RlvAttachmentLocks::isLockedAttachment(const LLViewerObject* pAttachObj) const
|
||||
{
|
||||
// If pObj is valid then it should always specify a root since we store root UUIDs in m_AttachObjRem
|
||||
RLV_ASSERT( (!pObj) || (pObj == pObj->getRootEdit()) );
|
||||
RLV_ASSERT( (!pAttachObj) || (pAttachObj == pAttachObj->getRootEdit()) );
|
||||
|
||||
// Object is locked if:
|
||||
// - it's specifically marked as non-detachable (ie @detach=n)
|
||||
// - it's attached to an attachment point that is RLV_LOCK_REMOVE locked (ie @remattach:<attachpt>=n)
|
||||
// - it's part of a locked folder
|
||||
return
|
||||
(pObj) && (pObj->isAttachment()) &&
|
||||
( (m_AttachObjRem.find(pObj->getID()) != m_AttachObjRem.end()) ||
|
||||
(isLockedAttachmentPoint(RlvAttachPtLookup::getAttachPointIndex(pObj), RLV_LOCK_REMOVE)) );
|
||||
(pAttachObj) && (pAttachObj->isAttachment()) &&
|
||||
( (m_AttachObjRem.find(pAttachObj->getID()) != m_AttachObjRem.end()) ||
|
||||
(isLockedAttachmentPoint(RlvAttachPtLookup::getAttachPointIndex(pAttachObj), RLV_LOCK_REMOVE)) ||
|
||||
(RlvFolderLocks::instance().isLockedAttachment(pAttachObj->getAttachmentItemID())) );
|
||||
}
|
||||
|
||||
// Checked: 2010-02-28 (RLVa-1.2.0a) | Added: RLVa-1.0.5a
|
||||
@@ -406,12 +527,13 @@ inline bool RlvWearableLocks::canRemove(const LLInventoryItem* pItem) const
|
||||
return (pWearable) && (!isLockedWearable(pWearable));
|
||||
}
|
||||
|
||||
// Checked: 2010-05-14 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g
|
||||
// Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
|
||||
inline ERlvWearMask RlvWearableLocks::canWear(const LLViewerInventoryItem* pItem) const
|
||||
{
|
||||
// The specified item can be worn if the wearable type it specifies can be worn on
|
||||
RLV_ASSERT( (pItem) && (LLInventoryType::IT_WEARABLE == pItem->getInventoryType()) );
|
||||
return (pItem) ? canWear(pItem->getWearableType()) : RLV_WEAR_LOCKED;
|
||||
return ((pItem) && (!RlvFolderLocks::instance().isLockedFolder(pItem->getParentUUID(), RLV_LOCK_ADD)))
|
||||
? canWear(pItem->getWearableType()) : RLV_WEAR_LOCKED;
|
||||
}
|
||||
|
||||
// Checked: 2010-05-14 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g
|
||||
@@ -435,15 +557,18 @@ inline bool RlvWearableLocks::hasLockedWearableType(ERlvLockMask eLock) const
|
||||
return ( (eLock & RLV_LOCK_REMOVE) && (!m_WearableTypeRem.empty()) ) || ( (eLock & RLV_LOCK_ADD) && (!m_WearableTypeAdd.empty()) );
|
||||
}
|
||||
|
||||
// Checked: 2010-03-19 (RLVa-1.2.0c) | Added: RLVa-1.2.0a
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.2.0a
|
||||
inline bool RlvWearableLocks::isLockedWearable(const LLWearable* pWearable) const
|
||||
{
|
||||
// Wearable is locked if:
|
||||
// - it's specifically marked as non-removable
|
||||
// - it's worn on a wearable type that is RLV_LOCK_REMOVE locked
|
||||
// - it's part of a locked folder
|
||||
// TODO-RLVa: [RLVa-1.2.1] We don't have the ability to lock a specific wearable yet so rewrite this when we do
|
||||
RLV_ASSERT(pWearable);
|
||||
return (pWearable) && (isLockedWearableType(pWearable->getType(), RLV_LOCK_REMOVE));
|
||||
return
|
||||
(pWearable) &&
|
||||
( (isLockedWearableType(pWearable->getType(), RLV_LOCK_REMOVE)) || (RlvFolderLocks::instance().isLockedWearable(pWearable->getItemID())) );
|
||||
}
|
||||
|
||||
// Checked: 2010-03-19 (RLVa-1.2.0c) | Added: RLVa-1.2.0a
|
||||
@@ -454,6 +579,134 @@ inline bool RlvWearableLocks::isLockedWearableType(LLWearableType::EType eType,
|
||||
( (eLock & RLV_LOCK_ADD) && (m_WearableTypeAdd.find(eType) != m_WearableTypeAdd.end()) );
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// RlvFolderLocks member functions
|
||||
//
|
||||
|
||||
// Checked: 2011-03-27 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
inline RlvFolderLocks::folderlock_descr_t::folderlock_descr_t(const LLUUID& rlvObj, ERlvLockMask lockType, folderlock_source_t source,
|
||||
ELockPermission perm, ELockScope scope)
|
||||
: idRlvObj(rlvObj), eLockType(lockType), lockSource(source), eLockPermission(perm), eLockScope(scope)
|
||||
{
|
||||
}
|
||||
|
||||
// Checked: 2011-03-27 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
inline bool RlvFolderLocks::folderlock_descr_t::operator ==(const folderlock_descr_t& rhs) const
|
||||
{
|
||||
return (idRlvObj == rhs.idRlvObj) && (eLockType == rhs.eLockType) && (lockSource == rhs.lockSource) &&
|
||||
(eLockPermission == rhs.eLockPermission) && (eLockScope == rhs.eLockScope);
|
||||
}
|
||||
|
||||
// Checked: 2011-03-29 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
inline bool RlvFolderLocks::canMoveFolder(const LLUUID& idFolder, const LLUUID& idFolderDest) const
|
||||
{
|
||||
// Block moving the folder to destination if:
|
||||
// - the folder (or one of its descendents) is explicitly locked
|
||||
// - folder and destination are subject to different locks
|
||||
// -> Possible combinations:
|
||||
// * folder locked + destination unlocked => block move
|
||||
// * folder unlocked + destination locked => block move
|
||||
// * folder locked + destination locked => allow move only if both are subject to the same folder lock
|
||||
// * folder unlocked + destination unlocked => allow move (special case of above since both locks are equal when there is none)
|
||||
// => so the above becomes (isLockedFolder(A) == isLockedFolder(B)) && (lockA == lockB)
|
||||
folderlock_source_t lockSource(ST_NONE, 0), lockSourceDest(ST_NONE, 0);
|
||||
return
|
||||
(!hasLockedFolderDescendent(idFolder, ST_MASK_ANY, PERM_MASK_ANY, RLV_LOCK_ANY, true)) &&
|
||||
( (isLockedFolder(idFolder, RLV_LOCK_ANY, ST_MASK_ANY, &lockSource) == isLockedFolder(idFolderDest, RLV_LOCK_ANY, ST_MASK_ANY, &lockSourceDest)) &&
|
||||
(lockSource == lockSourceDest) );
|
||||
}
|
||||
|
||||
// Checked: 2011-03-29 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
inline bool RlvFolderLocks::canRemoveFolder(const LLUUID& idFolder) const
|
||||
{
|
||||
// Block removing a folder if:
|
||||
// - the folder (or one of its descendents) is explicitly locked
|
||||
// - the folder itself is locked (but disregard root folder locks)
|
||||
return
|
||||
(!hasLockedFolderDescendent(idFolder, ST_MASK_ANY, PERM_MASK_ANY, RLV_LOCK_ANY, true)) &&
|
||||
(!isLockedFolder(idFolder, RLV_LOCK_ANY, ST_MASK_ANY & ~ST_ROOTFOLDER));
|
||||
}
|
||||
|
||||
// Checked: 2011-03-29 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
inline bool RlvFolderLocks::canRenameFolder(const LLUUID& idFolder) const
|
||||
{
|
||||
// Block renaming a folder if:
|
||||
// - the folder (or one of its descendents) is explicitly locked by:
|
||||
// -> a "shared path" => renaming the folder would change the shared path and hence invalidate the lock
|
||||
// -> an attachment point \
|
||||
// -> an attachment |--> renaming the folder to a "dot" (=invisible) folder would invalidate the lock
|
||||
// -> a wearable type /
|
||||
return !hasLockedFolderDescendent(idFolder, ST_SHAREDPATH | ST_ATTACHMENT | ST_ATTACHMENTPOINT | ST_WEARABLETYPE, PERM_MASK_ANY, RLV_LOCK_ANY, true);
|
||||
}
|
||||
|
||||
// Checked: 2011-03-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
inline bool RlvFolderLocks::canMoveItem(const LLUUID& idItem, const LLUUID& idFolderDest) const
|
||||
{
|
||||
// Block moving the folder to destination if:
|
||||
// - folder and destination are subject to different locks [see canMoveFolder() for more details]
|
||||
const LLViewerInventoryItem* pItem = gInventory.getItem(idItem); const LLUUID& idFolder = (pItem) ? pItem->getParentUUID() : LLUUID::null;
|
||||
int maskSource = ST_MASK_ANY & ~ST_ROOTFOLDER; folderlock_source_t lockSource(ST_NONE, 0), lockSourceDest(ST_NONE, 0);
|
||||
return
|
||||
(idFolder.notNull()) &&
|
||||
(isLockedFolder(idFolder, RLV_LOCK_ANY, maskSource, &lockSource) == isLockedFolder(idFolderDest, RLV_LOCK_ANY, maskSource, &lockSourceDest)) &&
|
||||
(lockSource == lockSourceDest);
|
||||
}
|
||||
|
||||
// Checked: 2011-03-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
inline bool RlvFolderLocks::canRemoveItem(const LLUUID& idItem) const
|
||||
{
|
||||
// Block removing items from locked folders (but disregard root folder locks)
|
||||
const LLViewerInventoryItem* pItem = gInventory.getItem(idItem); const LLUUID& idFolder = (pItem) ? pItem->getParentUUID() : LLUUID::null;
|
||||
int maskSource = ST_MASK_ANY & ~ST_ROOTFOLDER;
|
||||
return (idFolder.notNull()) && (!isLockedFolder(idFolder, RLV_LOCK_ANY, maskSource));
|
||||
}
|
||||
|
||||
// Checked: 2011-03-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0g
|
||||
inline bool RlvFolderLocks::canRenameItem(const LLUUID& idItem) const
|
||||
{
|
||||
// Items can always be renamed, regardless of folder locks
|
||||
return true;
|
||||
}
|
||||
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0b
|
||||
inline bool RlvFolderLocks::hasLockedAttachment() const
|
||||
{
|
||||
if (m_fLookupDirty)
|
||||
refreshLockedLookups();
|
||||
return !m_LockedAttachmentRem.empty();
|
||||
}
|
||||
|
||||
// Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g
|
||||
inline bool RlvFolderLocks::hasLockedFolder(ERlvLockMask eLock) const
|
||||
{
|
||||
// Remove locks are more common so check those first
|
||||
return ((eLock & RLV_LOCK_REMOVE) && (m_cntLockRem)) || ((eLock & RLV_LOCK_ADD) && (m_cntLockAdd));
|
||||
}
|
||||
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0b
|
||||
inline bool RlvFolderLocks::hasLockedWearable() const
|
||||
{
|
||||
if (m_fLookupDirty)
|
||||
refreshLockedLookups();
|
||||
return !m_LockedWearableRem.empty();
|
||||
}
|
||||
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0b
|
||||
inline bool RlvFolderLocks::isLockedAttachment(const LLUUID& idItem) const
|
||||
{
|
||||
if (m_fLookupDirty)
|
||||
refreshLockedLookups();
|
||||
return (std::find(m_LockedAttachmentRem.begin(), m_LockedAttachmentRem.end(), idItem) != m_LockedAttachmentRem.end());
|
||||
}
|
||||
|
||||
// Checked: 2010-11-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0b
|
||||
inline bool RlvFolderLocks::isLockedWearable(const LLUUID& idItem) const
|
||||
{
|
||||
if (m_fLookupDirty)
|
||||
refreshLockedLookups();
|
||||
return (std::find(m_LockedWearableRem.begin(), m_LockedWearableRem.end(), idItem) != m_LockedWearableRem.end());
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
#endif // RLV_LOCKS_H
|
||||
|
||||
@@ -23,7 +23,109 @@
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llagent.h"
|
||||
#include "llgesturemgr.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "cofmgr.h"
|
||||
#include "rlvviewer2.h"
|
||||
|
||||
// ============================================================================
|
||||
// From lloutfitobserver.cpp
|
||||
|
||||
LLCOFObserver::LLCOFObserver() :
|
||||
mCOFLastVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)
|
||||
{
|
||||
mItemNameHash.finalize();
|
||||
gInventory.addObserver(this);
|
||||
}
|
||||
|
||||
LLCOFObserver::~LLCOFObserver()
|
||||
{
|
||||
if (gInventory.containsObserver(this))
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLCOFObserver::changed(U32 mask)
|
||||
{
|
||||
if (!gInventory.isInventoryUsable())
|
||||
return;
|
||||
|
||||
checkCOF();
|
||||
}
|
||||
|
||||
// static
|
||||
S32 LLCOFObserver::getCategoryVersion(const LLUUID& cat_id)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
|
||||
if (!cat)
|
||||
return LLViewerInventoryCategory::VERSION_UNKNOWN;
|
||||
|
||||
return cat->getVersion();
|
||||
}
|
||||
|
||||
// static
|
||||
const std::string& LLCOFObserver::getCategoryName(const LLUUID& cat_id)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
|
||||
if (!cat)
|
||||
return LLStringUtil::null;
|
||||
|
||||
return cat->getName();
|
||||
}
|
||||
|
||||
bool LLCOFObserver::checkCOF()
|
||||
{
|
||||
LLUUID cof = LLCOFMgr::getInstance()->getCOF();
|
||||
if (cof.isNull())
|
||||
return false;
|
||||
|
||||
bool cof_changed = false;
|
||||
LLMD5 item_name_hash = hashDirectDescendentNames(cof);
|
||||
if (item_name_hash != mItemNameHash)
|
||||
{
|
||||
cof_changed = true;
|
||||
mItemNameHash = item_name_hash;
|
||||
}
|
||||
|
||||
S32 cof_version = getCategoryVersion(cof);
|
||||
if (cof_version != mCOFLastVersion)
|
||||
{
|
||||
cof_changed = true;
|
||||
mCOFLastVersion = cof_version;
|
||||
}
|
||||
|
||||
if (!cof_changed)
|
||||
return false;
|
||||
|
||||
mCOFChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
LLMD5 LLCOFObserver::hashDirectDescendentNames(const LLUUID& cat_id)
|
||||
{
|
||||
LLInventoryModel::cat_array_t* cat_array;
|
||||
LLInventoryModel::item_array_t* item_array;
|
||||
gInventory.getDirectDescendentsOf(cat_id,cat_array,item_array);
|
||||
LLMD5 item_name_hash;
|
||||
if (!item_array)
|
||||
{
|
||||
item_name_hash.finalize();
|
||||
return item_name_hash;
|
||||
}
|
||||
for (LLInventoryModel::item_array_t::const_iterator iter = item_array->begin();
|
||||
iter != item_array->end();
|
||||
iter++)
|
||||
{
|
||||
const LLViewerInventoryItem *item = (*iter);
|
||||
if (!item)
|
||||
continue;
|
||||
item_name_hash.update(item->getName());
|
||||
}
|
||||
item_name_hash.finalize();
|
||||
return item_name_hash;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -25,9 +25,39 @@
|
||||
#define RLV_VIEWER2_H
|
||||
|
||||
#include "llcallbacklist.h"
|
||||
#include "llinventoryobserver.h"
|
||||
|
||||
#include "boost/function.hpp"
|
||||
|
||||
// ============================================================================
|
||||
// From lloutfitobserver.h
|
||||
|
||||
class LLCOFObserver : public LLInventoryObserver, public LLSingleton<LLCOFObserver>
|
||||
{
|
||||
friend class LLSingleton<LLCOFObserver>;
|
||||
protected:
|
||||
LLCOFObserver();
|
||||
public:
|
||||
virtual ~LLCOFObserver();
|
||||
|
||||
virtual void changed(U32 mask);
|
||||
|
||||
typedef boost::signals2::signal<void (void)> signal_t;
|
||||
void addCOFChangedCallback(const signal_t::slot_type& cb) { mCOFChanged.connect(cb); }
|
||||
void addCOFSavedCallback(const signal_t::slot_type& cb) { mCOFSaved.connect(cb); }
|
||||
|
||||
protected:
|
||||
bool checkCOF();
|
||||
static S32 getCategoryVersion(const LLUUID& cat_id);
|
||||
static const std::string& getCategoryName(const LLUUID& cat_id);
|
||||
static LLMD5 hashDirectDescendentNames(const LLUUID& cat_id);
|
||||
|
||||
private:
|
||||
signal_t mCOFChanged;
|
||||
signal_t mCOFSaved;
|
||||
S32 mCOFLastVersion;
|
||||
LLMD5 mItemNameHash;
|
||||
};
|
||||
|
||||
|
||||
#endif // RLV_VIEWER2_H
|
||||
|
||||
Reference in New Issue
Block a user