/// <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; } }
void PrintFolder(InventoryFolder f, StringBuilder result, int indent) { foreach (InventoryBase i in Manager.FolderContents(f.UUID, Client.Self.AgentID, true, true, InventorySortOrder.ByName, 3000)) { 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); } } }
public bool Equals(InventoryFolder o) { return base.Equals(o as InventoryBase) && o.DescendentCount == DescendentCount && o.PreferredType == PreferredType && o.Version == Version; }
private void BulkUpdateInventoryHandler(Packet packet, Simulator simulator) { BulkUpdateInventoryPacket update = packet as BulkUpdateInventoryPacket; if (update.FolderData.Length > 0 && update.FolderData[0].FolderID != LLUUID.Zero) { foreach (BulkUpdateInventoryPacket.FolderDataBlock dataBlock in update.FolderData) { if (!_Store.Contains(dataBlock.FolderID)) _Client.Log("Received BulkUpdate for unknown folder: " + dataBlock.FolderID, Helpers.LogLevel.Warning); InventoryFolder folder = new InventoryFolder(dataBlock.FolderID); folder.Name = Helpers.FieldToUTF8String(dataBlock.Name); folder.OwnerID = update.AgentData.AgentID; folder.ParentUUID = dataBlock.ParentID; _Store[folder.UUID] = folder; } } if (update.ItemData.Length > 0 && update.ItemData[0].ItemID != LLUUID.Zero) { for (int i = 0; i < update.ItemData.Length; i++) { BulkUpdateInventoryPacket.ItemDataBlock dataBlock = update.ItemData[i]; if (!_Store.Contains(dataBlock.ItemID)) _Client.Log("Received BulkUpdate for unknown item: " + dataBlock.ItemID, Helpers.LogLevel.Warning); InventoryItem item = SafeCreateInventoryItem((InventoryType)dataBlock.InvType, dataBlock.ItemID); item.AssetType = (AssetType)dataBlock.Type; if (dataBlock.AssetID != LLUUID.Zero) item.AssetUUID = dataBlock.AssetID; item.CreationDate = Helpers.UnixTimeToDateTime(dataBlock.CreationDate); item.CreatorID = dataBlock.CreatorID; item.Description = Helpers.FieldToUTF8String(dataBlock.Description); item.Flags = dataBlock.Flags; item.GroupID = dataBlock.GroupID; item.GroupOwned = dataBlock.GroupOwned; item.Name = Helpers.FieldToUTF8String(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 e) { _Client.Log(e.ToString(), Helpers.LogLevel.Error); } } // Look for an "item copied" callback ItemCopiedCallback copyCallback; if (_ItemCopiedCallbacks.TryGetValue(dataBlock.CallbackID, out copyCallback)) { _ItemCopiedCallbacks.Remove(dataBlock.CallbackID); try { copyCallback(item); } catch (Exception e) { _Client.Log(e.ToString(), Helpers.LogLevel.Error); } } } } }
private void InventoryDescendentsHandler(Packet packet, Simulator simulator) { 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 != LLUUID.Zero) { // Iterate folders in this packet for (int i = 0; i < reply.FolderData.Length; i++) { InventoryFolder folder = new InventoryFolder(reply.FolderData[i].FolderID); folder.ParentUUID = reply.FolderData[i].ParentID; folder.Name = Helpers.FieldToUTF8String(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 != LLUUID.Zero) { // Iterate items in this packet for (int i = 0; i < reply.ItemData.Length; i++) { if (reply.ItemData[i].ItemID != LLUUID.Zero) { InventoryItem item = CreateInventoryItem((InventoryType)reply.ItemData[i].InvType,reply.ItemData[i].ItemID); 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 = Helpers.UnixTimeToDateTime((uint)reply.ItemData[i].CreationDate); item.Description = Helpers.FieldToUTF8String(reply.ItemData[i].Description); item.Flags = reply.ItemData[i].Flags; item.Name = Helpers.FieldToUTF8String(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 { _Client.Log("Don't have a reference to FolderID " + reply.AgentData.FolderID.ToString() + " or it is not a folder", Helpers.LogLevel.Error); return; } if (reply.AgentData.Version < parentFolder.Version) { _Client.Log("Got an outdated InventoryDescendents packet for folder " + parentFolder.Name + ", this version = " + reply.AgentData.Version + ", latest version = " + parentFolder.Version, Helpers.LogLevel.Warning); 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; #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) { _Client.DebugLog("Finished patch search of " + String.Join("/", search.Path)); // This is the last node in the path, fire the callback and clean up if (OnFindObjectByPath != null) { try { OnFindObjectByPath(String.Join("/", search.Path), folderContents[j].UUID); } catch (Exception e) { _Client.Log(e.ToString(), Helpers.LogLevel.Error); } } // 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 _Client.DebugLog(String.Format("Matched level {0}/{1} in a path search of {2}", search.Level, search.Path.Length - 1, String.Join("/", search.Path))); 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 (OnFolderUpdated != null) { try { OnFolderUpdated(parentFolder.UUID); } catch (Exception e) { _Client.Log(e.ToString(), Helpers.LogLevel.Error); } } }
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 LLUUID itemID = LLUUID.Zero; LLUUID parentID = LLUUID.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") { LLUUID.TryParse(value, out itemID); } else if (key == "parent_id") { LLUUID.TryParse(value, out parentID); } else if (key == "type") { assetType = 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 LLUUID itemID = LLUUID.Zero; LLUUID assetID = LLUUID.Zero; LLUUID parentID = LLUUID.Zero; LLUUID creatorID = LLUUID.Zero; LLUUID ownerID = LLUUID.Zero; LLUUID lastOwnerID = LLUUID.Zero; LLUUID groupID = LLUUID.Zero; bool groupOwned = false; string name = String.Empty; string desc = String.Empty; AssetType assetType = AssetType.Unknown; InventoryType inventoryType = InventoryType.Unknown; DateTime creationDate = Helpers.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") { LLUUID.TryParse(value, out itemID); } else if (key == "parent_id") { LLUUID.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 (Helpers.TryParseHex(value, out val)) perms.BaseMask = (PermissionMask)val; } else if (key == "base_mask") { uint val; if (Helpers.TryParseHex(value, out val)) perms.BaseMask = (PermissionMask)val; } else if (key == "owner_mask") { uint val; if (Helpers.TryParseHex(value, out val)) perms.OwnerMask = (PermissionMask)val; } else if (key == "group_mask") { uint val; if (Helpers.TryParseHex(value, out val)) perms.GroupMask = (PermissionMask)val; } else if (key == "everyone_mask") { uint val; if (Helpers.TryParseHex(value, out val)) perms.EveryoneMask = (PermissionMask)val; } else if (key == "next_owner_mask") { uint val; if (Helpers.TryParseHex(value, out val)) perms.NextOwnerMask = (PermissionMask)val; } else if (key == "creator_id") { Helpers.TryParse(value, out creatorID); } else if (key == "owner_id") { Helpers.TryParse(value, out ownerID); } else if (key == "last_owner_id") { Helpers.TryParse(value, out lastOwnerID); } else if (key == "group_id") { Helpers.TryParse(value, out groupID); } else if (key == "group_owned") { uint val; if (Helpers.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 = StringToSaleType(value); } else if (key == "sale_price") { Helpers.TryParse(value, out salePrice); } } } #endregion sale_info } else if (key == "shadow_id") { //FIXME: } else if (key == "asset_id") { LLUUID.TryParse(value, out assetID); } else if (key == "type") { assetType = StringToAssetType(value); } else if (key == "inv_type") { inventoryType = StringToInventoryType(value); } else if (key == "flags") { Helpers.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 (Helpers.TryParse(value, out timestamp)) creationDate = Helpers.UnixTimeToDateTime(timestamp); else SecondLife.LogStatic("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.ParentUUID = parentID; item.Permissions = perms; item.SalePrice = salePrice; item.SaleType = saleType; items.Add(item); #endregion inv_item } else { SecondLife.LogStatic("Unrecognized token " + key + " in: " + Helpers.NewLine + taskData, Helpers.LogLevel.Error); } } } return items; }
public LLUUID CreateFolder(LLUUID parentID, AssetType preferredType, string name) { LLUUID id = LLUUID.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) { _Client.Log(ie.Message, Helpers.LogLevel.Warning); } // 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 = Helpers.StringToField(name); _Client.Network.SendPacket(create); return id; }
/// <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; //set chat on DoCommand("chatSet", Self.AgentID); } }
public List<InventoryBase> GetContents(InventoryFolder folder) { return GetContents(folder.UUID); }
public static InventoryFolder[] ParseInventoryFolders(string key, LLUUID owner, LLSDMap reply) { List<InventoryFolder> folders = new List<InventoryFolder>(); LLSD skeleton; if (reply.TryGetValue(key, out skeleton) && skeleton.Type == LLSDType.Array) { LLSDArray array = (LLSDArray)skeleton; for (int i = 0; i < array.Count; i++) { if (array[i].Type == LLSDType.Map) { LLSDMap map = (LLSDMap)array[i]; InventoryFolder folder = new InventoryFolder(map["folder_id"].AsUUID()); folder.PreferredType = (AssetType)map["type_default"].AsInteger(); folder.Version = map["version"].AsInteger(); folder.OwnerID = owner; folder.ParentUUID = map["parent_id"].AsUUID(); folder.Name = map["name"].AsString(); folders.Add(folder); } } return folders.ToArray(); } return new InventoryFolder[0]; }
public InventoryFolder[] ParseSkeleton(NetworkManager.InventorySkeletonEntry[] skeleton, LLUUID owner) { Dictionary<LLUUID, InventoryFolder> Folders = new Dictionary<LLUUID, InventoryFolder>(); Dictionary<LLUUID, List<InventoryFolder>> FoldersChildren = new Dictionary<LLUUID, List<InventoryFolder>>(skeleton.Length); foreach (NetworkManager.InventorySkeletonEntry entry in skeleton) { InventoryFolder folder = new InventoryFolder(entry.folder_id); if (entry.type_default != -1) folder.PreferredType = (AssetType)entry.type_default; folder.Version = entry.version; folder.OwnerID = owner; folder.ParentUUID = LLUUID.Parse(entry.parent_id); folder.Name = entry.name; Folders.Add(entry.folder_id, folder); if (entry.parent_id != LLUUID.Zero) { List<InventoryFolder> parentChildren; if (!FoldersChildren.TryGetValue(entry.parent_id, out parentChildren)) { parentChildren = new List<InventoryFolder>(); FoldersChildren.Add(entry.parent_id, parentChildren); } parentChildren.Add(folder); } } foreach (KeyValuePair<LLUUID, List<InventoryFolder>> pair in FoldersChildren) { if (Folders.ContainsKey(pair.Key)) { InventoryFolder parentFolder = Folders[pair.Key]; parentFolder.DescendentCount = pair.Value.Count; // Should we set this here? it's just the folders, not the items! } } // Should we do this or just return an IEnumerable? InventoryFolder[] ret = new InventoryFolder[Folders.Count]; int index = 0; foreach (InventoryFolder folder in Folders.Values) { ret[index] = folder; ++index; } return ret; }
private TreeNode AddTreeFolder(InventoryFolder folder, TreeNode node) { if (treeLookup.ContainsKey(folder.UUID)) return treeLookup[folder.UUID]; TreeNode folderNode = node.Nodes.Add(folder.UUID.ToString(), folder.Name); folderNode.Tag = folder; folderNode.ImageKey = "ClosedFolder"; treeLookup.Add(folder.UUID, folderNode); return folderNode; }
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 = LLUUID.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 = LLUUID.Zero; _Store.LibraryFolder = libraryRootFolder; for(int i = 0; i < replyData.LibrarySkeleton.Length; i++) _Store.UpdateNodeFor(replyData.LibrarySkeleton[i]); } }
private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { if (loginSuccess) { _Client.DebugLog("Setting InventoryRoot to " + replyData.InventoryRoot.ToString()); InventoryFolder rootFolder = new InventoryFolder(replyData.InventoryRoot); rootFolder.Name = String.Empty; rootFolder.ParentUUID = LLUUID.Zero; _Store.RootFolder = rootFolder; for (int i = 0; i < replyData.InventorySkeleton.Length; i++) _Store.UpdateNodeFor(replyData.InventorySkeleton[i]); } }
/// <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 != LLUUID.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. Client.DebugLog("Attempting to update inventory child of " + item.ParentUUID.ToString() + " when we have no local reference to that folder"); if (Client.Settings.FETCH_MISSING_INVENTORY) { // Fetch the parent List<LLUUID> fetchreq = new List<LLUUID>(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; if (item != itemNode.Data) FireOnInventoryObjectUpdated(itemNode.Data, item); itemNode.Data = item; } else // We're adding. { itemNode = new InventoryNode(item, itemParent); Items.Add(item.UUID, itemNode); } } }
public void Move(InventoryBase item, InventoryFolder newParent) { if (item is InventoryFolder) MoveFolder(item.UUID, newParent.UUID); else MoveItem(item.UUID, newParent.UUID); }
private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, NetworkManager.LoginResponseData replyData) { if (loginSuccess) { _Client.DebugLog("Setting InventoryRoot to " + replyData.InventoryRoot.ToStringHyphenated()); InventoryFolder rootFolder = new InventoryFolder(replyData.InventoryRoot); rootFolder.Name = String.Empty; rootFolder.ParentUUID = LLUUID.Zero; _Store.RootFolder = rootFolder; foreach (InventoryFolder folder in replyData.InventorySkeleton) _Store.UpdateNodeFor(folder); } }