Applying patches from [LIBOMV-288] to completely redo the InventoryManager system, hopefully for great justice

git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@2021 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
John Hurliman
2008-07-29 21:36:53 +00:00
parent 71837bfcf6
commit bfa6f6ca3f
23 changed files with 2603 additions and 1659 deletions

View File

@@ -88,8 +88,13 @@ namespace OpenMetaverse
public class WearableData
{
public InventoryWearable Item;
public ItemData Item;
public AssetWearable Asset;
public WearableType WearableType
{
get { return (WearableType)Item.Flags; }
set { Item.Flags = (uint)value; }
}
}
/// <summary>
@@ -278,7 +283,7 @@ namespace OpenMetaverse
/// Replace the current outfit with a list of wearables and set appearance
/// </summary>
/// <param name="ibs">List of wearables that define the new outfit</param>
public void WearOutfit(List<InventoryBase> ibs)
public void WearOutfit(List<ItemData> ibs)
{
WearOutfit(ibs, true);
}
@@ -288,7 +293,7 @@ namespace OpenMetaverse
/// </summary>
/// <param name="ibs">List of wearables that define the new outfit</param>
/// <param name="bake">Whether to bake textures for the avatar or not</param>
public void WearOutfit(List<InventoryBase> ibs, bool bake)
public void WearOutfit(List<ItemData> ibs, bool bake)
{
_wearParams = new WearParams(ibs, bake);
Thread appearanceThread = new Thread(new ThreadStart(StartWearOutfit));
@@ -298,15 +303,15 @@ namespace OpenMetaverse
private WearParams _wearParams;
private void StartWearOutfit()
{
List<InventoryBase> ibs = (List<InventoryBase>)_wearParams.Param;
List<InventoryWearable> wearables = new List<InventoryWearable>();
List<InventoryBase> attachments = new List<InventoryBase>();
List<ItemData> ibs = (List<ItemData>)_wearParams.Param;
List<ItemData> wearables = new List<ItemData>();
List<ItemData> attachments = new List<ItemData>();
foreach (InventoryBase ib in ibs)
foreach (ItemData ib in ibs)
{
if (ib is InventoryWearable)
wearables.Add((InventoryWearable)ib);
else if (ib is InventoryAttachment || ib is InventoryObject)
if (ib.InventoryType == InventoryType.Wearable)
wearables.Add(ib);
else if (ib.InventoryType == InventoryType.Attachment || ib.InventoryType == InventoryType.Object)
attachments.Add(ib);
}
@@ -362,8 +367,8 @@ namespace OpenMetaverse
private void StartWearOutfitFolder()
{
SendAgentWearablesRequest(); // request current wearables async
List<InventoryWearable> wearables;
List<InventoryBase> attachments;
List<ItemData> wearables;
List<ItemData> attachments;
if (!GetFolderWearables(_wearOutfitParams.Param, out wearables, out attachments)) // get wearables in outfit folder
return; // TODO: this error condition should be passed back to the client somehow
@@ -374,7 +379,7 @@ namespace OpenMetaverse
AddAttachments(attachments, true);
}
private bool GetFolderWearables(object _folder, out List<InventoryWearable> wearables, out List<InventoryBase> attachments)
private bool GetFolderWearables(object _folder, out List<ItemData> wearables, out List<ItemData> attachments)
{
UUID folder;
wearables = null;
@@ -385,7 +390,7 @@ namespace OpenMetaverse
string[] path = (string[])_folder;
folder = Client.Inventory.FindObjectByPath(
Client.Inventory.Store.RootFolder.UUID, Client.Self.AgentID, String.Join("/", path), 1000 * 20);
Client.Inventory.InventorySkeleton.RootUUID, Client.Self.AgentID, String.Join("/", path), TimeSpan.FromMilliseconds(1000 * 20));
if (folder == UUID.Zero)
{
@@ -396,26 +401,29 @@ namespace OpenMetaverse
else
folder = (UUID)_folder;
wearables = new List<InventoryWearable>();
attachments = new List<InventoryBase>();
List<InventoryBase> objects = Client.Inventory.FolderContents(folder, Client.Self.AgentID,
false, true, InventorySortOrder.ByName, 1000 * 20);
wearables = new List<ItemData>();
attachments = new List<ItemData>();
if (objects != null)
List<FolderData> folders;
List<ItemData> items;
Client.Inventory.FolderContents(folder, Client.Self.AgentID,
false, true, InventorySortOrder.ByName, TimeSpan.FromMilliseconds(1000 * 20), out items, out folders);
if (items != null)
{
foreach (InventoryBase ib in objects)
foreach (ItemData ib in items)
{
if (ib is InventoryWearable)
if (ib.InventoryType == InventoryType.Wearable)
{
Logger.DebugLog("Adding wearable " + ib.Name, Client);
wearables.Add((InventoryWearable)ib);
wearables.Add(ib);
}
else if (ib is InventoryAttachment)
else if (ib.InventoryType == InventoryType.Attachment)
{
Logger.DebugLog("Adding attachment (attachment) " + ib.Name, Client);
attachments.Add(ib);
}
else if (ib is InventoryObject)
else if (ib.InventoryType == InventoryType.Object)
{
Logger.DebugLog("Adding attachment (object) " + ib.Name, Client);
attachments.Add(ib);
@@ -437,7 +445,7 @@ namespace OpenMetaverse
}
// this method will download the assets for all inventory items in iws
private void ReplaceOutfitWearables(List<InventoryWearable> iws)
private void ReplaceOutfitWearables(List<ItemData> iws)
{
lock (Wearables.Dictionary)
{
@@ -451,11 +459,11 @@ namespace OpenMetaverse
Wearables.Dictionary = preserve;
foreach (InventoryWearable iw in iws)
foreach (ItemData iw in iws)
{
WearableData wd = new WearableData();
wd.Item = iw;
Wearables.Dictionary[wd.Item.WearableType] = wd;
Wearables.Dictionary[wd.WearableType] = wd;
}
}
}
@@ -466,7 +474,7 @@ namespace OpenMetaverse
/// <param name="attachments">A List containing the attachments to add</param>
/// <param name="removeExistingFirst">If true, tells simulator to remove existing attachment
/// first</param>
public void AddAttachments(List<InventoryBase> attachments, bool removeExistingFirst)
public void AddAttachments(List<ItemData> attachments, bool removeExistingFirst)
{
// FIXME: Obey this
const int OBJECTS_PER_PACKET = 4;
@@ -483,10 +491,9 @@ namespace OpenMetaverse
attachmentsPacket.ObjectData = new RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[attachments.Count];
for (int i = 0; i < attachments.Count; i++)
{
if (attachments[i] is InventoryAttachment)
if (attachments[i].InventoryType == InventoryType.Attachment)
{
InventoryAttachment attachment = (InventoryAttachment)attachments[i];
ItemData attachment = attachments[i];
attachmentsPacket.ObjectData[i] = new RezMultipleAttachmentsFromInvPacket.ObjectDataBlock();
attachmentsPacket.ObjectData[i].AttachmentPt = 0;
attachmentsPacket.ObjectData[i].EveryoneMask = (uint)attachment.Permissions.EveryoneMask;
@@ -498,10 +505,9 @@ namespace OpenMetaverse
attachmentsPacket.ObjectData[i].NextOwnerMask = (uint)attachment.Permissions.NextOwnerMask;
attachmentsPacket.ObjectData[i].OwnerID = attachment.OwnerID;
}
else if (attachments[i] is InventoryObject)
else if (attachments[i].InventoryType == InventoryType.Object)
{
InventoryObject attachment = (InventoryObject)attachments[i];
ItemData attachment = attachments[i];
attachmentsPacket.ObjectData[i] = new RezMultipleAttachmentsFromInvPacket.ObjectDataBlock();
attachmentsPacket.ObjectData[i].AttachmentPt = 0;
attachmentsPacket.ObjectData[i].EveryoneMask = (uint)attachment.Permissions.EveryoneMask;
@@ -529,7 +535,7 @@ namespace OpenMetaverse
/// <param name="item">A <seealso cref="OpenMetaverse.InventoryItem"/> to attach</param>
/// <param name="attachPoint">the <seealso cref="OpenMetaverse.AttachmentPoint"/> on the avatar
/// to attach the item to</param>
public void Attach(InventoryItem item, AttachmentPoint attachPoint)
public void Attach(ItemData item, AttachmentPoint attachPoint)
{
Attach(item.UUID, item.OwnerID, item.Name, item.Description, item.Permissions, item.Flags,
attachPoint);
@@ -574,7 +580,7 @@ namespace OpenMetaverse
/// Detach an item from avatar using an <seealso cref="OpenMetaverse.InventoryItem"/> object
/// </summary>
/// <param name="item">An <seealso cref="OpenMetaverse.InventoryItem"/> object</param>
public void Detach(InventoryItem item)
public void Detach(ItemData item)
{
Detach(item.UUID);
}
@@ -796,10 +802,11 @@ namespace OpenMetaverse
{
WearableType type = (WearableType)update.WearableData[i].WearableType;
WearableData data = new WearableData();
data.Item = new InventoryWearable(update.WearableData[i].ItemID);
data.Item.WearableType = type;
data.Item.AssetType = WearableTypeToAssetType(type);
data.Item.AssetUUID = update.WearableData[i].AssetID;
ItemData itemData = new ItemData(update.WearableData[i].ItemID, InventoryType.Wearable);
itemData.AssetType = WearableTypeToAssetType(type);
itemData.AssetUUID = update.WearableData[i].AssetID;
data.Item = itemData;
data.WearableType = type;
// Add this wearable to our collection
lock (Wearables.Dictionary) Wearables.Dictionary[type] = data;
@@ -1012,7 +1019,7 @@ namespace OpenMetaverse
{
foreach (KeyValuePair<WearableType, WearableData> kvp in Wearables.Dictionary)
{
Logger.DebugLog("Requesting asset for wearable item " + kvp.Value.Item.WearableType + " (" + kvp.Value.Item.AssetUUID + ")", Client);
Logger.DebugLog("Requesting asset for wearable item " + kvp.Value.WearableType + " (" + kvp.Value.Item.AssetUUID + ")", Client);
AssetDownloads.Enqueue(new PendingAssetDownload(kvp.Value.Item.AssetUUID, kvp.Value.Item.AssetType));
}

View File

@@ -96,6 +96,44 @@ namespace OpenMetaverse
Simstate = 22,
}
public static class AssetTypeParser
{
private static readonly ReversableDictionary<string, AssetType> AssetTypeMap = new ReversableDictionary<string, AssetType>();
static AssetTypeParser()
{
AssetTypeMap.Add("animatn", AssetType.Animation);
AssetTypeMap.Add("clothing", AssetType.Clothing);
AssetTypeMap.Add("callcard", AssetType.CallingCard);
AssetTypeMap.Add("object", AssetType.Object);
AssetTypeMap.Add("texture", AssetType.Texture);
AssetTypeMap.Add("sound", AssetType.Sound);
AssetTypeMap.Add("bodypart", AssetType.Bodypart);
AssetTypeMap.Add("gesture", AssetType.Gesture);
AssetTypeMap.Add("lsltext", AssetType.LSLText);
AssetTypeMap.Add("landmark", AssetType.Landmark);
AssetTypeMap.Add("notecard", AssetType.Notecard);
AssetTypeMap.Add("category", AssetType.Folder);
}
public static AssetType Parse(string str)
{
AssetType t;
if (AssetTypeMap.TryGetValue(str, out t))
return t;
else
return AssetType.Unknown;
}
public static string StringValueOf(AssetType type)
{
string str;
if (AssetTypeMap.TryGetKey(type, out str))
return str;
else
return "unknown";
}
}
/// <summary>
///
/// </summary>
@@ -520,7 +558,7 @@ namespace OpenMetaverse
return transfer.ID;
}
public UUID RequestInventoryAsset(InventoryItem item, bool priority)
public UUID RequestInventoryAsset(ItemData item, bool priority)
{
return RequestInventoryAsset(item.AssetUUID, item.UUID, UUID.Zero, item.OwnerID, item.AssetType, priority);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -121,8 +121,8 @@ namespace OpenMetaverse
public DateTime SecondsSinceEpoch;
public UUID InventoryRoot;
public UUID LibraryRoot;
public InventoryFolder[] InventorySkeleton;
public InventoryFolder[] LibrarySkeleton;
public FolderData[] InventoryFolders;
public FolderData[] LibraryFolders;
public UUID LibraryOwner;
public void Parse(LLSDMap reply)
@@ -203,10 +203,10 @@ namespace OpenMetaverse
SecondsSinceEpoch = Helpers.UnixTimeToDateTime(ParseUInt("seconds_since_epoch", reply));
InventoryRoot = ParseMappedUUID("inventory-root", "folder_id", reply);
InventorySkeleton = ParseInventoryFolders("inventory-skeleton", AgentID, reply);
InventoryFolders = ParseInventoryFolders("inventory-skeleton", AgentID, reply);
LibraryRoot = ParseMappedUUID("inventory-lib-root", "folder_id", reply);
LibraryOwner = ParseMappedUUID("inventory-lib-owner", "agent_id", reply);
LibrarySkeleton = ParseInventoryFolders("inventory-skel-lib", LibraryOwner, reply);
LibraryFolders = ParseInventoryFolders("inventory-skel-lib", LibraryOwner, reply);
}
#region Parsing Helpers
@@ -279,9 +279,9 @@ namespace OpenMetaverse
return UUID.Zero;
}
public static InventoryFolder[] ParseInventoryFolders(string key, UUID owner, LLSDMap reply)
public static FolderData[] ParseInventoryFolders(string key, UUID owner, LLSDMap reply)
{
List<InventoryFolder> folders = new List<InventoryFolder>();
List<FolderData> folders = new List<FolderData>();
LLSD skeleton;
if (reply.TryGetValue(key, out skeleton) && skeleton.Type == LLSDType.Array)
@@ -293,7 +293,7 @@ namespace OpenMetaverse
if (array[i].Type == LLSDType.Map)
{
LLSDMap map = (LLSDMap)array[i];
InventoryFolder folder = new InventoryFolder(map["folder_id"].AsUUID());
FolderData folder = new FolderData(map["folder_id"].AsUUID());
folder.PreferredType = (AssetType)map["type_default"].AsInteger();
folder.Version = map["version"].AsInteger();
folder.OwnerID = owner;
@@ -303,11 +303,9 @@ namespace OpenMetaverse
folders.Add(folder);
}
}
return folders.ToArray();
}
return new InventoryFolder[0];
return folders.ToArray();
}
#endregion Parsing Helpers

View File

@@ -0,0 +1,176 @@
/*
* Copyright (c) 2008, openmetaverse.org
* All rights reserved.
*
* - Redistribution and use in source and binary forms, with or without
* 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.
* - Neither the name of the openmetaverse.org nor the names
* of its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* 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
* POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenMetaverse
{
public class ReversableDictionary<K, V> : IDictionary<K, V>
{
private Dictionary<K, V> dict;
private Dictionary<V, K> reverseDict;
public ReversableDictionary()
: this(10) { }
public ReversableDictionary(int initialCapacity)
{
dict = new Dictionary<K, V>(initialCapacity);
reverseDict = new Dictionary<V, K>(initialCapacity);
}
#region IDictionary<K,V> Members
public void Add(K key, V value)
{
dict.Add(key, value);
reverseDict.Add(value, key);
}
public bool ContainsKey(K key)
{
return dict.ContainsKey(key);
}
public ICollection<K> Keys
{
get { return dict.Keys; }
}
public bool Remove(K key)
{
V value = dict[key];
bool success = dict.Remove(key);
reverseDict.Remove(value);
return success;
}
public bool TryGetValue(K key, out V value)
{
return dict.TryGetValue(key, out value);
}
public bool TryGetKey(V value, out K key)
{
return reverseDict.TryGetValue(value, out key);
}
public ICollection<V> Values
{
get { return dict.Values; }
}
public V this[K key]
{
get
{
return dict[key];
}
set
{
dict[key] = value;
}
}
public K this[V val]
{
get
{
return reverseDict[val];
}
set
{
reverseDict[val] = value;
}
}
#endregion
#region ICollection<KeyValuePair<K,V>> Members
public void Add(KeyValuePair<K, V> item)
{
Add(item.Key, item.Value);
}
public void Clear()
{
dict.Clear();
reverseDict.Clear();
}
public bool Contains(KeyValuePair<K, V> item)
{
return dict.ContainsKey(item.Key);
}
public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
{
foreach (KeyValuePair<K, V> kvp in dict)
array[arrayIndex++] = kvp;
}
public int Count
{
get { return dict.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(KeyValuePair<K, V> item)
{
return Remove(item.Key);
}
#endregion
#region IEnumerable<KeyValuePair<K,V>> Members
public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
{
foreach (KeyValuePair<K, V> kvp in dict)
{
yield return kvp;
}
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
}

View File

@@ -0,0 +1,207 @@
/*
* Copyright (c) 2008, openmetaverse.org
* All rights reserved.
*
* - Redistribution and use in source and binary forms, with or without
* 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.
* - Neither the name of the openmetaverse.org nor the names
* of its contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* 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
* POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace OpenMetaverse
{
public class IndentWriter : TextWriter
{
private string Prefix = String.Empty;
public string Indent = String.Empty;
private bool AddPrefix = false;
private StringBuilder builder = new StringBuilder();
private void TryAddPrefix()
{
if (AddPrefix)
{
builder.Append(Prefix);
AddPrefix = false;
}
}
public override void Write(string str)
{
TryAddPrefix();
builder.Append(str);
}
public override void Write(char c)
{
if (c == '}')
Prefix.Remove(0, Indent.Length);
TryAddPrefix();
builder.Append(c);
if (c == '{')
Prefix += Indent;
}
public override void Write(object o)
{
TryAddPrefix();
builder.Append(o);
}
public override void WriteLine(string line)
{
TryAddPrefix();
builder.AppendLine(line);
AddPrefix = true;
}
public override void WriteLine(char c)
{
if (c == '}')
Prefix = Prefix.Remove(0, Indent.Length);
TryAddPrefix();
builder.Append(c);
builder.AppendLine();
if (c == '{')
Prefix += Indent;
AddPrefix = true;
}
public override void WriteLine(object o)
{
TryAddPrefix();
builder.Append(o);
builder.AppendLine();
AddPrefix = true;
}
public override Encoding Encoding
{
get { return Encoding.UTF8; }
}
public override string ToString()
{
return builder.ToString();
}
}
public class TextData
{
public string Name;
public string Value;
public Dictionary<string, TextData> Nested = new Dictionary<string, TextData>();
public void ParseLine(string line)
{
int firstSpace = line.IndexOfAny(TextHierarchyParser.WordSeperators);
Name = line.Substring(0, firstSpace);
Value = line.Substring(firstSpace + 1).Trim();
}
public override string ToString()
{
IndentWriter writer = new IndentWriter();
writer.Indent = "\t";
ToString(writer);
return writer.ToString();
}
public void ToString(TextWriter sink)
{
sink.Write(Name);
sink.Write('\t');
sink.WriteLine(Value);
if (Nested.Count > 0)
{
sink.WriteLine('{');
foreach (TextData child in Nested.Values)
{
child.ToString(sink);
}
sink.WriteLine('}');
}
}
}
public class TextHierarchyParser
{
protected internal static readonly char[] WordSeperators = new char[] { ' ', '\t' };
public static TextData Parse(TextReader source)
{
string prevLine = null;
string startLine = source.ReadLine().Trim();
while (startLine[0] != '{')
{
prevLine = startLine;
startLine = source.ReadLine().Trim();
}
TextData startParent = new TextData();
if (prevLine != null)
startParent.ParseLine(prevLine);
ParseNested(startParent, source);
return startParent;
}
private static void ParseNested(TextData parent, TextReader source)
{
string line = null;
TextData current = null;
do
{
line = source.ReadLine().Trim();
if (line.Length > 0)
{
if (line[0] == '{')
{
if (current == null)
current = new TextData();
ParseNested(current, source);
}
else if (line[0] == '}')
{
return;
}
else
{
current = new TextData();
current.ParseLine(line);
}
}
if (current != null)
parent.Nested[current.Name] = current;
} while (line != null);
}
}
}

View File

@@ -93,7 +93,7 @@ namespace OpenMetaverse.Packets
get { return (Data[0] & Helpers.MSG_APPENDED_ACKS) != 0; }
set { if (value) { Data[0] |= (byte)Helpers.MSG_APPENDED_ACKS; } else { byte mask = (byte)Helpers.MSG_APPENDED_ACKS ^ 0xFF; Data[0] &= mask; } }
}
/// <summary>Packet sequence number, three bytes long</summary>
/// <summary>Packet sequence number</summary>
public uint Sequence
{
get { return (uint)((Data[1] << 24) + (Data[2] << 16) + (Data[3] << 8) + Data[4]); }

View File

@@ -312,12 +312,11 @@ namespace GridImageUpload
UpdateAssetID();
// Fix the permissions on the new upload since they are fscked by default
InventoryItem item = Client.Inventory.FetchItem(itemID, Client.Self.AgentID, 1000 * 15);
Transferred = UploadData.Length;
BeginInvoke((MethodInvoker)delegate() { SetProgress(); });
if (item != null)
ItemData item;
if (Client.Inventory.FetchItem(itemID, Client.Self.AgentID, TimeSpan.FromSeconds(15), out item))
{
item.Permissions.EveryoneMask = PermissionMask.All;
item.Permissions.NextOwnerMask = PermissionMask.All;

View File

@@ -182,7 +182,7 @@ public class ClientAO : ProxyPlugin
// Number of directory descendents received
int nbdescendantsreceived;
//List of items in the current folder
Dictionary<string,InventoryItem> currentFolderItems;
Dictionary<string,ItemData> currentFolderItems;
//Asset download request ID
UUID assetdownloadID;
//Downloaded bytes so far
@@ -295,7 +295,7 @@ public class ClientAO : ProxyPlugin
InventorySortOrder order)
{
//empty the dictionnary containing current folder items by name
currentFolderItems = new Dictionary<string, InventoryItem>();
currentFolderItems = new Dictionary<string, ItemData>();
//reset the number of descendants received
nbdescendantsreceived = 0;
//build a packet to request the content
@@ -388,7 +388,7 @@ public class ClientAO : ProxyPlugin
//configuration notecard
if (reply.ItemData[i].ItemID != UUID.Zero)
{
InventoryItem item = CreateInventoryItem((InventoryType)reply.ItemData[i].InvType, reply.ItemData[i].ItemID);
ItemData item = CreateInventoryItem((InventoryType)reply.ItemData[i].InvType, reply.ItemData[i].ItemID);
item.ParentUUID = reply.ItemData[i].FolderID;
item.CreatorID = reply.ItemData[i].CreatorID;
item.AssetType = (AssetType)reply.ItemData[i].Type;
@@ -465,29 +465,13 @@ public class ClientAO : ProxyPlugin
}
}
public static InventoryItem CreateInventoryItem(InventoryType type, UUID id)
public static ItemData 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);
}
return new ItemData(id, type);
}
//Ask for download of an item
public UUID RequestInventoryAsset(InventoryItem item)
public UUID RequestInventoryAsset(ItemData item)
{
// Build the request packet and send it
TransferRequestPacket request = new TransferRequestPacket();

View File

@@ -61,7 +61,7 @@ namespace OpenMetaverse.TestClient
#endregion AvatarAppearance to AgentSetAppearance
// Detach everything we are currently wearing
Client.Appearance.AddAttachments(new List<InventoryBase>(), true);
Client.Appearance.AddAttachments(new List<ItemData>(0), true);
// Send the new appearance packet
Client.Network.SendPacket(set);

View File

@@ -240,7 +240,7 @@ namespace OpenMetaverse.TestClient
DirectoryInfo di = new DirectoryInfo(args[1]);
// recurse on the root folder into the entire inventory
BackupFolder(Client.Inventory.Store.RootNode, di.FullName);
BackupFolder(Client.InventoryStore.RootFolder, di.FullName);
}
/// <summary>
@@ -248,41 +248,42 @@ namespace OpenMetaverse.TestClient
/// </summary>
/// <param name="folder">The current leaf in the inventory tree</param>
/// <param name="sPathSoFar">path so far, in the form @"c:\here" -- this needs to be "clean" for the current filesystem</param>
private void BackupFolder(InventoryNode folder, string sPathSoFar)
private void BackupFolder(InventoryFolder folder, string sPathSoFar)
{
StringBuilder sbRequests = new StringBuilder();
// FIXME:
//Client.Inventory.RequestFolderContents(folder.Data.UUID, Client.Self.AgentID, true, true, false,
// InventorySortOrder.ByName);
if (folder.IsStale)
folder.DownloadContents(TimeSpan.FromSeconds(10));
// first scan this folder for text
foreach (InventoryNode iNode in folder.Nodes.Values)
foreach (InventoryBase ib in folder)
{
if (BackupWorker.CancellationPending)
return;
if (iNode.Data is OpenMetaverse.InventoryItem)
if (ib is InventoryItem)
{
InventoryItem ii = iNode.Data as InventoryItem;
if (ii.AssetType == AssetType.LSLText || ii.AssetType == AssetType.Notecard)
InventoryItem ii = ib as InventoryItem;
if (ii.Data.AssetType == AssetType.LSLText || ii.Data.AssetType == AssetType.Notecard)
{
// check permissions on scripts
if (ii.AssetType == AssetType.LSLText)
if (ii.Data.AssetType == AssetType.LSLText)
{
if ((ii.Permissions.OwnerMask & PermissionMask.Modify) == PermissionMask.None)
if ((ii.Data.Permissions.OwnerMask & PermissionMask.Modify) == PermissionMask.None)
{
// skip this one
continue;
}
}
string sExtension = (ii.AssetType == AssetType.LSLText) ? ".lsl" : ".txt";
string sExtension = (ii.Data.AssetType == AssetType.LSLText) ? ".lsl" : ".txt";
// make the output file
string sPath = sPathSoFar + @"\" + MakeValid(ii.Name.Trim()) + sExtension;
// create the new qdi
QueuedDownloadInfo qdi = new QueuedDownloadInfo(sPath, ii.AssetUUID, iNode.Data.UUID, UUID.Zero,
Client.Self.AgentID, ii.AssetType);
QueuedDownloadInfo qdi = new QueuedDownloadInfo(sPath, ii.Data.AssetUUID, ii.UUID, UUID.Zero,
Client.Self.AgentID, ii.Data.AssetType);
// add it to the queue
lock (PendingDownloads)
@@ -295,12 +296,12 @@ namespace OpenMetaverse.TestClient
}
// now run any subfolders
foreach (InventoryNode i in folder.Nodes.Values)
foreach (InventoryBase ib in folder)
{
if (BackupWorker.CancellationPending)
return;
else if (i.Data is OpenMetaverse.InventoryFolder)
BackupFolder(i, sPathSoFar + @"\" + MakeValid(i.Data.Name.Trim()));
else if (ib is InventoryFolder)
BackupFolder(ib as InventoryFolder, sPathSoFar + @"\" + MakeValid(ib.Name.Trim()));
}
}

View File

@@ -19,7 +19,7 @@ namespace OpenMetaverse.TestClient.Commands.Inventory.Shell
public override string Execute(string[] args, UUID fromAgentID)
{
Manager = Client.Inventory;
Inventory = Client.Inventory.Store;
Inventory = Client.InventoryStore;
if (args.Length > 1)
return "Usage: cd [path-to-folder]";
@@ -52,17 +52,19 @@ namespace OpenMetaverse.TestClient.Commands.Inventory.Shell
if (nextName == ".." && currentFolder != Inventory.RootFolder)
{
// If we encounter .., move to the parent folder.
currentFolder = Inventory[currentFolder.ParentUUID] as InventoryFolder;
currentFolder = currentFolder.Parent;
}
else
{
List<InventoryBase> currentContents = Inventory.GetContents(currentFolder);
if (currentFolder.IsStale)
currentFolder.DownloadContents(TimeSpan.FromSeconds(30));
// Try and find an InventoryBase with the corresponding name.
bool found = false;
foreach (InventoryBase item in currentContents)
foreach (InventoryBase item in currentFolder)
{
string name = item.Name;
// Allow lookup by UUID as well as name:
if (item.Name == nextName || item.UUID.ToString() == nextName)
if (name == nextName || item.UUID.ToString() == nextName)
{
found = true;
if (item is InventoryFolder)
@@ -71,16 +73,16 @@ namespace OpenMetaverse.TestClient.Commands.Inventory.Shell
}
else
{
return item.Name + " is not a folder.";
return name + " is not a folder.";
}
}
}
if (!found)
return nextName + " not found in " + currentFolder.Name;
return nextName + " not found in " + currentFolder.Data.Name;
}
}
Client.CurrentDirectory = currentFolder;
return "Current folder: " + currentFolder.Name;
return "Current folder: " + currentFolder.Data.Name;
}
}
}
}

View File

@@ -45,7 +45,7 @@ namespace OpenMetaverse.TestClient
Client.Inventory.RequestCreateItem(Client.Inventory.FindFolderForType(AssetType.Notecard),
file, desc, AssetType.Notecard, UUID.Random(), InventoryType.Notecard, PermissionMask.All,
delegate(bool success, InventoryItem item) {
delegate(bool success, ItemData item) {
if(success) // upload the asset
Client.Inventory.RequestUploadNotecardAsset(CreateNotecardAsset(body), item.UUID, new InventoryManager.NotecardUploadedAssetCallback(OnNoteUpdate));
}
@@ -83,4 +83,4 @@ namespace OpenMetaverse.TestClient
return assetData;
}
}
}
}

View File

@@ -34,12 +34,20 @@ namespace OpenMetaverse.TestClient
try
{
// find the folder
found = Client.Inventory.LocalFind(Client.Inventory.Store.RootFolder.UUID, target.Split('/'), 0, true);
if (found.Count.Equals(1))
found = Client.InventoryStore.InventoryFromPath(target.Split('/'), Client.InventoryStore.RootFolder);
if (found.Count > 0)
{
// move the folder to the trash folder
Client.Inventory.MoveFolder(found[0].UUID, Client.Inventory.FindFolderForType(AssetType.TrashFolder));
return String.Format("Moved folder {0} to Trash", found[0].Name);
InventoryBase item = found[0];
InventoryFolder trash = Client.InventoryStore[Client.Inventory.FindFolderForType(AssetType.TrashFolder)] as InventoryFolder;
if (trash != null)
{
item.Move(trash);
return String.Format("Moved folder {0} ({1}) to Trash", item.Name, item.UUID);
}
}
else
{
return String.Format("Unable to locate {0}", target);
}
}
catch (InvalidOutfitException ex)
@@ -49,4 +57,4 @@ namespace OpenMetaverse.TestClient
return string.Empty;
}
}
}
}

View File

@@ -26,29 +26,26 @@ namespace OpenMetaverse.TestClient.Commands.Inventory.Shell
return "First argument expected agent UUID.";
}
Manager = Client.Inventory;
Inventory = Manager.Store;
Inventory = Client.InventoryStore;
string ret = "";
string nl = "\n";
for (int i = 1; i < args.Length; ++i)
{
string inventoryName = args[i];
// WARNING: Uses local copy of inventory contents, need to download them first.
List<InventoryBase> contents = Inventory.GetContents(Client.CurrentDirectory);
if (Client.CurrentDirectory.IsStale)
{
Client.CurrentDirectory.DownloadContents(TimeSpan.FromSeconds(30));
}
bool found = false;
foreach (InventoryBase b in contents) {
if (inventoryName == b.Name || inventoryName == b.UUID.ToString())
foreach (InventoryBase b in Client.CurrentDirectory) {
string name = b.Name;
if (inventoryName == name || inventoryName == b.UUID.ToString())
{
found = true;
if (b is InventoryItem)
{
InventoryItem item = b as InventoryItem;
Manager.GiveItem(item.UUID, item.Name, item.AssetType, dest, true);
ret += "Gave " + item.Name + nl;
}
else
{
ret += "Unable to give folder " + b.Name + nl;
}
b.Give(dest, true);
ret += "Gave " + name + nl;
}
}
if (!found)

View File

@@ -25,27 +25,39 @@ namespace OpenMetaverse.TestClient
public override string Execute(string[] args, UUID fromAgentID)
{
Manager = Client.Inventory;
Inventory = Manager.Store;
Inventory = Client.InventoryStore;
StringBuilder result = new StringBuilder();
InventoryFolder rootFolder = Inventory.RootFolder;
PrintFolder(rootFolder, result, 0);
return result.ToString();
}
void PrintFolder(InventoryFolder f, StringBuilder result, int indent)
void PrintFolder(InventoryFolder folder, StringBuilder result, int indent)
{
foreach (InventoryBase i in Manager.FolderContents(f.UUID, Client.Self.AgentID, true, true, InventorySortOrder.ByName, 3000))
folder.DownloadContents(TimeSpan.FromSeconds(10));
foreach (InventoryBase b in folder)
{
result.AppendFormat("{0}{1} ({2})\n", new String(' ', indent * 2), i.Name, i.UUID);
if (i is InventoryFolder)
if (b is InventoryFolder)
{
InventoryFolder folder = (InventoryFolder)i;
PrintFolder(folder, result, indent + 1);
result.Append(Print(b as InventoryFolder, indent));
PrintFolder(b as InventoryFolder, result, indent + 1);
}
else if (b is InventoryItem)
{
result.Append(Print(b as InventoryItem, indent));
}
}
}
string Print(InventoryItem item, int indent)
{
return string.Format("{0}{1} ({2})\n", new String(' ', indent * 2), item.Data.Name, item.UUID);
}
string Print(InventoryFolder folder, int indent)
{
return string.Format("{0}{1} ({2})\n", new String(' ', indent * 2), folder.Data.Name, folder.UUID);
}
}
}
}

View File

@@ -24,13 +24,15 @@ namespace OpenMetaverse.TestClient.Commands.Inventory.Shell
longDisplay = true;
Manager = Client.Inventory;
Inventory = Manager.Store;
// WARNING: Uses local copy of inventory contents, need to download them first.
List<InventoryBase> contents = Inventory.GetContents(Client.CurrentDirectory);
Inventory = Client.InventoryStore;
if (Client.CurrentDirectory.IsStale)
Client.CurrentDirectory.DownloadContents(TimeSpan.FromSeconds(30));
string displayString = "";
string nl = "\n"; // New line character
// Pretty simple, just print out the contents.
foreach (InventoryBase b in contents)
foreach (InventoryBase b in Client.CurrentDirectory)
{
if (longDisplay)
{
@@ -51,16 +53,17 @@ namespace OpenMetaverse.TestClient.Commands.Inventory.Shell
{
InventoryItem item = b as InventoryItem;
displayString += "-";
displayString += PermMaskString(item.Permissions.OwnerMask);
displayString += PermMaskString(item.Permissions.GroupMask);
displayString += PermMaskString(item.Permissions.EveryoneMask);
displayString += PermMaskString(item.Data.Permissions.OwnerMask);
displayString += PermMaskString(item.Data.Permissions.GroupMask);
displayString += PermMaskString(item.Data.Permissions.EveryoneMask);
displayString += " " + item.UUID;
displayString += " " + item.Name;
}
}
else
{
displayString += b.Name;
string name = b.Name;
displayString += name;
}
displayString += nl;
}

View File

@@ -29,24 +29,22 @@ namespace OpenMetaverse.TestClient
else
return "Couldn't find prim " + objectID.ToString();
List<InventoryBase> items = Client.Inventory.GetTaskInventory(objectID, objectLocalID, 1000 * 30);
List<ItemData> items;
List<FolderData> folders;
Client.Inventory.GetTaskInventory(objectID, objectLocalID, TimeSpan.FromMilliseconds(1000 * 30), out items, out folders);
if (items != null)
{
string result = String.Empty;
for (int i = 0; i < items.Count; i++)
foreach (ItemData item in items)
{
if (items[i] is InventoryFolder)
{
result += String.Format("[Folder] Name: {0}", items[i].Name) + Environment.NewLine;
}
else
{
InventoryItem item = (InventoryItem)items[i];
result += String.Format("[Item] Name: {0} Desc: {1} Type: {2}", item.Name, item.Description,
result += String.Format("[Item] Name: {0} Desc: {1} Type: {2}", item.Name, item.Description,
item.AssetType) + Environment.NewLine;
}
}
foreach (FolderData folder in folders)
{
result += String.Format("[Folder] Name: {0}", folder.Name) + Environment.NewLine;
}
return result;

View File

@@ -131,20 +131,18 @@ namespace OpenMetaverse.TestClient
{
if ((prim.Flags & LLObject.ObjectFlags.InventoryEmpty) == 0)
{
List<InventoryBase> items = Client.Inventory.GetTaskInventory(prim.ID, prim.LocalID, 1000 * 30);
List<ItemData> items;
List<FolderData> folders;
Client.Inventory.GetTaskInventory(prim.ID, prim.LocalID, TimeSpan.FromSeconds(30), out items, out folders);
if (items != null)
{
for (int i = 0; i < items.Count; i++)
foreach (ItemData item in items)
{
if (!(items[i] is InventoryFolder))
{
InventoryItem item = (InventoryItem)items[i];
item.Permissions.NextOwnerMask = Perms;
Client.Inventory.UpdateTaskInventory(prim.LocalID, item);
++taskItems;
}
ItemData iitem = item;
iitem.Permissions.NextOwnerMask = Perms;
Client.Inventory.UpdateTaskInventory(prim.LocalID, iitem);
++taskItems;
}
}
}

View File

@@ -28,6 +28,8 @@ namespace OpenMetaverse.TestClient
private Vector3 left = new Vector3(0.9999f, 0, 0);
private Vector3 up = new Vector3(0, 0, 0.9999f);
private System.Timers.Timer updateTimer;
public Inventory InventoryStore;
public Inventory LibraryStore;
/// <summary>
///
@@ -59,7 +61,6 @@ namespace OpenMetaverse.TestClient
Network.RegisterCallback(PacketType.AlertMessage, new NetworkManager.PacketCallback(AlertMessageHandler));
VoiceManager = new VoiceManager(this);
updateTimer.Start();
}
@@ -72,8 +73,12 @@ namespace OpenMetaverse.TestClient
{
if (login == LoginStatus.Success)
{
// Start in the inventory root folder.
CurrentDirectory = Inventory.Store.RootFolder;
// Create the stores:
InventoryStore = new Inventory(Inventory, Inventory.InventorySkeleton);
LibraryStore = new Inventory(Inventory, Inventory.LibrarySkeleton);
// Start in the inventory root folder:
CurrentDirectory = InventoryStore.RootFolder;
}
}
@@ -244,20 +249,20 @@ namespace OpenMetaverse.TestClient
}
private bool Inventory_OnInventoryObjectReceived(InstantMessage offer, AssetType type,
private UUID Inventory_OnInventoryObjectReceived(InstantMessage offer, AssetType type,
UUID objectID, bool fromTask)
{
if (MasterKey != UUID.Zero)
{
if (offer.FromAgentID != MasterKey)
return false;
return UUID.Zero;
}
else if (GroupMembers != null && !GroupMembers.ContainsKey(offer.FromAgentID))
{
return false;
return UUID.Zero;
}
return true;
return Inventory.FindFolderForType(type);
}
}
}

View File

@@ -131,7 +131,7 @@ namespace importprimscript
//
// Create a folder to hold all of our texture uploads
UploadFolderID = Client.Inventory.CreateFolder(Client.Inventory.Store.RootFolder.UUID, scriptfilename);
UploadFolderID = Client.Inventory.CreateFolder(Client.Inventory.InventorySkeleton.RootUUID, scriptfilename);
// Loop through each sculpty and do what we need to do
for (int i = 0; i < sculpties.Count; i++)

View File

@@ -93,7 +93,7 @@ namespace OpenMetaverse.Packets
get { return (Data[0] & Helpers.MSG_APPENDED_ACKS) != 0; }
set { if (value) { Data[0] |= (byte)Helpers.MSG_APPENDED_ACKS; } else { byte mask = (byte)Helpers.MSG_APPENDED_ACKS ^ 0xFF; Data[0] &= mask; } }
}
/// <summary>Packet sequence number, three bytes long</summary>
/// <summary>Packet sequence number</summary>
public uint Sequence
{
get { return (uint)((Data[1] << 24) + (Data[2] << 16) + (Data[3] << 8) + Data[4]); }