A folder contains T:OpenMetaverse.InventoryItems and has certain attributes specific to itself
Inheritance: InventoryBase
コード例 #1
0
ファイル: TestClient.cs プロジェクト: RavenB/gridsearch
 /// <summary>
 /// Initialize everything that needs to be initialized once we're logged in.
 /// </summary>
 /// <param name="login">The status of the login</param>
 /// <param name="message">Error message on failure, MOTD on success.</param>
 public void LoginHandler(LoginStatus login, string message)
 {
     if (login == LoginStatus.Success)
     {
         // Start in the inventory root folder.
         CurrentDirectory = Inventory.Store.RootFolder;
     }
 }
コード例 #2
0
        public void myfolder_OnContentsRetrieved(InventoryFolder folder)
        {
            regFolderHook(folder);
            // folder.DownloadContentsOpenSim(TimeSpan.FromSeconds(60));
            // WriteLine("    myfolder_OnContentsRetrieved [" + folder.Name + "] = " + folder.UUID.ToString()+ " with count="+folder.Contents.Count.ToString());
            List<InventoryBase> folderContents = client.Inventory.FolderContents(folder.UUID, client.Self.AgentID,
                                                                                    true, true, InventorySortOrder.ByName, 10000);
            if (folderContents != null)
            {

                foreach (InventoryBase ib in folderContents)
                {
                    if (ib is InventoryItem)
                    {
                        InventoryItem ii = ib as InventoryItem;
                        if (current_operation == "print")
                        {
                            //int indent = 1;
                            //StringBuilder result = new StringBuilder();
                            //result.AppendFormat("{0}{1} ({2})\n", new String(' ', indent * 2), ii.Name, ii.UUID.ToString());
                            //WriteLine(result.ToString());
                            WriteLine("   [Inventory Item] Name: " + ii.Name + " <==> " + ii.UUID.ToString() + " in folder[" + folder.Name + "]");
                        }


                        if (ii.Name == current_itemName)
                        {
                            // we found a matcher so lets do our ops
                            if (current_operation == "wear") client.Appearance.AddToOutfit(new List<InventoryItem> { ii });
                            if (current_operation == "animationStart") client.Self.AnimationStart(ii.UUID, false);
                            if (current_operation == "animationStop") client.Self.AnimationStop(ii.UUID, false);
                            if (current_operation == "attach") client.Appearance.Attach(ii, AttachmentPoint.Default);
                            if (current_operation == "rez")
                            {
                                client.Inventory.RequestRestoreRezFromInventory(client.Network.CurrentSim, ii,
                                                                                   UUID.Random());
                            }
                        }
                    }
                }
                // now run any sub folders
                foreach (InventoryBase ib in folderContents)
                {
                    if (ib is InventoryFolder)
                    {
                        InventoryFolder fld = (InventoryFolder)ib;

                        WriteLine(String.Format(" [Folder] Name: {0} <==> {1} in folder[{2}] RECIEVED", ib.Name, ib.UUID, folder.Name));

                        //evalOnFolders(ib as InventoryFolder, operation, itemName);
                        appendFolderHook(fld);
                        //fld.RequestContents();

                    }
                }
            }

        }
コード例 #3
0
        public void regFolderHook(InventoryFolder folder)
        {
            if (!hooked.ContainsKey(folder.UUID))
            {
                hooked.Add(folder.UUID, folder.Name);
                WriteLine("  regFolderHook " + folder.Name);
            }

        }
コード例 #4
0
        public void appendFolderHook(InventoryFolder folder)
        {
            if (!hooked.ContainsKey(folder.UUID))
            {
                hooked.Add(folder.UUID, folder.Name);
                //    botclient.Inventory.OnContentsRetrieved += new InventoryFolder.ContentsRetrieved(myfolder_OnContentsRetrieved);
                WriteLine("  appendFolderHook " + folder.Name);
            }

        }
コード例 #5
0
ファイル: TestClient.cs プロジェクト: RavenB/gridsearch
        /// <summary>
        /// Initialize everything that needs to be initialized once we're logged in.
        /// </summary>
        /// <param name="login">The status of the login</param>
        /// <param name="message">Error message on failure, MOTD on success.</param>
        public void  LoginHandler(LoginStatus login, string message)
        {
            if (login == LoginStatus.Success)
            {
                // Create the stores:
                InventoryStore = new Inventory(Inventory, Inventory.InventorySkeleton);
                LibraryStore = new Inventory(Inventory, Inventory.LibrarySkeleton);

                // Start in the inventory root folder:
                CurrentDirectory = InventoryStore.RootFolder;
            }
        }
コード例 #6
0
ファイル: InventoryCommand.cs プロジェクト: RavenB/gridsearch
 void PrintFolder(InventoryFolder folder, StringBuilder result, int indent)
 {
     folder.DownloadContents(TimeSpan.FromSeconds(10));
     foreach (InventoryBase b in folder)
     {
         if (b is InventoryFolder)
         {
             result.Append(Print(b as InventoryFolder, indent));
             PrintFolder(b as InventoryFolder, result, indent + 1);
         }
         else if (b is InventoryItem)
         {
             result.Append(Print(b as InventoryItem, indent));
         }
     }
 }
コード例 #7
0
        private void PrintFolder(InventoryFolder f, StringBuilder result, int indent)
        {
            List<InventoryBase> contents = Manager.FolderContents(f.UUID, Client.Self.AgentID,
                                                                  true, true, InventorySortOrder.ByName, 10000);

            if (contents != null)
            {
                foreach (InventoryBase i in contents)
                {
                    result.AppendFormat("{0}{1} ({2})\n", new String(' ', indent*2), i.Name, i.UUID);
                    if (i is InventoryFolder)
                    {
                        InventoryFolder folder = (InventoryFolder) i;
                        PrintFolder(folder, result, indent + 1);
                    }
                }
            }
        }
コード例 #8
0
ファイル: FolderCopy.cs プロジェクト: TooheyPaneer/radegast
 public void CopyFolder(InventoryFolder dest, InventoryFolder folder)
 {
     UUID newFolderID = Client.Inventory.CreateFolder(dest.UUID, folder.Name, AssetType.Unknown);
     Thread.Sleep(500);
     var items = Client.Inventory.FolderContents(folder.UUID, folder.OwnerID, true, true, InventorySortOrder.ByDate, 45 * 1000);
     AutoResetEvent copied = new AutoResetEvent(false);
     foreach (var item in items)
     {
         if (item is InventoryItem)
         {
             copied.Reset();
             Client.Inventory.RequestCopyItem(item.UUID, newFolderID, item.Name, folder.OwnerID, (InventoryBase target) =>
             {
                 Instance.TabConsole.DisplayNotificationInChat(string.Format("    * Copied {0} to {1}", item.Name, dest.Name));
                 copied.Set();
             });
             copied.WaitOne(15 * 1000, false);
         }
     }
 }
コード例 #9
0
ファイル: Login.cs プロジェクト: RavenB/gridsearch
        public InventoryFolder[] ParseInventorySkeleton(string key, OSDMap reply)
        {
            List<InventoryFolder> folders = new List<InventoryFolder>();

            OSD skeleton;
            if (reply.TryGetValue(key, out skeleton) && skeleton.Type == OSDType.Array)
            {
                OSDArray array = (OSDArray)skeleton;
                for (int i = 0; i < array.Count; i++)
                {
                    if (array[i].Type == OSDType.Map)
                    {
                        OSDMap map = (OSDMap)array[i];
                        InventoryFolder folder = new InventoryFolder(map["folder_id"].AsUUID());
                        folder.Name = map["name"].AsString();
                        folder.ParentUUID = map["parent_id"].AsUUID();
                        folder.PreferredType = (AssetType)map["type_default"].AsInteger();
                        folder.Version = map["version"].AsInteger();
                        folders.Add(folder);
                    }
                }
            }
            return folders.ToArray();
        }
コード例 #10
0
ファイル: InventoryManager.cs プロジェクト: RavenB/gridsearch
        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void BulkUpdateInventoryHandler(object sender, PacketReceivedEventArgs e)
        {
            Packet packet = e.Packet;

            BulkUpdateInventoryPacket update = packet as BulkUpdateInventoryPacket;

            if (update.FolderData.Length > 0 && update.FolderData[0].FolderID != UUID.Zero)
            {
                foreach (BulkUpdateInventoryPacket.FolderDataBlock dataBlock in update.FolderData)
                {
                    if (!_Store.Contains(dataBlock.FolderID))
                        Logger.Log("Received BulkUpdate for unknown folder: " + dataBlock.FolderID, Helpers.LogLevel.Warning, Client);

                    InventoryFolder folder = new InventoryFolder(dataBlock.FolderID);
                    folder.Name = Utils.BytesToString(dataBlock.Name);
                    folder.OwnerID = update.AgentData.AgentID;
                    folder.ParentUUID = dataBlock.ParentID;
                    _Store[folder.UUID] = folder;
                }
            }

            if (update.ItemData.Length > 0 && update.ItemData[0].ItemID != UUID.Zero)
            {
                for (int i = 0; i < update.ItemData.Length; i++)
                {
                    BulkUpdateInventoryPacket.ItemDataBlock dataBlock = update.ItemData[i];

                    // If we are given a folder of items, the item information might arrive before the folder
                    // (parent) is in the store
                    if (!_Store.Contains(dataBlock.ItemID))
                        Logger.Log("Received BulkUpdate for unknown item: " + dataBlock.ItemID, Helpers.LogLevel.Warning, Client);

                    InventoryItem item = SafeCreateInventoryItem((InventoryType)dataBlock.InvType, dataBlock.ItemID);

                    item.AssetType = (AssetType)dataBlock.Type;
                    if (dataBlock.AssetID != UUID.Zero) item.AssetUUID = dataBlock.AssetID;
                    item.CreationDate = Utils.UnixTimeToDateTime(dataBlock.CreationDate);
                    item.CreatorID = dataBlock.CreatorID;
                    item.Description = Utils.BytesToString(dataBlock.Description);
                    item.Flags = dataBlock.Flags;
                    item.GroupID = dataBlock.GroupID;
                    item.GroupOwned = dataBlock.GroupOwned;
                    item.Name = Utils.BytesToString(dataBlock.Name);
                    item.OwnerID = dataBlock.OwnerID;
                    item.ParentUUID = dataBlock.FolderID;
                    item.Permissions = new Permissions(
                        dataBlock.BaseMask,
                        dataBlock.EveryoneMask,
                        dataBlock.GroupMask,
                        dataBlock.NextOwnerMask,
                        dataBlock.OwnerMask);
                    item.SalePrice = dataBlock.SalePrice;
                    item.SaleType = (SaleType)dataBlock.SaleType;

                    _Store[item.UUID] = item;

                    // Look for an "item created" callback
                    ItemCreatedCallback callback;
                    if (_ItemCreatedCallbacks.TryGetValue(dataBlock.CallbackID, out callback))
                    {
                        _ItemCreatedCallbacks.Remove(dataBlock.CallbackID);

                        try { callback(true, item); }
                        catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); }
                    }

                    // Look for an "item copied" callback
                    ItemCopiedCallback copyCallback;
                    if (_ItemCopiedCallbacks.TryGetValue(dataBlock.CallbackID, out copyCallback))
                    {
                        _ItemCopiedCallbacks.Remove(dataBlock.CallbackID);

                        try { copyCallback(item); }
                        catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); }
                    }
                }
            }
        }
コード例 #11
0
ファイル: InventoryManager.cs プロジェクト: RavenB/gridsearch
        private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData)
        {
            if (loginSuccess)
            {
                // Initialize the store here so we know who owns it:
                _Store = new Inventory(Client, this, Client.Self.AgentID);
                Logger.DebugLog("Setting InventoryRoot to " + replyData.InventoryRoot.ToString(), Client);
                InventoryFolder rootFolder = new InventoryFolder(replyData.InventoryRoot);
                rootFolder.Name = String.Empty;
                rootFolder.ParentUUID = UUID.Zero;
                _Store.RootFolder = rootFolder;

                for (int i = 0; i < replyData.InventorySkeleton.Length; i++)
                    _Store.UpdateNodeFor(replyData.InventorySkeleton[i]);

                InventoryFolder libraryRootFolder = new InventoryFolder(replyData.LibraryRoot);
                libraryRootFolder.Name = String.Empty;
                libraryRootFolder.ParentUUID = UUID.Zero;
                _Store.LibraryFolder = libraryRootFolder;

                for (int i = 0; i < replyData.LibrarySkeleton.Length; i++)
                    _Store.UpdateNodeFor(replyData.LibrarySkeleton[i]);
            }
        }
コード例 #12
0
ファイル: InventoryManager.cs プロジェクト: RavenB/gridsearch
 /// <summary>
 /// Creates inventory link to another inventory folder
 /// </summary>
 /// <param name="folderID">Put newly created link in folder with this UUID</param>
 /// <param name="folder">Original inventory folder</param>
 /// <param name="callback">Method to call upon creation of the link</param>
 public void CreateLink(UUID folderID, InventoryFolder folder, ItemCreatedCallback callback)
 {
     CreateLink(folderID, folder.UUID, folder.Name, "", AssetType.LinkFolder, InventoryType.Folder, UUID.Random(), callback);
 }
コード例 #13
0
ファイル: InventoryManager.cs プロジェクト: RavenB/gridsearch
 /// <summary>
 /// Move an inventory item or folder to a new location and change its name
 /// </summary>
 /// <param name="item">The <seealso cref="T:InventoryBase"/> item or folder to move</param>
 /// <param name="newParent">The <seealso cref="T:InventoryFolder"/> to move item or folder to</param>
 /// <param name="newName">The name to change the item or folder to</param>
 public void Move(InventoryBase item, InventoryFolder newParent, string newName)
 {
     if (item is InventoryFolder)
         MoveFolder(item.UUID, newParent.UUID, newName);
     else
         MoveItem(item.UUID, newParent.UUID, newName);
 }
コード例 #14
0
 TreeNode AddDir(TreeNode parentNode, InventoryFolder f)
 {
     TreeNode dirNode = new TreeNode();
     dirNode.Name = f.UUID.ToString();
     dirNode.Text = f.Name;
     dirNode.Tag = f;
     dirNode.ImageIndex = GetDirImageIndex(f.PreferredType.ToString().ToLower());
     dirNode.SelectedImageIndex = dirNode.ImageIndex;
     if (parentNode == null)
     {
         invTree.Nodes.Add(dirNode);
     }
     else
     {
         parentNode.Nodes.Add(dirNode);
     }
     lock (UUID2NodeCache)
     {
         UUID2NodeCache[f.UUID] = dirNode;
     }
     return dirNode;
 }
コード例 #15
0
ファイル: Inventory.cs プロジェクト: RavenB/gridsearch
 public List<InventoryBase> GetContents(InventoryFolder folder)
 {
     return GetContents(folder.UUID);
 }
コード例 #16
0
        public void Init2()
        {
            if (instance.MainForm.InvokeRequired)
            {
                instance.MainForm.BeginInvoke(new MethodInvoker(() => Init2()));
                return;
            }

            AddFolderFromStore(invRootNode, Inventory.RootFolder);

            sorter = new InvNodeSorter();

            if (!instance.GlobalSettings.ContainsKey("inv_sort_bydate"))
                instance.GlobalSettings["inv_sort_bydate"] = OSD.FromBoolean(true);
            if (!instance.GlobalSettings.ContainsKey("inv_sort_sysfirst"))
                instance.GlobalSettings["inv_sort_sysfirst"] = OSD.FromBoolean(true);

            sorter.ByDate = instance.GlobalSettings["inv_sort_bydate"].AsBoolean();
            sorter.SystemFoldersFirst = instance.GlobalSettings["inv_sort_sysfirst"].AsBoolean();

            tbtnSortByDate.Checked = sorter.ByDate;
            tbtbSortByName.Checked = !sorter.ByDate;
            tbtnSystemFoldersFirst.Checked = sorter.SystemFoldersFirst;

            invTree.TreeViewNodeSorter = sorter;

            if (instance.MonoRuntime)
            {
                invTree.BackColor = Color.FromKnownColor(KnownColor.Window);
                invTree.ForeColor = invTree.LineColor = Color.FromKnownColor(KnownColor.WindowText);
                InventoryFolder f = new InventoryFolder(UUID.Random());
                f.Name = "";
                f.ParentUUID = UUID.Zero;
                f.PreferredType = AssetType.Unknown;
                TreeNode dirNode = new TreeNode();
                dirNode.Name = f.UUID.ToString();
                dirNode.Text = f.Name;
                dirNode.Tag = f;
                dirNode.ImageIndex = GetDirImageIndex(f.PreferredType.ToString().ToLower());
                dirNode.SelectedImageIndex = dirNode.ImageIndex;
                invTree.Nodes.Add(dirNode);
                invTree.Sort();
            }

            saveAllTToolStripMenuItem.Enabled = false;
            InventoryUpdate = new Thread(new ThreadStart(StartTraverseNodes));
            InventoryUpdate.Name = "InventoryUpdate";
            InventoryUpdate.IsBackground = true;
            InventoryUpdate.Start();

            invRootNode.Expand();

            invTree.AfterExpand += new TreeViewEventHandler(TreeView_AfterExpand);
            invTree.NodeMouseClick += new TreeNodeMouseClickEventHandler(invTree_MouseClick);
            invTree.NodeMouseDoubleClick += new TreeNodeMouseClickEventHandler(invTree_NodeMouseDoubleClick);

            _EditTimer = new System.Threading.Timer(OnLabelEditTimer, null, System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite);

            // Callbacks
            Inventory.InventoryObjectAdded += new EventHandler<InventoryObjectAddedEventArgs>(Inventory_InventoryObjectAdded);
            Inventory.InventoryObjectUpdated += new EventHandler<InventoryObjectUpdatedEventArgs>(Inventory_InventoryObjectUpdated);
            Inventory.InventoryObjectRemoved += new EventHandler<InventoryObjectRemovedEventArgs>(Inventory_InventoryObjectRemoved);

            client.Objects.ObjectUpdate += new EventHandler<PrimEventArgs>(Objects_AttachmentUpdate);
            client.Objects.KillObject += new EventHandler<KillObjectEventArgs>(Objects_KillObject);
            client.Appearance.AppearanceSet += new EventHandler<AppearanceSetEventArgs>(Appearance_AppearanceSet);
        }
コード例 #17
0
 int CompareFolders(InventoryFolder x, InventoryFolder y)
 {
     if (_sysfirst)
     {
         if (x.PreferredType != AssetType.Unknown && y.PreferredType == AssetType.Unknown)
         {
             return -1;
         }
         else if (x.PreferredType == AssetType.Unknown && y.PreferredType != AssetType.Unknown)
         {
             return 1;
         }
     }
     return String.Compare(x.Name, y.Name);
 }
コード例 #18
0
ファイル: Inventory.cs プロジェクト: RavenB/gridsearch
        /// <summary>
        /// Updates the state of the InventoryNode and inventory data structure that
        /// is responsible for the InventoryObject. If the item was previously not added to inventory,
        /// it adds the item, and updates structure accordingly. If it was, it updates the 
        /// InventoryNode, changing the parent node if <code>item.parentUUID</code> does 
        /// not match <code>node.Parent.Data.UUID</code>.
        /// 
        /// You can not set the inventory root folder using this method
        /// </summary>
        /// <param name="item">The InventoryObject to store</param>
        public void UpdateNodeFor(InventoryBase item)
        {
            lock (Items)
            {
                InventoryNode itemParent = null;
                if (item.ParentUUID != UUID.Zero && !Items.TryGetValue(item.ParentUUID, out itemParent))
                {
                    // OK, we have no data on the parent, let's create a fake one.
                    InventoryFolder fakeParent = new InventoryFolder(item.ParentUUID);
                    fakeParent.DescendentCount = 1; // Dear god, please forgive me.
                    itemParent = new InventoryNode(fakeParent);
                    Items[item.ParentUUID] = itemParent;
                    // Unfortunately, this breaks the nice unified tree
                    // while we're waiting for the parent's data to come in.
                    // As soon as we get the parent, the tree repairs itself.
                    Logger.DebugLog("Attempting to update inventory child of " +
                        item.ParentUUID.ToString() + " when we have no local reference to that folder", Client);

                    if (Client.Settings.FETCH_MISSING_INVENTORY)
                    {
                        // Fetch the parent
                        List<UUID> fetchreq = new List<UUID>(1);
                        fetchreq.Add(item.ParentUUID);
                        //Manager.FetchInventory(fetchreq); // we cant fetch folder data! :-O
                    }
                }

                InventoryNode itemNode;
                if (Items.TryGetValue(item.UUID, out itemNode)) // We're updating.
                {
                    InventoryNode oldParent = itemNode.Parent;
                    // Handle parent change
                    if (oldParent == null || itemParent == null || itemParent.Data.UUID != oldParent.Data.UUID)
                    {
                        if (oldParent != null)
                        {
                            lock (oldParent.Nodes.SyncRoot)
                                oldParent.Nodes.Remove(item.UUID);
                        }
                        if (itemParent != null)
                        {
                            lock (itemParent.Nodes.SyncRoot)
                                itemParent.Nodes[item.UUID] = itemNode;
                        }
                    }

                    itemNode.Parent = itemParent;

                    FireOnInventoryObjectUpdated(itemNode.Data, item);

                    itemNode.Data = item;
                }
                else // We're adding.
                {
                    itemNode = new InventoryNode(item, itemParent);
                    Items.Add(item.UUID, itemNode);
                    FireOnInventoryObjectAdded(item);
                }
            }
        }
コード例 #19
0
 private void AddFolderFromStore(TreeNode parent, InventoryFolder f)
 {
     List<InventoryBase> contents = Inventory.GetContents(f);
     foreach (InventoryBase item in contents)
     {
         TreeNode node = AddBase(parent, item);
         if (item is InventoryFolder)
         {
             AddFolderFromStore(node, (InventoryFolder)item);
         }
     }
 }
コード例 #20
0
ファイル: TestClient.cs プロジェクト: zadark/par
 /// <summary>
 /// Initialize everything that needs to be initialized once we're logged in.
 /// </summary>
 /// <param name="login">The status of the login</param>
 /// <param name="message">Error message on failure, MOTD on success.</param>
 public void LoginHandler(object sender, LoginProgressEventArgs e)
 {
     if (e.Status == LoginStatus.Success)
     {
         // Start in the inventory root folder.
         CurrentDirectory = Inventory.Store.RootFolder;
     }
 }
コード例 #21
0
ファイル: InventoryManager.cs プロジェクト: RavenB/gridsearch
        /// <summary>
        /// Creates a new inventory folder
        /// </summary>
        /// <param name="parentID">ID of the folder to put this folder in</param>
        /// <param name="name">Name of the folder to create</param>
        /// <param name="preferredType">Sets this folder as the default folder
        /// for new assets of the specified type. Use <code>AssetType.Unknown</code>
        /// to create a normal folder, otherwise it will likely create a
        /// duplicate of an existing folder type</param>
        /// <returns>The UUID of the newly created folder</returns>
        /// <remarks>If you specify a preferred type of <code>AsseType.Folder</code>
        /// it will create a new root folder which may likely cause all sorts
        /// of strange problems</remarks>
        public UUID CreateFolder(UUID parentID, string name, AssetType preferredType)
        {
            UUID id = UUID.Random();

            // Assign a folder name if one is not already set
            if (String.IsNullOrEmpty(name))
            {
                if (preferredType >= AssetType.Texture && preferredType <= AssetType.Gesture)
                {
                    name = _NewFolderNames[(int)preferredType];
                }
                else
                {
                    name = "New Folder";
                }
            }

            // Create the new folder locally
            InventoryFolder newFolder = new InventoryFolder(id);
            newFolder.Version = 1;
            newFolder.DescendentCount = 0;
            newFolder.ParentUUID = parentID;
            newFolder.PreferredType = preferredType;
            newFolder.Name = name;
            newFolder.OwnerID = Client.Self.AgentID;

            // Update the local store
            try { _Store[newFolder.UUID] = newFolder; }
            catch (InventoryException ie) { Logger.Log(ie.Message, Helpers.LogLevel.Warning, Client, ie); }

            // Create the create folder packet and send it
            CreateInventoryFolderPacket create = new CreateInventoryFolderPacket();
            create.AgentData.AgentID = Client.Self.AgentID;
            create.AgentData.SessionID = Client.Self.SessionID;

            create.FolderData.FolderID = id;
            create.FolderData.ParentID = parentID;
            create.FolderData.Type = (sbyte)preferredType;
            create.FolderData.Name = Utils.StringToBytes(name);

            Client.Network.SendPacket(create);

            return id;
        }
コード例 #22
0
        void populate_top_level_inv()
        {
            lock (inventory)
            {
                if (MainClass.client.Inventory.Store.Items != null)
                {
                    foreach (KeyValuePair<UUID, InventoryNode> kvp in MainClass.client.Inventory.Store.Items)
                    {
                        if (kvp.Value.Data != null)
                        {
                            if (kvp.Value.Data.ParentUUID == UUID.Zero)
                            {
                                if (!assetmap.ContainsKey(MainClass.client.Inventory.Store.RootFolder.UUID))
                                {
                                    InventoryFolder fdr = new InventoryFolder(MainClass.client.Inventory.Store.RootFolder.UUID);
                                    fdr.Name = "My Inventory";
                                    Gtk.TreeIter iterx = inventory.AppendValues(folder_closed, kvp.Value.Data.Name, kvp.Value.Data.UUID, fdr);
                                    Console.Write("Creating top level folder " + kvp.Value.Data.Name + " : " + MainClass.client.Inventory.Store.Items[kvp.Value.Data.UUID].ToString());
                                    assetmap.Add(MainClass.client.Inventory.Store.RootFolder.UUID, iterx);
                                    inventory.AppendValues(iterx, folder_closed, "Waiting...", kvp.Value.Data.UUID, null);
                                    if (kvp.Value.Data.Name == "My Inventory")
                                        TLI = iterx;
                                }

                            }
                            Console.Write(kvp.Value.Data.ParentUUID.ToString() + " : ");
                        }
                    }

                    this.no_items = 0;
                    MainClass.client.Inventory.Store.RestoreFromDisk(MainClass.client.Settings.ASSET_CACHE_DIR + System.IO.Path.DirectorySeparatorChar + MainClass.client.Inventory.Store.RootFolder.UUID.ToString() + ".osl");

                    fetcherrunning = true;
                    Thread invRunner = new Thread(new ParameterizedThreadStart(fetchinventory));
                    invthreaddata itd = new invthreaddata(MainClass.client.Inventory.Store.RootFolder.UUID, "0", TLI, true, true);
                    invRunner.Start(itd);
                }
            }
        }
コード例 #23
0
ファイル: InventoryManager.cs プロジェクト: RavenB/gridsearch
        /// <summary>
        /// Parse the results of a RequestTaskInventory() response
        /// </summary>
        /// <param name="taskData">A string which contains the data from the task reply</param>
        /// <returns>A List containing the items contained within the tasks inventory</returns>
        public static List<InventoryBase> ParseTaskInventory(string taskData)
        {
            List<InventoryBase> items = new List<InventoryBase>();
            int lineNum = 0;
            string[] lines = taskData.Replace("\r\n", "\n").Split('\n');

            while (lineNum < lines.Length)
            {
                string key, value;
                if (ParseLine(lines[lineNum++], out key, out value))
                {
                    if (key == "inv_object")
                    {
                        #region inv_object

                        // In practice this appears to only be used for folders
                        UUID itemID = UUID.Zero;
                        UUID parentID = UUID.Zero;
                        string name = String.Empty;
                        AssetType assetType = AssetType.Unknown;

                        while (lineNum < lines.Length)
                        {
                            if (ParseLine(lines[lineNum++], out key, out value))
                            {
                                if (key == "{")
                                {
                                    continue;
                                }
                                else if (key == "}")
                                {
                                    break;
                                }
                                else if (key == "obj_id")
                                {
                                    UUID.TryParse(value, out itemID);
                                }
                                else if (key == "parent_id")
                                {
                                    UUID.TryParse(value, out parentID);
                                }
                                else if (key == "type")
                                {
                                    assetType = Utils.StringToAssetType(value);
                                }
                                else if (key == "name")
                                {
                                    name = value.Substring(0, value.IndexOf('|'));
                                }
                            }
                        }

                        if (assetType == AssetType.Folder)
                        {
                            InventoryFolder folder = new InventoryFolder(itemID);
                            folder.Name = name;
                            folder.ParentUUID = parentID;

                            items.Add(folder);
                        }
                        else
                        {
                            InventoryItem item = new InventoryItem(itemID);
                            item.Name = name;
                            item.ParentUUID = parentID;
                            item.AssetType = assetType;

                            items.Add(item);
                        }

                        #endregion inv_object
                    }
                    else if (key == "inv_item")
                    {
                        #region inv_item

                        // Any inventory item that links to an assetID, has permissions, etc
                        UUID itemID = UUID.Zero;
                        UUID assetID = UUID.Zero;
                        UUID parentID = UUID.Zero;
                        UUID creatorID = UUID.Zero;
                        UUID ownerID = UUID.Zero;
                        UUID lastOwnerID = UUID.Zero;
                        UUID groupID = UUID.Zero;
                        bool groupOwned = false;
                        string name = String.Empty;
                        string desc = String.Empty;
                        AssetType assetType = AssetType.Unknown;
                        InventoryType inventoryType = InventoryType.Unknown;
                        DateTime creationDate = Utils.Epoch;
                        uint flags = 0;
                        Permissions perms = Permissions.NoPermissions;
                        SaleType saleType = SaleType.Not;
                        int salePrice = 0;

                        while (lineNum < lines.Length)
                        {
                            if (ParseLine(lines[lineNum++], out key, out value))
                            {
                                if (key == "{")
                                {
                                    continue;
                                }
                                else if (key == "}")
                                {
                                    break;
                                }
                                else if (key == "item_id")
                                {
                                    UUID.TryParse(value, out itemID);
                                }
                                else if (key == "parent_id")
                                {
                                    UUID.TryParse(value, out parentID);
                                }
                                else if (key == "permissions")
                                {
                                    #region permissions

                                    while (lineNum < lines.Length)
                                    {
                                        if (ParseLine(lines[lineNum++], out key, out value))
                                        {
                                            if (key == "{")
                                            {
                                                continue;
                                            }
                                            else if (key == "}")
                                            {
                                                break;
                                            }
                                            else if (key == "creator_mask")
                                            {
                                                // Deprecated
                                                uint val;
                                                if (Utils.TryParseHex(value, out val))
                                                    perms.BaseMask = (PermissionMask)val;
                                            }
                                            else if (key == "base_mask")
                                            {
                                                uint val;
                                                if (Utils.TryParseHex(value, out val))
                                                    perms.BaseMask = (PermissionMask)val;
                                            }
                                            else if (key == "owner_mask")
                                            {
                                                uint val;
                                                if (Utils.TryParseHex(value, out val))
                                                    perms.OwnerMask = (PermissionMask)val;
                                            }
                                            else if (key == "group_mask")
                                            {
                                                uint val;
                                                if (Utils.TryParseHex(value, out val))
                                                    perms.GroupMask = (PermissionMask)val;
                                            }
                                            else if (key == "everyone_mask")
                                            {
                                                uint val;
                                                if (Utils.TryParseHex(value, out val))
                                                    perms.EveryoneMask = (PermissionMask)val;
                                            }
                                            else if (key == "next_owner_mask")
                                            {
                                                uint val;
                                                if (Utils.TryParseHex(value, out val))
                                                    perms.NextOwnerMask = (PermissionMask)val;
                                            }
                                            else if (key == "creator_id")
                                            {

                                                UUID.TryParse(value, out creatorID);
                                            }
                                            else if (key == "owner_id")
                                            {
                                                UUID.TryParse(value, out ownerID);
                                            }
                                            else if (key == "last_owner_id")
                                            {
                                                UUID.TryParse(value, out lastOwnerID);
                                            }
                                            else if (key == "group_id")
                                            {
                                                UUID.TryParse(value, out groupID);
                                            }
                                            else if (key == "group_owned")
                                            {
                                                uint val;
                                                if (UInt32.TryParse(value, out val))
                                                    groupOwned = (val != 0);
                                            }
                                        }
                                    }

                                    #endregion permissions
                                }
                                else if (key == "sale_info")
                                {
                                    #region sale_info

                                    while (lineNum < lines.Length)
                                    {
                                        if (ParseLine(lines[lineNum++], out key, out value))
                                        {
                                            if (key == "{")
                                            {
                                                continue;
                                            }
                                            else if (key == "}")
                                            {
                                                break;
                                            }
                                            else if (key == "sale_type")
                                            {
                                                saleType = Utils.StringToSaleType(value);
                                            }
                                            else if (key == "sale_price")
                                            {
                                                Int32.TryParse(value, out salePrice);
                                            }
                                        }
                                    }

                                    #endregion sale_info
                                }
                                else if (key == "shadow_id")
                                {
                                    UUID shadowID;
                                    if (UUID.TryParse(value, out shadowID))
                                        assetID = DecryptShadowID(shadowID);
                                }
                                else if (key == "asset_id")
                                {
                                    UUID.TryParse(value, out assetID);
                                }
                                else if (key == "type")
                                {
                                    assetType = Utils.StringToAssetType(value);
                                }
                                else if (key == "inv_type")
                                {
                                    inventoryType = Utils.StringToInventoryType(value);
                                }
                                else if (key == "flags")
                                {
                                    UInt32.TryParse(value, out flags);
                                }
                                else if (key == "name")
                                {
                                    name = value.Substring(0, value.IndexOf('|'));
                                }
                                else if (key == "desc")
                                {
                                    desc = value.Substring(0, value.IndexOf('|'));
                                }
                                else if (key == "creation_date")
                                {
                                    uint timestamp;
                                    if (UInt32.TryParse(value, out timestamp))
                                        creationDate = Utils.UnixTimeToDateTime(timestamp);
                                    else
                                        Logger.Log("Failed to parse creation_date " + value, Helpers.LogLevel.Warning);
                                }
                            }
                        }

                        InventoryItem item = CreateInventoryItem(inventoryType, itemID);
                        item.AssetUUID = assetID;
                        item.AssetType = assetType;
                        item.CreationDate = creationDate;
                        item.CreatorID = creatorID;
                        item.Description = desc;
                        item.Flags = flags;
                        item.GroupID = groupID;
                        item.GroupOwned = groupOwned;
                        item.Name = name;
                        item.OwnerID = ownerID;
                        item.LastOwnerID = lastOwnerID;
                        item.ParentUUID = parentID;
                        item.Permissions = perms;
                        item.SalePrice = salePrice;
                        item.SaleType = saleType;

                        items.Add(item);

                        #endregion inv_item
                    }
                    else
                    {
                        Logger.Log("Unrecognized token " + key + " in: " + Environment.NewLine + taskData,
                            Helpers.LogLevel.Error);
                    }
                }
            }

            return items;
        }
コード例 #24
0
        Gdk.Pixbuf getprettyfoldericon(InventoryFolder item)
        {
            // Assume this is a InventoryFolder
            if (item.PreferredType == AssetType.Animation)
                return this.folder_animation;

            if (item.PreferredType == AssetType.Gesture)
                return this.folder_gesture;

            if (item.PreferredType == AssetType.Sound)
                return this.folder_sound;

            if (item.PreferredType == AssetType.Texture)
                return this.folder_texture;

            if (item.PreferredType == AssetType.SnapshotFolder)
                return this.folder_snapshot;

            if(item.PreferredType == AssetType.TrashFolder)
                return this.folder_trash;

            if (item.PreferredType == AssetType.Notecard)
                return this.folder_notecard;

            if (item.PreferredType == AssetType.LSLText || item.PreferredType == AssetType.LSLBytecode)
                return this.folder_script;

            if (item.PreferredType == AssetType.LostAndFoundFolder)
                return this.folder_lostandfound;

            if (item.PreferredType == AssetType.Landmark)
                return this.folder_landmark;

            if (item.PreferredType == AssetType.Bodypart)
                return this.folder_bodypart;

            if (item.PreferredType == AssetType.CallingCard)
                return this.folder_callingcard;

            if (item.PreferredType == AssetType.Clothing)
                return this.folder_clothing;

            return folder_closed;
        }
コード例 #25
0
ファイル: InventoryManager.cs プロジェクト: RavenB/gridsearch
        /// <summary>Process an incoming packet and raise the appropriate events</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The EventArgs object containing the packet data</param>
        protected void InventoryDescendentsHandler(object sender, PacketReceivedEventArgs e)
        {
            Packet packet = e.Packet;

            InventoryDescendentsPacket reply = (InventoryDescendentsPacket)packet;

            if (reply.AgentData.Descendents > 0)
            {
                // InventoryDescendantsReply sends a null folder if the parent doesnt contain any folders
                if (reply.FolderData[0].FolderID != UUID.Zero)
                {
                    // Iterate folders in this packet
                    for (int i = 0; i < reply.FolderData.Length; i++)
                    {
                        // If folder already exists then ignore, we assume the version cache
                        // logic is working and if the folder is stale then it should not be present.

                        if (!_Store.Contains(reply.FolderData[i].FolderID))
                        {
                            InventoryFolder folder = new InventoryFolder(reply.FolderData[i].FolderID);
                            folder.ParentUUID = reply.FolderData[i].ParentID;
                            folder.Name = Utils.BytesToString(reply.FolderData[i].Name);
                            folder.PreferredType = (AssetType)reply.FolderData[i].Type;
                            folder.OwnerID = reply.AgentData.OwnerID;

                            _Store[folder.UUID] = folder;
                        }
                    }
                }

                // InventoryDescendantsReply sends a null item if the parent doesnt contain any items.
                if (reply.ItemData[0].ItemID != UUID.Zero)
                {
                    // Iterate items in this packet
                    for (int i = 0; i < reply.ItemData.Length; i++)
                    {
                        if (reply.ItemData[i].ItemID != UUID.Zero)
                        {
                            InventoryItem item;
                            /* 
                             * Objects that have been attached in-world prior to being stored on the 
                             * asset server are stored with the InventoryType of 0 (Texture) 
                             * instead of 17 (Attachment) 
                             * 
                             * This corrects that behavior by forcing Object Asset types that have an 
                             * invalid InventoryType with the proper InventoryType of Attachment.
                             */
                            if ((AssetType)reply.ItemData[i].Type == AssetType.Object
                                && (InventoryType)reply.ItemData[i].InvType == InventoryType.Texture)
                            {
                                item = CreateInventoryItem(InventoryType.Attachment, reply.ItemData[i].ItemID);
                                item.InventoryType = InventoryType.Attachment;
                            }
                            else
                            {
                                item = CreateInventoryItem((InventoryType)reply.ItemData[i].InvType, reply.ItemData[i].ItemID);
                                item.InventoryType = (InventoryType)reply.ItemData[i].InvType;
                            }

                            item.ParentUUID = reply.ItemData[i].FolderID;
                            item.CreatorID = reply.ItemData[i].CreatorID;
                            item.AssetType = (AssetType)reply.ItemData[i].Type;
                            item.AssetUUID = reply.ItemData[i].AssetID;
                            item.CreationDate = Utils.UnixTimeToDateTime((uint)reply.ItemData[i].CreationDate);
                            item.Description = Utils.BytesToString(reply.ItemData[i].Description);
                            item.Flags = reply.ItemData[i].Flags;
                            item.Name = Utils.BytesToString(reply.ItemData[i].Name);
                            item.GroupID = reply.ItemData[i].GroupID;
                            item.GroupOwned = reply.ItemData[i].GroupOwned;
                            item.Permissions = new Permissions(
                                reply.ItemData[i].BaseMask,
                                reply.ItemData[i].EveryoneMask,
                                reply.ItemData[i].GroupMask,
                                reply.ItemData[i].NextOwnerMask,
                                reply.ItemData[i].OwnerMask);
                            item.SalePrice = reply.ItemData[i].SalePrice;
                            item.SaleType = (SaleType)reply.ItemData[i].SaleType;
                            item.OwnerID = reply.AgentData.OwnerID;

                            _Store[item.UUID] = item;
                        }
                    }
                }
            }

            InventoryFolder parentFolder = null;

            if (_Store.Contains(reply.AgentData.FolderID) &&
                _Store[reply.AgentData.FolderID] is InventoryFolder)
            {
                parentFolder = _Store[reply.AgentData.FolderID] as InventoryFolder;
            }
            else
            {
                Logger.Log("Don't have a reference to FolderID " + reply.AgentData.FolderID.ToString() +
                    " or it is not a folder", Helpers.LogLevel.Error, Client);
                return;
            }

            if (reply.AgentData.Version < parentFolder.Version)
            {
                Logger.Log("Got an outdated InventoryDescendents packet for folder " + parentFolder.Name +
                    ", this version = " + reply.AgentData.Version + ", latest version = " + parentFolder.Version,
                    Helpers.LogLevel.Warning, Client);
                return;
            }

            parentFolder.Version = reply.AgentData.Version;
            // FIXME: reply.AgentData.Descendants is not parentFolder.DescendentCount if we didn't 
            // request items and folders
            parentFolder.DescendentCount = reply.AgentData.Descendents;
            _Store.GetNodeFor(reply.AgentData.FolderID).NeedsUpdate = false;

            #region FindObjectsByPath Handling

            if (_Searches.Count > 0)
            {
                lock (_Searches)
                {
                StartSearch:

                    // Iterate over all of the outstanding searches
                    for (int i = 0; i < _Searches.Count; i++)
                    {
                        InventorySearch search = _Searches[i];
                        List<InventoryBase> folderContents = _Store.GetContents(search.Folder);

                        // Iterate over all of the inventory objects in the base search folder
                        for (int j = 0; j < folderContents.Count; j++)
                        {
                            // Check if this inventory object matches the current path node
                            if (folderContents[j].Name == search.Path[search.Level])
                            {
                                if (search.Level == search.Path.Length - 1)
                                {
                                    Logger.DebugLog("Finished path search of " + String.Join("/", search.Path), Client);

                                    // This is the last node in the path, fire the callback and clean up
                                    if (m_FindObjectByPathReply != null)
                                    {
                                        OnFindObjectByPathReply(new FindObjectByPathReplyEventArgs(String.Join("/", search.Path),
                                            folderContents[j].UUID));
                                    }

                                    // Remove this entry and restart the loop since we are changing the collection size
                                    _Searches.RemoveAt(i);
                                    goto StartSearch;
                                }
                                else
                                {
                                    // We found a match but it is not the end of the path, request the next level
                                    Logger.DebugLog(String.Format("Matched level {0}/{1} in a path search of {2}",
                                        search.Level, search.Path.Length - 1, String.Join("/", search.Path)), Client);

                                    search.Folder = folderContents[j].UUID;
                                    search.Level++;
                                    _Searches[i] = search;

                                    RequestFolderContents(search.Folder, search.Owner, true, true,
                                        InventorySortOrder.ByName);
                                }
                            }
                        }
                    }
                }
            }

            #endregion FindObjectsByPath Handling

            // Callback for inventory folder contents being updated
            if (m_FolderUpdated != null)
            {
                OnFolderUpdated(new FolderUpdatedEventArgs(parentFolder.UUID));
            }
        }
コード例 #26
0
        void menu_on_new_folder(object o, ButtonPressEventArgs args)
        {
            Gtk.TreeModel mod;
            Gtk.TreeIter iter;

            TreePath[] paths = treeview_inv.Selection.GetSelectedRows(out mod);
            if(paths.Length!=1)
                return;

            foreach (TreePath path in paths)
            {
                if (mod.GetIter(out iter, path))
                {
                    InventoryBase item = (InventoryBase)mod.GetValue(iter, 3);
                    if(item is InventoryFolder)
                    {
                        Gtk.TreeIter iterx;
                        if(assetmap.TryGetValue(item.UUID,out iterx))
                        {
                            UUID newfolder=MainClass.client.Inventory.CreateFolder(item.UUID,"New Folder");
                            Gdk.Pixbuf buf = getprettyicon(item);	//a folder so fine.
                            InventoryFolder nf = new InventoryFolder(newfolder);
                            nf.Name = "New Folder";
                            nf.ParentUUID = item.UUID;
                            nf.Version = 1;
                            Gtk.TreeIter newiter=inventory.AppendValues(iterx, buf, "New Folder", newfolder, (InventoryBase)nf);
                            assetmap.Add(newfolder,newiter);
                            treeview_inv.Selection.UnselectAll();

                            treeview_inv.Selection.SelectIter(filter.ConvertChildIterToIter(newiter));
                            treeview_inv.ScrollToCell(inventory.GetPath(newiter), null, true, (float)0.5, (float)0.5);
                            treeview_inv.SetCursor(inventory.GetPath(newiter), null, true);
                        }
             		            }
                }
            }
        }
コード例 #27
0
ファイル: InventoryManager.cs プロジェクト: RavenB/gridsearch
 /// <summary>
 /// 
 /// </summary>
 /// <param name="o"></param>
 /// <returns></returns>
 public bool Equals(InventoryFolder o)
 {
     return base.Equals(o as InventoryBase)
         && o.DescendentCount == DescendentCount
         && o.PreferredType == PreferredType
         && o.Version == Version;
 }
コード例 #28
0
        void PerformClipboardOperation(InventoryFolder dest)
        {
            if (instance.InventoryClipboard == null) return;

            if (dest == null) return;

            if (instance.InventoryClipboard.Operation == ClipboardOperation.Cut)
            {
                if (instance.InventoryClipboard.Item is InventoryItem)
                {
                    client.Inventory.MoveItem(instance.InventoryClipboard.Item.UUID, dest.UUID, instance.InventoryClipboard.Item.Name);
                }
                else if (instance.InventoryClipboard.Item is InventoryFolder)
                {
                    if (instance.InventoryClipboard.Item.UUID != dest.UUID)
                    {
                        client.Inventory.MoveFolder(instance.InventoryClipboard.Item.UUID, dest.UUID, instance.InventoryClipboard.Item.Name);
                    }
                }

                instance.InventoryClipboard = null;
            }
            else if (instance.InventoryClipboard.Operation == ClipboardOperation.Copy)
            {
                if (instance.InventoryClipboard.Item is InventoryItem)
                {
                    client.Inventory.RequestCopyItem(instance.InventoryClipboard.Item.UUID, dest.UUID, instance.InventoryClipboard.Item.Name, instance.InventoryClipboard.Item.OwnerID, (InventoryBase target) =>
                    {
                    }
                    );
                }
                else if (instance.InventoryClipboard.Item is InventoryFolder)
                {
                    ThreadPool.QueueUserWorkItem((object state) =>
                        {
                            UUID newFolderID = client.Inventory.CreateFolder(dest.UUID, instance.InventoryClipboard.Item.Name, AssetType.Unknown);
                            Thread.Sleep(500);

                            // FIXME: for some reason copying a bunch of items in one operation does not work

                            //List<UUID> items = new List<UUID>();
                            //List<UUID> folders = new List<UUID>();
                            //List<string> names = new List<string>();
                            //UUID oldOwner = UUID.Zero;

                            foreach (InventoryBase oldItem in Inventory.GetContents((InventoryFolder)instance.InventoryClipboard.Item))
                            {
                                //folders.Add(newFolderID);
                                //names.Add(oldItem.Name);
                                //items.Add(oldItem.UUID);
                                //oldOwner = oldItem.OwnerID;
                                client.Inventory.RequestCopyItem(oldItem.UUID, newFolderID, oldItem.Name, oldItem.OwnerID, (InventoryBase target) => { });
                            }

                            //if (folders.Count > 0)
                            //{
                            //    client.Inventory.RequestCopyItems(items, folders, names, oldOwner, (InventoryBase target) => { });
                            //}
                        }
                    );
                }
            }
        }
コード例 #29
0
ファイル: Login.cs プロジェクト: RavenB/gridsearch
        public InventoryFolder[] ParseInventorySkeleton(string key, Hashtable reply)
        {
            UUID ownerID;
            if (key.Equals("inventory-skel-lib"))
                ownerID = LibraryOwner;
            else
                ownerID = AgentID;

            List<InventoryFolder> folders = new List<InventoryFolder>();

            if (reply.ContainsKey(key) && reply[key] is ArrayList)
            {
                ArrayList array = (ArrayList)reply[key];
                for (int i = 0; i < array.Count; i++)
                {
                    if (array[i] is Hashtable)
                    {
                        Hashtable map = (Hashtable)array[i];
                        InventoryFolder folder = new InventoryFolder(ParseUUID("folder_id", map));
                        folder.Name = ParseString("name", map);
                        folder.ParentUUID = ParseUUID("parent_id", map);
                        folder.PreferredType = (AssetType)ParseUInt("type_default", map);
                        folder.Version = (int)ParseUInt("version", map);
                        folder.OwnerID = ownerID;

                        folders.Add(folder);
                    }
                }
            }

            return folders.ToArray();
        }
コード例 #30
0
        void PerformLinkOperation(InventoryFolder dest)
        {
            if (instance.InventoryClipboard == null) return;

            if (dest == null) return;

            client.Inventory.CreateLink(dest.UUID, instance.InventoryClipboard.Item, (bool success, InventoryItem item) => { });
        }