From 3bedb5f6d4e770e0a4feb1517cf4d5528ae137d4 Mon Sep 17 00:00:00 2001 From: Lirusaito Date: Thu, 26 May 2016 10:13:42 -0400 Subject: [PATCH] Sync llappearancemgr.cpp with upstream and rllva Remove old unused stuff Comment out some questionable stuff that's not upstream Rearrange a thing to match upstream Hopefully this fixes the baking bug? --- indra/llmessage/aihttptimeoutpolicy.cpp | 1 - indra/newview/llappearancemgr.cpp | 815 ++++++++++-------------- indra/newview/llappearancemgr.h | 62 +- indra/newview/llinventoryfunctions.cpp | 12 +- 4 files changed, 377 insertions(+), 513 deletions(-) diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index ba8de6bad..b20e8f844 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -948,7 +948,6 @@ P(productInfoRequestResponder); P(regionResponder); P(remoteParcelRequestResponder); P(requestAgentUpdateAppearance); -P2(incrementCofVersionResponder_timeouts, transfer_30s_connect_10s); P(responderIgnore); P(setDisplayNameResponder); P2(baseFeaturesReceived, transfer_22s_connect_10s); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index e2b5185e8..bcdb57e65 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -34,6 +34,7 @@ #include "llattachmentsmgr.h" #include "llcommandhandler.h" #include "lleventtimer.h" +#include "llfloatercustomize.h" #include "llgesturemgr.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" @@ -53,8 +54,7 @@ #include "llhttpretrypolicy.h" #include "llaisapi.h" #include "llinventorypanel.h" -#include "llfloatercustomize.h" -// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) #include "rlvhandler.h" #include "rlvhelper.h" #include "rlvlocks.h" @@ -458,7 +458,7 @@ private: class LLTrackPhaseWrapper : public LLInventoryCallback { public: - LLTrackPhaseWrapper(const std::string& phase_name, LLPointer cb = NULL): + LLTrackPhaseWrapper(const std::string& phase_name, LLPointer cb = nullptr): mTrackingPhase(phase_name), mCB(cb) { @@ -526,6 +526,20 @@ LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy() U32 LLUpdateAppearanceOnDestroy::sActiveCallbacks = 0; +LLUpdateAppearanceAndEditWearableOnDestroy::LLUpdateAppearanceAndEditWearableOnDestroy(const LLUUID& item_id): + mItemID(item_id) +{ +} + +LLRequestServerAppearanceUpdateOnDestroy::~LLRequestServerAppearanceUpdateOnDestroy() +{ + LL_DEBUGS("Avatar") << "ATT requesting server appearance update" << LL_ENDL; + if (!LLApp::isExiting()) + { + LLAppearanceMgr::instance().requestServerAppearanceUpdate(); + } +} + void edit_wearable_and_customize_avatar(LLUUID item_id) { // Start editing the item if previously requested. @@ -537,7 +551,16 @@ void edit_wearable_and_customize_avatar(LLUUID item_id) // If we're in appearance editing mode, the current tab may need to be refreshed LLFloaterCustomize::getInstance()->switchToDefaultSubpart(); } +} +LLUpdateAppearanceAndEditWearableOnDestroy::~LLUpdateAppearanceAndEditWearableOnDestroy() +{ + if (!LLApp::isExiting()) + { + LLAppearanceMgr::instance().updateAppearanceFromCOF( + true,true, + boost::bind(edit_wearable_and_customize_avatar, mItemID)); + } } @@ -590,7 +613,7 @@ public: bool pollMissingWearables(); bool isMissingCompleted(); void recoverMissingWearable(LLWearableType::EType type); - void clearCOFLinksForMissingWearables(); +// void clearCOFLinksForMissingWearables(); void onWearableAssetFetch(LLViewerWearable *wearable); void onAllComplete(); @@ -603,7 +626,7 @@ public: found_list_t& getFoundList(); void eraseTypeToLink(LLWearableType::EType type); void eraseTypeToRecover(LLWearableType::EType type); - void setObjItems(const LLInventoryModel::item_array_t& items); +// void setObjItems(const LLInventoryModel::item_array_t& items); void setGestItems(const LLInventoryModel::item_array_t& items); bool isMostRecent(); void handleLateArrivals(); @@ -613,7 +636,7 @@ public: private: found_list_t mFoundList; - LLInventoryModel::item_array_t mObjItems; +// LLInventoryModel::item_array_t mObjItems; LLInventoryModel::item_array_t mGestItems; typedef std::set type_set_t; type_set_t mTypesToRecover; @@ -820,9 +843,15 @@ void LLWearableHoldingPattern::onAllComplete() // // pre-attachment states. // gAgentAvatarp->clearAttachmentPosOverrides(); // +// if (objects_to_remove.size() || items_to_add.size()) +// { +// LL_DEBUGS("Avatar") << "ATT will remove " << objects_to_remove.size() +// << " and add " << items_to_add.size() << " items" << LL_ENDL; +// } +// // // 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; @@ -1010,19 +1039,19 @@ bool LLWearableHoldingPattern::isMissingCompleted() return mTypesToLink.size()==0 && mTypesToRecover.size()==0; } -void LLWearableHoldingPattern::clearCOFLinksForMissingWearables() -{ - for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it) - { - LLFoundData &data = *it; - if ((data.mWearableType < LLWearableType::WT_COUNT) && (!data.mWearable)) - { - // Wearable link that was never resolved; remove links to it from COF - LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " removing link for unresolved item " << data.mItemID.asString() << LL_ENDL; - LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID); - } - } -} +//void LLWearableHoldingPattern::clearCOFLinksForMissingWearables() +//{ +// for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it) +// { +// LLFoundData &data = *it; +// if ((data.mWearableType < LLWearableType::WT_COUNT) && (!data.mWearable)) +// { +// // Wearable link that was never resolved; remove links to it from COF +// LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " removing link for unresolved item " << data.mItemID.asString() << LL_ENDL; +// LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID); +// } +// } +//} // [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0) bool LLWearableHoldingPattern::pollStopped() @@ -1219,6 +1248,7 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLViewerWearable *wearable) if(wearable->getAssetID() == data.mAssetID) { // Failing this means inventory or asset server are corrupted in a way we don't handle. + // Singu Note: This code conflict exists because we correct corrupted clothing items to their correct wearable type. if (data.mWearableType >= LLWearableType::WT_COUNT || wearable->getType() >= LLWearableType::WT_UNKNOWN || (data.mWearableType != wearable->getType() && @@ -1295,20 +1325,24 @@ static void removeDuplicateItems(LLInventoryModel::item_array_t& items) items = new_items; } -// [SL:KB] - Patch: Appearance-WearableDuplicateAssets | Checked: 2011-07-24 (Catznip-2.6.0e) | Added: Catznip-2.6.0e +//========================================================================= + +// [SL:KB] - Patch: Appearance-WearableDuplicateAssets | Checked: 2015-06-30 (Catznip-3.7) static void removeDuplicateWearableItemsByAssetID(LLInventoryModel::item_array_t& items) { std::set idsAsset; - for (S32 idxItem = items.size() - 1; idxItem >= 0; idxItem--) - { - const LLViewerInventoryItem* pItem = items.at(idxItem); - if (!pItem->isWearableType()) - continue; - if (idsAsset.end() == idsAsset.find(pItem->getAssetUUID())) - idsAsset.insert(pItem->getAssetUUID()); - else - items.erase(items.begin() + idxItem); - } + items.erase(std::remove_if(items.begin(), items.end(), + [&idsAsset](const LLViewerInventoryItem* pItem) + { + if (pItem->isWearableType()) + { + const LLUUID& idAsset = pItem->getAssetUUID(); + if ( (idAsset.notNull()) && (idsAsset.end() != idsAsset.find(idAsset)) ) + return true; + idsAsset.insert(idAsset); + } + return false; + }), items.end()); } // [/SL:KB] @@ -1396,7 +1430,7 @@ const LLUUID LLAppearanceMgr::getBaseOutfitUUID() return outfit_cat->getUUID(); } -void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace/*= false*/) +void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace = false) { if (inv_item.isNull()) return; @@ -1426,43 +1460,63 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear, const LLUUID& item_id_to_wear = *it; - if (item_id_to_wear.isNull()) continue; + if (item_id_to_wear.isNull()) + { + LL_DEBUGS("Avatar") << "null id " << item_id_to_wear << LL_ENDL; + continue; + } LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear); - if (!item_to_wear) continue; + if (!item_to_wear) + { + LL_DEBUGS("Avatar") << "inventory item not found for id " << item_id_to_wear << LL_ENDL; + continue; + } if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID())) { + LL_DEBUGS("Avatar") << "inventory item in library, will copy and wear " + << item_to_wear->getName() << " id " << item_id_to_wear << LL_ENDL; LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb,_1,replace)); - copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(), cb); + copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), + item_to_wear->getUUID(), LLUUID::null, std::string(), cb); continue; } else if (!gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getRootFolderID())) { - continue; // not in library and not in agent's inventory + // not in library and not in agent's inventory + LL_DEBUGS("Avatar") << "inventory item not in user inventory or library, skipping " + << item_to_wear->getName() << " id " << item_id_to_wear << LL_ENDL; + continue; } else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH))) { LLNotificationsUtil::add("CannotWearTrash"); + LL_DEBUGS("Avatar") << "inventory item is in trash, skipping " + << item_to_wear->getName() << " id " << item_id_to_wear << LL_ENDL; continue; } else if (isLinkedInCOF(item_to_wear->getUUID())) // EXT-84911 { + LL_DEBUGS("Avatar") << "inventory item is already in COF, skipping " + << item_to_wear->getName() << " id " << item_id_to_wear << LL_ENDL; continue; } + /* Singu TODO: Find out why this was here, it wasn't in any upstream so I've commented it out. ~Liru else if (item_to_wear->isWearableType()) { LLViewerWearable* wearable = gAgentWearables.getWearableFromAssetID(item_to_wear->getAssetUUID()); if (wearable && (!replace || wearable != gAgentWearables.getTopWearable(item_to_wear->getWearableType()))) continue; } + */ // [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)) ) - { - continue; - } + 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)) ) + { + continue; + } // [/RLVa:KB] switch (item_to_wear->getType()) @@ -1473,7 +1527,7 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear, { if (!cb && do_update) { - cb = new LLUpdateAppearanceOnDestroy(true, true, boost::bind(&edit_wearable_and_customize_avatar, item_id_to_wear)); + cb = new LLUpdateAppearanceAndEditWearableOnDestroy(item_id_to_wear); } LLWearableType::EType type = item_to_wear->getWearableType(); S32 wearable_count = gAgentWearables.getWearableCount(type); @@ -1498,11 +1552,11 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear, // Remove the existing wearables of the same type. // Remove existing body parts anyway because we must not be able to wear e.g. two skins. + removeCOFLinksOfType(item_to_wear->getWearableType()); if (!cb && do_update) { - cb = new LLUpdateAppearanceOnDestroy(true, true, boost::bind(&edit_wearable_and_customize_avatar, item_id_to_wear)); + cb = new LLUpdateAppearanceAndEditWearableOnDestroy(item_id_to_wear); } - removeCOFLinksOfType(item_to_wear->getWearableType(), NULL, true); items_to_link.push_back(item_to_wear); } break; @@ -1723,12 +1777,6 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL LLInventoryModel::cat_array_t* cats; LLInventoryModel::item_array_t* items; gInventory.getDirectDescendentsOf(src_id, cats, items); - LL_INFOS() << "copying " << items->size() << " items" << LL_ENDL; - copyItems(dst_id, items, cb); -} - -void LLAppearanceMgr::copyItems(const LLUUID& dst_id, LLInventoryModel::item_array_t* items, LLPointer cb) -{ LL_INFOS() << "copying " << items->size() << " items" << LL_ENDL; LLInventoryObject::const_object_list_t link_array; for (LLInventoryModel::item_array_t::const_iterator iter = items->begin(); @@ -1761,9 +1809,7 @@ void LLAppearanceMgr::copyItems(const LLUUID& dst_id, LLInventoryModel::item_arr case LLAssetType::AT_GESTURE: { if(!item->getPermissions().allowCopyBy(gAgent.getID())) - { link_array.push_back(LLConstPointer(item)); - } else { LL_DEBUGS("Avatar") << "copying inventory item " << item->getName() << LL_ENDL; @@ -1853,14 +1899,16 @@ bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id) { return false; } - - LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false); - // Singu Note: Diverge from LL here in order to dive into subfolder. - //return gInventory.hasMatchingDirectDescendent(outfit_cat_id, is_worn, true); - LLInventoryModel::item_array_t items; LLInventoryModel::cat_array_t cats; - gInventory.collectDescendentsIf(outfit_cat_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_worn, /*follow_folder_links=*/ true); - return items.size(); + LLInventoryModel::item_array_t items; + LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false); + gInventory.collectDescendentsIf(outfit_cat_id, + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + is_worn, + /*follow_folder_links=*/ true); + return items.size() > 0; } // static @@ -1938,9 +1986,9 @@ bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids) { ++n_clothes; } - else if (item->getType() == LLAssetType::AT_BODYPART) + else if (item->getType() == LLAssetType::AT_BODYPART || item->getType() == LLAssetType::AT_GESTURE) { - return false; //If we have a bodypart in selection we cannot use 'add'. + return isAgentAvatarValid(); } else { @@ -1982,24 +2030,6 @@ void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category, LLPointergetActualType() == LLAssetType::AT_LINK_FOLDER)) - continue; - if (item->getIsLinkType()) - { - remove_inventory_item(item->getUUID(), NULL); - } - } -} - // 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( @@ -2045,13 +2075,16 @@ void LLAppearanceMgr::filterWearableItems( // [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0) void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) { - 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; +// 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.0) + LL_INFOS("Avatar") << "starting" << LL_ENDL; +// [/RLVa:KB] LLInventoryModel::item_array_t body_items_new, wear_items_new, obj_items_new, gest_items_new; getDescendentsOfAssetType(category, body_items_new, LLAssetType::AT_BODYPART); @@ -2068,17 +2101,6 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, 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.0) - LL_INFOS("Avatar") << "starting" << LL_ENDL; -// [/RLVa:KB] - const LLUUID cof = getCOF(); // Deactivate currently active gestures in the COF, if replacing outfit @@ -2098,8 +2120,9 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, // Collect and filter descendents to determine new COF contents. - // - Body parts: always include COF contents as a fallback in case any - // required parts are missing. + // + // - Body parts: always include COF contents as a fallback in case any required parts are missing. + // // Preserve body parts from COF if appending. LLInventoryModel::item_array_t body_items; getDescendentsOfAssetType(cof, body_items, LLAssetType::AT_BODYPART); @@ -2117,7 +2140,9 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, removeDuplicateItems(body_items); filterWearableItems(body_items, 1, 0); + // // - Wearables: include COF contents only if appending. + // LLInventoryModel::item_array_t wear_items; if (append) getDescendentsOfAssetType(cof, wear_items, LLAssetType::AT_CLOTHING); @@ -2229,7 +2254,10 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, const LLUUID& base_id = (append) ? getBaseOutfitUUID() : idOutfit; LLViewerInventoryCategory* base_cat = (base_id.notNull()) ? gInventory.getCategory(base_id) : NULL; // [/RLVa:KB] - if (base_cat) +// if (base_cat) +// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-06-27 (Catznip-3.7) + if ((base_cat) && (base_cat->getPreferredType() == LLFolderType::FT_OUTFIT)) +// [/SL:KB] { LLSD base_contents; base_contents["name"] = base_cat->getName(); @@ -2238,7 +2266,8 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, base_contents["type"] = LLAssetType::AT_LINK_FOLDER; contents.append(base_contents); } - if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) + static LLCachedControl debug_ava_appr_msg(gSavedSettings, "DebugAvatarAppearanceMessage"); + if (debug_ava_appr_msg) { dump_sequential_xml(gAgentAvatarp->getFullname() + "_slam_request", contents); } @@ -2249,7 +2278,8 @@ void LLAppearanceMgr::updateCOF(LLInventoryModel::item_array_t& body_items_new, void LLAppearanceMgr::updatePanelOutfitName(const std::string& name) { - LLFloaterCustomize* panel_appearance = LLFloaterCustomize::instanceExists() ? LLFloaterCustomize::getInstance() : NULL; + LLFloaterCustomize* panel_appearance = + LLFloaterCustomize::instanceExists() ? LLFloaterCustomize::getInstance() : nullptr; if (panel_appearance) { panel_appearance->refreshCurrentOutfitName(name); @@ -2537,7 +2567,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, remove_non_link_items(obj_items); remove_non_link_items(gest_items); // [SL:KB] - Patch: Apperance-Misc | Checked: 2010-11-24 (Catznip-2.4) - // Since we're following folder links we might have picked up new duplicates, or exceeded MAX_CLOTHING_PER_TYPE + // Since we're following folder links we might have picked up new duplicates, or exceeded MAX_CLOTHING_LAYERS removeDuplicateItems(wear_items); removeDuplicateItems(obj_items); removeDuplicateItems(gest_items); @@ -2563,23 +2593,23 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, 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()) + std::set pendingAttachments; + if (LLAttachmentsMgr::instance().getPendingAttachments(pendingAttachments)) { - const LLUUID& idItem = *itPendingAttachLink; - if ( (!gAgentAvatarp->isWearingAttachment(idItem)) || (isLinkInCOF(idItem)) ) + for (const LLUUID& idAttachItem : pendingAttachments) { - itPendingAttachLink = mPendingAttachLinks.erase(itPendingAttachLink); - continue; - } + if ( (!gAgentAvatarp->isWearingAttachment(idAttachItem)) || (isLinkedInCOF(idAttachItem)) ) + { + LLAttachmentsMgr::instance().clearPendingAttachmentLink(idAttachItem); + continue; + } - LLViewerInventoryItem* pItem = gInventory.getItem(idItem); - if (pItem) - { - obj_items.push_back(pItem); + LLViewerInventoryItem* pAttachItem = gInventory.getItem(idAttachItem); + if (pAttachItem) + { + obj_items.push_back(pAttachItem); + } } - - ++itPendingAttachLink; } LL_DEBUGS("Avatar") << self_av_string() << "Updating " << obj_items.size() << " attachments" << LL_ENDL; @@ -2593,7 +2623,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, // 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(); + 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) @@ -2603,13 +2633,12 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, 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) + // 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; @@ -2639,19 +2668,19 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, // callback will be called (and this object deleted) // before the final getNextData(). + // Fault injection: use debug setting to test asset + // 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.2) + U32 missing_type = gSavedSettings.getU32("ForceMissingType"); +// [/RLVa:KB] + for(U32 i = 0; i < wear_items.size(); ++i) { LLViewerInventoryItem *item = wear_items.at(i); LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; - // Fault injection: use debug setting to test asset - // 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.2) - U32 missing_type = gSavedSettings.getU32("ForceMissingType"); -// [/RLVa:KB] - if (item && item->getIsLinkType() && linked_item) { LLFoundData found(linked_item->getUUID(), @@ -2731,7 +2760,18 @@ void LLAppearanceMgr::updateAppearanceFromInitialWearables(LLInventoryObject::co const LLUUID& idCOF = getCOF(); // Remove current COF contents - purgeCategory(idCOF, false); + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + gInventory.collectDescendents(idCOF, cats, items, + LLInventoryModel::EXCLUDE_TRASH); + for (U32 i = 0; i < items.size(); ++i) + { + LLViewerInventoryItem *item = items.at(i); + if (item->getIsLinkType()) + { + remove_inventory_item(item->getUUID(), NULL); + } + } // Create links to new COF contents LLPointer link_waiter = new LLUpdateAppearanceOnDestroy(); link_inventory_array(idCOF, initial_items, link_waiter); @@ -3051,15 +3091,17 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, item_array, LLInventoryModel::EXCLUDE_TRASH); bool linked_already = false; - - LLUUID remove_id; - for (U32 i=0; igetWearableType(); + const bool is_body_part = (wearable_type == LLWearableType::WT_SHAPE) + || (wearable_type == LLWearableType::WT_HAIR) + || (wearable_type == LLWearableType::WT_EYES) + || (wearable_type == LLWearableType::WT_SKIN); + if (inv_item->getLinkedUUID() == vitem->getLinkedUUID()) { linked_already = true; @@ -3068,13 +3110,17 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, // type? If so, new item will replace old. else if ((vitem->isWearableType()) && (vitem->getWearableType() == wearable_type)) { - if (remove_id.isNull() && !gAgentWearables.canAddWearable(wearable_type)) + if (is_body_part && inv_item->getIsLinkType()) + { + remove_inventory_item(inv_item->getUUID(), cb); + } + else if (!gAgentWearables.canAddWearable(wearable_type)) { // MULTI-WEARABLES: make sure we don't go over clothing limits - remove_id = inv_item->getUUID(); + remove_inventory_item(inv_item->getUUID(), cb); } // [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()) + else if ( (vitem->getWearableType() == wearable_type) && (vitem->getAssetUUID() == inv_item->getAssetUUID()) ) { // Only allow one wearable per unique asset linked_already = true; @@ -3085,10 +3131,6 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, if (!linked_already) { - if( remove_id.notNull() ) - { - remove_inventory_item(remove_id, cb); - } LLViewerInventoryItem *copy_item = new LLViewerInventoryItem; copy_item->copyViewerItem(vitem); copy_item->setDescription(description); @@ -3098,26 +3140,21 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, LLInventoryModel::item_array_t LLAppearanceMgr::findCOFItemLinks(const LLUUID& item_id) { - LLInventoryModel::item_array_t result; - const LLViewerInventoryItem *vitem = - dynamic_cast(gInventory.getItem(item_id)); - if (vitem) + LLUUID linked_id = gInventory.getLinkedItemID(item_id); + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + gInventory.collectDescendents(LLAppearanceMgr::getCOF(), + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH); + for (U32 i=0; igetLinkedUUID() == linked_id) { - const LLViewerInventoryItem* inv_item = item_array.at(i).get(); - if (inv_item->getLinkedUUID() == vitem->getLinkedUUID()) - { - result.push_back(item_array.at(i)); - } + result.push_back(item_array.at(i)); } } return result; @@ -3757,6 +3794,69 @@ void RequestAgentUpdateAppearanceResponder::sendRequest() gAgentAvatarp->mLastUpdateRequestCOFVersion = cof_version; } +LLSD LLAppearanceMgr::dumpCOF() const +{ + LLSD links = LLSD::emptyArray(); + LLMD5 md5; + + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + gInventory.collectDescendents(getCOF(),cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH); + for (U32 i=0; igetUUID()); + md5.update((unsigned char*)item_id.mData, 16); + item["description"] = inv_item->getActualDescription(); + md5.update(inv_item->getActualDescription()); + item["asset_type"] = inv_item->getActualType(); + LLUUID linked_id(inv_item->getLinkedUUID()); + item["linked_id"] = linked_id; + md5.update((unsigned char*)linked_id.mData, 16); + + if (LLAssetType::AT_LINK == inv_item->getActualType()) + { + const LLViewerInventoryItem* linked_item = inv_item->getLinkedItem(); + if (NULL == linked_item) + { + LL_WARNS() << "Broken link for item '" << inv_item->getName() + << "' (" << inv_item->getUUID() + << ") during requestServerAppearanceUpdate" << LL_ENDL; + continue; + } + // Some assets may be 'hidden' and show up as null in the viewer. + //if (linked_item->getAssetUUID().isNull()) + //{ + // LL_WARNS() << "Broken link (null asset) for item '" << inv_item->getName() + // << "' (" << inv_item->getUUID() + // << ") during requestServerAppearanceUpdate" << LL_ENDL; + // continue; + //} + LLUUID linked_asset_id(linked_item->getAssetUUID()); + md5.update((unsigned char*)linked_asset_id.mData, 16); + U32 flags = linked_item->getFlags(); + md5.update(boost::lexical_cast(flags)); + } + else if (LLAssetType::AT_LINK_FOLDER != inv_item->getActualType()) + { + LL_WARNS() << "Non-link item '" << inv_item->getName() + << "' (" << inv_item->getUUID() + << ") type " << (S32) inv_item->getActualType() + << " during requestServerAppearanceUpdate" << LL_ENDL; + continue; + } + links.append(item); + } + LLSD result = LLSD::emptyMap(); + result["cof_contents"] = links; + char cof_md5sum[MD5HEX_STR_SIZE]; + md5.finalize(); + md5.hex_digest(cof_md5sum); + result["cof_md5sum"] = std::string(cof_md5sum); + return result; +} + void RequestAgentUpdateAppearanceResponder::debugCOF(const LLSD& content) { LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger() @@ -3800,8 +3900,8 @@ void RequestAgentUpdateAppearanceResponder::debugCOF(const LLSD& content) LLInventoryModel::cat_array_t cat_array; LLInventoryModel::item_array_t item_array; gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(), - cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH); - for (U32 i=0; igetUUID()); @@ -3829,7 +3929,7 @@ void RequestAgentUpdateAppearanceResponder::debugCOF(const LLSD& content) ais_only++; } } - if (local_only==0 && ais_only==0) + if (local_only == 0 && ais_only == 0) { LL_INFOS("Avatar") << "COF contents identical, only version numbers differ (req " << content["observed"].asInteger() @@ -3901,170 +4001,12 @@ void RequestAgentUpdateAppearanceResponder::onFailure() } -LLSD LLAppearanceMgr::dumpCOF() const -{ - LLSD links = LLSD::emptyArray(); - LLMD5 md5; - - LLInventoryModel::cat_array_t cat_array; - LLInventoryModel::item_array_t item_array; - gInventory.collectDescendents(getCOF(),cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH); - for (U32 i=0; igetUUID()); - md5.update((unsigned char*)item_id.mData, 16); - item["description"] = inv_item->getActualDescription(); - md5.update(inv_item->getActualDescription()); - item["asset_type"] = inv_item->getActualType(); - LLUUID linked_id(inv_item->getLinkedUUID()); - item["linked_id"] = linked_id; - md5.update((unsigned char*)linked_id.mData, 16); - - if (LLAssetType::AT_LINK == inv_item->getActualType()) - { - const LLViewerInventoryItem* linked_item = inv_item->getLinkedItem(); - if (NULL == linked_item) - { - LL_WARNS() << "Broken link for item '" << inv_item->getName() - << "' (" << inv_item->getUUID() - << ") during requestServerAppearanceUpdate" << LL_ENDL; - continue; - } - // Some assets may be 'hidden' and show up as null in the viewer. - //if (linked_item->getAssetUUID().isNull()) - //{ - // LL_WARNS() << "Broken link (null asset) for item '" << inv_item->getName() - // << "' (" << inv_item->getUUID() - // << ") during requestServerAppearanceUpdate" << LL_ENDL; - // continue; - //} - LLUUID linked_asset_id(linked_item->getAssetUUID()); - md5.update((unsigned char*)linked_asset_id.mData, 16); - U32 flags = linked_item->getFlags(); - md5.update(boost::lexical_cast(flags)); - } - else if (LLAssetType::AT_LINK_FOLDER != inv_item->getActualType()) - { - LL_WARNS() << "Non-link item '" << inv_item->getName() - << "' (" << inv_item->getUUID() - << ") type " << (S32) inv_item->getActualType() - << " during requestServerAppearanceUpdate" << LL_ENDL; - continue; - } - links.append(item); - } - LLSD result = LLSD::emptyMap(); - result["cof_contents"] = links; - char cof_md5sum[MD5HEX_STR_SIZE]; - md5.finalize(); - md5.hex_digest(cof_md5sum); - result["cof_md5sum"] = std::string(cof_md5sum); - return result; -} void LLAppearanceMgr::requestServerAppearanceUpdate() { mAppearanceResponder->onRequestRequested(); } -extern AIHTTPTimeoutPolicy incrementCofVersionResponder_timeout; -class LLIncrementCofVersionResponder : public LLHTTPClient::ResponderWithResult -{ - LOG_CLASS(LLIncrementCofVersionResponder); -public: - LLIncrementCofVersionResponder() : LLHTTPClient::ResponderWithResult() - { - mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 16.0, 2.0, 5); - } - - virtual ~LLIncrementCofVersionResponder() - { - } - -protected: - virtual void httpSuccess() - { - LL_INFOS() << "Successfully incremented agent's COF." << LL_ENDL; - const LLSD& content = getContent(); - if (!content.isMap()) - { - failureResult(400, "Malformed response contents", content); - return; - } - S32 new_version = content["category"]["version"].asInteger(); - - // cof_version should have increased - llassert(new_version > gAgentAvatarp->mLastUpdateRequestCOFVersion); - - gAgentAvatarp->mLastUpdateRequestCOFVersion = new_version; - } - - virtual void httpFailure() - { - LL_WARNS("Avatar") << "While attempting to increment the agent's cof we got an error " - << dumpResponse() << LL_ENDL; - F32 seconds_to_wait; - mRetryPolicy->onFailure(getStatus(), getResponseHeaders()); - if (mRetryPolicy->shouldRetry(seconds_to_wait)) - { - LL_INFOS() << "retrying" << LL_ENDL; - doAfterInterval(boost::bind(&LLAppearanceMgr::incrementCofVersion, - LLAppearanceMgr::getInstance(), - LLHTTPClient::ResponderPtr(this)), - seconds_to_wait); - } - else - { - LL_WARNS() << "giving up after too many retries" << LL_ENDL; - } - } - -private: - LLPointer mRetryPolicy; -protected: - /*virtual*/ char const* getName(void) const { return "LLIncrementCofVersionResponder"; } - /*virtual*/ bool needsHeaders() const { return true; } -}; - -void LLAppearanceMgr::incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr) -{ - // If we don't have a region, report it as an error - if (gAgent.getRegion() == NULL) - { - LL_WARNS() << "Region not set, cannot request cof_version increment" << LL_ENDL; - return; - } - - std::string url = gAgent.getRegion()->getCapability("IncrementCofVersion"); - if (url.empty()) - { - LL_WARNS() << "No cap for IncrementCofVersion." << LL_ENDL; - return; - } - - LL_INFOS() << "Requesting cof_version be incremented via capability to: " - << url << LL_ENDL; - LLSD body = LLSD::emptyMap(); - - if (!responder_ptr.get()) - { - responder_ptr = LLHTTPClient::ResponderPtr(new LLIncrementCofVersionResponder()); - } - - LLHTTPClient::get(url, body, responder_ptr); -} - -U32 LLAppearanceMgr::getNumAttachmentsInCOF() -{ - const LLUUID cof = getCOF(); - LLInventoryModel::item_array_t obj_items; - getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT); - return obj_items.size(); -} - - std::string LLAppearanceMgr::getAppearanceServiceURL() const { if (gSavedSettings.getString("AgentAppearanceServiceURL").empty()) @@ -4082,14 +4024,15 @@ void show_created_outfit(const LLUUID& folder_id, bool show_panel = true) return; } - LL_INFOS("Avatar") << "called" << LL_ENDL; + LL_DEBUGS("Avatar") << "called" << LL_ENDL; LLSD key; - //EXT-7727. For new accounts LLShowCreatedOutfit is created during login process - // add may be processed after login process is finished + //EXT-7727. For new accounts inventory callback is created during login process + // and may be processed after login process is finished // MULTI-WEARABLES TODO - /*if (mShowPanel) + /*if (show_panel) { + LL_DEBUGS("Avatar") << "showing panel" << LL_ENDL; LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key); } @@ -4097,7 +4040,7 @@ void show_created_outfit(const LLUUID& folder_id, bool show_panel = true) dynamic_cast(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab")); if (outfits_list) { - outfits_list->setSelectedOutfitByUUID(mFolderID); + outfits_list->setSelectedOutfitByUUID(folder_id); }*/ LLAppearanceMgr::getInstance()->updateIsDirty(); @@ -4108,7 +4051,7 @@ void show_created_outfit(const LLUUID& folder_id, bool show_panel = true) // link, since, the COF version has changed. There is a race // condition in initial outfit setup which can lead to rez // failures - SH-3860. - LL_INFOS("Avatar") << "requesting appearance update after createBaseOutfitLink" << LL_ENDL; + LL_DEBUGS("Avatar") << "requesting appearance update after createBaseOutfitLink" << LL_ENDL; LLPointer cb = new LLUpdateAppearanceOnDestroy; LLAppearanceMgr::getInstance()->createBaseOutfitLink(folder_id, cb); } @@ -4227,36 +4170,6 @@ public: if (!LLApp::isRunning() || mFailed) return; - /* Singu Note: This wasn't working when we detached copyable attachments early, changeOutfit instead - LLInventoryModel::item_array_t body_items, wear_items, obj_items, gest_items; - for(std::set::const_iterator it = mWearItems.begin(); it != mWearItems.end(); ++it) - { - LLViewerInventoryItem* item = gInventory.getItem(*it); - if(item) - { - switch(item->getType()) - { - case LLAssetType::AT_BODYPART: - body_items.push_back(item); - break; - case LLAssetType::AT_CLOTHING: - wear_items.push_back(item); - break; - case LLAssetType::AT_OBJECT: - obj_items.push_back(item); - break; - case LLAssetType::AT_GESTURE: - gest_items.push_back(item); - break; - default: - break; - } - } - } - - if(!body_items.empty() || !wear_items.empty() || !obj_items.empty() || !gest_items.empty()) - LLAppearanceMgr::instance().updateCOF(body_items, wear_items, obj_items, gest_items, false); - */ LLAppearanceMgr::instance().changeOutfit(true, mFolderID, false); } @@ -4513,6 +4426,16 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, LLP continue; } + LLViewerInventoryItem *item = gInventory.getItem(linked_item_id); + if (item && item->getType() == LLAssetType::AT_OBJECT) + { + LL_DEBUGS("Avatar") << "ATT removing attachment " << item->getName() << " id " << item->getUUID() << LL_ENDL; + } + if (item && item->getType() == LLAssetType::AT_BODYPART) + { + continue; + } + if (!cb) cb = new LLUpdateAppearanceOnDestroy(); removeCOFItemLinks(linked_item_id, cb, immediate_delete); @@ -4546,28 +4469,12 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, LLP 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(linked_item_id)) ) - { - return; - } -// [/RLVA:KB] - + uuid_vec_t ids_to_remove; + ids_to_remove.push_back(id_to_remove); // [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7) - if (!cb) - { - cb = new LLUpdateAppearanceOnDestroy; - } - removeCOFItemLinks(linked_item_id, cb, immediate_delete); + removeItemsFromAvatar(ids_to_remove, 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); +// removeItemsFromAvatar(ids_to_remove); } @@ -4679,7 +4586,7 @@ void LLAppearanceMgr::dumpCat(const LLUUID& cat_id, const std::string& msg) S32 hitcount = 0; for(S32 i=0; igetName() <getAssetUUID(); } - LL_DEBUGS("Avatar") << self_av_string() << msg << " " << i << " " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << LL_ENDL; + LL_DEBUGS("Avatar") << self_av_string() << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << LL_ENDL; } } @@ -4731,12 +4638,6 @@ void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val) { 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) @@ -4758,94 +4659,34 @@ void dumpAttachmentSet(const std::set& atts, const std::string& msg) void LLAppearanceMgr::registerAttachment(const LLUUID& item_id) { + LLViewerInventoryItem *item = gInventory.getItem(item_id); + LL_DEBUGS("Avatar") << "ATT registering attachment " + << (item ? item->getName() : "UNKNOWN") << " " << item_id << LL_ENDL; 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) - { - // we have to pass do_update = true to call LLAppearanceMgr::updateAppearanceFromCOF. - // it will trigger gAgentWariables.notifyLoadingFinished() - // But it is not acceptable solution. See EXT-7777 - if (!isLinkedInCOF(item_id)) - { -// [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 - { - //LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL; - } + LLAttachmentsMgr::instance().onAttachmentArrived(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] + LLViewerInventoryItem *item = gInventory.getItem(item_id); + LL_DEBUGS("Avatar") << "ATT unregistering attachment " + << (item ? item->getName() : "UNKNOWN") << " " << item_id << LL_ENDL; + gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); - if (mAttachmentInvLinkEnabled) - { - LLAppearanceMgr::removeCOFItemLinks(item_id); - } - else - { - //LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL; - } -} - -// [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) + LLAttachmentsMgr::instance().onDetachCompleted(item_id); + if (mAttachmentInvLinkEnabled && isLinkedInCOF(item_id)) { - 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); - } + LL_DEBUGS("Avatar") << "ATT removing COF link for attachment " + << (item ? item->getName() : "UNKNOWN") << " " << item_id << LL_ENDL; + LLAppearanceMgr::removeCOFItemLinks(item_id); + } + else + { + //LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL; } } -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(); @@ -4857,14 +4698,6 @@ BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const return FALSE; } -// static -bool LLAppearanceMgr::isLinkInCOF(const LLUUID& obj_id) -{ - const LLUUID& target_id = gInventory.getLinkedItemID(obj_id); - LLLinkedItemIDMatches find_links(target_id); - return gInventory.hasMatchingDirectDescendent(LLAppearanceMgr::instance().getCOF(), find_links); -} - BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const { if (!getIsInCOF(obj_id)) return FALSE; @@ -4983,10 +4816,56 @@ void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb) } } +void add_wearable_type_counts(const uuid_vec_t& ids, + S32& clothing_count, + S32& bodypart_count, + S32& object_count, + S32& other_count) +{ + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + const LLUUID& item_id_to_wear = *it; + LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear); + if (item_to_wear) + { + if (item_to_wear->getType() == LLAssetType::AT_CLOTHING) + { + clothing_count++; + } + else if (item_to_wear->getType() == LLAssetType::AT_BODYPART) + { + bodypart_count++; + } + else if (item_to_wear->getType() == LLAssetType::AT_OBJECT) + { + object_count++; + } + else + { + other_count++; + } + } + else + { + other_count++; + } + } +} + void wear_multiple(const uuid_vec_t& ids, bool replace) { - LLPointer cb = new LLUpdateAppearanceOnDestroy; - LLAppearanceMgr::instance().wearItemsOnAvatar(ids, false, replace, cb); + S32 clothing_count = 0; + S32 bodypart_count = 0; + S32 object_count = 0; + S32 other_count = 0; + add_wearable_type_counts(ids, clothing_count, bodypart_count, object_count, other_count); + + LLPointer cb = NULL; + if (clothing_count > 0 || bodypart_count > 0) + { + cb = new LLUpdateAppearanceOnDestroy; + } + LLAppearanceMgr::instance().wearItemsOnAvatar(ids, true, replace, cb); } // SLapp for easy-wearing of a stock (library) avatar diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 70323b526..2aee3a578 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -58,7 +58,6 @@ public: // [SL:KB] - Patch: Appearance-MixedViewers | Checked: 2010-04-02 (Catznip-3.0.0a) | Added: Catznip-2.0.0a void updateAppearanceFromInitialWearables(LLInventoryObject::const_object_list_t& initial_items); // [/SL:KB] - bool needToSaveCOF(); void updateCOF(const LLUUID& category, bool append = false); // [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, @@ -115,7 +114,6 @@ public: // Copy all items in a category. void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, LLPointer cb); - void copyItems(const LLUUID& dst_id, LLInventoryModel::item_array_t* items, LLPointer cb); // Find the Current Outfit folder. const LLUUID getCOF() const; @@ -156,6 +154,9 @@ public: // Attachment link management void unregisterAttachment(const LLUUID& item_id); void registerAttachment(const LLUUID& item_id); +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2015-06-24 (Catznip-3.7) + bool getAttachmentInvLinkEnable() { return mAttachmentInvLinkEnabled; } +// [/SL:KB] void setAttachmentInvLinkEnable(bool val); // Add COF link to individual item. @@ -246,13 +247,6 @@ public: void requestServerAppearanceUpdate(); - void incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr = NULL); - - U32 getNumAttachmentsInCOF(); - - // *HACK Remove this after server side texture baking is deployed on all sims. - void incrementCofVersionLegacy(); - void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; } std::string getAppearanceServiceURL() const; @@ -279,11 +273,8 @@ private: LLInventoryModel::item_array_t& gest_items, bool follow_folder_links = false); - void purgeCategory(const LLUUID& category, bool keep_outfit_links); - static void onOutfitRename(const LLSD& notification, const LLSD& response); - bool mAttachmentInvLinkEnabled; bool mOutfitIsDirty; bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls. @@ -304,15 +295,6 @@ 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: @@ -320,11 +302,6 @@ public: BOOL getIsInCOF(const LLUUID& obj_id) const; // Is this in the COF and can the user delete it from the COF? BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const; - - /** - * Checks if COF contains link to specified object. - */ - static bool isLinkInCOF(const LLUUID& obj_id); }; class LLUpdateAppearanceOnDestroy: public LLInventoryCallback @@ -344,22 +321,29 @@ private: nullary_func_t mPostUpdateFunc; }; -// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-08-31 (Catznip-2.1) -class LLRegisterAttachmentCallback : public LLInventoryCallback +class LLUpdateAppearanceAndEditWearableOnDestroy: 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] -void edit_wearable_and_customize_avatar(LLUUID item_id); + LLUpdateAppearanceAndEditWearableOnDestroy(const LLUUID& item_id); + /* virtual */ void fire(const LLUUID& item_id) {} + + ~LLUpdateAppearanceAndEditWearableOnDestroy(); + +private: + LLUUID mItemID; +}; + +class LLRequestServerAppearanceUpdateOnDestroy: public LLInventoryCallback +{ +public: + LLRequestServerAppearanceUpdateOnDestroy() {} + ~LLRequestServerAppearanceUpdateOnDestroy(); + + /* virtual */ void fire(const LLUUID& item_id) {} +}; + +void edit_wearable_and_customize_avatar(LLUUID item_id); LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 124fbffe1..e79d75679 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -253,16 +253,18 @@ BOOL get_is_parent_to_worn_item(const LLUUID& id) return FALSE; } + BOOL get_is_item_worn(const LLInventoryItem *item) { if (!item) return FALSE; // Consider the item as worn if it has links in COF. - /* if (LLCOFMgr::instance().isLinkInCOF(item->getUUID())) - { REMOVED due to advice from Kitty Barnett, looks like it WILL cause trouble on some grids -SG - return TRUE; - } */ +// [SL:KB] - The code below causes problems across the board so it really just needs to go +// if (LLAppearanceMgr::instance().isLinkedInCOF(id)) +// { +// return TRUE; +// } switch(item->getType()) { @@ -298,7 +300,7 @@ BOOL get_can_item_be_worn(const LLUUID& id) if (!item) return FALSE; - if (LLAppearanceMgr::isLinkInCOF(item->getLinkedUUID())) + if (LLAppearanceMgr::isLinkedInCOF(item->getLinkedUUID())) { // an item having links in COF (i.e. a worn item) return FALSE;