示例#1
0
        public override InventoryItemBase GetItem(InventoryItemBase item)
        {
            string invServerURL = "", assetServerURL = "";

            if (GetHandlers.GetIsForeign(item.Owner, "InventoryServerURI", m_registry, out invServerURL))
            {
                XInventoryServicesConnector xinv = new XInventoryServicesConnector(invServerURL + "xinventory");
                InventoryItemBase           it   = xinv.GetItem(item);
                if (GetHandlers.GetIsForeign(item.Owner, "AssetServerURI", m_registry, out assetServerURL))
                {
                    GetAssets(it, assetServerURL + "assets");
                }
                return(it);
            }
            else
            {
                InventoryItemBase it = base.GetItem(item);
                if (it != null)
                {
                    UserAccount user = m_UserAccountService.GetUserAccount(null, UUID.Parse(it.CreatorId));

                    // Adjust the creator data
                    if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty))
                    {
                        it.CreatorData = GetHandlers.PROFILE_URL + "/" + it.CreatorId + ";" + user.FirstName + " " + user.LastName;
                    }
                }
                return(it);
            }
        }
示例#2
0
        private IDataReader GetForeignInventory(UUID AgentID, UUID folder_id, string serverURL)
        {
            FakeDataReader        d             = new FakeDataReader();
            IConfigurationService configService = m_registry.RequestModuleInterface <IConfigurationService>();

            if (serverURL == "" && configService != null)
            {
                List <string> urls = configService.FindValueOf("InventoryServerURI");
                if (urls.Count > 0)
                {
                    serverURL = urls[0];
                }
                else
                {
                    return(null);
                }
            }
            XInventoryServicesConnector xinv = new XInventoryServicesConnector(serverURL + "xinventory");
            InventoryCollection         c    = xinv.GetFolderContent(AgentID, folder_id);

            if (c != null)
            {
                foreach (InventoryItemBase item in c.Items)
                {
                    d.items.Add(item);
                }
            }
            return(d);
        }
示例#3
0
        public override bool AddFolder(InventoryFolderBase folder)
        {
            string invserverURL = "";

            if (GetHandlers.GetIsForeign(folder.Owner, "InventoryServerURI", m_registry, out invserverURL))
            {
                XInventoryServicesConnector xinv = new XInventoryServicesConnector(invserverURL + "xinventory");
                return(xinv.AddFolder(folder));
            }
            return(base.AddFolder(folder));
        }
示例#4
0
        public override InventoryFolderBase GetRootFolder(UUID principalID)
        {
            string invserverURL = "";

            if (GetHandlers.GetIsForeign(principalID, "InventoryServerURI", m_registry, out invserverURL))
            {
                XInventoryServicesConnector xinv = new XInventoryServicesConnector(invserverURL + "xinventory");
                return(xinv.GetRootFolder(principalID));
            }
            return(base.GetRootFolder(principalID));
        }
示例#5
0
        public override InventoryFolderBase GetFolderForType(UUID principalID, InventoryType invType, AssetType type)
        {
            string invserverURL = "";

            if (GetHandlers.GetIsForeign(principalID, "InventoryServerURI", m_registry, out invserverURL))
            {
                XInventoryServicesConnector xinv = new XInventoryServicesConnector(invserverURL + "xinventory");
                return(xinv.GetFolderForType(principalID, invType, type));
            }
            return(base.GetFolderForType(principalID, invType, type));
        }
示例#6
0
        public override bool AddItem(InventoryItemBase item)
        {
            string invserverURL = "";

            if (GetHandlers.GetIsForeign(item.Owner, "InventoryServerURI", m_registry, out invserverURL))
            {
                XInventoryServicesConnector xinv = new XInventoryServicesConnector(invserverURL + "xinventory");
                bool success = xinv.AddItem(item);
                return(success);
            }
            return(base.AddItem(item));
        }
示例#7
0
        public void Inventory_002_MultipleItemsRequest()
        {
            TestHelpers.InMethod();
            XInventoryServicesConnector m_Connector = new XInventoryServicesConnector(DemonServer.Address);

            // Prefetch Notecard 1, will be cached from here on
            InventoryItemBase item = new InventoryItemBase(new UUID("10000000-0000-0000-0000-000000000001"), m_userID);

            item = m_Connector.GetItem(item);
            Assert.NotNull(item, "Failed to get Notecard 1");
            Assert.AreEqual("Test Notecard 1", item.Name, "Wrong name for Notecard 1");

            UUID[] uuids = new UUID[2];
            uuids[0] = item.ID;
            uuids[1] = new UUID("20000000-0000-0000-0000-000000000002");

            InventoryItemBase[] items = m_Connector.GetMultipleItems(m_userID, uuids);
            Assert.NotNull(items, "Failed to get multiple items");
            Assert.IsTrue(items.Length == 2, "Requested 2 items, but didn't receive 2 items");

            // Now they should both be cached
            items = m_Connector.GetMultipleItems(m_userID, uuids);
            Assert.NotNull(items, "(Repeat) Failed to get multiple items");
            Assert.IsTrue(items.Length == 2, "(Repeat) Requested 2 items, but didn't receive 2 items");

            // This item doesn't exist, but [0] does, and it's cached.
            uuids[1] = new UUID("bb000000-0000-0000-0000-0000000000bb");
            // Fetching should return 2 items, but [1] should be null
            items = m_Connector.GetMultipleItems(m_userID, uuids);
            Assert.NotNull(items, "(Three times) Failed to get multiple items");
            Assert.IsTrue(items.Length == 2, "(Three times) Requested 2 items, but didn't receive 2 items");
            Assert.AreEqual("Test Notecard 1", items[0].Name, "(Three times) Wrong name for Notecard 1");
            Assert.IsNull(items[1], "(Three times) Expecting 2nd item to be null");

            // Now both don't exist
            uuids[0] = new UUID("aa000000-0000-0000-0000-0000000000aa");
            items    = m_Connector.GetMultipleItems(m_userID, uuids);
            Assert.Null(items[0], "Request to multiple non-existent items is supposed to return null [0]");
            Assert.Null(items[1], "Request to multiple non-existent items is supposed to return null [1]");

            // This item exists, and it's not cached
            uuids[1] = new UUID("b0000000-0000-0000-0000-00000000000b");
            // Fetching should return 2 items, but [0] should be null
            items = m_Connector.GetMultipleItems(m_userID, uuids);
            Assert.NotNull(items, "(Four times) Failed to get multiple items");
            Assert.IsTrue(items.Length == 2, "(Four times) Requested 2 items, but didn't receive 2 items");
            Assert.AreEqual("Some Object", items[1].Name, "(Four times) Wrong name for Some Object");
            Assert.IsNull(items[0], "(Four times) Expecting 1st item to be null");
        }
 public RemoteXInventoryServicesConnector(string url)
 {
     m_RemoteConnector = new XInventoryServicesConnector(url);
 }
 protected void Init(IConfigSource source)
 {
     m_RemoteConnector = new XInventoryServicesConnector(source);
 }
示例#10
0
        public void Inventory_001_CreateInventory()
        {
            TestHelpers.InMethod();
            XInventoryServicesConnector m_Connector = new XInventoryServicesConnector(DemonServer.Address);

            // Create an inventory that looks like this:
            //
            // /My Inventory
            //   <other system folders>
            //   /Objects
            //      Some Object
            //   /Notecards
            //      Notecard 1
            //      Notecard 2
            //   /Test Folder
            //      Link to notecard  -> /Notecards/Notecard 2
            //      Link to Objects folder -> /Objects

            bool success = m_Connector.CreateUserInventory(m_userID);

            Assert.IsTrue(success, "Failed to create user inventory");

            m_rootFolderID = m_Connector.GetRootFolder(m_userID).ID;
            Assert.AreNotEqual(m_rootFolderID, UUID.Zero, "Root folder ID must not be UUID.Zero");

            InventoryFolderBase of = m_Connector.GetFolderForType(m_userID, FolderType.Object);

            Assert.IsNotNull(of, "Failed to retrieve Objects folder");
            m_objectsFolder = of.ID;
            Assert.AreNotEqual(m_objectsFolder, UUID.Zero, "Objects folder ID must not be UUID.Zero");

            // Add an object
            InventoryItemBase item = new InventoryItemBase(new UUID("b0000000-0000-0000-0000-00000000000b"), m_userID);

            item.AssetID     = UUID.Random();
            item.AssetType   = (int)AssetType.Object;
            item.Folder      = m_objectsFolder;
            item.Name        = "Some Object";
            item.Description = string.Empty;
            success          = m_Connector.AddItem(item);
            Assert.IsTrue(success, "Failed to add object to inventory");

            InventoryFolderBase ncf = m_Connector.GetFolderForType(m_userID, FolderType.Notecard);

            Assert.IsNotNull(of, "Failed to retrieve Notecards folder");
            m_notecardsFolder = ncf.ID;
            Assert.AreNotEqual(m_notecardsFolder, UUID.Zero, "Notecards folder ID must not be UUID.Zero");
            m_notecardsFolder = ncf.ID;

            // Add a notecard
            item             = new InventoryItemBase(new UUID("10000000-0000-0000-0000-000000000001"), m_userID);
            item.AssetID     = UUID.Random();
            item.AssetType   = (int)AssetType.Notecard;
            item.Folder      = m_notecardsFolder;
            item.Name        = "Test Notecard 1";
            item.Description = string.Empty;
            success          = m_Connector.AddItem(item);
            Assert.IsTrue(success, "Failed to add Notecard 1 to inventory");
            // Add another notecard
            item.ID          = new UUID("20000000-0000-0000-0000-000000000002");
            item.AssetID     = new UUID("a0000000-0000-0000-0000-00000000000a");
            item.Name        = "Test Notecard 2";
            item.Description = string.Empty;
            success          = m_Connector.AddItem(item);
            Assert.IsTrue(success, "Failed to add Notecard 2 to inventory");

            // Add a folder
            InventoryFolderBase folder = new InventoryFolderBase(new UUID("f0000000-0000-0000-0000-00000000000f"), "Test Folder", m_userID, m_rootFolderID);

            folder.Type = (int)FolderType.None;
            success     = m_Connector.AddFolder(folder);
            Assert.IsTrue(success, "Failed to add Test Folder to inventory");

            // Add a link to notecard 2 in Test Folder
            item.AssetID     = item.ID; // use item ID of notecard 2
            item.ID          = new UUID("40000000-0000-0000-0000-000000000004");
            item.AssetType   = (int)AssetType.Link;
            item.Folder      = folder.ID;
            item.Name        = "Link to notecard";
            item.Description = string.Empty;
            success          = m_Connector.AddItem(item);
            Assert.IsTrue(success, "Failed to add link to notecard to inventory");

            // Add a link to the Objects folder in Test Folder
            item.AssetID     = m_Connector.GetFolderForType(m_userID, FolderType.Object).ID; // use item ID of Objects folder
            item.ID          = new UUID("50000000-0000-0000-0000-000000000005");
            item.AssetType   = (int)AssetType.LinkFolder;
            item.Folder      = folder.ID;
            item.Name        = "Link to Objects folder";
            item.Description = string.Empty;
            success          = m_Connector.AddItem(item);
            Assert.IsTrue(success, "Failed to add link to objects folder to inventory");

            InventoryCollection coll = m_Connector.GetFolderContent(m_userID, m_rootFolderID);

            Assert.IsNotNull(coll, "Failed to retrieve contents of root folder");
            Assert.Greater(coll.Folders.Count, 0, "Root folder does not have any subfolders");

            coll = m_Connector.GetFolderContent(m_userID, folder.ID);
            Assert.IsNotNull(coll, "Failed to retrieve contents of Test Folder");
            Assert.AreEqual(coll.Items.Count + coll.Folders.Count, 2, "Test Folder is expected to have exactly 2 things inside");
        }
示例#11
0
        public override byte[] FetchInventoryReply(OSDArray fetchRequest, UUID AgentID, UUID forceOwnerID, UUID libraryOwnerID)
        {
            LLSDSerializationDictionary contents = new LLSDSerializationDictionary();

            contents.WriteStartMap("llsd");      //Start llsd

            contents.WriteKey("folders");        //Start array items
            contents.WriteStartArray("folders"); //Start array folders

            foreach (OSD m in fetchRequest)
            {
                contents.WriteStartMap("internalContents"); //Start internalContents kvp
                OSDMap invFetch = (OSDMap)m;

                //UUID agent_id = invFetch["agent_id"].AsUUID();
                UUID owner_id      = invFetch["owner_id"].AsUUID();
                UUID folder_id     = invFetch["folder_id"].AsUUID();
                bool fetch_folders = invFetch["fetch_folders"].AsBoolean();
                bool fetch_items   = invFetch["fetch_items"].AsBoolean();
                int  sort_order    = invFetch["sort_order"].AsInteger();

                //Set the normal stuff
                contents["agent_id"]  = forceOwnerID == UUID.Zero ? owner_id : forceOwnerID;
                contents["owner_id"]  = forceOwnerID == UUID.Zero ? owner_id : forceOwnerID;
                contents["folder_id"] = folder_id;

                contents.WriteKey("items"); //Start array items
                contents.WriteStartArray("items");
                List <UUID> moreLinkedItems = new List <UUID>();
                int         count           = 0;
                bool        addToCount      = true;
                string      invServer       = "";
                bool        isForeign       = GetIsForeign(AgentID, "InventoryServerURI", m_registry, out invServer);
                IDataReader fretVal         = null;
                if (isForeign)
                {
                    fretVal = GetForeignInventory(AgentID, folder_id, invServer);
                }
                string query = String.Format("where {0} = '{1}'", "parentFolderID", folder_id,
                                             "avatarID", AgentID, "avatarID", libraryOwnerID);
redoQuery:
                using (IDataReader retVal = isForeign ? fretVal : GD.QueryData(query, m_itemsrealm, "*"))
                {
                    try
                    {
                        while (retVal.Read())
                        {
                            contents.WriteStartMap("item"); //Start item kvp
                            UUID assetID = UUID.Parse(retVal["assetID"].ToString());
                            contents["asset_id"] = assetID;
                            contents["name"]     = retVal["inventoryName"].ToString();
                            contents["desc"]     = retVal["inventoryDescription"].ToString();


                            contents.WriteKey("permissions"); //Start permissions kvp
                            contents.WriteStartMap("permissions");
                            contents["group_id"]       = UUID.Parse(retVal["groupID"].ToString());
                            contents["is_owner_group"] = int.Parse(retVal["groupOwned"].ToString()) == 1;
                            contents["group_mask"]     = uint.Parse(retVal["inventoryGroupPermissions"].ToString());
                            contents["owner_id"]       = forceOwnerID == UUID.Zero
                                                       ? UUID.Parse(retVal["avatarID"].ToString())
                                                       : forceOwnerID;
                            contents["last_owner_id"]   = UUID.Parse(retVal["avatarID"].ToString());
                            contents["next_owner_mask"] = uint.Parse(retVal["inventoryNextPermissions"].ToString());
                            contents["owner_mask"]      = uint.Parse(retVal["inventoryCurrentPermissions"].ToString());
                            UUID creator;
                            if (UUID.TryParse(retVal["creatorID"].ToString(), out creator))
                            {
                                contents["creator_id"] = creator;
                            }
                            else
                            {
                                contents["creator_id"] = UUID.Zero;
                            }
                            contents["base_mask"]     = uint.Parse(retVal["inventoryBasePermissions"].ToString());
                            contents["everyone_mask"] = uint.Parse(retVal["inventoryEveryOnePermissions"].ToString());
                            contents.WriteEndMap(/*Permissions*/);

                            contents.WriteKey("sale_info");      //Start permissions kvp
                            contents.WriteStartMap("sale_info"); //Start sale_info kvp
                            contents["sale_price"] = int.Parse(retVal["salePrice"].ToString());
                            switch (byte.Parse(retVal["saleType"].ToString()))
                            {
                            default:
                                contents["sale_type"] = "not";
                                break;

                            case 1:
                                contents["sale_type"] = "original";
                                break;

                            case 2:
                                contents["sale_type"] = "copy";
                                break;

                            case 3:
                                contents["sale_type"] = "contents";
                                break;
                            }
                            contents.WriteEndMap(/*sale_info*/);


                            contents["created_at"] = int.Parse(retVal["creationDate"].ToString());
                            contents["flags"]      = uint.Parse(retVal["flags"].ToString());
                            UUID inventoryID = UUID.Parse(retVal["inventoryID"].ToString());
                            contents["item_id"]   = inventoryID;
                            contents["parent_id"] = UUID.Parse(retVal["parentFolderID"].ToString());
                            UUID avatarID = forceOwnerID == UUID.Zero
                                                ? UUID.Parse(retVal["avatarID"].ToString())
                                                : forceOwnerID;
                            contents["agent_id"] = avatarID;

                            AssetType assetType = (AssetType)int.Parse(retVal["assetType"].ToString());
                            if (assetType == AssetType.Link)
                            {
                                moreLinkedItems.Add(assetID);
                            }
                            contents["type"] = Utils.AssetTypeToString(assetType);
                            InventoryType invType = (InventoryType)int.Parse(retVal["invType"].ToString());
                            contents["inv_type"] = Utils.InventoryTypeToString(invType);

                            if (addToCount)
                            {
                                count++;
                            }
                            contents.WriteEndMap(/*"item"*/);  //end array items
                        }
                    }
                    catch
                    {
                    }
                    finally
                    {
                        try
                        {
                            //Slow, and doesn't help, plus they get called by the using statement
                            //if (retVal != null)
                            //{
                            //    retVal.Close ();
                            //    retVal.Dispose ();
                            //}
                        }
                        catch
                        {
                        }
                        GD.CloseDatabase();
                    }
                }
                if (moreLinkedItems.Count > 0)
                {
                    addToCount = false;
                    query      = String.Format("where {0} = '{1}' and (", "avatarID", AgentID);
#if (!ISWIN)
                    foreach (UUID item in moreLinkedItems)
                    {
                        query = query + String.Format("{0} = '{1}' or ", "inventoryID", item);
                    }
#else
                    query = moreLinkedItems.Aggregate(query, (current, t) => current + String.Format("{0} = '{1}' or ", "inventoryID", t));
#endif
                    query  = query.Remove(query.Length - 4, 4);
                    query += ")";
                    if (isForeign)
                    {
                        fretVal = new FakeDataReader();
                        IConfigurationService configService = m_registry.RequestModuleInterface <IConfigurationService>();
                        if (invServer == "" && configService != null)
                        {
                            List <string> urls = configService.FindValueOf("InventoryServerURI");
                            if (urls.Count > 0)
                            {
                                invServer = urls[0];
                            }
                            else
                            {
                                return(null);
                            }
                        }
                        XInventoryServicesConnector xinv = new XInventoryServicesConnector(invServer + "xinventory");
                        foreach (UUID t in moreLinkedItems)
                        {
                            ((FakeDataReader)fretVal).items.Add(xinv.GetItem(new InventoryItemBase(t)));
                        }
                    }
                    moreLinkedItems.Clear();
                    goto redoQuery;
                }
                contents.WriteEndArray(/*"items"*/);    //end array items

                contents.WriteStartArray("categories"); //We don't send any folders
                int         version = 0;
                QueryFilter filter  = new QueryFilter();
                filter.andFilters["folderID"] = folder_id;
                List <string> versionRetVal = GD.Query(new string[2] {
                    "version", "type"
                }, m_foldersrealm, filter, null, null, null);
                List <InventoryFolderBase> foldersToAdd = new List <InventoryFolderBase>();
                if (versionRetVal.Count > 0)
                {
                    version = int.Parse(versionRetVal[0]);
                    if (int.Parse(versionRetVal[1]) == (int)AssetType.TrashFolder ||
                        int.Parse(versionRetVal[1]) == (int)AssetType.CurrentOutfitFolder ||
                        int.Parse(versionRetVal[1]) == (int)AssetType.LinkFolder)
                    {
                        //If it is the trash folder, we need to send its descendents, because the viewer wants it
                        query = String.Format("where {0} = '{1}' and {2} = '{3}'", "parentFolderID", folder_id,
                                              "agentID", AgentID);
                        using (IDataReader retVal = GD.QueryData(query, m_foldersrealm, "*"))
                        {
                            try
                            {
                                while (retVal.Read())
                                {
                                    contents.WriteStartMap("folder"); //Start item kvp
                                    contents["folder_id"] = UUID.Parse(retVal["folderID"].ToString());
                                    contents["parent_id"] = UUID.Parse(retVal["parentFolderID"].ToString());
                                    contents["name"]      = retVal["folderName"].ToString();
                                    int type = int.Parse(retVal["type"].ToString());
                                    contents["type"]           = type;
                                    contents["preferred_type"] = type;

                                    count++;
                                    contents.WriteEndMap(/*"folder"*/);  //end array items
                                }
                            }
                            catch
                            {
                            }
                            finally
                            {
                                try
                                {
                                    //if (retVal != null)
                                    //{
                                    //    retVal.Close ();
                                    //    retVal.Dispose ();
                                    //}
                                }
                                catch
                                {
                                }
                                GD.CloseDatabase();
                            }
                        }
                    }
                }

                contents.WriteEndArray(/*"categories"*/);
                contents["descendents"] = count;
                contents["version"]     = version;

                //Now add it to the folder array
                contents.WriteEndMap(); //end array internalContents
            }

            contents.WriteEndArray();         //end array folders
            contents.WriteEndMap(/*"llsd"*/); //end llsd

            try
            {
                return(contents.GetSerializer());
            }
            finally
            {
                contents = null;
            }
        }
 public override List<InventoryItemBase> GetItems(UUID avatarID, string[] fields, string[] vals)
 {
     IUserFinder userFinder = m_registry.RequestModuleInterface<IUserFinder>();
     if (userFinder != null && !userFinder.IsLocalGridUser(avatarID))
     {
         string serverURL = userFinder.GetUserServerURL(avatarID, "InventoryServerURI") + "xinventory";
         UUID id = UUID.Parse(vals[0]);
         XInventoryServicesConnector xinv = new XInventoryServicesConnector(serverURL);
         if(fields[0] == "parentFolderID")
         {
             return xinv.GetFolderContent(avatarID, id).Items;
         }
         else
         {
             return new List<InventoryItemBase> { xinv.GetItem(new InventoryItemBase(id)) };
         }
     }
     return base.GetItems(avatarID, fields, vals);
 }
        public override OSDArray GetLLSDItems(string[] fields, string[] vals)
        {
            string query = "";
            for (int i = 0; i < fields.Length; i++)
            {
                query += String.Format("where {0} = '{1}' and ", fields[i], vals[i]);
                i++;
            }
            query = query.Remove(query.Length - 5);
            if (fields[0] == "inventoryID")
            {
                IInventoryService invService = m_registry.RequestModuleInterface<IInventoryService>();
                if (invService != null)
                {
                    UUID inventoryID = UUID.Parse(vals[0]);
                    InventoryItemBase baseItem = new InventoryItemBase(UUID.Parse(vals[0]));
                    if (vals.Count() > 1)
                    {
                        UUID avatarID = UUID.Parse(vals[1]);
                        IUserFinder userFinder = m_registry.RequestModuleInterface<IUserFinder>();
                        if (userFinder != null && !userFinder.IsLocalGridUser(avatarID))
                        {
                            string serverURL = userFinder.GetUserServerURL(avatarID, "InventoryServerURI") + "xinventory";
                            XInventoryServicesConnector xinv = new XInventoryServicesConnector(serverURL);
                            return BuildLLSDInventoryItems(xinv.GetItem(baseItem));
                        }
                    }
                    return BuildLLSDInventoryItems(invService.GetItem(baseItem));
                }
            }

            return null;
        }
 private IDataReader GetForeignInventory(UUID AgentID, UUID folder_id, string serverURL)
 {
     FakeDataReader d = new FakeDataReader();
     IConfigurationService configService = m_registry.RequestModuleInterface<IConfigurationService>();
     if (serverURL == "" && configService != null)
     {
         List<string> urls = configService.FindValueOf("InventoryServerURI");
         if (urls.Count > 0)
             serverURL = urls[0];
         else
             return null;
     }
     XInventoryServicesConnector xinv = new XInventoryServicesConnector(serverURL + "xinventory");
     InventoryCollection c = xinv.GetFolderContent(AgentID, folder_id);
     if (c != null)
     {
         foreach (InventoryItemBase item in c.Items)
         {
             d.items.Add(item);
         }
     }
     return d;
 }
        public override byte[] FetchInventoryReply(OSDArray fetchRequest, UUID AgentID, UUID forceOwnerID, UUID libraryOwnerID)
        {
            LLSDSerializationDictionary contents = new LLSDSerializationDictionary();
            contents.WriteStartMap("llsd"); //Start llsd

            contents.WriteKey("folders"); //Start array items
            contents.WriteStartArray("folders"); //Start array folders

            foreach (OSD m in fetchRequest)
            {
                contents.WriteStartMap("internalContents"); //Start internalContents kvp
                OSDMap invFetch = (OSDMap) m;

                //UUID agent_id = invFetch["agent_id"].AsUUID();
                UUID owner_id = invFetch["owner_id"].AsUUID();
                UUID folder_id = invFetch["folder_id"].AsUUID();
                bool fetch_folders = invFetch["fetch_folders"].AsBoolean();
                bool fetch_items = invFetch["fetch_items"].AsBoolean();
                int sort_order = invFetch["sort_order"].AsInteger();

                //Set the normal stuff
                contents["agent_id"] = forceOwnerID == UUID.Zero ? owner_id : forceOwnerID;
                contents["owner_id"] = forceOwnerID == UUID.Zero ? owner_id : forceOwnerID;
                contents["folder_id"] = folder_id;

                contents.WriteKey("items"); //Start array items
                contents.WriteStartArray("items");
                List<UUID> moreLinkedItems = new List<UUID>();
                int count = 0;
                bool addToCount = true;
                string invServer = "";
                bool isForeign = GetIsForeign(AgentID, "InventoryServerURI", m_registry, out invServer);
                IDataReader fretVal = null;
                if (isForeign)
                    fretVal = GetForeignInventory(AgentID, folder_id, invServer);
                string query = String.Format("where {0} = '{1}'", "parentFolderID", folder_id,
                                             "avatarID", AgentID, "avatarID", libraryOwnerID);
                redoQuery:
                using (DataReaderConnection retVal = isForeign ? new DataReaderConnection() { DataReader = fretVal } : GD.QueryData(query, m_itemsrealm, "*"))
                {
                    try
                    {
                        while (retVal.DataReader.Read())
                        {
                            contents.WriteStartMap("item"); //Start item kvp
                            UUID assetID = UUID.Parse(retVal.DataReader["assetID"].ToString());
                            contents["asset_id"] = assetID;
                            contents["name"] = retVal.DataReader["inventoryName"].ToString();
                            contents["desc"] = retVal.DataReader["inventoryDescription"].ToString();


                            contents.WriteKey("permissions"); //Start permissions kvp
                            contents.WriteStartMap("permissions");
                            contents["group_id"] = UUID.Parse(retVal.DataReader["groupID"].ToString());
                            contents["is_owner_group"] = int.Parse(retVal.DataReader["groupOwned"].ToString()) == 1;
                            contents["group_mask"] = uint.Parse(retVal.DataReader["inventoryGroupPermissions"].ToString());
                            contents["owner_id"] = forceOwnerID == UUID.Zero
                                                       ? UUID.Parse(retVal.DataReader["avatarID"].ToString())
                                                       : forceOwnerID;
                            contents["last_owner_id"] = UUID.Parse(retVal.DataReader["avatarID"].ToString());
                            contents["next_owner_mask"] = uint.Parse(retVal.DataReader["inventoryNextPermissions"].ToString());
                            contents["owner_mask"] = uint.Parse(retVal.DataReader["inventoryCurrentPermissions"].ToString());
                            UUID creator;
                            if (UUID.TryParse(retVal.DataReader["creatorID"].ToString(), out creator))
                                contents["creator_id"] = creator;
                            else
                                contents["creator_id"] = UUID.Zero;
                            contents["base_mask"] = uint.Parse(retVal.DataReader["inventoryBasePermissions"].ToString());
                            contents["everyone_mask"] = uint.Parse(retVal.DataReader["inventoryEveryOnePermissions"].ToString());
                            contents.WriteEndMap( /*Permissions*/);

                            contents.WriteKey("sale_info"); //Start permissions kvp
                            contents.WriteStartMap("sale_info"); //Start sale_info kvp
                            contents["sale_price"] = int.Parse(retVal.DataReader["salePrice"].ToString());
                            switch (byte.Parse(retVal.DataReader["saleType"].ToString()))
                            {
                                default:
                                    contents["sale_type"] = "not";
                                    break;
                                case 1:
                                    contents["sale_type"] = "original";
                                    break;
                                case 2:
                                    contents["sale_type"] = "copy";
                                    break;
                                case 3:
                                    contents["sale_type"] = "contents";
                                    break;
                            }
                            contents.WriteEndMap( /*sale_info*/);


                            contents["created_at"] = int.Parse(retVal.DataReader["creationDate"].ToString());
                            contents["flags"] = uint.Parse(retVal.DataReader["flags"].ToString());
                            UUID inventoryID = UUID.Parse(retVal.DataReader["inventoryID"].ToString());
                            contents["item_id"] = inventoryID;
                            contents["parent_id"] = UUID.Parse(retVal.DataReader["parentFolderID"].ToString());
                            UUID avatarID = forceOwnerID == UUID.Zero
                                                ? UUID.Parse(retVal.DataReader["avatarID"].ToString())
                                                : forceOwnerID;
                            contents["agent_id"] = avatarID;

                            AssetType assetType = (AssetType)int.Parse(retVal.DataReader["assetType"].ToString());
                            if (assetType == AssetType.Link)
                                moreLinkedItems.Add(assetID);
                            contents["type"] = Utils.AssetTypeToString(assetType);
                            InventoryType invType = (InventoryType)int.Parse(retVal.DataReader["invType"].ToString());
                            contents["inv_type"] = Utils.InventoryTypeToString(invType);

                            if (addToCount)
                                count++;
                            contents.WriteEndMap( /*"item"*/); //end array items
                        }
                    }
                    catch
                    {
                    }
                    finally
                    {
                        GD.CloseDatabase(retVal);
                    }
                }
                if (moreLinkedItems.Count > 0)
                {
                    addToCount = false;
                    query = String.Format("where {0} = '{1}' and (", "avatarID", AgentID);
#if (!ISWIN)
                    foreach (UUID item in moreLinkedItems)
                        query = query + String.Format("{0} = '{1}' or ", "inventoryID", item);
#else
                    query = moreLinkedItems.Aggregate(query, (current, t) => current + String.Format("{0} = '{1}' or ", "inventoryID", t));
#endif
                    query = query.Remove(query.Length - 4, 4);
                    query += ")";
                    if (isForeign)
                    {
                        fretVal = new FakeDataReader();
                        IConfigurationService configService = m_registry.RequestModuleInterface<IConfigurationService>();
                        if (invServer == "" && configService != null)
                        {
                            List<string> urls = configService.FindValueOf("InventoryServerURI");
                            if (urls.Count > 0)
                                invServer = urls[0];
                            else
                                return null;
                        }
                        XInventoryServicesConnector xinv = new XInventoryServicesConnector(invServer + "xinventory");
                        foreach (UUID t in moreLinkedItems)
                        {
                            ((FakeDataReader) fretVal).items.Add(xinv.GetItem(new InventoryItemBase(t)));
                        }
                    }
                    moreLinkedItems.Clear();
                    goto redoQuery;
                }
                contents.WriteEndArray( /*"items"*/); //end array items

                contents.WriteStartArray("categories"); //We don't send any folders
                int version = 0;
                QueryFilter filter = new QueryFilter();
                filter.andFilters["folderID"] = folder_id;
                List<string> versionRetVal = GD.Query(new string[2] { "version", "type" }, m_foldersrealm, filter, null, null, null);
                List<InventoryFolderBase> foldersToAdd = new List<InventoryFolderBase>();
                if (versionRetVal.Count > 0)
                {
                    version = int.Parse(versionRetVal[0]);
                    if (int.Parse(versionRetVal[1]) == (int) AssetType.TrashFolder ||
                        int.Parse(versionRetVal[1]) == (int) AssetType.CurrentOutfitFolder ||
                        int.Parse(versionRetVal[1]) == (int) AssetType.LinkFolder)
                    {
                        //If it is the trash folder, we need to send its descendents, because the viewer wants it
                        query = String.Format("where {0} = '{1}' and {2} = '{3}'", "parentFolderID", folder_id,
                                              "agentID", AgentID);
                        using (DataReaderConnection retVal = GD.QueryData(query, m_foldersrealm, "*"))
                        {
                            try
                            {
                                while (retVal.DataReader.Read())
                                {
                                    contents.WriteStartMap("folder"); //Start item kvp
                                    contents["folder_id"] = UUID.Parse(retVal.DataReader["folderID"].ToString());
                                    contents["parent_id"] = UUID.Parse(retVal.DataReader["parentFolderID"].ToString());
                                    contents["name"] = retVal.DataReader["folderName"].ToString();
                                    int type = int.Parse(retVal.DataReader["type"].ToString());
                                    contents["type"] = type;
                                    contents["preferred_type"] = type;

                                    count++;
                                    contents.WriteEndMap( /*"folder"*/); //end array items
                                }
                            }
                            catch
                            {
                            }
                            finally
                            {
                                GD.CloseDatabase(retVal);
                            }
                        }
                    }
                }

                contents.WriteEndArray( /*"categories"*/);
                contents["descendents"] = count;
                contents["version"] = version;

                //Now add it to the folder array
                contents.WriteEndMap(); //end array internalContents
            }

            contents.WriteEndArray(); //end array folders
            contents.WriteEndMap( /*"llsd"*/); //end llsd

            try
            {
                return contents.GetSerializer();
            }
            finally
            {
                contents = null;
            }
        }