Merge commit 'cmickeyb/dev-appearance'
commit
934e536738
|
@ -1614,12 +1614,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attachments
|
// Attachments
|
||||||
Dictionary<int, AvatarAttachment> attachments = avatarAppearance.Attachments;
|
List<AvatarAttachment> attachments = avatarAppearance.GetAttachments();
|
||||||
|
|
||||||
foreach (KeyValuePair<int, AvatarAttachment> attachment in attachments)
|
foreach (AvatarAttachment attachment in attachments)
|
||||||
{
|
{
|
||||||
int attachpoint = attachment.Value.AttachPoint;
|
int attachpoint = attachment.AttachPoint;
|
||||||
UUID itemID = attachment.Value.ItemID;
|
UUID itemID = attachment.ItemID;
|
||||||
|
|
||||||
if (itemID != UUID.Zero)
|
if (itemID != UUID.Zero)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
@ -765,25 +766,19 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||||
FormatPart(rdata, "UnderShirt", rdata.userAppearance.UnderShirtItem, rdata.userAppearance.UnderShirtAsset);
|
FormatPart(rdata, "UnderShirt", rdata.userAppearance.UnderShirtItem, rdata.userAppearance.UnderShirtAsset);
|
||||||
FormatPart(rdata, "UnderPants", rdata.userAppearance.UnderPantsItem, rdata.userAppearance.UnderPantsAsset);
|
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<AvatarAttachment> attachments = rdata.userAppearance.GetAttachments();
|
||||||
|
foreach (AvatarAttachment attach in attachments)
|
||||||
{
|
{
|
||||||
|
rdata.writer.WriteStartElement("Attachment");
|
||||||
Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting attachments", MsgId);
|
rdata.writer.WriteAttributeString("AtPoint", attach.AttachPoint.ToString());
|
||||||
|
rdata.writer.WriteAttributeString("Item", attach.ItemID.ToString());
|
||||||
rdata.writer.WriteStartElement("Attachments");
|
rdata.writer.WriteAttributeString("Asset", attach.AssetID.ToString());
|
||||||
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.WriteEndElement();
|
rdata.writer.WriteEndElement();
|
||||||
}
|
}
|
||||||
|
rdata.writer.WriteEndElement();
|
||||||
|
|
||||||
Primitive.TextureEntry texture = rdata.userAppearance.Texture;
|
Primitive.TextureEntry texture = rdata.userAppearance.Texture;
|
||||||
|
|
||||||
|
|
|
@ -206,16 +206,18 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
args["service_session_id"] = OSD.FromString(ServiceSessionID);
|
args["service_session_id"] = OSD.FromString(ServiceSessionID);
|
||||||
args["start_pos"] = OSD.FromString(startpos.ToString());
|
args["start_pos"] = OSD.FromString(startpos.ToString());
|
||||||
args["appearance_serial"] = OSD.FromInteger(Appearance.Serial);
|
|
||||||
args["client_ip"] = OSD.FromString(IPAddress);
|
args["client_ip"] = OSD.FromString(IPAddress);
|
||||||
args["viewer"] = OSD.FromString(Viewer);
|
args["viewer"] = OSD.FromString(Viewer);
|
||||||
args["channel"] = OSD.FromString(Channel);
|
args["channel"] = OSD.FromString(Channel);
|
||||||
args["mac"] = OSD.FromString(Mac);
|
args["mac"] = OSD.FromString(Mac);
|
||||||
args["id0"] = OSD.FromString(Id0);
|
args["id0"] = OSD.FromString(Id0);
|
||||||
|
|
||||||
/*
|
// Eventually this code should be deprecated, use full appearance
|
||||||
|
// packing in packed_appearance
|
||||||
if (Appearance != null)
|
if (Appearance != null)
|
||||||
{
|
{
|
||||||
|
args["appearance_serial"] = OSD.FromInteger(Appearance.Serial);
|
||||||
|
|
||||||
//System.Console.WriteLine("XXX Before packing Wearables");
|
//System.Console.WriteLine("XXX Before packing Wearables");
|
||||||
if ((Appearance.Wearables != null) && (Appearance.Wearables.Length > 0))
|
if ((Appearance.Wearables != null) && (Appearance.Wearables.Length > 0))
|
||||||
{
|
{
|
||||||
|
@ -230,20 +232,19 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
|
|
||||||
//System.Console.WriteLine("XXX Before packing Attachments");
|
//System.Console.WriteLine("XXX Before packing Attachments");
|
||||||
Dictionary<int, AvatarAttachment> attachments = Appearance.Attachments;
|
List<AvatarAttachment> attachments = Appearance.GetAttachments();
|
||||||
if ((attachments != null) && (attachments.Count > 0))
|
if ((attachments != null) && (attachments.Count > 0))
|
||||||
{
|
{
|
||||||
OSDArray attachs = new OSDArray(attachments.Count);
|
OSDArray attachs = new OSDArray(attachments.Count);
|
||||||
foreach (KeyValuePair<int, AvatarAttachment> kvp in attachments)
|
foreach (AvatarAttachment attach in attachments)
|
||||||
{
|
{
|
||||||
AvatarAttachment adata = new AvatarAttachment(kvp.Value);
|
attachs.Add(attach.Pack());
|
||||||
attachs.Add(adata.Pack());
|
|
||||||
//System.Console.WriteLine("XXX att.pt=" + kvp.Key + "; itemID=" + kvp.Value[0] + "; assetID=" + kvp.Value[1]);
|
//System.Console.WriteLine("XXX att.pt=" + kvp.Key + "; itemID=" + kvp.Value[0] + "; assetID=" + kvp.Value[1]);
|
||||||
}
|
}
|
||||||
args["attachments"] = attachs;
|
args["attachments"] = attachs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
if (Appearance != null)
|
if (Appearance != null)
|
||||||
{
|
{
|
||||||
OSDMap appmap = Appearance.Pack();
|
OSDMap appmap = Appearance.Pack();
|
||||||
|
@ -339,15 +340,40 @@ namespace OpenSim.Framework
|
||||||
try {
|
try {
|
||||||
// Unpack various appearance elements
|
// Unpack various appearance elements
|
||||||
Appearance = new AvatarAppearance(AgentID);
|
Appearance = new AvatarAppearance(AgentID);
|
||||||
if (args["packed_appearance"] != null)
|
|
||||||
|
// Eventually this code should be deprecated, use full appearance
|
||||||
|
// packing in packed_appearance
|
||||||
|
if (args["appearance_serial"] != null)
|
||||||
|
Appearance.Serial = args["appearance_serial"].AsInteger();
|
||||||
|
|
||||||
|
if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
|
||||||
{
|
{
|
||||||
if (args["packed_appearance"].Type == OSDType.Map)
|
OSDArray wears = (OSDArray)(args["wearables"]);
|
||||||
|
for (int i = 0; i < wears.Count / 2; i++)
|
||||||
{
|
{
|
||||||
Appearance.Unpack((OSDMap)args["packed_appearance"]);
|
AvatarWearable awear = new AvatarWearable(wears[i*2].AsUUID(),wears[(i*2)+1].AsUUID());
|
||||||
m_log.WarnFormat("[AGENTCIRCUITDATA] unpacked appearance");
|
Appearance.SetWearable(i,awear);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
m_log.WarnFormat("[AGENTCIRCUITDATA] packed_appearance is not a map:\n{0}",args["packed_appearance"].ToString());
|
|
||||||
|
if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
|
||||||
|
{
|
||||||
|
OSDArray attachs = (OSDArray)(args["attachments"]);
|
||||||
|
foreach (OSD o in attachs)
|
||||||
|
{
|
||||||
|
if (o.Type == OSDType.Map)
|
||||||
|
{
|
||||||
|
Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map))
|
||||||
|
{
|
||||||
|
Appearance.Unpack((OSDMap)args["packed_appearance"]);
|
||||||
|
// DEBUG ON
|
||||||
|
m_log.WarnFormat("[AGENTCIRCUITDATA] unpacked appearance");
|
||||||
|
// DEBUG OFF
|
||||||
}
|
}
|
||||||
// DEBUG ON
|
// DEBUG ON
|
||||||
else
|
else
|
||||||
|
@ -358,36 +384,6 @@ namespace OpenSim.Framework
|
||||||
m_log.ErrorFormat("[AGENTCIRCUITDATA] failed to unpack appearance; {0}",e.Message);
|
m_log.ErrorFormat("[AGENTCIRCUITDATA] failed to unpack appearance; {0}",e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (args["appearance_serial"] != null)
|
|
||||||
Appearance.Serial = args["appearance_serial"].AsInteger();
|
|
||||||
|
|
||||||
if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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.SetAttachments(attachments);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
ServiceURLs = new Dictionary<string, object>();
|
ServiceURLs = new Dictionary<string, object>();
|
||||||
if (args.ContainsKey("service_urls") && args["service_urls"] != null && (args["service_urls"]).Type == OSDType.Array)
|
if (args.ContainsKey("service_urls") && args["service_urls"] != null && (args["service_urls"]).Type == OSDType.Array)
|
||||||
{
|
{
|
||||||
|
|
|
@ -143,13 +143,14 @@ namespace OpenSim.Framework
|
||||||
public readonly static int VISUALPARAM_COUNT = 218;
|
public readonly static int VISUALPARAM_COUNT = 218;
|
||||||
|
|
||||||
public readonly static int TEXTURE_COUNT = 21;
|
public readonly static int TEXTURE_COUNT = 21;
|
||||||
|
public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
|
||||||
|
|
||||||
protected UUID m_owner;
|
protected UUID m_owner;
|
||||||
protected int m_serial = 1;
|
protected int m_serial = 1;
|
||||||
protected byte[] m_visualparams;
|
protected byte[] m_visualparams;
|
||||||
protected Primitive.TextureEntry m_texture;
|
protected Primitive.TextureEntry m_texture;
|
||||||
protected AvatarWearable[] m_wearables;
|
protected AvatarWearable[] m_wearables;
|
||||||
protected Dictionary<int, AvatarAttachment> m_attachments;
|
protected Dictionary<int, List<AvatarAttachment>> m_attachments;
|
||||||
protected float m_avatarHeight = 0;
|
protected float m_avatarHeight = 0;
|
||||||
protected float m_hipOffset = 0;
|
protected float m_hipOffset = 0;
|
||||||
|
|
||||||
|
@ -183,11 +184,6 @@ namespace OpenSim.Framework
|
||||||
set { m_wearables = value; }
|
set { m_wearables = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Dictionary<int, AvatarAttachment> Attachments
|
|
||||||
{
|
|
||||||
get { return m_attachments; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual UUID BodyItem {
|
public virtual UUID BodyItem {
|
||||||
get { return m_wearables[AvatarWearable.BODY].ItemID; }
|
get { return m_wearables[AvatarWearable.BODY].ItemID; }
|
||||||
set { m_wearables[AvatarWearable.BODY].ItemID = value; }
|
set { m_wearables[AvatarWearable.BODY].ItemID = value; }
|
||||||
|
@ -336,7 +332,7 @@ namespace OpenSim.Framework
|
||||||
// DEBUG ON
|
// DEBUG ON
|
||||||
m_log.WarnFormat("[AVATAR APPEARANCE] create empty appearance for {0}",owner);
|
m_log.WarnFormat("[AVATAR APPEARANCE] create empty appearance for {0}",owner);
|
||||||
// DEBUG OFF
|
// DEBUG OFF
|
||||||
m_serial = 0;
|
m_serial = 1;
|
||||||
m_owner = owner;
|
m_owner = owner;
|
||||||
|
|
||||||
SetDefaultWearables();
|
SetDefaultWearables();
|
||||||
|
@ -344,7 +340,7 @@ namespace OpenSim.Framework
|
||||||
SetDefaultParams();
|
SetDefaultParams();
|
||||||
SetHeight();
|
SetHeight();
|
||||||
|
|
||||||
m_attachments = new Dictionary<int, AvatarAttachment>();
|
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AvatarAppearance(UUID avatarID, OSDMap map)
|
public AvatarAppearance(UUID avatarID, OSDMap map)
|
||||||
|
@ -382,7 +378,7 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
SetHeight();
|
SetHeight();
|
||||||
|
|
||||||
m_attachments = new Dictionary<int, AvatarAttachment>();
|
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AvatarAppearance(AvatarAppearance appearance)
|
public AvatarAppearance(AvatarAppearance appearance)
|
||||||
|
@ -392,7 +388,7 @@ namespace OpenSim.Framework
|
||||||
// DEBUG OFF
|
// DEBUG OFF
|
||||||
if (appearance == null)
|
if (appearance == null)
|
||||||
{
|
{
|
||||||
m_serial = 0;
|
m_serial = 1;
|
||||||
m_owner = UUID.Zero;
|
m_owner = UUID.Zero;
|
||||||
|
|
||||||
SetDefaultWearables();
|
SetDefaultWearables();
|
||||||
|
@ -400,7 +396,7 @@ namespace OpenSim.Framework
|
||||||
SetDefaultParams();
|
SetDefaultParams();
|
||||||
SetHeight();
|
SetHeight();
|
||||||
|
|
||||||
m_attachments = new Dictionary<int, AvatarAttachment>();
|
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -427,9 +423,10 @@ namespace OpenSim.Framework
|
||||||
if (appearance.VisualParams != null)
|
if (appearance.VisualParams != null)
|
||||||
m_visualparams = (byte[])appearance.VisualParams.Clone();
|
m_visualparams = (byte[])appearance.VisualParams.Clone();
|
||||||
|
|
||||||
m_attachments = new Dictionary<int, AvatarAttachment>();
|
// Copy the attachment, force append mode since that ensures consistency
|
||||||
foreach (KeyValuePair<int, AvatarAttachment> kvp in appearance.Attachments)
|
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||||
m_attachments[kvp.Key] = new AvatarAttachment(kvp.Value);
|
foreach (AvatarAttachment attachment in appearance.GetAttachments())
|
||||||
|
AppendAttachment(new AvatarAttachment(attachment));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void SetDefaultWearables()
|
protected virtual void SetDefaultWearables()
|
||||||
|
@ -449,14 +446,8 @@ namespace OpenSim.Framework
|
||||||
protected virtual void SetDefaultTexture()
|
protected virtual void SetDefaultTexture()
|
||||||
{
|
{
|
||||||
m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
|
m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97"));
|
||||||
// The initialization of these seems to force a rebake regardless of whether it is needed
|
for (uint i = 0; i < TEXTURE_COUNT; i++)
|
||||||
// m_textures.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012");
|
m_texture.CreateFace(i).TextureID = new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE);
|
||||||
// m_textures.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID;
|
|
||||||
// m_textures.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID;
|
|
||||||
// m_textures.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77");
|
|
||||||
// m_textures.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B");
|
|
||||||
// m_textures.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010");
|
|
||||||
// m_textures.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -473,7 +464,7 @@ namespace OpenSim.Framework
|
||||||
// made. We determine if any of the textures actually
|
// made. We determine if any of the textures actually
|
||||||
// changed to know if the appearance should be saved later
|
// changed to know if the appearance should be saved later
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
||||||
{
|
{
|
||||||
Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i];
|
Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i];
|
||||||
Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i];
|
Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i];
|
||||||
|
@ -487,14 +478,14 @@ namespace OpenSim.Framework
|
||||||
if (oldface != null && oldface.TextureID == newface.TextureID) continue;
|
if (oldface != null && oldface.TextureID == newface.TextureID) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_texture.FaceTextures[i] = (newface != null) ? new Primitive.TextureEntryFace(newface) : null;
|
|
||||||
changed = true;
|
changed = true;
|
||||||
// DEBUG ON
|
// DEBUG ON
|
||||||
if (newface != null)
|
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
|
// DEBUG OFF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_texture = textureEntry;
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,8 +508,8 @@ namespace OpenSim.Framework
|
||||||
if (visualParams[i] != m_visualparams[i])
|
if (visualParams[i] != m_visualparams[i])
|
||||||
{
|
{
|
||||||
// DEBUG ON
|
// DEBUG ON
|
||||||
m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
|
// m_log.WarnFormat("[AVATARAPPEARANCE] vparams changed [{0}] {1} ==> {2}",
|
||||||
i,m_visualparams[i],visualParams[i]);
|
// i,m_visualparams[i],visualParams[i]);
|
||||||
// DEBUG OFF
|
// DEBUG OFF
|
||||||
m_visualparams[i] = visualParams[i];
|
m_visualparams[i] = visualParams[i];
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -569,6 +560,9 @@ namespace OpenSim.Framework
|
||||||
public override String ToString()
|
public override String ToString()
|
||||||
{
|
{
|
||||||
String s = "";
|
String s = "";
|
||||||
|
|
||||||
|
s += String.Format("Serial: {0}\n",m_serial);
|
||||||
|
|
||||||
for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++)
|
||||||
if (m_texture.FaceTextures[i] != null)
|
if (m_texture.FaceTextures[i] != null)
|
||||||
s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID);
|
s += String.Format("Texture: {0} --> {1}\n",i,m_texture.FaceTextures[i].TextureID);
|
||||||
|
@ -585,12 +579,41 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
// DEBUG OFF
|
// DEBUG OFF
|
||||||
|
|
||||||
public void SetAttachments(AvatarAttachment[] data)
|
/// <summary>
|
||||||
|
/// Get a list of the attachments, note that there may be
|
||||||
|
/// duplicate attachpoints
|
||||||
|
/// </summary>
|
||||||
|
public List<AvatarAttachment> GetAttachments()
|
||||||
{
|
{
|
||||||
foreach (AvatarAttachment attach in data)
|
List<AvatarAttachment> alist = new List<AvatarAttachment>();
|
||||||
m_attachments[attach.AttachPoint] = new AvatarAttachment(attach);
|
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
|
||||||
|
{
|
||||||
|
foreach (AvatarAttachment attach in kvp.Value)
|
||||||
|
alist.Add(new AvatarAttachment(attach));
|
||||||
|
}
|
||||||
|
|
||||||
|
return alist;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void AppendAttachment(AvatarAttachment attach)
|
||||||
|
{
|
||||||
|
if (! m_attachments.ContainsKey(attach.AttachPoint))
|
||||||
|
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
|
||||||
|
m_attachments[attach.AttachPoint].Add(attach);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void ReplaceAttachment(AvatarAttachment attach)
|
||||||
|
{
|
||||||
|
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
|
||||||
|
m_attachments[attach.AttachPoint].Add(attach);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
public void SetAttachment(int attachpoint, UUID item, UUID asset)
|
public void SetAttachment(int attachpoint, UUID item, UUID asset)
|
||||||
{
|
{
|
||||||
if (attachpoint == 0)
|
if (attachpoint == 0)
|
||||||
|
@ -603,67 +626,47 @@ namespace OpenSim.Framework
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_attachments[attachpoint] = new AvatarAttachment(attachpoint,item,asset);
|
// check if this is an append or a replace, 0x80 marks it as an append
|
||||||
}
|
if ((attachpoint & 0x80) > 0)
|
||||||
|
|
||||||
public Hashtable GetAttachments()
|
|
||||||
{
|
|
||||||
if (m_attachments.Count == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Hashtable ret = new Hashtable();
|
|
||||||
|
|
||||||
foreach (KeyValuePair<int, AvatarAttachment> kvp in m_attachments)
|
|
||||||
{
|
{
|
||||||
Hashtable data = new Hashtable();
|
// strip the append bit
|
||||||
data["item"] = kvp.Value.ItemID.ToString();
|
int point = attachpoint & 0x7F;
|
||||||
data["asset"] = kvp.Value.AssetID.ToString();
|
AppendAttachment(new AvatarAttachment(point, item, asset));
|
||||||
|
}
|
||||||
ret[kvp.Key] = data;
|
else
|
||||||
|
{
|
||||||
|
ReplaceAttachment(new AvatarAttachment(attachpoint,item,asset));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<int> GetAttachedPoints()
|
|
||||||
{
|
|
||||||
return new List<int>(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)
|
public int GetAttachpoint(UUID itemID)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<int, AvatarAttachment> kvp in m_attachments)
|
foreach (KeyValuePair<int, List<AvatarAttachment>> 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 kvp.Key;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DetachAttachment(UUID itemID)
|
public void DetachAttachment(UUID itemID)
|
||||||
{
|
{
|
||||||
int attachpoint = GetAttachpoint(itemID);
|
foreach (KeyValuePair<int, List<AvatarAttachment>> 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)
|
// And remove the list if there are no more attachments here
|
||||||
m_attachments.Remove(attachpoint);
|
if (m_attachments[kvp.Key].Count == 0)
|
||||||
|
m_attachments.Remove(kvp.Key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearAttachments()
|
public void ClearAttachments()
|
||||||
|
@ -671,6 +674,8 @@ namespace OpenSim.Framework
|
||||||
m_attachments.Clear();
|
m_attachments.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Packing Functions
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create an OSDMap from the appearance data
|
/// Create an OSDMap from the appearance data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -695,7 +700,7 @@ namespace OpenSim.Framework
|
||||||
if (m_texture.FaceTextures[i] != null)
|
if (m_texture.FaceTextures[i] != null)
|
||||||
textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID));
|
textures.Add(OSD.FromUUID(m_texture.FaceTextures[i].TextureID));
|
||||||
else
|
else
|
||||||
textures.Add(OSD.FromUUID(UUID.Zero));
|
textures.Add(OSD.FromUUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE));
|
||||||
}
|
}
|
||||||
data["textures"] = textures;
|
data["textures"] = textures;
|
||||||
|
|
||||||
|
@ -705,8 +710,8 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
// Attachments
|
// Attachments
|
||||||
OSDArray attachs = new OSDArray(m_attachments.Count);
|
OSDArray attachs = new OSDArray(m_attachments.Count);
|
||||||
foreach (KeyValuePair<int, AvatarAttachment> kvp in m_attachments)
|
foreach (AvatarAttachment attach in GetAttachments())
|
||||||
attachs.Add(kvp.Value.Pack());
|
attachs.Add(attach.Pack());
|
||||||
data["attachments"] = attachs;
|
data["attachments"] = attachs;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -718,8 +723,8 @@ namespace OpenSim.Framework
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Unpack(OSDMap data)
|
public void Unpack(OSDMap data)
|
||||||
{
|
{
|
||||||
if ((data != null) && (data["appearance_serial"] != null))
|
if ((data != null) && (data["serial"] != null))
|
||||||
m_serial = data["appearance_serial"].AsInteger();
|
m_serial = data["serial"].AsInteger();
|
||||||
if ((data != null) && (data["height"] != null))
|
if ((data != null) && (data["height"] != null))
|
||||||
m_avatarHeight = (float)data["height"].AsReal();
|
m_avatarHeight = (float)data["height"].AsReal();
|
||||||
if ((data != null) && (data["hipoffset"] != null))
|
if ((data != null) && (data["hipoffset"] != null))
|
||||||
|
@ -747,12 +752,10 @@ namespace OpenSim.Framework
|
||||||
OSDArray textures = (OSDArray)(data["textures"]);
|
OSDArray textures = (OSDArray)(data["textures"]);
|
||||||
for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++)
|
for (int i = 0; i < AvatarAppearance.TEXTURE_COUNT && i < textures.Count; i++)
|
||||||
{
|
{
|
||||||
|
UUID textureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE;
|
||||||
if (textures[i] != null)
|
if (textures[i] != null)
|
||||||
{
|
textureID = textures[i].AsUUID();
|
||||||
UUID textureID = textures[i].AsUUID();
|
m_texture.CreateFace((uint)i).TextureID = new UUID(textureID);
|
||||||
if (textureID != UUID.Zero)
|
|
||||||
m_texture.CreateFace((uint)i).TextureID = textureID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -773,15 +776,12 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attachments
|
// Attachments
|
||||||
m_attachments = new Dictionary<int, AvatarAttachment>();
|
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||||
if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array)
|
if ((data != null) && (data["attachments"] != null) && (data["attachments"]).Type == OSDType.Array)
|
||||||
{
|
{
|
||||||
OSDArray attachs = (OSDArray)(data["attachments"]);
|
OSDArray attachs = (OSDArray)(data["attachments"]);
|
||||||
for (int i = 0; i < attachs.Count; i++)
|
for (int i = 0; i < attachs.Count; i++)
|
||||||
{
|
AppendAttachment(new AvatarAttachment((OSDMap)attachs[i]));
|
||||||
AvatarAttachment attach = new AvatarAttachment((OSDMap)attachs[i]);
|
|
||||||
m_attachments[attach.AttachPoint] = attach;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -790,6 +790,9 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region VPElement
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Viewer Params Array Element for AgentSetAppearance
|
/// Viewer Params Array Element for AgentSetAppearance
|
||||||
|
@ -1553,5 +1556,6 @@ namespace OpenSim.Framework
|
||||||
SKIRT_SKIRT_GREEN = 216,
|
SKIRT_SKIRT_GREEN = 216,
|
||||||
SKIRT_SKIRT_BLUE = 217
|
SKIRT_SKIRT_BLUE = 217
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework.Servers;
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
@ -112,6 +113,8 @@ namespace OpenSim.Framework.Capabilities
|
||||||
private string m_regionName;
|
private string m_regionName;
|
||||||
private object m_fetchLock = new Object();
|
private object m_fetchLock = new Object();
|
||||||
|
|
||||||
|
private bool m_persistBakedTextures = false;
|
||||||
|
|
||||||
public bool SSLCaps
|
public bool SSLCaps
|
||||||
{
|
{
|
||||||
get { return m_httpListener.UseSSL; }
|
get { return m_httpListener.UseSSL; }
|
||||||
|
@ -145,6 +148,15 @@ namespace OpenSim.Framework.Capabilities
|
||||||
|
|
||||||
m_httpListenPort = httpPort;
|
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)
|
if (httpServer != null && httpServer.UseSSL)
|
||||||
{
|
{
|
||||||
m_httpListenPort = httpServer.SSLPort;
|
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 = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString());
|
||||||
asset.Data = data;
|
asset.Data = data;
|
||||||
asset.Temporary = true;
|
asset.Temporary = true;
|
||||||
asset.Local = true;
|
asset.Local = ! m_persistBakedTextures; // Local assets aren't persisted, non-local are
|
||||||
m_assetCache.Store(asset);
|
m_assetCache.Store(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.StructuredData;
|
using OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
|
@ -310,6 +312,12 @@ namespace OpenSim.Framework
|
||||||
// Appearance
|
// Appearance
|
||||||
public AvatarAppearance Appearance;
|
public AvatarAppearance Appearance;
|
||||||
|
|
||||||
|
// DEBUG ON
|
||||||
|
private static readonly ILog m_log =
|
||||||
|
LogManager.GetLogger(
|
||||||
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
// DEBUG OFF
|
||||||
|
|
||||||
/*
|
/*
|
||||||
public byte[] AgentTextures;
|
public byte[] AgentTextures;
|
||||||
public byte[] VisualParams;
|
public byte[] VisualParams;
|
||||||
|
@ -323,6 +331,10 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public virtual OSDMap Pack()
|
public virtual OSDMap Pack()
|
||||||
{
|
{
|
||||||
|
// DEBUG ON
|
||||||
|
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Pack data");
|
||||||
|
// DEBUG OFF
|
||||||
|
|
||||||
OSDMap args = new OSDMap();
|
OSDMap args = new OSDMap();
|
||||||
args["message_type"] = OSD.FromString("AgentData");
|
args["message_type"] = OSD.FromString("AgentData");
|
||||||
|
|
||||||
|
@ -387,31 +399,40 @@ namespace OpenSim.Framework
|
||||||
// args["agent_textures"] = textures;
|
// args["agent_textures"] = textures;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/*
|
// The code to pack textures, visuals, wearables and attachments
|
||||||
if ((AgentTextures != null) && (AgentTextures.Length > 0))
|
// should be removed; packed appearance contains the full appearance
|
||||||
args["texture_entry"] = OSD.FromBinary(AgentTextures);
|
// This is retained for backward compatibility only
|
||||||
|
if (Appearance.Texture != null)
|
||||||
|
{
|
||||||
|
byte[] rawtextures = Appearance.Texture.GetBytes();
|
||||||
|
args["texture_entry"] = OSD.FromBinary(rawtextures);
|
||||||
|
}
|
||||||
|
|
||||||
if ((VisualParams != null) && (VisualParams.Length > 0))
|
if ((Appearance.VisualParams != null) && (Appearance.VisualParams.Length > 0))
|
||||||
args["visual_params"] = OSD.FromBinary(VisualParams);
|
args["visual_params"] = OSD.FromBinary(Appearance.VisualParams);
|
||||||
|
|
||||||
// We might not pass this in all cases...
|
// 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);
|
OSDArray wears = new OSDArray(Appearance.Wearables.Length * 2);
|
||||||
foreach (UUID uuid in Wearables)
|
foreach (AvatarWearable awear in Appearance.Wearables)
|
||||||
wears.Add(OSD.FromUUID(uuid));
|
{
|
||||||
|
wears.Add(OSD.FromUUID(awear.ItemID));
|
||||||
|
wears.Add(OSD.FromUUID(awear.AssetID));
|
||||||
|
}
|
||||||
args["wearables"] = wears;
|
args["wearables"] = wears;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<AvatarAttachment> attachments = Appearance.GetAttachments();
|
||||||
if ((Attachments != null) && (Attachments.Length > 0))
|
if ((attachments != null) && (attachments.Count > 0))
|
||||||
{
|
{
|
||||||
OSDArray attachs = new OSDArray(Attachments.Length);
|
OSDArray attachs = new OSDArray(attachments.Count);
|
||||||
foreach (AvatarAttachment att in Attachments)
|
foreach (AvatarAttachment att in attachments)
|
||||||
attachs.Add(att.Pack());
|
attachs.Add(att.Pack());
|
||||||
args["attachments"] = attachs;
|
args["attachments"] = attachs;
|
||||||
}
|
}
|
||||||
*/
|
// End of code to remove
|
||||||
|
|
||||||
if ((Controllers != null) && (Controllers.Length > 0))
|
if ((Controllers != null) && (Controllers.Length > 0))
|
||||||
{
|
{
|
||||||
OSDArray controls = new OSDArray(Controllers.Length);
|
OSDArray controls = new OSDArray(Controllers.Length);
|
||||||
|
@ -435,6 +456,10 @@ namespace OpenSim.Framework
|
||||||
/// <param name="hash"></param>
|
/// <param name="hash"></param>
|
||||||
public virtual void Unpack(OSDMap args)
|
public virtual void Unpack(OSDMap args)
|
||||||
{
|
{
|
||||||
|
// DEBUG ON
|
||||||
|
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Unpack data");
|
||||||
|
// DEBUG OFF
|
||||||
|
|
||||||
if (args.ContainsKey("region_id"))
|
if (args.ContainsKey("region_id"))
|
||||||
UUID.TryParse(args["region_id"].AsString(), out RegionID);
|
UUID.TryParse(args["region_id"].AsString(), out RegionID);
|
||||||
|
|
||||||
|
@ -547,41 +572,54 @@ namespace OpenSim.Framework
|
||||||
// AgentTextures[i++] = o.AsUUID();
|
// AgentTextures[i++] = o.AsUUID();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (args["packed_appearance"] != null)
|
Appearance = new AvatarAppearance(AgentID);
|
||||||
Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]);
|
|
||||||
else
|
// The code to unpack textures, visuals, wearables and attachments
|
||||||
Appearance = new AvatarAppearance(AgentID);
|
// should be removed; packed appearance contains the full appearance
|
||||||
|
// This is retained for backward compatibility only
|
||||||
/*
|
|
||||||
if (args["texture_entry"] != null)
|
if (args["texture_entry"] != null)
|
||||||
AgentTextures = 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)
|
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)
|
if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array)
|
||||||
{
|
{
|
||||||
OSDArray wears = (OSDArray)(args["wearables"]);
|
OSDArray wears = (OSDArray)(args["wearables"]);
|
||||||
Wearables = new UUID[wears.Count];
|
for (int i = 0; i < wears.Count / 2; i++)
|
||||||
int i = 0;
|
{
|
||||||
foreach (OSD o in wears)
|
AvatarWearable awear = new AvatarWearable(wears[i*2].AsUUID(),wears[(i*2)+1].AsUUID());
|
||||||
Wearables[i++] = o.AsUUID();
|
Appearance.SetWearable(i,awear);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
|
if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array)
|
||||||
{
|
{
|
||||||
OSDArray attachs = (OSDArray)(args["attachments"]);
|
OSDArray attachs = (OSDArray)(args["attachments"]);
|
||||||
Attachments = new AvatarAttachment[attachs.Count];
|
|
||||||
int i = 0;
|
|
||||||
foreach (OSD o in attachs)
|
foreach (OSD o in attachs)
|
||||||
{
|
{
|
||||||
if (o.Type == OSDType.Map)
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
// end of code to remove
|
||||||
|
|
||||||
|
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
|
||||||
|
Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]);
|
||||||
|
// DEBUG ON
|
||||||
|
else
|
||||||
|
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance");
|
||||||
|
// DEBUG OFF
|
||||||
|
|
||||||
if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
|
if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array)
|
||||||
{
|
{
|
||||||
OSDArray controls = (OSDArray)(args["controllers"]);
|
OSDArray controls = (OSDArray)(args["controllers"]);
|
||||||
|
|
|
@ -123,15 +123,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
|
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
|
||||||
|
|
||||||
// Save avatar attachment information
|
// Save avatar attachment information
|
||||||
ScenePresence presence;
|
m_log.Info(
|
||||||
if (m_scene.AvatarService != null && m_scene.TryGetScenePresence(remoteClient.AgentId, out presence))
|
"[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
|
||||||
{
|
+ ", AttachmentPoint: " + AttachmentPt);
|
||||||
m_log.Info(
|
|
||||||
"[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
|
|
||||||
+ ", AttachmentPoint: " + AttachmentPt);
|
|
||||||
|
|
||||||
m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance);
|
if (m_scene.AvatarFactory != null)
|
||||||
}
|
m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -382,8 +379,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
item = m_scene.InventoryService.GetItem(item);
|
item = m_scene.InventoryService.GetItem(item);
|
||||||
presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */);
|
presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */);
|
||||||
|
|
||||||
if (m_scene.AvatarService != null)
|
if (m_scene.AvatarFactory != null)
|
||||||
m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance);
|
m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,11 +402,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
presence.Appearance.DetachAttachment(itemID);
|
presence.Appearance.DetachAttachment(itemID);
|
||||||
|
|
||||||
// Save avatar attachment information
|
// Save avatar attachment information
|
||||||
if (m_scene.AvatarService != null)
|
m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
|
||||||
{
|
if (m_scene.AvatarFactory != null)
|
||||||
m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID);
|
m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
|
||||||
m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DetachSingleAttachmentToInv(itemID, remoteClient);
|
DetachSingleAttachmentToInv(itemID, remoteClient);
|
||||||
|
@ -435,10 +430,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
|
|
||||||
presence.Appearance.DetachAttachment(itemID);
|
presence.Appearance.DetachAttachment(itemID);
|
||||||
|
|
||||||
if (m_scene.AvatarService != null)
|
if (m_scene.AvatarFactory != null)
|
||||||
{
|
m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId);
|
||||||
m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance);
|
|
||||||
}
|
|
||||||
part.ParentGroup.DetachToGround();
|
part.ParentGroup.DetachToGround();
|
||||||
|
|
||||||
List<UUID> uuids = new List<UUID>();
|
List<UUID> uuids = new List<UUID>();
|
||||||
|
|
|
@ -32,23 +32,45 @@ using Nini.Config;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
|
||||||
|
using System.Threading;
|
||||||
|
using System.Timers;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
|
|
||||||
namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
{
|
{
|
||||||
public class AvatarFactoryModule : IRegionModule
|
public class AvatarFactoryModule : IAvatarFactory, IRegionModule
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
|
|
||||||
private Scene m_scene = null;
|
private Scene m_scene = null;
|
||||||
|
|
||||||
private bool m_startAnimationSet = false;
|
private int m_savetime = 5; // seconds to wait before saving changed appearance
|
||||||
|
private int m_sendtime = 2; // seconds to wait before sending changed appearance
|
||||||
|
|
||||||
public void Initialise(Scene scene, IConfigSource source)
|
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<UUID,long> m_savequeue = new Dictionary<UUID,long>();
|
||||||
|
private Dictionary<UUID,long> m_sendqueue = new Dictionary<UUID,long>();
|
||||||
|
|
||||||
|
#region RegionModule Members
|
||||||
|
|
||||||
|
public void Initialise(Scene scene, IConfigSource config)
|
||||||
{
|
{
|
||||||
|
scene.RegisterModuleInterface<IAvatarFactory>(this);
|
||||||
scene.EventManager.OnNewClient += NewClient;
|
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)
|
if (m_scene == null)
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
|
@ -56,6 +78,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
|
|
||||||
public void PostInitialise()
|
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()
|
public void Close()
|
||||||
|
@ -84,6 +110,36 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
// client.OnAvatarNowWearing -= AvatarIsWearing;
|
// client.OnAvatarNowWearing -= AvatarIsWearing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public bool ValidateBakedTextureCache(IClientAPI client)
|
||||||
|
{
|
||||||
|
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||||
|
if (sp == null)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[AVFACTORY] SetAppearance unable to find presence for {0}",client.AgentId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cached = true;
|
||||||
|
|
||||||
|
// Process the texture entry
|
||||||
|
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
|
||||||
|
{
|
||||||
|
int idx = AvatarAppearance.BAKE_INDICES[i];
|
||||||
|
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
|
||||||
|
if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
|
||||||
|
if (! CheckBakedTextureAsset(client,face.TextureID,idx))
|
||||||
|
{
|
||||||
|
sp.Appearance.Texture.FaceTextures[idx] = null;
|
||||||
|
cached = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set appearance data (textureentry and slider settings) received from the client
|
/// Set appearance data (textureentry and slider settings) received from the client
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -91,6 +147,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
/// <param name="visualParam"></param>
|
/// <param name="visualParam"></param>
|
||||||
public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
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);
|
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||||
if (sp == null)
|
if (sp == null)
|
||||||
{
|
{
|
||||||
|
@ -98,85 +158,179 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
return;
|
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;
|
bool changed = false;
|
||||||
|
|
||||||
// Process the texture entry
|
// Process the texture entry
|
||||||
if (textureEntry != null)
|
if (textureEntry != null)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < BAKE_INDICES.Length; i++)
|
|
||||||
{
|
|
||||||
int j = BAKE_INDICES[i];
|
|
||||||
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,this.Name);
|
|
||||||
client.SendRebakeAvatarTextures(face.TextureID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
changed = sp.Appearance.SetTextureEntries(textureEntry);
|
changed = sp.Appearance.SetTextureEntries(textureEntry);
|
||||||
|
|
||||||
|
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
|
||||||
|
{
|
||||||
|
int idx = AvatarAppearance.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) {
|
||||||
|
if (! CheckBakedTextureAsset(client,face.TextureID,idx))
|
||||||
|
client.SendRebakeAvatarTextures(face.TextureID);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Bake Cache Check
|
// Process the visual params, this may change height as well
|
||||||
|
if (visualParams != null)
|
||||||
changed = sp.Appearance.SetVisualParams(visualParams) || changed;
|
|
||||||
|
|
||||||
// If nothing changed (this happens frequently) just return
|
|
||||||
if (changed)
|
|
||||||
{
|
{
|
||||||
// DEBUG ON
|
if (sp.Appearance.SetVisualParams(visualParams))
|
||||||
m_log.Warn("[AVFACTORY] Appearance changed");
|
{
|
||||||
// DEBUG OFF
|
changed = true;
|
||||||
sp.Appearance.SetAppearance(textureEntry, visualParams);
|
if (sp.Appearance.AvatarHeight > 0)
|
||||||
if (sp.Appearance.AvatarHeight > 0)
|
sp.SetHeight(sp.Appearance.AvatarHeight);
|
||||||
sp.SetHeight(sp.Appearance.AvatarHeight);
|
}
|
||||||
|
|
||||||
m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance);
|
|
||||||
}
|
}
|
||||||
// DEBUG ON
|
|
||||||
else
|
// If something changed in the appearance then queue an appearance save
|
||||||
m_log.Warn("[AVFACTORY] Appearance did not change");
|
if (changed)
|
||||||
// DEBUG OFF
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks for the existance of a baked texture asset and
|
||||||
|
/// requests the viewer rebake if the asset is not found
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client"></param>
|
||||||
|
/// <param name="textureID"></param>
|
||||||
|
/// <param name="idx"></param>
|
||||||
|
private bool CheckBakedTextureAsset(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);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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.WarnFormat("[AVFACTORY] Queue appearance save for {0}",agentid);
|
||||||
|
// DEBUG OFF
|
||||||
|
|
||||||
|
// 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
|
||||||
|
m_log.WarnFormat("[AVFACTORY] Handle appearance send for {0}",agentid);
|
||||||
|
// DEBUG OFF
|
||||||
|
|
||||||
|
// Send the appearance to everyone in the scene
|
||||||
sp.SendAppearanceToAllOtherAgents();
|
sp.SendAppearanceToAllOtherAgents();
|
||||||
|
sp.ControllingClient.SendAvatarDataImmediate(sp);
|
||||||
|
|
||||||
|
// Send the appearance back to the avatar
|
||||||
|
// AvatarAppearance avp = sp.Appearance;
|
||||||
|
// 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)
|
if (!m_startAnimationSet)
|
||||||
{
|
{
|
||||||
sp.Animator.UpdateMovementAnimations();
|
sp.Animator.UpdateMovementAnimations();
|
||||||
m_startAnimationSet = true;
|
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<UUID,long> sends = new Dictionary<UUID,long>(m_sendqueue);
|
||||||
|
foreach (KeyValuePair<UUID,long> kvp in sends)
|
||||||
|
{
|
||||||
|
if (kvp.Value < now)
|
||||||
|
{
|
||||||
|
Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); });
|
||||||
|
m_sendqueue.Remove(kvp.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (m_savequeue)
|
||||||
|
{
|
||||||
|
Dictionary<UUID,long> saves = new Dictionary<UUID,long>(m_savequeue);
|
||||||
|
foreach (KeyValuePair<UUID,long> 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
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tell the client for this scene presence what items it should be wearing now
|
/// Tell the client for this scene presence what items it should be wearing now
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -215,14 +369,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
|
|
||||||
AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance);
|
AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance);
|
||||||
|
|
||||||
//if (!TryGetAvatarAppearance(client.AgentId, out avatAppearance))
|
|
||||||
//{
|
|
||||||
// m_log.Warn("[AVFACTORY]: We didn't seem to find the appearance, falling back to ScenePresence");
|
|
||||||
// avatAppearance = sp.Appearance;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[AVFACTORY]: Received wearables for {0}", client.Name);
|
|
||||||
|
|
||||||
foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
|
foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
|
||||||
{
|
{
|
||||||
if (wear.Type < AvatarWearable.MAX_WEARABLES)
|
if (wear.Type < AvatarWearable.MAX_WEARABLES)
|
||||||
|
@ -232,10 +378,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This could take awhile since it needs to pull inventory
|
||||||
SetAppearanceAssets(sp.UUID, ref avatAppearance);
|
SetAppearanceAssets(sp.UUID, ref avatAppearance);
|
||||||
|
|
||||||
m_scene.AvatarService.SetAppearance(client.AgentId, avatAppearance);
|
|
||||||
sp.Appearance = avatAppearance;
|
sp.Appearance = avatAppearance;
|
||||||
|
m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
|
private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Framework.Interfaces
|
||||||
|
{
|
||||||
|
public interface IAvatarFactory
|
||||||
|
{
|
||||||
|
bool ValidateBakedTextureCache(IClientAPI client);
|
||||||
|
void QueueAppearanceSend(UUID agentid);
|
||||||
|
void QueueAppearanceSave(UUID agentid);
|
||||||
|
}
|
||||||
|
}
|
|
@ -119,6 +119,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
protected IXMLRPC m_xmlrpcModule;
|
protected IXMLRPC m_xmlrpcModule;
|
||||||
protected IWorldComm m_worldCommModule;
|
protected IWorldComm m_worldCommModule;
|
||||||
|
protected IAvatarFactory m_AvatarFactory;
|
||||||
protected IConfigSource m_config;
|
protected IConfigSource m_config;
|
||||||
protected IRegionSerialiserModule m_serialiser;
|
protected IRegionSerialiserModule m_serialiser;
|
||||||
protected IDialogModule m_dialogModule;
|
protected IDialogModule m_dialogModule;
|
||||||
|
@ -398,6 +399,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public IAttachmentsModule AttachmentsModule { get; set; }
|
public IAttachmentsModule AttachmentsModule { get; set; }
|
||||||
|
|
||||||
|
public IAvatarFactory AvatarFactory
|
||||||
|
{
|
||||||
|
get { return m_AvatarFactory; }
|
||||||
|
}
|
||||||
|
|
||||||
public ICapabilitiesModule CapsModule
|
public ICapabilitiesModule CapsModule
|
||||||
{
|
{
|
||||||
get { return m_capsModule; }
|
get { return m_capsModule; }
|
||||||
|
@ -1153,6 +1159,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_xmlrpcModule = RequestModuleInterface<IXMLRPC>();
|
m_xmlrpcModule = RequestModuleInterface<IXMLRPC>();
|
||||||
m_worldCommModule = RequestModuleInterface<IWorldComm>();
|
m_worldCommModule = RequestModuleInterface<IWorldComm>();
|
||||||
XferManager = RequestModuleInterface<IXfer>();
|
XferManager = RequestModuleInterface<IXfer>();
|
||||||
|
m_AvatarFactory = RequestModuleInterface<IAvatarFactory>();
|
||||||
AttachmentsModule = RequestModuleInterface<IAttachmentsModule>();
|
AttachmentsModule = RequestModuleInterface<IAttachmentsModule>();
|
||||||
m_serialiser = RequestModuleInterface<IRegionSerialiserModule>();
|
m_serialiser = RequestModuleInterface<IRegionSerialiserModule>();
|
||||||
m_dialogModule = RequestModuleInterface<IDialogModule>();
|
m_dialogModule = RequestModuleInterface<IDialogModule>();
|
||||||
|
|
|
@ -704,20 +704,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// we created a new ScenePresence (a new child agent) in a fresh region.
|
// we created a new ScenePresence (a new child agent) in a fresh region.
|
||||||
// Request info about all the (root) agents in this region
|
// Request info about all the (root) agents in this region
|
||||||
// Note: This won't send data *to* other clients in that region (children don't send)
|
// Note: This won't send data *to* other clients in that region (children don't send)
|
||||||
|
|
||||||
|
// MIC: This gets called again in CompleteMovement
|
||||||
SendInitialFullUpdateToAllClients();
|
SendInitialFullUpdateToAllClients();
|
||||||
|
|
||||||
RegisterToEvents();
|
RegisterToEvents();
|
||||||
SetDirectionVectors();
|
SetDirectionVectors();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams,
|
|
||||||
AvatarWearable[] wearables)
|
|
||||||
: this(client, world, reginfo)
|
|
||||||
{
|
|
||||||
m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
|
public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance)
|
||||||
: this(client, world, reginfo)
|
: this(client, world, reginfo)
|
||||||
{
|
{
|
||||||
|
@ -1081,7 +1075,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void CompleteMovement(IClientAPI client)
|
public void CompleteMovement(IClientAPI client)
|
||||||
{
|
{
|
||||||
//m_log.Debug("[SCENE PRESENCE]: CompleteMovement");
|
// DEBUG ON
|
||||||
|
m_log.WarnFormat("[SCENE PRESENCE]: CompleteMovement for {0}",UUID);
|
||||||
|
// DEBUG OFF
|
||||||
|
|
||||||
Vector3 look = Velocity;
|
Vector3 look = Velocity;
|
||||||
if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
|
if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
|
||||||
|
@ -2381,12 +2377,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// 2 stage check is needed.
|
// 2 stage check is needed.
|
||||||
if (remoteAvatar == null)
|
if (remoteAvatar == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IClientAPI cl=remoteAvatar.ControllingClient;
|
IClientAPI cl=remoteAvatar.ControllingClient;
|
||||||
if (cl == null)
|
if (cl == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_appearance.Texture == null)
|
if (m_appearance.Texture == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (LocalId == remoteAvatar.LocalId)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (IsChildAgent)
|
if (IsChildAgent)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[SCENEPRESENCE] A child agent is attempting to send out avatar data");
|
m_log.WarnFormat("[SCENEPRESENCE] A child agent is attempting to send out avatar data");
|
||||||
|
@ -2407,20 +2411,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
|
m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
|
||||||
{
|
{
|
||||||
++avUpdates;
|
++avUpdates;
|
||||||
// only send if this is the root (children are only "listening posts" in a foreign region)
|
|
||||||
|
// Don't update ourselves
|
||||||
|
if (avatar.LocalId == LocalId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If this is a root agent, then get info about the avatar
|
||||||
if (!IsChildAgent)
|
if (!IsChildAgent)
|
||||||
{
|
{
|
||||||
SendFullUpdateToOtherClient(avatar);
|
SendFullUpdateToOtherClient(avatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avatar.LocalId != LocalId)
|
// If the other avatar is a root
|
||||||
|
if (!avatar.IsChildAgent)
|
||||||
{
|
{
|
||||||
if (!avatar.IsChildAgent)
|
avatar.SendFullUpdateToOtherClient(this);
|
||||||
{
|
avatar.SendAppearanceToOtherAgent(this);
|
||||||
avatar.SendFullUpdateToOtherClient(this);
|
avatar.Animator.SendAnimPackToClient(ControllingClient);
|
||||||
avatar.SendAppearanceToOtherAgent(this);
|
|
||||||
avatar.Animator.SendAnimPackToClient(ControllingClient);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2465,7 +2472,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
|
// m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance);
|
||||||
|
|
||||||
m_controllingClient.SendAvatarDataImmediate(this);
|
m_controllingClient.SendAvatarDataImmediate(this);
|
||||||
m_controllingClient.SendAppearance(m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes());
|
if (m_scene.AvatarFactory != null)
|
||||||
|
{
|
||||||
|
if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient))
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[SP] baked textures are in the ache for {0}",Name);
|
||||||
|
m_controllingClient.SendAppearance(
|
||||||
|
m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[SP] AvatarFactory not set");
|
||||||
|
}
|
||||||
|
|
||||||
SendInitialFullUpdateToAllClients();
|
SendInitialFullUpdateToAllClients();
|
||||||
}
|
}
|
||||||
|
@ -2497,9 +2516,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="avatar"></param>
|
/// <param name="avatar"></param>
|
||||||
public void SendAppearanceToOtherAgent(ScenePresence avatar)
|
public void SendAppearanceToOtherAgent(ScenePresence avatar)
|
||||||
{
|
{
|
||||||
|
if (LocalId == avatar.LocalId)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// DEBUG ON
|
// DEBUG ON
|
||||||
m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId);
|
// m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId);
|
||||||
// DEBUG OFF
|
// DEBUG OFF
|
||||||
|
|
||||||
avatar.ControllingClient.SendAppearance(
|
avatar.ControllingClient.SendAppearance(
|
||||||
m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
|
m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes());
|
||||||
}
|
}
|
||||||
|
@ -3656,15 +3682,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<int> attPoints = m_appearance.GetAttachedPoints();
|
List<AvatarAttachment> attachments = m_appearance.GetAttachments();
|
||||||
foreach (int p in attPoints)
|
foreach (AvatarAttachment attach in attachments)
|
||||||
{
|
{
|
||||||
if (m_isDeleted)
|
if (m_isDeleted)
|
||||||
return;
|
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
|
// 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.
|
// But they're not used anyway, the item is being looked up for now, so let's proceed.
|
||||||
//if (UUID.Zero == assetID)
|
//if (UUID.Zero == assetID)
|
||||||
|
|
|
@ -29,6 +29,7 @@ using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
|
||||||
|
@ -81,16 +82,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
|
||||||
get {
|
get {
|
||||||
List<IAvatarAttachment> attachments = new List<IAvatarAttachment>();
|
List<IAvatarAttachment> attachments = new List<IAvatarAttachment>();
|
||||||
|
|
||||||
Hashtable internalAttachments = GetSP().Appearance.GetAttachments();
|
List<AvatarAttachment> internalAttachments = GetSP().Appearance.GetAttachments();
|
||||||
if (internalAttachments != null)
|
foreach (AvatarAttachment attach in internalAttachments)
|
||||||
{
|
{
|
||||||
foreach (DictionaryEntry element in internalAttachments)
|
attachments.Add(new SPAvatarAttachment(m_rootScene, this, attach.AttachPoint,
|
||||||
{
|
new UUID(attach.ItemID),
|
||||||
Hashtable attachInfo = (Hashtable)element.Value;
|
new UUID(attach.AssetID), m_security));
|
||||||
attachments.Add(new SPAvatarAttachment(m_rootScene, this, (int) element.Key,
|
|
||||||
new UUID((string) attachInfo["item"]),
|
|
||||||
new UUID((string) attachInfo["asset"]), m_security));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return attachments.ToArray();
|
return attachments.ToArray();
|
||||||
|
|
|
@ -178,17 +178,11 @@ namespace OpenSim.Services.Interfaces
|
||||||
Data["UnderShirtAsset"] = appearance.UnderShirtAsset.ToString();
|
Data["UnderShirtAsset"] = appearance.UnderShirtAsset.ToString();
|
||||||
|
|
||||||
// Attachments
|
// Attachments
|
||||||
Hashtable attachs = appearance.GetAttachments();
|
List<AvatarAttachment> attachments = appearance.GetAttachments();
|
||||||
if (attachs != null)
|
foreach (AvatarAttachment attach in attachments)
|
||||||
foreach (DictionaryEntry dentry in attachs)
|
{
|
||||||
{
|
Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString();
|
||||||
if (dentry.Value != null)
|
}
|
||||||
{
|
|
||||||
Hashtable tab = (Hashtable)dentry.Value;
|
|
||||||
if (tab.ContainsKey("item") && tab["item"] != null)
|
|
||||||
Data["_ap_" + dentry.Key] = tab["item"].ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AvatarAppearance ToAvatarAppearance(UUID owner)
|
public AvatarAppearance ToAvatarAppearance(UUID owner)
|
||||||
|
|
|
@ -255,6 +255,20 @@
|
||||||
; OpenJPEG if false
|
; OpenJPEG if false
|
||||||
; UseCSJ2K = true
|
; 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]
|
[SMTP]
|
||||||
enabled=false
|
enabled=false
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue