From da794f34a56f7c88904315ae538de8f3790e6891 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Wed, 19 Oct 2011 14:41:44 -0700 Subject: [PATCH] Renamed and rearranged AvatarFactoryModule to eliminate redundant lookups of scene presence by client ID. --- .../AvatarFactory/AvatarFactoryModule.cs | 616 +++++++++--------- .../Tests/AvatarFactoryModuleTests.cs | 12 +- ...atarFactory.cs => IAvatarFactoryModule.cs} | 9 +- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +- .../Region/Framework/Scenes/ScenePresence.cs | 2 +- .../Avatar/Appearance/AppearanceInfoModule.cs | 12 +- .../OptionalModules/World/NPC/NPCModule.cs | 2 +- .../World/NPC/Tests/NPCModuleTests.cs | 2 +- .../Shared/Api/Implementation/OSSL_Api.cs | 2 +- 9 files changed, 319 insertions(+), 344 deletions(-) rename OpenSim/Region/Framework/Interfaces/{IAvatarFactory.cs => IAvatarFactoryModule.cs} (93%) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index d4e173663b..0c7c690d96 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -42,7 +42,7 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { - public class AvatarFactoryModule : IAvatarFactory, IRegionModule + public class AvatarFactoryModule : IAvatarFactoryModule, IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene = null; @@ -57,12 +57,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory private object m_setAppearanceLock = new object(); - #region RegionModule Members + #region IRegionModule public void Initialise(Scene scene, IConfigSource config) { - scene.RegisterModuleInterface(this); - scene.EventManager.OnNewClient += NewClient; + scene.RegisterModuleInterface(this); + scene.EventManager.OnNewClient += SubscribeToClientEvents; IConfig sconfig = config.Configs["Startup"]; if (sconfig != null) @@ -98,44 +98,201 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory get { return false; } } - public void NewClient(IClientAPI client) + private void SubscribeToClientEvents(IClientAPI client) { - client.OnRequestWearables += SendWearables; - client.OnSetAppearance += SetAppearanceFromClient; - client.OnAvatarNowWearing += AvatarIsWearing; + client.OnRequestWearables += Client_OnRequestWearables; + client.OnSetAppearance += Client_OnSetAppearance; + client.OnAvatarNowWearing += Client_OnAvatarNowWearing; } - public void RemoveClient(IClientAPI client) - { - // client.OnAvatarNowWearing -= AvatarIsWearing; - } - - #endregion - + #endregion + + #region IAvatarFactoryModule + + /// + /// Set appearance data (texture asset IDs and slider settings) + /// + /// + /// + /// + public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) + { + // m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId); + + // TODO: This is probably not necessary any longer, just assume the + // textureEntry set implies that the appearance transaction is complete + bool changed = false; + + // Process the texture entry transactionally, this doesn't guarantee that Appearance is + // going to be handled correctly but it does serialize the updates to the appearance + lock (m_setAppearanceLock) + { + // Process the visual params, this may change height as well + if (visualParams != null) + { + // string[] visualParamsStrings = new string[visualParams.Length]; + // for (int i = 0; i < visualParams.Length; i++) + // visualParamsStrings[i] = visualParams[i].ToString(); + // m_log.DebugFormat( + // "[AVFACTORY]: Setting visual params for {0} to {1}", + // client.Name, string.Join(", ", visualParamsStrings)); + + float oldHeight = sp.Appearance.AvatarHeight; + changed = sp.Appearance.SetVisualParams(visualParams); + + if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) + ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); + } + + // Process the baked texture array + if (textureEntry != null) + { + changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; + + m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", sp.UUID); + Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(sp, false); }); + + // This appears to be set only in the final stage of the appearance + // update transaction. In theory, we should be able to do an immediate + // appearance send and save here. + + } + // save only if there were changes, send no matter what (doesn't hurt to send twice) + if (changed) + QueueAppearanceSave(sp.ControllingClient.AgentId); + + QueueAppearanceSend(sp.ControllingClient.AgentId); + } + + // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); + } + + public bool SendAppearance(UUID agentId) + { + ScenePresence sp = m_scene.GetScenePresence(agentId); + if (sp == null) + { + m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); + return false; + } + + // Send the appearance to everyone in the scene + sp.SendAppearanceToAllOtherAgents(); + + // Send animations back to the avatar as well + sp.Animator.SendAnimPack(); + + return true; + } + + public Dictionary GetBakedTextureFaces(UUID agentId) + { + ScenePresence sp = m_scene.GetScenePresence(agentId); + + if (sp == null) + return new Dictionary(); + + return GetBakedTextureFaces(sp); + } + + public bool SaveBakedTextures(UUID agentId) + { + ScenePresence sp = m_scene.GetScenePresence(agentId); + + if (sp == null) + return false; + + m_log.DebugFormat( + "[AV FACTORY]: Permanently saving baked textures for {0} in {1}", + sp.Name, m_scene.RegionInfo.RegionName); + + Dictionary bakedTextures = GetBakedTextureFaces(sp); + + if (bakedTextures.Count == 0) + return false; + + foreach (BakeType bakeType in bakedTextures.Keys) + { + Primitive.TextureEntryFace bakedTextureFace = bakedTextures[bakeType]; + + if (bakedTextureFace == null) + { + m_log.WarnFormat( + "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently", + bakeType, sp.Name, m_scene.RegionInfo.RegionName); + + continue; + } + + AssetBase asset = m_scene.AssetService.Get(bakedTextureFace.TextureID.ToString()); + + if (asset != null) + { + asset.Temporary = false; + asset.Local = false; + m_scene.AssetService.Store(asset); + } + else + { + m_log.WarnFormat( + "[AV FACTORY]: Baked texture id {0} not found for bake {1} for avatar {2} in {3} when trying to save permanently", + bakedTextureFace.TextureID, bakeType, sp.Name, m_scene.RegionInfo.RegionName); + } + } + return true; + } + /// /// Check for the existence of the baked texture assets. /// - /// - public bool ValidateBakedTextureCache(IClientAPI client) + /// + public bool ValidateBakedTextureCache(IScenePresence sp) { - return ValidateBakedTextureCache(client, true); - } - + return ValidateBakedTextureCache(sp, true); + } + + /// + /// Queue up a request to send appearance, makes it possible to + /// accumulate changes without sending out each one separately. + /// + public void QueueAppearanceSend(UUID agentid) + { + // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); + + // 10000 ticks per millisecond, 1000 milliseconds per second + long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); + lock (m_sendqueue) + { + m_sendqueue[agentid] = timestamp; + m_updateTimer.Start(); + } + } + + public void QueueAppearanceSave(UUID agentid) + { + // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid); + + // 10000 ticks per millisecond, 1000 milliseconds per second + long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); + lock (m_savequeue) + { + m_savequeue[agentid] = timestamp; + m_updateTimer.Start(); + } + } + + #endregion + + #region AvatarFactoryModule private methods + /// /// Check for the existence of the baked texture assets. Request a rebake /// unless checkonly is true. /// /// /// - private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly) + private bool ValidateBakedTextureCache(IScenePresence sp, bool checkonly) { - 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 defonly = true; // are we only using default textures // Process the texture entry @@ -161,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory defonly = false; // found a non-default texture reference - if (!CheckBakedTextureAsset(client, face.TextureID, idx)) + if (!CheckBakedTextureAsset(sp, face.TextureID, idx)) { // the asset didn't exist if we are only checking, then we found a bad // one and we're done otherwise, ask for a rebake @@ -170,109 +327,34 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake", face.TextureID); - client.SendRebakeAvatarTextures(face.TextureID); + sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID); } } - m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", client.AgentId); + m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", sp.UUID); // If we only found default textures, then the appearance is not cached return (defonly ? false : true); } - /// - /// Set appearance data (texture asset IDs and slider settings) received from the client - /// - /// - /// - /// - public void SetAppearanceFromClient(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) - { - ScenePresence sp = m_scene.GetScenePresence(client.AgentId); - if (sp == null) - { - m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId); - return; - } - -// m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId); - - // TODO: This is probably not necessary any longer, just assume the - // textureEntry set implies that the appearance transaction is complete - bool changed = false; - - // Process the texture entry transactionally, this doesn't guarantee that Appearance is - // going to be handled correctly but it does serialize the updates to the appearance - lock (m_setAppearanceLock) - { - // Process the visual params, this may change height as well - if (visualParams != null) - { -// string[] visualParamsStrings = new string[visualParams.Length]; -// for (int i = 0; i < visualParams.Length; i++) -// visualParamsStrings[i] = visualParams[i].ToString(); -// m_log.DebugFormat( -// "[AVFACTORY]: Setting visual params for {0} to {1}", -// client.Name, string.Join(", ", visualParamsStrings)); - - float oldHeight = sp.Appearance.AvatarHeight; - changed = sp.Appearance.SetVisualParams(visualParams); - - if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) - sp.SetHeight(sp.Appearance.AvatarHeight); - } - - // Process the baked texture array - if (textureEntry != null) - { - changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; - - m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", client.AgentId); - Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client, false); }); - - // This appears to be set only in the final stage of the appearance - // update transaction. In theory, we should be able to do an immediate - // appearance send and save here. - - } - // save only if there were changes, send no matter what (doesn't hurt to send twice) - if (changed) - QueueAppearanceSave(client.AgentId); - - QueueAppearanceSend(client.AgentId); - } - - // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); - } - /// /// Checks for the existance of a baked texture asset and /// requests the viewer rebake if the asset is not found /// - /// + /// /// /// - private bool CheckBakedTextureAsset(IClientAPI client, UUID textureID, int idx) + private bool CheckBakedTextureAsset(IScenePresence sp, 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); + textureID, idx, sp.Name); return false; } return true; } - public Dictionary GetBakedTextureFaces(UUID agentId) - { - ScenePresence sp = m_scene.GetScenePresence(agentId); - - if (sp == null) - return new Dictionary(); - - return GetBakedTextureFaces(sp); - } - private Dictionary GetBakedTextureFaces(ScenePresence sp) { if (sp.IsChildAgent) @@ -302,136 +384,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return bakedTextures; } - public bool SaveBakedTextures(UUID agentId) - { - ScenePresence sp = m_scene.GetScenePresence(agentId); - - if (sp == null) - return false; - - m_log.DebugFormat( - "[AV FACTORY]: Permanently saving baked textures for {0} in {1}", - sp.Name, m_scene.RegionInfo.RegionName); - - Dictionary bakedTextures = GetBakedTextureFaces(sp); - - if (bakedTextures.Count == 0) - return false; - - foreach (BakeType bakeType in bakedTextures.Keys) - { - Primitive.TextureEntryFace bakedTextureFace = bakedTextures[bakeType]; - - if (bakedTextureFace == null) - { - m_log.WarnFormat( - "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently", - bakeType, sp.Name, m_scene.RegionInfo.RegionName); - - continue; - } - - AssetBase asset = m_scene.AssetService.Get(bakedTextureFace.TextureID.ToString()); - - if (asset != null) - { - asset.Temporary = false; - asset.Local = false; - m_scene.AssetService.Store(asset); - } - else - { - m_log.WarnFormat( - "[AV FACTORY]: Baked texture id {0} not found for bake {1} for avatar {2} in {3} when trying to save permanently", - bakedTextureFace.TextureID, bakeType, sp.Name, m_scene.RegionInfo.RegionName); - } - } - -// for (int i = 0; i < faceTextures.Length; i++) -// { -//// m_log.DebugFormat( -//// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}", -//// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); -// -// if (faceTextures[i] == null) -// continue; -// -// AssetBase asset = m_scene.AssetService.Get(faceTextures[i].TextureID.ToString()); -// -// if (asset != null) -// { -// asset.Temporary = false; -// m_scene.AssetService.Store(asset); -// } -// else -// { -// m_log.WarnFormat( -// "[AV FACTORY]: Baked texture {0} for {1} in {2} not found when trying to save permanently", -// faceTextures[i].TextureID, sp.Name, m_scene.RegionInfo.RegionName); -// } -// } - - return true; - } - - #region UpdateAppearanceTimer - - /// - /// Queue up a request to send appearance, makes it possible to - /// accumulate changes without sending out each one separately. - /// - public void QueueAppearanceSend(UUID agentid) - { - // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); - - // 10000 ticks per millisecond, 1000 milliseconds per second - long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); - lock (m_sendqueue) - { - m_sendqueue[agentid] = timestamp; - m_updateTimer.Start(); - } - } - - public void QueueAppearanceSave(UUID agentid) - { - // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid); - - // 10000 ticks per millisecond, 1000 milliseconds per second - long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 1000 * 10000); - lock (m_savequeue) - { - m_savequeue[agentid] = timestamp; - m_updateTimer.Start(); - } - } - - private void SaveAppearance(UUID agentid) - { - // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved - // in a culture where decimal points are commas and then reloaded in a culture which just treats them as - // number seperators. - Culture.SetCurrentCulture(); - - ScenePresence sp = m_scene.GetScenePresence(agentid); - if (sp == null) - { - m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); - return; - } - - // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); - - // This could take awhile since it needs to pull inventory - // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape - // assets and item asset id changes to complete. - // I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids - // multiple save requests. - SetAppearanceAssets(sp.UUID, sp.Appearance); - - m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); - } - private void HandleAppearanceUpdateTimer(object sender, EventArgs ea) { long now = DateTime.Now.Ticks; @@ -464,43 +416,122 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory if (m_savequeue.Count == 0 && m_sendqueue.Count == 0) m_updateTimer.Stop(); - } - - #endregion - + } + + private void SaveAppearance(UUID agentid) + { + // We must set appearance parameters in the en_US culture in order to avoid issues where values are saved + // in a culture where decimal points are commas and then reloaded in a culture which just treats them as + // number seperators. + Culture.SetCurrentCulture(); + + ScenePresence sp = m_scene.GetScenePresence(agentid); + if (sp == null) + { + m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); + return; + } + + // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); + + // This could take awhile since it needs to pull inventory + // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape + // assets and item asset id changes to complete. + // I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids + // multiple save requests. + SetAppearanceAssets(sp.UUID, sp.Appearance); + + m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); + } + + private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) + { + IInventoryService invService = m_scene.InventoryService; + + if (invService.GetRootFolder(userID) != null) + { + for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) + { + for (int j = 0; j < appearance.Wearables[j].Count; j++) + { + if (appearance.Wearables[i][j].ItemID == UUID.Zero) + continue; + + // Ignore ruth's assets + if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) + continue; + InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); + baseItem = invService.GetItem(baseItem); + + if (baseItem != null) + { + appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); + } + else + { + m_log.ErrorFormat( + "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", + appearance.Wearables[i][j].ItemID, (WearableType)i); + + appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); + } + } + } + } + else + { + m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); + } + } + + #endregion + + #region Client Event Handlers /// /// Tell the client for this scene presence what items it should be wearing now - /// - public void SendWearables(IClientAPI client) - { + /// + /// + private void Client_OnRequestWearables(IClientAPI client) + { + // m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId); ScenePresence sp = m_scene.GetScenePresence(client.AgentId); - if (sp == null) - { - m_log.WarnFormat("[AVFACTORY]: SendWearables unable to find presence for {0}", client.AgentId); - return; - } - -// m_log.DebugFormat("[AVFACTORY]: Received request for wearables of {0}", client.Name); - - client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); + if (sp != null) + client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); + else + m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId); + } + + /// + /// Set appearance data (texture asset IDs and slider settings) received from a client + /// + /// + /// + /// + private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) + { + // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); + ScenePresence sp = m_scene.GetScenePresence(client.AgentId); + if (sp != null) + SetAppearance(sp, textureEntry, visualParams); + else + m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); } /// /// Update what the avatar is wearing using an item from their inventory. /// - /// + /// /// - public void AvatarIsWearing(IClientAPI client, AvatarWearingArgs e) - { + private void Client_OnAvatarNowWearing(IClientAPI client, AvatarWearingArgs e) + { + // m_log.WarnFormat("[AVFACTORY]: Client_OnAvatarNowWearing called for {0} ({1})", client.Name, client.AgentId); ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) { - m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing unable to find presence for {0}", client.AgentId); + m_log.WarnFormat("[AVFACTORY]: Client_OnAvatarNowWearing unable to find presence for {0}", client.AgentId); return; } - // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); - // we need to clean out the existing textures sp.Appearance.ResetAppearance(); @@ -527,65 +558,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // of visual param and baked texture changes. When those complete, the new appearance will be sent QueueAppearanceSave(client.AgentId); - } - } - - public bool SendAppearance(UUID agentId) - { - ScenePresence sp = m_scene.GetScenePresence(agentId); - if (sp == null) - { - m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); - return false; - } - - // Send the appearance to everyone in the scene - sp.SendAppearanceToAllOtherAgents(); - - // Send animations back to the avatar as well - sp.Animator.SendAnimPack(); - - return true; - } - - private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) - { - IInventoryService invService = m_scene.InventoryService; - - if (invService.GetRootFolder(userID) != null) - { - for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) - { - for (int j = 0; j < appearance.Wearables[j].Count; j++) - { - if (appearance.Wearables[i][j].ItemID == UUID.Zero) - continue; - - // Ignore ruth's assets - if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) - continue; - InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); - baseItem = invService.GetItem(baseItem); - - if (baseItem != null) - { - appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); - } - else - { - m_log.ErrorFormat( - "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", - appearance.Wearables[i][j].ItemID, (WearableType)i); - - appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); - } - } - } - } - else - { - m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); - } - } + } + } + #endregion } } diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index 7b2f14e963..931d52fb01 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs @@ -55,15 +55,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(scene, afm); - IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient; + ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT]; for (byte i = 0; i < visualParams.Length; i++) visualParams[i] = i; - afm.SetAppearanceFromClient(tc, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); - - ScenePresence sp = scene.GetScenePresence(userId); + afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams); // TODO: Check baked texture Assert.AreEqual(visualParams, sp.Appearance.VisualParams); @@ -84,8 +82,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneHelpers.SetupScene(assetCache); - SceneHelpers.SetupSceneModules(scene, afm); - IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient; + SceneHelpers.SetupSceneModules(scene, afm); + ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); // TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules AssetBase uploadedAsset; @@ -104,7 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex); eyesFace.TextureID = eyesTextureId; - afm.SetAppearanceFromClient(tc, bakedTextureEntry, visualParams); + afm.SetAppearance(sp, bakedTextureEntry, visualParams); afm.SaveBakedTextures(userId); // Dictionary bakedTextures = afm.GetBakedTextureFaces(userId); diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs similarity index 93% rename from OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs rename to OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs index 4dbddf476b..98228e4d36 100644 --- a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs +++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs @@ -31,8 +31,11 @@ using OpenSim.Framework; namespace OpenSim.Region.Framework.Interfaces { - public interface IAvatarFactory - { + public interface IAvatarFactoryModule + { + + void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams); + /// /// Send the appearance of an avatar to others in the scene. /// @@ -57,7 +60,7 @@ namespace OpenSim.Region.Framework.Interfaces /// true if a valid agent was found, false otherwise bool SaveBakedTextures(UUID agentId); - bool ValidateBakedTextureCache(IClientAPI client); + bool ValidateBakedTextureCache(IScenePresence sp); void QueueAppearanceSend(UUID agentid); void QueueAppearanceSave(UUID agentid); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 8a32e1d8d7..724c635d02 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -135,7 +135,7 @@ namespace OpenSim.Region.Framework.Scenes protected IXMLRPC m_xmlrpcModule; protected IWorldComm m_worldCommModule; - protected IAvatarFactory m_AvatarFactory; + protected IAvatarFactoryModule m_AvatarFactory; protected IConfigSource m_config; protected IRegionSerialiserModule m_serialiser; protected IDialogModule m_dialogModule; @@ -444,7 +444,7 @@ namespace OpenSim.Region.Framework.Scenes public IAttachmentsModule AttachmentsModule { get; set; } - public IAvatarFactory AvatarFactory + public IAvatarFactoryModule AvatarFactory { get { return m_AvatarFactory; } } @@ -1154,7 +1154,7 @@ namespace OpenSim.Region.Framework.Scenes m_xmlrpcModule = RequestModuleInterface(); m_worldCommModule = RequestModuleInterface(); XferManager = RequestModuleInterface(); - m_AvatarFactory = 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 e0fd84abd2..464f8f05a3 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2538,7 +2538,7 @@ namespace OpenSim.Region.Framework.Scenes // We have an appearance but we may not have the baked textures. Check the asset cache // to see if all the baked textures are already here. if (m_scene.AvatarFactory != null) - cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(ControllingClient); + cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(this); // If we aren't using a cached appearance, then clear out the baked textures if (!cachedappearance) diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 77e7acf15e..2cef8a9f8b 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Dictionary m_scenes = new Dictionary(); - protected IAvatarFactory m_avatarFactory; + protected IAvatarFactoryModule m_avatarFactory; public string Name { get { return "Appearance Information Module"; } } @@ -106,14 +106,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { foreach (Scene scene in m_scenes.Values) { - scene.ForEachClient( - delegate(IClientAPI client) + scene.ForEachScenePresence( + delegate(ScenePresence sp) { - if (client is LLClientView && !((LLClientView)client).ChildAgentStatus()) + if (sp.ControllingClient is LLClientView && !((LLClientView)sp.ControllingClient).ChildAgentStatus()) { - bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(client); + bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp); MainConsole.Instance.OutputFormat( - "{0} baked appearance texture is {1}", client.Name, bakedTextureValid ? "OK" : "corrupt"); + "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); } }); } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index e94ed85ba9..10181aa9a5 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -84,7 +84,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC sp.Appearance = npcAppearance; scene.AttachmentsModule.RezAttachments(sp); - IAvatarFactory module = scene.RequestModuleInterface(); + IAvatarFactoryModule module = scene.RequestModuleInterface(); module.SendAppearance(sp.UUID); return true; diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index be1ecd0612..ce8d1db07c 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -106,7 +106,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests // ScenePresence.SendInitialData() to reset our entire appearance. scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId)); - afm.SetAppearanceFromClient(sp.ControllingClient, originalTe, null); + afm.SetAppearance(sp, originalTe, null); INPCModule npcModule = scene.RequestModuleInterface(); UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 49c8722dfb..52d787db0c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2405,7 +2405,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected LSL_Key SaveAppearanceToNotecard(ScenePresence sp, string notecard) { - IAvatarFactory appearanceModule = World.RequestModuleInterface(); + IAvatarFactoryModule appearanceModule = World.RequestModuleInterface(); if (appearanceModule != null) {