private void FetchInventoryReplyHandler(Packet packet, Simulator simulator) { lock (_FetchRequests) { FetchInventoryReplyPacket reply = packet as FetchInventoryReplyPacket; foreach (FetchInventoryReplyPacket.InventoryDataBlock dataBlock in reply.InventoryData) { if (dataBlock.InvType == (sbyte)InventoryType.Folder) { Logger.Log("Received FetchInventoryReply for an inventory folder, this should not happen!", Helpers.LogLevel.Error, _Client); continue; } ItemData item = new ItemData(dataBlock.ItemID); item.InventoryType = (InventoryType)dataBlock.InvType; item.AssetType = (AssetType)dataBlock.Type; 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; #region FetchItems Handling // Iterate backwards through fetch requests, ensures safe removal: for (int i = _FetchRequests.Count - 1; i >= 0; --i) { FetchRequest request = _FetchRequests[i]; if (request.RequestedItems.ContainsKey(item.UUID)) { request.StoreFetchedItem(item); if (request.ItemsFetched == request.RequestedItems.Count) { // We're done, create the list that the callback needs: List<ItemData> items = new List<ItemData>(request.ItemsFetched); foreach (KeyValuePair<UUID, ItemData?> pair in request.RequestedItems) items.Add(pair.Value.Value); // Fire the callback: request.Callback(items); _FetchRequests.RemoveAt(i); } _FetchRequests[i] = request; } } #endregion FetchItems Handling } } }
/// <summary> /// UpdateCreateInventoryItem packets are received when a new inventory item /// is created. This may occur when an object that's rezzed in world is /// taken into inventory, when an item is created using the CreateInventoryItem /// packet, or when an object is purchased /// </summary> private void UpdateCreateInventoryItemHandler(Packet packet, Simulator simulator) { UpdateCreateInventoryItemPacket reply = packet as UpdateCreateInventoryItemPacket; foreach (UpdateCreateInventoryItemPacket.InventoryDataBlock dataBlock in reply.InventoryData) { if (dataBlock.InvType == (sbyte)InventoryType.Folder) { Logger.Log("Received InventoryFolder in an UpdateCreateInventoryItem packet, this should not happen!", Helpers.LogLevel.Error, _Client); continue; } ItemData item = new ItemData(dataBlock.ItemID, (InventoryType)dataBlock.InvType); item.AssetType = (AssetType)dataBlock.Type; 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; // Look for an "item created" callback // Let the requester know that its item was created. ItemCreatedCallback createdCallback; if (_ItemCreatedCallbacks.TryGetValue(dataBlock.CallbackID, out createdCallback)) { _ItemCreatedCallbacks.Remove(dataBlock.CallbackID); try { createdCallback(true, item); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, _Client, e); } } // Let everyone know that the item was created if (OnItemCreated != null) { try { OnItemCreated(true, item); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, _Client, e); } } //This is triggered when an item is received from a task if (OnTaskItemReceived != null) { try { OnTaskItemReceived(dataBlock.ItemID, dataBlock.FolderID, item.CreatorID, item.AssetUUID, item.InventoryType); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, _Client, e); } } } }
private void BulkUpdateInventoryHandler(Packet packet, Simulator simulator) { BulkUpdateInventoryPacket update = packet as BulkUpdateInventoryPacket; if (update.FolderData.Length > 0 && update.FolderData[0].FolderID != UUID.Zero) { foreach (BulkUpdateInventoryPacket.FolderDataBlock dataBlock in update.FolderData) { if (OnFolderUpdate != null) { FolderData folderParams = new FolderData(); folderParams.Name = Utils.BytesToString(dataBlock.Name); folderParams.OwnerID = update.AgentData.AgentID; folderParams.ParentUUID = dataBlock.ParentID; try { OnFolderUpdate(folderParams); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, _Client, e); } } } } 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]; ItemData item = new ItemData(dataBlock.ItemID, (InventoryType)dataBlock.InvType); 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; // 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) { Logger.Log(e.Message, Helpers.LogLevel.Error, _Client, e); } } // 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) { Logger.Log(e.Message, Helpers.LogLevel.Error, _Client, e); } } if (OnItemUpdate != null) { try { OnItemUpdate(item); } catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, _Client, e); } } } } }
/// <summary> /// Parse the results of a RequestTaskInventory() response /// </summary> /// <param name="manager"></param> /// <param name="taskData">A string which contains the data from the task reply</param> /// <param name="items"></param> /// <param name="folders"></param> /// <returns>A List containing the items contained within the tasks inventory</returns> public static void ParseTaskInventory(InventoryManager manager, string taskData, out List<ItemData> items, out List<FolderData> folders) { items = new List<ItemData>(); folders = new List<FolderData>(); 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 = StringToAssetType(value); } else if (key == "name") { name = value.Substring(0, value.IndexOf('|')); } } } if (assetType == AssetType.Folder) { FolderData folderData = new FolderData(itemID); folderData.Name = name; folderData.ParentUUID = parentID; folders.Add(folderData); } else { ItemData itemParams = new ItemData(itemID); itemParams.Name = name; itemParams.ParentUUID = parentID; itemParams.AssetType = assetType; items.Add(itemParams); } #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 = StringToSaleType(value); } else if (key == "sale_price") { Int32.TryParse(value, out salePrice); } } } #endregion sale_info } else if (key == "shadow_id") { //FIXME: } else if (key == "asset_id") { UUID.TryParse(value, out assetID); } else if (key == "type") { assetType = StringToAssetType(value); } else if (key == "inv_type") { inventoryType = 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); } } } ItemData item = new ItemData(itemID, inventoryType); 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 { Logger.Log("Unrecognized token " + key + " in: " + Helpers.NewLine + taskData, Helpers.LogLevel.Error); } } } }
private void InventoryDescendentsHandler(Packet packet, Simulator simulator) { InventoryDescendentsPacket reply = (InventoryDescendentsPacket)packet; ItemData[] items = null; FolderData[] folders = null; if (reply.AgentData.Descendents > 0) { // InventoryDescendantsReply sends a null folder if the parent doesnt contain any folders if (reply.FolderData[0].FolderID != UUID.Zero) { folders = new FolderData[reply.FolderData.Length]; // Iterate folders in this packet for (int i = 0; i < reply.FolderData.Length; i++) { UUID folderID = reply.FolderData[i].FolderID; FolderData folder = new FolderData(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; folders[i] = folder; } } // InventoryDescendantsReply sends a null item if the parent doesnt contain any items. if (reply.ItemData[0].ItemID != UUID.Zero) { items = new ItemData[reply.ItemData.Length]; // Iterate items in this packet for (int i = 0; i < reply.ItemData.Length; i++) { if (reply.ItemData[i].ItemID != UUID.Zero) { UUID itemID = reply.ItemData[i].ItemID; ItemData item = new ItemData(itemID); /* * 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.InventoryType = InventoryType.Attachment; } else { 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; items[i] = item; } } } } #region FolderContents Handling if (_DescendentsRequests.Count > 0) { lock (_DescendentsRequests) { // Iterate backwards, ensures safe removal: for (int i = _DescendentsRequests.Count - 1; i >= 0; --i) { DescendentsRequest request = _DescendentsRequests[i]; if (request.Folder == reply.AgentData.FolderID) { // Store the descendent count if we haven't received a responce yet: if (!request.ReceivedResponse) { request.ReceivedResponse = true; request.Descendents = reply.AgentData.Descendents; } // Store the items and folders: if (folders != null) request.FolderContents.AddRange(folders); if (items != null) request.ItemContents.AddRange(items); _DescendentsRequests[i] = request; int contentsReceived = request.FolderContents.Count + request.ItemContents.Count; // Fire the partial callback, if we have one: if (request.PartialCallback != null) { request.PartialCallback(reply.AgentData.FolderID, items, folders, request.Descendents - contentsReceived); } // Check if we're done: if (contentsReceived >= request.Descendents) { // Fire the callback: if (request.Callback != null) { request.Callback(reply.AgentData.FolderID, request.ItemContents, request.FolderContents); } _DescendentsRequests.RemoveAt(i); } } } } } #endregion FolderContents Handling }
/// <summary> /// <seealso cref="ItemData.Parse"/> /// </summary> /// <param name="reader">Text source.</param> /// <param name="item">Parsed ItemData.</param> /// <returns><code>true</code> if successful <code>false</code> otherwise.</returns> public static bool TryParse(TextReader reader, out ItemData item) { try { item = Parse(reader); } catch (Exception e) { item = new ItemData(); Logger.Log(e.Message, Helpers.LogLevel.Error, e); return false; } return true; }
/// <summary> /// Detach an item from avatar using an <seealso cref="OpenMetaverse.InventoryItem"/> object /// </summary> /// <param name="item">An <seealso cref="OpenMetaverse.InventoryItem"/> object</param> public void Detach(ItemData item) { Detach(item.UUID); }
/// <summary> /// Rez an object from inventory /// </summary> /// <param name="simulator">Simulator to place object in</param> /// <param name="rotation">Rotation of the object when rezzed</param> /// <param name="position">Vector of where to place object</param> /// <param name="item">InventoryObject object containing item details</param> /// <param name="groupOwner">UUID of group to own the object</param> public UUID RequestRezFromInventory(Simulator simulator, Quaternion rotation, Vector3 position, ItemData item, UUID groupOwner) { return RequestRezFromInventory(simulator, rotation, position, item, groupOwner, UUID.Random(), false); }
/// <summary> /// Rez an object from inventory /// </summary> /// <param name="simulator">Simulator to place object in</param> /// <param name="rotation">Rotation of the object when rezzed</param> /// <param name="position">Vector of where to place object</param> /// <param name="item">InventoryObject object containing item details</param> /// <param name="groupOwner">UUID of group to own the object</param> /// <param name="queryID">User defined queryID to correlate replies</param> /// <param name="requestObjectDetails">if set to true the simulator /// will automatically send object detail packet(s) back to the client</param> public UUID RequestRezFromInventory(Simulator simulator, Quaternion rotation, Vector3 position, ItemData item, UUID groupOwner, UUID queryID, bool requestObjectDetails) { RezObjectPacket add = new RezObjectPacket(); add.AgentData.AgentID = _Agents.AgentID; add.AgentData.SessionID = _Agents.SessionID; add.AgentData.GroupID = groupOwner; add.RezData.FromTaskID = UUID.Zero; add.RezData.BypassRaycast = 1; add.RezData.RayStart = position; add.RezData.RayEnd = position; add.RezData.RayTargetID = UUID.Zero; add.RezData.RayEndIsIntersection = false; add.RezData.RezSelected = requestObjectDetails; add.RezData.RemoveItem = false; add.RezData.ItemFlags = (uint)item.Flags; add.RezData.GroupMask = (uint)item.Permissions.GroupMask; add.RezData.EveryoneMask = (uint)item.Permissions.EveryoneMask; add.RezData.NextOwnerMask = (uint)item.Permissions.NextOwnerMask; add.InventoryData.ItemID = item.UUID; add.InventoryData.FolderID = item.ParentUUID; add.InventoryData.CreatorID = item.CreatorID; add.InventoryData.OwnerID = item.OwnerID; add.InventoryData.GroupID = item.GroupID; add.InventoryData.BaseMask = (uint)item.Permissions.BaseMask; add.InventoryData.OwnerMask = (uint)item.Permissions.OwnerMask; add.InventoryData.GroupMask = (uint)item.Permissions.GroupMask; add.InventoryData.EveryoneMask = (uint)item.Permissions.EveryoneMask; add.InventoryData.NextOwnerMask = (uint)item.Permissions.NextOwnerMask; add.InventoryData.GroupOwned = item.GroupOwned; add.InventoryData.TransactionID = queryID; add.InventoryData.Type = (sbyte)item.InventoryType; add.InventoryData.InvType = (sbyte)item.InventoryType; add.InventoryData.Flags = (uint)item.Flags; add.InventoryData.SaleType = (byte)item.SaleType; add.InventoryData.SalePrice = item.SalePrice; add.InventoryData.Name = Utils.StringToBytes(item.Name); add.InventoryData.Description = Utils.StringToBytes(item.Description); add.InventoryData.CreationDate = (int)Utils.DateTimeToUnixTime(item.CreationDate); _Network.SendPacket(add, simulator); return queryID; }
/// <summary> /// /// </summary> /// <param name="parameters"></param> public void RequestUpdateItem(ItemData parameters) { RequestUpdateItems(new ItemData[] { parameters }, UUID.Random()); }
/// <summary> /// Rez an object from inventory /// </summary> /// <param name="simulator">Simulator to place object in</param> /// <param name="rotation">Rotation of the object when rezzed</param> /// <param name="position">Vector of where to place object</param> /// <param name="item">InventoryObject object containing item details</param> public UUID RequestRezFromInventory(Simulator simulator, Quaternion rotation, Vector3 position, ItemData item) { return RequestRezFromInventory(simulator, rotation, position, item, _Agents.ActiveGroup, UUID.Random(), false); }
public bool CopyItem(UUID itemUUID, UUID newParent, string newName, TimeSpan timeout, out ItemData copy) { ManualResetEvent mre = new ManualResetEvent(false); ItemData _copy = new ItemData(); ItemCopiedCallback callback = delegate(ItemData item) { _copy = item; mre.Set(); }; RequestCopyItem(itemUUID, newParent, newName, callback); if (mre.WaitOne(timeout, false)) { copy = _copy; return true; } else { copy = _copy; return false; } }
/// <summary> /// Fetch a single inventory item. /// </summary> /// <param name="itemID">The item's <seealso cref="UUID"/></param> /// <param name="ownerID">The item owner's <seealso cref="UUID"/></param> /// <param name="timeout">The amount of time to wait for results.</param> /// <param name="item">The item retrieved.</param> /// <returns>true if successful, false if not.</returns> public bool FetchItem(UUID itemID, UUID ownerID, TimeSpan timeout, out ItemData item) { List<ItemData> items = FetchItems(new UUID[] { itemID }, ownerID, timeout); if (items == null || items.Count == 0) { item = new ItemData(); return false; } else { item = items[0]; return true; } }
private void AgentWearablesUpdateHandler(Packet packet, Simulator simulator) { // Lock to prevent a race condition with multiple AgentWearables packets lock (WearablesRequestEvent) { AgentWearablesUpdatePacket update = (AgentWearablesUpdatePacket)packet; // Reset the Wearables collection lock (Wearables.Dictionary) Wearables.Dictionary.Clear(); for (int i = 0; i < update.WearableData.Length; i++) { if (update.WearableData[i].AssetID != UUID.Zero) { WearableType type = (WearableType)update.WearableData[i].WearableType; WearableData data = new WearableData(); ItemData itemData = new ItemData(update.WearableData[i].ItemID, InventoryType.Wearable); itemData.AssetType = WearableTypeToAssetType(type); itemData.AssetUUID = update.WearableData[i].AssetID; data.Item = itemData; data.WearableType = type; // Add this wearable to our collection lock (Wearables.Dictionary) Wearables.Dictionary[type] = data; } } } WearablesRequestEvent.Set(); }
/// <summary> /// Reads an ItemData from a TextReader source. The format of the text /// should be the same as the one used by Second Life Notecards. The TextReader should /// be placed ideally on the line containing "inv_item" but parsing will succeed as long /// as it is before the opening bracket immediately following the inv_item line. /// The TextReader will be placed on the line following the inv_item's closing bracket. /// </summary> /// <param name="reader">text source</param> /// <returns>Parsed item.</returns> public static ItemData Parse(TextReader reader) { ItemData item = new ItemData(); #region Parsing TextData invItem = TextHierarchyParser.Parse(reader); Console.WriteLine(invItem); //if (invItem.Name == "inv_item") // YAY item.UUID = new UUID(invItem.Nested["item_id"].Value); item.ParentUUID = new UUID(invItem.Nested["parent_id"].Value); item.AssetUUID = new UUID(invItem.Nested["asset_id"].Value); item.AssetType = AssetTypeParser.Parse(invItem.Nested["type"].Value); item.InventoryType = InventoryTypeParser.Parse(invItem.Nested["inv_type"].Value); item.Flags = uint.Parse(invItem.Nested["flags"].Value, NumberStyles.HexNumber); string rawName = invItem.Nested["name"].Value; item.Name = rawName.Substring(0, rawName.LastIndexOf('|')); string rawDesc = invItem.Nested["desc"].Value; item.Description = rawDesc.Substring(0, rawDesc.LastIndexOf('|')); item.CreationDate = Utils.UnixTimeToDateTime(uint.Parse(invItem.Nested["creation_date"].Value)); // Sale info: TextData saleInfo = invItem.Nested["sale_info"]; item.SalePrice = int.Parse(saleInfo.Nested["sale_price"].Value); item.SaleType = SaleTypeParser.Parse(saleInfo.Nested["sale_type"].Value); TextData permissions = invItem.Nested["permissions"]; item.Permissions = new Permissions(); item.Permissions.BaseMask = (PermissionMask)uint.Parse(permissions.Nested["base_mask"].Value, NumberStyles.HexNumber); item.Permissions.EveryoneMask = (PermissionMask)uint.Parse(permissions.Nested["everyone_mask"].Value, NumberStyles.HexNumber); item.Permissions.GroupMask = (PermissionMask)uint.Parse(permissions.Nested["group_mask"].Value, NumberStyles.HexNumber); item.Permissions.OwnerMask = (PermissionMask)uint.Parse(permissions.Nested["owner_mask"].Value, NumberStyles.HexNumber); item.Permissions.NextOwnerMask = (PermissionMask)uint.Parse(permissions.Nested["next_owner_mask"].Value, NumberStyles.HexNumber); item.CreatorID = new UUID(permissions.Nested["creator_id"].Value); item.OwnerID = new UUID(permissions.Nested["owner_id"].Value); item.GroupID = new UUID(permissions.Nested["group_id"].Value); // permissions.Nested["last_owner_id"] // FIXME? #endregion return item; }
/// <summary> /// /// </summary> /// <param name="objectLocalID"></param> /// <param name="item"></param> /// <returns></returns> public UUID UpdateTaskInventory(uint objectLocalID, ItemData item) { UUID transactionID = UUID.Random(); UpdateTaskInventoryPacket update = new UpdateTaskInventoryPacket(); update.AgentData.AgentID = _Agents.AgentID; update.AgentData.SessionID = _Agents.SessionID; update.UpdateData.Key = 0; update.UpdateData.LocalID = objectLocalID; update.InventoryData.ItemID = item.UUID; update.InventoryData.FolderID = item.ParentUUID; update.InventoryData.CreatorID = item.CreatorID; update.InventoryData.OwnerID = item.OwnerID; update.InventoryData.GroupID = item.GroupID; update.InventoryData.BaseMask = (uint)item.Permissions.BaseMask; update.InventoryData.OwnerMask = (uint)item.Permissions.OwnerMask; update.InventoryData.GroupMask = (uint)item.Permissions.GroupMask; update.InventoryData.EveryoneMask = (uint)item.Permissions.EveryoneMask; update.InventoryData.NextOwnerMask = (uint)item.Permissions.NextOwnerMask; update.InventoryData.GroupOwned = item.GroupOwned; update.InventoryData.TransactionID = transactionID; update.InventoryData.Type = (sbyte)item.AssetType; update.InventoryData.InvType = (sbyte)item.InventoryType; update.InventoryData.Flags = (uint)item.Flags; update.InventoryData.SaleType = (byte)item.SaleType; update.InventoryData.SalePrice = item.SalePrice; update.InventoryData.Name = Utils.StringToBytes(item.Name); update.InventoryData.Description = Utils.StringToBytes(item.Description); update.InventoryData.CreationDate = (int)Utils.DateTimeToUnixTime(item.CreationDate); update.InventoryData.CRC = ItemCRC(item); _Network.SendPacket(update); return transactionID; }
/// <summary> /// <seealso cref="ItemData.Parse"/> /// </summary> /// <param name="str">String to parse from.</param> /// <param name="item">Parsed ItemData.</param> /// <returns><code>true</code> if successful, <code>false</code> otherwise.</returns> public static bool TryParse(string str, out ItemData item) { return TryParse(new StringReader(str), out item); }
/// <summary> /// Create a CRC from an InventoryItem /// </summary> /// <param name="iitem">The source InventoryItem</param> /// <returns>A uint representing the source InventoryItem as a CRC</returns> public static uint ItemCRC(ItemData iitem) { uint CRC = 0; // IDs CRC += iitem.AssetUUID.CRC(); // AssetID CRC += iitem.ParentUUID.CRC(); // FolderID CRC += iitem.UUID.CRC(); // ItemID // Permission stuff CRC += iitem.CreatorID.CRC(); // CreatorID CRC += iitem.OwnerID.CRC(); // OwnerID CRC += iitem.GroupID.CRC(); // GroupID // CRC += another 4 words which always seem to be zero -- unclear if this is a UUID or what CRC += (uint)iitem.Permissions.OwnerMask; //owner_mask; // Either owner_mask or next_owner_mask may need to be CRC += (uint)iitem.Permissions.NextOwnerMask; //next_owner_mask; // switched with base_mask -- 2 values go here and in my CRC += (uint)iitem.Permissions.EveryoneMask; //everyone_mask; // study item, the three were identical. CRC += (uint)iitem.Permissions.GroupMask; //group_mask; // The rest of the CRC fields CRC += (uint)iitem.Flags; // Flags CRC += (uint)iitem.InventoryType; // InvType CRC += (uint)iitem.AssetType; // Type CRC += (uint)Utils.DateTimeToUnixTime(iitem.CreationDate); // CreationDate CRC += (uint)iitem.SalePrice; // SalePrice CRC += (uint)((uint)iitem.SaleType * 0x07073096); // SaleType return CRC; }
public void StoreFetchedItem(ItemData item) { if (RequestedItems.ContainsKey(item.UUID) && RequestedItems[item.UUID] == null) { ++ItemsFetched; RequestedItems[item.UUID] = item; } }
/// <summary> /// Attach an item to an avatar at a specific attach point /// </summary> /// <param name="item">A <seealso cref="OpenMetaverse.InventoryItem"/> to attach</param> /// <param name="attachPoint">the <seealso cref="OpenMetaverse.AttachmentPoint"/> on the avatar /// to attach the item to</param> public void Attach(ItemData item, AttachmentPoint attachPoint) { Attach(item.UUID, item.OwnerID, item.Name, item.Description, item.Permissions, item.Flags, attachPoint); }