From d2aea3ef59f93decf7330efd2aedff7b74cf356c Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 13 May 2011 03:24:19 +0100
Subject: Fix broken inventory links on viewer 2.

It appears that if the viewer requests a folder containing links, we must also send the folders that contain the link targets first.
This was tested with Kokua 0.1.0 WIP though I predict it will also work with other viewer 2s
---
 .../Region/ClientStack/LindenUDP/LLClientView.cs    |  7 ++++++-
 OpenSim/Region/Framework/Scenes/Scene.Inventory.cs  | 21 +++++++++++++++++++--
 .../Region/Framework/Scenes/Scene.PacketHandlers.cs |  4 ++++
 bin/OpenSim.exe.config                              |  2 +-
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index ad015e7..0e448d1 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -1607,14 +1607,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                     currentPacket.ItemData[itemsSent % MAX_ITEMS_PER_PACKET] = CreateItemDataBlock(items[itemsSent++]);
                 else
                 {
+//                    m_log.DebugFormat(
+//                        "[LLCLIENTVIEW]: Sending inventory folder details packet to {0} for folder {1}", Name, folderID);
                     OutPacket(currentPacket, ThrottleOutPacketType.Asset, false);
                     currentPacket = null;
                 }
-
             }
 
             if (currentPacket != null)
+            {
+//                m_log.DebugFormat(
+//                    "[LLCLIENTVIEW]: Sending inventory folder details packet to {0} for folder {1}", Name, folderID);
                 OutPacket(currentPacket, ThrottleOutPacketType.Asset, false);
+            }
         }
 
         private InventoryDescendentsPacket.FolderDataBlock CreateFolderDataBlock(InventoryFolderBase folder)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index a65ceeb..3bf2c2b 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -1382,11 +1382,28 @@ namespace OpenSim.Region.Framework.Scenes
             InventoryFolderBase containingFolder = new InventoryFolderBase(folder.ID, client.AgentId);
             containingFolder = InventoryService.GetFolder(containingFolder);
 
-            //m_log.DebugFormat("[AGENT INVENTORY]: Sending inventory folder contents ({0} nodes) for \"{1}\" to {2} {3}",
-            //    contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName);
+//            m_log.DebugFormat("[AGENT INVENTORY]: Sending inventory folder contents ({0} nodes) for \"{1}\" to {2} {3}",
+//                contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName);
 
             if (containingFolder != null && containingFolder != null)
+            {
+                // If the folder requested contains links, then we need to send those folders first, otherwise the links
+                // will be broken in the viewer.
+                HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>();
+                foreach (InventoryItemBase item in contents.Items)
+                {
+                    if (item.AssetType == (int)AssetType.Link)
+                    {
+                        InventoryItemBase linkedItem = InventoryService.GetItem(new InventoryItemBase(item.AssetID));
+                        linkedItemFolderIdsToSend.Add(linkedItem.Folder);
+                    }
+                }
+
+                foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend)
+                    SendInventoryUpdate(client, new InventoryFolderBase(linkedItemFolderId), false, true);
+
                 client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, containingFolder.Version, fetchFolders, fetchItems);
+            }
         }
 
         /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index ab567fb..e2d7208 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -499,6 +499,10 @@ namespace OpenSim.Region.Framework.Scenes
         public void HandleFetchInventoryDescendents(IClientAPI remoteClient, UUID folderID, UUID ownerID,
                                                     bool fetchFolders, bool fetchItems, int sortOrder)
         {
+//            m_log.DebugFormat(
+//                "[USER INVENTORY]: HandleFetchInventoryDescendents() for {0}, folder={1}, fetchFolders={2}, fetchItems={3}, sortOrder={4}",
+//                remoteClient.Name, folderID, fetchFolders, fetchItems, sortOrder);
+
             if (folderID == UUID.Zero)
                 return;
 
diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config
index eece040..4a49fc5 100755
--- a/bin/OpenSim.exe.config
+++ b/bin/OpenSim.exe.config
@@ -14,7 +14,7 @@
       <layout type="log4net.Layout.PatternLayout">
         <conversionPattern value="%date{HH:mm:ss} - %message" />
         <!-- console log with milliseconds.  Useful for debugging -->
-        <!-- <conversionPattern value="%date{HH:mm:ss.fff} - %message" /> -->
+<!--        <conversionPattern value="%date{HH:mm:ss.fff} - %message" /> -->
       </layout>
     </appender>
 
-- 
cgit v1.1