From 7bb005b0d1a5ae63ca94a3a3f8ad98e0388ea76b Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 16 Nov 2010 21:01:56 +0000 Subject: Change the way attachments are persisted. Editing a worn attachment will now save properly, as will the results of a resizer script working. Attachment positions are no longer saved on each move, but instead are saved once on logout. Attachment script states are saved as part of the attachment now when detaching. --- .../Avatar/Attachments/AttachmentsModule.cs | 34 ++++++++-------------- 1 file changed, 12 insertions(+), 22 deletions(-) (limited to 'OpenSim/Region/CoreModules/Avatar') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 348b8b9..1744fb3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -273,6 +273,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (objatt != null) { + // Loading the inventory from XML will have set this, but + // there is no way the object could have changed yet, + // since scripts aren't running yet. So, clear it here. + objatt.HasGroupChanged = false; bool tainted = false; if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) tainted = true; @@ -470,6 +474,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); group.DetachToInventoryPrep(); m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); + + // If an item contains scripts, it's always changed. + // This ensures script state is saved on detach + foreach (SceneObjectPart p in group.Parts) + if (p.Inventory.ContainsScripts()) + group.HasGroupChanged = true; + UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); m_scene.DeleteSceneObject(group, false); return; @@ -478,25 +489,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - public void UpdateAttachmentPosition(IClientAPI client, SceneObjectGroup sog, Vector3 pos) - { - // If this is an attachment, then we need to save the modified - // object back into the avatar's inventory. First we save the - // attachment point information, then we update the relative - // positioning (which caused this method to get driven in the - // first place. Then we have to mark the object as NOT an - // attachment. This is necessary in order to correctly save - // and retrieve GroupPosition information for the attachment. - // Then we save the asset back into the appropriate inventory - // entry. Finally, we restore the object's attachment status. - byte attachmentPoint = sog.GetAttachmentPoint(); - sog.UpdateGroupPosition(pos); - sog.RootPart.IsAttachment = false; - sog.AbsolutePosition = sog.RootPart.AttachedPos; - UpdateKnownItem(client, sog, sog.GetFromItemID(), sog.OwnerID); - sog.SetAttachmentPoint(attachmentPoint); - } - /// /// Update the attachment asset for the new sog details if they have changed. /// @@ -508,7 +500,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// - protected void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID) + public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID) { if (grp != null) { @@ -523,7 +515,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments grp.UUID, grp.GetAttachmentPoint()); string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); - InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); @@ -617,7 +608,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // In case it is later dropped again, don't let // it get cleaned up so.RootPart.RemFlag(PrimFlags.TemporaryOnRez); - so.HasGroupChanged = false; } } } -- cgit v1.1 From 8f1a79420be062ea59b3c04aacb439fb57713ac7 Mon Sep 17 00:00:00 2001 From: Master ScienceSim Date: Thu, 18 Nov 2010 10:01:10 -0800 Subject: Fixed appearance send for avatars with only default textures. This should fix some of the appearance problems on osgrid. Also added a transaction lock on SetAppearance. This won't prevent concurrent access to Appearance but it will at least make sure each update completes. Signed-off-by: Melanie --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 127 ++++++++++++--------- 1 file changed, 74 insertions(+), 53 deletions(-) (limited to 'OpenSim/Region/CoreModules/Avatar') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 2dd444d..0df4585 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -55,6 +55,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory private Dictionary m_savequeue = new Dictionary(); private Dictionary m_sendqueue = new Dictionary(); + private object m_setAppearanceLock = new object(); + #region RegionModule Members public void Initialise(Scene scene, IConfigSource config) @@ -69,6 +71,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); + // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime); } } @@ -117,26 +120,28 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance unable to find presence for {0}", client.AgentId); + m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId); return false; } - bool cached = true; + bool defonly = true; // are we only using default textures // 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; - } + if (face == null || face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) + continue; + + defonly = false; // found a non-default texture reference + + if (! CheckBakedTextureAsset(client,face.TextureID,idx)) + return false; } - return cached; + // If we only found default textures, then the appearance is not cached + return (defonly ? false : true); } /// @@ -146,44 +151,59 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory /// public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) { -// m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance for {0}",client.AgentId); - ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: SetAppearance unable to find presence for {0}",client.AgentId); + m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}",client.AgentId); return; } + // m_log.WarnFormat("[AVFACTORY]: Start SetAppearance for {0}",client.AgentId); + bool changed = false; - // Process the texture entry - if (textureEntry != null) + // 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) { - changed = sp.Appearance.SetTextureEntries(textureEntry); - - for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) + if (textureEntry != null) { - int idx = AvatarAppearance.BAKE_INDICES[i]; - Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; - if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) - Util.FireAndForget(delegate(object o) { - if (! CheckBakedTextureAsset(client,face.TextureID,idx)) - client.SendRebakeAvatarTextures(face.TextureID); - }); + changed = sp.Appearance.SetTextureEntries(textureEntry); + + // m_log.WarnFormat("[AVFACTORY]: Prepare to check textures for {0}",client.AgentId); + + for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) + { + int idx = AvatarAppearance.BAKE_INDICES[i]; + Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; + if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) + Util.FireAndForget(delegate(object o) { + if (! CheckBakedTextureAsset(client,face.TextureID,idx)) + client.SendRebakeAvatarTextures(face.TextureID); + }); + } + + // m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId); } - } - // Process the visual params, this may change height as well - if (visualParams != null) - { - if (sp.Appearance.SetVisualParams(visualParams)) + // Process the visual params, this may change height as well + if (visualParams != null) { - changed = true; - if (sp.Appearance.AvatarHeight > 0) - sp.SetHeight(sp.Appearance.AvatarHeight); + if (sp.Appearance.SetVisualParams(visualParams)) + { + changed = true; + if (sp.Appearance.AvatarHeight > 0) + sp.SetHeight(sp.Appearance.AvatarHeight); + } } + + // Send the appearance back to the avatar, not clear that this is needed + sp.ControllingClient.SendAvatarDataImmediate(sp); + // AvatarAppearance avp = sp.Appearance; + // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); + } + // If something changed in the appearance then queue an appearance save if (changed) @@ -192,10 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // 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()); + // m_log.WarnFormat("[AVFACTORY]: Complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); } /// @@ -209,7 +226,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { if (m_scene.AssetService.Get(textureID.ToString()) == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: Missing baked texture {0} ({1}) for avatar {2}", + m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}", textureID, idx, client.Name); return false; } @@ -220,10 +237,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public void QueueAppearanceSend(UUID agentid) { -// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Queue appearance send for {0}", agentid); + // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); - // 100 nanoseconds (ticks) we should wait - long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 10000000); + // 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; @@ -233,10 +250,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public void QueueAppearanceSave(UUID agentid) { -// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Queue appearance save for {0}", agentid); + // m_log.WarnFormat("[AVFACTORY]: Queue appearance save for {0}", agentid); - // 100 nanoseconds (ticks) we should wait - long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_savetime * 10000000); + // 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; @@ -249,15 +266,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory ScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: Agent {0} no longer in the scene", agentid); + m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); return; } -// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Handle appearance send for {0}", agentid); + // m_log.WarnFormat("[AVFACTORY]: Handle appearance send for {0}", agentid); // Send the appearance to everyone in the scene sp.SendAppearanceToAllOtherAgents(); - sp.ControllingClient.SendAvatarDataImmediate(sp); + // sp.ControllingClient.SendAvatarDataImmediate(sp); // Send the appearance back to the avatar // AvatarAppearance avp = sp.Appearance; @@ -279,10 +296,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory ScenePresence sp = m_scene.GetScenePresence(agentid); if (sp == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: Agent {0} no longer in the scene", agentid); + m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); return; } + // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); + m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); } @@ -330,11 +349,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: SendWearables unable to find presence for {0}", client.AgentId); + m_log.WarnFormat("[AVFACTORY]: SendWearables unable to find presence for {0}", client.AgentId); return; } -// m_log.WarnFormat("[AVATAR FACTORY MODULE]: Received request for wearables of {0}", client.AgentId); + // m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId); client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); } @@ -349,11 +368,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory ScenePresence sp = m_scene.GetScenePresence(client.AgentId); if (sp == null) { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: AvatarIsWearing unable to find presence for {0}", client.AgentId); + m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing unable to find presence for {0}", client.AgentId); return; } -// m_log.WarnFormat("[AVATAR FACTORY MODULE]: AvatarIsWearing called for {0}", client.AgentId); + // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); @@ -368,6 +387,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // This could take awhile since it needs to pull inventory SetAppearanceAssets(sp.UUID, ref avatAppearance); + // could get fancier with the locks here, but in the spirit of "last write wins" + // this should work correctly sp.Appearance = avatAppearance; m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); } @@ -398,7 +419,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory else { m_log.ErrorFormat( - "[AVATAR FACTORY MODULE]: Can't find inventory item {0} for {1}, setting to default", + "[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); @@ -408,7 +429,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } else { - m_log.WarnFormat("[AVATAR FACTORY MODULE]: user {0} has no inventory, appearance isn't going to work", userID); + m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); } } } -- cgit v1.1 From 6a9ae9e7cb71d79e9ec06cf25009e8bf45850dd1 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 21 Nov 2010 13:16:52 -0800 Subject: Global creator information working on MySQL DB and on load/save OARs. Creator name properly shown on the viewer as first.last @authority. New option added to save oar -profile=url. Migration on RegionStore making CreatorID be 255 chars. Moved Handling of user UUID -> name requests to a new module UserManagement/UserManagementModule. --- OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/CoreModules/Avatar') diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs index 25322a1..a5fcb49 100644 --- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs @@ -115,10 +115,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule // Try to find the avatar wielding the killing object killingAvatar = deadAvatar.Scene.GetScenePresence(part.OwnerID); if (killingAvatar == null) - deadAvatarMessage = String.Format("You impaled yourself on {0} owned by {1}!", part.Name, deadAvatar.Scene.GetUserName(part.OwnerID)); + { + IUserManagement userManager = deadAvatar.Scene.RequestModuleInterface(); + string userName = "Unkown User"; + if (userManager != null) + userName = userManager.GetUserName(part.OwnerID); + deadAvatarMessage = String.Format("You impaled yourself on {0} owned by {1}!", part.Name, userName); + } else { -// killingAvatarMessage = String.Format("You fragged {0}!", deadAvatar.Name); + // killingAvatarMessage = String.Format("You fragged {0}!", deadAvatar.Name); deadAvatarMessage = String.Format("You got killed by {0}!", killingAvatar.Name); } } -- cgit v1.1