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.cs987
-rw-r--r--OpenSim/Framework/AvatarAttachment.cs78
-rw-r--r--OpenSim/Framework/AvatarWearable.cs46
-rw-r--r--OpenSim/Framework/Capabilities/Caps.cs18
-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.cs26
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs390
-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/Interfaces/IAvatarFactory.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs216
-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
-rw-r--r--bin/OpenSimDefaults.ini14
-rw-r--r--bin/assets/TexturesAssetSet/TexturesAssetSet.xml6
-rw-r--r--bin/assets/TexturesAssetSet/default_alpha.jp2bin0 -> 319 bytes
-rw-r--r--bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml28
35 files changed, 1443 insertions, 873 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..a4bb765 100644
--- a/OpenSim/Framework/AvatarAppearance.cs
+++ b/OpenSim/Framework/AvatarAppearance.cs
@@ -26,59 +26,139 @@
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{
38 // A special dictionary for avatar appearance
39 public struct LayerItem
40 {
41 public UUID ItemID;
42 public UUID AssetID;
43
44 public LayerItem(UUID itemID, UUID assetID)
45 {
46 ItemID = itemID;
47 AssetID = assetID;
48 }
49 }
50
51 public class Layer
52 {
53 protected int m_layerType;
54 protected Dictionary<UUID, UUID> m_items = new Dictionary<UUID, UUID>();
55 protected List<UUID> m_ids = new List<UUID>();
56
57 public Layer(int type)
58 {
59 m_layerType = type;
60 }
61
62 public int LayerType
63 {
64 get { return m_layerType; }
65 }
66
67 public int Count
68 {
69 get { return m_ids.Count; }
70 }
71
72 public void Add(UUID itemID, UUID assetID)
73 {
74 if (m_items.ContainsKey(itemID))
75 return;
76 if (m_ids.Count >= 5)
77 return;
78
79 m_ids.Add(itemID);
80 m_items[itemID] = assetID;
81 }
82
83 public void Wear(UUID itemID, UUID assetID)
84 {
85 Clear();
86 Add(itemID, assetID);
87 }
88
89 public void Clear()
90 {
91 m_ids.Clear();
92 m_items.Clear();
93 }
94
95 public void RemoveItem(UUID itemID)
96 {
97 if (m_items.ContainsKey(itemID))
98 {
99 m_ids.Remove(itemID);
100 m_items.Remove(itemID);
101 }
102 }
103
104 public void RemoveAsset(UUID assetID)
105 {
106 UUID itemID = UUID.Zero;
107
108 foreach (KeyValuePair<UUID, UUID> kvp in m_items)
109 {
110 if (kvp.Value == assetID)
111 {
112 itemID = kvp.Key;
113 break;
114 }
115 }
116
117 if (itemID != UUID.Zero)
118 {
119 m_ids.Remove(itemID);
120 m_items.Remove(itemID);
121 }
122 }
123
124 public LayerItem this [int idx]
125 {
126 get
127 {
128 if (idx >= m_ids.Count || idx < 0)
129 return new LayerItem(UUID.Zero, UUID.Zero);
130
131 return new LayerItem(m_ids[idx], m_items[m_ids[idx]]);
132 }
133 }
134 }
135
35 /// <summary> 136 /// <summary>
36 /// Contains the Avatar's Appearance and methods to manipulate the appearance. 137 /// Contains the Avatar's Appearance and methods to manipulate the appearance.
37 /// </summary> 138 /// </summary>
38 public class AvatarAppearance 139 public class AvatarAppearance
39 { 140 {
40 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 141 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 142
72 public readonly static int VISUALPARAM_COUNT = 218; 143 public readonly static int VISUALPARAM_COUNT = 218;
73 144
145 public readonly static int TEXTURE_COUNT = 21;
146 public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
147
74 protected UUID m_owner; 148 protected UUID m_owner;
149 protected int m_serial = 1;
150 protected byte[] m_visualparams;
151 protected Primitive.TextureEntry m_texture;
152 protected AvatarWearable[] m_wearables;
153 protected Dictionary<int, List<AvatarAttachment>> m_attachments;
154 protected float m_avatarHeight = 0;
155 protected float m_hipOffset = 0;
75 156
76 public virtual UUID Owner 157 public virtual UUID Owner
77 { 158 {
78 get { return m_owner; } 159 get { return m_owner; }
79 set { m_owner = value; } 160 set { m_owner = value; }
80 } 161 }
81 protected int m_serial = 1;
82 162
83 public virtual int Serial 163 public virtual int Serial
84 { 164 {
@@ -86,15 +166,17 @@ namespace OpenSim.Framework
86 set { m_serial = value; } 166 set { m_serial = value; }
87 } 167 }
88 168
89 protected byte[] m_visualparams;
90
91 public virtual byte[] VisualParams 169 public virtual byte[] VisualParams
92 { 170 {
93 get { return m_visualparams; } 171 get { return m_visualparams; }
94 set { m_visualparams = value; } 172 set { m_visualparams = value; }
95 } 173 }
96 174
97 protected AvatarWearable[] m_wearables; 175 public virtual Primitive.TextureEntry Texture
176 {
177 get { return m_texture; }
178 set { m_texture = value; }
179 }
98 180
99 public virtual AvatarWearable[] Wearables 181 public virtual AvatarWearable[] Wearables
100 { 182 {
@@ -103,178 +185,135 @@ namespace OpenSim.Framework
103 } 185 }
104 186
105 public virtual UUID BodyItem { 187 public virtual UUID BodyItem {
106 get { return m_wearables[BODY].ItemID; } 188 get { return m_wearables[AvatarWearable.BODY].ItemID; }
107 set { m_wearables[BODY].ItemID = value; } 189 set { m_wearables[AvatarWearable.BODY].ItemID = value; }
108 } 190 }
109 191
110 public virtual UUID BodyAsset { 192 public virtual UUID BodyAsset {
111 get { return m_wearables[BODY].AssetID; } 193 get { return m_wearables[AvatarWearable.BODY].AssetID; }
112 set { m_wearables[BODY].AssetID = value; } 194 set { m_wearables[AvatarWearable.BODY].AssetID = value; }
113 } 195 }
114 196
115 public virtual UUID SkinItem { 197 public virtual UUID SkinItem {
116 get { return m_wearables[SKIN].ItemID; } 198 get { return m_wearables[AvatarWearable.SKIN].ItemID; }
117 set { m_wearables[SKIN].ItemID = value; } 199 set { m_wearables[AvatarWearable.SKIN].ItemID = value; }
118 } 200 }
119 201
120 public virtual UUID SkinAsset { 202 public virtual UUID SkinAsset {
121 get { return m_wearables[SKIN].AssetID; } 203 get { return m_wearables[AvatarWearable.SKIN].AssetID; }
122 set { m_wearables[SKIN].AssetID = value; } 204 set { m_wearables[AvatarWearable.SKIN].AssetID = value; }
123 } 205 }
124 206
125 public virtual UUID HairItem { 207 public virtual UUID HairItem {
126 get { return m_wearables[HAIR].ItemID; } 208 get { return m_wearables[AvatarWearable.HAIR].ItemID; }
127 set { m_wearables[HAIR].ItemID = value; } 209 set { m_wearables[AvatarWearable.HAIR].ItemID = value; }
128 } 210 }
129 211
130 public virtual UUID HairAsset { 212 public virtual UUID HairAsset {
131 get { return m_wearables[HAIR].AssetID; } 213 get { return m_wearables[AvatarWearable.HAIR].AssetID; }
132 set { m_wearables[HAIR].AssetID = value; } 214 set { m_wearables[AvatarWearable.HAIR].AssetID = value; }
133 } 215 }
134 216
135 public virtual UUID EyesItem { 217 public virtual UUID EyesItem {
136 get { return m_wearables[EYES].ItemID; } 218 get { return m_wearables[AvatarWearable.EYES].ItemID; }
137 set { m_wearables[EYES].ItemID = value; } 219 set { m_wearables[AvatarWearable.EYES].ItemID = value; }
138 } 220 }
139 221
140 public virtual UUID EyesAsset { 222 public virtual UUID EyesAsset {
141 get { return m_wearables[EYES].AssetID; } 223 get { return m_wearables[AvatarWearable.EYES].AssetID; }
142 set { m_wearables[EYES].AssetID = value; } 224 set { m_wearables[AvatarWearable.EYES].AssetID = value; }
143 } 225 }
144 226
145 public virtual UUID ShirtItem { 227 public virtual UUID ShirtItem {
146 get { return m_wearables[SHIRT].ItemID; } 228 get { return m_wearables[AvatarWearable.SHIRT].ItemID; }
147 set { m_wearables[SHIRT].ItemID = value; } 229 set { m_wearables[AvatarWearable.SHIRT].ItemID = value; }
148 } 230 }
149 231
150 public virtual UUID ShirtAsset { 232 public virtual UUID ShirtAsset {
151 get { return m_wearables[SHIRT].AssetID; } 233 get { return m_wearables[AvatarWearable.SHIRT].AssetID; }
152 set { m_wearables[SHIRT].AssetID = value; } 234 set { m_wearables[AvatarWearable.SHIRT].AssetID = value; }
153 } 235 }
154 236
155 public virtual UUID PantsItem { 237 public virtual UUID PantsItem {
156 get { return m_wearables[PANTS].ItemID; } 238 get { return m_wearables[AvatarWearable.PANTS].ItemID; }
157 set { m_wearables[PANTS].ItemID = value; } 239 set { m_wearables[AvatarWearable.PANTS].ItemID = value; }
158 } 240 }
159 241
160 public virtual UUID PantsAsset { 242 public virtual UUID PantsAsset {
161 get { return m_wearables[PANTS].AssetID; } 243 get { return m_wearables[AvatarWearable.PANTS].AssetID; }
162 set { m_wearables[PANTS].AssetID = value; } 244 set { m_wearables[AvatarWearable.PANTS].AssetID = value; }
163 } 245 }
164 246
165 public virtual UUID ShoesItem { 247 public virtual UUID ShoesItem {
166 get { return m_wearables[SHOES].ItemID; } 248 get { return m_wearables[AvatarWearable.SHOES].ItemID; }
167 set { m_wearables[SHOES].ItemID = value; } 249 set { m_wearables[AvatarWearable.SHOES].ItemID = value; }
168 } 250 }
169 251
170 public virtual UUID ShoesAsset { 252 public virtual UUID ShoesAsset {
171 get { return m_wearables[SHOES].AssetID; } 253 get { return m_wearables[AvatarWearable.SHOES].AssetID; }
172 set { m_wearables[SHOES].AssetID = value; } 254 set { m_wearables[AvatarWearable.SHOES].AssetID = value; }
173 } 255 }
174 256
175 public virtual UUID SocksItem { 257 public virtual UUID SocksItem {
176 get { return m_wearables[SOCKS].ItemID; } 258 get { return m_wearables[AvatarWearable.SOCKS].ItemID; }
177 set { m_wearables[SOCKS].ItemID = value; } 259 set { m_wearables[AvatarWearable.SOCKS].ItemID = value; }
178 } 260 }
179 261
180 public virtual UUID SocksAsset { 262 public virtual UUID SocksAsset {
181 get { return m_wearables[SOCKS].AssetID; } 263 get { return m_wearables[AvatarWearable.SOCKS].AssetID; }
182 set { m_wearables[SOCKS].AssetID = value; } 264 set { m_wearables[AvatarWearable.SOCKS].AssetID = value; }
183 } 265 }
184 266
185 public virtual UUID JacketItem { 267 public virtual UUID JacketItem {
186 get { return m_wearables[JACKET].ItemID; } 268 get { return m_wearables[AvatarWearable.JACKET].ItemID; }
187 set { m_wearables[JACKET].ItemID = value; } 269 set { m_wearables[AvatarWearable.JACKET].ItemID = value; }
188 } 270 }
189 271
190 public virtual UUID JacketAsset { 272 public virtual UUID JacketAsset {
191 get { return m_wearables[JACKET].AssetID; } 273 get { return m_wearables[AvatarWearable.JACKET].AssetID; }
192 set { m_wearables[JACKET].AssetID = value; } 274 set { m_wearables[AvatarWearable.JACKET].AssetID = value; }
193 } 275 }
194 276
195 public virtual UUID GlovesItem { 277 public virtual UUID GlovesItem {
196 get { return m_wearables[GLOVES].ItemID; } 278 get { return m_wearables[AvatarWearable.GLOVES].ItemID; }
197 set { m_wearables[GLOVES].ItemID = value; } 279 set { m_wearables[AvatarWearable.GLOVES].ItemID = value; }
198 } 280 }
199 281
200 public virtual UUID GlovesAsset { 282 public virtual UUID GlovesAsset {
201 get { return m_wearables[GLOVES].AssetID; } 283 get { return m_wearables[AvatarWearable.GLOVES].AssetID; }
202 set { m_wearables[GLOVES].AssetID = value; } 284 set { m_wearables[AvatarWearable.GLOVES].AssetID = value; }
203 } 285 }
204 286
205 public virtual UUID UnderShirtItem { 287 public virtual UUID UnderShirtItem {
206 get { return m_wearables[UNDERSHIRT].ItemID; } 288 get { return m_wearables[AvatarWearable.UNDERSHIRT].ItemID; }
207 set { m_wearables[UNDERSHIRT].ItemID = value; } 289 set { m_wearables[AvatarWearable.UNDERSHIRT].ItemID = value; }
208 } 290 }
209 291
210 public virtual UUID UnderShirtAsset { 292 public virtual UUID UnderShirtAsset {
211 get { return m_wearables[UNDERSHIRT].AssetID; } 293 get { return m_wearables[AvatarWearable.UNDERSHIRT].AssetID; }
212 set { m_wearables[UNDERSHIRT].AssetID = value; } 294 set { m_wearables[AvatarWearable.UNDERSHIRT].AssetID = value; }
213 } 295 }
214 296
215 public virtual UUID UnderPantsItem { 297 public virtual UUID UnderPantsItem {
216 get { return m_wearables[UNDERPANTS].ItemID; } 298 get { return m_wearables[AvatarWearable.UNDERPANTS].ItemID; }
217 set { m_wearables[UNDERPANTS].ItemID = value; } 299 set { m_wearables[AvatarWearable.UNDERPANTS].ItemID = value; }
218 } 300 }
219 301
220 public virtual UUID UnderPantsAsset { 302 public virtual UUID UnderPantsAsset {
221 get { return m_wearables[UNDERPANTS].AssetID; } 303 get { return m_wearables[AvatarWearable.UNDERPANTS].AssetID; }
222 set { m_wearables[UNDERPANTS].AssetID = value; } 304 set { m_wearables[AvatarWearable.UNDERPANTS].AssetID = value; }
223 } 305 }
224 306
225 public virtual UUID SkirtItem { 307 public virtual UUID SkirtItem {
226 get { return m_wearables[SKIRT].ItemID; } 308 get { return m_wearables[AvatarWearable.SKIRT].ItemID; }
227 set { m_wearables[SKIRT].ItemID = value; } 309 set { m_wearables[AvatarWearable.SKIRT].ItemID = value; }
228 } 310 }
229 311
230 public virtual UUID SkirtAsset { 312 public virtual UUID SkirtAsset {
231 get { return m_wearables[SKIRT].AssetID; } 313 get { return m_wearables[AvatarWearable.SKIRT].AssetID; }
232 set { m_wearables[SKIRT].AssetID = value; } 314 set { m_wearables[AvatarWearable.SKIRT].AssetID = value; }
233 } 315 }
234 316
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 }
274
275 protected float m_avatarHeight = 0;
276 protected float m_hipOffset = 0;
277
278 public virtual float AvatarHeight 317 public virtual float AvatarHeight
279 { 318 {
280 get { return m_avatarHeight; } 319 get { return m_avatarHeight; }
@@ -286,366 +325,295 @@ namespace OpenSim.Framework
286 get { return m_hipOffset; } 325 get { return m_hipOffset; }
287 } 326 }
288 327
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) {} 328 public AvatarAppearance() : this(UUID.Zero) {}
348 329
349 public AvatarAppearance(UUID owner) 330 public AvatarAppearance(UUID owner)
350 { 331 {
351 m_wearables = new AvatarWearable[MAX_WEARABLES]; 332// DEBUG ON
352 for (int i = 0; i < MAX_WEARABLES; i++) 333 m_log.WarnFormat("[AVATAR APPEARANCE] create empty appearance for {0}",owner);
353 { 334// DEBUG OFF
354 // this makes them all null 335 m_serial = 1;
355 m_wearables[i] = new AvatarWearable();
356 }
357 m_serial = 0;
358 m_owner = owner; 336 m_owner = owner;
359 //BuildVisualParamEnum() 337
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(); 338 SetDefaultWearables();
364 m_texture = GetDefaultTexture(); 339 SetDefaultTexture();
340 SetDefaultParams();
341 SetHeight();
342
343 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
365 } 344 }
366 345
367 public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, byte[] visualParams) 346 public AvatarAppearance(UUID avatarID, OSDMap map)
368 { 347 {
348// DEBUG ON
349 m_log.WarnFormat("[AVATAR APPEARANCE] create appearance for {0} from OSDMap",avatarID);
350// DEBUG OFF
369 m_owner = avatarID; 351 m_owner = avatarID;
370 m_serial = 1; 352 Unpack(map);
371 m_wearables = wearables; 353 SetHeight();
372 m_visualparams = visualParams;
373 m_texture = GetDefaultTexture();
374 } 354 }
375 355
376 /// <summary> 356 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 { 357 {
358// DEBUG ON
359 m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance for {0}",avatarID);
360// DEBUG OFF
361 m_serial = 1;
362 m_owner = avatarID;
363
364 if (wearables != null)
365 m_wearables = wearables;
366 else
367 SetDefaultWearables();
368
381 if (textureEntry != null) 369 if (textureEntry != null)
382 m_texture = textureEntry; 370 m_texture = textureEntry;
371 else
372 SetDefaultTexture();
373
383 if (visualParams != null) 374 if (visualParams != null)
384 m_visualparams = visualParams; 375 m_visualparams = visualParams;
376 else
377 SetDefaultParams();
385 378
386 m_avatarHeight = 1.23077f // Shortest possible avatar height 379 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 380
416 public virtual void SetWearable(int wearableId, AvatarWearable wearable) 381 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
417 {
418 m_wearables[wearableId] = wearable;
419 } 382 }
420 383
421 public static Primitive.TextureEntry GetDefaultTexture() 384 public AvatarAppearance(AvatarAppearance appearance)
422 { 385 {
423 Primitive.TextureEntry textu = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97")); 386// DEBUG ON
424 textu.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012"); 387 m_log.WarnFormat("[AVATAR APPEARANCE] create from an existing appearance");
425 textu.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID; 388// DEBUG OFF
426 textu.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID; 389 if (appearance == null)
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 }
433
434 public static byte[] GetDefaultVisualParams()
435 {
436 byte[] visualParams;
437 visualParams = new byte[VISUALPARAM_COUNT];
438 for (int i = 0; i < VISUALPARAM_COUNT; i++)
439 { 390 {
440 visualParams[i] = 100; 391 m_serial = 1;
441 } 392 m_owner = UUID.Zero;
442 return visualParams;
443 }
444 393
445 public override String ToString() 394 SetDefaultWearables();
446 { 395 SetDefaultTexture();
447 String s = "[Wearables] =>"; 396 SetDefaultParams();
448 s += " Body Item: " + BodyItem.ToString() + ";"; 397 SetHeight();
449 s += " Skin Item: " + SkinItem.ToString() + ";";
450 s += " Shirt Item: " + ShirtItem.ToString() + ";";
451 s += " Pants Item: " + PantsItem.ToString() + ";";
452 return s;
453 }
454 398
455 // this is used for OGS1 399 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 400
504 if (h.Contains("texture")) 401 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 } 402 }
516
517 403
518 AvatarHeight = (float)Convert.ToDouble((string)h["avatar_height"]); 404 m_serial = appearance.Serial;
405 m_owner = appearance.Owner;
519 406
520 m_wearables = new AvatarWearable[MAX_WEARABLES]; 407 m_wearables = null;
521 for (int i = 0; i < MAX_WEARABLES; i++) 408 if (appearance.Wearables != null)
522 { 409 {
523 // this makes them all null 410 m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES]; //should be 13 of these
524 m_wearables[i] = new AvatarWearable(); 411 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
412 SetWearable(i,appearance.Wearables[i]);
525 } 413 }
526 414
527 BodyItem = new UUID((string)h["body_item"]); 415 m_texture = null;
528 BodyAsset = new UUID((string)h["body_asset"]); 416 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 { 417 {
556 SetAttachmentsString(h["attachments"].ToString()); 418 byte[] tbytes = appearance.Texture.GetBytes();
419 m_texture = new Primitive.TextureEntry(tbytes,0,tbytes.Length);
557 } 420 }
421
422 m_visualparams = null;
423 if (appearance.VisualParams != null)
424 m_visualparams = (byte[])appearance.VisualParams.Clone();
425
426 // Copy the attachment, force append mode since that ensures consistency
427 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
428 foreach (AvatarAttachment attachment in appearance.GetAttachments())
429 AppendAttachment(new AvatarAttachment(attachment));
430 }
431
432 protected virtual void SetDefaultWearables()
433 {
434 m_wearables = AvatarWearable.DefaultWearables;
558 } 435 }
559 436
560 private Dictionary<int, UUID[]> m_attachments = new Dictionary<int, UUID[]>(); 437 protected virtual void SetDefaultParams()
561
562 public void SetAttachments(AttachmentData[] data)
563 { 438 {
564 foreach (AttachmentData a in data) 439 m_visualparams = new byte[VISUALPARAM_COUNT];
440 for (int i = 0; i < VISUALPARAM_COUNT; i++)
565 { 441 {
566 m_attachments[a.AttachPoint] = new UUID[2]; 442 m_visualparams[i] = 150;
567 m_attachments[a.AttachPoint][0] = a.ItemID;
568 m_attachments[a.AttachPoint][1] = a.AssetID;
569 } 443 }
570 } 444 }
571 445
572 public void SetAttachments(Hashtable data) 446 protected virtual void SetDefaultTexture()
573 { 447 {
574 m_attachments.Clear(); 448 m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
575 449 for (uint i = 0; i < TEXTURE_COUNT; i++)
576 if (data == null) 450 m_texture.CreateFace(i).TextureID = new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE);
577 return; 451 }
578 452
579 foreach (DictionaryEntry e in data) 453 /// <summary>
454 /// Set up appearance textures.
455 /// Returns boolean that indicates whether the new entries actually change the
456 /// existing values.
457 /// </summary>
458 public virtual bool SetTextureEntries(Primitive.TextureEntry textureEntry)
459 {
460 if (textureEntry == null)
461 return false;
462
463 // There are much simpler versions of this copy that could be
464 // made. We determine if any of the textures actually
465 // changed to know if the appearance should be saved later
466 bool changed = false;
467 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
580 { 468 {
581 int attachpoint = Convert.ToInt32(e.Key); 469 Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i];
582 470 Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i];
583 if (m_attachments.ContainsKey(attachpoint)) 471
584 continue; 472 if (newface == null)
473 {
474 if (oldface == null) continue;
475 }
476 else
477 {
478 if (oldface != null && oldface.TextureID == newface.TextureID) continue;
479 }
585 480
586 UUID item; 481 changed = true;
587 UUID asset; 482// DEBUG ON
483 if (newface != null)
484 m_log.WarnFormat("[AVATAR APPEARANCE] index {0}, new texture id {1}",i,newface.TextureID);
485// DEBUG OFF
486 }
588 487
589 Hashtable uuids = (Hashtable) e.Value; 488 m_texture = textureEntry;
590 UUID.TryParse(uuids["item"].ToString(), out item); 489 return changed;
591 UUID.TryParse(uuids["asset"].ToString(), out asset); 490 }
491
492 /// <summary>
493 /// Set up visual parameters for the avatar and refresh the avatar height
494 /// Returns boolean that indicates whether the new entries actually change the
495 /// existing values.
496 /// </summary>
497 public virtual bool SetVisualParams(byte[] visualParams)
498 {
499 if (visualParams == null)
500 return false;
501
502 // There are much simpler versions of this copy that could be
503 // made. We determine if any of the visual parameters actually
504 // changed to know if the appearance should be saved later
505 bool changed = false;
506 for (int i = 0; i < AvatarAppearance.VISUALPARAM_COUNT; i++)
507 {
508 if (visualParams[i] != m_visualparams[i])
509 {
510// DEBUG ON
511// m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
512// i,m_visualparams[i],visualParams[i]);
513// DEBUG OFF
514 m_visualparams[i] = visualParams[i];
515 changed = true;
516 }
517 }
592 518
593 UUID[] attachment = new UUID[2]; 519 // Reset the height if the visual parameters actually changed
594 attachment[0] = item; 520 if (changed)
595 attachment[1] = asset; 521 SetHeight();
596 522
597 m_attachments[attachpoint] = attachment; 523 return changed;
598 }
599 } 524 }
600 525
601 public Dictionary<int, UUID[]> GetAttachmentDictionary() 526 public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
602 { 527 {
603 return m_attachments; 528 SetTextureEntries(textureEntry);
529 SetVisualParams(visualParams);
604 } 530 }
531
532 public virtual void SetHeight()
533 {
534 m_avatarHeight = 1.23077f // Shortest possible avatar height
535 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
536 + 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size
537 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
538 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
539 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
540 + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length
605 541
606 public Hashtable GetAttachments() 542 m_hipOffset = (((1.23077f // Half of avatar
543 + 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
544 + 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
545 + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
546 + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
547 ) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f;
548 }
549
550 public virtual void SetWearable(int wearableId, AvatarWearable wearable)
607 { 551 {
608 if (m_attachments.Count == 0) 552// DEBUG ON
609 return null; 553// m_log.WarnFormat("[AVATARAPPEARANCE] set wearable {0} --> {1}:{2}",wearableId,wearable.ItemID,wearable.AssetID);
554// DEBUG OFF
555 m_wearables[wearableId] = new AvatarWearable(wearable.ItemID,wearable.AssetID);
556 }
610 557
611 Hashtable ret = new Hashtable();
612 558
613 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 559// DEBUG ON
614 { 560 public override String ToString()
615 int attachpoint = kvp.Key; 561 {
616 UUID[] uuids = kvp.Value; 562 String s = "";
617 563
618 Hashtable data = new Hashtable(); 564 s += String.Format("Serial: {0}\n",m_serial);
619 data["item"] = uuids[0].ToString(); 565
620 data["asset"] = uuids[1].ToString(); 566 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
567 if (m_texture.FaceTextures[i] != null)
568 s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID);
621 569
622 ret[attachpoint] = data; 570 foreach (AvatarWearable awear in m_wearables)
623 } 571 s += String.Format("Wearable: item={0}, asset={1}\n",awear.ItemID,awear.AssetID);
624 572
625 return ret; 573 s += "Visual Params: ";
574 for (uint j = 0; j < AvatarAppearance.VISUALPARAM_COUNT; j++)
575 s += String.Format("{0},",m_visualparams[j]);
576 s += "\n";
577
578 return s;
626 } 579 }
580// DEBUG OFF
627 581
628 public List<int> GetAttachedPoints() 582 /// <summary>
583 /// Get a list of the attachments, note that there may be
584 /// duplicate attachpoints
585 /// </summary>
586 public List<AvatarAttachment> GetAttachments()
629 { 587 {
630 return new List<int>(m_attachments.Keys); 588 List<AvatarAttachment> alist = new List<AvatarAttachment>();
589 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
590 {
591 foreach (AvatarAttachment attach in kvp.Value)
592 alist.Add(new AvatarAttachment(attach));
593 }
594
595 return alist;
631 } 596 }
632 597
633 public UUID GetAttachedItem(int attachpoint) 598 internal void AppendAttachment(AvatarAttachment attach)
634 { 599 {
635 if (!m_attachments.ContainsKey(attachpoint)) 600 if (! m_attachments.ContainsKey(attach.AttachPoint))
636 return UUID.Zero; 601 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
637 602 m_attachments[attach.AttachPoint].Add(attach);
638 return m_attachments[attachpoint][0];
639 } 603 }
640 604
641 public UUID GetAttachedAsset(int attachpoint) 605 internal void ReplaceAttachment(AvatarAttachment attach)
642 { 606 {
643 if (!m_attachments.ContainsKey(attachpoint)) 607 m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
644 return UUID.Zero; 608 m_attachments[attach.AttachPoint].Add(attach);
645
646 return m_attachments[attachpoint][1];
647 } 609 }
648 610
611 /// <summary>
612 /// Add an attachment, if the attachpoint has the
613 /// 0x80 bit set then we assume this is an append
614 /// operation otherwise we replace whatever is
615 /// currently attached at the attachpoint
616 /// </summary>
649 public void SetAttachment(int attachpoint, UUID item, UUID asset) 617 public void SetAttachment(int attachpoint, UUID item, UUID asset)
650 { 618 {
651 if (attachpoint == 0) 619 if (attachpoint == 0)
@@ -658,31 +626,47 @@ namespace OpenSim.Framework
658 return; 626 return;
659 } 627 }
660 628
661 if (!m_attachments.ContainsKey(attachpoint)) 629 // check if this is an append or a replace, 0x80 marks it as an append
662 m_attachments[attachpoint] = new UUID[2]; 630 if ((attachpoint & 0x80) > 0)
663 631 {
664 m_attachments[attachpoint][0] = item; 632 // strip the append bit
665 m_attachments[attachpoint][1] = asset; 633 int point = attachpoint & 0x7F;
634 AppendAttachment(new AvatarAttachment(point, item, asset));
635 }
636 else
637 {
638 ReplaceAttachment(new AvatarAttachment(attachpoint,item,asset));
639 }
666 } 640 }
667 641
668 public int GetAttachpoint(UUID itemID) 642 public int GetAttachpoint(UUID itemID)
669 { 643 {
670 foreach (KeyValuePair<int, UUID[]> kvp in m_attachments) 644 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
671 { 645 {
672 if (kvp.Value[0] == itemID) 646 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
673 { 647 if (index >= 0)
674 return kvp.Key; 648 return kvp.Key;
675 }
676 } 649 }
650
677 return 0; 651 return 0;
678 } 652 }
679 653
680 public void DetachAttachment(UUID itemID) 654 public void DetachAttachment(UUID itemID)
681 { 655 {
682 int attachpoint = GetAttachpoint(itemID); 656 foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
657 {
658 int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
659 if (index >= 0)
660 {
661 // Remove it from the list of attachments at that attach point
662 m_attachments[kvp.Key].RemoveAt(index);
683 663
684 if (attachpoint > 0) 664 // And remove the list if there are no more attachments here
685 m_attachments.Remove(attachpoint); 665 if (m_attachments[kvp.Key].Count == 0)
666 m_attachments.Remove(kvp.Key);
667 return;
668 }
669 }
686 } 670 }
687 671
688 public void ClearAttachments() 672 public void ClearAttachments()
@@ -690,42 +674,126 @@ namespace OpenSim.Framework
690 m_attachments.Clear(); 674 m_attachments.Clear();
691 } 675 }
692 676
693 string GetAttachmentsString() 677 #region Packing Functions
678
679 /// <summary>
680 /// Create an OSDMap from the appearance data
681 /// </summary>
682 public OSDMap Pack()
694 { 683 {
695 List<string> strings = new List<string>(); 684 OSDMap data = new OSDMap();
696 685
697 foreach (KeyValuePair<int, UUID[]> e in m_attachments) 686 data["serial"] = OSD.FromInteger(m_serial);
687 data["height"] = OSD.FromReal(m_avatarHeight);
688 data["hipoffset"] = OSD.FromReal(m_hipOffset);
689
690 // Wearables
691 OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
692 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
693 wears.Add(m_wearables[i].Pack());
694 data["wearables"] = wears;
695
696 // Avatar Textures
697 OSDArray textures = new OSDArray(AvatarAppearance.TEXTURE_COUNT);
698 for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
698 { 699 {
699 strings.Add(e.Key.ToString()); 700 if (m_texture.FaceTextures[i] != null)
700 strings.Add(e.Value[0].ToString()); 701 textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID));
701 strings.Add(e.Value[1].ToString()); 702 else
703 textures.Add(OSD.FromUUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE));
702 } 704 }
705 data["textures"] = textures;
706
707 // Visual Parameters
708 OSDBinary visualparams = new OSDBinary(m_visualparams);
709 data["visualparams"] = visualparams;
710
711 // Attachments
712 OSDArray attachs = new OSDArray(m_attachments.Count);
713 foreach (AvatarAttachment attach in GetAttachments())
714 attachs.Add(attach.Pack());
715 data["attachments"] = attachs;
703 716
704 return String.Join(",", strings.ToArray()); 717 return data;
705 } 718 }
706 719
707 void SetAttachmentsString(string data) 720 /// <summary>
721 /// Unpack and OSDMap and initialize the appearance
722 /// from it
723 /// </summary>
724 public void Unpack(OSDMap data)
708 { 725 {
709 string[] strings = data.Split(new char[] {','}); 726 if ((data != null) && (data["serial"] != null))
710 int i = 0; 727 m_serial = data["serial"].AsInteger();
728 if ((data != null) && (data["height"] != null))
729 m_avatarHeight = (float)data["height"].AsReal();
730 if ((data != null) && (data["hipoffset"] != null))
731 m_hipOffset = (float)data["hipoffset"].AsReal();
732
733 try
734 {
735 // Wearables
736 SetDefaultWearables();
737 if ((data != null) && (data["wearables"] != null) && (data["wearables"]).Type == OSDType.Array)
738 {
739 OSDArray wears = (OSDArray)(data["wearables"]);
740 for (int i = 0; i < wears.Count; i++)
741 m_wearables[i] = new AvatarWearable((OSDMap)wears[i]);
742 }
743 else
744 {
745 m_log.Warn("[AVATARAPPEARANCE] failed to unpack wearables");
746 }
711 747
712 m_attachments.Clear(); 748 // Avatar Textures
749 SetDefaultTexture();
750 if ((data != null) && (data["textures"] != null) && (data["textures"]).Type == OSDType.Array)
751 {
752 OSDArray textures = (OSDArray)(data["textures"]);
753 for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++)
754 {
755 UUID textureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
756 if (textures[i] != null)
757 textureID = textures[i].AsUUID();
758 m_texture.CreateFace((uint)i).TextureID = new UUID(textureID);
759 }
760 }
761 else
762 {
763 m_log.Warn("[AVATARAPPEARANCE] failed to unpack textures");
764 }
713 765
714 while (strings.Length - i > 2) 766 // Visual Parameters
715 { 767 SetDefaultParams();
716 int attachpoint = Int32.Parse(strings[i]); 768 if ((data != null) && (data["visualparams"] != null))
717 UUID item = new UUID(strings[i+1]); 769 {
718 UUID asset = new UUID(strings[i+2]); 770 if ((data["visualparams"].Type == OSDType.Binary) || (data["visualparams"].Type == OSDType.Array))
719 i += 3; 771 m_visualparams = data["visualparams"].AsBinary();
772 }
773 else
774 {
775 m_log.Warn("[AVATARAPPEARANCE] failed to unpack visual parameters");
776 }
720 777
721 if (!m_attachments.ContainsKey(attachpoint)) 778 // Attachments
779 m_attachments = new Dictionary<int, List<AvatarAttachment>>();
780 if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array)
722 { 781 {
723 m_attachments[attachpoint] = new UUID[2]; 782 OSDArray attachs = (OSDArray)(data["attachments"]);
724 m_attachments[attachpoint][0] = item; 783 for (int i = 0; i < attachs.Count; i++)
725 m_attachments[attachpoint][1] = asset; 784 AppendAttachment(new AvatarAttachment((OSDMap)attachs[i]));
726 } 785 }
727 } 786 }
787 catch (Exception e)
788 {
789 m_log.ErrorFormat("[AVATARAPPEARANCE] unpack failed badly: {0}",e.Message);
790 }
728 } 791 }
792
793 #endregion
794
795 #region VPElement
796
729 /// <summary> 797 /// <summary>
730 /// Viewer Params Array Element for AgentSetAppearance 798 /// Viewer Params Array Element for AgentSetAppearance
731 /// Generated from LibOMV's Visual Params list 799 /// Generated from LibOMV's Visual Params list
@@ -1488,5 +1556,6 @@ namespace OpenSim.Framework
1488 SKIRT_SKIRT_GREEN = 216, 1556 SKIRT_SKIRT_GREEN = 216,
1489 SKIRT_SKIRT_BLUE = 217 1557 SKIRT_SKIRT_BLUE = 217
1490 } 1558 }
1559 #endregion
1491 } 1560 }
1492} \ No newline at end of file 1561}
diff --git a/OpenSim/Framework/AvatarAttachment.cs b/OpenSim/Framework/AvatarAttachment.cs
new file mode 100644
index 0000000..c68d78d
--- /dev/null
+++ b/OpenSim/Framework/AvatarAttachment.cs
@@ -0,0 +1,78 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenMetaverse;
30using OpenMetaverse.StructuredData;
31
32namespace OpenSim.Framework
33{
34 public class AvatarAttachment
35 {
36 public int AttachPoint;
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 }
77 }
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..872de9a 100644
--- a/OpenSim/Framework/Capabilities/Caps.cs
+++ b/OpenSim/Framework/Capabilities/Caps.cs
@@ -31,6 +31,7 @@ using System.Collections.Generic;
31using System.IO; 31using System.IO;
32using System.Reflection; 32using System.Reflection;
33using log4net; 33using log4net;
34using Nini.Config;
34using OpenMetaverse; 35using OpenMetaverse;
35using OpenSim.Framework.Servers; 36using OpenSim.Framework.Servers;
36using OpenSim.Framework.Servers.HttpServer; 37using OpenSim.Framework.Servers.HttpServer;
@@ -112,6 +113,8 @@ namespace OpenSim.Framework.Capabilities
112 private string m_regionName; 113 private string m_regionName;
113 private object m_fetchLock = new Object(); 114 private object m_fetchLock = new Object();
114 115
116 private bool m_persistBakedTextures = false;
117
115 public bool SSLCaps 118 public bool SSLCaps
116 { 119 {
117 get { return m_httpListener.UseSSL; } 120 get { return m_httpListener.UseSSL; }
@@ -145,6 +148,15 @@ namespace OpenSim.Framework.Capabilities
145 148
146 m_httpListenPort = httpPort; 149 m_httpListenPort = httpPort;
147 150
151 m_persistBakedTextures = false;
152 IConfigSource config = m_Scene.Config;
153 if (config != null)
154 {
155 IConfig sconfig = config.Configs["Startup"];
156 if (sconfig != null)
157 m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures",m_persistBakedTextures);
158 }
159
148 if (httpServer != null && httpServer.UseSSL) 160 if (httpServer != null && httpServer.UseSSL)
149 { 161 {
150 m_httpListenPort = httpServer.SSLPort; 162 m_httpListenPort = httpServer.SSLPort;
@@ -976,12 +988,14 @@ namespace OpenSim.Framework.Capabilities
976 988
977 public void BakedTextureUploaded(UUID assetID, byte[] data) 989 public void BakedTextureUploaded(UUID assetID, byte[] data)
978 { 990 {
979 m_log.DebugFormat("[CAPS]: Received baked texture {0}", assetID.ToString()); 991// DEBUG ON
992 m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
993// DEBUG OFF
980 AssetBase asset; 994 AssetBase asset;
981 asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString()); 995 asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString());
982 asset.Data = data; 996 asset.Data = data;
983 asset.Temporary = true; 997 asset.Temporary = true;
984 asset.Local = true; 998 asset.Local = ! m_persistBakedTextures; // Local assets aren't persisted, non-local are
985 m_assetCache.Store(asset); 999 m_assetCache.Store(asset);
986 } 1000 }
987 1001
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..e89368a 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -123,15 +123,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
123 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); 123 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
124 124
125 // Save avatar attachment information 125 // Save avatar attachment information
126 ScenePresence presence; 126 m_log.Info(
127 if (m_scene.AvatarFactory != null && m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 127 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
128 { 128 + ", AttachmentPoint: " + AttachmentPt);
129 m_log.Info(
130 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
131 + ", AttachmentPoint: " + AttachmentPt);
132 129
133 m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); 130 if (m_scene.AvatarFactory != null)
134 } 131 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
135 } 132 }
136 } 133 }
137 catch (Exception e) 134 catch (Exception e)
@@ -383,7 +380,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
383 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */); 380 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */);
384 381
385 if (m_scene.AvatarFactory != null) 382 if (m_scene.AvatarFactory != null)
386 m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); 383 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
387 } 384 }
388 } 385 }
389 386
@@ -405,11 +402,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
405 presence.Appearance.DetachAttachment(itemID); 402 presence.Appearance.DetachAttachment(itemID);
406 403
407 // Save avatar attachment information 404 // Save avatar attachment information
405 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
408 if (m_scene.AvatarFactory != null) 406 if (m_scene.AvatarFactory != null)
409 { 407 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
410 m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
411 m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
412 }
413 } 408 }
414 409
415 DetachSingleAttachmentToInv(itemID, remoteClient); 410 DetachSingleAttachmentToInv(itemID, remoteClient);
@@ -436,9 +431,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
436 presence.Appearance.DetachAttachment(itemID); 431 presence.Appearance.DetachAttachment(itemID);
437 432
438 if (m_scene.AvatarFactory != null) 433 if (m_scene.AvatarFactory != null)
439 { 434 m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
440 m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); 435
441 }
442 part.ParentGroup.DetachToGround(); 436 part.ParentGroup.DetachToGround();
443 437
444 List<UUID> uuids = new List<UUID>(); 438 List<UUID> uuids = new List<UUID>();
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 22c8937..bfbbcf8 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -32,6 +32,10 @@ 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;
@@ -42,48 +46,42 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
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);
44 private Scene m_scene = null; 48 private Scene m_scene = null;
45 private static readonly AvatarAppearance def = new AvatarAppearance();
46
47 public bool TryGetAvatarAppearance(UUID avatarId, out AvatarAppearance appearance)
48 {
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 49
57 m_log.ErrorFormat("[APPEARANCE]: Appearance not found for {0}, creating default", avatarId); 50 private int m_savetime = 5; // seconds to wait before saving changed appearance
58 appearance = CreateDefault(avatarId); 51 private int m_sendtime = 2; // seconds to wait before sending changed appearance
59 return false;
60 }
61 52
62 private AvatarAppearance CreateDefault(UUID avatarId) 53 private int m_checkTime = 500; // milliseconds to wait between checks for appearance updates
63 { 54 private System.Timers.Timer m_updateTimer = new System.Timers.Timer();
64 AvatarAppearance appearance = null; 55 private Dictionary<UUID,long> m_savequeue = new Dictionary<UUID,long>();
65 AvatarWearable[] wearables; 56 private Dictionary<UUID,long> m_sendqueue = new Dictionary<UUID,long>();
66 byte[] visualParams;
67 GetDefaultAvatarAppearance(out wearables, out visualParams);
68 appearance = new AvatarAppearance(avatarId, wearables, visualParams);
69 57
70 return appearance; 58 #region RegionModule Members
71 }
72 59
73 public void Initialise(Scene scene, IConfigSource source) 60 public void Initialise(Scene scene, IConfigSource config)
74 { 61 {
75 scene.RegisterModuleInterface<IAvatarFactory>(this); 62 scene.RegisterModuleInterface<IAvatarFactory>(this);
76 scene.EventManager.OnNewClient += NewClient; 63 scene.EventManager.OnNewClient += NewClient;
77 64
78 if (m_scene == null) 65 if (config != null)
79 { 66 {
80 m_scene = scene; 67 IConfig sconfig = config.Configs["Startup"];
68 if (sconfig != null)
69 {
70 m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
71 m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
72 }
81 } 73 }
82 74
75 if (m_scene == null)
76 m_scene = scene;
83 } 77 }
84 78
85 public void PostInitialise() 79 public void PostInitialise()
86 { 80 {
81 m_updateTimer.Enabled = false;
82 m_updateTimer.AutoReset = true;
83 m_updateTimer.Interval = m_checkTime; // 500 milliseconds wait to start async ops
84 m_updateTimer.Elapsed += new ElapsedEventHandler(HandleAppearanceUpdateTimer);
87 } 85 }
88 86
89 public void Close() 87 public void Close()
@@ -102,6 +100,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
102 100
103 public void NewClient(IClientAPI client) 101 public void NewClient(IClientAPI client)
104 { 102 {
103 client.OnRequestWearables += SendWearables;
104 client.OnSetAppearance += SetAppearance;
105 client.OnAvatarNowWearing += AvatarIsWearing; 105 client.OnAvatarNowWearing += AvatarIsWearing;
106 } 106 }
107 107
@@ -110,42 +110,243 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
110 // client.OnAvatarNowWearing -= AvatarIsWearing; 110 // client.OnAvatarNowWearing -= AvatarIsWearing;
111 } 111 }
112 112
113 public void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) 113 #endregion
114
115 public bool ValidateBakedTextureCache(IClientAPI client)
114 { 116 {
115 IInventoryService invService = m_scene.InventoryService; 117 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
118 if (sp == null)
119 {
120 m_log.WarnFormat("[AVFACTORY] SetAppearance unable to find presence for {0}",client.AgentId);
121 return false;
122 }
116 123
117 if (invService.GetRootFolder(userID) != null) 124 bool cached = true;
125
126 // Process the texture entry
127 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
118 { 128 {
119 for (int i = 0; i < 13; i++) 129 int idx = AvatarAppearance.BAKE_INDICES[i];
120 { 130 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
121 if (appearance.Wearables[i].ItemID == UUID.Zero) 131 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
132 if (! CheckBakedTextureAsset(client,face.TextureID,idx))
122 { 133 {
123 appearance.Wearables[i].AssetID = UUID.Zero; 134 sp.Appearance.Texture.FaceTextures[idx] = null;
135 cached = false;
124 } 136 }
125 else 137 }
138
139 return cached;
140 }
141
142
143 /// <summary>
144 /// Set appearance data (textureentry and slider settings) received from the client
145 /// </summary>
146 /// <param name="texture"></param>
147 /// <param name="visualParam"></param>
148 public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
149 {
150// DEBUG ON
151 m_log.WarnFormat("[AVFACTORY] SetAppearance for {0}",client.AgentId);
152// DEBUG OFF
153
154 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
155 if (sp == null)
156 {
157 m_log.WarnFormat("[AVFACTORY] SetAppearance unable to find presence for {0}",client.AgentId);
158 return;
159 }
160
161 bool changed = false;
162
163 // Process the texture entry
164 if (textureEntry != null)
165 {
166 changed = sp.Appearance.SetTextureEntries(textureEntry);
167
168 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
169 {
170 int idx = AvatarAppearance.BAKE_INDICES[i];
171 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
172 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
173 Util.FireAndForget(delegate(object o) {
174 if (! CheckBakedTextureAsset(client,face.TextureID,idx))
175 client.SendRebakeAvatarTextures(face.TextureID);
176 });
177 }
178 }
179
180 // Process the visual params, this may change height as well
181 if (visualParams != null)
182 {
183 if (sp.Appearance.SetVisualParams(visualParams))
184 {
185 changed = true;
186 if (sp.Appearance.AvatarHeight > 0)
187 sp.SetHeight(sp.Appearance.AvatarHeight);
188 }
189 }
190
191 // If something changed in the appearance then queue an appearance save
192 if (changed)
193 QueueAppearanceSave(client.AgentId);
194
195 // And always queue up an appearance update to send out
196 QueueAppearanceSend(client.AgentId);
197
198 // Send the appearance back to the avatar
199 // AvatarAppearance avp = sp.Appearance;
200 // sp.ControllingClient.SendAvatarDataImmediate(sp);
201 // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
202 }
203
204 /// <summary>
205 /// Checks for the existance of a baked texture asset and
206 /// requests the viewer rebake if the asset is not found
207 /// </summary>
208 /// <param name="client"></param>
209 /// <param name="textureID"></param>
210 /// <param name="idx"></param>
211 private bool CheckBakedTextureAsset(IClientAPI client, UUID textureID, int idx)
212 {
213 if (m_scene.AssetService.Get(textureID.ToString()) == null)
214 {
215 m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",
216 textureID,idx,client.Name);
217 return false;
218 }
219 return true;
220 }
221
222 #region UpdateAppearanceTimer
223
224 public void QueueAppearanceSend(UUID agentid)
225 {
226// DEBUG ON
227 m_log.WarnFormat("[AVFACTORY] Queue appearance send for {0}",agentid);
228// DEBUG OFF
229
230 // 100 nanoseconds (ticks) we should wait
231 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 10000000);
232 lock (m_sendqueue)
233 {
234 m_sendqueue[agentid] = timestamp;
235 m_updateTimer.Start();
236 }
237 }
238
239 public void QueueAppearanceSave(UUID agentid)
240 {
241// DEBUG ON
242 m_log.WarnFormat("[AVFACTORY] Queue appearance save for {0}",agentid);
243// DEBUG OFF
244
245 // 100 nanoseconds (ticks) we should wait
246 long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 10000000);
247 lock (m_savequeue)
248 {
249 m_savequeue[agentid] = timestamp;
250 m_updateTimer.Start();
251 }
252 }
253
254 private void HandleAppearanceSend(UUID agentid)
255 {
256 ScenePresence sp = m_scene.GetScenePresence(agentid);
257 if (sp == null)
258 {
259 m_log.WarnFormat("[AVFACTORY] Agent {0} no longer in the scene",agentid);
260 return;
261 }
262
263// DEBUG ON
264 m_log.WarnFormat("[AVFACTORY] Handle appearance send for {0}",agentid);
265// DEBUG OFF
266
267 // Send the appearance to everyone in the scene
268 sp.SendAppearanceToAllOtherAgents();
269 sp.ControllingClient.SendAvatarDataImmediate(sp);
270
271 // Send the appearance back to the avatar
272 // AvatarAppearance avp = sp.Appearance;
273 // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
274
275/*
276// this needs to be fixed, the flag should be on scene presence not the region module
277 // Start the animations if necessary
278 if (!m_startAnimationSet)
279 {
280 sp.Animator.UpdateMovementAnimations();
281 m_startAnimationSet = true;
282 }
283*/
284 }
285
286 private void HandleAppearanceSave(UUID agentid)
287 {
288 ScenePresence sp = m_scene.GetScenePresence(agentid);
289 if (sp == null)
290 {
291 m_log.WarnFormat("[AVFACTORY] Agent {0} no longer in the scene",agentid);
292 return;
293 }
294
295 m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
296 }
297
298 private void HandleAppearanceUpdateTimer(object sender, EventArgs ea)
299 {
300 long now = DateTime.Now.Ticks;
301
302 lock (m_sendqueue)
303 {
304 Dictionary<UUID,long> sends = new Dictionary<UUID,long>(m_sendqueue);
305 foreach (KeyValuePair<UUID,long> kvp in sends)
306 {
307 if (kvp.Value < now)
126 { 308 {
127 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i].ItemID, userID); 309 Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); });
128 baseItem = invService.GetItem(baseItem); 310 m_sendqueue.Remove(kvp.Key);
311 }
312 }
313 }
129 314
130 if (baseItem != null) 315 lock (m_savequeue)
131 { 316 {
132 appearance.Wearables[i].AssetID = baseItem.AssetID; 317 Dictionary<UUID,long> saves = new Dictionary<UUID,long>(m_savequeue);
133 } 318 foreach (KeyValuePair<UUID,long> kvp in saves)
134 else 319 {
135 { 320 if (kvp.Value < now)
136 m_log.ErrorFormat( 321 {
137 "[APPEARANCE]: Can't find inventory item {0} for {1}, setting to default", 322 Util.FireAndForget(delegate(object o) { HandleAppearanceSave(kvp.Key); });
138 appearance.Wearables[i].ItemID, (WearableType)i); 323 m_savequeue.Remove(kvp.Key);
139
140 appearance.Wearables[i].AssetID = def.Wearables[i].AssetID;
141 }
142 } 324 }
143 } 325 }
144 } 326 }
145 else 327
328 if (m_savequeue.Count == 0 && m_sendqueue.Count == 0)
329 m_updateTimer.Stop();
330 }
331
332 #endregion
333
334 /// <summary>
335 /// Tell the client for this scene presence what items it should be wearing now
336 /// </summary>
337 public void SendWearables(IClientAPI client)
338 {
339 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
340 if (sp == null)
146 { 341 {
147 m_log.WarnFormat("[APPEARANCE]: user {0} has no inventory, appearance isn't going to work", userID); 342 m_log.WarnFormat("[AVFACTORY] SendWearables unable to find presence for {0}",client.AgentId);
343 return;
148 } 344 }
345
346// DEBUG ON
347 m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId);
348// DEBUG OFF
349 client.SendWearables(sp.Appearance.Wearables,sp.Appearance.Serial++);
149 } 350 }
150 351
151 /// <summary> 352 /// <summary>
@@ -153,65 +354,74 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
153 /// </summary> 354 /// </summary>
154 /// <param name="sender"></param> 355 /// <param name="sender"></param>
155 /// <param name="e"></param> 356 /// <param name="e"></param>
156 public void AvatarIsWearing(Object sender, AvatarWearingArgs e) 357 public void AvatarIsWearing(IClientAPI client, AvatarWearingArgs e)
157 { 358 {
158 m_log.DebugFormat("[APPEARANCE]: AvatarIsWearing"); 359 ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
159 360 if (sp == null)
160 IClientAPI clientView = (IClientAPI)sender;
161 ScenePresence sp = m_scene.GetScenePresence(clientView.AgentId);
162
163 if (sp == null)
164 { 361 {
165 m_log.Error("[APPEARANCE]: Avatar is child agent, ignoring AvatarIsWearing event"); 362 m_log.WarnFormat("[AVFACTORY] AvatarIsWearing unable to find presence for {0}",client.AgentId);
166 return; 363 return;
167 } 364 }
168
169 AvatarAppearance avatAppearance = sp.Appearance;
170 //if (!TryGetAvatarAppearance(clientView.AgentId, out avatAppearance))
171 //{
172 // m_log.Warn("[APPEARANCE]: We didn't seem to find the appearance, falling back to ScenePresence");
173 // avatAppearance = sp.Appearance;
174 //}
175
176 //m_log.DebugFormat("[APPEARANCE]: Received wearables for {0}", clientView.Name);
177 365
366// DEBUG ON
367 m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}",client.AgentId);
368// DEBUG OFF
369
370 AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance);
371
178 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) 372 foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
179 { 373 {
180 if (wear.Type < 13) 374 if (wear.Type < AvatarWearable.MAX_WEARABLES)
181 { 375 {
182 avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID; 376 AvatarWearable newWearable = new AvatarWearable(wear.ItemID,UUID.Zero);
377 avatAppearance.SetWearable(wear.Type, newWearable);
183 } 378 }
184 } 379 }
185 380
381 // This could take awhile since it needs to pull inventory
186 SetAppearanceAssets(sp.UUID, ref avatAppearance); 382 SetAppearanceAssets(sp.UUID, ref avatAppearance);
187 AvatarData adata = new AvatarData(avatAppearance);
188 m_scene.AvatarService.SetAvatar(clientView.AgentId, adata);
189 383
190 sp.Appearance = avatAppearance; 384 sp.Appearance = avatAppearance;
385 m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance);
191 } 386 }
192 387
193 public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams) 388 private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
194 { 389 {
195 visualParams = GetDefaultVisualParams(); 390 IInventoryService invService = m_scene.InventoryService;
196 wearables = AvatarWearable.DefaultWearables;
197 }
198 391
199 public void UpdateDatabase(UUID user, AvatarAppearance appearance) 392 if (invService.GetRootFolder(userID) != null)
200 { 393 {
201 //m_log.DebugFormat("[APPEARANCE]: UpdateDatabase"); 394 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
202 AvatarData adata = new AvatarData(appearance); 395 {
203 m_scene.AvatarService.SetAvatar(user, adata); 396 if (appearance.Wearables[i].ItemID == UUID.Zero)
204 } 397 {
398 appearance.Wearables[i].AssetID = UUID.Zero;
399 }
400 else
401 {
402 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i].ItemID, userID);
403 baseItem = invService.GetItem(baseItem);
205 404
206 private static byte[] GetDefaultVisualParams() 405 if (baseItem != null)
207 { 406 {
208 byte[] visualParams; 407 appearance.Wearables[i].AssetID = baseItem.AssetID;
209 visualParams = new byte[218]; 408 }
210 for (int i = 0; i < 218; i++) 409 else
410 {
411 m_log.ErrorFormat(
412 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
413 appearance.Wearables[i].ItemID, (WearableType)i);
414
415 appearance.Wearables[i].ItemID = UUID.Zero;
416 appearance.Wearables[i].AssetID = UUID.Zero;
417 }
418 }
419 }
420 }
421 else
211 { 422 {
212 visualParams[i] = 100; 423 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
213 } 424 }
214 return visualParams;
215 } 425 }
216 } 426 }
217} 427}
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/Interfaces/IAvatarFactory.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs
index c967f30..22795fc 100644
--- a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs
@@ -32,7 +32,8 @@ namespace OpenSim.Region.Framework.Interfaces
32{ 32{
33 public interface IAvatarFactory 33 public interface IAvatarFactory
34 { 34 {
35 bool TryGetAvatarAppearance(UUID avatarId, out AvatarAppearance appearance); 35 bool ValidateBakedTextureCache(IClientAPI client);
36 void UpdateDatabase(UUID userID, AvatarAppearance avatAppearance); 36 void QueueAppearanceSend(UUID agentid);
37 void QueueAppearanceSave(UUID agentid);
37 } 38 }
38} 39}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index f0ae45e..3343d08 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -403,7 +403,7 @@ namespace OpenSim.Region.Framework.Scenes
403 { 403 {
404 get { return m_AvatarFactory; } 404 get { return m_AvatarFactory; }
405 } 405 }
406 406
407 public ICapabilitiesModule CapsModule 407 public ICapabilitiesModule CapsModule
408 { 408 {
409 get { return m_capsModule; } 409 get { return m_capsModule; }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 03aa8cf..1fc3ed6 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;
@@ -707,19 +704,14 @@ namespace OpenSim.Region.Framework.Scenes
707 // we created a new ScenePresence (a new child agent) in a fresh region. 704 // we created a new ScenePresence (a new child agent) in a fresh region.
708 // Request info about all the (root) agents in this region 705 // Request info about all the (root) agents in this region
709 // Note: This won't send data *to* other clients in that region (children don't send) 706 // Note: This won't send data *to* other clients in that region (children don't send)
707
708// MIC: This gets called again in CompleteMovement
710 SendInitialFullUpdateToAllClients(); 709 SendInitialFullUpdateToAllClients();
711 710
712 RegisterToEvents(); 711 RegisterToEvents();
713 SetDirectionVectors(); 712 SetDirectionVectors();
714 } 713 }
715 714
716 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams,
717 AvatarWearable[] wearables)
718 : this(client, world, reginfo)
719 {
720 m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams);
721 }
722
723 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) 715 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
724 : this(client, world, reginfo) 716 : this(client, world, reginfo)
725 { 717 {
@@ -733,8 +725,6 @@ namespace OpenSim.Region.Framework.Scenes
733 725
734 public void RegisterToEvents() 726 public void RegisterToEvents()
735 { 727 {
736 m_controllingClient.OnRequestWearables += SendWearables;
737 m_controllingClient.OnSetAppearance += SetAppearance;
738 m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; 728 m_controllingClient.OnCompleteMovementToRegion += CompleteMovement;
739 //m_controllingClient.OnCompleteMovementToRegion += SendInitialData; 729 //m_controllingClient.OnCompleteMovementToRegion += SendInitialData;
740 m_controllingClient.OnAgentUpdate += HandleAgentUpdate; 730 m_controllingClient.OnAgentUpdate += HandleAgentUpdate;
@@ -1068,7 +1058,7 @@ namespace OpenSim.Region.Framework.Scenes
1068 /// <summary> 1058 /// <summary>
1069 /// Sets avatar height in the phyiscs plugin 1059 /// Sets avatar height in the phyiscs plugin
1070 /// </summary> 1060 /// </summary>
1071 internal void SetHeight(float height) 1061 public void SetHeight(float height)
1072 { 1062 {
1073 m_avHeight = height; 1063 m_avHeight = height;
1074 if (PhysicsActor != null && !IsChildAgent) 1064 if (PhysicsActor != null && !IsChildAgent)
@@ -2393,15 +2383,26 @@ namespace OpenSim.Region.Framework.Scenes
2393 // 2 stage check is needed. 2383 // 2 stage check is needed.
2394 if (remoteAvatar == null) 2384 if (remoteAvatar == null)
2395 return; 2385 return;
2386
2396 IClientAPI cl=remoteAvatar.ControllingClient; 2387 IClientAPI cl=remoteAvatar.ControllingClient;
2397 if (cl == null) 2388 if (cl == null)
2398 return; 2389 return;
2390
2399 if (m_appearance.Texture == null) 2391 if (m_appearance.Texture == null)
2400 return; 2392 return;
2401 2393
2402 Vector3 pos = m_pos; 2394 if (LocalId == remoteAvatar.LocalId)
2403 pos.Z += m_appearance.HipOffset; 2395 {
2396 m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID);
2397 return;
2398 }
2404 2399
2400 if (IsChildAgent)
2401 {
2402 m_log.WarnFormat("[SCENEPRESENCE] A child agent is attempting to send out avatar data");
2403 return;
2404 }
2405
2405 remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); 2406 remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this);
2406 m_scene.StatsReporter.AddAgentUpdates(1); 2407 m_scene.StatsReporter.AddAgentUpdates(1);
2407 } 2408 }
@@ -2416,20 +2417,23 @@ namespace OpenSim.Region.Framework.Scenes
2416 m_scene.ForEachScenePresence(delegate(ScenePresence avatar) 2417 m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
2417 { 2418 {
2418 ++avUpdates; 2419 ++avUpdates;
2419 // only send if this is the root (children are only "listening posts" in a foreign region) 2420
2421 // Don't update ourselves
2422 if (avatar.LocalId == LocalId)
2423 return;
2424
2425 // If this is a root agent, then get info about the avatar
2420 if (!IsChildAgent) 2426 if (!IsChildAgent)
2421 { 2427 {
2422 SendFullUpdateToOtherClient(avatar); 2428 SendFullUpdateToOtherClient(avatar);
2423 } 2429 }
2424 2430
2425 if (avatar.LocalId != LocalId) 2431 // If the other avatar is a root
2432 if (!avatar.IsChildAgent)
2426 { 2433 {
2427 if (!avatar.IsChildAgent) 2434 avatar.SendFullUpdateToOtherClient(this);
2428 { 2435 avatar.SendAppearanceToOtherAgent(this);
2429 avatar.SendFullUpdateToOtherClient(this); 2436 avatar.Animator.SendAnimPackToClient(ControllingClient);
2430 avatar.SendAppearanceToOtherAgent(this);
2431 avatar.Animator.SendAnimPackToClient(ControllingClient);
2432 }
2433 } 2437 }
2434 }); 2438 });
2435 2439
@@ -2444,6 +2448,12 @@ namespace OpenSim.Region.Framework.Scenes
2444 m_perfMonMS = Util.EnvironmentTickCount(); 2448 m_perfMonMS = Util.EnvironmentTickCount();
2445 2449
2446 // only send update from root agents to other clients; children are only "listening posts" 2450 // only send update from root agents to other clients; children are only "listening posts"
2451 if (IsChildAgent)
2452 {
2453 m_log.Warn("[SCENEPRESENCE] attempt to send update from a childagent");
2454 return;
2455 }
2456
2447 int count = 0; 2457 int count = 0;
2448 m_scene.ForEachScenePresence(delegate(ScenePresence sp) 2458 m_scene.ForEachScenePresence(delegate(ScenePresence sp)
2449 { 2459 {
@@ -2467,29 +2477,32 @@ namespace OpenSim.Region.Framework.Scenes
2467 // the inventory arrives 2477 // the inventory arrives
2468 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); 2478 // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
2469 2479
2470 Vector3 pos = m_pos;
2471 pos.Z += m_appearance.HipOffset;
2472
2473 m_controllingClient.SendAvatarDataImmediate(this); 2480 m_controllingClient.SendAvatarDataImmediate(this);
2481 if (m_scene.AvatarFactory != null)
2482 {
2483 if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient))
2484 {
2485 m_log.WarnFormat("[SP] baked textures are in the ache for {0}",Name);
2486 m_controllingClient.SendAppearance(
2487 m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes());
2488 }
2489 }
2490 else
2491 {
2492 m_log.WarnFormat("[SP] AvatarFactory not set");
2493 }
2474 2494
2475 SendInitialFullUpdateToAllClients(); 2495 SendInitialFullUpdateToAllClients();
2476 } 2496 }
2477 2497
2478 /// <summary> 2498 /// <summary>
2479 /// Tell the client for this scene presence what items it should be wearing now
2480 /// </summary>
2481 public void SendWearables()
2482 {
2483 m_log.DebugFormat("[SCENE]: Received request for wearables of {0}", Name);
2484
2485 ControllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++);
2486 }
2487
2488 /// <summary>
2489 /// 2499 ///
2490 /// </summary> 2500 /// </summary>
2491 public void SendAppearanceToAllOtherAgents() 2501 public void SendAppearanceToAllOtherAgents()
2492 { 2502 {
2503// DEBUG ON
2504 m_log.WarnFormat("[SP] Send appearance from {0} to all other agents",m_uuid);
2505// DEBUG OFF
2493 m_perfMonMS = Util.EnvironmentTickCount(); 2506 m_perfMonMS = Util.EnvironmentTickCount();
2494 2507
2495 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 2508 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
@@ -2509,85 +2522,18 @@ namespace OpenSim.Region.Framework.Scenes
2509 /// <param name="avatar"></param> 2522 /// <param name="avatar"></param>
2510 public void SendAppearanceToOtherAgent(ScenePresence avatar) 2523 public void SendAppearanceToOtherAgent(ScenePresence avatar)
2511 { 2524 {
2512 avatar.ControllingClient.SendAppearance( 2525 if (LocalId == avatar.LocalId)
2513 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
2514 }
2515
2516 /// <summary>
2517 /// Set appearance data (textureentry and slider settings) received from the client
2518 /// </summary>
2519 /// <param name="texture"></param>
2520 /// <param name="visualParam"></param>
2521 public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams)
2522 {
2523 if (m_physicsActor != null)
2524 {
2525 if (!IsChildAgent)
2526 {
2527 // This may seem like it's redundant, remove the avatar from the physics scene
2528 // just to add it back again, but it saves us from having to update
2529 // 3 variables 10 times a second.
2530 bool flyingTemp = m_physicsActor.Flying;
2531 RemoveFromPhysicalScene();
2532 //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor);
2533
2534 //PhysicsActor = null;
2535
2536 AddToPhysicalScene(flyingTemp);
2537 }
2538 }
2539
2540 #region Bake Cache Check
2541
2542 if (textureEntry != null)
2543 {
2544 for (int i = 0; i < BAKE_INDICES.Length; i++)
2545 {
2546 int j = BAKE_INDICES[i];
2547 Primitive.TextureEntryFace face = textureEntry.FaceTextures[j];
2548
2549 if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
2550 {
2551 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
2552 {
2553 m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + this.Name);
2554 this.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
2555 }
2556 }
2557 }
2558
2559 }
2560
2561
2562 #endregion Bake Cache Check
2563
2564 m_appearance.SetAppearance(textureEntry, visualParams);
2565 if (m_appearance.AvatarHeight > 0)
2566 SetHeight(m_appearance.AvatarHeight);
2567
2568 // This is not needed, because only the transient data changed
2569 //AvatarData adata = new AvatarData(m_appearance);
2570 //m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata);
2571
2572 SendAppearanceToAllOtherAgents();
2573 if (!m_startAnimationSet)
2574 { 2526 {
2575 Animator.UpdateMovementAnimations(); 2527 m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID);
2576 m_startAnimationSet = true; 2528 return;
2577 } 2529 }
2578 2530
2579 Vector3 pos = m_pos; 2531// DEBUG ON
2580 pos.Z += m_appearance.HipOffset; 2532// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId);
2581 2533// DEBUG OFF
2582 m_controllingClient.SendAvatarDataImmediate(this);
2583 }
2584 2534
2585 public void SetWearable(int wearableId, AvatarWearable wearable) 2535 avatar.ControllingClient.SendAppearance(
2586 { 2536 m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
2587 m_appearance.SetWearable(wearableId, wearable);
2588 AvatarData adata = new AvatarData(m_appearance);
2589 m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata);
2590 m_controllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++);
2591 } 2537 }
2592 2538
2593 // Because appearance setting is in a module, we actually need 2539 // Because appearance setting is in a module, we actually need
@@ -2983,6 +2929,8 @@ namespace OpenSim.Region.Framework.Scenes
2983 2929
2984 public void CopyTo(AgentData cAgent) 2930 public void CopyTo(AgentData cAgent)
2985 { 2931 {
2932 cAgent.CallbackURI = m_callbackURI;
2933
2986 cAgent.AgentID = UUID; 2934 cAgent.AgentID = UUID;
2987 cAgent.RegionID = Scene.RegionInfo.RegionID; 2935 cAgent.RegionID = Scene.RegionInfo.RegionID;
2988 2936
@@ -3022,6 +2970,9 @@ namespace OpenSim.Region.Framework.Scenes
3022 2970
3023 cAgent.AlwaysRun = m_setAlwaysRun; 2971 cAgent.AlwaysRun = m_setAlwaysRun;
3024 2972
2973 cAgent.Appearance = new AvatarAppearance(m_appearance);
2974
2975/*
3025 try 2976 try
3026 { 2977 {
3027 // We might not pass the Wearables in all cases... 2978 // We might not pass the Wearables in all cases...
@@ -3061,14 +3012,14 @@ namespace OpenSim.Region.Framework.Scenes
3061 { 3012 {
3062 //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); 3013 //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count);
3063 int i = 0; 3014 int i = 0;
3064 AttachmentData[] attachs = new AttachmentData[attPoints.Count]; 3015 AvatarAttachment[] attachs = new AvatarAttachment[attPoints.Count];
3065 foreach (int point in attPoints) 3016 foreach (int point in attPoints)
3066 { 3017 {
3067 attachs[i++] = new AttachmentData(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); 3018 attachs[i++] = new AvatarAttachment(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point));
3068 } 3019 }
3069 cAgent.Attachments = attachs; 3020 cAgent.Attachments = attachs;
3070 } 3021 }
3071 3022*/
3072 lock (scriptedcontrols) 3023 lock (scriptedcontrols)
3073 { 3024 {
3074 ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; 3025 ControllerData[] controls = new ControllerData[scriptedcontrols.Count];
@@ -3095,6 +3046,9 @@ namespace OpenSim.Region.Framework.Scenes
3095 3046
3096 public void CopyFrom(AgentData cAgent) 3047 public void CopyFrom(AgentData cAgent)
3097 { 3048 {
3049// DEBUG ON
3050 m_log.ErrorFormat("[SCENEPRESENCE] CALLING COPYFROM");
3051// DEBUG OFF
3098 m_originRegionID = cAgent.RegionID; 3052 m_originRegionID = cAgent.RegionID;
3099 3053
3100 m_callbackURI = cAgent.CallbackURI; 3054 m_callbackURI = cAgent.CallbackURI;
@@ -3120,6 +3074,9 @@ namespace OpenSim.Region.Framework.Scenes
3120 m_godLevel = cAgent.GodLevel; 3074 m_godLevel = cAgent.GodLevel;
3121 m_setAlwaysRun = cAgent.AlwaysRun; 3075 m_setAlwaysRun = cAgent.AlwaysRun;
3122 3076
3077 m_appearance = new AvatarAppearance(cAgent.Appearance);
3078
3079/*
3123 uint i = 0; 3080 uint i = 0;
3124 try 3081 try
3125 { 3082 {
@@ -3132,15 +3089,17 @@ namespace OpenSim.Region.Framework.Scenes
3132 UUID assetId = cAgent.Wearables[n + 1]; 3089 UUID assetId = cAgent.Wearables[n + 1];
3133 wears[i++] = new AvatarWearable(itemId, assetId); 3090 wears[i++] = new AvatarWearable(itemId, assetId);
3134 } 3091 }
3135 m_appearance.Wearables = wears; 3092 // m_appearance.Wearables = wears;
3136 Primitive.TextureEntry te; 3093 Primitive.TextureEntry textures = null;
3137 if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) 3094 if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1)
3138 te = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); 3095 textures = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length);
3139 else 3096
3140 te = AvatarAppearance.GetDefaultTexture(); 3097 byte[] visuals = null;
3141 if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) 3098
3142 cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams(); 3099 if ((cAgent.VisualParams != null) && (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT))
3143 m_appearance.SetAppearance(te, (byte[])cAgent.VisualParams.Clone()); 3100 visuals = (byte[])cAgent.VisualParams.Clone();
3101
3102 m_appearance = new AvatarAppearance(cAgent.AgentID,wears,textures,visuals);
3144 } 3103 }
3145 catch (Exception e) 3104 catch (Exception e)
3146 { 3105 {
@@ -3153,14 +3112,14 @@ namespace OpenSim.Region.Framework.Scenes
3153 if (cAgent.Attachments != null) 3112 if (cAgent.Attachments != null)
3154 { 3113 {
3155 m_appearance.ClearAttachments(); 3114 m_appearance.ClearAttachments();
3156 foreach (AttachmentData att in cAgent.Attachments) 3115 foreach (AvatarAttachment att in cAgent.Attachments)
3157 { 3116 {
3158 m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); 3117 m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID);
3159 } 3118 }
3160 } 3119 }
3161 } 3120 }
3162 catch { } 3121 catch { }
3163 3122*/
3164 try 3123 try
3165 { 3124 {
3166 lock (scriptedcontrols) 3125 lock (scriptedcontrols)
@@ -3729,15 +3688,16 @@ namespace OpenSim.Region.Framework.Scenes
3729 return; 3688 return;
3730 } 3689 }
3731 3690
3732 List<int> attPoints = m_appearance.GetAttachedPoints(); 3691 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
3733 foreach (int p in attPoints) 3692 foreach (AvatarAttachment attach in attachments)
3734 { 3693 {
3735 if (m_isDeleted) 3694 if (m_isDeleted)
3736 return; 3695 return;
3737 3696
3738 UUID itemID = m_appearance.GetAttachedItem(p); 3697 int p = attach.AttachPoint;
3698 UUID itemID = attach.ItemID;
3739 3699
3740 //UUID assetID = m_appearance.GetAttachedAsset(p); 3700 //UUID assetID = attach.AssetID;
3741 // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down 3701 // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down
3742 // But they're not used anyway, the item is being looked up for now, so let's proceed. 3702 // But they're not used anyway, the item is being looked up for now, so let's proceed.
3743 //if (UUID.Zero == assetID) 3703 //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;
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 82267ed..5ced7d5 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -255,6 +255,20 @@
255 ; OpenJPEG if false 255 ; OpenJPEG if false
256 ; UseCSJ2K = true 256 ; UseCSJ2K = true
257 257
258 ; Persist avatar baked textures
259 ; Persisting baked textures can speed up login and region border
260 ; crossings especially with large numbers of users, though it
261 ; will store potentially large numbers of textures in your asset
262 ; database
263 PersistBakedTextures = false
264
265 ; Control the delay before appearance is sent to other avatars and
266 ; saved in the avatar service. Attempts to limit the impact caused
267 ; by the very chatty dialog that sets appearance when an avatar
268 ; logs in or teleports into a region; values are in seconds
269 DelayBeforeAppearanceSave = 5
270 DelayBeforeAppearanceSend = 2
271
258[SMTP] 272[SMTP]
259 enabled=false 273 enabled=false
260 274
diff --git a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml
index c5cafa7..5484ee2 100644
--- a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml
+++ b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml
@@ -1,4 +1,10 @@
1<Nini> 1<Nini>
2 <Section Name="Default Alpha">
3 <Key Name="assetID" Value="1578a2b1-5179-4b53-b618-fe00ca5a5594" />
4 <Key Name="name" Value="alpha" />
5 <Key Name="assetType" Value="0" />
6 <Key Name="fileName" Value="default_alpha.jp2" />
7 </Section>
2 <Section Name="texture1"> 8 <Section Name="texture1">
3 <Key Name="assetID" Value="00000000-0000-2222-3333-000000000099" /> 9 <Key Name="assetID" Value="00000000-0000-2222-3333-000000000099" />
4 <Key Name="name" Value="femface" /> 10 <Key Name="name" Value="femface" />
diff --git a/bin/assets/TexturesAssetSet/default_alpha.jp2 b/bin/assets/TexturesAssetSet/default_alpha.jp2
new file mode 100644
index 0000000..af73c1e
--- /dev/null
+++ b/bin/assets/TexturesAssetSet/default_alpha.jp2
Binary files differ
diff --git a/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml b/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml
index aa8d9d9..5cb71c0 100644
--- a/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml
+++ b/bin/inventory/BodyPartsLibrary/BodyPartsLibraryItems.xml
@@ -16,6 +16,34 @@
16 </Section> 16 </Section>
17--> 17-->
18<!-- 18<!--
19 <Section Name="Tattoo">
20 <Key Name="inventoryID" Value="c47e22bd-3021-4ba4-82aa-2b5cb34d35e1" />
21 <Key Name="assetID" Value="00000000-0000-2222-3333-100000001007" />
22 <Key Name="folderID" Value="d499e5e0-b9bf-11dc-95ff-0800200c9a66"/>
23 <Key Name="description" Value="Tattoo" />
24 <Key Name="name" Value="Tattoo" />
25 <Key Name="assetType" Value="13" />
26 <Key Name="inventoryType" Value="18" />
27 <Key Name="currentPermissions" Value="2147483647" />
28 <Key Name="nextPermissions" Value="2147483647" />
29 <Key Name="everyonePermissions" Value="2147483647" />
30 <Key Name="basePermissions" Value="2147483647" />
31 </Section>
32
33 <Section Name="Alpha">
34 <Key Name="inventoryID" Value="bfb9923c-4838-4d2d-bf07-608c5b1165c8" />
35 <Key Name="assetID" Value="1578a2b1-5179-4b53-b618-fe00ca5a5594" />
36 <Key Name="folderID" Value="d499e5e0-b9bf-11dc-95ff-0800200c9a66"/>
37 <Key Name="description" Value="Hair" />
38 <Key Name="name" Value="Hair" />
39 <Key Name="assetType" Value="13" />
40 <Key Name="inventoryType" Value="18" />
41 <Key Name="currentPermissions" Value="2147483647" />
42 <Key Name="nextPermissions" Value="2147483647" />
43 <Key Name="everyonePermissions" Value="2147483647" />
44 <Key Name="basePermissions" Value="2147483647" />
45 </Section>
46
19 <Section Name="Hair"> 47 <Section Name="Hair">
20 <Key Name="inventoryID" Value="d342e6c1-b9d2-11dc-95ff-0800200c9a66" /> 48 <Key Name="inventoryID" Value="d342e6c1-b9d2-11dc-95ff-0800200c9a66" />
21 <Key Name="assetID" Value="d342e6c0-b9d2-11dc-95ff-0800200c9a66" /> 49 <Key Name="assetID" Value="d342e6c0-b9d2-11dc-95ff-0800200c9a66" />