private void RequestFolder(DescendentRequest dr) { Packet packet = InvPacketHelper.FetchInventoryDescendents( dr.FolderID , dr.FetchFolders , dr.FetchItems); htFolderDownloadStatus[dr.FolderID] = dr; slClient.Network.SendPacket(packet); }
public void InventoryDescendentsHandler(Packet packet, Simulator simulator) { InventoryDescendentsPacket reply = (InventoryDescendentsPacket)packet; LastPacketRecieved = Helpers.GetUnixTime(); InventoryItem invItem; InventoryFolder invFolder; LLUUID uuidFolderID = new LLUUID(); int iDescendentsExpected = int.MaxValue; int iDescendentsReceivedThisBlock = 0; foreach (InventoryDescendentsPacket.ItemDataBlock itemBlock in reply.ItemData) { // There is always an item block, even if there isn't any items // the "filler" block will not have a name if (itemBlock.Name.Length != 0) { iDescendentsReceivedThisBlock++; invItem = new InventoryItem(this, itemBlock); InventoryFolder ifolder = (InventoryFolder)htFoldersByUUID[invItem.FolderID]; if (ifolder.alContents.Contains(invItem) == false) { if ((invItem.InvType == 7) && (invItem.Type == Asset.ASSET_TYPE_NOTECARD)) { InventoryItem temp = new InventoryNotecard(this, invItem); invItem = temp; } if ((invItem.InvType == 0) && (invItem.Type == Asset.ASSET_TYPE_IMAGE)) { InventoryItem temp = new InventoryImage(this, invItem); invItem = temp; } ifolder.alContents.Add(invItem); } } } foreach (InventoryDescendentsPacket.FolderDataBlock folderBlock in reply.FolderData) { String name = System.Text.Encoding.UTF8.GetString(folderBlock.Name).Trim().Replace("\0", ""); LLUUID folderid = folderBlock.FolderID; LLUUID parentid = folderBlock.ParentID; sbyte type = folderBlock.Type; // There is always an folder block, even if there isn't any folders // the "filler" block will not have a name if (folderBlock.Name.Length != 0) { invFolder = new InventoryFolder(this, name, folderid, parentid); iDescendentsReceivedThisBlock++; // Add folder to Parent InventoryFolder ifolder = (InventoryFolder)htFoldersByUUID[invFolder.ParentID]; if (ifolder.alContents.Contains(invFolder) == false) { ifolder.alContents.Add(invFolder); } // Add folder to UUID Lookup htFoldersByUUID[invFolder.FolderID] = invFolder; // It's not the root, should be safe to "recurse" if (!invFolder.FolderID.Equals(uuidRootFolder)) { bool alreadyQueued = false; foreach (DescendentRequest dr in alFolderRequestQueue) { if (dr.FolderID == invFolder.FolderID) { alreadyQueued = true; break; } } if (!alreadyQueued) { alFolderRequestQueue.Add(new DescendentRequest(invFolder.FolderID)); } } } } // Check how many descendents we're actually supposed to receive iDescendentsExpected = reply.AgentData.Descendents; uuidFolderID = reply.AgentData.FolderID; // Update download status for this folder if (iDescendentsReceivedThisBlock >= iDescendentsExpected) { // We received all the descendents we're expecting for this folder // in this packet, so go ahead and remove folder from status list. htFolderDownloadStatus.Remove(uuidFolderID); } else { // This one packet didn't have all the descendents we're expecting // so update the total we're expecting, and update the total downloaded DescendentRequest dr = (DescendentRequest)htFolderDownloadStatus[uuidFolderID]; dr.Expected = iDescendentsExpected; dr.Received += iDescendentsReceivedThisBlock; dr.LastReceived = Helpers.GetUnixTime(); if (dr.Received >= dr.Expected) { // Looks like after updating, we have all the descendents, // remove from folder status. htFolderDownloadStatus.Remove(uuidFolderID); } else { htFolderDownloadStatus[uuidFolderID] = dr; // Console.WriteLine( uuidFolderID + " is expecting " + (iDescendentsExpected - iStatus[1]) + " more packets." ); } } }
public void DownloadInventory() { resetFoldersByUUID(); if (htFolderDownloadStatus == null) { // Create status table htFolderDownloadStatus = new Dictionary <LLUUID, DescendentRequest>(); } else { if (htFolderDownloadStatus.Count != 0) { throw new Exception("Inventory Download requested while previous download in progress."); } } if (alFolderRequestQueue == null) { alFolderRequestQueue = new List <DescendentRequest>(); } // Set last packet received to now, just so out time-out timer works LastPacketRecieved = Helpers.GetUnixTime(); // Send Packet requesting the root Folder, // this should recurse through all folders RequestFolder(new DescendentRequest(uuidRootFolder)); while ((htFolderDownloadStatus.Count > 0) || (alFolderRequestQueue.Count > 0)) { if (htFolderDownloadStatus.Count == 0) { DescendentRequest dr = alFolderRequestQueue[0]; alFolderRequestQueue.RemoveAt(0); RequestFolder(dr); } if ((Helpers.GetUnixTime() - LastPacketRecieved) > 10) { Console.WriteLine("Time-out while waiting for packets (" + (Helpers.GetUnixTime() - LastPacketRecieved) + " seconds since last packet)"); Console.WriteLine("Current Status:"); // have to make a seperate list otherwise we run into modifying the original array // while still enumerating it. List <DescendentRequest> alRestartList = new List <DescendentRequest>(); //if (htFolderDownloadStatus[0] != null) //{ // Console.WriteLine(htFolderDownloadStatus[0].GetType()); //} foreach (DescendentRequest dr in htFolderDownloadStatus.Values) { Console.WriteLine(dr.FolderID + " " + dr.Expected + " / " + dr.Received + " / " + dr.LastReceived); alRestartList.Add(dr); } LastPacketRecieved = Helpers.GetUnixTime(); foreach (DescendentRequest dr in alRestartList) { RequestFolder(dr); } } slClient.Tick(); } }