private void AddLibraryFolders(List <LLSDFetchInventoryDescendents> fetchFolders, List <InventoryCollectionWithDescendents> result)
        {
            InventoryFolderImpl fold;

            if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null)
            {
                List <LLSDFetchInventoryDescendents> libfolders = fetchFolders.FindAll(f => f.owner_id == m_LibraryService.LibraryRootFolder.Owner);
                fetchFolders.RemoveAll(f => libfolders.Contains(f));

                //m_log.DebugFormat("[XXX]: Found {0} library folders in request", libfolders.Count);

                foreach (LLSDFetchInventoryDescendents f in libfolders)
                {
                    if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null)
                    {
                        InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents();
                        ret.Collection          = new InventoryCollection();
                        ret.Collection.Folders  = new List <InventoryFolderBase>();
                        ret.Collection.Items    = fold.RequestListOfItems();
                        ret.Collection.OwnerID  = m_LibraryService.LibraryRootFolder.Owner;
                        ret.Collection.FolderID = f.folder_id;
                        ret.Collection.Version  = fold.Version;

                        ret.Descendents = ret.Collection.Items.Count;
                        result.Add(ret);

                        //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID);
                    }
                }
            }
        }
Esempio n. 2
0
        private List <InventoryCollectionWithDescendents> Fetch(List <LLSDFetchInventoryDescendents> fetchFolders, List <UUID> bad_folders)
        {
            //m_log.DebugFormat(
            //    "[WEB FETCH INV DESC HANDLER]: Fetching {0} folders for owner {1}", fetchFolders.Count, fetchFolders[0].owner_id);

            // FIXME MAYBE: We're not handling sortOrder!

            List <InventoryCollectionWithDescendents> result = new List <InventoryCollectionWithDescendents>();

            AddLibraryFolders(fetchFolders, result);

            if (fetchFolders.Count > 0)
            {
                UUID[] fids = new UUID[fetchFolders.Count];
                int    i    = 0;
                foreach (LLSDFetchInventoryDescendents f in fetchFolders)
                {
                    fids[i++] = f.folder_id;
                }

                //m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids));

                InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(fetchFolders[0].owner_id, fids);

                if (fetchedContents == null || (fetchedContents != null && fetchedContents.Length == 0))
                {
                    //m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of multiple folders for user {0}", fetchFolders[0].owner_id);
                    return(null);
                }

                i = 0;
                // Do some post-processing. May need to fetch more from inv server for links
                foreach (InventoryCollection contents in fetchedContents)
                {
                    // Find the original request
                    LLSDFetchInventoryDescendents freq = fetchFolders[i++];

                    InventoryCollectionWithDescendents coll = new InventoryCollectionWithDescendents();
                    coll.Collection = contents;

                    if (BadFolder(freq, contents, bad_folders))
                    {
                        continue;
                    }

                    // Next: link management
                    ProcessLinks(freq, coll);

                    result.Add(coll);
                }
            }

            return(result);
        }
Esempio n. 3
0
        private void AddLibraryFolders(List <LLSDFetchInventoryDescendents> libFolders, List <InventoryCollectionWithDescendents> result)
        {
            InventoryFolderImpl fold;

            foreach (LLSDFetchInventoryDescendents f in libFolders)
            {
                if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null)
                {
                    InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents();
                    ret.Collection = new InventoryCollection();
//                        ret.Collection.Folders = new List<InventoryFolderBase>();
                    ret.Collection.Folders  = fold.RequestListOfFolders();
                    ret.Collection.Items    = fold.RequestListOfItems();
                    ret.Collection.OwnerID  = m_LibraryService.LibraryRootFolder.Owner;
                    ret.Collection.FolderID = f.folder_id;
                    ret.Collection.Version  = fold.Version;

                    ret.Descendents = ret.Collection.Items.Count + ret.Collection.Folders.Count;
                    result.Add(ret);

                    //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID);
                }
            }
        }
        private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollectionWithDescendents coll)
        {
            InventoryCollection contents = coll.Collection;

            if (freq.fetch_items && contents.Items != null)
            {
                List <InventoryItemBase> itemsToReturn = contents.Items;

                // descendents must only include the links, not the linked items we add
                coll.Descendents = itemsToReturn.Count;

                // Add target items for links in this folder before the links themselves.
                List <UUID> itemIDs   = new List <UUID>();
                List <UUID> folderIDs = new List <UUID>();
                foreach (InventoryItemBase item in itemsToReturn)
                {
                    //m_log.DebugFormat("[XXX]:   {0} {1}", item.Name, item.AssetType);
                    if (item.AssetType == (int)AssetType.Link)
                    {
                        itemIDs.Add(item.AssetID);
                    }

                    else if (item.AssetType == (int)AssetType.LinkFolder)
                    {
                        folderIDs.Add(item.AssetID);
                    }
                }

                //m_log.DebugFormat("[XXX]: folder {0} has {1} links and {2} linkfolders", contents.FolderID, itemIDs.Count, folderIDs.Count);

                // Scan for folder links and insert the items they target and those links at the head of the return data
                if (folderIDs.Count > 0)
                {
                    InventoryCollection[] linkedFolders = m_InventoryService.GetMultipleFoldersContent(coll.Collection.OwnerID, folderIDs.ToArray());
                    foreach (InventoryCollection linkedFolderContents in linkedFolders)
                    {
                        if (linkedFolderContents == null)
                        {
                            continue;
                        }

                        List <InventoryItemBase> links = linkedFolderContents.Items;

                        itemsToReturn.InsertRange(0, links);
                    }
                }

                if (itemIDs.Count > 0)
                {
                    InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray());
                    if (linked == null)
                    {
                        // OMG!!! One by one!!! This is fallback code, in case the backend isn't updated
                        m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one.");
                        linked = new InventoryItemBase[itemIDs.Count];
                        int i = 0;
                        InventoryItemBase item = new InventoryItemBase();
                        item.Owner = freq.owner_id;
                        foreach (UUID id in itemIDs)
                        {
                            item.ID     = id;
                            linked[i++] = m_InventoryService.GetItem(item);
                        }
                    }

                    //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Processing folder {0}. Existing items:", freq.folder_id);
                    //foreach (InventoryItemBase item in itemsToReturn)
                    //    m_log.DebugFormat("[XXX]: {0} {1} {2}", item.Name, item.AssetType, item.Folder);

                    if (linked != null)
                    {
                        foreach (InventoryItemBase linkedItem in linked)
                        {
                            // Take care of genuinely broken links where the target doesn't exist
                            // HACK: Also, don't follow up links that just point to other links.  In theory this is legitimate,
                            // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
                            // rather than having to keep track of every folder requested in the recursion.
                            if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
                            {
                                itemsToReturn.Insert(0, linkedItem);
                                //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 5
0
        private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollectionWithDescendents coll)
        {
            InventoryCollection contents = coll.Collection;

            if (freq.fetch_items && contents.Items != null)
            {
                // viewers are lasy and want a copy of the linked item sent before the link to it

                // descendents must only include the links, not the linked items we add
                coll.Descendents = contents.Items.Count + contents.Folders.Count;

                // look for item links
                List <UUID> itemIDs = new List <UUID>();
                foreach (InventoryItemBase item in contents.Items)
                {
                    //m_log.DebugFormat("[XXX]:   {0} {1}", item.Name, item.AssetType);
                    if (item.AssetType == (int)AssetType.Link)
                    {
                        itemIDs.Add(item.AssetID);
                    }
                }

                // get the linked if any
                if (itemIDs.Count > 0)
                {
                    InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray());
                    if (linked == null)
                    {
                        // OMG!!! One by one!!! This is fallback code, in case the backend isn't updated
                        m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one.");
                        linked = new InventoryItemBase[itemIDs.Count];
                        int i = 0;
                        foreach (UUID id in itemIDs)
                        {
                            linked[i++] = m_InventoryService.GetItem(freq.owner_id, id);
                        }
                    }

                    if (linked != null)
                    {
                        List <InventoryItemBase> linkedItems = new List <InventoryItemBase>();
                        // check for broken
                        foreach (InventoryItemBase linkedItem in linked)
                        {
                            // Take care of genuinely broken links where the target doesn't exist
                            // HACK: Also, don't follow up links that just point to other links.  In theory this is legitimate,
                            // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
                            // rather than having to keep track of every folder requested in the recursion.
                            if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
                            {
                                linkedItems.Add(linkedItem);
                                //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder);
                            }
                        }
                        // insert them
                        if (linkedItems.Count > 0)
                        {
                            contents.Items.InsertRange(0, linkedItems);
                        }
                    }
                }
            }
        }
Esempio n. 6
0
        private List <InventoryCollectionWithDescendents> Fetch(List <LLSDFetchInventoryDescendents> fetchFolders, List <UUID> bad_folders)
        {
            //m_log.DebugFormat(
            //    "[WEB FETCH INV DESC HANDLER]: Fetching {0} folders for owner {1}", fetchFolders.Count, fetchFolders[0].owner_id);

            // FIXME MAYBE: We're not handling sortOrder!

            List <InventoryCollectionWithDescendents> result       = new List <InventoryCollectionWithDescendents>();
            List <LLSDFetchInventoryDescendents>      libFolders   = new List <LLSDFetchInventoryDescendents>();
            List <LLSDFetchInventoryDescendents>      otherFolders = new List <LLSDFetchInventoryDescendents>();
            HashSet <UUID> libIDs   = new HashSet <UUID>();
            HashSet <UUID> otherIDs = new HashSet <UUID>();

            bool dolib    = (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null);
            UUID libOwner = UUID.Zero;

            if (dolib)
            {
                libOwner = m_LibraryService.LibraryRootFolder.Owner;
            }

            // Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense
            // and can kill the sim (all root folders have parent_id Zero)
            // send something.
            bool doneZeroID = false;

            foreach (LLSDFetchInventoryDescendents f in fetchFolders)
            {
                if (f.folder_id == UUID.Zero)
                {
                    if (doneZeroID)
                    {
                        continue;
                    }
                    doneZeroID = true;
                    InventoryCollectionWithDescendents zeroColl = new InventoryCollectionWithDescendents();
                    zeroColl.Collection          = new InventoryCollection();
                    zeroColl.Collection.OwnerID  = f.owner_id;
                    zeroColl.Collection.Version  = 0;
                    zeroColl.Collection.FolderID = f.folder_id;
                    zeroColl.Descendents         = 0;
                    result.Add(zeroColl);
                    continue;
                }
                if (dolib && f.owner_id == libOwner)
                {
                    if (libIDs.Contains(f.folder_id))
                    {
                        continue;
                    }
                    libIDs.Add(f.folder_id);
                    libFolders.Add(f);
                    continue;
                }
                if (otherIDs.Contains(f.folder_id))
                {
                    continue;
                }
                otherIDs.Add(f.folder_id);
                otherFolders.Add(f);
            }

            if (otherFolders.Count > 0)
            {
                int i = 0;

                //m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids));

                InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(otherFolders[0].owner_id, otherIDs.ToArray());

                if (fetchedContents == null)
                {
                    return(null);
                }

                if (fetchedContents.Length == 0)
                {
                    foreach (LLSDFetchInventoryDescendents freq in otherFolders)
                    {
                        BadFolder(freq, null, bad_folders);
                    }
                }
                else
                {
                    i = 0;
                    // Do some post-processing. May need to fetch more from inv server for links
                    foreach (InventoryCollection contents in fetchedContents)
                    {
                        // Find the original request
                        LLSDFetchInventoryDescendents freq = otherFolders[i++];

                        InventoryCollectionWithDescendents coll = new InventoryCollectionWithDescendents();
                        coll.Collection = contents;

                        if (BadFolder(freq, contents, bad_folders))
                        {
                            continue;
                        }

                        // Next: link management
                        ProcessLinks(freq, coll);

                        result.Add(coll);
                    }
                }
            }

            if (dolib && libFolders.Count > 0)
            {
                AddLibraryFolders(libFolders, result);
            }

            return(result);
        }
Esempio n. 7
0
        private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollectionWithDescendents coll)
        {
            InventoryCollection contents = coll.Collection;

            if (freq.fetch_items && contents.Items != null)
            {
                List<InventoryItemBase> itemsToReturn = contents.Items;

                // descendents must only include the links, not the linked items we add
                coll.Descendents = itemsToReturn.Count;

                // Add target items for links in this folder before the links themselves.
                List<UUID> itemIDs = new List<UUID>();
                List<UUID> folderIDs = new List<UUID>();
                foreach (InventoryItemBase item in itemsToReturn)
                {
                    //m_log.DebugFormat("[XXX]:   {0} {1}", item.Name, item.AssetType);
                    if (item.AssetType == (int)AssetType.Link)
                        itemIDs.Add(item.AssetID);

//                    else if (item.AssetType == (int)AssetType.LinkFolder)
//                        folderIDs.Add(item.AssetID);
                }

                //m_log.DebugFormat("[XXX]: folder {0} has {1} links and {2} linkfolders", contents.FolderID, itemIDs.Count, folderIDs.Count);

                // Scan for folder links and insert the items they target and those links at the head of the return data
                if (folderIDs.Count > 0)
                {
                    InventoryCollection[] linkedFolders = m_InventoryService.GetMultipleFoldersContent(coll.Collection.OwnerID, folderIDs.ToArray());
                    foreach (InventoryCollection linkedFolderContents in linkedFolders)
                    {
                        if (linkedFolderContents == null)
                            continue;

                        List<InventoryItemBase> links = linkedFolderContents.Items;

                        itemsToReturn.InsertRange(0, links);

                    }
                }

                if (itemIDs.Count > 0)
                {
                    InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray());
                    if (linked == null)
                    {
                        // OMG!!! One by one!!! This is fallback code, in case the backend isn't updated
                        m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one.");
                        linked = new InventoryItemBase[itemIDs.Count];
                        int i = 0;
                        InventoryItemBase item = new InventoryItemBase();
                        item.Owner = freq.owner_id;
                        foreach (UUID id in itemIDs)
                        {
                            item.ID = id;
                            linked[i++] = m_InventoryService.GetItem(item);
                        }
                    }

                    //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Processing folder {0}. Existing items:", freq.folder_id);
                    //foreach (InventoryItemBase item in itemsToReturn)
                    //    m_log.DebugFormat("[XXX]: {0} {1} {2}", item.Name, item.AssetType, item.Folder);

                    if (linked != null)
                    {
                        foreach (InventoryItemBase linkedItem in linked)
                        {
                            // Take care of genuinely broken links where the target doesn't exist
                            // HACK: Also, don't follow up links that just point to other links.  In theory this is legitimate,
                            // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
                            // rather than having to keep track of every folder requested in the recursion.
                            if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
                            {
                                itemsToReturn.Insert(0, linkedItem);
                                //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder);
                            }
                        }
                    }
                }
            }

        }
Esempio n. 8
0
        private List<InventoryCollectionWithDescendents> Fetch(List<LLSDFetchInventoryDescendents> fetchFolders, List<UUID> bad_folders)
        {
            //m_log.DebugFormat(
            //    "[WEB FETCH INV DESC HANDLER]: Fetching {0} folders for owner {1}", fetchFolders.Count, fetchFolders[0].owner_id);

            // FIXME MAYBE: We're not handling sortOrder!

            List<InventoryCollectionWithDescendents> result = new List<InventoryCollectionWithDescendents>();

            AddLibraryFolders(fetchFolders, result);

            // Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense
            // and can kill the sim (all root folders have parent_id Zero)
            LLSDFetchInventoryDescendents zero = fetchFolders.Find(f => f.folder_id == UUID.Zero);
            if (zero != null)
            {
                fetchFolders.Remove(zero);
                BadFolder(zero, null, bad_folders);
            }

            if (fetchFolders.Count > 0)
            {
                UUID[] fids = new UUID[fetchFolders.Count];
                int i = 0;
                foreach (LLSDFetchInventoryDescendents f in fetchFolders)
                    fids[i++] = f.folder_id;

                //m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids));

                InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(fetchFolders[0].owner_id, fids);

                if (fetchedContents == null || (fetchedContents != null && fetchedContents.Length == 0))
                {
                    m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of multiple folders for user {0}", fetchFolders[0].owner_id);
                    foreach (LLSDFetchInventoryDescendents freq in fetchFolders)
                        BadFolder(freq, null, bad_folders);
                    return null;
                }

                i = 0;
                // Do some post-processing. May need to fetch more from inv server for links
                foreach (InventoryCollection contents in fetchedContents)
                {
                    // Find the original request
                    LLSDFetchInventoryDescendents freq = fetchFolders[i++];

                    InventoryCollectionWithDescendents coll = new InventoryCollectionWithDescendents();
                    coll.Collection = contents;

                    if (BadFolder(freq, contents, bad_folders))
                        continue;

                    // Next: link management
                    ProcessLinks(freq, coll);

                    result.Add(coll);
                }
            }

            return result;
        }
Esempio n. 9
0
        private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> fetchFolders, List<InventoryCollectionWithDescendents> result)
        {
            InventoryFolderImpl fold;
            if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null)
            {
                List<LLSDFetchInventoryDescendents> libfolders = fetchFolders.FindAll(f => f.owner_id == m_LibraryService.LibraryRootFolder.Owner);
                fetchFolders.RemoveAll(f => libfolders.Contains(f));

                //m_log.DebugFormat("[XXX]: Found {0} library folders in request", libfolders.Count);

                foreach (LLSDFetchInventoryDescendents f in libfolders)
                {
                    if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null)
                    {
                        InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents();
                        ret.Collection = new InventoryCollection();
                        ret.Collection.Folders = new List<InventoryFolderBase>();
                        ret.Collection.Items = fold.RequestListOfItems();
                        ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner;
                        ret.Collection.FolderID = f.folder_id;
                        ret.Collection.Version = fold.Version;

                        ret.Descendents = ret.Collection.Items.Count;
                        result.Add(ret);

                        //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID);
                    }
                }
            }
        }