2007-07-13 14:49:36 +00:00
/ *
2008-08-21 01:19:06 +00:00
* Copyright ( c ) 2006 - 2008 , openmetaverse . org
2007-07-13 14:49:36 +00:00
* All rights reserved .
*
2008-08-21 01:19:06 +00:00
* - Redistribution and use in source and binary forms , with or without
2007-07-13 14:49:36 +00:00
* modification , are permitted provided that the following conditions are met :
*
* - Redistributions of source code must retain the above copyright notice , this
* list of conditions and the following disclaimer .
2008-08-21 01:19:06 +00:00
* - Neither the name of the openmetaverse . org nor the names
2007-07-13 14:49:36 +00:00
* of its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission .
*
2008-08-21 01:19:06 +00:00
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR
* CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS
* INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN
* CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE )
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
2007-07-13 14:49:36 +00:00
* POSSIBILITY OF SUCH DAMAGE .
* /
using System ;
using System.Collections.Generic ;
2009-07-10 19:36:59 +00:00
using System.Net ;
2007-07-13 14:49:36 +00:00
using System.Text.RegularExpressions ;
using System.Threading ;
2007-09-10 10:20:30 +00:00
using System.Text ;
2009-02-26 20:41:39 +00:00
using System.Runtime.Serialization ;
2008-12-29 20:44:28 +00:00
using OpenMetaverse.Http ;
2009-05-09 02:23:39 +00:00
using OpenMetaverse.Messages.Linden ;
2008-07-21 21:12:59 +00:00
using OpenMetaverse.StructuredData ;
using OpenMetaverse.Packets ;
2007-07-13 14:49:36 +00:00
2008-07-21 21:12:59 +00:00
namespace OpenMetaverse
2007-07-13 14:49:36 +00:00
{
2007-09-10 10:20:30 +00:00
#region Enums
2007-11-06 09:26:10 +00:00
2007-07-13 14:49:36 +00:00
[Flags]
public enum InventorySortOrder : int
{
/// <summary>Sort by name</summary>
ByName = 0 ,
/// <summary>Sort by date</summary>
ByDate = 1 ,
/// <summary>Sort folders by name, regardless of whether items are
/// sorted by name or date</summary>
FoldersByName = 2 ,
/// <summary>Place system folders at the top</summary>
SystemFoldersToTop = 4
}
2008-05-14 11:17:45 +00:00
/// <summary>
/// Possible destinations for DeRezObject request
/// </summary>
public enum DeRezDestination : byte
{
2008-08-27 23:27:48 +00:00
/// <summary></summary>
AgentInventorySave = 0 ,
/// <summary>Copy from in-world to agent inventory</summary>
AgentInventoryCopy = 1 ,
2008-05-14 11:17:45 +00:00
/// <summary>Derez to TaskInventory</summary>
TaskInventory = 2 ,
2008-08-27 23:27:48 +00:00
/// <summary></summary>
Attachment = 3 ,
2008-05-14 11:17:45 +00:00
/// <summary>Take Object</summary>
2008-08-27 23:27:48 +00:00
AgentInventoryTake = 4 ,
/// <summary></summary>
ForceToGodInventory = 5 ,
2008-05-14 11:17:45 +00:00
/// <summary>Delete Object</summary>
2008-08-27 23:27:48 +00:00
TrashFolder = 6 ,
/// <summary>Put an avatar attachment into agent inventory</summary>
AttachmentToInventory = 7 ,
/// <summary></summary>
AttachmentExists = 8 ,
/// <summary>Return an object back to the owner's inventory</summary>
ReturnToOwner = 9 ,
/// <summary>Return a deeded object back to the last owner's inventory</summary>
ReturnToLastOwner = 10
2008-05-14 11:17:45 +00:00
}
2009-03-19 00:25:03 +00:00
/// <summary>
/// Upper half of the Flags field for inventory items
/// </summary>
[Flags]
2009-03-19 00:52:03 +00:00
public enum InventoryItemFlags : uint
2009-03-19 00:25:03 +00:00
{
None = 0 ,
2009-03-19 00:52:03 +00:00
/// <summary>Indicates that the NextOwner permission will be set to the
/// most restrictive set of permissions found in the object set
/// (including linkset items and object inventory items) on next rez</summary>
2009-03-19 00:25:03 +00:00
ObjectSlamPerm = 0x100 ,
2009-03-19 00:52:03 +00:00
/// <summary>Indicates that the object sale information has been
/// changed</summary>
2009-03-19 00:25:03 +00:00
ObjectSlamSale = 0x1000 ,
2009-03-19 00:52:03 +00:00
/// <summary>If set, and a slam bit is set, indicates BaseMask will be overwritten on Rez</summary>
ObjectOverwriteBase = 0x010000 ,
/// <summary>If set, and a slam bit is set, indicates OwnerMask will be overwritten on Rez</summary>
ObjectOverwriteOwner = 0x020000 ,
/// <summary>If set, and a slam bit is set, indicates GroupMask will be overwritten on Rez</summary>
ObjectOverwriteGroup = 0x040000 ,
/// <summary>If set, and a slam bit is set, indicates EveryoneMask will be overwritten on Rez</summary>
ObjectOverwriteEveryone = 0x080000 ,
/// <summary>If set, and a slam bit is set, indicates NextOwnerMask will be overwritten on Rez</summary>
ObjectOverwriteNextOwner = 0x100000 ,
/// <summary>Indicates whether this object is composed of multiple
/// items or not</summary>
2009-03-19 00:25:03 +00:00
ObjectHasMultipleItems = 0x200000 ,
2009-03-19 00:52:03 +00:00
/// <summary>Indicates that the asset is only referenced by this
/// inventory item. If this item is deleted or updated to reference a
/// new assetID, the asset can be deleted</summary>
2009-03-19 00:25:03 +00:00
SharedSingleReference = 0x40000000 ,
}
2007-09-10 10:20:30 +00:00
#endregion Enums
2008-08-21 01:19:06 +00:00
#region Inventory Object Classes
2009-04-09 01:17:40 +00:00
2008-03-22 00:11:40 +00:00
/// <summary>
2008-08-21 01:19:06 +00:00
/// Base Class for Inventory Items
2008-03-22 00:11:40 +00:00
/// </summary>
2009-02-26 20:41:39 +00:00
[Serializable()]
public abstract class InventoryBase : ISerializable
2007-07-13 14:49:36 +00:00
{
2008-07-28 22:23:48 +00:00
/// <summary><seealso cref="OpenMetaverse.UUID"/> of item/folder</summary>
2009-06-14 11:28:31 +00:00
public UUID UUID ;
2008-07-28 22:23:48 +00:00
/// <summary><seealso cref="OpenMetaverse.UUID"/> of parent folder</summary>
2008-07-25 05:15:05 +00:00
public UUID ParentUUID ;
2008-05-03 04:10:02 +00:00
/// <summary>Name of item/folder</summary>
2007-07-13 14:49:36 +00:00
public string Name ;
2008-07-28 22:23:48 +00:00
/// <summary>Item/Folder Owners <seealso cref="OpenMetaverse.UUID"/></summary>
2008-07-25 05:15:05 +00:00
public UUID OwnerID ;
2008-08-21 01:19:06 +00:00
/// <summary>
/// Constructor, takes an itemID as a parameter
/// </summary>
/// <param name="itemID">The <seealso cref="OpenMetaverse.UUID"/> of the item</param>
public InventoryBase ( UUID itemID )
{
if ( itemID = = UUID . Zero )
Logger . Log ( "Initializing an InventoryBase with UUID.Zero" , Helpers . LogLevel . Warning ) ;
UUID = itemID ;
}
2009-02-26 20:41:39 +00:00
/// <summary>
///
/// </summary>
/// <returns></returns>
2009-06-27 20:51:14 +00:00
public virtual void GetObjectData ( SerializationInfo info , StreamingContext ctxt )
2009-02-26 20:41:39 +00:00
{
info . AddValue ( "UUID" , UUID ) ;
2009-10-29 09:39:43 +00:00
info . AddValue ( "ParentUUID" , ParentUUID ) ;
2009-02-26 20:41:39 +00:00
info . AddValue ( "Name" , Name ) ;
info . AddValue ( "OwnerID" , OwnerID ) ;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public InventoryBase ( SerializationInfo info , StreamingContext ctxt )
{
UUID = ( UUID ) info . GetValue ( "UUID" , typeof ( UUID ) ) ;
ParentUUID = ( UUID ) info . GetValue ( "ParentUUID" , typeof ( UUID ) ) ;
Name = ( string ) info . GetValue ( "Name" , typeof ( string ) ) ;
OwnerID = ( UUID ) info . GetValue ( "OwnerID" , typeof ( UUID ) ) ;
}
2008-08-21 01:19:06 +00:00
/// <summary>
/// Generates a number corresponding to the value of the object to support the use of a hash table,
/// suitable for use in hashing algorithms and data structures such as a hash table
/// </summary>
/// <returns>A Hashcode of all the combined InventoryBase fields</returns>
public override int GetHashCode ( )
{
return UUID . GetHashCode ( ) ^ ParentUUID . GetHashCode ( ) ^ Name . GetHashCode ( ) ^ OwnerID . GetHashCode ( ) ;
}
/// <summary>
/// Determine whether the specified <seealso cref="OpenMetaverse.InventoryBase"/> object is equal to the current object
/// </summary>
/// <param name="o">InventoryBase object to compare against</param>
/// <returns>true if objects are the same</returns>
public override bool Equals ( object o )
{
InventoryBase inv = o as InventoryBase ;
return inv ! = null & & Equals ( inv ) ;
}
/// <summary>
/// Determine whether the specified <seealso cref="OpenMetaverse.InventoryBase"/> object is equal to the current object
/// </summary>
/// <param name="o">InventoryBase object to compare against</param>
/// <returns>true if objects are the same</returns>
public virtual bool Equals ( InventoryBase o )
{
return o . UUID = = UUID
& & o . ParentUUID = = ParentUUID
& & o . Name = = Name
& & o . OwnerID = = OwnerID ;
}
2012-12-18 04:35:49 +01:00
/// <summary>
/// Convert inventory to OSD
/// </summary>
/// <returns>OSD representation</returns>
public abstract OSD GetOSD ( ) ;
2008-08-21 01:19:06 +00:00
}
/// <summary>
/// An Item in Inventory
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2008-08-21 01:19:06 +00:00
public class InventoryItem : InventoryBase
{
2012-05-30 15:16:26 -07:00
public override string ToString ( )
{
return AssetType + " " + AssetUUID + " (" + InventoryType + " " + UUID + ") '" + Name + "'/'" +
Description + "' " + Permissions ;
}
2008-07-28 22:23:48 +00:00
/// <summary>The <seealso cref="OpenMetaverse.UUID"/> of this item</summary>
2008-07-25 05:15:05 +00:00
public UUID AssetUUID ;
2008-07-21 21:12:59 +00:00
/// <summary>The combined <seealso cref="OpenMetaverse.Permissions"/> of this item</summary>
2007-07-13 14:49:36 +00:00
public Permissions Permissions ;
2008-07-21 21:12:59 +00:00
/// <summary>The type of item from <seealso cref="OpenMetaverse.AssetType"/></summary>
2007-07-13 14:49:36 +00:00
public AssetType AssetType ;
2008-07-21 21:12:59 +00:00
/// <summary>The type of item from the <seealso cref="OpenMetaverse.InventoryType"/> enum</summary>
2007-07-13 14:49:36 +00:00
public InventoryType InventoryType ;
2008-07-28 22:23:48 +00:00
/// <summary>The <seealso cref="OpenMetaverse.UUID"/> of the creator of this item</summary>
2008-07-25 05:15:05 +00:00
public UUID CreatorID ;
2008-03-22 00:11:40 +00:00
/// <summary>A Description of this item</summary>
2007-07-13 14:49:36 +00:00
public string Description ;
2008-07-28 22:23:48 +00:00
/// <summary>The <seealso cref="OpenMetaverse.Group"/>s <seealso cref="OpenMetaverse.UUID"/> this item is set to or owned by</summary>
2008-07-25 05:15:05 +00:00
public UUID GroupID ;
2008-05-03 04:10:02 +00:00
/// <summary>If true, item is owned by a group</summary>
2007-07-13 14:49:36 +00:00
public bool GroupOwned ;
2008-03-22 00:11:40 +00:00
/// <summary>The price this item can be purchased for</summary>
2007-07-13 14:49:36 +00:00
public int SalePrice ;
2008-07-21 21:12:59 +00:00
/// <summary>The type of sale from the <seealso cref="OpenMetaverse.SaleType"/> enum</summary>
2007-07-13 14:49:36 +00:00
public SaleType SaleType ;
2008-07-21 21:12:59 +00:00
/// <summary>Combined flags from <seealso cref="OpenMetaverse.InventoryItemFlags"/></summary>
2008-05-05 02:02:29 +00:00
public uint Flags ;
2007-07-13 14:49:36 +00:00
/// <summary>Time and date this inventory item was created, stored as
/// UTC (Coordinated Universal Time)</summary>
public DateTime CreationDate ;
2009-07-11 23:22:41 +00:00
/// <summary>Used to update the AssetID in requests sent to the server</summary>
public UUID TransactionID ;
2009-07-11 14:50:45 +00:00
/// <summary>The <seealso cref="OpenMetaverse.UUID"/> of the previous owner of the item</summary>
public UUID LastOwnerID ;
2007-07-13 14:49:36 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
/// Construct a new InventoryItem object
/// </summary>
/// <param name="itemID">The <seealso cref="OpenMetaverse.UUID"/> of the item</param>
2009-10-29 09:39:43 +00:00
public InventoryItem ( UUID itemID )
2008-08-21 01:19:06 +00:00
: base ( itemID ) { }
2007-07-13 14:49:36 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
/// Construct a new InventoryItem object of a specific Type
/// </summary>
/// <param name="type">The type of item from <seealso cref="OpenMetaverse.InventoryType"/></param>
/// <param name="itemID"><seealso cref="OpenMetaverse.UUID"/> of the item</param>
public InventoryItem ( InventoryType type , UUID itemID ) : base ( itemID ) { InventoryType = type ; }
2010-02-26 11:54:08 +00:00
/// <summary>
/// Indicates inventory item is a link
/// </summary>
/// <returns>True if inventory item is a link to another inventory item</returns>
public bool IsLink ( )
{
return AssetType = = AssetType . Link | | AssetType = = AssetType . LinkFolder ;
}
2009-02-26 20:41:39 +00:00
/// <summary>
///
/// </summary>
/// <returns></returns>
2009-07-11 14:50:45 +00:00
override public void GetObjectData ( SerializationInfo info , StreamingContext ctxt )
2009-02-26 20:41:39 +00:00
{
2009-07-11 14:50:45 +00:00
base . GetObjectData ( info , ctxt ) ;
info . AddValue ( "AssetUUID" , AssetUUID , typeof ( UUID ) ) ;
info . AddValue ( "Permissions" , Permissions , typeof ( Permissions ) ) ;
2009-02-26 20:41:39 +00:00
info . AddValue ( "AssetType" , AssetType ) ;
info . AddValue ( "InventoryType" , InventoryType ) ;
info . AddValue ( "CreatorID" , CreatorID ) ;
info . AddValue ( "Description" , Description ) ;
info . AddValue ( "GroupID" , GroupID ) ;
info . AddValue ( "GroupOwned" , GroupOwned ) ;
info . AddValue ( "SalePrice" , SalePrice ) ;
info . AddValue ( "SaleType" , SaleType ) ;
info . AddValue ( "Flags" , Flags ) ;
2009-07-11 14:50:45 +00:00
info . AddValue ( "CreationDate" , CreationDate ) ;
info . AddValue ( "LastOwnerID" , LastOwnerID ) ;
2009-02-26 20:41:39 +00:00
}
/// <summary>
///
/// </summary>
/// <returns></returns>
2009-10-29 09:39:43 +00:00
public InventoryItem ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
AssetUUID = ( UUID ) info . GetValue ( "AssetUUID" , typeof ( UUID ) ) ;
Permissions = ( Permissions ) info . GetValue ( "Permissions" , typeof ( Permissions ) ) ;
AssetType = ( AssetType ) info . GetValue ( "AssetType" , typeof ( AssetType ) ) ;
InventoryType = ( InventoryType ) info . GetValue ( "InventoryType" , typeof ( InventoryType ) ) ;
CreatorID = ( UUID ) info . GetValue ( "CreatorID" , typeof ( UUID ) ) ;
Description = ( string ) info . GetValue ( "Description" , typeof ( string ) ) ;
GroupID = ( UUID ) info . GetValue ( "GroupID" , typeof ( UUID ) ) ;
GroupOwned = ( bool ) info . GetValue ( "GroupOwned" , typeof ( bool ) ) ;
SalePrice = ( int ) info . GetValue ( "SalePrice" , typeof ( int ) ) ;
SaleType = ( SaleType ) info . GetValue ( "SaleType" , typeof ( SaleType ) ) ;
Flags = ( uint ) info . GetValue ( "Flags" , typeof ( uint ) ) ;
CreationDate = ( DateTime ) info . GetValue ( "CreationDate" , typeof ( DateTime ) ) ;
LastOwnerID = ( UUID ) info . GetValue ( "LastOwnerID" , typeof ( UUID ) ) ;
2009-02-26 20:41:39 +00:00
}
2008-08-21 01:19:06 +00:00
/// <summary>
/// Generates a number corresponding to the value of the object to support the use of a hash table.
/// Suitable for use in hashing algorithms and data structures such as a hash table
/// </summary>
/// <returns>A Hashcode of all the combined InventoryItem fields</returns>
2008-07-29 21:36:53 +00:00
public override int GetHashCode ( )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
return AssetUUID . GetHashCode ( ) ^ Permissions . GetHashCode ( ) ^ AssetType . GetHashCode ( ) ^
InventoryType . GetHashCode ( ) ^ Description . GetHashCode ( ) ^ GroupID . GetHashCode ( ) ^
GroupOwned . GetHashCode ( ) ^ SalePrice . GetHashCode ( ) ^ SaleType . GetHashCode ( ) ^
2009-07-11 14:50:45 +00:00
Flags . GetHashCode ( ) ^ CreationDate . GetHashCode ( ) ^ LastOwnerID . GetHashCode ( ) ;
2007-07-13 14:49:36 +00:00
}
2008-08-21 01:19:06 +00:00
/// <summary>
/// Compares an object
/// </summary>
/// <param name="o">The object to compare</param>
/// <returns>true if comparison object matches</returns>
public override bool Equals ( object o )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
InventoryItem item = o as InventoryItem ;
return item ! = null & & Equals ( item ) ;
}
2007-07-13 14:49:36 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
/// Determine whether the specified <seealso cref="OpenMetaverse.InventoryBase"/> object is equal to the current object
/// </summary>
/// <param name="o">The <seealso cref="OpenMetaverse.InventoryBase"/> object to compare against</param>
/// <returns>true if objects are the same</returns>
public override bool Equals ( InventoryBase o )
{
InventoryItem item = o as InventoryItem ;
return item ! = null & & Equals ( item ) ;
}
/// <summary>
/// Determine whether the specified <seealso cref="OpenMetaverse.InventoryItem"/> object is equal to the current object
/// </summary>
/// <param name="o">The <seealso cref="OpenMetaverse.InventoryItem"/> object to compare against</param>
/// <returns>true if objects are the same</returns>
public bool Equals ( InventoryItem o )
{
return base . Equals ( o as InventoryBase )
2007-07-13 14:49:36 +00:00
& & o . AssetType = = AssetType
& & o . AssetUUID = = AssetUUID
& & o . CreationDate = = CreationDate
& & o . Description = = Description
& & o . Flags = = Flags
& & o . GroupID = = GroupID
& & o . GroupOwned = = GroupOwned
& & o . InventoryType = = InventoryType
& & o . Permissions . Equals ( Permissions )
& & o . SalePrice = = SalePrice
2009-07-11 14:50:45 +00:00
& & o . SaleType = = SaleType
& & o . LastOwnerID = = LastOwnerID ;
2007-07-13 14:49:36 +00:00
}
2012-12-18 02:31:40 +01:00
/// <summary>
/// Create InventoryItem from OSD
/// </summary>
/// <param name="data">OSD Data that makes up InventoryItem</param>
/// <returns>Inventory item created</returns>
public static InventoryItem FromOSD ( OSD data )
{
OSDMap descItem = ( OSDMap ) data ;
InventoryType type = ( InventoryType ) descItem [ "inv_type" ] . AsInteger ( ) ;
if ( type = = InventoryType . Texture & & ( AssetType ) descItem [ "type" ] . AsInteger ( ) = = AssetType . Object )
{
type = InventoryType . Attachment ;
}
InventoryItem item = InventoryManager . CreateInventoryItem ( type , descItem [ "item_id" ] ) ;
item . ParentUUID = descItem [ "parent_id" ] ;
item . Name = descItem [ "name" ] ;
item . Description = descItem [ "desc" ] ;
item . OwnerID = descItem [ "agent_id" ] ;
2012-12-18 04:35:49 +01:00
item . ParentUUID = descItem [ "parent_id" ] ;
2012-12-18 02:31:40 +01:00
item . AssetUUID = descItem [ "asset_id" ] ;
item . AssetType = ( AssetType ) descItem [ "type" ] . AsInteger ( ) ;
item . CreationDate = Utils . UnixTimeToDateTime ( descItem [ "created_at" ] ) ;
item . Flags = descItem [ "flags" ] ;
OSDMap perms = ( OSDMap ) descItem [ "permissions" ] ;
item . CreatorID = perms [ "creator_id" ] ;
item . LastOwnerID = perms [ "last_owner_id" ] ;
item . Permissions = new Permissions ( perms [ "base_mask" ] , perms [ "everyone_mask" ] , perms [ "group_mask" ] , perms [ "next_owner_mask" ] , perms [ "owner_mask" ] ) ;
item . GroupOwned = perms [ "is_owner_group" ] ;
item . GroupID = perms [ "group_id" ] ;
OSDMap sale = ( OSDMap ) descItem [ "sale_info" ] ;
item . SalePrice = sale [ "sale_price" ] ;
item . SaleType = ( SaleType ) sale [ "sale_type" ] . AsInteger ( ) ;
return item ;
}
/// <summary>
/// Convert InventoryItem to OSD
/// </summary>
/// <returns>OSD representation of InventoryItem</returns>
2012-12-18 04:35:49 +01:00
public override OSD GetOSD ( )
2012-12-18 02:31:40 +01:00
{
OSDMap map = new OSDMap ( ) ;
map [ "inv_type" ] = ( int ) InventoryType ;
map [ "parent_id" ] = ParentUUID ;
map [ "name" ] = Name ;
map [ "desc" ] = Description ;
map [ "agent_id" ] = OwnerID ;
2012-12-18 04:35:49 +01:00
map [ "parent_id" ] = ParentUUID ;
2012-12-18 02:31:40 +01:00
map [ "asset_id" ] = AssetUUID ;
map [ "type" ] = ( int ) AssetType ;
map [ "created_at" ] = CreationDate ;
map [ "flags" ] = Flags ;
OSDMap perms = ( OSDMap ) Permissions . GetOSD ( ) ;
perms [ "creator_id" ] = CreatorID ;
perms [ "last_owner_id" ] = LastOwnerID ;
perms [ "is_owner_group" ] = GroupOwned ;
perms [ "group_id" ] = GroupID ;
map [ "permissions" ] = perms ;
OSDMap sale = new OSDMap ( ) ;
sale [ "sale_price" ] = SalePrice ;
sale [ "sale_type" ] = ( int ) SaleType ;
map [ "sale_info" ] = sale ;
return map ;
}
2008-08-21 01:19:06 +00:00
}
2008-05-05 02:02:29 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
/// InventoryTexture Class representing a graphical image
/// </summary>
/// <seealso cref="ManagedImage"/>
2012-05-30 15:16:26 -07:00
[Serializable()]
2009-10-29 09:39:43 +00:00
public class InventoryTexture : InventoryItem
{
2008-08-21 01:19:06 +00:00
/// <summary>
/// Construct an InventoryTexture object
/// </summary>
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
2009-10-29 09:39:43 +00:00
public InventoryTexture ( UUID itemID )
: base ( itemID )
{
InventoryType = InventoryType . Texture ;
}
2009-03-02 22:49:25 +00:00
2009-02-26 20:41:39 +00:00
/// <summary>
/// Construct an InventoryTexture object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventoryTexture ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
InventoryType = InventoryType . Texture ;
2009-02-26 20:41:39 +00:00
}
2008-08-21 01:19:06 +00:00
}
/// <summary>
/// InventorySound Class representing a playable sound
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2009-10-29 09:39:43 +00:00
public class InventorySound : InventoryItem
2008-08-21 01:19:06 +00:00
{
/// <summary>
/// Construct an InventorySound object
/// </summary>
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
2009-10-29 09:39:43 +00:00
public InventorySound ( UUID itemID )
: base ( itemID )
{
InventoryType = InventoryType . Sound ;
}
2009-03-02 22:49:25 +00:00
2009-02-26 20:41:39 +00:00
/// <summary>
/// Construct an InventorySound object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventorySound ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
InventoryType = InventoryType . Sound ;
2009-02-26 20:41:39 +00:00
}
2008-08-21 01:19:06 +00:00
}
/// <summary>
/// InventoryCallingCard Class, contains information on another avatar
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2009-10-29 09:39:43 +00:00
public class InventoryCallingCard : InventoryItem
2008-08-21 01:19:06 +00:00
{
/// <summary>
/// Construct an InventoryCallingCard object
/// </summary>
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
2009-10-29 09:39:43 +00:00
public InventoryCallingCard ( UUID itemID )
: base ( itemID )
{
InventoryType = InventoryType . CallingCard ;
2009-03-02 22:49:25 +00:00
}
2009-02-26 20:41:39 +00:00
/// <summary>
/// Construct an InventoryCallingCard object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventoryCallingCard ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
InventoryType = InventoryType . CallingCard ;
2008-05-05 02:02:29 +00:00
}
2008-08-21 01:19:06 +00:00
}
2008-05-03 04:10:02 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
/// InventoryLandmark Class, contains details on a specific location
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2009-10-29 09:39:43 +00:00
public class InventoryLandmark : InventoryItem
2008-08-21 01:19:06 +00:00
{
2008-05-03 04:10:02 +00:00
/// <summary>
2008-08-21 01:19:06 +00:00
/// Construct an InventoryLandmark object
2008-05-03 04:10:02 +00:00
/// </summary>
2008-08-21 01:19:06 +00:00
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
2009-10-29 09:39:43 +00:00
public InventoryLandmark ( UUID itemID )
: base ( itemID )
{
InventoryType = InventoryType . Landmark ;
2008-05-05 02:02:29 +00:00
}
2009-03-02 22:49:25 +00:00
2009-02-26 20:41:39 +00:00
/// <summary>
/// Construct an InventoryLandmark object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventoryLandmark ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
InventoryType = InventoryType . Landmark ;
}
2008-05-05 02:02:29 +00:00
/// <summary>
2009-03-19 00:52:03 +00:00
/// Landmarks use the InventoryItemFlags struct and will have a flag of 1 set if they have been visited
2008-05-05 02:02:29 +00:00
/// </summary>
2009-03-19 00:52:03 +00:00
public bool LandmarkVisited
2008-05-05 02:02:29 +00:00
{
2009-03-19 00:52:03 +00:00
get { return ( Flags & 1 ) ! = 0 ; }
set
{
if ( value ) Flags | = 1 ;
else Flags & = ~ 1 u ;
}
2008-05-05 02:02:29 +00:00
}
2008-05-03 04:10:02 +00:00
}
/// <summary>
2008-08-21 01:19:06 +00:00
/// InventoryObject Class contains details on a primitive or coalesced set of primitives
2008-05-03 04:10:02 +00:00
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2009-10-29 09:39:43 +00:00
public class InventoryObject : InventoryItem
2008-05-03 04:10:02 +00:00
{
2008-08-21 01:19:06 +00:00
/// <summary>
/// Construct an InventoryObject object
/// </summary>
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
2009-10-29 09:39:43 +00:00
public InventoryObject ( UUID itemID )
: base ( itemID )
{
InventoryType = InventoryType . Object ;
2008-07-29 21:36:53 +00:00
}
2009-03-02 22:49:25 +00:00
2009-02-26 20:41:39 +00:00
/// <summary>
/// Construct an InventoryObject object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventoryObject ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
InventoryType = InventoryType . Object ;
2009-02-26 20:41:39 +00:00
}
2008-05-03 04:10:02 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
2009-03-19 00:52:03 +00:00
/// Gets or sets the upper byte of the Flags value
2008-08-21 01:19:06 +00:00
/// </summary>
2009-03-19 00:52:03 +00:00
public InventoryItemFlags ItemFlags
2008-07-29 21:36:53 +00:00
{
2009-03-19 00:52:03 +00:00
get { return ( InventoryItemFlags ) ( Flags & ~ 0xFF ) ; }
set { Flags = ( uint ) value | ( Flags & 0xFF ) ; }
2008-07-29 21:36:53 +00:00
}
2009-07-11 00:26:51 +00:00
/// <summary>
/// Gets or sets the object attachment point, the lower byte of the Flags value
/// </summary>
public AttachmentPoint AttachPoint
{
get { return ( AttachmentPoint ) ( Flags & 0xFF ) ; }
set { Flags = ( uint ) value | ( Flags & 0xFFFFFF00 ) ; }
}
2008-08-21 01:19:06 +00:00
}
2008-05-03 04:10:02 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
/// InventoryNotecard Class, contains details on an encoded text document
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2009-10-29 09:39:43 +00:00
public class InventoryNotecard : InventoryItem
2008-08-21 01:19:06 +00:00
{
/// <summary>
/// Construct an InventoryNotecard object
/// </summary>
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
2009-10-29 09:39:43 +00:00
public InventoryNotecard ( UUID itemID )
: base ( itemID )
{
InventoryType = InventoryType . Notecard ;
2009-03-02 22:49:25 +00:00
}
2009-02-26 20:41:39 +00:00
/// <summary>
/// Construct an InventoryNotecard object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventoryNotecard ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
InventoryType = InventoryType . Notecard ;
2009-02-26 20:41:39 +00:00
}
2008-08-21 01:19:06 +00:00
}
2008-05-03 04:10:02 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
/// InventoryCategory Class
/// </summary>
/// <remarks>TODO: Is this even used for anything?</remarks>
2012-05-30 15:16:26 -07:00
[Serializable()]
2009-10-29 09:39:43 +00:00
public class InventoryCategory : InventoryItem
2008-08-21 01:19:06 +00:00
{
/// <summary>
/// Construct an InventoryCategory object
/// </summary>
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
2009-10-29 09:39:43 +00:00
public InventoryCategory ( UUID itemID )
: base ( itemID )
{
InventoryType = InventoryType . Category ;
}
2009-02-26 20:41:39 +00:00
/// <summary>
/// Construct an InventoryCategory object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventoryCategory ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
InventoryType = InventoryType . Category ;
2009-02-26 20:41:39 +00:00
}
2008-08-21 01:19:06 +00:00
}
2008-05-05 02:02:29 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
/// InventoryLSL Class, represents a Linden Scripting Language object
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2009-10-29 09:39:43 +00:00
public class InventoryLSL : InventoryItem
2008-08-21 01:19:06 +00:00
{
/// <summary>
/// Construct an InventoryLSL object
/// </summary>
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
2009-10-29 09:39:43 +00:00
public InventoryLSL ( UUID itemID )
: base ( itemID )
{
InventoryType = InventoryType . LSL ;
}
2009-03-02 22:49:25 +00:00
2009-02-26 20:41:39 +00:00
/// <summary>
/// Construct an InventoryLSL object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventoryLSL ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
InventoryType = InventoryType . LSL ;
2009-02-26 20:41:39 +00:00
}
2008-08-21 01:19:06 +00:00
}
2008-05-03 04:10:02 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
/// InventorySnapshot Class, an image taken with the viewer
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2009-10-29 09:39:43 +00:00
public class InventorySnapshot : InventoryItem
2008-08-21 01:19:06 +00:00
{
/// <summary>
/// Construct an InventorySnapshot object
/// </summary>
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
2009-10-29 09:39:43 +00:00
public InventorySnapshot ( UUID itemID )
: base ( itemID )
{
InventoryType = InventoryType . Snapshot ;
}
2009-02-26 20:41:39 +00:00
/// <summary>
/// Construct an InventorySnapshot object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventorySnapshot ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
InventoryType = InventoryType . Snapshot ;
2009-02-26 20:41:39 +00:00
}
2008-08-21 01:19:06 +00:00
}
/// <summary>
/// InventoryAttachment Class, contains details on an attachable object
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2009-10-29 09:39:43 +00:00
public class InventoryAttachment : InventoryItem
2008-08-21 01:19:06 +00:00
{
/// <summary>
/// Construct an InventoryAttachment object
/// </summary>
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
2009-10-29 09:39:43 +00:00
public InventoryAttachment ( UUID itemID )
: base ( itemID )
{
InventoryType = InventoryType . Attachment ;
2009-03-02 22:49:25 +00:00
}
2009-02-26 20:41:39 +00:00
/// <summary>
/// Construct an InventoryAttachment object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventoryAttachment ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
InventoryType = InventoryType . Attachment ;
2007-08-25 09:36:33 +00:00
}
2008-05-03 04:10:02 +00:00
/// <summary>
2008-08-21 01:19:06 +00:00
/// Get the last AttachmentPoint this object was attached to
2008-05-03 04:10:02 +00:00
/// </summary>
2008-08-21 01:19:06 +00:00
public AttachmentPoint AttachmentPoint
2007-12-21 02:25:36 +00:00
{
2008-08-21 01:19:06 +00:00
get { return ( AttachmentPoint ) Flags ; }
set { Flags = ( uint ) value ; }
2007-12-21 02:25:36 +00:00
}
2008-08-21 01:19:06 +00:00
}
2007-12-21 02:25:36 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
/// InventoryWearable Class, details on a clothing item or body part
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2008-08-21 01:19:06 +00:00
public class InventoryWearable : InventoryItem
{
2008-05-03 04:10:02 +00:00
/// <summary>
2008-08-21 01:19:06 +00:00
/// Construct an InventoryWearable object
2008-05-03 04:10:02 +00:00
/// </summary>
2008-08-21 01:19:06 +00:00
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
public InventoryWearable ( UUID itemID ) : base ( itemID ) { InventoryType = InventoryType . Wearable ; }
2009-03-02 22:49:25 +00:00
2009-02-26 20:41:39 +00:00
/// <summary>
/// Construct an InventoryWearable object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventoryWearable ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
InventoryType = InventoryType . Wearable ;
2009-02-26 20:41:39 +00:00
}
2008-08-21 01:19:06 +00:00
/// <summary>
/// The <seealso cref="OpenMetaverse.WearableType"/>, Skin, Shape, Skirt, Etc
/// </summary>
public WearableType WearableType
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
get { return ( WearableType ) Flags ; }
set { Flags = ( uint ) value ; }
2007-07-13 14:49:36 +00:00
}
2008-08-21 01:19:06 +00:00
}
/// <summary>
/// InventoryAnimation Class, A bvh encoded object which animates an avatar
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2009-10-29 09:39:43 +00:00
public class InventoryAnimation : InventoryItem
2008-08-21 01:19:06 +00:00
{
/// <summary>
/// Construct an InventoryAnimation object
/// </summary>
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
2009-10-29 09:39:43 +00:00
public InventoryAnimation ( UUID itemID )
: base ( itemID )
{
InventoryType = InventoryType . Animation ;
2009-02-26 20:41:39 +00:00
}
2009-03-02 22:49:25 +00:00
2009-10-29 09:39:43 +00:00
/// <summary>
2009-02-26 20:41:39 +00:00
/// Construct an InventoryAnimation object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventoryAnimation ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
InventoryType = InventoryType . Animation ;
2009-02-26 20:41:39 +00:00
}
2009-10-29 09:39:43 +00:00
2009-02-26 20:41:39 +00:00
2008-08-21 01:19:06 +00:00
}
/// <summary>
/// InventoryGesture Class, details on a series of animations, sounds, and actions
/// </summary>
2012-06-02 03:40:27 -07:00
[Serializable()]
2009-10-29 09:39:43 +00:00
public class InventoryGesture : InventoryItem
2008-08-21 01:19:06 +00:00
{
/// <summary>
/// Construct an InventoryGesture object
/// </summary>
/// <param name="itemID">A <seealso cref="OpenMetaverse.UUID"/> which becomes the
/// <seealso cref="OpenMetaverse.InventoryItem"/> objects AssetUUID</param>
2009-10-29 09:39:43 +00:00
public InventoryGesture ( UUID itemID )
: base ( itemID )
{
InventoryType = InventoryType . Gesture ;
}
2009-03-02 22:49:25 +00:00
2009-02-26 20:41:39 +00:00
/// <summary>
/// Construct an InventoryGesture object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventoryGesture ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
InventoryType = InventoryType . Gesture ;
2009-02-26 20:41:39 +00:00
}
2008-08-21 01:19:06 +00:00
}
2009-10-29 09:39:43 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
/// A folder contains <seealso cref="T:OpenMetaverse.InventoryItem"/>s and has certain attributes specific
/// to itself
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2008-08-21 01:19:06 +00:00
public class InventoryFolder : InventoryBase
{
/// <summary>The Preferred <seealso cref="T:OpenMetaverse.AssetType"/> for a folder.</summary>
public AssetType PreferredType ;
/// <summary>The Version of this folder</summary>
public int Version ;
/// <summary>Number of child items this folder contains.</summary>
public int DescendentCount ;
/// <summary>
/// Constructor
/// </summary>
/// <param name="itemID">UUID of the folder</param>
public InventoryFolder ( UUID itemID )
2009-10-29 09:39:43 +00:00
: base ( itemID )
2009-06-15 13:11:55 +00:00
{
PreferredType = AssetType . Unknown ;
Version = 1 ;
DescendentCount = 0 ;
}
2007-07-13 14:49:36 +00:00
2008-05-03 04:10:02 +00:00
/// <summary>
2008-08-21 01:19:06 +00:00
///
2008-05-03 04:10:02 +00:00
/// </summary>
2008-08-21 01:19:06 +00:00
/// <returns></returns>
public override string ToString ( )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
return Name ;
2007-07-13 14:49:36 +00:00
}
2009-02-26 20:41:39 +00:00
/// <summary>
/// Get Serilization data for this InventoryFolder object
/// </summary>
2009-06-27 20:51:14 +00:00
override public void GetObjectData ( SerializationInfo info , StreamingContext ctxt )
2009-02-26 20:41:39 +00:00
{
2009-10-29 09:39:43 +00:00
base . GetObjectData ( info , ctxt ) ;
2009-02-26 20:41:39 +00:00
info . AddValue ( "PreferredType" , PreferredType , typeof ( AssetType ) ) ;
info . AddValue ( "Version" , Version ) ;
info . AddValue ( "DescendentCount" , DescendentCount ) ;
}
/// <summary>
/// Construct an InventoryFolder object from a serialization stream
/// </summary>
2009-10-29 09:39:43 +00:00
public InventoryFolder ( SerializationInfo info , StreamingContext ctxt )
: base ( info , ctxt )
2009-02-26 20:41:39 +00:00
{
PreferredType = ( AssetType ) info . GetValue ( "PreferredType" , typeof ( AssetType ) ) ;
2009-10-29 09:39:43 +00:00
Version = ( int ) info . GetValue ( "Version" , typeof ( int ) ) ;
2009-02-26 20:41:39 +00:00
DescendentCount = ( int ) info . GetValue ( "DescendentCount" , typeof ( int ) ) ;
}
2008-05-03 04:10:02 +00:00
/// <summary>
2008-08-21 01:19:06 +00:00
///
2008-05-03 04:10:02 +00:00
/// </summary>
2008-08-21 01:19:06 +00:00
/// <returns></returns>
public override int GetHashCode ( )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
return PreferredType . GetHashCode ( ) ^ Version . GetHashCode ( ) ^ DescendentCount . GetHashCode ( ) ;
2007-07-13 14:49:36 +00:00
}
2008-08-21 01:19:06 +00:00
/// <summary>
///
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
public override bool Equals ( object o )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
InventoryFolder folder = o as InventoryFolder ;
return folder ! = null & & Equals ( folder ) ;
2008-07-29 21:36:53 +00:00
}
2008-08-21 01:19:06 +00:00
/// <summary>
///
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
public override bool Equals ( InventoryBase o )
2008-07-29 21:36:53 +00:00
{
2008-08-21 01:19:06 +00:00
InventoryFolder folder = o as InventoryFolder ;
return folder ! = null & & Equals ( folder ) ;
2007-07-13 14:49:36 +00:00
}
2008-08-21 01:19:06 +00:00
/// <summary>
///
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
public bool Equals ( InventoryFolder o )
2008-07-29 21:36:53 +00:00
{
2008-08-21 01:19:06 +00:00
return base . Equals ( o as InventoryBase )
& & o . DescendentCount = = DescendentCount
& & o . PreferredType = = PreferredType
& & o . Version = = Version ;
2008-07-29 21:36:53 +00:00
}
2012-12-18 04:35:49 +01:00
/// <summary>
/// Create InventoryFolder from OSD
/// </summary>
/// <param name="data">OSD Data that makes up InventoryFolder</param>
/// <returns>Inventory folder created</returns>
public static InventoryFolder FromOSD ( OSD data )
{
OSDMap res = ( OSDMap ) data ;
UUID folderID = res . ContainsKey ( "category_id" ) ? res [ "category_id" ] : res [ "folder_id" ] ;
InventoryFolder folder = new InventoryFolder ( folderID ) ;
folder . Name = res [ "name" ] ;
folder . DescendentCount = res [ "descendents" ] ;
folder . Version = res [ "version" ] ;
folder . OwnerID = res . ContainsKey ( "agent_id" ) ? res [ "agent_id" ] : res [ "owner_id" ] ;
folder . ParentUUID = res [ "parent_id" ] ;
folder . PreferredType = ( AssetType ) ( int ) res [ "type_default" ] ;
return folder ;
}
/// <summary>
/// Convert InventoryItem to OSD
/// </summary>
/// <returns>OSD representation of InventoryItem</returns>
public override OSD GetOSD ( )
{
OSDMap res = new OSDMap ( 4 ) ;
res [ "name" ] = Name ;
res [ "type_default" ] = ( int ) PreferredType ;
res [ "folder_id" ] = UUID ;
res [ "descendents" ] = DescendentCount ;
res [ "version" ] = Version ;
res [ "owner_id" ] = OwnerID ;
res [ "parent_id" ] = ParentUUID ;
return res ;
}
2008-07-29 21:36:53 +00:00
}
2007-09-10 10:20:30 +00:00
2008-08-21 01:19:06 +00:00
#endregion Inventory Object Classes
2008-05-03 04:10:02 +00:00
/// <summary>
/// Tools for dealing with agents inventory
/// </summary>
2012-05-30 15:16:26 -07:00
[Serializable()]
2007-07-13 14:49:36 +00:00
public class InventoryManager
{
2009-07-11 23:22:41 +00:00
/// <summary>Used for converting shadow_id to asset_id</summary>
public static readonly UUID MAGIC_ID = new UUID ( "3c115e51-04f4-523c-9fa6-98aff1034730" ) ;
2008-08-21 01:19:06 +00:00
protected struct InventorySearch
2007-11-06 09:26:10 +00:00
{
2008-07-25 05:15:05 +00:00
public UUID Folder ;
2008-08-21 01:19:06 +00:00
public UUID Owner ;
public string [ ] Path ;
public int Level ;
2007-11-06 09:26:10 +00:00
}
2007-12-21 02:25:36 +00:00
#region Delegates
2007-09-10 10:20:30 +00:00
/// <summary>
/// Callback for inventory item creation finishing
/// </summary>
/// <param name="success">Whether the request to create an inventory
/// item succeeded or not</param>
/// <param name="item">Inventory item being created. If success is
/// false this will be null</param>
2008-08-21 01:19:06 +00:00
public delegate void ItemCreatedCallback ( bool success , InventoryItem item ) ;
2008-05-03 04:10:02 +00:00
2007-09-10 10:20:30 +00:00
/// <summary>
2008-05-03 04:10:02 +00:00
/// Callback for an inventory item being create from an uploaded asset
2007-11-06 09:26:10 +00:00
/// </summary>
2008-05-03 04:10:02 +00:00
/// <param name="success">true if inventory item creation was successful</param>
2007-11-06 09:26:10 +00:00
/// <param name="status"></param>
/// <param name="itemID"></param>
/// <param name="assetID"></param>
2008-07-25 05:15:05 +00:00
public delegate void ItemCreatedFromAssetCallback ( bool success , string status , UUID itemID , UUID assetID ) ;
2008-05-03 04:10:02 +00:00
2007-11-06 09:26:10 +00:00
/// <summary>
///
/// </summary>
2008-09-12 00:32:05 +00:00
/// <param name="item"></param>
2008-08-21 01:19:06 +00:00
public delegate void ItemCopiedCallback ( InventoryBase item ) ;
2008-05-05 02:02:29 +00:00
2009-10-29 09:39:43 +00:00
/// <summary>The event subscribers, null of no subscribers</summary>
private EventHandler < ItemReceivedEventArgs > m_ItemReceived ;
2008-05-03 04:10:02 +00:00
2009-10-29 09:39:43 +00:00
///<summary>Raises the ItemReceived Event</summary>
/// <param name="e">A ItemReceivedEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnItemReceived ( ItemReceivedEventArgs e )
{
EventHandler < ItemReceivedEventArgs > handler = m_ItemReceived ;
if ( handler ! = null )
handler ( this , e ) ;
}
2008-05-03 04:10:02 +00:00
2009-10-29 09:39:43 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_ItemReceivedLock = new object ( ) ;
2008-05-03 04:10:02 +00:00
2009-10-29 09:39:43 +00:00
/// <summary>Raised when the simulator sends us data containing
/// ...</summary>
public event EventHandler < ItemReceivedEventArgs > ItemReceived
{
add { lock ( m_ItemReceivedLock ) { m_ItemReceived + = value ; } }
remove { lock ( m_ItemReceivedLock ) { m_ItemReceived - = value ; } }
}
2008-05-03 04:10:02 +00:00
2009-10-29 09:39:43 +00:00
/// <summary>The event subscribers, null of no subscribers</summary>
private EventHandler < FolderUpdatedEventArgs > m_FolderUpdated ;
///<summary>Raises the FolderUpdated Event</summary>
/// <param name="e">A FolderUpdatedEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnFolderUpdated ( FolderUpdatedEventArgs e )
{
EventHandler < FolderUpdatedEventArgs > handler = m_FolderUpdated ;
if ( handler ! = null )
handler ( this , e ) ;
}
/// <summary>Thread sync lock object</summary>
private readonly object m_FolderUpdatedLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
/// ...</summary>
public event EventHandler < FolderUpdatedEventArgs > FolderUpdated
{
add { lock ( m_FolderUpdatedLock ) { m_FolderUpdated + = value ; } }
remove { lock ( m_FolderUpdatedLock ) { m_FolderUpdated - = value ; } }
}
/// <summary>The event subscribers, null of no subscribers</summary>
private EventHandler < InventoryObjectOfferedEventArgs > m_InventoryObjectOffered ;
///<summary>Raises the InventoryObjectOffered Event</summary>
/// <param name="e">A InventoryObjectOfferedEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnInventoryObjectOffered ( InventoryObjectOfferedEventArgs e )
{
EventHandler < InventoryObjectOfferedEventArgs > handler = m_InventoryObjectOffered ;
if ( handler ! = null )
handler ( this , e ) ;
}
/// <summary>Thread sync lock object</summary>
private readonly object m_InventoryObjectOfferedLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
/// an inventory object sent by another avatar or primitive</summary>
public event EventHandler < InventoryObjectOfferedEventArgs > InventoryObjectOffered
{
add { lock ( m_InventoryObjectOfferedLock ) { m_InventoryObjectOffered + = value ; } }
remove { lock ( m_InventoryObjectOfferedLock ) { m_InventoryObjectOffered - = value ; } }
}
/// <summary>The event subscribers, null of no subscribers</summary>
private EventHandler < TaskItemReceivedEventArgs > m_TaskItemReceived ;
///<summary>Raises the TaskItemReceived Event</summary>
/// <param name="e">A TaskItemReceivedEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnTaskItemReceived ( TaskItemReceivedEventArgs e )
{
EventHandler < TaskItemReceivedEventArgs > handler = m_TaskItemReceived ;
if ( handler ! = null )
handler ( this , e ) ;
}
/// <summary>Thread sync lock object</summary>
private readonly object m_TaskItemReceivedLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
/// ...</summary>
public event EventHandler < TaskItemReceivedEventArgs > TaskItemReceived
{
add { lock ( m_TaskItemReceivedLock ) { m_TaskItemReceived + = value ; } }
remove { lock ( m_TaskItemReceivedLock ) { m_TaskItemReceived - = value ; } }
}
/// <summary>The event subscribers, null of no subscribers</summary>
private EventHandler < FindObjectByPathReplyEventArgs > m_FindObjectByPathReply ;
///<summary>Raises the FindObjectByPath Event</summary>
/// <param name="e">A FindObjectByPathEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnFindObjectByPathReply ( FindObjectByPathReplyEventArgs e )
{
EventHandler < FindObjectByPathReplyEventArgs > handler = m_FindObjectByPathReply ;
if ( handler ! = null )
handler ( this , e ) ;
}
/// <summary>Thread sync lock object</summary>
private readonly object m_FindObjectByPathReplyLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
/// ...</summary>
public event EventHandler < FindObjectByPathReplyEventArgs > FindObjectByPathReply
{
add { lock ( m_FindObjectByPathReplyLock ) { m_FindObjectByPathReply + = value ; } }
remove { lock ( m_FindObjectByPathReplyLock ) { m_FindObjectByPathReply - = value ; } }
}
/// <summary>The event subscribers, null of no subscribers</summary>
private EventHandler < TaskInventoryReplyEventArgs > m_TaskInventoryReply ;
///<summary>Raises the TaskInventoryReply Event</summary>
/// <param name="e">A TaskInventoryReplyEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnTaskInventoryReply ( TaskInventoryReplyEventArgs e )
{
EventHandler < TaskInventoryReplyEventArgs > handler = m_TaskInventoryReply ;
if ( handler ! = null )
handler ( this , e ) ;
}
/// <summary>Thread sync lock object</summary>
private readonly object m_TaskInventoryReplyLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
/// ...</summary>
public event EventHandler < TaskInventoryReplyEventArgs > TaskInventoryReply
{
add { lock ( m_TaskInventoryReplyLock ) { m_TaskInventoryReply + = value ; } }
remove { lock ( m_TaskInventoryReplyLock ) { m_TaskInventoryReply - = value ; } }
}
2007-11-06 09:26:10 +00:00
2008-03-12 22:46:53 +00:00
/// <summary>
2009-07-18 15:55:23 +00:00
/// Reply received when uploading an inventory asset
2008-03-12 22:46:53 +00:00
/// </summary>
2009-07-15 22:11:48 +00:00
/// <param name="success">Has upload been successful</param>
/// <param name="status">Error message if upload failed</param>
/// <param name="itemID">Inventory asset UUID</param>
2009-07-18 15:55:23 +00:00
/// <param name="assetID">New asset UUID</param>
2009-07-15 22:11:48 +00:00
public delegate void InventoryUploadedAssetCallback ( bool success , string status , UUID itemID , UUID assetID ) ;
2008-03-12 22:46:53 +00:00
2011-03-30 11:56:33 +00:00
2009-10-29 09:39:43 +00:00
/// <summary>The event subscribers, null of no subscribers</summary>
private EventHandler < SaveAssetToInventoryEventArgs > m_SaveAssetToInventory ;
///<summary>Raises the SaveAssetToInventory Event</summary>
/// <param name="e">A SaveAssetToInventoryEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnSaveAssetToInventory ( SaveAssetToInventoryEventArgs e )
{
EventHandler < SaveAssetToInventoryEventArgs > handler = m_SaveAssetToInventory ;
if ( handler ! = null )
handler ( this , e ) ;
}
/// <summary>Thread sync lock object</summary>
private readonly object m_SaveAssetToInventoryLock = new object ( ) ;
/// <summary>Raised when the simulator sends us data containing
/// ...</summary>
public event EventHandler < SaveAssetToInventoryEventArgs > SaveAssetToInventory
{
add { lock ( m_SaveAssetToInventoryLock ) { m_SaveAssetToInventory + = value ; } }
remove { lock ( m_SaveAssetToInventoryLock ) { m_SaveAssetToInventory - = value ; } }
}
2009-04-23 09:54:52 +00:00
2009-05-09 02:23:39 +00:00
/// <summary>
2010-03-01 13:58:42 +00:00
/// Delegate that is invoked when script upload is completed
/// </summary>
/// <param name="uploadSuccess">Has upload succeded (note, there still might be compile errors)</param>
/// <param name="uploadStatus">Upload status message</param>
2010-03-01 15:50:42 +00:00
/// <param name="compileSuccess">Is compilation successful</param>
2010-03-01 13:58:42 +00:00
/// <param name="compileMessages">If compilation failed, list of error messages, null on compilation success</param>
/// <param name="itemID">Script inventory UUID</param>
/// <param name="assetID">Script's new asset UUID</param>
2010-03-01 15:50:42 +00:00
public delegate void ScriptUpdatedCallback ( bool uploadSuccess , string uploadStatus , bool compileSuccess , List < string > compileMessages , UUID itemID , UUID assetID ) ;
2011-03-30 11:56:33 +00:00
2009-10-29 09:39:43 +00:00
/// <summary>The event subscribers, null of no subscribers</summary>
private EventHandler < ScriptRunningReplyEventArgs > m_ScriptRunningReply ;
2009-05-13 23:53:16 +00:00
2009-10-29 09:39:43 +00:00
///<summary>Raises the ScriptRunningReply Event</summary>
/// <param name="e">A ScriptRunningReplyEventArgs object containing
/// the data sent from the simulator</param>
protected virtual void OnScriptRunningReply ( ScriptRunningReplyEventArgs e )
{
EventHandler < ScriptRunningReplyEventArgs > handler = m_ScriptRunningReply ;
if ( handler ! = null )
handler ( this , e ) ;
}
2007-09-10 10:20:30 +00:00
2009-10-29 09:39:43 +00:00
/// <summary>Thread sync lock object</summary>
private readonly object m_ScriptRunningReplyLock = new object ( ) ;
2009-04-23 09:54:52 +00:00
2009-10-29 09:39:43 +00:00
/// <summary>Raised when the simulator sends us data containing
/// ...</summary>
public event EventHandler < ScriptRunningReplyEventArgs > ScriptRunningReply
{
add { lock ( m_ScriptRunningReplyLock ) { m_ScriptRunningReply + = value ; } }
remove { lock ( m_ScriptRunningReplyLock ) { m_ScriptRunningReply - = value ; } }
}
2011-03-30 11:56:33 +00:00
#endregion Delegates
2007-12-21 02:25:36 +00:00
2007-11-06 09:26:10 +00:00
#region String Arrays
2007-07-13 14:49:36 +00:00
2007-09-10 10:20:30 +00:00
/// <summary>Partial mapping of AssetTypes to folder names</summary>
private static readonly string [ ] _NewFolderNames = new string [ ]
{
"Textures" ,
"Sounds" ,
"Calling Cards" ,
"Landmarks" ,
"Scripts" ,
"Clothing" ,
"Objects" ,
"Notecards" ,
"New Folder" ,
"Inventory" ,
"Scripts" ,
"Scripts" ,
"Uncompressed Images" ,
"Body Parts" ,
"Trash" ,
"Photo Album" ,
"Lost And Found" ,
"Uncompressed Sounds" ,
"Uncompressed Images" ,
"Uncompressed Images" ,
"Animations" ,
"Gestures"
} ;
2007-11-06 09:26:10 +00:00
#endregion String Arrays
2009-10-29 09:39:43 +00:00
private GridClient Client ;
2009-04-09 01:17:40 +00:00
private Inventory _Store ;
//private Random _RandNumbers = new Random();
private object _CallbacksLock = new object ( ) ;
private uint _CallbackPos ;
private Dictionary < uint , ItemCreatedCallback > _ItemCreatedCallbacks = new Dictionary < uint , ItemCreatedCallback > ( ) ;
2009-10-29 09:39:43 +00:00
private Dictionary < uint , ItemCopiedCallback > _ItemCopiedCallbacks = new Dictionary < uint , ItemCopiedCallback > ( ) ;
2012-12-21 01:49:36 +01:00
private Dictionary < uint , InventoryType > _ItemInventoryTypeRequest = new Dictionary < uint , InventoryType > ( ) ;
2009-04-09 01:17:40 +00:00
private List < InventorySearch > _Searches = new List < InventorySearch > ( ) ;
2007-09-10 10:20:30 +00:00
#region Properties
2008-08-21 01:19:06 +00:00
/// <summary>
/// Get this agents Inventory data
/// </summary>
public Inventory Store { get { return _Store ; } }
2007-09-10 10:20:30 +00:00
#endregion Properties
2007-11-06 09:26:10 +00:00
/// <summary>
/// Default constructor
/// </summary>
2008-08-21 01:19:06 +00:00
/// <param name="client">Reference to the GridClient object</param>
2008-07-21 21:12:59 +00:00
public InventoryManager ( GridClient client )
2007-07-13 14:49:36 +00:00
{
2009-10-29 09:39:43 +00:00
Client = client ;
2007-09-10 10:20:30 +00:00
2009-10-29 09:39:43 +00:00
Client . Network . RegisterCallback ( PacketType . UpdateCreateInventoryItem , UpdateCreateInventoryItemHandler ) ;
Client . Network . RegisterCallback ( PacketType . SaveAssetIntoInventory , SaveAssetIntoInventoryHandler ) ;
Client . Network . RegisterCallback ( PacketType . BulkUpdateInventory , BulkUpdateInventoryHandler ) ;
2011-10-23 00:42:34 +00:00
Client . Network . RegisterEventCallback ( "BulkUpdateInventory" , new Caps . EventQueueCallback ( BulkUpdateInventoryCapHandler ) ) ;
2009-10-29 09:39:43 +00:00
Client . Network . RegisterCallback ( PacketType . MoveInventoryItem , MoveInventoryItemHandler ) ;
Client . Network . RegisterCallback ( PacketType . InventoryDescendents , InventoryDescendentsHandler ) ;
Client . Network . RegisterCallback ( PacketType . FetchInventoryReply , FetchInventoryReplyHandler ) ;
Client . Network . RegisterCallback ( PacketType . ReplyTaskInventory , ReplyTaskInventoryHandler ) ;
Client . Network . RegisterEventCallback ( "ScriptRunningReply" , new Caps . EventQueueCallback ( ScriptRunningReplyMessageHandler ) ) ;
2009-05-13 23:53:16 +00:00
2009-10-16 02:53:53 +00:00
// Watch for inventory given to us through instant message
2009-10-29 09:39:43 +00:00
Client . Self . IM + = Self_IM ;
2007-12-21 02:25:36 +00:00
2008-08-01 06:38:42 +00:00
// Register extra parameters with login and parse the inventory data that comes back
2009-10-29 09:39:43 +00:00
Client . Network . RegisterLoginResponseCallback (
2008-08-21 01:19:06 +00:00
new NetworkManager . LoginResponseCallback ( Network_OnLoginResponse ) ,
new string [ ] {
"inventory-root" , "inventory-skeleton" , "inventory-lib-root" ,
"inventory-lib-owner" , "inventory-skel-lib" } ) ;
2007-11-06 09:26:10 +00:00
}
2009-10-16 02:53:53 +00:00
2009-04-06 07:48:20 +00:00
#region Fetch
2007-11-06 09:26:10 +00:00
2008-05-03 04:10:02 +00:00
/// <summary>
/// Fetch an inventory item from the dataserver
/// </summary>
2008-08-21 01:19:06 +00:00
/// <param name="itemID">The items <seealso cref="UUID"/></param>
2008-07-28 22:23:48 +00:00
/// <param name="ownerID">The item Owners <seealso cref="OpenMetaverse.UUID"/></param>
2008-08-21 01:19:06 +00:00
/// <param name="timeoutMS">a integer representing the number of milliseconds to wait for results</param>
2008-05-03 04:10:02 +00:00
/// <returns>An <seealso cref="InventoryItem"/> object on success, or null if no item was found</returns>
/// <remarks>Items will also be sent to the <seealso cref="InventoryManager.OnItemReceived"/> event</remarks>
2008-08-21 01:19:06 +00:00
public InventoryItem FetchItem ( UUID itemID , UUID ownerID , int timeoutMS )
2007-11-06 09:26:10 +00:00
{
AutoResetEvent fetchEvent = new AutoResetEvent ( false ) ;
2008-08-21 01:19:06 +00:00
InventoryItem fetchedItem = null ;
2007-11-06 09:26:10 +00:00
2009-10-29 09:39:43 +00:00
EventHandler < ItemReceivedEventArgs > callback =
delegate ( object sender , ItemReceivedEventArgs e )
2007-11-06 09:26:10 +00:00
{
2009-10-29 09:39:43 +00:00
if ( e . Item . UUID = = itemID )
2008-08-21 01:19:06 +00:00
{
2009-10-29 09:39:43 +00:00
fetchedItem = e . Item ;
2008-08-21 01:19:06 +00:00
fetchEvent . Set ( ) ;
}
2007-11-06 09:26:10 +00:00
} ;
2008-08-21 01:19:06 +00:00
2009-10-29 09:39:43 +00:00
ItemReceived + = callback ;
2008-08-21 01:19:06 +00:00
RequestFetchInventory ( itemID , ownerID ) ;
fetchEvent . WaitOne ( timeoutMS , false ) ;
2009-10-29 09:39:43 +00:00
ItemReceived - = callback ;
2008-08-21 01:19:06 +00:00
return fetchedItem ;
}
/// <summary>
/// Request A single inventory item
/// </summary>
/// <param name="itemID">The items <seealso cref="OpenMetaverse.UUID"/></param>
/// <param name="ownerID">The item Owners <seealso cref="OpenMetaverse.UUID"/></param>
/// <seealso cref="InventoryManager.OnItemReceived"/>
public void RequestFetchInventory ( UUID itemID , UUID ownerID )
{
2012-12-18 02:31:40 +01:00
RequestFetchInventory ( new List < UUID > ( 1 ) { itemID } , new List < UUID > ( 1 ) { ownerID } ) ;
2007-11-06 09:26:10 +00:00
}
2007-07-13 14:49:36 +00:00
2007-09-10 10:20:30 +00:00
/// <summary>
2007-11-06 09:26:10 +00:00
/// Request inventory items
2007-09-10 10:20:30 +00:00
/// </summary>
2007-11-06 09:26:10 +00:00
/// <param name="itemIDs">Inventory items to request</param>
2008-08-21 01:19:06 +00:00
/// <param name="ownerIDs">Owners of the inventory items</param>
2008-05-03 04:10:02 +00:00
/// <seealso cref="InventoryManager.OnItemReceived"/>
2008-08-21 01:19:06 +00:00
public void RequestFetchInventory ( List < UUID > itemIDs , List < UUID > ownerIDs )
2007-09-10 10:20:30 +00:00
{
2008-08-21 01:19:06 +00:00
if ( itemIDs . Count ! = ownerIDs . Count )
throw new ArgumentException ( "itemIDs and ownerIDs must contain the same number of entries" ) ;
2007-11-06 09:26:10 +00:00
2012-12-18 02:31:40 +01:00
if ( Client . Settings . HTTP_INVENTORY & &
Client . Network . CurrentSim . Caps ! = null & &
Client . Network . CurrentSim . Caps . CapabilityURI ( "FetchInventory2" ) ! = null )
{
RequestFetchInventoryCap ( itemIDs , ownerIDs ) ;
return ;
}
2007-09-10 10:20:30 +00:00
FetchInventoryPacket fetch = new FetchInventoryPacket ( ) ;
fetch . AgentData = new FetchInventoryPacket . AgentDataBlock ( ) ;
2009-10-29 09:39:43 +00:00
fetch . AgentData . AgentID = Client . Self . AgentID ;
fetch . AgentData . SessionID = Client . Self . SessionID ;
2007-09-10 10:20:30 +00:00
fetch . InventoryData = new FetchInventoryPacket . InventoryDataBlock [ itemIDs . Count ] ;
2008-08-21 01:19:06 +00:00
for ( int i = 0 ; i < itemIDs . Count ; i + + )
2007-07-13 14:49:36 +00:00
{
2007-09-10 10:20:30 +00:00
fetch . InventoryData [ i ] = new FetchInventoryPacket . InventoryDataBlock ( ) ;
2008-08-21 01:19:06 +00:00
fetch . InventoryData [ i ] . ItemID = itemIDs [ i ] ;
fetch . InventoryData [ i ] . OwnerID = ownerIDs [ i ] ;
2007-09-10 10:20:30 +00:00
}
2007-07-13 14:49:36 +00:00
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( fetch ) ;
2007-09-10 10:20:30 +00:00
}
2012-12-18 02:31:40 +01:00
/// <summary>
/// Request inventory items via Capabilities
/// </summary>
/// <param name="itemIDs">Inventory items to request</param>
/// <param name="ownerIDs">Owners of the inventory items</param>
/// <seealso cref="InventoryManager.OnItemReceived"/>
private void RequestFetchInventoryCap ( List < UUID > itemIDs , List < UUID > ownerIDs )
{
if ( itemIDs . Count ! = ownerIDs . Count )
throw new ArgumentException ( "itemIDs and ownerIDs must contain the same number of entries" ) ;
if ( Client . Settings . HTTP_INVENTORY & &
Client . Network . CurrentSim . Caps ! = null & &
Client . Network . CurrentSim . Caps . CapabilityURI ( "FetchInventory2" ) ! = null )
{
Uri url = Client . Network . CurrentSim . Caps . CapabilityURI ( "FetchInventory2" ) ;
CapsClient request = new CapsClient ( url ) ;
request . OnComplete + = ( client , result , error ) = >
{
if ( error = = null )
{
try
{
OSDMap res = ( OSDMap ) result ;
OSDArray itemsOSD = ( OSDArray ) res [ "items" ] ;
for ( int i = 0 ; i < itemsOSD . Count ; i + + )
{
InventoryItem item = InventoryItem . FromOSD ( itemsOSD [ i ] ) ;
_Store [ item . UUID ] = item ;
OnItemReceived ( new ItemReceivedEventArgs ( item ) ) ;
}
}
catch ( Exception ex )
{
Logger . Log ( "Failed getting data from FetchInventory2 capability." , Helpers . LogLevel . Error , Client , ex ) ;
}
}
} ;
OSDMap OSDRequest = new OSDMap ( ) ;
OSDRequest [ "agent_id" ] = Client . Self . AgentID ;
OSDArray items = new OSDArray ( itemIDs . Count ) ;
for ( int i = 0 ; i < itemIDs . Count ; i + + )
{
OSDMap item = new OSDMap ( 2 ) ;
item [ "item_id" ] = itemIDs [ i ] ;
item [ "owner_id" ] = ownerIDs [ i ] ;
items . Add ( item ) ;
}
OSDRequest [ "items" ] = items ;
request . BeginGetResponse ( OSDRequest , OSDFormat . Xml , Client . Settings . CAPS_TIMEOUT ) ;
}
}
2008-05-03 04:10:02 +00:00
/// <summary>
/// Get contents of a folder
/// </summary>
2008-07-28 22:23:48 +00:00
/// <param name="folder">The <seealso cref="UUID"/> of the folder to search</param>
/// <param name="owner">The <seealso cref="UUID"/> of the folders owner</param>
2008-05-03 04:10:02 +00:00
/// <param name="folders">true to retrieve folders</param>
/// <param name="items">true to retrieve items</param>
/// <param name="order">sort order to return results in</param>
2008-08-21 01:19:06 +00:00
/// <param name="timeoutMS">a integer representing the number of milliseconds to wait for results</param>
/// <returns>A list of inventory items matching search criteria within folder</returns>
2008-05-03 04:10:02 +00:00
/// <seealso cref="InventoryManager.RequestFolderContents"/>
2008-08-21 01:19:06 +00:00
/// <remarks>InventoryFolder.DescendentCount will only be accurate if both folders and items are
/// requested</remarks>
public List < InventoryBase > FolderContents ( UUID folder , UUID owner , bool folders , bool items ,
InventorySortOrder order , int timeoutMS )
{
List < InventoryBase > objects = null ;
AutoResetEvent fetchEvent = new AutoResetEvent ( false ) ;
2009-10-29 09:39:43 +00:00
EventHandler < FolderUpdatedEventArgs > callback =
delegate ( object sender , FolderUpdatedEventArgs e )
2007-11-06 09:26:10 +00:00
{
2009-10-29 09:39:43 +00:00
if ( e . FolderID = = folder
2008-08-21 01:19:06 +00:00
& & _Store [ folder ] is InventoryFolder )
{
// InventoryDescendentsHandler only stores DescendendCount if both folders and items are fetched.
if ( _Store . GetContents ( folder ) . Count > = ( ( InventoryFolder ) _Store [ folder ] ) . DescendentCount )
{
2009-10-29 09:39:43 +00:00
2008-08-21 01:19:06 +00:00
fetchEvent . Set ( ) ;
}
}
else
2008-05-20 03:09:31 +00:00
{
2008-08-21 01:19:06 +00:00
fetchEvent . Set ( ) ;
2008-05-20 03:09:31 +00:00
}
2008-08-21 01:19:06 +00:00
} ;
2007-11-06 09:26:10 +00:00
2009-10-29 09:39:43 +00:00
FolderUpdated + = callback ;
2007-07-13 14:49:36 +00:00
2008-08-21 01:19:06 +00:00
RequestFolderContents ( folder , owner , folders , items , order ) ;
if ( fetchEvent . WaitOne ( timeoutMS , false ) )
objects = _Store . GetContents ( folder ) ;
2009-10-29 09:39:43 +00:00
FolderUpdated - = callback ;
2008-08-21 01:19:06 +00:00
return objects ;
2008-08-12 05:55:42 +00:00
}
/// <summary>
2008-08-21 01:19:06 +00:00
/// Request the contents of an inventory folder
2008-05-03 04:10:02 +00:00
/// </summary>
/// <param name="folder">The folder to search</param>
2008-07-28 22:23:48 +00:00
/// <param name="owner">The folder owners <seealso cref="UUID"/></param>
2008-05-03 04:10:02 +00:00
/// <param name="folders">true to return <seealso cref="InventoryManager.InventoryFolder"/>s contained in folder</param>
/// <param name="items">true to return <seealso cref="InventoryManager.InventoryItem"/>s containd in folder</param>
/// <param name="order">the sort order to return items in</param>
/// <seealso cref="InventoryManager.FolderContents"/>
2009-10-29 09:39:43 +00:00
public void RequestFolderContents ( UUID folder , UUID owner , bool folders , bool items ,
2008-08-21 01:19:06 +00:00
InventorySortOrder order )
2007-09-10 10:20:30 +00:00
{
2012-12-16 19:21:23 +01:00
if ( Client . Settings . HTTP_INVENTORY & &
Client . Network . CurrentSim . Caps ! = null & &
Client . Network . CurrentSim . Caps . CapabilityURI ( "FetchInventoryDescendents2" ) ! = null )
{
RequestFolderContentsCap ( folder , owner , folders , items , order ) ;
return ;
}
2007-11-06 09:26:10 +00:00
FetchInventoryDescendentsPacket fetch = new FetchInventoryDescendentsPacket ( ) ;
2009-10-29 09:39:43 +00:00
fetch . AgentData . AgentID = Client . Self . AgentID ;
fetch . AgentData . SessionID = Client . Self . SessionID ;
2007-11-06 09:26:10 +00:00
fetch . InventoryData . FetchFolders = folders ;
fetch . InventoryData . FetchItems = items ;
fetch . InventoryData . FolderID = folder ;
fetch . InventoryData . OwnerID = owner ;
fetch . InventoryData . SortOrder = ( int ) order ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( fetch ) ;
2007-07-13 14:49:36 +00:00
}
2011-03-30 11:56:33 +00:00
/// <summary>
/// Request the contents of an inventory folder using HTTP capabilities
/// </summary>
/// <param name="folderID">The folder to search</param>
/// <param name="ownerID">The folder owners <seealso cref="UUID"/></param>
/// <param name="fetchFolders">true to return <seealso cref="InventoryManager.InventoryFolder"/>s contained in folder</param>
/// <param name="fetchItems">true to return <seealso cref="InventoryManager.InventoryItem"/>s containd in folder</param>
/// <param name="order">the sort order to return items in</param>
/// <seealso cref="InventoryManager.FolderContents"/>
public void RequestFolderContentsCap ( UUID folderID , UUID ownerID , bool fetchFolders , bool fetchItems ,
InventorySortOrder order )
{
Uri url = null ;
2013-06-15 23:11:12 +02:00
string cap = ownerID = = Client . Self . AgentID ? "FetchInventoryDescendents2" : "FetchLibDescendents2" ;
2011-03-30 11:56:33 +00:00
if ( Client . Network . CurrentSim . Caps = = null | |
2013-06-15 23:11:12 +02:00
null = = ( url = Client . Network . CurrentSim . Caps . CapabilityURI ( cap ) ) )
2011-03-30 11:56:33 +00:00
{
2013-06-15 23:11:12 +02:00
Logger . Log ( cap + " capability not available in the current sim" , Helpers . LogLevel . Warning , Client ) ;
2011-03-31 02:53:13 +00:00
OnFolderUpdated ( new FolderUpdatedEventArgs ( folderID , false ) ) ;
2011-03-30 11:56:33 +00:00
return ;
}
try
{
CapsClient request = new CapsClient ( url ) ;
request . OnComplete + = ( client , result , error ) = >
{
try
{
2013-03-30 15:31:00 +01:00
if ( error ! = null )
{
throw error ;
}
2011-03-30 11:56:33 +00:00
OSDArray fetchedFolders = ( OSDArray ) ( ( OSDMap ) result ) [ "folders" ] ;
for ( int fetchedFolderNr = 0 ; fetchedFolderNr < fetchedFolders . Count ; fetchedFolderNr + + )
{
OSDMap res = ( OSDMap ) fetchedFolders [ fetchedFolderNr ] ;
InventoryFolder fetchedFolder = null ;
if ( _Store . Contains ( res [ "folder_id" ] )
& & _Store [ res [ "folder_id" ] ] is InventoryFolder )
{
fetchedFolder = ( InventoryFolder ) _Store [ res [ "folder_id" ] ] ;
}
else
{
fetchedFolder = new InventoryFolder ( res [ "folder_id" ] ) ;
_Store [ res [ "folder_id" ] ] = fetchedFolder ;
}
fetchedFolder . DescendentCount = res [ "descendents" ] ;
fetchedFolder . Version = res [ "version" ] ;
fetchedFolder . OwnerID = res [ "owner_id" ] ;
_Store . GetNodeFor ( fetchedFolder . UUID ) . NeedsUpdate = false ;
// Do we have any descendants
if ( fetchedFolder . DescendentCount > 0 )
{
// Fetch descendent folders
if ( res [ "categories" ] is OSDArray )
{
OSDArray folders = ( OSDArray ) res [ "categories" ] ;
for ( int i = 0 ; i < folders . Count ; i + + )
{
OSDMap descFolder = ( OSDMap ) folders [ i ] ;
InventoryFolder folder ;
if ( ! _Store . Contains ( descFolder [ "category_id" ] ) )
{
folder = new InventoryFolder ( descFolder [ "category_id" ] ) ;
folder . ParentUUID = descFolder [ "parent_id" ] ;
_Store [ descFolder [ "category_id" ] ] = folder ;
}
else
{
folder = ( InventoryFolder ) _Store [ descFolder [ "category_id" ] ] ;
}
folder . OwnerID = descFolder [ "agent_id" ] ;
folder . ParentUUID = descFolder [ "parent_id" ] ;
folder . Name = descFolder [ "name" ] ;
folder . Version = descFolder [ "version" ] ;
folder . PreferredType = ( AssetType ) ( int ) descFolder [ "type_default" ] ;
}
// Fetch descendent items
OSDArray items = ( OSDArray ) res [ "items" ] ;
for ( int i = 0 ; i < items . Count ; i + + )
{
2012-12-18 02:31:40 +01:00
InventoryItem item = InventoryItem . FromOSD ( items [ i ] ) ;
_Store [ item . UUID ] = item ;
2011-03-30 11:56:33 +00:00
}
}
}
2011-03-31 02:53:13 +00:00
OnFolderUpdated ( new FolderUpdatedEventArgs ( res [ "folder_id" ] , true ) ) ;
2011-03-30 11:56:33 +00:00
}
}
catch ( Exception exc )
{
2011-04-09 10:48:34 +00:00
Logger . Log ( string . Format ( "Failed to fetch inventory descendants for folder id {0}: {1}\n{2}" , folderID , exc . Message , exc . StackTrace . ToString ( ) ) , Helpers . LogLevel . Warning , Client ) ;
2011-03-31 02:53:13 +00:00
OnFolderUpdated ( new FolderUpdatedEventArgs ( folderID , false ) ) ;
2011-03-30 11:56:33 +00:00
return ;
}
} ;
// Construct request
OSDMap requestedFolder = new OSDMap ( 1 ) ;
requestedFolder [ "folder_id" ] = folderID ;
requestedFolder [ "owner_id" ] = ownerID ;
requestedFolder [ "fetch_folders" ] = fetchFolders ;
requestedFolder [ "fetch_items" ] = fetchItems ;
requestedFolder [ "sort_order" ] = ( int ) order ;
OSDArray requestedFolders = new OSDArray ( 1 ) ;
requestedFolders . Add ( requestedFolder ) ;
OSDMap req = new OSDMap ( 1 ) ;
req [ "folders" ] = requestedFolders ;
request . BeginGetResponse ( req , OSDFormat . Xml , Client . Settings . CAPS_TIMEOUT ) ;
}
catch ( Exception ex )
{
2011-04-09 10:48:34 +00:00
Logger . Log ( string . Format ( "Failed to fetch inventory descendants for folder id {0}: {1}\n{2}" , folderID , ex . Message , ex . StackTrace . ToString ( ) ) , Helpers . LogLevel . Warning , Client ) ;
2011-03-31 02:53:13 +00:00
OnFolderUpdated ( new FolderUpdatedEventArgs ( folderID , false ) ) ;
2011-03-30 11:56:33 +00:00
return ;
}
}
2007-11-06 09:26:10 +00:00
#endregion Fetch
#region Find
2007-09-10 10:20:30 +00:00
/// <summary>
2007-11-06 09:26:10 +00:00
/// Returns the UUID of the folder (category) that defaults to
/// containing 'type'. The folder is not necessarily only for that
/// type
2007-09-10 10:20:30 +00:00
/// </summary>
2007-11-06 09:26:10 +00:00
/// <remarks>This will return the root folder if one does not exist</remarks>
/// <param name="type"></param>
/// <returns>The UUID of the desired folder if found, the UUID of the RootFolder
2008-07-28 22:23:48 +00:00
/// if not found, or UUID.Zero on failure</returns>
2008-07-25 05:15:05 +00:00
public UUID FindFolderForType ( AssetType type )
2007-08-25 09:36:33 +00:00
{
2008-08-21 01:19:06 +00:00
if ( _Store = = null )
2007-08-25 09:36:33 +00:00
{
2008-08-21 01:19:06 +00:00
Logger . Log ( "Inventory is null, FindFolderForType() lookup cannot continue" ,
2009-10-29 09:39:43 +00:00
Helpers . LogLevel . Error , Client ) ;
2008-07-25 05:15:05 +00:00
return UUID . Zero ;
2007-09-10 10:20:30 +00:00
}
2007-11-06 09:26:10 +00:00
// Folders go in the root
if ( type = = AssetType . Folder )
2008-08-21 01:19:06 +00:00
return _Store . RootFolder . UUID ;
2007-09-10 10:20:30 +00:00
2007-11-06 09:26:10 +00:00
// Loop through each top-level directory and check if PreferredType
// matches the requested type
2008-08-21 01:19:06 +00:00
List < InventoryBase > contents = _Store . GetContents ( _Store . RootFolder . UUID ) ;
foreach ( InventoryBase inv in contents )
2007-09-10 10:20:30 +00:00
{
2008-08-21 01:19:06 +00:00
if ( inv is InventoryFolder )
{
InventoryFolder folder = inv as InventoryFolder ;
if ( folder . PreferredType = = type )
return folder . UUID ;
}
2007-08-25 09:36:33 +00:00
}
2007-11-06 09:26:10 +00:00
// No match found, return Root Folder ID
2008-08-21 01:19:06 +00:00
return _Store . RootFolder . UUID ;
2007-08-25 09:36:33 +00:00
}
2008-05-03 04:10:02 +00:00
/// <summary>
/// Find an object in inventory using a specific path to search
/// </summary>
/// <param name="baseFolder">The folder to begin the search in</param>
2008-07-28 22:23:48 +00:00
/// <param name="inventoryOwner">The object owners <seealso cref="UUID"/></param>
2008-05-03 04:10:02 +00:00
/// <param name="path">A string path to search</param>
2008-08-21 01:19:06 +00:00
/// <param name="timeoutMS">milliseconds to wait for a reply</param>
2008-07-28 22:23:48 +00:00
/// <returns>Found items <seealso cref="UUID"/> or <seealso cref="UUID.Zero"/> if
2008-05-03 04:10:02 +00:00
/// timeout occurs or item is not found</returns>
2008-08-21 01:19:06 +00:00
public UUID FindObjectByPath ( UUID baseFolder , UUID inventoryOwner , string path , int timeoutMS )
2007-11-06 09:26:10 +00:00
{
AutoResetEvent findEvent = new AutoResetEvent ( false ) ;
2008-07-25 05:15:05 +00:00
UUID foundItem = UUID . Zero ;
2007-11-06 09:26:10 +00:00
2009-10-29 09:39:43 +00:00
EventHandler < FindObjectByPathReplyEventArgs > callback =
delegate ( object sender , FindObjectByPathReplyEventArgs e )
2007-11-06 09:26:10 +00:00
{
2009-10-29 09:39:43 +00:00
if ( e . Path = = path )
2007-11-06 09:26:10 +00:00
{
2009-10-29 09:39:43 +00:00
foundItem = e . InventoryObjectID ;
2007-11-06 09:26:10 +00:00
findEvent . Set ( ) ;
}
} ;
2007-09-10 10:20:30 +00:00
2009-10-29 09:39:43 +00:00
FindObjectByPathReply + = callback ;
2008-08-21 01:19:06 +00:00
RequestFindObjectByPath ( baseFolder , inventoryOwner , path ) ;
findEvent . WaitOne ( timeoutMS , false ) ;
2009-10-29 09:39:43 +00:00
FindObjectByPathReply - = callback ;
2007-11-06 09:26:10 +00:00
return foundItem ;
2007-07-13 14:49:36 +00:00
}
2008-05-03 04:10:02 +00:00
/// <summary>
/// Find inventory items by path
/// </summary>
/// <param name="baseFolder">The folder to begin the search in</param>
2008-07-28 22:23:48 +00:00
/// <param name="inventoryOwner">The object owners <seealso cref="UUID"/></param>
2008-05-03 04:10:02 +00:00
/// <param name="path">A string path to search, folders/objects separated by a '/'</param>
2008-08-21 01:19:06 +00:00
/// <remarks>Results are sent to the <seealso cref="InventoryManager.OnFindObjectByPath"/> event</remarks>
public void RequestFindObjectByPath ( UUID baseFolder , UUID inventoryOwner , string path )
2007-07-14 00:27:23 +00:00
{
2007-11-06 09:26:10 +00:00
if ( path = = null | | path . Length = = 0 )
throw new ArgumentException ( "Empty path is not supported" ) ;
2008-08-21 01:19:06 +00:00
// Store this search
InventorySearch search ;
search . Folder = baseFolder ;
search . Owner = inventoryOwner ;
search . Path = path . Split ( '/' ) ;
search . Level = 0 ;
lock ( _Searches ) _Searches . Add ( search ) ;
2007-11-06 09:26:10 +00:00
// Start the search
2008-08-21 01:19:06 +00:00
RequestFolderContents ( baseFolder , inventoryOwner , true , true , InventorySortOrder . ByName ) ;
2007-07-14 00:27:23 +00:00
}
2008-05-03 04:10:02 +00:00
/// <summary>
2008-08-21 01:19:06 +00:00
/// Search inventory Store object for an item or folder
2008-05-03 04:10:02 +00:00
/// </summary>
2008-08-21 01:19:06 +00:00
/// <param name="baseFolder">The folder to begin the search in</param>
/// <param name="path">An array which creates a path to search</param>
/// <param name="level">Number of levels below baseFolder to conduct searches</param>
/// <param name="firstOnly">if True, will stop searching after first match is found</param>
/// <returns>A list of inventory items found</returns>
public List < InventoryBase > LocalFind ( UUID baseFolder , string [ ] path , int level , bool firstOnly )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
List < InventoryBase > objects = new List < InventoryBase > ( ) ;
//List<InventoryFolder> folders = new List<InventoryFolder>();
List < InventoryBase > contents = _Store . GetContents ( baseFolder ) ;
foreach ( InventoryBase inv in contents )
{
if ( inv . Name . CompareTo ( path [ level ] ) = = 0 )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
if ( level = = path . Length - 1 )
2007-11-06 09:26:10 +00:00
{
2008-08-21 01:19:06 +00:00
objects . Add ( inv ) ;
if ( firstOnly ) return objects ;
2007-11-06 09:26:10 +00:00
}
2008-08-21 01:19:06 +00:00
else if ( inv is InventoryFolder )
objects . AddRange ( LocalFind ( inv . UUID , path , level + 1 , firstOnly ) ) ;
}
}
2007-11-06 09:26:10 +00:00
2008-08-21 01:19:06 +00:00
return objects ;
2007-07-13 14:49:36 +00:00
}
2007-11-06 09:26:10 +00:00
#endregion Find
2008-04-03 10:03:30 +00:00
#region Move / Rename
2009-10-29 09:39:43 +00:00
2008-08-21 01:19:06 +00:00
/// <summary>
/// Move an inventory item or folder to a new location
/// </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>
public void Move ( InventoryBase item , InventoryFolder newParent )
{
if ( item is InventoryFolder )
MoveFolder ( item . UUID , newParent . UUID ) ;
else
MoveItem ( item . UUID , newParent . UUID ) ;
}
2007-07-13 14:49:36 +00:00
2008-08-21 01:19:06 +00:00
/// <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 ) ;
}
2008-04-03 10:03:30 +00:00
2008-05-03 04:10:02 +00:00
/// <summary>
2008-08-21 01:19:06 +00:00
/// Move and rename a folder
2008-05-03 04:10:02 +00:00
/// </summary>
2008-08-21 01:19:06 +00:00
/// <param name="folderID">The source folders <seealso cref="UUID"/></param>
/// <param name="newparentID">The destination folders <seealso cref="UUID"/></param>
/// <param name="newName">The name to change the folder to</param>
public void MoveFolder ( UUID folderID , UUID newparentID , string newName )
2010-02-26 10:43:20 +00:00
{
UpdateFolderProperties ( folderID , newparentID , newName , AssetType . Unknown ) ;
}
/// <summary>
/// Update folder properties
/// </summary>
/// <param name="folderID"><seealso cref="UUID"/> of the folder to update</param>
/// <param name="parentID">Sets folder's parent to <seealso cref="UUID"/></param>
/// <param name="name">Folder name</param>
/// <param name="type">Folder type</param>
public void UpdateFolderProperties ( UUID folderID , UUID parentID , string name , AssetType type )
2008-04-03 10:03:30 +00:00
{
2008-08-21 01:19:06 +00:00
lock ( Store )
{
if ( _Store . Contains ( folderID ) )
{
2010-02-26 10:43:20 +00:00
InventoryFolder inv = ( InventoryFolder ) Store [ folderID ] ;
inv . Name = name ;
inv . ParentUUID = parentID ;
inv . PreferredType = type ;
2008-08-21 01:19:06 +00:00
_Store . UpdateNodeFor ( inv ) ;
}
}
2010-02-26 10:43:20 +00:00
UpdateInventoryFolderPacket invFolder = new UpdateInventoryFolderPacket ( ) ;
invFolder . AgentData . AgentID = Client . Self . AgentID ;
invFolder . AgentData . SessionID = Client . Self . SessionID ;
invFolder . FolderData = new UpdateInventoryFolderPacket . FolderDataBlock [ 1 ] ;
invFolder . FolderData [ 0 ] = new UpdateInventoryFolderPacket . FolderDataBlock ( ) ;
invFolder . FolderData [ 0 ] . FolderID = folderID ;
invFolder . FolderData [ 0 ] . ParentID = parentID ;
invFolder . FolderData [ 0 ] . Name = Utils . StringToBytes ( name ) ;
invFolder . FolderData [ 0 ] . Type = ( sbyte ) type ;
Client . Network . SendPacket ( invFolder ) ;
2008-04-03 10:03:30 +00:00
}
2008-05-03 04:10:02 +00:00
/// <summary>
/// Move a folder
/// </summary>
2008-08-21 01:19:06 +00:00
/// <param name="folderID">The source folders <seealso cref="UUID"/></param>
/// <param name="newParentID">The destination folders <seealso cref="UUID"/></param>
2008-07-25 05:15:05 +00:00
public void MoveFolder ( UUID folderID , UUID newParentID )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
lock ( Store )
{
if ( _Store . Contains ( folderID ) )
{
InventoryBase inv = Store [ folderID ] ;
inv . ParentUUID = newParentID ;
_Store . UpdateNodeFor ( inv ) ;
}
}
MoveInventoryFolderPacket move = new MoveInventoryFolderPacket ( ) ;
2009-10-29 09:39:43 +00:00
move . AgentData . AgentID = Client . Self . AgentID ;
move . AgentData . SessionID = Client . Self . SessionID ;
2008-08-21 01:19:06 +00:00
move . AgentData . Stamp = false ; //FIXME: ??
2007-08-25 09:36:33 +00:00
2008-08-21 01:19:06 +00:00
move . InventoryData = new MoveInventoryFolderPacket . InventoryDataBlock [ 1 ] ;
move . InventoryData [ 0 ] = new MoveInventoryFolderPacket . InventoryDataBlock ( ) ;
move . InventoryData [ 0 ] . FolderID = folderID ;
move . InventoryData [ 0 ] . ParentID = newParentID ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( move ) ;
2008-08-21 01:19:06 +00:00
}
2009-10-29 09:39:43 +00:00
2008-07-29 21:36:53 +00:00
/// <summary>
2008-08-21 01:19:06 +00:00
/// Move multiple folders, the keys in the Dictionary parameter,
/// to a new parents, the value of that folder's key.
2008-07-29 21:36:53 +00:00
/// </summary>
2008-08-21 01:19:06 +00:00
/// <param name="foldersNewParents">A Dictionary containing the
/// <seealso cref="UUID"/> of the source as the key, and the
/// <seealso cref="UUID"/> of the destination as the value</param>
public void MoveFolders ( Dictionary < UUID , UUID > foldersNewParents )
2008-07-29 21:36:53 +00:00
{
2008-08-21 01:19:06 +00:00
// FIXME: Use two List<UUID> to stay consistent
lock ( Store )
{
foreach ( KeyValuePair < UUID , UUID > entry in foldersNewParents )
{
if ( _Store . Contains ( entry . Key ) )
{
InventoryBase inv = _Store [ entry . Key ] ;
inv . ParentUUID = entry . Value ;
_Store . UpdateNodeFor ( inv ) ;
}
}
}
2007-11-06 09:26:10 +00:00
//TODO: Test if this truly supports multiple-folder move
MoveInventoryFolderPacket move = new MoveInventoryFolderPacket ( ) ;
2009-10-29 09:39:43 +00:00
move . AgentData . AgentID = Client . Self . AgentID ;
move . AgentData . SessionID = Client . Self . SessionID ;
2007-11-06 09:26:10 +00:00
move . AgentData . Stamp = false ; //FIXME: ??
2007-08-25 09:36:33 +00:00
2008-08-21 01:19:06 +00:00
move . InventoryData = new MoveInventoryFolderPacket . InventoryDataBlock [ foldersNewParents . Count ] ;
2007-11-06 09:26:10 +00:00
2008-08-21 01:19:06 +00:00
int index = 0 ;
foreach ( KeyValuePair < UUID , UUID > folder in foldersNewParents )
2007-08-25 09:36:33 +00:00
{
2007-11-06 09:26:10 +00:00
MoveInventoryFolderPacket . InventoryDataBlock block = new MoveInventoryFolderPacket . InventoryDataBlock ( ) ;
2008-08-21 01:19:06 +00:00
block . FolderID = folder . Key ;
block . ParentID = folder . Value ;
move . InventoryData [ index + + ] = block ;
2007-08-25 09:36:33 +00:00
}
2007-11-06 09:26:10 +00:00
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( move ) ;
2008-08-21 01:19:06 +00:00
}
/// <summary>
/// Move an inventory item to a new folder
/// </summary>
/// <param name="itemID">The <seealso cref="UUID"/> of the source item to move</param>
/// <param name="folderID">The <seealso cref="UUID"/> of the destination folder</param>
public void MoveItem ( UUID itemID , UUID folderID )
{
MoveItem ( itemID , folderID , String . Empty ) ;
2007-08-25 09:36:33 +00:00
}
2007-11-06 09:26:10 +00:00
2008-05-03 04:10:02 +00:00
/// <summary>
2008-08-21 01:19:06 +00:00
/// Move and rename an inventory item
2008-05-03 04:10:02 +00:00
/// </summary>
2008-07-28 22:23:48 +00:00
/// <param name="itemID">The <seealso cref="UUID"/> of the source item to move</param>
2008-08-21 01:19:06 +00:00
/// <param name="folderID">The <seealso cref="UUID"/> of the destination folder</param>
2008-05-03 04:10:02 +00:00
/// <param name="newName">The name to change the folder to</param>
2008-08-21 01:19:06 +00:00
public void MoveItem ( UUID itemID , UUID folderID , string newName )
2007-08-25 09:36:33 +00:00
{
2008-08-21 01:19:06 +00:00
lock ( _Store )
{
2009-10-29 09:39:43 +00:00
if ( _Store . Contains ( itemID ) )
{
InventoryBase inv = _Store [ itemID ] ;
inv . Name = newName ;
inv . ParentUUID = folderID ;
_Store . UpdateNodeFor ( inv ) ;
}
2008-08-21 01:19:06 +00:00
}
2007-11-06 09:26:10 +00:00
MoveInventoryItemPacket move = new MoveInventoryItemPacket ( ) ;
2009-10-29 09:39:43 +00:00
move . AgentData . AgentID = Client . Self . AgentID ;
move . AgentData . SessionID = Client . Self . SessionID ;
2007-11-06 09:26:10 +00:00
move . AgentData . Stamp = false ; //FIXME: ??
2007-08-25 09:36:33 +00:00
2007-11-06 09:26:10 +00:00
move . InventoryData = new MoveInventoryItemPacket . InventoryDataBlock [ 1 ] ;
move . InventoryData [ 0 ] = new MoveInventoryItemPacket . InventoryDataBlock ( ) ;
2008-05-03 04:10:02 +00:00
move . InventoryData [ 0 ] . ItemID = itemID ;
2008-08-21 01:19:06 +00:00
move . InventoryData [ 0 ] . FolderID = folderID ;
2008-08-12 22:38:02 +00:00
move . InventoryData [ 0 ] . NewName = Utils . StringToBytes ( newName ) ;
2007-08-25 09:36:33 +00:00
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( move ) ;
2007-11-06 09:26:10 +00:00
}
2007-08-25 09:36:33 +00:00
2008-05-03 04:10:02 +00:00
/// <summary>
2008-08-21 01:19:06 +00:00
/// Move multiple inventory items to new locations
2008-05-03 04:10:02 +00:00
/// </summary>
2008-08-21 01:19:06 +00:00
/// <param name="itemsNewParents">A Dictionary containing the
/// <seealso cref="UUID"/> of the source item as the key, and the
/// <seealso cref="UUID"/> of the destination folder as the value</param>
public void MoveItems ( Dictionary < UUID , UUID > itemsNewParents )
2007-11-06 09:26:10 +00:00
{
2008-08-21 01:19:06 +00:00
lock ( _Store )
{
foreach ( KeyValuePair < UUID , UUID > entry in itemsNewParents )
{
if ( _Store . Contains ( entry . Key ) )
{
InventoryBase inv = _Store [ entry . Key ] ;
inv . ParentUUID = entry . Value ;
_Store . UpdateNodeFor ( inv ) ;
}
}
}
2007-08-25 09:36:33 +00:00
2007-11-06 09:26:10 +00:00
MoveInventoryItemPacket move = new MoveInventoryItemPacket ( ) ;
2009-10-29 09:39:43 +00:00
move . AgentData . AgentID = Client . Self . AgentID ;
move . AgentData . SessionID = Client . Self . SessionID ;
2007-11-06 09:26:10 +00:00
move . AgentData . Stamp = false ; //FIXME: ??
2008-08-21 01:19:06 +00:00
move . InventoryData = new MoveInventoryItemPacket . InventoryDataBlock [ itemsNewParents . Count ] ;
2007-11-06 09:26:10 +00:00
2008-08-21 01:19:06 +00:00
int index = 0 ;
foreach ( KeyValuePair < UUID , UUID > entry in itemsNewParents )
2007-11-06 09:26:10 +00:00
{
MoveInventoryItemPacket . InventoryDataBlock block = new MoveInventoryItemPacket . InventoryDataBlock ( ) ;
2008-08-21 01:19:06 +00:00
block . ItemID = entry . Key ;
block . FolderID = entry . Value ;
2009-03-06 01:32:02 +00:00
block . NewName = Utils . EmptyBytes ;
2008-08-21 01:19:06 +00:00
move . InventoryData [ index + + ] = block ;
2007-11-06 09:26:10 +00:00
}
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( move ) ;
2007-08-25 09:36:33 +00:00
}
2007-11-06 09:26:10 +00:00
#endregion Move
#region Remove
2008-05-03 04:10:02 +00:00
/// <summary>
/// Remove descendants of a folder
/// </summary>
2008-07-28 22:23:48 +00:00
/// <param name="folder">The <seealso cref="UUID"/> of the folder</param>
2008-07-25 05:15:05 +00:00
public void RemoveDescendants ( UUID folder )
2007-08-25 09:36:33 +00:00
{
2007-11-06 09:26:10 +00:00
PurgeInventoryDescendentsPacket purge = new PurgeInventoryDescendentsPacket ( ) ;
2009-10-29 09:39:43 +00:00
purge . AgentData . AgentID = Client . Self . AgentID ;
purge . AgentData . SessionID = Client . Self . SessionID ;
2007-11-06 09:26:10 +00:00
purge . InventoryData . FolderID = folder ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( purge ) ;
2008-08-21 01:19:06 +00:00
// Update our local copy
lock ( _Store )
{
if ( _Store . Contains ( folder ) )
{
List < InventoryBase > contents = _Store . GetContents ( folder ) ;
foreach ( InventoryBase obj in contents )
{
_Store . RemoveNodeFor ( obj ) ;
}
}
}
2007-08-25 09:36:33 +00:00
}
2008-05-03 04:10:02 +00:00
/// <summary>
/// Remove a single item from inventory
/// </summary>
2008-07-28 22:23:48 +00:00
/// <param name="item">The <seealso cref="UUID"/> of the inventory item to remove</param>
2008-07-25 05:15:05 +00:00
public void RemoveItem ( UUID item )
2007-11-06 09:26:10 +00:00
{
2008-07-25 05:15:05 +00:00
List < UUID > items = new List < UUID > ( 1 ) ;
2007-11-06 09:26:10 +00:00
items . Add ( item ) ;
2007-07-13 14:49:36 +00:00
2007-11-06 09:26:10 +00:00
Remove ( items , null ) ;
}
2007-07-13 14:49:36 +00:00
2008-05-03 04:10:02 +00:00
/// <summary>
/// Remove a folder from inventory
/// </summary>
2008-07-28 22:23:48 +00:00
/// <param name="folder">The <seealso cref="UUID"/> of the folder to remove</param>
2008-07-25 05:15:05 +00:00
public void RemoveFolder ( UUID folder )
2007-07-13 14:49:36 +00:00
{
2008-07-25 05:15:05 +00:00
List < UUID > folders = new List < UUID > ( 1 ) ;
2007-11-06 09:26:10 +00:00
folders . Add ( folder ) ;
Remove ( null , folders ) ;
2007-07-14 00:27:23 +00:00
}
2008-05-03 04:10:02 +00:00
/// <summary>
/// Remove multiple items or folders from inventory
/// </summary>
2008-07-28 22:23:48 +00:00
/// <param name="items">A List containing the <seealso cref="UUID"/>s of items to remove</param>
/// <param name="folders">A List containing the <seealso cref="UUID"/>s of the folders to remove</param>
2008-08-21 01:19:06 +00:00
public void Remove ( List < UUID > items , List < UUID > folders )
2007-07-14 00:27:23 +00:00
{
2007-11-06 09:26:10 +00:00
if ( ( items = = null | | items . Count = = 0 ) & & ( folders = = null | | folders . Count = = 0 ) )
return ;
2007-07-13 14:49:36 +00:00
2007-11-06 09:26:10 +00:00
RemoveInventoryObjectsPacket rem = new RemoveInventoryObjectsPacket ( ) ;
2009-10-29 09:39:43 +00:00
rem . AgentData . AgentID = Client . Self . AgentID ;
rem . AgentData . SessionID = Client . Self . SessionID ;
2007-11-06 09:26:10 +00:00
if ( items = = null | | items . Count = = 0 )
2007-07-13 14:49:36 +00:00
{
2007-11-06 09:26:10 +00:00
// To indicate that we want no items removed:
rem . ItemData = new RemoveInventoryObjectsPacket . ItemDataBlock [ 1 ] ;
rem . ItemData [ 0 ] = new RemoveInventoryObjectsPacket . ItemDataBlock ( ) ;
2008-07-25 05:15:05 +00:00
rem . ItemData [ 0 ] . ItemID = UUID . Zero ;
2007-07-13 14:49:36 +00:00
}
2007-11-06 09:26:10 +00:00
else
{
2008-08-21 01:19:06 +00:00
lock ( _Store )
2007-11-06 09:26:10 +00:00
{
2008-08-21 01:19:06 +00:00
rem . ItemData = new RemoveInventoryObjectsPacket . ItemDataBlock [ items . Count ] ;
for ( int i = 0 ; i < items . Count ; i + + )
{
rem . ItemData [ i ] = new RemoveInventoryObjectsPacket . ItemDataBlock ( ) ;
rem . ItemData [ i ] . ItemID = items [ i ] ;
// Update local copy
if ( _Store . Contains ( items [ i ] ) )
_Store . RemoveNodeFor ( Store [ items [ i ] ] ) ;
}
2007-11-06 09:26:10 +00:00
}
}
2007-07-13 14:49:36 +00:00
2007-11-06 09:26:10 +00:00
if ( folders = = null | | folders . Count = = 0 )
2007-07-13 14:49:36 +00:00
{
2007-11-06 09:26:10 +00:00
// To indicate we want no folders removed:
rem . FolderData = new RemoveInventoryObjectsPacket . FolderDataBlock [ 1 ] ;
rem . FolderData [ 0 ] = new RemoveInventoryObjectsPacket . FolderDataBlock ( ) ;
2008-07-25 05:15:05 +00:00
rem . FolderData [ 0 ] . FolderID = UUID . Zero ;
2007-11-06 09:26:10 +00:00
}
else
{
2008-08-21 01:19:06 +00:00
lock ( _Store )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
rem . FolderData = new RemoveInventoryObjectsPacket . FolderDataBlock [ folders . Count ] ;
for ( int i = 0 ; i < folders . Count ; i + + )
{
rem . FolderData [ i ] = new RemoveInventoryObjectsPacket . FolderDataBlock ( ) ;
rem . FolderData [ i ] . FolderID = folders [ i ] ;
// Update local copy
if ( _Store . Contains ( folders [ i ] ) )
_Store . RemoveNodeFor ( Store [ folders [ i ] ] ) ;
}
2007-11-06 09:26:10 +00:00
}
}
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( rem ) ;
2007-11-06 09:26:10 +00:00
}
2009-10-29 09:39:43 +00:00
2008-05-03 04:10:02 +00:00
/// <summary>
/// Empty the Lost and Found folder
/// </summary>
2007-11-06 09:26:10 +00:00
public void EmptyLostAndFound ( )
{
EmptySystemFolder ( AssetType . LostAndFoundFolder ) ;
}
2008-05-03 04:10:02 +00:00
/// <summary>
/// Empty the Trash folder
/// </summary>
2007-11-06 09:26:10 +00:00
public void EmptyTrash ( )
{
EmptySystemFolder ( AssetType . TrashFolder ) ;
}
2008-05-03 04:10:02 +00:00
2007-11-06 09:26:10 +00:00
private void EmptySystemFolder ( AssetType folderType )
{
2008-08-21 01:19:06 +00:00
List < InventoryBase > items = _Store . GetContents ( _Store . RootFolder ) ;
UUID folderKey = UUID . Zero ;
foreach ( InventoryBase item in items )
{
if ( ( item as InventoryFolder ) ! = null )
{
InventoryFolder folder = item as InventoryFolder ;
if ( folder . PreferredType = = folderType )
{
folderKey = folder . UUID ;
break ;
}
}
}
items = _Store . GetContents ( folderKey ) ;
List < UUID > remItems = new List < UUID > ( ) ;
List < UUID > remFolders = new List < UUID > ( ) ;
foreach ( InventoryBase item in items )
{
if ( ( item as InventoryFolder ) ! = null )
{
remFolders . Add ( item . UUID ) ;
}
else
{
remItems . Add ( item . UUID ) ;
}
}
Remove ( remItems , remFolders ) ;
2009-10-29 09:39:43 +00:00
}
2007-11-06 09:26:10 +00:00
#endregion Remove
#region Create
2009-10-29 09:39:43 +00:00
2008-07-29 21:36:53 +00:00
/// <summary>
2008-08-21 01:19:06 +00:00
///
2008-02-28 21:48:39 +00:00
/// </summary>
2008-09-12 00:32:05 +00:00
/// <param name="parentFolder"></param>
/// <param name="name"></param>
/// <param name="description"></param>
/// <param name="type"></param>
2008-02-28 21:48:39 +00:00
/// <param name="assetTransactionID">Proper use is to upload the inventory's asset first, then provide the Asset's TransactionID here.</param>
2008-09-12 00:32:05 +00:00
/// <param name="invType"></param>
/// <param name="nextOwnerMask"></param>
/// <param name="callback"></param>
2008-07-25 05:15:05 +00:00
public void RequestCreateItem ( UUID parentFolder , string name , string description , AssetType type , UUID assetTransactionID ,
2008-02-28 21:48:39 +00:00
InventoryType invType , PermissionMask nextOwnerMask , ItemCreatedCallback callback )
{
// Even though WearableType 0 is Shape, in this context it is treated as NOT_WEARABLE
2009-10-29 09:39:43 +00:00
RequestCreateItem ( parentFolder , name , description , type , assetTransactionID , invType , ( WearableType ) 0 , nextOwnerMask ,
2008-02-28 21:48:39 +00:00
callback ) ;
}
/// <summary>
2008-08-21 01:19:06 +00:00
///
2008-02-28 21:48:39 +00:00
/// </summary>
2008-09-12 00:32:05 +00:00
/// <param name="parentFolder"></param>
/// <param name="name"></param>
/// <param name="description"></param>
/// <param name="type"></param>
2008-02-28 21:48:39 +00:00
/// <param name="assetTransactionID">Proper use is to upload the inventory's asset first, then provide the Asset's TransactionID here.</param>
2008-09-12 00:32:05 +00:00
/// <param name="invType"></param>
/// <param name="wearableType"></param>
/// <param name="nextOwnerMask"></param>
/// <param name="callback"></param>
2008-07-25 05:15:05 +00:00
public void RequestCreateItem ( UUID parentFolder , string name , string description , AssetType type , UUID assetTransactionID ,
2008-02-28 21:48:39 +00:00
InventoryType invType , WearableType wearableType , PermissionMask nextOwnerMask , ItemCreatedCallback callback )
2007-11-06 09:26:10 +00:00
{
CreateInventoryItemPacket create = new CreateInventoryItemPacket ( ) ;
2009-10-29 09:39:43 +00:00
create . AgentData . AgentID = Client . Self . AgentID ;
create . AgentData . SessionID = Client . Self . SessionID ;
2007-11-06 09:26:10 +00:00
create . InventoryBlock . CallbackID = RegisterItemCreatedCallback ( callback ) ;
create . InventoryBlock . FolderID = parentFolder ;
2008-02-28 21:48:39 +00:00
create . InventoryBlock . TransactionID = assetTransactionID ;
2007-11-06 09:26:10 +00:00
create . InventoryBlock . NextOwnerMask = ( uint ) nextOwnerMask ;
create . InventoryBlock . Type = ( sbyte ) type ;
create . InventoryBlock . InvType = ( sbyte ) invType ;
create . InventoryBlock . WearableType = ( byte ) wearableType ;
2008-08-12 22:38:02 +00:00
create . InventoryBlock . Name = Utils . StringToBytes ( name ) ;
create . InventoryBlock . Description = Utils . StringToBytes ( description ) ;
2007-07-13 14:49:36 +00:00
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( create ) ;
2007-07-13 14:49:36 +00:00
}
2007-12-23 04:33:08 +00:00
/// <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>
/// <returns>The UUID of the newly created folder</returns>
2008-07-25 05:15:05 +00:00
public UUID CreateFolder ( UUID parentID , string name )
2007-12-23 04:33:08 +00:00
{
return CreateFolder ( parentID , name , AssetType . Unknown ) ;
}
/// <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>
2008-07-25 05:15:05 +00:00
public UUID CreateFolder ( UUID parentID , string name , AssetType preferredType )
2007-07-13 14:49:36 +00:00
{
2008-07-25 05:15:05 +00:00
UUID id = UUID . Random ( ) ;
2007-07-13 14:49:36 +00:00
// Assign a folder name if one is not already set
if ( String . IsNullOrEmpty ( name ) )
{
if ( preferredType > = AssetType . Texture & & preferredType < = AssetType . Gesture )
{
2007-09-10 10:20:30 +00:00
name = _NewFolderNames [ ( int ) preferredType ] ;
2007-07-13 14:49:36 +00:00
}
else
{
name = "New Folder" ;
}
}
2008-08-21 01:19:06 +00:00
// 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 ;
2009-10-29 09:39:43 +00:00
newFolder . OwnerID = Client . Self . AgentID ;
2008-08-21 01:19:06 +00:00
// Update the local store
try { _Store [ newFolder . UUID ] = newFolder ; }
2009-10-29 09:39:43 +00:00
catch ( InventoryException ie ) { Logger . Log ( ie . Message , Helpers . LogLevel . Warning , Client , ie ) ; }
2008-08-21 01:19:06 +00:00
2007-07-13 14:49:36 +00:00
// Create the create folder packet and send it
CreateInventoryFolderPacket create = new CreateInventoryFolderPacket ( ) ;
2009-10-29 09:39:43 +00:00
create . AgentData . AgentID = Client . Self . AgentID ;
create . AgentData . SessionID = Client . Self . SessionID ;
2007-11-06 09:26:10 +00:00
2007-07-13 14:49:36 +00:00
create . FolderData . FolderID = id ;
create . FolderData . ParentID = parentID ;
create . FolderData . Type = ( sbyte ) preferredType ;
2008-08-12 22:38:02 +00:00
create . FolderData . Name = Utils . StringToBytes ( name ) ;
2007-07-13 14:49:36 +00:00
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( create ) ;
2007-07-13 14:49:36 +00:00
return id ;
}
2009-07-18 15:55:23 +00:00
/// <summary>
/// Create an inventory item and upload asset data
/// </summary>
/// <param name="data">Asset data</param>
/// <param name="name">Inventory item name</param>
/// <param name="description">Inventory item description</param>
/// <param name="assetType">Asset type</param>
/// <param name="invType">Inventory type</param>
/// <param name="folderID">Put newly created inventory in this folder</param>
/// <param name="callback">Delegate that will receive feedback on success or failure</param>
2007-11-06 09:26:10 +00:00
public void RequestCreateItemFromAsset ( byte [ ] data , string name , string description , AssetType assetType ,
2009-05-01 06:04:32 +00:00
InventoryType invType , UUID folderID , ItemCreatedFromAssetCallback callback )
2009-07-18 15:55:23 +00:00
{
Permissions permissions = new Permissions ( ) ;
permissions . EveryoneMask = PermissionMask . None ;
permissions . GroupMask = PermissionMask . None ;
permissions . NextOwnerMask = PermissionMask . All ;
RequestCreateItemFromAsset ( data , name , description , assetType , invType , folderID , permissions , callback ) ;
}
/// <summary>
/// Create an inventory item and upload asset data
/// </summary>
/// <param name="data">Asset data</param>
/// <param name="name">Inventory item name</param>
/// <param name="description">Inventory item description</param>
/// <param name="assetType">Asset type</param>
/// <param name="invType">Inventory type</param>
/// <param name="folderID">Put newly created inventory in this folder</param>
/// <param name="permissions">Permission of the newly created item
/// (EveryoneMask, GroupMask, and NextOwnerMask of Permissions struct are supported)</param>
/// <param name="callback">Delegate that will receive feedback on success or failure</param>
public void RequestCreateItemFromAsset ( byte [ ] data , string name , string description , AssetType assetType ,
InventoryType invType , UUID folderID , Permissions permissions , ItemCreatedFromAssetCallback callback )
2007-07-13 14:49:36 +00:00
{
2009-10-29 09:39:43 +00:00
if ( Client . Network . CurrentSim = = null | | Client . Network . CurrentSim . Caps = = null )
2007-11-06 09:26:10 +00:00
throw new Exception ( "NewFileAgentInventory capability is not currently available" ) ;
2007-07-13 14:49:36 +00:00
2009-10-29 09:39:43 +00:00
Uri url = Client . Network . CurrentSim . Caps . CapabilityURI ( "NewFileAgentInventory" ) ;
2007-07-13 14:49:36 +00:00
2007-12-06 00:58:28 +00:00
if ( url ! = null )
2007-07-13 14:49:36 +00:00
{
2008-10-30 01:50:59 +00:00
OSDMap query = new OSDMap ( ) ;
query . Add ( "folder_id" , OSD . FromUUID ( folderID ) ) ;
2009-04-09 01:17:40 +00:00
query . Add ( "asset_type" , OSD . FromString ( Utils . AssetTypeToString ( assetType ) ) ) ;
query . Add ( "inventory_type" , OSD . FromString ( Utils . InventoryTypeToString ( invType ) ) ) ;
2008-10-30 01:50:59 +00:00
query . Add ( "name" , OSD . FromString ( name ) ) ;
query . Add ( "description" , OSD . FromString ( description ) ) ;
2009-07-18 15:55:23 +00:00
query . Add ( "everyone_mask" , OSD . FromInteger ( ( int ) permissions . EveryoneMask ) ) ;
query . Add ( "group_mask" , OSD . FromInteger ( ( int ) permissions . GroupMask ) ) ;
query . Add ( "next_owner_mask" , OSD . FromInteger ( ( int ) permissions . NextOwnerMask ) ) ;
2009-10-29 09:39:43 +00:00
query . Add ( "expected_upload_cost" , OSD . FromInteger ( Client . Settings . UPLOAD_COST ) ) ;
2007-11-21 23:50:05 +00:00
2007-09-10 10:20:30 +00:00
// Make the request
2007-12-06 00:58:28 +00:00
CapsClient request = new CapsClient ( url ) ;
2009-05-07 18:09:58 +00:00
request . OnComplete + = CreateItemFromAssetResponse ;
2009-10-29 09:39:43 +00:00
request . UserData = new object [ ] { callback , data , Client . Settings . CAPS_TIMEOUT , query } ;
2008-07-09 23:43:49 +00:00
2009-10-29 09:39:43 +00:00
request . BeginGetResponse ( query , OSDFormat . Xml , Client . Settings . CAPS_TIMEOUT ) ;
2007-09-10 10:20:30 +00:00
}
else
{
throw new Exception ( "NewFileAgentInventory capability is not currently available" ) ;
2007-07-13 14:49:36 +00:00
}
}
2010-02-26 13:47:44 +00:00
/// <summary>
/// Creates inventory link to another inventory item or folder
/// </summary>
/// <param name="folderID">Put newly created link in folder with this UUID</param>
2010-03-01 15:50:42 +00:00
/// <param name="bse">Inventory item or folder</param>
2010-02-26 13:47:44 +00:00
/// <param name="callback">Method to call upon creation of the link</param>
public void CreateLink ( UUID folderID , InventoryBase bse , ItemCreatedCallback callback )
{
if ( bse is InventoryFolder )
{
InventoryFolder folder = ( InventoryFolder ) bse ;
CreateLink ( folderID , folder , callback ) ;
}
2011-03-30 11:56:33 +00:00
else if ( bse is InventoryItem )
2010-02-26 13:47:44 +00:00
{
InventoryItem item = ( InventoryItem ) bse ;
CreateLink ( folderID , item . UUID , item . Name , item . Description , AssetType . Link , item . InventoryType , UUID . Random ( ) , callback ) ;
}
}
/// <summary>
/// Creates inventory link to another inventory item
/// </summary>
/// <param name="folderID">Put newly created link in folder with this UUID</param>
/// <param name="item">Original inventory item</param>
/// <param name="callback">Method to call upon creation of the link</param>
public void CreateLink ( UUID folderID , InventoryItem item , ItemCreatedCallback callback )
{
CreateLink ( folderID , item . UUID , item . Name , item . Description , AssetType . Link , item . InventoryType , UUID . Random ( ) , callback ) ;
}
/// <summary>
/// Creates inventory link to another inventory folder
/// </summary>
/// <param name="folderID">Put newly created link in folder with this UUID</param>
2010-03-01 15:50:42 +00:00
/// <param name="folder">Original inventory folder</param>
2010-02-26 13:47:44 +00:00
/// <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 ) ;
}
/// <summary>
/// Creates inventory link to another inventory item or folder
/// </summary>
/// <param name="folderID">Put newly created link in folder with this UUID</param>
/// <param name="itemID">Original item's UUID</param>
/// <param name="name">Name</param>
/// <param name="description">Description</param>
/// <param name="assetType">Asset Type</param>
/// <param name="invType">Inventory Type</param>
/// <param name="transactionID">Transaction UUID</param>
/// <param name="callback">Method to call upon creation of the link</param>
public void CreateLink ( UUID folderID , UUID itemID , string name , string description , AssetType assetType , InventoryType invType , UUID transactionID , ItemCreatedCallback callback )
{
LinkInventoryItemPacket create = new LinkInventoryItemPacket ( ) ;
create . AgentData . AgentID = Client . Self . AgentID ;
create . AgentData . SessionID = Client . Self . SessionID ;
create . InventoryBlock . CallbackID = RegisterItemCreatedCallback ( callback ) ;
2012-12-21 01:49:36 +01:00
lock ( _ItemInventoryTypeRequest )
{
_ItemInventoryTypeRequest [ create . InventoryBlock . CallbackID ] = invType ;
}
2010-02-26 13:47:44 +00:00
create . InventoryBlock . FolderID = folderID ;
create . InventoryBlock . TransactionID = transactionID ;
create . InventoryBlock . OldItemID = itemID ;
create . InventoryBlock . Type = ( sbyte ) assetType ;
create . InventoryBlock . InvType = ( sbyte ) invType ;
create . InventoryBlock . Name = Utils . StringToBytes ( name ) ;
create . InventoryBlock . Description = Utils . StringToBytes ( description ) ;
2011-03-30 11:56:33 +00:00
2010-02-26 13:47:44 +00:00
Client . Network . SendPacket ( create ) ;
}
2007-11-06 09:26:10 +00:00
#endregion Create
#region Copy
2008-05-03 04:10:02 +00:00
/// <summary>
///
/// </summary>
/// <param name="item"></param>
/// <param name="newParent"></param>
/// <param name="newName"></param>
/// <param name="callback"></param>
2008-07-25 05:15:05 +00:00
public void RequestCopyItem ( UUID item , UUID newParent , string newName , ItemCopiedCallback callback )
2007-08-25 09:36:33 +00:00
{
2009-10-29 09:39:43 +00:00
RequestCopyItem ( item , newParent , newName , Client . Self . AgentID , callback ) ;
2007-11-06 09:26:10 +00:00
}
2007-08-25 09:36:33 +00:00
2008-05-03 04:10:02 +00:00
/// <summary>
///
/// </summary>
/// <param name="item"></param>
/// <param name="newParent"></param>
/// <param name="newName"></param>
/// <param name="oldOwnerID"></param>
/// <param name="callback"></param>
2008-07-25 05:15:05 +00:00
public void RequestCopyItem ( UUID item , UUID newParent , string newName , UUID oldOwnerID ,
2007-11-06 09:26:10 +00:00
ItemCopiedCallback callback )
{
2008-07-25 05:15:05 +00:00
List < UUID > items = new List < UUID > ( 1 ) ;
2007-11-06 09:26:10 +00:00
items . Add ( item ) ;
2007-07-13 14:49:36 +00:00
2008-07-25 05:15:05 +00:00
List < UUID > folders = new List < UUID > ( 1 ) ;
2007-11-06 09:26:10 +00:00
folders . Add ( newParent ) ;
2007-09-10 10:20:30 +00:00
2007-11-06 09:26:10 +00:00
List < string > names = new List < string > ( 1 ) ;
names . Add ( newName ) ;
RequestCopyItems ( items , folders , names , oldOwnerID , callback ) ;
2007-07-13 14:49:36 +00:00
}
2008-05-03 04:10:02 +00:00
/// <summary>
///
/// </summary>
/// <param name="items"></param>
/// <param name="targetFolders"></param>
/// <param name="newNames"></param>
/// <param name="oldOwnerID"></param>
/// <param name="callback"></param>
2008-08-21 01:19:06 +00:00
public void RequestCopyItems ( List < UUID > items , List < UUID > targetFolders , List < string > newNames ,
2008-07-25 05:15:05 +00:00
UUID oldOwnerID , ItemCopiedCallback callback )
2007-07-13 14:49:36 +00:00
{
2007-11-06 09:26:10 +00:00
if ( items . Count ! = targetFolders . Count | | ( newNames ! = null & & items . Count ! = newNames . Count ) )
throw new ArgumentException ( "All list arguments must have an equal number of entries" ) ;
uint callbackID = RegisterItemsCopiedCallback ( callback ) ;
CopyInventoryItemPacket copy = new CopyInventoryItemPacket ( ) ;
2009-10-29 09:39:43 +00:00
copy . AgentData . AgentID = Client . Self . AgentID ;
copy . AgentData . SessionID = Client . Self . SessionID ;
2007-11-06 09:26:10 +00:00
copy . InventoryData = new CopyInventoryItemPacket . InventoryDataBlock [ items . Count ] ;
for ( int i = 0 ; i < items . Count ; + + i )
{
copy . InventoryData [ i ] = new CopyInventoryItemPacket . InventoryDataBlock ( ) ;
copy . InventoryData [ i ] . CallbackID = callbackID ;
copy . InventoryData [ i ] . NewFolderID = targetFolders [ i ] ;
copy . InventoryData [ i ] . OldAgentID = oldOwnerID ;
copy . InventoryData [ i ] . OldItemID = items [ i ] ;
if ( newNames ! = null & & ! String . IsNullOrEmpty ( newNames [ i ] ) )
2008-08-12 22:38:02 +00:00
copy . InventoryData [ i ] . NewName = Utils . StringToBytes ( newNames [ i ] ) ;
2007-11-06 09:26:10 +00:00
else
2009-03-06 01:32:02 +00:00
copy . InventoryData [ i ] . NewName = Utils . EmptyBytes ;
2007-11-06 09:26:10 +00:00
}
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( copy ) ;
2007-09-10 10:20:30 +00:00
}
2007-07-13 14:49:36 +00:00
2008-05-03 04:10:02 +00:00
/// <summary>
2009-01-14 11:24:54 +00:00
/// Request a copy of an asset embedded within a notecard
/// </summary>
/// <param name="objectID">Usually UUID.Zero for copying an asset from a notecard</param>
/// <param name="notecardID">UUID of the notecard to request an asset from</param>
/// <param name="folderID">Target folder for asset to go to in your inventory</param>
/// <param name="itemID">UUID of the embedded asset</param>
/// <param name="callback">callback to run when item is copied to inventory</param>
public void RequestCopyItemFromNotecard ( UUID objectID , UUID notecardID , UUID folderID , UUID itemID , ItemCopiedCallback callback )
2007-09-10 10:20:30 +00:00
{
2009-07-27 19:54:08 +00:00
_ItemCopiedCallbacks [ 0 ] = callback ; //Notecards always use callback ID 0
2007-07-13 14:49:36 +00:00
2009-10-29 09:39:43 +00:00
Uri url = Client . Network . CurrentSim . Caps . CapabilityURI ( "CopyInventoryFromNotecard" ) ;
2007-07-13 14:49:36 +00:00
2009-07-27 19:54:08 +00:00
if ( url ! = null )
{
CopyInventoryFromNotecardMessage message = new CopyInventoryFromNotecardMessage ( ) ;
message . CallbackID = 0 ;
message . FolderID = folderID ;
message . ItemID = itemID ;
message . NotecardID = notecardID ;
message . ObjectID = objectID ;
2007-09-10 10:20:30 +00:00
2009-07-27 19:54:08 +00:00
CapsClient request = new CapsClient ( url ) ;
2009-10-29 09:39:43 +00:00
request . BeginGetResponse ( message . Serialize ( ) , OSDFormat . Xml , Client . Settings . CAPS_TIMEOUT ) ;
2009-07-27 19:54:08 +00:00
}
else
{
CopyInventoryFromNotecardPacket copy = new CopyInventoryFromNotecardPacket ( ) ;
2009-10-29 09:39:43 +00:00
copy . AgentData . AgentID = Client . Self . AgentID ;
copy . AgentData . SessionID = Client . Self . SessionID ;
2009-07-27 19:54:08 +00:00
copy . NotecardData . ObjectID = objectID ;
copy . NotecardData . NotecardItemID = notecardID ;
copy . InventoryData = new CopyInventoryFromNotecardPacket . InventoryDataBlock [ 1 ] ;
copy . InventoryData [ 0 ] = new CopyInventoryFromNotecardPacket . InventoryDataBlock ( ) ;
copy . InventoryData [ 0 ] . FolderID = folderID ;
copy . InventoryData [ 0 ] . ItemID = itemID ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( copy ) ;
2009-07-27 19:54:08 +00:00
}
2007-09-10 10:20:30 +00:00
}
2007-11-06 09:26:10 +00:00
#endregion Copy
2007-09-10 10:20:30 +00:00
2007-11-06 09:26:10 +00:00
#region Update
2008-05-03 04:10:02 +00:00
/// <summary>
///
/// </summary>
2008-08-21 01:19:06 +00:00
/// <param name="item"></param>
public void RequestUpdateItem ( InventoryItem item )
2007-09-10 10:20:30 +00:00
{
2008-08-21 01:19:06 +00:00
List < InventoryItem > items = new List < InventoryItem > ( 1 ) ;
items . Add ( item ) ;
RequestUpdateItems ( items , UUID . Random ( ) ) ;
2007-09-10 10:20:30 +00:00
}
2008-05-03 04:10:02 +00:00
/// <summary>
///
/// </summary>
/// <param name="items"></param>
2008-08-21 01:19:06 +00:00
public void RequestUpdateItems ( List < InventoryItem > items )
2007-09-10 10:20:30 +00:00
{
2008-07-25 05:15:05 +00:00
RequestUpdateItems ( items , UUID . Random ( ) ) ;
2007-11-06 09:26:10 +00:00
}
2007-09-10 10:20:30 +00:00
2008-05-03 04:10:02 +00:00
/// <summary>
///
/// </summary>
/// <param name="items"></param>
/// <param name="transactionID"></param>
2008-08-21 01:19:06 +00:00
public void RequestUpdateItems ( List < InventoryItem > items , UUID transactionID )
2007-11-06 09:26:10 +00:00
{
UpdateInventoryItemPacket update = new UpdateInventoryItemPacket ( ) ;
2009-10-29 09:39:43 +00:00
update . AgentData . AgentID = Client . Self . AgentID ;
update . AgentData . SessionID = Client . Self . SessionID ;
2007-11-06 09:26:10 +00:00
update . AgentData . TransactionID = transactionID ;
2007-09-10 10:20:30 +00:00
2007-11-06 09:26:10 +00:00
update . InventoryData = new UpdateInventoryItemPacket . InventoryDataBlock [ items . Count ] ;
2008-08-21 01:19:06 +00:00
for ( int i = 0 ; i < items . Count ; i + + )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
InventoryItem item = items [ i ] ;
2007-11-06 09:26:10 +00:00
UpdateInventoryItemPacket . InventoryDataBlock block = new UpdateInventoryItemPacket . InventoryDataBlock ( ) ;
block . BaseMask = ( uint ) item . Permissions . BaseMask ;
block . CRC = ItemCRC ( item ) ;
2008-08-12 22:38:02 +00:00
block . CreationDate = ( int ) Utils . DateTimeToUnixTime ( item . CreationDate ) ;
2007-11-06 09:26:10 +00:00
block . CreatorID = item . CreatorID ;
2008-08-12 22:38:02 +00:00
block . Description = Utils . StringToBytes ( item . Description ) ;
2007-11-06 09:26:10 +00:00
block . EveryoneMask = ( uint ) item . Permissions . EveryoneMask ;
2008-01-12 00:12:40 +00:00
block . Flags = ( uint ) item . Flags ;
2007-11-06 09:26:10 +00:00
block . FolderID = item . ParentUUID ;
block . GroupID = item . GroupID ;
block . GroupMask = ( uint ) item . Permissions . GroupMask ;
block . GroupOwned = item . GroupOwned ;
block . InvType = ( sbyte ) item . InventoryType ;
block . ItemID = item . UUID ;
2008-08-12 22:38:02 +00:00
block . Name = Utils . StringToBytes ( item . Name ) ;
2007-11-06 09:26:10 +00:00
block . NextOwnerMask = ( uint ) item . Permissions . NextOwnerMask ;
block . OwnerID = item . OwnerID ;
block . OwnerMask = ( uint ) item . Permissions . OwnerMask ;
block . SalePrice = item . SalePrice ;
block . SaleType = ( byte ) item . SaleType ;
2009-07-11 23:22:41 +00:00
block . TransactionID = item . TransactionID ;
2007-11-06 09:26:10 +00:00
block . Type = ( sbyte ) item . AssetType ;
2008-08-21 01:19:06 +00:00
update . InventoryData [ i ] = block ;
2007-07-13 14:49:36 +00:00
}
2007-11-06 09:26:10 +00:00
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( update ) ;
2007-08-26 16:52:08 +00:00
}
2008-03-12 22:46:53 +00:00
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="notecardID"></param>
/// <param name="callback"></param>
2009-07-15 22:11:48 +00:00
public void RequestUploadNotecardAsset ( byte [ ] data , UUID notecardID , InventoryUploadedAssetCallback callback )
2008-03-12 22:46:53 +00:00
{
2009-10-29 09:39:43 +00:00
if ( Client . Network . CurrentSim = = null | | Client . Network . CurrentSim . Caps = = null )
2008-03-12 22:46:53 +00:00
throw new Exception ( "UpdateNotecardAgentInventory capability is not currently available" ) ;
2009-10-29 09:39:43 +00:00
Uri url = Client . Network . CurrentSim . Caps . CapabilityURI ( "UpdateNotecardAgentInventory" ) ;
2008-03-12 22:46:53 +00:00
if ( url ! = null )
{
2008-10-30 01:50:59 +00:00
OSDMap query = new OSDMap ( ) ;
query . Add ( "item_id" , OSD . FromUUID ( notecardID ) ) ;
2008-03-12 22:46:53 +00:00
// Make the request
CapsClient request = new CapsClient ( url ) ;
2009-07-15 22:11:48 +00:00
request . OnComplete + = UploadInventoryAssetResponse ;
request . UserData = new object [ ] { new KeyValuePair < InventoryUploadedAssetCallback , byte [ ] > ( callback , data ) , notecardID } ;
2009-10-29 09:39:43 +00:00
request . BeginGetResponse ( query , OSDFormat . Xml , Client . Settings . CAPS_TIMEOUT ) ;
2008-03-12 22:46:53 +00:00
}
else
{
throw new Exception ( "UpdateNotecardAgentInventory capability is not currently available" ) ;
}
}
2009-05-13 17:10:44 +00:00
2010-03-01 13:58:42 +00:00
/// <summary>
/// Save changes to notecard embedded in object contents
/// </summary>
/// <param name="data">Encoded notecard asset data</param>
/// <param name="notecardID">Notecard UUID</param>
/// <param name="taskID">Object's UUID</param>
/// <param name="callback">Called upon finish of the upload with status information</param>
public void RequestUpdateNotecardTask ( byte [ ] data , UUID notecardID , UUID taskID , InventoryUploadedAssetCallback callback )
{
if ( Client . Network . CurrentSim = = null | | Client . Network . CurrentSim . Caps = = null )
throw new Exception ( "UpdateNotecardTaskInventory capability is not currently available" ) ;
Uri url = Client . Network . CurrentSim . Caps . CapabilityURI ( "UpdateNotecardTaskInventory" ) ;
if ( url ! = null )
{
OSDMap query = new OSDMap ( ) ;
query . Add ( "item_id" , OSD . FromUUID ( notecardID ) ) ;
query . Add ( "task_id" , OSD . FromUUID ( taskID ) ) ;
// Make the request
CapsClient request = new CapsClient ( url ) ;
request . OnComplete + = UploadInventoryAssetResponse ;
request . UserData = new object [ ] { new KeyValuePair < InventoryUploadedAssetCallback , byte [ ] > ( callback , data ) , notecardID } ;
request . BeginGetResponse ( query , OSDFormat . Xml , Client . Settings . CAPS_TIMEOUT ) ;
}
else
{
throw new Exception ( "UpdateNotecardTaskInventory capability is not currently available" ) ;
}
}
2009-07-15 22:11:48 +00:00
/// <summary>
/// Upload new gesture asset for an inventory gesture item
/// </summary>
/// <param name="data">Encoded gesture asset</param>
/// <param name="gestureID">Gesture inventory UUID</param>
/// <param name="callback">Callback whick will be called when upload is complete</param>
public void RequestUploadGestureAsset ( byte [ ] data , UUID gestureID , InventoryUploadedAssetCallback callback )
{
2009-10-29 09:39:43 +00:00
if ( Client . Network . CurrentSim = = null | | Client . Network . CurrentSim . Caps = = null )
2009-07-15 22:11:48 +00:00
throw new Exception ( "UpdateGestureAgentInventory capability is not currently available" ) ;
2009-10-29 09:39:43 +00:00
Uri url = Client . Network . CurrentSim . Caps . CapabilityURI ( "UpdateGestureAgentInventory" ) ;
2009-07-15 22:11:48 +00:00
if ( url ! = null )
{
OSDMap query = new OSDMap ( ) ;
query . Add ( "item_id" , OSD . FromUUID ( gestureID ) ) ;
// Make the request
CapsClient request = new CapsClient ( url ) ;
request . OnComplete + = UploadInventoryAssetResponse ;
request . UserData = new object [ ] { new KeyValuePair < InventoryUploadedAssetCallback , byte [ ] > ( callback , data ) , gestureID } ;
2009-10-29 09:39:43 +00:00
request . BeginGetResponse ( query , OSDFormat . Xml , Client . Settings . CAPS_TIMEOUT ) ;
2009-07-15 22:11:48 +00:00
}
else
{
throw new Exception ( "UpdateGestureAgentInventory capability is not currently available" ) ;
}
}
2009-05-09 02:23:39 +00:00
/// <summary>
2009-05-13 17:10:44 +00:00
/// Update an existing script in an agents Inventory
2009-05-09 02:23:39 +00:00
/// </summary>
/// <param name="data">A byte[] array containing the encoded scripts contents</param>
/// <param name="itemID">the itemID of the script</param>
2009-05-13 21:27:38 +00:00
/// <param name="mono">if true, sets the script content to run on the mono interpreter</param>
2009-05-09 02:23:39 +00:00
/// <param name="callback"></param>
2009-05-13 21:27:38 +00:00
public void RequestUpdateScriptAgentInventory ( byte [ ] data , UUID itemID , bool mono , ScriptUpdatedCallback callback )
2009-05-09 02:23:39 +00:00
{
2009-10-29 09:39:43 +00:00
Uri url = Client . Network . CurrentSim . Caps . CapabilityURI ( "UpdateScriptAgent" ) ;
2009-05-09 02:23:39 +00:00
2009-10-29 09:39:43 +00:00
if ( url ! = null )
2009-05-09 02:23:39 +00:00
{
2009-07-11 08:16:43 +00:00
UpdateScriptAgentRequestMessage msg = new UpdateScriptAgentRequestMessage ( ) ;
2009-05-13 17:10:44 +00:00
msg . ItemID = itemID ;
2009-05-13 21:27:38 +00:00
msg . Target = mono ? "mono" : "lsl2" ;
2009-10-29 09:39:43 +00:00
2009-05-09 02:23:39 +00:00
CapsClient request = new CapsClient ( url ) ;
request . OnComplete + = new CapsClient . CompleteCallback ( UpdateScriptAgentInventoryResponse ) ;
request . UserData = new object [ 2 ] { new KeyValuePair < ScriptUpdatedCallback , byte [ ] > ( callback , data ) , itemID } ;
2009-10-29 09:39:43 +00:00
request . BeginGetResponse ( msg . Serialize ( ) , OSDFormat . Xml , Client . Settings . CAPS_TIMEOUT ) ;
2009-05-09 02:23:39 +00:00
}
else
{
2009-05-13 17:10:44 +00:00
throw new Exception ( "UpdateScriptAgent capability is not currently available" ) ;
2009-05-09 02:23:39 +00:00
}
}
2010-03-01 13:58:42 +00:00
/// <summary>
/// Update an existing script in an task Inventory
/// </summary>
/// <param name="data">A byte[] array containing the encoded scripts contents</param>
/// <param name="itemID">the itemID of the script</param>
/// <param name="taskID">UUID of the prim containting the script</param>
/// <param name="mono">if true, sets the script content to run on the mono interpreter</param>
/// <param name="running">if true, sets the script to running</param>
/// <param name="callback"></param>
public void RequestUpdateScriptTask ( byte [ ] data , UUID itemID , UUID taskID , bool mono , bool running , ScriptUpdatedCallback callback )
{
Uri url = Client . Network . CurrentSim . Caps . CapabilityURI ( "UpdateScriptTask" ) ;
if ( url ! = null )
{
UpdateScriptTaskUpdateMessage msg = new UpdateScriptTaskUpdateMessage ( ) ;
msg . ItemID = itemID ;
msg . TaskID = taskID ;
msg . ScriptRunning = running ;
msg . Target = mono ? "mono" : "lsl2" ;
CapsClient request = new CapsClient ( url ) ;
request . OnComplete + = new CapsClient . CompleteCallback ( UpdateScriptAgentInventoryResponse ) ;
request . UserData = new object [ 2 ] { new KeyValuePair < ScriptUpdatedCallback , byte [ ] > ( callback , data ) , itemID } ;
request . BeginGetResponse ( msg . Serialize ( ) , OSDFormat . Xml , Client . Settings . CAPS_TIMEOUT ) ;
}
else
{
throw new Exception ( "UpdateScriptTask capability is not currently available" ) ;
}
}
2007-11-06 09:26:10 +00:00
#endregion Update
#region Rez / Give
2007-08-26 16:52:08 +00:00
/// <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>
2009-01-02 21:25:21 +00:00
/// <param name="item">InventoryItem object containing item details</param>
2008-07-25 05:15:05 +00:00
public UUID RequestRezFromInventory ( Simulator simulator , Quaternion rotation , Vector3 position ,
2009-01-02 21:25:21 +00:00
InventoryItem item )
2007-08-26 16:52:08 +00:00
{
2009-10-29 09:39:43 +00:00
return RequestRezFromInventory ( simulator , rotation , position , item , Client . Self . ActiveGroup ,
2009-07-31 01:28:24 +00:00
UUID . Random ( ) , true ) ;
2007-08-26 16:52:08 +00:00
}
/// <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>
2009-01-02 21:25:21 +00:00
/// <param name="item">InventoryItem object containing item details</param>
2008-07-28 22:23:48 +00:00
/// <param name="groupOwner">UUID of group to own the object</param>
2008-07-25 05:15:05 +00:00
public UUID RequestRezFromInventory ( Simulator simulator , Quaternion rotation , Vector3 position ,
2009-01-02 21:25:21 +00:00
InventoryItem item , UUID groupOwner )
2007-08-26 16:52:08 +00:00
{
2009-07-31 01:28:24 +00:00
return RequestRezFromInventory ( simulator , rotation , position , item , groupOwner , UUID . Random ( ) , true ) ;
2007-08-26 16:52:08 +00:00
}
2007-07-13 14:49:36 +00:00
2007-08-26 16:52:08 +00:00
/// <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>
2009-01-02 21:25:21 +00:00
/// <param name="item">InventoryItem object containing item details</param>
2008-07-28 22:23:48 +00:00
/// <param name="groupOwner">UUID of group to own the object</param>
2007-11-06 09:26:10 +00:00
/// <param name="queryID">User defined queryID to correlate replies</param>
2009-07-31 01:28:24 +00:00
/// <param name="rezSelected">If set to true, the CreateSelected flag
2009-11-07 14:57:56 +00:00
/// will be set on the rezzed object</param>
2008-07-25 05:15:05 +00:00
public UUID RequestRezFromInventory ( Simulator simulator , Quaternion rotation , Vector3 position ,
2009-07-31 01:28:24 +00:00
InventoryItem item , UUID groupOwner , UUID queryID , bool rezSelected )
2012-06-02 03:40:27 -07:00
{
return RequestRezFromInventory ( simulator , UUID . Zero , rotation , position , item , groupOwner , queryID ,
rezSelected ) ;
}
/// <summary>
/// Rez an object from inventory
/// </summary>
/// <param name="simulator">Simulator to place object in</param>
/// <param name="taskID">TaskID object when rezzed</param>
/// <param name="rotation">Rotation of the object when rezzed</param>
/// <param name="position">Vector of where to place object</param>
/// <param name="item">InventoryItem 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="rezSelected">If set to true, the CreateSelected flag
/// will be set on the rezzed object</param>
public UUID RequestRezFromInventory ( Simulator simulator , UUID taskID , Quaternion rotation , Vector3 position ,
InventoryItem item , UUID groupOwner , UUID queryID , bool rezSelected )
2007-08-26 16:52:08 +00:00
{
RezObjectPacket add = new RezObjectPacket ( ) ;
2009-10-29 09:39:43 +00:00
add . AgentData . AgentID = Client . Self . AgentID ;
add . AgentData . SessionID = Client . Self . SessionID ;
2007-08-26 16:52:08 +00:00
add . AgentData . GroupID = groupOwner ;
2012-06-02 03:40:27 -07:00
add . RezData . FromTaskID = taskID ;
2007-08-26 16:52:08 +00:00
add . RezData . BypassRaycast = 1 ;
add . RezData . RayStart = position ;
add . RezData . RayEnd = position ;
2008-07-25 05:15:05 +00:00
add . RezData . RayTargetID = UUID . Zero ;
2007-08-26 16:52:08 +00:00
add . RezData . RayEndIsIntersection = false ;
2009-07-31 01:28:24 +00:00
add . RezData . RezSelected = rezSelected ;
2007-08-26 16:52:08 +00:00
add . RezData . RemoveItem = false ;
2008-01-12 00:12:40 +00:00
add . RezData . ItemFlags = ( uint ) item . Flags ;
2007-08-26 16:52:08 +00:00
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 ;
2008-01-12 00:12:40 +00:00
add . InventoryData . Flags = ( uint ) item . Flags ;
2007-08-26 16:52:08 +00:00
add . InventoryData . SaleType = ( byte ) item . SaleType ;
add . InventoryData . SalePrice = item . SalePrice ;
2008-08-12 22:38:02 +00:00
add . InventoryData . Name = Utils . StringToBytes ( item . Name ) ;
add . InventoryData . Description = Utils . StringToBytes ( item . Description ) ;
add . InventoryData . CreationDate = ( int ) Utils . DateTimeToUnixTime ( item . CreationDate ) ;
2007-08-26 16:52:08 +00:00
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( add , simulator ) ;
2007-11-06 09:26:10 +00:00
2011-05-09 10:47:29 +00:00
// Remove from store if the item is no copy
if ( Store . Items . ContainsKey ( item . UUID ) & & Store [ item . UUID ] is InventoryItem )
{
InventoryItem invItem = ( InventoryItem ) Store [ item . UUID ] ;
if ( ( invItem . Permissions . OwnerMask & PermissionMask . Copy ) = = PermissionMask . None )
{
Store . RemoveNodeFor ( invItem ) ;
}
}
2007-08-26 16:52:08 +00:00
return queryID ;
2007-07-13 14:49:36 +00:00
}
2008-05-14 11:17:45 +00:00
/// <summary>
/// DeRez an object from the simulator to the agents Objects folder in the agents Inventory
/// </summary>
/// <param name="objectLocalID">The simulator Local ID of the object</param>
2009-11-07 14:57:56 +00:00
/// <remarks>If objectLocalID is a child primitive in a linkset, the entire linkset will be derezzed</remarks>
2008-05-14 11:17:45 +00:00
public void RequestDeRezToInventory ( uint objectLocalID )
{
2009-10-29 09:39:43 +00:00
RequestDeRezToInventory ( objectLocalID , DeRezDestination . AgentInventoryTake ,
Client . Inventory . FindFolderForType ( AssetType . Object ) , UUID . Random ( ) ) ;
2008-05-14 11:17:45 +00:00
}
/// <summary>
/// DeRez an object from the simulator and return to inventory
/// </summary>
/// <param name="objectLocalID">The simulator Local ID of the object</param>
/// <param name="destType">The type of destination from the <seealso cref="DeRezDestination"/> enum</param>
2008-07-28 22:23:48 +00:00
/// <param name="destFolder">The destination inventory folders <seealso cref="UUID"/> -or-
/// if DeRezzing object to a tasks Inventory, the Tasks <seealso cref="UUID"/></param>
2008-05-14 11:17:45 +00:00
/// <param name="transactionID">The transaction ID for this request which
/// can be used to correlate this request with other packets</param>
2009-11-07 14:57:56 +00:00
/// <remarks>If objectLocalID is a child primitive in a linkset, the entire linkset will be derezzed</remarks>
2008-07-25 05:15:05 +00:00
public void RequestDeRezToInventory ( uint objectLocalID , DeRezDestination destType , UUID destFolder , UUID transactionID )
2008-05-14 11:17:45 +00:00
{
DeRezObjectPacket take = new DeRezObjectPacket ( ) ;
2009-10-29 09:39:43 +00:00
take . AgentData . AgentID = Client . Self . AgentID ;
take . AgentData . SessionID = Client . Self . SessionID ;
2008-05-14 11:17:45 +00:00
take . AgentBlock = new DeRezObjectPacket . AgentBlockBlock ( ) ;
2008-07-25 05:15:05 +00:00
take . AgentBlock . GroupID = UUID . Zero ;
2008-05-14 11:17:45 +00:00
take . AgentBlock . Destination = ( byte ) destType ;
take . AgentBlock . DestinationID = destFolder ;
take . AgentBlock . PacketCount = 1 ;
take . AgentBlock . PacketNumber = 1 ;
take . AgentBlock . TransactionID = transactionID ;
take . ObjectData = new DeRezObjectPacket . ObjectDataBlock [ 1 ] ;
take . ObjectData [ 0 ] = new DeRezObjectPacket . ObjectDataBlock ( ) ;
take . ObjectData [ 0 ] . ObjectLocalID = objectLocalID ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( take ) ;
2008-05-14 11:17:45 +00:00
}
2009-10-29 09:39:43 +00:00
2009-05-10 09:31:07 +00:00
/// <summary>
/// Rez an item from inventory to its previous simulator location
/// </summary>
/// <param name="simulator"></param>
/// <param name="item"></param>
/// <param name="queryID"></param>
/// <returns></returns>
public UUID RequestRestoreRezFromInventory ( Simulator simulator , InventoryItem item , UUID queryID )
{
RezRestoreToWorldPacket add = new RezRestoreToWorldPacket ( ) ;
2009-10-29 09:39:43 +00:00
add . AgentData . AgentID = Client . Self . AgentID ;
add . AgentData . SessionID = Client . Self . SessionID ;
2009-05-10 09:31:07 +00:00
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 ) ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( add , simulator ) ;
2009-05-10 09:31:07 +00:00
return queryID ;
}
2008-05-14 11:17:45 +00:00
2008-05-03 04:10:02 +00:00
/// <summary>
/// Give an inventory item to another avatar
/// </summary>
2008-07-28 22:23:48 +00:00
/// <param name="itemID">The <seealso cref="UUID"/> of the item to give</param>
2008-05-03 04:10:02 +00:00
/// <param name="itemName">The name of the item</param>
/// <param name="assetType">The type of the item from the <seealso cref="AssetType"/> enum</param>
2008-07-28 22:23:48 +00:00
/// <param name="recipient">The <seealso cref="UUID"/> of the recipient</param>
2008-05-03 04:10:02 +00:00
/// <param name="doEffect">true to generate a beameffect during transfer</param>
2008-07-25 05:15:05 +00:00
public void GiveItem ( UUID itemID , string itemName , AssetType assetType , UUID recipient ,
2008-05-03 04:10:02 +00:00
bool doEffect )
2007-11-06 09:26:10 +00:00
{
2008-05-26 04:27:14 +00:00
byte [ ] bucket ;
2009-10-29 09:39:43 +00:00
bucket = new byte [ 17 ] ;
bucket [ 0 ] = ( byte ) assetType ;
Buffer . BlockCopy ( itemID . GetBytes ( ) , 0 , bucket , 1 , 16 ) ;
2008-05-26 04:27:14 +00:00
2009-10-29 09:39:43 +00:00
Client . Self . InstantMessage (
Client . Self . Name ,
2008-05-26 04:27:14 +00:00
recipient ,
itemName ,
2008-07-25 05:15:05 +00:00
UUID . Random ( ) ,
2008-05-26 04:27:14 +00:00
InstantMessageDialog . InventoryOffered ,
InstantMessageOnline . Online ,
2009-10-29 09:39:43 +00:00
Client . Self . SimPosition ,
Client . Network . CurrentSim . ID ,
2008-05-26 04:27:14 +00:00
bucket ) ;
if ( doEffect )
{
2009-10-29 09:39:43 +00:00
Client . Self . BeamEffect ( Client . Self . AgentID , recipient , Vector3d . Zero ,
Client . Settings . DEFAULT_EFFECT_COLOR , 1f , UUID . Random ( ) ) ;
2008-05-26 04:27:14 +00:00
}
2011-05-09 10:47:29 +00:00
// Remove from store if the item is no copy
if ( Store . Items . ContainsKey ( itemID ) & & Store [ itemID ] is InventoryItem )
{
InventoryItem invItem = ( InventoryItem ) Store [ itemID ] ;
if ( ( invItem . Permissions . OwnerMask & PermissionMask . Copy ) = = PermissionMask . None )
{
Store . RemoveNodeFor ( invItem ) ;
}
}
2008-05-26 04:27:14 +00:00
}
/// <summary>
/// Give an inventory Folder with contents to another avatar
/// </summary>
2008-07-28 22:23:48 +00:00
/// <param name="folderID">The <seealso cref="UUID"/> of the Folder to give</param>
2008-05-26 04:27:14 +00:00
/// <param name="folderName">The name of the folder</param>
/// <param name="assetType">The type of the item from the <seealso cref="AssetType"/> enum</param>
2008-07-28 22:23:48 +00:00
/// <param name="recipient">The <seealso cref="UUID"/> of the recipient</param>
2008-05-26 04:27:14 +00:00
/// <param name="doEffect">true to generate a beameffect during transfer</param>
2008-07-25 05:15:05 +00:00
public void GiveFolder ( UUID folderID , string folderName , AssetType assetType , UUID recipient ,
2008-05-26 04:27:14 +00:00
bool doEffect )
2008-07-29 21:36:53 +00:00
{
byte [ ] bucket ;
2009-10-29 09:39:43 +00:00
List < InventoryItem > folderContents = new List < InventoryItem > ( ) ;
2008-07-29 21:36:53 +00:00
2009-10-29 09:39:43 +00:00
Client . Inventory . FolderContents ( folderID , Client . Self . AgentID , false , true , InventorySortOrder . ByDate , 1000 * 15 ) . ForEach (
delegate ( InventoryBase ib )
{
folderContents . Add ( Client . Inventory . FetchItem ( ib . UUID , Client . Self . AgentID , 1000 * 10 ) ) ;
} ) ;
bucket = new byte [ 17 * ( folderContents . Count + 1 ) ] ;
2007-09-10 10:20:30 +00:00
2009-10-29 09:39:43 +00:00
//Add parent folder (first item in bucket)
bucket [ 0 ] = ( byte ) assetType ;
Buffer . BlockCopy ( folderID . GetBytes ( ) , 0 , bucket , 1 , 16 ) ;
2008-08-21 01:19:06 +00:00
2009-10-29 09:39:43 +00:00
//Add contents to bucket after folder
for ( int i = 1 ; i < = folderContents . Count ; + + i )
{
bucket [ i * 17 ] = ( byte ) folderContents [ i - 1 ] . AssetType ;
Buffer . BlockCopy ( folderContents [ i - 1 ] . UUID . GetBytes ( ) , 0 , bucket , i * 17 + 1 , 16 ) ;
}
2008-07-29 21:36:53 +00:00
2009-10-29 09:39:43 +00:00
Client . Self . InstantMessage (
Client . Self . Name ,
2008-05-26 04:27:14 +00:00
recipient ,
folderName ,
2008-07-25 05:15:05 +00:00
UUID . Random ( ) ,
2008-05-26 04:27:14 +00:00
InstantMessageDialog . InventoryOffered ,
InstantMessageOnline . Online ,
2009-10-29 09:39:43 +00:00
Client . Self . SimPosition ,
Client . Network . CurrentSim . ID ,
2008-05-26 04:27:14 +00:00
bucket ) ;
2007-11-06 09:26:10 +00:00
if ( doEffect )
{
2009-10-29 09:39:43 +00:00
Client . Self . BeamEffect ( Client . Self . AgentID , recipient , Vector3d . Zero ,
Client . Settings . DEFAULT_EFFECT_COLOR , 1f , UUID . Random ( ) ) ;
2007-11-06 09:26:10 +00:00
}
2011-05-09 10:47:29 +00:00
// Remove from store if items were no copy
for ( int i = 0 ; i < folderContents . Count ; i + + )
{
if ( Store . Items . ContainsKey ( folderContents [ i ] . UUID ) & & Store [ folderContents [ i ] . UUID ] is InventoryItem )
{
InventoryItem invItem = ( InventoryItem ) Store [ folderContents [ i ] . UUID ] ;
if ( ( invItem . Permissions . OwnerMask & PermissionMask . Copy ) = = PermissionMask . None )
{
Store . RemoveNodeFor ( invItem ) ;
}
}
}
2007-11-06 09:26:10 +00:00
}
#endregion Rez / Give
#region Task
2008-05-03 04:10:02 +00:00
/// <summary>
2009-10-29 09:39:43 +00:00
/// Copy or move an <see cref="InventoryItem"/> from agent inventory to a task (primitive) inventory
2008-05-03 04:10:02 +00:00
/// </summary>
2009-10-29 09:39:43 +00:00
/// <param name="objectLocalID">The target object</param>
/// <param name="item">The item to copy or move from inventory</param>
2008-05-03 04:10:02 +00:00
/// <returns></returns>
2009-10-29 09:39:43 +00:00
/// <remarks>For items with copy permissions a copy of the item is placed in the tasks inventory,
/// for no-copy items the object is moved to the tasks inventory</remarks>
// DocTODO: what does the return UUID correlate to if anything?
2008-08-21 01:19:06 +00:00
public UUID UpdateTaskInventory ( uint objectLocalID , InventoryItem item )
2007-11-06 09:26:10 +00:00
{
2008-07-25 05:15:05 +00:00
UUID transactionID = UUID . Random ( ) ;
2007-11-06 09:26:10 +00:00
UpdateTaskInventoryPacket update = new UpdateTaskInventoryPacket ( ) ;
2009-10-29 09:39:43 +00:00
update . AgentData . AgentID = Client . Self . AgentID ;
update . AgentData . SessionID = Client . Self . SessionID ;
2007-11-06 09:26:10 +00:00
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 ;
2008-01-12 00:12:40 +00:00
update . InventoryData . Flags = ( uint ) item . Flags ;
2007-11-06 09:26:10 +00:00
update . InventoryData . SaleType = ( byte ) item . SaleType ;
update . InventoryData . SalePrice = item . SalePrice ;
2008-08-12 22:38:02 +00:00
update . InventoryData . Name = Utils . StringToBytes ( item . Name ) ;
update . InventoryData . Description = Utils . StringToBytes ( item . Description ) ;
update . InventoryData . CreationDate = ( int ) Utils . DateTimeToUnixTime ( item . CreationDate ) ;
2007-11-06 09:26:10 +00:00
update . InventoryData . CRC = ItemCRC ( item ) ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( update ) ;
2007-11-06 09:26:10 +00:00
return transactionID ;
}
2008-05-03 04:10:02 +00:00
/// <summary>
2009-10-29 09:39:43 +00:00
/// Retrieve a listing of the items contained in a task (Primitive)
2008-05-03 04:10:02 +00:00
/// </summary>
2008-07-28 22:23:48 +00:00
/// <param name="objectID">The tasks <seealso cref="UUID"/></param>
2008-05-03 04:10:02 +00:00
/// <param name="objectLocalID">The tasks simulator local ID</param>
2008-08-21 01:19:06 +00:00
/// <param name="timeoutMS">milliseconds to wait for reply from simulator</param>
2009-10-29 09:39:43 +00:00
/// <returns>A list containing the inventory items inside the task or null
/// if a timeout occurs</returns>
/// <remarks>This request blocks until the response from the simulator arrives
/// or timeoutMS is exceeded</remarks>
public List < InventoryBase > GetTaskInventory ( UUID objectID , UInt32 objectLocalID , Int32 timeoutMS )
2007-11-06 09:26:10 +00:00
{
2009-10-29 09:39:43 +00:00
String filename = null ;
2007-11-06 09:26:10 +00:00
AutoResetEvent taskReplyEvent = new AutoResetEvent ( false ) ;
2009-10-29 09:39:43 +00:00
EventHandler < TaskInventoryReplyEventArgs > callback =
delegate ( object sender , TaskInventoryReplyEventArgs e )
2007-11-06 09:26:10 +00:00
{
2009-10-29 09:39:43 +00:00
if ( e . ItemID = = objectID )
2007-11-06 09:26:10 +00:00
{
2009-10-29 09:39:43 +00:00
filename = e . AssetFilename ;
2007-11-06 09:26:10 +00:00
taskReplyEvent . Set ( ) ;
}
} ;
2009-10-29 09:39:43 +00:00
TaskInventoryReply + = callback ;
2007-11-06 09:26:10 +00:00
RequestTaskInventory ( objectLocalID ) ;
2008-08-21 01:19:06 +00:00
if ( taskReplyEvent . WaitOne ( timeoutMS , false ) )
2007-11-06 09:26:10 +00:00
{
2009-10-29 09:39:43 +00:00
TaskInventoryReply - = callback ;
2007-11-06 09:26:10 +00:00
2008-01-15 20:16:13 +00:00
if ( ! String . IsNullOrEmpty ( filename ) )
{
byte [ ] assetData = null ;
ulong xferID = 0 ;
AutoResetEvent taskDownloadEvent = new AutoResetEvent ( false ) ;
2007-11-06 09:26:10 +00:00
2010-03-17 14:00:36 +00:00
EventHandler < XferReceivedEventArgs > xferCallback =
delegate ( object sender , XferReceivedEventArgs e )
2007-11-06 09:26:10 +00:00
{
2010-03-17 14:00:36 +00:00
if ( e . Xfer . XferID = = xferID )
2008-01-15 20:16:13 +00:00
{
2010-03-17 14:00:36 +00:00
assetData = e . Xfer . AssetData ;
2008-01-15 20:16:13 +00:00
taskDownloadEvent . Set ( ) ;
}
} ;
2007-11-06 09:26:10 +00:00
2010-03-17 14:00:36 +00:00
Client . Assets . XferReceived + = xferCallback ;
2007-11-06 09:26:10 +00:00
2008-01-15 20:16:13 +00:00
// Start the actual asset xfer
2009-10-29 09:39:43 +00:00
xferID = Client . Assets . RequestAssetXfer ( filename , true , false , UUID . Zero , AssetType . Unknown , true ) ;
2007-11-06 09:26:10 +00:00
2008-08-21 01:19:06 +00:00
if ( taskDownloadEvent . WaitOne ( timeoutMS , false ) )
2008-01-15 20:16:13 +00:00
{
2010-03-17 14:00:36 +00:00
Client . Assets . XferReceived - = xferCallback ;
2007-11-06 09:26:10 +00:00
2009-10-29 09:39:43 +00:00
String taskList = Utils . BytesToString ( assetData ) ;
2008-08-21 01:19:06 +00:00
return ParseTaskInventory ( taskList ) ;
2008-01-15 20:16:13 +00:00
}
else
{
2009-10-29 09:39:43 +00:00
Logger . Log ( "Timed out waiting for task inventory download for " + filename , Helpers . LogLevel . Warning , Client ) ;
2010-03-17 14:00:36 +00:00
Client . Assets . XferReceived - = xferCallback ;
2008-08-21 01:19:06 +00:00
return null ;
2008-01-15 20:16:13 +00:00
}
2007-11-06 09:26:10 +00:00
}
else
{
2009-10-29 09:39:43 +00:00
Logger . DebugLog ( "Task is empty for " + objectLocalID , Client ) ;
return new List < InventoryBase > ( 0 ) ;
2007-11-06 09:26:10 +00:00
}
}
else
{
2009-10-29 09:39:43 +00:00
Logger . Log ( "Timed out waiting for task inventory reply for " + objectLocalID , Helpers . LogLevel . Warning , Client ) ;
TaskInventoryReply - = callback ;
2008-08-21 01:19:06 +00:00
return null ;
2007-11-06 09:26:10 +00:00
}
}
2008-05-03 04:10:02 +00:00
/// <summary>
2009-10-29 09:39:43 +00:00
/// Request the contents of a tasks (primitives) inventory from the
/// current simulator
2008-05-03 04:10:02 +00:00
/// </summary>
2009-10-29 09:39:43 +00:00
/// <param name="objectLocalID">The LocalID of the object</param>
/// <seealso cref="TaskInventoryReply"/>
2007-11-06 09:26:10 +00:00
public void RequestTaskInventory ( uint objectLocalID )
{
2009-10-29 09:39:43 +00:00
RequestTaskInventory ( objectLocalID , Client . Network . CurrentSim ) ;
2007-11-06 09:26:10 +00:00
}
2008-05-03 04:10:02 +00:00
/// <summary>
/// Request the contents of a tasks (primitives) inventory
/// </summary>
/// <param name="objectLocalID">The simulator Local ID of the object</param>
/// <param name="simulator">A reference to the simulator object that contains the object</param>
2009-10-29 09:39:43 +00:00
/// <seealso cref="TaskInventoryReply"/>
2007-11-06 09:26:10 +00:00
public void RequestTaskInventory ( uint objectLocalID , Simulator simulator )
{
RequestTaskInventoryPacket request = new RequestTaskInventoryPacket ( ) ;
2009-10-29 09:39:43 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2007-11-06 09:26:10 +00:00
request . InventoryData . LocalID = objectLocalID ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( request , simulator ) ;
2007-11-06 09:26:10 +00:00
}
2009-10-29 09:39:43 +00:00
2008-03-13 06:45:42 +00:00
/// <summary>
2009-10-29 09:39:43 +00:00
/// Move an item from a tasks (Primitive) inventory to the specified folder in the avatars inventory
2008-03-13 06:45:42 +00:00
/// </summary>
/// <param name="objectLocalID">LocalID of the object in the simulator</param>
/// <param name="taskItemID">UUID of the task item to move</param>
2009-10-29 09:39:43 +00:00
/// <param name="inventoryFolderID">The ID of the destination folder in this agents inventory</param>
2008-03-13 06:45:42 +00:00
/// <param name="simulator">Simulator Object</param>
2009-10-29 09:39:43 +00:00
/// <remarks>Raises the <see cref="OnTaskItemReceived"/> event</remarks>
2008-07-25 05:15:05 +00:00
public void MoveTaskInventory ( uint objectLocalID , UUID taskItemID , UUID inventoryFolderID , Simulator simulator )
2008-03-13 06:45:42 +00:00
{
MoveTaskInventoryPacket request = new MoveTaskInventoryPacket ( ) ;
2009-10-29 09:39:43 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
request . AgentData . SessionID = Client . Self . SessionID ;
2008-03-13 06:45:42 +00:00
request . AgentData . FolderID = inventoryFolderID ;
request . InventoryData . ItemID = taskItemID ;
request . InventoryData . LocalID = objectLocalID ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( request , simulator ) ;
2008-03-13 06:45:42 +00:00
}
2009-10-29 09:39:43 +00:00
2008-03-13 06:45:42 +00:00
/// <summary>
/// Remove an item from an objects (Prim) Inventory
/// </summary>
/// <param name="objectLocalID">LocalID of the object in the simulator</param>
2008-07-28 22:23:48 +00:00
/// <param name="taskItemID">UUID of the task item to remove</param>
2008-03-13 06:45:42 +00:00
/// <param name="simulator">Simulator Object</param>
2009-10-29 09:39:43 +00:00
/// <remarks>You can confirm the removal by comparing the tasks inventory serial before and after the
/// request with the <see cref="RequestTaskInventory"/> request combined with
/// the <seealso cref="TaskInventoryReply"/> event</remarks>
2008-07-25 05:15:05 +00:00
public void RemoveTaskInventory ( uint objectLocalID , UUID taskItemID , Simulator simulator )
2008-03-13 06:45:42 +00:00
{
RemoveTaskInventoryPacket remove = new RemoveTaskInventoryPacket ( ) ;
2009-10-29 09:39:43 +00:00
remove . AgentData . AgentID = Client . Self . AgentID ;
remove . AgentData . SessionID = Client . Self . SessionID ;
2008-03-13 06:45:42 +00:00
remove . InventoryData . ItemID = taskItemID ;
remove . InventoryData . LocalID = objectLocalID ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( remove , simulator ) ;
2008-03-13 06:45:42 +00:00
}
2007-11-06 09:26:10 +00:00
2009-04-06 07:48:20 +00:00
/// <summary>
2009-04-06 07:24:02 +00:00
/// Copy an InventoryScript item from the Agents Inventory into a primitives task inventory
/// </summary>
/// <param name="objectLocalID">An unsigned integer representing a primitive being simulated</param>
/// <param name="item">An <seealso cref="InventoryItem"/> which represents a script object from the agents inventory</param>
2009-05-13 21:27:38 +00:00
/// <param name="enableScript">true to set the scripts running state to enabled</param>
2009-04-06 07:24:02 +00:00
/// <returns>A Unique Transaction ID</returns>
2009-10-29 09:39:43 +00:00
/// <example>
/// The following example shows the basic steps necessary to copy a script from the agents inventory into a tasks inventory
/// and assumes the script exists in the agents inventory.
2009-04-06 07:24:02 +00:00
/// <code>
2009-10-29 09:39:43 +00:00
/// uint primID = 95899503; // Fake prim ID
/// UUID scriptID = UUID.Parse("92a7fe8a-e949-dd39-a8d8-1681d8673232"); // Fake Script UUID in Inventory
2009-04-06 07:24:02 +00:00
///
/// Client.Inventory.FolderContents(Client.Inventory.FindFolderForType(AssetType.LSLText), Client.Self.AgentID,
/// false, true, InventorySortOrder.ByName, 10000);
///
2009-10-29 09:39:43 +00:00
/// Client.Inventory.RezScript(primID, (InventoryItem)Client.Inventory.Store[scriptID]);
2009-04-06 07:24:02 +00:00
/// </code>
2009-10-29 09:39:43 +00:00
/// </example>
// DocTODO: what does the return UUID correlate to if anything?
2009-05-13 21:27:38 +00:00
public UUID CopyScriptToTask ( uint objectLocalID , InventoryItem item , bool enableScript )
2009-04-06 07:24:02 +00:00
{
UUID transactionID = UUID . Random ( ) ;
RezScriptPacket ScriptPacket = new RezScriptPacket ( ) ;
2009-10-29 09:39:43 +00:00
ScriptPacket . AgentData . AgentID = Client . Self . AgentID ;
ScriptPacket . AgentData . SessionID = Client . Self . SessionID ;
2009-04-06 07:24:02 +00:00
ScriptPacket . UpdateBlock . ObjectLocalID = objectLocalID ;
2009-05-13 21:27:38 +00:00
ScriptPacket . UpdateBlock . Enabled = enableScript ;
2009-04-06 07:24:02 +00:00
ScriptPacket . InventoryBlock . ItemID = item . UUID ;
ScriptPacket . InventoryBlock . FolderID = item . ParentUUID ;
ScriptPacket . InventoryBlock . CreatorID = item . CreatorID ;
ScriptPacket . InventoryBlock . OwnerID = item . OwnerID ;
ScriptPacket . InventoryBlock . GroupID = item . GroupID ;
ScriptPacket . InventoryBlock . BaseMask = ( uint ) item . Permissions . BaseMask ;
ScriptPacket . InventoryBlock . OwnerMask = ( uint ) item . Permissions . OwnerMask ;
ScriptPacket . InventoryBlock . GroupMask = ( uint ) item . Permissions . GroupMask ;
ScriptPacket . InventoryBlock . EveryoneMask = ( uint ) item . Permissions . EveryoneMask ;
ScriptPacket . InventoryBlock . NextOwnerMask = ( uint ) item . Permissions . NextOwnerMask ;
ScriptPacket . InventoryBlock . GroupOwned = item . GroupOwned ;
ScriptPacket . InventoryBlock . TransactionID = transactionID ;
ScriptPacket . InventoryBlock . Type = ( sbyte ) item . AssetType ;
ScriptPacket . InventoryBlock . InvType = ( sbyte ) item . InventoryType ;
ScriptPacket . InventoryBlock . Flags = ( uint ) item . Flags ;
ScriptPacket . InventoryBlock . SaleType = ( byte ) item . SaleType ;
ScriptPacket . InventoryBlock . SalePrice = item . SalePrice ;
ScriptPacket . InventoryBlock . Name = Utils . StringToBytes ( item . Name ) ;
ScriptPacket . InventoryBlock . Description = Utils . StringToBytes ( item . Description ) ;
ScriptPacket . InventoryBlock . CreationDate = ( int ) Utils . DateTimeToUnixTime ( item . CreationDate ) ;
ScriptPacket . InventoryBlock . CRC = ItemCRC ( item ) ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( ScriptPacket ) ;
2009-04-06 07:24:02 +00:00
return transactionID ;
}
2009-05-13 20:35:47 +00:00
/// <summary>
2009-10-29 09:39:43 +00:00
/// Request the running status of a script contained in a task (primitive) inventory
2009-05-13 20:35:47 +00:00
/// </summary>
2009-10-29 09:39:43 +00:00
/// <param name="objectID">The ID of the primitive containing the script</param>
/// <param name="scriptID">The ID of the script</param>
/// <remarks>The <see cref="ScriptRunningReply"/> event can be used to obtain the results of the
/// request</remarks>
/// <seealso cref="ScriptRunningReply"/>
public void RequestGetScriptRunning ( UUID objectID , UUID scriptID )
2009-05-13 20:35:47 +00:00
{
GetScriptRunningPacket request = new GetScriptRunningPacket ( ) ;
request . Script . ObjectID = objectID ;
request . Script . ItemID = scriptID ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( request ) ;
2009-05-13 20:35:47 +00:00
}
2009-05-13 17:10:44 +00:00
/// <summary>
2009-10-29 09:39:43 +00:00
/// Send a request to set the running state of a script contained in a task (primitive) inventory
2009-05-13 17:10:44 +00:00
/// </summary>
2009-10-29 09:39:43 +00:00
/// <param name="objectID">The ID of the primitive containing the script</param>
/// <param name="scriptID">The ID of the script</param>
2009-05-13 17:10:44 +00:00
/// <param name="running">true to set the script running, false to stop a running script</param>
2009-10-29 09:39:43 +00:00
/// <remarks>To verify the change you can use the <see cref="RequestGetScriptRunning"/> method combined
/// with the <see cref="ScriptRunningReply"/> event</remarks>
public void RequestSetScriptRunning ( UUID objectID , UUID scriptID , bool running )
2009-05-13 17:10:44 +00:00
{
SetScriptRunningPacket request = new SetScriptRunningPacket ( ) ;
2009-10-29 09:39:43 +00:00
request . AgentData . AgentID = Client . Self . AgentID ;
2011-03-30 11:56:33 +00:00
request . AgentData . SessionID = Client . Self . SessionID ;
2009-05-13 17:10:44 +00:00
request . Script . Running = running ;
request . Script . ItemID = scriptID ;
request . Script . ObjectID = objectID ;
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( request ) ;
2009-05-13 17:10:44 +00:00
}
2007-11-06 09:26:10 +00:00
#endregion Task
#region Helper Functions
private uint RegisterItemCreatedCallback ( ItemCreatedCallback callback )
2007-09-10 10:20:30 +00:00
{
2007-11-06 09:26:10 +00:00
lock ( _CallbacksLock )
{
if ( _CallbackPos = = UInt32 . MaxValue )
_CallbackPos = 0 ;
_CallbackPos + + ;
if ( _ItemCreatedCallbacks . ContainsKey ( _CallbackPos ) )
2009-10-29 09:39:43 +00:00
Logger . Log ( "Overwriting an existing ItemCreatedCallback" , Helpers . LogLevel . Warning , Client ) ;
2007-11-06 09:26:10 +00:00
_ItemCreatedCallbacks [ _CallbackPos ] = callback ;
return _CallbackPos ;
}
2007-09-10 10:20:30 +00:00
}
2007-11-06 09:26:10 +00:00
private uint RegisterItemsCopiedCallback ( ItemCopiedCallback callback )
2007-09-10 10:20:30 +00:00
{
2007-11-06 09:26:10 +00:00
lock ( _CallbacksLock )
{
if ( _CallbackPos = = UInt32 . MaxValue )
_CallbackPos = 0 ;
2007-09-10 10:20:30 +00:00
2007-11-06 09:26:10 +00:00
_CallbackPos + + ;
if ( _ItemCopiedCallbacks . ContainsKey ( _CallbackPos ) )
2009-10-29 09:39:43 +00:00
Logger . Log ( "Overwriting an existing ItemsCopiedCallback" , Helpers . LogLevel . Warning , Client ) ;
2007-09-10 10:20:30 +00:00
2007-11-06 09:26:10 +00:00
_ItemCopiedCallbacks [ _CallbackPos ] = callback ;
return _CallbackPos ;
}
}
2007-09-10 10:20:30 +00:00
2008-05-03 04:10:02 +00:00
/// <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>
2008-08-21 01:19:06 +00:00
public static uint ItemCRC ( InventoryItem iitem )
2007-09-10 10:20:30 +00:00
{
2007-11-06 09:26:10 +00:00
uint CRC = 0 ;
// IDs
CRC + = iitem . AssetUUID . CRC ( ) ; // AssetID
CRC + = iitem . ParentUUID . CRC ( ) ; // FolderID
2008-03-06 05:57:16 +00:00
CRC + = iitem . UUID . CRC ( ) ; // ItemID
2007-09-10 10:20:30 +00:00
2007-11-06 09:26:10 +00:00
// Permission stuff
CRC + = iitem . CreatorID . CRC ( ) ; // CreatorID
CRC + = iitem . OwnerID . CRC ( ) ; // OwnerID
CRC + = iitem . GroupID . CRC ( ) ; // GroupID
2007-09-10 10:20:30 +00:00
2008-07-28 22:23:48 +00:00
// CRC += another 4 words which always seem to be zero -- unclear if this is a UUID or what
2007-11-06 09:26:10 +00:00
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;
2007-09-10 10:20:30 +00:00
2007-11-06 09:26:10 +00:00
// The rest of the CRC fields
2008-01-12 00:12:40 +00:00
CRC + = ( uint ) iitem . Flags ; // Flags
2007-11-06 09:26:10 +00:00
CRC + = ( uint ) iitem . InventoryType ; // InvType
CRC + = ( uint ) iitem . AssetType ; // Type
2008-08-12 22:38:02 +00:00
CRC + = ( uint ) Utils . DateTimeToUnixTime ( iitem . CreationDate ) ; // CreationDate
2007-11-06 09:26:10 +00:00
CRC + = ( uint ) iitem . SalePrice ; // SalePrice
CRC + = ( uint ) ( ( uint ) iitem . SaleType * 0x07073096 ) ; // SaleType
2007-09-10 10:20:30 +00:00
2007-11-06 09:26:10 +00:00
return CRC ;
2007-09-10 10:20:30 +00:00
}
2009-07-11 23:22:41 +00:00
/// <summary>
/// Reverses a cheesy XORing with a fixed UUID to convert a shadow_id to an asset_id
/// </summary>
/// <param name="shadowID">Obfuscated shadow_id value</param>
/// <returns>Deobfuscated asset_id value</returns>
public static UUID DecryptShadowID ( UUID shadowID )
{
return shadowID ^ MAGIC_ID ;
}
2009-07-29 17:29:36 +00:00
/// <summary>
/// Does a cheesy XORing with a fixed UUID to convert an asset_id to a shadow_id
/// </summary>
/// <param name="assetID">asset_id value to obfuscate</param>
/// <returns>Obfuscated shadow_id value</returns>
public static UUID EncryptAssetID ( UUID assetID )
{
return assetID ^ MAGIC_ID ;
}
2008-08-21 01:19:06 +00:00
/// <summary>
/// Wrapper for creating a new <seealso cref="InventoryItem"/> object
/// </summary>
/// <param name="type">The type of item from the <seealso cref="InventoryType"/> enum</param>
/// <param name="id">The <seealso cref="UUID"/> of the newly created object</param>
/// <returns>An <seealso cref="InventoryItem"/> object with the type and id passed</returns>
public static InventoryItem CreateInventoryItem ( InventoryType type , UUID id )
{
switch ( type )
{
case InventoryType . Texture : return new InventoryTexture ( id ) ;
case InventoryType . Sound : return new InventorySound ( id ) ;
case InventoryType . CallingCard : return new InventoryCallingCard ( id ) ;
case InventoryType . Landmark : return new InventoryLandmark ( id ) ;
case InventoryType . Object : return new InventoryObject ( id ) ;
case InventoryType . Notecard : return new InventoryNotecard ( id ) ;
case InventoryType . Category : return new InventoryCategory ( id ) ;
case InventoryType . LSL : return new InventoryLSL ( id ) ;
case InventoryType . Snapshot : return new InventorySnapshot ( id ) ;
case InventoryType . Attachment : return new InventoryAttachment ( id ) ;
case InventoryType . Wearable : return new InventoryWearable ( id ) ;
case InventoryType . Animation : return new InventoryAnimation ( id ) ;
case InventoryType . Gesture : return new InventoryGesture ( id ) ;
default : return new InventoryItem ( type , id ) ;
}
}
private InventoryItem SafeCreateInventoryItem ( InventoryType InvType , UUID ItemID )
{
InventoryItem ret = null ;
if ( _Store . Contains ( ItemID ) )
ret = _Store [ ItemID ] as InventoryItem ;
if ( ret = = null )
ret = CreateInventoryItem ( InvType , ItemID ) ;
return ret ;
}
2007-11-06 09:26:10 +00:00
private static bool ParseLine ( string line , out string key , out string value )
2007-09-10 10:20:30 +00:00
{
2007-11-06 09:26:10 +00:00
// Clean up and convert tabs to spaces
line = line . Trim ( ) ;
line = line . Replace ( '\t' , ' ' ) ;
// Shrink all whitespace down to single spaces
while ( line . IndexOf ( " " ) > 0 )
line = line . Replace ( " " , " " ) ;
if ( line . Length > 2 )
2007-09-10 10:20:30 +00:00
{
2007-11-06 09:26:10 +00:00
int sep = line . IndexOf ( ' ' ) ;
if ( sep > 0 )
2007-09-10 10:20:30 +00:00
{
2007-11-06 09:26:10 +00:00
key = line . Substring ( 0 , sep ) ;
value = line . Substring ( sep + 1 ) ;
return true ;
2007-09-10 10:20:30 +00:00
}
2007-11-06 09:26:10 +00:00
}
else if ( line . Length = = 1 )
{
key = line ;
value = String . Empty ;
return true ;
2007-09-10 10:20:30 +00:00
}
2007-11-06 09:26:10 +00:00
key = null ;
value = null ;
return false ;
2007-09-10 10:20:30 +00:00
}
2008-05-03 04:10:02 +00:00
/// <summary>
2008-05-05 02:02:29 +00:00
/// Parse the results of a RequestTaskInventory() response
2008-05-03 04:10:02 +00:00
/// </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>
2008-08-21 01:19:06 +00:00
public static List < InventoryBase > ParseTaskInventory ( string taskData )
2007-09-10 10:20:30 +00:00
{
2008-08-21 01:19:06 +00:00
List < InventoryBase > items = new List < InventoryBase > ( ) ;
2007-11-06 09:26:10 +00:00
int lineNum = 0 ;
string [ ] lines = taskData . Replace ( "\r\n" , "\n" ) . Split ( '\n' ) ;
while ( lineNum < lines . Length )
2007-09-10 10:20:30 +00:00
{
2007-11-06 09:26:10 +00:00
string key , value ;
if ( ParseLine ( lines [ lineNum + + ] , out key , out value ) )
2007-09-10 10:20:30 +00:00
{
2007-11-06 09:26:10 +00:00
if ( key = = "inv_object" )
2007-09-10 10:20:30 +00:00
{
2007-11-06 09:26:10 +00:00
#region inv_object
// In practice this appears to only be used for folders
2008-07-25 05:15:05 +00:00
UUID itemID = UUID . Zero ;
UUID parentID = UUID . Zero ;
2007-11-06 09:26:10 +00:00
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" )
{
2008-07-25 05:15:05 +00:00
UUID . TryParse ( value , out itemID ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "parent_id" )
{
2008-07-25 05:15:05 +00:00
UUID . TryParse ( value , out parentID ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "type" )
{
2009-04-09 01:17:40 +00:00
assetType = Utils . StringToAssetType ( value ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "name" )
{
name = value . Substring ( 0 , value . IndexOf ( '|' ) ) ;
}
}
}
if ( assetType = = AssetType . Folder )
{
2008-08-21 01:19:06 +00:00
InventoryFolder folder = new InventoryFolder ( itemID ) ;
folder . Name = name ;
folder . ParentUUID = parentID ;
2007-11-06 09:26:10 +00:00
2008-08-21 01:19:06 +00:00
items . Add ( folder ) ;
2007-11-06 09:26:10 +00:00
}
else
{
2008-08-21 01:19:06 +00:00
InventoryItem item = new InventoryItem ( itemID ) ;
item . Name = name ;
item . ParentUUID = parentID ;
item . AssetType = assetType ;
items . Add ( item ) ;
2007-11-06 09:26:10 +00:00
}
2007-09-10 10:20:30 +00:00
2007-11-06 09:26:10 +00:00
#endregion inv_object
}
else if ( key = = "inv_item" )
{
#region inv_item
// Any inventory item that links to an assetID, has permissions, etc
2008-07-25 05:15:05 +00:00
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 ;
2007-11-06 09:26:10 +00:00
bool groupOwned = false ;
string name = String . Empty ;
string desc = String . Empty ;
AssetType assetType = AssetType . Unknown ;
InventoryType inventoryType = InventoryType . Unknown ;
2008-08-12 22:38:02 +00:00
DateTime creationDate = Utils . Epoch ;
2007-11-06 09:26:10 +00:00
uint flags = 0 ;
Permissions perms = Permissions . NoPermissions ;
SaleType saleType = SaleType . Not ;
int salePrice = 0 ;
while ( lineNum < lines . Length )
2007-09-10 10:20:30 +00:00
{
2007-11-06 09:26:10 +00:00
if ( ParseLine ( lines [ lineNum + + ] , out key , out value ) )
2007-09-10 10:20:30 +00:00
{
2007-11-06 09:26:10 +00:00
if ( key = = "{" )
{
continue ;
}
else if ( key = = "}" )
{
break ;
}
else if ( key = = "item_id" )
{
2008-07-25 05:15:05 +00:00
UUID . TryParse ( value , out itemID ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "parent_id" )
{
2008-07-25 05:15:05 +00:00
UUID . TryParse ( value , out parentID ) ;
2007-11-06 09:26:10 +00:00
}
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 ;
2008-08-12 22:38:02 +00:00
if ( Utils . TryParseHex ( value , out val ) )
2007-11-06 09:26:10 +00:00
perms . BaseMask = ( PermissionMask ) val ;
}
else if ( key = = "base_mask" )
{
uint val ;
2008-08-12 22:38:02 +00:00
if ( Utils . TryParseHex ( value , out val ) )
2007-11-06 09:26:10 +00:00
perms . BaseMask = ( PermissionMask ) val ;
}
else if ( key = = "owner_mask" )
{
uint val ;
2008-08-12 22:38:02 +00:00
if ( Utils . TryParseHex ( value , out val ) )
2007-11-06 09:26:10 +00:00
perms . OwnerMask = ( PermissionMask ) val ;
}
else if ( key = = "group_mask" )
{
uint val ;
2008-08-12 22:38:02 +00:00
if ( Utils . TryParseHex ( value , out val ) )
2007-11-06 09:26:10 +00:00
perms . GroupMask = ( PermissionMask ) val ;
}
else if ( key = = "everyone_mask" )
{
uint val ;
2008-08-12 22:38:02 +00:00
if ( Utils . TryParseHex ( value , out val ) )
2007-11-06 09:26:10 +00:00
perms . EveryoneMask = ( PermissionMask ) val ;
}
else if ( key = = "next_owner_mask" )
{
uint val ;
2008-08-12 22:38:02 +00:00
if ( Utils . TryParseHex ( value , out val ) )
2007-11-06 09:26:10 +00:00
perms . NextOwnerMask = ( PermissionMask ) val ;
}
else if ( key = = "creator_id" )
{
2009-10-29 09:39:43 +00:00
2008-08-12 22:38:02 +00:00
UUID . TryParse ( value , out creatorID ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "owner_id" )
{
2008-08-12 22:38:02 +00:00
UUID . TryParse ( value , out ownerID ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "last_owner_id" )
{
2008-08-12 22:38:02 +00:00
UUID . TryParse ( value , out lastOwnerID ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "group_id" )
{
2008-08-12 22:38:02 +00:00
UUID . TryParse ( value , out groupID ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "group_owned" )
{
uint val ;
2008-08-12 22:38:02 +00:00
if ( UInt32 . TryParse ( value , out val ) )
2007-11-06 09:26:10 +00:00
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" )
{
2009-04-09 01:17:40 +00:00
saleType = Utils . StringToSaleType ( value ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "sale_price" )
{
2008-08-12 22:38:02 +00:00
Int32 . TryParse ( value , out salePrice ) ;
2007-11-06 09:26:10 +00:00
}
}
}
#endregion sale_info
}
else if ( key = = "shadow_id" )
{
2009-07-11 23:22:41 +00:00
UUID shadowID ;
if ( UUID . TryParse ( value , out shadowID ) )
assetID = DecryptShadowID ( shadowID ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "asset_id" )
{
2008-07-25 05:15:05 +00:00
UUID . TryParse ( value , out assetID ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "type" )
{
2009-04-09 01:17:40 +00:00
assetType = Utils . StringToAssetType ( value ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "inv_type" )
{
2009-04-09 01:17:40 +00:00
inventoryType = Utils . StringToInventoryType ( value ) ;
2007-11-06 09:26:10 +00:00
}
else if ( key = = "flags" )
{
2008-08-12 22:38:02 +00:00
UInt32 . TryParse ( value , out flags ) ;
2007-11-06 09:26:10 +00:00
}
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 ;
2008-08-12 22:38:02 +00:00
if ( UInt32 . TryParse ( value , out timestamp ) )
creationDate = Utils . UnixTimeToDateTime ( timestamp ) ;
2007-11-06 09:26:10 +00:00
else
2008-05-06 23:57:26 +00:00
Logger . Log ( "Failed to parse creation_date " + value , Helpers . LogLevel . Warning ) ;
2007-11-06 09:26:10 +00:00
}
2007-09-10 10:20:30 +00:00
}
}
2008-08-21 01:19:06 +00:00
InventoryItem item = CreateInventoryItem ( inventoryType , itemID ) ;
2007-11-06 09:26:10 +00:00
item . AssetUUID = assetID ;
item . AssetType = assetType ;
item . CreationDate = creationDate ;
item . CreatorID = creatorID ;
item . Description = desc ;
2008-05-05 02:02:29 +00:00
item . Flags = flags ;
2007-11-06 09:26:10 +00:00
item . GroupID = groupID ;
item . GroupOwned = groupOwned ;
item . Name = name ;
item . OwnerID = ownerID ;
2009-07-11 14:50:45 +00:00
item . LastOwnerID = lastOwnerID ;
2007-11-06 09:26:10 +00:00
item . ParentUUID = parentID ;
item . Permissions = perms ;
item . SalePrice = salePrice ;
item . SaleType = saleType ;
2008-08-21 01:19:06 +00:00
2007-11-06 09:26:10 +00:00
items . Add ( item ) ;
#endregion inv_item
2007-09-10 10:20:30 +00:00
}
else
{
2008-11-17 23:37:02 +00:00
Logger . Log ( "Unrecognized token " + key + " in: " + Environment . NewLine + taskData ,
2007-11-06 09:26:10 +00:00
Helpers . LogLevel . Error ) ;
2007-09-10 10:20:30 +00:00
}
}
}
2008-07-29 21:36:53 +00:00
2008-08-21 01:19:06 +00:00
return items ;
}
2009-10-29 09:39:43 +00:00
2007-11-06 09:26:10 +00:00
#endregion Helper Functions
2007-09-10 10:20:30 +00:00
2009-10-29 09:39:43 +00:00
#region Internal Callbacks
2007-07-13 14:49:36 +00:00
2009-10-16 02:53:53 +00:00
void Self_IM ( object sender , InstantMessageEventArgs e )
{
// TODO: MainAvatar.InstantMessageDialog.GroupNotice can also be an inventory offer, should we
// handle it here?
2009-10-29 09:39:43 +00:00
if ( m_InventoryObjectOffered ! = null & &
2009-10-16 02:53:53 +00:00
( e . IM . Dialog = = InstantMessageDialog . InventoryOffered
| | e . IM . Dialog = = InstantMessageDialog . TaskInventoryOffered ) )
{
AssetType type = AssetType . Unknown ;
UUID objectID = UUID . Zero ;
bool fromTask = false ;
if ( e . IM . Dialog = = InstantMessageDialog . InventoryOffered )
{
if ( e . IM . BinaryBucket . Length = = 17 )
{
type = ( AssetType ) e . IM . BinaryBucket [ 0 ] ;
objectID = new UUID ( e . IM . BinaryBucket , 1 ) ;
fromTask = false ;
}
else
{
2009-10-29 09:39:43 +00:00
Logger . Log ( "Malformed inventory offer from agent" , Helpers . LogLevel . Warning , Client ) ;
2009-10-16 02:53:53 +00:00
return ;
}
}
else if ( e . IM . Dialog = = InstantMessageDialog . TaskInventoryOffered )
{
if ( e . IM . BinaryBucket . Length = = 1 )
{
type = ( AssetType ) e . IM . BinaryBucket [ 0 ] ;
fromTask = true ;
}
else
{
2009-10-29 09:39:43 +00:00
Logger . Log ( "Malformed inventory offer from object" , Helpers . LogLevel . Warning , Client ) ;
2009-10-16 02:53:53 +00:00
return ;
}
}
// Find the folder where this is going to go
UUID destinationFolderID = FindFolderForType ( type ) ;
// Fire the callback
try
{
ImprovedInstantMessagePacket imp = new ImprovedInstantMessagePacket ( ) ;
2009-10-29 09:39:43 +00:00
imp . AgentData . AgentID = Client . Self . AgentID ;
imp . AgentData . SessionID = Client . Self . SessionID ;
2009-10-16 02:53:53 +00:00
imp . MessageBlock . FromGroup = false ;
imp . MessageBlock . ToAgentID = e . IM . FromAgentID ;
imp . MessageBlock . Offline = 0 ;
imp . MessageBlock . ID = e . IM . IMSessionID ;
imp . MessageBlock . Timestamp = 0 ;
2009-10-29 09:39:43 +00:00
imp . MessageBlock . FromAgentName = Utils . StringToBytes ( Client . Self . Name ) ;
2009-10-16 02:53:53 +00:00
imp . MessageBlock . Message = Utils . EmptyBytes ;
imp . MessageBlock . ParentEstateID = 0 ;
imp . MessageBlock . RegionID = UUID . Zero ;
2009-10-29 09:39:43 +00:00
imp . MessageBlock . Position = Client . Self . SimPosition ;
2009-11-07 15:05:44 +00:00
InventoryObjectOfferedEventArgs args = new InventoryObjectOfferedEventArgs ( e . IM , type , objectID , fromTask , destinationFolderID ) ;
2009-10-29 09:39:43 +00:00
OnInventoryObjectOffered ( args ) ;
2009-10-16 02:53:53 +00:00
2009-10-29 09:39:43 +00:00
if ( args . Accept )
2009-10-16 02:53:53 +00:00
{
// Accept the inventory offer
switch ( e . IM . Dialog )
{
case InstantMessageDialog . InventoryOffered :
imp . MessageBlock . Dialog = ( byte ) InstantMessageDialog . InventoryAccepted ;
break ;
case InstantMessageDialog . TaskInventoryOffered :
imp . MessageBlock . Dialog = ( byte ) InstantMessageDialog . TaskInventoryAccepted ;
break ;
case InstantMessageDialog . GroupNotice :
imp . MessageBlock . Dialog = ( byte ) InstantMessageDialog . GroupNoticeInventoryAccepted ;
2011-03-30 11:56:33 +00:00
break ;
2009-10-16 02:53:53 +00:00
}
2011-03-30 11:56:33 +00:00
imp . MessageBlock . BinaryBucket = args . FolderID . GetBytes ( ) ;
2009-10-16 02:53:53 +00:00
}
else
{
// Decline the inventory offer
switch ( e . IM . Dialog )
{
case InstantMessageDialog . InventoryOffered :
imp . MessageBlock . Dialog = ( byte ) InstantMessageDialog . InventoryDeclined ;
break ;
case InstantMessageDialog . TaskInventoryOffered :
imp . MessageBlock . Dialog = ( byte ) InstantMessageDialog . TaskInventoryDeclined ;
break ;
case InstantMessageDialog . GroupNotice :
imp . MessageBlock . Dialog = ( byte ) InstantMessageDialog . GroupNoticeInventoryDeclined ;
break ;
}
imp . MessageBlock . BinaryBucket = Utils . EmptyBytes ;
}
2009-10-29 09:39:43 +00:00
Client . Network . SendPacket ( imp , e . Simulator ) ;
2009-10-16 02:53:53 +00:00
}
catch ( Exception ex )
{
2009-10-29 09:39:43 +00:00
Logger . Log ( ex . Message , Helpers . LogLevel . Error , Client , ex ) ;
2009-10-16 02:53:53 +00:00
}
}
}
2008-10-30 01:50:59 +00:00
private void CreateItemFromAssetResponse ( CapsClient client , OSD result , Exception error )
2007-11-06 09:26:10 +00:00
{
2008-05-05 23:41:41 +00:00
object [ ] args = ( object [ ] ) client . UserData ;
2009-05-01 06:04:32 +00:00
ItemCreatedFromAssetCallback callback = ( ItemCreatedFromAssetCallback ) args [ 0 ] ;
byte [ ] itemData = ( byte [ ] ) args [ 1 ] ;
int millisecondsTimeout = ( int ) args [ 2 ] ;
2009-07-18 15:55:23 +00:00
OSDMap request = ( OSDMap ) args [ 3 ] ;
2009-10-29 09:39:43 +00:00
2008-02-03 04:02:14 +00:00
if ( result = = null )
{
2008-07-25 05:15:05 +00:00
try { callback ( false , error . Message , UUID . Zero , UUID . Zero ) ; }
2009-10-29 09:39:43 +00:00
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
2008-02-03 04:02:14 +00:00
return ;
}
2012-05-30 15:16:26 -07:00
if ( result . Type = = OSDType . Unknown )
{
try
{
callback ( false , "Failed to parse asset and item UUIDs" , UUID . Zero , UUID . Zero ) ;
}
catch ( Exception e )
{
Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ;
}
}
2008-10-30 01:50:59 +00:00
OSDMap contents = ( OSDMap ) result ;
2008-08-21 01:19:06 +00:00
2008-07-09 23:43:49 +00:00
string status = contents [ "state" ] . AsString ( ) . ToLower ( ) ;
2007-11-06 09:26:10 +00:00
if ( status = = "upload" )
{
2007-12-04 21:48:50 +00:00
string uploadURL = contents [ "uploader" ] . AsString ( ) ;
2007-11-06 09:26:10 +00:00
2008-07-09 23:43:49 +00:00
Logger . DebugLog ( "CreateItemFromAsset: uploading to " + uploadURL ) ;
2007-11-06 09:26:10 +00:00
// This makes the assumption that all uploads go to CurrentSim, to avoid
// the problem of HttpRequestState not knowing anything about simulators
2007-12-06 00:58:28 +00:00
CapsClient upload = new CapsClient ( new Uri ( uploadURL ) ) ;
2009-05-07 18:09:58 +00:00
upload . OnComplete + = CreateItemFromAssetResponse ;
2009-07-18 15:55:23 +00:00
upload . UserData = new object [ ] { callback , itemData , millisecondsTimeout , request } ;
2009-05-01 06:04:32 +00:00
upload . BeginGetResponse ( itemData , "application/octet-stream" , millisecondsTimeout ) ;
2007-11-06 09:26:10 +00:00
}
else if ( status = = "complete" )
{
2009-10-29 09:39:43 +00:00
Logger . DebugLog ( "CreateItemFromAsset: completed" ) ;
2008-07-09 23:43:49 +00:00
2007-11-06 09:26:10 +00:00
if ( contents . ContainsKey ( "new_inventory_item" ) & & contents . ContainsKey ( "new_asset" ) )
{
2009-08-19 07:25:30 +00:00
// Request full update on the item in order to update the local store
2009-10-29 09:39:43 +00:00
RequestFetchInventory ( contents [ "new_inventory_item" ] . AsUUID ( ) , Client . Self . AgentID ) ;
2009-07-18 15:55:23 +00:00
2007-12-04 21:48:50 +00:00
try { callback ( true , String . Empty , contents [ "new_inventory_item" ] . AsUUID ( ) , contents [ "new_asset" ] . AsUUID ( ) ) ; }
2009-10-29 09:39:43 +00:00
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
2007-11-06 09:26:10 +00:00
}
else
{
2008-07-25 05:15:05 +00:00
try { callback ( false , "Failed to parse asset and item UUIDs" , UUID . Zero , UUID . Zero ) ; }
2009-10-29 09:39:43 +00:00
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
2007-11-06 09:26:10 +00:00
}
}
else
{
// Failure
2008-07-25 05:15:05 +00:00
try { callback ( false , status , UUID . Zero , UUID . Zero ) ; }
2009-10-29 09:39:43 +00:00
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
2007-11-06 09:26:10 +00:00
}
}
2009-10-29 09:39:43 +00:00
private void Network_OnLoginResponse ( bool loginSuccess , bool redirect , string message , string reason , LoginResponseData replyData )
2007-09-10 10:20:30 +00:00
{
2009-10-29 09:39:43 +00:00
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 ] ) ;
}
}
private void UploadInventoryAssetResponse ( CapsClient client , OSD result , Exception error )
{
OSDMap contents = result as OSDMap ;
KeyValuePair < InventoryUploadedAssetCallback , byte [ ] > kvp = ( KeyValuePair < InventoryUploadedAssetCallback , byte [ ] > ) ( ( ( object [ ] ) client . UserData ) [ 0 ] ) ;
InventoryUploadedAssetCallback callback = kvp . Key ;
byte [ ] itemData = ( byte [ ] ) kvp . Value ;
if ( error = = null & & contents ! = null )
{
string status = contents [ "state" ] . AsString ( ) ;
if ( status = = "upload" )
{
Uri uploadURL = contents [ "uploader" ] . AsUri ( ) ;
if ( uploadURL ! = null )
{
// This makes the assumption that all uploads go to CurrentSim, to avoid
// the problem of HttpRequestState not knowing anything about simulators
CapsClient upload = new CapsClient ( uploadURL ) ;
upload . OnComplete + = UploadInventoryAssetResponse ;
upload . UserData = new object [ 2 ] { kvp , ( UUID ) ( ( ( object [ ] ) client . UserData ) [ 1 ] ) } ;
upload . BeginGetResponse ( itemData , "application/octet-stream" , Client . Settings . CAPS_TIMEOUT ) ;
}
else
{
try { callback ( false , "Missing uploader URL" , UUID . Zero , UUID . Zero ) ; }
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
}
}
else if ( status = = "complete" )
{
if ( contents . ContainsKey ( "new_asset" ) )
{
// Request full item update so we keep store in sync
RequestFetchInventory ( ( UUID ) ( ( ( object [ ] ) client . UserData ) [ 1 ] ) , contents [ "new_asset" ] . AsUUID ( ) ) ;
try { callback ( true , String . Empty , ( UUID ) ( ( ( object [ ] ) client . UserData ) [ 1 ] ) , contents [ "new_asset" ] . AsUUID ( ) ) ; }
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
}
else
{
try { callback ( false , "Failed to parse asset and item UUIDs" , UUID . Zero , UUID . Zero ) ; }
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
}
}
else
{
try { callback ( false , status , UUID . Zero , UUID . Zero ) ; }
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
}
}
else
{
string message = "Unrecognized or empty response" ;
if ( error ! = null )
{
if ( error is WebException )
message = ( ( HttpWebResponse ) ( ( WebException ) error ) . Response ) . StatusDescription ;
if ( message = = null | | message = = "None" )
message = error . Message ;
}
try { callback ( false , message , UUID . Zero , UUID . Zero ) ; }
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
}
}
private void UpdateScriptAgentInventoryResponse ( CapsClient client , OSD result , Exception error )
{
KeyValuePair < ScriptUpdatedCallback , byte [ ] > kvp = ( KeyValuePair < ScriptUpdatedCallback , byte [ ] > ) ( ( ( object [ ] ) client . UserData ) [ 0 ] ) ;
ScriptUpdatedCallback callback = kvp . Key ;
byte [ ] itemData = ( byte [ ] ) kvp . Value ;
if ( result = = null )
{
2010-03-01 13:58:42 +00:00
try { callback ( false , error . Message , false , null , UUID . Zero , UUID . Zero ) ; }
2009-10-29 09:39:43 +00:00
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
return ;
}
OSDMap contents = ( OSDMap ) result ;
string status = contents [ "state" ] . AsString ( ) ;
if ( status = = "upload" )
{
string uploadURL = contents [ "uploader" ] . AsString ( ) ;
CapsClient upload = new CapsClient ( new Uri ( uploadURL ) ) ;
upload . OnComplete + = new CapsClient . CompleteCallback ( UpdateScriptAgentInventoryResponse ) ;
upload . UserData = new object [ 2 ] { kvp , ( UUID ) ( ( ( object [ ] ) client . UserData ) [ 1 ] ) } ;
upload . BeginGetResponse ( itemData , "application/octet-stream" , Client . Settings . CAPS_TIMEOUT ) ;
}
else if ( status = = "complete" & & callback ! = null )
{
if ( contents . ContainsKey ( "new_asset" ) )
{
// Request full item update so we keep store in sync
RequestFetchInventory ( ( UUID ) ( ( ( object [ ] ) client . UserData ) [ 1 ] ) , contents [ "new_asset" ] . AsUUID ( ) ) ;
2011-03-30 11:56:33 +00:00
2010-03-01 13:58:42 +00:00
try
{
List < string > compileErrors = null ;
2011-03-30 11:56:33 +00:00
2010-03-01 13:58:42 +00:00
if ( contents . ContainsKey ( "errors" ) )
{
OSDArray errors = ( OSDArray ) contents [ "errors" ] ;
compileErrors = new List < string > ( errors . Count ) ;
2009-10-29 09:39:43 +00:00
2010-03-01 13:58:42 +00:00
for ( int i = 0 ; i < errors . Count ; i + + )
{
compileErrors . Add ( errors [ i ] . AsString ( ) ) ;
}
}
callback ( true ,
status ,
contents [ "compiled" ] . AsBoolean ( ) ,
compileErrors ,
( UUID ) ( ( ( object [ ] ) client . UserData ) [ 1 ] ) ,
contents [ "new_asset" ] . AsUUID ( ) ) ;
}
2009-10-29 09:39:43 +00:00
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
}
else
{
2010-03-01 13:58:42 +00:00
try { callback ( false , "Failed to parse asset UUID" , false , null , UUID . Zero , UUID . Zero ) ; }
2009-10-29 09:39:43 +00:00
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
}
}
else if ( callback ! = null )
{
2010-03-01 13:58:42 +00:00
try { callback ( false , status , false , null , UUID . Zero , UUID . Zero ) ; }
2009-10-29 09:39:43 +00:00
catch ( Exception e ) { Logger . Log ( e . Message , Helpers . LogLevel . Error , Client , e ) ; }
}
}
#endregion Internal Handlers
#region Packet Handlers
/// <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 SaveAssetIntoInventoryHandler ( object sender , PacketReceivedEventArgs e )
{
if ( m_SaveAssetToInventory ! = null )
2009-04-23 09:54:52 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
2009-10-29 09:39:43 +00:00
2009-04-23 09:54:52 +00:00
SaveAssetIntoInventoryPacket save = ( SaveAssetIntoInventoryPacket ) packet ;
2009-10-29 09:39:43 +00:00
OnSaveAssetToInventory ( new SaveAssetToInventoryEventArgs ( save . InventoryData . ItemID , save . InventoryData . NewAssetID ) ) ;
2009-04-23 09:54:52 +00:00
}
2007-09-10 10:20:30 +00:00
}
2009-10-29 09:39:43 +00:00
/// <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>
2009-10-28 08:01:52 +00:00
protected void InventoryDescendentsHandler ( object sender , PacketReceivedEventArgs e )
2007-07-13 14:49:36 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
2007-07-13 14:49:36 +00:00
InventoryDescendentsPacket reply = ( InventoryDescendentsPacket ) packet ;
2008-08-21 01:19:06 +00:00
2007-07-13 14:49:36 +00:00
if ( reply . AgentData . Descendents > 0 )
{
2007-11-06 09:26:10 +00:00
// InventoryDescendantsReply sends a null folder if the parent doesnt contain any folders
2008-07-25 05:15:05 +00:00
if ( reply . FolderData [ 0 ] . FolderID ! = UUID . Zero )
2007-07-13 14:49:36 +00:00
{
// Iterate folders in this packet
for ( int i = 0 ; i < reply . FolderData . Length ; i + + )
{
2009-06-27 20:51:14 +00:00
// 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 ;
2008-08-21 01:19:06 +00:00
2009-06-27 20:51:14 +00:00
_Store [ folder . UUID ] = folder ;
}
2007-07-13 14:49:36 +00:00
}
}
// InventoryDescendantsReply sends a null item if the parent doesnt contain any items.
2008-07-25 05:15:05 +00:00
if ( reply . ItemData [ 0 ] . ItemID ! = UUID . Zero )
2007-07-13 14:49:36 +00:00
{
// Iterate items in this packet
for ( int i = 0 ; i < reply . ItemData . Length ; i + + )
{
2008-07-25 05:15:05 +00:00
if ( reply . ItemData [ i ] . ItemID ! = UUID . Zero )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
InventoryItem item ;
2008-05-05 02:02:29 +00:00
/ *
* 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 .
* /
2009-10-29 09:39:43 +00:00
if ( ( AssetType ) reply . ItemData [ i ] . Type = = AssetType . Object
2008-05-05 02:02:29 +00:00
& & ( InventoryType ) reply . ItemData [ i ] . InvType = = InventoryType . Texture )
{
2008-08-21 01:19:06 +00:00
item = CreateInventoryItem ( InventoryType . Attachment , reply . ItemData [ i ] . ItemID ) ;
2008-05-05 02:02:29 +00:00
item . InventoryType = InventoryType . Attachment ;
}
else
{
2008-08-21 01:19:06 +00:00
item = CreateInventoryItem ( ( InventoryType ) reply . ItemData [ i ] . InvType , reply . ItemData [ i ] . ItemID ) ;
2008-05-05 02:02:29 +00:00
item . InventoryType = ( InventoryType ) reply . ItemData [ i ] . InvType ;
}
2009-10-29 09:39:43 +00:00
2007-07-13 14:49:36 +00:00
item . ParentUUID = reply . ItemData [ i ] . FolderID ;
2007-08-26 16:52:08 +00:00
item . CreatorID = reply . ItemData [ i ] . CreatorID ;
2007-07-13 14:49:36 +00:00
item . AssetType = ( AssetType ) reply . ItemData [ i ] . Type ;
item . AssetUUID = reply . ItemData [ i ] . AssetID ;
2008-08-12 22:38:02 +00:00
item . CreationDate = Utils . UnixTimeToDateTime ( ( uint ) reply . ItemData [ i ] . CreationDate ) ;
item . Description = Utils . BytesToString ( reply . ItemData [ i ] . Description ) ;
2008-05-05 02:02:29 +00:00
item . Flags = reply . ItemData [ i ] . Flags ;
2008-08-12 22:38:02 +00:00
item . Name = Utils . BytesToString ( reply . ItemData [ i ] . Name ) ;
2007-07-13 14:49:36 +00:00
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 ;
2008-08-21 01:19:06 +00:00
_Store [ item . UUID ] = item ;
2007-07-13 14:49:36 +00:00
}
}
}
}
2008-08-21 01:19:06 +00:00
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 ( ) +
2009-10-29 09:39:43 +00:00
" or it is not a folder" , Helpers . LogLevel . Error , Client ) ;
2008-08-21 01:19:06 +00:00
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 ,
2009-10-29 09:39:43 +00:00
Helpers . LogLevel . Warning , Client ) ;
2008-08-21 01:19:06 +00:00
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 ;
2009-06-28 16:13:58 +00:00
_Store . GetNodeFor ( reply . AgentData . FolderID ) . NeedsUpdate = false ;
2008-08-21 01:19:06 +00:00
#region FindObjectsByPath Handling
if ( _Searches . Count > 0 )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
lock ( _Searches )
2007-11-06 09:26:10 +00:00
{
2008-08-21 01:19:06 +00:00
StartSearch :
// Iterate over all of the outstanding searches
for ( int i = 0 ; i < _Searches . Count ; i + + )
2007-11-06 09:26:10 +00:00
{
2008-08-21 01:19:06 +00:00
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 + + )
2007-11-06 09:26:10 +00:00
{
2008-08-21 01:19:06 +00:00
// Check if this inventory object matches the current path node
if ( folderContents [ j ] . Name = = search . Path [ search . Level ] )
2007-11-06 09:26:10 +00:00
{
2008-08-21 01:19:06 +00:00
if ( search . Level = = search . Path . Length - 1 )
{
2009-10-29 09:39:43 +00:00
Logger . DebugLog ( "Finished path search of " + String . Join ( "/" , search . Path ) , Client ) ;
2007-11-06 09:26:10 +00:00
2008-08-21 01:19:06 +00:00
// This is the last node in the path, fire the callback and clean up
2009-10-29 09:39:43 +00:00
if ( m_FindObjectByPathReply ! = null )
2008-08-21 01:19:06 +00:00
{
2009-10-29 09:39:43 +00:00
OnFindObjectByPathReply ( new FindObjectByPathReplyEventArgs ( String . Join ( "/" , search . Path ) ,
folderContents [ j ] . UUID ) ) ;
2008-08-21 01:19:06 +00:00
}
2007-11-06 09:26:10 +00:00
2008-08-21 01:19:06 +00:00
// 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}" ,
2009-10-29 09:39:43 +00:00
search . Level , search . Path . Length - 1 , String . Join ( "/" , search . Path ) ) , Client ) ;
2008-08-12 05:55:42 +00:00
2008-08-21 01:19:06 +00:00
search . Folder = folderContents [ j ] . UUID ;
search . Level + + ;
_Searches [ i ] = search ;
2008-08-12 05:55:42 +00:00
2009-10-29 09:39:43 +00:00
RequestFolderContents ( search . Folder , search . Owner , true , true ,
2008-08-21 01:19:06 +00:00
InventorySortOrder . ByName ) ;
2008-08-13 06:03:00 +00:00
}
2007-11-06 09:26:10 +00:00
}
}
}
}
2007-07-13 14:49:36 +00:00
}
2008-08-21 01:19:06 +00:00
#endregion FindObjectsByPath Handling
// Callback for inventory folder contents being updated
2011-03-31 02:53:13 +00:00
OnFolderUpdated ( new FolderUpdatedEventArgs ( parentFolder . UUID , true ) ) ;
2007-07-13 14:49:36 +00:00
}
/// <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
2007-11-06 09:26:10 +00:00
/// packet, or when an object is purchased
2007-07-13 14:49:36 +00:00
/// </summary>
2009-10-29 09:39:43 +00:00
/// <param name="sender">The sender</param>
/// <param name="e">The EventArgs object containing the packet data</param>
2009-10-28 08:01:52 +00:00
protected void UpdateCreateInventoryItemHandler ( object sender , PacketReceivedEventArgs e )
2007-07-13 14:49:36 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
2009-10-29 09:39:43 +00:00
2007-07-13 14:49:36 +00:00
UpdateCreateInventoryItemPacket reply = packet as UpdateCreateInventoryItemPacket ;
foreach ( UpdateCreateInventoryItemPacket . InventoryDataBlock dataBlock in reply . InventoryData )
{
2007-11-06 09:26:10 +00:00
if ( dataBlock . InvType = = ( sbyte ) InventoryType . Folder )
{
2008-05-06 23:57:26 +00:00
Logger . Log ( "Received InventoryFolder in an UpdateCreateInventoryItem packet, this should not happen!" ,
2009-10-29 09:39:43 +00:00
Helpers . LogLevel . Error , Client ) ;
2007-07-13 14:49:36 +00:00
continue ;
}
2009-10-29 09:39:43 +00:00
InventoryItem item = CreateInventoryItem ( ( InventoryType ) dataBlock . InvType , dataBlock . ItemID ) ;
2007-07-13 14:49:36 +00:00
item . AssetType = ( AssetType ) dataBlock . Type ;
item . AssetUUID = dataBlock . AssetID ;
2008-08-12 22:38:02 +00:00
item . CreationDate = Utils . UnixTimeToDateTime ( dataBlock . CreationDate ) ;
2007-11-06 09:26:10 +00:00
item . CreatorID = dataBlock . CreatorID ;
2008-08-12 22:38:02 +00:00
item . Description = Utils . BytesToString ( dataBlock . Description ) ;
2008-05-05 02:02:29 +00:00
item . Flags = dataBlock . Flags ;
2007-07-13 14:49:36 +00:00
item . GroupID = dataBlock . GroupID ;
item . GroupOwned = dataBlock . GroupOwned ;
2008-08-12 22:38:02 +00:00
item . Name = Utils . BytesToString ( dataBlock . Name ) ;
2007-07-13 14:49:36 +00:00
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 ;
2008-10-19 00:16:58 +00:00
/ *
* When attaching new objects , an UpdateCreateInventoryItem packet will be
* returned by the server that has a FolderID / ParentUUID of zero . It is up
* to the client to make sure that the item gets a good folder , otherwise
* it will end up inaccesible in inventory .
* /
if ( item . ParentUUID = = UUID . Zero )
{
// assign default folder for type
item . ParentUUID = FindFolderForType ( item . AssetType ) ;
2009-07-10 19:36:59 +00:00
Logger . Log ( "Received an item through UpdateCreateInventoryItem with no parent folder, assigning to folder " +
item . ParentUUID , Helpers . LogLevel . Info ) ;
2008-10-19 00:16:58 +00:00
// send update to the sim
RequestUpdateItem ( item ) ;
}
2008-08-21 01:19:06 +00:00
// Update the local copy
_Store [ item . UUID ] = item ;
2007-11-06 09:26:10 +00:00
// Look for an "item created" callback
ItemCreatedCallback createdCallback ;
if ( _ItemCreatedCallbacks . TryGetValue ( dataBlock . CallbackID , out createdCallback ) )
2007-09-10 10:20:30 +00:00
{
_ItemCreatedCallbacks . Remove ( dataBlock . CallbackID ) ;
2007-11-06 09:26:10 +00:00
try { createdCallback ( true , item ) ; }
2009-10-29 09:39:43 +00:00
catch ( Exception ex ) { Logger . Log ( ex . Message , Helpers . LogLevel . Error , Client , ex ) ; }
2007-11-06 09:26:10 +00:00
}
2008-08-21 01:19:06 +00:00
// TODO: Is this callback even triggered when items are copied?
// Look for an "item copied" callback
ItemCopiedCallback copyCallback ;
if ( _ItemCopiedCallbacks . TryGetValue ( dataBlock . CallbackID , out copyCallback ) )
2008-07-29 23:38:07 +00:00
{
2008-08-21 01:19:06 +00:00
_ItemCopiedCallbacks . Remove ( dataBlock . CallbackID ) ;
try { copyCallback ( item ) ; }
2009-10-29 09:39:43 +00:00
catch ( Exception ex ) { Logger . Log ( ex . Message , Helpers . LogLevel . Error , Client , ex ) ; }
2008-07-29 23:38:07 +00:00
}
2009-10-29 09:39:43 +00:00
2007-11-06 09:26:10 +00:00
//This is triggered when an item is received from a task
2009-10-29 09:39:43 +00:00
if ( m_TaskItemReceived ! = null )
2007-11-06 09:26:10 +00:00
{
2009-10-29 09:39:43 +00:00
OnTaskItemReceived ( new TaskItemReceivedEventArgs ( item . UUID , dataBlock . FolderID ,
item . CreatorID , item . AssetUUID , item . InventoryType ) ) ;
2007-09-10 10:20:30 +00:00
}
}
}
2009-10-29 09:39:43 +00:00
/// <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>
2009-10-28 08:01:52 +00:00
protected void MoveInventoryItemHandler ( object sender , PacketReceivedEventArgs e )
2008-08-21 01:19:06 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
2009-10-29 09:39:43 +00:00
2008-08-21 01:19:06 +00:00
MoveInventoryItemPacket move = ( MoveInventoryItemPacket ) packet ;
for ( int i = 0 ; i < move . InventoryData . Length ; i + + )
{
// FIXME: Do something here
string newName = Utils . BytesToString ( move . InventoryData [ i ] . NewName ) ;
Logger . Log ( String . Format (
"MoveInventoryItemHandler: Item {0} is moving to Folder {1} with new name \"{2}\". Someone write this function!" ,
move . InventoryData [ i ] . ItemID . ToString ( ) , move . InventoryData [ i ] . FolderID . ToString ( ) ,
2009-10-29 09:39:43 +00:00
newName ) , Helpers . LogLevel . Warning , Client ) ;
2008-08-21 01:19:06 +00:00
}
}
2011-10-23 00:42:34 +00:00
protected void BulkUpdateInventoryCapHandler ( string capsKey , Interfaces . IMessage message , Simulator simulator )
{
BulkUpdateInventoryMessage msg = ( BulkUpdateInventoryMessage ) message ;
foreach ( BulkUpdateInventoryMessage . FolderDataInfo newFolder in msg . FolderData )
{
if ( newFolder . FolderID = = UUID . Zero ) continue ;
InventoryFolder folder ;
if ( ! _Store . Contains ( newFolder . FolderID ) )
{
folder = new InventoryFolder ( newFolder . FolderID ) ;
}
else
{
folder = ( InventoryFolder ) _Store [ newFolder . FolderID ] ;
}
folder . Name = newFolder . Name ;
folder . ParentUUID = newFolder . ParentID ;
folder . PreferredType = newFolder . Type ;
_Store [ folder . UUID ] = folder ;
}
foreach ( BulkUpdateInventoryMessage . ItemDataInfo newItem in msg . ItemData )
{
if ( newItem . ItemID = = UUID . Zero ) continue ;
2012-12-21 01:49:36 +01:00
InventoryType invType = newItem . InvType ;
2011-10-23 00:42:34 +00:00
2013-06-15 23:11:12 +02:00
lock ( _ItemInventoryTypeRequest )
2012-12-21 01:49:36 +01:00
{
2013-06-15 23:11:12 +02:00
InventoryType storedType = 0 ;
if ( _ItemInventoryTypeRequest . TryGetValue ( newItem . CallbackID , out storedType ) )
{
_ItemInventoryTypeRequest . Remove ( newItem . CallbackID ) ;
invType = storedType ;
}
2012-12-21 01:49:36 +01:00
}
InventoryItem item = SafeCreateInventoryItem ( invType , newItem . ItemID ) ;
2011-10-23 00:42:34 +00:00
item . AssetType = newItem . Type ;
item . AssetUUID = newItem . AssetID ;
item . CreationDate = newItem . CreationDate ;
item . CreatorID = newItem . CreatorID ;
item . Description = newItem . Description ;
item . Flags = newItem . Flags ;
item . GroupID = newItem . GroupID ;
item . GroupOwned = newItem . GroupOwned ;
item . Name = newItem . Name ;
item . OwnerID = newItem . OwnerID ;
item . ParentUUID = newItem . FolderID ;
item . Permissions . BaseMask = newItem . BaseMask ;
item . Permissions . EveryoneMask = newItem . EveryoneMask ;
item . Permissions . GroupMask = newItem . GroupMask ;
item . Permissions . NextOwnerMask = newItem . NextOwnerMask ;
item . Permissions . OwnerMask = newItem . OwnerMask ;
item . SalePrice = newItem . SalePrice ;
item . SaleType = newItem . SaleType ;
_Store [ item . UUID ] = item ;
// Look for an "item created" callback
ItemCreatedCallback callback ;
if ( _ItemCreatedCallbacks . TryGetValue ( newItem . CallbackID , out callback ) )
{
_ItemCreatedCallbacks . Remove ( newItem . 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 ( newItem . CallbackID , out copyCallback ) )
{
_ItemCopiedCallbacks . Remove ( newItem . CallbackID ) ;
try { copyCallback ( item ) ; }
catch ( Exception ex ) { Logger . Log ( ex . Message , Helpers . LogLevel . Error , Client , ex ) ; }
}
}
}
2009-10-29 09:39:43 +00:00
/// <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 )
2007-07-13 14:49:36 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
2009-10-29 09:39:43 +00:00
2007-07-13 14:49:36 +00:00
BulkUpdateInventoryPacket update = packet as BulkUpdateInventoryPacket ;
2008-07-25 05:15:05 +00:00
if ( update . FolderData . Length > 0 & & update . FolderData [ 0 ] . FolderID ! = UUID . Zero )
2007-07-13 14:49:36 +00:00
{
foreach ( BulkUpdateInventoryPacket . FolderDataBlock dataBlock in update . FolderData )
{
2011-10-22 21:08:43 +00:00
InventoryFolder folder ;
2008-08-21 01:19:06 +00:00
if ( ! _Store . Contains ( dataBlock . FolderID ) )
2011-10-22 21:08:43 +00:00
{
folder = new InventoryFolder ( dataBlock . FolderID ) ;
}
else
{
folder = ( InventoryFolder ) _Store [ dataBlock . FolderID ] ;
}
2008-08-21 01:19:06 +00:00
2011-10-22 21:08:43 +00:00
if ( dataBlock . Name ! = null )
{
folder . Name = Utils . BytesToString ( dataBlock . Name ) ;
}
2008-08-21 01:19:06 +00:00
folder . OwnerID = update . AgentData . AgentID ;
folder . ParentUUID = dataBlock . ParentID ;
_Store [ folder . UUID ] = folder ;
2007-07-13 14:49:36 +00:00
}
}
2008-07-25 05:15:05 +00:00
if ( update . ItemData . Length > 0 & & update . ItemData [ 0 ] . ItemID ! = UUID . Zero )
2007-07-13 14:49:36 +00:00
{
2007-11-06 09:26:10 +00:00
for ( int i = 0 ; i < update . ItemData . Length ; i + + )
2007-07-13 14:49:36 +00:00
{
2007-11-06 09:26:10 +00:00
BulkUpdateInventoryPacket . ItemDataBlock dataBlock = update . ItemData [ i ] ;
2008-08-21 01:19:06 +00:00
InventoryItem item = SafeCreateInventoryItem ( ( InventoryType ) dataBlock . InvType , dataBlock . ItemID ) ;
2007-07-13 14:49:36 +00:00
item . AssetType = ( AssetType ) dataBlock . Type ;
2008-07-25 05:15:05 +00:00
if ( dataBlock . AssetID ! = UUID . Zero ) item . AssetUUID = dataBlock . AssetID ;
2008-08-12 22:38:02 +00:00
item . CreationDate = Utils . UnixTimeToDateTime ( dataBlock . CreationDate ) ;
2007-11-06 09:26:10 +00:00
item . CreatorID = dataBlock . CreatorID ;
2008-08-12 22:38:02 +00:00
item . Description = Utils . BytesToString ( dataBlock . Description ) ;
2008-05-05 02:02:29 +00:00
item . Flags = dataBlock . Flags ;
2007-07-13 14:49:36 +00:00
item . GroupID = dataBlock . GroupID ;
item . GroupOwned = dataBlock . GroupOwned ;
2008-08-12 22:38:02 +00:00
item . Name = Utils . BytesToString ( dataBlock . Name ) ;
2007-07-13 14:49:36 +00:00
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 ;
2008-08-21 01:19:06 +00:00
_Store [ item . UUID ] = item ;
2007-11-06 09:26:10 +00:00
// Look for an "item created" callback
2007-09-10 10:20:30 +00:00
ItemCreatedCallback callback ;
if ( _ItemCreatedCallbacks . TryGetValue ( dataBlock . CallbackID , out callback ) )
{
_ItemCreatedCallbacks . Remove ( dataBlock . CallbackID ) ;
try { callback ( true , item ) ; }
2009-10-29 09:39:43 +00:00
catch ( Exception ex ) { Logger . Log ( ex . Message , Helpers . LogLevel . Error , Client , ex ) ; }
2007-09-10 10:20:30 +00:00
}
2007-11-06 09:26:10 +00:00
// Look for an "item copied" callback
ItemCopiedCallback copyCallback ;
if ( _ItemCopiedCallbacks . TryGetValue ( dataBlock . CallbackID , out copyCallback ) )
{
_ItemCopiedCallbacks . Remove ( dataBlock . CallbackID ) ;
try { copyCallback ( item ) ; }
2009-10-29 09:39:43 +00:00
catch ( Exception ex ) { Logger . Log ( ex . Message , Helpers . LogLevel . Error , Client , ex ) ; }
2007-11-06 09:26:10 +00:00
}
2007-07-13 14:49:36 +00:00
}
}
}
2009-10-29 09:39:43 +00:00
/// <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 FetchInventoryReplyHandler ( object sender , PacketReceivedEventArgs e )
2007-07-13 14:49:36 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
2009-10-29 09:39:43 +00:00
2008-08-21 01:19:06 +00:00
FetchInventoryReplyPacket reply = packet as FetchInventoryReplyPacket ;
2009-10-29 09:39:43 +00:00
foreach ( FetchInventoryReplyPacket . InventoryDataBlock dataBlock in reply . InventoryData )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
if ( dataBlock . InvType = = ( sbyte ) InventoryType . Folder )
2007-07-13 14:49:36 +00:00
{
2008-08-21 01:19:06 +00:00
Logger . Log ( "Received FetchInventoryReply for an inventory folder, this should not happen!" ,
2009-10-29 09:39:43 +00:00
Helpers . LogLevel . Error , Client ) ;
2008-08-21 01:19:06 +00:00
continue ;
}
2007-07-13 14:49:36 +00:00
2009-07-10 19:36:59 +00:00
InventoryItem item = CreateInventoryItem ( ( InventoryType ) dataBlock . InvType , dataBlock . ItemID ) ;
2008-08-21 01:19:06 +00:00
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 ;
2009-07-10 19:36:59 +00:00
item . InventoryType = ( InventoryType ) dataBlock . InvType ;
2008-08-21 01:19:06 +00:00
item . Name = Utils . BytesToString ( dataBlock . Name ) ;
item . OwnerID = dataBlock . OwnerID ;
item . ParentUUID = dataBlock . FolderID ;
item . Permissions = new Permissions (
2009-10-29 09:39:43 +00:00
dataBlock . BaseMask ,
dataBlock . EveryoneMask ,
dataBlock . GroupMask ,
dataBlock . NextOwnerMask ,
2008-08-21 01:19:06 +00:00
dataBlock . OwnerMask ) ;
item . SalePrice = dataBlock . SalePrice ;
item . SaleType = ( SaleType ) dataBlock . SaleType ;
2009-07-10 19:36:59 +00:00
item . UUID = dataBlock . ItemID ;
2007-11-06 09:26:10 +00:00
2008-08-21 01:19:06 +00:00
_Store [ item . UUID ] = item ;
// Fire the callback for an item being fetched
2012-12-18 02:31:40 +01:00
OnItemReceived ( new ItemReceivedEventArgs ( item ) ) ;
2007-11-06 09:26:10 +00:00
}
}
2009-10-29 09:39:43 +00:00
/// <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 ReplyTaskInventoryHandler ( object sender , PacketReceivedEventArgs e )
2007-11-06 09:26:10 +00:00
{
2009-10-29 09:39:43 +00:00
if ( m_TaskInventoryReply ! = null )
2007-11-06 09:26:10 +00:00
{
2009-10-28 08:01:52 +00:00
Packet packet = e . Packet ;
2009-10-29 09:39:43 +00:00
2007-11-06 09:26:10 +00:00
ReplyTaskInventoryPacket reply = ( ReplyTaskInventoryPacket ) packet ;
2009-10-29 09:39:43 +00:00
OnTaskInventoryReply ( new TaskInventoryReplyEventArgs ( reply . InventoryData . TaskID , reply . InventoryData . Serial ,
Utils . BytesToString ( reply . InventoryData . Filename ) ) ) ;
2007-07-13 14:49:36 +00:00
}
}
2011-03-30 11:56:33 +00:00
2009-10-29 09:39:43 +00:00
protected void ScriptRunningReplyMessageHandler ( string capsKey , Interfaces . IMessage message , Simulator simulator )
2007-09-10 10:20:30 +00:00
{
2009-10-29 09:39:43 +00:00
if ( m_ScriptRunningReply ! = null )
2007-09-10 10:20:30 +00:00
{
2009-10-29 09:39:43 +00:00
ScriptRunningReplyMessage msg = ( ScriptRunningReplyMessage ) message ;
OnScriptRunningReply ( new ScriptRunningReplyEventArgs ( msg . ObjectID , msg . ItemID , msg . Mono , msg . Running ) ) ;
2007-09-10 10:20:30 +00:00
}
}
2009-10-29 09:39:43 +00:00
#endregion Packet Handlers
}
2008-03-12 22:46:53 +00:00
2009-10-29 09:39:43 +00:00
#region EventArgs
2011-03-30 11:56:33 +00:00
2009-10-29 09:39:43 +00:00
public class InventoryObjectOfferedEventArgs : EventArgs
{
private readonly InstantMessage m_Offer ;
private readonly AssetType m_AssetType ;
private readonly UUID m_ObjectID ;
private readonly bool m_FromTask ;
/// <summary>Set to true to accept offer, false to decline it</summary>
public bool Accept { get ; set ; }
2009-11-07 14:57:56 +00:00
/// <summary>The folder to accept the inventory into, if null default folder for <see cref="AssetType"/> will be used</summary>
public UUID FolderID { get ; set ; }
2009-10-29 09:39:43 +00:00
public InstantMessage Offer { get { return m_Offer ; } }
public AssetType AssetType { get { return m_AssetType ; } }
public UUID ObjectID { get { return m_ObjectID ; } }
public bool FromTask { get { return m_FromTask ; } }
2011-03-30 11:56:33 +00:00
2009-11-07 15:05:44 +00:00
public InventoryObjectOfferedEventArgs ( InstantMessage offerDetails , AssetType type , UUID objectID , bool fromTask , UUID folderID )
2009-10-29 09:39:43 +00:00
{
this . Accept = false ;
2009-11-07 15:05:44 +00:00
this . FolderID = folderID ;
2009-10-29 09:39:43 +00:00
this . m_Offer = offerDetails ;
this . m_AssetType = type ;
this . m_ObjectID = objectID ;
this . m_FromTask = fromTask ;
}
}
2011-03-30 11:56:33 +00:00
2009-10-29 09:39:43 +00:00
public class FolderUpdatedEventArgs : EventArgs
{
private readonly UUID m_FolderID ;
public UUID FolderID { get { return m_FolderID ; } }
2011-03-31 02:53:13 +00:00
private readonly bool m_Success ;
public bool Success { get { return m_Success ; } }
public FolderUpdatedEventArgs ( UUID folderID , bool success )
2009-10-29 09:39:43 +00:00
{
this . m_FolderID = folderID ;
2011-03-31 02:53:13 +00:00
this . m_Success = success ;
2009-10-29 09:39:43 +00:00
}
}
2009-07-09 22:24:04 +00:00
2009-10-29 09:39:43 +00:00
public class ItemReceivedEventArgs : EventArgs
{
private readonly InventoryItem m_Item ;
2009-08-19 07:25:30 +00:00
2009-10-29 09:39:43 +00:00
public InventoryItem Item { get { return m_Item ; } }
2009-07-10 19:36:59 +00:00
2009-10-29 09:39:43 +00:00
public ItemReceivedEventArgs ( InventoryItem item )
{
this . m_Item = item ;
}
}
2011-03-30 11:56:33 +00:00
2009-10-29 09:39:43 +00:00
public class FindObjectByPathReplyEventArgs : EventArgs
{
private readonly String m_Path ;
private readonly UUID m_InventoryObjectID ;
2009-07-10 20:20:49 +00:00
2009-10-29 09:39:43 +00:00
public String Path { get { return m_Path ; } }
public UUID InventoryObjectID { get { return m_InventoryObjectID ; } }
2009-07-10 19:36:59 +00:00
2009-10-29 09:39:43 +00:00
public FindObjectByPathReplyEventArgs ( string path , UUID inventoryObjectID )
{
this . m_Path = path ;
this . m_InventoryObjectID = inventoryObjectID ;
2008-03-12 22:46:53 +00:00
}
2009-10-29 09:39:43 +00:00
}
2008-03-12 22:46:53 +00:00
2009-10-29 09:39:43 +00:00
/// <summary>
/// Callback when an inventory object is accepted and received from a
/// task inventory. This is the callback in which you actually get
/// the ItemID, as in ObjectOfferedCallback it is null when received
/// from a task.
/// </summary>
public class TaskItemReceivedEventArgs : EventArgs
{
private readonly UUID m_ItemID ;
private readonly UUID m_FolderID ;
private readonly UUID m_CreatorID ;
private readonly UUID m_AssetID ;
private readonly InventoryType m_Type ;
public UUID ItemID { get { return m_ItemID ; } }
public UUID FolderID { get { return m_FolderID ; } }
public UUID CreatorID { get { return m_CreatorID ; } }
public UUID AssetID { get { return m_AssetID ; } }
public InventoryType Type { get { return m_Type ; } }
public TaskItemReceivedEventArgs ( UUID itemID , UUID folderID , UUID creatorID , UUID assetID , InventoryType type )
2009-05-09 02:23:39 +00:00
{
2009-10-29 09:39:43 +00:00
this . m_ItemID = itemID ;
this . m_FolderID = folderID ;
this . m_CreatorID = creatorID ;
this . m_AssetID = assetID ;
this . m_Type = type ;
}
}
2011-03-30 11:56:33 +00:00
2009-10-29 09:39:43 +00:00
public class TaskInventoryReplyEventArgs : EventArgs
{
private readonly UUID m_ItemID ;
private readonly Int16 m_Serial ;
private readonly String m_AssetFilename ;
2009-05-09 02:23:39 +00:00
2009-10-29 09:39:43 +00:00
public UUID ItemID { get { return m_ItemID ; } }
public Int16 Serial { get { return m_Serial ; } }
public String AssetFilename { get { return m_AssetFilename ; } }
2009-05-09 02:23:39 +00:00
2009-10-29 09:39:43 +00:00
public TaskInventoryReplyEventArgs ( UUID itemID , short serial , string assetFilename )
{
this . m_ItemID = itemID ;
this . m_Serial = serial ;
this . m_AssetFilename = assetFilename ;
}
}
2011-03-30 11:56:33 +00:00
2009-10-29 09:39:43 +00:00
public class SaveAssetToInventoryEventArgs : EventArgs
{
private readonly UUID m_ItemID ;
private readonly UUID m_NewAssetID ;
2009-05-09 02:23:39 +00:00
2009-10-29 09:39:43 +00:00
public UUID ItemID { get { return m_ItemID ; } }
2011-03-30 11:56:33 +00:00
public UUID NewAssetID { get { return m_NewAssetID ; } }
2009-08-19 07:25:30 +00:00
2009-10-29 09:39:43 +00:00
public SaveAssetToInventoryEventArgs ( UUID itemID , UUID newAssetID )
{
this . m_ItemID = itemID ;
this . m_NewAssetID = newAssetID ;
2009-05-09 02:23:39 +00:00
}
2009-10-29 09:39:43 +00:00
}
2011-03-30 11:56:33 +00:00
2009-10-29 09:39:43 +00:00
public class ScriptRunningReplyEventArgs : EventArgs
{
private readonly UUID m_ObjectID ;
private readonly UUID m_ScriptID ;
private readonly bool m_IsMono ;
private readonly bool m_IsRunning ;
public UUID ObjectID { get { return m_ObjectID ; } }
public UUID ScriptID { get { return m_ScriptID ; } }
public bool IsMono { get { return m_IsMono ; } }
2011-03-30 11:56:33 +00:00
public bool IsRunning { get { return m_IsRunning ; } }
2009-05-09 02:23:39 +00:00
2009-10-29 09:39:43 +00:00
public ScriptRunningReplyEventArgs ( UUID objectID , UUID sctriptID , bool isMono , bool isRunning )
2009-05-13 23:53:16 +00:00
{
2009-10-29 09:39:43 +00:00
this . m_ObjectID = objectID ;
this . m_ScriptID = sctriptID ;
this . m_IsMono = isMono ;
this . m_IsRunning = isRunning ;
2009-05-13 23:53:16 +00:00
}
2007-07-14 00:27:23 +00:00
}
2009-10-29 09:39:43 +00:00
#endregion
2007-07-13 14:49:36 +00:00
}