From da794f34a56f7c88904315ae538de8f3790e6891 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Wed, 19 Oct 2011 14:41:44 -0700 Subject: Renamed and rearranged AvatarFactoryModule to eliminate redundant lookups of scene presence by client ID. --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 616 ++++++++++----------- .../Tests/AvatarFactoryModuleTests.cs | 12 +- .../Region/Framework/Interfaces/IAvatarFactory.cs | 64 --- .../Framework/Interfaces/IAvatarFactoryModule.cs | 67 +++ OpenSim/Region/Framework/Scenes/Scene.cs | 6 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- .../Avatar/Appearance/AppearanceInfoModule.cs | 12 +- .../Region/OptionalModules/World/NPC/NPCModule.cs | 2 +- .../World/NPC/Tests/NPCModuleTests.cs | 2 +- .../Shared/Api/Implementation/OSSL_Api.cs | 2 +- 10 files changed, 380 insertions(+), 405 deletions(-) delete mode 100644 OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs create mode 100644 OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index d4e1736..0c7c690 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 7b2f14e..931d52f 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/IAvatarFactory.cs deleted file mode 100644 index 4dbddf4..0000000 --- a/OpenSim/Region/Framework/Interfaces/IAvatarFactory.cs +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 System.Collections.Generic; -using OpenMetaverse; -using OpenSim.Framework; - -namespace OpenSim.Region.Framework.Interfaces -{ - public interface IAvatarFactory - { - /// - /// Send the appearance of an avatar to others in the scene. - /// - /// - /// - bool SendAppearance(UUID agentId); - - /// - /// Return the baked texture ids of the given agent. - /// - /// - /// An empty list if this agent has no baked textures (e.g. because it's a child agent) - Dictionary GetBakedTextureFaces(UUID agentId); - - /// - /// Save the baked textures for the given agent permanently in the asset database. - /// - /// - /// This is used to preserve apperance textures for NPCs - /// - /// - /// true if a valid agent was found, false otherwise - bool SaveBakedTextures(UUID agentId); - - bool ValidateBakedTextureCache(IClientAPI client); - void QueueAppearanceSend(UUID agentid); - void QueueAppearanceSave(UUID agentid); - } -} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs new file mode 100644 index 0000000..98228e4 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs @@ -0,0 +1,67 @@ +/* + * 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 System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface IAvatarFactoryModule + { + + void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams); + + /// + /// Send the appearance of an avatar to others in the scene. + /// + /// + /// + bool SendAppearance(UUID agentId); + + /// + /// Return the baked texture ids of the given agent. + /// + /// + /// An empty list if this agent has no baked textures (e.g. because it's a child agent) + Dictionary GetBakedTextureFaces(UUID agentId); + + /// + /// Save the baked textures for the given agent permanently in the asset database. + /// + /// + /// This is used to preserve apperance textures for NPCs + /// + /// + /// true if a valid agent was found, false otherwise + bool SaveBakedTextures(UUID agentId); + + bool ValidateBakedTextureCache(IScenePresence sp); + void QueueAppearanceSend(UUID agentid); + void QueueAppearanceSave(UUID agentid); + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 8a32e1d..724c635 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 e0fd84a..464f8f0 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 77e7acf..2cef8a9 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 e94ed85..10181aa 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 be1ecd0..ce8d1db 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 49c8722..52d787d 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) { -- cgit v1.1