From 441b564afe705bb76b80e9ae13c783ae78577ca9 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Tue, 26 Mar 2013 00:46:11 -0500 Subject: [PATCH] RLVa update. --- indra/llappearance/llavatarappearance.cpp | 19 +- indra/llappearance/llavatarappearance.h | 4 + indra/llappearance/llwearabledata.cpp | 21 +- indra/llappearance/llwearabletype.cpp | 5 +- indra/newview/character/avatar_lad.xml | 19 +- indra/newview/llagent.cpp | 22 +- indra/newview/llagent.h | 2 +- indra/newview/llagentwearables.cpp | 105 ++------ indra/newview/llagentwearables.h | 2 +- indra/newview/llappearancemgr.cpp | 248 ++++++++++-------- indra/newview/llappearancemgr.h | 5 +- indra/newview/llappviewer.cpp | 10 +- indra/newview/llgiveinventory.cpp | 5 + indra/newview/llhudtext.cpp | 13 +- indra/newview/llhudtext.h | 10 +- indra/newview/lltooldraganddrop.cpp | 23 +- indra/newview/llviewercamera.cpp | 8 +- indra/newview/llviewermessage.cpp | 31 ++- indra/newview/llviewerobject.cpp | 15 +- indra/newview/llvoavatarself.cpp | 45 +++- indra/newview/llvoavatarself.h | 13 + indra/newview/rlvcommon.cpp | 43 ++- indra/newview/rlvcommon.h | 6 +- indra/newview/rlvdefines.h | 4 +- indra/newview/rlvhandler.cpp | 69 ++--- indra/newview/rlvhandler.h | 4 +- indra/newview/rlvhelper.cpp | 151 ++++++----- indra/newview/rlvhelper.h | 9 +- indra/newview/rlvinventory.cpp | 24 +- indra/newview/rlvinventory.h | 4 + indra/newview/rlvlocks.h | 7 +- .../skins/default/xui/en-us/strings.xml | 3 + 32 files changed, 585 insertions(+), 364 deletions(-) diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index d186ce79b..db3def4f4 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -465,6 +465,13 @@ void LLAvatarAppearance::computeBodySize() LLVector3 foot = mFootLeftp->getPosition(); + LLVector3 old_offset = mAvatarOffset; + +// [RLVa:KB] - Checked: 2013-03-03 (RLVa-1.4.8) + mAvatarOffset = getAvatarOffset(); +// [/RLVa:KB] +// mAvatarOffset.mV[VZ] = getVisualParamWeight(11001); + mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] - knee.mV[VZ] * hip_scale.mV[VZ] - ankle.mV[VZ] * knee_scale.mV[VZ] - @@ -484,13 +491,23 @@ void LLAvatarAppearance::computeBodySize() new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH; new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH; - if (new_body_size != mBodySize) + //mAvatarOffset.mV[VX] = 0.0f; + //mAvatarOffset.mV[VY] = 0.0f; + + if (new_body_size != mBodySize || old_offset != mAvatarOffset) { mBodySize = new_body_size; bodySizeChanged(); } } +// [RLVa:KB] - Checked: 2013-03-03 (RLVa-1.4.8) +LLVector3 LLAvatarAppearance::getAvatarOffset() /*const*/ +{ + return LLVector3(0.f,0.f,getVisualParamWeight(11001)); +} +// [/RLVa:KB] + //----------------------------------------------------------------------------- // parseSkeletonFile() //----------------------------------------------------------------------------- diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 21a813cc8..1882e2582 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -150,6 +150,9 @@ protected: virtual void buildCharacter(); virtual BOOL loadAvatar(); virtual void bodySizeChanged() = 0; +// [RLVa:KB] - Checked: 2013-03-03 (RLVa-1.4.8) + virtual LLVector3 getAvatarOffset() /*const*/; +// [/RLVa:KB] BOOL setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 ¤t_volume_num, S32 ¤t_joint_num); BOOL allocateCharacterJoints(U32 num); @@ -165,6 +168,7 @@ protected: //-------------------------------------------------------------------- public: LLVector3 mBodySize; + LLVector3 mAvatarOffset; protected: F32 mPelvisToFoot; diff --git a/indra/llappearance/llwearabledata.cpp b/indra/llappearance/llwearabledata.cpp index 4d06c56f7..4ade2b33a 100644 --- a/indra/llappearance/llwearabledata.cpp +++ b/indra/llappearance/llwearabledata.cpp @@ -104,19 +104,12 @@ U32 LLWearableData::pushWearable(const LLWearableType::EType type, llwarns << "Null wearable sent for type " << type << llendl; return MAX_CLOTHING_PER_TYPE; } -// if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) -// { -// mWearableDatas[type].push_back(wearable); -// wearableUpdated(wearable); -// checkWearableAgainstInventory(wearable); -// return mWearableDatas[type].size()-1; -// } // [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0g) | Added: RLVa-1.2.0g if ( (type < LLWearableType::WT_COUNT) && (mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) ) { // Don't add the same wearable twice U32 idxWearable = getWearableIndex(wearable); - //RLV_ASSERT(MAX_CLOTHING_PER_TYPE == idxWearable); // pushWearable() on an already added wearable is a bug *somewhere* + llassert(MAX_CLOTHING_PER_TYPE == idxWearable); // pushWearable() on an already added wearable is a bug *somewhere* if (MAX_CLOTHING_PER_TYPE == idxWearable) { mWearableDatas[type].push_back(wearable); @@ -128,8 +121,18 @@ U32 LLWearableData::pushWearable(const LLWearableType::EType type, wearableUpdated(wearable, removed); } return idxWearable; -// [/RLVa:KB] } +// [/RLVa:KB] +// if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) +// { +// mWearableDatas[type].push_back(wearable); +// if (trigger_updated) +// { +// const BOOL removed = FALSE; +// wearableUpdated(wearable, removed); +// } +// return mWearableDatas[type].size()-1; +// } return MAX_CLOTHING_PER_TYPE; } diff --git a/indra/llappearance/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp index bccc4ed18..1daecdc3d 100644 --- a/indra/llappearance/llwearabletype.cpp +++ b/indra/llappearance/llwearabletype.cpp @@ -99,7 +99,10 @@ LLWearableDictionary::LLWearableDictionary() addEntry(LLWearableType::WT_ALPHA, new WearableEntry("alpha", "New Alpha", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE)); addEntry(LLWearableType::WT_TATTOO, new WearableEntry("tattoo", "New Tattoo", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE)); - addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE)); +// addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE)); +// [SL:KB] - Patch: Appearance-Misc | Checked: 2011-05-29 (Catznip-2.6) + addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, FALSE)); +// [/SL:KB] addEntry(LLWearableType::WT_INVALID, new WearableEntry("invalid", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_NONE, FALSE, FALSE)); addEntry(LLWearableType::WT_NONE, new WearableEntry("none", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_NONE, FALSE, FALSE)); diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 23d23b5c2..48e6205bc 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -823,7 +823,24 @@ - + + + + + + mBodySize; - - static LLCachedControl x_off("AscentAvatarXModifier"); - static LLCachedControl y_off("AscentAvatarYModifier"); - static LLCachedControl z_off("AscentAvatarZModifier"); - - body_size.mV[VX] += x_off; - body_size.mV[VY] += y_off; - body_size.mV[VZ] += z_off; // Offset by RLVa, but not overridden. -// [RLVa:KB] - Checked: 2010-10-11 (RLVa-1.2.0e) | Added: RLVa-1.2.0e - body_size.mV[VZ] += RlvSettings::getAvatarOffsetZ(); -// [/RLVa:KB] - + const LLVector3 body_size = gAgentAvatarp->mBodySize + gAgentAvatarp->mAvatarOffset; msg->addVector3Fast(_PREHASH_Size, body_size); // To guard against out of order packets diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 23c73b671..51b8c2e6e 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -811,7 +811,7 @@ private: //-------------------------------------------------------------------- public: // Checks against all groups in the entire agent group list. - BOOL isInGroup(const LLUUID& group_id) const; + BOOL isInGroup(const LLUUID& group_id, BOOL ingnore_God_mod = FALSE) const; protected: // Only used for building titles. BOOL isGroupMember() const { return !mGroupID.isNull(); } diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index cdf4a4c11..904ddc17c 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1209,11 +1209,7 @@ void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_ { LLViewerWearable* old_wearable = getViewerWearable(type,index); -// if (old_wearable) -// [RLVa:KB] - Checked: 2010-05-11 (RLVa-1.2.0c) | Modified: RLVa-1.2.0g - // NOTE: we block actual removal in removeWearableFinal(); all we really want here is to avoid showing the save notice - if ( (old_wearable) && ((!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.isLockedWearable(old_wearable))) ) -// [/RLVa:KB] + if (old_wearable) { if (old_wearable->isDirty()) { @@ -1271,19 +1267,16 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_ { LLViewerWearable* old_wearable = getViewerWearable(type,i); //queryWearableCache(); // moved below -// if (old_wearable) -// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Added: RLVa-1.2.0g - if ( (old_wearable) && ((!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.isLockedWearable(old_wearable))) ) -// [/RLVa:KB] + if (old_wearable) { popWearable(old_wearable); old_wearable->removeFromAvatar(TRUE); } } -// mWearableDatas[type].clear(); -// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Added: RLVa-1.2.0g - // The line above shouldn't be needed and would cause issues if we block removing one of the wearables - RLV_VERIFY( ((!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.hasLockedWearable(type))) ? mWearableDatas[type].empty() : true ); +// clearWearableType(type); +// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0) + // The line above shouldn't be needed + RLV_VERIFY(0 == getWearableCount(type)); // [/RLVa:KB] } else @@ -1291,10 +1284,7 @@ void LLAgentWearables::removeWearableFinal( LLWearableType::EType type, bool do_ LLViewerWearable* old_wearable = getViewerWearable(type, index); //queryWearableCache(); // moved below -// if (old_wearable) -// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Added: RLVa-1.2.0g - if ( (old_wearable) && ((!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.isLockedWearable(old_wearable))) ) -// [/RLVa:KB] + if (old_wearable) { popWearable(old_wearable); old_wearable->removeFromAvatar(TRUE); @@ -1356,12 +1346,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it S32 count = wearables.count(); llassert(items.count() == count); -// [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0g) | Added: RLVa-1.2.0g - // If the user is @add/remoutfit restricted in any way then this function won't just work as-is, so instead of removing and re-adding - // we're stuck with any wearable type potentially having left-over (remove locked) clothing that we'll need to reorder in-place - S32 idxCurPerType[LLWearableType::WT_COUNT] = { 0 }; -// [/RLVa:KB] - S32 i; for (i = 0; i < count; i++) { @@ -1386,51 +1370,10 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it // exactly one wearable per body part setWearable(type,0,new_wearable); } -// else -// { -// pushWearable(type,new_wearable); -// } -// [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0g) | Added: RLVa-1.2.0g - else if ( (!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.hasLockedWearable(type)) || (!remove) ) - { - // Sanity check: there shouldn't be any worn wearables for this type the first time we encounter it - RLV_ASSERT( (!remove) || (0 != idxCurPerType[type]) || (0 == getWearableCount(type)) ); - pushWearable(type,new_wearable); - } else { - // Get the current index of the wearable (or add it if doesn't exist yet) - S32 idxCur = getWearableIndex(new_wearable); - if (MAX_CLOTHING_PER_TYPE == idxCur) - { - // Skip adding if @addoutfit=n restricted *unless* the wearable made it into COF [see LLAppMgr::updateAgentWearables()] - if ( (RLV_WEAR_LOCKED == gRlvWearableLocks.canWear(type)) && - (!gInventory.isObjectDescendentOf(new_item->getUUID(), LLAppearanceMgr::instance().getCOF())) ) - { - continue; - } - idxCur = pushWearable(type,new_wearable); - } - - // Since we're moving up from index 0 we just swap the two wearables and things will work out in the end (hopefully) - if (idxCurPerType[type] != idxCur) - { - wearableentry_map_t::iterator itWearable = mWearableDatas.find(type); - RLV_ASSERT(itWearable != mWearableDatas.end()); - if (itWearable == mWearableDatas.end()) continue; - wearableentry_vec_t& typeWearable = itWearable->second; - RLV_ASSERT(typeWearable.size() >= 2); - if (typeWearable.size() < 2) continue; - - typeWearable[idxCur] = typeWearable[idxCurPerType[type]]; - typeWearable[idxCurPerType[type]] = new_wearable; - //wearableUpdated(new_wearable); - //checkWearableAgainstInventory(new_wearable); - } + pushWearable(type,new_wearable); } - idxCurPerType[type]++; -// [/RLVa:KB] - const BOOL removed = FALSE; wearableUpdated(new_wearable, removed); } @@ -1475,7 +1418,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it // User has picked "wear on avatar" from a menu. -void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append) +/*void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append) { //LLAgentDumper dumper("setWearableItem"); if (isWearingItem(new_item->getUUID())) @@ -1523,7 +1466,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearab } setWearableFinal(new_item, new_wearable, do_append); -} +}*/ // static bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable) @@ -1696,8 +1639,8 @@ void LLAgentWearables::invalidateBakedTextureHash(LLMD5& hash) const // Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to // get attachments into desired state with minimal number of adds/removes. //void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array) -// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-3.0.0a) | Added: Catznip-2.2.0a -void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly) +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2) +void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool attach_only) // [/SL:KB] { // Possible cases: @@ -1764,8 +1707,8 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj // Remove everything in objects_to_remove // userRemoveMultipleAttachments(objects_to_remove); -// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-3.0.0a) | Added: Catznip-2.2.0a - if (!fAttachOnly) +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2) + if (!attach_only) { userRemoveMultipleAttachments(objects_to_remove); } @@ -1779,12 +1722,12 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo { if (!isAgentAvatarValid()) return; -// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a - // RELEASE-RLVa: [SL-2.0.0] Check our callers and verify that erasing elements from the passed vector won't break random things +// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.0) + // RELEASE-RLVa: [SL-3.4] Check our callers and verify that erasing elements from the passed vector won't break random things if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) ) { llvo_vec_t::iterator itObj = objects_to_remove.begin(); - while (itObj != objects_to_remove.end()) + while (objects_to_remove.end() != itObj) { const LLViewerObject* pAttachObj = *itObj; if (gRlvAttachmentLocks.isLockedAttachment(pAttachObj)) @@ -1792,12 +1735,12 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo itObj = objects_to_remove.erase(itObj); // Fall-back code: re-add the attachment if it got removed from COF somehow (compensates for possible bugs elsewhere) - LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; - LLLinkedItemIDMatches f(pAttachObj->getAttachmentItemID()); - gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH, f); - RLV_ASSERT( 0 != items.count() ); - if (0 == items.count()) + bool fInCOF = LLAppearanceMgr::isLinkInCOF(pAttachObj->getAttachmentItemID()); + RLV_ASSERT(fInCOF); + if (!fInCOF) + { LLAppearanceMgr::instance().registerAttachment(pAttachObj->getAttachmentItemID()); + } } else { @@ -1828,10 +1771,10 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array) { -// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1b) | Added: RLVa-1.3.1b +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) static bool sInitialAttachmentsRequested = false; - // RELEASE-RLVa: [SL-2.5.2] Check our callers and verify that erasing elements from the passed vector won't break random things + // RELEASE-RLVa: [SL-3.4] Check our callers and verify that erasing elements from the passed vector won't break random things if ( (rlv_handler_t::isEnabled()) && (sInitialAttachmentsRequested) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) { // Fall-back code: everything should really already have been pruned before we get this far diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 794d656b3..5c0c060e7 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -113,7 +113,7 @@ public: private: /*virtual*/void wearableUpdated(LLWearable *wearable, BOOL removed); public: - void setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false); +// void setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false); void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLViewerWearable* >& wearables, BOOL remove); void setWearableName(const LLUUID& item_id, const std::string& new_name); // *TODO: Move this into llappearance/LLWearableData ? diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index a5d67e356..0fb2d48d6 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1374,30 +1374,11 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up return false; } -// [RLVa:KB] - Checked: 2010-09-04 (RLVa-1.2.1a) | Modified: RLVa-1.2.1a - if ( (rlv_handler_t::isEnabled()) && - ((gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) || (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY))) ) +// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) + replace |= (LLAssetType::AT_BODYPART == item_to_wear->getType()); // Body parts should always replace + if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanWearItem(item_to_wear, (replace) ? RLV_WEAR_REPLACE : RLV_WEAR_ADD)) ) { - switch (item_to_wear->getType()) - { - case LLAssetType::AT_BODYPART: - case LLAssetType::AT_CLOTHING: - { - ERlvWearMask eWear = gRlvWearableLocks.canWear(item_to_wear); - if ( (RLV_WEAR_LOCKED == eWear) || ((replace) && ((RLV_WEAR_REPLACE & eWear) == 0)) ) - return false; - } - break; - case LLAssetType::AT_OBJECT: - { - ERlvWearMask eWear = gRlvAttachmentLocks.canAttach(item_to_wear); - if ( (RLV_WEAR_LOCKED == eWear) || ((replace) && ((RLV_WEAR_REPLACE & eWear) == 0)) ) - return false; - } - break; - default: - return false; - } + return false; } // [/RLVa:KB] @@ -1793,25 +1774,56 @@ void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_lin } // [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f -void LLAppearanceMgr::syncCOF(const LLInventoryModel::item_array_t& items, LLAssetType::EType type, LLCallAfterInventoryLinkMgr* link_waiter) +void LLAppearanceMgr::purgeItems(const LLInventoryModel::item_array_t& items) +{ + for (LLInventoryModel::item_array_t::const_iterator itItem = items.begin(); itItem != items.end(); ++itItem) + { + const LLViewerInventoryItem* pItem = *itItem; + if (pItem->getIsLinkType()) + { + gInventory.purgeObject(pItem->getUUID()); + } + } +} + +void LLAppearanceMgr::purgeItemsOfType(LLAssetType::EType asset_type) +{ + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + gInventory.collectDescendents(getCOF(), cats, items, LLInventoryModel::EXCLUDE_TRASH); + for (LLInventoryModel::item_array_t::const_iterator itItem = items.begin(); itItem != items.end(); ++itItem) + { + const LLInventoryItem* pItem = *itItem; + if ( (pItem->getIsLinkType()) && (asset_type == pItem->getType()) ) + { + gInventory.purgeObject(pItem->getUUID()); + } + } +} + +void LLAppearanceMgr::syncCOF(const LLInventoryModel::item_array_t& items, + LLInventoryModel::item_array_t& items_to_add, LLInventoryModel::item_array_t& items_to_remove) { const LLUUID idCOF = getCOF(); LLInventoryModel::item_array_t cur_cof_items, new_cof_items = items; // Grab the current COF contents - LLIsType f(type); LLInventoryModel::cat_array_t cats; - gInventory.collectDescendentsIf(getCOF(), cats, cur_cof_items, LLInventoryModel::EXCLUDE_TRASH, f); + gInventory.collectDescendents(getCOF(), cats, cur_cof_items, LLInventoryModel::EXCLUDE_TRASH); // Purge everything in cur_cof_items that isn't part of new_cof_items for (S32 idxCurItem = 0, cntCurItem = cur_cof_items.count(); idxCurItem < cntCurItem; idxCurItem++) { - const LLViewerInventoryItem* pItem = cur_cof_items.get(idxCurItem); + LLViewerInventoryItem* pItem = cur_cof_items.get(idxCurItem); if (std::find_if(new_cof_items.begin(), new_cof_items.end(), RlvPredIsEqualOrLinkedItem(pItem)) == new_cof_items.end()) { // Item doesn't exist in new_cof_items => purge (if it's a link) - if (pItem->getIsLinkType()) - gInventory.purgeObject(pItem->getUUID()); + if ( (pItem->getIsLinkType()) && + (LLAssetType::AT_LINK_FOLDER != pItem->getActualType()) && + (items_to_remove.end() == std::find(items_to_remove.begin(), items_to_remove.end(), pItem)) ) + { + items_to_remove.push_back(pItem); + } } else { @@ -1821,10 +1833,14 @@ void LLAppearanceMgr::syncCOF(const LLInventoryModel::item_array_t& items, LLAss } } - // Link to whatever remains in new_cof_items + // Whatever remains in new_cof_items will need to have a link created for (S32 idxNewItem = 0, cntNewItem = new_cof_items.count(); idxNewItem < cntNewItem; idxNewItem++) { - link_waiter->addItem(new_cof_items.get(idxNewItem)->getLinkedUUID()); + LLViewerInventoryItem* pItem = new_cof_items.get(idxNewItem); + if (items_to_add.end() == std::find(items_to_add.begin(), items_to_add.end(), pItem)) + { + items_to_add.push_back(pItem); + } } } // [/SL:KB] @@ -1893,11 +1909,12 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) getDescendentsOfAssetType(category, gest_items_new, LLAssetType::AT_GESTURE, false); updateCOF(body_items_new, wear_items_new, obj_items_new, gest_items_new, append, category); } + void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t& wear_items_new, LLInventoryModel::item_array_t& obj_items_new, LLInventoryModel::item_array_t& gest_items_new, - bool append /*=false*/, const LLUUID& category /*=LLUUID::null*/) + bool append /*=false*/, const LLUUID& idOutfit /*=LLUUID::null*/) // [/RLVa:KB] { // LLViewerInventoryCategory *pcat = gInventory.getCategory(category); @@ -2006,60 +2023,57 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, // [/RLVa:KB] removeDuplicateItems(gest_items); -#ifndef LL_RELEASE_FOR_DOWNLOAD - LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL; -#endif - // Create links to new COF contents. - LL_DEBUGS("Avatar") << self_av_string() << "creating LLCallAfterInventoryLinkMgr" << LL_ENDL; - LLInventoryModel::item_array_t all_items; - /*all_items += body_items; + all_items += body_items; all_items += wear_items; all_items += obj_items; - all_items += gest_items;*/ + all_items += gest_items; - // Will link all the above items. - bool update_base_outfit_ordering = !append; - LLCallAfterInventoryLinkMgr *link_waiter = - new LLCallAfterInventoryLinkMgr(all_items,cof,"update_appearance_on_destroy", - boost::bind(&LLAppearanceMgr::updateAppearanceFromCOF, - LLAppearanceMgr::getInstance(), - update_base_outfit_ordering)); - -// [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f - if(append) - { - // Synchronize COF - // -> it's possible that we don't link to any new items in which case 'link_waiter' fires when it goes out of scope below - syncCOF(body_items, LLAssetType::AT_BODYPART, link_waiter); - syncCOF(wear_items, LLAssetType::AT_CLOTHING, link_waiter); - syncCOF(obj_items, LLAssetType::AT_OBJECT, link_waiter); - syncCOF(gest_items, LLAssetType::AT_GESTURE, link_waiter); - } +// [SL:KB] + // Synchronize COF + // -> it's possible that we don't link to any new items in which case 'link_waiter' fires when it goes out of scope below + LLInventoryModel::item_array_t items_add, items_remove; + syncCOF(all_items, items_add, items_remove); // [/SL:KB] + // Will link all the above items. + LLPointer link_waiter = new LLUpdateAppearanceOnDestroy; +// [SL:KB] - Checked: 2013-03-05 (RLVa-1.4.8) + linkAll(cof, items_add, link_waiter); +// [/SL:KB] +// linkAll(cof,all_items,link_waiter); + // Add link to outfit if category is an outfit. -// [RLVa:KB] - Checked: Never | Added: RLVa-1.2.0b - if (!append && category.notNull()) -// [/RLVa:KB] - if (!append) +// [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f + if ( (!append) && (idOutfit.notNull()) ) { - link_waiter->addItems(body_items); - link_waiter->addItems(wear_items); - link_waiter->addItems(obj_items); - link_waiter->addItems(gest_items); - if(category.notNull()) - link_waiter->addItem(category); - + createBaseOutfitLink(idOutfit, link_waiter); + } +// [/SL:KB] +// if (!append) +// { +// createBaseOutfitLink(category, link_waiter); +// } +// // Remove current COF contents. Have to do this after creating // the link_waiter so links can be followed for any items that get // carried over (e.g. keeping old shape if the new outfit does not // contain one) +// [SL:KB] + purgeItems(items_remove); + bool keep_outfit_links = append; - purgeCategory(cof, keep_outfit_links); + if (!keep_outfit_links) + { + purgeItemsOfType(LLAssetType::AT_LINK_FOLDER); } + gInventory.notifyObservers(); +// [/SL:KB] +// bool keep_outfit_links = append; +// purgeCategory(cof, keep_outfit_links, &all_items); +// gInventory.notifyObservers(); LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL; } @@ -2163,7 +2177,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo // We need to report removals before additions or scripts will get confused for (uuid_vec_t::const_iterator itItemID = idsCurrent.begin(); itItemID != idsCurrent.end(); ++itItemID) { - const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(*itItemID); + const LLWearable* pWearable = gAgentWearables.getWearableFromItemID(*itItemID); if (pWearable) RlvBehaviourNotifyHandler::onTakeOff(pWearable->getType(), true); } @@ -2317,7 +2331,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) //dumpCat(getCOF(),"COF, start"); - bool follow_folder_links = true; + bool follow_folder_links = false; LLUUID current_outfit_id = getCOF(); // Find all the wearables that are in the COF's subtree. @@ -2362,13 +2376,15 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering) LLViewerInventoryItem* pItem = gInventory.getItem(idItem); if (pItem) + { obj_items.push_back(pItem); + } ++itPendingAttachLink; } // Don't remove attachments until avatar is fully loaded (should reduce random attaching/detaching/reattaching at log-on) - llinfos << "Updating " << obj_items.count() << " attachments" << llendl; + LL_DEBUGS("Avatar") << self_av_string() << "Updating " << obj_items.count() << " attachments" << LL_ENDL; LLAgentWearables::userUpdateAttachments(obj_items, !gAgentAvatarp->isFullyLoaded()); } // [/SL:KB] @@ -2908,14 +2924,9 @@ void LLAppearanceMgr::removeAllClothesFromAvatar() is_clothing, false); uuid_vec_t item_ids; - // Take them off by removing from COF. - for (LLInventoryModel::item_array_t::const_iterator it = clothing_items.begin(); + for (LLInventoryModel::item_array_t::iterator it = clothing_items.begin(); it != clothing_items.end(); ++it) { -// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g - if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(*it)) ) - continue; -// [/RLVa:KB] item_ids.push_back((*it).get()->getLinkedUUID()); } @@ -2970,6 +2981,16 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id) const LLInventoryItem* item = item_array.get(i).get(); if (item->getIsLinkType() && item->getLinkedUUID() == item_id) { +// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) +#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG + // NOTE-RLVa: debug-only, can be removed down the line + if (rlv_handler_t::isEnabled()) + { + RLV_ASSERT(rlvPredCanRemoveItem(item)); + } +#endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG +// [/RLVa:KB] + gInventory.purgeObject(item->getUUID()); } } @@ -2988,6 +3009,16 @@ void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type) const LLViewerInventoryItem* item = *it; if (item->getIsLinkType()) // we must operate on links only { +// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) +#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG + // NOTE-RLVa: debug-only, can be removed down the line + if (rlv_handler_t::isEnabled()) + { + RLV_ASSERT(rlvPredCanRemoveItem(item)); + } +#endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG +// [/RLVa:KB] + gInventory.purgeObject(item->getUUID()); } } @@ -3886,40 +3917,49 @@ void LLAppearanceMgr::wearBaseOutfit() void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) { - if (ids_to_remove.empty()) - { - llwarns << "called with empty list, nothing to do" << llendl; - } +// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) + bool fUpdateAppearance = false; for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it) { - const LLUUID& id_to_remove = *it; - const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove); - - // [SL:KB] - Patch: Appearance-RemoveWearableFromAvatar | Checked: 2010-08-13 (Catznip-3.0.0a) | Added: Catznip-2.1.1d -// [RLVa:KB] - Checked: Never | Added: RLVa-1.2.1c - LLViewerInventoryItem * item_to_remove = gInventory.getItem(id_to_remove); - if (!item_to_remove) - continue; - if (rlv_handler_t::isEnabled() && !gRlvWearableLocks.canRemove(item_to_remove)) - continue; - if (item_to_remove->getType() == LLAssetType::AT_CLOTHING) + const LLInventoryItem* linked_item = gInventory.getLinkedItem(*it); + if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(linked_item)) ) { - const LLViewerWearable* pWearable = gAgentWearables.getWearableFromItemID(item_to_remove->getLinkedUUID()); - if(!pWearable || pWearable->getAssetType() == LLAssetType::AT_BODYPART || gAgentWearables.getWearableIndex(pWearable) >= LLAgentWearables::MAX_CLOTHING_PER_TYPE ) - continue; - RlvBehaviourNotifyHandler::onTakeOff(pWearable->getType(), true); - } -// [/RLVa:KB] - removeCOFItemLinks(linked_item_id); + continue; + } + + fUpdateAppearance = true; + removeCOFItemLinks(linked_item->getUUID()); } - updateAppearanceFromCOF(); + + if (fUpdateAppearance) + { + updateAppearanceFromCOF(); + } +// [/RLVa:KB] +// for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it) +// { +// const LLUUID& id_to_remove = *it; +// const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove); +// removeCOFItemLinks(linked_item_id); +// } +// updateAppearanceFromCOF(); } void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove) { - LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove); - removeCOFItemLinks(linked_item_id); +// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) + const LLInventoryItem* linked_item = gInventory.getLinkedItem(id_to_remove); + if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(linked_item)) ) + { + return; + } + + removeCOFItemLinks(linked_item->getUUID()); updateAppearanceFromCOF(); +// [/RLVA:KB] +// LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove); +// removeCOFItemLinks(linked_item_id); +// updateAppearanceFromCOF(); } bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body) diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 1718f6d5d..b3539de66 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -239,7 +239,10 @@ private: void setOutfitLocked(bool locked); // [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f - void syncCOF(const LLInventoryModel::item_array_t& items, LLAssetType::EType type, LLCallAfterInventoryLinkMgr* link_waiter); + void purgeItems(const LLInventoryModel::item_array_t& items); + void purgeItemsOfType(LLAssetType::EType asset_type); + void syncCOF(const LLInventoryModel::item_array_t& items, + LLInventoryModel::item_array_t& items_to_add, LLInventoryModel::item_array_t& items_to_remove); // [/SL:KB] bool mAttachmentInvLinkEnabled; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index af9e0032a..3315d7b8b 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -203,6 +203,9 @@ // [RLVa:KB] #include "rlvhandler.h" // [/RLVa:KB] +// [SL:KB] - Patch: Appearance-Misc | Checked: 2013-02-12 (Catznip-3.4) +#include "llappearancemgr.h" +// [/SL:KB] // *FIX: These extern globals should be cleaned up. // The globals either represent state/config/resource-storage of either @@ -4454,7 +4457,8 @@ void LLAppViewer::idleNetwork() gObjectList.mNumNewObjects = 0; S32 total_decoded = 0; - if (!gSavedSettings.getBOOL("SpeedTest")) + static const LLCachedControl speedTest(gSavedSettings, "SpeedTest"); + if (!speedTest) { LLFastTimer t(FTM_IDLE_NETWORK); // decode @@ -4633,6 +4637,10 @@ void LLAppViewer::disconnectViewer() // close inventory interface, close all windows LLInventoryView::cleanup(); +// [SL:KB] - Patch: Appearance-Misc | Checked: 2013-02-12 (Catznip-3.4) + // Destroying all objects below will trigger attachment detaching code and attempt to remove the COF links for them + LLAppearanceMgr::instance().setAttachmentInvLinkEnable(false); +// [/SL:KB] gAgentWearables.cleanup(); gAgentCamera.cleanup(); diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index 926fdb8d1..09f690cf0 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -46,6 +46,11 @@ #include "llmutelist.h" #include "llviewerobjectlist.h" #include "llvoavatarself.h" +// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.2a) +#include "llavatarnamecache.h" +#include "rlvhandler.h" +#include "rlvui.h" +// [/RLVa:KB] // MAX ITEMS is based on (sizeof(uuid)+2) * count must be < MTUBYTES // or 18 * count < 1200 => count < 1200/18 => 66. I've cut it down a diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 338bf45cf..861d4f677 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -492,7 +492,7 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset) LLVector3 x_pixel_vec; LLVector3 y_pixel_vec; LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); - LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec); +// LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec); // if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen) // { // // bubble off-screen, so find a spot for it along screen edge @@ -690,17 +690,14 @@ F32 LLHUDText::LLHUDTextSegment::getWidth(const LLFontGL* font) } } -// [RLVa:KB] - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f +// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f void LLHUDText::refreshAllObjectText() { - for (TextObjectIterator itText = sTextObjects.begin(); itText != sTextObjects.end(); itText++) + for (TextObjectIterator itText = sTextObjects.begin(); itText != sTextObjects.end(); ++itText) { LLHUDText* pText = *itText; - if ( (pText) && (!pText->getPreFilteredText().empty() && ("" != pText->getPreFilteredText()) ) && - (pText->mSourceObject) && (LL_PCODE_VOLUME == pText->mSourceObject->getPCode()) ) - { - pText->setString(pText->mPreFilteredText); - } + if ( (pText) && (!pText->mObjText.empty()) && (pText->mSourceObject) && (LL_PCODE_VOLUME == pText->mSourceObject->getPCode()) ) + pText->setString(pText->mObjText); } } // [/RLVa:KB] diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h index 2583862cc..68450753c 100644 --- a/indra/newview/llhudtext.h +++ b/indra/newview/llhudtext.h @@ -124,8 +124,10 @@ public: static void renderAllHUD(); static void reshape(); static void setDisplayText(BOOL flag) { sDisplayText = flag ; } -// [RLVa:KB] - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f - const std::string &getPreFilteredText() const {return mPreFilteredText;} + +// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f + const std::string& getObjectText() const { return mObjText; } + void setObjectText(const std::string &utf8string) { mObjText = utf8string; } static void refreshAllObjectText(); // [/RLVa:KB] @@ -170,8 +172,8 @@ private: ETextAlignment mTextAlignment; EVertAlignment mVertAlignment; BOOL mHidden; -// [RLVa:KB] - Checked: 2009-07-09 (RLVa-1.0.0f) | Added: RLVa-1.0.0f - std::string mPreFilteredText; +// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f + std::string mObjText; // [/RLVa:KB] static BOOL sDisplayText ; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 159717515..485a96634 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1722,12 +1722,11 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( return ACCEPT_NO; } -// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f - if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) +// [RLVa:KB] - Checked: 2013-02-13 (RLVa-1.4.8) + bool fReplace = !(mask & MASK_CONTROL); + if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanWearItem(item, (fReplace) ? RLV_WEAR_REPLACE : RLV_WEAR_ADD)) ) { - ERlvWearMask eWearMask = gRlvAttachmentLocks.canAttach(item); bool fReplace = !(mask & MASK_CONTROL); - if ( ((!fReplace) && ((RLV_WEAR_ADD & eWearMask) == 0)) || ((fReplace) && ((RLV_WEAR_REPLACE & eWearMask) == 0)) ) - return ACCEPT_NO_LOCKED; + return ACCEPT_NO_LOCKED; } // [/RLVa:KB] @@ -2086,12 +2085,11 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem( return ACCEPT_NO; } -// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f - if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) ) +// [RLVa:KB] - Checked: 2013-02-13 (RLVa-1.4.8) + bool fReplace = (!(mask & MASK_CONTROL)) || (LLAssetType::AT_BODYPART == item->getType()); // Body parts should always replace + if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanWearItem(item, (fReplace) ? RLV_WEAR_REPLACE : RLV_WEAR_ADD)) ) { - ERlvWearMask eWearMask = gRlvWearableLocks.canWear(item); bool fReplace = !(mask & MASK_CONTROL); - if ( ((!fReplace) && ((RLV_WEAR_ADD & eWearMask) == 0)) || ((fReplace) && ((RLV_WEAR_REPLACE & eWearMask) == 0)) ) - return ACCEPT_NO_LOCKED; + return ACCEPT_NO_LOCKED; } // [/RLVa:KB] @@ -2107,7 +2105,10 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem( // TODO: investigate wearables may not be loaded at this point EXT-8231 - LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(),true, !(mask & MASK_CONTROL)); +// [RLVa:KB] - Checked: 2013-02-13 (RLVa-1.4.8) + LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, fReplace); +// [/RLVa:KB] +// LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(),true, !(mask & MASK_CONTROL)); } return ACCEPT_YES_MULTI; } diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 4d357433e..9266dc434 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -45,6 +45,9 @@ #include "llworld.h" #include "lltoolmgr.h" #include "llviewerjoystick.h" +// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) +#include "rlvhandler.h" +// [/RLVa:KB] // Linden library includes #include "lldrawable.h" @@ -350,7 +353,10 @@ void LLViewerCamera::setPerspective(BOOL for_selection, if (limit_select_distance) { // ...select distance from control - z_far = gSavedSettings.getF32("MaxSelectDistance"); +// z_far = gSavedSettings.getF32("MaxSelectDistance"); +// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Added: RLVa-1.2.0e + z_far = (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) ? gSavedSettings.getF32("MaxSelectDistance") : 1.5; +// [/RLVa:KB] } else { diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index ca71d11a8..4bd6c9187 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1517,6 +1517,15 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& sizeof(mFolderID.mData)); // send the message msg->sendReliable(mHost); + +// [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1e) | Added: RLVa-1.2.1e + if (fRlvNotifyAccepted) + { + std::string::size_type idxToken = mDesc.find("' ( http://"); + if (std::string::npos != idxToken) + RlvBehaviourNotifyHandler::sendNotification("accepted_in_inv inv_offer " + mDesc.substr(1, idxToken - 1)); + } +// [/RLVa:KB] //don't spam them if they are getting flooded if (check_offer_throttle(mFromName, true)) @@ -6525,12 +6534,6 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp { // got the region, so include the region and 3d coordinates of the object notice.setArg("[REGIONNAME]", viewregion->getName()); -// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) - if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ) - { - notice.setArg("[REGIONNAME]", RlvStrings::getString(RLV_STRING_HIDDEN_REGION)); - } -// [/RLVa:KB] std::string formatpos = llformat("%.1f, %.1f,%.1f", objpos[VX], objpos[VY], objpos[VZ]); notice.setArg("[REGIONPOS]", formatpos); @@ -6538,7 +6541,15 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp } } - if (!foundpos) +// [RLVa:KB] - Checked: 2010-04-23 (RLVa-1.2.0g) | Modified: RLVa-1.0.0a + if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) + { + notice.setArg("[REGIONNAME]", RlvStrings::getString(RLV_STRING_HIDDEN_REGION)); + notice.setArg("[REGIONPOS]", RlvStrings::getString(RLV_STRING_HIDDEN)); + } + else if (!foundpos) +// [/RLVa:KB] +// if (!foundpos) { // unable to determine location of the object notice.setArg("[REGIONNAME]", "(unknown region)"); @@ -6552,7 +6563,11 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp std::string perms; for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++) { - if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && SCRIPT_QUESTION_IS_CAUTION[i]) +// if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && SCRIPT_QUESTION_IS_CAUTION[i]) +// [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7) + if ( (orig_questions & LSCRIPTRunTimePermissionBits[i]) && + ((SCRIPT_QUESTION_IS_CAUTION[i]) || (notification["payload"]["rlv_notify"].asBoolean())) ) +// [/RLVa:KB] { count++; caution = TRUE; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index d80fd9713..6d725bbe3 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1270,6 +1270,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, mText->setColor(mHudTextColor); mText->setString(mHudTextString); } +// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f + if (rlv_handler_t::isEnabled()) + { + mText->setObjectText(mHudTextString); + } +// [/RLVa:KB] setChanged(MOVED | SILHOUETTE); } @@ -1648,10 +1654,15 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, coloru.mV[3] = 255 - coloru.mV[3]; mHudTextColor = LLColor4(coloru); //Cache for reset on debug infodisplay toggle. if(mText->getDoFade()) //Fade is disabled when this is being overridden by debug text. + mText->setColor(mHudTextColor); + mText->setString(mHudTextString); + +// [RLVa:KB] - Checked: 2010-03-27 (RLVa-1.4.0a) | Added: RLVa-1.0.0f + if (rlv_handler_t::isEnabled()) { - mText->setColor(mHudTextColor); - mText->setString(mHudTextString); + mText->setObjectText(mHudTextString); } +// [/RLVa:KB] setChanged(TEXTURE); } else if(mText.notNull()) diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index bad259ac6..13c063a5e 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -162,6 +162,9 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp) : LLVOAvatar(id, pcode, regionp), +// [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7) + mAttachmentSignal(NULL), +// [/RLVa:KB] mScreenp(NULL), mLastRegionHandle(0), mRegionCrossingCount(0), @@ -1130,6 +1133,14 @@ LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id) return NULL; } +// [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7) +boost::signals2::connection LLVOAvatarSelf::setAttachmentCallback(const attachment_signal_t::slot_type& cb) +{ + if (!mAttachmentSignal) + mAttachmentSignal = new attachment_signal_t(); + return mAttachmentSignal->connect(cb); +} +// [/RLVa:KB] // [RLVa:KB] - Checked: 2010-03-14 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a LLViewerJointAttachment* LLVOAvatarSelf::getWornAttachmentPoint(const LLUUID& idItem) const { @@ -1185,6 +1196,10 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view // [RLVa:KB] - Checked: 2010-08-22 (RLVa-1.2.1a) | Modified: RLVa-1.2.1a // NOTE: RLVa event handlers should be invoked *after* LLVOAvatar::attachObject() calls LLViewerJointAttachment::addObject() + if (mAttachmentSignal) + { + (*mAttachmentSignal)(viewer_object, attachment, ACTION_ATTACH); + } if (rlv_handler_t::isEnabled()) { RlvAttachmentLockWatchdog::instance().onAttach(viewer_object, attachment); @@ -1213,16 +1228,24 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object) // [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0a) | Added: RLVa-1.2.0a // NOTE: RLVa event handlers should be invoked *before* LLVOAvatar::detachObject() calls LLViewerJointAttachment::removeObject() - if (rlv_handler_t::isEnabled()) + { for (attachment_map_t::const_iterator itAttachPt = mAttachmentPoints.begin(); itAttachPt != mAttachmentPoints.end(); ++itAttachPt) { const LLViewerJointAttachment* pAttachPt = itAttachPt->second; if (pAttachPt->isObjectAttached(viewer_object)) { - RlvAttachmentLockWatchdog::instance().onDetach(viewer_object, pAttachPt); - gRlvHandler.onDetach(viewer_object, pAttachPt); + if (rlv_handler_t::isEnabled()) + { + RlvAttachmentLockWatchdog::instance().onDetach(viewer_object, pAttachPt); + gRlvHandler.onDetach(viewer_object, pAttachPt); + } + if (mAttachmentSignal) + { + (*mAttachmentSignal)(viewer_object, pAttachPt, ACTION_DETACH); + } } + break; } } // [/RLVa:KB] @@ -3171,6 +3194,22 @@ void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile) apr_file_printf( file, "\n\n" ); } + +// [RLVa:KB] - Checked: 2013-03-03 (RLVa-1.4.8) +LLVector3 LLVOAvatarSelf::getAvatarOffset() /*const*/ +{ + if(isUsingServerBakes()) + return LLAvatarAppearance::getAvatarOffset(); + else + { + static LLCachedControl x_off("AscentAvatarXModifier"); + static LLCachedControl y_off("AscentAvatarYModifier"); + static LLCachedControl z_off("AscentAvatarZModifier"); + return LLVector3(x_off,y_off,z_off+RlvSettings::getAvatarOffsetZ()); + } +} +// [/RLVa:KB] + // static void LLVOAvatarSelf::onChangeSelfInvisible(bool invisible) { diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index c8c87c27b..b5a15ec9d 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -318,9 +318,17 @@ public: /*virtual*/ BOOL detachObject(LLViewerObject *viewer_object); static BOOL detachAttachmentIntoInventory(const LLUUID& item_id); +// [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7) + enum EAttachAction { ACTION_ATTACH, ACTION_DETACH }; + typedef boost::signals2::signal attachment_signal_t; + boost::signals2::connection setAttachmentCallback(const attachment_signal_t::slot_type& cb); +// [/RLVa:KB] private: // Track attachments that have been requested but have not arrived yet. mutable std::map mAttachmentRequests; +// [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7) + attachment_signal_t* mAttachmentSignal; +// [/RLVa:KB] //-------------------------------------------------------------------- // HUDs @@ -347,6 +355,11 @@ public: public: bool sendAppearanceMessage(LLMessageSystem *mesgsys) const; +// [RLVa:KB] - Checked: 2013-03-03 (RLVa-1.4.8) +protected: + /*virtual*/ LLVector3 getAvatarOffset() /*const*/; +// [/RLVa:KB] + /** Appearance ** ** *******************************************************************************/ diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index 2f01d4a84..e2f3403f9 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -29,6 +29,8 @@ #include "llvoavatar.h" #include "llworld.h" +#include "../lscript/lscript_byteformat.h" //Need LSCRIPTRunTimePermissionBits and SCRIPT_PERMISSION_* + #include "rlvcommon.h" #include "rlvhelper.h" #include "rlvhandler.h" @@ -296,6 +298,8 @@ const char* RlvStrings::getStringFromReturnCode(ERlvCmdRet eRet) return "unset"; case RLV_RET_SUCCESS_DUPLICATE: return "duplicate"; + case RLV_RET_SUCCESS_DELAYED: + return "delayed"; case RLV_RET_FAILED_SYNTAX: return "syntax error"; case RLV_RET_FAILED_OPTION: @@ -414,6 +418,28 @@ void RlvUtil::filterNames(std::string& strUTF8Text, bool fFilterLegacy) } } +// Checked: 2012-08-19 (RLVa-1.4.7) +void RlvUtil::filterScriptQuestions(S32& nQuestions, LLSD& sdPayload) +{ + // Check SCRIPT_PERMISSION_ATTACH + if ( (!gRlvAttachmentLocks.canAttach()) && (LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_ATTACH] & nQuestions) ) + { + // Notify the user that we blocked it since they're not allowed to wear any new attachments + sdPayload["rlv_blocked"] = RLV_STRING_BLOCKED_PERMATTACH; + nQuestions &= ~LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_ATTACH]; + } + + // Check SCRIPT_PERMISSION_TELEPORT + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)) && (LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TELEPORT] & nQuestions) ) + { + // Notify the user that we blocked it since they're not allowed to teleport + sdPayload["rlv_blocked"] = RLV_STRING_BLOCKED_PERMTELEPORT; + nQuestions &= ~LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_TELEPORT]; + } + + sdPayload["questions"] = nQuestions; +} + // Checked: 2010-08-29 (RLVa-1.2.1c) | Added: RLVa-1.2.1c void RlvUtil::forceTp(const LLVector3d& posDest) { @@ -582,14 +608,23 @@ bool RlvEnableIfNot::handleEvent(LLPointer, const LLSD& userdata) // Selection functors // -// Checked: 2010-04-11 (RLVa-1.2.0b) | Modified: RLVa-0.2.0g +// Checked: 2011-05-28 (RLVa-1.4.6) | Modified: RLVa-1.4.0 +bool rlvCanDeleteOrReturn(const LLViewerObject* pObj) +{ + // Block if: @rez=n restricted and owned by us or a group *or* @unsit=n restricted and being sat on by us + return + ( (!gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) || ((!pObj->permYouOwner()) && (!pObj->permGroupOwner())) ) && + ( (!gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (!isAgentAvatarValid()) || (!pObj->getRootEdit()->isChild(gAgentAvatarp)) ); +} + +// Checked: 2011-05-28 (RLVa-1.4.6) | Modified: RLVa-1.4.0 bool rlvCanDeleteOrReturn() { if ( (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) || (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) ) { struct RlvCanDeleteOrReturn : public LLSelectedObjectFunctor { - /*virtual*/ bool apply(LLViewerObject* pObj) { return pObj->isReturnable(); } + /*virtual*/ bool apply(LLViewerObject* pObj) { return rlvCanDeleteOrReturn(pObj); } } f; LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection(); return (hSel.notNull()) && (0 != hSel->getRootObjectCount()) && (hSel->applyToRootObjects(&f, false)); @@ -652,7 +687,7 @@ bool rlvPredCanNotWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWea } // Checked: 2010-03-22 (RLVa-1.2.0c) | Added: RLVa-1.2.0a -bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem) +bool rlvPredCanRemoveItem(const LLInventoryItem* pItem) { if ( (pItem) && (RlvForceWear::isWearableItem(pItem)) ) { @@ -673,7 +708,7 @@ bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem) } // Checked: 2010-03-22 (RLVa-1.2.0c) | Added: RLVa-1.2.0a -bool rlvPredCanNotRemoveItem(const LLViewerInventoryItem* pItem) +bool rlvPredCanNotRemoveItem(const LLInventoryItem* pItem) { return !rlvPredCanRemoveItem(pItem); } diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index 463b6f17d..3d34ab101 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -157,6 +157,7 @@ public: static void filterLocation(std::string& strUTF8Text); // @showloc static void filterNames(std::string& strUTF8Text, bool fFilterLegacy = true); // @shownames + static void filterScriptQuestions(S32& nQuestions, LLSD& sdPayload); static bool isForceTp() { return m_fForceTp; } static void forceTp(const LLVector3d& posDest); // Ignores restrictions that might otherwise prevent tp'ing @@ -210,6 +211,7 @@ class RlvEnableIfNot : public LLMemberListener // bool rlvCanDeleteOrReturn(); +bool rlvCanDeleteOrReturn(const LLViewerObject* pObj); struct RlvSelectHasLockedAttach : public LLSelectedNodeFunctor { @@ -238,8 +240,8 @@ protected: bool rlvPredCanWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWearMask); bool rlvPredCanNotWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWearMask); -bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem); -bool rlvPredCanNotRemoveItem(const LLViewerInventoryItem* pItem); +bool rlvPredCanRemoveItem(const LLInventoryItem* pItem); +bool rlvPredCanNotRemoveItem(const LLInventoryItem* pItem); struct RlvPredCanWearItem { diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 17118d4fa..b7857fd41 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -253,7 +253,8 @@ enum ERlvCmdRet { RLV_RET_SUCCESS = 0x0100, // Command executed succesfully RLV_RET_SUCCESS_UNSET, // Command executed succesfully (RLV_TYPE_REMOVE for an unrestricted behaviour) RLV_RET_SUCCESS_DUPLICATE, // Command executed succesfully (RLV_TYPE_ADD for an already restricted behaviour) - RLV_RET_FAILED = 0x0200, // Command failed (general failure) + RLV_RET_SUCCESS_DELAYED, // Command parsed valid but will execute at a later time + RLV_RET_FAILED = 0x0200, // Command failed (general failure) RLV_RET_FAILED_SYNTAX, // Command failed (syntax error) RLV_RET_FAILED_OPTION, // Command failed (invalid option) RLV_RET_FAILED_PARAM, // Command failed (invalid param) @@ -337,6 +338,7 @@ enum ERlvAttachGroupType #define RLV_STRING_BLOCKED_GENERIC "blocked_generic" #define RLV_STRING_BLOCKED_PERMATTACH "blocked_permattach" +#define RLV_STRING_BLOCKED_PERMTELEPORT "blocked_permteleport" #define RLV_STRING_BLOCKED_RECVIM "blocked_recvim" #define RLV_STRING_BLOCKED_RECVIM_REMOTE "blocked_recvim_remote" #define RLV_STRING_BLOCKED_SENDIM "blocked_sendim" diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 71ed40b0a..15518ad0d 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -422,6 +422,10 @@ bool RlvHandler::handleEvent(LLPointer event, const LLSD& gAgent.sendReliableMessage(); return true; } + else + { + m_idAgentGroup = gAgent.getGroupID(); + } return false; } @@ -881,7 +885,7 @@ bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const if ( (getCompositeInfo(idItem, &strComposite, &pFolder)) && (cstrItemType != strComposite) ) { LLUUID idCompositeItem; - if ((type = LLViewerWearable::typeNameToType(strComposite)) != WT_INVALID) + if ((type = LLWearable::typeNameToType(strComposite)) != WT_INVALID) { idCompositeItem = gAgent.getWearableItem(type); } @@ -1252,14 +1256,6 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd) RlvBehaviourNotifyHandler::getInstance()->removeNotify(rlvCmd.getObjectID(), nChannel, strFilter); } break; - case RLV_BHVR_SETGROUP: // @setgroup=n|y - Checked: 2011-05-22 (RLVa-1.4.1a) | Added: RLVa-1.3.1b - { - VERIFY_OPTION_REF(strOption.empty()); - - // Save the currently active group UUID since we'll need it when the user joins (or creates) a new group - m_idAgentGroup = gAgent.getGroupID(); - } - break; case RLV_BHVR_SHOWHOVERTEXT: // @showhovertext:=n|y - Checked: 2010-03-27 (RLVa-1.2.0b) | Modified: RLVa-1.1.0h { // There should be an option and it should specify a valid UUID @@ -1273,8 +1269,8 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd) // Clear/restore the object's hover text as needed LLViewerObject* pObj = gObjectList.findObject(idException); - if ( (pObj) && (pObj->mText.notNull()) && (!pObj->mText->getPreFilteredText().empty()) ) - pObj->mText->setString( (RLV_TYPE_ADD == eType) ? "" : pObj->mText->getPreFilteredText()); + if ( (pObj) && (pObj->mText.notNull()) && (!pObj->mText->getObjectText().empty()) ) + pObj->mText->setString( (RLV_TYPE_ADD == eType) ? "" : pObj->mText->getObjectText()); } break; // The following block is only valid if there's no option @@ -1312,6 +1308,7 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd) 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_FLY: // @fly=n|y - Checked: 2010-03-02 (RLVa-1.2.0a) + case RLV_BHVR_SETGROUP: // @setgroup=n|y - Checked: 2011-05-22 (RLVa-1.4.1a) | Added: RLVa-1.3.1b case RLV_BHVR_ALWAYSRUN: // @alwaysrun=n|y - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i case RLV_BHVR_TEMPRUN: // @temprun=n|y - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i case RLV_BHVR_UNSIT: // @unsit=n|y - Checked: 2009-12-05 (RLVa-1.1.0h) | Modified: RLVa-1.1.0h @@ -1641,15 +1638,9 @@ ERlvCmdRet RlvHandler::processForceCommand(const RlvCommand& rlvCmd) const case RLV_BHVR_ATTACHALLTHISOVER: case RLV_BHVR_DETACHALLTHIS: { - RlvCommandOptionGetPath rlvGetPathOption(rlvCmd); + RlvCommandOptionGetPath rlvGetPathOption(rlvCmd, boost::bind(&RlvHandler::onForceWearCallback, this, _1, rlvCmd.getBehaviourType())); VERIFY_OPTION(rlvGetPathOption.isValid()); - - LLInventoryModel::cat_array_t folders; - if (RlvInventory::instance().getPath(rlvGetPathOption.getItemIDs(), folders)) - { - for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) - onForceWear(folders.get(idxFolder), rlvCmd.getBehaviourType()); - } + eRet = (!rlvGetPathOption.isCallback()) ? RLV_RET_SUCCESS : RLV_RET_SUCCESS_DELAYED; } break; case RLV_BHVR_DETACHME: // @detachme=force - Checked: 2010-09-04 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c @@ -1727,10 +1718,15 @@ ERlvCmdRet RlvHandler::onForceRemOutfit(const RlvCommand& rlvCmd) const // Checked: 2011-07-23 (RLVa-1.4.1a) | Modified: RLVa-1.4.1a ERlvCmdRet RlvHandler::onForceGroup(const RlvCommand& rlvCmd) const { + if (hasBehaviourExcept(RLV_BHVR_SETGROUP, rlvCmd.getObjectID())) + { + return RLV_RET_FAILED_LOCK; + } + LLUUID idGroup; bool fValid = false; if (idGroup.set(rlvCmd.getOption())) { - fValid = (idGroup.isNull()) || (gAgent.isInGroup(idGroup)); + fValid = (idGroup.isNull()) || (gAgent.isInGroup(idGroup, true)); } else { @@ -1742,16 +1738,15 @@ ERlvCmdRet RlvHandler::onForceGroup(const RlvCommand& rlvCmd) const if (fValid) { - if (!gRlvHandler.hasBehaviour(RLV_BHVR_SETGROUP)) - { - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ActivateGroup); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_GroupID, idGroup); - gAgent.sendReliableMessage(); - } + m_idAgentGroup = idGroup; + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ActivateGroup); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_GroupID, idGroup); + gAgent.sendReliableMessage(); } return (fValid) ? RLV_RET_SUCCESS : RLV_RET_FAILED_OPTION; @@ -1818,6 +1813,20 @@ ERlvCmdRet RlvHandler::onForceWear(const LLViewerInventoryCategory* pFolder, ERl return RLV_RET_SUCCESS; } +void RlvHandler::onForceWearCallback(const uuid_vec_t& idItems, ERlvBehaviour eBhvr) const +{ + LLInventoryModel::cat_array_t folders; + if (RlvInventory::instance().getPath(idItems, folders)) + { + for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) + onForceWear(folders.get(idxFolder), eBhvr); + + // If we're not executing a command then we're a delayed callback and need to manually call done() + if ( (!getCurrentCommand()) && (RlvForceWear::instanceExists()) ) + RlvForceWear::instance().done(); + } +} + // ============================================================================ // Command handlers (RLV_TYPE_REPLY) // diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h index 685bf68ec..815c57d4a 100644 --- a/indra/newview/rlvhandler.h +++ b/indra/newview/rlvhandler.h @@ -84,6 +84,7 @@ public: */ public: // Accessors + const LLUUID& getAgentGroup() const { return m_idAgentGroup; } // @setgroup bool getCanCancelTp() const { return m_fCanCancelTp; } // @accepttp and @tpto void setCanCancelTp(bool fAllow) { m_fCanCancelTp = fAllow; } // @accepttp and @tpto const LLVector3d& getSitSource() const { return m_posSitSource; } // @standtp @@ -169,6 +170,7 @@ protected: ERlvCmdRet onForceGroup(const RlvCommand& rlvCmd) const; ERlvCmdRet onForceSit(const RlvCommand& rlvCmd) const; ERlvCmdRet onForceWear(const LLViewerInventoryCategory* pFolder, ERlvBehaviour eBhvr) const; + void onForceWearCallback(const uuid_vec_t& idItems, ERlvBehaviour eBhvr) const; // Command handlers (RLV_TYPE_REPLY) ERlvCmdRet processReplyCommand(const RlvCommand& rlvCmd) const; ERlvCmdRet onFindFolder(const RlvCommand& rlvCmd, std::string& strReply) const; @@ -208,7 +210,7 @@ protected: bool m_fCanCancelTp; // @accepttp=n and @tpto=force mutable LLVector3d m_posSitSource; // @standtp=n (mutable because onForceXXX handles are all declared as const) - LLUUID m_idAgentGroup; // @setgroup=n + mutable LLUUID m_idAgentGroup; // @setgroup=n friend class RlvSharedRootFetcher; // Fetcher needs access to m_fFetchComplete friend class RlvGCTimer; // Timer clear its own point at destruction diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 936dd41db..08b1db1dc 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -210,13 +210,56 @@ RlvCommandOptionGeneric::RlvCommandOptionGeneric(const std::string& strOption) m_fValid = true; } +// Checked: 2012-07-28 (RLVa-1.4.7) +class RlvCommandOptionGetPathCallback +{ +public: + RlvCommandOptionGetPathCallback(const LLUUID& idAttachObj, RlvCommandOptionGetPath::getpath_callback_t cb) + : mObjectId(idAttachObj), mCallback(cb) + { + if (isAgentAvatarValid()) + mAttachmentConnection = gAgentAvatarp->setAttachmentCallback(boost::bind(&RlvCommandOptionGetPathCallback::onAttachment, this, _1, _3)); + gIdleCallbacks.addFunction(&onIdle, this); + } + + ~RlvCommandOptionGetPathCallback() + { + if (mAttachmentConnection.connected()) + mAttachmentConnection.disconnect(); + gIdleCallbacks.deleteFunction(&onIdle, this); + } + + void onAttachment(LLViewerObject* pAttachObj, LLVOAvatarSelf::EAttachAction eAction) + { + if ( (LLVOAvatarSelf::ACTION_ATTACH == eAction) && (pAttachObj->getID() == mObjectId) ) + { + uuid_vec_t idItems(1, pAttachObj->getAttachmentItemID()); + mCallback(idItems); + delete this; + } + } + + static void onIdle(void* pData) + { + RlvCommandOptionGetPathCallback* pInstance = reinterpret_cast(pData); + if (pInstance->mExpirationTimer.getElapsedTimeF32() > 30.0f) + delete pInstance; + } + +protected: + LLUUID mObjectId; + RlvCommandOptionGetPath::getpath_callback_t mCallback; + boost::signals2::connection mAttachmentConnection; + LLFrameTimer mExpirationTimer; +}; + // Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.3.0b -RlvCommandOptionGetPath::RlvCommandOptionGetPath(const RlvCommand& rlvCmd) +RlvCommandOptionGetPath::RlvCommandOptionGetPath(const RlvCommand& rlvCmd, getpath_callback_t cb) + : m_fCallback(false) { m_fValid = true; // Assume the option will be a valid one until we find out otherwise // @getpath[: