From 267f18925d06ca05e2a5ffbfbb63582783762439 Mon Sep 17 00:00:00 2001 From: Master ScienceSim Date: Thu, 21 Oct 2010 16:48:58 -0700 Subject: First attempt to get multiple attachments working to support viewer2. The attachment code appears to work correctly for 1.23 viewers so, in spite of some big changes in the internal representation, there don't appear to be regressions. That being said, I still can't get a viewer2 avatar to show correctly. --- .../RemoteController/RemoteAdminPlugin.cs | 8 +- .../Rest/Inventory/RestAppearanceServices.cs | 25 ++-- OpenSim/Framework/AvatarAppearance.cs | 138 +++++++++++---------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 +- .../Scripting/Minimodule/SPAvatar.cs | 15 +-- OpenSim/Services/Interfaces/IAvatarService.cs | 16 +-- 6 files changed, 100 insertions(+), 111 deletions(-) diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 0589748..1829c8d 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -1614,12 +1614,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController } // Attachments - Dictionary attachments = avatarAppearance.Attachments; + List attachments = avatarAppearance.GetAttachments(); - foreach (KeyValuePair attachment in attachments) + foreach (AvatarAttachment attachment in attachments) { - int attachpoint = attachment.Value.AttachPoint; - UUID itemID = attachment.Value.ItemID; + int attachpoint = attachment.AttachPoint; + UUID itemID = attachment.ItemID; if (itemID != UUID.Zero) { 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 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Xml; using OpenMetaverse; using OpenSim.Framework; @@ -765,25 +766,19 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory FormatPart(rdata, "UnderShirt", rdata.userAppearance.UnderShirtItem, rdata.userAppearance.UnderShirtAsset); FormatPart(rdata, "UnderPants", rdata.userAppearance.UnderPantsItem, rdata.userAppearance.UnderPantsAsset); - Hashtable attachments = rdata.userAppearance.GetAttachments(); + Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting attachments", MsgId); - if (attachments != null) + rdata.writer.WriteStartElement("Attachments"); + List attachments = rdata.userAppearance.GetAttachments(); + foreach (AvatarAttachment attach in attachments) { - - Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting attachments", MsgId); - - rdata.writer.WriteStartElement("Attachments"); - for (int i = 0; i < attachments.Count; i++) - { - Hashtable attachment = attachments[i] as Hashtable; - rdata.writer.WriteStartElement("Attachment"); - rdata.writer.WriteAttributeString("AtPoint", i.ToString()); - rdata.writer.WriteAttributeString("Item", (string) attachment["item"]); - rdata.writer.WriteAttributeString("Asset", (string) attachment["asset"]); - rdata.writer.WriteEndElement(); - } + rdata.writer.WriteStartElement("Attachment"); + rdata.writer.WriteAttributeString("AtPoint", attach.AttachPoint.ToString()); + rdata.writer.WriteAttributeString("Item", attach.ItemID.ToString()); + rdata.writer.WriteAttributeString("Asset", attach.AssetID.ToString()); rdata.writer.WriteEndElement(); } + rdata.writer.WriteEndElement(); Primitive.TextureEntry texture = rdata.userAppearance.Texture; diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 55646dd..ba0cad2 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -51,7 +51,7 @@ namespace OpenSim.Framework protected byte[] m_visualparams; protected Primitive.TextureEntry m_texture; protected AvatarWearable[] m_wearables; - protected Dictionary m_attachments; + protected Dictionary> m_attachments; protected float m_avatarHeight = 0; protected float m_hipOffset = 0; @@ -85,11 +85,6 @@ namespace OpenSim.Framework set { m_wearables = value; } } - public virtual Dictionary Attachments - { - get { return m_attachments; } - } - public virtual UUID BodyItem { get { return m_wearables[AvatarWearable.BODY].ItemID; } set { m_wearables[AvatarWearable.BODY].ItemID = value; } @@ -246,7 +241,7 @@ namespace OpenSim.Framework SetDefaultParams(); SetHeight(); - m_attachments = new Dictionary(); + m_attachments = new Dictionary>(); } public AvatarAppearance(UUID avatarID, OSDMap map) @@ -284,7 +279,7 @@ namespace OpenSim.Framework SetHeight(); - m_attachments = new Dictionary(); + m_attachments = new Dictionary>(); } public AvatarAppearance(AvatarAppearance appearance) @@ -302,7 +297,7 @@ namespace OpenSim.Framework SetDefaultParams(); SetHeight(); - m_attachments = new Dictionary(); + m_attachments = new Dictionary>(); return; } @@ -329,9 +324,10 @@ namespace OpenSim.Framework if (appearance.VisualParams != null) m_visualparams = (byte[])appearance.VisualParams.Clone(); - m_attachments = new Dictionary(); - foreach (KeyValuePair kvp in appearance.Attachments) - m_attachments[kvp.Key] = new AvatarAttachment(kvp.Value); + // Copy the attachment, force append mode since that ensures consistency + m_attachments = new Dictionary>(); + foreach (AvatarAttachment attachment in appearance.GetAttachments()) + AppendAttachment(new AvatarAttachment(attachment)); } protected virtual void SetDefaultWearables() @@ -487,12 +483,41 @@ namespace OpenSim.Framework } // DEBUG OFF - public void SetAttachments(AvatarAttachment[] data) + /// + /// Get a list of the attachments, note that there may be + /// duplicate attachpoints + /// + public List GetAttachments() + { + List alist = new List(); + foreach (KeyValuePair> kvp in m_attachments) + { + foreach (AvatarAttachment attach in kvp.Value) + alist.Add(new AvatarAttachment(attach)); + } + + return alist; + } + + internal void AppendAttachment(AvatarAttachment attach) { - foreach (AvatarAttachment attach in data) - m_attachments[attach.AttachPoint] = new AvatarAttachment(attach); + if (! m_attachments.ContainsKey(attach.AttachPoint)) + m_attachments[attach.AttachPoint] = new List(); + m_attachments[attach.AttachPoint].Add(attach); } + internal void ReplaceAttachment(AvatarAttachment attach) + { + m_attachments[attach.AttachPoint] = new List(); + m_attachments[attach.AttachPoint].Add(attach); + } + + /// + /// Add an attachment, if the attachpoint has the + /// 0x80 bit set then we assume this is an append + /// operation otherwise we replace whatever is + /// currently attached at the attachpoint + /// public void SetAttachment(int attachpoint, UUID item, UUID asset) { if (attachpoint == 0) @@ -505,67 +530,47 @@ namespace OpenSim.Framework return; } - m_attachments[attachpoint] = new AvatarAttachment(attachpoint,item,asset); - } - - public Hashtable GetAttachments() - { - if (m_attachments.Count == 0) - return null; - - Hashtable ret = new Hashtable(); - - foreach (KeyValuePair kvp in m_attachments) + // check if this is an append or a replace, 0x80 marks it as an append + if ((attachpoint & 0x80) > 0) { - Hashtable data = new Hashtable(); - data["item"] = kvp.Value.ItemID.ToString(); - data["asset"] = kvp.Value.AssetID.ToString(); - - ret[kvp.Key] = data; + // strip the append bit + int point = attachpoint & 0x7F; + AppendAttachment(new AvatarAttachment(point, item, asset)); + } + else + { + ReplaceAttachment(new AvatarAttachment(attachpoint,item,asset)); } - - return ret; - } - - public List GetAttachedPoints() - { - return new List(m_attachments.Keys); - } - - public UUID GetAttachedItem(int attachpoint) - { - if (!m_attachments.ContainsKey(attachpoint)) - return UUID.Zero; - - return m_attachments[attachpoint].ItemID; - } - - public UUID GetAttachedAsset(int attachpoint) - { - if (!m_attachments.ContainsKey(attachpoint)) - return UUID.Zero; - - return m_attachments[attachpoint].AssetID; } public int GetAttachpoint(UUID itemID) { - foreach (KeyValuePair kvp in m_attachments) + foreach (KeyValuePair> kvp in m_attachments) { - if (kvp.Value.ItemID == itemID) - { + int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; }); + if (index >= 0) return kvp.Key; - } } + return 0; } public void DetachAttachment(UUID itemID) { - int attachpoint = GetAttachpoint(itemID); + foreach (KeyValuePair> kvp in m_attachments) + { + int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; }); + if (index >= 0) + { + // Remove it from the list of attachments at that attach point + m_attachments[kvp.Key].RemoveAt(index); - if (attachpoint > 0) - m_attachments.Remove(attachpoint); + // And remove the list if there are no more attachments here + if (m_attachments[kvp.Key].Count == 0) + m_attachments.Remove(kvp.Key); + return; + } + } } public void ClearAttachments() @@ -607,8 +612,8 @@ namespace OpenSim.Framework // Attachments OSDArray attachs = new OSDArray(m_attachments.Count); - foreach (KeyValuePair kvp in m_attachments) - attachs.Add(kvp.Value.Pack()); + foreach (AvatarAttachment attach in GetAttachments()) + attachs.Add(attach.Pack()); data["attachments"] = attachs; return data; @@ -675,15 +680,12 @@ namespace OpenSim.Framework } // Attachments - m_attachments = new Dictionary(); + m_attachments = new Dictionary>(); if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array) { OSDArray attachs = (OSDArray)(data["attachments"]); for (int i = 0; i < attachs.Count; i++) - { - AvatarAttachment attach = new AvatarAttachment((OSDMap)attachs[i]); - m_attachments[attach.AttachPoint] = attach; - } + AppendAttachment(new AvatarAttachment((OSDMap)attachs[i])); } } catch (Exception e) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5dc48d7..f828a2d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3657,15 +3657,16 @@ namespace OpenSim.Region.Framework.Scenes return; } - List attPoints = m_appearance.GetAttachedPoints(); - foreach (int p in attPoints) + List attachments = m_appearance.GetAttachments(); + foreach (AvatarAttachment attach in attachments) { if (m_isDeleted) return; - UUID itemID = m_appearance.GetAttachedItem(p); + int p = attach.AttachPoint; + UUID itemID = attach.ItemID; - //UUID assetID = m_appearance.GetAttachedAsset(p); + //UUID assetID = attach.AssetID; // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down // But they're not used anyway, the item is being looked up for now, so let's proceed. //if (UUID.Zero == assetID) 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; using System.Collections.Generic; using System.Security; using OpenMetaverse; +using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; @@ -81,16 +82,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule get { List attachments = new List(); - Hashtable internalAttachments = GetSP().Appearance.GetAttachments(); - if (internalAttachments != null) + List internalAttachments = GetSP().Appearance.GetAttachments(); + foreach (AvatarAttachment attach in internalAttachments) { - foreach (DictionaryEntry element in internalAttachments) - { - Hashtable attachInfo = (Hashtable)element.Value; - attachments.Add(new SPAvatarAttachment(m_rootScene, this, (int) element.Key, - new UUID((string) attachInfo["item"]), - new UUID((string) attachInfo["asset"]), m_security)); - } + attachments.Add(new SPAvatarAttachment(m_rootScene, this, attach.AttachPoint, + new UUID(attach.ItemID), + new UUID(attach.AssetID), m_security)); } return attachments.ToArray(); diff --git a/OpenSim/Services/Interfaces/IAvatarService.cs b/OpenSim/Services/Interfaces/IAvatarService.cs index 93b977b..eaa6534 100644 --- a/OpenSim/Services/Interfaces/IAvatarService.cs +++ b/OpenSim/Services/Interfaces/IAvatarService.cs @@ -178,17 +178,11 @@ namespace OpenSim.Services.Interfaces Data["UnderShirtAsset"] = appearance.UnderShirtAsset.ToString(); // Attachments - Hashtable attachs = appearance.GetAttachments(); - if (attachs != null) - foreach (DictionaryEntry dentry in attachs) - { - if (dentry.Value != null) - { - Hashtable tab = (Hashtable)dentry.Value; - if (tab.ContainsKey("item") && tab["item"] != null) - Data["_ap_" + dentry.Key] = tab["item"].ToString(); - } - } + List attachments = appearance.GetAttachments(); + foreach (AvatarAttachment attach in attachments) + { + Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString(); + } } public AvatarAppearance ToAvatarAppearance(UUID owner) -- cgit v1.1 From 657cceb8847f94a9af0c8b2358124105d778486c Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Mon, 25 Oct 2010 09:41:08 -0700 Subject: Intermediate commit for backward compatability; does not compile yet --- OpenSim/Framework/AgentCircuitData.cs | 65 ++++++++++++++-------------- OpenSim/Framework/ChildAgentDataUpdate.cs | 70 ++++++++++++++++++------------- 2 files changed, 73 insertions(+), 62 deletions(-) diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index be98380..30a9548 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs @@ -206,16 +206,18 @@ namespace OpenSim.Framework args["service_session_id"] = OSD.FromString(ServiceSessionID); args["start_pos"] = OSD.FromString(startpos.ToString()); - args["appearance_serial"] = OSD.FromInteger(Appearance.Serial); args["client_ip"] = OSD.FromString(IPAddress); args["viewer"] = OSD.FromString(Viewer); args["channel"] = OSD.FromString(Channel); args["mac"] = OSD.FromString(Mac); args["id0"] = OSD.FromString(Id0); -/* + // Eventually this code should be deprecated, use full appearance + // packing in packed_appearance if (Appearance != null) { + args["appearance_serial"] = OSD.FromInteger(Appearance.Serial); + //System.Console.WriteLine("XXX Before packing Wearables"); if ((Appearance.Wearables != null) && (Appearance.Wearables.Length > 0)) { @@ -230,20 +232,19 @@ namespace OpenSim.Framework } //System.Console.WriteLine("XXX Before packing Attachments"); - Dictionary attachments = Appearance.Attachments; + List attachments = Appearance.GetAttachments(); if ((attachments != null) && (attachments.Count > 0)) { OSDArray attachs = new OSDArray(attachments.Count); - foreach (KeyValuePair kvp in attachments) + foreach (AvatarAttachment attach in attachments) { - AvatarAttachment adata = new AvatarAttachment(kvp.Value); - attachs.Add(adata.Pack()); + attachs.Add(attach.Pack()); //System.Console.WriteLine("XXX att.pt=" + kvp.Key + "; itemID=" + kvp.Value[0] + "; assetID=" + kvp.Value[1]); } args["attachments"] = attachs; } } -*/ + if (Appearance != null) { OSDMap appmap = Appearance.Pack(); @@ -339,27 +340,9 @@ namespace OpenSim.Framework try { // Unpack various appearance elements Appearance = new AvatarAppearance(AgentID); - if (args["packed_appearance"] != null) - { - if (args["packed_appearance"].Type == OSDType.Map) - { - Appearance.Unpack((OSDMap)args["packed_appearance"]); - m_log.WarnFormat("[AGENTCIRCUITDATA] unpacked appearance"); - } - else - m_log.WarnFormat("[AGENTCIRCUITDATA] packed_appearance is not a map:\n{0}",args["packed_appearance"].ToString()); - } -// DEBUG ON - else - m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance"); -// DEBUG OFF - } catch (Exception e) - { - m_log.ErrorFormat("[AGENTCIRCUITDATA] failed to unpack appearance; {0}",e.Message); - } - - -/* + + // Eventually this code should be deprecated, use full appearance + // packing in packed_appearance if (args["appearance_serial"] != null) Appearance.Serial = args["appearance_serial"].AsInteger(); @@ -376,18 +359,34 @@ namespace OpenSim.Framework if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array) { OSDArray attachs = (OSDArray)(args["attachments"]); - AvatarAttachment[] attachments = new AvatarAttachment[attachs.Count]; - int i = 0; foreach (OSD o in attachs) { if (o.Type == OSDType.Map) { - attachments[i++] = new AvatarAttachment((OSDMap)o); + Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o)); } } - Appearance.SetAttachments(attachments); } -*/ + + if (args["packed_appearance"] != null) + { + if (args["packed_appearance"].Type == OSDType.Map) + { + Appearance.Unpack((OSDMap)args["packed_appearance"]); + m_log.WarnFormat("[AGENTCIRCUITDATA] unpacked appearance"); + } + else + m_log.WarnFormat("[AGENTCIRCUITDATA] packed_appearance is not a map:\n{0}",args["packed_appearance"].ToString()); + } +// DEBUG ON + else + m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance"); +// DEBUG OFF + } catch (Exception e) + { + m_log.ErrorFormat("[AGENTCIRCUITDATA] failed to unpack appearance; {0}",e.Message); + } + ServiceURLs = new Dictionary(); if (args.ContainsKey("service_urls") && args["service_urls"] != null && (args["service_urls"]).Type == OSDType.Array) { diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index fdebba3..d7a7d1e 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -387,31 +387,37 @@ namespace OpenSim.Framework // args["agent_textures"] = textures; //} -/* - if ((AgentTextures != null) && (AgentTextures.Length > 0)) - args["texture_entry"] = OSD.FromBinary(AgentTextures); + // The code to pack textures, visuals, wearables and attachments + // should be removed; packed appearance contains the full appearance + // This is retained for backward compatibility only + if ((Appearance.Texture != null) && (Appearance.Texture.Length > 0)) + args["texture_entry"] = OSD.FromBinary(Appearance.Texture); - if ((VisualParams != null) && (VisualParams.Length > 0)) - args["visual_params"] = OSD.FromBinary(VisualParams); + if ((Appearance.VisualParams != null) && (Appearance.VisualParams.Length > 0)) + args["visual_params"] = OSD.FromBinary(Appearance.VisualParams); // We might not pass this in all cases... - if ((Wearables != null) && (Wearables.Length > 0)) + if ((Appearance.Wearables != null) && (Appearance.Wearables.Length > 0)) { - OSDArray wears = new OSDArray(Wearables.Length); - foreach (UUID uuid in Wearables) - wears.Add(OSD.FromUUID(uuid)); + OSDArray wears = new OSDArray(Appearance.Wearables.Length * 2); + foreach (AvatarWearable awear in Appearance.Wearables) + { + wears.Add(OSD.FromUUID(awear.ItemID)); + wears.Add(OSD.FromUUID(awear.AssetID)); + } args["wearables"] = wears; } - - if ((Attachments != null) && (Attachments.Length > 0)) + List attachments = Appearance.GetAttachments(); + if ((attachments != null) && (attachments.Length > 0)) { - OSDArray attachs = new OSDArray(Attachments.Length); - foreach (AvatarAttachment att in Attachments) + OSDArray attachs = new OSDArray(attachments.Length); + foreach (AvatarAttachment att in attachments) attachs.Add(att.Pack()); args["attachments"] = attachs; } -*/ + // End of code to remove + if ((Controllers != null) && (Controllers.Length > 0)) { OSDArray controls = new OSDArray(Controllers.Length); @@ -547,41 +553,47 @@ namespace OpenSim.Framework // AgentTextures[i++] = o.AsUUID(); //} - if (args["packed_appearance"] != null) - Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]); - else - Appearance = new AvatarAppearance(AgentID); - -/* + + Appearance = new AvatarAppearance(AgentID); + + // The code to pack textures, visuals, wearables and attachments + // should be removed; packed appearance contains the full appearance + // This is retained for backward compatibility only if (args["texture_entry"] != null) - AgentTextures = args["texture_entry"].AsBinary(); + Appearance.SetTextureEntries(args["texture_entry"].AsBinary()); if (args["visual_params"] != null) - VisualParams = args["visual_params"].AsBinary(); + Appearance.SetVisualParams(args["visual_params"].AsBinary()); if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array) { OSDArray wears = (OSDArray)(args["wearables"]); - Wearables = new UUID[wears.Count]; - int i = 0; - foreach (OSD o in wears) - Wearables[i++] = o.AsUUID(); + for (int i = 0; i < wears.Count / 2; i++) + { + Appearance.Wearables[i].ItemID = wears[i*2].AsUUID(); + Appearance.Wearables[i].AssetID = wears[(i*2)+1].AsUUID(); + } } if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array) { OSDArray attachs = (OSDArray)(args["attachments"]); - Attachments = new AvatarAttachment[attachs.Count]; + AvatarAttachment[] attachments = new AvatarAttachment[attachs.Count]; int i = 0; foreach (OSD o in attachs) { if (o.Type == OSDType.Map) { - Attachments[i++] = new AvatarAttachment((OSDMap)o); + attachments[i++] = new AvatarAttachment((OSDMap)o); } } + Appearance.SetAttachments(attachments); } -*/ + // end of code to remove + + if (args["packed_appearance"] != null) + Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]); + if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) { OSDArray controls = (OSDArray)(args["controllers"]); -- cgit v1.1 From 6e58c3d563b50c5797d1cfffbaec3fe82f18c2ea Mon Sep 17 00:00:00 2001 From: Master ScienceSim Date: Mon, 25 Oct 2010 14:11:47 -0700 Subject: Half of the compatibility is working. Login into a new region with old data works. Teleport out of a new region with old data works. Teleport into a new region with old data does not trigger the necessary rebake. --- OpenSim/Framework/AgentCircuitData.cs | 13 ++++----- OpenSim/Framework/AvatarAppearance.cs | 2 +- OpenSim/Framework/ChildAgentDataUpdate.cs | 33 ++++++++++++++-------- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 2 +- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index 30a9548..098b33c 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs @@ -368,15 +368,12 @@ namespace OpenSim.Framework } } - if (args["packed_appearance"] != null) + if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map)) { - if (args["packed_appearance"].Type == OSDType.Map) - { - Appearance.Unpack((OSDMap)args["packed_appearance"]); - m_log.WarnFormat("[AGENTCIRCUITDATA] unpacked appearance"); - } - else - m_log.WarnFormat("[AGENTCIRCUITDATA] packed_appearance is not a map:\n{0}",args["packed_appearance"].ToString()); + Appearance.Unpack((OSDMap)args["packed_appearance"]); +// DEBUG ON + m_log.WarnFormat("[AGENTCIRCUITDATA] unpacked appearance"); +// DEBUG OFF } // DEBUG ON else diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index ba0cad2..05330c7 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -389,7 +389,7 @@ namespace OpenSim.Framework changed = true; // DEBUG ON if (newface != null) - m_log.WarnFormat("[SCENEPRESENCE] index {0}, new texture id {1}",i,newface.TextureID); + m_log.WarnFormat("[AVATAR APPEARANCE] index {0}, new texture id {1}",i,newface.TextureID); // DEBUG OFF } diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index d7a7d1e..215682f 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -390,8 +390,11 @@ namespace OpenSim.Framework // The code to pack textures, visuals, wearables and attachments // should be removed; packed appearance contains the full appearance // This is retained for backward compatibility only - if ((Appearance.Texture != null) && (Appearance.Texture.Length > 0)) - args["texture_entry"] = OSD.FromBinary(Appearance.Texture); + if (Appearance.Texture != null) + { + byte[] rawtextures = Appearance.Texture.GetBytes(); + args["texture_entry"] = OSD.FromBinary(rawtextures); + } if ((Appearance.VisualParams != null) && (Appearance.VisualParams.Length > 0)) args["visual_params"] = OSD.FromBinary(Appearance.VisualParams); @@ -408,10 +411,10 @@ namespace OpenSim.Framework args["wearables"] = wears; } - List attachments = Appearance.GetAttachments(); - if ((attachments != null) && (attachments.Length > 0)) + List attachments = Appearance.GetAttachments(); + if ((attachments != null) && (attachments.Count > 0)) { - OSDArray attachs = new OSDArray(attachments.Length); + OSDArray attachs = new OSDArray(attachments.Count); foreach (AvatarAttachment att in attachments) attachs.Add(att.Pack()); args["attachments"] = attachs; @@ -560,7 +563,11 @@ namespace OpenSim.Framework // should be removed; packed appearance contains the full appearance // This is retained for backward compatibility only if (args["texture_entry"] != null) - Appearance.SetTextureEntries(args["texture_entry"].AsBinary()); + { + byte[] rawtextures = args["texture_entry"].AsBinary(); + Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures,0,rawtextures.Length); + Appearance.SetTextureEntries(textures); + } if (args["visual_params"] != null) Appearance.SetVisualParams(args["visual_params"].AsBinary()); @@ -578,21 +585,25 @@ namespace OpenSim.Framework if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array) { OSDArray attachs = (OSDArray)(args["attachments"]); - AvatarAttachment[] attachments = new AvatarAttachment[attachs.Count]; - int i = 0; foreach (OSD o in attachs) { if (o.Type == OSDType.Map) { - attachments[i++] = new AvatarAttachment((OSDMap)o); + // We know all of these must end up as attachments so we + // append rather than replace to ensure multiple attachments + // per point continues to work + Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o)); } } - Appearance.SetAttachments(attachments); } // end of code to remove - if (args["packed_appearance"] != null) + if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map) Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]); +// DEBUG ON + else + System.Console.WriteLine("No packed appearance in AgentUpdate"); +// DEBUG OFF if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) { diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 9f7ff7f..b74cdc9 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -136,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) { - m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",face.TextureID,j,this.Name); + m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",face.TextureID,j,client.Name); client.SendRebakeAvatarTextures(face.TextureID); } } -- cgit v1.1 From 9132e251aa0d0d7395dc4868fd57799dd679cdb7 Mon Sep 17 00:00:00 2001 From: Master ScienceSim Date: Tue, 26 Oct 2010 12:53:15 -0700 Subject: Made the check for texture assets asynchronous. This is one part of a bigger clean up that needs to happen around locks on appearance. --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index b74cdc9..5444f80 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -84,6 +84,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // client.OnAvatarNowWearing -= AvatarIsWearing; } + public void CheckBakedTextureAssets(IClientAPI client, UUID textureID, int idx) + { + if (m_scene.AssetService.Get(textureID.ToString()) == null) + { + m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",textureID,idx,client.Name); + client.SendRebakeAvatarTextures(textureID); + } + } + /// /// Set appearance data (textureentry and slider settings) received from the client /// @@ -133,13 +142,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) - { - if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) - { - m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",face.TextureID,j,client.Name); - client.SendRebakeAvatarTextures(face.TextureID); - } - } + Util.FireAndForget(delegate(object o) { CheckBakedTextureAssets(client,face.TextureID,j); }); } changed = sp.Appearance.SetTextureEntries(textureEntry); -- cgit v1.1 From 9cfd3e1d5ac8383087fb09cf076e9ec199808fd7 Mon Sep 17 00:00:00 2001 From: Master ScienceSim Date: Tue, 26 Oct 2010 12:54:28 -0700 Subject: Small cleanup and add more debugging information --- OpenSim/Framework/AgentCircuitData.cs | 4 ++-- OpenSim/Framework/ChildAgentDataUpdate.cs | 27 +++++++++++++++++++++------ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index 098b33c..640a646 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs @@ -351,8 +351,8 @@ namespace OpenSim.Framework OSDArray wears = (OSDArray)(args["wearables"]); for (int i = 0; i < wears.Count / 2; i++) { - Appearance.Wearables[i].ItemID = wears[i*2].AsUUID(); - Appearance.Wearables[i].AssetID = wears[(i*2)+1].AsUUID(); + AvatarWearable awear = new AvatarWearable(wears[i*2].AsUUID(),wears[(i*2)+1].AsUUID()); + Appearance.SetWearable(i,awear); } } diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index 215682f..66487f7 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -28,6 +28,8 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Reflection; +using log4net; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -310,6 +312,12 @@ namespace OpenSim.Framework // Appearance public AvatarAppearance Appearance; +// DEBUG ON + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); +// DEBUG OFF + /* public byte[] AgentTextures; public byte[] VisualParams; @@ -323,6 +331,10 @@ namespace OpenSim.Framework public virtual OSDMap Pack() { +// DEBUG ON + m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Pack data"); +// DEBUG OFF + OSDMap args = new OSDMap(); args["message_type"] = OSD.FromString("AgentData"); @@ -444,6 +456,10 @@ namespace OpenSim.Framework /// public virtual void Unpack(OSDMap args) { +// DEBUG ON + m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Unpack data"); +// DEBUG OFF + if (args.ContainsKey("region_id")) UUID.TryParse(args["region_id"].AsString(), out RegionID); @@ -556,10 +572,9 @@ namespace OpenSim.Framework // AgentTextures[i++] = o.AsUUID(); //} - Appearance = new AvatarAppearance(AgentID); - // The code to pack textures, visuals, wearables and attachments + // The code to unpack textures, visuals, wearables and attachments // should be removed; packed appearance contains the full appearance // This is retained for backward compatibility only if (args["texture_entry"] != null) @@ -577,8 +592,8 @@ namespace OpenSim.Framework OSDArray wears = (OSDArray)(args["wearables"]); for (int i = 0; i < wears.Count / 2; i++) { - Appearance.Wearables[i].ItemID = wears[i*2].AsUUID(); - Appearance.Wearables[i].AssetID = wears[(i*2)+1].AsUUID(); + AvatarWearable awear = new AvatarWearable(wears[i*2].AsUUID(),wears[(i*2)+1].AsUUID()); + Appearance.SetWearable(i,awear); } } @@ -602,8 +617,8 @@ namespace OpenSim.Framework Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]); // DEBUG ON else - System.Console.WriteLine("No packed appearance in AgentUpdate"); -// DEBUG OFF + m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance"); +// DEBUG OFF if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) { -- cgit v1.1 From 0f28fa400d1f853cc3c3ebd2707b08ed06d2f127 Mon Sep 17 00:00:00 2001 From: Master ScienceSim Date: Thu, 28 Oct 2010 09:00:39 -0700 Subject: Added background thread to handle delayed send and save of appearance to accommodate batching of the many updates that happen on login and teleport. Fixed handling of the serial property in appearance. --- OpenSim/Framework/AvatarAppearance.cs | 11 +- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 219 +++++++++++++++------ 2 files changed, 171 insertions(+), 59 deletions(-) diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 05330c7..e66a1e7 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -233,7 +233,7 @@ namespace OpenSim.Framework // DEBUG ON m_log.WarnFormat("[AVATAR APPEARANCE] create empty appearance for {0}",owner); // DEBUG OFF - m_serial = 0; + m_serial = 1; m_owner = owner; SetDefaultWearables(); @@ -289,7 +289,7 @@ namespace OpenSim.Framework // DEBUG OFF if (appearance == null) { - m_serial = 0; + m_serial = 1; m_owner = UUID.Zero; SetDefaultWearables(); @@ -467,6 +467,9 @@ namespace OpenSim.Framework public override String ToString() { String s = ""; + + s += String.Format("Serial: {0}\n",m_serial); + for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) if (m_texture.FaceTextures[i] != null) s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID); @@ -625,8 +628,8 @@ namespace OpenSim.Framework /// public void Unpack(OSDMap data) { - if ((data != null) && (data["appearance_serial"] != null)) - m_serial = data["appearance_serial"].AsInteger(); + if ((data != null) && (data["serial"] != null)) + m_serial = data["serial"].AsInteger(); if ((data != null) && (data["height"] != null)) m_avatarHeight = (float)data["height"].AsReal(); if ((data != null) && (data["hipoffset"] != null)) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 5444f80..903e94b 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -32,6 +32,10 @@ using Nini.Config; using OpenMetaverse; using OpenSim.Framework; +using System.Threading; +using System.Timers; +using System.Collections.Generic; + using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; @@ -44,7 +48,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; private Scene m_scene = null; - private bool m_startAnimationSet = false; + private static readonly int m_savetime = 5; // seconds to wait before saving changed appearance + private static readonly int m_sendtime = 2; // seconds to wait before sending changed appearance + + private static readonly int m_checkTime = 500; // milliseconds to wait between checks for appearance updates + private System.Timers.Timer m_updateTimer = new System.Timers.Timer(); + private Dictionary m_savequeue = new Dictionary(); + private Dictionary m_sendqueue = new Dictionary(); + + #region RegionModule Members public void Initialise(Scene scene, IConfigSource source) { @@ -56,6 +68,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public void PostInitialise() { + m_updateTimer.Enabled = false; + m_updateTimer.AutoReset = true; + m_updateTimer.Interval = m_checkTime; // 500 milliseconds wait to start async ops + m_updateTimer.Elapsed += new ElapsedEventHandler(HandleAppearanceUpdateTimer); } public void Close() @@ -84,15 +100,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // client.OnAvatarNowWearing -= AvatarIsWearing; } - public void CheckBakedTextureAssets(IClientAPI client, UUID textureID, int idx) - { - if (m_scene.AssetService.Get(textureID.ToString()) == null) - { - m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",textureID,idx,client.Name); - client.SendRebakeAvatarTextures(textureID); - } - } - + #endregion + /// /// Set appearance data (textureentry and slider settings) received from the client /// @@ -100,6 +109,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory /// public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) { +// DEBUG ON + m_log.WarnFormat("[AVFACTORY] SetAppearance for {0}",client.AgentId); +// DEBUG OFF + ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) { @@ -107,79 +120,175 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return; } -// DEBUG ON - m_log.WarnFormat("[AVFACTORY] SetAppearance for {0}",client.AgentId); -// DEBUG OFF - -/* - if (m_physicsActor != null) - { - if (!IsChildAgent) - { - // This may seem like it's redundant, remove the avatar from the physics scene - // just to add it back again, but it saves us from having to update - // 3 variables 10 times a second. - bool flyingTemp = m_physicsActor.Flying; - RemoveFromPhysicalScene(); - //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); - - //PhysicsActor = null; - - AddToPhysicalScene(flyingTemp); - } - } -*/ - #region Bake Cache Check - bool changed = false; // Process the texture entry if (textureEntry != null) { + changed = sp.Appearance.SetTextureEntries(textureEntry); + for (int i = 0; i < BAKE_INDICES.Length; i++) { - int j = BAKE_INDICES[i]; - Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; - + int idx = BAKE_INDICES[i]; + Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) - Util.FireAndForget(delegate(object o) { CheckBakedTextureAssets(client,face.TextureID,j); }); + Util.FireAndForget(delegate(object o) { CheckBakedTextureAssets(client,face.TextureID,idx); }); } - changed = sp.Appearance.SetTextureEntries(textureEntry); - } - #endregion Bake Cache Check - - changed = sp.Appearance.SetVisualParams(visualParams) || changed; - - // If nothing changed (this happens frequently) just return + // Process the visual params, this may change height as well + if (visualParams != null) + { + if (sp.Appearance.SetVisualParams(visualParams)) + { + changed = true; + if (sp.Appearance.AvatarHeight > 0) + sp.SetHeight(sp.Appearance.AvatarHeight); + } + } + + // If something changed in the appearance then queue an appearance save if (changed) + QueueAppearanceSave(client.AgentId); + + // And always queue up an appearance update to send out + QueueAppearanceSend(client.AgentId); + + // Send the appearance back to the avatar + AvatarAppearance avp = sp.Appearance; + sp.ControllingClient.SendAvatarDataImmediate(sp); + sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); + } + + /// + /// Checks for the existance of a baked texture asset and + /// requests the viewer rebake if the asset is not found + /// + /// + /// + /// + private void CheckBakedTextureAssets(IClientAPI client, UUID textureID, int idx) + { + if (m_scene.AssetService.Get(textureID.ToString()) == null) + { + m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}", + textureID,idx,client.Name); + client.SendRebakeAvatarTextures(textureID); + } + } + + #region UpdateAppearanceTimer + + public void QueueAppearanceSend(UUID agentid) + { +// DEBUG ON + m_log.WarnFormat("[AVFACTORY] Queue appearance send for {0}",agentid); +// DEBUG OFF + + // 100 nanoseconds (ticks) we should wait + long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 10000000); + lock (m_sendqueue) { + m_sendqueue[agentid] = timestamp; + m_updateTimer.Start(); + } + } + + public void QueueAppearanceSave(UUID agentid) + { // DEBUG ON - m_log.Warn("[AVFACTORY] Appearance changed"); + m_log.WarnFormat("[AVFACTORY] Queue appearance save for {0}",agentid); // DEBUG OFF - sp.Appearance.SetAppearance(textureEntry, visualParams); - if (sp.Appearance.AvatarHeight > 0) - sp.SetHeight(sp.Appearance.AvatarHeight); - m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); + // 100 nanoseconds (ticks) we should wait + long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 10000000); + lock (m_savequeue) + { + m_savequeue[agentid] = timestamp; + m_updateTimer.Start(); + } + } + + private void HandleAppearanceSend(UUID agentid) + { + ScenePresence sp = m_scene.GetScenePresence(agentid); + if (sp == null) + { + m_log.WarnFormat("[AVFACTORY] Agent {0} no longer in the scene",agentid); + return; } + // DEBUG ON - else - m_log.Warn("[AVFACTORY] Appearance did not change"); -// DEBUG OFF + m_log.WarnFormat("[AVFACTORY] Handle appearance send for {0}\n{1}",agentid,sp.Appearance.ToString()); +// DEBUG OFF + // Send the appearance to everyone in the scene sp.SendAppearanceToAllOtherAgents(); + + // Send the appearance back to the avatar + AvatarAppearance avp = sp.Appearance; + sp.ControllingClient.SendAvatarDataImmediate(sp); + sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); + +/* +// this needs to be fixed, the flag should be on scene presence not the region module + // Start the animations if necessary if (!m_startAnimationSet) { sp.Animator.UpdateMovementAnimations(); m_startAnimationSet = true; } +*/ + } - client.SendAvatarDataImmediate(sp); - client.SendAppearance(sp.Appearance.Owner,sp.Appearance.VisualParams,sp.Appearance.Texture.GetBytes()); + private void HandleAppearanceSave(UUID agentid) + { + ScenePresence sp = m_scene.GetScenePresence(agentid); + if (sp == null) + { + m_log.WarnFormat("[AVFACTORY] Agent {0} no longer in the scene",agentid); + return; + } + + m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); } + private void HandleAppearanceUpdateTimer(object sender, EventArgs ea) + { + long now = DateTime.Now.Ticks; + + lock (m_sendqueue) + { + Dictionary sends = new Dictionary(m_sendqueue); + foreach (KeyValuePair kvp in sends) + { + if (kvp.Value < now) + { + Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); }); + m_sendqueue.Remove(kvp.Key); + } + } + } + + lock (m_savequeue) + { + Dictionary saves = new Dictionary(m_savequeue); + foreach (KeyValuePair kvp in saves) + { + if (kvp.Value < now) + { + Util.FireAndForget(delegate(object o) { HandleAppearanceSave(kvp.Key); }); + m_savequeue.Remove(kvp.Key); + } + } + } + + if (m_savequeue.Count == 0 && m_sendqueue.Count == 0) + m_updateTimer.Stop(); + } + + #endregion + /// /// Tell the client for this scene presence what items it should be wearing now /// -- cgit v1.1 From 68666efd25f4d094949f31eae08ee17fd821b7e4 Mon Sep 17 00:00:00 2001 From: Master ScienceSim Date: Thu, 28 Oct 2010 12:00:04 -0700 Subject: Configuration of persistent baked textures and save/send delays. --- OpenSim/Framework/Capabilities/Caps.cs | 14 +++++++++++++- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 18 ++++++++++++++---- bin/OpenSimDefaults.ini | 14 ++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs index 6b64e12..872de9a 100644 --- a/OpenSim/Framework/Capabilities/Caps.cs +++ b/OpenSim/Framework/Capabilities/Caps.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; using log4net; +using Nini.Config; using OpenMetaverse; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; @@ -112,6 +113,8 @@ namespace OpenSim.Framework.Capabilities private string m_regionName; private object m_fetchLock = new Object(); + private bool m_persistBakedTextures = false; + public bool SSLCaps { get { return m_httpListener.UseSSL; } @@ -145,6 +148,15 @@ namespace OpenSim.Framework.Capabilities m_httpListenPort = httpPort; + m_persistBakedTextures = false; + IConfigSource config = m_Scene.Config; + if (config != null) + { + IConfig sconfig = config.Configs["Startup"]; + if (sconfig != null) + m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures",m_persistBakedTextures); + } + if (httpServer != null && httpServer.UseSSL) { m_httpListenPort = httpServer.SSLPort; @@ -983,7 +995,7 @@ namespace OpenSim.Framework.Capabilities asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString()); asset.Data = data; asset.Temporary = true; - asset.Local = true; + asset.Local = ! m_persistBakedTextures; // Local assets aren't persisted, non-local are m_assetCache.Store(asset); } diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 903e94b..5f8b4f6 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -48,20 +48,30 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; private Scene m_scene = null; - private static readonly int m_savetime = 5; // seconds to wait before saving changed appearance - private static readonly int m_sendtime = 2; // seconds to wait before sending changed appearance + private int m_savetime = 5; // seconds to wait before saving changed appearance + private int m_sendtime = 2; // seconds to wait before sending changed appearance - private static readonly int m_checkTime = 500; // milliseconds to wait between checks for appearance updates + private int m_checkTime = 500; // milliseconds to wait between checks for appearance updates private System.Timers.Timer m_updateTimer = new System.Timers.Timer(); private Dictionary m_savequeue = new Dictionary(); private Dictionary m_sendqueue = new Dictionary(); #region RegionModule Members - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(Scene scene, IConfigSource config) { scene.EventManager.OnNewClient += NewClient; + if (config != null) + { + IConfig sconfig = config.Configs["Startup"]; + if (sconfig != null) + { + m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); + m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); + } + } + if (m_scene == null) m_scene = scene; } 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 @@ ; OpenJPEG if false ; UseCSJ2K = true + ; Persist avatar baked textures + ; Persisting baked textures can speed up login and region border + ; crossings especially with large numbers of users, though it + ; will store potentially large numbers of textures in your asset + ; database + PersistBakedTextures = false + + ; Control the delay before appearance is sent to other avatars and + ; saved in the avatar service. Attempts to limit the impact caused + ; by the very chatty dialog that sets appearance when an avatar + ; logs in or teleports into a region; values are in seconds + DelayBeforeAppearanceSave = 5 + DelayBeforeAppearanceSend = 2 + [SMTP] enabled=false -- cgit v1.1 From 5f4badf9e2cd96f4a4a48b0019bd5f39298213ab Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 29 Oct 2010 20:48:37 +0200 Subject: Add my work on top of cmickeyb's --- OpenSim/Framework/AvatarAppearance.cs | 100 ++++++++++++++++++++- bin/assets/TexturesAssetSet/TexturesAssetSet.xml | 6 ++ .../BodyPartsLibrary/BodyPartsLibraryItems.xml | 28 ++++++ 3 files changed, 133 insertions(+), 1 deletion(-) diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 55646dd..4738d88 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -35,6 +35,104 @@ using log4net; namespace OpenSim.Framework { + // A special dictionary for avatar appearance + public struct LayerItem + { + public UUID ItemID; + public UUID AssetID; + + public LayerItem(UUID itemID, UUID assetID) + { + ItemID = itemID; + AssetID = assetID; + } + } + + public class Layer + { + protected int m_layerType; + protected Dictionary m_items = new Dictionary(); + protected List m_ids = new List(); + + public Layer(int type) + { + m_layerType = type; + } + + public int LayerType + { + get { return m_layerType; } + } + + public int Count + { + get { return m_ids.Count; } + } + + public void Add(UUID itemID, UUID assetID) + { + if (m_items.ContainsKey(itemID)) + return; + if (m_ids.Count >= 5) + return; + + m_ids.Add(itemID); + m_items[itemID] = assetID; + } + + public void Wear(UUID itemID, UUID assetID) + { + Clear(); + Add(itemID, assetID); + } + + public void Clear() + { + m_ids.Clear(); + m_items.Clear(); + } + + public void RemoveItem(UUID itemID) + { + if (m_items.ContainsKey(itemID)) + { + m_ids.Remove(itemID); + m_items.Remove(itemID); + } + } + + public void RemoveAsset(UUID assetID) + { + UUID itemID = UUID.Zero; + + foreach (KeyValuePair kvp in m_items) + { + if (kvp.Value == assetID) + { + itemID = kvp.Key; + break; + } + } + + if (itemID != UUID.Zero) + { + m_ids.Remove(itemID); + m_items.Remove(itemID); + } + } + + public LayerItem this [int idx] + { + get + { + if (idx >= m_ids.Count || idx < 0) + return new LayerItem(UUID.Zero, UUID.Zero); + + return new LayerItem(m_ids[idx], m_items[m_ids[idx]]); + } + } + } + /// /// Contains the Avatar's Appearance and methods to manipulate the appearance. /// @@ -1456,4 +1554,4 @@ namespace OpenSim.Framework SKIRT_SKIRT_BLUE = 217 } } -} \ No newline at end of file +} diff --git a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml index c5cafa7..7c74a48 100644 --- a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml +++ b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml @@ -1,4 +1,10 @@ +
+ + + + +
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 @@
-->