diff --git a/indra/newview/rlvlocks.cpp b/indra/newview/rlvlocks.cpp index b7ac55da32..908fc9fd04 100644 --- a/indra/newview/rlvlocks.cpp +++ b/indra/newview/rlvlocks.cpp @@ -1138,7 +1138,7 @@ bool RlvFolderLocks::isLockedFolderEntry(const LLUUID& idFolder, int eSourceType } // Checked: 2011-03-27 (RLVa-1.3.0g) | Modified: RLVa-1.3.0g -bool RlvFolderLocks::isLockedFolder(LLUUID idFolder, ERlvLockMask eLockTypeMask, int eSourceTypeMask, folderlock_source_t* plockSource) const +bool RlvFolderLocks::isLockedFolder(LLUUID idFolder, ERlvLockMask eLockTypeMask, int eSourceTypeMask, std::list* pLockSourceList) const { // Sanity check - if there are no folder locks then we don't have to actually do anything if (!hasLockedFolder(eLockTypeMask)) @@ -1178,9 +1178,10 @@ bool RlvFolderLocks::isLockedFolder(LLUUID idFolder, ERlvLockMask eLockTypeMask, if (PERM_DENY == pLockDescr->eLockPermission) { - if (plockSource) - *plockSource = pLockDescr->lockSource; - return true; // Folder is explicitly denied, indicate locked folder to our caller + if (pLockSourceList) + pLockSourceList->push_back(pLockDescr->lockSource); + else + return true; // Folder is explicitly denied, indicate locked folder to our caller (unless it wants a list of all lock sources) } else if (PERM_ALLOW == pLockDescr->eLockPermission) { @@ -1192,6 +1193,14 @@ bool RlvFolderLocks::isLockedFolder(LLUUID idFolder, ERlvLockMask eLockTypeMask, const LLViewerInventoryCategory* pParent = gInventory.getCategory(idFolderCur); idFolderCur = (pParent) ? pParent->getParentUUID() : idFolderRoot; } + + if ( (pLockSourceList) && (!pLockSourceList->empty()) ) + { + // If we're asked to return a list, make sure it's sorted so we can compare them + pLockSourceList->sort([](const folderlock_source_t& lhs, const folderlock_source_t& rhs) { return lhs.first < rhs.first && lhs.second < rhs.second; }); + return true; + } + // If we didn't encounter an explicit deny lock with no exception then the folder is locked if the entire inventory is locked down return (m_RootLockType & eLockTypeMask) && (eSourceTypeMask & ST_ROOTFOLDER) && (idsRlvObjRem.empty()) && (idsRlvObjAdd.empty()); } diff --git a/indra/newview/rlvlocks.h b/indra/newview/rlvlocks.h index 61ab0acbb0..bdbfc35170 100644 --- a/indra/newview/rlvlocks.h +++ b/indra/newview/rlvlocks.h @@ -326,7 +326,7 @@ public: // Returns TRUE if the attachment (specified by item UUID) is non-detachable as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock bool isLockedAttachment(const LLUUID& idItem) const; // Returns TRUE if the folder is locked as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock - bool isLockedFolder(LLUUID idFolder, ERlvLockMask eLock, int eSourceTypeMask = ST_MASK_ANY, folderlock_source_t* plockSource = NULL) const; + bool isLockedFolder(LLUUID idFolder, ERlvLockMask eLock, int eSourceTypeMask = ST_MASK_ANY, std::list* pLockSourceList = nullptr) const; // Returns TRUE if the wearable (specified by item UUID) is non-removable as a result of a RLV_LOCK_REMOVE folder PERM_DENY lock bool isLockedWearable(const LLUUID& idItem) const; @@ -608,11 +608,11 @@ inline bool RlvFolderLocks::canMoveFolder(const LLUUID& idFolder, const LLUUID& // * folder locked + destination locked => allow move only if both are subject to the same folder lock // * folder unlocked + destination unlocked => allow move (special case of above since both locks are equal when there is none) // => so the above becomes (isLockedFolder(A) == isLockedFolder(B)) && (lockA == lockB) - folderlock_source_t lockSource(ST_NONE, 0), lockSourceDest(ST_NONE, 0); - return + std::list locksSource, locksSourceDest; + return (!hasLockedFolderDescendent(idFolder, ST_MASK_ANY, PERM_MASK_ANY, RLV_LOCK_ANY, true)) && - ( (isLockedFolder(idFolder, RLV_LOCK_ANY, ST_MASK_ANY, &lockSource) == isLockedFolder(idFolderDest, RLV_LOCK_ANY, ST_MASK_ANY, &lockSourceDest)) && - (lockSource == lockSourceDest) ); + ( (isLockedFolder(idFolder, RLV_LOCK_ANY, ST_MASK_ANY, &locksSource) == isLockedFolder(idFolderDest, RLV_LOCK_ANY, ST_MASK_ANY, &locksSourceDest)) && + (locksSource == locksSourceDest) ); } // Checked: 2011-03-29 (RLVa-1.3.0g) | Added: RLVa-1.3.0g @@ -644,11 +644,11 @@ inline bool RlvFolderLocks::canMoveItem(const LLUUID& idItem, const LLUUID& idFo // Block moving the folder to destination if: // - folder and destination are subject to different locks [see canMoveFolder() for more details] const LLViewerInventoryItem* pItem = gInventory.getItem(idItem); const LLUUID& idFolder = (pItem) ? pItem->getParentUUID() : LLUUID::null; - int maskSource = ST_MASK_ANY & ~ST_ROOTFOLDER; folderlock_source_t lockSource(ST_NONE, 0), lockSourceDest(ST_NONE, 0); - return - (idFolder.notNull()) && - (isLockedFolder(idFolder, RLV_LOCK_ANY, maskSource, &lockSource) == isLockedFolder(idFolderDest, RLV_LOCK_ANY, maskSource, &lockSourceDest)) && - (lockSource == lockSourceDest); + int maskSource = ST_MASK_ANY & ~ST_ROOTFOLDER; std::list locksSource, locksSourceDest; + return + (idFolder.notNull()) && + (isLockedFolder(idFolder, RLV_LOCK_ANY, maskSource, &locksSource) == isLockedFolder(idFolderDest, RLV_LOCK_ANY, maskSource, &locksSourceDest)) && + (locksSource == locksSourceDest); } // Checked: 2011-03-30 (RLVa-1.3.0g) | Added: RLVa-1.3.0g