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. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 +++++---- .../OptionalModules/Scripting/Minimodule/SPAvatar.cs | 15 ++++++--------- 2 files changed, 11 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') 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(); -- 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/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') 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(-) (limited to 'OpenSim/Region') 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 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. --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 219 +++++++++++++++------ 1 file changed, 164 insertions(+), 55 deletions(-) (limited to 'OpenSim/Region') 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. --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') 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; } -- cgit v1.1 From f5c9a56c8b73ef93db712fefe9f0366c4983e04f Mon Sep 17 00:00:00 2001 From: Master ScienceSim Date: Fri, 29 Oct 2010 13:37:13 -0700 Subject: Bunch of fixes that reduce the number of times appearance and avatar data are sent. And the number of times they are stored. --- .../Avatar/Attachments/AttachmentsModule.cs | 32 ++++------ .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 73 +++++++++++++++------- OpenSim/Region/Framework/Scenes/Scene.cs | 7 +++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 66 +++++++++++++------ 4 files changed, 115 insertions(+), 63 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index ad6b1de..e89368a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -123,15 +123,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); // Save avatar attachment information - ScenePresence presence; - if (m_scene.AvatarService != null && m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) - { - m_log.Info( - "[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) @@ -382,8 +379,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments item = m_scene.InventoryService.GetItem(item); presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */); - if (m_scene.AvatarService != null) - m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); + if (m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); } } @@ -405,11 +402,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments presence.Appearance.DetachAttachment(itemID); // Save avatar attachment information - if (m_scene.AvatarService != null) - { - m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); - m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); - } + m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); + if (m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); } DetachSingleAttachmentToInv(itemID, remoteClient); @@ -435,10 +430,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments presence.Appearance.DetachAttachment(itemID); - if (m_scene.AvatarService != null) - { - m_scene.AvatarService.SetAppearance(remoteClient.AgentId, presence.Appearance); - } + if (m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); + part.ParentGroup.DetachToGround(); List uuids = new List(); diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 5f8b4f6..bfbbcf8 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -42,10 +42,9 @@ using OpenSim.Services.Interfaces; 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 byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; private Scene m_scene = null; private int m_savetime = 5; // seconds to wait before saving changed appearance @@ -60,8 +59,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public void Initialise(Scene scene, IConfigSource config) { + scene.RegisterModuleInterface(this); scene.EventManager.OnNewClient += NewClient; - + if (config != null) { IConfig sconfig = config.Configs["Startup"]; @@ -112,6 +112,34 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory #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; + } + + /// /// Set appearance data (textureentry and slider settings) received from the client /// @@ -137,12 +165,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { changed = sp.Appearance.SetTextureEntries(textureEntry); - for (int i = 0; i < BAKE_INDICES.Length; i++) + for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) { - int idx = BAKE_INDICES[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) { CheckBakedTextureAssets(client,face.TextureID,idx); }); + Util.FireAndForget(delegate(object o) { + if (! CheckBakedTextureAsset(client,face.TextureID,idx)) + client.SendRebakeAvatarTextures(face.TextureID); + }); } } @@ -165,9 +196,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory 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()); + // AvatarAppearance avp = sp.Appearance; + // sp.ControllingClient.SendAvatarDataImmediate(sp); + // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); } /// @@ -177,14 +208,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory /// /// /// - private void CheckBakedTextureAssets(IClientAPI client, UUID textureID, int idx) + 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); - client.SendRebakeAvatarTextures(textureID); + return false; } + return true; } #region UpdateAppearanceTimer @@ -229,16 +261,16 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } // DEBUG ON - m_log.WarnFormat("[AVFACTORY] Handle appearance send for {0}\n{1}",agentid,sp.Appearance.ToString()); + m_log.WarnFormat("[AVFACTORY] Handle appearance send for {0}",agentid); // DEBUG OFF // Send the appearance to everyone in the scene sp.SendAppearanceToAllOtherAgents(); + sp.ControllingClient.SendAvatarDataImmediate(sp); // 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()); + // 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 @@ -337,14 +369,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory 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) { if (wear.Type < AvatarWearable.MAX_WEARABLES) @@ -354,10 +378,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } } + // This could take awhile since it needs to pull inventory SetAppearanceAssets(sp.UUID, ref avatAppearance); - m_scene.AvatarService.SetAppearance(client.AgentId, avatAppearance); sp.Appearance = avatAppearance; + m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); } private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6367fcf..3343d08 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -119,6 +119,7 @@ namespace OpenSim.Region.Framework.Scenes protected IXMLRPC m_xmlrpcModule; protected IWorldComm m_worldCommModule; + protected IAvatarFactory m_AvatarFactory; protected IConfigSource m_config; protected IRegionSerialiserModule m_serialiser; protected IDialogModule m_dialogModule; @@ -398,6 +399,11 @@ namespace OpenSim.Region.Framework.Scenes public IAttachmentsModule AttachmentsModule { get; set; } + public IAvatarFactory AvatarFactory + { + get { return m_AvatarFactory; } + } + public ICapabilitiesModule CapsModule { get { return m_capsModule; } @@ -1153,6 +1159,7 @@ namespace OpenSim.Region.Framework.Scenes m_xmlrpcModule = RequestModuleInterface(); m_worldCommModule = RequestModuleInterface(); XferManager = RequestModuleInterface(); + m_AvatarFactory = RequestModuleInterface(); AttachmentsModule = RequestModuleInterface(); m_serialiser = RequestModuleInterface(); m_dialogModule = RequestModuleInterface(); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f828a2d..7d9c8e5 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -704,20 +704,14 @@ namespace OpenSim.Region.Framework.Scenes // we created a new ScenePresence (a new child agent) in a fresh 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) - SendInitialFullUpdateToAllClients(); + +// MIC: This should be called by OnCompleteMovement +// SendInitialFullUpdateToAllClients(); RegisterToEvents(); 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) : this(client, world, reginfo) { @@ -1081,7 +1075,9 @@ namespace OpenSim.Region.Framework.Scenes /// 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; if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) @@ -2381,12 +2377,20 @@ namespace OpenSim.Region.Framework.Scenes // 2 stage check is needed. if (remoteAvatar == null) return; + IClientAPI cl=remoteAvatar.ControllingClient; if (cl == null) return; + if (m_appearance.Texture == null) return; + if (LocalId == remoteAvatar.LocalId) + { + m_log.WarnFormat("[SP] An agent is attempting to send data to itself; {0}",UUID); + return; + } + if (IsChildAgent) { 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) { ++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) { 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.Animator.SendAnimPackToClient(ControllingClient); - } + avatar.SendFullUpdateToOtherClient(this); + 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_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(); } @@ -2497,9 +2516,16 @@ namespace OpenSim.Region.Framework.Scenes /// 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 - 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 + avatar.ControllingClient.SendAppearance( m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); } -- cgit v1.1 From 49fa7e91b93221f4bd33e6f009185bc0e043a880 Mon Sep 17 00:00:00 2001 From: Master ScienceSim Date: Fri, 29 Oct 2010 13:45:59 -0700 Subject: Clean up some cruft from the last commit. Re-add the initial update send in the scene presence constructor... need to figure this out later. --- .../Region/Framework/Interfaces/IAvatarFactory.cs | 39 ++++++++++++++++++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 +-- 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs new file mode 100644 index 0000000..22795fc --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs @@ -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); + } +} diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7d9c8e5..d4d6979 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -705,8 +705,8 @@ namespace OpenSim.Region.Framework.Scenes // 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) -// MIC: This should be called by OnCompleteMovement -// SendInitialFullUpdateToAllClients(); +// MIC: This gets called again in CompleteMovement + SendInitialFullUpdateToAllClients(); RegisterToEvents(); SetDirectionVectors(); -- cgit v1.1