public override byte[] FetchInventoryReply (OSDArray fetchRequest, UUID AgentID, UUID forceOwnerID) { 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}' and {2} = '{3}'", "parentFolderID", folder_id, "avatarID", AgentID); 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); for(int i = 0; i < moreLinkedItems.Count; i++) query += String.Format("{0} = '{1}' or ", "inventoryID", moreLinkedItems[i]); 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"); for (int i = 0; i < moreLinkedItems.Count; i++) { ((FakeDataReader)fretVal).items.Add(xinv.GetItem(new InventoryItemBase(moreLinkedItems[i]))); } } moreLinkedItems.Clear (); goto redoQuery; } contents.WriteEndArray(/*"items"*/); //end array items contents.WriteStartArray ("categories"); //We don't send any folders int version = 0; List<string> versionRetVal = GD.Query ("folderID", folder_id, m_foldersrealm, "version, type"); 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; } }
private const int FOLDER_FAIL_TRACKING_TIME = 15 * 60; //15 minutes public byte[] FetchInventoryDescendentsRequest( string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { OpenMetaverse.StructuredData.OSDMap map = (OpenMetaverse.StructuredData.OSDMap)OSDParser.DeserializeLLSDXml(request); OpenMetaverse.StructuredData.OSDArray osdFoldersRequested = (OpenMetaverse.StructuredData.OSDArray)map["folders"]; // m_log.ErrorFormat("[CAPS/INVENTORY] Handling a FetchInventoryDescendents Request for {0}: {1}", m_Caps.AgentID, map.ToString()); LLSDSerializationDictionary contents = new LLSDSerializationDictionary(); contents.WriteStartMap("llsd"); //Start llsd contents.WriteKey("folders"); //Start array items contents.WriteStartArray("folders"); //Start array folders foreach (OSD folderInfo in osdFoldersRequested) { OpenMetaverse.StructuredData.OSDMap fiMap = folderInfo as OpenMetaverse.StructuredData.OSDMap; if (fiMap == null) continue; UUID folderId = fiMap["folder_id"].AsUUID(); bool fetchItems = fiMap["fetch_items"].AsBoolean(); bool fetchFolders = fiMap["fetch_folders"].AsBoolean(); int count = 0; InventoryFolderBase folder = null; try { if (folderId == UUID.Zero) { //indicates the client wants the root for this user folder = m_checkedStorageProvider.FindFolderForType(m_Caps.AgentID, (AssetType)FolderType.Root); folderId = folder.ID; } else { lock (m_blackListedFolders) { TimestampedItem<int> entry; if (m_blackListedFolders.TryGetValue(folderId, out entry)) { if (entry.ElapsedSeconds > FOLDER_FAIL_TRACKING_TIME) { m_blackListedFolders.Remove(folderId); } else { if (entry.Item >= MAX_FOLDER_FAIL_COUNT) { //we're at the fail threshold. return a fake folder folder = new InventoryFolderBase { ID = folderId, Name = "[unable to load folder]", Owner = m_agentID }; m_log.ErrorFormat("[CAPS/INVENTORY]: Fail threshold reached for {0}, sending empty folder", folderId); } } } } if (folder == null) { // See if its a library folder if (m_libraryFolder != null) folder = m_libraryFolder.FindFolder(folderId); if (folder == null) { // Nope, Look for it in regular folders folder = m_checkedStorageProvider.GetFolder(m_Caps.AgentID, folderId); } } } } catch (Exception e) { m_log.ErrorFormat("[CAPS/INVENTORY] Could not retrieve requested folder {0} for {1}: {2}", folderId, m_Caps.AgentID, e); if (folderId != UUID.Zero) { lock (m_blackListedFolders) { TimestampedItem<int> entry; if (m_blackListedFolders.TryGetValue(folderId, out entry)) { entry.ResetTimestamp(); entry.Item = entry.Item + 1; } else { m_blackListedFolders.Add(folderId, new TimestampedItem<int>(1)); } } } continue; } contents.WriteStartMap("internalContents"); //Start internalContents kvp //Set the normal stuff contents["agent_id"] = folder.Owner; contents["owner_id"] = folder.Owner; contents["folder_id"] = folder.ID; contents.WriteKey("items"); //Start array items contents.WriteStartArray("items"); List<UUID> linkedFolders = new List<UUID>(); if (fetchItems) { foreach (InventoryItemBase item in folder.Items) { item.SerializeToLLSD(contents); count++; if (item.AssetType == (int)AssetType.LinkFolder) { // Add this when we do categories below linkedFolders.Add(item.AssetID); } else if (item.AssetType == (int)AssetType.Link) { try { InventoryItemBase linkedItem = m_checkedStorageProvider.GetItem(m_agentID, item.AssetID, UUID.Zero); if (linkedItem != null) { linkedItem.SerializeToLLSD(contents); } else { m_log.ErrorFormat( "[CAPS/INVENTORY] Failed to resolve link to item {0} for {1}", item.AssetID, m_Caps.AgentID); } // Don't add it to the count. It was accounted for with the link. //count++; } catch (Exception e) { m_log.ErrorFormat( "[CAPS/INVENTORY] Failed to resolve link to item {0} for {1}: {2}", item.AssetID, m_Caps.AgentID, e.Message); } } } } contents.WriteEndArray(/*"items"*/); //end array items contents.WriteKey("categories"); //Start array cats contents.WriteStartArray("categories"); //We don't send any folders // If there were linked folders include the folders referenced here if (linkedFolders.Count > 0) { foreach (UUID linkedFolderID in linkedFolders) { try { InventoryFolderBase linkedFolder = m_checkedStorageProvider.GetFolderAttributes(m_agentID, linkedFolderID); if (linkedFolder != null) { linkedFolder.SerializeToLLSD(contents); // Don't add it to the count.. it was accounted for with the link. //count++; } } catch (InventoryObjectMissingException) { m_log.ErrorFormat("[CAPS/INVENTORY] Failed to resolve link to folder {0} for {1}", linkedFolderID, m_agentID); } catch (Exception e) { m_log.ErrorFormat( "[CAPS/INVENTORY] Failed to resolve link to folder {0} for {1}: {2}", linkedFolderID, m_agentID, e); } } } if (fetchFolders) { foreach (InventorySubFolderBase subFolder in folder.SubFolders) { subFolder.SerializeToLLSD(contents, folder.ID); count++; } } contents.WriteEndArray(/*"categories"*/); contents["descendents"] = count; contents["version"] = folder.Version; //Now add it to the folder array contents.WriteEndMap(); //end array internalContents } contents.WriteEndArray(); //end array folders contents.WriteEndMap(/*"llsd"*/); //end llsd return (contents.GetSerializer()); }
public byte[] FetchInventoryReply(OSDArray fetchRequest, UUID AgentID) { 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"] = AgentID; contents["owner_id"] = owner_id; contents["folder_id"] = folder_id; contents.WriteKey("items"); //Start array items contents.WriteStartArray("items"); List<UUID> moreLinkedItems = new List<UUID> (); int count = 0; string query = String.Format("where {0} = '{1}' and {2} = '{3}'", "parentFolderID", folder_id, "avatarID", AgentID); redoQuery: using (IDataReader retVal = 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"] = UUID.Parse (retVal["avatarID"].ToString ()); 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 ()); contents["agent_id"] = UUID.Parse (retVal["avatarID"].ToString ()); AssetType assetType = (AssetType)int.Parse (retVal["assetType"].ToString ()); if(assetType == AssetType.Link) moreLinkedItems.Add(assetID); contents["type"] = Utils.AssetTypeToString (assetType); contents["inv_type"] = Utils.InventoryTypeToString ((InventoryType)int.Parse (retVal["invType"].ToString ())); count++; contents.WriteEndMap (/*"item"*/); //end array items } } catch { } finally { try { //if (retVal != null) //{ // retVal.Close (); // retVal.Dispose (); //} } catch { } GD.CloseDatabase (); } } if(moreLinkedItems.Count > 0) { query = String.Format("where {0} = '{1}' and (", "avatarID", AgentID); for(int i = 0; i < moreLinkedItems.Count; i++) query += String.Format("{0} = '{1}' or ", "inventoryID", moreLinkedItems[i]); query = query.Remove (query.Length - 4, 4); query += ")"; moreLinkedItems.Clear (); goto redoQuery; } contents.WriteEndArray(/*"items"*/); //end array items contents.WriteStartArray ("categories"); //We don't send any folders int version = 0; List<string> versionRetVal = GD.Query ("folderID", folder_id, m_foldersrealm, "version, type"); List<InventoryFolderBase> foldersToAdd = new List<InventoryFolderBase> (); if (versionRetVal.Count > 0) { version = int.Parse (versionRetVal[0]); if(int.Parse(versionRetVal[1]) == (int)AssetType.TrashFolder) { //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 (); contents["type"] = int.Parse(retVal["type"].ToString ()); contents["preferred_type"] = -1; 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 byte[] FetchInventoryReply(OSDArray fetchRequest, UUID AgentID) { 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"] = AgentID; contents["owner_id"] = owner_id; contents["folder_id"] = folder_id; contents.WriteKey("items"); //Start array items contents.WriteStartArray("items"); int count = 0; string query = String.Format("where {0} = '{1}'", "parentFolderID", folder_id); using (IDataReader retVal = GD.QueryData (query, m_itemsrealm, "*")) { try { while (retVal.Read ()) { contents.WriteStartMap ("item"); //Start item kvp contents["asset_id"] = UUID.Parse (retVal["assetID"].ToString ()); 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"] = UUID.Parse (retVal["avatarID"].ToString ()); 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 ()); contents["agent_id"] = UUID.Parse (retVal["avatarID"].ToString ()); contents["type"] = Utils.AssetTypeToString ((AssetType)int.Parse (retVal["assetType"].ToString ())); contents["inv_type"] = Utils.InventoryTypeToString ((InventoryType)int.Parse (retVal["invType"].ToString ())); count++; contents.WriteEndMap (/*"item"*/); //end array items } } catch { } finally { try { if (retVal != null) { retVal.Close (); retVal.Dispose (); } } catch { } GD.CloseDatabase (); } } contents.WriteEndArray(/*"items"*/); //end array items int version = 0; List<string> versionRetVal = GD.Query("folderID", folder_id, m_foldersrealm, "version"); if(versionRetVal.Count > 0) version = int.Parse(versionRetVal[0]); contents.WriteStartArray("categories"); //We don't send any folders 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 return contents.GetSerializer(); }