From 0463a00d34af4752936817e826d735e3f36d33f1 Mon Sep 17 00:00:00 2001
From: Melanie
Date: Wed, 28 Mar 2012 02:45:50 +0100
Subject: Start on Bulk inventory update via CAPS. Not functional yet. HG v2

---
 CONTRIBUTORS.txt                                   |  2 +-
 OpenSim/Framework/Client/IClientInventory.cs       |  2 +
 .../Region/ClientStack/Linden/UDP/LLClientView.cs  | 48 ++++++++++++++++++++++
 3 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 31aeda3..089d2f5 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -1,4 +1,4 @@
-The following people have contributed to OpenSim (Thank you 
+   <<<>>>>The following people have contributed to OpenSim (Thank you 
 for your effort!)
 
 = Current OpenSim Developers (in very rough order of appearance) =
diff --git a/OpenSim/Framework/Client/IClientInventory.cs b/OpenSim/Framework/Client/IClientInventory.cs
index d59f8b7..a6e0510 100644
--- a/OpenSim/Framework/Client/IClientInventory.cs
+++ b/OpenSim/Framework/Client/IClientInventory.cs
@@ -27,6 +27,7 @@
 
 using System;
 using OpenMetaverse;
+using OpenSim.Framework;
 
 namespace OpenSim.Framework.Client
 {
@@ -34,5 +35,6 @@ namespace OpenSim.Framework.Client
     {
         void SendRemoveInventoryFolders(UUID[] folders);
         void SendRemoveInventoryItems(UUID[] folders);
+        void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items);
     }
 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 0c1d7f2..4107209 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -12339,5 +12339,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             eq.Enqueue(BuildEvent("RemoveInventoryFolder",
                     llsd), AgentId);
         }
+
+        public void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items)
+        {
+            IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
+
+            if (eq == null)
+            {
+                m_log.DebugFormat("[LLCLIENT]: Null event queue");
+                return;
+            }
+
+            OSDMap llsd = new OSDMap(3);
+
+            OSDMap AgentDataMap = new OSDMap(1);
+            AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
+            AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
+
+            OSDArray AgentData = new OSDArray(1);
+            AgentData.Add(AgentDataMap);
+
+            llsd.Add("AgentData", AgentData);
+
+            OSDArray FolderData = new OSDArray();
+
+            foreach (UUID InventoryFolderBase in folders)
+            {
+                OSDMap FolderDataMap = new OSDMap(5);
+                FolderDataMap.Add("FolderID", OSD.FromUUID(folder.ID));
+                FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId));
+                FolderDataMap.Add("ParentID", OSD.FromUUID(folder.ParentID));
+                FolderDataMap.Add("Type", OSD.FromInteger(folder.Type));
+                FolderDataMap.Add("Name", OSD.FromString(folder.Name));
+
+                FolderData.Add(FolderDataMap);
+            }
+
+            llsd.Add("FolderData", FolderData);
+
+            OSDArray ItemData = new OSDArray();
+
+            foreach (UUID InventoryItemBase in items)
+            {
+                OSDMap ItemDataMap = new OSDMap();
+                ItemData.Add(DataMap);
+            }
+
+            llsd.Add("ItemData", ItemData);
+        }
     }
 }
-- 
cgit v1.1


From 12d3ea3029854b48b302459226fc88415e78630c Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 28 Mar 2012 02:51:34 +0100
Subject: Add "friends show cache <first-name> <last-name>" command for
 debugging purposes.

This adds a reverse lookup (name -> ID) to IUserManagement instead of hitting the UserAccountService directly.
---
 .../CoreModules/Avatar/Friends/FriendsModule.cs    | 78 +++++++++++++++++++++-
 .../UserManagement/UserManagementModule.cs         | 29 ++++++++
 .../Region/Framework/Interfaces/IUserManagement.cs | 15 +++++
 3 files changed, 120 insertions(+), 2 deletions(-)

diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index be767c4..d1a1af0 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -214,6 +214,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
 
         public virtual void RegionLoaded(Scene scene)
         {
+            scene.AddCommand(
+                "Friends", this, "friends show cache",
+                "friends show cache [<first-name> <last-name>]",
+                "Show the friends cache for the given user",
+                HandleFriendsShowCacheCommand);
         }
 
         public void RemoveRegion(Scene scene)
@@ -890,7 +895,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
         /// Get friends from local cache only
         /// </summary>
         /// <param name="agentID"></param>
-        /// <returns></returns>
+        /// <returns>
+        /// An empty array if the user has no friends or friends have not been cached.
+        /// </returns>
         protected FriendInfo[] GetFriends(UUID agentID)
         {
             UserFriendData friendsData;
@@ -939,6 +946,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
             }
         }
 
+        /// <summary>
+        /// Are friends cached on this simulator for a particular user?
+        /// </summary>
+        /// <param name="userID"></param>
+        /// <returns></returns>
+        protected bool AreFriendsCached(UUID userID)
+        {
+            lock (m_Friends)
+                return m_Friends.ContainsKey(userID);
+        }
+
         protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights)
         {
             FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
@@ -964,5 +982,61 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
         }
 
         #endregion
+
+        protected void HandleFriendsShowCacheCommand(string module, string[] cmd)
+        {
+            if (cmd.Length != 5)
+            {
+                MainConsole.Instance.OutputFormat("Usage: friends show cache [<first-name> <last-name>]");
+                return;
+            }
+
+            string firstName = cmd[3];
+            string lastName = cmd[4];
+
+            IUserManagement umModule = m_Scenes[0].RequestModuleInterface<IUserManagement>();
+            UUID userId = umModule.GetUserIdByName(firstName, lastName);
+
+//            UserAccount ua
+//                = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, firstName, lastName);
+
+            if (userId == UUID.Zero)
+            {
+                MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName);
+                return;
+            }
+
+            if (!AreFriendsCached(userId))
+            {
+                MainConsole.Instance.OutputFormat("No friends cached on this simulator for {0} {1}", firstName, lastName);
+                return;
+            }
+
+            MainConsole.Instance.OutputFormat("Cached friends for {0} {1}:", firstName, lastName);
+
+            MainConsole.Instance.OutputFormat("UUID\n");
+
+            FriendInfo[] friends = GetFriends(userId);
+
+            foreach (FriendInfo friend in friends)
+            {
+//                MainConsole.Instance.OutputFormat(friend.PrincipalID.ToString());
+
+//                string friendFirstName, friendLastName;
+//
+//                UserAccount friendUa
+//                    = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friend.PrincipalID);
+
+                UUID friendId;
+                string friendName;
+
+                if (UUID.TryParse(friend.Friend, out friendId))
+                    friendName = umModule.GetUserName(friendId);
+                else
+                    friendName = friend.Friend;
+
+                MainConsole.Instance.OutputFormat("{0} {1} {2}", friendName, friend.MyFlags, friend.TheirFlags);
+            }
+        }
     }
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 0397478..f4ed67b 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -297,6 +297,35 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
 
         #region IUserManagement
 
+        public UUID GetUserIdByName(string name)
+        {
+            string[] parts = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
+            if (parts.Length < 2)
+                throw new Exception("Name must have 2 components");
+
+            return GetUserIdByName(parts[0], parts[1]);
+        }
+
+        public UUID GetUserIdByName(string firstName, string lastName)
+        {
+            // TODO: Optimize for reverse lookup if this gets used by non-console commands.
+            lock (m_UserCache)
+            {
+                foreach (UserData user in m_UserCache.Values)
+                {
+                    if (user.FirstName == firstName && user.LastName == lastName)
+                        return user.Id;
+                }
+            }
+
+            UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, firstName, lastName);
+
+            if (account != null)
+                return account.PrincipalID;
+
+            return UUID.Zero;
+        }
+
         public string GetUserName(UUID uuid)
         {
             string[] names = GetUserNames(uuid);
diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
index bfb8369..24cd069 100644
--- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
@@ -16,6 +16,21 @@ namespace OpenSim.Region.Framework.Interfaces
         string GetUserServerURL(UUID uuid, string serverType);
 
         /// <summary>
+        /// Get user ID by the given name.
+        /// </summary>
+        /// <param name="name"></param>
+        /// <returns>UUID.Zero if no user with that name is found or if the name is "Unknown User"</returns>
+        UUID GetUserIdByName(string name);
+
+        /// <summary>
+        /// Get user ID by the given name.
+        /// </summary>
+        /// <param name="firstName"></param>
+        /// <param name="lastName"></param>
+        /// <returns>UUID.Zero if no user with that name is found or if the name is "Unknown User"</returns>
+        UUID GetUserIdByName(string firstName, string lastName);
+
+        /// <summary>
         /// Add a user.
         /// </summary>
         /// <remarks>
-- 
cgit v1.1


From 300968e9339786611c9ac5c2ff3b58dec1c0c30e Mon Sep 17 00:00:00 2001
From: Diva Canto
Date: Tue, 27 Mar 2012 19:08:29 -0700
Subject: HG: Switch root folders from under the viewer. Towards HG 2.0. This
 is guarded by an obscure config that no one but me should be using at this
 point.

---
 .../EntityTransfer/HGEntityTransferModule.cs       | 54 ++++++++++++++++++----
 OpenSim/Region/Framework/Scenes/Scene.cs           | 15 ++++--
 2 files changed, 55 insertions(+), 14 deletions(-)

diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index b277095..4cdf303 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
 using System.Reflection;
 
 using OpenSim.Framework;
+using OpenSim.Framework.Client;
 using OpenSim.Region.Framework.Interfaces;
 using OpenSim.Region.Framework.Scenes;
 using OpenSim.Services.Connectors.Hypergrid;
@@ -177,9 +178,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
                     logout = success; // flag for later logout from this grid; this is an HG TP
 
                     if (success && m_RestrictInventoryAccessAbroad)
-                    {
-                        // TODO tell the viewer to remove the root folder
-                    }
+                        RemoveRootFolderContents(sp.ControllingClient);
 
                     return success;
                 }
@@ -299,13 +298,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
             base.Fail(sp, finalDestination, logout);
             if (logout && m_RestrictInventoryAccessAbroad)
             {
-                // Restore the user's inventory, because we removed it earlier on
-                InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(sp.UUID);
-                if (root != null)
-                {
-                    m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Restoring");
-                    sp.ControllingClient.SendBulkUpdateInventory(root);
-                }
+                RestoreRootFolderContents(sp.ControllingClient);
             }
         }
 
@@ -363,6 +356,47 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
 
         #endregion
 
+        private void RemoveRootFolderContents(IClientAPI client)
+        {
+            // TODO tell the viewer to remove the root folder's content
+            if (client is IClientCore)
+            {
+                IClientCore core = (IClientCore)client;
+                IClientInventory inv;
+
+                if (core.TryGet<IClientInventory>(out inv))
+                {
+                    InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId);
+                    if (root != null)
+                    {
+                        m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Removing root inventory");
+                        InventoryCollection content = m_Scenes[0].InventoryService.GetFolderContent(client.AgentId, root.ID);
+                        UUID[] ids = new UUID[content.Folders.Count];
+                        int i = 0;
+                        foreach (InventoryFolderBase f in content.Folders)
+                            ids[i++] = f.ID;
+                        inv.SendRemoveInventoryFolders(ids);
+                        ids = new UUID[content.Items.Count];
+                        i = 0;
+                        foreach (InventoryItemBase it in content.Items)
+                            ids[i++] = it.ID;
+                        inv.SendRemoveInventoryItems(ids);
+                    }
+                }
+            }
+        }
+
+        private void RestoreRootFolderContents(IClientAPI client)
+        {
+            // Restore the user's inventory, because we removed it earlier on
+            InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId);
+            if (root != null)
+            {
+                m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Restoring root inventory");
+                client.SendBulkUpdateInventory(root);
+            }
+        }
+
         private GridRegion MakeRegion(AgentCircuitData aCircuit)
         {
             GridRegion region = new GridRegion();
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0b31e0c..1f5cddd 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2675,12 +2675,19 @@ namespace OpenSim.Region.Framework.Scenes
             // Cache the user's name
             CacheUserName(sp, aCircuit);
 
-            // Let's send the Suitcase folder for incoming HG agents
+            // Let's send the Suitcase or the real root folder folder for incoming HG agents
+            // Visiting agents get their suitcase contents; incoming local users get their real root folder's content
             if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
             {
-                m_log.DebugFormat("[SCENE]: Sending root folder to viewer...");
-                InventoryFolderBase suitcase = InventoryService.GetRootFolder(client.AgentId);
-                client.SendBulkUpdateInventory(suitcase);
+                // HACK FOR NOW. JUST TESTING, SO KEEPING EVERYONE ELSE OUT OF THESE TESTS
+                IConfig config = m_config.Configs["HGEntityTransfer"];
+                if (config != null && config.GetBoolean("RestrictInventoryAccessAbroad", false))
+                {
+                    m_log.DebugFormat("[SCENE]: Sending root folder to viewer...");
+                    InventoryFolderBase root = InventoryService.GetRootFolder(client.AgentId);
+                    //InventoryCollection rootContents = InventoryService.GetFolderContent(client.AgentId, root.ID);
+                    client.SendBulkUpdateInventory(root);
+                }
             }
 
             EventManager.TriggerOnNewClient(client);
-- 
cgit v1.1