aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Capabilities
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs313
1 files changed, 77 insertions, 236 deletions
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs
index e3a9a22..2fb1c63 100644
--- a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs
+++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Linq; 31using System.Linq;
32using System.Reflection; 32using System.Reflection;
33using System.Text;
33using log4net; 34using log4net;
34using Nini.Config; 35using Nini.Config;
35using OpenMetaverse; 36using OpenMetaverse;
@@ -59,7 +60,6 @@ namespace OpenSim.Capabilities.Handlers
59 m_LibraryService = libService; 60 m_LibraryService = libService;
60 m_Scene = s; 61 m_Scene = s;
61 } 62 }
62
63 63
64 public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 64 public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
65 { 65 {
@@ -93,8 +93,8 @@ namespace OpenSim.Capabilities.Handlers
93 93
94 ArrayList foldersrequested = (ArrayList)hash["folders"]; 94 ArrayList foldersrequested = (ArrayList)hash["folders"];
95 95
96 string response = ""; 96 StringBuilder tmpresponse = new StringBuilder(1024);
97 string bad_folders_response = ""; 97 StringBuilder tmpbadfolders = new StringBuilder(1024);
98 98
99 List<LLSDFetchInventoryDescendents> folders = new List<LLSDFetchInventoryDescendents>(); 99 List<LLSDFetchInventoryDescendents> folders = new List<LLSDFetchInventoryDescendents>();
100 for (int i = 0; i < foldersrequested.Count; i++) 100 for (int i = 0; i < foldersrequested.Count; i++)
@@ -136,49 +136,44 @@ namespace OpenSim.Capabilities.Handlers
136 string inventoryitemstr = string.Empty; 136 string inventoryitemstr = string.Empty;
137 foreach (InventoryCollectionWithDescendents icoll in invcollSet) 137 foreach (InventoryCollectionWithDescendents icoll in invcollSet)
138 { 138 {
139 LLSDInventoryDescendents reply = ToLLSD(icoll.Collection, icoll.Descendents); 139 LLSDInventoryFolderContents thiscontents = contentsToLLSD(icoll.Collection, icoll.Descendents);
140 140 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(thiscontents);
141 inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); 141// inventoryitemstr = inventoryitemstr.Replace("<llsd>", "");
142 inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); 142// inventoryitemstr = inventoryitemstr.Replace("</llsd>", "");
143 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); 143// inventoryitemstr = inventoryitemstr.Substring(6,inventoryitemstr.Length - 13);
144 144// tmpresponse.Append(inventoryitemstr);
145 response += inventoryitemstr; 145 tmpresponse.Append(inventoryitemstr.Substring(6,inventoryitemstr.Length - 13));
146 } 146 }
147 147
148 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders)); 148 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders));
149 foreach (UUID bad in bad_folders) 149 foreach (UUID bad in bad_folders)
150 bad_folders_response += "<uuid>" + bad + "</uuid>"; 150 {
151 tmpbadfolders.Append("<map><key>folder_id</key><uuid>");
152 tmpbadfolders.Append(bad.ToString());
153 tmpbadfolders.Append("</uuid><key>error</key><string>Unknown</string></map>");
154 }
151 } 155 }
152 156
153 if (response.Length == 0) 157 StringBuilder lastresponse = new StringBuilder(1024);
158 lastresponse.Append("<llsd>");
159 if(tmpresponse.Length > 0)
154 { 160 {
155 /* Viewers expect a bad_folders array when not available */ 161 lastresponse.Append("<map><key>folders</key><array>");
156 if (bad_folders_response.Length != 0) 162 lastresponse.Append(tmpresponse.ToString());
157 { 163 lastresponse.Append("</array></map>");
158 response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
159 }
160 else
161 {
162 response = "<llsd><map><key>folders</key><array /></map></llsd>";
163 }
164 } 164 }
165 else 165 else
166 lastresponse.Append("<map><key>folders</key><array /></map>");
167
168 if(tmpbadfolders.Length > 0)
166 { 169 {
167 if (bad_folders_response.Length != 0) 170 lastresponse.Append("<map><key>bad_folders</key><array>");
168 { 171 lastresponse.Append(tmpbadfolders.ToString());
169 response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>"; 172 lastresponse.Append("</array></map>");
170 }
171 else
172 {
173 response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
174 }
175 } 173 }
174 lastresponse.Append("</llsd>");
176 175
177 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request for {0} folders. Item count {1}", folders.Count, item_count); 176 return lastresponse.ToString();
178 //m_log.Debug("[WEB FETCH INV DESC HANDLER] " + response);
179
180 return response;
181
182 } 177 }
183 178
184 /// <summary> 179 /// <summary>
@@ -240,24 +235,19 @@ namespace OpenSim.Capabilities.Handlers
240 return reply; 235 return reply;
241 } 236 }
242 237
243 private LLSDInventoryDescendents ToLLSD(InventoryCollection inv, int descendents) 238 private LLSDInventoryFolderContents contentsToLLSD(InventoryCollection inv, int descendents)
244 { 239 {
245 LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
246 LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); 240 LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
247 contents.agent_id = inv.OwnerID; 241 contents.agent_id = inv.OwnerID;
248 contents.owner_id = inv.OwnerID; 242 contents.owner_id = inv.OwnerID;
249 contents.folder_id = inv.FolderID; 243 contents.folder_id = inv.FolderID;
250 244
251 reply.folders.Array.Add(contents);
252
253 if (inv.Folders != null) 245 if (inv.Folders != null)
254 { 246 {
255 foreach (InventoryFolderBase invFolder in inv.Folders) 247 foreach (InventoryFolderBase invFolder in inv.Folders)
256 { 248 {
257 contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); 249 contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
258 } 250 }
259
260 descendents += inv.Folders.Count;
261 } 251 }
262 252
263 if (inv.Items != null) 253 if (inv.Items != null)
@@ -271,7 +261,7 @@ namespace OpenSim.Capabilities.Handlers
271 contents.descendents = descendents; 261 contents.descendents = descendents;
272 contents.version = inv.Version; 262 contents.version = inv.Version;
273 263
274 return reply; 264 return contents;
275 } 265 }
276 /// <summary> 266 /// <summary>
277 /// Old style. Soon to be deprecated. 267 /// Old style. Soon to be deprecated.
@@ -285,8 +275,8 @@ namespace OpenSim.Capabilities.Handlers
285 { 275 {
286 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request for {0} folders", foldersrequested.Count); 276 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request for {0} folders", foldersrequested.Count);
287 277
288 string response = ""; 278 StringBuilder tmpresponse = new StringBuilder(1024);
289 string bad_folders_response = ""; 279 StringBuilder tmpbadfolders = new StringBuilder(1024);
290 280
291 for (int i = 0; i < foldersrequested.Count; i++) 281 for (int i = 0; i < foldersrequested.Count; i++)
292 { 282 {
@@ -308,7 +298,9 @@ namespace OpenSim.Capabilities.Handlers
308 298
309 if (null == reply) 299 if (null == reply)
310 { 300 {
311 bad_folders_response += "<uuid>" + llsdRequest.folder_id.ToString() + "</uuid>"; 301 tmpbadfolders.Append("<map><key>folder_id</key><uuid>");
302 tmpbadfolders.Append(llsdRequest.folder_id.ToString());
303 tmpbadfolders.Append("</uuid><key>error</key><string>Unknown</string></map>");
312 } 304 }
313 else 305 else
314 { 306 {
@@ -317,39 +309,29 @@ namespace OpenSim.Capabilities.Handlers
317 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); 309 inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
318 } 310 }
319 311
320 response += inventoryitemstr; 312 tmpresponse.Append(inventoryitemstr);
321 } 313 }
322 314
323 if (response.Length == 0) 315 StringBuilder lastresponse = new StringBuilder(1024);
316 lastresponse.Append("<llsd>");
317 if(tmpresponse.Length > 0)
324 { 318 {
325 /* Viewers expect a bad_folders array when not available */ 319 lastresponse.Append("<map><key>folders</key><array>");
326 if (bad_folders_response.Length != 0) 320 lastresponse.Append(tmpresponse.ToString());
327 { 321 lastresponse.Append("</array></map>");
328 response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>";
329 }
330 else
331 {
332 response = "<llsd><map><key>folders</key><array /></map></llsd>";
333 }
334 } 322 }
335 else 323 else
324 lastresponse.Append("<map><key>folders</key><array /></map>");
325
326 if(tmpbadfolders.Length > 0)
336 { 327 {
337 if (bad_folders_response.Length != 0) 328 lastresponse.Append("<map><key>bad_folders</key><array>");
338 { 329 lastresponse.Append(tmpbadfolders.ToString());
339 response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>"; 330 lastresponse.Append("</array></map>");
340 }
341 else
342 {
343 response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
344 }
345 } 331 }
332 lastresponse.Append("</llsd>");
346 333
347 // m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request"); 334 return lastresponse.ToString();
348 //m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response);
349
350 return response;
351
352 // }
353 } 335 }
354 336
355 /// <summary> 337 /// <summary>
@@ -436,108 +418,7 @@ namespace OpenSim.Capabilities.Handlers
436 itemsToReturn.Insert(0, linkedItem); 418 itemsToReturn.Insert(0, linkedItem);
437 } 419 }
438 } 420 }
439
440 // Now scan for folder links and insert the items they target and those links at the head of the return data
441
442/* dont send contents of LinkFolders.
443from docs seems this was never a spec
444
445 foreach (InventoryItemBase item in originalItems)
446 {
447 if (item.AssetType == (int)AssetType.LinkFolder)
448 {
449 InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID);
450 List<InventoryItemBase> links = linkedFolderContents.Items;
451
452 itemsToReturn.InsertRange(0, links);
453
454 foreach (InventoryItemBase link in linkedFolderContents.Items)
455 {
456 // Take care of genuinely broken links where the target doesn't exist
457 // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
458 // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
459 // rather than having to keep track of every folder requested in the recursion.
460 if (link != null)
461 {
462// m_log.DebugFormat(
463// "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}",
464// link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name);
465
466 InventoryItemBase linkedItem
467 = m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
468
469 if (linkedItem != null)
470 itemsToReturn.Insert(0, linkedItem);
471 }
472 }
473 }
474 }
475*/
476 } 421 }
477
478// foreach (InventoryItemBase item in contents.Items)
479// {
480// m_log.DebugFormat(
481// "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}",
482// item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID);
483// }
484
485 // =====
486
487//
488// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
489// {
490// m_log.DebugFormat(
491// "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}",
492// linkedItem.Name, folderID, agentID);
493//
494// contents.Items.Add(linkedItem);
495// }
496//
497// // If the folder requested contains links, then we need to send those folders first, otherwise the links
498// // will be broken in the viewer.
499// HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>();
500// foreach (InventoryItemBase item in contents.Items)
501// {
502// if (item.AssetType == (int)AssetType.Link)
503// {
504// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
505//
506// // Take care of genuinely broken links where the target doesn't exist
507// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
508// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
509// // rather than having to keep track of every folder requested in the recursion.
510// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
511// {
512// // We don't need to send the folder if source and destination of the link are in the same
513// // folder.
514// if (linkedItem.Folder != containingFolder.ID)
515// linkedItemFolderIdsToSend.Add(linkedItem.Folder);
516// }
517// }
518// }
519//
520// foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend)
521// {
522// m_log.DebugFormat(
523// "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}",
524// linkedItemFolderId, folderID, agentID);
525//
526// int dummyVersion;
527// InventoryCollection linkedCollection
528// = Fetch(
529// agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion);
530//
531// InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId);
532// linkedFolder.Owner = agentID;
533// linkedFolder = m_InventoryService.GetFolder(linkedFolder);
534//
535//// contents.Folders.AddRange(linkedCollection.Folders);
536//
537// contents.Folders.Add(linkedFolder);
538// contents.Items.AddRange(linkedCollection.Items);
539// }
540// }
541 } 422 }
542 } 423 }
543 else 424 else
@@ -566,13 +447,14 @@ from docs seems this was never a spec
566 { 447 {
567 InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents(); 448 InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents();
568 ret.Collection = new InventoryCollection(); 449 ret.Collection = new InventoryCollection();
569 ret.Collection.Folders = new List<InventoryFolderBase>(); 450// ret.Collection.Folders = new List<InventoryFolderBase>();
451 ret.Collection.Folders = fold.RequestListOfFolders();
570 ret.Collection.Items = fold.RequestListOfItems(); 452 ret.Collection.Items = fold.RequestListOfItems();
571 ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner; 453 ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner;
572 ret.Collection.FolderID = f.folder_id; 454 ret.Collection.FolderID = f.folder_id;
573 ret.Collection.Version = fold.Version; 455 ret.Collection.Version = fold.Version;
574 456
575 ret.Descendents = ret.Collection.Items.Count; 457 ret.Descendents = ret.Collection.Items.Count + ret.Collection.Folders.Count;
576 result.Add(ret); 458 result.Add(ret);
577 459
578 //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID); 460 //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID);
@@ -594,11 +476,18 @@ from docs seems this was never a spec
594 476
595 // Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense 477 // Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense
596 // and can kill the sim (all root folders have parent_id Zero) 478 // and can kill the sim (all root folders have parent_id Zero)
479 // send something.
597 LLSDFetchInventoryDescendents zero = fetchFolders.Find(f => f.folder_id == UUID.Zero); 480 LLSDFetchInventoryDescendents zero = fetchFolders.Find(f => f.folder_id == UUID.Zero);
598 if (zero != null) 481 if (zero != null)
599 { 482 {
600 fetchFolders.Remove(zero); 483 fetchFolders.Remove(zero);
601 BadFolder(zero, null, bad_folders); 484 InventoryCollectionWithDescendents zeroColl = new InventoryCollectionWithDescendents();
485 zeroColl.Collection = new InventoryCollection();
486 zeroColl.Collection.OwnerID = zero.owner_id;
487 zeroColl.Collection.Version = 0;
488 zeroColl.Collection.FolderID = zero.folder_id;
489 zeroColl.Descendents = 0;
490 result.Add(zeroColl);
602 } 491 }
603 492
604 if (fetchFolders.Count > 0) 493 if (fetchFolders.Count > 0)
@@ -666,35 +555,8 @@ from docs seems this was never a spec
666 } 555 }
667 else 556 else
668 { 557 {
669 // Was it really a request for folder Zero? 558 m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id);
670 // This is an overkill, but Firestorm really asks for folder Zero. 559 bad_folders.Add(freq.folder_id);
671 // I'm leaving the code here for the time being, but commented.
672 if (freq.folder_id == UUID.Zero)
673 {
674 //coll.Collection.OwnerID = freq.owner_id;
675 //coll.Collection.FolderID = contents.FolderID;
676 //containingFolder = m_InventoryService.GetRootFolder(freq.owner_id);
677 //if (containingFolder != null)
678 //{
679 // m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Request for parent of folder {0}", containingFolder.ID);
680 // coll.Collection.Folders.Clear();
681 // coll.Collection.Folders.Add(containingFolder);
682 // if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null)
683 // {
684 // InventoryFolderBase lib = new InventoryFolderBase(m_LibraryService.LibraryRootFolder.ID, m_LibraryService.LibraryRootFolder.Owner);
685 // lib.Name = m_LibraryService.LibraryRootFolder.Name;
686 // lib.Type = m_LibraryService.LibraryRootFolder.Type;
687 // lib.Version = m_LibraryService.LibraryRootFolder.Version;
688 // coll.Collection.Folders.Add(lib);
689 // }
690 // coll.Collection.Items.Clear();
691 //}
692 }
693 else
694 {
695 m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id);
696 bad_folders.Add(freq.folder_id);
697 }
698 bad = true; 560 bad = true;
699 } 561 }
700 } 562 }
@@ -708,42 +570,21 @@ from docs seems this was never a spec
708 570
709 if (freq.fetch_items && contents.Items != null) 571 if (freq.fetch_items && contents.Items != null)
710 { 572 {
711 List<InventoryItemBase> itemsToReturn = contents.Items; 573 // viewers are lasy and want a copy of the linked item sent before the link to it
712 574
713 // descendents must only include the links, not the linked items we add 575 // descendents must only include the links, not the linked items we add
714 coll.Descendents = itemsToReturn.Count; 576 coll.Descendents = contents.Items.Count + contents.Folders.Count;
715 577
716 // Add target items for links in this folder before the links themselves. 578 // look for item links
717 List<UUID> itemIDs = new List<UUID>(); 579 List<UUID> itemIDs = new List<UUID>();
718 List<UUID> folderIDs = new List<UUID>(); 580 foreach (InventoryItemBase item in contents.Items)
719 foreach (InventoryItemBase item in itemsToReturn)
720 { 581 {
721 //m_log.DebugFormat("[XXX]: {0} {1}", item.Name, item.AssetType); 582 //m_log.DebugFormat("[XXX]: {0} {1}", item.Name, item.AssetType);
722 if (item.AssetType == (int)AssetType.Link) 583 if (item.AssetType == (int)AssetType.Link)
723 itemIDs.Add(item.AssetID); 584 itemIDs.Add(item.AssetID);
724
725// else if (item.AssetType == (int)AssetType.LinkFolder)
726// folderIDs.Add(item.AssetID);
727 }
728
729 //m_log.DebugFormat("[XXX]: folder {0} has {1} links and {2} linkfolders", contents.FolderID, itemIDs.Count, folderIDs.Count);
730
731 // Scan for folder links and insert the items they target and those links at the head of the return data
732 if (folderIDs.Count > 0)
733 {
734 InventoryCollection[] linkedFolders = m_InventoryService.GetMultipleFoldersContent(coll.Collection.OwnerID, folderIDs.ToArray());
735 foreach (InventoryCollection linkedFolderContents in linkedFolders)
736 {
737 if (linkedFolderContents == null)
738 continue;
739
740 List<InventoryItemBase> links = linkedFolderContents.Items;
741
742 itemsToReturn.InsertRange(0, links);
743
744 }
745 } 585 }
746 586
587 // get the linked if any
747 if (itemIDs.Count > 0) 588 if (itemIDs.Count > 0)
748 { 589 {
749 InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray()); 590 InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray());
@@ -758,13 +599,11 @@ from docs seems this was never a spec
758 linked[i++] = m_InventoryService.GetItem(freq.owner_id, id); 599 linked[i++] = m_InventoryService.GetItem(freq.owner_id, id);
759 } 600 }
760 } 601 }
761 602
762 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Processing folder {0}. Existing items:", freq.folder_id);
763 //foreach (InventoryItemBase item in itemsToReturn)
764 // m_log.DebugFormat("[XXX]: {0} {1} {2}", item.Name, item.AssetType, item.Folder);
765
766 if (linked != null) 603 if (linked != null)
767 { 604 {
605 List<InventoryItemBase> linkedItems = new List<InventoryItemBase>();
606 // check for broken
768 foreach (InventoryItemBase linkedItem in linked) 607 foreach (InventoryItemBase linkedItem in linked)
769 { 608 {
770 // Take care of genuinely broken links where the target doesn't exist 609 // Take care of genuinely broken links where the target doesn't exist
@@ -773,14 +612,16 @@ from docs seems this was never a spec
773 // rather than having to keep track of every folder requested in the recursion. 612 // rather than having to keep track of every folder requested in the recursion.
774 if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) 613 if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
775 { 614 {
776 itemsToReturn.Insert(0, linkedItem); 615 linkedItems.Add(linkedItem);
777 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder); 616 //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder);
778 } 617 }
779 } 618 }
619 // insert them
620 if(linkedItems.Count > 0)
621 contents.Items.InsertRange(0,linkedItems);
780 } 622 }
781 } 623 }
782 } 624 }
783
784 } 625 }
785 626
786 /// <summary> 627 /// <summary>