Files
libremetaverse/libsecondlife-cs/InventorySystem/InventoryPacketHelper.cs
Michael Cortez b686cebf3d Begining major rework of Asset/Inventory code. Doing a lot of refectoing. What's in here so far?
+ Inventory, Asset and Image managers are now directly apart of the SecondLife class
+ Root Inventory folder has been added to MainAvatar and is set upon login
+ Inventory is no longer downloaded all at once, you have to request the download of individual folders
+ Folder downloading is available Asynchronously, and returns a object that has a ManualResetEvent that you can use to optionally block with
+ The code for AssetManager has been reworked some in prep for allowing Wearables to be Saved/Loaded to/from disk, and for creating new wearables.


git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@742 52acb1d6-8a22-11de-b505-999d5b087335
2006-12-19 23:13:04 +00:00

398 lines
13 KiB
C#

using System;
using System.Collections.Generic;
using libsecondlife;
using libsecondlife.Packets;
namespace libsecondlife.InventorySystem
{
/// <summary>
/// Summary description for Other.
/// </summary>
public class InventoryPacketHelper
{
private SecondLife Client;
private LLUUID AgentID
{
get { return Client.Network.AgentID; }
}
private LLUUID SessionID
{
get { return Client.Network.SessionID; }
}
public InventoryPacketHelper(SecondLife client)
{
Client = client;
}
public const int FETCH_INVENTORY_SORT_NAME = 0;
public const int FETCH_INVENTORY_SORT_TIME = 1;
public Packet FetchInventoryDescendents( LLUUID folderID )
{
return FetchInventoryDescendents( folderID, true, true );
}
public Packet FetchInventoryDescendents( LLUUID folderID, bool fetchFolders, bool fetchItems )
{
FetchInventoryDescendentsPacket p = new FetchInventoryDescendentsPacket();
p.InventoryData.OwnerID = AgentID;
p.InventoryData.FolderID = folderID;
p.InventoryData.SortOrder = FETCH_INVENTORY_SORT_NAME;
p.InventoryData.FetchFolders = fetchFolders;
p.InventoryData.FetchItems = fetchItems;
p.AgentData.AgentID = AgentID;
p.AgentData.SessionID = SessionID;
return p;
}
public Packet FetchInventory(LLUUID OwnerID, LLUUID ItemID)
{
FetchInventoryPacket p = new FetchInventoryPacket();
p.InventoryData = new FetchInventoryPacket.InventoryDataBlock[1];
p.InventoryData[0] = new FetchInventoryPacket.InventoryDataBlock();
p.InventoryData[0].OwnerID = OwnerID;
p.InventoryData[0].ItemID = ItemID;
p.AgentData.AgentID = AgentID;
p.AgentData.SessionID = SessionID;
return p;
}
public Packet CreateInventoryFolder(
string name
, LLUUID parentID
, sbyte type
, LLUUID folderID
)
{
CreateInventoryFolderPacket p = new CreateInventoryFolderPacket();
p.AgentData.AgentID = AgentID;
p.AgentData.SessionID = SessionID;
p.FolderData.Name = Helpers.StringToField(name);
p.FolderData.ParentID = parentID;
p.FolderData.Type = type;
p.FolderData.FolderID = folderID;
return p;
}
public Packet MoveInventoryFolder(
LLUUID parentID
, LLUUID folderID
)
{
MoveInventoryFolderPacket p = new MoveInventoryFolderPacket();
p.AgentData.AgentID = AgentID;
p.AgentData.SessionID = SessionID;
p.AgentData.Stamp = false;
p.InventoryData = new MoveInventoryFolderPacket.InventoryDataBlock[1];
p.InventoryData[0] = new MoveInventoryFolderPacket.InventoryDataBlock();
p.InventoryData[0].ParentID = parentID;
p.InventoryData[0].FolderID = folderID;
return p;
}
public Packet RemoveInventoryFolder(
LLUUID folderID
)
{
RemoveInventoryFolderPacket p = new RemoveInventoryFolderPacket();
p.AgentData.AgentID = AgentID;
p.AgentData.SessionID = SessionID;
p.FolderData = new RemoveInventoryFolderPacket.FolderDataBlock[1];
p.FolderData[0] = new RemoveInventoryFolderPacket.FolderDataBlock();
p.FolderData[0].FolderID = folderID;
return p;
}
public Packet UpdateInventoryFolder(
string name
, LLUUID parentID
, sbyte type
, LLUUID folderID
)
{
UpdateInventoryFolderPacket p = new UpdateInventoryFolderPacket();
p.AgentData.AgentID = AgentID;
p.AgentData.SessionID = SessionID;
p.FolderData = new UpdateInventoryFolderPacket.FolderDataBlock[1];
p.FolderData[0] = new UpdateInventoryFolderPacket.FolderDataBlock();
p.FolderData[0].Name = Helpers.StringToField(name);
p.FolderData[0].ParentID = parentID;
p.FolderData[0].Type = type;
p.FolderData[0].FolderID = folderID;
return p;
}
public Packet MoveInventoryItem(
LLUUID itemID
, LLUUID folderID
)
{
Console.WriteLine("WARNING: Using the new MoveInventoryItem packet, without specifying new folder name has unknown results.");
return MoveInventoryItem( itemID, folderID, null );
}
public Packet MoveInventoryItem(
LLUUID itemID
, LLUUID folderID
, string newFolderName
)
{
MoveInventoryItemPacket p = new MoveInventoryItemPacket();
p.AgentData.AgentID = AgentID;
p.AgentData.SessionID = SessionID;
p.AgentData.Stamp = true;
p.InventoryData = new MoveInventoryItemPacket.InventoryDataBlock[1];
p.InventoryData[0] = new MoveInventoryItemPacket.InventoryDataBlock();
p.InventoryData[0].ItemID = itemID;
p.InventoryData[0].FolderID = folderID;
if (newFolderName != null)
{
p.InventoryData[0].NewName = Helpers.StringToField(newFolderName);
}
return p;
}
public Packet CopyInventoryItem(
LLUUID itemID
, LLUUID folderID
)
{
return CopyInventoryItem( itemID, folderID, null );
}
public Packet CopyInventoryItem(
LLUUID itemID
, LLUUID folderID
, string newItemName
)
{
CopyInventoryItemPacket p = new CopyInventoryItemPacket();
p.AgentData.AgentID = AgentID;
p.AgentData.SessionID = SessionID;
p.InventoryData = new CopyInventoryItemPacket.InventoryDataBlock[1];
p.InventoryData[0] = new CopyInventoryItemPacket.InventoryDataBlock();
p.InventoryData[0].CallbackID = 0;
p.InventoryData[0].OldAgentID = AgentID; //TODO: Find out what this is supposed to be. Added field 10/11/06, no docs in Message Template
p.InventoryData[0].OldItemID = itemID;
p.InventoryData[0].NewFolderID = folderID;
if (newItemName != null)
{
p.InventoryData[0].NewName = Helpers.StringToField(newItemName);
}
return p;
}
public Packet RemoveInventoryItem(
LLUUID itemID
)
{
RemoveInventoryItemPacket p = new RemoveInventoryItemPacket();
p.AgentData.AgentID = AgentID;
p.AgentData.SessionID = SessionID;
p.InventoryData = new RemoveInventoryItemPacket.InventoryDataBlock[1];
p.InventoryData[0] = new RemoveInventoryItemPacket.InventoryDataBlock();
p.InventoryData[0].ItemID = itemID;
return p;
}
public Packet GiveItemViaImprovedInstantMessage(
LLUUID ID
, LLUUID ToAgentID
, String FromAgentName
, LLVector3 FromAgentLoc
, InventoryItem Item
)
{
byte[] BinaryBucket = new byte[17];
BinaryBucket[0] = (byte)Item.Type;
Array.Copy(Item.ItemID.Data, 0, BinaryBucket, 1, 16);
ImprovedInstantMessagePacket p = new ImprovedInstantMessagePacket();
p.AgentData.AgentID = AgentID;
p.AgentData.SessionID = SessionID;
p.MessageBlock.ID = ID;
p.MessageBlock.ToAgentID = ToAgentID;
p.MessageBlock.Offline = (byte)0;
p.MessageBlock.Timestamp = Helpers.GetUnixTime();
p.MessageBlock.Message = Helpers.StringToField(Item.Name);
p.MessageBlock.Dialog = (byte)4;
p.MessageBlock.BinaryBucket = BinaryBucket;
p.MessageBlock.FromAgentName = Helpers.StringToField(FromAgentName);
p.MessageBlock.Position = FromAgentLoc;
// TODO: Either overload this method to allow inclusion of region info or
// overload the ImprovedInstantMessage in the avatar class to allow item payloads
p.MessageBlock.RegionID = LLUUID.Zero;
p.MessageBlock.ParentEstateID = (uint)0;
return p;
}
public Packet CreateInventoryItem(InventoryItem iitem)
{
CreateInventoryItemPacket p = new CreateInventoryItemPacket();
p.InventoryBlock.CallbackID = 0;
p.InventoryBlock.TransactionID = LLUUID.Zero;
p.InventoryBlock.WearableType = 0; //TODO: Specify the current type here
p.InventoryBlock.Type = iitem.Type;
p.InventoryBlock.InvType = iitem.InvType;
p.InventoryBlock.Name = Helpers.StringToField(iitem.Name);
p.InventoryBlock.FolderID = iitem.FolderID;
p.InventoryBlock.Description = Helpers.StringToField(iitem.Description);
p.InventoryBlock.NextOwnerMask = iitem.NextOwnerMask;
p.AgentData.AgentID = AgentID;
p.AgentData.SessionID = SessionID;
return p;
}
public Packet UpdateInventoryItem(InventoryItem iitem)
{
UpdateInventoryItemPacket p = new UpdateInventoryItemPacket();
p.InventoryData = new UpdateInventoryItemPacket.InventoryDataBlock[1];
p.InventoryData[0] = new UpdateInventoryItemPacket.InventoryDataBlock();
p.InventoryData[0].TransactionID = iitem.TransactionID;
p.InventoryData[0].GroupOwned = iitem.GroupOwned;
p.InventoryData[0].CRC = iitem.CRC;
p.InventoryData[0].CreationDate = iitem.CreationDate;
p.InventoryData[0].SaleType = iitem.SaleType;
p.InventoryData[0].BaseMask = iitem.BaseMask;
p.InventoryData[0].Name = Helpers.StringToField(iitem.Name);
p.InventoryData[0].InvType = iitem.InvType;
p.InventoryData[0].Type = iitem.Type;
p.InventoryData[0].GroupID = iitem.GroupID;
p.InventoryData[0].SalePrice = iitem.SalePrice;
p.InventoryData[0].OwnerID = iitem.OwnerID;
p.InventoryData[0].CreatorID = iitem.CreatorID;
p.InventoryData[0].ItemID = iitem.ItemID;
p.InventoryData[0].FolderID = iitem.FolderID;
p.InventoryData[0].EveryoneMask = iitem.EveryoneMask;
p.InventoryData[0].Description = Helpers.StringToField(iitem.Description);
p.InventoryData[0].Flags = iitem.Flags;
p.InventoryData[0].NextOwnerMask= iitem.NextOwnerMask;
p.InventoryData[0].GroupMask = iitem.GroupMask;
p.InventoryData[0].OwnerMask = iitem.OwnerMask;
p.AgentData.AgentID = AgentID;
p.AgentData.SessionID = SessionID;
return p;
}
/*
// Confirm InventoryUpdate CRC
uint test = libsecondlife.Packets.InventoryPackets.InventoryUpdateCRC
(
(int)1159214416
, (byte)0
, (sbyte)7
, (sbyte)7
, (LLUUID)"00000000000000000000000000000000"
, (LLUUID)"00000000000000000000000000000000"
, (int)10
, (LLUUID)"25472683cb324516904a6cd0ecabf128"
, (LLUUID)"25472683cb324516904a6cd0ecabf128"
, (LLUUID)"77364021f09f13dfb692f036be53b9e2"
, (LLUUID)"a4947fc066c247518d9854aaf90097f4"
, (uint)0
, (uint)0
, (uint)2147483647
, (uint)0
, (uint)2147483647
);
if( test != (uint)895206313 )
{
Console.WriteLine("CRC Generation is no longer correct.");
return;
}
*/
public static uint InventoryUpdateCRC(InventoryItem iitem)
{
uint CRC = 0;
/* IDs */
CRC += iitem.AssetID.CRC(); // AssetID
CRC += iitem.FolderID.CRC(); // FolderID
CRC += iitem.ItemID == null ? LLUUID.Zero.CRC() : iitem.ItemID.CRC(); // ItemID
/* Permission stuff */
CRC += iitem.CreatorID.CRC(); // CreatorID
CRC += iitem.OwnerID.CRC(); // OwnerID
CRC += iitem.GroupID.CRC(); // GroupID
/* CRC += another 4 words which always seem to be zero -- unclear if this is a LLUUID or what */
CRC += iitem.OwnerMask; //owner_mask; // Either owner_mask or next_owner_mask may need to be
CRC += iitem.NextOwnerMask; //next_owner_mask; // switched with base_mask -- 2 values go here and in my
CRC += iitem.EveryoneMask; //everyone_mask; // study item, the three were identical.
CRC += iitem.GroupMask; //group_mask;
/* The rest of the CRC fields */
CRC += iitem.Flags; // Flags
CRC += (uint)iitem.InvType; // InvType
CRC += (uint)iitem.Type; // Type
CRC += (uint)iitem.CreationDate; // CreationDate
CRC += (uint)iitem.SalePrice; // SalePrice
CRC += (uint)((uint)iitem.SaleType * 0x07073096); // SaleType
return CRC;
}
}
}