diff --git a/libsecondlife-cs/AvatarManager.cs b/libsecondlife-cs/AvatarManager.cs
index 47b31b41..2946872d 100644
--- a/libsecondlife-cs/AvatarManager.cs
+++ b/libsecondlife-cs/AvatarManager.cs
@@ -32,7 +32,7 @@ using libsecondlife.Packets;
namespace libsecondlife
{
///
- /// Class to manage multiple Avatars
+ /// Class to manage multiple AvatarList
///
public class AvatarManager
{
@@ -71,8 +71,9 @@ namespace libsecondlife
/// Triggered whenever a friend comes online or goes offline
public event FriendNotificationCallback OnFriendNotification;
+ public Dictionary AvatarList;
+
private SecondLife Client;
- private Dictionary Avatars;
private AgentNamesCallback OnAgentNames;
private Dictionary AvatarPropertiesCallbacks;
private Dictionary AvatarStatisticsCallbacks;
@@ -85,7 +86,7 @@ namespace libsecondlife
public AvatarManager(SecondLife client)
{
Client = client;
- Avatars = new Dictionary();
+ AvatarList = new Dictionary();
//Callback Dictionaries
AvatarPropertiesCallbacks = new Dictionary();
AvatarStatisticsCallbacks = new Dictionary();
@@ -102,25 +103,25 @@ namespace libsecondlife
///
- /// Add an Avatar into the Avatars Dictionary
+ /// Add an Avatar into the AvatarList Dictionary
///
/// Filled-out Avatar class to insert
public void AddAvatar(Avatar avatar)
{
- lock (Avatars)
+ lock (AvatarList)
{
- Avatars[avatar.ID] = avatar;
+ AvatarList[avatar.ID] = avatar;
}
}
///
- /// Used to search all known Avatars for a particular Avatar Key
+ /// Used to search all known AvatarList for a particular Avatar Key
///
///
///
public bool Contains(LLUUID id)
{
- return Avatars.ContainsKey(id);
+ return AvatarList.ContainsKey(id);
}
///
@@ -170,11 +171,11 @@ namespace libsecondlife
{
string name = "";
- lock (Avatars)
+ lock (AvatarList)
{
- if (Avatars.ContainsKey(id))
+ if (AvatarList.ContainsKey(id))
{
- name = Avatars[id].Name;
+ name = AvatarList[id].Name;
}
}
@@ -212,9 +213,9 @@ namespace libsecondlife
// Fire callbacks for the ones we already have cached
foreach (LLUUID id in ids)
{
- if (Avatars.ContainsKey(id))
+ if (AvatarList.ContainsKey(id))
{
- havenames[id] = Avatars[id].Name;
+ havenames[id] = AvatarList[id].Name;
}
else
{
@@ -244,7 +245,7 @@ namespace libsecondlife
}
///
- /// Process an incoming UUIDNameReply Packet and insert Full Names into the Avatars Dictionary
+ /// Process an incoming UUIDNameReply Packet and insert Full Names into the AvatarList Dictionary
///
/// Incoming Packet to process
/// Unused
@@ -253,20 +254,20 @@ namespace libsecondlife
Dictionary names = new Dictionary();
UUIDNameReplyPacket reply = (UUIDNameReplyPacket)packet;
- lock (Avatars)
+ lock (AvatarList)
{
foreach (UUIDNameReplyPacket.UUIDNameBlockBlock block in reply.UUIDNameBlock)
{
- if (!Avatars.ContainsKey(block.ID))
+ if (!AvatarList.ContainsKey(block.ID))
{
- Avatars[block.ID] = new Avatar();
- Avatars[block.ID].ID = block.ID;
+ AvatarList[block.ID] = new Avatar();
+ AvatarList[block.ID].ID = block.ID;
}
- Avatars[block.ID].Name = Helpers.FieldToString(block.FirstName) +
+ AvatarList[block.ID].Name = Helpers.FieldToString(block.FirstName) +
" " + Helpers.FieldToString(block.LastName);
- names[block.ID] = Avatars[block.ID].Name;
+ names[block.ID] = AvatarList[block.ID].Name;
}
}
@@ -289,18 +290,18 @@ namespace libsecondlife
// If the agent is online...
foreach (OnlineNotificationPacket.AgentBlockBlock block in ((OnlineNotificationPacket)packet).AgentBlock)
{
- lock (Avatars)
+ lock (AvatarList)
{
- if (!Avatars.ContainsKey(block.AgentID))
+ if (!AvatarList.ContainsKey(block.AgentID))
{
// Mark this avatar for a name request
requestids.Add(block.AgentID);
- Avatars[block.AgentID] = new Avatar();
- Avatars[block.AgentID].ID = block.AgentID;
+ AvatarList[block.AgentID] = new Avatar();
+ AvatarList[block.AgentID].ID = block.AgentID;
}
- Avatars[block.AgentID].Online = true;
+ AvatarList[block.AgentID].Online = true;
}
if (OnFriendNotification != null)
@@ -314,18 +315,18 @@ namespace libsecondlife
// If the agent is Offline...
foreach (OfflineNotificationPacket.AgentBlockBlock block in ((OfflineNotificationPacket)packet).AgentBlock)
{
- lock (Avatars)
+ lock (AvatarList)
{
- if (!Avatars.ContainsKey(block.AgentID))
+ if (!AvatarList.ContainsKey(block.AgentID))
{
// Mark this avatar for a name request
requestids.Add(block.AgentID);
- Avatars[block.AgentID] = new Avatar();
- Avatars[block.AgentID].ID = block.AgentID;
+ AvatarList[block.AgentID] = new Avatar();
+ AvatarList[block.AgentID].ID = block.AgentID;
}
- Avatars[block.AgentID].Online = false;
+ AvatarList[block.AgentID].Online = false;
}
if (OnFriendNotification != null)
@@ -348,17 +349,17 @@ namespace libsecondlife
private void AvatarStatisticsHandler(Packet packet, Simulator simulator)
{
AvatarStatisticsReplyPacket asr = (AvatarStatisticsReplyPacket)packet;
- lock(Avatars)
+ lock(AvatarList)
{
Avatar av;
- if (!Avatars.ContainsKey(asr.AvatarData.AvatarID))
+ if (!AvatarList.ContainsKey(asr.AvatarData.AvatarID))
{
av = new Avatar();
av.ID = asr.AvatarData.AvatarID;
}
else
{
- av = Avatars[asr.AvatarData.AvatarID];
+ av = AvatarList[asr.AvatarData.AvatarID];
}
foreach(AvatarStatisticsReplyPacket.StatisticsDataBlock b in asr.StatisticsData)
@@ -392,9 +393,9 @@ namespace libsecondlife
{
Avatar av;
AvatarPropertiesReplyPacket reply = (AvatarPropertiesReplyPacket)packet;
- lock(Avatars)
+ lock(AvatarList)
{
- if (!Avatars.ContainsKey(reply.AgentData.AvatarID))
+ if (!AvatarList.ContainsKey(reply.AgentData.AvatarID))
{
//not in our "cache", create a new object
av = new Avatar();
@@ -402,7 +403,7 @@ namespace libsecondlife
else
{
//Cache hit, modify existing avatar
- av = Avatars[reply.AgentData.AvatarID];
+ av = AvatarList[reply.AgentData.AvatarID];
}
av.ID = reply.AgentData.AvatarID;
av.ProfileImage = reply.PropertiesData.ImageID;
@@ -419,7 +420,7 @@ namespace libsecondlife
av.Transacted = reply.PropertiesData.Transacted;
av.ProfileURL = Helpers.FieldToString(reply.PropertiesData.ProfileURL);
//reassign in the cache
- Avatars[av.ID] = av;
+ AvatarList[av.ID] = av;
//Heaven forbid that we actually get a packet we didn't ask for.
if (AvatarPropertiesCallbacks.ContainsKey(av.ID) && AvatarPropertiesCallbacks[av.ID] != null)
AvatarPropertiesCallbacks[av.ID](av);
@@ -458,9 +459,9 @@ namespace libsecondlife
{
AvatarInterestsReplyPacket airp = (AvatarInterestsReplyPacket)packet;
Avatar av;
- lock (Avatars)
+ lock (AvatarList)
{
- if (!Avatars.ContainsKey(airp.AgentData.AvatarID))
+ if (!AvatarList.ContainsKey(airp.AgentData.AvatarID))
{
//not in our "cache", create a new object
av = new Avatar();
@@ -469,7 +470,7 @@ namespace libsecondlife
else
{
//Cache hit, modify existing avatar
- av = Avatars[airp.AgentData.AvatarID];
+ av = AvatarList[airp.AgentData.AvatarID];
}
//The rest of the properties, thanks LL.
av.WantToMask = airp.PropertiesData.WantToMask;
diff --git a/libsecondlife-cs/MainAvatar.cs b/libsecondlife-cs/MainAvatar.cs
index e7e261cc..af2dd857 100644
--- a/libsecondlife-cs/MainAvatar.cs
+++ b/libsecondlife-cs/MainAvatar.cs
@@ -1122,5 +1122,4 @@ namespace libsecondlife
TeleportTimeout = true;
}
}
-
-}
+}
\ No newline at end of file
diff --git a/libsecondlife-cs/SecondLife.cs b/libsecondlife-cs/SecondLife.cs
index 5ef30591..07c201f5 100644
--- a/libsecondlife-cs/SecondLife.cs
+++ b/libsecondlife-cs/SecondLife.cs
@@ -52,7 +52,7 @@ namespace libsecondlife
public ParcelManager Parcels;
/// 'Client's Avatar' Subsystem
public MainAvatar Self;
- /// Other Avatars Subsystem
+ /// Other AvatarList Subsystem
public AvatarManager Avatars;
/// Grid (aka simulator group) Subsystem
public GridManager Grid;
diff --git a/libsecondlife-cs/examples/TestClient/ClientManager.cs b/libsecondlife-cs/examples/TestClient/ClientManager.cs
new file mode 100644
index 00000000..be49553f
--- /dev/null
+++ b/libsecondlife-cs/examples/TestClient/ClientManager.cs
@@ -0,0 +1,209 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Xml;
+using libsecondlife;
+using libsecondlife.Packets;
+using libsecondlife.AssetSystem;
+
+namespace libsecondlife.TestClient
+{
+ public class LoginDetails
+ {
+ public string FirstName;
+ public string LastName;
+ public string Password;
+ public string Master;
+ }
+
+ public class ClientManager
+ {
+ public Dictionary Clients = new Dictionary();
+ public Dictionary> SimPrims = new Dictionary>();
+ //public Dictionary Appearances = new Dictionary();
+
+ public Dictionary SharedValues = new Dictionary();
+ public bool Running = true;
+
+ ///
+ ///
+ ///
+ ///
+ public ClientManager(List accounts)
+ {
+ foreach (LoginDetails account in accounts)
+ Login(account);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public TestClient Login(LoginDetails account)
+ {
+ // Check if this client is already logged in
+ foreach (TestClient c in Clients.Values)
+ {
+ if (c.Self.FirstName == account.FirstName && c.Self.LastName == account.LastName)
+ {
+ Logout(c);
+ break;
+ }
+ }
+
+ TestClient client = new TestClient(this);
+
+ client.SimPrims = SimPrims;
+ client.Master = account.Master;
+
+ bool login = client.Network.Login(account.FirstName, account.LastName, account.Password,
+ "TestClient", "contact@libsecondlife.org");
+
+ if (login)
+ {
+ // Set our appearance
+ //AppearanceManager appearance = new AppearanceManager(client);
+ //appearance.SendAgentSetAppearance();
+ }
+
+ if (client.Network.Connected)
+ {
+ Clients[client.Network.AgentID] = client;
+
+ Console.WriteLine("Logged in " + client.ToString());
+
+ // Throttle the connection to not receive LayerData or asset packets
+ client.Throttle.Total = 0.0f;
+ client.Throttle.Task = 1536000.0f;
+ client.Throttle.Set();
+ }
+ else
+ {
+ Console.WriteLine("Failed to login " + account.FirstName + " " + account.LastName +
+ ": " + client.Network.LoginError);
+ }
+
+ return client;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public TestClient Login(string[] args)
+ {
+ LoginDetails account = new LoginDetails();
+ account.FirstName = args[0];
+ account.LastName = args[1];
+ account.Password = args[2];
+
+ return Login(account);
+ }
+
+ ///
+ ///
+ ///
+ public void Run()
+ {
+ Console.WriteLine("Type quit to exit. Type help for a command list.");
+
+ while (Running)
+ {
+ PrintPrompt();
+ string input = Console.ReadLine();
+ DoCommandAll(input, null, null);
+ }
+
+ foreach (SecondLife client in Clients.Values)
+ {
+ if (client.Network.Connected)
+ client.Network.Logout();
+ }
+ }
+
+ private void PrintPrompt()
+ {
+ //Console.Write(String.Format("{0} {1} - {2}> ", client.Self.FirstName, client.Self.LastName, client.Network.CurrentSim.Region.Name));
+
+ int online = 0;
+
+ foreach (SecondLife client in Clients.Values)
+ {
+ if (client.Network.Connected) online++;
+ }
+
+ Console.Write(online + " avatars online> ");
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void DoCommandAll(string cmd, LLUUID fromAgentID, LLUUID imSessionID)
+ {
+ string[] tokens = cmd.Trim().Split(new char[] { ' ', '\t' });
+ string firstToken = tokens[0].ToLower();
+
+ if (tokens.Length == 0)
+ return;
+
+ if (firstToken == "login")
+ {
+ // Special login case: Only call it once, and allow it with
+ // no logged in avatars
+ string[] args = new string[tokens.Length - 1];
+ Array.Copy(tokens, 1, args, 0, args.Length);
+ Login(args);
+ }
+ else if (firstToken == "quit")
+ {
+ Quit();
+ Console.WriteLine("All clients logged out and program finished running.");
+ }
+ else
+ {
+ // make a copy of the clients list so that it can be iterated without fear of being changed during iteration
+ Dictionary clientsCopy = new Dictionary(Clients);
+
+ foreach (TestClient client in clientsCopy.Values)
+ client.DoCommand(cmd, fromAgentID, imSessionID);
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void Logout(TestClient client)
+ {
+ Clients.Remove(client.Network.AgentID);
+ client.Network.Logout();
+ }
+
+ ///
+ ///
+ ///
+ public void LogoutAll()
+ {
+ // make a copy of the clients list so that it can be iterated without fear of being changed during iteration
+ Dictionary clientsCopy = new Dictionary(Clients);
+
+ foreach (TestClient client in clientsCopy.Values)
+ Logout(client);
+ }
+
+ ///
+ ///
+ ///
+ public void Quit()
+ {
+ LogoutAll();
+ Running = false;
+ // TODO: It would be really nice if we could figure out a way to abort the ReadLine here in so that Run() will exit.
+ }
+ }
+}
diff --git a/libsecondlife-cs/examples/TestClient/Commands/EchoMasterCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/EchoMasterCommand.cs
new file mode 100644
index 00000000..48efcf64
--- /dev/null
+++ b/libsecondlife-cs/examples/TestClient/Commands/EchoMasterCommand.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using libsecondlife;
+using libsecondlife.Packets;
+
+namespace libsecondlife.TestClient
+{
+ public class EchoMasterCommand: Command
+ {
+ public EchoMasterCommand()
+ {
+ Name = "echoMaster";
+ Description = "Repeat everything that master says.";
+ }
+
+ public override string Execute(SecondLife Client, string[] args, LLUUID fromAgentID)
+ {
+ if (!Active)
+ {
+ Active = true;
+ Client.Self.OnChat += new ChatCallback(Self_OnChat);
+ return "Echoing is now on.";
+ }
+ else
+ {
+ Active = false;
+ Client.Self.OnChat -= new ChatCallback(Self_OnChat);
+ return "Echoing is now off.";
+ }
+ }
+
+ void Self_OnChat(string message, byte audible, byte type, byte sourcetype, string fromName, LLUUID id, LLUUID ownerid, LLVector3 position)
+ {
+ if (message.Length > 0 && TestClient.Master == fromName)
+ {
+ TestClient.Self.Chat(message, 0, MainAvatar.ChatType.Normal);
+ }
+ }
+ }
+}
diff --git a/libsecondlife-cs/examples/TestClient/Commands/ExportCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/ExportCommand.cs
index c5340c05..c8520694 100644
--- a/libsecondlife-cs/examples/TestClient/Commands/ExportCommand.cs
+++ b/libsecondlife-cs/examples/TestClient/Commands/ExportCommand.cs
@@ -61,26 +61,34 @@ namespace libsecondlife.TestClient
{
try
{
- XmlWriter writer = XmlWriter.Create(file);
- List prims = new List();
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.Indent = true;
+ XmlWriter writer = XmlWriter.Create(file, settings);
+ try
+ {
+ List prims = new List();
- lock (TestClient.SimPrims)
- {
- if (TestClient.SimPrims.ContainsKey(Client.Network.CurrentSim))
- {
- foreach (PrimObject prim in TestClient.SimPrims[Client.Network.CurrentSim].Values)
- {
- if (prim.LocalID == localid || prim.ParentID == localid)
- {
- prims.Add(prim);
- count++;
- }
- }
- }
- }
- //Serialize it!
- Helpers.PrimListToXml(prims, writer);
- writer.Close();
+ lock (TestClient.SimPrims)
+ {
+ if (TestClient.SimPrims.ContainsKey(Client.Network.CurrentSim))
+ {
+ foreach (PrimObject prim in TestClient.SimPrims[Client.Network.CurrentSim].Values)
+ {
+ if (prim.LocalID == localid || prim.ParentID == localid)
+ {
+ prims.Add(prim);
+ count++;
+ }
+ }
+ }
+ }
+ //Serialize it!
+ Helpers.PrimListToXml(prims, writer);
+ }
+ finally
+ {
+ writer.Close();
+ }
}
catch (Exception e)
{
diff --git a/libsecondlife-cs/examples/TestClient/Commands/ExportOutfitCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/ExportOutfitCommand.cs
index 65676487..cc99d3d6 100644
--- a/libsecondlife-cs/examples/TestClient/Commands/ExportOutfitCommand.cs
+++ b/libsecondlife-cs/examples/TestClient/Commands/ExportOutfitCommand.cs
@@ -37,8 +37,17 @@ namespace libsecondlife.TestClient
{
try
{
- XmlWriter writer = XmlWriter.Create(args[1]);
- TestClient.Appearances[id].ToXml(writer);
+ XmlWriterSettings settings = new XmlWriterSettings();
+ settings.Indent = true;
+ XmlWriter writer = XmlWriter.Create(args[1], settings);
+ try
+ {
+ TestClient.Appearances[id].ToXml(writer);
+ }
+ finally
+ {
+ writer.Close();
+ }
}
catch (Exception e)
{
diff --git a/libsecondlife-cs/examples/TestClient/Commands/FollowCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/FollowCommand.cs
index f6bc0b79..0ecfba0f 100644
--- a/libsecondlife-cs/examples/TestClient/Commands/FollowCommand.cs
+++ b/libsecondlife-cs/examples/TestClient/Commands/FollowCommand.cs
@@ -43,7 +43,7 @@ namespace libsecondlife.TestClient
bool Follow(string name)
{
- foreach (Avatar av in TestClient.Avatars.Values)
+ foreach (Avatar av in TestClient.Avatars.AvatarList.Values)
{
if (av.Name == name)
{
diff --git a/libsecondlife-cs/examples/TestClient/Commands/ImportCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/ImportCommand.cs
index 806b90ff..8972f382 100644
--- a/libsecondlife-cs/examples/TestClient/Commands/ImportCommand.cs
+++ b/libsecondlife-cs/examples/TestClient/Commands/ImportCommand.cs
@@ -3,48 +3,18 @@ using System.Collections.Generic;
using libsecondlife;
using libsecondlife.Packets;
using System.Xml;
-using System.Threading;
using System.Xml.Serialization;
using System.IO;
-
namespace libsecondlife.TestClient
{
- public class Linkset
- {
- public PrimObject RootPrim;
- public List Children;
-
- public Linkset()
- {
- RootPrim = new PrimObject();
- Children = new List();
- }
-
- public Linkset(PrimObject rootPrim)
- {
- RootPrim = rootPrim;
- Children = new List();
- }
- }
-
public class ImportCommand : Command
{
- PrimObject currentPrim;
- LLVector3 currentPosition;
- SecondLife currentClient;
- ManualResetEvent primDone;
- List primsCreated;
- uint rootLocalID = 0;
- bool registeredCreateEvent = false;
- bool rezzingRootPrim = false;
- bool linking = false;
-
public ImportCommand()
{
Name = "import";
Description = "Import prims from an exported xml file. Usage: import [filename.xml]";
- primDone = new ManualResetEvent(false);
- registeredCreateEvent = false;
+
+// Execute(null, new string[] {"prims.xml"}, LLUUID.Zero);
}
public override string Execute(SecondLife Client, string[] args, LLUUID fromAgentID)
@@ -53,160 +23,30 @@ namespace libsecondlife.TestClient
return "Usage: import inputfile.xml";
string name = args[0];
- Dictionary prims;
-
- currentClient = Client;
+ List prims;
try
{
- XmlReader reader = XmlReader.Create(name);
- List listprims = Helpers.PrimListFromXml(reader);
- reader.Close();
+ //XmlReader reader = XmlReader.Create(name);
+ //prims = Helpers.PrimListFromXml(reader);
+ //reader.Close();
- // Create a dictionary indexed by the old local ID of the prims
- prims = new Dictionary();
- foreach (PrimObject prim in listprims)
- {
- prims.Add(prim.LocalID, prim);
- }
+ XmlSerializer serializer = new XmlSerializer(typeof(List));
+ XmlDeserializationEvents events = new XmlDeserializationEvents();
+ events.OnUnknownAttribute += new XmlAttributeEventHandler(OnUnknownAttribute);
+ events.OnUnknownElement += new XmlElementEventHandler(OnUnknownElement);
+ events.OnUnknownNode += new XmlNodeEventHandler(OnUnknownNode);
+ events.OnUnreferencedObject += new UnreferencedObjectEventHandler(OnUnreferenced);
+ prims = (List)serializer.Deserialize(XmlReader.Create(name), events);
+ //return list;
}
catch (Exception ex)
{
return "Deserialize failed: " + ex.ToString();
}
- if (!registeredCreateEvent)
- {
- TestClient.OnPrimCreated += new TestClient.PrimCreatedCallback(TestClient_OnPrimCreated);
- registeredCreateEvent = true;
- }
-
- // Build an organized structure from the imported prims
- Dictionary linksets = new Dictionary();
- foreach (PrimObject prim in prims.Values)
- {
- if (prim.ParentID == 0)
- {
- if (linksets.ContainsKey(prim.LocalID))
- linksets[prim.LocalID].RootPrim = prim;
- else
- linksets[prim.LocalID] = new Linkset(prim);
- }
- else
- {
- if (!linksets.ContainsKey(prim.ParentID))
- linksets[prim.ParentID] = new Linkset();
-
- linksets[prim.ParentID].Children.Add(prim);
- }
- }
-
- primsCreated = new List();
- linking = false;
- Console.WriteLine("Importing " + linksets.Count + " structures.");
-
- foreach (Linkset linkset in linksets.Values)
- {
- if (linkset.RootPrim.LocalID != 0)
- {
- // HACK: Offset the root prim position so it's not lying on top of the original
- // We need a more elaborate solution for importing with relative or absolute offsets
- linkset.RootPrim.Position.Z += 3.0f;
- currentPosition = linkset.RootPrim.Position;
-
- // Rez the root prim with no rotation
- LLQuaternion rootRotation = linkset.RootPrim.Rotation;
- linkset.RootPrim.Rotation = LLQuaternion.Identity;
-
- rezzingRootPrim = true;
- currentPrim = linkset.RootPrim;
-
- Client.Objects.AddPrim(Client.Network.CurrentSim, linkset.RootPrim, linkset.RootPrim.Position);
-
- if (!primDone.WaitOne(10000, false))
- return "Rez failed, timed out while creating a prim.";
- primDone.Reset();
-
- rezzingRootPrim = false;
-
- // Rez the child prims
- foreach (PrimObject prim in linkset.Children)
- {
- currentPrim = prim;
- currentPosition = prim.Position + linkset.RootPrim.Position;
-
- Client.Objects.AddPrim(Client.Network.CurrentSim, prim, currentPosition);
-
- if (!primDone.WaitOne(10000, false))
- return "Rez failed, timed out while creating a prim.";
- primDone.Reset();
- }
-
- // Create a list of the local IDs of the newly created prims
- List primIDs = new List();
- foreach (PrimObject prim in primsCreated)
- {
- if (prim.LocalID != rootLocalID)
- primIDs.Add(prim.LocalID);
- }
- // Make sure the root object is the last in our list so it becomes the new root
- primIDs.Add(rootLocalID);
-
- // Link and set the permissions + rotation
- linking = true;
-
- Client.Objects.LinkPrims(Client.Network.CurrentSim, primIDs);
-
- Client.Objects.SetPermissions(Client.Network.CurrentSim, primIDs,
- Helpers.PermissionWho.Everyone | Helpers.PermissionWho.Group | Helpers.PermissionWho.NextOwner,
- Helpers.PermissionType.Copy | Helpers.PermissionType.Modify | Helpers.PermissionType.Move |
- Helpers.PermissionType.Transfer, true);
-
- Client.Objects.SetRotation(Client.Network.CurrentSim, rootLocalID, rootRotation);
-
- for (int i = 0; i < linkset.Children.Count + 1; i++)
- {
- primDone.WaitOne(10000, false);
- primDone.Reset();
- }
-
- linking = false;
- }
- else
- {
- // Skip linksets with a missing root prim
- Console.WriteLine("WARNING: Skipping a linkset with a missing root prim");
- }
-
- // Reset everything for the next linkset
- primsCreated.Clear();
- }
-
- return "Import complete.";
- }
-
- void TestClient_OnPrimCreated(Simulator simulator, PrimObject prim)
- {
- if (rezzingRootPrim)
- {
- rootLocalID = prim.LocalID;
- }
-
- if (!linking)
- {
- Console.WriteLine("Setting properties for " + prim.LocalID);
-
- primsCreated.Add(prim);
-
- // FIXME: Replace these individual calls with a single ObjectUpdate that sets the
- // particle system and everything
- currentClient.Objects.SetPosition(simulator, prim.LocalID, currentPosition);
- currentClient.Objects.SetTextures(simulator, prim.LocalID, currentPrim.Textures);
- //currentClient.Objects.SetLight(simulator, prim.LocalID, currentPrim.Light);
- //currentClient.Objects.SetFlexible(simulator, prim.LocalID, currentPrim.Flexible);
- }
-
- primDone.Set();
+ // deserialization done, just need to code to rez and link.
+ return "Deserialized prims, rez code missing.";
}
void OnUnknownAttribute(object obj, XmlAttributeEventArgs args)
diff --git a/libsecondlife-cs/examples/TestClient/Commands/LoginCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/LoginCommand.cs
index 532ce46c..df8328ce 100644
--- a/libsecondlife-cs/examples/TestClient/Commands/LoginCommand.cs
+++ b/libsecondlife-cs/examples/TestClient/Commands/LoginCommand.cs
@@ -19,35 +19,15 @@ namespace libsecondlife.TestClient
if (args.Length != 3)
return "usage: login firstname lastname password";
- LoginDetails account = new LoginDetails();
- account.FirstName = args[0];
- account.LastName = args[1];
- account.Password = args[2];
-
- // Check if this client is already logged in
- foreach (SecondLife client in TestClient.Clients.Values)
- {
- if (client.Self.FirstName == account.FirstName && client.Self.LastName == account.LastName)
- {
- TestClient.Clients.Remove(client.Network.AgentID);
-
- client.Network.Logout();
-
- break;
- }
- }
-
- SecondLife newClient = TestClient.InitializeClient(account);
+ SecondLife newClient = TestClient.ClientManager.Login(args);
if (newClient.Network.Connected)
{
- TestClient.Clients[newClient.Network.AgentID] = newClient;
-
return "Logged in " + newClient.ToString();
}
else
{
- return "Failed to login " + account.FirstName + " " + account.LastName + ": " +
+ return "Failed to login: " +
newClient.Network.LoginError;
}
}
diff --git a/libsecondlife-cs/examples/TestClient/Commands/LogoutCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/LogoutCommand.cs
index 303e4b0d..c03b24be 100644
--- a/libsecondlife-cs/examples/TestClient/Commands/LogoutCommand.cs
+++ b/libsecondlife-cs/examples/TestClient/Commands/LogoutCommand.cs
@@ -17,19 +17,8 @@ namespace libsecondlife.TestClient
public override string Execute(SecondLife Client, string[] args, LLUUID fromAgentID)
{
string name = Client.ToString();
- TestClient.Clients.Remove(Client.Network.AgentID);
- Client.Network.Logout();
- Client = null;
-
- if (TestClient.Clients.Count > 0)
- {
- return "Logged " + name + " out";
- }
- else
- {
- TestClient.Running = false;
- return "All avatars logged out";
- }
+ TestClient.ClientManager.Logout(TestClient);
+ return "Logged " + name + " out";
}
}
}
diff --git a/libsecondlife-cs/examples/TestClient/Commands/QuitCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/QuitCommand.cs
index 2883676a..185c6f9b 100644
--- a/libsecondlife-cs/examples/TestClient/Commands/QuitCommand.cs
+++ b/libsecondlife-cs/examples/TestClient/Commands/QuitCommand.cs
@@ -16,12 +16,8 @@ namespace libsecondlife.TestClient
public override string Execute(SecondLife Client, string[] args, LLUUID fromAgentID)
{
- foreach (SecondLife client in TestClient.Clients.Values)
- {
- client.Network.Logout();
- }
-
- TestClient.Running = false;
+ TestClient.ClientManager.LogoutAll();
+ TestClient.ClientManager.Running = false;
return "All avatars logged out";
}
}
diff --git a/libsecondlife-cs/examples/TestClient/Commands/SayCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/SayCommand.cs
index d5d1f3bb..9c2f5d37 100644
--- a/libsecondlife-cs/examples/TestClient/Commands/SayCommand.cs
+++ b/libsecondlife-cs/examples/TestClient/Commands/SayCommand.cs
@@ -11,7 +11,7 @@ namespace libsecondlife.TestClient
public SayCommand()
{
Name = "say";
- Description = "Say something.";
+ Description = "Say something. (usage: say (optional channel) whatever)";
}
public override string Execute(SecondLife Client, string[] args, LLUUID fromAgentID)
@@ -25,15 +25,8 @@ namespace libsecondlife.TestClient
}
else if (args.Length > 1)
{
- try
- {
- channel = Convert.ToInt32(args[0]);
- startIndex = 1;
- }
- catch (FormatException)
- {
- channel = 0;
- }
+ if (Int32.TryParse(args[0], out channel))
+ startIndex = 1;
}
for (int i = startIndex; i < args.Length; i++) {
diff --git a/libsecondlife-cs/examples/TestClient/Commands/SetMasterCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/SetMasterCommand.cs
index c7e27f90..60d4e229 100644
--- a/libsecondlife-cs/examples/TestClient/Commands/SetMasterCommand.cs
+++ b/libsecondlife-cs/examples/TestClient/Commands/SetMasterCommand.cs
@@ -23,13 +23,13 @@ namespace libsecondlife.TestClient
masterName = masterName + args[ct] + " ";
TestClient.Master = masterName.TrimEnd();
- foreach (Avatar av in TestClient.Avatars.Values)
+ foreach (Avatar av in TestClient.Avatars.AvatarList.Values)
{
- if (av.Name == TestClient.Master)
- {
- Client.Self.InstantMessage(av.ID, "You are now my master. IM me with \"help\" for a command list.");
- break;
- }
+ if (av.Name == TestClient.Master)
+ {
+ Client.Self.InstantMessage(av.ID, "You are now my master. IM me with \"help\" for a command list.");
+ break;
+ }
}
return "Master set to " + masterName;
diff --git a/libsecondlife-cs/examples/TestClient/Commands/SitCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/SitCommand.cs
index f6de5cd6..33e069be 100644
--- a/libsecondlife-cs/examples/TestClient/Commands/SitCommand.cs
+++ b/libsecondlife-cs/examples/TestClient/Commands/SitCommand.cs
@@ -13,7 +13,7 @@ namespace libsecondlife.TestClient
Name = "sit";
Description = "Attempt to sit on the closest prim";
}
-
+
public override string Execute(SecondLife Client, string[] args, LLUUID fromAgentID)
{
PrimObject closest = null;
diff --git a/libsecondlife-cs/examples/TestClient/Commands/WhoCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/WhoCommand.cs
index 05520aae..e267a724 100644
--- a/libsecondlife-cs/examples/TestClient/Commands/WhoCommand.cs
+++ b/libsecondlife-cs/examples/TestClient/Commands/WhoCommand.cs
@@ -17,9 +17,9 @@ namespace libsecondlife.TestClient
public override string Execute(SecondLife Client, string[] args, LLUUID fromAgentID)
{
StringBuilder result = new StringBuilder();
- foreach (Avatar av in TestClient.Avatars.Values)
+ foreach (Avatar av in TestClient.Avatars.AvatarList.Values)
{
- result.AppendFormat("\n{0} {1}", av.Name, av.GroupName);
+ result.AppendFormat("\n{0} {1} {2}/{3} ID: {4}", av.Name, av.GroupName, av.CurrentRegion.Name, av.Position, av.ID);
}
return result.ToString();
diff --git a/libsecondlife-cs/examples/TestClient/Program.cs b/libsecondlife-cs/examples/TestClient/Program.cs
index e304ba82..66407768 100644
--- a/libsecondlife-cs/examples/TestClient/Program.cs
+++ b/libsecondlife-cs/examples/TestClient/Program.cs
@@ -18,7 +18,7 @@ namespace libsecondlife.TestClient
{
Arguments arguments = new Arguments(args);
- TestClient tester;
+ ClientManager manager;
List accounts = new List();
LoginDetails account;
string master = "";
@@ -98,10 +98,12 @@ namespace libsecondlife.TestClient
}
}
+ foreach (LoginDetails a in accounts)
+ a.Master = master;
+
// Login the accounts and run the input loop
- tester = new TestClient(accounts);
- tester.Master = master;
- tester.Run();
+ manager = new ClientManager(accounts);
+ manager.Run();
}
}
}
diff --git a/libsecondlife-cs/examples/TestClient/TestClient.cs b/libsecondlife-cs/examples/TestClient/TestClient.cs
index 77cf0d27..ef23e0df 100644
--- a/libsecondlife-cs/examples/TestClient/TestClient.cs
+++ b/libsecondlife-cs/examples/TestClient/TestClient.cs
@@ -8,25 +8,17 @@ using libsecondlife.AssetSystem;
namespace libsecondlife.TestClient
{
- public struct LoginDetails
+ public class TestClient : SecondLife
{
- public string FirstName;
- public string LastName;
- public string Password;
- }
-
- public class TestClient
- {
- public Dictionary Clients = new Dictionary();
+ public Dictionary> SimPrims;
public LLUUID GroupID = LLUUID.Zero;
public Dictionary GroupMembers;
- public Dictionary> SimPrims = new Dictionary>();
- public Dictionary Appearances = new Dictionary();
- public Dictionary Avatars = new Dictionary();
- public Dictionary Commands = new Dictionary();
+ public Dictionary Appearances = new Dictionary();
+ public Dictionary Commands = new Dictionary();
public Dictionary SharedValues = new Dictionary();
public bool Running = true;
public string Master = "";
+ public ClientManager ClientManager;
public delegate void PrimCreatedCallback(Simulator simulator, PrimObject prim);
public event PrimCreatedCallback OnPrimCreated;
@@ -38,100 +30,39 @@ namespace libsecondlife.TestClient
private int DrawDistance = 64;
private System.Timers.Timer updateTimer;
+
///
///
///
- ///
- public TestClient(List accounts)
+ public TestClient(ClientManager manager)
{
+ ClientManager = manager;
+
updateTimer = new System.Timers.Timer(1000);
updateTimer.Elapsed += new System.Timers.ElapsedEventHandler(updateTimer_Elapsed);
RegisterAllCommands(Assembly.GetExecutingAssembly());
- foreach (LoginDetails account in accounts)
- {
- SecondLife client = InitializeClient(account);
- if (client.Network.Connected)
- {
- Clients[client.Network.AgentID] = client;
+ Debug = false;
- Console.WriteLine("Logged in " + client.ToString());
+ Network.RegisterCallback(PacketType.AgentDataUpdate, new NetworkManager.PacketCallback(AgentDataUpdateHandler));
+
+ Objects.OnNewPrim += new ObjectManager.NewPrimCallback(Objects_OnNewPrim);
+ Objects.OnPrimMoved += new ObjectManager.PrimMovedCallback(Objects_OnPrimMoved);
+ Objects.OnObjectKilled += new ObjectManager.KillObjectCallback(Objects_OnObjectKilled);
+ //Objects.OnNewAvatar += new ObjectManager.NewAvatarCallback(Objects_OnNewAvatar);
+ //Objects.OnAvatarMoved += new ObjectManager.AvatarMovedCallback(Objects_OnAvatarMoved);
+ Self.OnInstantMessage += new InstantMessageCallback(Self_OnInstantMessage);
+
+ Network.RegisterCallback(PacketType.AvatarAppearance, new NetworkManager.PacketCallback(AvatarAppearanceHandler));
+
+ Objects.RequestAllObjects = true;
- // Throttle the connection to not receive LayerData or asset packets
- client.Throttle.Total = 0.0f;
- client.Throttle.Task = 1536000.0f;
- client.Throttle.Set();
- }
- else
- {
- Console.WriteLine("Failed to login " + account.FirstName + " " + account.LastName +
- ": " + client.Network.LoginError);
- }
- }
updateTimer.Start();
}
- ///
- ///
- ///
- ///
- ///
- public SecondLife InitializeClient(LoginDetails account)
- {
- SecondLife client = new SecondLife();
-
- client.Debug = false;
-
- client.Network.RegisterCallback(PacketType.AgentDataUpdate, new NetworkManager.PacketCallback(AgentDataUpdateHandler));
-
- client.Objects.OnNewPrim += new ObjectManager.NewPrimCallback(Objects_OnNewPrim);
- client.Objects.OnPrimMoved += new ObjectManager.PrimMovedCallback(Objects_OnPrimMoved);
- client.Objects.OnObjectKilled += new ObjectManager.KillObjectCallback(Objects_OnObjectKilled);
- client.Objects.OnNewAvatar += new ObjectManager.NewAvatarCallback(Objects_OnNewAvatar);
- client.Objects.OnAvatarMoved += new ObjectManager.AvatarMovedCallback(Objects_OnAvatarMoved);
- client.Self.OnInstantMessage += new InstantMessageCallback(Self_OnInstantMessage);
-
- client.Network.RegisterCallback(PacketType.AvatarAppearance, new NetworkManager.PacketCallback(AvatarAppearanceHandler));
-
- client.Objects.RequestAllObjects = true;
-
- bool login = client.Network.Login(account.FirstName, account.LastName, account.Password,
- "TestClient", "contact@libsecondlife.org");
-
- if (login)
- {
- // Set our appearance
- //AppearanceManager appearance = new AppearanceManager(client);
- //appearance.SendAgentSetAppearance();
- }
-
- return client;
- }
-
- ///
- ///
- ///
- public void Run()
- {
- Console.WriteLine("Type quit to exit. Type help for a command list.");
-
- while (Running)
- {
- PrintPrompt();
- string input = Console.ReadLine();
- DoCommandAll(input, null, null);
- }
-
- foreach (SecondLife client in Clients.Values)
- {
- if (client.Network.Connected)
- client.Network.Logout();
- }
- }
-
public void RegisterAllCommands(Assembly assembly)
{
foreach (Type t in assembly.GetTypes())
@@ -170,7 +101,8 @@ namespace libsecondlife.TestClient
client.Self.InstantMessage(fromAgentID, message, imSessionID);
}
}
- private void DoCommand(SecondLife client, string cmd, LLUUID fromAgentID, LLUUID imSessionID)
+
+ public void DoCommand(string cmd, LLUUID fromAgentID, LLUUID imSessionID)
{
string[] tokens = cmd.Trim().Split(new char[] { ' ', '\t' });
string firstToken = tokens[0].ToLower();
@@ -179,124 +111,45 @@ namespace libsecondlife.TestClient
return;
// "all balance" will send the balance command to all currently logged in bots
- if (firstToken == "all" && tokens.Length > 1)
- {
- cmd = "";
+ if (firstToken == "all" && tokens.Length > 1)
+ {
+ cmd = "";
- // Reserialize all of the arguments except for "all"
- for (int i = 1; i < tokens.Length; i++)
- {
- cmd += tokens[i] + " ";
- }
+ // Reserialize all of the arguments except for "all"
+ for (int i = 1; i < tokens.Length; i++)
+ {
+ cmd += tokens[i] + " ";
+ }
- DoCommandAll(cmd, fromAgentID, imSessionID);
+ ClientManager.DoCommandAll(cmd, fromAgentID, imSessionID);
- return;
- }
+ return;
+ }
if (Commands.ContainsKey(firstToken))
{
string[] args = new string[tokens.Length - 1];
Array.Copy(tokens, 1, args, 0, args.Length);
- string response = response = Commands[firstToken].Execute(client, args, fromAgentID);
+ string response = response = Commands[firstToken].Execute(this, args, fromAgentID);
if (response.Length > 0)
{
- if (fromAgentID != null && client.Network.Connected)
- SendResponseIM(client, fromAgentID, response, imSessionID);
+ if (fromAgentID != null && Network.Connected)
+ SendResponseIM(this, fromAgentID, response, imSessionID);
Console.WriteLine(response);
}
}
}
- private void DoCommandAll(string cmd, LLUUID fromAgentID, LLUUID imSessionID)
- {
- string[] tokens = cmd.Trim().Split(new char[] { ' ', '\t' });
- string firstToken = tokens[0].ToLower();
-
- if (tokens.Length == 0)
- return;
-
-Begin:
-
- int avatars = Clients.Count;
-
- if (Commands.ContainsKey(firstToken))
- {
- if (firstToken == "login")
- {
- // Special login case: Only call it once, and allow it with
- // no logged in avatars
- string[] args = new string[tokens.Length - 1];
- Array.Copy(tokens, 1, args, 0, args.Length);
- string response = Commands["login"].Execute(null, args, null);
-
- if (response.Length > 0)
- {
- Console.WriteLine(response);
- }
- }
- else if (firstToken == "quit")
- {
- // Special quit case: This allows us to quit even when there
- // are zero avatars logged in
- Commands["quit"].Execute(null, null, null);
- }
- else
- {
- foreach (SecondLife client in Clients.Values)
- {
- if (client.Network.Connected)
- {
- string[] args = new string[tokens.Length - 1];
- Array.Copy(tokens, 1, args, 0, args.Length);
- string response = Commands[firstToken].Execute(client, args, fromAgentID);
-
- if (response.Length > 0)
- {
- if (fromAgentID != null && client.Network.Connected)
- SendResponseIM(client, fromAgentID, response, imSessionID);
- Console.WriteLine(response);
- }
- }
-
- if (avatars != Clients.Count)
- {
- // The dictionary size changed, start over since the
- // foreach is shot
- goto Begin;
- }
- }
- }
- }
- }
-
- private void PrintPrompt()
- {
- //Console.Write(String.Format("{0} {1} - {2}> ", client.Self.FirstName, client.Self.LastName, client.Network.CurrentSim.Region.Name));
-
- int online = 0;
-
- foreach (SecondLife client in Clients.Values)
- {
- if (client.Network.Connected) online++;
- }
-
- Console.Write(online + " avatars online> ");
- }
-
private void updateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
- foreach (SecondLife client in Clients.Values)
- {
- client.Self.UpdateCamera(0, client.Self.Position, forward, left, up, bodyRotation,
- LLQuaternion.Identity, DrawDistance, false);
+ Self.UpdateCamera(0, Self.Position, forward, left, up, bodyRotation,
+ LLQuaternion.Identity, DrawDistance, false);
- foreach (Command c in Commands.Values)
- if (c.Active)
- c.Think(client);
- }
+ foreach (Command c in Commands.Values)
+ if (c.Active)
+ c.Think(this);
}
private void AgentDataUpdateHandler(Packet packet, Simulator sim)
@@ -315,7 +168,6 @@ Begin:
{
Console.WriteLine("Got " + members.Count + " group members.");
GroupMembers = members;
- PrintPrompt();
}
private void Objects_OnObjectKilled(Simulator simulator, uint objectID)
@@ -326,11 +178,11 @@ Begin:
SimPrims[simulator].Remove(objectID);
}
- lock (Avatars)
- {
- if (Avatars.ContainsKey(objectID))
- Avatars.Remove(objectID);
- }
+ //lock (AvatarList)
+ //{
+ // if (AvatarList.ContainsKey(objectID))
+ // AvatarList.Remove(objectID);
+ //}
}
private void Objects_OnPrimMoved(Simulator simulator, PrimUpdate prim, ulong regionHandle, ushort timeDilation)
@@ -363,25 +215,25 @@ Begin:
}
}
- private void Objects_OnNewAvatar(Simulator simulator, Avatar avatar, ulong regionHandle, ushort timeDilation)
- {
- lock (Avatars)
- {
- Avatars[avatar.LocalID] = avatar;
- }
- }
+ //private void Objects_OnNewAvatar(Simulator simulator, Avatar avatar, ulong regionHandle, ushort timeDilation)
+ //{
+ // lock (AvatarList)
+ // {
+ // AvatarList[avatar.LocalID] = avatar;
+ // }
+ //}
- private void Objects_OnAvatarMoved(Simulator simulator, AvatarUpdate avatar, ulong regionHandle, ushort timeDilation)
- {
- lock (Avatars)
- {
- if (Avatars.ContainsKey(avatar.LocalID))
- {
- Avatars[avatar.LocalID].Position = avatar.Position;
- Avatars[avatar.LocalID].Rotation = avatar.Rotation;
- }
- }
- }
+ //private void Objects_OnAvatarMoved(Simulator simulator, AvatarUpdate avatar, ulong regionHandle, ushort timeDilation)
+ //{
+ // lock (AvatarList)
+ // {
+ // if (AvatarList.ContainsKey(avatar.LocalID))
+ // {
+ // AvatarList[avatar.LocalID].Position = avatar.Position;
+ // AvatarList[avatar.LocalID].Rotation = avatar.Rotation;
+ // }
+ // }
+ //}
private void AvatarAppearanceHandler(Packet packet, Simulator simulator)
{
@@ -415,16 +267,16 @@ Begin:
Console.WriteLine("" + fromAgentName + ": " + message);
- if (Clients.ContainsKey(toAgentID))
+ if (Self.ID == toAgentID)
{
if (dialog == 22)
{
Console.WriteLine("Accepting teleport lure");
- Clients[toAgentID].Self.TeleportLureRespond(fromAgentID, true);
+ Self.TeleportLureRespond(fromAgentID, true);
}
else
{
- DoCommand(Clients[toAgentID], message, fromAgentID, imSessionID);
+ DoCommand(message, fromAgentID, imSessionID);
}
}
else
@@ -433,5 +285,5 @@ Begin:
Console.WriteLine("A bot that we aren't tracking received an IM?");
}
}
- }
-}
+ }
+}
\ No newline at end of file
diff --git a/libsecondlife-cs/examples/TestClient/TestClient.csproj b/libsecondlife-cs/examples/TestClient/TestClient.csproj
index 912281d8..30b2845a 100644
--- a/libsecondlife-cs/examples/TestClient/TestClient.csproj
+++ b/libsecondlife-cs/examples/TestClient/TestClient.csproj
@@ -36,24 +36,37 @@
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
-
-
-
-
-
-
@@ -61,7 +74,10 @@
-
+
+
+ Code
+
diff --git a/libsecondlife-cs/libsecondlife.sln b/libsecondlife-cs/libsecondlife.sln
index c1e677e0..87bad82a 100644
--- a/libsecondlife-cs/libsecondlife.sln
+++ b/libsecondlife-cs/libsecondlife.sln
@@ -38,6 +38,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IA_TestAsyncImage", "exampl
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SLIRC", "..\applications\SLIRC\SLIRC.csproj", "{8855EB2F-BC4C-485A-A577-0989EB16BFDC}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "InventoryImageAssets", "InventoryImageAssets", "{AE3B6C21-9B43-490E-ABCE-2018DC1AEA44}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IA_MultiImageUpload", "examples\IA_MultiImageUpload\IA_MultiImageUpload.csproj", "{8598E42A-DCBC-4224-9503-5694F17B2F45}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SLProxy", "..\SLProxy\SLProxy.csproj", "{E4115DC9-FC88-47D6-B3B6-2400AD19B80D}"
@@ -48,8 +50,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatConsole", "..\SLProxy\C
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BodyPartMorphGenerator", "examples\BodyPartMorphGenerator\BodyPartMorphGenerator.csproj", "{98C44481-3F15-4305-840D-037EA0D9C221}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools and Examples", "Tools and Examples", "{F35EF72F-4302-4924-A162-10447B94F635}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SL Proxy", "SL Proxy", "{C754652B-2ACB-4D47-8914-834E17919132}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClient", "examples\TestClient\TestClient.csproj", "{B87682F6-B2D7-4C4D-A529-400C24FD4880}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sit", "..\..\SurveyAndSit\Sit.csproj", "{C741A2FF-732C-4724-A4D3-D52324D09C8E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -156,8 +164,36 @@ Global
{B87682F6-B2D7-4C4D-A529-400C24FD4880}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B87682F6-B2D7-4C4D-A529-400C24FD4880}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B87682F6-B2D7-4C4D-A529-400C24FD4880}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C741A2FF-732C-4724-A4D3-D52324D09C8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C741A2FF-732C-4724-A4D3-D52324D09C8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C741A2FF-732C-4724-A4D3-D52324D09C8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C741A2FF-732C-4724-A4D3-D52324D09C8E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {FC19D5F6-076E-4923-8456-9B0E00E22896} = {F35EF72F-4302-4924-A162-10447B94F635}
+ {66FFD34E-652C-4EF5-81FE-06AD011169D2} = {F35EF72F-4302-4924-A162-10447B94F635}
+ {623B86F7-7753-44B7-A8C8-CBC89FB8AF8E} = {F35EF72F-4302-4924-A162-10447B94F635}
+ {77E5330D-8A8C-41B4-A2D1-6F06FE45ED6D} = {F35EF72F-4302-4924-A162-10447B94F635}
+ {B5AC6795-E426-4BC3-950F-D7B2970E2394} = {F35EF72F-4302-4924-A162-10447B94F635}
+ {7AE16AC1-E64C-4FDC-9B85-4BB6145D511C} = {F35EF72F-4302-4924-A162-10447B94F635}
+ {F460FAB3-0D12-4873-89EB-2696818764B8} = {F35EF72F-4302-4924-A162-10447B94F635}
+ {4EF98AD4-B3B3-42B0-9273-13A614A823F7} = {F35EF72F-4302-4924-A162-10447B94F635}
+ {8855EB2F-BC4C-485A-A577-0989EB16BFDC} = {F35EF72F-4302-4924-A162-10447B94F635}
+ {F6258A68-C624-46A0-BA73-B55D21BB0A3B} = {F35EF72F-4302-4924-A162-10447B94F635}
+ {B87682F6-B2D7-4C4D-A529-400C24FD4880} = {F35EF72F-4302-4924-A162-10447B94F635}
+ {C741A2FF-732C-4724-A4D3-D52324D09C8E} = {F35EF72F-4302-4924-A162-10447B94F635}
+ {E185E4E1-62D2-430C-A94C-E8E38190805B} = {AE3B6C21-9B43-490E-ABCE-2018DC1AEA44}
+ {8D2E5240-2247-42F5-AAAC-CF0CCCEE349A} = {AE3B6C21-9B43-490E-ABCE-2018DC1AEA44}
+ {D6D1D020-D8D8-4D7E-B7AC-5913A903D6E7} = {AE3B6C21-9B43-490E-ABCE-2018DC1AEA44}
+ {A4F59DE9-E382-401D-AA8D-4557779D764E} = {AE3B6C21-9B43-490E-ABCE-2018DC1AEA44}
+ {E464B963-46E3-4E1A-A36F-9C640C880E68} = {AE3B6C21-9B43-490E-ABCE-2018DC1AEA44}
+ {8598E42A-DCBC-4224-9503-5694F17B2F45} = {AE3B6C21-9B43-490E-ABCE-2018DC1AEA44}
+ {98C44481-3F15-4305-840D-037EA0D9C221} = {AE3B6C21-9B43-490E-ABCE-2018DC1AEA44}
+ {6222B134-AE5F-489A-8A77-423A721B7C62} = {C754652B-2ACB-4D47-8914-834E17919132}
+ {D8ECCBE1-AC71-4054-AAA6-2D50E5629504} = {C754652B-2ACB-4D47-8914-834E17919132}
+ {E4115DC9-FC88-47D6-B3B6-2400AD19B80D} = {C754652B-2ACB-4D47-8914-834E17919132}
+ EndGlobalSection
EndGlobal