aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs28
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs25
-rw-r--r--OpenSim/Client/MXP/ClientStack/MXPClientView.cs4
-rw-r--r--OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs4
-rw-r--r--OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs2
-rw-r--r--OpenSim/Framework/AgentCircuitData.cs63
-rw-r--r--OpenSim/Framework/AvatarAppearance.cs888
-rw-r--r--OpenSim/Framework/AvatarAttachment.cs (renamed from OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs)50
-rw-r--r--OpenSim/Framework/AvatarWearable.cs46
-rw-r--r--OpenSim/Framework/Capabilities/Caps.cs4
-rw-r--r--OpenSim/Framework/ChildAgentDataUpdate.cs140
-rw-r--r--OpenSim/Framework/IClientAPI.cs6
-rw-r--r--OpenSim/Framework/Tests/AgentCircuitDataTest.cs2
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs8
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs16
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs347
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs11
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs172
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs15
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs16
-rw-r--r--OpenSim/Services/AvatarService/AvatarService.cs14
-rw-r--r--OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs12
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs82
-rw-r--r--OpenSim/Services/Interfaces/IAvatarService.cs48
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs10
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs2
30 files changed, 1172 insertions, 858 deletions
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
index aeed467..1829c8d 100644
--- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
+++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
@@ -1472,12 +1472,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
1472 { 1472 {
1473 m_log.DebugFormat("[RADMIN] Initializing inventory for {0} from {1}", destination, source); 1473 m_log.DebugFormat("[RADMIN] Initializing inventory for {0} from {1}", destination, source);
1474 Scene scene = m_application.SceneManager.CurrentOrFirstScene; 1474 Scene scene = m_application.SceneManager.CurrentOrFirstScene;
1475 AvatarAppearance avatarAppearance = null;
1476 AvatarData avatar = scene.AvatarService.GetAvatar(source);
1477 if (avatar != null)
1478 avatarAppearance = avatar.ToAvatarAppearance(source);
1479 1475
1480 // If the model has no associated appearance we're done. 1476 // If the model has no associated appearance we're done.
1477 AvatarAppearance avatarAppearance = scene.AvatarService.GetAppearance(source);
1481 if (avatarAppearance == null) 1478 if (avatarAppearance == null)
1482 return; 1479 return;
1483 1480
@@ -1491,8 +1488,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
1491 { 1488 {
1492 CopyWearablesAndAttachments(destination, source, avatarAppearance); 1489 CopyWearablesAndAttachments(destination, source, avatarAppearance);
1493 1490
1494 AvatarData avatarData = new AvatarData(avatarAppearance); 1491 scene.AvatarService.SetAppearance(destination, avatarAppearance);
1495 scene.AvatarService.SetAvatar(destination, avatarData);
1496 } 1492 }
1497 catch (Exception e) 1493 catch (Exception e)
1498 { 1494 {
@@ -1523,8 +1519,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
1523 } 1519 }
1524 } 1520 }
1525 1521
1526 AvatarData avatarData = new AvatarData(avatarAppearance); 1522 scene.AvatarService.SetAppearance(destination, avatarAppearance);
1527 scene.AvatarService.SetAvatar(destination, avatarData);
1528 } 1523 }
1529 catch (Exception e) 1524 catch (Exception e)
1530 { 1525 {
@@ -1619,12 +1614,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController
1619 } 1614 }
1620 1615
1621 // Attachments 1616 // Attachments
1622 Dictionary<int, UUID[]> attachments = avatarAppearance.GetAttachmentDictionary(); 1617 List<AvatarAttachment> attachments = avatarAppearance.GetAttachments();
1623 1618
1624 foreach (KeyValuePair<int, UUID[]> attachment in attachments) 1619 foreach (AvatarAttachment attachment in attachments)
1625 { 1620 {
1626 int attachpoint = attachment.Key; 1621 int attachpoint = attachment.AttachPoint;
1627 UUID itemID = attachment.Value[0]; 1622 UUID itemID = attachment.ItemID;
1628 1623
1629 if (itemID != UUID.Zero) 1624 if (itemID != UUID.Zero)
1630 { 1625 {
@@ -1908,10 +1903,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
1908 if (include) 1903 if (include)
1909 { 1904 {
1910 // Setup for appearance processing 1905 // Setup for appearance processing
1911 AvatarData avatarData = scene.AvatarService.GetAvatar(ID); 1906 avatarAppearance = scene.AvatarService.GetAppearance(ID);
1912 if (avatarData != null) 1907 if (avatarAppearance == null)
1913 avatarAppearance = avatarData.ToAvatarAppearance(ID);
1914 else
1915 avatarAppearance = new AvatarAppearance(); 1908 avatarAppearance = new AvatarAppearance();
1916 1909
1917 AvatarWearable[] wearables = avatarAppearance.Wearables; 1910 AvatarWearable[] wearables = avatarAppearance.Wearables;
@@ -2076,8 +2069,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
2076 m_log.DebugFormat("[RADMIN] Outfit {0} load completed", outfitName); 2069 m_log.DebugFormat("[RADMIN] Outfit {0} load completed", outfitName);
2077 } // foreach outfit 2070 } // foreach outfit
2078 m_log.DebugFormat("[RADMIN] Inventory update complete for {0}", name); 2071 m_log.DebugFormat("[RADMIN] Inventory update complete for {0}", name);
2079 AvatarData avatarData2 = new AvatarData(avatarAppearance); 2072 scene.AvatarService.SetAppearance(ID, avatarAppearance);
2080 scene.AvatarService.SetAvatar(ID, avatarData2);
2081 } 2073 }
2082 catch (Exception e) 2074 catch (Exception e)
2083 { 2075 {
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs
index 8271d76..3f6d4d6 100644
--- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestAppearanceServices.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic;
30using System.Xml; 31using System.Xml;
31using OpenMetaverse; 32using OpenMetaverse;
32using OpenSim.Framework; 33using OpenSim.Framework;
@@ -765,25 +766,19 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
765 FormatPart(rdata, "UnderShirt", rdata.userAppearance.UnderShirtItem, rdata.userAppearance.UnderShirtAsset); 766 FormatPart(rdata, "UnderShirt", rdata.userAppearance.UnderShirtItem, rdata.userAppearance.UnderShirtAsset);
766 FormatPart(rdata, "UnderPants", rdata.userAppearance.UnderPantsItem, rdata.userAppearance.UnderPantsAsset); 767 FormatPart(rdata, "UnderPants", rdata.userAppearance.UnderPantsItem, rdata.userAppearance.UnderPantsAsset);
767 768
768 Hashtable attachments = rdata.userAppearance.GetAttachments(); 769 Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting attachments", MsgId);
769 770
770 if (attachments != null) 771 rdata.writer.WriteStartElement("Attachments");
772 List<AvatarAttachment> attachments = rdata.userAppearance.GetAttachments();
773 foreach (AvatarAttachment attach in attachments)
771 { 774 {
772 775 rdata.writer.WriteStartElement("Attachment");
773 Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting attachments", MsgId); 776 rdata.writer.WriteAttributeString("AtPoint", attach.AttachPoint.ToString());
774 777 rdata.writer.WriteAttributeString("Item", attach.ItemID.ToString());
775 rdata.writer.WriteStartElement("Attachments"); 778 rdata.writer.WriteAttributeString("Asset", attach.AssetID.ToString());
776 for (int i = 0; i < attachments.Count; i++)
777 {
778 Hashtable attachment = attachments[i] as Hashtable;
779 rdata.writer.WriteStartElement("Attachment");
780 rdata.writer.WriteAttributeString("AtPoint", i.ToString());
781 rdata.writer.WriteAttributeString("Item", (string) attachment["item"]);
782 rdata.writer.WriteAttributeString("Asset", (string) attachment["asset"]);
783 rdata.writer.WriteEndElement();
784 }
785 rdata.writer.WriteEndElement(); 779 rdata.writer.WriteEndElement();
786 } 780 }
781 rdata.writer.WriteEndElement();
787 782
788 Primitive.TextureEntry texture = rdata.userAppearance.Texture; 783 Primitive.TextureEntry texture = rdata.userAppearance.Texture;
789 784
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
index af9478e..19331c6 100644
--- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
+++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
@@ -596,7 +596,7 @@ namespace OpenSim.Client.MXP.ClientStack
596 public event TeleportLandmarkRequest OnTeleportLandmarkRequest; 596 public event TeleportLandmarkRequest OnTeleportLandmarkRequest;
597 public event DeRezObject OnDeRezObject; 597 public event DeRezObject OnDeRezObject;
598 public event Action<IClientAPI> OnRegionHandShakeReply; 598 public event Action<IClientAPI> OnRegionHandShakeReply;
599 public event GenericCall2 OnRequestWearables; 599 public event GenericCall1 OnRequestWearables;
600 public event GenericCall1 OnCompleteMovementToRegion; 600 public event GenericCall1 OnCompleteMovementToRegion;
601 public event UpdateAgent OnPreAgentUpdate; 601 public event UpdateAgent OnPreAgentUpdate;
602 public event UpdateAgent OnAgentUpdate; 602 public event UpdateAgent OnAgentUpdate;
@@ -861,7 +861,7 @@ namespace OpenSim.Client.MXP.ClientStack
861 OpenSim.Region.Framework.Scenes.Scene scene=(OpenSim.Region.Framework.Scenes.Scene)Scene; 861 OpenSim.Region.Framework.Scenes.Scene scene=(OpenSim.Region.Framework.Scenes.Scene)Scene;
862 AvatarAppearance appearance; 862 AvatarAppearance appearance;
863 scene.GetAvatarAppearance(this,out appearance); 863 scene.GetAvatarAppearance(this,out appearance);
864 OnSetAppearance(appearance.Texture, (byte[])appearance.VisualParams.Clone()); 864 OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone());
865 } 865 }
866 866
867 public void Stop() 867 public void Stop()
diff --git a/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs b/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs
index 7056e01..dcecb8b 100644
--- a/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs
+++ b/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs
@@ -533,9 +533,7 @@ namespace OpenSim.Client.MXP.PacketHandler
533 agent.InventoryFolder = UUID.Zero; 533 agent.InventoryFolder = UUID.Zero;
534 agent.startpos = new Vector3(0, 0, 0); // TODO Fill in region start position 534 agent.startpos = new Vector3(0, 0, 0); // TODO Fill in region start position
535 agent.CapsPath = "http://localhost/"; 535 agent.CapsPath = "http://localhost/";
536 AvatarData avatar = scene.AvatarService.GetAvatar(account.PrincipalID); 536 agent.Appearance = scene.AvatarService.GetAppearance(account.PrincipalID);
537 if (avatar != null)
538 agent.Appearance = avatar.ToAvatarAppearance(account.PrincipalID); //userService.GetUserAppearance(userProfile.ID);
539 537
540 if (agent.Appearance == null) 538 if (agent.Appearance == null)
541 { 539 {
diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
index 99a46dc..0d23232 100644
--- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
+++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
@@ -245,7 +245,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
245 public event TeleportLandmarkRequest OnTeleportLandmarkRequest = delegate { }; 245 public event TeleportLandmarkRequest OnTeleportLandmarkRequest = delegate { };
246 public event DeRezObject OnDeRezObject = delegate { }; 246 public event DeRezObject OnDeRezObject = delegate { };
247 public event Action<IClientAPI> OnRegionHandShakeReply = delegate { }; 247 public event Action<IClientAPI> OnRegionHandShakeReply = delegate { };
248 public event GenericCall2 OnRequestWearables = delegate { }; 248 public event GenericCall1 OnRequestWearables = delegate { };
249 public event GenericCall1 OnCompleteMovementToRegion = delegate { }; 249 public event GenericCall1 OnCompleteMovementToRegion = delegate { };
250 public event UpdateAgent OnPreAgentUpdate; 250 public event UpdateAgent OnPreAgentUpdate;
251 public event UpdateAgent OnAgentUpdate = delegate { }; 251 public event UpdateAgent OnAgentUpdate = delegate { };
diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs
index 4f89d78..640a646 100644
--- a/OpenSim/Framework/AgentCircuitData.cs
+++ b/OpenSim/Framework/AgentCircuitData.cs
@@ -26,7 +26,9 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using System.Collections.Generic; 30using System.Collections.Generic;
31using log4net;
30using OpenMetaverse; 32using OpenMetaverse;
31using OpenMetaverse.StructuredData; 33using OpenMetaverse.StructuredData;
32 34
@@ -38,6 +40,12 @@ namespace OpenSim.Framework
38 /// </summary> 40 /// </summary>
39 public class AgentCircuitData 41 public class AgentCircuitData
40 { 42 {
43// DEBUG ON
44 private static readonly ILog m_log =
45 LogManager.GetLogger(
46 MethodBase.GetCurrentMethod().DeclaringType);
47// DEBUG OFF
48
41 /// <summary> 49 /// <summary>
42 /// Avatar Unique Agent Identifier 50 /// Avatar Unique Agent Identifier
43 /// </summary> 51 /// </summary>
@@ -198,15 +206,18 @@ namespace OpenSim.Framework
198 206
199 args["service_session_id"] = OSD.FromString(ServiceSessionID); 207 args["service_session_id"] = OSD.FromString(ServiceSessionID);
200 args["start_pos"] = OSD.FromString(startpos.ToString()); 208 args["start_pos"] = OSD.FromString(startpos.ToString());
201 args["appearance_serial"] = OSD.FromInteger(Appearance.Serial);
202 args["client_ip"] = OSD.FromString(IPAddress); 209 args["client_ip"] = OSD.FromString(IPAddress);
203 args["viewer"] = OSD.FromString(Viewer); 210 args["viewer"] = OSD.FromString(Viewer);
204 args["channel"] = OSD.FromString(Channel); 211 args["channel"] = OSD.FromString(Channel);
205 args["mac"] = OSD.FromString(Mac); 212 args["mac"] = OSD.FromString(Mac);
206 args["id0"] = OSD.FromString(Id0); 213 args["id0"] = OSD.FromString(Id0);
207 214
215 // Eventually this code should be deprecated, use full appearance
216 // packing in packed_appearance
208 if (Appearance != null) 217 if (Appearance != null)
209 { 218 {
219 args["appearance_serial"] = OSD.FromInteger(Appearance.Serial);
220
210 //System.Console.WriteLine("XXX Before packing Wearables"); 221 //System.Console.WriteLine("XXX Before packing Wearables");
211 if ((Appearance.Wearables != null) && (Appearance.Wearables.Length > 0)) 222 if ((Appearance.Wearables != null) && (Appearance.Wearables.Length > 0))
212 { 223 {
@@ -221,20 +232,25 @@ namespace OpenSim.Framework
221 } 232 }
222 233
223 //System.Console.WriteLine("XXX Before packing Attachments"); 234 //System.Console.WriteLine("XXX Before packing Attachments");
224 Dictionary<int, UUID[]> attachments = Appearance.GetAttachmentDictionary(); 235 List<AvatarAttachment> attachments = Appearance.GetAttachments();
225 if ((attachments != null) && (attachments.Count > 0)) 236 if ((attachments != null) && (attachments.Count > 0))
226 { 237 {
227 OSDArray attachs = new OSDArray(attachments.Count); 238 OSDArray attachs = new OSDArray(attachments.Count);
228 foreach (KeyValuePair<int, UUID[]> kvp in attachments) 239 foreach (AvatarAttachment attach in attachments)
229 { 240 {
230 AttachmentData adata = new AttachmentData(kvp.Key, kvp.Value[0], kvp.Value[1]); 241 attachs.Add(attach.Pack());
231 attachs.Add(adata.PackUpdateMessage());
232 //System.Console.WriteLine("XXX att.pt=" + kvp.Key + "; itemID=" + kvp.Value[0] + "; assetID=" + kvp.Value[1]); 242 //System.Console.WriteLine("XXX att.pt=" + kvp.Key + "; itemID=" + kvp.Value[0] + "; assetID=" + kvp.Value[1]);
233 } 243 }
234 args["attachments"] = attachs; 244 args["attachments"] = attachs;
235 } 245 }
236 } 246 }
237 247
248 if (Appearance != null)
249 {
250 OSDMap appmap = Appearance.Pack();
251 args["packed_appearance"] = appmap;
252 }
253
238 if (ServiceURLs != null && ServiceURLs.Count > 0) 254 if (ServiceURLs != null && ServiceURLs.Count > 0)
239 { 255 {
240 OSDArray urls = new OSDArray(ServiceURLs.Count * 2); 256 OSDArray urls = new OSDArray(ServiceURLs.Count * 2);
@@ -317,34 +333,57 @@ namespace OpenSim.Framework
317 if (args["start_pos"] != null) 333 if (args["start_pos"] != null)
318 Vector3.TryParse(args["start_pos"].AsString(), out startpos); 334 Vector3.TryParse(args["start_pos"].AsString(), out startpos);
319 335
336// DEBUG ON
337 m_log.WarnFormat("[AGENTCIRCUITDATA] agentid={0}, child={1}, startpos={2}",AgentID,child,startpos.ToString());
338// DEBUG OFF
339
340 try {
341 // Unpack various appearance elements
320 Appearance = new AvatarAppearance(AgentID); 342 Appearance = new AvatarAppearance(AgentID);
343
344 // Eventually this code should be deprecated, use full appearance
345 // packing in packed_appearance
321 if (args["appearance_serial"] != null) 346 if (args["appearance_serial"] != null)
322 Appearance.Serial = args["appearance_serial"].AsInteger(); 347 Appearance.Serial = args["appearance_serial"].AsInteger();
348
323 if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array) 349 if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
324 { 350 {
325 OSDArray wears = (OSDArray)(args["wearables"]); 351 OSDArray wears = (OSDArray)(args["wearables"]);
326 for (int i = 0; i < wears.Count / 2; i++) 352 for (int i = 0; i < wears.Count / 2; i++)
327 { 353 {
328 Appearance.Wearables[i].ItemID = wears[i*2].AsUUID(); 354 AvatarWearable awear = new AvatarWearable(wears[i*2].AsUUID(),wears[(i*2)+1].AsUUID());
329 Appearance.Wearables[i].AssetID = wears[(i*2)+1].AsUUID(); 355 Appearance.SetWearable(i,awear);
330 } 356 }
331 } 357 }
332 358
333 if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array) 359 if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
334 { 360 {
335 OSDArray attachs = (OSDArray)(args["attachments"]); 361 OSDArray attachs = (OSDArray)(args["attachments"]);
336 AttachmentData[] attachments = new AttachmentData[attachs.Count];
337 int i = 0;
338 foreach (OSD o in attachs) 362 foreach (OSD o in attachs)
339 { 363 {
340 if (o.Type == OSDType.Map) 364 if (o.Type == OSDType.Map)
341 { 365 {
342 attachments[i++] = new AttachmentData((OSDMap)o); 366 Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
343 } 367 }
344 } 368 }
345 Appearance.SetAttachments(attachments);
346 } 369 }
347 370
371 if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map))
372 {
373 Appearance.Unpack((OSDMap)args["packed_appearance"]);
374// DEBUG ON
375 m_log.WarnFormat("[AGENTCIRCUITDATA] unpacked appearance");
376// DEBUG OFF
377 }
378// DEBUG ON
379 else
380 m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance");
381// DEBUG OFF
382 } catch (Exception e)
383 {
384 m_log.ErrorFormat("[AGENTCIRCUITDATA] failed to unpack appearance; {0}",e.Message);
385 }
386
348 ServiceURLs = new Dictionary<string, object>(); 387 ServiceURLs = new Dictionary<string, object>();
349 if (args.ContainsKey("service_urls") && args["service_urls"] != null && (args["service_urls"]).Type == OSDType.Array) 388 if (args.ContainsKey("service_urls") && args["service_urls"] != null && (args["service_urls"]).Type == OSDType.Array)
350 { 389 {
diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs
index 5da8ba1..e66a1e7 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -26,9 +26,12 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using System.Collections; 30using System.Collections;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using OpenMetaverse; 32using OpenMetaverse;
33using OpenMetaverse.StructuredData;
34using log4net;
32 35
33namespace OpenSim.Framework 36namespace OpenSim.Framework
34{ 37{
@@ -37,48 +40,26 @@ namespace OpenSim.Framework
37 /// </summary> 40 /// </summary>
38 public class AvatarAppearance 41 public class AvatarAppearance
39 { 42 {
40 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41
42 // these are guessed at by the list here -
43 // http://wiki.secondlife.com/wiki/Avatar_Appearance. We'll
44 // correct them over time for when were are wrong.
45 public readonly static int BODY = 0;
46 public readonly static int SKIN = 1;
47 public readonly static int HAIR = 2;
48 public readonly static int EYES = 3;
49 public readonly static int SHIRT = 4;
50 public readonly static int PANTS = 5;
51 public readonly static int SHOES = 6;
52 public readonly static int SOCKS = 7;
53 public readonly static int JACKET = 8;
54 public readonly static int GLOVES = 9;
55 public readonly static int UNDERSHIRT = 10;
56 public readonly static int UNDERPANTS = 11;
57 public readonly static int SKIRT = 12;
58
59 private readonly static int MAX_WEARABLES = 13;
60
61 private static UUID BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
62 private static UUID BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9");
63 private static UUID SKIN_ASSET = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb");
64 private static UUID SKIN_ITEM = new UUID("77c41e39-38f9-f75a-024e-585989bfabc9");
65 private static UUID SHIRT_ASSET = new UUID("00000000-38f9-1111-024e-222222111110");
66 private static UUID SHIRT_ITEM = new UUID("77c41e39-38f9-f75a-0000-585989bf0000");
67 private static UUID PANTS_ASSET = new UUID("00000000-38f9-1111-024e-222222111120");
68 private static UUID PANTS_ITEM = new UUID("77c41e39-38f9-f75a-0000-5859892f1111");
69 private static UUID HAIR_ASSET = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66");
70 private static UUID HAIR_ITEM = new UUID("d342e6c1-b9d2-11dc-95ff-0800200c9a66");
71 44
72 public readonly static int VISUALPARAM_COUNT = 218; 45 public readonly static int VISUALPARAM_COUNT = 218;
73 46
47 public readonly static int TEXTURE_COUNT = 21;
48
74 protected UUID m_owner; 49 protected UUID m_owner;
50 protected int m_serial = 1;
51 protected byte[] m_visualparams;
52 protected Primitive.TextureEntry m_texture;
53 protected AvatarWearable[] m_wearables;
54 protected Dictionary<int, List<AvatarAttachment>> m_attachments;
55 protected float m_avatarHeight = 0;
56 protected float m_hipOffset = 0;
75 57
76 public virtual UUID Owner 58 public virtual UUID Owner
77 { 59 {
78 get { return m_owner; } 60 get { return m_owner; }
79 set { m_owner = value; } 61 set { m_owner = value; }
80 } 62 }
81 protected int m_serial = 1;
82 63
83 public virtual int Serial 64 public virtual int Serial
84 { 65 {
@@ -86,15 +67,17 @@ namespace OpenSim.Framework
86 set { m_serial = value; } 67 set { m_serial = value; }
87 } 68 }
88 69
89 protected byte[] m_visualparams;
90
91 public virtual byte[] VisualParams 70 public virtual byte[] VisualParams
92 { 71 {
93 get { return m_visualparams; } 72 get { return m_visualparams; }
94 set { m_visualparams = value; } 73 set { m_visualparams = value; }
95 } 74 }
96 75
97 protected AvatarWearable[] m_wearables; 76 public virtual Primitive.TextureEntry Texture
77 {
78 get { return m_texture; }
79 set { m_texture = value; }
80 }
98 81
99 public virtual AvatarWearable[] Wearables 82 public virtual AvatarWearable[] Wearables
100 { 83 {
@@ -103,178 +86,135 @@ namespace OpenSim.Framework
103 } 86 }
104 87
105 public virtual UUID BodyItem { 88 public virtual UUID BodyItem {
106 get { return m_wearables[BODY].ItemID; } 89 get { return m_wearables[AvatarWearable.BODY].ItemID; }
107 set { m_wearables[BODY].ItemID = value; } 90 set { m_wearables[AvatarWearable.BODY].ItemID = value; }
108 } 91 }
109 92
110 public virtual UUID BodyAsset { 93 public virtual UUID BodyAsset {
111 get { return m_wearables[BODY].AssetID; } 94 get { return m_wearables[AvatarWearable.BODY].AssetID; }
112 set { m_wearables[BODY].AssetID = value; } 95 set { m_wearables[AvatarWearable.BODY].AssetID = value; }
113 } 96 }
114 97
115 public virtual UUID SkinItem { 98 public virtual UUID SkinItem {
116 get { return m_wearables[SKIN].ItemID; } 99 get { return m_wearables[AvatarWearable.SKIN].ItemID; }
117 set { m_wearables[SKIN].ItemID = value; } 100 set { m_wearables[AvatarWearable.SKIN].ItemID = value; }
118 } 101 }
119 102
120 public virtual UUID SkinAsset { 103 public virtual UUID SkinAsset {
121 get { return m_wearables[SKIN].AssetID; } 104 get { return m_wearables[AvatarWearable.SKIN].AssetID; }
122 set { m_wearables[SKIN].AssetID = value; } 105 set { m_wearables[AvatarWearable.SKIN].AssetID = value; }
123 } 106 }
124 107
125 public virtual UUID HairItem { 108 public virtual UUID HairItem {
126 get { return m_wearables[HAIR].ItemID; } 109 get { return m_wearables[AvatarWearable.HAIR].ItemID; }
127 set { m_wearables[HAIR].ItemID = value; } 110 set { m_wearables[AvatarWearable.HAIR].ItemID = value; }
128 } 111 }
129 112
130 public virtual UUID HairAsset { 113 public virtual UUID HairAsset {
131 get { return m_wearables[HAIR].AssetID; } 114 get { return m_wearables[AvatarWearable.HAIR].AssetID; }
132 set { m_wearables[HAIR].AssetID = value; } 115 set { m_wearables[AvatarWearable.HAIR].AssetID = value; }
133 } 116 }
134 117
135 public virtual UUID EyesItem { 118 public virtual UUID EyesItem {
136 get { return m_wearables[EYES].ItemID; } 119 get { return m_wearables[AvatarWearable.EYES].ItemID; }
137 set { m_wearables[EYES].ItemID = value; } 120 set { m_wearables[AvatarWearable.EYES].ItemID = value; }
138 } 121 }
139 122
140 public virtual UUID EyesAsset { 123 public virtual UUID EyesAsset {
141 get { return m_wearables[EYES].AssetID; } 124 get { return m_wearables[AvatarWearable.EYES].AssetID; }
142 set { m_wearables[EYES].AssetID = value; } 125 set { m_wearables[AvatarWearable.EYES].AssetID = value; }
143 } 126 }
144 127
145 public virtual UUID ShirtItem { 128 public virtual UUID ShirtItem {
146 get { return m_wearables[SHIRT].ItemID; } 129 get { return m_wearables[AvatarWearable.SHIRT].ItemID; }
147 set { m_wearables[SHIRT].ItemID = value; } 130 set { m_wearables[AvatarWearable.SHIRT].ItemID = value; }
148 } 131 }
149 132
150 public virtual UUID ShirtAsset { 133 public virtual UUID ShirtAsset {
151 get { return m_wearables[SHIRT].AssetID; } 134 get { return m_wearables[AvatarWearable.SHIRT].AssetID; }
152 set { m_wearables[SHIRT].AssetID = value; } 135 set { m_wearables[AvatarWearable.SHIRT].AssetID = value; }
153 } 136 }
154 137
155 public virtual UUID PantsItem { 138 public virtual UUID PantsItem {
156 get { return m_wearables[PANTS].ItemID; } 139 get { return m_wearables[AvatarWearable.PANTS].ItemID; }
157 set { m_wearables[PANTS].ItemID = value; } 140 set { m_wearables[AvatarWearable.PANTS].ItemID = value; }
158 } 141 }
159 142
160 public virtual UUID PantsAsset { 143 public virtual UUID PantsAsset {
161 get { return m_wearables[PANTS].AssetID; } 144 get { return m_wearables[AvatarWearable.PANTS].AssetID; }
162 set { m_wearables[PANTS].AssetID = value; } 145 set { m_wearables[AvatarWearable.PANTS].AssetID = value; }
163 } 146 }
164 147
165 public virtual UUID ShoesItem { 148 public virtual UUID ShoesItem {
166 get { return m_wearables[SHOES].ItemID; } 149 get { return m_wearables[AvatarWearable.SHOES].ItemID; }
167 set { m_wearables[SHOES].ItemID = value; } 150 set { m_wearables[AvatarWearable.SHOES].ItemID = value; }
168 } 151 }
169 152
170 public virtual UUID ShoesAsset { 153 public virtual UUID ShoesAsset {
171 get { return m_wearables[SHOES].AssetID; } 154 get { return m_wearables[AvatarWearable.SHOES].AssetID; }
172 set { m_wearables[SHOES].AssetID = value; } 155 set { m_wearables[AvatarWearable.SHOES].AssetID = value; }
173 } 156 }
174 157
175 public virtual UUID SocksItem { 158 public virtual UUID SocksItem {
176 get { return m_wearables[SOCKS].ItemID; } 159 get { return m_wearables[AvatarWearable.SOCKS].ItemID; }
177 set { m_wearables[SOCKS].ItemID = value; } 160 set { m_wearables[AvatarWearable.SOCKS].ItemID = value; }
178 } 161 }
179 162
180 public virtual UUID SocksAsset { 163 public virtual UUID SocksAsset {
181 get { return m_wearables[SOCKS].AssetID; } 164 get { return m_wearables[AvatarWearable.SOCKS].AssetID; }
182 set { m_wearables[SOCKS].AssetID = value; } 165 set { m_wearables[AvatarWearable.SOCKS].AssetID = value; }
183 } 166 }
184 167
185 public virtual UUID JacketItem { 168 public virtual UUID JacketItem {
186 get { return m_wearables[JACKET].ItemID; } 169 get { return m_wearables[AvatarWearable.JACKET].ItemID; }
187 set { m_wearables[JACKET].ItemID = value; } 170 set { m_wearables[AvatarWearable.JACKET].ItemID = value; }
188 } 171 }
189 172
190 public virtual UUID JacketAsset { 173 public virtual UUID JacketAsset {
191 get { return m_wearables[JACKET].AssetID; } 174 get { return m_wearables[AvatarWearable.JACKET].AssetID; }
192 set { m_wearables[JACKET].AssetID = value; } 175 set { m_wearables[AvatarWearable.JACKET].AssetID = value; }
193 } 176 }
194 177
195 public virtual UUID GlovesItem { 178 public virtual UUID GlovesItem {
196 get { return m_wearables[GLOVES].ItemID; } 179 get { return m_wearables[AvatarWearable.GLOVES].ItemID; }
197 set { m_wearables[GLOVES].ItemID = value; } 180 set { m_wearables[AvatarWearable.GLOVES].ItemID = value; }
198 } 181 }
199 182
200 public virtual UUID GlovesAsset { 183 public virtual UUID GlovesAsset {
201 get { return m_wearables[GLOVES].AssetID; } 184 get { return m_wearables[AvatarWearable.GLOVES].AssetID; }
202 set { m_wearables[GLOVES].AssetID = value; } 185 set { m_wearables[AvatarWearable.GLOVES].AssetID = value; }
203 } 186 }
204 187
205 public virtual UUID UnderShirtItem { 188 public virtual UUID UnderShirtItem {
206 get { return m_wearables[UNDERSHIRT].ItemID; } 189 get { return m_wearables[AvatarWearable.UNDERSHIRT].ItemID; }
207 set { m_wearables[UNDERSHIRT].ItemID = value; } 190 set { m_wearables[AvatarWearable.UNDERSHIRT].ItemID = value; }
208 } 191 }
209 192
210 public virtual UUID UnderShirtAsset { 193 public virtual UUID UnderShirtAsset {
211 get { return m_wearables[UNDERSHIRT].AssetID; } 194 get { return m_wearables[AvatarWearable.UNDERSHIRT].AssetID; }
212 set { m_wearables[UNDERSHIRT].AssetID = value; } 195 set { m_wearables[AvatarWearable.UNDERSHIRT].AssetID = value; }
213 } 196 }
214 197
215 public virtual UUID UnderPantsItem { 198 public virtual UUID UnderPantsItem {
216 get { return m_wearables[UNDERPANTS].ItemID; } 199 get { return m_wearables[AvatarWearable.UNDERPANTS].ItemID; }
217 set { m_wearables[UNDERPANTS].ItemID = value; } 200 set { m_wearables[AvatarWearable.UNDERPANTS].ItemID = value; }
218 } 201 }
219 202
220 public virtual UUID UnderPantsAsset { 203 public virtual UUID UnderPantsAsset {
221 get { return m_wearables[UNDERPANTS].AssetID; } 204 get { return m_wearables[AvatarWearable.UNDERPANTS].AssetID; }
222 set { m_wearables[UNDERPANTS].AssetID = value; } 205 set { m_wearables[AvatarWearable.UNDERPANTS].AssetID = value; }
223 } 206 }
224 207
225 public virtual UUID SkirtItem { 208 public virtual UUID SkirtItem {
226 get { return m_wearables[SKIRT].ItemID; } 209 get { return m_wearables[AvatarWearable.SKIRT].ItemID; }
227 set { m_wearables[SKIRT].ItemID = value; } 210 set { m_wearables[AvatarWearable.SKIRT].ItemID = value; }
228 } 211 }
229 212
230 public virtual UUID SkirtAsset { 213 public virtual UUID SkirtAsset {
231 get { return m_wearables[SKIRT].AssetID; } 214 get { return m_wearables[AvatarWearable.SKIRT].AssetID; }
232 set { m_wearables[SKIRT].AssetID = value; } 215 set { m_wearables[AvatarWearable.SKIRT].AssetID = value; }
233 }
234
235 public virtual void SetDefaultWearables()
236 {
237 m_wearables[BODY].AssetID = BODY_ASSET;
238 m_wearables[BODY].ItemID = BODY_ITEM;
239 m_wearables[SKIN].AssetID = SKIN_ASSET;
240 m_wearables[SKIN].ItemID = SKIN_ITEM;
241 m_wearables[HAIR].AssetID = HAIR_ASSET;
242 m_wearables[HAIR].ItemID = HAIR_ITEM;
243 m_wearables[SHIRT].AssetID = SHIRT_ASSET;
244 m_wearables[SHIRT].ItemID = SHIRT_ITEM;
245 m_wearables[PANTS].AssetID = PANTS_ASSET;
246 m_wearables[PANTS].ItemID = PANTS_ITEM;
247 }
248
249 public virtual void ClearWearables()
250 {
251 for (int i = 0; i < 13; i++)
252 {
253 m_wearables[i].AssetID = UUID.Zero;
254 m_wearables[i].ItemID = UUID.Zero;
255 }
256 }
257
258 public virtual void SetDefaultParams(byte[] vparams)
259 {
260 // TODO: Figure out better values then 'fat scientist 150' or 'alien 0'
261 for (int i = 0; i < VISUALPARAM_COUNT; i++)
262 {
263 vparams[i] = 150;
264 }
265 }
266
267 protected Primitive.TextureEntry m_texture;
268
269 public virtual Primitive.TextureEntry Texture
270 {
271 get { return m_texture; }
272 set { m_texture = value; }
273 } 216 }
274 217
275 protected float m_avatarHeight = 0;
276 protected float m_hipOffset = 0;
277
278 public virtual float AvatarHeight 218 public virtual float AvatarHeight
279 { 219 {
280 get { return m_avatarHeight; } 220 get { return m_avatarHeight; }
@@ -286,366 +226,301 @@ namespace OpenSim.Framework
286 get { return m_hipOffset; } 226 get { return m_hipOffset; }
287 } 227 }
288 228
289 //Builds the VisualParam Enum using LIBOMV's Visual Param NameValues
290 /*
291 public void BuildVisualParamEnum()
292 {
293 Dictionary<string, int> IndexedParams = new Dictionary<string, int>();
294 int vpIndex = 0;
295 IndexedParams = new Dictionary<string, int>();
296
297 System.Text.StringBuilder sb = new System.Text.StringBuilder();
298
299 sb.Append("public enum VPElement: int\n");
300 sb.Append("{\n");
301 foreach (KeyValuePair<int, VisualParam> kvp in OpenMetaverse.VisualParams.Params)
302 {
303 VisualParam vp = kvp.Value;
304
305 // Only Group-0 parameters are sent in AgentSetAppearance packets
306 if (kvp.Value.Group == 0)
307 {
308
309 if (!IndexedParams.ContainsKey(vp.Name))
310 {
311
312 if (vp.Label.Length > 0 || vp.LabelMin.Length > 0 || vp.LabelMax.Length > 0)
313 {
314
315 sb.Append("/// <summary>\n");
316 if (vp.LabelMin.Length > 0 && vp.LabelMax.Length > 0)
317 sb.Append(string.Format("/// {0} - {1} 0--+255 {2}\n", vp.Label, vp.LabelMin,
318 vp.LabelMax));
319
320 else
321 sb.Append(string.Format("/// {0}\n", vp.Label));
322
323 sb.Append("/// </summary>\n");
324 }
325 sb.Append(string.Format(" {0}_{1} = {2}", vp.Wearable.ToUpper(), vp.Name.ToUpper().Replace(" ", "_"),vpIndex));
326
327 IndexedParams.Add(vp.Name, vpIndex++);
328 }
329 else
330 {
331 sb.Append(string.Format(" {0}_{1}_{2} = {2}", vp.Wearable.ToUpper(), vp.Name.ToUpper().Replace(" ", "_"), vpIndex));
332 vpIndex++;
333 //int i = 0;
334 }
335 }
336 if (vpIndex < 217)
337 sb.Append(",\n");
338 else
339 sb.Append("\n");
340
341 }
342 sb.Append("}\n");
343
344 }
345 */
346
347 public AvatarAppearance() : this(UUID.Zero) {} 229 public AvatarAppearance() : this(UUID.Zero) {}
348 230
349 public AvatarAppearance(UUID owner) 231 public AvatarAppearance(UUID owner)
350 { 232 {
351 m_wearables = new AvatarWearable[MAX_WEARABLES]; 233// DEBUG ON
352 for (int i = 0; i < MAX_WEARABLES; i++) 234 m_log.WarnFormat("[AVATAR APPEARANCE] create empty appearance for {0}",owner);
353 { 235// DEBUG OFF
354 // this makes them all null 236 m_serial = 1;
355 m_wearables[i] = new AvatarWearable();
356 }
357 m_serial = 0;
358 m_owner = owner; 237 m_owner = owner;
359 //BuildVisualParamEnum() 238
360 m_visualparams = new byte[VISUALPARAM_COUNT];
361 // This sets Visual Params with *less* weirder values then default. Instead of a ugly alien, it looks like a fat scientist
362 SetDefaultParams(m_visualparams);
363 SetDefaultWearables(); 239 SetDefaultWearables();
364 m_texture = GetDefaultTexture(); 240 SetDefaultTexture();
241 SetDefaultParams();
242 SetHeight();
243
244 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
365 } 245 }
366 246
367 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, byte[] visualParams) 247 public AvatarAppearance(UUID avatarID, OSDMap map)
368 { 248 {
249// DEBUG ON
250 m_log.WarnFormat("[AVATAR APPEARANCE] create appearance for {0} from OSDMap",avatarID);
251// DEBUG OFF
369 m_owner = avatarID; 252 m_owner = avatarID;
370 m_serial = 1; 253 Unpack(map);
371 m_wearables = wearables; 254 SetHeight();
372 m_visualparams = visualParams;
373 m_texture = GetDefaultTexture();
374 } 255 }
375 256
376 /// <summary> 257 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
377 /// Set up appearance textures and avatar parameters, including a height calculation
378 /// </summary>
379 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
380 { 258 {
259// DEBUG ON
260 m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance for {0}",avatarID);
261// DEBUG OFF
262 m_serial = 1;
263 m_owner = avatarID;
264
265 if (wearables != null)
266 m_wearables = wearables;
267 else
268 SetDefaultWearables();
269
381 if (textureEntry != null) 270 if (textureEntry != null)
382 m_texture = textureEntry; 271 m_texture = textureEntry;
272 else
273 SetDefaultTexture();
274
383 if (visualParams != null) 275 if (visualParams != null)
384 m_visualparams = visualParams; 276 m_visualparams = visualParams;
277 else
278 SetDefaultParams();
385 279
386 m_avatarHeight = 1.23077f // Shortest possible avatar height 280 SetHeight();
387 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
388 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size
389 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
390 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
391 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
392 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length
393 m_hipOffset = (((1.23077f // Half of avatar
394 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
395 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
396 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
397 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
398 ) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f;
399
400
401
402 //System.Console.WriteLine(">>>>>>> [APPEARANCE]: Height {0} Hip offset {1}" + m_avatarHeight + " " + m_hipOffset);
403 //m_log.Debug("------------- Set Appearance Texture ---------------");
404 //Primitive.TextureEntryFace[] faces = Texture.FaceTextures;
405 //foreach (Primitive.TextureEntryFace face in faces)
406 //{
407 // if (face != null)
408 // m_log.Debug(" ++ " + face.TextureID);
409 // else
410 // m_log.Debug(" ++ NULL ");
411 //}
412 //m_log.Debug("----------------------------");
413
414 }
415
416 public virtual void SetWearable(int wearableId, AvatarWearable wearable)
417 {
418 m_wearables[wearableId] = wearable;
419 }
420 281
421 public static Primitive.TextureEntry GetDefaultTexture() 282 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
422 {
423 Primitive.TextureEntry textu = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
424 textu.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012");
425 textu.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID;
426 textu.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID;
427 textu.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77");
428 textu.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B");
429 textu.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010");
430 textu.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011");
431 return textu;
432 } 283 }
433 284
434 public static byte[] GetDefaultVisualParams() 285 public AvatarAppearance(AvatarAppearance appearance)
435 { 286 {
436 byte[] visualParams; 287// DEBUG ON
437 visualParams = new byte[VISUALPARAM_COUNT]; 288 m_log.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance");
438 for (int i = 0; i < VISUALPARAM_COUNT; i++) 289// DEBUG OFF
290 if (appearance == null)
439 { 291 {
440 visualParams[i] = 100; 292 m_serial = 1;
441 } 293 m_owner = UUID.Zero;
442 return visualParams;
443 }
444 294
445 public override String ToString() 295 SetDefaultWearables();
446 { 296 SetDefaultTexture();
447 String s = "[Wearables] =>"; 297 SetDefaultParams();
448 s += " Body Item: " + BodyItem.ToString() + ";"; 298 SetHeight();
449 s += " Skin Item: " + SkinItem.ToString() + ";";
450 s += " Shirt Item: " + ShirtItem.ToString() + ";";
451 s += " Pants Item: " + PantsItem.ToString() + ";";
452 return s;
453 }
454 299
455 // this is used for OGS1 300 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
456 public virtual Hashtable ToHashTable()
457 {
458 Hashtable h = new Hashtable();
459 h["owner"] = Owner.ToString();
460 h["serial"] = Serial.ToString();
461 h["visual_params"] = VisualParams;
462 h["texture"] = Texture.GetBytes();
463 h["avatar_height"] = AvatarHeight.ToString();
464 h["body_item"] = BodyItem.ToString();
465 h["body_asset"] = BodyAsset.ToString();
466 h["skin_item"] = SkinItem.ToString();
467 h["skin_asset"] = SkinAsset.ToString();
468 h["hair_item"] = HairItem.ToString();
469 h["hair_asset"] = HairAsset.ToString();
470 h["eyes_item"] = EyesItem.ToString();
471 h["eyes_asset"] = EyesAsset.ToString();
472 h["shirt_item"] = ShirtItem.ToString();
473 h["shirt_asset"] = ShirtAsset.ToString();
474 h["pants_item"] = PantsItem.ToString();
475 h["pants_asset"] = PantsAsset.ToString();
476 h["shoes_item"] = ShoesItem.ToString();
477 h["shoes_asset"] = ShoesAsset.ToString();
478 h["socks_item"] = SocksItem.ToString();
479 h["socks_asset"] = SocksAsset.ToString();
480 h["jacket_item"] = JacketItem.ToString();
481 h["jacket_asset"] = JacketAsset.ToString();
482 h["gloves_item"] = GlovesItem.ToString();
483 h["gloves_asset"] = GlovesAsset.ToString();
484 h["undershirt_item"] = UnderShirtItem.ToString();
485 h["undershirt_asset"] = UnderShirtAsset.ToString();
486 h["underpants_item"] = UnderPantsItem.ToString();
487 h["underpants_asset"] = UnderPantsAsset.ToString();
488 h["skirt_item"] = SkirtItem.ToString();
489 h["skirt_asset"] = SkirtAsset.ToString();
490
491 string attachments = GetAttachmentsString();
492 if (attachments != String.Empty)
493 h["attachments"] = attachments;
494
495 return h;
496 }
497
498 public AvatarAppearance(Hashtable h)
499 {
500 Owner = new UUID((string)h["owner"]);
501 Serial = Convert.ToInt32((string)h["serial"]);
502 VisualParams = (byte[])h["visual_params"];
503 301
504 if (h.Contains("texture")) 302 return;
505 {
506 byte[] te = h["texture"] as byte[];
507 if (te != null && te.Length > 0)
508 Texture = new Primitive.TextureEntry(te, 0, te.Length);
509 }
510 else
511 {
512 // We shouldn't be receiving appearance hashtables without a TextureEntry,
513 // but in case we do this will prevent a failure when saving to the database
514 Texture = GetDefaultTexture();
515 } 303 }
516
517 304
518 AvatarHeight = (float)Convert.ToDouble((string)h["avatar_height"]); 305 m_serial = appearance.Serial;
306 m_owner = appearance.Owner;
519 307
520 m_wearables = new AvatarWearable[MAX_WEARABLES]; 308 m_wearables = null;
521 for (int i = 0; i < MAX_WEARABLES; i++) 309 if (appearance.Wearables != null)
522 { 310 {
523 // this makes them all null 311 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; //should be 13 of these
524 m_wearables[i] = new AvatarWearable(); 312 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
313 SetWearable(i,appearance.Wearables[i]);
525 } 314 }
526 315
527 BodyItem = new UUID((string)h["body_item"]); 316 m_texture = null;
528 BodyAsset = new UUID((string)h["body_asset"]); 317 if (appearance.Texture != null)
529 SkinItem = new UUID((string)h["skin_item"]);
530 SkinAsset = new UUID((string)h["skin_asset"]);
531 HairItem = new UUID((string)h["hair_item"]);
532 HairAsset = new UUID((string)h["hair_asset"]);
533 EyesItem = new UUID((string)h["eyes_item"]);
534 EyesAsset = new UUID((string)h["eyes_asset"]);
535 ShirtItem = new UUID((string)h["shirt_item"]);
536 ShirtAsset = new UUID((string)h["shirt_asset"]);
537 PantsItem = new UUID((string)h["pants_item"]);
538 PantsAsset = new UUID((string)h["pants_asset"]);
539 ShoesItem = new UUID((string)h["shoes_item"]);
540 ShoesAsset = new UUID((string)h["shoes_asset"]);
541 SocksItem = new UUID((string)h["socks_item"]);
542 SocksAsset = new UUID((string)h["socks_asset"]);
543 JacketItem = new UUID((string)h["jacket_item"]);
544 JacketAsset = new UUID((string)h["jacket_asset"]);
545 GlovesItem = new UUID((string)h["gloves_item"]);
546 GlovesAsset = new UUID((string)h["gloves_asset"]);
547 UnderShirtItem = new UUID((string)h["undershirt_item"]);
548 UnderShirtAsset = new UUID((string)h["undershirt_asset"]);
549 UnderPantsItem = new UUID((string)h["underpants_item"]);
550 UnderPantsAsset = new UUID((string)h["underpants_asset"]);
551 SkirtItem = new UUID((string)h["skirt_item"]);
552 SkirtAsset = new UUID((string)h["skirt_asset"]);
553
554 if (h.ContainsKey("attachments"))
555 { 318 {
556 SetAttachmentsString(h["attachments"].ToString()); 319 byte[] tbytes = appearance.Texture.GetBytes();
320 m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
557 } 321 }
322
323 m_visualparams = null;
324 if (appearance.VisualParams != null)
325 m_visualparams = (byte[])appearance.VisualParams.Clone();
326
327 // Copy the attachment, force append mode since that ensures consistency
328 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
329 foreach (AvatarAttachment attachment in appearance.GetAttachments())
330 AppendAttachment(new AvatarAttachment(attachment));
331 }
332
333 protected virtual void SetDefaultWearables()
334 {
335 m_wearables = AvatarWearable.DefaultWearables;
558 } 336 }
559 337
560 private Dictionary<int, UUID[]> m_attachments = new Dictionary<int, UUID[]>(); 338 protected virtual void SetDefaultParams()
561
562 public void SetAttachments(AttachmentData[] data)
563 { 339 {
564 foreach (AttachmentData a in data) 340 m_visualparams = new byte[VISUALPARAM_COUNT];
341 for (int i = 0; i < VISUALPARAM_COUNT; i++)
565 { 342 {
566 m_attachments[a.AttachPoint] = new UUID[2]; 343 m_visualparams[i] = 150;
567 m_attachments[a.AttachPoint][0] = a.ItemID;
568 m_attachments[a.AttachPoint][1] = a.AssetID;
569 } 344 }
570 } 345 }
571 346
572 public void SetAttachments(Hashtable data) 347 protected virtual void SetDefaultTexture()
573 { 348 {
574 m_attachments.Clear(); 349 m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
575 350 // The initialization of these seems to force a rebake regardless of whether it is needed
576 if (data == null) 351 // m_textures.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012");
577 return; 352 // m_textures.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID;
353 // m_textures.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID;
354 // m_textures.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77");
355 // m_textures.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B");
356 // m_textures.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010");
357 // m_textures.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011");
358 }
578 359
579 foreach (DictionaryEntry e in data) 360 /// <summary>
361 /// Set up appearance textures.
362 /// Returns boolean that indicates whether the new entries actually change the
363 /// existing values.
364 /// </summary>
365 public virtual bool SetTextureEntries(Primitive.TextureEntry textureEntry)
366 {
367 if (textureEntry == null)
368 return false;
369
370 // There are much simpler versions of this copy that could be
371 // made. We determine if any of the textures actually
372 // changed to know if the appearance should be saved later
373 bool changed = false;
374 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
580 { 375 {
581 int attachpoint = Convert.ToInt32(e.Key); 376 Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i];
582 377 Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i];
583 if (m_attachments.ContainsKey(attachpoint)) 378
584 continue; 379 if (newface == null)
380 {
381 if (oldface == null) continue;
382 }
383 else
384 {
385 if (oldface != null && oldface.TextureID == newface.TextureID) continue;
386 }
585 387
586 UUID item; 388 m_texture.FaceTextures[i] = (newface != null) ? new Primitive.TextureEntryFace(newface) : null;
587 UUID asset; 389 changed = true;
390// DEBUG ON
391 if (newface != null)
392 m_log.WarnFormat("[AVATAR APPEARANCE] index {0}, new texture id {1}",i,newface.TextureID);
393// DEBUG OFF
394 }
588 395
589 Hashtable uuids = (Hashtable) e.Value; 396 return changed;
590 UUID.TryParse(uuids["item"].ToString(), out item); 397 }
591 UUID.TryParse(uuids["asset"].ToString(), out asset); 398
399 /// <summary>
400 /// Set up visual parameters for the avatar and refresh the avatar height
401 /// Returns boolean that indicates whether the new entries actually change the
402 /// existing values.
403 /// </summary>
404 public virtual bool SetVisualParams(byte[] visualParams)
405 {
406 if (visualParams == null)
407 return false;
408
409 // There are much simpler versions of this copy that could be
410 // made. We determine if any of the visual parameters actually
411 // changed to know if the appearance should be saved later
412 bool changed = false;
413 for (int i = 0; i < AvatarAppearance.VISUALPARAM_COUNT; i++)
414 {
415 if (visualParams[i] != m_visualparams[i])
416 {
417// DEBUG ON
418 m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
419 i,m_visualparams[i],visualParams[i]);
420// DEBUG OFF
421 m_visualparams[i] = visualParams[i];
422 changed = true;
423 }
424 }
592 425
593 UUID[] attachment = new UUID[2]; 426 // Reset the height if the visual parameters actually changed
594 attachment[0] = item; 427 if (changed)
595 attachment[1] = asset; 428 SetHeight();
596 429
597 m_attachments[attachpoint] = attachment; 430 return changed;
598 }
599 } 431 }
600 432
601 public Dictionary<int, UUID[]> GetAttachmentDictionary() 433 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
602 { 434 {
603 return m_attachments; 435 SetTextureEntries(textureEntry);
436 SetVisualParams(visualParams);
604 } 437 }
438
439 public virtual void SetHeight()
440 {
441 m_avatarHeight = 1.23077f // Shortest possible avatar height
442 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
443 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size
444 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
445 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
446 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
447 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length
605 448
606 public Hashtable GetAttachments() 449 m_hipOffset = (((1.23077f // Half of avatar
450 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
451 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
452 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
453 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
454 ) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f;
455 }
456
457 public virtual void SetWearable(int wearableId, AvatarWearable wearable)
607 { 458 {
608 if (m_attachments.Count == 0) 459// DEBUG ON
609 return null; 460// m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID);
461// DEBUG OFF
462 m_wearables[wearableId] = new AvatarWearable(wearable.ItemID,wearable.AssetID);
463 }
610 464
611 Hashtable ret = new Hashtable();
612 465
613 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 466// DEBUG ON
614 { 467 public override String ToString()
615 int attachpoint = kvp.Key; 468 {
616 UUID[] uuids = kvp.Value; 469 String s = "";
617 470
618 Hashtable data = new Hashtable(); 471 s += String.Format("Serial: {0}\n",m_serial);
619 data["item"] = uuids[0].ToString(); 472
620 data["asset"] = uuids[1].ToString(); 473 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
474 if (m_texture.FaceTextures[i] != null)
475 s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID);
621 476
622 ret[attachpoint] = data; 477 foreach (AvatarWearable awear in m_wearables)
623 } 478 s += String.Format("Wearable: item={0}, asset={1}\n",awear.ItemID,awear.AssetID);
624 479
625 return ret; 480 s += "Visual Params: ";
481 for (uint j = 0; j < AvatarAppearance.VISUALPARAM_COUNT; j++)
482 s += String.Format("{0},",m_visualparams[j]);
483 s += "\n";
484
485 return s;
626 } 486 }
487// DEBUG OFF
627 488
628 public List<int> GetAttachedPoints() 489 /// <summary>
490 /// Get a list of the attachments, note that there may be
491 /// duplicate attachpoints
492 /// </summary>
493 public List<AvatarAttachment> GetAttachments()
629 { 494 {
630 return new List<int>(m_attachments.Keys); 495 List<AvatarAttachment> alist = new List<AvatarAttachment>();
496 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
497 {
498 foreach (AvatarAttachment attach in kvp.Value)
499 alist.Add(new AvatarAttachment(attach));
500 }
501
502 return alist;
631 } 503 }
632 504
633 public UUID GetAttachedItem(int attachpoint) 505 internal void AppendAttachment(AvatarAttachment attach)
634 { 506 {
635 if (!m_attachments.ContainsKey(attachpoint)) 507 if (! m_attachments.ContainsKey(attach.AttachPoint))
636 return UUID.Zero; 508 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
637 509 m_attachments[attach.AttachPoint].Add(attach);
638 return m_attachments[attachpoint][0];
639 } 510 }
640 511
641 public UUID GetAttachedAsset(int attachpoint) 512 internal void ReplaceAttachment(AvatarAttachment attach)
642 { 513 {
643 if (!m_attachments.ContainsKey(attachpoint)) 514 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
644 return UUID.Zero; 515 m_attachments[attach.AttachPoint].Add(attach);
645
646 return m_attachments[attachpoint][1];
647 } 516 }
648 517
518 /// <summary>
519 /// Add an attachment, if the attachpoint has the
520 /// 0x80 bit set then we assume this is an append
521 /// operation otherwise we replace whatever is
522 /// currently attached at the attachpoint
523 /// </summary>
649 public void SetAttachment(int attachpoint, UUID item, UUID asset) 524 public void SetAttachment(int attachpoint, UUID item, UUID asset)
650 { 525 {
651 if (attachpoint == 0) 526 if (attachpoint == 0)
@@ -658,31 +533,47 @@ namespace OpenSim.Framework
658 return; 533 return;
659 } 534 }
660 535
661 if (!m_attachments.ContainsKey(attachpoint)) 536 // check if this is an append or a replace, 0x80 marks it as an append
662 m_attachments[attachpoint] = new UUID[2]; 537 if ((attachpoint & 0x80) > 0)
663 538 {
664 m_attachments[attachpoint][0] = item; 539 // strip the append bit
665 m_attachments[attachpoint][1] = asset; 540 int point = attachpoint & 0x7F;
541 AppendAttachment(new AvatarAttachment(point, item, asset));
542 }
543 else
544 {
545 ReplaceAttachment(new AvatarAttachment(attachpoint,item,asset));
546 }
666 } 547 }
667 548
668 public int GetAttachpoint(UUID itemID) 549 public int GetAttachpoint(UUID itemID)
669 { 550 {
670 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 551 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
671 { 552 {
672 if (kvp.Value[0] == itemID) 553 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
673 { 554 if (index >= 0)
674 return kvp.Key; 555 return kvp.Key;
675 }
676 } 556 }
557
677 return 0; 558 return 0;
678 } 559 }
679 560
680 public void DetachAttachment(UUID itemID) 561 public void DetachAttachment(UUID itemID)
681 { 562 {
682 int attachpoint = GetAttachpoint(itemID); 563 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
564 {
565 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
566 if (index >= 0)
567 {
568 // Remove it from the list of attachments at that attach point
569 m_attachments[kvp.Key].RemoveAt(index);
683 570
684 if (attachpoint > 0) 571 // And remove the list if there are no more attachments here
685 m_attachments.Remove(attachpoint); 572 if (m_attachments[kvp.Key].Count == 0)
573 m_attachments.Remove(kvp.Key);
574 return;
575 }
576 }
686 } 577 }
687 578
688 public void ClearAttachments() 579 public void ClearAttachments()
@@ -690,42 +581,123 @@ namespace OpenSim.Framework
690 m_attachments.Clear(); 581 m_attachments.Clear();
691 } 582 }
692 583
693 string GetAttachmentsString() 584 /// <summary>
585 /// Create an OSDMap from the appearance data
586 /// </summary>
587 public OSDMap Pack()
694 { 588 {
695 List<string> strings = new List<string>(); 589 OSDMap data = new OSDMap();
696 590
697 foreach (KeyValuePair<int, UUID[]> e in m_attachments) 591 data["serial"] = OSD.FromInteger(m_serial);
592 data["height"] = OSD.FromReal(m_avatarHeight);
593 data["hipoffset"] = OSD.FromReal(m_hipOffset);
594
595 // Wearables
596 OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
597 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
598 wears.Add(m_wearables[i].Pack());
599 data["wearables"] = wears;
600
601 // Avatar Textures
602 OSDArray textures = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
603 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
698 { 604 {
699 strings.Add(e.Key.ToString()); 605 if (m_texture.FaceTextures[i] != null)
700 strings.Add(e.Value[0].ToString()); 606 textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID));
701 strings.Add(e.Value[1].ToString()); 607 else
608 textures.Add(OSD.FromUUID(UUID.Zero));
702 } 609 }
610 data["textures"] = textures;
703 611
704 return String.Join(",", strings.ToArray()); 612 // Visual Parameters
613 OSDBinary visualparams = new OSDBinary(m_visualparams);
614 data["visualparams"] = visualparams;
615
616 // Attachments
617 OSDArray attachs = new OSDArray(m_attachments.Count);
618 foreach (AvatarAttachment attach in GetAttachments())
619 attachs.Add(attach.Pack());
620 data["attachments"] = attachs;
621
622 return data;
705 } 623 }
706 624
707 void SetAttachmentsString(string data) 625 /// <summary>
626 /// Unpack and OSDMap and initialize the appearance
627 /// from it
628 /// </summary>
629 public void Unpack(OSDMap data)
708 { 630 {
709 string[] strings = data.Split(new char[] {','}); 631 if ((data != null) && (data["serial"] != null))
710 int i = 0; 632 m_serial = data["serial"].AsInteger();
633 if ((data != null) && (data["height"] != null))
634 m_avatarHeight = (float)data["height"].AsReal();
635 if ((data != null) && (data["hipoffset"] != null))
636 m_hipOffset = (float)data["hipoffset"].AsReal();
637
638 try
639 {
640 // Wearables
641 SetDefaultWearables();
642 if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
643 {
644 OSDArray wears = (OSDArray)(data["wearables"]);
645 for (int i = 0; i < wears.Count; i++)
646 m_wearables[i] = new AvatarWearable((OSDMap)wears[i]);
647 }
648 else
649 {
650 m_log.Warn("[AVATARAPPEARANCE] failed to unpack wearables");
651 }
711 652
712 m_attachments.Clear(); 653 // Avatar Textures
654 SetDefaultTexture();
655 if ((data != null) && (data["textures"] != null) && (data["textures"]).Type == OSDType.Array)
656 {
657 OSDArray textures = (OSDArray)(data["textures"]);
658 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++)
659 {
660 if (textures[i] != null)
661 {
662 UUID textureID = textures[i].AsUUID();
663 if (textureID != UUID.Zero)
664 m_texture.CreateFace((uint)i).TextureID = textureID;
665 }
666 }
667 }
668 else
669 {
670 m_log.Warn("[AVATARAPPEARANCE] failed to unpack textures");
671 }
713 672
714 while (strings.Length - i > 2) 673 // Visual Parameters
715 { 674 SetDefaultParams();
716 int attachpoint = Int32.Parse(strings[i]); 675 if ((data != null) && (data["visualparams"] != null))
717 UUID item = new UUID(strings[i+1]); 676 {
718 UUID asset = new UUID(strings[i+2]); 677 if ((data["visualparams"].Type == OSDType.Binary) || (data["visualparams"].Type == OSDType.Array))
719 i += 3; 678 m_visualparams = data["visualparams"].AsBinary();
679 }
680 else
681 {
682 m_log.Warn("[AVATARAPPEARANCE] failed to unpack visual parameters");
683 }
720 684
721 if (!m_attachments.ContainsKey(attachpoint)) 685 // Attachments
686 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
687 if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array)
722 { 688 {
723 m_attachments[attachpoint] = new UUID[2]; 689 OSDArray attachs = (OSDArray)(data["attachments"]);
724 m_attachments[attachpoint][0] = item; 690 for (int i = 0; i < attachs.Count; i++)
725 m_attachments[attachpoint][1] = asset; 691 AppendAttachment(new AvatarAttachment((OSDMap)attachs[i]));
726 } 692 }
727 } 693 }
694 catch (Exception e)
695 {
696 m_log.ErrorFormat("[AVATARAPPEARANCE] unpack failed badly: {0}",e.Message);
697 }
728 } 698 }
699
700
729 /// <summary> 701 /// <summary>
730 /// Viewer Params Array Element for AgentSetAppearance 702 /// Viewer Params Array Element for AgentSetAppearance
731 /// Generated from LibOMV's Visual Params list 703 /// Generated from LibOMV's Visual Params list
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs b/OpenSim/Framework/AvatarAttachment.cs
index c967f30..c68d78d 100644
--- a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs
+++ b/OpenSim/Framework/AvatarAttachment.cs
@@ -25,14 +25,54 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
28using OpenMetaverse; 29using OpenMetaverse;
29using OpenSim.Framework; 30using OpenMetaverse.StructuredData;
30 31
31namespace OpenSim.Region.Framework.Interfaces 32namespace OpenSim.Framework
32{ 33{
33 public interface IAvatarFactory 34 public class AvatarAttachment
34 { 35 {
35 bool TryGetAvatarAppearance(UUID avatarId, out AvatarAppearance appearance); 36 public int AttachPoint;
36 void UpdateDatabase(UUID userID, AvatarAppearance avatAppearance); 37 public UUID ItemID;
38 public UUID AssetID;
39
40 public AvatarAttachment(AvatarAttachment attach)
41 {
42 AttachPoint = attach.AttachPoint;
43 ItemID = attach.ItemID;
44 AssetID = attach.AssetID;
45 }
46
47 public AvatarAttachment(int point, UUID item, UUID asset)
48 {
49 AttachPoint = point;
50 ItemID = item;
51 AssetID = asset;
52 }
53
54 public AvatarAttachment(OSDMap args)
55 {
56 Unpack(args);
57 }
58
59 public OSDMap Pack()
60 {
61 OSDMap attachdata = new OSDMap();
62 attachdata["point"] = OSD.FromInteger(AttachPoint);
63 attachdata["item"] = OSD.FromUUID(ItemID);
64 attachdata["asset"] = OSD.FromUUID(AssetID);
65
66 return attachdata;
67 }
68
69
70 public void Unpack(OSDMap args)
71 {
72 if (args["point"] != null)
73 AttachPoint = args["point"].AsInteger();
74 ItemID = (args["item"] != null) ? args["item"].AsUUID() : UUID.Zero;
75 AssetID = (args["asset"] != null) ? args["asset"].AsUUID() : UUID.Zero;
76 }
37 } 77 }
38} 78}
diff --git a/OpenSim/Framework/AvatarWearable.cs b/OpenSim/Framework/AvatarWearable.cs
index 30c5172..87098bf 100644
--- a/OpenSim/Framework/AvatarWearable.cs
+++ b/OpenSim/Framework/AvatarWearable.cs
@@ -26,14 +26,32 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Runtime.Serialization;
30using System.Security.Permissions;
31using OpenMetaverse; 29using OpenMetaverse;
30using OpenMetaverse.StructuredData;
32 31
33namespace OpenSim.Framework 32namespace OpenSim.Framework
34{ 33{
35 public class AvatarWearable 34 public class AvatarWearable
36 { 35 {
36 // these are guessed at by the list here -
37 // http://wiki.secondlife.com/wiki/Avatar_Appearance. We'll
38 // correct them over time for when were are wrong.
39 public static readonly int BODY = 0;
40 public static readonly int SKIN = 1;
41 public static readonly int HAIR = 2;
42 public static readonly int EYES = 3;
43 public static readonly int SHIRT = 4;
44 public static readonly int PANTS = 5;
45 public static readonly int SHOES = 6;
46 public static readonly int SOCKS = 7;
47 public static readonly int JACKET = 8;
48 public static readonly int GLOVES = 9;
49 public static readonly int UNDERSHIRT = 10;
50 public static readonly int UNDERPANTS = 11;
51 public static readonly int SKIRT = 12;
52
53 public static readonly int MAX_WEARABLES = 13;
54
37 public static readonly UUID DEFAULT_BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9"); 55 public static readonly UUID DEFAULT_BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9");
38 public static readonly UUID DEFAULT_BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73"); 56 public static readonly UUID DEFAULT_BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73");
39 57
@@ -62,12 +80,32 @@ namespace OpenSim.Framework
62 ItemID = itemId; 80 ItemID = itemId;
63 } 81 }
64 82
83 public AvatarWearable(OSDMap args)
84 {
85 Unpack(args);
86 }
87
88 public OSDMap Pack()
89 {
90 OSDMap weardata = new OSDMap();
91 weardata["item"] = OSD.FromUUID(ItemID);
92 weardata["asset"] = OSD.FromUUID(AssetID);
93
94 return weardata;
95 }
96
97 public void Unpack(OSDMap args)
98 {
99 ItemID = (args["item"] != null) ? args["item"].AsUUID() : UUID.Zero;
100 AssetID = (args["asset"] != null) ? args["asset"].AsUUID() : UUID.Zero;
101 }
102
65 public static AvatarWearable[] DefaultWearables 103 public static AvatarWearable[] DefaultWearables
66 { 104 {
67 get 105 get
68 { 106 {
69 AvatarWearable[] defaultWearables = new AvatarWearable[13]; //should be 13 of these 107 AvatarWearable[] defaultWearables = new AvatarWearable[MAX_WEARABLES]; //should be 13 of these
70 for (int i = 0; i < 13; i++) 108 for (int i = 0; i < MAX_WEARABLES; i++)
71 { 109 {
72 defaultWearables[i] = new AvatarWearable(); 110 defaultWearables[i] = new AvatarWearable();
73 } 111 }
diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs
index 72283de..6b64e12 100644
--- a/OpenSim/Framework/Capabilities/Caps.cs
+++ b/OpenSim/Framework/Capabilities/Caps.cs
@@ -976,7 +976,9 @@ namespace OpenSim.Framework.Capabilities
976 976
977 public void BakedTextureUploaded(UUID assetID, byte[] data) 977 public void BakedTextureUploaded(UUID assetID, byte[] data)
978 { 978 {
979 m_log.DebugFormat("[CAPS]: Received baked texture {0}", assetID.ToString()); 979// DEBUG ON
980 m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
981// DEBUG OFF
980 AssetBase asset; 982 AssetBase asset;
981 asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString()); 983 asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString());
982 asset.Data = data; 984 asset.Data = data;
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs
index 0dc5dbc..66487f7 100644
--- a/OpenSim/Framework/ChildAgentDataUpdate.cs
+++ b/OpenSim/Framework/ChildAgentDataUpdate.cs
@@ -28,6 +28,8 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
31using OpenMetaverse; 33using OpenMetaverse;
32using OpenMetaverse.StructuredData; 34using OpenMetaverse.StructuredData;
33 35
@@ -225,46 +227,6 @@ namespace OpenSim.Framework
225 } 227 }
226 } 228 }
227 229
228 public class AttachmentData
229 {
230 public int AttachPoint;
231 public UUID ItemID;
232 public UUID AssetID;
233
234 public AttachmentData(int point, UUID item, UUID asset)
235 {
236 AttachPoint = point;
237 ItemID = item;
238 AssetID = asset;
239 }
240
241 public AttachmentData(OSDMap args)
242 {
243 UnpackUpdateMessage(args);
244 }
245
246 public OSDMap PackUpdateMessage()
247 {
248 OSDMap attachdata = new OSDMap();
249 attachdata["point"] = OSD.FromInteger(AttachPoint);
250 attachdata["item"] = OSD.FromUUID(ItemID);
251 attachdata["asset"] = OSD.FromUUID(AssetID);
252
253 return attachdata;
254 }
255
256
257 public void UnpackUpdateMessage(OSDMap args)
258 {
259 if (args["point"] != null)
260 AttachPoint = args["point"].AsInteger();
261 if (args["item"] != null)
262 ItemID = args["item"].AsUUID();
263 if (args["asset"] != null)
264 AssetID = args["asset"].AsUUID();
265 }
266 }
267
268 public class ControllerData 230 public class ControllerData
269 { 231 {
270 public UUID ItemID; 232 public UUID ItemID;
@@ -348,11 +310,20 @@ namespace OpenSim.Framework
348 public UUID GranterID; 310 public UUID GranterID;
349 311
350 // Appearance 312 // Appearance
313 public AvatarAppearance Appearance;
314
315// DEBUG ON
316 private static readonly ILog m_log =
317 LogManager.GetLogger(
318 MethodBase.GetCurrentMethod().DeclaringType);
319// DEBUG OFF
320
321/*
351 public byte[] AgentTextures; 322 public byte[] AgentTextures;
352 public byte[] VisualParams; 323 public byte[] VisualParams;
353 public UUID[] Wearables; 324 public UUID[] Wearables;
354 public AttachmentData[] Attachments; 325 public AvatarAttachment[] Attachments;
355 326*/
356 // Scripted 327 // Scripted
357 public ControllerData[] Controllers; 328 public ControllerData[] Controllers;
358 329
@@ -360,6 +331,10 @@ namespace OpenSim.Framework
360 331
361 public virtual OSDMap Pack() 332 public virtual OSDMap Pack()
362 { 333 {
334// DEBUG ON
335 m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Pack data");
336// DEBUG OFF
337
363 OSDMap args = new OSDMap(); 338 OSDMap args = new OSDMap();
364 args["message_type"] = OSD.FromString("AgentData"); 339 args["message_type"] = OSD.FromString("AgentData");
365 340
@@ -413,6 +388,9 @@ namespace OpenSim.Framework
413 args["animations"] = anims; 388 args["animations"] = anims;
414 } 389 }
415 390
391 if (Appearance != null)
392 args["packed_appearance"] = Appearance.Pack();
393
416 //if ((AgentTextures != null) && (AgentTextures.Length > 0)) 394 //if ((AgentTextures != null) && (AgentTextures.Length > 0))
417 //{ 395 //{
418 // OSDArray textures = new OSDArray(AgentTextures.Length); 396 // OSDArray textures = new OSDArray(AgentTextures.Length);
@@ -421,30 +399,39 @@ namespace OpenSim.Framework
421 // args["agent_textures"] = textures; 399 // args["agent_textures"] = textures;
422 //} 400 //}
423 401
424 402 // The code to pack textures, visuals, wearables and attachments
425 if ((AgentTextures != null) && (AgentTextures.Length > 0)) 403 // should be removed; packed appearance contains the full appearance
426 args["texture_entry"] = OSD.FromBinary(AgentTextures); 404 // This is retained for backward compatibility only
405 if (Appearance.Texture != null)
406 {
407 byte[] rawtextures = Appearance.Texture.GetBytes();
408 args["texture_entry"] = OSD.FromBinary(rawtextures);
409 }
427 410
428 if ((VisualParams != null) && (VisualParams.Length > 0)) 411 if ((Appearance.VisualParams != null) && (Appearance.VisualParams.Length > 0))
429 args["visual_params"] = OSD.FromBinary(VisualParams); 412 args["visual_params"] = OSD.FromBinary(Appearance.VisualParams);
430 413
431 // We might not pass this in all cases... 414 // We might not pass this in all cases...
432 if ((Wearables != null) && (Wearables.Length > 0)) 415 if ((Appearance.Wearables != null) && (Appearance.Wearables.Length > 0))
433 { 416 {
434 OSDArray wears = new OSDArray(Wearables.Length); 417 OSDArray wears = new OSDArray(Appearance.Wearables.Length * 2);
435 foreach (UUID uuid in Wearables) 418 foreach (AvatarWearable awear in Appearance.Wearables)
436 wears.Add(OSD.FromUUID(uuid)); 419 {
420 wears.Add(OSD.FromUUID(awear.ItemID));
421 wears.Add(OSD.FromUUID(awear.AssetID));
422 }
437 args["wearables"] = wears; 423 args["wearables"] = wears;
438 } 424 }
439 425
440 426 List<AvatarAttachment> attachments = Appearance.GetAttachments();
441 if ((Attachments != null) && (Attachments.Length > 0)) 427 if ((attachments != null) && (attachments.Count > 0))
442 { 428 {
443 OSDArray attachs = new OSDArray(Attachments.Length); 429 OSDArray attachs = new OSDArray(attachments.Count);
444 foreach (AttachmentData att in Attachments) 430 foreach (AvatarAttachment att in attachments)
445 attachs.Add(att.PackUpdateMessage()); 431 attachs.Add(att.Pack());
446 args["attachments"] = attachs; 432 args["attachments"] = attachs;
447 } 433 }
434 // End of code to remove
448 435
449 if ((Controllers != null) && (Controllers.Length > 0)) 436 if ((Controllers != null) && (Controllers.Length > 0))
450 { 437 {
@@ -469,6 +456,10 @@ namespace OpenSim.Framework
469 /// <param name="hash"></param> 456 /// <param name="hash"></param>
470 public virtual void Unpack(OSDMap args) 457 public virtual void Unpack(OSDMap args)
471 { 458 {
459// DEBUG ON
460 m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Unpack data");
461// DEBUG OFF
462
472 if (args.ContainsKey("region_id")) 463 if (args.ContainsKey("region_id"))
473 UUID.TryParse(args["region_id"].AsString(), out RegionID); 464 UUID.TryParse(args["region_id"].AsString(), out RegionID);
474 465
@@ -581,34 +572,53 @@ namespace OpenSim.Framework
581 // AgentTextures[i++] = o.AsUUID(); 572 // AgentTextures[i++] = o.AsUUID();
582 //} 573 //}
583 574
575 Appearance = new AvatarAppearance(AgentID);
576
577 // The code to unpack textures, visuals, wearables and attachments
578 // should be removed; packed appearance contains the full appearance
579 // This is retained for backward compatibility only
584 if (args["texture_entry"] != null) 580 if (args["texture_entry"] != null)
585 AgentTextures = args["texture_entry"].AsBinary(); 581 {
582 byte[] rawtextures = args["texture_entry"].AsBinary();
583 Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures,0,rawtextures.Length);
584 Appearance.SetTextureEntries(textures);
585 }
586 586
587 if (args["visual_params"] != null) 587 if (args["visual_params"] != null)
588 VisualParams = args["visual_params"].AsBinary(); 588 Appearance.SetVisualParams(args["visual_params"].AsBinary());
589 589
590 if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array) 590 if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
591 { 591 {
592 OSDArray wears = (OSDArray)(args["wearables"]); 592 OSDArray wears = (OSDArray)(args["wearables"]);
593 Wearables = new UUID[wears.Count]; 593 for (int i = 0; i < wears.Count / 2; i++)
594 int i = 0; 594 {
595 foreach (OSD o in wears) 595 AvatarWearable awear = new AvatarWearable(wears[i*2].AsUUID(),wears[(i*2)+1].AsUUID());
596 Wearables[i++] = o.AsUUID(); 596 Appearance.SetWearable(i,awear);
597 }
597 } 598 }
598 599
599 if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array) 600 if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
600 { 601 {
601 OSDArray attachs = (OSDArray)(args["attachments"]); 602 OSDArray attachs = (OSDArray)(args["attachments"]);
602 Attachments = new AttachmentData[attachs.Count];
603 int i = 0;
604 foreach (OSD o in attachs) 603 foreach (OSD o in attachs)
605 { 604 {
606 if (o.Type == OSDType.Map) 605 if (o.Type == OSDType.Map)
607 { 606 {
608 Attachments[i++] = new AttachmentData((OSDMap)o); 607 // We know all of these must end up as attachments so we
608 // append rather than replace to ensure multiple attachments
609 // per point continues to work
610 Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
609 } 611 }
610 } 612 }
611 } 613 }
614 // end of code to remove
615
616 if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
617 Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]);
618// DEBUG ON
619 else
620 m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance");
621// DEBUG OFF
612 622
613 if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) 623 if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
614 { 624 {
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 94815cd..027f9c5 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -43,7 +43,7 @@ namespace OpenSim.Framework
43 43
44 public delegate void TextureRequest(Object sender, TextureRequestArgs e); 44 public delegate void TextureRequest(Object sender, TextureRequestArgs e);
45 45
46 public delegate void AvatarNowWearing(Object sender, AvatarWearingArgs e); 46 public delegate void AvatarNowWearing(IClientAPI sender, AvatarWearingArgs e);
47 47
48 public delegate void ImprovedInstantMessage(IClientAPI remoteclient, GridInstantMessage im); 48 public delegate void ImprovedInstantMessage(IClientAPI remoteclient, GridInstantMessage im);
49 49
@@ -65,7 +65,7 @@ namespace OpenSim.Framework
65 65
66 public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); 66 public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes);
67 67
68 public delegate void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams); 68 public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams);
69 69
70 public delegate void StartAnim(IClientAPI remoteClient, UUID animID); 70 public delegate void StartAnim(IClientAPI remoteClient, UUID animID);
71 71
@@ -711,7 +711,7 @@ namespace OpenSim.Framework
711 event TeleportLandmarkRequest OnTeleportLandmarkRequest; 711 event TeleportLandmarkRequest OnTeleportLandmarkRequest;
712 event DeRezObject OnDeRezObject; 712 event DeRezObject OnDeRezObject;
713 event Action<IClientAPI> OnRegionHandShakeReply; 713 event Action<IClientAPI> OnRegionHandShakeReply;
714 event GenericCall2 OnRequestWearables; 714 event GenericCall1 OnRequestWearables;
715 event GenericCall1 OnCompleteMovementToRegion; 715 event GenericCall1 OnCompleteMovementToRegion;
716 event UpdateAgent OnPreAgentUpdate; 716 event UpdateAgent OnPreAgentUpdate;
717 event UpdateAgent OnAgentUpdate; 717 event UpdateAgent OnAgentUpdate;
diff --git a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs
index 2fda6f3..05d8469 100644
--- a/OpenSim/Framework/Tests/AgentCircuitDataTest.cs
+++ b/OpenSim/Framework/Tests/AgentCircuitDataTest.cs
@@ -65,9 +65,7 @@ namespace OpenSim.Framework.Tests
65 SessionId = UUID.Random(); 65 SessionId = UUID.Random();
66 66
67 AvAppearance = new AvatarAppearance(AgentId); 67 AvAppearance = new AvatarAppearance(AgentId);
68 AvAppearance.SetDefaultWearables();
69 VisualParams = new byte[218]; 68 VisualParams = new byte[218];
70 AvAppearance.SetDefaultParams(VisualParams);
71 69
72 //body 70 //body
73 VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HEIGHT] = 155; 71 VisualParams[(int)AvatarAppearance.VPElement.SHAPE_HEIGHT] = 155;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 74ad485..14f923d 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -79,7 +79,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
79 public event DeRezObject OnDeRezObject; 79 public event DeRezObject OnDeRezObject;
80 public event ModifyTerrain OnModifyTerrain; 80 public event ModifyTerrain OnModifyTerrain;
81 public event Action<IClientAPI> OnRegionHandShakeReply; 81 public event Action<IClientAPI> OnRegionHandShakeReply;
82 public event GenericCall2 OnRequestWearables; 82 public event GenericCall1 OnRequestWearables;
83 public event SetAppearance OnSetAppearance; 83 public event SetAppearance OnSetAppearance;
84 public event AvatarNowWearing OnAvatarNowWearing; 84 public event AvatarNowWearing OnAvatarNowWearing;
85 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; 85 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
@@ -5647,11 +5647,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5647 5647
5648 private bool HandlerAgentWearablesRequest(IClientAPI sender, Packet Pack) 5648 private bool HandlerAgentWearablesRequest(IClientAPI sender, Packet Pack)
5649 { 5649 {
5650 GenericCall2 handlerRequestWearables = OnRequestWearables; 5650 GenericCall1 handlerRequestWearables = OnRequestWearables;
5651 5651
5652 if (handlerRequestWearables != null) 5652 if (handlerRequestWearables != null)
5653 { 5653 {
5654 handlerRequestWearables(); 5654 handlerRequestWearables(sender);
5655 } 5655 }
5656 5656
5657 Action<IClientAPI> handlerRequestAvatarsData = OnRequestAvatarsData; 5657 Action<IClientAPI> handlerRequestAvatarsData = OnRequestAvatarsData;
@@ -5694,7 +5694,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5694 if (appear.ObjectData.TextureEntry.Length > 1) 5694 if (appear.ObjectData.TextureEntry.Length > 1)
5695 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); 5695 te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
5696 5696
5697 handlerSetAppearance(te, visualparams); 5697 handlerSetAppearance(sender, te, visualparams);
5698 } 5698 }
5699 catch (Exception e) 5699 catch (Exception e)
5700 { 5700 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 2a0c0b1..ad6b1de 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -124,13 +124,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
124 124
125 // Save avatar attachment information 125 // Save avatar attachment information
126 ScenePresence presence; 126 ScenePresence presence;
127 if (m_scene.AvatarFactory != null && m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 127 if (m_scene.AvatarService != null && m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
128 { 128 {
129 m_log.Info( 129 m_log.Info(
130 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId 130 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
131 + ", AttachmentPoint: " + AttachmentPt); 131 + ", AttachmentPoint: " + AttachmentPt);
132 132
133 m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); 133 m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance);
134 } 134 }
135 } 135 }
136 } 136 }
@@ -382,8 +382,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
382 item = m_scene.InventoryService.GetItem(item); 382 item = m_scene.InventoryService.GetItem(item);
383 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */); 383 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */);
384 384
385 if (m_scene.AvatarFactory != null) 385 if (m_scene.AvatarService != null)
386 m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); 386 m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance);
387 } 387 }
388 } 388 }
389 389
@@ -405,10 +405,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
405 presence.Appearance.DetachAttachment(itemID); 405 presence.Appearance.DetachAttachment(itemID);
406 406
407 // Save avatar attachment information 407 // Save avatar attachment information
408 if (m_scene.AvatarFactory != null) 408 if (m_scene.AvatarService != null)
409 { 409 {
410 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); 410 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
411 m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); 411 m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance);
412 } 412 }
413 } 413 }
414 414
@@ -435,9 +435,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
435 435
436 presence.Appearance.DetachAttachment(itemID); 436 presence.Appearance.DetachAttachment(itemID);
437 437
438 if (m_scene.AvatarFactory != null) 438 if (m_scene.AvatarService != null)
439 { 439 {
440 m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); 440 m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance);
441 } 441 }
442 part.ParentGroup.DetachToGround(); 442 part.ParentGroup.DetachToGround();
443 443
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 22c8937..903e94b 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -32,58 +32,46 @@ using Nini.Config;
32using OpenMetaverse; 32using OpenMetaverse;
33using OpenSim.Framework; 33using OpenSim.Framework;
34 34
35using System.Threading;
36using System.Timers;
37using System.Collections.Generic;
38
35using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
37using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
38 42
39namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory 43namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
40{ 44{
41 public class AvatarFactoryModule : IAvatarFactory, IRegionModule 45 public class AvatarFactoryModule : IRegionModule
42 { 46 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
44 private Scene m_scene = null; 49 private Scene m_scene = null;
45 private static readonly AvatarAppearance def = new AvatarAppearance();
46 50
47 public bool TryGetAvatarAppearance(UUID avatarId, out AvatarAppearance appearance) 51 private static readonly int m_savetime = 5; // seconds to wait before saving changed appearance
48 { 52 private static readonly int m_sendtime = 2; // seconds to wait before sending changed appearance
49 AvatarData avatar = m_scene.AvatarService.GetAvatar(avatarId);
50 //if ((profile != null) && (profile.RootFolder != null))
51 if (avatar != null)
52 {
53 appearance = avatar.ToAvatarAppearance(avatarId);
54 return true;
55 }
56 53
57 m_log.ErrorFormat("[APPEARANCE]: Appearance not found for {0}, creating default", avatarId); 54 private static readonly int m_checkTime = 500; // milliseconds to wait between checks for appearance updates
58 appearance = CreateDefault(avatarId); 55 private System.Timers.Timer m_updateTimer = new System.Timers.Timer();
59 return false; 56 private Dictionary<UUID,long> m_savequeue = new Dictionary<UUID,long>();
60 } 57 private Dictionary<UUID,long> m_sendqueue = new Dictionary<UUID,long>();
61 58
62 private AvatarAppearance CreateDefault(UUID avatarId) 59 #region RegionModule Members
63 {
64 AvatarAppearance appearance = null;
65 AvatarWearable[] wearables;
66 byte[] visualParams;
67 GetDefaultAvatarAppearance(out wearables, out visualParams);
68 appearance = new AvatarAppearance(avatarId, wearables, visualParams);
69
70 return appearance;
71 }
72 60
73 public void Initialise(Scene scene, IConfigSource source) 61 public void Initialise(Scene scene, IConfigSource source)
74 { 62 {
75 scene.RegisterModuleInterface<IAvatarFactory>(this);
76 scene.EventManager.OnNewClient += NewClient; 63 scene.EventManager.OnNewClient += NewClient;
77 64
78 if (m_scene == null) 65 if (m_scene == null)
79 {
80 m_scene = scene; 66 m_scene = scene;
81 }
82
83 } 67 }
84 68
85 public void PostInitialise() 69 public void PostInitialise()
86 { 70 {
71 m_updateTimer.Enabled = false;
72 m_updateTimer.AutoReset = true;
73 m_updateTimer.Interval = m_checkTime; // 500 milliseconds wait to start async ops
74 m_updateTimer.Elapsed += new ElapsedEventHandler(HandleAppearanceUpdateTimer);
87 } 75 }
88 76
89 public void Close() 77 public void Close()
@@ -102,6 +90,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
102 90
103 public void NewClient(IClientAPI client) 91 public void NewClient(IClientAPI client)
104 { 92 {
93 client.OnRequestWearables += SendWearables;
94 client.OnSetAppearance += SetAppearance;
105 client.OnAvatarNowWearing += AvatarIsWearing; 95 client.OnAvatarNowWearing += AvatarIsWearing;
106 } 96 }
107 97
@@ -110,42 +100,211 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
110 // client.OnAvatarNowWearing -= AvatarIsWearing; 100 // client.OnAvatarNowWearing -= AvatarIsWearing;
111 } 101 }
112 102
113 public void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) 103 #endregion
104
105 /// <summary>
106 /// Set appearance data (textureentry and slider settings) received from the client
107 /// </summary>
108 /// <param name="texture"></param>
109 /// <param name="visualParam"></param>
110 public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
114 { 111 {
115 IInventoryService invService = m_scene.InventoryService; 112// DEBUG ON
113 m_log.WarnFormat("[AVFACTORY] SetAppearance for {0}",client.AgentId);
114// DEBUG OFF
116 115
117 if (invService.GetRootFolder(userID) != null) 116 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
117 if (sp == null)
118 { 118 {
119 for (int i = 0; i < 13; i++) 119 m_log.WarnFormat("[AVFACTORY] SetAppearance unable to find presence for {0}",client.AgentId);
120 return;
121 }
122
123 bool changed = false;
124
125 // Process the texture entry
126 if (textureEntry != null)
127 {
128 changed = sp.Appearance.SetTextureEntries(textureEntry);
129
130 for (int i = 0; i < BAKE_INDICES.Length; i++)
120 { 131 {
121 if (appearance.Wearables[i].ItemID == UUID.Zero) 132 int idx = BAKE_INDICES[i];
133 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
134 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
135 Util.FireAndForget(delegate(object o) { CheckBakedTextureAssets(client,face.TextureID,idx); });
136 }
137 }
138
139 // Process the visual params, this may change height as well
140 if (visualParams != null)
141 {
142 if (sp.Appearance.SetVisualParams(visualParams))
143 {
144 changed = true;
145 if (sp.Appearance.AvatarHeight > 0)
146 sp.SetHeight(sp.Appearance.AvatarHeight);
147 }
148 }
149
150 // If something changed in the appearance then queue an appearance save
151 if (changed)
152 QueueAppearanceSave(client.AgentId);
153
154 // And always queue up an appearance update to send out
155 QueueAppearanceSend(client.AgentId);
156
157 // Send the appearance back to the avatar
158 AvatarAppearance avp = sp.Appearance;
159 sp.ControllingClient.SendAvatarDataImmediate(sp);
160 sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
161 }
162
163 /// <summary>
164 /// Checks for the existance of a baked texture asset and
165 /// requests the viewer rebake if the asset is not found
166 /// </summary>
167 /// <param name="client"></param>
168 /// <param name="textureID"></param>
169 /// <param name="idx"></param>
170 private void CheckBakedTextureAssets(IClientAPI client, UUID textureID, int idx)
171 {
172 if (m_scene.AssetService.Get(textureID.ToString()) == null)
173 {
174 m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",
175 textureID,idx,client.Name);
176 client.SendRebakeAvatarTextures(textureID);
177 }
178 }
179
180 #region UpdateAppearanceTimer
181
182 public void QueueAppearanceSend(UUID agentid)
183 {
184// DEBUG ON
185 m_log.WarnFormat("[AVFACTORY] Queue appearance send for {0}",agentid);
186// DEBUG OFF
187
188 // 100 nanoseconds (ticks) we should wait
189 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 10000000);
190 lock (m_sendqueue)
191 {
192 m_sendqueue[agentid] = timestamp;
193 m_updateTimer.Start();
194 }
195 }
196
197 public void QueueAppearanceSave(UUID agentid)
198 {
199// DEBUG ON
200 m_log.WarnFormat("[AVFACTORY] Queue appearance save for {0}",agentid);
201// DEBUG OFF
202
203 // 100 nanoseconds (ticks) we should wait
204 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 10000000);
205 lock (m_savequeue)
206 {
207 m_savequeue[agentid] = timestamp;
208 m_updateTimer.Start();
209 }
210 }
211
212 private void HandleAppearanceSend(UUID agentid)
213 {
214 ScenePresence sp = m_scene.GetScenePresence(agentid);
215 if (sp == null)
216 {
217 m_log.WarnFormat("[AVFACTORY] Agent {0} no longer in the scene",agentid);
218 return;
219 }
220
221// DEBUG ON
222 m_log.WarnFormat("[AVFACTORY] Handle appearance send for {0}\n{1}",agentid,sp.Appearance.ToString());
223// DEBUG OFF
224
225 // Send the appearance to everyone in the scene
226 sp.SendAppearanceToAllOtherAgents();
227
228 // Send the appearance back to the avatar
229 AvatarAppearance avp = sp.Appearance;
230 sp.ControllingClient.SendAvatarDataImmediate(sp);
231 sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
232
233/*
234// this needs to be fixed, the flag should be on scene presence not the region module
235 // Start the animations if necessary
236 if (!m_startAnimationSet)
237 {
238 sp.Animator.UpdateMovementAnimations();
239 m_startAnimationSet = true;
240 }
241*/
242 }
243
244 private void HandleAppearanceSave(UUID agentid)
245 {
246 ScenePresence sp = m_scene.GetScenePresence(agentid);
247 if (sp == null)
248 {
249 m_log.WarnFormat("[AVFACTORY] Agent {0} no longer in the scene",agentid);
250 return;
251 }
252
253 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
254 }
255
256 private void HandleAppearanceUpdateTimer(object sender, EventArgs ea)
257 {
258 long now = DateTime.Now.Ticks;
259
260 lock (m_sendqueue)
261 {
262 Dictionary<UUID,long> sends = new Dictionary<UUID,long>(m_sendqueue);
263 foreach (KeyValuePair<UUID,long> kvp in sends)
264 {
265 if (kvp.Value < now)
122 { 266 {
123 appearance.Wearables[i].AssetID = UUID.Zero; 267 Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); });
268 m_sendqueue.Remove(kvp.Key);
124 } 269 }
125 else 270 }
126 { 271 }
127 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i].ItemID, userID);
128 baseItem = invService.GetItem(baseItem);
129 272
130 if (baseItem != null) 273 lock (m_savequeue)
131 { 274 {
132 appearance.Wearables[i].AssetID = baseItem.AssetID; 275 Dictionary<UUID,long> saves = new Dictionary<UUID,long>(m_savequeue);
133 } 276 foreach (KeyValuePair<UUID,long> kvp in saves)
134 else 277 {
135 { 278 if (kvp.Value < now)
136 m_log.ErrorFormat( 279 {
137 "[APPEARANCE]: Can't find inventory item {0} for {1}, setting to default", 280 Util.FireAndForget(delegate(object o) { HandleAppearanceSave(kvp.Key); });
138 appearance.Wearables[i].ItemID, (WearableType)i); 281 m_savequeue.Remove(kvp.Key);
139
140 appearance.Wearables[i].AssetID = def.Wearables[i].AssetID;
141 }
142 } 282 }
143 } 283 }
144 } 284 }
145 else 285
286 if (m_savequeue.Count == 0 && m_sendqueue.Count == 0)
287 m_updateTimer.Stop();
288 }
289
290 #endregion
291
292 /// <summary>
293 /// Tell the client for this scene presence what items it should be wearing now
294 /// </summary>
295 public void SendWearables(IClientAPI client)
296 {
297 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
298 if (sp == null)
146 { 299 {
147 m_log.WarnFormat("[APPEARANCE]: user {0} has no inventory, appearance isn't going to work", userID); 300 m_log.WarnFormat("[AVFACTORY] SendWearables unable to find presence for {0}",client.AgentId);
301 return;
148 } 302 }
303
304// DEBUG ON
305 m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId);
306// DEBUG OFF
307 client.SendWearables(sp.Appearance.Wearables,sp.Appearance.Serial++);
149 } 308 }
150 309
151 /// <summary> 310 /// <summary>
@@ -153,65 +312,81 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
153 /// </summary> 312 /// </summary>
154 /// <param name="sender"></param> 313 /// <param name="sender"></param>
155 /// <param name="e"></param> 314 /// <param name="e"></param>
156 public void AvatarIsWearing(Object sender, AvatarWearingArgs e) 315 public void AvatarIsWearing(IClientAPI client, AvatarWearingArgs e)
157 { 316 {
158 m_log.DebugFormat("[APPEARANCE]: AvatarIsWearing"); 317 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
159 318 if (sp == null)
160 IClientAPI clientView = (IClientAPI)sender;
161 ScenePresence sp = m_scene.GetScenePresence(clientView.AgentId);
162
163 if (sp == null)
164 { 319 {
165 m_log.Error("[APPEARANCE]: Avatar is child agent, ignoring AvatarIsWearing event"); 320 m_log.WarnFormat("[AVFACTORY] AvatarIsWearing unable to find presence for {0}",client.AgentId);
166 return; 321 return;
167 } 322 }
323
324// DEBUG ON
325 m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}",client.AgentId);
326// DEBUG OFF
168 327
169 AvatarAppearance avatAppearance = sp.Appearance; 328 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance);
170 //if (!TryGetAvatarAppearance(clientView.AgentId, out avatAppearance)) 329
330 //if (!TryGetAvatarAppearance(client.AgentId, out avatAppearance))
171 //{ 331 //{
172 // m_log.Warn("[APPEARANCE]: We didn't seem to find the appearance, falling back to ScenePresence"); 332 // m_log.Warn("[AVFACTORY]: We didn't seem to find the appearance, falling back to ScenePresence");
173 // avatAppearance = sp.Appearance; 333 // avatAppearance = sp.Appearance;
174 //} 334 //}
175 335
176 //m_log.DebugFormat("[APPEARANCE]: Received wearables for {0}", clientView.Name); 336 //m_log.DebugFormat("[AVFACTORY]: Received wearables for {0}", client.Name);
177 337
178 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) 338 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
179 { 339 {
180 if (wear.Type < 13) 340 if (wear.Type < AvatarWearable.MAX_WEARABLES)
181 { 341 {
182 avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID; 342 AvatarWearable newWearable = new AvatarWearable(wear.ItemID,UUID.Zero);
343 avatAppearance.SetWearable(wear.Type, newWearable);
183 } 344 }
184 } 345 }
185 346
186 SetAppearanceAssets(sp.UUID, ref avatAppearance); 347 SetAppearanceAssets(sp.UUID, ref avatAppearance);
187 AvatarData adata = new AvatarData(avatAppearance);
188 m_scene.AvatarService.SetAvatar(clientView.AgentId, adata);
189 348
349 m_scene.AvatarService.SetAppearance(client.AgentId, avatAppearance);
190 sp.Appearance = avatAppearance; 350 sp.Appearance = avatAppearance;
191 } 351 }
192 352
193 public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams) 353 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
194 { 354 {
195 visualParams = GetDefaultVisualParams(); 355 IInventoryService invService = m_scene.InventoryService;
196 wearables = AvatarWearable.DefaultWearables;
197 }
198 356
199 public void UpdateDatabase(UUID user, AvatarAppearance appearance) 357 if (invService.GetRootFolder(userID) != null)
200 { 358 {
201 //m_log.DebugFormat("[APPEARANCE]: UpdateDatabase"); 359 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
202 AvatarData adata = new AvatarData(appearance); 360 {
203 m_scene.AvatarService.SetAvatar(user, adata); 361 if (appearance.Wearables[i].ItemID == UUID.Zero)
204 } 362 {
363 appearance.Wearables[i].AssetID = UUID.Zero;
364 }
365 else
366 {
367 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i].ItemID, userID);
368 baseItem = invService.GetItem(baseItem);
205 369
206 private static byte[] GetDefaultVisualParams() 370 if (baseItem != null)
207 { 371 {
208 byte[] visualParams; 372 appearance.Wearables[i].AssetID = baseItem.AssetID;
209 visualParams = new byte[218]; 373 }
210 for (int i = 0; i < 218; i++) 374 else
375 {
376 m_log.ErrorFormat(
377 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
378 appearance.Wearables[i].ItemID, (WearableType)i);
379
380 appearance.Wearables[i].ItemID = UUID.Zero;
381 appearance.Wearables[i].AssetID = UUID.Zero;
382 }
383 }
384 }
385 }
386 else
211 { 387 {
212 visualParams[i] = 100; 388 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
213 } 389 }
214 return visualParams;
215 } 390 }
216 } 391 }
217} 392}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs
index 47f19a3..9ee19f8 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Nini.Config; 32using Nini.Config;
33using OpenSim.Framework;
33using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
35using OpenSim.Server.Base; 36using OpenSim.Server.Base;
@@ -137,6 +138,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar
137 138
138 #region IAvatarService 139 #region IAvatarService
139 140
141 public AvatarAppearance GetAppearance(UUID userID)
142 {
143 return m_AvatarService.GetAppearance(userID);
144 }
145
146 public bool SetAppearance(UUID userID, AvatarAppearance appearance)
147 {
148 return m_AvatarService.SetAppearance(userID,appearance);
149 }
150
140 public AvatarData GetAvatar(UUID userID) 151 public AvatarData GetAvatar(UUID userID)
141 { 152 {
142 return m_AvatarService.GetAvatar(userID); 153 return m_AvatarService.GetAvatar(userID);
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index 268612e..f128aa2 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -82,7 +82,7 @@ namespace OpenSim.Region.Examples.SimpleModule
82 82
83 public event DeRezObject OnDeRezObject; 83 public event DeRezObject OnDeRezObject;
84 public event Action<IClientAPI> OnRegionHandShakeReply; 84 public event Action<IClientAPI> OnRegionHandShakeReply;
85 public event GenericCall2 OnRequestWearables; 85 public event GenericCall1 OnRequestWearables;
86 public event GenericCall1 OnCompleteMovementToRegion; 86 public event GenericCall1 OnCompleteMovementToRegion;
87 public event UpdateAgent OnPreAgentUpdate; 87 public event UpdateAgent OnPreAgentUpdate;
88 public event UpdateAgent OnAgentUpdate; 88 public event UpdateAgent OnAgentUpdate;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index f0ae45e..6367fcf 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -119,7 +119,6 @@ namespace OpenSim.Region.Framework.Scenes
119 119
120 protected IXMLRPC m_xmlrpcModule; 120 protected IXMLRPC m_xmlrpcModule;
121 protected IWorldComm m_worldCommModule; 121 protected IWorldComm m_worldCommModule;
122 protected IAvatarFactory m_AvatarFactory;
123 protected IConfigSource m_config; 122 protected IConfigSource m_config;
124 protected IRegionSerialiserModule m_serialiser; 123 protected IRegionSerialiserModule m_serialiser;
125 protected IDialogModule m_dialogModule; 124 protected IDialogModule m_dialogModule;
@@ -399,11 +398,6 @@ namespace OpenSim.Region.Framework.Scenes
399 398
400 public IAttachmentsModule AttachmentsModule { get; set; } 399 public IAttachmentsModule AttachmentsModule { get; set; }
401 400
402 public IAvatarFactory AvatarFactory
403 {
404 get { return m_AvatarFactory; }
405 }
406
407 public ICapabilitiesModule CapsModule 401 public ICapabilitiesModule CapsModule
408 { 402 {
409 get { return m_capsModule; } 403 get { return m_capsModule; }
@@ -1159,7 +1153,6 @@ namespace OpenSim.Region.Framework.Scenes
1159 m_xmlrpcModule = RequestModuleInterface<IXMLRPC>(); 1153 m_xmlrpcModule = RequestModuleInterface<IXMLRPC>();
1160 m_worldCommModule = RequestModuleInterface<IWorldComm>(); 1154 m_worldCommModule = RequestModuleInterface<IWorldComm>();
1161 XferManager = RequestModuleInterface<IXfer>(); 1155 XferManager = RequestModuleInterface<IXfer>();
1162 m_AvatarFactory = RequestModuleInterface<IAvatarFactory>();
1163 AttachmentsModule = RequestModuleInterface<IAttachmentsModule>(); 1156 AttachmentsModule = RequestModuleInterface<IAttachmentsModule>();
1164 m_serialiser = RequestModuleInterface<IRegionSerialiserModule>(); 1157 m_serialiser = RequestModuleInterface<IRegionSerialiserModule>();
1165 m_dialogModule = RequestModuleInterface<IDialogModule>(); 1158 m_dialogModule = RequestModuleInterface<IDialogModule>();
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 13d9964..f828a2d 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -75,7 +75,6 @@ namespace OpenSim.Region.Framework.Scenes
75 75
76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 77
78 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
79// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); 78// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
80 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); 79 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
81 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); 80 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
@@ -137,8 +136,6 @@ namespace OpenSim.Region.Framework.Scenes
137 136
138 private SendCourseLocationsMethod m_sendCourseLocationsMethod; 137 private SendCourseLocationsMethod m_sendCourseLocationsMethod;
139 138
140 private bool m_startAnimationSet;
141
142 //private Vector3 m_requestedSitOffset = new Vector3(); 139 //private Vector3 m_requestedSitOffset = new Vector3();
143 140
144 private Vector3 m_LastFinitePos; 141 private Vector3 m_LastFinitePos;
@@ -713,13 +710,14 @@ namespace OpenSim.Region.Framework.Scenes
713 SetDirectionVectors(); 710 SetDirectionVectors();
714 } 711 }
715 712
713/*
716 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, 714 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams,
717 AvatarWearable[] wearables) 715 AvatarWearable[] wearables)
718 : this(client, world, reginfo) 716 : this(client, world, reginfo)
719 { 717 {
720 m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); 718 m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams);
721 } 719 }
722 720*/
723 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) 721 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
724 : this(client, world, reginfo) 722 : this(client, world, reginfo)
725 { 723 {
@@ -733,8 +731,6 @@ namespace OpenSim.Region.Framework.Scenes
733 731
734 public void RegisterToEvents() 732 public void RegisterToEvents()
735 { 733 {
736 m_controllingClient.OnRequestWearables += SendWearables;
737 m_controllingClient.OnSetAppearance += SetAppearance;
738 m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; 734 m_controllingClient.OnCompleteMovementToRegion += CompleteMovement;
739 //m_controllingClient.OnCompleteMovementToRegion += SendInitialData; 735 //m_controllingClient.OnCompleteMovementToRegion += SendInitialData;
740 m_controllingClient.OnAgentUpdate += HandleAgentUpdate; 736 m_controllingClient.OnAgentUpdate += HandleAgentUpdate;
@@ -1068,7 +1064,7 @@ namespace OpenSim.Region.Framework.Scenes
1068 /// <summary> 1064 /// <summary>
1069 /// Sets avatar height in the phyiscs plugin 1065 /// Sets avatar height in the phyiscs plugin
1070 /// </summary> 1066 /// </summary>
1071 internal void SetHeight(float height) 1067 public void SetHeight(float height)
1072 { 1068 {
1073 m_avHeight = height; 1069 m_avHeight = height;
1074 if (PhysicsActor != null && !IsChildAgent) 1070 if (PhysicsActor != null && !IsChildAgent)
@@ -1133,7 +1129,6 @@ namespace OpenSim.Region.Framework.Scenes
1133 if (friendsModule != null) 1129 if (friendsModule != null)
1134 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1130 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1135 } 1131 }
1136
1137 } 1132 }
1138 1133
1139 /// <summary> 1134 /// <summary>
@@ -2392,9 +2387,12 @@ namespace OpenSim.Region.Framework.Scenes
2392 if (m_appearance.Texture == null) 2387 if (m_appearance.Texture == null)
2393 return; 2388 return;
2394 2389
2395 Vector3 pos = m_pos; 2390 if (IsChildAgent)
2396 pos.Z += m_appearance.HipOffset; 2391 {
2397 2392 m_log.WarnFormat("[SCENEPRESENCE] A child agent is attempting to send out avatar data");
2393 return;
2394 }
2395
2398 remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); 2396 remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this);
2399 m_scene.StatsReporter.AddAgentUpdates(1); 2397 m_scene.StatsReporter.AddAgentUpdates(1);
2400 } 2398 }
@@ -2437,6 +2435,12 @@ namespace OpenSim.Region.Framework.Scenes
2437 m_perfMonMS = Util.EnvironmentTickCount(); 2435 m_perfMonMS = Util.EnvironmentTickCount();
2438 2436
2439 // only send update from root agents to other clients; children are only "listening posts" 2437 // only send update from root agents to other clients; children are only "listening posts"
2438 if (IsChildAgent)
2439 {
2440 m_log.Warn("[SCENEPRESENCE] attempt to send update from a childagent");
2441 return;
2442 }
2443
2440 int count = 0; 2444 int count = 0;
2441 m_scene.ForEachScenePresence(delegate(ScenePresence sp) 2445 m_scene.ForEachScenePresence(delegate(ScenePresence sp)
2442 { 2446 {
@@ -2460,29 +2464,20 @@ namespace OpenSim.Region.Framework.Scenes
2460 // the inventory arrives 2464 // the inventory arrives
2461 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); 2465 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
2462 2466
2463 Vector3 pos = m_pos;
2464 pos.Z += m_appearance.HipOffset;
2465
2466 m_controllingClient.SendAvatarDataImmediate(this); 2467 m_controllingClient.SendAvatarDataImmediate(this);
2468 m_controllingClient.SendAppearance(m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes());
2467 2469
2468 SendInitialFullUpdateToAllClients(); 2470 SendInitialFullUpdateToAllClients();
2469 } 2471 }
2470 2472
2471 /// <summary> 2473 /// <summary>
2472 /// Tell the client for this scene presence what items it should be wearing now
2473 /// </summary>
2474 public void SendWearables()
2475 {
2476 m_log.DebugFormat("[SCENE]: Received request for wearables of {0}", Name);
2477
2478 ControllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++);
2479 }
2480
2481 /// <summary>
2482 /// 2474 ///
2483 /// </summary> 2475 /// </summary>
2484 public void SendAppearanceToAllOtherAgents() 2476 public void SendAppearanceToAllOtherAgents()
2485 { 2477 {
2478// DEBUG ON
2479 m_log.WarnFormat("[SP] Send appearance from {0} to all other agents",m_uuid);
2480// DEBUG OFF
2486 m_perfMonMS = Util.EnvironmentTickCount(); 2481 m_perfMonMS = Util.EnvironmentTickCount();
2487 2482
2488 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 2483 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
@@ -2502,87 +2497,13 @@ namespace OpenSim.Region.Framework.Scenes
2502 /// <param name="avatar"></param> 2497 /// <param name="avatar"></param>
2503 public void SendAppearanceToOtherAgent(ScenePresence avatar) 2498 public void SendAppearanceToOtherAgent(ScenePresence avatar)
2504 { 2499 {
2500// DEBUG ON
2501 m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId);
2502// DEBUG OFF
2505 avatar.ControllingClient.SendAppearance( 2503 avatar.ControllingClient.SendAppearance(
2506 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); 2504 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
2507 } 2505 }
2508 2506
2509 /// <summary>
2510 /// Set appearance data (textureentry and slider settings) received from the client
2511 /// </summary>
2512 /// <param name="texture"></param>
2513 /// <param name="visualParam"></param>
2514 public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
2515 {
2516 if (m_physicsActor != null)
2517 {
2518 if (!IsChildAgent)
2519 {
2520 // This may seem like it's redundant, remove the avatar from the physics scene
2521 // just to add it back again, but it saves us from having to update
2522 // 3 variables 10 times a second.
2523 bool flyingTemp = m_physicsActor.Flying;
2524 RemoveFromPhysicalScene();
2525 //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor);
2526
2527 //PhysicsActor = null;
2528
2529 AddToPhysicalScene(flyingTemp);
2530 }
2531 }
2532
2533 #region Bake Cache Check
2534
2535 if (textureEntry != null)
2536 {
2537 for (int i = 0; i < BAKE_INDICES.Length; i++)
2538 {
2539 int j = BAKE_INDICES[i];
2540 Primitive.TextureEntryFace face = textureEntry.FaceTextures[j];
2541
2542 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
2543 {
2544 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
2545 {
2546 m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + this.Name);
2547 this.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
2548 }
2549 }
2550 }
2551
2552 }
2553
2554
2555 #endregion Bake Cache Check
2556
2557 m_appearance.SetAppearance(textureEntry, visualParams);
2558 if (m_appearance.AvatarHeight > 0)
2559 SetHeight(m_appearance.AvatarHeight);
2560
2561 // This is not needed, because only the transient data changed
2562 //AvatarData adata = new AvatarData(m_appearance);
2563 //m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata);
2564
2565 SendAppearanceToAllOtherAgents();
2566 if (!m_startAnimationSet)
2567 {
2568 Animator.UpdateMovementAnimations();
2569 m_startAnimationSet = true;
2570 }
2571
2572 Vector3 pos = m_pos;
2573 pos.Z += m_appearance.HipOffset;
2574
2575 m_controllingClient.SendAvatarDataImmediate(this);
2576 }
2577
2578 public void SetWearable(int wearableId, AvatarWearable wearable)
2579 {
2580 m_appearance.SetWearable(wearableId, wearable);
2581 AvatarData adata = new AvatarData(m_appearance);
2582 m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata);
2583 m_controllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++);
2584 }
2585
2586 // Because appearance setting is in a module, we actually need 2507 // Because appearance setting is in a module, we actually need
2587 // to give it access to our appearance directly, otherwise we 2508 // to give it access to our appearance directly, otherwise we
2588 // get a synchronization issue. 2509 // get a synchronization issue.
@@ -2976,6 +2897,9 @@ namespace OpenSim.Region.Framework.Scenes
2976 2897
2977 public void CopyTo(AgentData cAgent) 2898 public void CopyTo(AgentData cAgent)
2978 { 2899 {
2900// DEBUG ON
2901 m_log.ErrorFormat("[SCENEPRESENCE] CALLING COPYTO");
2902// DEBUG OFF
2979 cAgent.AgentID = UUID; 2903 cAgent.AgentID = UUID;
2980 cAgent.RegionID = Scene.RegionInfo.RegionID; 2904 cAgent.RegionID = Scene.RegionInfo.RegionID;
2981 2905
@@ -3015,6 +2939,9 @@ namespace OpenSim.Region.Framework.Scenes
3015 2939
3016 cAgent.AlwaysRun = m_setAlwaysRun; 2940 cAgent.AlwaysRun = m_setAlwaysRun;
3017 2941
2942 cAgent.Appearance = new AvatarAppearance(m_appearance);
2943
2944/*
3018 try 2945 try
3019 { 2946 {
3020 // We might not pass the Wearables in all cases... 2947 // We might not pass the Wearables in all cases...
@@ -3054,14 +2981,14 @@ namespace OpenSim.Region.Framework.Scenes
3054 { 2981 {
3055 //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); 2982 //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count);
3056 int i = 0; 2983 int i = 0;
3057 AttachmentData[] attachs = new AttachmentData[attPoints.Count]; 2984 AvatarAttachment[] attachs = new AvatarAttachment[attPoints.Count];
3058 foreach (int point in attPoints) 2985 foreach (int point in attPoints)
3059 { 2986 {
3060 attachs[i++] = new AttachmentData(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); 2987 attachs[i++] = new AvatarAttachment(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point));
3061 } 2988 }
3062 cAgent.Attachments = attachs; 2989 cAgent.Attachments = attachs;
3063 } 2990 }
3064 2991*/
3065 lock (scriptedcontrols) 2992 lock (scriptedcontrols)
3066 { 2993 {
3067 ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; 2994 ControllerData[] controls = new ControllerData[scriptedcontrols.Count];
@@ -3088,6 +3015,9 @@ namespace OpenSim.Region.Framework.Scenes
3088 3015
3089 public void CopyFrom(AgentData cAgent) 3016 public void CopyFrom(AgentData cAgent)
3090 { 3017 {
3018// DEBUG ON
3019 m_log.ErrorFormat("[SCENEPRESENCE] CALLING COPYFROM");
3020// DEBUG OFF
3091 m_originRegionID = cAgent.RegionID; 3021 m_originRegionID = cAgent.RegionID;
3092 3022
3093 m_callbackURI = cAgent.CallbackURI; 3023 m_callbackURI = cAgent.CallbackURI;
@@ -3113,6 +3043,9 @@ namespace OpenSim.Region.Framework.Scenes
3113 m_godLevel = cAgent.GodLevel; 3043 m_godLevel = cAgent.GodLevel;
3114 m_setAlwaysRun = cAgent.AlwaysRun; 3044 m_setAlwaysRun = cAgent.AlwaysRun;
3115 3045
3046 m_appearance = new AvatarAppearance(cAgent.Appearance);
3047
3048/*
3116 uint i = 0; 3049 uint i = 0;
3117 try 3050 try
3118 { 3051 {
@@ -3125,15 +3058,17 @@ namespace OpenSim.Region.Framework.Scenes
3125 UUID assetId = cAgent.Wearables[n + 1]; 3058 UUID assetId = cAgent.Wearables[n + 1];
3126 wears[i++] = new AvatarWearable(itemId, assetId); 3059 wears[i++] = new AvatarWearable(itemId, assetId);
3127 } 3060 }
3128 m_appearance.Wearables = wears; 3061 // m_appearance.Wearables = wears;
3129 Primitive.TextureEntry te; 3062 Primitive.TextureEntry textures = null;
3130 if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) 3063 if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1)
3131 te = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); 3064 textures = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length);
3132 else 3065
3133 te = AvatarAppearance.GetDefaultTexture(); 3066 byte[] visuals = null;
3134 if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) 3067
3135 cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams(); 3068 if ((cAgent.VisualParams != null) && (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT))
3136 m_appearance.SetAppearance(te, (byte[])cAgent.VisualParams.Clone()); 3069 visuals = (byte[])cAgent.VisualParams.Clone();
3070
3071 m_appearance = new AvatarAppearance(cAgent.AgentID,wears,textures,visuals);
3137 } 3072 }
3138 catch (Exception e) 3073 catch (Exception e)
3139 { 3074 {
@@ -3146,14 +3081,14 @@ namespace OpenSim.Region.Framework.Scenes
3146 if (cAgent.Attachments != null) 3081 if (cAgent.Attachments != null)
3147 { 3082 {
3148 m_appearance.ClearAttachments(); 3083 m_appearance.ClearAttachments();
3149 foreach (AttachmentData att in cAgent.Attachments) 3084 foreach (AvatarAttachment att in cAgent.Attachments)
3150 { 3085 {
3151 m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); 3086 m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID);
3152 } 3087 }
3153 } 3088 }
3154 } 3089 }
3155 catch { } 3090 catch { }
3156 3091*/
3157 try 3092 try
3158 { 3093 {
3159 lock (scriptedcontrols) 3094 lock (scriptedcontrols)
@@ -3722,15 +3657,16 @@ namespace OpenSim.Region.Framework.Scenes
3722 return; 3657 return;
3723 } 3658 }
3724 3659
3725 List<int> attPoints = m_appearance.GetAttachedPoints(); 3660 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
3726 foreach (int p in attPoints) 3661 foreach (AvatarAttachment attach in attachments)
3727 { 3662 {
3728 if (m_isDeleted) 3663 if (m_isDeleted)
3729 return; 3664 return;
3730 3665
3731 UUID itemID = m_appearance.GetAttachedItem(p); 3666 int p = attach.AttachPoint;
3667 UUID itemID = attach.ItemID;
3732 3668
3733 //UUID assetID = m_appearance.GetAttachedAsset(p); 3669 //UUID assetID = attach.AssetID;
3734 // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down 3670 // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down
3735 // But they're not used anyway, the item is being looked up for now, so let's proceed. 3671 // But they're not used anyway, the item is being looked up for now, so let's proceed.
3736 //if (UUID.Zero == assetID) 3672 //if (UUID.Zero == assetID)
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 159af79..fc17192 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -676,7 +676,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
676 public event TeleportLandmarkRequest OnTeleportLandmarkRequest; 676 public event TeleportLandmarkRequest OnTeleportLandmarkRequest;
677 public event DeRezObject OnDeRezObject; 677 public event DeRezObject OnDeRezObject;
678 public event Action<IClientAPI> OnRegionHandShakeReply; 678 public event Action<IClientAPI> OnRegionHandShakeReply;
679 public event GenericCall2 OnRequestWearables; 679 public event GenericCall1 OnRequestWearables;
680 public event GenericCall1 OnCompleteMovementToRegion; 680 public event GenericCall1 OnCompleteMovementToRegion;
681 public event UpdateAgent OnPreAgentUpdate; 681 public event UpdateAgent OnPreAgentUpdate;
682 public event UpdateAgent OnAgentUpdate; 682 public event UpdateAgent OnAgentUpdate;
@@ -899,7 +899,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
899 Scene scene = (Scene)Scene; 899 Scene scene = (Scene)Scene;
900 AvatarAppearance appearance; 900 AvatarAppearance appearance;
901 scene.GetAvatarAppearance(this, out appearance); 901 scene.GetAvatarAppearance(this, out appearance);
902 OnSetAppearance(appearance.Texture, (byte[])appearance.VisualParams.Clone()); 902 OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone());
903 } 903 }
904 904
905 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) 905 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs
index 0786bd9..922eaaf 100644
--- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs
@@ -29,6 +29,7 @@ using System.Collections;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Security; 30using System.Security;
31using OpenMetaverse; 31using OpenMetaverse;
32using OpenSim.Framework;
32using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
33using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
34 35
@@ -81,16 +82,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
81 get { 82 get {
82 List<IAvatarAttachment> attachments = new List<IAvatarAttachment>(); 83 List<IAvatarAttachment> attachments = new List<IAvatarAttachment>();
83 84
84 Hashtable internalAttachments = GetSP().Appearance.GetAttachments(); 85 List<AvatarAttachment> internalAttachments = GetSP().Appearance.GetAttachments();
85 if (internalAttachments != null) 86 foreach (AvatarAttachment attach in internalAttachments)
86 { 87 {
87 foreach (DictionaryEntry element in internalAttachments) 88 attachments.Add(new SPAvatarAttachment(m_rootScene, this, attach.AttachPoint,
88 { 89 new UUID(attach.ItemID),
89 Hashtable attachInfo = (Hashtable)element.Value; 90 new UUID(attach.AssetID), m_security));
90 attachments.Add(new SPAvatarAttachment(m_rootScene, this, (int) element.Key,
91 new UUID((string) attachInfo["item"]),
92 new UUID((string) attachInfo["asset"]), m_security));
93 }
94 } 91 }
95 92
96 return attachments.ToArray(); 93 return attachments.ToArray();
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index fae12b6..6928c4e 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -188,7 +188,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
188 188
189 public event DeRezObject OnDeRezObject; 189 public event DeRezObject OnDeRezObject;
190 public event Action<IClientAPI> OnRegionHandShakeReply; 190 public event Action<IClientAPI> OnRegionHandShakeReply;
191 public event GenericCall2 OnRequestWearables; 191 public event GenericCall1 OnRequestWearables;
192 public event GenericCall1 OnCompleteMovementToRegion; 192 public event GenericCall1 OnCompleteMovementToRegion;
193 public event UpdateAgent OnPreAgentUpdate; 193 public event UpdateAgent OnPreAgentUpdate;
194 public event UpdateAgent OnAgentUpdate; 194 public event UpdateAgent OnAgentUpdate;
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index ab0be77..c471636 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -64,15 +64,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
64 if (m_appearanceCache.ContainsKey(target)) 64 if (m_appearanceCache.ContainsKey(target))
65 return m_appearanceCache[target]; 65 return m_appearanceCache[target];
66 66
67 AvatarData adata = scene.AvatarService.GetAvatar(target); 67 AvatarAppearance appearance = scene.AvatarService.GetAppearance(target);
68 if (adata != null) 68 if (appearance != null)
69 { 69 {
70 AvatarAppearance x = adata.ToAvatarAppearance(target); 70 m_appearanceCache.Add(target, appearance);
71 71 return appearance;
72 m_appearanceCache.Add(target, x);
73
74 return x;
75 } 72 }
73
76 return new AvatarAppearance(); 74 return new AvatarAppearance();
77 } 75 }
78 76
@@ -169,7 +167,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
169 { 167 {
170 AvatarAppearance x = GetAppearance(p_cloneAppearanceFrom, p_scene); 168 AvatarAppearance x = GetAppearance(p_cloneAppearanceFrom, p_scene);
171 169
172 sp.SetAppearance(x.Texture, (byte[])x.VisualParams.Clone()); 170 sp.Appearance.SetTextureEntries(x.Texture);
171 sp.Appearance.SetVisualParams((byte[])x.VisualParams.Clone());
172 sp.SendAppearanceToAllOtherAgents();
173 } 173 }
174 174
175 m_avatars.Add(npcAvatar.AgentId, npcAvatar); 175 m_avatars.Add(npcAvatar.AgentId, npcAvatar);
diff --git a/OpenSim/Services/AvatarService/AvatarService.cs b/OpenSim/Services/AvatarService/AvatarService.cs
index 19e662c..a8ad413 100644
--- a/OpenSim/Services/AvatarService/AvatarService.cs
+++ b/OpenSim/Services/AvatarService/AvatarService.cs
@@ -51,6 +51,20 @@ namespace OpenSim.Services.AvatarService
51 m_log.Debug("[AVATAR SERVICE]: Starting avatar service"); 51 m_log.Debug("[AVATAR SERVICE]: Starting avatar service");
52 } 52 }
53 53
54 // Get|SetAppearance should preserve existing semantics
55 // until AvatarData can be removed completely
56 public AvatarAppearance GetAppearance(UUID principalID)
57 {
58 AvatarData avatar = GetAvatar(principalID);
59 return avatar.ToAvatarAppearance(principalID);
60 }
61
62 public bool SetAppearance(UUID principalID, AvatarAppearance appearance)
63 {
64 AvatarData avatar = new AvatarData(appearance);
65 return SetAvatar(principalID,avatar);
66 }
67
54 public AvatarData GetAvatar(UUID principalID) 68 public AvatarData GetAvatar(UUID principalID)
55 { 69 {
56 AvatarBaseData[] av = m_Database.Get("PrincipalID", principalID.ToString()); 70 AvatarBaseData[] av = m_Database.Get("PrincipalID", principalID.ToString());
diff --git a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs
index 96c05a9..1cd6bf8 100644
--- a/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Avatar/AvatarServiceConnector.cs
@@ -87,6 +87,18 @@ namespace OpenSim.Services.Connectors
87 87
88 #region IAvatarService 88 #region IAvatarService
89 89
90 public AvatarAppearance GetAppearance(UUID userID)
91 {
92 AvatarData avatar = GetAvatar(userID);
93 return avatar.ToAvatarAppearance(userID);
94 }
95
96 public bool SetAppearance(UUID userID, AvatarAppearance appearance)
97 {
98 AvatarData avatar = new AvatarData(appearance);
99 return SetAvatar(userID,avatar);
100 }
101
90 public AvatarData GetAvatar(UUID userID) 102 public AvatarData GetAvatar(UUID userID)
91 { 103 {
92 Dictionary<string, object> sendData = new Dictionary<string, object>(); 104 Dictionary<string, object> sendData = new Dictionary<string, object>();
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
index 4d0d53e..ea9b4b4 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
@@ -28,6 +28,9 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Collections.Specialized; 30using System.Collections.Specialized;
31// DEBUG ON
32using System.Diagnostics;
33// DEBUG OFF
31using System.Reflection; 34using System.Reflection;
32using log4net; 35using log4net;
33using Mono.Addins; 36using Mono.Addins;
@@ -106,6 +109,80 @@ namespace OpenSim.Services.Connectors.SimianGrid
106 109
107 #region IAvatarService 110 #region IAvatarService
108 111
112 // <summary>
113 // Retrieves the LLPackedAppearance field from user data and unpacks
114 // it into an AvatarAppearance structure
115 // </summary>
116 // <param name="userID"></param>
117 public AvatarAppearance GetAppearance(UUID userID)
118 {
119 NameValueCollection requestArgs = new NameValueCollection
120 {
121 { "RequestMethod", "GetUser" },
122 { "UserID", userID.ToString() }
123 };
124
125 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
126 if (response["Success"].AsBoolean())
127 {
128 OSDMap map = null;
129 try { map = OSDParser.DeserializeJson(response["LLPackedAppearance"].AsString()) as OSDMap; }
130 catch { }
131
132 if (map != null)
133 {
134 AvatarAppearance appearance = new AvatarAppearance(map);
135// DEBUG ON
136 m_log.WarnFormat("[SIMIAN AVATAR CONNECTOR] retrieved appearance for {0}:\n{1}",userID,appearance.ToString());
137// DEBUG OFF
138 return appearance;
139 }
140
141 m_log.WarnFormat("[SIMIAN AVATAR CONNECTOR]: Failed to decode appearance for {0}",userID);
142 return null;
143 }
144
145 m_log.WarnFormat("[SIMIAN AVATAR CONNECTOR]: Failed to get appearance for {0}: {1}",
146 userID,response["Message"].AsString());
147 return null;
148 }
149
150 // <summary>
151 // </summary>
152 // <param name=""></param>
153 public bool SetAppearance(UUID userID, AvatarAppearance appearance)
154 {
155 OSDMap map = appearance.Pack();
156 if (map == null)
157 {
158 m_log.WarnFormat("[SIMIAN AVATAR CONNECTOR]: Failed to encode appearance for {0}",userID);
159 return false;
160 }
161
162// DEBUG ON
163 m_log.WarnFormat("[SIMIAN AVATAR CONNECTOR] save appearance for {0}",userID);
164// DEBUG OFF
165
166 NameValueCollection requestArgs = new NameValueCollection
167 {
168 { "RequestMethod", "AddUserData" },
169 { "UserID", userID.ToString() },
170 { "LLPackedAppearance", OSDParser.SerializeJsonString(map) }
171 };
172
173 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
174 bool success = response["Success"].AsBoolean();
175
176 if (! success)
177 m_log.WarnFormat("[SIMIAN AVATAR CONNECTOR]: Failed to save appearance for {0}: {1}",
178 userID,response["Message"].AsString());
179
180 return success;
181 }
182
183 // <summary>
184 // </summary>
185 // <param name=""></param>
109 public AvatarData GetAvatar(UUID userID) 186 public AvatarData GetAvatar(UUID userID)
110 { 187 {
111 NameValueCollection requestArgs = new NameValueCollection 188 NameValueCollection requestArgs = new NameValueCollection
@@ -154,7 +231,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
154 foreach (KeyValuePair<string, OSD> kvp in map) 231 foreach (KeyValuePair<string, OSD> kvp in map)
155 avatar.Data[kvp.Key] = kvp.Value.AsString(); 232 avatar.Data[kvp.Key] = kvp.Value.AsString();
156 } 233 }
157 234
158 return avatar; 235 return avatar;
159 } 236 }
160 else 237 else
@@ -173,6 +250,9 @@ namespace OpenSim.Services.Connectors.SimianGrid
173 return null; 250 return null;
174 } 251 }
175 252
253 // <summary>
254 // </summary>
255 // <param name=""></param>
176 public bool SetAvatar(UUID userID, AvatarData avatar) 256 public bool SetAvatar(UUID userID, AvatarData avatar)
177 { 257 {
178 m_log.Debug("[SIMIAN AVATAR CONNECTOR]: SetAvatar called for " + userID); 258 m_log.Debug("[SIMIAN AVATAR CONNECTOR]: SetAvatar called for " + userID);
diff --git a/OpenSim/Services/Interfaces/IAvatarService.cs b/OpenSim/Services/Interfaces/IAvatarService.cs
index de3bcf9..eaa6534 100644
--- a/OpenSim/Services/Interfaces/IAvatarService.cs
+++ b/OpenSim/Services/Interfaces/IAvatarService.cs
@@ -42,6 +42,21 @@ namespace OpenSim.Services.Interfaces
42 /// </summary> 42 /// </summary>
43 /// <param name="userID"></param> 43 /// <param name="userID"></param>
44 /// <returns></returns> 44 /// <returns></returns>
45 AvatarAppearance GetAppearance(UUID userID);
46
47 /// <summary>
48 /// Called by everyone who can change the avatar data (so, regions)
49 /// </summary>
50 /// <param name="userID"></param>
51 /// <param name="appearance"></param>
52 /// <returns></returns>
53 bool SetAppearance(UUID userID, AvatarAppearance appearance);
54
55 /// <summary>
56 /// Called by the login service
57 /// </summary>
58 /// <param name="userID"></param>
59 /// <returns></returns>
45 AvatarData GetAvatar(UUID userID); 60 AvatarData GetAvatar(UUID userID);
46 61
47 /// <summary> 62 /// <summary>
@@ -163,17 +178,11 @@ namespace OpenSim.Services.Interfaces
163 Data["UnderShirtAsset"] = appearance.UnderShirtAsset.ToString(); 178 Data["UnderShirtAsset"] = appearance.UnderShirtAsset.ToString();
164 179
165 // Attachments 180 // Attachments
166 Hashtable attachs = appearance.GetAttachments(); 181 List<AvatarAttachment> attachments = appearance.GetAttachments();
167 if (attachs != null) 182 foreach (AvatarAttachment attach in attachments)
168 foreach (DictionaryEntry dentry in attachs) 183 {
169 { 184 Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString();
170 if (dentry.Value != null) 185 }
171 {
172 Hashtable tab = (Hashtable)dentry.Value;
173 if (tab.ContainsKey("item") && tab["item"] != null)
174 Data["_ap_" + dentry.Key] = tab["item"].ToString();
175 }
176 }
177 } 186 }
178 187
179 public AvatarAppearance ToAvatarAppearance(UUID owner) 188 public AvatarAppearance ToAvatarAppearance(UUID owner)
@@ -217,23 +226,26 @@ namespace OpenSim.Services.Interfaces
217 foreach (KeyValuePair<string, string> _kvp in Data) 226 foreach (KeyValuePair<string, string> _kvp in Data)
218 if (_kvp.Key.StartsWith("_ap_")) 227 if (_kvp.Key.StartsWith("_ap_"))
219 attchs[_kvp.Key] = _kvp.Value; 228 attchs[_kvp.Key] = _kvp.Value;
220 Hashtable aaAttachs = new Hashtable(); 229
221 foreach (KeyValuePair<string, string> _kvp in attchs) 230 foreach (KeyValuePair<string, string> _kvp in attchs)
222 { 231 {
223 string pointStr = _kvp.Key.Substring(4); 232 string pointStr = _kvp.Key.Substring(4);
224 int point = 0; 233 int point = 0;
225 if (!Int32.TryParse(pointStr, out point)) 234 if (!Int32.TryParse(pointStr, out point))
226 continue; 235 continue;
227 Hashtable tmp = new Hashtable(); 236
228 UUID uuid = UUID.Zero; 237 UUID uuid = UUID.Zero;
229 UUID.TryParse(_kvp.Value, out uuid); 238 UUID.TryParse(_kvp.Value, out uuid);
230 tmp["item"] = uuid; 239
231 tmp["asset"] = UUID.Zero.ToString(); 240 appearance.SetAttachment(point,uuid,UUID.Zero);
232 aaAttachs[point] = tmp;
233 } 241 }
234 appearance.SetAttachments(aaAttachs);
235 } 242 }
236 catch { } 243 catch
244 {
245 // We really should report something here, returning null
246 // will at least break the wrapper
247 return null;
248 }
237 249
238 return appearance; 250 return appearance;
239 } 251 }
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
index 127c4b2..a06476e 100644
--- a/OpenSim/Services/LLLoginService/LLLoginService.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -330,10 +330,10 @@ namespace OpenSim.Services.LLLoginService
330 // 330 //
331 // Get the avatar 331 // Get the avatar
332 // 332 //
333 AvatarData avatar = null; 333 AvatarAppearance avatar = null;
334 if (m_AvatarService != null) 334 if (m_AvatarService != null)
335 { 335 {
336 avatar = m_AvatarService.GetAvatar(account.PrincipalID); 336 avatar = m_AvatarService.GetAppearance(account.PrincipalID);
337 } 337 }
338 338
339 // 339 //
@@ -601,7 +601,7 @@ namespace OpenSim.Services.LLLoginService
601 } 601 }
602 } 602 }
603 603
604 protected AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar, 604 protected AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarAppearance avatar,
605 UUID session, UUID secureSession, Vector3 position, string currentWhere, string viewer, string channel, string mac, string id0, 605 UUID session, UUID secureSession, Vector3 position, string currentWhere, string viewer, string channel, string mac, string id0,
606 IPEndPoint clientIP, out string where, out string reason, out GridRegion dest) 606 IPEndPoint clientIP, out string where, out string reason, out GridRegion dest)
607 { 607 {
@@ -697,14 +697,14 @@ namespace OpenSim.Services.LLLoginService
697 } 697 }
698 698
699 private AgentCircuitData MakeAgent(GridRegion region, UserAccount account, 699 private AgentCircuitData MakeAgent(GridRegion region, UserAccount account,
700 AvatarData avatar, UUID session, UUID secureSession, uint circuit, Vector3 position, 700 AvatarAppearance avatar, UUID session, UUID secureSession, uint circuit, Vector3 position,
701 string ipaddress, string viewer, string channel, string mac, string id0) 701 string ipaddress, string viewer, string channel, string mac, string id0)
702 { 702 {
703 AgentCircuitData aCircuit = new AgentCircuitData(); 703 AgentCircuitData aCircuit = new AgentCircuitData();
704 704
705 aCircuit.AgentID = account.PrincipalID; 705 aCircuit.AgentID = account.PrincipalID;
706 if (avatar != null) 706 if (avatar != null)
707 aCircuit.Appearance = avatar.ToAvatarAppearance(account.PrincipalID); 707 aCircuit.Appearance = new AvatarAppearance(avatar);
708 else 708 else
709 aCircuit.Appearance = new AvatarAppearance(account.PrincipalID); 709 aCircuit.Appearance = new AvatarAppearance(account.PrincipalID);
710 710
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index e46f9b7..b2c8b35 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Tests.Common.Mock
94 94
95 public event DeRezObject OnDeRezObject; 95 public event DeRezObject OnDeRezObject;
96 public event Action<IClientAPI> OnRegionHandShakeReply; 96 public event Action<IClientAPI> OnRegionHandShakeReply;
97 public event GenericCall2 OnRequestWearables; 97 public event GenericCall1 OnRequestWearables;
98 public event GenericCall1 OnCompleteMovementToRegion; 98 public event GenericCall1 OnCompleteMovementToRegion;
99 public event UpdateAgent OnPreAgentUpdate; 99 public event UpdateAgent OnPreAgentUpdate;
100 public event UpdateAgent OnAgentUpdate; 100 public event UpdateAgent OnAgentUpdate;