Пример #1
0
        /// <summary>
        /// Create a test user with a standard inventory
        /// </summary>
        /// <param name="commsManager"></param>
        /// <param name="userId">Explicit user id to use for user creation</param>
        /// <returns></returns>
        public static CachedUserInfo CreateUserWithInventory(CommunicationsManager commsManager, UUID userId)
        {
            LocalUserServices lus = (LocalUserServices)commsManager.UserService;

            lus.AddUser("Bill", "Bailey", "troll", "*****@*****.**", 1000, 1000, userId);

            CachedUserInfo userInfo = commsManager.UserProfileCacheService.GetUserDetails(userId);

            userInfo.FetchInventory();

            return(userInfo);
        }
Пример #2
0
        /// <summary>
        /// Test replication of an archive path to the user's inventory.
        /// </summary>
        //[Test]
        public void TestReplicateArchivePathToUserInventory()
        {
            TestHelper.InMethod();
            Scene scene = SceneSetupHelpers.SetupScene(false);
            CommunicationsManager commsManager = scene.CommsManager;

            CachedUserInfo userInfo = UserProfileTestUtils.CreateUserWithInventory(commsManager);

            userInfo.FetchInventory();
            for (int i = 0; i < 50; i++)
            {
                if (userInfo.HasReceivedInventory == true)
                {
                    break;
                }
                Thread.Sleep(200);
            }
            Assert.That(userInfo.HasReceivedInventory, Is.True, "FetchInventory timed out (10 seconds)");
            Dictionary <string, InventoryFolderImpl> foldersCreated = new Dictionary <string, InventoryFolderImpl>();
            List <InventoryNodeBase> nodesLoaded = new List <InventoryNodeBase>();

            string folder1Name = "a";
            string folder2Name = "b";
            string itemName    = "c.lsl";

            string folder1ArchiveName
                = string.Format(
                      "{0}{1}{2}", folder1Name, ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, UUID.Random());
            string folder2ArchiveName
                = string.Format(
                      "{0}{1}{2}", folder2Name, ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, UUID.Random());
            string itemArchivePath
                = string.Format(
                      "{0}{1}/{2}/{3}",
                      ArchiveConstants.INVENTORY_PATH, folder1ArchiveName, folder2ArchiveName, itemName);

            new InventoryArchiveReadRequest(userInfo, null, (Stream)null, null, null)
            .ReplicateArchivePathToUserInventory(itemArchivePath, false, userInfo.RootFolder, foldersCreated, nodesLoaded);

            InventoryFolderImpl folder1 = userInfo.RootFolder.FindFolderByPath("a");

            Assert.That(folder1, Is.Not.Null, "Could not find folder a");
            InventoryFolderImpl folder2 = folder1.FindFolderByPath("b");

            Assert.That(folder2, Is.Not.Null, "Could not find folder b");
        }
Пример #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="msg"></param>
        private void OnGridInstantMessage(GridInstantMessage msg)
        {
            // Check if this is ours to handle
            //
            m_log.Info("OnFridInstantMessage");
            if (msg.dialog != (byte)InstantMessageDialog.InventoryOffered)
            {
                return;
            }

            if (msg.binaryBucket.Length < 17) // Invalid
            {
                return;
            }

            Scene scene = FindClientScene(new UUID(msg.toAgentID));

            // Find agent to deliver to
            //
            ScenePresence user = scene.GetScenePresence(new UUID(msg.toAgentID));

            if (user == null) // Shouldn't happen
            {
                m_log.Debug("[INVENTORY TRANSFER] Can't find recipient");
                return;
            }

            CachedUserInfo userInfo =
                scene.CommsManager.UserProfileCacheService.
                GetUserDetails(user.ControllingClient.AgentId);

            if (userInfo == null)
            {
                m_log.Debug("[INVENTORY TRANSFER] Can't find user info of recipient");
                return;
            }

            AssetType assetType = (AssetType)msg.binaryBucket[0];

            if (AssetType.Folder == assetType)
            {
                UUID folderID = new UUID(msg.binaryBucket, 1);
                InventoryFolderBase folder = new InventoryFolderBase();

                folder.ID    = folderID;
                folder.Owner = user.ControllingClient.AgentId;

                // Fetch from database
                //
                if (!userInfo.QueryFolder(folder))
                {
                    m_log.Debug("[INVENTORY TRANSFER] Can't find folder to give");
                    return;
                }

                // Get folder info
                //
                InventoryFolderImpl folderInfo = userInfo.RootFolder.FindFolder(folder.ID);
                if (folderInfo == null)
                {
                    m_log.Debug("[INVENTORY TRANSFER] Can't retrieve folder to give");
                    return;
                }

                user.ControllingClient.SendBulkUpdateInventory(folderInfo);

                // This unelegant, slow kludge is to reload the folders and
                // items. Since a folder give can transfer subfolders and
                // items, this is the easiest way to pull that stuff in
                //
                userInfo.DropInventory();
                userInfo.FetchInventory();

                // Deliver message
                //
                user.ControllingClient.SendInstantMessage(msg);
            }
            else
            {
                UUID itemID            = new UUID(msg.binaryBucket, 1);
                InventoryItemBase item = new InventoryItemBase();

                item.ID    = itemID;
                item.Owner = user.ControllingClient.AgentId;

                // Fetch from database
                //
                if (!userInfo.QueryItem(item))
                {
                    m_log.Debug("[INVENTORY TRANSFER] Can't find item to give");
                    return;
                }

                // Get item info
                //
                item = userInfo.RootFolder.FindItem(item.ID);
                if (item == null)
                {
                    m_log.Debug("[INVENTORY TRANSFER] Can't retrieve item to give");
                    return;
                }

                // Update item to viewer (makes it appear in proper folder)
                //
                user.ControllingClient.SendBulkUpdateInventory(item);

                // Deliver message
                //
                user.ControllingClient.SendInstantMessage(msg);
            }
        }
        /// <summary>
        /// Execute the request
        /// </summary>
        /// <returns>
        /// A list of the inventory nodes loaded.  If folders were loaded then only the root folders are
        /// returned
        /// </returns>
        public List <InventoryNodeBase> Execute()
        {
            string filePath = "ERROR";
            int    successfulAssetRestores       = 0;
            int    failedAssetRestores           = 0;
            int    successfulItemRestores        = 0;
            List <InventoryNodeBase> nodesLoaded = new List <InventoryNodeBase>();

            if (!m_userInfo.HasReceivedInventory)
            {
                // If the region server has access to the user admin service (by which users are created),
                // then we'll assume that it's okay to fiddle with the user's inventory even if they are not on the
                // server.
                //
                // FIXME: FetchInventory should probably be assumed to by async anyway, since even standalones might
                // use a remote inventory service, though this is vanishingly rare at the moment.
                if (null == m_commsManager.UserAdminService)
                {
                    m_log.ErrorFormat(
                        "[INVENTORY ARCHIVER]: Have not yet received inventory info for user {0} {1}",
                        m_userInfo.UserProfile.Name, m_userInfo.UserProfile.ID);

                    return(nodesLoaded);
                }
                else
                {
                    m_userInfo.FetchInventory();
                }
            }

            InventoryFolderImpl rootDestinationFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath);

            if (null == rootDestinationFolder)
            {
                // Possibly provide an option later on to automatically create this folder if it does not exist
                m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath);

                return(nodesLoaded);
            }

            archive = new TarArchiveReader(m_loadStream);

            // In order to load identically named folders, we need to keep track of the folders that we have already
            // created
            Dictionary <string, InventoryFolderImpl> foldersCreated = new Dictionary <string, InventoryFolderImpl>();

            byte[] data;
            TarArchiveReader.TarEntryType entryType;
            while ((data = archive.ReadEntry(out filePath, out entryType)) != null)
            {
                if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
                {
                    if (LoadAsset(filePath, data))
                    {
                        successfulAssetRestores++;
                    }
                    else
                    {
                        failedAssetRestores++;
                    }
                }
                else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH))
                {
                    InventoryFolderImpl foundFolder
                        = ReplicateArchivePathToUserInventory(
                              filePath, TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType,
                              rootDestinationFolder, foldersCreated, nodesLoaded);

                    if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
                    {
                        InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data);

                        // Don't use the item ID that's in the file
                        item.ID = UUID.Random();

                        UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_commsManager);
                        if (UUID.Zero != ospResolvedId)
                        {
                            item.CreatorIdAsUuid = ospResolvedId;
                        }

                        item.Owner = m_userInfo.UserProfile.ID;

                        // Reset folder ID to the one in which we want to load it
                        item.Folder = foundFolder.ID;

                        m_userInfo.AddItem(item);
                        successfulItemRestores++;

                        // If we're loading an item directly into the given destination folder then we need to record
                        // it separately from any loaded root folders
                        if (rootDestinationFolder == foundFolder)
                        {
                            nodesLoaded.Add(item);
                        }
                    }
                }
            }

            archive.Close();

            m_log.DebugFormat("[INVENTORY ARCHIVER]: Restored {0} assets", successfulAssetRestores);
            m_log.InfoFormat("[INVENTORY ARCHIVER]: Restored {0} items", successfulItemRestores);

            return(nodesLoaded);
        }
Пример #5
0
        public void TestSaveIarV0p1()
        {
            TestHelper.InMethod();
            //log4net.Config.XmlConfigurator.Configure();

            InventoryArchiverModule archiverModule = new InventoryArchiverModule();

            Scene scene = SceneSetupHelpers.SetupScene(false);

            SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
            CommunicationsManager cm = scene.CommsManager;

            // Create user
            string userFirstName = "Jock";
            string userLastName  = "Stirrup";
            UUID   userId        = UUID.Parse("00000000-0000-0000-0000-000000000020");

            cm.UserAdminService.AddUser(userFirstName, userLastName, string.Empty, string.Empty, 1000, 1000, userId);
            CachedUserInfo userInfo = cm.UserProfileCacheService.GetUserDetails(userId);

            userInfo.FetchInventory();

            // Create asset
            SceneObjectGroup object1;
            SceneObjectPart  part1;
            {
                string             partName       = "My Little Dog Object";
                UUID               ownerId        = UUID.Parse("00000000-0000-0000-0000-000000000040");
                PrimitiveBaseShape shape          = PrimitiveBaseShape.CreateSphere();
                Vector3            groupPosition  = new Vector3(10, 20, 30);
                Quaternion         rotationOffset = new Quaternion(20, 30, 40, 50);
                Vector3            offsetPosition = new Vector3(5, 10, 15);

                part1
                    = new SceneObjectPart(
                          ownerId, shape, groupPosition, rotationOffset, offsetPosition);
                part1.Name = partName;

                object1 = new SceneObjectGroup(part1);
                scene.AddNewSceneObject(object1, false);
            }

            UUID      asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
            AssetBase asset1   = new AssetBase();

            asset1.FullID = asset1Id;
            asset1.Data   = Encoding.ASCII.GetBytes(SceneObjectSerializer.ToXml2Format(object1));
            cm.AssetCache.AddAsset(asset1);

            // Create item
            UUID item1Id            = UUID.Parse("00000000-0000-0000-0000-000000000080");
            InventoryItemBase item1 = new InventoryItemBase();

            item1.Name    = "My Little Dog";
            item1.AssetID = asset1.FullID;
            item1.ID      = item1Id;
            item1.Folder  = userInfo.RootFolder.FindFolderByPath("Objects").ID;
            scene.AddInventoryItem(userId, item1);

            MemoryStream archiveWriteStream = new MemoryStream();

            archiverModule.OnInventoryArchiveSaved += SaveCompleted;

            lock (this)
            {
                archiverModule.ArchiveInventory(userFirstName, userLastName, "Objects", archiveWriteStream);
                AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer;
                while (assetServer.HasWaitingRequests())
                {
                    assetServer.ProcessNextRequest();
                }

                Monitor.Wait(this, 60000);
            }

            byte[]           archive           = archiveWriteStream.ToArray();
            MemoryStream     archiveReadStream = new MemoryStream(archive);
            TarArchiveReader tar = new TarArchiveReader(archiveReadStream);

            InventoryFolderImpl objectsFolder = userInfo.RootFolder.FindFolderByPath("Objects");

            //bool gotControlFile = false;
            bool gotObject1File = false;
            //bool gotObject2File = false;
            string expectedObject1FilePath = string.Format(
                "{0}{1}/{2}_{3}.xml",
                ArchiveConstants.INVENTORY_PATH,
                string.Format(
                    "Objects{0}{1}", ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, objectsFolder.ID),
                item1.Name,
                item1Id);

/*
 *          string expectedObject2FileName = string.Format(
 *              "{0}_{1:000}-{2:000}-{3:000}__{4}.xml",
 *              part2.Name,
 *              Math.Round(part2.GroupPosition.X), Math.Round(part2.GroupPosition.Y), Math.Round(part2.GroupPosition.Z),
 *              part2.UUID);
 */

            string filePath;

            TarArchiveReader.TarEntryType tarEntryType;

            while (tar.ReadEntry(out filePath, out tarEntryType) != null)
            {
                Console.WriteLine("Got {0}", filePath);

                /*
                 * if (ArchiveConstants.CONTROL_FILE_PATH == filePath)
                 * {
                 *  gotControlFile = true;
                 * }
                 */
                if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml"))
                {
                    //string fileName = filePath.Remove(0, "Objects/".Length);

                    //if (fileName.StartsWith(part1.Name))
                    //{
                    Assert.That(filePath, Is.EqualTo(expectedObject1FilePath));
                    gotObject1File = true;
                    //}
                    //else if (fileName.StartsWith(part2.Name))
                    //{
                    //    Assert.That(fileName, Is.EqualTo(expectedObject2FileName));
                    //    gotObject2File = true;
                    //}
                }
            }

            //Assert.That(gotControlFile, Is.True, "No control file in archive");
            Assert.That(gotObject1File, Is.True, "No item1 file in archive");
            //Assert.That(gotObject2File, Is.True, "No object2 file in archive");

            // TODO: Test presence of more files and contents of files.
        }
Пример #6
0
        /// <summary>
        /// Execute the inventory write request
        /// </summary>
        public void Execute()
        {
            InventoryFolderImpl inventoryFolder = null;
            InventoryItemBase   inventoryItem   = null;

            if (!m_userInfo.HasReceivedInventory)
            {
                // If the region server has access to the user admin service (by which users are created),
                // then we'll assume that it's okay to fiddle with the user's inventory even if they are not on the
                // server.
                //
                // FIXME: FetchInventory should probably be assumed to by async anyway, since even standalones might
                // use a remote inventory service, though this is vanishingly rare at the moment.
                if (null == m_module.CommsManager.UserAdminService)
                {
                    m_log.ErrorFormat(
                        "[INVENTORY ARCHIVER]: Have not yet received inventory info for user {0} {1}",
                        m_userInfo.UserProfile.Name, m_userInfo.UserProfile.ID);

                    return;
                }
                else
                {
                    m_userInfo.FetchInventory();
                }
            }

            bool foundStar = false;

            // Eliminate double slashes and any leading / on the path.  This might be better done within InventoryFolderImpl
            // itself (possibly at a small loss in efficiency).
            string[] components
                = m_invPath.Split(new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries);

            int maxComponentIndex = components.Length - 1;

            // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the
            // folder itself.  This may get more sophisicated later on
            if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD)
            {
                foundStar = true;
                maxComponentIndex--;
            }

            m_invPath = String.Empty;
            for (int i = 0; i <= maxComponentIndex; i++)
            {
                m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER;
            }

            // Annoyingly Split actually returns the original string if the input string consists only of delimiters
            // Therefore if we still start with a / after the split, then we need the root folder
            if (m_invPath.Length == 0)
            {
                inventoryFolder = m_userInfo.RootFolder;
            }
            else
            {
                m_invPath       = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER));
                inventoryFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath);
            }

            // The path may point to an item instead
            if (inventoryFolder == null)
            {
                inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
            }

            m_archiveWriter = new TarArchiveWriter(m_saveStream);

            if (null == inventoryFolder)
            {
                if (null == inventoryItem)
                {
                    // We couldn't find the path indicated
                    m_saveStream.Close();
                    m_module.TriggerInventoryArchiveSaved(
                        false, m_userInfo, m_invPath, m_saveStream,
                        new Exception(string.Format("Could not find inventory entry at path {0}", m_invPath)));
                    return;
                }
                else
                {
                    m_log.DebugFormat(
                        "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}",
                        inventoryItem.Name, inventoryItem.ID, m_invPath);

                    SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH);
                }
            }
            else
            {
                m_log.DebugFormat(
                    "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}",
                    inventoryFolder.Name, inventoryFolder.ID, m_invPath);

                //recurse through all dirs getting dirs and files
                SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !foundStar);
            }

            SaveUsers();
            new AssetsRequest(
                new AssetsArchiver(m_archiveWriter), m_assetUuids.Keys,
                m_module.AssetService, ReceivedAllAssets).Execute();
        }
Пример #7
0
        /// <summary>
        /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
        /// no account exists with the creator name
        /// </summary>
        //[Test]
        public void TestLoadIarV0_1TempProfiles()
        {
            TestHelper.InMethod();

            log4net.Config.XmlConfigurator.Configure();

            string userFirstName  = "Dennis";
            string userLastName   = "Menace";
            UUID   userUuid       = UUID.Parse("00000000-0000-0000-0000-000000000aaa");
            string user2FirstName = "Walter";
            string user2LastName  = "Mitty";

            string itemName = "b.lsl";
            string archiveItemName
                = string.Format("{0}{1}{2}", itemName, "_", UUID.Random());

            MemoryStream     archiveWriteStream = new MemoryStream();
            TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);

            InventoryItemBase item1 = new InventoryItemBase();

            item1.Name      = itemName;
            item1.AssetID   = UUID.Random();
            item1.GroupID   = UUID.Random();
            item1.CreatorId = OspResolver.MakeOspa(user2FirstName, user2LastName);
            item1.Owner     = UUID.Zero;

            string item1FileName
                = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);

            tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1));
            tar.Close();

            MemoryStream            archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
            SerialiserModule        serialiserModule  = new SerialiserModule();
            InventoryArchiverModule archiverModule    = new InventoryArchiverModule();

            // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
            Scene             scene            = SceneSetupHelpers.SetupScene();
            IUserAdminService userAdminService = scene.CommsManager.UserAdminService;

            SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
            userAdminService.AddUser(
                userFirstName, userLastName, "meowfood", String.Empty, 1000, 1000, userUuid);

            archiverModule.DearchiveInventory(userFirstName, userLastName, "/", archiveReadStream);

            // Check that a suitable temporary user profile has been created.
            UserProfileData user2Profile
                = scene.CommsManager.UserService.GetUserProfile(
                      OspResolver.HashName(user2FirstName + " " + user2LastName));

            Assert.That(user2Profile, Is.Not.Null);
            Assert.That(user2Profile.FirstName == user2FirstName);
            Assert.That(user2Profile.SurName == user2LastName);

            CachedUserInfo userInfo
                = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName);

            userInfo.FetchInventory();
            for (int i = 0; i < 50; i++)
            {
                if (userInfo.HasReceivedInventory == true)
                {
                    break;
                }
                Thread.Sleep(200);
            }
            Assert.That(userInfo.HasReceivedInventory, Is.True, "FetchInventory timed out (10 seconds)");
            InventoryItemBase foundItem = userInfo.RootFolder.FindItemByPath(itemName);

            Assert.That(foundItem.CreatorId, Is.EqualTo(item1.CreatorId));
            Assert.That(
                foundItem.CreatorIdAsUuid, Is.EqualTo(OspResolver.HashName(user2FirstName + " " + user2LastName)));
            Assert.That(foundItem.Owner, Is.EqualTo(userUuid));

            Console.WriteLine("### Successfully completed {0} ###", MethodBase.GetCurrentMethod());
        }