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
This commit is contained in:
@@ -18,30 +18,23 @@ namespace libsecondlife.AssetSystem
|
||||
private uint SerialNum = 1;
|
||||
|
||||
private ManualResetEvent AgentWearablesSignal = null;
|
||||
private AgentWearablesUpdatePacket.WearableDataBlock[] AgentWearablesData;
|
||||
|
||||
// This data defines all appearance info for an avatar
|
||||
public AgentWearablesUpdatePacket.WearableDataBlock[] AgentWearablesData;
|
||||
public SerializableDictionary<uint, float> AgentAppearanceParams = new SerializableDictionary<uint, float>();
|
||||
public TextureEntry AgentTextureEntry = new TextureEntry("C228D1CF4B5D4BA884F4899A0796AA97"); // if this isn't valid, blame JH ;-)
|
||||
|
||||
|
||||
|
||||
public AppearanceManager(SecondLife client)
|
||||
{
|
||||
Client = client;
|
||||
AManager = AssetManager.GetAssetManager(client);
|
||||
AManager = client.Assets;
|
||||
|
||||
Client.Objects.OnNewAvatar += new ObjectManager.NewAvatarCallback(Objects_OnNewAvatar);
|
||||
RegisterCallbacks();
|
||||
|
||||
}
|
||||
|
||||
void Objects_OnNewAvatar(Simulator simulator, Avatar avatar, ulong regionHandle, ushort timeDilation)
|
||||
{
|
||||
if (avatar.ID == Client.Network.AgentID)
|
||||
{
|
||||
Console.WriteLine("**********************");
|
||||
Console.WriteLine("**********************");
|
||||
Console.WriteLine("Saw Myself");
|
||||
Console.WriteLine("**********************");
|
||||
Console.WriteLine("**********************");
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterCallbacks()
|
||||
{
|
||||
Client.Network.RegisterCallback(libsecondlife.Packets.PacketType.AgentWearablesUpdate, new NetworkManager.PacketCallback(AgentWearablesUpdateCallbackHandler));
|
||||
@@ -61,33 +54,8 @@ namespace libsecondlife.AssetSystem
|
||||
return AgentWearablesData;
|
||||
}
|
||||
|
||||
public void SendAgentSetAppearance()
|
||||
public void GetAvatarAppearanceInfoFromWearableAssets()
|
||||
{
|
||||
|
||||
TextureEntry textures = new TextureEntry("C228D1CF4B5D4BA884F4899A0796AA97"); // if this isn't valid, blame JH ;-)
|
||||
|
||||
// Face 17 - Under Pants
|
||||
// textures.CreateFace(17).TextureID = "b0bac26505cc7076202ba2a2e05fd172"; //Default Men's briefs
|
||||
|
||||
// Face 16 - Under Shirt
|
||||
// textures.CreateFace(16).TextureID = "d283de852dc3dc07dc452e1bfd4cf193"; //Default Men's tank
|
||||
|
||||
// Face 11 - Eyes
|
||||
// textures.CreateFace(11).TextureID = "3abd329a78478984ac1cb95f4ef35fbe"; //Default Eye
|
||||
|
||||
// Face 10 -
|
||||
// textures.CreateFace(10).TextureID = "c24403bc4569361852b31917ad733035"; //Default
|
||||
|
||||
// Face 9 -
|
||||
// textures.CreateFace(9).TextureID = "a88225377555cf975720aa128e47f934"; //Default
|
||||
|
||||
// Face 8 -
|
||||
// textures.CreateFace(8).TextureID = "472ccc472a4e2556d082f7bb708bcca7"; //Default
|
||||
|
||||
|
||||
|
||||
Dictionary<uint, float> AgentAppearance = new Dictionary<uint, float>();
|
||||
|
||||
foreach (AgentWearablesUpdatePacket.WearableDataBlock wdb in GetWearables())
|
||||
{
|
||||
if (wdb.ItemID == LLUUID.Zero)
|
||||
@@ -124,13 +92,12 @@ namespace libsecondlife.AssetSystem
|
||||
|
||||
foreach (KeyValuePair<uint, LLUUID> texture in bp.textures)
|
||||
{
|
||||
Console.WriteLine(texture.Key + " : " + texture.Value);
|
||||
textures.CreateFace(texture.Key).TextureID = texture.Value;
|
||||
AgentTextureEntry.CreateFace(texture.Key).TextureID = texture.Value;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<uint, float> kvp in bp.parameters)
|
||||
{
|
||||
AgentAppearance[kvp.Key] = bp.parameters[kvp.Key];
|
||||
AgentAppearanceParams[kvp.Key] = bp.parameters[kvp.Key];
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -145,46 +112,9 @@ namespace libsecondlife.AssetSystem
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Dictionary<uint, byte> VisualParams = new Dictionary<uint, byte>();
|
||||
|
||||
|
||||
float maxVal = 0;
|
||||
float minVal = 0;
|
||||
uint packetIdx = 0;
|
||||
float range = 0;
|
||||
float percentage = 0;
|
||||
byte packetVal = 0;
|
||||
|
||||
foreach (KeyValuePair<uint, float> kvp in AgentAppearance)
|
||||
{
|
||||
packetIdx = AppearanceManager.GetAgentSetAppearanceIndex(kvp.Key) - 1; //TODO/FIXME: this should be zero indexed, not 1 based.
|
||||
maxVal = BodyShapeParams.GetValueMax(kvp.Key);
|
||||
minVal = BodyShapeParams.GetValueMin(kvp.Key);
|
||||
|
||||
range = maxVal - minVal;
|
||||
|
||||
percentage = (kvp.Value - minVal) / range;
|
||||
|
||||
packetVal = (byte)(percentage * (byte)255);
|
||||
|
||||
VisualParams[packetIdx] = packetVal;
|
||||
}
|
||||
|
||||
|
||||
AgentSetAppearancePacket p = new AgentSetAppearancePacket();
|
||||
p.AgentData.AgentID = Client.Network.AgentID;
|
||||
p.AgentData.SessionID = Client.Network.SessionID;
|
||||
p.AgentData.SerialNum = ++SerialNum;
|
||||
|
||||
float AV_Height_Range = 2.025506f - 1.50856f;
|
||||
float AV_Height = 1.50856f + (((float)VisualParams[25] / 255.0f) * AV_Height_Range);
|
||||
|
||||
p.AgentData.Size = new LLVector3(0.45f, 0.6f, AV_Height);
|
||||
// p.AgentData.Size = new LLVector3(0.45f, 0.6f, 1.35187f);
|
||||
// p.ObjectData.TextureEntry = textures.ToBytes();
|
||||
|
||||
foreach( uint faceid in textures.FaceTextures.Keys )
|
||||
// Correct the order of the textures
|
||||
foreach (uint faceid in AgentTextureEntry.FaceTextures.Keys)
|
||||
{
|
||||
switch (faceid)
|
||||
{
|
||||
@@ -210,22 +140,78 @@ namespace libsecondlife.AssetSystem
|
||||
}
|
||||
|
||||
//Re-order texture faces to match Linden Labs internal data structure.
|
||||
TextureEntry te2 = new TextureEntry(textures.DefaultTexture.TextureID);
|
||||
te2.CreateFace(18).TextureID = textures.GetFace(18).TextureID;
|
||||
te2.CreateFace(17).TextureID = textures.GetFace(17).TextureID;
|
||||
te2.CreateFace(16).TextureID = textures.GetFace(16).TextureID;
|
||||
te2.CreateFace(15).TextureID = textures.GetFace(15).TextureID;
|
||||
te2.CreateFace(2).TextureID = textures.GetFace(2).TextureID;
|
||||
te2.CreateFace(12).TextureID = textures.GetFace(12).TextureID;
|
||||
te2.CreateFace(7).TextureID = textures.GetFace(7).TextureID;
|
||||
te2.CreateFace(6).TextureID = textures.GetFace(6).TextureID;
|
||||
te2.CreateFace(5).TextureID = textures.GetFace(5).TextureID;
|
||||
te2.CreateFace(4).TextureID = textures.GetFace(4).TextureID;
|
||||
te2.CreateFace(3).TextureID = textures.GetFace(3).TextureID;
|
||||
te2.CreateFace(1).TextureID = textures.GetFace(1).TextureID;
|
||||
te2.CreateFace(0).TextureID = textures.GetFace(0).TextureID;
|
||||
p.ObjectData.TextureEntry = te2.ToBytes();
|
||||
TextureEntry te2 = new TextureEntry(AgentTextureEntry.DefaultTexture.TextureID);
|
||||
te2.CreateFace(18).TextureID = AgentTextureEntry.GetFace(18).TextureID;
|
||||
te2.CreateFace(17).TextureID = AgentTextureEntry.GetFace(17).TextureID;
|
||||
te2.CreateFace(16).TextureID = AgentTextureEntry.GetFace(16).TextureID;
|
||||
te2.CreateFace(15).TextureID = AgentTextureEntry.GetFace(15).TextureID;
|
||||
te2.CreateFace(2).TextureID = AgentTextureEntry.GetFace(2).TextureID;
|
||||
te2.CreateFace(12).TextureID = AgentTextureEntry.GetFace(12).TextureID;
|
||||
te2.CreateFace(7).TextureID = AgentTextureEntry.GetFace(7).TextureID;
|
||||
te2.CreateFace(6).TextureID = AgentTextureEntry.GetFace(6).TextureID;
|
||||
te2.CreateFace(5).TextureID = AgentTextureEntry.GetFace(5).TextureID;
|
||||
te2.CreateFace(4).TextureID = AgentTextureEntry.GetFace(4).TextureID;
|
||||
te2.CreateFace(3).TextureID = AgentTextureEntry.GetFace(3).TextureID;
|
||||
te2.CreateFace(1).TextureID = AgentTextureEntry.GetFace(1).TextureID;
|
||||
te2.CreateFace(0).TextureID = AgentTextureEntry.GetFace(0).TextureID;
|
||||
|
||||
AgentTextureEntry = te2;
|
||||
}
|
||||
|
||||
private Dictionary<uint, byte> GetAssetParamsAsVisualParams()
|
||||
{
|
||||
Dictionary<uint, byte> VisualParams = new Dictionary<uint, byte>();
|
||||
|
||||
float maxVal = 0;
|
||||
float minVal = 0;
|
||||
uint packetIdx = 0;
|
||||
float range = 0;
|
||||
float percentage = 0;
|
||||
byte packetVal = 0;
|
||||
|
||||
foreach (KeyValuePair<uint, float> kvp in AgentAppearanceParams)
|
||||
{
|
||||
packetIdx = AppearanceManager.GetAgentSetAppearanceIndex(kvp.Key) - 1; //TODO/FIXME: this should be zero indexed, not 1 based.
|
||||
maxVal = BodyShapeParams.GetValueMax(kvp.Key);
|
||||
minVal = BodyShapeParams.GetValueMin(kvp.Key);
|
||||
|
||||
range = maxVal - minVal;
|
||||
|
||||
percentage = (kvp.Value - minVal) / range;
|
||||
|
||||
packetVal = (byte)(percentage * (byte)255);
|
||||
|
||||
VisualParams[packetIdx] = packetVal;
|
||||
}
|
||||
|
||||
return VisualParams;
|
||||
}
|
||||
|
||||
private LLVector3 GetAgentSizeFromVisualParams(Dictionary<uint, byte> VisualParams)
|
||||
{
|
||||
float AV_Height_Range = 2.025506f - 1.50856f;
|
||||
float AV_Height = 1.50856f + (((float)VisualParams[25] / 255.0f) * AV_Height_Range);
|
||||
return new LLVector3(0.45f, 0.6f, AV_Height);
|
||||
}
|
||||
|
||||
public void SendAgentSetAppearance()
|
||||
{
|
||||
// Get latest appearance info
|
||||
if (AgentAppearanceParams.Count == 0)
|
||||
{
|
||||
GetAvatarAppearanceInfoFromWearableAssets();
|
||||
}
|
||||
|
||||
AgentSetAppearancePacket p = new AgentSetAppearancePacket();
|
||||
p.AgentData.AgentID = Client.Network.AgentID;
|
||||
p.AgentData.SessionID = Client.Network.SessionID;
|
||||
p.AgentData.SerialNum = ++SerialNum;
|
||||
|
||||
// Add Texture Data
|
||||
p.ObjectData.TextureEntry = AgentTextureEntry.ToBytes();
|
||||
|
||||
// Add Visual Params
|
||||
Dictionary<uint, byte> VisualParams = GetAssetParamsAsVisualParams();
|
||||
p.VisualParam = new AgentSetAppearancePacket.VisualParamBlock[218];
|
||||
for (uint i = 0; i < 218; i++)
|
||||
{
|
||||
@@ -240,33 +226,22 @@ namespace libsecondlife.AssetSystem
|
||||
uint paramid = GetParamID(i + 1);
|
||||
float defaultValue = BodyShapeParams.GetValueDefault(paramid);
|
||||
|
||||
maxVal = BodyShapeParams.GetValueMax(paramid);
|
||||
minVal = BodyShapeParams.GetValueMin(paramid);
|
||||
float minVal = BodyShapeParams.GetValueMin(paramid);
|
||||
|
||||
range = maxVal - minVal;
|
||||
float range = BodyShapeParams.GetValueMax(paramid) - minVal;
|
||||
|
||||
percentage = (defaultValue - minVal) / range;
|
||||
float percentage = (defaultValue - minVal) / range;
|
||||
|
||||
packetVal = (byte)(percentage * (byte)255);
|
||||
byte packetVal = (byte)(percentage * (byte)255);
|
||||
|
||||
// Console.WriteLine("Warning Visual Param not defined, IDX: " + (i+1));
|
||||
// Console.WriteLine("PID: " + paramid + " / Default: " + defaultValue);
|
||||
p.VisualParam[i].ParamValue = packetVal;
|
||||
}
|
||||
}
|
||||
|
||||
// Add Size Data
|
||||
p.AgentData.Size = GetAgentSizeFromVisualParams(VisualParams);
|
||||
|
||||
Client.Network.SendPacket(p);
|
||||
|
||||
Console.WriteLine("Default: " + textures.DefaultTexture.TextureID);
|
||||
|
||||
foreach (KeyValuePair<uint, TextureEntryFace> kvp in textures.FaceTextures)
|
||||
{
|
||||
Console.WriteLine(kvp.Key + " : " + kvp.Value.TextureID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Console.WriteLine(p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -43,8 +43,6 @@ namespace libsecondlife.AssetSystem
|
||||
/// </summary>
|
||||
public class AssetManager
|
||||
{
|
||||
private static Dictionary<LLUUID,AssetManager> AssetManagers = new Dictionary<LLUUID,AssetManager>();
|
||||
|
||||
public const int SINK_FEE_IMAGE = 1;
|
||||
|
||||
private SecondLife slClient;
|
||||
@@ -55,12 +53,13 @@ namespace libsecondlife.AssetSystem
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
private AssetManager(SecondLife client)
|
||||
internal AssetManager(SecondLife client)
|
||||
{
|
||||
slClient = client;
|
||||
|
||||
// need to make sure we don't keep around old AssetManagers connected to stale instances of SL
|
||||
// Need to know when we're Connected/Disconnected to clear state
|
||||
slClient.Network.OnDisconnected += new NetworkManager.DisconnectCallback(Network_OnDisconnected);
|
||||
slClient.Network.OnConnected += new NetworkManager.ConnectedCallback(Network_OnConnected);
|
||||
|
||||
// Used to upload small assets, or as an initial start packet for large transfers
|
||||
slClient.Network.RegisterCallback(PacketType.AssetUploadComplete, new NetworkManager.PacketCallback(AssetUploadCompleteCallbackHandler));
|
||||
@@ -72,30 +71,20 @@ namespace libsecondlife.AssetSystem
|
||||
slClient.Network.RegisterCallback(PacketType.RequestXfer, new NetworkManager.PacketCallback(RequestXferCallbackHandler));
|
||||
}
|
||||
|
||||
void Network_OnDisconnected(NetworkManager.DisconnectType reason, string message)
|
||||
void Network_OnConnected(object sender)
|
||||
{
|
||||
// Remove this asset manager from the managers list.
|
||||
AssetManager.AssetManagers.Remove(this.slClient.Network.AgentID);
|
||||
ClearState();
|
||||
}
|
||||
|
||||
public static AssetManager GetAssetManager( SecondLife client )
|
||||
void Network_OnDisconnected(NetworkManager.DisconnectType reason, string message)
|
||||
{
|
||||
lock (AssetManagers)
|
||||
{
|
||||
if (AssetManagers.ContainsKey(client.Network.AgentID))
|
||||
{
|
||||
AssetManager existingAssetManager = AssetManagers[client.Network.AgentID];
|
||||
if (existingAssetManager.slClient.Network.Connected == false)
|
||||
{
|
||||
existingAssetManager.slClient = client;
|
||||
}
|
||||
return existingAssetManager;
|
||||
} else {
|
||||
AssetManager am = new AssetManager(client);
|
||||
AssetManagers[client.Network.AgentID] = am;
|
||||
return am;
|
||||
}
|
||||
}
|
||||
ClearState();
|
||||
}
|
||||
|
||||
private void ClearState()
|
||||
{
|
||||
htDownloadRequests.Clear();
|
||||
curUploadRequest = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -9,6 +9,8 @@ namespace libsecondlife.InventorySystem
|
||||
/// </summary>
|
||||
public class InventoryFolder : InventoryBase
|
||||
{
|
||||
public enum FolderUpdateFlag { None, NoRecurse, Recurse };
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _Name; }
|
||||
@@ -33,10 +35,10 @@ namespace libsecondlife.InventorySystem
|
||||
set
|
||||
{
|
||||
InventoryFolder ifParent = iManager.getFolder(this.ParentID);
|
||||
ifParent.alContents.Remove(this);
|
||||
ifParent._Contents.Remove(this);
|
||||
|
||||
ifParent = iManager.getFolder(value);
|
||||
ifParent.alContents.Add(this);
|
||||
ifParent._Contents.Add(this);
|
||||
|
||||
this._ParentID = value;
|
||||
|
||||
@@ -50,7 +52,8 @@ namespace libsecondlife.InventorySystem
|
||||
get { return _Type; }
|
||||
}
|
||||
|
||||
public List<InventoryBase> alContents = new List<InventoryBase>();
|
||||
internal List<InventoryBase> _Contents = new List<InventoryBase>();
|
||||
|
||||
|
||||
internal InventoryFolder(InventoryManager manager)
|
||||
: base(manager)
|
||||
@@ -88,6 +91,29 @@ namespace libsecondlife.InventorySystem
|
||||
this._Type = sbyte.Parse(htData["type_default"].ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the contents of this folder
|
||||
/// </summary>
|
||||
/// <returns>Contents of this folder</returns>
|
||||
public List<InventoryBase> GetContents()
|
||||
{
|
||||
return _Contents;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request a download of this folder's content information.
|
||||
/// </summary>
|
||||
/// <param name="Recurse">Indicate if we should recursively download content information.</param>
|
||||
/// <returns>The Request object for this download</returns>
|
||||
public DownloadRequest_Folder BeginDownloadContents(bool recurse)
|
||||
{
|
||||
_Contents.Clear();
|
||||
|
||||
DownloadRequest_Folder dr = new DownloadRequest_Folder(FolderID, recurse);
|
||||
iManager.RequestFolder(dr);
|
||||
|
||||
return dr;
|
||||
}
|
||||
|
||||
public InventoryFolder CreateFolder(string name)
|
||||
{
|
||||
@@ -96,7 +122,7 @@ namespace libsecondlife.InventorySystem
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
iManager.getFolder(this.ParentID).alContents.Remove(this);
|
||||
iManager.getFolder(this.ParentID)._Contents.Remove(this);
|
||||
iManager.FolderRemove(this);
|
||||
}
|
||||
|
||||
@@ -123,7 +149,7 @@ namespace libsecondlife.InventorySystem
|
||||
public List<InventoryBase> GetItemByName(string name)
|
||||
{
|
||||
List<InventoryBase> items = new List<InventoryBase>();
|
||||
foreach (InventoryBase ib in alContents)
|
||||
foreach (InventoryBase ib in _Contents)
|
||||
{
|
||||
if (ib is InventoryFolder)
|
||||
{
|
||||
@@ -155,7 +181,7 @@ namespace libsecondlife.InventorySystem
|
||||
output += "Type = '" + Type + "' ";
|
||||
output += ">\n";
|
||||
|
||||
foreach (Object oContent in alContents)
|
||||
foreach (Object oContent in _Contents)
|
||||
{
|
||||
output += ((InventoryBase)oContent).toXML(outputAssets);
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ namespace libsecondlife.InventorySystem
|
||||
throw new Exception("Target Folder [" + value + "] does not exist.");
|
||||
}
|
||||
|
||||
base.iManager.getFolder(this.FolderID).alContents.Remove(this);
|
||||
iTargetFolder.alContents.Add(this);
|
||||
base.iManager.getFolder(this.FolderID)._Contents.Remove(this);
|
||||
iTargetFolder._Contents.Add(this);
|
||||
|
||||
_FolderID = value;
|
||||
UpdateItem();
|
||||
@@ -422,7 +422,7 @@ namespace libsecondlife.InventorySystem
|
||||
/// </summary>
|
||||
public void Delete()
|
||||
{
|
||||
base.iManager.getFolder(this.FolderID).alContents.Remove(this);
|
||||
base.iManager.getFolder(this.FolderID)._Contents.Remove(this);
|
||||
base.iManager.ItemRemove(this);
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
//#define DEBUG_PACKETS
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
@@ -46,6 +47,7 @@ namespace libsecondlife.InventorySystem
|
||||
|
||||
// Reference to the SLClient Library
|
||||
private SecondLife slClient;
|
||||
private ManualResetEvent InventoryManagerInitialized = new ManualResetEvent(false);
|
||||
|
||||
// Reference to the Asset Manager
|
||||
private static AssetManager slAssetManager;
|
||||
@@ -56,15 +58,12 @@ namespace libsecondlife.InventorySystem
|
||||
|
||||
public InventoryPacketHelper InvPacketHelper = null;
|
||||
|
||||
// UUID of Root Inventory Folder
|
||||
private LLUUID uuidRootFolder;
|
||||
|
||||
// Setup a dictionary to easily lookup folders by UUID
|
||||
private Dictionary<LLUUID, InventoryFolder> htFoldersByUUID = new Dictionary<LLUUID, InventoryFolder>();
|
||||
|
||||
// Setup a dictionary to track download progress
|
||||
private Dictionary<LLUUID, DescendentRequest> htFolderDownloadStatus;
|
||||
private List<DescendentRequest> alFolderRequestQueue;
|
||||
private Dictionary<LLUUID, DownloadRequest_Folder> FolderDownloadStatus = new Dictionary<LLUUID, DownloadRequest_Folder>();
|
||||
private List<DownloadRequest_Folder> alFolderRequestQueue = new List<DownloadRequest_Folder>();
|
||||
|
||||
// Used to track current item being created
|
||||
private InventoryItem iiCreationInProgress;
|
||||
@@ -73,19 +72,16 @@ namespace libsecondlife.InventorySystem
|
||||
private int LastPacketRecievedAtTick;
|
||||
|
||||
// Each InventorySystem needs to be initialized with a client and root folder.
|
||||
public InventoryManager(SecondLife client, LLUUID rootFolder)
|
||||
public InventoryManager(SecondLife client)
|
||||
{
|
||||
slClient = client;
|
||||
if (slAssetManager == null)
|
||||
{
|
||||
slAssetManager = AssetManager.GetAssetManager(slClient);
|
||||
}
|
||||
slAssetManager = slClient.Assets;
|
||||
|
||||
InvPacketHelper = new InventoryPacketHelper(slClient.Network.AgentID, slClient.Network.SessionID);
|
||||
InvPacketHelper = new InventoryPacketHelper(slClient);
|
||||
|
||||
uuidRootFolder = rootFolder;
|
||||
|
||||
resetFoldersByUUID();
|
||||
// Need to know what when we're connected/disconnected
|
||||
slClient.Network.OnConnected += new NetworkManager.ConnectedCallback(Network_OnConnected);
|
||||
slClient.Network.OnDisconnected += new NetworkManager.DisconnectCallback(Network_OnDisconnected);
|
||||
|
||||
// Setup the callback for Inventory Downloads
|
||||
slClient.Network.RegisterCallback(PacketType.InventoryDescendents, new NetworkManager.PacketCallback(InventoryDescendentsHandler));
|
||||
@@ -95,25 +91,35 @@ namespace libsecondlife.InventorySystem
|
||||
|
||||
}
|
||||
|
||||
// Used primarily for debugging and testing
|
||||
public AssetManager getAssetManager()
|
||||
void Network_OnDisconnected(NetworkManager.DisconnectType reason, string message)
|
||||
{
|
||||
// Console.WriteLine("It is not recommended that you access the asset manager directly");
|
||||
return AssetManager;
|
||||
// Clear out current state
|
||||
ClearState();
|
||||
}
|
||||
|
||||
private void resetFoldersByUUID()
|
||||
void Network_OnConnected(object sender)
|
||||
{
|
||||
// Init folder structure with root
|
||||
htFoldersByUUID = new Dictionary<LLUUID,InventoryFolder>();
|
||||
// Clear out current state
|
||||
ClearState();
|
||||
}
|
||||
|
||||
InventoryFolder ifRootFolder = new InventoryFolder(this, "My Inventory", uuidRootFolder, null);
|
||||
htFoldersByUUID[uuidRootFolder] = ifRootFolder;
|
||||
private void ClearState()
|
||||
{
|
||||
htFoldersByUUID.Clear();
|
||||
FolderDownloadStatus.Clear();
|
||||
alFolderRequestQueue.Clear();
|
||||
|
||||
if (slClient.Self.InventoryRootFolderUUID != null)
|
||||
{
|
||||
// Init folder structure with root
|
||||
InventoryFolder ifRootFolder = new InventoryFolder(this, "My Inventory", slClient.Self.InventoryRootFolderUUID, null);
|
||||
htFoldersByUUID[slClient.Self.InventoryRootFolderUUID] = ifRootFolder;
|
||||
}
|
||||
}
|
||||
|
||||
public InventoryFolder getRootFolder()
|
||||
{
|
||||
return htFoldersByUUID[uuidRootFolder];
|
||||
return htFoldersByUUID[slClient.Self.InventoryRootFolderUUID];
|
||||
}
|
||||
|
||||
public InventoryFolder getFolder(LLUUID folderID)
|
||||
@@ -157,7 +163,7 @@ namespace libsecondlife.InventorySystem
|
||||
{
|
||||
string sCurFolder = qFolderPath.Dequeue();
|
||||
|
||||
foreach (InventoryBase ibFolder in ifRoot.alContents)
|
||||
foreach (InventoryBase ibFolder in ifRoot._Contents)
|
||||
{
|
||||
if (ibFolder is libsecondlife.InventorySystem.InventoryFolder)
|
||||
{
|
||||
@@ -178,14 +184,18 @@ namespace libsecondlife.InventorySystem
|
||||
return null;
|
||||
}
|
||||
|
||||
private void RequestFolder(DescendentRequest dr)
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dr"></param>
|
||||
internal void RequestFolder(DownloadRequest_Folder dr)
|
||||
{
|
||||
Packet packet = InvPacketHelper.FetchInventoryDescendents(
|
||||
dr.FolderID
|
||||
, dr.FetchFolders
|
||||
, dr.FetchItems);
|
||||
|
||||
htFolderDownloadStatus[dr.FolderID] = dr;
|
||||
FolderDownloadStatus[dr.FolderID] = dr;
|
||||
|
||||
slClient.Network.SendPacket(packet);
|
||||
}
|
||||
@@ -197,10 +207,10 @@ namespace libsecondlife.InventorySystem
|
||||
|
||||
if (htFoldersByUUID.ContainsKey(ifolder.ParentID))
|
||||
{
|
||||
if (((InventoryFolder)htFoldersByUUID[ifolder.ParentID]).alContents.Contains(ifolder) == false)
|
||||
if (((InventoryFolder)htFoldersByUUID[ifolder.ParentID])._Contents.Contains(ifolder) == false)
|
||||
{
|
||||
// Add new folder to the contents of the parent folder.
|
||||
((InventoryFolder)htFoldersByUUID[ifolder.ParentID]).alContents.Add(ifolder);
|
||||
((InventoryFolder)htFoldersByUUID[ifolder.ParentID])._Contents.Add(ifolder);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -317,7 +327,7 @@ namespace libsecondlife.InventorySystem
|
||||
internal void ItemRemove(InventoryItem iitem)
|
||||
{
|
||||
InventoryFolder ifolder = getFolder(iitem.FolderID);
|
||||
ifolder.alContents.Remove(iitem);
|
||||
ifolder._Contents.Remove(iitem);
|
||||
|
||||
Packet packet = InvPacketHelper.RemoveInventoryItem(iitem.ItemID);
|
||||
slClient.Network.SendPacket(packet);
|
||||
@@ -359,16 +369,16 @@ namespace libsecondlife.InventorySystem
|
||||
|
||||
public void DownloadInventory()
|
||||
{
|
||||
resetFoldersByUUID();
|
||||
ClearState();
|
||||
|
||||
if (htFolderDownloadStatus == null)
|
||||
if (FolderDownloadStatus == null)
|
||||
{
|
||||
// Create status table
|
||||
htFolderDownloadStatus = new Dictionary<LLUUID,DescendentRequest>();
|
||||
FolderDownloadStatus = new Dictionary<LLUUID, DownloadRequest_Folder>();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (htFolderDownloadStatus.Count != 0)
|
||||
if (FolderDownloadStatus.Count != 0)
|
||||
{
|
||||
throw new Exception("Inventory Download requested while previous download in progress.");
|
||||
}
|
||||
@@ -376,7 +386,7 @@ namespace libsecondlife.InventorySystem
|
||||
|
||||
if (alFolderRequestQueue == null)
|
||||
{
|
||||
alFolderRequestQueue = new List<DescendentRequest>();
|
||||
alFolderRequestQueue = new List<DownloadRequest_Folder>();
|
||||
}
|
||||
|
||||
// Set last packet received to now, just so out time-out timer works
|
||||
@@ -384,13 +394,13 @@ namespace libsecondlife.InventorySystem
|
||||
|
||||
// Send Packet requesting the root Folder,
|
||||
// this should recurse through all folders
|
||||
RequestFolder(new DescendentRequest(uuidRootFolder));
|
||||
RequestFolder(new DownloadRequest_Folder(slClient.Self.InventoryRootFolderUUID));
|
||||
|
||||
while ((htFolderDownloadStatus.Count > 0) || (alFolderRequestQueue.Count > 0))
|
||||
while ((FolderDownloadStatus.Count > 0) || (alFolderRequestQueue.Count > 0))
|
||||
{
|
||||
if (htFolderDownloadStatus.Count == 0)
|
||||
if (FolderDownloadStatus.Count == 0)
|
||||
{
|
||||
DescendentRequest dr = alFolderRequestQueue[0];
|
||||
DownloadRequest_Folder dr = alFolderRequestQueue[0];
|
||||
alFolderRequestQueue.RemoveAt(0);
|
||||
RequestFolder(dr);
|
||||
}
|
||||
@@ -403,14 +413,14 @@ namespace libsecondlife.InventorySystem
|
||||
|
||||
// have to make a seperate list otherwise we run into modifying the original array
|
||||
// while still enumerating it.
|
||||
List<DescendentRequest> alRestartList = new List<DescendentRequest>();
|
||||
List<DownloadRequest_Folder> alRestartList = new List<DownloadRequest_Folder>();
|
||||
|
||||
//if (htFolderDownloadStatus[0] != null)
|
||||
//if (FolderDownloadStatus[0] != null)
|
||||
//{
|
||||
// Console.WriteLine(htFolderDownloadStatus[0].GetType());
|
||||
// Console.WriteLine(FolderDownloadStatus[0].GetType());
|
||||
//}
|
||||
|
||||
foreach (DescendentRequest dr in htFolderDownloadStatus.Values)
|
||||
foreach (DownloadRequest_Folder dr in FolderDownloadStatus.Values)
|
||||
{
|
||||
Console.WriteLine(dr.FolderID + " " + dr.Expected + " / " + dr.Received + " / " + dr.LastReceivedAtTick);
|
||||
|
||||
@@ -418,7 +428,7 @@ namespace libsecondlife.InventorySystem
|
||||
}
|
||||
|
||||
LastPacketRecievedAtTick = Environment.TickCount;
|
||||
foreach (DescendentRequest dr in alRestartList)
|
||||
foreach (DownloadRequest_Folder dr in alRestartList)
|
||||
{
|
||||
RequestFolder(dr);
|
||||
}
|
||||
@@ -477,21 +487,36 @@ namespace libsecondlife.InventorySystem
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returned in response to a InventoryDescendantRequest. Contains information about the
|
||||
/// contents of a folder.
|
||||
/// </summary>
|
||||
/// <seealso cref="InventoryManager.RequestFolder"/>
|
||||
/// <param name="packet"></param>
|
||||
/// <param name="simulator"></param>
|
||||
public void InventoryDescendentsHandler(Packet packet, Simulator simulator)
|
||||
{
|
||||
InventoryDescendentsPacket reply = (InventoryDescendentsPacket)packet;
|
||||
|
||||
// The UUID of this folder.
|
||||
LLUUID uuidFolderID = reply.AgentData.FolderID;
|
||||
|
||||
// Get the original Descendent Request for this Packet
|
||||
DownloadRequest_Folder dr = (DownloadRequest_Folder)FolderDownloadStatus[uuidFolderID];
|
||||
|
||||
// Update Inventory Manager's last tick point, used for timeouts and such
|
||||
LastPacketRecievedAtTick = Environment.TickCount;
|
||||
|
||||
// Some temp variables to be reused as we're parsing the packet
|
||||
InventoryItem invItem;
|
||||
InventoryFolder invFolder;
|
||||
|
||||
LLUUID uuidFolderID = LLUUID.Zero;
|
||||
|
||||
int iDescendentsExpected = int.MaxValue;
|
||||
// Used to count the number of descendants received to see if we're finished or not.
|
||||
int iDescendentsExpected = reply.AgentData.Descendents;
|
||||
int iDescendentsReceivedThisBlock = 0;
|
||||
|
||||
|
||||
|
||||
foreach (InventoryDescendentsPacket.ItemDataBlock itemBlock in reply.ItemData)
|
||||
{
|
||||
// There is always an item block, even if there isn't any items
|
||||
@@ -502,8 +527,8 @@ namespace libsecondlife.InventorySystem
|
||||
|
||||
if (itemBlock.ItemID == LLUUID.Zero)
|
||||
{
|
||||
// this shouldn't ever happen, but unless you've uploaded an invalid item
|
||||
// to yourself while developping inventory code
|
||||
// this shouldn't ever happen, unless you've uploaded an invalid item
|
||||
// to yourself while developping inventory code :-(
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -511,7 +536,7 @@ namespace libsecondlife.InventorySystem
|
||||
|
||||
InventoryFolder ifolder = (InventoryFolder)htFoldersByUUID[invItem.FolderID];
|
||||
|
||||
if (ifolder.alContents.Contains(invItem) == false)
|
||||
if (ifolder._Contents.Contains(invItem) == false)
|
||||
{
|
||||
if ((invItem.InvType == 7) && (invItem.Type == Asset.ASSET_TYPE_NOTECARD))
|
||||
{
|
||||
@@ -525,7 +550,7 @@ namespace libsecondlife.InventorySystem
|
||||
invItem = temp;
|
||||
}
|
||||
|
||||
ifolder.alContents.Add(invItem);
|
||||
ifolder._Contents.Add(invItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -549,9 +574,9 @@ namespace libsecondlife.InventorySystem
|
||||
|
||||
// Add folder to Parent
|
||||
InventoryFolder ifolder = (InventoryFolder)htFoldersByUUID[invFolder.ParentID];
|
||||
if (ifolder.alContents.Contains(invFolder) == false)
|
||||
if (ifolder._Contents.Contains(invFolder) == false)
|
||||
{
|
||||
ifolder.alContents.Add(invFolder);
|
||||
ifolder._Contents.Add(invFolder);
|
||||
}
|
||||
|
||||
|
||||
@@ -559,45 +584,45 @@ namespace libsecondlife.InventorySystem
|
||||
htFoldersByUUID[invFolder.FolderID] = invFolder;
|
||||
|
||||
|
||||
// It's not the root, should be safe to "recurse"
|
||||
if (!invFolder.FolderID.Equals(uuidRootFolder))
|
||||
// Do we recurse?
|
||||
if (dr.Recurse)
|
||||
{
|
||||
bool alreadyQueued = false;
|
||||
foreach (DescendentRequest dr in alFolderRequestQueue)
|
||||
// It's not the root, should be safe to "recurse"
|
||||
if (!invFolder.FolderID.Equals(slClient.Self.InventoryRootFolderUUID))
|
||||
{
|
||||
if (dr.FolderID == invFolder.FolderID)
|
||||
bool alreadyQueued = false;
|
||||
foreach (DownloadRequest_Folder adr in alFolderRequestQueue)
|
||||
{
|
||||
alreadyQueued = true;
|
||||
break;
|
||||
if (adr.FolderID == invFolder.FolderID)
|
||||
{
|
||||
alreadyQueued = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadyQueued)
|
||||
{
|
||||
alFolderRequestQueue.Add(new DescendentRequest(invFolder.FolderID));
|
||||
if (!alreadyQueued)
|
||||
{
|
||||
alFolderRequestQueue.Add(new DownloadRequest_Folder(invFolder.FolderID));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check how many descendents we're actually supposed to receive
|
||||
iDescendentsExpected = reply.AgentData.Descendents;
|
||||
uuidFolderID = reply.AgentData.FolderID;
|
||||
|
||||
// Update download status for this folder
|
||||
if (iDescendentsReceivedThisBlock >= iDescendentsExpected)
|
||||
{
|
||||
// We received all the descendents we're expecting for this folder
|
||||
// in this packet, so go ahead and remove folder from status list.
|
||||
htFolderDownloadStatus.Remove(uuidFolderID);
|
||||
FolderDownloadStatus.Remove(uuidFolderID);
|
||||
dr.RequestComplete.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
// This one packet didn't have all the descendents we're expecting
|
||||
// so update the total we're expecting, and update the total downloaded
|
||||
|
||||
DescendentRequest dr = (DescendentRequest)htFolderDownloadStatus[uuidFolderID];
|
||||
dr.Expected = iDescendentsExpected;
|
||||
dr.Received += iDescendentsReceivedThisBlock;
|
||||
dr.LastReceivedAtTick = Environment.TickCount;
|
||||
@@ -606,41 +631,15 @@ namespace libsecondlife.InventorySystem
|
||||
{
|
||||
// Looks like after updating, we have all the descendents,
|
||||
// remove from folder status.
|
||||
htFolderDownloadStatus.Remove(uuidFolderID);
|
||||
FolderDownloadStatus.Remove(uuidFolderID);
|
||||
dr.RequestComplete.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
htFolderDownloadStatus[uuidFolderID] = dr;
|
||||
FolderDownloadStatus[uuidFolderID] = dr;
|
||||
// Console.WriteLine( uuidFolderID + " is expecting " + (iDescendentsExpected - iStatus[1]) + " more packets." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DescendentRequest
|
||||
{
|
||||
public LLUUID FolderID;
|
||||
|
||||
public int Expected = int.MaxValue;
|
||||
public int Received = 0;
|
||||
public int LastReceivedAtTick = 0;
|
||||
|
||||
public bool FetchFolders = true;
|
||||
public bool FetchItems = true;
|
||||
|
||||
public DescendentRequest(LLUUID folderID)
|
||||
{
|
||||
FolderID = folderID;
|
||||
LastReceivedAtTick = Environment.TickCount;
|
||||
}
|
||||
|
||||
public DescendentRequest(LLUUID folderID, bool fetchFolders, bool fetchItems)
|
||||
{
|
||||
FolderID = folderID;
|
||||
FetchFolders = fetchFolders;
|
||||
FetchItems = fetchItems;
|
||||
LastReceivedAtTick = Environment.TickCount;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,21 @@ namespace libsecondlife.InventorySystem
|
||||
/// </summary>
|
||||
public class InventoryPacketHelper
|
||||
{
|
||||
private LLUUID AgentID;
|
||||
private LLUUID SessionID;
|
||||
private SecondLife Client;
|
||||
|
||||
public InventoryPacketHelper(LLUUID AgentID, LLUUID SessionID)
|
||||
private LLUUID AgentID
|
||||
{
|
||||
get { return Client.Network.AgentID; }
|
||||
}
|
||||
|
||||
private LLUUID SessionID
|
||||
{
|
||||
get { return Client.Network.SessionID; }
|
||||
}
|
||||
|
||||
public InventoryPacketHelper(SecondLife client)
|
||||
{
|
||||
this.AgentID = AgentID;
|
||||
this.SessionID = SessionID;
|
||||
Client = client;
|
||||
}
|
||||
|
||||
public const int FETCH_INVENTORY_SORT_NAME = 0;
|
||||
|
||||
@@ -175,6 +175,9 @@ namespace libsecondlife
|
||||
public LLVector3 HomeLookAt = LLVector3.Zero;
|
||||
/// <summary>Used for camera and control key state tracking</summary>
|
||||
public MainAvatarStatus Status;
|
||||
/// <summary>The UUID of your root inventory folder</summary>
|
||||
public LLUUID InventoryRootFolderUUID;
|
||||
|
||||
|
||||
/// <summary>Gets the health of the agent</summary>
|
||||
public float Health
|
||||
|
||||
@@ -1154,6 +1154,13 @@ namespace libsecondlife
|
||||
Client.Self.HomePosition = posVector;
|
||||
Client.Self.HomeLookAt = lookatVector;
|
||||
|
||||
// Get Inventory Root Folder
|
||||
Client.Log("Pulling root folder UUID from login data.", Helpers.LogLevel.Debug);
|
||||
ArrayList alInventoryRoot = (ArrayList)LoginValues["inventory-root"];
|
||||
Hashtable htInventoryRoot = (Hashtable)alInventoryRoot[0];
|
||||
Client.Self.InventoryRootFolderUUID = new LLUUID((string)htInventoryRoot["folder_id"]);
|
||||
|
||||
|
||||
// Connect to the sim given in the login reply
|
||||
Simulator simulator = new Simulator(Client, this.Callbacks, (uint)(int)LoginValues["circuit_code"],
|
||||
IPAddress.Parse((string)LoginValues["sim_ip"]), (int)LoginValues["sim_port"]);
|
||||
|
||||
@@ -28,6 +28,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using libsecondlife.Packets;
|
||||
using libsecondlife.AssetSystem;
|
||||
using libsecondlife.InventorySystem;
|
||||
|
||||
namespace libsecondlife
|
||||
{
|
||||
@@ -60,34 +61,19 @@ namespace libsecondlife
|
||||
public ObjectManager Objects;
|
||||
/// <summary>Group Subsystem</summary>
|
||||
public GroupManager Groups;
|
||||
|
||||
/// <summary>Asset Subsystem</summary>
|
||||
public AssetManager Assets;
|
||||
/// <summary>Inventory Subsystem</summary>
|
||||
public InventoryManager Inventory;
|
||||
/// <summary>Image Subsystem</summary>
|
||||
public ImageManager Images;
|
||||
|
||||
/// <summary>Throttling Subsystem</summary>
|
||||
public AgentThrottle Throttle;
|
||||
/// <summary>Settings Subsystem</summary>
|
||||
public Settings Settings;
|
||||
|
||||
private ImageManager _ImageManager;
|
||||
/// <summary>Image Subsystem</summary>
|
||||
public ImageManager Images
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ImageManager == null)
|
||||
{
|
||||
_ImageManager = new ImageManager(this);
|
||||
return _ImageManager;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _ImageManager;
|
||||
}
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_ImageManager = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Triggered whenever a message is logged.
|
||||
/// If this is left null, log messages will go to
|
||||
/// the console</summary>
|
||||
@@ -107,6 +93,11 @@ namespace libsecondlife
|
||||
Grid = new GridManager(this);
|
||||
Objects = new ObjectManager(this);
|
||||
Groups = new GroupManager(this);
|
||||
|
||||
Assets = new AssetManager(this);
|
||||
Images = new ImageManager(this);
|
||||
Inventory = new InventoryManager(this);
|
||||
|
||||
Throttle = new AgentThrottle(this);
|
||||
Settings = new Settings(this);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
using IA_SimpleInventory;
|
||||
|
||||
@@ -13,8 +14,12 @@ namespace IA_ImageTool
|
||||
/// <summary>
|
||||
/// Summary description for Class1.
|
||||
/// </summary>
|
||||
class ImageTool : SimpleInventory
|
||||
class ImageTool
|
||||
{
|
||||
private SecondLife _Client;
|
||||
private ManualResetEvent ConnectedSignal = new ManualResetEvent(false);
|
||||
|
||||
|
||||
private List<LLUUID> _ImageIDs = new List<LLUUID>();
|
||||
private string _FileName;
|
||||
private bool _Put;
|
||||
@@ -24,7 +29,7 @@ namespace IA_ImageTool
|
||||
/// Used to upload/download images.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static new void Main(string[] args)
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if ( (File.Exists("libjasper.dll") == false) )
|
||||
{
|
||||
@@ -94,17 +99,16 @@ namespace IA_ImageTool
|
||||
|
||||
ImageTool it = new ImageTool(uuidList, filename, put, rate);
|
||||
|
||||
// Only download the inventory tree if we're planning on putting/uploading files.
|
||||
it.DownloadInventoryOnConnect = put;
|
||||
|
||||
if (it.Connect(args[0], args[1], args[2]))
|
||||
{
|
||||
it.doStuff();
|
||||
it.Disconnect();
|
||||
if (it.ConnectedSignal.WaitOne(TimeSpan.FromMinutes(1), false))
|
||||
{
|
||||
it.doStuff();
|
||||
|
||||
System.Threading.Thread.Sleep(500);
|
||||
it.Disconnect();
|
||||
}
|
||||
|
||||
Console.WriteLine("Done logging out.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,12 +118,62 @@ namespace IA_ImageTool
|
||||
_FileName = filename;
|
||||
_Put = put;
|
||||
_Rate = rate;
|
||||
|
||||
try
|
||||
{
|
||||
_Client = new SecondLife();
|
||||
_Client.Network.OnConnected += new NetworkManager.ConnectedCallback(Network_OnConnected);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Error initializing the client
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(e.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected new void doStuff()
|
||||
void Network_OnConnected(object sender)
|
||||
{
|
||||
ConnectedSignal.Set();
|
||||
}
|
||||
|
||||
protected bool Connect(string FirstName, string LastName, string Password)
|
||||
{
|
||||
Console.WriteLine("Attempting to connect and login to SecondLife.");
|
||||
|
||||
// Setup Login to Second Life
|
||||
Dictionary<string, object> loginReply = new Dictionary<string, object>();
|
||||
|
||||
// Login
|
||||
if (!_Client.Network.Login(FirstName, LastName, Password, "ImageTool", "static.sprocket@gmail.com"))
|
||||
{
|
||||
// Login failed
|
||||
Console.WriteLine("Error logging in: " + _Client.Network.LoginError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Login was successful
|
||||
Console.WriteLine("Login was successful.");
|
||||
Console.WriteLine("AgentID: " + _Client.Network.AgentID);
|
||||
Console.WriteLine("SessionID: " + _Client.Network.SessionID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void Disconnect()
|
||||
{
|
||||
// Logout of Second Life
|
||||
Console.WriteLine("Request logout");
|
||||
_Client.Network.Logout();
|
||||
}
|
||||
|
||||
protected void doStuff()
|
||||
{
|
||||
if (_Put)
|
||||
{
|
||||
|
||||
|
||||
Console.WriteLine("Reading: " + _FileName);
|
||||
|
||||
byte[] j2cdata;
|
||||
@@ -135,7 +189,7 @@ namespace IA_ImageTool
|
||||
|
||||
|
||||
Console.WriteLine("Connecting to your Texture folder...");
|
||||
InventoryFolder iFolder = AgentInventory.getFolder("Textures");
|
||||
InventoryFolder iFolder = _Client.Inventory.getFolder("Textures");
|
||||
|
||||
Console.WriteLine("Uploading Texture...");
|
||||
InventoryImage image = iFolder.NewImage(_FileName, "ImageTool Upload", j2cdata);
|
||||
@@ -162,7 +216,7 @@ namespace IA_ImageTool
|
||||
|
||||
try
|
||||
{
|
||||
j2cdata = client.Images.RequestImage(ImageID);
|
||||
j2cdata = _Client.Images.RequestImage(ImageID);
|
||||
|
||||
int end = Environment.TickCount;
|
||||
Console.WriteLine("Elapsed download time, in TickCounts: " + (end - start));
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
@@ -23,7 +25,7 @@ namespace IA_InventoryManager
|
||||
/// * MOVE
|
||||
/// * GIVE
|
||||
/// </summary>
|
||||
class iManager : SimpleInventory
|
||||
class iManager
|
||||
{
|
||||
private char[] cmdSeperators = { ' ' };
|
||||
private string curDirectory = "/";
|
||||
@@ -31,9 +33,12 @@ namespace IA_InventoryManager
|
||||
private string TYPE_DIR = "<DIR> ";
|
||||
private string TYPE_ITEM = "<ITEM> ";
|
||||
|
||||
private SecondLife _Client;
|
||||
private AppearanceManager aManager;
|
||||
|
||||
static new void Main(string[] args)
|
||||
private ManualResetEvent ConnectedSignal = new ManualResetEvent(false);
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length < 3)
|
||||
{
|
||||
@@ -42,18 +47,35 @@ namespace IA_InventoryManager
|
||||
}
|
||||
|
||||
iManager it = new iManager();
|
||||
it.Connect(args[0], args[1], args[2]);
|
||||
it.doStuff();
|
||||
it.Disconnect();
|
||||
if (it.Connect(args[0], args[1], args[2]))
|
||||
{
|
||||
if (it.ConnectedSignal.WaitOne(TimeSpan.FromMinutes(1), false))
|
||||
{
|
||||
it.doStuff();
|
||||
it.Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
public iManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
_Client = new SecondLife();
|
||||
_Client.Network.OnConnected += new NetworkManager.ConnectedCallback(Network_OnConnected);
|
||||
_Client.Self.OnTeleport += new TeleportCallback(Self_OnTeleport);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Error initializing the client
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(e.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private new void doStuff()
|
||||
private void doStuff()
|
||||
{
|
||||
client.Self.OnTeleport += new TeleportCallback(Self_OnTeleport);
|
||||
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
|
||||
Console.WriteLine("==================================================================");
|
||||
@@ -164,6 +186,17 @@ namespace IA_InventoryManager
|
||||
getlook();
|
||||
break;
|
||||
|
||||
case "saveav":
|
||||
saveavatar(curCmdLine);
|
||||
break;
|
||||
|
||||
case "savew":
|
||||
savewearables(curCmdLine);
|
||||
break;
|
||||
|
||||
case "loadw":
|
||||
loadwearables(curCmdLine);
|
||||
break;
|
||||
|
||||
default:
|
||||
Console.WriteLine("Unknown command '" + curCmdLine[0] + "'.");
|
||||
@@ -192,10 +225,144 @@ namespace IA_InventoryManager
|
||||
Console.WriteLine("REGIONINFO - Display Grid Region Info.");
|
||||
Console.WriteLine("TELEPORT - Teleport to a new sim.");
|
||||
Console.WriteLine("NOTECARD - Create a new notecard.");
|
||||
Console.WriteLine("XML - Display an item as xml");
|
||||
Console.WriteLine("XML - Display an item as xml.");
|
||||
Console.WriteLine("GETLOOK - Send an AgentSetAppearance based on your current weables.");
|
||||
Console.WriteLine("SAVEAV - Serialize your current wearables and the info from them.");
|
||||
Console.WriteLine("SAVEW - Serialize your current wearables.");
|
||||
Console.WriteLine("LOADW - Load a previously serialized wearables.");
|
||||
Console.WriteLine("QUIT - Exit the Inventory Manager.");
|
||||
}
|
||||
|
||||
private void savewearables(string[] cmdLine)
|
||||
{
|
||||
if (aManager == null)
|
||||
{
|
||||
aManager = new AppearanceManager(_Client);
|
||||
}
|
||||
|
||||
// Get Wearable Data
|
||||
AgentWearablesUpdatePacket.WearableDataBlock[] wdbs = aManager.GetWearables();
|
||||
List<AgentWearablesUpdatePacket.WearableDataBlock> WearablesList = new List<AgentWearablesUpdatePacket.WearableDataBlock>();
|
||||
foreach (AgentWearablesUpdatePacket.WearableDataBlock wdb in wdbs)
|
||||
{
|
||||
WearablesList.Add(wdb);
|
||||
}
|
||||
|
||||
// Serialize to XML
|
||||
StringBuilder sb = new StringBuilder();
|
||||
XmlWriterSettings xmlws = new XmlWriterSettings();
|
||||
xmlws.Indent = true;
|
||||
XmlWriter xmlw = XmlWriter.Create(sb, xmlws);
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(List<AgentWearablesUpdatePacket.WearableDataBlock>));
|
||||
serializer.Serialize(xmlw, WearablesList);
|
||||
|
||||
// Output
|
||||
if (cmdLine.Length >= 2)
|
||||
{
|
||||
Console.WriteLine("Writing wearable data to : " + cmdLine[1]);
|
||||
|
||||
File.WriteAllText(cmdLine[1], sb.ToString());
|
||||
|
||||
Console.WriteLine("Done...");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void loadwearables(string[] cmdLine)
|
||||
{
|
||||
if (cmdLine.Length < 2)
|
||||
{
|
||||
Console.WriteLine("You must specify the file to load the wearables from.");
|
||||
Console.WriteLine("Usage: loadw [file.xml]");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("Reading Wearable data from: " + cmdLine[1]);
|
||||
|
||||
try
|
||||
{
|
||||
XmlReader xmlr = XmlReader.Create(File.OpenText(cmdLine[1]));
|
||||
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(List<AgentWearablesUpdatePacket.WearableDataBlock>));
|
||||
List<AgentWearablesUpdatePacket.WearableDataBlock> WearablesList = (List<AgentWearablesUpdatePacket.WearableDataBlock>)serializer.Deserialize(xmlr);
|
||||
|
||||
foreach (AgentWearablesUpdatePacket.WearableDataBlock wdb in WearablesList)
|
||||
{
|
||||
Console.WriteLine(wdb.AssetID);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("An error has occured...");
|
||||
Console.WriteLine(e.Message);
|
||||
Console.WriteLine(e.StackTrace);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void saveavatar(string[] cmdLine)
|
||||
{
|
||||
if (aManager == null)
|
||||
{
|
||||
aManager = new AppearanceManager(_Client);
|
||||
}
|
||||
|
||||
AgentWearablesUpdatePacket.WearableDataBlock[] wdbs = aManager.GetWearables();
|
||||
aManager.GetAvatarAppearanceInfoFromWearableAssets();
|
||||
|
||||
// Get the list of wearables
|
||||
|
||||
List<AgentWearablesUpdatePacket.WearableDataBlock> WearablesList = new List<AgentWearablesUpdatePacket.WearableDataBlock>();
|
||||
foreach (AgentWearablesUpdatePacket.WearableDataBlock wdb in wdbs)
|
||||
{
|
||||
WearablesList.Add(wdb);
|
||||
}
|
||||
|
||||
XmlWriterSettings xmlws = new XmlWriterSettings();
|
||||
xmlws.OmitXmlDeclaration = true;
|
||||
xmlws.Indent = true;
|
||||
xmlws.CloseOutput = false;
|
||||
|
||||
StringBuilder Save = new StringBuilder();
|
||||
Save.Append("<avatar_appearance>");
|
||||
|
||||
// Wearables
|
||||
StringBuilder sb = new StringBuilder();
|
||||
XmlWriter xmlw = XmlWriter.Create(sb, xmlws);
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(List<AgentWearablesUpdatePacket.WearableDataBlock>));
|
||||
serializer.Serialize(xmlw, WearablesList);
|
||||
|
||||
Save.AppendLine(sb.ToString());
|
||||
|
||||
// Parameters
|
||||
sb = new StringBuilder();
|
||||
xmlw = XmlWriter.Create(sb, xmlws);
|
||||
serializer = new XmlSerializer(typeof(SerializableDictionary<uint, float>));
|
||||
serializer.Serialize(xmlw, aManager.AgentAppearanceParams);
|
||||
|
||||
Save.AppendLine(sb.ToString());
|
||||
|
||||
// Parameters
|
||||
sb = new StringBuilder();
|
||||
xmlw = XmlWriter.Create(sb, xmlws);
|
||||
serializer = new XmlSerializer(typeof(TextureEntry));
|
||||
serializer.Serialize(xmlw, aManager.AgentTextureEntry);
|
||||
|
||||
Save.AppendLine(sb.ToString());
|
||||
|
||||
// Finish off save data
|
||||
Save.Append("</avatar_appearance>");
|
||||
|
||||
Console.WriteLine(Save.ToString());
|
||||
|
||||
//aManager.SendAgentSetAppearance
|
||||
|
||||
}
|
||||
|
||||
private void StandUpStraight()
|
||||
{
|
||||
AgentUpdatePacket p = new AgentUpdatePacket();
|
||||
@@ -206,17 +373,17 @@ namespace IA_InventoryManager
|
||||
p.AgentData.CameraUpAxis = new LLVector3(0, 0, 0);
|
||||
p.AgentData.HeadRotation = new LLQuaternion(0, 0, 0, 1); ;
|
||||
p.AgentData.BodyRotation = new LLQuaternion(0, 0, 0, 1); ;
|
||||
p.AgentData.AgentID = client.Network.AgentID;
|
||||
p.AgentData.SessionID = client.Network.SessionID;
|
||||
p.AgentData.AgentID = _Client.Network.AgentID;
|
||||
p.AgentData.SessionID = _Client.Network.SessionID;
|
||||
p.AgentData.ControlFlags = (uint)Avatar.AgentUpdateFlags.AGENT_CONTROL_STAND_UP;
|
||||
client.Network.SendPacket(p);
|
||||
_Client.Network.SendPacket(p);
|
||||
}
|
||||
|
||||
private void getlook()
|
||||
{
|
||||
if (aManager == null)
|
||||
{
|
||||
aManager = new AppearanceManager(client);
|
||||
aManager = new AppearanceManager(_Client);
|
||||
}
|
||||
|
||||
|
||||
@@ -242,17 +409,20 @@ namespace IA_InventoryManager
|
||||
{
|
||||
}
|
||||
|
||||
InventoryFolder iFolder = AgentInventory.getFolder(curDirectory);
|
||||
InventoryFolder iFolder = _Client.Inventory.getFolder(curDirectory);
|
||||
|
||||
InventoryBase itemOfInterest = null;
|
||||
|
||||
foreach (InventoryBase ib in iFolder.alContents)
|
||||
iFolder.BeginDownloadContents(false).RequestComplete.WaitOne(15000,false);
|
||||
foreach (InventoryBase ib in iFolder.GetContents())
|
||||
{
|
||||
if (ib is InventoryFolder)
|
||||
{
|
||||
InventoryFolder folder = (InventoryFolder)ib;
|
||||
if (folder.Name.Equals(cmdLine[1]) || folder.FolderID.Equals(uuid))
|
||||
{
|
||||
// Refresh the folder tree for this folder before outputing it.
|
||||
folder.BeginDownloadContents(true).RequestComplete.WaitOne(30000, false);
|
||||
itemOfInterest = folder;
|
||||
break;
|
||||
}
|
||||
@@ -309,7 +479,7 @@ namespace IA_InventoryManager
|
||||
sb.Append(cki.Key.ToString());
|
||||
} while (cki.Key != ConsoleKey.Escape);
|
||||
|
||||
InventoryFolder iFolder = AgentInventory.getFolder(curDirectory);
|
||||
InventoryFolder iFolder = _Client.Inventory.getFolder(curDirectory);
|
||||
iFolder.NewNotecard(cmdLine[1], NoteDesc, sb.ToString());
|
||||
|
||||
Console.WriteLine("Notecard '" + NoteName + " 'Created");
|
||||
@@ -324,22 +494,22 @@ namespace IA_InventoryManager
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmdLine[1].ToLower() == client.Network.CurrentSim.Region.Name.ToLower())
|
||||
if (cmdLine[1].ToLower() == _Client.Network.CurrentSim.Region.Name.ToLower())
|
||||
{
|
||||
Console.WriteLine("TODO: Add the ability to teleport somewhere in the local region. " +
|
||||
"Exiting for now, please specify a region other than the current one");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (client.Grid.Regions.Count == 0)
|
||||
if (_Client.Grid.Regions.Count == 0)
|
||||
{
|
||||
Console.WriteLine("Caching estate sims...");
|
||||
client.Grid.AddEstateSims();
|
||||
_Client.Grid.AddEstateSims();
|
||||
System.Threading.Thread.Sleep(3000);
|
||||
}
|
||||
|
||||
|
||||
client.Self.Teleport(cmdLine[1], new LLVector3( float.Parse(cmdLine[2]), float.Parse(cmdLine[3]), float.Parse(cmdLine[4]) ) );
|
||||
|
||||
_Client.Self.Teleport(cmdLine[1], new LLVector3(float.Parse(cmdLine[2]), float.Parse(cmdLine[3]), float.Parse(cmdLine[4])));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -360,7 +530,7 @@ namespace IA_InventoryManager
|
||||
}
|
||||
regionName = regionName.Trim();
|
||||
|
||||
GridRegion gr = client.Grid.GetGridRegion(regionName);
|
||||
GridRegion gr = _Client.Grid.GetGridRegion(regionName);
|
||||
Console.WriteLine(gr);
|
||||
}
|
||||
|
||||
@@ -382,15 +552,17 @@ namespace IA_InventoryManager
|
||||
// Arbitrary Asset
|
||||
Asset asset = new Asset(cmdLine[2], sbyte.Parse(cmdLine[1]), null);
|
||||
|
||||
AgentInventory.getAssetManager().GetInventoryAsset(asset);
|
||||
_Client.Assets.GetInventoryAsset(asset);
|
||||
|
||||
Console.WriteLine(asset.AssetDataToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Asset for an item in inventory
|
||||
InventoryFolder iFolder = AgentInventory.getFolder(curDirectory);
|
||||
foreach (InventoryBase ib in iFolder.alContents)
|
||||
InventoryFolder iFolder = _Client.Inventory.getFolder(curDirectory);
|
||||
|
||||
iFolder.BeginDownloadContents(false).RequestComplete.WaitOne(15000, false);
|
||||
foreach (InventoryBase ib in iFolder.GetContents())
|
||||
{
|
||||
if (ib is InventoryItem)
|
||||
{
|
||||
@@ -423,7 +595,7 @@ namespace IA_InventoryManager
|
||||
}
|
||||
targetDir += combineCmdArg(cmdLine);
|
||||
|
||||
InventoryFolder iFolder = AgentInventory.getFolder(targetDir);
|
||||
InventoryFolder iFolder = _Client.Inventory.getFolder(targetDir);
|
||||
if (iFolder == null)
|
||||
{
|
||||
Console.WriteLine("Could not find directory: " + targetDir);
|
||||
@@ -446,7 +618,7 @@ namespace IA_InventoryManager
|
||||
|
||||
string targetDir = combineCmdArg(cmdLine);
|
||||
|
||||
InventoryFolder iFolder = AgentInventory.getFolder(curDirectory);
|
||||
InventoryFolder iFolder = _Client.Inventory.getFolder(curDirectory);
|
||||
|
||||
InventoryFolder newFolder = iFolder.CreateFolder(targetDir);
|
||||
|
||||
@@ -492,7 +664,7 @@ namespace IA_InventoryManager
|
||||
Console.WriteLine("Changing directory to: " + targetDir );
|
||||
|
||||
|
||||
InventoryFolder iFolder = AgentInventory.getFolder(targetDir);
|
||||
InventoryFolder iFolder = _Client.Inventory.getFolder(targetDir);
|
||||
|
||||
if (iFolder == null)
|
||||
{
|
||||
@@ -521,8 +693,9 @@ namespace IA_InventoryManager
|
||||
Console.WriteLine("..");
|
||||
}
|
||||
|
||||
InventoryFolder iFolder = AgentInventory.getFolder(curDirectory);
|
||||
foreach (InventoryBase ib in iFolder.alContents)
|
||||
InventoryFolder iFolder = _Client.Inventory.getFolder(curDirectory);
|
||||
iFolder.BeginDownloadContents(false).RequestComplete.WaitOne(15000, false);
|
||||
foreach (InventoryBase ib in iFolder.GetContents())
|
||||
{
|
||||
if (ib is InventoryFolder)
|
||||
{
|
||||
@@ -550,5 +723,41 @@ namespace IA_InventoryManager
|
||||
}
|
||||
return rtn.Trim();
|
||||
}
|
||||
|
||||
void Network_OnConnected(object sender)
|
||||
{
|
||||
ConnectedSignal.Set();
|
||||
}
|
||||
|
||||
protected bool Connect(string FirstName, string LastName, string Password)
|
||||
{
|
||||
Console.WriteLine("Attempting to connect and login to SecondLife.");
|
||||
|
||||
// Setup Login to Second Life
|
||||
Dictionary<string, object> loginReply = new Dictionary<string, object>();
|
||||
|
||||
// Login
|
||||
if (!_Client.Network.Login(FirstName, LastName, Password, "createnotecard", "static.sprocket@gmail.com"))
|
||||
{
|
||||
// Login failed
|
||||
Console.WriteLine("Error logging in: " + _Client.Network.LoginError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Login was successful
|
||||
Console.WriteLine("Login was successful.");
|
||||
Console.WriteLine("AgentID: " + _Client.Network.AgentID);
|
||||
Console.WriteLine("SessionID: " + _Client.Network.SessionID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void Disconnect()
|
||||
{
|
||||
// Logout of Second Life
|
||||
Console.WriteLine("Request logout");
|
||||
_Client.Network.Logout();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
using IA_SimpleInventory;
|
||||
using IA_ImageTool;
|
||||
@@ -11,11 +12,14 @@ using libsecondlife.AssetSystem;
|
||||
|
||||
namespace IA_MultiImageUpload
|
||||
{
|
||||
class MultiImageUpload : SimpleInventory
|
||||
class MultiImageUpload
|
||||
{
|
||||
private SecondLife _Client;
|
||||
private ManualResetEvent ConnectedSignal = new ManualResetEvent(false);
|
||||
|
||||
protected string ImageDirectory;
|
||||
|
||||
static new void Main(string[] args)
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length < 4)
|
||||
{
|
||||
@@ -32,14 +36,31 @@ namespace IA_MultiImageUpload
|
||||
}
|
||||
|
||||
MultiImageUpload app = new MultiImageUpload( fullpath );
|
||||
app.Connect(args[0], args[1], args[2]);
|
||||
app.doStuff();
|
||||
app.Disconnect();
|
||||
if (app.Connect(args[0], args[1], args[2]))
|
||||
{
|
||||
if (app.ConnectedSignal.WaitOne(TimeSpan.FromMinutes(1), false))
|
||||
{
|
||||
app.doStuff();
|
||||
app.Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MultiImageUpload(string dir)
|
||||
{
|
||||
ImageDirectory = dir;
|
||||
try
|
||||
{
|
||||
_Client = new SecondLife();
|
||||
_Client.Network.OnConnected += new NetworkManager.ConnectedCallback(Network_OnConnected);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Error initializing the client
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(e.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void Usage()
|
||||
@@ -47,9 +68,9 @@ namespace IA_MultiImageUpload
|
||||
System.Console.WriteLine("MultiImageUpload [FirstName] [LastName] [Password] [Directory]");
|
||||
}
|
||||
|
||||
protected new void doStuff()
|
||||
protected void doStuff()
|
||||
{
|
||||
InventoryFolder iFolder = AgentInventory.getFolder("Textures");
|
||||
InventoryFolder iFolder = _Client.Inventory.getFolder("Textures");
|
||||
iFolder = iFolder.CreateFolder(Helpers.GetUnixTime().ToString());
|
||||
|
||||
Console.WriteLine("Uploading images:");
|
||||
@@ -79,5 +100,39 @@ namespace IA_MultiImageUpload
|
||||
}
|
||||
}
|
||||
}
|
||||
void Network_OnConnected(object sender)
|
||||
{
|
||||
ConnectedSignal.Set();
|
||||
}
|
||||
|
||||
protected bool Connect(string FirstName, string LastName, string Password)
|
||||
{
|
||||
Console.WriteLine("Attempting to connect and login to SecondLife.");
|
||||
|
||||
// Setup Login to Second Life
|
||||
Dictionary<string, object> loginReply = new Dictionary<string, object>();
|
||||
|
||||
// Login
|
||||
if (!_Client.Network.Login(FirstName, LastName, Password, "MultiImageUpload", "static.sprocket@gmail.com"))
|
||||
{
|
||||
// Login failed
|
||||
Console.WriteLine("Error logging in: " + _Client.Network.LoginError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Login was successful
|
||||
Console.WriteLine("Login was successful.");
|
||||
Console.WriteLine("AgentID: " + _Client.Network.AgentID);
|
||||
Console.WriteLine("SessionID: " + _Client.Network.SessionID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void Disconnect()
|
||||
{
|
||||
// Logout of Second Life
|
||||
Console.WriteLine("Request logout");
|
||||
_Client.Network.Logout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
using IA_SimpleInventory;
|
||||
using libsecondlife;
|
||||
@@ -35,12 +36,16 @@ using libsecondlife.InventorySystem;
|
||||
|
||||
namespace IA_NotecardTool
|
||||
{
|
||||
class NotecardTool : SimpleInventory
|
||||
class NotecardTool
|
||||
{
|
||||
private string FileName;
|
||||
private string NotecardName;
|
||||
|
||||
static new void Main(string[] args)
|
||||
private SecondLife _Client;
|
||||
private ManualResetEvent ConnectedSignal = new ManualResetEvent(false);
|
||||
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length < 6)
|
||||
{
|
||||
@@ -59,21 +64,22 @@ namespace IA_NotecardTool
|
||||
tool.FileName = args[5];
|
||||
|
||||
tool.Connect(args[0], args[1], args[2]);
|
||||
tool.doStuff();
|
||||
tool.Disconnect();
|
||||
|
||||
System.Threading.Thread.Sleep(500);
|
||||
|
||||
if (tool.ConnectedSignal.WaitOne(TimeSpan.FromMinutes(1), false))
|
||||
{
|
||||
tool.doStuff();
|
||||
tool.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private new void doStuff()
|
||||
private void doStuff()
|
||||
{
|
||||
Console.WriteLine("Reading " + FileName);
|
||||
StreamReader sr = File.OpenText(FileName);
|
||||
string Body = sr.ReadToEnd();
|
||||
|
||||
Console.WriteLine("Getting Notecard Folder");
|
||||
InventoryFolder iFolder = base.AgentInventory.getFolder("Notecards");
|
||||
InventoryFolder iFolder = _Client.Inventory.getFolder("Notecards");
|
||||
|
||||
|
||||
Console.WriteLine("Creating Notecard");
|
||||
@@ -81,5 +87,55 @@ namespace IA_NotecardTool
|
||||
|
||||
Console.WriteLine("Done.");
|
||||
}
|
||||
|
||||
public NotecardTool()
|
||||
{
|
||||
try
|
||||
{
|
||||
_Client = new SecondLife();
|
||||
_Client.Network.OnConnected += new NetworkManager.ConnectedCallback(Network_OnConnected);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Error initializing the client
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
void Network_OnConnected(object sender)
|
||||
{
|
||||
ConnectedSignal.Set();
|
||||
}
|
||||
|
||||
protected bool Connect(string FirstName, string LastName, string Password)
|
||||
{
|
||||
Console.WriteLine("Attempting to connect and login to SecondLife.");
|
||||
|
||||
// Setup Login to Second Life
|
||||
Dictionary<string, object> loginReply = new Dictionary<string, object>();
|
||||
|
||||
// Login
|
||||
if (!_Client.Network.Login(FirstName, LastName, Password, "createnotecard", "static.sprocket@gmail.com"))
|
||||
{
|
||||
// Login failed
|
||||
Console.WriteLine("Error logging in: " + _Client.Network.LoginError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Login was successful
|
||||
Console.WriteLine("Login was successful.");
|
||||
Console.WriteLine("AgentID: " + _Client.Network.AgentID);
|
||||
Console.WriteLine("SessionID: " + _Client.Network.SessionID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void Disconnect()
|
||||
{
|
||||
// Logout of Second Life
|
||||
Console.WriteLine("Request logout");
|
||||
_Client.Network.Logout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
using libsecondlife;
|
||||
using libsecondlife.InventorySystem;
|
||||
@@ -38,10 +39,8 @@ namespace IA_SimpleInventory
|
||||
/// </summary>
|
||||
public class SimpleInventory
|
||||
{
|
||||
protected SecondLife client;
|
||||
protected InventoryManager AgentInventory;
|
||||
|
||||
protected bool DownloadInventoryOnConnect = true;
|
||||
private SecondLife client;
|
||||
private ManualResetEvent ConnectedSignal = new ManualResetEvent(false);
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
@@ -53,9 +52,14 @@ namespace IA_SimpleInventory
|
||||
}
|
||||
|
||||
SimpleInventory simple = new SimpleInventory();
|
||||
simple.Connect(args[0], args[1], args[2]);
|
||||
simple.doStuff();
|
||||
simple.Disconnect();
|
||||
if (simple.Connect(args[0], args[1], args[2]))
|
||||
{
|
||||
if (simple.ConnectedSignal.WaitOne(TimeSpan.FromMinutes(1), false))
|
||||
{
|
||||
simple.doStuff();
|
||||
simple.Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected SimpleInventory()
|
||||
@@ -63,6 +67,7 @@ namespace IA_SimpleInventory
|
||||
try
|
||||
{
|
||||
client = new SecondLife();
|
||||
client.Network.OnConnected += new NetworkManager.ConnectedCallback(Network_OnConnected);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -72,6 +77,11 @@ namespace IA_SimpleInventory
|
||||
}
|
||||
}
|
||||
|
||||
void Network_OnConnected(object sender)
|
||||
{
|
||||
ConnectedSignal.Set();
|
||||
}
|
||||
|
||||
protected bool Connect(string FirstName, string LastName, string Password)
|
||||
{
|
||||
Console.WriteLine("Attempting to connect and login to SecondLife.");
|
||||
@@ -80,7 +90,7 @@ namespace IA_SimpleInventory
|
||||
Dictionary<string, object> loginReply = new Dictionary<string, object>();
|
||||
|
||||
// Login
|
||||
if (!client.Network.Login(FirstName, LastName, Password, "createnotecard", "static.sprocket@gmail.com"))
|
||||
if (!client.Network.Login(FirstName, LastName, Password, "IA_SimpleInventory", "static.sprocket@gmail.com"))
|
||||
{
|
||||
// Login failed
|
||||
Console.WriteLine("Error logging in: " + client.Network.LoginError);
|
||||
@@ -92,22 +102,6 @@ namespace IA_SimpleInventory
|
||||
Console.WriteLine("AgentID: " + client.Network.AgentID);
|
||||
Console.WriteLine("SessionID: " + client.Network.SessionID);
|
||||
|
||||
// Get Root Inventory Folder UUID
|
||||
Console.WriteLine("Pulling root folder UUID from login data.");
|
||||
ArrayList alInventoryRoot = (ArrayList)client.Network.LoginValues["inventory-root"];
|
||||
Hashtable htInventoryRoot = (Hashtable)alInventoryRoot[0];
|
||||
LLUUID agentRootFolderID = new LLUUID((string)htInventoryRoot["folder_id"]);
|
||||
|
||||
// Initialize Inventory Manager object
|
||||
Console.WriteLine("Initializing Inventory Manager.");
|
||||
AgentInventory = new InventoryManager(client, agentRootFolderID);
|
||||
|
||||
if (DownloadInventoryOnConnect)
|
||||
{
|
||||
// and request an inventory download
|
||||
Console.WriteLine("Downloading Inventory.");
|
||||
AgentInventory.DownloadInventory();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -120,17 +114,19 @@ namespace IA_SimpleInventory
|
||||
|
||||
protected void doStuff()
|
||||
{
|
||||
// and request an inventory download
|
||||
Console.WriteLine("Downloading Inventory.");
|
||||
client.Inventory.DownloadInventory();
|
||||
|
||||
|
||||
Console.WriteLine("Dumping a copy of " + client.Self.FirstName + "'s inventory to the console.");
|
||||
Console.WriteLine();
|
||||
|
||||
if (AgentInventory != null)
|
||||
{
|
||||
InventoryFolder root = AgentInventory.getRootFolder();
|
||||
InventoryFolder root = client.Inventory.getRootFolder();
|
||||
|
||||
if (root != null)
|
||||
{
|
||||
Console.WriteLine(root.toXML(false));
|
||||
}
|
||||
if (root != null)
|
||||
{
|
||||
Console.WriteLine(root.toXML(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
using IA_SimpleInventory;
|
||||
|
||||
using libsecondlife;
|
||||
@@ -10,76 +11,79 @@ using libsecondlife.AssetSystem;
|
||||
|
||||
namespace IA_TestAsyncImage
|
||||
{
|
||||
class TestAsync : SimpleInventory
|
||||
class TestAsync
|
||||
{
|
||||
ImageManager imgManager;
|
||||
private SecondLife _Client;
|
||||
private ManualResetEvent ConnectedSignal = new ManualResetEvent(false);
|
||||
|
||||
Queue<LLUUID> TextureQueue = new Queue<LLUUID>();
|
||||
|
||||
string OutputDirectory = "IA_TestAsyncImages";
|
||||
private Queue<LLUUID> TextureQueue = new Queue<LLUUID>();
|
||||
|
||||
private string OutputDirectory = "IA_TestAsyncImages";
|
||||
|
||||
[STAThread]
|
||||
static new void Main(string[] args)
|
||||
static void Main(string[] args)
|
||||
{
|
||||
TestAsync app = new TestAsync();
|
||||
app.DownloadInventoryOnConnect = false;
|
||||
|
||||
app.client.Objects.OnNewPrim += new ObjectManager.NewPrimCallback(app.Objects_OnNewPrim);
|
||||
app.client.Objects.OnNewAvatar += new ObjectManager.NewAvatarCallback(app.Objects_OnNewAvatar);
|
||||
app._Client.Objects.OnNewPrim += new ObjectManager.NewPrimCallback(app.Objects_OnNewPrim);
|
||||
app._Client.Objects.OnNewAvatar += new ObjectManager.NewAvatarCallback(app.Objects_OnNewAvatar);
|
||||
|
||||
|
||||
app.Connect(args[0], args[1], args[2]);
|
||||
app.doStuff();
|
||||
app.Disconnect();
|
||||
|
||||
System.Threading.Thread.Sleep(500);
|
||||
|
||||
if (app.ConnectedSignal.WaitOne(TimeSpan.FromMinutes(1), false))
|
||||
{
|
||||
app.doStuff();
|
||||
app.Disconnect();
|
||||
}
|
||||
Console.WriteLine("Done...");
|
||||
}
|
||||
|
||||
public TestAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_Client = new SecondLife();
|
||||
_Client.Images = new ImageManager(_Client, ImageManager.CacheTypes.Disk, OutputDirectory);
|
||||
_Client.Network.OnConnected += new NetworkManager.ConnectedCallback(Network_OnConnected);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Error initializing the client
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void Objects_OnNewAvatar(Simulator simulator, Avatar avatar, ulong regionHandle, ushort timeDilation)
|
||||
{
|
||||
if (imgManager == null)
|
||||
if (avatar.FirstLifeImage != null)
|
||||
{
|
||||
Console.WriteLine("ImageManager not ready yet, queueing Avatar textures.");
|
||||
TextureQueue.Enqueue(avatar.FirstLifeImage);
|
||||
TextureQueue.Enqueue(avatar.ProfileImage);
|
||||
|
||||
foreach (TextureEntryFace tef in avatar.Textures.FaceTextures.Values)
|
||||
if (_Client.Images.isCachedImage(avatar.FirstLifeImage) == false)
|
||||
{
|
||||
TextureQueue.Enqueue(tef.TextureID);
|
||||
_Client.Images.RequestImageAsync(avatar.FirstLifeImage);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (avatar.ProfileImage != null)
|
||||
{
|
||||
if (avatar.FirstLifeImage != null)
|
||||
if (_Client.Images.isCachedImage(avatar.FirstLifeImage) == false)
|
||||
{
|
||||
if (imgManager.isCachedImage(avatar.FirstLifeImage) == false)
|
||||
{
|
||||
imgManager.RequestImageAsync(avatar.FirstLifeImage);
|
||||
}
|
||||
_Client.Images.RequestImageAsync(avatar.ProfileImage);
|
||||
}
|
||||
}
|
||||
|
||||
if (avatar.ProfileImage != null)
|
||||
if (avatar.Textures != null)
|
||||
{
|
||||
foreach (TextureEntryFace tef in avatar.Textures.FaceTextures.Values)
|
||||
{
|
||||
if (imgManager.isCachedImage(avatar.FirstLifeImage) == false)
|
||||
if (_Client.Images.isCachedImage(tef.TextureID) == false)
|
||||
{
|
||||
imgManager.RequestImageAsync(avatar.ProfileImage);
|
||||
_Client.Images.RequestImageAsync(tef.TextureID);
|
||||
}
|
||||
}
|
||||
|
||||
if (avatar.Textures != null)
|
||||
{
|
||||
foreach (TextureEntryFace tef in avatar.Textures.FaceTextures.Values)
|
||||
else
|
||||
{
|
||||
if (imgManager.isCachedImage(tef.TextureID) == false)
|
||||
{
|
||||
imgManager.RequestImageAsync(tef.TextureID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Already cached: " + tef.TextureID);
|
||||
}
|
||||
Console.WriteLine("Already cached: " + tef.TextureID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,42 +91,29 @@ namespace IA_TestAsyncImage
|
||||
|
||||
private void Objects_OnNewPrim(Simulator simulator, PrimObject prim, ulong regionHandle, ushort timeDilation)
|
||||
{
|
||||
if (imgManager == null)
|
||||
if ((prim.Textures.DefaultTexture != null) && (prim.Textures.DefaultTexture.TextureID != null))
|
||||
{
|
||||
Console.WriteLine("ImageManager not ready yet, queueing Prim textures.");
|
||||
TextureQueue.Enqueue(prim.Textures.DefaultTexture.TextureID);
|
||||
|
||||
foreach (TextureEntryFace tef in prim.Textures.FaceTextures.Values)
|
||||
if (_Client.Images.isCachedImage(prim.Textures.DefaultTexture.TextureID) == false)
|
||||
{
|
||||
TextureQueue.Enqueue(tef.TextureID);
|
||||
_Client.Images.RequestImageAsync(prim.Textures.DefaultTexture.TextureID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Already cached: " + prim.Textures.DefaultTexture.TextureID);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (prim.Textures.FaceTextures != null)
|
||||
{
|
||||
if ((prim.Textures.DefaultTexture != null) && (prim.Textures.DefaultTexture.TextureID != null))
|
||||
foreach (TextureEntryFace tef in prim.Textures.FaceTextures.Values)
|
||||
{
|
||||
if (imgManager.isCachedImage(prim.Textures.DefaultTexture.TextureID) == false)
|
||||
if (_Client.Images.isCachedImage(tef.TextureID) == false)
|
||||
{
|
||||
imgManager.RequestImageAsync(prim.Textures.DefaultTexture.TextureID);
|
||||
_Client.Images.RequestImageAsync(tef.TextureID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Already cached: " + prim.Textures.DefaultTexture.TextureID);
|
||||
}
|
||||
}
|
||||
|
||||
if (prim.Textures.FaceTextures != null)
|
||||
{
|
||||
foreach (TextureEntryFace tef in prim.Textures.FaceTextures.Values)
|
||||
{
|
||||
if (imgManager.isCachedImage(tef.TextureID) == false)
|
||||
{
|
||||
imgManager.RequestImageAsync(tef.TextureID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Already cached: " + tef.TextureID);
|
||||
}
|
||||
Console.WriteLine("Already cached: " + tef.TextureID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,14 +144,14 @@ namespace IA_TestAsyncImage
|
||||
}
|
||||
}
|
||||
|
||||
protected new void doStuff()
|
||||
protected void doStuff()
|
||||
{
|
||||
imgManager = new ImageManager(client, ImageManager.CacheTypes.Disk, OutputDirectory);
|
||||
imgManager.OnImageRetrieved += new ImageRetrievedCallback(NewImageRetrievedCallBack);
|
||||
|
||||
_Client.Images.OnImageRetrieved += new ImageRetrievedCallback(NewImageRetrievedCallBack);
|
||||
|
||||
while (TextureQueue.Count > 0)
|
||||
{
|
||||
imgManager.RequestImageAsync(TextureQueue.Dequeue());
|
||||
_Client.Images.RequestImageAsync(TextureQueue.Dequeue());
|
||||
}
|
||||
|
||||
Console.WriteLine("Press any key to stop.");
|
||||
@@ -183,5 +174,40 @@ namespace IA_TestAsyncImage
|
||||
File.WriteAllBytes(filename, JasperWrapper.jasper_decode_j2c_to_tiff(j2cdata));
|
||||
}
|
||||
}
|
||||
|
||||
void Network_OnConnected(object sender)
|
||||
{
|
||||
ConnectedSignal.Set();
|
||||
}
|
||||
|
||||
protected bool Connect(string FirstName, string LastName, string Password)
|
||||
{
|
||||
Console.WriteLine("Attempting to connect and login to SecondLife.");
|
||||
|
||||
// Setup Login to Second Life
|
||||
Dictionary<string, object> loginReply = new Dictionary<string, object>();
|
||||
|
||||
// Login
|
||||
if (!_Client.Network.Login(FirstName, LastName, Password, "createnotecard", "static.sprocket@gmail.com"))
|
||||
{
|
||||
// Login failed
|
||||
Console.WriteLine("Error logging in: " + _Client.Network.LoginError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Login was successful
|
||||
Console.WriteLine("Login was successful.");
|
||||
Console.WriteLine("AgentID: " + _Client.Network.AgentID);
|
||||
Console.WriteLine("SessionID: " + _Client.Network.SessionID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void Disconnect()
|
||||
{
|
||||
// Logout of Second Life
|
||||
Console.WriteLine("Request logout");
|
||||
_Client.Network.Logout();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ namespace Teleport
|
||||
}
|
||||
}
|
||||
|
||||
Client.Self.OnTeleport += new TeleportCallback(Avatar_OnTeleportMessage);
|
||||
Client.Self.OnTeleport += new TeleportCallback(Self_OnTeleport);
|
||||
|
||||
DoneTeleporting = false;
|
||||
Client.Self.Teleport(RegionHandle, coords);
|
||||
@@ -147,7 +147,7 @@ namespace Teleport
|
||||
}
|
||||
}
|
||||
|
||||
private void Avatar_OnTeleportMessage(Simulator currentSim, string message, TeleportStatus status)
|
||||
void Self_OnTeleport(Simulator currentSim, string message, TeleportStatus status)
|
||||
{
|
||||
Console.WriteLine(message);
|
||||
|
||||
|
||||
@@ -107,6 +107,8 @@
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="AvatarManager.cs" />
|
||||
<Compile Include="InventorySystem\DownloadRequest_Folder.cs" />
|
||||
<Compile Include="InventorySystem\InventoryWearable.cs" />
|
||||
<Compile Include="MainAvatarStatus.cs" />
|
||||
<Compile Include="MainAvatar.cs" />
|
||||
<Compile Include="EstateTools.cs">
|
||||
|
||||
Reference in New Issue
Block a user