From 48c6d052d94a7ab57c5264f09e989fa717c730f5 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 7 Nov 2008 05:48:44 +0000 Subject: Attachments, attachments, and, did I say attachments? Too many fixes to list. --- .../Modules/ContentManagementSystem/CMModel.cs | 2 +- .../Modules/ContentManagementSystem/MetaEntity.cs | 5 +- .../World/TreePopulator/TreePopulatorModule.cs | 2 +- OpenSim/Region/Environment/Scenes/InnerScene.cs | 12 +-- .../Region/Environment/Scenes/Scene.Inventory.cs | 17 ++-- OpenSim/Region/Environment/Scenes/Scene.cs | 25 +++--- .../Scenes/SceneCommunicationService.cs | 7 +- .../Region/Environment/Scenes/SceneObjectGroup.cs | 60 ++++++++----- OpenSim/Region/Environment/Scenes/ScenePresence.cs | 99 ++++++++++++++-------- 9 files changed, 141 insertions(+), 88 deletions(-) (limited to 'OpenSim/Region/Environment') diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs index edf5ec1..9d81262 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs @@ -262,7 +262,7 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor); scene.SendKillObject(scene.Entities[uuid].LocalId); scene.m_innerScene.DeleteSceneObject(uuid, false); - ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroup(); + ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroup(false); } catch(Exception e) { diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs index d6fca7b..16edc2c 100644 --- a/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs +++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/MetaEntity.cs @@ -211,14 +211,13 @@ namespace OpenSim.Region.Environment.Modules.ContentManagement public void SendFullUpdate(IClientAPI client, uint clientFlags) { - m_Entity.SendFullUpdateToClient(client, clientFlags); + m_Entity.SendFullUpdateToClient(client); } public void SendFullUpdateToAll() { - uint clientFlags = 0; m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller) - { m_Entity.SendFullUpdateToClient(controller, clientFlags); } + { m_Entity.SendFullUpdateToClient(controller); } ); } diff --git a/OpenSim/Region/Environment/Modules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/Environment/Modules/World/TreePopulator/TreePopulatorModule.cs index 827540d..b6879b0 100644 --- a/OpenSim/Region/Environment/Modules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/Environment/Modules/World/TreePopulator/TreePopulatorModule.cs @@ -181,7 +181,7 @@ namespace OpenSim.Region.Environment.Modules.World.TreePopulator if (Util.RandomClass.NextDouble() < killLikelyhood) { - m_scene.DeleteSceneObject(selectedTree.ParentGroup); + m_scene.DeleteSceneObject(selectedTree.ParentGroup, false); m_trees.Remove(selectedTree.ParentGroup.UUID); m_scene.ForEachClient(delegate(IClientAPI controller) diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index 4e7494e..6c0f57b 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs @@ -433,7 +433,7 @@ namespace OpenSim.Region.Environment.Scenes /// /// /// - protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot) + protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) { // If we can't take it, we can't attach it! // @@ -447,7 +447,7 @@ namespace OpenSim.Region.Environment.Scenes // Calls attach with a Zero position // - AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero); + AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false); } public SceneObjectGroup RezSingleAttachment( @@ -464,7 +464,7 @@ namespace OpenSim.Region.Environment.Scenes if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) tainted = true; - AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition); + AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false); objatt.ScheduleGroupForFullUpdate(); if (tainted) objatt.HasGroupChanged = true; @@ -491,14 +491,14 @@ namespace OpenSim.Region.Environment.Scenes group.DetachToInventoryPrep(); m_log.Debug("[DETACH]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); m_parentScene.updateKnownAsset(remoteClient, group, group.GetFromAssetID(), group.OwnerID); - m_parentScene.DeleteSceneObject(group); + m_parentScene.DeleteSceneObject(group, false); } } } } protected internal void AttachObject( - IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos) + IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) { List EntityList = GetEntities(); foreach (EntityBase obj in EntityList) @@ -553,7 +553,7 @@ namespace OpenSim.Region.Environment.Scenes m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group); - group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos); + group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); // In case it is later dropped again, don't let // it get cleaned up // diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index 42986ec..c59fffc 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs @@ -1601,7 +1601,7 @@ namespace OpenSim.Region.Environment.Scenes } else if (permissionToDelete) { - DeleteSceneObject(grp); + DeleteSceneObject(grp, false); } } @@ -1735,7 +1735,7 @@ namespace OpenSim.Region.Environment.Scenes // Finally remove the item, for reals this time. if (permissionToDelete) - DeleteSceneObject(objectGroup); + DeleteSceneObject(objectGroup, false); } public void updateKnownAsset(IClientAPI remoteClient, SceneObjectGroup grp, UUID assetID, UUID agentID) @@ -2279,7 +2279,7 @@ namespace OpenSim.Region.Environment.Scenes returnobjects[i] = null; - DeleteSceneObject(ObjectDeleting); + DeleteSceneObject(ObjectDeleting, false); ObjectDeleting = null; } else @@ -2320,7 +2320,7 @@ namespace OpenSim.Region.Environment.Scenes EventManager.TriggerStopScript(part.LocalId, itemID); } - public void RezSingleAttachment(IClientAPI remoteClient, UUID itemID, + public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { SceneObjectGroup att = m_innerScene.RezSingleAttachment(remoteClient, itemID, AttachmentPt); @@ -2328,13 +2328,13 @@ namespace OpenSim.Region.Environment.Scenes if (att == null) { DetachSingleAttachmentToInv(itemID, remoteClient); - return; + return UUID.Zero; } - RezSingleAttachment(att, remoteClient, itemID, AttachmentPt); + return RezSingleAttachment(att, remoteClient, itemID, AttachmentPt); } - public void RezSingleAttachment(SceneObjectGroup att, + public UUID RezSingleAttachment(SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { if (att.RootPart != null) @@ -2351,11 +2351,12 @@ namespace OpenSim.Region.Environment.Scenes } } + return att.UUID; } public void AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos) { - m_innerScene.AttachObject(controllingClient, localID, attachPoint, rot, pos); + m_innerScene.AttachObject(controllingClient, localID, attachPoint, rot, pos, false); } public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index cee183c..40f8605 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1831,7 +1831,7 @@ namespace OpenSim.Region.Environment.Scenes foreach (EntityBase e in entities) { if (e is SceneObjectGroup) - DeleteSceneObject((SceneObjectGroup)e); + DeleteSceneObject((SceneObjectGroup)e, false); } } } @@ -1840,7 +1840,7 @@ namespace OpenSim.Region.Environment.Scenes /// Delete the given object from the scene. /// /// - public void DeleteSceneObject(SceneObjectGroup group) + public void DeleteSceneObject(SceneObjectGroup group, bool silent) { //SceneObjectPart rootPart = group.GetChildPart(group.UUID); @@ -1866,7 +1866,7 @@ namespace OpenSim.Region.Environment.Scenes EventManager.TriggerParcelPrimCountTainted(); } - group.DeleteGroup(); + group.DeleteGroup(silent); } /// @@ -1982,7 +1982,7 @@ namespace OpenSim.Region.Environment.Scenes /// /// the attempted out of region position of the scene object /// the scene object that we're crossing - public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp) + public void CrossPrimGroupIntoNewRegion(Vector3 attemptedPosition, SceneObjectGroup grp, bool silent) { if (grp == null) return; @@ -1994,7 +1994,7 @@ namespace OpenSim.Region.Environment.Scenes // We remove the object here try { - DeleteSceneObject(grp); + DeleteSceneObject(grp, false); } catch (Exception) { @@ -2044,7 +2044,7 @@ namespace OpenSim.Region.Environment.Scenes grp.OffsetForNewRegion(pos); // If we fail to cross the border, then reset the position of the scene object on that border. - if (!CrossPrimGroupIntoNewRegion(newRegionHandle, grp)) + if (!CrossPrimGroupIntoNewRegion(newRegionHandle, grp, silent)) { grp.OffsetForNewRegion(oldGroupPosition); } @@ -2059,7 +2059,7 @@ namespace OpenSim.Region.Environment.Scenes /// true if the crossing itself was successful, false on failure /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region /// - public bool CrossPrimGroupIntoNewRegion(ulong newRegionHandle, SceneObjectGroup grp) + public bool CrossPrimGroupIntoNewRegion(ulong newRegionHandle, SceneObjectGroup grp, bool silent) { bool successYN = false; int primcrossingXMLmethod = 0; @@ -2075,7 +2075,7 @@ namespace OpenSim.Region.Environment.Scenes // We remove the object here try { - DeleteSceneObject(grp); + DeleteSceneObject(grp, silent); } catch (Exception e) { @@ -2115,7 +2115,7 @@ namespace OpenSim.Region.Environment.Scenes /// public bool IncomingInterRegionPrimGroup(ulong regionHandle, UUID primID, string objXMLData, int XMLMethod) { - m_log.Warn("{[INTERREGION]: A new prim arrived from a neighbor"); + m_log.Warn("[INTERREGION]: A new prim arrived from a neighbor"); if (XMLMethod == 0) { SceneObjectGroup sceneObject = m_serialiser.DeserializeGroupFromXml2(objXMLData); @@ -2129,7 +2129,7 @@ namespace OpenSim.Region.Environment.Scenes SceneObjectGroup grp = RootPrim.ParentGroup; if (grp != null) { - DeleteSceneObject(grp); + DeleteSceneObject(grp, false); } m_log.Info("[INTERREGION]: Denied prim crossing for banned avatar"); @@ -2145,6 +2145,8 @@ namespace OpenSim.Region.Environment.Scenes { // Never persist + m_log.DebugFormat("[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.RootPart.LastOwnerID.ToString(), grp.UUID.ToString()); + grp.DetachFromBackup(); // Attachment @@ -2156,6 +2158,7 @@ namespace OpenSim.Region.Environment.Scenes // with the deeded object, it goes back to them grp.SetFromAssetID(grp.RootPart.LastOwnerID); + m_log.DebugFormat("[ATTACHMENT]: Attach to avatar {0}", sp.UUID.ToString()); AttachObject(sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition); } else @@ -4354,7 +4357,7 @@ namespace OpenSim.Region.Environment.Scenes if ((grp.RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) { if (grp.RootPart.Expires <= DateTime.Now) - DeleteSceneObject(grp); + DeleteSceneObject(grp, false); } } } diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index fb8ec94..be21460 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -675,8 +675,6 @@ namespace OpenSim.Region.Environment.Scenes // the avatar.Close below will clear the child region list. We need this below for (possibly) // closing the child agents, so save it here (we need a copy as it is Clear()-ed). List childRegions = new List(avatar.GetKnownRegionList()); - avatar.Close(); - // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport // failure at this point (unlike a border crossing failure). So perhaps this can never fail // once we reach here... @@ -712,11 +710,14 @@ namespace OpenSim.Region.Environment.Scenes avatar.MakeChildAgent(); Thread.Sleep(5000); - avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle); + avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); if (KiPrimitive != null) { KiPrimitive(avatar.LocalId); } + + avatar.Close(); + uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40); diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 2f25478..a19564f 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -227,7 +227,7 @@ namespace OpenSim.Region.Environment.Scenes if ((val.X > 257f || val.X < -1f || val.Y > 257f || val.Y < -1f) && !IsAttachment) { - m_scene.CrossPrimGroupIntoNewRegion(val, this); + m_scene.CrossPrimGroupIntoNewRegion(val, this, true); } lock (m_parts) @@ -319,7 +319,7 @@ namespace OpenSim.Region.Environment.Scenes { m_isSelected = value; // Tell physics engine that group is selected - if (m_rootPart.PhysActor != null) + if (m_rootPart != null && m_rootPart.PhysActor != null) { m_rootPart.PhysActor.Selected = value; // Pass it on to the children. @@ -746,7 +746,7 @@ namespace OpenSim.Region.Environment.Scenes /// /// /// - public void AttachToAgent(UUID agentID, uint attachmentpoint, Vector3 AttachOffset) + public void AttachToAgent(UUID agentID, uint attachmentpoint, Vector3 AttachOffset, bool silent) { ScenePresence avatar = m_scene.GetScenePresence(agentID); if (avatar != null) @@ -777,19 +777,24 @@ namespace OpenSim.Region.Environment.Scenes SetAttachmentPoint(Convert.ToByte(attachmentpoint)); avatar.AddAttachment(this); - // Killing it here will cause the client to deselect it - // It then reappears on the avatar, deselected - // through the full update below - // - if (IsSelected) + + if(!silent) { - m_scene.SendKillObject(m_rootPart.LocalId); - } + // Killing it here will cause the client to deselect it + // It then reappears on the avatar, deselected + // through the full update below + // + if (IsSelected) + { + m_scene.SendKillObject(m_rootPart.LocalId); + } - IsSelected = false; // fudge.... - ScheduleGroupForFullUpdate(); + IsSelected = false; // fudge.... + ScheduleGroupForFullUpdate(); + } } } + public byte GetAttachmentPoint() { if (m_rootPart != null) @@ -994,7 +999,7 @@ namespace OpenSim.Region.Environment.Scenes /// /// Delete this group from its scene and tell all the scene presences about that deletion. /// - public void DeleteGroup() + public void DeleteGroup(bool silent) { // We need to keep track of this state in case this group is still queued for backup. // FIXME: This is a poor temporary solution, since it still leaves plenty of scope for race @@ -1018,8 +1023,11 @@ namespace OpenSim.Region.Environment.Scenes avatars[i].StandUp(); } - if (m_rootPart != null && part == m_rootPart) - avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); + if (!silent) + { + if (m_rootPart != null && part == m_rootPart) + avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); + } } } @@ -1257,13 +1265,16 @@ namespace OpenSim.Region.Environment.Scenes #region Client Updating - public void SendFullUpdateToClient(IClientAPI remoteClient, uint clientFlags) + public void SendFullUpdateToClient(IClientAPI remoteClient) { + SendPartFullUpdate(remoteClient, RootPart, m_scene.ExternalChecks.ExternalChecksGenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { - SendPartFullUpdate(remoteClient, part, clientFlags); + if (part != RootPart) + SendPartFullUpdate(remoteClient, part, m_scene.ExternalChecks.ExternalChecksGenerateClientFlags(remoteClient.AgentId, part.UUID)); } } } @@ -1626,11 +1637,14 @@ namespace OpenSim.Region.Environment.Scenes public void ScheduleFullUpdateToAvatar(ScenePresence presence) { + RootPart.AddFullUpdateToAvatar(presence); + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { - part.AddFullUpdateToAvatar(presence); + if (part != RootPart) + part.AddFullUpdateToAvatar(presence); } } } @@ -1652,11 +1666,14 @@ namespace OpenSim.Region.Environment.Scenes public void ScheduleGroupForFullUpdate() { checkAtTargets(); + RootPart.ScheduleFullUpdate(); + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { - part.ScheduleFullUpdate(); + if (part != RootPart) + part.ScheduleFullUpdate(); } } } @@ -1680,11 +1697,14 @@ namespace OpenSim.Region.Environment.Scenes /// public void SendGroupFullUpdate() { + RootPart.SendFullUpdateToAllClients(); + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { - part.SendFullUpdateToAllClients(); + if (part != RootPart) + part.SendFullUpdateToAllClients(); } } } diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index db4ab52..ad12420 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -114,8 +114,6 @@ namespace OpenSim.Region.Environment.Scenes private static readonly Vector3 m_sitTargetCorrectionOffset = new Vector3(0.1f, 0.0f, 0.3f); private float m_godlevel = 0; - private bool m_attachmentsTransported = true; - private bool m_invulnerable = true; private Vector3 m_LastChildAgentUpdatePosition = new Vector3(); @@ -611,8 +609,10 @@ namespace OpenSim.Region.Environment.Scenes } foreach (EntityBase e in ents) + { if (e is SceneObjectGroup) m_pendingObjects.Enqueue((SceneObjectGroup)e); + } } } @@ -626,7 +626,7 @@ namespace OpenSim.Region.Environment.Scenes // So it's not implemented now. // - // Don't even queue if we have seent this one + // Don't even queue if we have sent this one // if (!m_updateTimes.ContainsKey(g.UUID)) g.ScheduleFullUpdateToAvatar(this); @@ -637,6 +637,8 @@ namespace OpenSim.Region.Environment.Scenes while (m_partsUpdateQueue.Count > 0) { SceneObjectPart part = m_partsUpdateQueue.Dequeue(); + if (part.ParentGroup == null || part.ParentGroup.RootPart == null) + continue; if (m_updateTimes.ContainsKey(part.UUID)) { ScenePartUpdate update = m_updateTimes[part.UUID]; @@ -680,12 +682,25 @@ namespace OpenSim.Region.Environment.Scenes { //never been sent to client before so do full update - part.SendFullUpdate(ControllingClient, - GenerateClientFlags(part.UUID)); + + // Attachment handling + // + if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) + { + if (part != part.ParentGroup.RootPart) + continue; + + part.ParentGroup.SendFullUpdateToClient(ControllingClient); + continue; + } + ScenePartUpdate update = new ScenePartUpdate(); update.FullID = part.UUID; update.LastFullUpdateTime = part.TimeStampFull; m_updateTimes.Add(part.UUID, update); + + part.SendFullUpdate(ControllingClient, + GenerateClientFlags(part.UUID)); updateCount++; } @@ -1115,7 +1130,7 @@ namespace OpenSim.Region.Environment.Scenes // { proxyObjectGroup.SendGroupFullUpdate(); remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); - m_scene.DeleteSceneObject(proxyObjectGroup); + m_scene.DeleteSceneObject(proxyObjectGroup, false); // } // else // { @@ -2206,9 +2221,9 @@ namespace OpenSim.Region.Environment.Scenes // now we have a child agent in this region. Request all interesting data about other (root) agents SendInitialFullUpdateToAllClients(); - CrossAttachmentsIntoNewRegion(neighbourHandle); + CrossAttachmentsIntoNewRegion(neighbourHandle, true); - m_scene.SendKillObject(m_localId); +// m_scene.SendKillObject(m_localId); m_scene.NotifyMyCoarseLocationChange(); // the user may change their profile information in other region, @@ -2473,22 +2488,19 @@ namespace OpenSim.Region.Environment.Scenes { lock (m_attachments) { - if (!m_attachmentsTransported) + try { - try - { - foreach (SceneObjectGroup grp in m_attachments) - { - // ControllingClient may be null at this point! - m_scene.m_innerScene.DetachSingleAttachmentToInv(grp.GetFromAssetID(), ControllingClient); - } - } - catch (InvalidOperationException) + foreach (SceneObjectGroup grp in m_attachments) { - m_log.Info("[CLIENT]: Couldn't save attachments. :("); + // ControllingClient may be null at this point! + m_scene.m_innerScene.DetachSingleAttachmentToInv(grp.GetFromAssetID(), ControllingClient); } - m_attachments.Clear(); } + catch (InvalidOperationException) + { + m_log.Info("[CLIENT]: Couldn't save attachments. :("); + } + m_attachments.Clear(); } lock (m_knownChildRegions) { @@ -2582,9 +2594,8 @@ namespace OpenSim.Region.Environment.Scenes return true; } - public bool CrossAttachmentsIntoNewRegion(ulong regionHandle) + public bool CrossAttachmentsIntoNewRegion(ulong regionHandle, bool silent) { - m_attachmentsTransported = true; lock (m_attachments) { // Validate @@ -2604,7 +2615,8 @@ namespace OpenSim.Region.Environment.Scenes gobj.RootPart.IsAttachment = false; gobj.AbsolutePosition = gobj.RootPart.AttachedPos; gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); - m_scene.CrossPrimGroupIntoNewRegion(regionHandle, gobj); + m_log.DebugFormat("[ATTACHMENT]: Sending attachment {0} to region {1}", gobj.UUID, regionHandle); + m_scene.CrossPrimGroupIntoNewRegion(regionHandle, gobj, silent); } } m_attachments.Clear(); @@ -3130,6 +3142,9 @@ namespace OpenSim.Region.Environment.Scenes private void ItemReceived(UUID itemID) { + if (IsChildAgent) + return; + if (null == m_appearance) { m_log.Warn("[ATTACHMENT] Appearance has not been initialized"); @@ -3143,14 +3158,20 @@ namespace OpenSim.Region.Environment.Scenes UUID asset = m_appearance.GetAttachedAsset(attachpoint); if (UUID.Zero == asset) // We have just logged in { - m_log.InfoFormat("[ATTACHMENT] Rez attachment {0}", - itemID.ToString()); - try { // Rez from inventory - m_scene.RezSingleAttachment(ControllingClient, itemID, - (uint)attachpoint); + asset = m_scene.RezSingleAttachment(ControllingClient, + itemID, (uint)attachpoint); + // Corner case: We are not yet a Scene Entity + // Setting attachment info in RezSingleAttachment will fail + // Set it here + // + m_appearance.SetAttachment((int)attachpoint, itemID, + asset); + m_log.InfoFormat("[ATTACHMENT] Rezzed attachment {0}, inworld asset {1}", + itemID.ToString(), asset); + } catch (Exception e) { @@ -3160,20 +3181,28 @@ namespace OpenSim.Region.Environment.Scenes return; } - SceneObjectPart att = m_scene.GetSceneObjectPart(m_appearance.GetAttachedAsset(attachpoint)); + SceneObjectPart att = m_scene.GetSceneObjectPart(asset); // If this is null, then the asset has not yet appeared in world // so we revisit this when it does // - if (att != null) + if (att != null && att.UUID != asset) // Yes. It's really needed { - m_log.InfoFormat("[ATTACHEMENT] Attach from world {0}", - itemID.ToString()); + m_log.DebugFormat("[ATTACHMENT]: Attach from in world: ItemID {0}, Asset ID {1}, Attachment inworld: {2}", itemID.ToString(), asset.ToString(), att.UUID.ToString()); - // Attach from world, if not already attached - if (att.ParentGroup != null && !att.IsAttachment) - m_scene.AttachObject(ControllingClient, att.ParentGroup.LocalId, (uint)0, att.ParentGroup.GroupRotation, Vector3.Zero); + // This will throw if crossing katty-korner + // So catch it here to avoid the noid + // + try + { + // Attach from world, if not already attached + if (att.ParentGroup != null && !att.IsAttachment) + m_scene.AttachObject(ControllingClient, att.ParentGroup.LocalId, (uint)0, att.ParentGroup.GroupRotation, Vector3.Zero); + } + catch (System.NullReferenceException e) + { + } } } } -- cgit v1.1