diff options
| author | Jonathan "Geenz" Goodman <geenz@lindenlab.com> | 2026-08-17 20:30:20 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-17 20:30:20 -0400 |
| commit | 18648fc51e2a0c750182d8aa3814ed5b6bf8445e (patch) | |
| tree | 0517959512fc0d6876780641da88b74dd72aec5b /indra/newview/llattachmentsmgr.cpp | |
| parent | 6d4c4c029ce43aa413266135829cd2bc00001890 (diff) | |
| parent | 932e8ac318eb2e29ea519249348315b50c7d1d58 (diff) | |
Merge pull request #5638 from secondlife/release/26.3
Release/26.3
Diffstat (limited to 'indra/newview/llattachmentsmgr.cpp')
| -rw-r--r-- | indra/newview/llattachmentsmgr.cpp | 146 |
1 files changed, 59 insertions, 87 deletions
diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp index 8b5db2c0fa..f73d4241c9 100644 --- a/indra/newview/llattachmentsmgr.cpp +++ b/indra/newview/llattachmentsmgr.cpp @@ -42,10 +42,19 @@ const F32 MAX_ATTACHMENT_REQUEST_LIFETIME = 30.0F; const F32 MIN_RETRY_REQUEST_TIME = 5.0F; const F32 MAX_BAD_COF_TIME = 30.0F; +class LLRegisterAttachmentCallback : public LLRequestServerAppearanceUpdateOnDestroy +{ +public: + void fire(const LLUUID& item_id) override + { + LLAttachmentsMgr::instance().onRegisterAttachmentComplete(item_id); + LLRequestServerAppearanceUpdateOnDestroy::fire(item_id); + } +}; + LLAttachmentsMgr::LLAttachmentsMgr(): mAttachmentRequests("attach",MIN_RETRY_REQUEST_TIME), - mDetachRequests("detach",MIN_RETRY_REQUEST_TIME), - mQuestionableCOFLinks("badcof",MAX_BAD_COF_TIME) + mDetachRequests("detach",MIN_RETRY_REQUEST_TIME) { } @@ -80,6 +89,9 @@ void LLAttachmentsMgr::addAttachmentRequest(const LLUUID& item_id, void LLAttachmentsMgr::onAttachmentRequested(const LLUUID& item_id) { + if (item_id.isNull()) + return; + LLViewerInventoryItem *item = gInventory.getItem(item_id); LL_DEBUGS("Avatar") << "ATT attachment was requested " << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL; @@ -113,8 +125,6 @@ void LLAttachmentsMgr::onIdle() expireOldDetachRequests(); - checkInvalidCOFLinks(); - spamStatusInfo(); } @@ -222,6 +232,11 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments() { if (mRecentlyArrivedAttachments.size()) { + if (!LLAppearanceMgr::instance().getAttachmentInvLinkEnable()) + { + return; + } + // One or more attachments have arrived but have not yet been // processed for COF links if (mAttachmentRequests.empty()) @@ -268,17 +283,49 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments() } if (ids_to_link.size()) { - LLPointer<LLInventoryCallback> cb = new LLRequestServerAppearanceUpdateOnDestroy(); - for (uuid_vec_t::const_iterator uuid_it = ids_to_link.begin(); - uuid_it != ids_to_link.end(); ++uuid_it) + LLPointer<LLInventoryCallback> cb = new LLRegisterAttachmentCallback(); + for (const LLUUID& id_item: ids_to_link) { - LLAppearanceMgr::instance().addCOFItemLink(*uuid_it, cb); + if (std::find(mPendingAttachLinks.begin(), mPendingAttachLinks.end(), id_item) == mPendingAttachLinks.end()) + { + LLAppearanceMgr::instance().addCOFItemLink(id_item, cb); + mPendingAttachLinks.insert(id_item); + } } } mRecentlyArrivedAttachments.clear(); } } +bool LLAttachmentsMgr::getPendingAttachments(std::set<LLUUID>& ids) const +{ + ids.clear(); + + // Returns the combined set of attachments that are pending link creation and those that currently have an ongoing link creation process. + set_union(mRecentlyArrivedAttachments.begin(), mRecentlyArrivedAttachments.end(), mPendingAttachLinks.begin(), mPendingAttachLinks.end(), std::inserter(ids, ids.begin())); + + return !ids.empty(); +} + +void LLAttachmentsMgr::clearPendingAttachmentLink(const LLUUID& idItem) +{ + mPendingAttachLinks.erase(idItem); +} + +void LLAttachmentsMgr::onRegisterAttachmentComplete(const LLUUID& id_item_link) +{ + if (const LLUUID& id_item = gInventory.getLinkedItemID(id_item_link); id_item != id_item_link) + { + clearPendingAttachmentLink(id_item); + + // It may have been detached already in which case we should remove the COF link + if ( isAgentAvatarValid() && !gAgentAvatarp->isWearingAttachment(id_item) ) + { + LLAppearanceMgr::instance().removeCOFItemLinks(id_item); + } + } +} + LLAttachmentsMgr::LLItemRequestTimes::LLItemRequestTimes(const std::string& op_name, F32 timeout): mOpName(op_name), mTimeout(timeout) @@ -407,6 +454,8 @@ void LLAttachmentsMgr::onDetachRequested(const LLUUID& inv_item_id) void LLAttachmentsMgr::onDetachCompleted(const LLUUID& inv_item_id) { + clearPendingAttachmentLink(inv_item_id); + LLTimer timer; LLInventoryItem *item = gInventory.getItem(inv_item_id); if (mDetachRequests.getTime(inv_item_id, timer)) @@ -428,10 +477,6 @@ void LLAttachmentsMgr::onDetachCompleted(const LLUUID& inv_item_id) { LL_DEBUGS("Avatar") << "ATT detach on shutdown for " << (item ? item->getName() : "UNKNOWN") << " " << inv_item_id << LL_ENDL; } - - LL_DEBUGS("Avatar") << "ATT detached item flagging as questionable for COF link checking " - << (item ? item->getName() : "UNKNOWN") << " id " << inv_item_id << LL_ENDL; - mQuestionableCOFLinks.addTime(inv_item_id); } bool LLAttachmentsMgr::isAttachmentStateComplete() const @@ -440,81 +485,8 @@ bool LLAttachmentsMgr::isAttachmentStateComplete() const && mAttachmentRequests.empty() && mDetachRequests.empty() && mRecentlyArrivedAttachments.empty() - && mQuestionableCOFLinks.empty(); -} - -// Check for attachments that are (a) linked in COF and (b) not -// attached to the avatar. This is a rotten function to have to -// include, because it runs the risk of either repeatedly spamming out -// COF link removals if they're failing for some reason, or getting -// into a tug of war with some other sequence of events that's in the -// process of adding the attachment in question. However, it's needed -// because we have no definitive source of authority for what things -// are actually supposed to be attached. Scripts, run on the server -// side, can remove an attachment without our expecting it. If this -// happens to an attachment that's just been added, then the COF link -// creation may still be in flight, and we will have to delete the -// link after it shows up. -// -// Note that we only flag items for possible link removal if they have -// been previously detached. This means that an attachment failure -// will leave the link in the COF, where it will hopefully resolve -// correctly on relog. -// -// See related: MAINT-5070, MAINT-4409 -// -void LLAttachmentsMgr::checkInvalidCOFLinks() -{ - if (!gInventory.isInventoryUsable() || mQuestionableCOFLinks.empty()) - { - return; - } - 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 (S32 i=0; i<item_array.size(); i++) - { - const LLViewerInventoryItem* inv_item = item_array.at(i).get(); - const LLUUID& item_id = inv_item->getLinkedUUID(); - if (inv_item->getType() == LLAssetType::AT_OBJECT) - { - LLTimer timer; - bool is_flagged_questionable = mQuestionableCOFLinks.getTime(item_id,timer); - bool is_wearing_attachment = isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item_id); - if (is_wearing_attachment && is_flagged_questionable) - { - LL_DEBUGS("Avatar") << "ATT was flagged questionable but is now " - << (is_wearing_attachment ? "attached " : "") - <<"removing flag after " - << timer.getElapsedTimeF32() << " item " - << inv_item->getName() << " id " << item_id << LL_ENDL; - mQuestionableCOFLinks.removeTime(item_id); - } - } - } - - for(LLItemRequestTimes::iterator it = mQuestionableCOFLinks.begin(); - it != mQuestionableCOFLinks.end(); ) - { - LLItemRequestTimes::iterator curr_it = it; - ++it; - const LLUUID& item_id = curr_it->first; - LLViewerInventoryItem *inv_item = gInventory.getItem(item_id); - if (curr_it->second.getElapsedTimeF32() > MAX_BAD_COF_TIME) - { - if (LLAppearanceMgr::instance().isLinkedInCOF(item_id)) - { - LL_DEBUGS("Avatar") << "ATT Linked in COF but not attached or requested, deleting link after " - << curr_it->second.getElapsedTimeF32() << " seconds for " - << (inv_item ? inv_item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL; - LLAppearanceMgr::instance().removeCOFItemLinks(item_id); - } - mQuestionableCOFLinks.erase(curr_it); - continue; - } - } -} + && mPendingAttachLinks.empty(); + } void LLAttachmentsMgr::spamStatusInfo() { |
