From a3801612833072d8a6726cfd41a5ed2d08032586 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Fri, 26 Jun 2015 20:59:31 -0500 Subject: [PATCH] Merge in select parts of https://bitbucket.org/Kitty_Barnett/rlva-development @ 1adfc2cd210c4cf3a8800b31915d363bfe47d045 --- indra/newview/llagentwearables.cpp | 27 +- indra/newview/llagentwearables.h | 11 - indra/newview/llappearancemgr.cpp | 444 ++++++++++++------ indra/newview/llappearancemgr.h | 44 +- indra/newview/llattachmentsmgr.cpp | 6 +- indra/newview/llinventoryactions.cpp | 12 +- indra/newview/llinventorybridge.cpp | 29 +- indra/newview/llinventorymodel.cpp | 18 +- indra/newview/llinventorymodel.h | 9 +- indra/newview/lltooldraganddrop.cpp | 2 +- indra/newview/llviewerinventory.cpp | 142 +++++- indra/newview/llvoavatar.cpp | 62 +-- indra/newview/llvoavatar.h | 1 - indra/newview/llvoavatarself.cpp | 21 +- indra/newview/llvoavatarself.h | 2 +- indra/newview/llwearablelist.cpp | 18 +- indra/newview/rlvcommon.cpp | 30 +- indra/newview/rlvcommon.h | 2 + indra/newview/rlvdefines.h | 2 +- indra/newview/rlvfloaters.cpp | 8 +- indra/newview/rlvhandler.cpp | 2 +- indra/newview/rlvhelper.cpp | 110 +++-- indra/newview/rlvhelper.h | 12 + indra/newview/rlvinventory.cpp | 11 +- indra/newview/rlvlocks.cpp | 9 +- indra/newview/rlvlocks.h | 4 +- .../skins/default/xui/en-us/strings.xml | 10 +- 27 files changed, 714 insertions(+), 334 deletions(-) diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index a8f21ed2f..5e4cd8f3a 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -57,8 +57,7 @@ // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) #include "rlvhandler.h" -#include "rlvinventory.h" -#include "llattachmentsmgr.h" +#include "rlvlocks.h" // [/RLVa:KB] #include "hippogridmanager.h" @@ -242,18 +241,6 @@ void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar) } } -// wearables -LLAgentWearables::createStandardWearablesAllDoneCallback::~createStandardWearablesAllDoneCallback() -{ - LL_INFOS() << "destructor - all done?" << LL_ENDL; - gAgentWearables.createStandardWearablesAllDone(); -} - -LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCallback() -{ - gAgentWearables.sendAgentWearablesUpdate(); -} - /** * @brief Construct a callback for dealing with the wearables. * @@ -1892,15 +1879,9 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra 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 - for (S32 idxItem = obj_item_array.size() - 1; idxItem >= 0; idxItem--) - { - const LLInventoryItem* pItem = obj_item_array.at(idxItem).get(); - if (!gRlvAttachmentLocks.canAttach(pItem)) - { - obj_item_array.erase( obj_item_array.begin() + idxItem ); - RLV_ASSERT(false); - } - } + LLInventoryModel::item_array_t::size_type cntAttach = obj_item_array.size(); + obj_item_array.erase(std::remove_if(obj_item_array.begin(), obj_item_array.end(), RlvPredCanNotWearItem(RLV_WEAR)), obj_item_array.end()); + RLV_ASSERT(cntAttach == obj_item_array.size()); } // [/RLVa:KB] diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 4475da01e..09284bda2 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -264,17 +264,6 @@ private: // Support classes //-------------------------------------------------------------------------------- private: - class createStandardWearablesAllDoneCallback : public LLRefCount - { - protected: - ~createStandardWearablesAllDoneCallback(); - }; - class sendAgentWearablesUpdateCallback : public LLRefCount - { - protected: - ~sendAgentWearablesUpdateCallback(); - }; - class AddWearableToAgentInventoryCallback : public LLInventoryCallback { public: diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 0b804a4da..413dd812d 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -700,10 +700,11 @@ void LLWearableHoldingPattern::eraseTypeToRecover(LLWearableType::EType type) mTypesToRecover.erase(type); } -void LLWearableHoldingPattern::setObjItems(const LLInventoryModel::item_array_t& items) -{ - mObjItems = items; -} +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-06-19 (Catznip-2.1) +//void LLWearableHoldingPattern::setObjItems(const LLInventoryModel::item_array_t& items) +//{ +// mObjItems = items; +//} void LLWearableHoldingPattern::setGestItems(const LLInventoryModel::item_array_t& items) { @@ -810,46 +811,46 @@ void LLWearableHoldingPattern::onAllComplete() if (isAgentAvatarValid()) { - LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.size() << " attachments" << LL_ENDL; - LLAgentWearables::llvo_vec_t objects_to_remove; - LLAgentWearables::llvo_vec_t objects_to_retain; - LLInventoryModel::item_array_t items_to_add; - - LLAgentWearables::findAttachmentsAddRemoveInfo(mObjItems, - objects_to_remove, - objects_to_retain, - items_to_add); - - LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size() - << " attachments" << LL_ENDL; - - // Here we remove the attachment pos overrides for *all* - // attachments, even those that are not being removed. This is - // needed to get joint positions all slammed down to their - // pre-attachment states. - //gAgentAvatarp->clearAttachmentPosOverrides(); - - // Take off the attachments that will no longer be in the outfit. - LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove); +// LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.size() << " attachments" << LL_ENDL; +// LLAgentWearables::llvo_vec_t objects_to_remove; +// LLAgentWearables::llvo_vec_t objects_to_retain; +// LLInventoryModel::item_array_t items_to_add; +// +// LLAgentWearables::findAttachmentsAddRemoveInfo(mObjItems, +// objects_to_remove, +// objects_to_retain, +// items_to_add); +// +// LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size() +// << " attachments" << LL_ENDL; +// +// // Here we remove the attachment pos overrides for *all* +// // attachments, even those that are not being removed. This is +// // needed to get joint positions all slammed down to their +// // pre-attachment states. +// gAgentAvatarp->clearAttachmentPosOverrides(); +// +// // Take off the attachments that will no longer be in the outfit. +// LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove); // Update wearables. LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " updating agent wearables with " << mResolved << " wearable items " << LL_ENDL; LLAppearanceMgr::instance().updateAgentWearables(this); - // Restore attachment pos overrides for the attachments that - // are remaining in the outfit. - for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin(); - it != objects_to_retain.end(); - ++it) - { - //LLViewerObject *objectp = *it; - //gAgentAvatarp->addAttachmentPosOverridesForObject(objectp); - } +// // Restore attachment pos overrides for the attachments that +// // are remaining in the outfit. +// for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin(); +// it != objects_to_retain.end(); +// ++it) +// { +// LLViewerObject *objectp = *it; +// gAgentAvatarp->addAttachmentPosOverridesForObject(objectp); +// } - // Add new attachments to match those requested. - LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL; - LLAgentWearables::userAttachMultipleAttachments(items_to_add); +// // Add new attachments to match those requested. +// LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL; +// LLAgentWearables::userAttachMultipleAttachments(items_to_add); } if (isFetchCompleted() && isMissingCompleted()) @@ -1484,7 +1485,10 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear, { LLUUID item_id = gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1); - removeCOFItemLinks(item_id, cb); +// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-05-02 (Catznip-3.7) + removeCOFItemLinks(item_id, NULL, true); +// [/SL:KB] +// removeCOFItemLinks(item_id, cb); } items_to_link.push_back(item_to_wear); @@ -1991,35 +1995,6 @@ 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::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()) - { - remove_inventory_object(pItem->getUUID(), NULL); - } - } -} - -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()) ) - { - remove_inventory_object(pItem->getUUID(), NULL); - } - } -} -// [/SL:KB] - // Keep the last N wearables of each type. For viewer 2.0, N is 1 for // both body parts and clothing items. void LLAppearanceMgr::filterWearableItems( @@ -2051,7 +2026,7 @@ void LLAppearanceMgr::filterWearableItems( continue; // S32 start_index = llmax(0,size-max_per_type); // [SL:KB] - Patch: Appearance-Misc | Checked: 2010-05-11 (Catznip-2.0) - S32 start_index = llmax(0, size - ((LLAssetType::AT_BODYPART == LLWearableType::getAssetType((LLWearableType::EType)i)) ? 1 : max_per_type)); + S32 start_index = llmax(0, size - ((LLWearableType::getAllowMultiwear((LLWearableType::EType)i)) ? max_per_type : 1)); // [/SL:KB[ for (S32 j = start_index; jgetName() : "[UNKNOWN]") << "'" << LL_ENDL; + LLInventoryModel::item_array_t body_items_new, wear_items_new, obj_items_new, gest_items_new; + getDescendentsOfAssetType(category, body_items_new, LLAssetType::AT_BODYPART); + getDescendentsOfAssetType(category, wear_items_new, LLAssetType::AT_CLOTHING); + getDescendentsOfAssetType(category, obj_items_new, LLAssetType::AT_OBJECT); + getDescendentsOfAssetType(category, gest_items_new, LLAssetType::AT_GESTURE); updateCOF(body_items_new, wear_items_new, obj_items_new, gest_items_new, append, category); } @@ -2078,14 +2060,18 @@ 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*/, LLPointer link_waiter /*= NULL*/) // [/RLVa:KB] { // LLViewerInventoryCategory *pcat = gInventory.getCategory(category); +// if (!pcat) +// { +// LL_WARNS() << "no category found for id " << category << LL_ENDL; +// return; +// } // LL_INFOS("Avatar") << self_av_string() << "starting, cat '" << (pcat ? pcat->getName() : "[UNKNOWN]") << "'" << LL_ENDL; -// [RLVa:KB] - Checked: 2010-03-26 (RLVa-1.2.0b) | Added: RLVa-1.2.0b - // RELEASE-RLVa: [SL-2.0.0] If pcat ever gets used for anything further down the beta we'll know about it - LL_INFOS() << "starting" << LL_ENDL; +// [RLVa:KB] - Checked: 2010-03-26 (RLVa-1.2.0) + LL_INFOS("Avatar") << "starting" << LL_ENDL; // [/RLVa:KB] const LLUUID cof = getCOF(); @@ -2113,7 +2099,7 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t body_items; getDescendentsOfAssetType(cof, body_items, LLAssetType::AT_BODYPART); // getDescendentsOfAssetType(category, body_items, LLAssetType::AT_BODYPART); -// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0c) | Modified: RLVa-1.2.0b +// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0) // Filter out any new body parts that can't be worn before adding them if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) ) body_items_new.erase(std::remove_if(body_items_new.begin(), body_items_new.end(), RlvPredCanNotWearItem(RLV_WEAR_REPLACE)), body_items_new.end()); @@ -2130,16 +2116,16 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t wear_items; if (append) getDescendentsOfAssetType(cof, wear_items, LLAssetType::AT_CLOTHING); -// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0c) | Modified: RLVa-1.2.0b +// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0) else if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) ) { // Make sure that all currently locked clothing layers remain in COF when replacing getDescendentsOfAssetType(cof, wear_items, LLAssetType::AT_CLOTHING); - wear_items.erase(std::remove_if(wear_items.begin(), wear_items.end(), rlvPredCanRemoveItem), wear_items.end()); + wear_items.erase(std::remove_if(wear_items.begin(), wear_items.end(), RlvPredCanRemoveItem()), wear_items.end()); } // [/RLVa:KB] // getDescendentsOfAssetType(category, wear_items, LLAssetType::AT_CLOTHING); -// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0c) | Modified: RLVa-1.2.0b +// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0) // Filter out any new wearables that can't be worn before adding them if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY)) ) wear_items_new.erase(std::remove_if(wear_items_new.begin(), wear_items_new.end(), RlvPredCanNotWearItem(RLV_WEAR)), wear_items_new.end()); @@ -2152,7 +2138,9 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, // [/SL:KB] filterWearableItems(wear_items, 0, LLAgentWearables::MAX_CLOTHING_LAYERS); + // // - Attachments: include COF contents only if appending. + // LLInventoryModel::item_array_t obj_items; if (append) getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT); @@ -2161,11 +2149,11 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, { // Make sure that all currently locked attachments remain in COF when replacing getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT); - obj_items.erase(std::remove_if(obj_items.begin(), obj_items.end(), rlvPredCanRemoveItem), obj_items.end()); + obj_items.erase(std::remove_if(obj_items.begin(), obj_items.end(), RlvPredCanRemoveItem()), obj_items.end()); } // [/RLVa:KB] // getDescendentsOfAssetType(category, obj_items, LLAssetType::AT_OBJECT); -// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0z) | Modified: RLVa-1.2.0b +// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0) // Filter out any new attachments that can't be worn before adding them if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) obj_items_new.erase(std::remove_if(obj_items_new.begin(), obj_items_new.end(), RlvPredCanNotWearItem(RLV_WEAR)), obj_items_new.end()); @@ -2180,7 +2168,7 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, if (append) getDescendentsOfAssetType(cof, gest_items, LLAssetType::AT_GESTURE); // getDescendentsOfAssetType(category, gest_items, LLAssetType::AT_GESTURE); -// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0z) | Added: RLVa-1.2.0b +// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0) gest_items.insert(gest_items.end(), gest_items_new.begin(), gest_items_new.end()); // [/RLVa:KB] removeDuplicateItems(gest_items); @@ -2198,7 +2186,11 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, // Will link all the above items. // link_waiter enforce flags are false because we've already fixed everything up in updateCOF(). - LLPointer link_waiter = new LLUpdateAppearanceOnDestroy(false,false); +// LLPointer link_waiter = new LLUpdateAppearanceOnDestroy(false,false); +// [RLVa:KB] Checked: 2015-05-05 (RLVa-1.4.12) + if (!link_waiter) + link_waiter = new LLUpdateAppearanceOnDestroy(false, false); +// [/RLVa:KB] LLSD contents = LLSD::emptyArray(); for (LLInventoryModel::item_array_t::const_iterator it = all_items.begin(); @@ -2226,8 +2218,12 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, item_contents["type"] = LLAssetType::AT_LINK; contents.append(item_contents); } - const LLUUID& base_id = append ? getBaseOutfitUUID() : category; - LLViewerInventoryCategory *base_cat = gInventory.getCategory(base_id); +// const LLUUID& base_id = append ? getBaseOutfitUUID() : category; +// LLViewerInventoryCategory *base_cat = gInventory.getCategory(base_id); +// [RLVa:KB] - Checked: 2014-11-02 (RLVa-1.4.11) + const LLUUID& base_id = (append) ? getBaseOutfitUUID() : idOutfit; + LLViewerInventoryCategory* base_cat = (base_id.notNull()) ? gInventory.getCategory(base_id) : NULL; +// [/RLVa:KB] if (base_cat) { LLSD base_contents; @@ -2278,7 +2274,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder) LLInventoryItem::item_array_t items; std::vector< LLViewerWearable* > wearables; wearables.reserve(32); -// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f +// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0) uuid_vec_t idsCurrent; LLInventoryModel::item_array_t itemsNew; if (rlv_handler_t::isEnabled()) { @@ -2300,7 +2296,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder) LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID); if( item && (item->getAssetUUID() == wearable->getAssetID()) ) { -// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g +// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0) // TODO-RLVa: [RLVa-1.2.1] This is fall-back code so if we don't ever trigger this code it can just be removed // -> one way to trigger the assertion: // 1) "Replace Outfit" on a folder with clothing and an attachment that goes @addoutfit=n @@ -2321,7 +2317,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder) // [/RLVa:KB] items.push_back(item); wearables.push_back(wearable); -// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f +// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0) if ( (rlv_handler_t::isEnabled()) && (gAgentWearables.areInitalWearablesLoaded()) ) { // Remove the wearable from current item UUIDs if currently worn and requested, otherwise mark it as a new item @@ -2337,7 +2333,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder) } } -// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f +// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0) if ( (rlv_handler_t::isEnabled()) && (gAgentWearables.areInitalWearablesLoaded()) ) { // We need to report removals before additions or scripts will get confused @@ -2491,14 +2487,18 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, { //checking integrity of the COF in terms of ordering of wearables, //checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state) +// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-03-01 (Catznip-3.7) + // Ordering information is pre-applied locally so no reason to reason to wait on the inventory backend + updateClothingOrderingInfo(LLUUID::null); +// [/SL:KB] - // As with enforce_item_restrictions handling above, we want - // to wait for the update callbacks, then (finally!) call - // updateAppearanceFromCOF() with no additional COF munging needed. - LLPointer cb( - new LLUpdateAppearanceOnDestroy(false, false, post_update_func)); - updateClothingOrderingInfo(LLUUID::null, cb); - return; +// // As with enforce_item_restrictions handling above, we want +// // to wait for the update callbacks, then (finally!) call +// // updateAppearanceFromCOF() with no additional COF munging needed. +// LLPointer cb( +// new LLUpdateAppearanceOnDestroy(false, false, post_update_func)); +// updateClothingOrderingInfo(LLUUID::null, cb); +// return; } if (!validateClothingOrderingInfo()) @@ -2536,7 +2536,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, removeDuplicateItems(wear_items); removeDuplicateItems(obj_items); removeDuplicateItems(gest_items); - filterWearableItems(wear_items, 0, LLAgentWearables::MAX_CLOTHING_LAYERS); + filterWearableItems(wear_items, LLAgentWearables::MAX_CLOTHING_LAYERS, LLAgentWearables::MAX_CLOTHING_LAYERS); // [/SL:KB] // [SL:KB] - Patch: Appearance-WearableDuplicateAssets | Checked: 2011-07-24 (Catznip-2.6.0e) | Added: Catznip-2.6.0e // Wearing two wearables that share the same asset causes some issues @@ -2553,6 +2553,65 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, << " descendent_count " << cof->getDescendentCount() << " viewer desc count " << cof->getViewerDescendentCount() << LL_ENDL; } +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2) + // Update attachments to match those requested. + if (isAgentAvatarValid()) + { + // Include attachments which should be in COF but don't have their link created yet + uuid_vec_t::iterator itPendingAttachLink = mPendingAttachLinks.begin(); + while (itPendingAttachLink != mPendingAttachLinks.end()) + { + const LLUUID& idItem = *itPendingAttachLink; + if ( (!gAgentAvatarp->isWearingAttachment(idItem)) || (isLinkInCOF(idItem)) ) + { + itPendingAttachLink = mPendingAttachLinks.erase(itPendingAttachLink); + continue; + } + + LLViewerInventoryItem* pItem = gInventory.getItem(idItem); + if (pItem) + { + obj_items.push_back(pItem); + } + + ++itPendingAttachLink; + } + + LL_DEBUGS("Avatar") << self_av_string() << "Updating " << obj_items.size() << " attachments" << LL_ENDL; + + LLAgentWearables::llvo_vec_t objects_to_remove; + LLAgentWearables::llvo_vec_t objects_to_retain; + LLInventoryModel::item_array_t items_to_add; + LLAgentWearables::findAttachmentsAddRemoveInfo(obj_items, objects_to_remove, objects_to_retain, items_to_add); + + // Here we remove the attachment pos overrides for *all* + // attachments, even those that are not being removed. This is + // needed to get joint positions all slammed down to their + // pre-attachment states. + //gAgentAvatarp->clearAttachmentPosOverrides(); + + // Take off the attachments that will no longer be in the outfit. + // (but don't remove attachments until avatar is fully loaded - should reduce random attaching/detaching/reattaching at log-on) + if (gAgentAvatarp->isFullyLoaded()) + { + LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size() << " attachments" << LL_ENDL; + LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove); + } + + // Restore attachment pos overrides for the attachments that + // are remaining in the outfit. + /*for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin(); it != objects_to_retain.end(); ++it) + { + LLViewerObject *objectp = *it; + gAgentAvatarp->addAttachmentPosOverridesForObject(objectp); + }*/ + + // Add new attachments to match those requested. + LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL; + LLAgentWearables::userAttachMultipleAttachments(items_to_add); + } +// [/SL:KB] + if(!wear_items.size()) { LLNotificationsUtil::add("CouldNotPutOnOutfit"); @@ -2567,7 +2626,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, LLTimer hp_block_timer; LLWearableHoldingPattern* holder = new LLWearableHoldingPattern; - holder->setObjItems(obj_items); +// holder->setObjItems(obj_items); holder->setGestItems(gest_items); // Note: can't do normal iteration, because if all the @@ -2584,7 +2643,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, // fetch failures (should be replaced by new defaults in // lost&found). U32 skip_type = gSavedSettings.getU32("ForceAssetFail"); -// [RLVa:KB] - Checked: 2010-12-11 (RLVa-1.2.2c) | Added: RLVa-1.2.2c +// [RLVa:KB] - Checked: 2010-12-11 (RLVa-1.2.2) U32 missing_type = gSavedSettings.getU32("ForceMissingType"); // [/RLVa:KB] @@ -2597,7 +2656,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID ); -// [RLVa:KB] - Checked: 2010-12-15 (RLVa-1.2.2c) | Modified: RLVa-1.2.2c +// [RLVa:KB] - Checked: 2010-12-15 (RLVa-1.2.2) #ifdef LL_RELEASE_FOR_DOWNLOAD // Don't allow forcing an invalid wearable if the initial wearables aren't set yet, or if any wearable type is currently locked if ( (!rlv_handler_t::isEnabled()) || @@ -2609,11 +2668,11 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, continue; } // [/RLVa:KB] - if (skip_type != LLWearableType::WT_INVALID && skip_type == found.mWearableType) - { - found.mAssetID.generate(); // Replace with new UUID, guaranteed not to exist in DB - } -// [RLVa:KB] - Checked: 2010-12-15 (RLVa-1.2.2c) | Modified: RLVa-1.2.2c + if (skip_type != LLWearableType::WT_INVALID && skip_type == found.mWearableType) + { + found.mAssetID.generate(); // Replace with new UUID, guaranteed not to exist in DB + } +// [RLVa:KB] - Checked: 2010-12-15 (RLVa-1.2.2) } // [/RLVa:KB] //pushing back, not front, to preserve order of wearables for LLAgentWearables @@ -2981,13 +3040,6 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, { linked_already = true; } -// [SL:KB] - Patch: Appearance-WearableDuplicateAssets | Checked: 2011-07-24 (Catznip-2.6.0e) | Added: Catznip-2.6.0e - else if (inv_item->getAssetUUID() == vitem->getAssetUUID()) - { - // Only allow one wearable per unique asset - linked_already = true; - } -// [/SL:KB] // Are these links to different items of the same body part // type? If so, new item will replace old. else if ((vitem->isWearableType()) && (vitem->getWearableType() == wearable_type)) @@ -2997,6 +3049,13 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, // MULTI-WEARABLES: make sure we don't go over clothing limits remove_id = inv_item->getUUID(); } +// [SL:KB] - Patch: Appearance-WearableDuplicateAssets | Checked: 2011-07-24 (Catznip-2.6.0e) | Added: Catznip-2.6.0e + else if (inv_item->getAssetUUID() == vitem->getAssetUUID()) + { + // Only allow one wearable per unique asset + linked_already = true; + } +// [/SL:KB] } } @@ -3100,7 +3159,10 @@ void LLAppearanceMgr::removeAllAttachmentsFromAvatar() removeItemsFromAvatar(ids_to_remove); } -void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer cb) +//void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer cb) +// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-05-02 (Catznip-3.7) +void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer cb, bool immediate_delete) +// [/SL:KB] { gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); @@ -3112,14 +3174,20 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointergetIsLinkType() && item->getLinkedUUID() == item_id) { - bool immediate_delete = false; - if (item->getType() == LLAssetType::AT_OBJECT) +// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) + if (rlv_handler_t::isEnabled()) { - immediate_delete = true; + RLV_ASSERT(rlvPredCanRemoveItem(item)); } +// [/RLVa:KB] +// bool immediate_delete = false; +// if (item->getType() == LLAssetType::AT_OBJECT) +// { +// immediate_delete = true; +// } remove_inventory_item(item->getUUID(), cb, immediate_delete); } } @@ -3138,6 +3206,12 @@ void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, LLPointer const LLViewerInventoryItem* item = *it; if (item->getIsLinkType()) // we must operate on links only { +// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) + if (rlv_handler_t::isEnabled()) + { + RLV_ASSERT(rlvPredCanRemoveItem(item)); + } +// [/RLVa:KB] remove_inventory_item(item->getUUID(), cb); } } @@ -4393,41 +4467,82 @@ void LLAppearanceMgr::wearBaseOutfit() updateCOF(base_outfit_id); } -void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) +//void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) +// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7) +void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, LLPointer cb /*= NULL*/, bool immediate_delete /*= false*/) +// [/SL:KB] { if (ids_to_remove.empty()) { LL_WARNS() << "called with empty list, nothing to do" << LL_ENDL; return; } - LLPointer cb = new LLUpdateAppearanceOnDestroy; +// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) +// LLPointer cb = NULL; 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); -// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) - if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(gInventory.getItem(linked_item_id))) ) + + if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(linked_item_id)) ) { continue; } -// [/RLVa:KB] - removeCOFItemLinks(linked_item_id, cb); + + if (!cb) + cb = new LLUpdateAppearanceOnDestroy(); + removeCOFItemLinks(linked_item_id, cb, immediate_delete); +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2015-03-01 (Catznip-3.7) + clearPendingAttachment(linked_item_id); +// [/SL:KB] addDoomedTempAttachment(linked_item_id); } -// updateAppearanceFromCOF(); +// [/RLVa:KB] +//// LLPointer cb = new LLUpdateAppearanceOnDestroy; +//// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7) +// if (!cb) +// { +// cb = new LLUpdateAppearanceOnDestroy; +// } +//// [/SL: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); +//// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7) +// removeCOFItemLinks(linked_item_id, cb, immediate_delete); +//// [/SL:KB] +//// removeCOFItemLinks(linked_item_id, cb); +// addDoomedTempAttachment(linked_item_id); +// } } -void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove) +//void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove) +// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7) +void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove, LLPointer cb /*= NULL*/, bool immediate_delete /*= false*/) +// [/SL:KB] { LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove); + // [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) - if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(gInventory.getItem(linked_item_id))) ) + if ( (rlv_handler_t::isEnabled()) && (!rlvPredCanRemoveItem(linked_item_id)) ) { return; } // [/RLVA:KB] - LLPointer cb = new LLUpdateAppearanceOnDestroy; - removeCOFItemLinks(linked_item_id, cb); + +// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7) + if (!cb) + { + cb = new LLUpdateAppearanceOnDestroy; + } + removeCOFItemLinks(linked_item_id, cb, immediate_delete); +// [/SL:KB] +// LLPointer cb = new LLUpdateAppearanceOnDestroy; +// removeCOFItemLinks(linked_item_id, cb); +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2015-03-01 (Catznip-3.7) + clearPendingAttachment(linked_item_id); +// [/SL:KB] addDoomedTempAttachment(linked_item_id); } @@ -4590,8 +4705,14 @@ LLAppearanceMgr::~LLAppearanceMgr() void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val) { - LL_DEBUGS("Avatar") << "setAttachmentInvLinkEnable => " << (int)val << LL_ENDL; + LL_DEBUGS("Avatar") << "setAttachmentInvLinkEnable => " << (int) val << LL_ENDL; mAttachmentInvLinkEnabled = val; +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-10-05 (Catznip-2.2) + if (mAttachmentInvLinkEnabled) + { + linkPendingAttachments(); + } +// [/SL:KB] } void dumpAttachmentSet(const std::set& atts, const std::string& msg) @@ -4614,6 +4735,13 @@ void dumpAttachmentSet(const std::set& atts, const std::string& msg) void LLAppearanceMgr::registerAttachment(const LLUUID& item_id) { gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-10-05 (Catznip-2.2) + if (isLinkInCOF(item_id)) + { + return; + } + mPendingAttachLinks.push_back(item_id); +// [/SL:KB] if (mAttachmentInvLinkEnabled) { @@ -4622,8 +4750,12 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id) // But it is not acceptable solution. See EXT-7777 if (!isLinkedInCOF(item_id)) { - LLPointer cb = new LLUpdateAppearanceOnDestroy(); - LLAppearanceMgr::addCOFItemLink(item_id, cb); // Add COF link for item. +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-10-05 (Catznip-2.2) + LLPointer cb = new LLRegisterAttachmentCallback(item_id); + LLAppearanceMgr::addCOFItemLink(item_id, cb); // Add COF link for item. +// [/SL:KB] +// LLPointer cb = new LLUpdateAppearanceOnDestroy(); +// LLAppearanceMgr::addCOFItemLink(item_id, cb); // Add COF link for item. } } else @@ -4635,6 +4767,9 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id) void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id) { gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-10-05 (Catznip-2.2) + clearPendingAttachment(item_id); +// [/SL:KB] if (mAttachmentInvLinkEnabled) { @@ -4646,6 +4781,47 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id) } } +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-18 (Catznip-2.2) +void LLAppearanceMgr::linkPendingAttachments() +{ + LLPointer cb = NULL; + for (uuid_vec_t::const_iterator itPendingAttachLink = mPendingAttachLinks.begin(); itPendingAttachLink != mPendingAttachLinks.end(); ++itPendingAttachLink) + { + const LLUUID& idAttachItem = *itPendingAttachLink; + if ( (gAgentAvatarp->isWearingAttachment(idAttachItem)) && (!isLinkInCOF(idAttachItem)) ) + { +// if (!cb) +// cb = new LLRegisterAttachmentCallback(idAttachItem); + // One LLInventoryCallback instance should handle multiple items but thanks to AIS we don't currently have access to the UUIDs of the new links + // so we need one instance per needed link - yay for progress + cb = new LLRegisterAttachmentCallback(idAttachItem); + LLAppearanceMgr::addCOFItemLink(idAttachItem, cb); + } + } +} + +void LLAppearanceMgr::clearPendingAttachment(const LLUUID& idItem) +{ + uuid_vec_t::iterator itPendingAttachLink = std::find(mPendingAttachLinks.begin(), mPendingAttachLinks.end(), idItem); + if (itPendingAttachLink != mPendingAttachLinks.end()) + { + mPendingAttachLinks.erase(itPendingAttachLink); + } +} + +void LLAppearanceMgr::onRegisterAttachmentComplete(const LLUUID& idAttachItem) +{ + // Remove the attachment from the pending list + clearPendingAttachment(idAttachItem); + + // It may have been detached already in which case we should remove the COF link + if ( (isAgentAvatarValid()) && (!gAgentAvatarp->isWearingAttachment(idAttachItem)) ) + { + removeCOFItemLinks(idAttachItem); + } +} +// [/SL:KB] + BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const { const LLUUID& cof = getCOF(); diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index b268db601..27351f5aa 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -63,7 +63,7 @@ public: // [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0a) | Added: RLVa-1.2.0a void 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& idOutfit = LLUUID::null); + bool append = false, const LLUUID& idOutfit = LLUUID::null, LLPointer link_waiter = NULL); // [/RLVa:KB] void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append); void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append); @@ -167,7 +167,10 @@ public: bool isLinkedInCOF(const LLUUID& item_id); // Remove COF entries - void removeCOFItemLinks(const LLUUID& item_id, LLPointer cb = NULL); +// void removeCOFItemLinks(const LLUUID& item_id, LLPointer cb = NULL); +// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-05-02 (Catznip-3.7) + void removeCOFItemLinks(const LLUUID& item_id, LLPointer cb = NULL, bool immediate_delete = false); +// [/SL:KB] void removeCOFLinksOfType(LLWearableType::EType type, LLPointer cb = NULL); void removeAllClothesFromAvatar(); void removeAllAttachmentsFromAvatar(); @@ -200,8 +203,13 @@ public: bool updateBaseOutfit(); //Remove clothing or detach an object from the agent (a bodypart cannot be removed) - void removeItemsFromAvatar(const uuid_vec_t& item_ids); - void removeItemFromAvatar(const LLUUID& item_id); +// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7) + void removeItemFromAvatar(const LLUUID& id_to_remove, LLPointer cb = NULL, bool immediate_delete = false); + + void removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, LLPointer cb = NULL, bool immediate_delete = false); +// [/SL:KB] +// void removeItemsFromAvatar(const uuid_vec_t& item_ids); +// void removeItemFromAvatar(const LLUUID& item_id); void onOutfitFolderCreated(const LLUUID& folder_id, bool show_panel); @@ -275,10 +283,6 @@ private: static void onOutfitRename(const LLSD& notification, const LLSD& response); -// [SL:KB] - Checked: 2010-04-24 (RLVa-1.2.0f) | Added: RLVa-1.2.0f - void purgeItems(const LLInventoryModel::item_array_t& items); - void purgeItemsOfType(LLAssetType::EType asset_type); -// [/SL:KB] bool mAttachmentInvLinkEnabled; bool mOutfitIsDirty; @@ -300,6 +304,15 @@ private: void addDoomedTempAttachment(const LLUUID& id_to_remove); +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-18 (Catznip-2.1) +public: + void linkPendingAttachments(); + void clearPendingAttachment(const LLUUID& idItem); + void onRegisterAttachmentComplete(const LLUUID& idAttachItem); +private: + uuid_vec_t mPendingAttachLinks; +// [/SL:KB] + ////////////////////////////////////////////////////////////////////////////////// // Item-specific convenience functions public: @@ -330,6 +343,21 @@ private: nullary_func_t mPostUpdateFunc; }; +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-08-31 (Catznip-2.1) +class LLRegisterAttachmentCallback : public LLInventoryCallback +{ +public: + LLRegisterAttachmentCallback(const LLUUID& idAttachItem) : m_idAttachItem(idAttachItem) {} + /*virtual*/ void fire(const LLUUID&) + { + // NOTE: AISCommand::getResponseUUID() currently returns false so the passed UUID is NULL and hence useless + LLAppearanceMgr::instance().onRegisterAttachmentComplete(m_idAttachItem); + } +protected: + LLUUID m_idAttachItem; +}; +// [/SL:KB] + class LLUpdateAppearanceAndEditWearableOnDestroy: public LLInventoryCallback { public: diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp index d78e64a83..6f2f4d7d2 100644 --- a/indra/newview/llattachmentsmgr.cpp +++ b/indra/newview/llattachmentsmgr.cpp @@ -33,7 +33,7 @@ #include "llviewerinventory.h" #include "llviewerregion.h" #include "message.h" -// [RLVa:KB] - Checked: 2010-09-13 (RLVa-1.2.1c) +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) #include "rlvhandler.h" #include "rlvlocks.h" // [/RLVa:KB] @@ -49,7 +49,7 @@ LLAttachmentsMgr::~LLAttachmentsMgr() void LLAttachmentsMgr::addAttachment(const LLUUID& item_id, const U8 attachment_pt, // const BOOL add) -// [RLVa:KB] - Checked: 2010-09-13 (RLVa-1.2.1c) | Added: RLVa-1.2.1c +// [RLVa:KB] - Checked: 2010-09-13 (RLVa-1.2.1) const BOOL add, const BOOL fRlvForce /*=FALSE*/) // [/RLVa:KB] { @@ -58,7 +58,7 @@ void LLAttachmentsMgr::addAttachment(const LLUUID& item_id, attachment.mAttachmentPt = attachment_pt; attachment.mAdd = add; -// [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1d) | Modified: RLVa-1.2.1d +// [RLVa:KB] - Checked: 2010-09-23 (RLVa-1.2.1) if ( (rlv_handler_t::isEnabled()) && (!fRlvForce) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) { const LLInventoryItem* pItem = gInventory.getItem(item_id); diff --git a/indra/newview/llinventoryactions.cpp b/indra/newview/llinventoryactions.cpp index 02429f13f..74691e4af 100644 --- a/indra/newview/llinventoryactions.cpp +++ b/indra/newview/llinventoryactions.cpp @@ -418,10 +418,9 @@ struct LLAttachObject : public inventory_panel_listener_t LLUUID id = *selected_items.begin(); std::string joint_name = userdata.asString(); - LLVOAvatar *avatarp = gAgentAvatarp; LLViewerJointAttachment* attachmentp = NULL; - for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); - iter != avatarp->mAttachmentPoints.end(); ) + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); + iter != gAgentAvatarp->mAttachmentPoints.end(); ) { LLVOAvatar::attachment_map_t::iterator curiter = iter++; LLViewerJointAttachment* attachment = curiter->second; @@ -435,7 +434,7 @@ struct LLAttachObject : public inventory_panel_listener_t { return true; } - if (LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(id)) + if (LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getLinkedItem(id)) { if(gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID())) { @@ -444,7 +443,10 @@ struct LLAttachObject : public inventory_panel_listener_t else if(item->isFinished()) { // must be in library. copy it to our inventory and put it on. - LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp, false)); +// LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&rez_attachment_cb, _1, attachmentp)); +// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2013-02-04 (Catznip-3.4) + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&rez_attachment_cb, _1, attachmentp, false)); +// [/SL;KB] copy_inventory_item( gAgentID, item->getPermissions().getOwner(), diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 0d7adca28..403f8910f 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -86,6 +86,7 @@ #include "hippogridmanager.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) +#include "rlvactions.h" #include "rlvhandler.h" #include "rlvlocks.h" // [/RLVa:KB] @@ -5364,7 +5365,7 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action) else if(item && item->isFinished()) { // must be in library. copy it to our inventory and put it on. - LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0, false)); + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&rez_attachment_cb, _1, (LLViewerJointAttachment*)0, false)); copy_inventory_item( gAgent.getID(), item->getPermissions().getOwner(), @@ -5406,19 +5407,25 @@ std::string LLObjectBridge::getLabelSuffix() const { return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn"); } - std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(mUUID); - if (attachment_point_name == LLStringUtil::null) // Error condition, invalid attach point + std::string attachment_point_name; + if (gAgentAvatarp->getAttachedPointName(mUUID, attachment_point_name)) { - attachment_point_name = "Invalid Attachment"; - } - // e.g. "(worn on ...)" / "(attached to ...)" - LLStringUtil::format_map_t args; - args["[ATTACHMENT_POINT]"] = LLTrans::getString(attachment_point_name); - if (gRlvAttachmentLocks.canDetach(getItem())) - return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args); + // e.g. "(worn on ...)" / "(attached to ...)" + LLStringUtil::format_map_t args; + args["[ATTACHMENT_POINT]"] = LLTrans::getString(attachment_point_name); + + if (gRlvAttachmentLocks.canDetach(getItem())) + return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args); + else + return LLItemBridge::getLabelSuffix() + LLTrans::getString("LockedOnAttachmentPoint", args); + } else - return LLItemBridge::getLabelSuffix() + LLTrans::getString("LockedOnAttachmentPoint", args); + { + LLStringUtil::format_map_t args; + args["[ATTACHMENT_ERROR]"] = LLTrans::getString(attachment_point_name); + return LLItemBridge::getLabelSuffix() + LLTrans::getString("AttachmentErrorMessage", args); + } } return LLItemBridge::getLabelSuffix(); } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index d87fad1c6..732db0aac 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -767,12 +767,19 @@ void LLInventoryModel::collectDescendents(const LLUUID& id, collectDescendentsIf(id, cats, items, include_trash, always); } +//void LLInventoryModel::collectDescendentsIf(const LLUUID& id, +// cat_array_t& cats, +// item_array_t& items, +// BOOL include_trash, +// LLInventoryCollectFunctor& add) +// [RLVa:KB] - Checked: 2013-04-15 (RLVa-1.4.8) void LLInventoryModel::collectDescendentsIf(const LLUUID& id, cat_array_t& cats, item_array_t& items, BOOL include_trash, LLInventoryCollectFunctor& add, - BOOL follow_folder_links) + bool follow_folder_links) +// [/RLVa:KB] { // Start with categories if(!include_trash) @@ -792,7 +799,10 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, { cats.push_back(cat); } - collectDescendentsIf(cat->getUUID(), cats, items, include_trash, add); +// [RLVa:KB] - Checked: 2013-04-15 (RLVa-1.4.8) + collectDescendentsIf(cat->getUUID(), cats, items, include_trash, add, follow_folder_links); +// [/RLVa:KB] +// collectDescendentsIf(cat->getUUID(), cats, items, include_trash, add); } } @@ -820,7 +830,6 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, // This breaks the "finish collecting all folders before collecting items (top to bottom and then bottom to top)" // assumption but no functor is (currently) relying on it (and likely never should since it's an implementation detail?) // [Only LLAppearanceMgr actually ever passes in 'follow_folder_links == TRUE'] -// [/RLVa:KB] // Follow folder links recursively. Currently never goes more // than one level deep (for current outfit support) // Note: if making it fully recursive, need more checking against infinite loops. @@ -845,11 +854,12 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, // outfit traversal. cats.push_back(LLPointer(linked_cat)); } - collectDescendentsIf(linked_cat->getUUID(), cats, items, include_trash, add, FALSE); + collectDescendentsIf(linked_cat->getUUID(), cats, items, include_trash, add, false); } } } } +// [/RLVa:KB] } void LLInventoryModel::addChangedMaskForLinks(const LLUUID& object_id, U32 mask) diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index da2937d00..20bbafe5a 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -231,12 +231,19 @@ public: cat_array_t& categories, item_array_t& items, BOOL include_trash); +// [RLVa:KB] - Checked: 2013-04-15 (RLVa-1.4.8) void collectDescendentsIf(const LLUUID& id, cat_array_t& categories, item_array_t& items, BOOL include_trash, LLInventoryCollectFunctor& add, - BOOL follow_folder_links = FALSE); + bool follow_folder_links = false); +// [/RLVa:KB] +// void collectDescendentsIf(const LLUUID& id, +// cat_array_t& categories, +// item_array_t& items, +// BOOL include_trash, +// LLInventoryCollectFunctor& add); // Collect all items in inventory that are linked to item_id. // Assumes item_id is itself not a linked item. diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 8ee9ada0e..5a0711b91 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1778,7 +1778,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( // LLPointer cb = new RezAttachmentCallback(0); // [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.0.0a) | Added: Catznip-2.2.0a // Make this behave consistent with dad3dWearItem - LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&rez_attachment_cb, _1, (LLViewerJointAttachment*)0, !(mask & MASK_CONTROL))); + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&rez_attachment_cb, _1, (LLViewerJointAttachment*)0, fReplace)); // [/SL:KB] copy_inventory_item( gAgent.getID(), diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index b5456d30b..fb9295631 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -69,6 +69,9 @@ #include "llappviewer.h" // System Folders bool use_http_inventory(); // UseHTTPInventory replacement // +// [RLVa:KB] - Checked: 2014-11-02 (RLVa-1.4.11) +#include "rlvcommon.h" +// [/RLVa:KB] // do-nothing ops for use in callbacks. void no_op_inventory_func(const LLUUID&) {} @@ -939,10 +942,10 @@ void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachme LLViewerInventoryItem *item = gInventory.getItem(inv_item); if (item) { -// rez_attachment(item, attachmentp); -// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.0.0a) | Added: Catznip-2.2.0a +// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.4) rez_attachment(item, attachmentp, replace); // [/SL:KB] +// rez_attachment(item, attachmentp); } } @@ -1312,15 +1315,35 @@ void update_inventory_item( const LLSD& updates, LLPointer cb) { - { - LLPointer obj = gInventory.getItem(item_id); - LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << (obj ? obj->getName() : "(NOT FOUND)") << LL_ENDL; - if(obj) - { - LLPointer new_item(new LLViewerInventoryItem); - new_item->copyViewerItem(obj); - new_item->fromLLSD(updates,false); +// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-03-01 (Catznip-3.7) + LLPointer obj = gInventory.getItem(item_id); + LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << (obj ? obj->getName() : "(NOT FOUND)") << LL_ENDL; + LLPointer new_item = NULL; + if (obj) + { + new_item->copyViewerItem(obj); + new_item->fromLLSD(updates,false); + + LLInventoryModel::LLCategoryUpdate up(new_item->getParentUUID(), 0); + gInventory.accountForUpdate(up); + gInventory.updateItem(new_item); + } +// [/SL:KB] + + { +// LLPointer obj = gInventory.getItem(item_id); +// LL_DEBUGS(LOG_INV) << "item_id: [" << item_id << "] name " << (obj ? obj->getName() : "(NOT FOUND)") << LL_ENDL; +// if(obj) +// { +// LLPointer new_item(new LLViewerInventoryItem); +// new_item->copyViewerItem(obj); +// new_item->fromLLSD(updates,false); + +// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-03-01 (Catznip-3.7) + if (new_item) + { +// [/SL:KB] LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_UpdateInventoryItem); msg->nextBlockFast(_PREHASH_AgentData); @@ -1332,9 +1355,9 @@ void update_inventory_item( new_item->packMessage(msg); gAgent.sendReliableMessage(); - LLInventoryModel::LLCategoryUpdate up(new_item->getParentUUID(), 0); - gInventory.accountForUpdate(up); - gInventory.updateItem(new_item); +// LLInventoryModel::LLCategoryUpdate up(new_item->getParentUUID(), 0); +// gInventory.accountForUpdate(up); +// gInventory.updateItem(new_item); if (cb) { cb->fire(item_id); @@ -1728,23 +1751,100 @@ void create_new_item(const std::string& name, cb); } +// [RLVa:KB] - Checked: 2014-11-02 (RLVa-1.4.11) +void sync_inventory_folder(const LLUUID& folder_id, const LLInventoryModel::item_array_t& items, LLInventoryModel::item_array_t& items_to_add, LLInventoryModel::item_array_t& items_to_remove) +{ + LLInventoryModel::item_array_t curItems, newItems = items; + + // Grab the current contents + LLInventoryModel::cat_array_t cats; + gInventory.collectDescendents(folder_id, cats, curItems, LLInventoryModel::EXCLUDE_TRASH); + + // Purge everything in curItems that isn't part of newItems + for (LLInventoryModel::item_array_t::const_iterator itCurItem = curItems.begin(); itCurItem != curItems.end(); ++itCurItem) + { + LLViewerInventoryItem* pItem = *itCurItem; + if (std::find_if(newItems.begin(), newItems.end(), RlvPredIsEqualOrLinkedItem(pItem)) == newItems.end()) + { + // Item doesn't exist in newItems => purge (if it's a link) + 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 + { + // Item exists in newItems => remove *all* occurances in newItems (removes duplicate COF links to this item as well) + newItems.erase(std::remove_if(newItems.begin(), newItems.end(), RlvPredIsEqualOrLinkedItem(pItem)), newItems.end()); + } + } + + // Whatever remains in newItems will need to have a link created + for (LLInventoryModel::item_array_t::const_iterator itNewItem = newItems.begin(); itNewItem != newItems.end(); ++itNewItem) + { + LLViewerInventoryItem* pItem = *itNewItem; + if (items_to_add.end() == std::find(items_to_add.begin(), items_to_add.end(), pItem)) + items_to_add.push_back(pItem); + } +} + +void link_inventory_items(const LLUUID& folder_id, const LLInventoryModel::item_array_t& items, LLPointer cb) +{ + for (LLInventoryModel::item_array_t::const_iterator itItem = items.begin(); itItem != items.end(); ++itItem) + { + const LLViewerInventoryItem* pItem = *itItem; + link_inventory_object(folder_id, pItem, cb); + } +} + +void remove_inventory_items(const LLInventoryModel::item_array_t& items, LLPointer cb) +{ + for (LLInventoryModel::item_array_t::const_iterator itItem = items.begin(); itItem != items.end(); ++itItem) + { + const LLViewerInventoryItem* pItem = *itItem; + if (pItem->getIsLinkType()) + remove_inventory_item(pItem->getUUID(), cb); + } +} +// [/RLVa:KB] + void slam_inventory_folder(const LLUUID& folder_id, const LLSD& contents, LLPointer cb) { { +// [RLVa:KB] - Checked: 2014-11-02 (RLVa-1.4.11) LL_DEBUGS(LOG_INV) << "using item-by-item calls to slam folder, id " << folder_id << " new contents: " << ll_pretty_print_sd(contents) << LL_ENDL; - for (LLSD::array_const_iterator it = contents.beginArray(); - it != contents.endArray(); - ++it) + + LLInventoryModel::item_array_t items; + for (LLSD::array_const_iterator itItem = contents.beginArray(); itItem != contents.endArray(); ++itItem) { - const LLSD& item_contents = *it; - LLViewerInventoryItem *item = new LLViewerInventoryItem; - item->fromLLSD(item_contents); - link_inventory_object(folder_id, item, cb); + LLViewerInventoryItem* pItem = new LLViewerInventoryItem; + pItem->fromLLSD(*itItem); + items.push_back(pItem); } - remove_folder_contents(folder_id,false,cb); + + LLInventoryModel::item_array_t items_to_add, items_to_remove; + sync_inventory_folder(folder_id, items, items_to_add, items_to_remove); + + link_inventory_items(folder_id, items_to_add, cb); + remove_inventory_items(items_to_remove, cb); +// [/RLVa:KB] +// LL_DEBUGS(LOG_INV) << "using item-by-item calls to slam folder, id " << folder_id +// << " new contents: " << ll_pretty_print_sd(contents) << LL_ENDL; +// for (LLSD::array_const_iterator it = contents.beginArray(); +// it != contents.endArray(); +// ++it) +// { +// const LLSD& item_contents = *it; +// LLViewerInventoryItem *item = new LLViewerInventoryItem; +// item->fromLLSD(item_contents); +// link_inventory_object(folder_id, item, cb); +// } +// remove_folder_contents(folder_id,false,cb); } } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 0d7ce6e58..7ad832ea6 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -345,6 +345,25 @@ struct LLTextureMaskData ** **/ +struct LLAppearanceMessageContents +{ + LLAppearanceMessageContents(): + mAppearanceVersion(-1), + mParamAppearanceVersion(-1), + mCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN) + { + } + LLTEContents mTEContents; + S32 mAppearanceVersion; + S32 mParamAppearanceVersion; + S32 mCOFVersion; + // For future use: + //U32 appearance_flags = 0; + std::vector mParamWeights; + std::vector mParams; + LLVector3 mHoverOffset; + bool mHoverOffsetWasSet; +}; //----------------------------------------------------------------------------- // class LLBodyNoiseMotion //----------------------------------------------------------------------------- @@ -6950,23 +6969,6 @@ LLViewerObject* LLVOAvatar::getWornAttachment( const LLUUID& inv_item_id ) return NULL; } -const std::string LLVOAvatar::getAttachedPointName(const LLUUID& inv_item_id) -{ - const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); ) - { - attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - if (attachment->getAttachedObject(base_inv_item_id)) - { - return attachment->getName(); - } - } - - return LLStringUtil::null; -} - LLViewerObject * LLVOAvatar::findAttachmentByID( const LLUUID & target_id ) const { for(attachment_map_t::const_iterator attachment_points_iter = mAttachmentPoints.begin(); @@ -7319,11 +7321,9 @@ BOOL LLVOAvatar::isFullyLoaded() const // [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2.0a) | Added: Catznip-2.2.0a // Changes to LLAppearanceMgr::updateAppearanceFromCOF() expect this function to actually return mFullyLoaded for gAgentAvatarp - if ( (!isSelf()) && render_unloaded_avatar ) - return TRUE; - else - return mFullyLoaded; + return (render_unloaded_avatar && !isSelf()) ||(mFullyLoaded); // [/SL:KB] +// return (render_unloaded_avatar || mFullyLoaded); } bool LLVOAvatar::isTooComplex() const @@ -7986,26 +7986,6 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, } } -struct LLAppearanceMessageContents -{ - LLAppearanceMessageContents(): - mAppearanceVersion(-1), - mParamAppearanceVersion(-1), - mCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN) - { - } - LLTEContents mTEContents; - S32 mAppearanceVersion; - S32 mParamAppearanceVersion; - S32 mCOFVersion; - // For future use: - //U32 appearance_flags = 0; - std::vector mParamWeights; - std::vector mParams; - LLVector3 mHoverOffset; - bool mHoverOffsetWasSet; -}; - void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& contents) { parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, contents.mTEContents); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 8ed1430e6..8e3ece6d9 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -784,7 +784,6 @@ public: BOOL isWearingAttachment( const LLUUID& inv_item_id ); LLViewerObject* getWornAttachment( const LLUUID& inv_item_id ); - const std::string getAttachedPointName(const LLUUID& inv_item_id); /** Wearables ** ** diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 3a3c8d550..e0e998d49 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -643,6 +643,9 @@ void LLVOAvatarSelf::cleanup() LLVOAvatarSelf::~LLVOAvatarSelf() { cleanup(); +// [RLVa:KB] - Checked: 2012-07-28 (RLVa-1.4.7) + delete mAttachmentSignal; +// [/RLVa:KB] } /** @@ -1219,9 +1222,19 @@ LLViewerJointAttachment* LLVOAvatarSelf::getWornAttachmentPoint(const LLUUID& id } // [/RLVa:KB] -const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id) const +bool LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const { + if (!gInventory.getItem(inv_item_id)) + { + name = "ATTACHMENT_MISSING_ITEM"; + return false; + } const LLUUID& base_inv_item_id = gInventory.getLinkedItemID(inv_item_id); + if (!gInventory.getItem(base_inv_item_id)) + { + name = "ATTACHMENT_MISSING_BASE_ITEM"; + return false; + } for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter) @@ -1229,11 +1242,13 @@ const std::string LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id const LLViewerJointAttachment* attachment = iter->second; if (attachment->getAttachedObject(base_inv_item_id)) { - return attachment->getName(); + name = attachment->getName(); + return true; } } - return LLStringUtil::null; + name = "ATTACHMENT_NOT_ATTACHED"; + return false; } //virtual diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index a83a6d029..1988a51fd 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -311,10 +311,10 @@ public: void addAttachmentRequest(const LLUUID& inv_item_id); void removeAttachmentRequest(const LLUUID& inv_item_id); LLViewerObject* getWornAttachment(const LLUUID& inv_item_id); + bool getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const; // [RLVa:KB] - Checked: 2009-12-18 (RLVa-1.1.0i) | Added: RLVa-1.1.0i LLViewerJointAttachment* getWornAttachmentPoint(const LLUUID& inv_item_id) const; // [/RLVa:KB] - const std::string getAttachedPointName(const LLUUID& inv_item_id) const; /*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object); /*virtual*/ BOOL detachObject(LLViewerObject *viewer_object); static BOOL detachAttachmentIntoInventory(const LLUUID& item_id); diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp index 3c2ca3777..6efd8aab2 100644 --- a/indra/newview/llwearablelist.cpp +++ b/indra/newview/llwearablelist.cpp @@ -98,7 +98,23 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID { BOOL isNewWearable = FALSE; LLWearableArrivedData* data = (LLWearableArrivedData*) userdata; - LLViewerWearable* wearable = NULL; // NULL indicates failure +// LLViewerWearable* wearable = NULL; // NULL indicates failure +// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-08-13 (Catznip-2.1) + LLViewerWearable* wearable = get_if_there(LLWearableList::instance().mList, uuid, (LLViewerWearable*)NULL); + if (wearable) + { + LL_DEBUGS("Wearable") << "processGetAssetReply()" << LL_ENDL; + LL_DEBUGS("Wearable") << wearable << LL_ENDL; + + if(data->mCallback) + { + data->mCallback(wearable, data->mUserdata); + } + delete data; + + return; + } +// [/SL:KB] LLAvatarAppearance *avatarp = data->mAvatarp; if( !filename ) diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index 3c527118d..f2d3ecfee 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -692,10 +692,30 @@ bool rlvPredCanNotWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWea return !rlvPredCanWearItem(pItem, eWearMask); } -// Checked: 2010-03-22 (RLVa-1.2.0c) | Added: RLVa-1.2.0a +// Checked: 2014-11-02 (RLVa-1.4.11) +bool rlvPredCanRemoveItem(const LLUUID& idItem) +{ + // Check the inventory item if it's available + const LLViewerInventoryItem* pItem = gInventory.getItem(idItem); + if (pItem) + { + return rlvPredCanRemoveItem(pItem); + } + + // Temporary attachments don't have inventory items associated with them so check the attachment itself + if (isAgentAvatarValid()) + { + const LLViewerObject* pAttachObj = gAgentAvatarp->getWornAttachment(idItem); + return (pAttachObj) && (!gRlvAttachmentLocks.isLockedAttachment(pAttachObj)); + } + + return false; +} + +// Checked: 2010-03-22 (RLVa-1.2.0) bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem) { - if ( (pItem) && (RlvForceWear::isWearableItem(pItem)) ) + if (pItem) { switch (pItem->getType()) { @@ -707,12 +727,10 @@ bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem) case LLAssetType::AT_GESTURE: return true; default: - RLV_ASSERT(false); + RLV_ASSERT(!RlvForceWear::isWearableItem(pItem)); } } - // HACK-RLVa: Until LL supports temporary attachment detection assume that no inventory item means a temporary - // attachment which are always removeable - return true; + return false; } // Checked: 2010-03-22 (RLVa-1.2.0c) | Added: RLVa-1.2.0a diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index ef7d90ea6..0520eb7c6 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -243,7 +243,9 @@ protected: bool rlvPredCanWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWearMask); bool rlvPredCanNotWearItem(const LLViewerInventoryItem* pItem, ERlvWearMask eWearMask); +bool rlvPredCanRemoveItem(const LLUUID& idItem); bool rlvPredCanRemoveItem(const LLViewerInventoryItem* pItem); +bool rlvPredCanNotRemoveItem(const LLUUID& idItem); bool rlvPredCanNotRemoveItem(const LLViewerInventoryItem* pItem); struct RlvPredCanWearItem diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 3aa90e168..70520d87c 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -68,7 +68,7 @@ const S32 RLVa_VERSION_PATCH = 10; const S32 RLVa_VERSION_BUILD = 0; // Uncomment before a final release -#define RLV_RELEASE +//#define RLV_RELEASE // Defining these makes it easier if we ever need to change our tag #define RLV_WARNS LL_WARNS("RLV") diff --git a/indra/newview/rlvfloaters.cpp b/indra/newview/rlvfloaters.cpp index 8c0ebe1e0..b4c0e917f 100644 --- a/indra/newview/rlvfloaters.cpp +++ b/indra/newview/rlvfloaters.cpp @@ -43,9 +43,15 @@ std::string rlvGetItemName(const LLViewerInventoryItem* pItem) { if ( (pItem) && ((LLAssetType::AT_BODYPART == pItem->getType()) || (LLAssetType::AT_CLOTHING == pItem->getType())) ) + { return llformat("%s (%s)", pItem->getName().c_str(), LLWearableType::getTypeName(pItem->getWearableType()).c_str()); + } else if ( (pItem) && (LLAssetType::AT_OBJECT == pItem->getType()) && (isAgentAvatarValid()) ) - return llformat("%s (%s)", pItem->getName().c_str(), gAgentAvatarp->getAttachedPointName(pItem->getUUID()).c_str()); + { + std::string strAttachPtName; + gAgentAvatarp->getAttachedPointName(pItem->getUUID(), strAttachPtName); + return llformat("%s (%s)", pItem->getName().c_str(), strAttachPtName.c_str()); + } return (pItem) ? pItem->getName() : LLStringUtil::null; } diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 1439c92d1..a7398ca4e 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -2135,7 +2135,7 @@ ERlvCmdRet RlvHandler::onGetInvWorn(const RlvCommand& rlvCmd, std::string& strRe // Collect everything @attachall would be attaching LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; RlvWearableItemCollector f(pFolder, RlvForceWear::ACTION_WEAR_REPLACE, RlvForceWear::FLAG_MATCHALL); - gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, f, TRUE); + gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, f, true); rlv_wear_info wi = {0}; diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 84fd3e4b4..e8083d3c1 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -30,6 +30,7 @@ #include "rlvinventory.h" #include +#include // ============================================================================ // RlvCommmand @@ -478,7 +479,7 @@ void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, EWearAc // Grab a list of all the items we'll be wearing/attaching LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; RlvWearableItemCollector f(pFolder, eAction, eFlags); - gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, f, TRUE); + gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, f, true); // TRUE if we've already encountered this LLWearableType::EType (used only on wear actions and only for AT_CLOTHING) bool fSeenWType[LLWearableType::WT_COUNT] = { false }; @@ -887,7 +888,35 @@ void RlvForceWear::remWearable(const LLViewerWearable* pWearable) m_remWearables.push_back(pWearable); } -// Checked: 2010-09-18 (RLVa-1.2.1) +// Checked: 2015-05-05 (RLVa-1.4.12) +void RlvForceWear::updatePendingAttachments() +{ + if (RlvForceWear::instanceExists()) + { + RlvForceWear* pThis = RlvForceWear::getInstance(); + for (const pendingattachments_map_t::value_type& itAttach : pThis->m_pendingAttachments) + LLAttachmentsMgr::instance().addAttachment(itAttach.first, itAttach.second & ~ATTACHMENT_ADD, itAttach.second & ATTACHMENT_ADD); + pThis->m_pendingAttachments.clear(); + } +} + +// Checked: 2015-05-05 (RLVa-1.4.12) +void RlvForceWear::addPendingAttachment(const LLUUID& idItem, U8 idxPoint) +{ + auto itAttach = m_pendingAttachments.find(idItem); + if (m_pendingAttachments.end() == itAttach) + m_pendingAttachments.insert(std::make_pair(idItem, idxPoint)); + else + itAttach->second = idxPoint; +} + +// Checked: 2015-05-05 (RLVa-1.4.12) +void RlvForceWear::remPendingAttachment(const LLUUID& idItem) +{ + m_pendingAttachments.erase(idItem); +} + +// Checked: 2015-05-05 (RLVa-1.4.12) void RlvForceWear::done() { // Sanity check - don't go through all the motions below only to find out there's nothing to actually do @@ -897,41 +926,35 @@ void RlvForceWear::done() return; } - LLAppearanceMgr* pAppearanceMgr = LLAppearanceMgr::getInstance(); - // // Process removals // + uuid_vec_t remItems; + // Wearables if (m_remWearables.size()) { - for (std::list::const_iterator itWearable = m_remWearables.begin(); itWearable != m_remWearables.end(); ++itWearable) - pAppearanceMgr->removeItemFromAvatar((*itWearable)->getItemID()); + BOOST_FOREACH(const LLViewerWearable* pWearable, m_remWearables) + remItems.push_back(pWearable->getItemID()); m_remWearables.clear(); } // Gestures if (m_remGestures.size()) { - // NOTE: LLGestureMgr::deactivateGesture() will call LLAppearanceMgr::removeCOFItemLinks() for us - for (S32 idxItem = 0, cntItem = m_remGestures.size(); idxItem < cntItem; idxItem++) - LLGestureMgr::instance().deactivateGesture(m_remGestures.at(idxItem)->getUUID()); + // NOTE: LLGestureMgr::deactivateGesture() will call LLAppearanceMgr::removeCOFItemLinks() for us and supply its own callback + BOOST_FOREACH(const LLViewerInventoryItem* pItem, m_remGestures) + LLGestureMgr::instance().deactivateGesture(pItem->getUUID()); m_remGestures.clear(); } // Attachments if (m_remAttachments.size()) { - // Don't bother with COF if all we're doing is detaching some attachments (keeps people from rebaking on every @remattach=force) LLAgentWearables::userRemoveMultipleAttachments(m_remAttachments); - - for (std::vector::const_iterator itAttachObj = m_remAttachments.begin(); - itAttachObj != m_remAttachments.end(); ++itAttachObj) - { - pAppearanceMgr->removeCOFItemLinks((*itAttachObj)->getAttachmentItemID()); - } - + BOOST_FOREACH(const LLViewerObject* pAttachObj, m_remAttachments) + remItems.push_back(pAttachObj->getAttachmentItemID()); m_remAttachments.clear(); } @@ -941,50 +964,51 @@ void RlvForceWear::done() // Wearables need to be split into AT_BODYPART and AT_CLOTHING for COF LLInventoryModel::item_array_t addBodyParts, addClothing; - for (addwearables_map_t::const_iterator itAddWearables = m_addWearables.begin(); itAddWearables != m_addWearables.end(); ++itAddWearables) + for (addwearables_map_t::const_iterator itAddWearables = m_addWearables.cbegin(); itAddWearables != m_addWearables.cend(); ++itAddWearables) { - const LLInventoryModel::item_array_t& wearItems = itAddWearables->second; - for (S32 idxItem = 0, cntItem = wearItems.size(); idxItem < cntItem; idxItem++) + // NOTE: LLAppearanceMgr will filter our duplicates so no need for us to check here + for (LLViewerInventoryItem* pItem : itAddWearables->second) { - LLViewerInventoryItem* pItem = wearItems.at(idxItem); - if (!pAppearanceMgr->isLinkInCOF(pItem->getUUID())) // It's important to examine COF here and *not* gAgentWearables - { - if (LLAssetType::AT_BODYPART == pItem->getType()) - addBodyParts.push_back(pItem); - else - addClothing.push_back(pItem); - } + if (LLAssetType::AT_BODYPART == pItem->getType()) + addBodyParts.push_back(pItem); + else + addClothing.push_back(pItem); } } m_addWearables.clear(); // Until LL provides a way for updateCOF to selectively attach add/replace we have to deal with attachments ourselves - for (addattachments_map_t::const_iterator itAddAttachments = m_addAttachments.begin(); - itAddAttachments != m_addAttachments.end(); ++itAddAttachments) + for (addattachments_map_t::const_iterator itAddAttachments = m_addAttachments.cbegin(); itAddAttachments != m_addAttachments.cend(); ++itAddAttachments) { - const LLInventoryModel::item_array_t& wearItems = itAddAttachments->second; - for (S32 idxItem = 0, cntItem = wearItems.size(); idxItem < cntItem; idxItem++) - { - const LLUUID& idItem = wearItems.at(idxItem)->getLinkedUUID(); - if (gAgentAvatarp->attachmentWasRequested(idItem)) - continue; - gAgentAvatarp->addAttachmentRequest(idItem); - - LLAttachmentsMgr::instance().addAttachment(idItem, itAddAttachments->first & ~ATTACHMENT_ADD, itAddAttachments->first & ATTACHMENT_ADD); - } + for (const LLViewerInventoryItem* pItem : itAddAttachments->second) + addPendingAttachment(pItem->getLinkedUUID(), itAddAttachments->first); } m_addAttachments.clear(); - // If there are additions we need to call LLAppearanceManager::updateCOF(), otherwise LLAppearanceManager::updateAppearanceFromCOF() + // + // Tie it all together + // + + // | Wearables | Attachments | Gestures | + // |======================================================| + // Add : | LLAppearanceMgr | | LLAppearanceMgr | + // Remove : | LLAppearanceMgr | LLAppearanceMgr | LLGestureMgr | + LLPointer cb = new LLUpdateAppearanceOnDestroy(false, false, boost::bind(RlvForceWear::updatePendingAttachments)); + + if (!remItems.empty()) + { + LLAppearanceMgr::instance().removeItemsFromAvatar(remItems, cb, true); + } + if ( (!addBodyParts.empty()) || (!addClothing.empty()) || (!m_addGestures.empty()) ) { LLInventoryModel::item_array_t addAttachments; - pAppearanceMgr->updateCOF(addBodyParts, addClothing, addAttachments, m_addGestures, true); + LLAppearanceMgr::instance().updateCOF(addBodyParts, addClothing, addAttachments, m_addGestures, true, LLUUID::null, cb); m_addGestures.clear(); } - // Since RlvForceWear is a singleton now we want to be sure there aren't any leftovers + // Make sure there are no leftovers for the next cycle RLV_ASSERT( (m_remWearables.empty()) && (m_remAttachments.empty()) && (m_remGestures.empty()) ); RLV_ASSERT( (m_addWearables.empty()) && (m_addAttachments.empty()) && (m_addGestures.empty()) ); } diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index 4fe17168e..a57d77d6b 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -276,6 +276,15 @@ protected: return std::find(m_remWearables.begin(), m_remWearables.end(), pWearable) != m_remWearables.end(); } + /* + * Pending attachments + */ +public: + static void updatePendingAttachments(); +protected: + void addPendingAttachment(const LLUUID& idItem, U8 idxPoint); + void remPendingAttachment(const LLUUID& idItem); + protected: typedef std::pair addwearable_pair_t; typedef std::map addwearables_map_t; @@ -288,6 +297,9 @@ protected: std::list m_remWearables; LLInventoryModel::item_array_t m_remGestures; + typedef std::map pendingattachments_map_t; + pendingattachments_map_t m_pendingAttachments; + private: friend class LLSingleton; }; diff --git a/indra/newview/rlvinventory.cpp b/indra/newview/rlvinventory.cpp index ccfa1f3f7..6bb039360 100644 --- a/indra/newview/rlvinventory.cpp +++ b/indra/newview/rlvinventory.cpp @@ -133,7 +133,7 @@ void RlvInventory::fetchSharedLinks() // Grab all the inventory links under the shared root LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; RlvIsLinkType f; - gInventory.collectDescendentsIf(pRlvRoot->getUUID(), folders, items, FALSE, f, FALSE); + gInventory.collectDescendentsIf(pRlvRoot->getUUID(), folders, items, FALSE, f, false); // Add them to the "to fetch" list based on link type uuid_vec_t idFolders, idItems; @@ -282,11 +282,11 @@ LLViewerInventoryCategory* RlvInventory::getSharedFolder(const LLUUID& idParent, for (LLInventoryModel::cat_array_t::const_iterator itFolder = pFolders->begin(); itFolder != pFolders->end(); ++itFolder) { LLViewerInventoryCategory* pFolder = *itFolder; - std::string strName = pFolder->getName(); + const std::string& strName = pFolder->getName(); if (boost::iequals(strName, strFolderName)) return pFolder; // Found an exact match, no need to keep on going - else if ( (fMatchPartial) && (!pPartial) && (RLV_FOLDER_PREFIX_HIDDEN != strName[0]) && (boost::icontains(strName, strFolderName) ) ) + else if ( (fMatchPartial) && (!pPartial) && (RLV_FOLDER_PREFIX_HIDDEN != strName[0]) && (boost::icontains(strName, strFolderName)) ) pPartial = pFolder; // Found a partial (non-hidden) match, but we might still find an exact one (first partial match wins) } @@ -405,8 +405,9 @@ void RlvRenameOnWearObserver::doneIdle() LLInventoryModel::item_array_t items; if (gInventory.isObjectDescendentOf(idAttachItem, pRlvRoot->getUUID())) items.push_back(gInventory.getItem(idAttachItem)); - else - items = gInventory.collectLinksTo(idAttachItem, pRlvRoot->getUUID()); +// // LL kind of messed up the collectLinkedItems (now collectLinksTo) function but I'm not sure if this use-case if worth fixing it for +// else +// items = gInventory.collectLinkedItems(idAttachItem, pRlvRoot->getUUID()); if (items.empty()) continue; diff --git a/indra/newview/rlvlocks.cpp b/indra/newview/rlvlocks.cpp index a2216e0d1..92c869bc2 100644 --- a/indra/newview/rlvlocks.cpp +++ b/indra/newview/rlvlocks.cpp @@ -1164,8 +1164,11 @@ bool RlvFolderLocks::getLockedItems(const LLUUID& idFolder, LLInventoryModel::it // Check the parent folders of any links to this item that exist under #RLV if (!fItemLocked) { - LLInventoryModel::item_array_t itemLinks = - gInventory.collectLinksTo(pItem->getUUID(), RlvInventory::instance().getSharedRootID()); + LLInventoryModel::item_array_t itemLinks; + LLInventoryModel::cat_array_t cats; + LLLinkedItemIDMatches f(pItem->getUUID()); + gInventory.collectDescendentsIf(RlvInventory::instance().getSharedRootID(), cats, itemLinks, LLInventoryModel::EXCLUDE_TRASH, f); + for (LLInventoryModel::item_array_t::iterator itItemLink = itemLinks.begin(); (itItemLink < itemLinks.end()) && (!fItemLocked); ++itItemLink) { @@ -1204,7 +1207,7 @@ bool RlvFolderLocks::hasLockedFolderDescendent(const LLUUID& idFolder, int eSour LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; RlvLockedDescendentsCollector f(eSourceTypeMask, ePermMask, eLockTypeMask); - gInventory.collectDescendentsIf(idFolder, folders, items, FALSE, f, FALSE); + gInventory.collectDescendentsIf(idFolder, folders, items, FALSE, f, false); return !folders.empty(); } diff --git a/indra/newview/rlvlocks.h b/indra/newview/rlvlocks.h index 83316097e..e3f8a9fd9 100644 --- a/indra/newview/rlvlocks.h +++ b/indra/newview/rlvlocks.h @@ -457,7 +457,7 @@ inline bool RlvAttachmentLocks::canDetach(const LLInventoryItem* pItem) const { const LLViewerObject* pAttachObj = ((pItem) && (isAgentAvatarValid())) ? gAgentAvatarp->getWornAttachment(pItem->getLinkedUUID()) : NULL; - return (pAttachObj) && (!isLockedAttachment(pAttachObj)); + return (!pAttachObj) || (!isLockedAttachment(pAttachObj)); } // Checked: 2010-11-30 (RLVa-1.3.0b) | Modified: RLVa-1.3.0b @@ -480,7 +480,7 @@ inline bool RlvAttachmentLocks::isLockedAttachment(const LLViewerObject* pAttach // - it's attached to an attachment point that is RLV_LOCK_REMOVE locked (ie @remattach:=n) // - it's part of a locked folder return - (pAttachObj) && (pAttachObj->isAttachment()) && + (pAttachObj) && (pAttachObj->isAttachment()) && (!pAttachObj->isTempAttachment()) && ( (m_AttachObjRem.find(pAttachObj->getID()) != m_AttachObjRem.end()) || (isLockedAttachmentPoint(RlvAttachPtLookup::getAttachPointIndex(pAttachObj), RLV_LOCK_REMOVE)) || (RlvFolderLocks::instance().isLockedAttachment(pAttachObj->getAttachmentItemID())) ); diff --git a/indra/newview/skins/default/xui/en-us/strings.xml b/indra/newview/skins/default/xui/en-us/strings.xml index 15594f42c..c6832e159 100644 --- a/indra/newview/skins/default/xui/en-us/strings.xml +++ b/indra/newview/skins/default/xui/en-us/strings.xml @@ -3183,6 +3183,7 @@ The No contents + Yes @@ -3264,9 +3265,12 @@ The Stomach Left Pec Right Pec - Neck - Root - Invalid Attachment Point + Neck + Root + Invalid Attachment Point + Error: missing item + Error: missing base item + Error: object is in current outfit but not attached Resident